From 7ad920b504a980adcab4d3f6b85695526e6fd7bb Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 6 Oct 2009 11:31:05 -0700 Subject: ceph: documentation Mount options, syntax. Signed-off-by: Sage Weil diff --git a/Documentation/filesystems/ceph.txt b/Documentation/filesystems/ceph.txt new file mode 100644 index 0000000..6e03917 --- /dev/null +++ b/Documentation/filesystems/ceph.txt @@ -0,0 +1,139 @@ +Ceph Distributed File System +============================ + +Ceph is a distributed network file system designed to provide good +performance, reliability, and scalability. + +Basic features include: + + * POSIX semantics + * Seamless scaling from 1 to many thousands of nodes + * High availability and reliability. No single points of failure. + * N-way replication of data across storage nodes + * Fast recovery from node failures + * Automatic rebalancing of data on node addition/removal + * Easy deployment: most FS components are userspace daemons + +Also, + * Flexible snapshots (on any directory) + * Recursive accounting (nested files, directories, bytes) + +In contrast to cluster filesystems like GFS, OCFS2, and GPFS that rely +on symmetric access by all clients to shared block devices, Ceph +separates data and metadata management into independent server +clusters, similar to Lustre. Unlike Lustre, however, metadata and +storage nodes run entirely as user space daemons. Storage nodes +utilize btrfs to store data objects, leveraging its advanced features +(checksumming, metadata replication, etc.). File data is striped +across storage nodes in large chunks to distribute workload and +facilitate high throughputs. When storage nodes fail, data is +re-replicated in a distributed fashion by the storage nodes themselves +(with some minimal coordination from a cluster monitor), making the +system extremely efficient and scalable. + +Metadata servers effectively form a large, consistent, distributed +in-memory cache above the file namespace that is extremely scalable, +dynamically redistributes metadata in response to workload changes, +and can tolerate arbitrary (well, non-Byzantine) node failures. The +metadata server takes a somewhat unconventional approach to metadata +storage to significantly improve performance for common workloads. In +particular, inodes with only a single link are embedded in +directories, allowing entire directories of dentries and inodes to be +loaded into its cache with a single I/O operation. The contents of +extremely large directories can be fragmented and managed by +independent metadata servers, allowing scalable concurrent access. + +The system offers automatic data rebalancing/migration when scaling +from a small cluster of just a few nodes to many hundreds, without +requiring an administrator carve the data set into static volumes or +go through the tedious process of migrating data between servers. +When the file system approaches full, new nodes can be easily added +and things will "just work." + +Ceph includes flexible snapshot mechanism that allows a user to create +a snapshot on any subdirectory (and its nested contents) in the +system. Snapshot creation and deletion are as simple as 'mkdir +.snap/foo' and 'rmdir .snap/foo'. + +Ceph also provides some recursive accounting on directories for nested +files and bytes. That is, a 'getfattr -d foo' on any directory in the +system will reveal the total number of nested regular files and +subdirectories, and a summation of all nested file sizes. This makes +the identification of large disk space consumers relatively quick, as +no 'du' or similar recursive scan of the file system is required. + + +Mount Syntax +============ + +The basic mount syntax is: + + # mount -t ceph monip[:port][,monip2[:port]...]:/[subdir] mnt + +You only need to specify a single monitor, as the client will get the +full list when it connects. (However, if the monitor you specify +happens to be down, the mount won't succeed.) The port can be left +off if the monitor is using the default. So if the monitor is at +1.2.3.4, + + # mount -t ceph 1.2.3.4:/ /mnt/ceph + +is sufficient. If /sbin/mount.ceph is installed, a hostname can be +used instead of an IP address. + + + +Mount Options +============= + + ip=A.B.C.D[:N] + Specify the IP and/or port the client should bind to locally. + There is normally not much reason to do this. If the IP is not + specified, the client's IP address is determined by looking at the + address it's connection to the monitor originates from. + + wsize=X + Specify the maximum write size in bytes. By default there is no + maximu. Ceph will normally size writes based on the file stripe + size. + + rsize=X + Specify the maximum readahead. + + mount_timeout=X + Specify the timeout value for mount (in seconds), in the case + of a non-responsive Ceph file system. The default is 30 + seconds. + + rbytes + When stat() is called on a directory, set st_size to 'rbytes', + the summation of file sizes over all files nested beneath that + directory. This is the default. + + norbytes + When stat() is called on a directory, set st_size to the + number of entries in that directory. + + nocrc + Disable CRC32C calculation for data writes. If set, the OSD + must rely on TCP's error correction to detect data corruption + in the data payload. + + noasyncreaddir + Disable client's use its local cache to satisfy readdir + requests. (This does not change correctness; the client uses + cached metadata only when a lease or capability ensures it is + valid.) + + +More Information +================ + +For more information on Ceph, see the home page at + http://ceph.newdream.net/ + +The Linux kernel client source tree is available at + git://ceph.newdream.net/linux-ceph-client.git + +and the source for the full system is at + git://ceph.newdream.net/ceph.git -- cgit v0.10.2 From 0dee3c28af2fbe22ca62739a7f57da5435d35793 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 6 Oct 2009 11:31:06 -0700 Subject: ceph: on-wire types These headers describe the types used to exchange messages between the Ceph client and various servers. All types are little-endian and packed. These headers are shared between the kernel and userspace, so all types are in terms of e.g. __u32. Additionally, we define a few magic values to identify the current version of the protocol(s) in use, so that discrepancies to be detected on mount. Signed-off-by: Sage Weil diff --git a/fs/ceph/ceph_fs.c b/fs/ceph/ceph_fs.c new file mode 100644 index 0000000..9371ff1 --- /dev/null +++ b/fs/ceph/ceph_fs.c @@ -0,0 +1,80 @@ +/* + * Some non-inline ceph helpers + */ +#include "types.h" + +int ceph_flags_to_mode(int flags) +{ +#ifdef O_DIRECTORY /* fixme */ + if ((flags & O_DIRECTORY) == O_DIRECTORY) + return CEPH_FILE_MODE_PIN; +#endif +#ifdef O_LAZY + if (flags & O_LAZY) + return CEPH_FILE_MODE_LAZY; +#endif + if ((flags & O_APPEND) == O_APPEND) + flags |= O_WRONLY; + + flags &= O_ACCMODE; + if ((flags & O_RDWR) == O_RDWR) + return CEPH_FILE_MODE_RDWR; + if ((flags & O_WRONLY) == O_WRONLY) + return CEPH_FILE_MODE_WR; + return CEPH_FILE_MODE_RD; +} + +int ceph_caps_for_mode(int mode) +{ + switch (mode) { + case CEPH_FILE_MODE_PIN: + return CEPH_CAP_PIN; + case CEPH_FILE_MODE_RD: + return CEPH_CAP_PIN | CEPH_CAP_FILE_SHARED | + CEPH_CAP_FILE_RD | CEPH_CAP_FILE_CACHE; + case CEPH_FILE_MODE_RDWR: + return CEPH_CAP_PIN | CEPH_CAP_FILE_SHARED | + CEPH_CAP_FILE_EXCL | + CEPH_CAP_FILE_RD | CEPH_CAP_FILE_CACHE | + CEPH_CAP_FILE_WR | CEPH_CAP_FILE_BUFFER | + CEPH_CAP_AUTH_SHARED | CEPH_CAP_AUTH_EXCL | + CEPH_CAP_XATTR_SHARED | CEPH_CAP_XATTR_EXCL; + case CEPH_FILE_MODE_WR: + return CEPH_CAP_PIN | CEPH_CAP_FILE_SHARED | + CEPH_CAP_FILE_EXCL | + CEPH_CAP_FILE_WR | CEPH_CAP_FILE_BUFFER | + CEPH_CAP_AUTH_SHARED | CEPH_CAP_AUTH_EXCL | + CEPH_CAP_XATTR_SHARED | CEPH_CAP_XATTR_EXCL; + } + return 0; +} + +/* Name hashing routines. Initial hash value */ +/* Hash courtesy of the R5 hash in reiserfs modulo sign bits */ +#define ceph_init_name_hash() 0 + +/* partial hash update function. Assume roughly 4 bits per character */ +static unsigned long ceph_partial_name_hash(unsigned long c, + unsigned long prevhash) +{ + return (prevhash + (c << 4) + (c >> 4)) * 11; +} + +/* + * Finally: cut down the number of bits to a int value (and try to avoid + * losing bits) + */ +static unsigned long ceph_end_name_hash(unsigned long hash) +{ + return hash & 0xffffffff; +} + +/* Compute the hash for a name string. */ +unsigned int ceph_full_name_hash(const char *name, unsigned int len) +{ + unsigned long hash = ceph_init_name_hash(); + while (len--) + hash = ceph_partial_name_hash(*name++, hash); + return ceph_end_name_hash(hash); +} + diff --git a/fs/ceph/ceph_fs.h b/fs/ceph/ceph_fs.h new file mode 100644 index 0000000..21ed51b --- /dev/null +++ b/fs/ceph/ceph_fs.h @@ -0,0 +1,629 @@ +/* + * ceph_fs.h - Ceph constants and data types to share between kernel and + * user space. + * + * Most types in this file are defined as little-endian, and are + * primarily intended to describe data structures that pass over the + * wire or that are stored on disk. + * + * LGPL2 + */ + +#ifndef _FS_CEPH_CEPH_FS_H +#define _FS_CEPH_CEPH_FS_H + +#include "msgr.h" +#include "rados.h" + +/* + * Ceph release version + */ +#define CEPH_VERSION_MAJOR 0 +#define CEPH_VERSION_MINOR 16 +#define CEPH_VERSION_PATCH 1 + +#define _CEPH_STRINGIFY(x) #x +#define CEPH_STRINGIFY(x) _CEPH_STRINGIFY(x) +#define CEPH_MAKE_VERSION(x, y, z) CEPH_STRINGIFY(x) "." CEPH_STRINGIFY(y) \ + "." CEPH_STRINGIFY(z) +#define CEPH_VERSION CEPH_MAKE_VERSION(CEPH_VERSION_MAJOR, \ + CEPH_VERSION_MINOR, CEPH_VERSION_PATCH) + +/* + * subprotocol versions. when specific messages types or high-level + * protocols change, bump the affected components. we keep rev + * internal cluster protocols separately from the public, + * client-facing protocol. + */ +#define CEPH_OSD_PROTOCOL 7 /* cluster internal */ +#define CEPH_MDS_PROTOCOL 9 /* cluster internal */ +#define CEPH_MON_PROTOCOL 4 /* cluster internal */ +#define CEPH_OSDC_PROTOCOL 20 /* server/client */ +#define CEPH_MDSC_PROTOCOL 29 /* server/client */ +#define CEPH_MONC_PROTOCOL 14 /* server/client */ + + +#define CEPH_INO_ROOT 1 + +/* arbitrary limit on max # of monitors (cluster of 3 is typical) */ +#define CEPH_MAX_MON 31 + + +unsigned int ceph_full_name_hash(const char *name, unsigned int len); + + +/* + * ceph_file_layout - describe data layout for a file/inode + */ +struct ceph_file_layout { + /* file -> object mapping */ + __le32 fl_stripe_unit; /* stripe unit, in bytes. must be multiple + of page size. */ + __le32 fl_stripe_count; /* over this many objects */ + __le32 fl_object_size; /* until objects are this big, then move to + new objects */ + __le32 fl_cas_hash; /* 0 = none; 1 = sha256 */ + + /* pg -> disk layout */ + __le32 fl_object_stripe_unit; /* for per-object parity, if any */ + + /* object -> pg layout */ + __le32 fl_pg_preferred; /* preferred primary for pg (-1 for none) */ + __le32 fl_pg_pool; /* namespace, crush ruleset, rep level */ +} __attribute__ ((packed)); + + + + +/********************************************* + * message layer + */ + +/* + * message types + */ + +/* misc */ +#define CEPH_MSG_SHUTDOWN 1 +#define CEPH_MSG_PING 2 + +/* client <-> monitor */ +#define CEPH_MSG_MON_MAP 4 +#define CEPH_MSG_MON_GET_MAP 5 +#define CEPH_MSG_CLIENT_MOUNT 10 +#define CEPH_MSG_CLIENT_MOUNT_ACK 11 +#define CEPH_MSG_STATFS 13 +#define CEPH_MSG_STATFS_REPLY 14 +#define CEPH_MSG_MON_SUBSCRIBE 15 +#define CEPH_MSG_MON_SUBSCRIBE_ACK 16 + +/* client <-> mds */ +#define CEPH_MSG_MDS_GETMAP 20 +#define CEPH_MSG_MDS_MAP 21 + +#define CEPH_MSG_CLIENT_SESSION 22 +#define CEPH_MSG_CLIENT_RECONNECT 23 + +#define CEPH_MSG_CLIENT_REQUEST 24 +#define CEPH_MSG_CLIENT_REQUEST_FORWARD 25 +#define CEPH_MSG_CLIENT_REPLY 26 +#define CEPH_MSG_CLIENT_CAPS 0x310 +#define CEPH_MSG_CLIENT_LEASE 0x311 +#define CEPH_MSG_CLIENT_SNAP 0x312 +#define CEPH_MSG_CLIENT_CAPRELEASE 0x313 + +/* osd */ +#define CEPH_MSG_OSD_GETMAP 40 +#define CEPH_MSG_OSD_MAP 41 +#define CEPH_MSG_OSD_OP 42 +#define CEPH_MSG_OSD_OPREPLY 43 + + +struct ceph_mon_statfs { + __le64 have_version; + struct ceph_fsid fsid; + __le64 tid; +} __attribute__ ((packed)); + +struct ceph_statfs { + __le64 kb, kb_used, kb_avail; + __le64 num_objects; +} __attribute__ ((packed)); + +struct ceph_mon_statfs_reply { + struct ceph_fsid fsid; + __le64 tid; + __le64 version; + struct ceph_statfs st; +} __attribute__ ((packed)); + +struct ceph_osd_getmap { + __le64 have_version; + struct ceph_fsid fsid; + __le32 start; +} __attribute__ ((packed)); + +struct ceph_mds_getmap { + __le64 have_version; + struct ceph_fsid fsid; +} __attribute__ ((packed)); + +struct ceph_client_mount { + __le64 have_version; +} __attribute__ ((packed)); + +struct ceph_mon_subscribe_item { + __le64 have; + __u8 onetime; +} __attribute__ ((packed)); + +/* + * mds states + * > 0 -> in + * <= 0 -> out + */ +#define CEPH_MDS_STATE_DNE 0 /* down, does not exist. */ +#define CEPH_MDS_STATE_STOPPED -1 /* down, once existed, but no subtrees. + empty log. */ +#define CEPH_MDS_STATE_BOOT -4 /* up, boot announcement. */ +#define CEPH_MDS_STATE_STANDBY -5 /* up, idle. waiting for assignment. */ +#define CEPH_MDS_STATE_CREATING -6 /* up, creating MDS instance. */ +#define CEPH_MDS_STATE_STARTING -7 /* up, starting previously stopped mds */ +#define CEPH_MDS_STATE_STANDBY_REPLAY -8 /* up, tailing active node's journal */ + +#define CEPH_MDS_STATE_REPLAY 8 /* up, replaying journal. */ +#define CEPH_MDS_STATE_RESOLVE 9 /* up, disambiguating distributed + operations (import, rename, etc.) */ +#define CEPH_MDS_STATE_RECONNECT 10 /* up, reconnect to clients */ +#define CEPH_MDS_STATE_REJOIN 11 /* up, rejoining distributed cache */ +#define CEPH_MDS_STATE_CLIENTREPLAY 12 /* up, replaying client operations */ +#define CEPH_MDS_STATE_ACTIVE 13 /* up, active */ +#define CEPH_MDS_STATE_STOPPING 14 /* up, but exporting metadata */ + +extern const char *ceph_mds_state_name(int s); + + +/* + * metadata lock types. + * - these are bitmasks.. we can compose them + * - they also define the lock ordering by the MDS + * - a few of these are internal to the mds + */ +#define CEPH_LOCK_DN 1 +#define CEPH_LOCK_ISNAP 2 +#define CEPH_LOCK_IVERSION 4 /* mds internal */ +#define CEPH_LOCK_IFILE 8 /* mds internal */ +#define CEPH_LOCK_IAUTH 32 +#define CEPH_LOCK_ILINK 64 +#define CEPH_LOCK_IDFT 128 /* dir frag tree */ +#define CEPH_LOCK_INEST 256 /* mds internal */ +#define CEPH_LOCK_IXATTR 512 +#define CEPH_LOCK_INO 2048 /* immutable inode bits; not a lock */ + +/* client_session ops */ +enum { + CEPH_SESSION_REQUEST_OPEN, + CEPH_SESSION_OPEN, + CEPH_SESSION_REQUEST_CLOSE, + CEPH_SESSION_CLOSE, + CEPH_SESSION_REQUEST_RENEWCAPS, + CEPH_SESSION_RENEWCAPS, + CEPH_SESSION_STALE, + CEPH_SESSION_RECALL_STATE, +}; + +extern const char *ceph_session_op_name(int op); + +struct ceph_mds_session_head { + __le32 op; + __le64 seq; + struct ceph_timespec stamp; + __le32 max_caps, max_leases; +} __attribute__ ((packed)); + +/* client_request */ +/* + * metadata ops. + * & 0x001000 -> write op + * & 0x010000 -> follow symlink (e.g. stat(), not lstat()). + & & 0x100000 -> use weird ino/path trace + */ +#define CEPH_MDS_OP_WRITE 0x001000 +enum { + CEPH_MDS_OP_LOOKUP = 0x00100, + CEPH_MDS_OP_GETATTR = 0x00101, + CEPH_MDS_OP_LOOKUPHASH = 0x00102, + CEPH_MDS_OP_LOOKUPPARENT = 0x00103, + + CEPH_MDS_OP_SETXATTR = 0x01105, + CEPH_MDS_OP_RMXATTR = 0x01106, + CEPH_MDS_OP_SETLAYOUT = 0x01107, + CEPH_MDS_OP_SETATTR = 0x01108, + + CEPH_MDS_OP_MKNOD = 0x01201, + CEPH_MDS_OP_LINK = 0x01202, + CEPH_MDS_OP_UNLINK = 0x01203, + CEPH_MDS_OP_RENAME = 0x01204, + CEPH_MDS_OP_MKDIR = 0x01220, + CEPH_MDS_OP_RMDIR = 0x01221, + CEPH_MDS_OP_SYMLINK = 0x01222, + + CEPH_MDS_OP_CREATE = 0x00301, + CEPH_MDS_OP_OPEN = 0x00302, + CEPH_MDS_OP_READDIR = 0x00305, + + CEPH_MDS_OP_LOOKUPSNAP = 0x00400, + CEPH_MDS_OP_MKSNAP = 0x01400, + CEPH_MDS_OP_RMSNAP = 0x01401, + CEPH_MDS_OP_LSSNAP = 0x00402, +}; + +extern const char *ceph_mds_op_name(int op); + + +#define CEPH_SETATTR_MODE 1 +#define CEPH_SETATTR_UID 2 +#define CEPH_SETATTR_GID 4 +#define CEPH_SETATTR_MTIME 8 +#define CEPH_SETATTR_ATIME 16 +#define CEPH_SETATTR_SIZE 32 +#define CEPH_SETATTR_CTIME 64 + +union ceph_mds_request_args { + struct { + __le32 mask; /* CEPH_CAP_* */ + } __attribute__ ((packed)) getattr; + struct { + __le32 mode; + __le32 uid; + __le32 gid; + struct ceph_timespec mtime; + struct ceph_timespec atime; + __le64 size, old_size; /* old_size needed by truncate */ + __le32 mask; /* CEPH_SETATTR_* */ + } __attribute__ ((packed)) setattr; + struct { + __le32 frag; /* which dir fragment */ + __le32 max_entries; /* how many dentries to grab */ + } __attribute__ ((packed)) readdir; + struct { + __le32 mode; + __le32 rdev; + } __attribute__ ((packed)) mknod; + struct { + __le32 mode; + } __attribute__ ((packed)) mkdir; + struct { + __le32 flags; + __le32 mode; + __le32 stripe_unit; /* layout for newly created file */ + __le32 stripe_count; /* ... */ + __le32 object_size; + __le32 file_replication; + __le32 preferred; + } __attribute__ ((packed)) open; + struct { + __le32 flags; + } __attribute__ ((packed)) setxattr; + struct { + struct ceph_file_layout layout; + } __attribute__ ((packed)) setlayout; +} __attribute__ ((packed)); + +#define CEPH_MDS_FLAG_REPLAY 1 /* this is a replayed op */ +#define CEPH_MDS_FLAG_WANT_DENTRY 2 /* want dentry in reply */ + +struct ceph_mds_request_head { + __le64 tid, oldest_client_tid; + __le32 mdsmap_epoch; /* on client */ + __le32 flags; /* CEPH_MDS_FLAG_* */ + __u8 num_retry, num_fwd; /* count retry, fwd attempts */ + __le16 num_releases; /* # include cap/lease release records */ + __le32 op; /* mds op code */ + __le32 caller_uid, caller_gid; + __le64 ino; /* use this ino for openc, mkdir, mknod, + etc. (if replaying) */ + union ceph_mds_request_args args; +} __attribute__ ((packed)); + +/* cap/lease release record */ +struct ceph_mds_request_release { + __le64 ino, cap_id; /* ino and unique cap id */ + __le32 caps, wanted; /* new issued, wanted */ + __le32 seq, issue_seq, mseq; + __le32 dname_seq; /* if releasing a dentry lease, a */ + __le32 dname_len; /* string follows. */ +} __attribute__ ((packed)); + +/* client reply */ +struct ceph_mds_reply_head { + __le64 tid; + __le32 op; + __le32 result; + __le32 mdsmap_epoch; + __u8 safe; /* true if committed to disk */ + __u8 is_dentry, is_target; /* true if dentry, target inode records + are included with reply */ +} __attribute__ ((packed)); + +/* one for each node split */ +struct ceph_frag_tree_split { + __le32 frag; /* this frag splits... */ + __le32 by; /* ...by this many bits */ +} __attribute__ ((packed)); + +struct ceph_frag_tree_head { + __le32 nsplits; /* num ceph_frag_tree_split records */ + struct ceph_frag_tree_split splits[]; +} __attribute__ ((packed)); + +/* capability issue, for bundling with mds reply */ +struct ceph_mds_reply_cap { + __le32 caps, wanted; /* caps issued, wanted */ + __le64 cap_id; + __le32 seq, mseq; + __le64 realm; /* snap realm */ + __u8 flags; /* CEPH_CAP_FLAG_* */ +} __attribute__ ((packed)); + +#define CEPH_CAP_FLAG_AUTH 1 /* cap is issued by auth mds */ + +/* inode record, for bundling with mds reply */ +struct ceph_mds_reply_inode { + __le64 ino; + __le64 snapid; + __le32 rdev; + __le64 version; /* inode version */ + __le64 xattr_version; /* version for xattr blob */ + struct ceph_mds_reply_cap cap; /* caps issued for this inode */ + struct ceph_file_layout layout; + struct ceph_timespec ctime, mtime, atime; + __le32 time_warp_seq; + __le64 size, max_size, truncate_size; + __le32 truncate_seq; + __le32 mode, uid, gid; + __le32 nlink; + __le64 files, subdirs, rbytes, rfiles, rsubdirs; /* dir stats */ + struct ceph_timespec rctime; + struct ceph_frag_tree_head fragtree; /* (must be at end of struct) */ +} __attribute__ ((packed)); +/* followed by frag array, then symlink string, then xattr blob */ + +/* reply_lease follows dname, and reply_inode */ +struct ceph_mds_reply_lease { + __le16 mask; /* lease type(s) */ + __le32 duration_ms; /* lease duration */ + __le32 seq; +} __attribute__ ((packed)); + +struct ceph_mds_reply_dirfrag { + __le32 frag; /* fragment */ + __le32 auth; /* auth mds, if this is a delegation point */ + __le32 ndist; /* number of mds' this is replicated on */ + __le32 dist[]; +} __attribute__ ((packed)); + +/* file access modes */ +#define CEPH_FILE_MODE_PIN 0 +#define CEPH_FILE_MODE_RD 1 +#define CEPH_FILE_MODE_WR 2 +#define CEPH_FILE_MODE_RDWR 3 /* RD | WR */ +#define CEPH_FILE_MODE_LAZY 4 /* lazy io */ +#define CEPH_FILE_MODE_NUM 8 /* bc these are bit fields.. mostly */ + +int ceph_flags_to_mode(int flags); + + +/* capability bits */ +#define CEPH_CAP_PIN 1 /* no specific capabilities beyond the pin */ + +/* generic cap bits */ +#define CEPH_CAP_GSHARED 1 /* client can reads */ +#define CEPH_CAP_GEXCL 2 /* client can read and update */ +#define CEPH_CAP_GCACHE 4 /* (file) client can cache reads */ +#define CEPH_CAP_GRD 8 /* (file) client can read */ +#define CEPH_CAP_GWR 16 /* (file) client can write */ +#define CEPH_CAP_GBUFFER 32 /* (file) client can buffer writes */ +#define CEPH_CAP_GWREXTEND 64 /* (file) client can extend EOF */ +#define CEPH_CAP_GLAZYIO 128 /* (file) client can perform lazy io */ + +/* per-lock shift */ +#define CEPH_CAP_SAUTH 2 +#define CEPH_CAP_SLINK 4 +#define CEPH_CAP_SXATTR 6 +#define CEPH_CAP_SFILE 8 /* goes at the end (uses >2 cap bits) */ + +#define CEPH_CAP_BITS 16 + +/* composed values */ +#define CEPH_CAP_AUTH_SHARED (CEPH_CAP_GSHARED << CEPH_CAP_SAUTH) +#define CEPH_CAP_AUTH_EXCL (CEPH_CAP_GEXCL << CEPH_CAP_SAUTH) +#define CEPH_CAP_LINK_SHARED (CEPH_CAP_GSHARED << CEPH_CAP_SLINK) +#define CEPH_CAP_LINK_EXCL (CEPH_CAP_GEXCL << CEPH_CAP_SLINK) +#define CEPH_CAP_XATTR_SHARED (CEPH_CAP_GSHARED << CEPH_CAP_SXATTR) +#define CEPH_CAP_XATTR_EXCL (CEPH_CAP_GEXCL << CEPH_CAP_SXATTR) +#define CEPH_CAP_FILE(x) (x << CEPH_CAP_SFILE) +#define CEPH_CAP_FILE_SHARED (CEPH_CAP_GSHARED << CEPH_CAP_SFILE) +#define CEPH_CAP_FILE_EXCL (CEPH_CAP_GEXCL << CEPH_CAP_SFILE) +#define CEPH_CAP_FILE_CACHE (CEPH_CAP_GCACHE << CEPH_CAP_SFILE) +#define CEPH_CAP_FILE_RD (CEPH_CAP_GRD << CEPH_CAP_SFILE) +#define CEPH_CAP_FILE_WR (CEPH_CAP_GWR << CEPH_CAP_SFILE) +#define CEPH_CAP_FILE_BUFFER (CEPH_CAP_GBUFFER << CEPH_CAP_SFILE) +#define CEPH_CAP_FILE_WREXTEND (CEPH_CAP_GWREXTEND << CEPH_CAP_SFILE) +#define CEPH_CAP_FILE_LAZYIO (CEPH_CAP_GLAZYIO << CEPH_CAP_SFILE) + +/* cap masks (for getattr) */ +#define CEPH_STAT_CAP_INODE CEPH_CAP_PIN +#define CEPH_STAT_CAP_TYPE CEPH_CAP_PIN /* mode >> 12 */ +#define CEPH_STAT_CAP_SYMLINK CEPH_CAP_PIN +#define CEPH_STAT_CAP_UID CEPH_CAP_AUTH_SHARED +#define CEPH_STAT_CAP_GID CEPH_CAP_AUTH_SHARED +#define CEPH_STAT_CAP_MODE CEPH_CAP_AUTH_SHARED +#define CEPH_STAT_CAP_NLINK CEPH_CAP_LINK_SHARED +#define CEPH_STAT_CAP_LAYOUT CEPH_CAP_FILE_SHARED +#define CEPH_STAT_CAP_MTIME CEPH_CAP_FILE_SHARED +#define CEPH_STAT_CAP_SIZE CEPH_CAP_FILE_SHARED +#define CEPH_STAT_CAP_ATIME CEPH_CAP_FILE_SHARED /* fixme */ +#define CEPH_STAT_CAP_XATTR CEPH_CAP_XATTR_SHARED +#define CEPH_STAT_CAP_INODE_ALL (CEPH_CAP_PIN | \ + CEPH_CAP_AUTH_SHARED | \ + CEPH_CAP_LINK_SHARED | \ + CEPH_CAP_FILE_SHARED | \ + CEPH_CAP_XATTR_SHARED) + +#define CEPH_CAP_ANY_SHARED (CEPH_CAP_AUTH_SHARED | \ + CEPH_CAP_LINK_SHARED | \ + CEPH_CAP_XATTR_SHARED | \ + CEPH_CAP_FILE_SHARED) +#define CEPH_CAP_ANY_RD (CEPH_CAP_ANY_SHARED | CEPH_CAP_FILE_RD | \ + CEPH_CAP_FILE_CACHE) + +#define CEPH_CAP_ANY_EXCL (CEPH_CAP_AUTH_EXCL | \ + CEPH_CAP_LINK_EXCL | \ + CEPH_CAP_XATTR_EXCL | \ + CEPH_CAP_FILE_EXCL) +#define CEPH_CAP_ANY_FILE_WR (CEPH_CAP_FILE_WR | CEPH_CAP_FILE_BUFFER | \ + CEPH_CAP_FILE_EXCL) +#define CEPH_CAP_ANY_WR (CEPH_CAP_ANY_EXCL | CEPH_CAP_ANY_FILE_WR) +#define CEPH_CAP_ANY (CEPH_CAP_ANY_RD | CEPH_CAP_ANY_EXCL | \ + CEPH_CAP_ANY_FILE_WR | CEPH_CAP_PIN) + +#define CEPH_CAP_LOCKS (CEPH_LOCK_IFILE | CEPH_LOCK_IAUTH | CEPH_LOCK_ILINK | \ + CEPH_LOCK_IXATTR) + +int ceph_caps_for_mode(int mode); + +enum { + CEPH_CAP_OP_GRANT, /* mds->client grant */ + CEPH_CAP_OP_REVOKE, /* mds->client revoke */ + CEPH_CAP_OP_TRUNC, /* mds->client trunc notify */ + CEPH_CAP_OP_EXPORT, /* mds has exported the cap */ + CEPH_CAP_OP_IMPORT, /* mds has imported the cap */ + CEPH_CAP_OP_UPDATE, /* client->mds update */ + CEPH_CAP_OP_DROP, /* client->mds drop cap bits */ + CEPH_CAP_OP_FLUSH, /* client->mds cap writeback */ + CEPH_CAP_OP_FLUSH_ACK, /* mds->client flushed */ + CEPH_CAP_OP_FLUSHSNAP, /* client->mds flush snapped metadata */ + CEPH_CAP_OP_FLUSHSNAP_ACK, /* mds->client flushed snapped metadata */ + CEPH_CAP_OP_RELEASE, /* client->mds release (clean) cap */ + CEPH_CAP_OP_RENEW, /* client->mds renewal request */ +}; + +extern const char *ceph_cap_op_name(int op); + +/* + * caps message, used for capability callbacks, acks, requests, etc. + */ +struct ceph_mds_caps { + __le32 op; /* CEPH_CAP_OP_* */ + __le64 ino, realm; + __le64 cap_id; + __le32 seq, issue_seq; + __le32 caps, wanted, dirty; /* latest issued/wanted/dirty */ + __le32 migrate_seq; + __le64 snap_follows; + __le32 snap_trace_len; + __le64 client_tid; /* for FLUSH(SNAP) -> FLUSH(SNAP)_ACK */ + + /* authlock */ + __le32 uid, gid, mode; + + /* linklock */ + __le32 nlink; + + /* xattrlock */ + __le32 xattr_len; + __le64 xattr_version; + + /* filelock */ + __le64 size, max_size, truncate_size; + __le32 truncate_seq; + struct ceph_timespec mtime, atime, ctime; + struct ceph_file_layout layout; + __le32 time_warp_seq; +} __attribute__ ((packed)); + +/* cap release msg head */ +struct ceph_mds_cap_release { + __le32 num; /* number of cap_items that follow */ +} __attribute__ ((packed)); + +struct ceph_mds_cap_item { + __le64 ino; + __le64 cap_id; + __le32 migrate_seq, seq; +} __attribute__ ((packed)); + +#define CEPH_MDS_LEASE_REVOKE 1 /* mds -> client */ +#define CEPH_MDS_LEASE_RELEASE 2 /* client -> mds */ +#define CEPH_MDS_LEASE_RENEW 3 /* client <-> mds */ +#define CEPH_MDS_LEASE_REVOKE_ACK 4 /* client -> mds */ + +extern const char *ceph_lease_op_name(int o); + +/* lease msg header */ +struct ceph_mds_lease { + __u8 action; /* CEPH_MDS_LEASE_* */ + __le16 mask; /* which lease */ + __le64 ino; + __le64 first, last; /* snap range */ + __le32 seq; + __le32 duration_ms; /* duration of renewal */ +} __attribute__ ((packed)); +/* followed by a __le32+string for dname */ + +/* client reconnect */ +struct ceph_mds_cap_reconnect { + __le64 cap_id; + __le32 wanted; + __le32 issued; + __le64 size; + struct ceph_timespec mtime, atime; + __le64 snaprealm; + __le64 pathbase; /* base ino for our path to this ino */ +} __attribute__ ((packed)); +/* followed by encoded string */ + +struct ceph_mds_snaprealm_reconnect { + __le64 ino; /* snap realm base */ + __le64 seq; /* snap seq for this snap realm */ + __le64 parent; /* parent realm */ +} __attribute__ ((packed)); + +/* + * snaps + */ +enum { + CEPH_SNAP_OP_UPDATE, /* CREATE or DESTROY */ + CEPH_SNAP_OP_CREATE, + CEPH_SNAP_OP_DESTROY, + CEPH_SNAP_OP_SPLIT, +}; + +extern const char *ceph_snap_op_name(int o); + +/* snap msg header */ +struct ceph_mds_snap_head { + __le32 op; /* CEPH_SNAP_OP_* */ + __le64 split; /* ino to split off, if any */ + __le32 num_split_inos; /* # inos belonging to new child realm */ + __le32 num_split_realms; /* # child realms udner new child realm */ + __le32 trace_len; /* size of snap trace blob */ +} __attribute__ ((packed)); +/* followed by split ino list, then split realms, then the trace blob */ + +/* + * encode info about a snaprealm, as viewed by a client + */ +struct ceph_mds_snap_realm { + __le64 ino; /* ino */ + __le64 created; /* snap: when created */ + __le64 parent; /* ino: parent realm */ + __le64 parent_since; /* snap: same parent since */ + __le64 seq; /* snap: version */ + __le32 num_snaps; + __le32 num_prior_parent_snaps; +} __attribute__ ((packed)); +/* followed by my snap list, then prior parent snap list */ + +#endif diff --git a/fs/ceph/ceph_strings.c b/fs/ceph/ceph_strings.c new file mode 100644 index 0000000..90d19d9 --- /dev/null +++ b/fs/ceph/ceph_strings.c @@ -0,0 +1,163 @@ +/* + * Ceph string constants + */ +#include "types.h" + +const char *ceph_osd_op_name(int op) +{ + switch (op) { + case CEPH_OSD_OP_READ: return "read"; + case CEPH_OSD_OP_STAT: return "stat"; + + case CEPH_OSD_OP_MASKTRUNC: return "masktrunc"; + + case CEPH_OSD_OP_WRITE: return "write"; + case CEPH_OSD_OP_DELETE: return "delete"; + case CEPH_OSD_OP_TRUNCATE: return "truncate"; + case CEPH_OSD_OP_ZERO: return "zero"; + case CEPH_OSD_OP_WRITEFULL: return "writefull"; + + case CEPH_OSD_OP_APPEND: return "append"; + case CEPH_OSD_OP_STARTSYNC: return "startsync"; + case CEPH_OSD_OP_SETTRUNC: return "settrunc"; + case CEPH_OSD_OP_TRIMTRUNC: return "trimtrunc"; + + case CEPH_OSD_OP_TMAPUP: return "tmapup"; + case CEPH_OSD_OP_TMAPGET: return "tmapget"; + case CEPH_OSD_OP_TMAPPUT: return "tmapput"; + + case CEPH_OSD_OP_GETXATTR: return "getxattr"; + case CEPH_OSD_OP_GETXATTRS: return "getxattrs"; + case CEPH_OSD_OP_SETXATTR: return "setxattr"; + case CEPH_OSD_OP_SETXATTRS: return "setxattrs"; + case CEPH_OSD_OP_RESETXATTRS: return "resetxattrs"; + case CEPH_OSD_OP_RMXATTR: return "rmxattr"; + + case CEPH_OSD_OP_PULL: return "pull"; + case CEPH_OSD_OP_PUSH: return "push"; + case CEPH_OSD_OP_BALANCEREADS: return "balance-reads"; + case CEPH_OSD_OP_UNBALANCEREADS: return "unbalance-reads"; + case CEPH_OSD_OP_SCRUB: return "scrub"; + + case CEPH_OSD_OP_WRLOCK: return "wrlock"; + case CEPH_OSD_OP_WRUNLOCK: return "wrunlock"; + case CEPH_OSD_OP_RDLOCK: return "rdlock"; + case CEPH_OSD_OP_RDUNLOCK: return "rdunlock"; + case CEPH_OSD_OP_UPLOCK: return "uplock"; + case CEPH_OSD_OP_DNLOCK: return "dnlock"; + + case CEPH_OSD_OP_CALL: return "call"; + + case CEPH_OSD_OP_PGLS: return "pgls"; + } + return "???"; +} + +const char *ceph_mds_state_name(int s) +{ + switch (s) { + /* down and out */ + case CEPH_MDS_STATE_DNE: return "down:dne"; + case CEPH_MDS_STATE_STOPPED: return "down:stopped"; + /* up and out */ + case CEPH_MDS_STATE_BOOT: return "up:boot"; + case CEPH_MDS_STATE_STANDBY: return "up:standby"; + case CEPH_MDS_STATE_STANDBY_REPLAY: return "up:standby-replay"; + case CEPH_MDS_STATE_CREATING: return "up:creating"; + case CEPH_MDS_STATE_STARTING: return "up:starting"; + /* up and in */ + case CEPH_MDS_STATE_REPLAY: return "up:replay"; + case CEPH_MDS_STATE_RESOLVE: return "up:resolve"; + case CEPH_MDS_STATE_RECONNECT: return "up:reconnect"; + case CEPH_MDS_STATE_REJOIN: return "up:rejoin"; + case CEPH_MDS_STATE_CLIENTREPLAY: return "up:clientreplay"; + case CEPH_MDS_STATE_ACTIVE: return "up:active"; + case CEPH_MDS_STATE_STOPPING: return "up:stopping"; + } + return "???"; +} + +const char *ceph_session_op_name(int op) +{ + switch (op) { + case CEPH_SESSION_REQUEST_OPEN: return "request_open"; + case CEPH_SESSION_OPEN: return "open"; + case CEPH_SESSION_REQUEST_CLOSE: return "request_close"; + case CEPH_SESSION_CLOSE: return "close"; + case CEPH_SESSION_REQUEST_RENEWCAPS: return "request_renewcaps"; + case CEPH_SESSION_RENEWCAPS: return "renewcaps"; + case CEPH_SESSION_STALE: return "stale"; + case CEPH_SESSION_RECALL_STATE: return "recall_state"; + } + return "???"; +} + +const char *ceph_mds_op_name(int op) +{ + switch (op) { + case CEPH_MDS_OP_LOOKUP: return "lookup"; + case CEPH_MDS_OP_LOOKUPHASH: return "lookuphash"; + case CEPH_MDS_OP_LOOKUPPARENT: return "lookupparent"; + case CEPH_MDS_OP_GETATTR: return "getattr"; + case CEPH_MDS_OP_SETXATTR: return "setxattr"; + case CEPH_MDS_OP_SETATTR: return "setattr"; + case CEPH_MDS_OP_RMXATTR: return "rmxattr"; + case CEPH_MDS_OP_READDIR: return "readdir"; + case CEPH_MDS_OP_MKNOD: return "mknod"; + case CEPH_MDS_OP_LINK: return "link"; + case CEPH_MDS_OP_UNLINK: return "unlink"; + case CEPH_MDS_OP_RENAME: return "rename"; + case CEPH_MDS_OP_MKDIR: return "mkdir"; + case CEPH_MDS_OP_RMDIR: return "rmdir"; + case CEPH_MDS_OP_SYMLINK: return "symlink"; + case CEPH_MDS_OP_CREATE: return "create"; + case CEPH_MDS_OP_OPEN: return "open"; + case CEPH_MDS_OP_LOOKUPSNAP: return "lookupsnap"; + case CEPH_MDS_OP_LSSNAP: return "lssnap"; + case CEPH_MDS_OP_MKSNAP: return "mksnap"; + case CEPH_MDS_OP_RMSNAP: return "rmsnap"; + } + return "???"; +} + +const char *ceph_cap_op_name(int op) +{ + switch (op) { + case CEPH_CAP_OP_GRANT: return "grant"; + case CEPH_CAP_OP_REVOKE: return "revoke"; + case CEPH_CAP_OP_TRUNC: return "trunc"; + case CEPH_CAP_OP_EXPORT: return "export"; + case CEPH_CAP_OP_IMPORT: return "import"; + case CEPH_CAP_OP_UPDATE: return "update"; + case CEPH_CAP_OP_DROP: return "drop"; + case CEPH_CAP_OP_FLUSH: return "flush"; + case CEPH_CAP_OP_FLUSH_ACK: return "flush_ack"; + case CEPH_CAP_OP_FLUSHSNAP: return "flushsnap"; + case CEPH_CAP_OP_FLUSHSNAP_ACK: return "flushsnap_ack"; + case CEPH_CAP_OP_RELEASE: return "release"; + case CEPH_CAP_OP_RENEW: return "renew"; + } + return "???"; +} + +const char *ceph_lease_op_name(int o) +{ + switch (o) { + case CEPH_MDS_LEASE_REVOKE: return "revoke"; + case CEPH_MDS_LEASE_RELEASE: return "release"; + case CEPH_MDS_LEASE_RENEW: return "renew"; + case CEPH_MDS_LEASE_REVOKE_ACK: return "revoke_ack"; + } + return "???"; +} + +const char *ceph_snap_op_name(int o) +{ + switch (o) { + case CEPH_SNAP_OP_UPDATE: return "update"; + case CEPH_SNAP_OP_CREATE: return "create"; + case CEPH_SNAP_OP_DESTROY: return "destroy"; + case CEPH_SNAP_OP_SPLIT: return "split"; + } + return "???"; +} diff --git a/fs/ceph/msgr.h b/fs/ceph/msgr.h new file mode 100644 index 0000000..73921ae --- /dev/null +++ b/fs/ceph/msgr.h @@ -0,0 +1,157 @@ +#ifndef __MSGR_H +#define __MSGR_H + +/* + * Data types for message passing layer used by Ceph. + */ + +#define CEPH_MON_PORT 6789 /* default monitor port */ + +/* + * client-side processes will try to bind to ports in this + * range, simply for the benefit of tools like nmap or wireshark + * that would like to identify the protocol. + */ +#define CEPH_PORT_FIRST 6789 +#define CEPH_PORT_START 6800 /* non-monitors start here */ +#define CEPH_PORT_LAST 6900 + +/* + * tcp connection banner. include a protocol version. and adjust + * whenever the wire protocol changes. try to keep this string length + * constant. + */ +#define CEPH_BANNER "ceph v021" +#define CEPH_BANNER_MAX_LEN 30 + + +/* + * Rollover-safe type and comparator for 32-bit sequence numbers. + * Comparator returns -1, 0, or 1. + */ +typedef __u32 ceph_seq_t; + +static inline __s32 ceph_seq_cmp(__u32 a, __u32 b) +{ + return (__s32)a - (__s32)b; +} + + +/* + * entity_name -- logical name for a process participating in the + * network, e.g. 'mds0' or 'osd3'. + */ +struct ceph_entity_name { + __u8 type; /* CEPH_ENTITY_TYPE_* */ + __le64 num; +} __attribute__ ((packed)); + +#define CEPH_ENTITY_TYPE_MON 1 +#define CEPH_ENTITY_TYPE_MDS 2 +#define CEPH_ENTITY_TYPE_OSD 3 +#define CEPH_ENTITY_TYPE_CLIENT 4 +#define CEPH_ENTITY_TYPE_ADMIN 5 + +/* + * entity_addr -- network address + */ +struct ceph_entity_addr { + __le32 erank; /* entity's rank in process */ + __le32 nonce; /* unique id for process (e.g. pid) */ + struct sockaddr_storage in_addr; +} __attribute__ ((packed)); + +static inline bool ceph_entity_addr_is_local(const struct ceph_entity_addr *a, + const struct ceph_entity_addr *b) +{ + return a->nonce == b->nonce && + memcmp(&a->in_addr, &b->in_addr, sizeof(a->in_addr)) == 0; +} + +static inline bool ceph_entity_addr_equal(const struct ceph_entity_addr *a, + const struct ceph_entity_addr *b) +{ + return memcmp(a, b, sizeof(*a)) == 0; +} + +struct ceph_entity_inst { + struct ceph_entity_name name; + struct ceph_entity_addr addr; +} __attribute__ ((packed)); + + +/* used by message exchange protocol */ +#define CEPH_MSGR_TAG_READY 1 /* server->client: ready for messages */ +#define CEPH_MSGR_TAG_RESETSESSION 2 /* server->client: reset, try again */ +#define CEPH_MSGR_TAG_WAIT 3 /* server->client: wait for racing + incoming connection */ +#define CEPH_MSGR_TAG_RETRY_SESSION 4 /* server->client + cseq: try again + with higher cseq */ +#define CEPH_MSGR_TAG_RETRY_GLOBAL 5 /* server->client + gseq: try again + with higher gseq */ +#define CEPH_MSGR_TAG_CLOSE 6 /* closing pipe */ +#define CEPH_MSGR_TAG_MSG 7 /* message */ +#define CEPH_MSGR_TAG_ACK 8 /* message ack */ +#define CEPH_MSGR_TAG_KEEPALIVE 9 /* just a keepalive byte! */ +#define CEPH_MSGR_TAG_BADPROTOVER 10 /* bad protocol version */ + + +/* + * connection negotiation + */ +struct ceph_msg_connect { + __le32 host_type; /* CEPH_ENTITY_TYPE_* */ + __le32 global_seq; /* count connections initiated by this host */ + __le32 connect_seq; /* count connections initiated in this session */ + __le32 protocol_version; + __u8 flags; /* CEPH_MSG_CONNECT_* */ +} __attribute__ ((packed)); + +struct ceph_msg_connect_reply { + __u8 tag; + __le32 global_seq; + __le32 connect_seq; + __le32 protocol_version; + __u8 flags; +} __attribute__ ((packed)); + +#define CEPH_MSG_CONNECT_LOSSY 1 /* messages i send may be safely dropped */ + + +/* + * message header + */ +struct ceph_msg_header { + __le64 seq; /* message seq# for this session */ + __le16 type; /* message type */ + __le16 priority; /* priority. higher value == higher priority */ + + __le32 front_len; /* bytes in main payload */ + __le32 middle_len;/* bytes in middle payload */ + __le32 data_len; /* bytes of data payload */ + __le16 data_off; /* sender: include full offset; + receiver: mask against ~PAGE_MASK */ + + struct ceph_entity_inst src, orig_src; + __le32 dst_erank; + __le32 crc; /* header crc32c */ +} __attribute__ ((packed)); + +#define CEPH_MSG_PRIO_LOW 64 +#define CEPH_MSG_PRIO_DEFAULT 127 +#define CEPH_MSG_PRIO_HIGH 196 +#define CEPH_MSG_PRIO_HIGHEST 255 + +/* + * follows data payload + */ +struct ceph_msg_footer { + __le32 front_crc, middle_crc, data_crc; + __u8 flags; +} __attribute__ ((packed)); + +#define CEPH_MSG_FOOTER_COMPLETE (1<<0) /* msg wasn't aborted */ +#define CEPH_MSG_FOOTER_NOCRC (1<<1) /* no data crc */ + + +#endif diff --git a/fs/ceph/rados.h b/fs/ceph/rados.h new file mode 100644 index 0000000..a48cf4a --- /dev/null +++ b/fs/ceph/rados.h @@ -0,0 +1,372 @@ +#ifndef __RADOS_H +#define __RADOS_H + +/* + * Data types for the Ceph distributed object storage layer RADOS + * (Reliable Autonomic Distributed Object Store). + */ + +#include "msgr.h" + +/* + * fs id + */ +struct ceph_fsid { + unsigned char fsid[16]; +}; + +static inline int ceph_fsid_compare(const struct ceph_fsid *a, + const struct ceph_fsid *b) +{ + return memcmp(a, b, sizeof(*a)); +} + +/* + * ino, object, etc. + */ +typedef __le64 ceph_snapid_t; +#define CEPH_SNAPDIR ((__u64)(-1)) /* reserved for hidden .snap dir */ +#define CEPH_NOSNAP ((__u64)(-2)) /* "head", "live" revision */ +#define CEPH_MAXSNAP ((__u64)(-3)) /* largest valid snapid */ + +struct ceph_timespec { + __le32 tv_sec; + __le32 tv_nsec; +} __attribute__ ((packed)); + + +/* + * object layout - how objects are mapped into PGs + */ +#define CEPH_OBJECT_LAYOUT_HASH 1 +#define CEPH_OBJECT_LAYOUT_LINEAR 2 +#define CEPH_OBJECT_LAYOUT_HASHINO 3 + +/* + * pg layout -- how PGs are mapped onto (sets of) OSDs + */ +#define CEPH_PG_LAYOUT_CRUSH 0 +#define CEPH_PG_LAYOUT_HASH 1 +#define CEPH_PG_LAYOUT_LINEAR 2 +#define CEPH_PG_LAYOUT_HYBRID 3 + + +/* + * placement group. + * we encode this into one __le64. + */ +union ceph_pg { + __u64 pg64; + struct { + __s16 preferred; /* preferred primary osd */ + __u16 ps; /* placement seed */ + __u32 pool; /* object pool */ + } __attribute__ ((packed)) pg; +} __attribute__ ((packed)); + +/* + * pg_pool is a set of pgs storing a pool of objects + * + * pg_num -- base number of pseudorandomly placed pgs + * + * pgp_num -- effective number when calculating pg placement. this + * is used for pg_num increases. new pgs result in data being "split" + * into new pgs. for this to proceed smoothly, new pgs are intiially + * colocated with their parents; that is, pgp_num doesn't increase + * until the new pgs have successfully split. only _then_ are the new + * pgs placed independently. + * + * lpg_num -- localized pg count (per device). replicas are randomly + * selected. + * + * lpgp_num -- as above. + */ +#define CEPH_PG_TYPE_REP 1 +#define CEPH_PG_TYPE_RAID4 2 +struct ceph_pg_pool { + __u8 type; /* CEPH_PG_TYPE_* */ + __u8 size; /* number of osds in each pg */ + __u8 crush_ruleset; /* crush placement rule */ + __le32 pg_num, pgp_num; /* number of pg's */ + __le32 lpg_num, lpgp_num; /* number of localized pg's */ + __le32 last_change; /* most recent epoch changed */ + __le64 snap_seq; /* seq for per-pool snapshot */ + __le32 snap_epoch; /* epoch of last snap */ + __le32 num_snaps; + __le32 num_removed_snap_intervals; +} __attribute__ ((packed)); + +/* + * stable_mod func is used to control number of placement groups. + * similar to straight-up modulo, but produces a stable mapping as b + * increases over time. b is the number of bins, and bmask is the + * containing power of 2 minus 1. + * + * b <= bmask and bmask=(2**n)-1 + * e.g., b=12 -> bmask=15, b=123 -> bmask=127 + */ +static inline int ceph_stable_mod(int x, int b, int bmask) +{ + if ((x & bmask) < b) + return x & bmask; + else + return x & (bmask >> 1); +} + +/* + * object layout - how a given object should be stored. + */ +struct ceph_object_layout { + __le64 ol_pgid; /* raw pg, with _full_ ps precision. */ + __le32 ol_stripe_unit; /* for per-object parity, if any */ +} __attribute__ ((packed)); + +/* + * compound epoch+version, used by storage layer to serialize mutations + */ +struct ceph_eversion { + __le32 epoch; + __le64 version; +} __attribute__ ((packed)); + +/* + * osd map bits + */ + +/* status bits */ +#define CEPH_OSD_EXISTS 1 +#define CEPH_OSD_UP 2 + +/* osd weights. fixed point value: 0x10000 == 1.0 ("in"), 0 == "out" */ +#define CEPH_OSD_IN 0x10000 +#define CEPH_OSD_OUT 0 + + +/* + * osd map flag bits + */ +#define CEPH_OSDMAP_NEARFULL (1<<0) /* sync writes (near ENOSPC) */ +#define CEPH_OSDMAP_FULL (1<<1) /* no data writes (ENOSPC) */ +#define CEPH_OSDMAP_PAUSERD (1<<2) /* pause all reads */ +#define CEPH_OSDMAP_PAUSEWR (1<<3) /* pause all writes */ +#define CEPH_OSDMAP_PAUSEREC (1<<4) /* pause recovery */ + +/* + * osd ops + */ +#define CEPH_OSD_OP_MODE 0xf000 +#define CEPH_OSD_OP_MODE_RD 0x1000 +#define CEPH_OSD_OP_MODE_WR 0x2000 +#define CEPH_OSD_OP_MODE_RMW 0x3000 +#define CEPH_OSD_OP_MODE_SUB 0x4000 +#define CEPH_OSD_OP_MODE_EXEC 0x8000 + +#define CEPH_OSD_OP_TYPE 0x0f00 +#define CEPH_OSD_OP_TYPE_LOCK 0x0100 +#define CEPH_OSD_OP_TYPE_DATA 0x0200 +#define CEPH_OSD_OP_TYPE_ATTR 0x0300 +#define CEPH_OSD_OP_TYPE_EXEC 0x0400 +#define CEPH_OSD_OP_TYPE_PG 0x0500 + +enum { + /** data **/ + /* read */ + CEPH_OSD_OP_READ = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_DATA | 1, + CEPH_OSD_OP_STAT = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_DATA | 2, + + /* fancy read */ + CEPH_OSD_OP_MASKTRUNC = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_DATA | 4, + + /* write */ + CEPH_OSD_OP_WRITE = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 1, + CEPH_OSD_OP_WRITEFULL = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 2, + CEPH_OSD_OP_TRUNCATE = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 3, + CEPH_OSD_OP_ZERO = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 4, + CEPH_OSD_OP_DELETE = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 5, + + /* fancy write */ + CEPH_OSD_OP_APPEND = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 6, + CEPH_OSD_OP_STARTSYNC = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 7, + CEPH_OSD_OP_SETTRUNC = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 8, + CEPH_OSD_OP_TRIMTRUNC = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 9, + + CEPH_OSD_OP_TMAPUP = CEPH_OSD_OP_MODE_RMW | CEPH_OSD_OP_TYPE_DATA | 10, + CEPH_OSD_OP_TMAPPUT = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 11, + CEPH_OSD_OP_TMAPGET = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_DATA | 12, + + CEPH_OSD_OP_CREATE = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 13, + + /** attrs **/ + /* read */ + CEPH_OSD_OP_GETXATTR = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_ATTR | 1, + CEPH_OSD_OP_GETXATTRS = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_ATTR | 2, + + /* write */ + CEPH_OSD_OP_SETXATTR = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_ATTR | 1, + CEPH_OSD_OP_SETXATTRS = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_ATTR | 2, + CEPH_OSD_OP_RESETXATTRS = CEPH_OSD_OP_MODE_WR|CEPH_OSD_OP_TYPE_ATTR | 3, + CEPH_OSD_OP_RMXATTR = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_ATTR | 4, + + /** subop **/ + CEPH_OSD_OP_PULL = CEPH_OSD_OP_MODE_SUB | 1, + CEPH_OSD_OP_PUSH = CEPH_OSD_OP_MODE_SUB | 2, + CEPH_OSD_OP_BALANCEREADS = CEPH_OSD_OP_MODE_SUB | 3, + CEPH_OSD_OP_UNBALANCEREADS = CEPH_OSD_OP_MODE_SUB | 4, + CEPH_OSD_OP_SCRUB = CEPH_OSD_OP_MODE_SUB | 5, + + /** lock **/ + CEPH_OSD_OP_WRLOCK = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_LOCK | 1, + CEPH_OSD_OP_WRUNLOCK = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_LOCK | 2, + CEPH_OSD_OP_RDLOCK = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_LOCK | 3, + CEPH_OSD_OP_RDUNLOCK = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_LOCK | 4, + CEPH_OSD_OP_UPLOCK = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_LOCK | 5, + CEPH_OSD_OP_DNLOCK = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_LOCK | 6, + + /** exec **/ + CEPH_OSD_OP_CALL = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_EXEC | 1, + + /** pg **/ + CEPH_OSD_OP_PGLS = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_PG | 1, +}; + +static inline int ceph_osd_op_type_lock(int op) +{ + return (op & CEPH_OSD_OP_TYPE) == CEPH_OSD_OP_TYPE_LOCK; +} +static inline int ceph_osd_op_type_data(int op) +{ + return (op & CEPH_OSD_OP_TYPE) == CEPH_OSD_OP_TYPE_DATA; +} +static inline int ceph_osd_op_type_attr(int op) +{ + return (op & CEPH_OSD_OP_TYPE) == CEPH_OSD_OP_TYPE_ATTR; +} +static inline int ceph_osd_op_type_exec(int op) +{ + return (op & CEPH_OSD_OP_TYPE) == CEPH_OSD_OP_TYPE_EXEC; +} +static inline int ceph_osd_op_type_pg(int op) +{ + return (op & CEPH_OSD_OP_TYPE) == CEPH_OSD_OP_TYPE_PG; +} + +static inline int ceph_osd_op_mode_subop(int op) +{ + return (op & CEPH_OSD_OP_MODE) == CEPH_OSD_OP_MODE_SUB; +} +static inline int ceph_osd_op_mode_read(int op) +{ + return (op & CEPH_OSD_OP_MODE) == CEPH_OSD_OP_MODE_RD; +} +static inline int ceph_osd_op_mode_modify(int op) +{ + return (op & CEPH_OSD_OP_MODE) == CEPH_OSD_OP_MODE_WR; +} + +#define CEPH_OSD_TMAP_HDR 'h' +#define CEPH_OSD_TMAP_SET 's' +#define CEPH_OSD_TMAP_RM 'r' + +extern const char *ceph_osd_op_name(int op); + + +/* + * osd op flags + * + * An op may be READ, WRITE, or READ|WRITE. + */ +enum { + CEPH_OSD_FLAG_ACK = 1, /* want (or is) "ack" ack */ + CEPH_OSD_FLAG_ONNVRAM = 2, /* want (or is) "onnvram" ack */ + CEPH_OSD_FLAG_ONDISK = 4, /* want (or is) "ondisk" ack */ + CEPH_OSD_FLAG_RETRY = 8, /* resend attempt */ + CEPH_OSD_FLAG_READ = 16, /* op may read */ + CEPH_OSD_FLAG_WRITE = 32, /* op may write */ + CEPH_OSD_FLAG_ORDERSNAP = 64, /* EOLDSNAP if snapc is out of order */ + CEPH_OSD_FLAG_PEERSTAT = 128, /* msg includes osd_peer_stat */ + CEPH_OSD_FLAG_BALANCE_READS = 256, + CEPH_OSD_FLAG_PARALLELEXEC = 512, /* execute op in parallel */ + CEPH_OSD_FLAG_PGOP = 1024, /* pg op, no object */ +}; + +enum { + CEPH_OSD_OP_FLAG_EXCL = 1, /* EXCL object create */ +}; + +#define EOLDSNAPC ERESTART /* ORDERSNAP flag set; writer has old snapc*/ +#define EBLACKLISTED ESHUTDOWN /* blacklisted */ + +/* + * an individual object operation. each may be accompanied by some data + * payload + */ +struct ceph_osd_op { + __le16 op; /* CEPH_OSD_OP_* */ + __le32 flags; /* CEPH_OSD_FLAG_* */ + union { + struct { + __le64 offset, length; + } __attribute__ ((packed)) extent; + struct { + __le32 name_len; + __le32 value_len; + } __attribute__ ((packed)) xattr; + struct { + __le64 truncate_size; + __le32 truncate_seq; + } __attribute__ ((packed)) trunc; + struct { + __u8 class_len; + __u8 method_len; + __u8 argc; + __le32 indata_len; + } __attribute__ ((packed)) cls; + struct { + __le64 cookie, count; + } __attribute__ ((packed)) pgls; + }; + __le32 payload_len; +} __attribute__ ((packed)); + +/* + * osd request message header. each request may include multiple + * ceph_osd_op object operations. + */ +struct ceph_osd_request_head { + __le64 tid; /* transaction id */ + __le32 client_inc; /* client incarnation */ + struct ceph_object_layout layout; /* pgid */ + __le32 osdmap_epoch; /* client's osdmap epoch */ + + __le32 flags; + + struct ceph_timespec mtime; /* for mutations only */ + struct ceph_eversion reassert_version; /* if we are replaying op */ + + __le32 object_len; /* length of object name */ + + __le64 snapid; /* snapid to read */ + __le64 snap_seq; /* writer's snap context */ + __le32 num_snaps; + + __le16 num_ops; + struct ceph_osd_op ops[]; /* followed by ops[], obj, ticket, snaps */ +} __attribute__ ((packed)); + +struct ceph_osd_reply_head { + __le64 tid; /* transaction id */ + __le32 client_inc; /* client incarnation */ + __le32 flags; + struct ceph_object_layout layout; + __le32 osdmap_epoch; + struct ceph_eversion reassert_version; /* for replaying uncommitted */ + + __le32 result; /* result code */ + + __le32 object_len; /* length of object name */ + __le32 num_ops; + struct ceph_osd_op ops[0]; /* ops[], object */ +} __attribute__ ((packed)); + + +#endif -- cgit v0.10.2 From de57606c23afded22202825b3db8a5d61859f198 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 6 Oct 2009 11:31:07 -0700 Subject: ceph: client types We first define constants, types, and prototypes for the kernel client proper. A few subsystems are defined separately later: the MDS, OSD, and monitor clients, and the messaging layer. Signed-off-by: Sage Weil diff --git a/fs/ceph/ceph_debug.h b/fs/ceph/ceph_debug.h new file mode 100644 index 0000000..1818c23 --- /dev/null +++ b/fs/ceph/ceph_debug.h @@ -0,0 +1,37 @@ +#ifndef _FS_CEPH_DEBUG_H +#define _FS_CEPH_DEBUG_H + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#ifdef CONFIG_CEPH_FS_PRETTYDEBUG + +/* + * wrap pr_debug to include a filename:lineno prefix on each line. + * this incurs some overhead (kernel size and execution time) due to + * the extra function call at each call site. + */ + +# if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG) +extern const char *ceph_file_part(const char *s, int len); +# define dout(fmt, ...) \ + pr_debug(" %12.12s:%-4d : " fmt, \ + ceph_file_part(__FILE__, sizeof(__FILE__)), \ + __LINE__, ##__VA_ARGS__) +# else +/* faux printk call just to see any compiler warnings. */ +# define dout(fmt, ...) do { \ + if (0) \ + printk(KERN_DEBUG fmt, ##__VA_ARGS__); \ + } while (0) +# endif + +#else + +/* + * or, just wrap pr_debug + */ +# define dout(fmt, ...) pr_debug(" " fmt, ##__VA_ARGS__) + +#endif + +#endif diff --git a/fs/ceph/ceph_frag.c b/fs/ceph/ceph_frag.c new file mode 100644 index 0000000..ab6cf35 --- /dev/null +++ b/fs/ceph/ceph_frag.c @@ -0,0 +1,21 @@ +/* + * Ceph 'frag' type + */ +#include "types.h" + +int ceph_frag_compare(__u32 a, __u32 b) +{ + unsigned va = ceph_frag_value(a); + unsigned vb = ceph_frag_value(b); + if (va < vb) + return -1; + if (va > vb) + return 1; + va = ceph_frag_bits(a); + vb = ceph_frag_bits(b); + if (va < vb) + return -1; + if (va > vb) + return 1; + return 0; +} diff --git a/fs/ceph/ceph_frag.h b/fs/ceph/ceph_frag.h new file mode 100644 index 0000000..793f50c --- /dev/null +++ b/fs/ceph/ceph_frag.h @@ -0,0 +1,109 @@ +#ifndef _FS_CEPH_FRAG_H +#define _FS_CEPH_FRAG_H + +/* + * "Frags" are a way to describe a subset of a 32-bit number space, + * using a mask and a value to match against that mask. Any given frag + * (subset of the number space) can be partitioned into 2^n sub-frags. + * + * Frags are encoded into a 32-bit word: + * 8 upper bits = "bits" + * 24 lower bits = "value" + * (We could go to 5+27 bits, but who cares.) + * + * We use the _most_ significant bits of the 24 bit value. This makes + * values logically sort. + * + * Unfortunately, because the "bits" field is still in the high bits, we + * can't sort encoded frags numerically. However, it does allow you + * to feed encoded frags as values into frag_contains_value. + */ +static inline __u32 ceph_frag_make(__u32 b, __u32 v) +{ + return (b << 24) | + (v & (0xffffffu << (24-b)) & 0xffffffu); +} +static inline __u32 ceph_frag_bits(__u32 f) +{ + return f >> 24; +} +static inline __u32 ceph_frag_value(__u32 f) +{ + return f & 0xffffffu; +} +static inline __u32 ceph_frag_mask(__u32 f) +{ + return (0xffffffu << (24-ceph_frag_bits(f))) & 0xffffffu; +} +static inline __u32 ceph_frag_mask_shift(__u32 f) +{ + return 24 - ceph_frag_bits(f); +} + +static inline int ceph_frag_contains_value(__u32 f, __u32 v) +{ + return (v & ceph_frag_mask(f)) == ceph_frag_value(f); +} +static inline int ceph_frag_contains_frag(__u32 f, __u32 sub) +{ + /* is sub as specific as us, and contained by us? */ + return ceph_frag_bits(sub) >= ceph_frag_bits(f) && + (ceph_frag_value(sub) & ceph_frag_mask(f)) == ceph_frag_value(f); +} + +static inline __u32 ceph_frag_parent(__u32 f) +{ + return ceph_frag_make(ceph_frag_bits(f) - 1, + ceph_frag_value(f) & (ceph_frag_mask(f) << 1)); +} +static inline int ceph_frag_is_left_child(__u32 f) +{ + return ceph_frag_bits(f) > 0 && + (ceph_frag_value(f) & (0x1000000 >> ceph_frag_bits(f))) == 0; +} +static inline int ceph_frag_is_right_child(__u32 f) +{ + return ceph_frag_bits(f) > 0 && + (ceph_frag_value(f) & (0x1000000 >> ceph_frag_bits(f))) == 1; +} +static inline __u32 ceph_frag_sibling(__u32 f) +{ + return ceph_frag_make(ceph_frag_bits(f), + ceph_frag_value(f) ^ (0x1000000 >> ceph_frag_bits(f))); +} +static inline __u32 ceph_frag_left_child(__u32 f) +{ + return ceph_frag_make(ceph_frag_bits(f)+1, ceph_frag_value(f)); +} +static inline __u32 ceph_frag_right_child(__u32 f) +{ + return ceph_frag_make(ceph_frag_bits(f)+1, + ceph_frag_value(f) | (0x1000000 >> (1+ceph_frag_bits(f)))); +} +static inline __u32 ceph_frag_make_child(__u32 f, int by, int i) +{ + int newbits = ceph_frag_bits(f) + by; + return ceph_frag_make(newbits, + ceph_frag_value(f) | (i << (24 - newbits))); +} +static inline int ceph_frag_is_leftmost(__u32 f) +{ + return ceph_frag_value(f) == 0; +} +static inline int ceph_frag_is_rightmost(__u32 f) +{ + return ceph_frag_value(f) == ceph_frag_mask(f); +} +static inline __u32 ceph_frag_next(__u32 f) +{ + return ceph_frag_make(ceph_frag_bits(f), + ceph_frag_value(f) + (0x1000000 >> ceph_frag_bits(f))); +} + +/* + * comparator to sort frags logically, as when traversing the + * number space in ascending order... + */ +int ceph_frag_compare(__u32 a, __u32 b); + +#endif diff --git a/fs/ceph/ceph_ver.h b/fs/ceph/ceph_ver.h new file mode 100644 index 0000000..66c3727 --- /dev/null +++ b/fs/ceph/ceph_ver.h @@ -0,0 +1,6 @@ +#ifndef __CEPH_VERSION_H +#define __CEPH_VERSION_H + +#define CEPH_GIT_VER 335cd8f952b457095ea2a66aee3db50efb63c91d + +#endif diff --git a/fs/ceph/super.h b/fs/ceph/super.h new file mode 100644 index 0000000..cfd39ef --- /dev/null +++ b/fs/ceph/super.h @@ -0,0 +1,890 @@ +#ifndef _FS_CEPH_SUPER_H +#define _FS_CEPH_SUPER_H + +#include "ceph_debug.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "types.h" +#include "messenger.h" +#include "msgpool.h" +#include "mon_client.h" +#include "mds_client.h" +#include "osd_client.h" +#include "ceph_fs.h" + +/* f_type in struct statfs */ +#define CEPH_SUPER_MAGIC 0x00c36400 + +/* large granularity for statfs utilization stats to facilitate + * large volume sizes on 32-bit machines. */ +#define CEPH_BLOCK_SHIFT 20 /* 1 MB */ +#define CEPH_BLOCK (1 << CEPH_BLOCK_SHIFT) + +/* + * mount options + */ +#define CEPH_OPT_FSID (1<<0) +#define CEPH_OPT_NOSHARE (1<<1) /* don't share client with other sbs */ +#define CEPH_OPT_MYIP (1<<2) /* specified my ip */ +#define CEPH_OPT_DIRSTAT (1<<4) /* funky `cat dirname` for stats */ +#define CEPH_OPT_RBYTES (1<<5) /* dir st_bytes = rbytes */ +#define CEPH_OPT_NOCRC (1<<6) /* no data crc on writes */ +#define CEPH_OPT_NOASYNCREADDIR (1<<7) /* no dcache readdir */ + +#define CEPH_OPT_DEFAULT (CEPH_OPT_RBYTES) + +#define ceph_set_opt(client, opt) \ + (client)->mount_args.flags |= CEPH_OPT_##opt; +#define ceph_test_opt(client, opt) \ + (!!((client)->mount_args.flags & CEPH_OPT_##opt)) + + +#define CEPH_MAX_MON_MOUNT_ADDR 5 + +struct ceph_mount_args { + int sb_flags; + int flags; + int mount_timeout; + int caps_wanted_delay_min, caps_wanted_delay_max; + struct ceph_fsid fsid; + struct ceph_entity_addr my_addr; + int wsize; + int rsize; /* max readahead */ + int max_readdir; /* max readdir size */ + int osd_timeout; + char *snapdir_name; /* default ".snap" */ + char *secret; + int cap_release_safety; +}; + +/* + * defaults + */ +#define CEPH_MOUNT_TIMEOUT_DEFAULT 60 +#define CEPH_MOUNT_RSIZE_DEFAULT (128*1024) /* readahead */ + +#define CEPH_MSG_MAX_FRONT_LEN (16*1024*1024) +#define CEPH_MSG_MAX_DATA_LEN (16*1024*1024) + +#define CEPH_SNAPDIRNAME_DEFAULT ".snap" + +/* + * Delay telling the MDS we no longer want caps, in case we reopen + * the file. Delay a minimum amount of time, even if we send a cap + * message for some other reason. Otherwise, take the oppotunity to + * update the mds to avoid sending another message later. + */ +#define CEPH_CAPS_WANTED_DELAY_MIN_DEFAULT 5 /* cap release delay */ +#define CEPH_CAPS_WANTED_DELAY_MAX_DEFAULT 60 /* cap release delay */ + + +/* mount state */ +enum { + CEPH_MOUNT_MOUNTING, + CEPH_MOUNT_MOUNTED, + CEPH_MOUNT_UNMOUNTING, + CEPH_MOUNT_UNMOUNTED, + CEPH_MOUNT_SHUTDOWN, +}; + +/* + * subtract jiffies + */ +static inline unsigned long time_sub(unsigned long a, unsigned long b) +{ + BUG_ON(time_after(b, a)); + return (long)a - (long)b; +} + +/* + * per-filesystem client state + * + * possibly shared by multiple mount points, if they are + * mounting the same ceph filesystem/cluster. + */ +struct ceph_client { + __s64 whoami; /* my client number */ + struct dentry *debugfs_monmap; + struct dentry *debugfs_mdsmap, *debugfs_osdmap; + struct dentry *debugfs_dir, *debugfs_dentry_lru, *debugfs_caps; + + struct mutex mount_mutex; /* serialize mount attempts */ + struct ceph_mount_args mount_args; + struct ceph_fsid fsid; + + struct super_block *sb; + + unsigned long mount_state; + wait_queue_head_t mount_wq; + + int mount_err; + void *signed_ticket; /* our keys to the kingdom */ + int signed_ticket_len; + + struct ceph_messenger *msgr; /* messenger instance */ + struct ceph_mon_client monc; + struct ceph_mds_client mdsc; + struct ceph_osd_client osdc; + + /* writeback */ + mempool_t *wb_pagevec_pool; + struct workqueue_struct *wb_wq; + struct workqueue_struct *pg_inv_wq; + struct workqueue_struct *trunc_wq; + + struct backing_dev_info backing_dev_info; +}; + +static inline struct ceph_client *ceph_client(struct super_block *sb) +{ + return sb->s_fs_info; +} + + +/* + * File i/o capability. This tracks shared state with the metadata + * server that allows us to cache or writeback attributes or to read + * and write data. For any given inode, we should have one or more + * capabilities, one issued by each metadata server, and our + * cumulative access is the OR of all issued capabilities. + * + * Each cap is referenced by the inode's i_caps rbtree and by per-mds + * session capability lists. + */ +struct ceph_cap { + struct ceph_inode_info *ci; + struct rb_node ci_node; /* per-ci cap tree */ + struct ceph_mds_session *session; + struct list_head session_caps; /* per-session caplist */ + int mds; + u64 cap_id; /* unique cap id (mds provided) */ + int issued; /* latest, from the mds */ + int implemented; /* implemented superset of issued (for revocation) */ + int mds_wanted; + u32 seq, issue_seq, mseq, gen; + unsigned long last_used; + struct list_head caps_item; +}; + +#define CHECK_CAPS_NODELAY 1 /* do not delay any further */ +#define CHECK_CAPS_AUTHONLY 2 /* only check auth cap */ +#define CHECK_CAPS_FLUSH 4 /* flush any dirty caps */ + +/* + * Snapped cap state that is pending flush to mds. When a snapshot occurs, + * we first complete any in-process sync writes and writeback any dirty + * data before flushing the snapped state (tracked here) back to the MDS. + */ +struct ceph_cap_snap { + atomic_t nref; + struct ceph_inode_info *ci; + struct list_head ci_item, flushing_item; + + u64 follows, flush_tid; + int issued, dirty; + struct ceph_snap_context *context; + + mode_t mode; + uid_t uid; + gid_t gid; + + void *xattr_blob; + int xattr_len; + u64 xattr_version; + + u64 size; + struct timespec mtime, atime, ctime; + u64 time_warp_seq; + int writing; /* a sync write is still in progress */ + int dirty_pages; /* dirty pages awaiting writeback */ +}; + +static inline void ceph_put_cap_snap(struct ceph_cap_snap *capsnap) +{ + if (atomic_dec_and_test(&capsnap->nref)) + kfree(capsnap); +} + +/* + * The frag tree describes how a directory is fragmented, potentially across + * multiple metadata servers. It is also used to indicate points where + * metadata authority is delegated, and whether/where metadata is replicated. + * + * A _leaf_ frag will be present in the i_fragtree IFF there is + * delegation info. That is, if mds >= 0 || ndist > 0. + */ +#define CEPH_MAX_DIRFRAG_REP 4 + +struct ceph_inode_frag { + struct rb_node node; + + /* fragtree state */ + u32 frag; + int split_by; /* i.e. 2^(split_by) children */ + + /* delegation and replication info */ + int mds; /* -1 if same authority as parent */ + int ndist; /* >0 if replicated */ + int dist[CEPH_MAX_DIRFRAG_REP]; +}; + +/* + * We cache inode xattrs as an encoded blob until they are first used, + * at which point we parse them into an rbtree. + */ +struct ceph_inode_xattr { + struct rb_node node; + + const char *name; + int name_len; + const char *val; + int val_len; + int dirty; + + int should_free_name; + int should_free_val; +}; + +struct ceph_inode_xattrs_info { + /* + * (still encoded) xattr blob. we avoid the overhead of parsing + * this until someone actually calls getxattr, etc. + * + * blob->vec.iov_len == 4 implies there are no xattrs; blob == + * NULL means we don't know. + */ + struct ceph_buffer *blob, *prealloc_blob; + + struct rb_root index; + bool dirty; + int count; + int names_size; + int vals_size; + u64 version, index_version; +}; + +/* + * Ceph inode. + */ +#define CEPH_I_COMPLETE 1 /* we have complete directory cached */ +#define CEPH_I_NODELAY 4 /* do not delay cap release */ +#define CEPH_I_FLUSH 8 /* do not delay flush of dirty metadata */ + +struct ceph_inode_info { + struct ceph_vino i_vino; /* ceph ino + snap */ + + u64 i_version; + u32 i_time_warp_seq; + + unsigned i_ceph_flags; + unsigned long i_release_count; + + struct ceph_file_layout i_layout; + char *i_symlink; + + /* for dirs */ + struct timespec i_rctime; + u64 i_rbytes, i_rfiles, i_rsubdirs; + u64 i_files, i_subdirs; + u64 i_max_offset; /* largest readdir offset, set with I_COMPLETE */ + + struct rb_root i_fragtree; + struct mutex i_fragtree_mutex; + + struct ceph_inode_xattrs_info i_xattrs; + + /* capabilities. protected _both_ by i_lock and cap->session's + * s_mutex. */ + struct rb_root i_caps; /* cap list */ + struct ceph_cap *i_auth_cap; /* authoritative cap, if any */ + unsigned i_dirty_caps, i_flushing_caps; /* mask of dirtied fields */ + struct list_head i_dirty_item, i_flushing_item; + u64 i_cap_flush_seq; + /* we need to track cap writeback on a per-cap-bit basis, to allow + * overlapping, pipelined cap flushes to the mds. we can probably + * reduce the tid to 8 bits if we're concerned about inode size. */ + u16 i_cap_flush_last_tid, i_cap_flush_tid[CEPH_CAP_BITS]; + wait_queue_head_t i_cap_wq; /* threads waiting on a capability */ + unsigned long i_hold_caps_min; /* jiffies */ + unsigned long i_hold_caps_max; /* jiffies */ + struct list_head i_cap_delay_list; /* for delayed cap release to mds */ + int i_cap_exporting_mds; /* to handle cap migration between */ + unsigned i_cap_exporting_mseq; /* mds's. */ + unsigned i_cap_exporting_issued; + struct ceph_cap_reservation i_cap_migration_resv; + struct list_head i_cap_snaps; /* snapped state pending flush to mds */ + struct ceph_snap_context *i_head_snapc; /* set if wr_buffer_head > 0 */ + unsigned i_snap_caps; /* cap bits for snapped files */ + + int i_nr_by_mode[CEPH_FILE_MODE_NUM]; /* open file counts */ + + u32 i_truncate_seq; /* last truncate to smaller size */ + u64 i_truncate_size; /* and the size we last truncated down to */ + int i_truncate_pending; /* still need to call vmtruncate */ + + u64 i_max_size; /* max file size authorized by mds */ + u64 i_reported_size; /* (max_)size reported to or requested of mds */ + u64 i_wanted_max_size; /* offset we'd like to write too */ + u64 i_requested_max_size; /* max_size we've requested */ + + /* held references to caps */ + int i_pin_ref; + int i_rd_ref, i_rdcache_ref, i_wr_ref; + int i_wrbuffer_ref, i_wrbuffer_ref_head; + u32 i_shared_gen; /* increment each time we get FILE_SHARED */ + u32 i_rdcache_gen; /* we increment this each time we get + FILE_CACHE. If it's non-zero, we + _may_ have cached pages. */ + u32 i_rdcache_revoking; /* RDCACHE gen to async invalidate, if any */ + + struct list_head i_unsafe_writes; /* uncommitted sync writes */ + struct list_head i_unsafe_dirops; /* uncommitted mds dir ops */ + spinlock_t i_unsafe_lock; + + struct ceph_snap_realm *i_snap_realm; /* snap realm (if caps) */ + int i_snap_realm_counter; /* snap realm (if caps) */ + struct list_head i_snap_realm_item; + struct list_head i_snap_flush_item; + + struct work_struct i_wb_work; /* writeback work */ + struct work_struct i_pg_inv_work; /* page invalidation work */ + + struct work_struct i_vmtruncate_work; + + struct inode vfs_inode; /* at end */ +}; + +static inline struct ceph_inode_info *ceph_inode(struct inode *inode) +{ + return list_entry(inode, struct ceph_inode_info, vfs_inode); +} + +static inline void ceph_i_clear(struct inode *inode, unsigned mask) +{ + struct ceph_inode_info *ci = ceph_inode(inode); + + spin_lock(&inode->i_lock); + ci->i_ceph_flags &= ~mask; + spin_unlock(&inode->i_lock); +} + +static inline void ceph_i_set(struct inode *inode, unsigned mask) +{ + struct ceph_inode_info *ci = ceph_inode(inode); + + spin_lock(&inode->i_lock); + ci->i_ceph_flags |= mask; + spin_unlock(&inode->i_lock); +} + +static inline bool ceph_i_test(struct inode *inode, unsigned mask) +{ + struct ceph_inode_info *ci = ceph_inode(inode); + bool r; + + smp_mb(); + r = (ci->i_ceph_flags & mask) == mask; + return r; +} + + +/* find a specific frag @f */ +extern struct ceph_inode_frag *__ceph_find_frag(struct ceph_inode_info *ci, + u32 f); + +/* + * choose fragment for value @v. copy frag content to pfrag, if leaf + * exists + */ +extern u32 ceph_choose_frag(struct ceph_inode_info *ci, u32 v, + struct ceph_inode_frag *pfrag, + int *found); + +/* + * Ceph dentry state + */ +struct ceph_dentry_info { + struct ceph_mds_session *lease_session; + u32 lease_gen, lease_shared_gen; + u32 lease_seq; + unsigned long lease_renew_after, lease_renew_from; + struct list_head lru; + struct dentry *dentry; + u64 time; + u64 offset; +}; + +static inline struct ceph_dentry_info *ceph_dentry(struct dentry *dentry) +{ + return (struct ceph_dentry_info *)dentry->d_fsdata; +} + +static inline loff_t ceph_make_fpos(unsigned frag, unsigned off) +{ + return ((loff_t)frag << 32) | (loff_t)off; +} + +/* + * ino_t is <64 bits on many architectures, blech. + * + * don't include snap in ino hash, at least for now. + */ +static inline ino_t ceph_vino_to_ino(struct ceph_vino vino) +{ + ino_t ino = (ino_t)vino.ino; /* ^ (vino.snap << 20); */ +#if BITS_PER_LONG == 32 + ino ^= vino.ino >> (sizeof(u64)-sizeof(ino_t)) * 8; + if (!ino) + ino = 1; +#endif + return ino; +} + +static inline int ceph_set_ino_cb(struct inode *inode, void *data) +{ + ceph_inode(inode)->i_vino = *(struct ceph_vino *)data; + inode->i_ino = ceph_vino_to_ino(*(struct ceph_vino *)data); + return 0; +} + +static inline struct ceph_vino ceph_vino(struct inode *inode) +{ + return ceph_inode(inode)->i_vino; +} + +/* for printf-style formatting */ +#define ceph_vinop(i) ceph_inode(i)->i_vino.ino, ceph_inode(i)->i_vino.snap + +static inline u64 ceph_ino(struct inode *inode) +{ + return ceph_inode(inode)->i_vino.ino; +} +static inline u64 ceph_snap(struct inode *inode) +{ + return ceph_inode(inode)->i_vino.snap; +} + +static inline int ceph_ino_compare(struct inode *inode, void *data) +{ + struct ceph_vino *pvino = (struct ceph_vino *)data; + struct ceph_inode_info *ci = ceph_inode(inode); + return ci->i_vino.ino == pvino->ino && + ci->i_vino.snap == pvino->snap; +} + +static inline struct inode *ceph_find_inode(struct super_block *sb, + struct ceph_vino vino) +{ + ino_t t = ceph_vino_to_ino(vino); + return ilookup5(sb, t, ceph_ino_compare, &vino); +} + + +/* + * caps helpers + */ +static inline bool __ceph_is_any_real_caps(struct ceph_inode_info *ci) +{ + return !RB_EMPTY_ROOT(&ci->i_caps); +} + +extern int __ceph_caps_issued(struct ceph_inode_info *ci, int *implemented); +extern int __ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask, int t); +extern int __ceph_caps_issued_other(struct ceph_inode_info *ci, + struct ceph_cap *cap); + +static inline int ceph_caps_issued(struct ceph_inode_info *ci) +{ + int issued; + spin_lock(&ci->vfs_inode.i_lock); + issued = __ceph_caps_issued(ci, NULL); + spin_unlock(&ci->vfs_inode.i_lock); + return issued; +} + +static inline int ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask, + int touch) +{ + int r; + spin_lock(&ci->vfs_inode.i_lock); + r = __ceph_caps_issued_mask(ci, mask, touch); + spin_unlock(&ci->vfs_inode.i_lock); + return r; +} + +static inline int __ceph_caps_dirty(struct ceph_inode_info *ci) +{ + return ci->i_dirty_caps | ci->i_flushing_caps; +} +extern int __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask); + +extern int ceph_caps_revoking(struct ceph_inode_info *ci, int mask); +extern int __ceph_caps_used(struct ceph_inode_info *ci); + +extern int __ceph_caps_file_wanted(struct ceph_inode_info *ci); + +/* + * wanted, by virtue of open file modes AND cap refs (buffered/cached data) + */ +static inline int __ceph_caps_wanted(struct ceph_inode_info *ci) +{ + int w = __ceph_caps_file_wanted(ci) | __ceph_caps_used(ci); + if (w & CEPH_CAP_FILE_BUFFER) + w |= CEPH_CAP_FILE_EXCL; /* we want EXCL if dirty data */ + return w; +} + +/* what the mds thinks we want */ +extern int __ceph_caps_mds_wanted(struct ceph_inode_info *ci); + +extern void ceph_caps_init(void); +extern void ceph_caps_finalize(void); +extern int ceph_reserve_caps(struct ceph_cap_reservation *ctx, int need); +extern int ceph_unreserve_caps(struct ceph_cap_reservation *ctx); +extern void ceph_reservation_status(struct ceph_client *client, + int *total, int *avail, int *used, + int *reserved); + +static inline struct ceph_client *ceph_inode_to_client(struct inode *inode) +{ + return (struct ceph_client *)inode->i_sb->s_fs_info; +} + +static inline struct ceph_client *ceph_sb_to_client(struct super_block *sb) +{ + return (struct ceph_client *)sb->s_fs_info; +} + +static inline int ceph_queue_writeback(struct inode *inode) +{ + return queue_work(ceph_inode_to_client(inode)->wb_wq, + &ceph_inode(inode)->i_wb_work); +} + +static inline int ceph_queue_page_invalidation(struct inode *inode) +{ + return queue_work(ceph_inode_to_client(inode)->pg_inv_wq, + &ceph_inode(inode)->i_pg_inv_work); +} + + +/* + * we keep buffered readdir results attached to file->private_data + */ +struct ceph_file_info { + int fmode; /* initialized on open */ + + /* readdir: position within the dir */ + u32 frag; + struct ceph_mds_request *last_readdir; + int at_end; + + /* readdir: position within a frag */ + unsigned offset; /* offset of last chunk, adjusted for . and .. */ + u64 next_offset; /* offset of next chunk (last_name's + 1) */ + char *last_name; /* last entry in previous chunk */ + struct dentry *dentry; /* next dentry (for dcache readdir) */ + unsigned long dir_release_count; + + /* used for -o dirstat read() on directory thing */ + char *dir_info; + int dir_info_len; +}; + + + +/* + * snapshots + */ + +/* + * A "snap context" is the set of existing snapshots when we + * write data. It is used by the OSD to guide its COW behavior. + * + * The ceph_snap_context is refcounted, and attached to each dirty + * page, indicating which context the dirty data belonged when it was + * dirtied. + */ +struct ceph_snap_context { + atomic_t nref; + u64 seq; + int num_snaps; + u64 snaps[]; +}; + +static inline struct ceph_snap_context * +ceph_get_snap_context(struct ceph_snap_context *sc) +{ + /* + printk("get_snap_context %p %d -> %d\n", sc, atomic_read(&sc->nref), + atomic_read(&sc->nref)+1); + */ + if (sc) + atomic_inc(&sc->nref); + return sc; +} + +static inline void ceph_put_snap_context(struct ceph_snap_context *sc) +{ + if (!sc) + return; + /* + printk("put_snap_context %p %d -> %d\n", sc, atomic_read(&sc->nref), + atomic_read(&sc->nref)-1); + */ + if (atomic_dec_and_test(&sc->nref)) { + /*printk(" deleting snap_context %p\n", sc);*/ + kfree(sc); + } +} + +/* + * A "snap realm" describes a subset of the file hierarchy sharing + * the same set of snapshots that apply to it. The realms themselves + * are organized into a hierarchy, such that children inherit (some of) + * the snapshots of their parents. + * + * All inodes within the realm that have capabilities are linked into a + * per-realm list. + */ +struct ceph_snap_realm { + u64 ino; + atomic_t nref; + u64 created, seq; + u64 parent_ino; + u64 parent_since; /* snapid when our current parent became so */ + + u64 *prior_parent_snaps; /* snaps inherited from any parents we */ + int num_prior_parent_snaps; /* had prior to parent_since */ + u64 *snaps; /* snaps specific to this realm */ + int num_snaps; + + struct ceph_snap_realm *parent; + struct list_head children; /* list of child realms */ + struct list_head child_item; + + struct list_head empty_item; /* if i have ref==0 */ + + /* the current set of snaps for this realm */ + struct ceph_snap_context *cached_context; + + struct list_head inodes_with_caps; + spinlock_t inodes_with_caps_lock; +}; + + + +/* + * calculate the number of pages a given length and offset map onto, + * if we align the data. + */ +static inline int calc_pages_for(u64 off, u64 len) +{ + return ((off+len+PAGE_CACHE_SIZE-1) >> PAGE_CACHE_SHIFT) - + (off >> PAGE_CACHE_SHIFT); +} + + + +/* snap.c */ +struct ceph_snap_realm *ceph_lookup_snap_realm(struct ceph_mds_client *mdsc, + u64 ino); +extern void ceph_get_snap_realm(struct ceph_mds_client *mdsc, + struct ceph_snap_realm *realm); +extern void ceph_put_snap_realm(struct ceph_mds_client *mdsc, + struct ceph_snap_realm *realm); +extern int ceph_update_snap_trace(struct ceph_mds_client *m, + void *p, void *e, bool deletion); +extern void ceph_handle_snap(struct ceph_mds_client *mdsc, + struct ceph_msg *msg); +extern void ceph_queue_cap_snap(struct ceph_inode_info *ci, + struct ceph_snap_context *snapc); +extern int __ceph_finish_cap_snap(struct ceph_inode_info *ci, + struct ceph_cap_snap *capsnap); +extern void ceph_cleanup_empty_realms(struct ceph_mds_client *mdsc); + +/* + * a cap_snap is "pending" if it is still awaiting an in-progress + * sync write (that may/may not still update size, mtime, etc.). + */ +static inline bool __ceph_have_pending_cap_snap(struct ceph_inode_info *ci) +{ + return !list_empty(&ci->i_cap_snaps) && + list_entry(ci->i_cap_snaps.prev, struct ceph_cap_snap, + ci_item)->writing; +} + + +/* super.c */ +extern struct kmem_cache *ceph_inode_cachep; +extern struct kmem_cache *ceph_cap_cachep; +extern struct kmem_cache *ceph_dentry_cachep; +extern struct kmem_cache *ceph_file_cachep; + +extern const char *ceph_msg_type_name(int type); + +#define FSID_FORMAT "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-" \ + "%02x%02x%02x%02x%02x%02x" +#define PR_FSID(f) (f)->fsid[0], (f)->fsid[1], (f)->fsid[2], (f)->fsid[3], \ + (f)->fsid[4], (f)->fsid[5], (f)->fsid[6], (f)->fsid[7], \ + (f)->fsid[8], (f)->fsid[9], (f)->fsid[10], (f)->fsid[11], \ + (f)->fsid[12], (f)->fsid[13], (f)->fsid[14], (f)->fsid[15] + +/* inode.c */ +extern const struct inode_operations ceph_file_iops; + +extern struct inode *ceph_alloc_inode(struct super_block *sb); +extern void ceph_destroy_inode(struct inode *inode); + +extern struct inode *ceph_get_inode(struct super_block *sb, + struct ceph_vino vino); +extern struct inode *ceph_get_snapdir(struct inode *parent); +extern int ceph_fill_file_size(struct inode *inode, int issued, + u32 truncate_seq, u64 truncate_size, u64 size); +extern void ceph_fill_file_time(struct inode *inode, int issued, + u64 time_warp_seq, struct timespec *ctime, + struct timespec *mtime, struct timespec *atime); +extern int ceph_fill_trace(struct super_block *sb, + struct ceph_mds_request *req, + struct ceph_mds_session *session); +extern int ceph_readdir_prepopulate(struct ceph_mds_request *req, + struct ceph_mds_session *session); + +extern int ceph_inode_holds_cap(struct inode *inode, int mask); + +extern int ceph_inode_set_size(struct inode *inode, loff_t size); +extern void ceph_inode_writeback(struct work_struct *work); +extern void ceph_vmtruncate_work(struct work_struct *work); +extern void __ceph_do_pending_vmtruncate(struct inode *inode); +extern void __ceph_queue_vmtruncate(struct inode *inode); + +extern int ceph_do_getattr(struct inode *inode, int mask); +extern int ceph_permission(struct inode *inode, int mask); +extern int ceph_setattr(struct dentry *dentry, struct iattr *attr); +extern int ceph_getattr(struct vfsmount *mnt, struct dentry *dentry, + struct kstat *stat); + +/* xattr.c */ +extern int ceph_setxattr(struct dentry *, const char *, const void *, + size_t, int); +extern ssize_t ceph_getxattr(struct dentry *, const char *, void *, size_t); +extern ssize_t ceph_listxattr(struct dentry *, char *, size_t); +extern int ceph_removexattr(struct dentry *, const char *); +extern void __ceph_build_xattrs_blob(struct ceph_inode_info *ci); +extern void __ceph_destroy_xattrs(struct ceph_inode_info *ci); + +/* caps.c */ +extern const char *ceph_cap_string(int c); +extern void ceph_handle_caps(struct ceph_mds_session *session, + struct ceph_msg *msg); +extern int ceph_add_cap(struct inode *inode, + struct ceph_mds_session *session, u64 cap_id, + int fmode, unsigned issued, unsigned wanted, + unsigned cap, unsigned seq, u64 realmino, int flags, + struct ceph_cap_reservation *caps_reservation); +extern void __ceph_remove_cap(struct ceph_cap *cap, + struct ceph_cap_reservation *ctx); +static inline void ceph_remove_cap(struct ceph_cap *cap) +{ + struct inode *inode = &cap->ci->vfs_inode; + spin_lock(&inode->i_lock); + __ceph_remove_cap(cap, NULL); + spin_unlock(&inode->i_lock); +} + +extern void ceph_queue_caps_release(struct inode *inode); +extern int ceph_write_inode(struct inode *inode, int unused); +extern int ceph_fsync(struct file *file, struct dentry *dentry, int datasync); +extern void ceph_kick_flushing_caps(struct ceph_mds_client *mdsc, + struct ceph_mds_session *session); +extern int ceph_get_cap_mds(struct inode *inode); +extern void ceph_get_cap_refs(struct ceph_inode_info *ci, int caps); +extern void ceph_put_cap_refs(struct ceph_inode_info *ci, int had); +extern void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr, + struct ceph_snap_context *snapc); +extern void __ceph_flush_snaps(struct ceph_inode_info *ci, + struct ceph_mds_session **psession); +extern void ceph_check_caps(struct ceph_inode_info *ci, int flags, + struct ceph_mds_session *session); +extern void ceph_check_delayed_caps(struct ceph_mds_client *mdsc, + int flushdirty); + +extern int ceph_encode_inode_release(void **p, struct inode *inode, + int mds, int drop, int unless, int force); +extern int ceph_encode_dentry_release(void **p, struct dentry *dn, + int mds, int drop, int unless); + +extern int ceph_get_caps(struct ceph_inode_info *ci, int need, int want, + int *got, loff_t endoff); + +/* for counting open files by mode */ +static inline void __ceph_get_fmode(struct ceph_inode_info *ci, int mode) +{ + ci->i_nr_by_mode[mode]++; +} +extern void ceph_put_fmode(struct ceph_inode_info *ci, int mode); + +/* addr.c */ +extern const struct address_space_operations ceph_aops; +extern int ceph_mmap(struct file *file, struct vm_area_struct *vma); + +/* file.c */ +extern const struct file_operations ceph_file_fops; +extern const struct address_space_operations ceph_aops; +extern int ceph_open(struct inode *inode, struct file *file); +extern struct dentry *ceph_lookup_open(struct inode *dir, struct dentry *dentry, + struct nameidata *nd, int mode, + int locked_dir); +extern int ceph_release(struct inode *inode, struct file *filp); +extern void ceph_release_page_vector(struct page **pages, int num_pages); + +/* dir.c */ +extern const struct file_operations ceph_dir_fops; +extern const struct inode_operations ceph_dir_iops; +extern struct dentry_operations ceph_dentry_ops, ceph_snap_dentry_ops, + ceph_snapdir_dentry_ops; + +extern int ceph_handle_notrace_create(struct inode *dir, struct dentry *dentry); +extern struct dentry *ceph_finish_lookup(struct ceph_mds_request *req, + struct dentry *dentry, int err); + +extern void ceph_dentry_lru_add(struct dentry *dn); +extern void ceph_dentry_lru_touch(struct dentry *dn); +extern void ceph_dentry_lru_del(struct dentry *dn); + +/* + * our d_ops vary depending on whether the inode is live, + * snapshotted (read-only), or a virtual ".snap" directory. + */ +int ceph_init_dentry(struct dentry *dentry); + + +/* ioctl.c */ +extern long ceph_ioctl(struct file *file, unsigned int cmd, unsigned long arg); + +/* export.c */ +extern const struct export_operations ceph_export_ops; + +/* debugfs.c */ +extern int ceph_debugfs_init(void); +extern void ceph_debugfs_cleanup(void); +extern int ceph_debugfs_client_init(struct ceph_client *client); +extern void ceph_debugfs_client_cleanup(struct ceph_client *client); + +static inline struct inode *get_dentry_parent_inode(struct dentry *dentry) +{ + if (dentry && dentry->d_parent) + return dentry->d_parent->d_inode; + + return NULL; +} + +#endif /* _FS_CEPH_SUPER_H */ diff --git a/fs/ceph/types.h b/fs/ceph/types.h new file mode 100644 index 0000000..8a51456 --- /dev/null +++ b/fs/ceph/types.h @@ -0,0 +1,28 @@ +#ifndef _FS_CEPH_TYPES_H +#define _FS_CEPH_TYPES_H + +/* needed before including ceph_fs.h */ +#include +#include +#include +#include + +#include "ceph_fs.h" +#include "ceph_frag.h" + +/* + * Identify inodes by both their ino AND snapshot id (a u64). + */ +struct ceph_vino { + u64 ino; + u64 snap; +}; + + +/* context for the caps reservation mechanism */ +struct ceph_cap_reservation { + int count; +}; + + +#endif -- cgit v0.10.2 From c30dbb9cc7fc75ab1d0ee6fb084ba4684f7a665d Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 6 Oct 2009 11:31:07 -0700 Subject: ceph: ref counted buffer struct ceph_buffer is a simple ref-counted buffer. We transparently choose between kmalloc for small buffers and vmalloc for large ones. This is currently used only for allocating memory for xattr data. Signed-off-by: Sage Weil diff --git a/fs/ceph/buffer.c b/fs/ceph/buffer.c new file mode 100644 index 0000000..cf9aacc --- /dev/null +++ b/fs/ceph/buffer.c @@ -0,0 +1,34 @@ + +#include "ceph_debug.h" +#include "buffer.h" + +struct ceph_buffer *ceph_buffer_new(gfp_t gfp) +{ + struct ceph_buffer *b; + + b = kmalloc(sizeof(*b), gfp); + if (!b) + return NULL; + atomic_set(&b->nref, 1); + b->vec.iov_base = NULL; + b->vec.iov_len = 0; + b->alloc_len = 0; + return b; +} + +int ceph_buffer_alloc(struct ceph_buffer *b, int len, gfp_t gfp) +{ + b->vec.iov_base = kmalloc(len, gfp | __GFP_NOWARN); + if (b->vec.iov_base) { + b->is_vmalloc = false; + } else { + b->vec.iov_base = __vmalloc(len, gfp, PAGE_KERNEL); + b->is_vmalloc = true; + } + if (!b->vec.iov_base) + return -ENOMEM; + b->alloc_len = len; + b->vec.iov_len = len; + return 0; +} + diff --git a/fs/ceph/buffer.h b/fs/ceph/buffer.h new file mode 100644 index 0000000..16b1930 --- /dev/null +++ b/fs/ceph/buffer.h @@ -0,0 +1,55 @@ +#ifndef __FS_CEPH_BUFFER_H +#define __FS_CEPH_BUFFER_H + +#include +#include +#include +#include + +/* + * a simple reference counted buffer. + * + * use kmalloc for small sizes (<= one page), vmalloc for larger + * sizes. + */ +struct ceph_buffer { + atomic_t nref; + struct kvec vec; + size_t alloc_len; + bool is_vmalloc; +}; + +struct ceph_buffer *ceph_buffer_new(gfp_t gfp); +int ceph_buffer_alloc(struct ceph_buffer *b, int len, gfp_t gfp); + +static inline struct ceph_buffer *ceph_buffer_get(struct ceph_buffer *b) +{ + atomic_inc(&b->nref); + return b; +} + +static inline void ceph_buffer_put(struct ceph_buffer *b) +{ + if (b && atomic_dec_and_test(&b->nref)) { + if (b->vec.iov_base) { + if (b->is_vmalloc) + vfree(b->vec.iov_base); + else + kfree(b->vec.iov_base); + } + kfree(b); + } +} + +static inline struct ceph_buffer *ceph_buffer_new_alloc(int len, gfp_t gfp) +{ + struct ceph_buffer *b = ceph_buffer_new(gfp); + + if (b && ceph_buffer_alloc(b, len, gfp) < 0) { + ceph_buffer_put(b); + b = NULL; + } + return b; +} + +#endif -- cgit v0.10.2 From 16725b9d2a2e3d0fd2b0034482e2eb0a2d78050f Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 6 Oct 2009 11:31:07 -0700 Subject: ceph: super.c Mount option parsing, client setup and teardown, and a few odds and ends (e.g., statfs). Signed-off-by: Sage Weil diff --git a/fs/ceph/super.c b/fs/ceph/super.c new file mode 100644 index 0000000..0723fb6 --- /dev/null +++ b/fs/ceph/super.c @@ -0,0 +1,936 @@ + +#include "ceph_debug.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ceph_ver.h" +#include "decode.h" +#include "super.h" +#include "mon_client.h" + +/* + * Ceph superblock operations + * + * Handle the basics of mounting, unmounting. + */ + + +/* + * find filename portion of a path (/foo/bar/baz -> baz) + */ +const char *ceph_file_part(const char *s, int len) +{ + const char *e = s + len; + + while (e != s && *(e-1) != '/') + e--; + return e; +} + + +/* + * super ops + */ +static void ceph_put_super(struct super_block *s) +{ + struct ceph_client *cl = ceph_client(s); + + dout("put_super\n"); + ceph_mdsc_close_sessions(&cl->mdsc); + return; +} + +static int ceph_statfs(struct dentry *dentry, struct kstatfs *buf) +{ + struct ceph_client *client = ceph_inode_to_client(dentry->d_inode); + struct ceph_monmap *monmap = client->monc.monmap; + struct ceph_statfs st; + u64 fsid; + int err; + + dout("statfs\n"); + err = ceph_monc_do_statfs(&client->monc, &st); + if (err < 0) + return err; + + /* fill in kstatfs */ + buf->f_type = CEPH_SUPER_MAGIC; /* ?? */ + + /* + * express utilization in terms of large blocks to avoid + * overflow on 32-bit machines. + */ + buf->f_bsize = 1 << CEPH_BLOCK_SHIFT; + buf->f_blocks = le64_to_cpu(st.kb) >> (CEPH_BLOCK_SHIFT-10); + buf->f_bfree = (le64_to_cpu(st.kb) - le64_to_cpu(st.kb_used)) >> + (CEPH_BLOCK_SHIFT-10); + buf->f_bavail = le64_to_cpu(st.kb_avail) >> (CEPH_BLOCK_SHIFT-10); + + buf->f_files = le64_to_cpu(st.num_objects); + buf->f_ffree = -1; + buf->f_namelen = PATH_MAX; + buf->f_frsize = PAGE_CACHE_SIZE; + + /* leave fsid little-endian, regardless of host endianness */ + fsid = *(u64 *)(&monmap->fsid) ^ *((u64 *)&monmap->fsid + 1); + buf->f_fsid.val[0] = fsid & 0xffffffff; + buf->f_fsid.val[1] = fsid >> 32; + + return 0; +} + + +static int ceph_syncfs(struct super_block *sb, int wait) +{ + dout("sync_fs %d\n", wait); + ceph_osdc_sync(&ceph_client(sb)->osdc); + ceph_mdsc_sync(&ceph_client(sb)->mdsc); + return 0; +} + + +/** + * ceph_show_options - Show mount options in /proc/mounts + * @m: seq_file to write to + * @mnt: mount descriptor + */ +static int ceph_show_options(struct seq_file *m, struct vfsmount *mnt) +{ + struct ceph_client *client = ceph_sb_to_client(mnt->mnt_sb); + struct ceph_mount_args *args = &client->mount_args; + + if (args->flags & CEPH_OPT_FSID) + seq_printf(m, ",fsidmajor=%llu,fsidminor%llu", + le64_to_cpu(*(__le64 *)&args->fsid.fsid[0]), + le64_to_cpu(*(__le64 *)&args->fsid.fsid[8])); + if (args->flags & CEPH_OPT_NOSHARE) + seq_puts(m, ",noshare"); + if (args->flags & CEPH_OPT_DIRSTAT) + seq_puts(m, ",dirstat"); + if ((args->flags & CEPH_OPT_RBYTES) == 0) + seq_puts(m, ",norbytes"); + if (args->flags & CEPH_OPT_NOCRC) + seq_puts(m, ",nocrc"); + if (args->flags & CEPH_OPT_NOASYNCREADDIR) + seq_puts(m, ",noasyncreaddir"); + if (strcmp(args->snapdir_name, CEPH_SNAPDIRNAME_DEFAULT)) + seq_printf(m, ",snapdirname=%s", args->snapdir_name); + if (args->secret) + seq_puts(m, ",secret="); + return 0; +} + +/* + * caches + */ +struct kmem_cache *ceph_inode_cachep; +struct kmem_cache *ceph_cap_cachep; +struct kmem_cache *ceph_dentry_cachep; +struct kmem_cache *ceph_file_cachep; + +static void ceph_inode_init_once(void *foo) +{ + struct ceph_inode_info *ci = foo; + inode_init_once(&ci->vfs_inode); +} + +static int __init init_caches(void) +{ + ceph_inode_cachep = kmem_cache_create("ceph_inode_info", + sizeof(struct ceph_inode_info), + __alignof__(struct ceph_inode_info), + (SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD), + ceph_inode_init_once); + if (ceph_inode_cachep == NULL) + return -ENOMEM; + + ceph_cap_cachep = KMEM_CACHE(ceph_cap, + SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD); + if (ceph_cap_cachep == NULL) + goto bad_cap; + + ceph_dentry_cachep = KMEM_CACHE(ceph_dentry_info, + SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD); + if (ceph_dentry_cachep == NULL) + goto bad_dentry; + + ceph_file_cachep = KMEM_CACHE(ceph_file_info, + SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD); + if (ceph_file_cachep == NULL) + goto bad_file; + + return 0; + +bad_file: + kmem_cache_destroy(ceph_dentry_cachep); +bad_dentry: + kmem_cache_destroy(ceph_cap_cachep); +bad_cap: + kmem_cache_destroy(ceph_inode_cachep); + return -ENOMEM; +} + +static void destroy_caches(void) +{ + kmem_cache_destroy(ceph_inode_cachep); + kmem_cache_destroy(ceph_cap_cachep); + kmem_cache_destroy(ceph_dentry_cachep); + kmem_cache_destroy(ceph_file_cachep); +} + + +/* + * ceph_umount_begin - initiate forced umount. Tear down down the + * mount, skipping steps that may hang while waiting for server(s). + */ +static void ceph_umount_begin(struct super_block *sb) +{ + struct ceph_client *client = ceph_sb_to_client(sb); + + dout("ceph_umount_begin - starting forced umount\n"); + if (!client) + return; + client->mount_state = CEPH_MOUNT_SHUTDOWN; + return; +} + +static const struct super_operations ceph_super_ops = { + .alloc_inode = ceph_alloc_inode, + .destroy_inode = ceph_destroy_inode, + .write_inode = ceph_write_inode, + .sync_fs = ceph_syncfs, + .put_super = ceph_put_super, + .show_options = ceph_show_options, + .statfs = ceph_statfs, + .umount_begin = ceph_umount_begin, +}; + + +const char *ceph_msg_type_name(int type) +{ + switch (type) { + case CEPH_MSG_SHUTDOWN: return "shutdown"; + case CEPH_MSG_PING: return "ping"; + case CEPH_MSG_MON_MAP: return "mon_map"; + case CEPH_MSG_MON_GET_MAP: return "mon_get_map"; + case CEPH_MSG_MON_SUBSCRIBE: return "mon_subscribe"; + case CEPH_MSG_MON_SUBSCRIBE_ACK: return "mon_subscribe_ack"; + case CEPH_MSG_CLIENT_MOUNT: return "client_mount"; + case CEPH_MSG_CLIENT_MOUNT_ACK: return "client_mount_ack"; + case CEPH_MSG_STATFS: return "statfs"; + case CEPH_MSG_STATFS_REPLY: return "statfs_reply"; + case CEPH_MSG_MDS_GETMAP: return "mds_getmap"; + case CEPH_MSG_MDS_MAP: return "mds_map"; + case CEPH_MSG_CLIENT_SESSION: return "client_session"; + case CEPH_MSG_CLIENT_RECONNECT: return "client_reconnect"; + case CEPH_MSG_CLIENT_REQUEST: return "client_request"; + case CEPH_MSG_CLIENT_REQUEST_FORWARD: return "client_request_forward"; + case CEPH_MSG_CLIENT_REPLY: return "client_reply"; + case CEPH_MSG_CLIENT_CAPS: return "client_caps"; + case CEPH_MSG_CLIENT_CAPRELEASE: return "client_cap_release"; + case CEPH_MSG_CLIENT_SNAP: return "client_snap"; + case CEPH_MSG_CLIENT_LEASE: return "client_lease"; + case CEPH_MSG_OSD_GETMAP: return "osd_getmap"; + case CEPH_MSG_OSD_MAP: return "osd_map"; + case CEPH_MSG_OSD_OP: return "osd_op"; + case CEPH_MSG_OSD_OPREPLY: return "osd_opreply"; + default: return "unknown"; + } +} + + +/* + * mount options + */ +enum { + Opt_fsidmajor, + Opt_fsidminor, + Opt_monport, + Opt_wsize, + Opt_rsize, + Opt_osdtimeout, + Opt_mount_timeout, + Opt_caps_wanted_delay_min, + Opt_caps_wanted_delay_max, + Opt_readdir_max_entries, + /* int args above */ + Opt_snapdirname, + Opt_secret, + /* string args above */ + Opt_ip, + Opt_noshare, + Opt_dirstat, + Opt_nodirstat, + Opt_rbytes, + Opt_norbytes, + Opt_nocrc, + Opt_noasyncreaddir, +}; + +static match_table_t arg_tokens = { + {Opt_fsidmajor, "fsidmajor=%ld"}, + {Opt_fsidminor, "fsidminor=%ld"}, + {Opt_monport, "monport=%d"}, + {Opt_wsize, "wsize=%d"}, + {Opt_rsize, "rsize=%d"}, + {Opt_osdtimeout, "osdtimeout=%d"}, + {Opt_mount_timeout, "mount_timeout=%d"}, + {Opt_caps_wanted_delay_min, "caps_wanted_delay_min=%d"}, + {Opt_caps_wanted_delay_max, "caps_wanted_delay_max=%d"}, + {Opt_readdir_max_entries, "readdir_max_entries=%d"}, + /* int args above */ + {Opt_snapdirname, "snapdirname=%s"}, + {Opt_secret, "secret=%s"}, + /* string args above */ + {Opt_ip, "ip=%s"}, + {Opt_noshare, "noshare"}, + {Opt_dirstat, "dirstat"}, + {Opt_nodirstat, "nodirstat"}, + {Opt_rbytes, "rbytes"}, + {Opt_norbytes, "norbytes"}, + {Opt_nocrc, "nocrc"}, + {Opt_noasyncreaddir, "noasyncreaddir"}, + {-1, NULL} +}; + + +static int parse_mount_args(struct ceph_client *client, + int flags, char *options, const char *dev_name, + const char **path) +{ + struct ceph_mount_args *args = &client->mount_args; + const char *c; + int err; + substring_t argstr[MAX_OPT_ARGS]; + int num_mon; + struct ceph_entity_addr mon_addr[CEPH_MAX_MON_MOUNT_ADDR]; + int i; + + dout("parse_mount_args dev_name '%s'\n", dev_name); + memset(args, 0, sizeof(*args)); + + /* start with defaults */ + args->sb_flags = flags; + args->flags = CEPH_OPT_DEFAULT; + args->osd_timeout = 5; /* seconds */ + args->mount_timeout = CEPH_MOUNT_TIMEOUT_DEFAULT; /* seconds */ + args->caps_wanted_delay_min = CEPH_CAPS_WANTED_DELAY_MIN_DEFAULT; + args->caps_wanted_delay_max = CEPH_CAPS_WANTED_DELAY_MAX_DEFAULT; + args->snapdir_name = kstrdup(CEPH_SNAPDIRNAME_DEFAULT, GFP_KERNEL); + args->cap_release_safety = CEPH_CAPS_PER_RELEASE * 4; + args->max_readdir = 1024; + + /* ip1[:port1][,ip2[:port2]...]:/subdir/in/fs */ + if (!dev_name) + return -EINVAL; + *path = strstr(dev_name, ":/"); + if (*path == NULL) { + pr_err("device name is missing path (no :/ in %s)\n", + dev_name); + return -EINVAL; + } + + /* get mon ip(s) */ + err = ceph_parse_ips(dev_name, *path, mon_addr, + CEPH_MAX_MON_MOUNT_ADDR, &num_mon); + if (err < 0) + return err; + + /* build initial monmap */ + client->monc.monmap = kzalloc(sizeof(*client->monc.monmap) + + num_mon*sizeof(client->monc.monmap->mon_inst[0]), + GFP_KERNEL); + if (!client->monc.monmap) + return -ENOMEM; + for (i = 0; i < num_mon; i++) { + client->monc.monmap->mon_inst[i].addr = mon_addr[i]; + client->monc.monmap->mon_inst[i].addr.erank = 0; + client->monc.monmap->mon_inst[i].addr.nonce = 0; + client->monc.monmap->mon_inst[i].name.type = + CEPH_ENTITY_TYPE_MON; + client->monc.monmap->mon_inst[i].name.num = cpu_to_le64(i); + } + client->monc.monmap->num_mon = num_mon; + memset(&args->my_addr.in_addr, 0, sizeof(args->my_addr.in_addr)); + + /* path on server */ + *path += 2; + dout("server path '%s'\n", *path); + + /* parse mount options */ + while ((c = strsep(&options, ",")) != NULL) { + int token, intval, ret; + if (!*c) + continue; + token = match_token((char *)c, arg_tokens, argstr); + if (token < 0) { + pr_err("bad mount option at '%s'\n", c); + return -EINVAL; + + } + if (token < Opt_ip) { + ret = match_int(&argstr[0], &intval); + if (ret < 0) { + pr_err("bad mount option arg (not int) " + "at '%s'\n", c); + continue; + } + dout("got token %d intval %d\n", token, intval); + } + switch (token) { + case Opt_fsidmajor: + *(__le64 *)&args->fsid.fsid[0] = cpu_to_le64(intval); + break; + case Opt_fsidminor: + *(__le64 *)&args->fsid.fsid[8] = cpu_to_le64(intval); + break; + case Opt_ip: + err = ceph_parse_ips(argstr[0].from, + argstr[0].to, + &args->my_addr, + 1, NULL); + if (err < 0) + return err; + args->flags |= CEPH_OPT_MYIP; + break; + + case Opt_snapdirname: + kfree(args->snapdir_name); + args->snapdir_name = kstrndup(argstr[0].from, + argstr[0].to-argstr[0].from, + GFP_KERNEL); + break; + case Opt_secret: + args->secret = kstrndup(argstr[0].from, + argstr[0].to-argstr[0].from, + GFP_KERNEL); + break; + + /* misc */ + case Opt_wsize: + args->wsize = intval; + break; + case Opt_rsize: + args->rsize = intval; + break; + case Opt_osdtimeout: + args->osd_timeout = intval; + break; + case Opt_mount_timeout: + args->mount_timeout = intval; + break; + case Opt_caps_wanted_delay_min: + args->caps_wanted_delay_min = intval; + break; + case Opt_caps_wanted_delay_max: + args->caps_wanted_delay_max = intval; + break; + case Opt_readdir_max_entries: + args->max_readdir = intval; + break; + + case Opt_noshare: + args->flags |= CEPH_OPT_NOSHARE; + break; + + case Opt_dirstat: + args->flags |= CEPH_OPT_DIRSTAT; + break; + case Opt_nodirstat: + args->flags &= ~CEPH_OPT_DIRSTAT; + break; + case Opt_rbytes: + args->flags |= CEPH_OPT_RBYTES; + break; + case Opt_norbytes: + args->flags &= ~CEPH_OPT_RBYTES; + break; + case Opt_nocrc: + args->flags |= CEPH_OPT_NOCRC; + break; + case Opt_noasyncreaddir: + args->flags |= CEPH_OPT_NOASYNCREADDIR; + break; + + default: + BUG_ON(token); + } + } + + return 0; +} + +static void release_mount_args(struct ceph_mount_args *args) +{ + kfree(args->snapdir_name); + args->snapdir_name = NULL; + kfree(args->secret); + args->secret = NULL; +} + +/* + * create a fresh client instance + */ +static struct ceph_client *ceph_create_client(void) +{ + struct ceph_client *client; + int err = -ENOMEM; + + client = kzalloc(sizeof(*client), GFP_KERNEL); + if (client == NULL) + return ERR_PTR(-ENOMEM); + + mutex_init(&client->mount_mutex); + + init_waitqueue_head(&client->mount_wq); + + client->sb = NULL; + client->mount_state = CEPH_MOUNT_MOUNTING; + client->whoami = -1; + + client->msgr = NULL; + + client->mount_err = 0; + client->signed_ticket = NULL; + client->signed_ticket_len = 0; + + err = -ENOMEM; + client->wb_wq = create_workqueue("ceph-writeback"); + if (client->wb_wq == NULL) + goto fail; + client->pg_inv_wq = create_singlethread_workqueue("ceph-pg-invalid"); + if (client->pg_inv_wq == NULL) + goto fail_wb_wq; + client->trunc_wq = create_singlethread_workqueue("ceph-trunc"); + if (client->trunc_wq == NULL) + goto fail_pg_inv_wq; + + /* subsystems */ + err = ceph_monc_init(&client->monc, client); + if (err < 0) + goto fail_trunc_wq; + err = ceph_osdc_init(&client->osdc, client); + if (err < 0) + goto fail_monc; + ceph_mdsc_init(&client->mdsc, client); + return client; + +fail_monc: + ceph_monc_stop(&client->monc); +fail_trunc_wq: + destroy_workqueue(client->trunc_wq); +fail_pg_inv_wq: + destroy_workqueue(client->pg_inv_wq); +fail_wb_wq: + destroy_workqueue(client->wb_wq); +fail: + kfree(client); + return ERR_PTR(err); +} + +static void ceph_destroy_client(struct ceph_client *client) +{ + dout("destroy_client %p\n", client); + + /* unmount */ + ceph_mdsc_stop(&client->mdsc); + ceph_monc_stop(&client->monc); + ceph_osdc_stop(&client->osdc); + + kfree(client->signed_ticket); + + ceph_debugfs_client_cleanup(client); + destroy_workqueue(client->wb_wq); + destroy_workqueue(client->pg_inv_wq); + destroy_workqueue(client->trunc_wq); + + if (client->msgr) + ceph_messenger_destroy(client->msgr); + if (client->wb_pagevec_pool) + mempool_destroy(client->wb_pagevec_pool); + + release_mount_args(&client->mount_args); + + kfree(client); + dout("destroy_client %p done\n", client); +} + +/* + * true if we have the mon map (and have thus joined the cluster) + */ +static int have_mon_map(struct ceph_client *client) +{ + return client->monc.monmap && client->monc.monmap->epoch; +} + +/* + * Bootstrap mount by opening the root directory. Note the mount + * @started time from caller, and time out if this takes too long. + */ +static struct dentry *open_root_dentry(struct ceph_client *client, + const char *path, + unsigned long started) +{ + struct ceph_mds_client *mdsc = &client->mdsc; + struct ceph_mds_request *req = NULL; + int err; + struct dentry *root; + + /* open dir */ + dout("open_root_inode opening '%s'\n", path); + req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_GETATTR, USE_ANY_MDS); + if (IS_ERR(req)) + return ERR_PTR(PTR_ERR(req)); + req->r_path1 = kstrdup(path, GFP_NOFS); + req->r_ino1.ino = CEPH_INO_ROOT; + req->r_ino1.snap = CEPH_NOSNAP; + req->r_started = started; + req->r_timeout = client->mount_args.mount_timeout * HZ; + req->r_args.getattr.mask = cpu_to_le32(CEPH_STAT_CAP_INODE); + req->r_num_caps = 2; + err = ceph_mdsc_do_request(mdsc, NULL, req); + if (err == 0) { + dout("open_root_inode success\n"); + if (ceph_ino(req->r_target_inode) == CEPH_INO_ROOT && + client->sb->s_root == NULL) + root = d_alloc_root(req->r_target_inode); + else + root = d_obtain_alias(req->r_target_inode); + req->r_target_inode = NULL; + dout("open_root_inode success, root dentry is %p\n", root); + } else { + root = ERR_PTR(err); + } + ceph_mdsc_put_request(req); + return root; +} + +/* + * mount: join the ceph cluster, and open root directory. + */ +static int ceph_mount(struct ceph_client *client, struct vfsmount *mnt, + const char *path) +{ + struct ceph_entity_addr *myaddr = NULL; + int err; + unsigned long timeout = client->mount_args.mount_timeout * HZ; + unsigned long started = jiffies; /* note the start time */ + struct dentry *root; + + dout("mount start\n"); + mutex_lock(&client->mount_mutex); + + /* initialize the messenger */ + if (client->msgr == NULL) { + if (ceph_test_opt(client, MYIP)) + myaddr = &client->mount_args.my_addr; + client->msgr = ceph_messenger_create(myaddr); + if (IS_ERR(client->msgr)) { + err = PTR_ERR(client->msgr); + client->msgr = NULL; + goto out; + } + client->msgr->nocrc = ceph_test_opt(client, NOCRC); + } + + /* send mount request, and wait for mon, mds, and osd maps */ + err = ceph_monc_request_mount(&client->monc); + if (err < 0) + goto out; + + while (!have_mon_map(client) && !client->mount_err) { + err = -EIO; + if (timeout && time_after_eq(jiffies, started + timeout)) + goto out; + + /* wait */ + dout("mount waiting for mount\n"); + err = wait_event_interruptible_timeout(client->mount_wq, + client->mount_err || have_mon_map(client), + timeout); + if (err == -EINTR || err == -ERESTARTSYS) + goto out; + if (client->mount_err) { + err = client->mount_err; + goto out; + } + } + + dout("mount opening root\n"); + root = open_root_dentry(client, "", started); + if (IS_ERR(root)) { + err = PTR_ERR(root); + goto out; + } + if (client->sb->s_root) + dput(root); + else + client->sb->s_root = root; + + if (path[0] == 0) { + dget(root); + } else { + dout("mount opening base mountpoint\n"); + root = open_root_dentry(client, path, started); + if (IS_ERR(root)) { + err = PTR_ERR(root); + dput(client->sb->s_root); + client->sb->s_root = NULL; + goto out; + } + } + + mnt->mnt_root = root; + mnt->mnt_sb = client->sb; + + client->mount_state = CEPH_MOUNT_MOUNTED; + dout("mount success\n"); + err = 0; + +out: + mutex_unlock(&client->mount_mutex); + return err; +} + +static int ceph_set_super(struct super_block *s, void *data) +{ + struct ceph_client *client = data; + int ret; + + dout("set_super %p data %p\n", s, data); + + s->s_flags = client->mount_args.sb_flags; + s->s_maxbytes = 1ULL << 40; /* temp value until we get mdsmap */ + + s->s_fs_info = client; + client->sb = s; + + s->s_op = &ceph_super_ops; + s->s_export_op = &ceph_export_ops; + + s->s_time_gran = 1000; /* 1000 ns == 1 us */ + + ret = set_anon_super(s, NULL); /* what is that second arg for? */ + if (ret != 0) + goto fail; + + return ret; + +fail: + s->s_fs_info = NULL; + client->sb = NULL; + return ret; +} + +/* + * share superblock if same fs AND options + */ +static int ceph_compare_super(struct super_block *sb, void *data) +{ + struct ceph_client *new = data; + struct ceph_mount_args *args = &new->mount_args; + struct ceph_client *other = ceph_sb_to_client(sb); + int i; + + dout("ceph_compare_super %p\n", sb); + if (args->flags & CEPH_OPT_FSID) { + if (ceph_fsid_compare(&args->fsid, &other->fsid)) { + dout("fsid doesn't match\n"); + return 0; + } + } else { + /* do we share (a) monitor? */ + for (i = 0; i < new->monc.monmap->num_mon; i++) + if (ceph_monmap_contains(other->monc.monmap, + &new->monc.monmap->mon_inst[i].addr)) + break; + if (i == new->monc.monmap->num_mon) { + dout("mon ip not part of monmap\n"); + return 0; + } + dout("mon ip matches existing sb %p\n", sb); + } + if (args->sb_flags != other->mount_args.sb_flags) { + dout("flags differ\n"); + return 0; + } + return 1; +} + +/* + * construct our own bdi so we can control readahead, etc. + */ +static int ceph_init_bdi(struct super_block *sb, struct ceph_client *client) +{ + int err; + + err = bdi_init(&client->backing_dev_info); + if (err < 0) + return err; + + /* set ra_pages based on rsize mount option? */ + if (client->mount_args.rsize >= PAGE_CACHE_SIZE) + client->backing_dev_info.ra_pages = + (client->mount_args.rsize + PAGE_CACHE_SIZE - 1) + >> PAGE_SHIFT; + + err = bdi_register_dev(&client->backing_dev_info, sb->s_dev); + return err; +} + +static int ceph_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, + struct vfsmount *mnt) +{ + struct super_block *sb; + struct ceph_client *client; + int err; + int (*compare_super)(struct super_block *, void *) = ceph_compare_super; + const char *path; + + dout("ceph_get_sb\n"); + + /* create client (which we may/may not use) */ + client = ceph_create_client(); + if (IS_ERR(client)) + return PTR_ERR(client); + + err = parse_mount_args(client, flags, data, dev_name, &path); + if (err < 0) + goto out; + + if (client->mount_args.flags & CEPH_OPT_NOSHARE) + compare_super = NULL; + sb = sget(fs_type, compare_super, ceph_set_super, client); + if (IS_ERR(sb)) { + err = PTR_ERR(sb); + goto out; + } + + if (ceph_client(sb) != client) { + ceph_destroy_client(client); + client = ceph_client(sb); + dout("get_sb got existing client %p\n", client); + } else { + dout("get_sb using new client %p\n", client); + + /* set up mempools */ + err = -ENOMEM; + client->wb_pagevec_pool = mempool_create_kmalloc_pool(10, + client->mount_args.wsize >> PAGE_CACHE_SHIFT); + if (!client->wb_pagevec_pool) + goto out_splat; + + err = ceph_init_bdi(sb, client); + if (err < 0) + goto out_splat; + } + + err = ceph_mount(client, mnt, path); + if (err < 0) + goto out_splat; + dout("root %p inode %p ino %llx.%llx\n", mnt->mnt_root, + mnt->mnt_root->d_inode, ceph_vinop(mnt->mnt_root->d_inode)); + return 0; + +out_splat: + ceph_mdsc_close_sessions(&client->mdsc); + up_write(&sb->s_umount); + deactivate_super(sb); + goto out_final; + +out: + ceph_destroy_client(client); +out_final: + dout("ceph_get_sb fail %d\n", err); + return err; +} + +static void ceph_kill_sb(struct super_block *s) +{ + struct ceph_client *client = ceph_sb_to_client(s); + dout("kill_sb %p\n", s); + ceph_mdsc_pre_umount(&client->mdsc); + bdi_unregister(&client->backing_dev_info); + kill_anon_super(s); /* will call put_super after sb is r/o */ + bdi_destroy(&client->backing_dev_info); + ceph_destroy_client(client); +} + +static struct file_system_type ceph_fs_type = { + .owner = THIS_MODULE, + .name = "ceph", + .get_sb = ceph_get_sb, + .kill_sb = ceph_kill_sb, + .fs_flags = FS_RENAME_DOES_D_MOVE, +}; + +#define _STRINGIFY(x) #x +#define STRINGIFY(x) _STRINGIFY(x) + +static int __init init_ceph(void) +{ + int ret = 0; + + ret = ceph_debugfs_init(); + if (ret < 0) + goto out; + + ret = ceph_msgr_init(); + if (ret < 0) + goto out_debugfs; + + ret = init_caches(); + if (ret) + goto out_msgr; + + ceph_caps_init(); + + ret = register_filesystem(&ceph_fs_type); + if (ret) + goto out_icache; + + pr_info("loaded (%s)\n", STRINGIFY(CEPH_GIT_VER)); + return 0; + +out_icache: + destroy_caches(); +out_msgr: + ceph_msgr_exit(); +out_debugfs: + ceph_debugfs_cleanup(); +out: + return ret; +} + +static void __exit exit_ceph(void) +{ + dout("exit_ceph\n"); + unregister_filesystem(&ceph_fs_type); + ceph_caps_finalize(); + destroy_caches(); + ceph_msgr_exit(); + ceph_debugfs_cleanup(); +} + +module_init(init_ceph); +module_exit(exit_ceph); + +MODULE_AUTHOR("Sage Weil "); +MODULE_AUTHOR("Yehuda Sadeh "); +MODULE_AUTHOR("Patience Warnick "); +MODULE_DESCRIPTION("Ceph filesystem for Linux"); +MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 355da1eb7a1f91c276b991764e951bbcd8047599 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 6 Oct 2009 11:31:08 -0700 Subject: ceph: inode operations Inode cache and inode operations. We also include routines to incorporate metadata structures returned by the MDS into the client cache, and some helpers to deal with file capabilities and metadata leases. The bulk of that work is done by fill_inode() and fill_trace(). Signed-off-by: Sage Weil diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c new file mode 100644 index 0000000..6097af7 --- /dev/null +++ b/fs/ceph/inode.c @@ -0,0 +1,1620 @@ +#include "ceph_debug.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "super.h" +#include "decode.h" + +/* + * Ceph inode operations + * + * Implement basic inode helpers (get, alloc) and inode ops (getattr, + * setattr, etc.), xattr helpers, and helpers for assimilating + * metadata returned by the MDS into our cache. + * + * Also define helpers for doing asynchronous writeback, invalidation, + * and truncation for the benefit of those who can't afford to block + * (typically because they are in the message handler path). + */ + +static const struct inode_operations ceph_symlink_iops; + +static void ceph_inode_invalidate_pages(struct work_struct *work); + +/* + * find or create an inode, given the ceph ino number + */ +struct inode *ceph_get_inode(struct super_block *sb, struct ceph_vino vino) +{ + struct inode *inode; + ino_t t = ceph_vino_to_ino(vino); + + inode = iget5_locked(sb, t, ceph_ino_compare, ceph_set_ino_cb, &vino); + if (inode == NULL) + return ERR_PTR(-ENOMEM); + if (inode->i_state & I_NEW) { + dout("get_inode created new inode %p %llx.%llx ino %llx\n", + inode, ceph_vinop(inode), (u64)inode->i_ino); + unlock_new_inode(inode); + } + + dout("get_inode on %lu=%llx.%llx got %p\n", inode->i_ino, vino.ino, + vino.snap, inode); + return inode; +} + +/* + * get/constuct snapdir inode for a given directory + */ +struct inode *ceph_get_snapdir(struct inode *parent) +{ + struct ceph_vino vino = { + .ino = ceph_ino(parent), + .snap = CEPH_SNAPDIR, + }; + struct inode *inode = ceph_get_inode(parent->i_sb, vino); + + BUG_ON(!S_ISDIR(parent->i_mode)); + if (IS_ERR(inode)) + return ERR_PTR(PTR_ERR(inode)); + inode->i_mode = parent->i_mode; + inode->i_uid = parent->i_uid; + inode->i_gid = parent->i_gid; + inode->i_op = &ceph_dir_iops; + inode->i_fop = &ceph_dir_fops; + ceph_inode(inode)->i_snap_caps = CEPH_CAP_PIN; /* so we can open */ + return inode; +} + +const struct inode_operations ceph_file_iops = { + .permission = ceph_permission, + .setattr = ceph_setattr, + .getattr = ceph_getattr, + .setxattr = ceph_setxattr, + .getxattr = ceph_getxattr, + .listxattr = ceph_listxattr, + .removexattr = ceph_removexattr, +}; + + +/* + * We use a 'frag tree' to keep track of the MDS's directory fragments + * for a given inode (usually there is just a single fragment). We + * need to know when a child frag is delegated to a new MDS, or when + * it is flagged as replicated, so we can direct our requests + * accordingly. + */ + +/* + * find/create a frag in the tree + */ +static struct ceph_inode_frag *__get_or_create_frag(struct ceph_inode_info *ci, + u32 f) +{ + struct rb_node **p; + struct rb_node *parent = NULL; + struct ceph_inode_frag *frag; + int c; + + p = &ci->i_fragtree.rb_node; + while (*p) { + parent = *p; + frag = rb_entry(parent, struct ceph_inode_frag, node); + c = ceph_frag_compare(f, frag->frag); + if (c < 0) + p = &(*p)->rb_left; + else if (c > 0) + p = &(*p)->rb_right; + else + return frag; + } + + frag = kmalloc(sizeof(*frag), GFP_NOFS); + if (!frag) { + pr_err("__get_or_create_frag ENOMEM on %p %llx.%llx " + "frag %x\n", &ci->vfs_inode, + ceph_vinop(&ci->vfs_inode), f); + return ERR_PTR(-ENOMEM); + } + frag->frag = f; + frag->split_by = 0; + frag->mds = -1; + frag->ndist = 0; + + rb_link_node(&frag->node, parent, p); + rb_insert_color(&frag->node, &ci->i_fragtree); + + dout("get_or_create_frag added %llx.%llx frag %x\n", + ceph_vinop(&ci->vfs_inode), f); + return frag; +} + +/* + * find a specific frag @f + */ +struct ceph_inode_frag *__ceph_find_frag(struct ceph_inode_info *ci, u32 f) +{ + struct rb_node *n = ci->i_fragtree.rb_node; + + while (n) { + struct ceph_inode_frag *frag = + rb_entry(n, struct ceph_inode_frag, node); + int c = ceph_frag_compare(f, frag->frag); + if (c < 0) + n = n->rb_left; + else if (c > 0) + n = n->rb_right; + else + return frag; + } + return NULL; +} + +/* + * Choose frag containing the given value @v. If @pfrag is + * specified, copy the frag delegation info to the caller if + * it is present. + */ +u32 ceph_choose_frag(struct ceph_inode_info *ci, u32 v, + struct ceph_inode_frag *pfrag, + int *found) +{ + u32 t = ceph_frag_make(0, 0); + struct ceph_inode_frag *frag; + unsigned nway, i; + u32 n; + + if (found) + *found = 0; + + mutex_lock(&ci->i_fragtree_mutex); + while (1) { + WARN_ON(!ceph_frag_contains_value(t, v)); + frag = __ceph_find_frag(ci, t); + if (!frag) + break; /* t is a leaf */ + if (frag->split_by == 0) { + if (pfrag) + memcpy(pfrag, frag, sizeof(*pfrag)); + if (found) + *found = 1; + break; + } + + /* choose child */ + nway = 1 << frag->split_by; + dout("choose_frag(%x) %x splits by %d (%d ways)\n", v, t, + frag->split_by, nway); + for (i = 0; i < nway; i++) { + n = ceph_frag_make_child(t, frag->split_by, i); + if (ceph_frag_contains_value(n, v)) { + t = n; + break; + } + } + BUG_ON(i == nway); + } + dout("choose_frag(%x) = %x\n", v, t); + + mutex_unlock(&ci->i_fragtree_mutex); + return t; +} + +/* + * Process dirfrag (delegation) info from the mds. Include leaf + * fragment in tree ONLY if ndist > 0. Otherwise, only + * branches/splits are included in i_fragtree) + */ +static int ceph_fill_dirfrag(struct inode *inode, + struct ceph_mds_reply_dirfrag *dirinfo) +{ + struct ceph_inode_info *ci = ceph_inode(inode); + struct ceph_inode_frag *frag; + u32 id = le32_to_cpu(dirinfo->frag); + int mds = le32_to_cpu(dirinfo->auth); + int ndist = le32_to_cpu(dirinfo->ndist); + int i; + int err = 0; + + mutex_lock(&ci->i_fragtree_mutex); + if (ndist == 0) { + /* no delegation info needed. */ + frag = __ceph_find_frag(ci, id); + if (!frag) + goto out; + if (frag->split_by == 0) { + /* tree leaf, remove */ + dout("fill_dirfrag removed %llx.%llx frag %x" + " (no ref)\n", ceph_vinop(inode), id); + rb_erase(&frag->node, &ci->i_fragtree); + kfree(frag); + } else { + /* tree branch, keep and clear */ + dout("fill_dirfrag cleared %llx.%llx frag %x" + " referral\n", ceph_vinop(inode), id); + frag->mds = -1; + frag->ndist = 0; + } + goto out; + } + + + /* find/add this frag to store mds delegation info */ + frag = __get_or_create_frag(ci, id); + if (IS_ERR(frag)) { + /* this is not the end of the world; we can continue + with bad/inaccurate delegation info */ + pr_err("fill_dirfrag ENOMEM on mds ref %llx.%llx fg %x\n", + ceph_vinop(inode), le32_to_cpu(dirinfo->frag)); + err = -ENOMEM; + goto out; + } + + frag->mds = mds; + frag->ndist = min_t(u32, ndist, CEPH_MAX_DIRFRAG_REP); + for (i = 0; i < frag->ndist; i++) + frag->dist[i] = le32_to_cpu(dirinfo->dist[i]); + dout("fill_dirfrag %llx.%llx frag %x ndist=%d\n", + ceph_vinop(inode), frag->frag, frag->ndist); + +out: + mutex_unlock(&ci->i_fragtree_mutex); + return err; +} + + +/* + * initialize a newly allocated inode. + */ +struct inode *ceph_alloc_inode(struct super_block *sb) +{ + struct ceph_inode_info *ci; + int i; + + ci = kmem_cache_alloc(ceph_inode_cachep, GFP_NOFS); + if (!ci) + return NULL; + + dout("alloc_inode %p\n", &ci->vfs_inode); + + ci->i_version = 0; + ci->i_time_warp_seq = 0; + ci->i_ceph_flags = 0; + ci->i_release_count = 0; + ci->i_symlink = NULL; + + ci->i_fragtree = RB_ROOT; + mutex_init(&ci->i_fragtree_mutex); + + ci->i_xattrs.blob = NULL; + ci->i_xattrs.prealloc_blob = NULL; + ci->i_xattrs.dirty = false; + ci->i_xattrs.index = RB_ROOT; + ci->i_xattrs.count = 0; + ci->i_xattrs.names_size = 0; + ci->i_xattrs.vals_size = 0; + ci->i_xattrs.version = 0; + ci->i_xattrs.index_version = 0; + + ci->i_caps = RB_ROOT; + ci->i_auth_cap = NULL; + ci->i_dirty_caps = 0; + ci->i_flushing_caps = 0; + INIT_LIST_HEAD(&ci->i_dirty_item); + INIT_LIST_HEAD(&ci->i_flushing_item); + ci->i_cap_flush_seq = 0; + ci->i_cap_flush_last_tid = 0; + memset(&ci->i_cap_flush_tid, 0, sizeof(ci->i_cap_flush_tid)); + init_waitqueue_head(&ci->i_cap_wq); + ci->i_hold_caps_min = 0; + ci->i_hold_caps_max = 0; + INIT_LIST_HEAD(&ci->i_cap_delay_list); + ci->i_cap_exporting_mds = 0; + ci->i_cap_exporting_mseq = 0; + ci->i_cap_exporting_issued = 0; + INIT_LIST_HEAD(&ci->i_cap_snaps); + ci->i_head_snapc = NULL; + ci->i_snap_caps = 0; + + for (i = 0; i < CEPH_FILE_MODE_NUM; i++) + ci->i_nr_by_mode[i] = 0; + + ci->i_truncate_seq = 0; + ci->i_truncate_size = 0; + ci->i_truncate_pending = 0; + + ci->i_max_size = 0; + ci->i_reported_size = 0; + ci->i_wanted_max_size = 0; + ci->i_requested_max_size = 0; + + ci->i_pin_ref = 0; + ci->i_rd_ref = 0; + ci->i_rdcache_ref = 0; + ci->i_wr_ref = 0; + ci->i_wrbuffer_ref = 0; + ci->i_wrbuffer_ref_head = 0; + ci->i_shared_gen = 0; + ci->i_rdcache_gen = 0; + ci->i_rdcache_revoking = 0; + + INIT_LIST_HEAD(&ci->i_unsafe_writes); + INIT_LIST_HEAD(&ci->i_unsafe_dirops); + spin_lock_init(&ci->i_unsafe_lock); + + ci->i_snap_realm = NULL; + INIT_LIST_HEAD(&ci->i_snap_realm_item); + INIT_LIST_HEAD(&ci->i_snap_flush_item); + + INIT_WORK(&ci->i_wb_work, ceph_inode_writeback); + INIT_WORK(&ci->i_pg_inv_work, ceph_inode_invalidate_pages); + + INIT_WORK(&ci->i_vmtruncate_work, ceph_vmtruncate_work); + + return &ci->vfs_inode; +} + +void ceph_destroy_inode(struct inode *inode) +{ + struct ceph_inode_info *ci = ceph_inode(inode); + struct ceph_inode_frag *frag; + struct rb_node *n; + + dout("destroy_inode %p ino %llx.%llx\n", inode, ceph_vinop(inode)); + + ceph_queue_caps_release(inode); + + kfree(ci->i_symlink); + while ((n = rb_first(&ci->i_fragtree)) != NULL) { + frag = rb_entry(n, struct ceph_inode_frag, node); + rb_erase(n, &ci->i_fragtree); + kfree(frag); + } + + __ceph_destroy_xattrs(ci); + ceph_buffer_put(ci->i_xattrs.blob); + ceph_buffer_put(ci->i_xattrs.prealloc_blob); + + kmem_cache_free(ceph_inode_cachep, ci); +} + + +/* + * Helpers to fill in size, ctime, mtime, and atime. We have to be + * careful because either the client or MDS may have more up to date + * info, depending on which capabilities are held, and whether + * time_warp_seq or truncate_seq have increased. (Ordinarily, mtime + * and size are monotonically increasing, except when utimes() or + * truncate() increments the corresponding _seq values.) + */ +int ceph_fill_file_size(struct inode *inode, int issued, + u32 truncate_seq, u64 truncate_size, u64 size) +{ + struct ceph_inode_info *ci = ceph_inode(inode); + int queue_trunc = 0; + + if (ceph_seq_cmp(truncate_seq, ci->i_truncate_seq) > 0 || + (truncate_seq == ci->i_truncate_seq && size > inode->i_size)) { + dout("size %lld -> %llu\n", inode->i_size, size); + inode->i_size = size; + inode->i_blocks = (size + (1<<9) - 1) >> 9; + ci->i_reported_size = size; + if (truncate_seq != ci->i_truncate_seq) { + dout("truncate_seq %u -> %u\n", + ci->i_truncate_seq, truncate_seq); + ci->i_truncate_seq = truncate_seq; + if (issued & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_RD| + CEPH_CAP_FILE_WR|CEPH_CAP_FILE_BUFFER| + CEPH_CAP_FILE_EXCL)) { + ci->i_truncate_pending++; + queue_trunc = 1; + } + } + } + if (ceph_seq_cmp(truncate_seq, ci->i_truncate_seq) >= 0 && + ci->i_truncate_size != truncate_size) { + dout("truncate_size %lld -> %llu\n", ci->i_truncate_size, + truncate_size); + ci->i_truncate_size = truncate_size; + } + return queue_trunc; +} + +void ceph_fill_file_time(struct inode *inode, int issued, + u64 time_warp_seq, struct timespec *ctime, + struct timespec *mtime, struct timespec *atime) +{ + struct ceph_inode_info *ci = ceph_inode(inode); + int warn = 0; + + if (issued & (CEPH_CAP_FILE_EXCL| + CEPH_CAP_FILE_WR| + CEPH_CAP_FILE_BUFFER)) { + if (timespec_compare(ctime, &inode->i_ctime) > 0) { + dout("ctime %ld.%09ld -> %ld.%09ld inc w/ cap\n", + inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec, + ctime->tv_sec, ctime->tv_nsec); + inode->i_ctime = *ctime; + } + if (ceph_seq_cmp(time_warp_seq, ci->i_time_warp_seq) > 0) { + /* the MDS did a utimes() */ + dout("mtime %ld.%09ld -> %ld.%09ld " + "tw %d -> %d\n", + inode->i_mtime.tv_sec, inode->i_mtime.tv_nsec, + mtime->tv_sec, mtime->tv_nsec, + ci->i_time_warp_seq, (int)time_warp_seq); + + inode->i_mtime = *mtime; + inode->i_atime = *atime; + ci->i_time_warp_seq = time_warp_seq; + } else if (time_warp_seq == ci->i_time_warp_seq) { + /* nobody did utimes(); take the max */ + if (timespec_compare(mtime, &inode->i_mtime) > 0) { + dout("mtime %ld.%09ld -> %ld.%09ld inc\n", + inode->i_mtime.tv_sec, + inode->i_mtime.tv_nsec, + mtime->tv_sec, mtime->tv_nsec); + inode->i_mtime = *mtime; + } + if (timespec_compare(atime, &inode->i_atime) > 0) { + dout("atime %ld.%09ld -> %ld.%09ld inc\n", + inode->i_atime.tv_sec, + inode->i_atime.tv_nsec, + atime->tv_sec, atime->tv_nsec); + inode->i_atime = *atime; + } + } else if (issued & CEPH_CAP_FILE_EXCL) { + /* we did a utimes(); ignore mds values */ + } else { + warn = 1; + } + } else { + /* we have no write caps; whatever the MDS says is true */ + if (ceph_seq_cmp(time_warp_seq, ci->i_time_warp_seq) >= 0) { + inode->i_ctime = *ctime; + inode->i_mtime = *mtime; + inode->i_atime = *atime; + ci->i_time_warp_seq = time_warp_seq; + } else { + warn = 1; + } + } + if (warn) /* time_warp_seq shouldn't go backwards */ + dout("%p mds time_warp_seq %llu < %u\n", + inode, time_warp_seq, ci->i_time_warp_seq); +} + +/* + * Populate an inode based on info from mds. May be called on new or + * existing inodes. + */ +static int fill_inode(struct inode *inode, + struct ceph_mds_reply_info_in *iinfo, + struct ceph_mds_reply_dirfrag *dirinfo, + struct ceph_mds_session *session, + unsigned long ttl_from, int cap_fmode, + struct ceph_cap_reservation *caps_reservation) +{ + struct ceph_mds_reply_inode *info = iinfo->in; + struct ceph_inode_info *ci = ceph_inode(inode); + int i; + int issued, implemented; + struct timespec mtime, atime, ctime; + u32 nsplits; + struct ceph_buffer *xattr_blob = NULL; + int err = 0; + int queue_trunc = 0; + + dout("fill_inode %p ino %llx.%llx v %llu had %llu\n", + inode, ceph_vinop(inode), le64_to_cpu(info->version), + ci->i_version); + + /* + * prealloc xattr data, if it looks like we'll need it. only + * if len > 4 (meaning there are actually xattrs; the first 4 + * bytes are the xattr count). + */ + if (iinfo->xattr_len > 4) { + xattr_blob = ceph_buffer_new_alloc(iinfo->xattr_len, GFP_NOFS); + if (!xattr_blob) + pr_err("fill_inode ENOMEM xattr blob %d bytes\n", + iinfo->xattr_len); + } + + spin_lock(&inode->i_lock); + + /* + * provided version will be odd if inode value is projected, + * even if stable. skip the update if we have a newer info + * (e.g., due to inode info racing form multiple MDSs), or if + * we are getting projected (unstable) inode info. + */ + if (le64_to_cpu(info->version) > 0 && + (ci->i_version & ~1) > le64_to_cpu(info->version)) + goto no_change; + + issued = __ceph_caps_issued(ci, &implemented); + issued |= implemented | __ceph_caps_dirty(ci); + + /* update inode */ + ci->i_version = le64_to_cpu(info->version); + inode->i_version++; + inode->i_rdev = le32_to_cpu(info->rdev); + + if ((issued & CEPH_CAP_AUTH_EXCL) == 0) { + inode->i_mode = le32_to_cpu(info->mode); + inode->i_uid = le32_to_cpu(info->uid); + inode->i_gid = le32_to_cpu(info->gid); + dout("%p mode 0%o uid.gid %d.%d\n", inode, inode->i_mode, + inode->i_uid, inode->i_gid); + } + + if ((issued & CEPH_CAP_LINK_EXCL) == 0) + inode->i_nlink = le32_to_cpu(info->nlink); + + /* be careful with mtime, atime, size */ + ceph_decode_timespec(&atime, &info->atime); + ceph_decode_timespec(&mtime, &info->mtime); + ceph_decode_timespec(&ctime, &info->ctime); + queue_trunc = ceph_fill_file_size(inode, issued, + le32_to_cpu(info->truncate_seq), + le64_to_cpu(info->truncate_size), + S_ISDIR(inode->i_mode) ? + ci->i_rbytes : + le64_to_cpu(info->size)); + ceph_fill_file_time(inode, issued, + le32_to_cpu(info->time_warp_seq), + &ctime, &mtime, &atime); + + ci->i_max_size = le64_to_cpu(info->max_size); + ci->i_layout = info->layout; + inode->i_blkbits = fls(le32_to_cpu(info->layout.fl_stripe_unit)) - 1; + + /* xattrs */ + /* note that if i_xattrs.len <= 4, i_xattrs.data will still be NULL. */ + if ((issued & CEPH_CAP_XATTR_EXCL) == 0 && + le64_to_cpu(info->xattr_version) > ci->i_xattrs.version) { + if (ci->i_xattrs.blob) + ceph_buffer_put(ci->i_xattrs.blob); + ci->i_xattrs.blob = xattr_blob; + if (xattr_blob) + memcpy(ci->i_xattrs.blob->vec.iov_base, + iinfo->xattr_data, iinfo->xattr_len); + ci->i_xattrs.version = le64_to_cpu(info->xattr_version); + } + + inode->i_mapping->a_ops = &ceph_aops; + inode->i_mapping->backing_dev_info = + &ceph_client(inode->i_sb)->backing_dev_info; + + switch (inode->i_mode & S_IFMT) { + case S_IFIFO: + case S_IFBLK: + case S_IFCHR: + case S_IFSOCK: + init_special_inode(inode, inode->i_mode, inode->i_rdev); + inode->i_op = &ceph_file_iops; + break; + case S_IFREG: + inode->i_op = &ceph_file_iops; + inode->i_fop = &ceph_file_fops; + break; + case S_IFLNK: + inode->i_op = &ceph_symlink_iops; + if (!ci->i_symlink) { + int symlen = iinfo->symlink_len; + char *sym; + + BUG_ON(symlen != inode->i_size); + spin_unlock(&inode->i_lock); + + err = -ENOMEM; + sym = kmalloc(symlen+1, GFP_NOFS); + if (!sym) + goto out; + memcpy(sym, iinfo->symlink, symlen); + sym[symlen] = 0; + + spin_lock(&inode->i_lock); + if (!ci->i_symlink) + ci->i_symlink = sym; + else + kfree(sym); /* lost a race */ + } + break; + case S_IFDIR: + inode->i_op = &ceph_dir_iops; + inode->i_fop = &ceph_dir_fops; + + ci->i_files = le64_to_cpu(info->files); + ci->i_subdirs = le64_to_cpu(info->subdirs); + ci->i_rbytes = le64_to_cpu(info->rbytes); + ci->i_rfiles = le64_to_cpu(info->rfiles); + ci->i_rsubdirs = le64_to_cpu(info->rsubdirs); + ceph_decode_timespec(&ci->i_rctime, &info->rctime); + + /* set dir completion flag? */ + if (ci->i_files == 0 && ci->i_subdirs == 0 && + ceph_snap(inode) == CEPH_NOSNAP && + (le32_to_cpu(info->cap.caps) & CEPH_CAP_FILE_SHARED)) { + dout(" marking %p complete (empty)\n", inode); + ci->i_ceph_flags |= CEPH_I_COMPLETE; + ci->i_max_offset = 2; + } + + /* it may be better to set st_size in getattr instead? */ + if (ceph_test_opt(ceph_client(inode->i_sb), RBYTES)) + inode->i_size = ci->i_rbytes; + break; + default: + pr_err("fill_inode %llx.%llx BAD mode 0%o\n", + ceph_vinop(inode), inode->i_mode); + } + +no_change: + spin_unlock(&inode->i_lock); + + /* queue truncate if we saw i_size decrease */ + if (queue_trunc) + if (queue_work(ceph_client(inode->i_sb)->trunc_wq, + &ci->i_vmtruncate_work)) + igrab(inode); + + /* populate frag tree */ + /* FIXME: move me up, if/when version reflects fragtree changes */ + nsplits = le32_to_cpu(info->fragtree.nsplits); + mutex_lock(&ci->i_fragtree_mutex); + for (i = 0; i < nsplits; i++) { + u32 id = le32_to_cpu(info->fragtree.splits[i].frag); + struct ceph_inode_frag *frag = __get_or_create_frag(ci, id); + + if (IS_ERR(frag)) + continue; + frag->split_by = le32_to_cpu(info->fragtree.splits[i].by); + dout(" frag %x split by %d\n", frag->frag, frag->split_by); + } + mutex_unlock(&ci->i_fragtree_mutex); + + /* were we issued a capability? */ + if (info->cap.caps) { + if (ceph_snap(inode) == CEPH_NOSNAP) { + ceph_add_cap(inode, session, + le64_to_cpu(info->cap.cap_id), + cap_fmode, + le32_to_cpu(info->cap.caps), + le32_to_cpu(info->cap.wanted), + le32_to_cpu(info->cap.seq), + le32_to_cpu(info->cap.mseq), + le64_to_cpu(info->cap.realm), + info->cap.flags, + caps_reservation); + } else { + spin_lock(&inode->i_lock); + dout(" %p got snap_caps %s\n", inode, + ceph_cap_string(le32_to_cpu(info->cap.caps))); + ci->i_snap_caps |= le32_to_cpu(info->cap.caps); + if (cap_fmode >= 0) + __ceph_get_fmode(ci, cap_fmode); + spin_unlock(&inode->i_lock); + } + } + + /* update delegation info? */ + if (dirinfo) + ceph_fill_dirfrag(inode, dirinfo); + + err = 0; + +out: + ceph_buffer_put(xattr_blob); + return err; +} + +/* + * caller should hold session s_mutex. + */ +static void update_dentry_lease(struct dentry *dentry, + struct ceph_mds_reply_lease *lease, + struct ceph_mds_session *session, + unsigned long from_time) +{ + struct ceph_dentry_info *di = ceph_dentry(dentry); + long unsigned duration = le32_to_cpu(lease->duration_ms); + long unsigned ttl = from_time + (duration * HZ) / 1000; + long unsigned half_ttl = from_time + (duration * HZ / 2) / 1000; + struct inode *dir; + + /* only track leases on regular dentries */ + if (dentry->d_op != &ceph_dentry_ops) + return; + + spin_lock(&dentry->d_lock); + dout("update_dentry_lease %p mask %d duration %lu ms ttl %lu\n", + dentry, le16_to_cpu(lease->mask), duration, ttl); + + /* make lease_rdcache_gen match directory */ + dir = dentry->d_parent->d_inode; + di->lease_shared_gen = ceph_inode(dir)->i_shared_gen; + + if (lease->mask == 0) + goto out_unlock; + + if (di->lease_gen == session->s_cap_gen && + time_before(ttl, dentry->d_time)) + goto out_unlock; /* we already have a newer lease. */ + + if (di->lease_session && di->lease_session != session) + goto out_unlock; + + ceph_dentry_lru_touch(dentry); + + if (!di->lease_session) + di->lease_session = ceph_get_mds_session(session); + di->lease_gen = session->s_cap_gen; + di->lease_seq = le32_to_cpu(lease->seq); + di->lease_renew_after = half_ttl; + di->lease_renew_from = 0; + dentry->d_time = ttl; +out_unlock: + spin_unlock(&dentry->d_lock); + return; +} + +/* + * splice a dentry to an inode. + * caller must hold directory i_mutex for this to be safe. + * + * we will only rehash the resulting dentry if @prehash is + * true; @prehash will be set to false (for the benefit of + * the caller) if we fail. + */ +static struct dentry *splice_dentry(struct dentry *dn, struct inode *in, + bool *prehash) +{ + struct dentry *realdn; + + /* dn must be unhashed */ + if (!d_unhashed(dn)) + d_drop(dn); + realdn = d_materialise_unique(dn, in); + if (IS_ERR(realdn)) { + pr_err("splice_dentry error %p inode %p ino %llx.%llx\n", + dn, in, ceph_vinop(in)); + if (prehash) + *prehash = false; /* don't rehash on error */ + dn = realdn; /* note realdn contains the error */ + goto out; + } else if (realdn) { + dout("dn %p (%d) spliced with %p (%d) " + "inode %p ino %llx.%llx\n", + dn, atomic_read(&dn->d_count), + realdn, atomic_read(&realdn->d_count), + realdn->d_inode, ceph_vinop(realdn->d_inode)); + dput(dn); + dn = realdn; + } else { + BUG_ON(!ceph_dentry(dn)); + + dout("dn %p attached to %p ino %llx.%llx\n", + dn, dn->d_inode, ceph_vinop(dn->d_inode)); + } + if ((!prehash || *prehash) && d_unhashed(dn)) + d_rehash(dn); +out: + return dn; +} + +/* + * Incorporate results into the local cache. This is either just + * one inode, or a directory, dentry, and possibly linked-to inode (e.g., + * after a lookup). + * + * A reply may contain + * a directory inode along with a dentry. + * and/or a target inode + * + * Called with snap_rwsem (read). + */ +int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req, + struct ceph_mds_session *session) +{ + struct ceph_mds_reply_info_parsed *rinfo = &req->r_reply_info; + struct inode *in = NULL; + struct ceph_mds_reply_inode *ininfo; + struct ceph_vino vino; + int i = 0; + int err = 0; + + dout("fill_trace %p is_dentry %d is_target %d\n", req, + rinfo->head->is_dentry, rinfo->head->is_target); + +#if 0 + /* + * Debugging hook: + * + * If we resend completed ops to a recovering mds, we get no + * trace. Since that is very rare, pretend this is the case + * to ensure the 'no trace' handlers in the callers behave. + * + * Fill in inodes unconditionally to avoid breaking cap + * invariants. + */ + if (rinfo->head->op & CEPH_MDS_OP_WRITE) { + pr_info("fill_trace faking empty trace on %lld %s\n", + req->r_tid, ceph_mds_op_name(rinfo->head->op)); + if (rinfo->head->is_dentry) { + rinfo->head->is_dentry = 0; + err = fill_inode(req->r_locked_dir, + &rinfo->diri, rinfo->dirfrag, + session, req->r_request_started, -1); + } + if (rinfo->head->is_target) { + rinfo->head->is_target = 0; + ininfo = rinfo->targeti.in; + vino.ino = le64_to_cpu(ininfo->ino); + vino.snap = le64_to_cpu(ininfo->snapid); + in = ceph_get_inode(sb, vino); + err = fill_inode(in, &rinfo->targeti, NULL, + session, req->r_request_started, + req->r_fmode); + iput(in); + } + } +#endif + + if (!rinfo->head->is_target && !rinfo->head->is_dentry) { + dout("fill_trace reply is empty!\n"); + if (rinfo->head->result == 0 && req->r_locked_dir) { + struct ceph_inode_info *ci = + ceph_inode(req->r_locked_dir); + dout(" clearing %p complete (empty trace)\n", + req->r_locked_dir); + ci->i_ceph_flags &= ~CEPH_I_COMPLETE; + ci->i_release_count++; + } + return 0; + } + + if (rinfo->head->is_dentry) { + /* + * lookup link rename : null -> possibly existing inode + * mknod symlink mkdir : null -> new inode + * unlink : linked -> null + */ + struct inode *dir = req->r_locked_dir; + struct dentry *dn = req->r_dentry; + bool have_dir_cap, have_lease; + + BUG_ON(!dn); + BUG_ON(!dir); + BUG_ON(dn->d_parent->d_inode != dir); + BUG_ON(ceph_ino(dir) != + le64_to_cpu(rinfo->diri.in->ino)); + BUG_ON(ceph_snap(dir) != + le64_to_cpu(rinfo->diri.in->snapid)); + + err = fill_inode(dir, &rinfo->diri, rinfo->dirfrag, + session, req->r_request_started, -1, + &req->r_caps_reservation); + if (err < 0) + return err; + + /* do we have a lease on the whole dir? */ + have_dir_cap = + (le32_to_cpu(rinfo->diri.in->cap.caps) & + CEPH_CAP_FILE_SHARED); + + /* do we have a dn lease? */ + have_lease = have_dir_cap || + (le16_to_cpu(rinfo->dlease->mask) & + CEPH_LOCK_DN); + + if (!have_lease) + dout("fill_trace no dentry lease or dir cap\n"); + + /* rename? */ + if (req->r_old_dentry && req->r_op == CEPH_MDS_OP_RENAME) { + dout(" src %p '%.*s' dst %p '%.*s'\n", + req->r_old_dentry, + req->r_old_dentry->d_name.len, + req->r_old_dentry->d_name.name, + dn, dn->d_name.len, dn->d_name.name); + dout("fill_trace doing d_move %p -> %p\n", + req->r_old_dentry, dn); + d_move(req->r_old_dentry, dn); + dout(" src %p '%.*s' dst %p '%.*s'\n", + req->r_old_dentry, + req->r_old_dentry->d_name.len, + req->r_old_dentry->d_name.name, + dn, dn->d_name.len, dn->d_name.name); + /* take overwritten dentry's readdir offset */ + ceph_dentry(req->r_old_dentry)->offset = + ceph_dentry(dn)->offset; + dn = req->r_old_dentry; /* use old_dentry */ + in = dn->d_inode; + } + + /* null dentry? */ + if (!rinfo->head->is_target) { + dout("fill_trace null dentry\n"); + if (dn->d_inode) { + dout("d_delete %p\n", dn); + d_delete(dn); + } else { + dout("d_instantiate %p NULL\n", dn); + d_instantiate(dn, NULL); + if (have_lease && d_unhashed(dn)) + d_rehash(dn); + update_dentry_lease(dn, rinfo->dlease, + session, + req->r_request_started); + } + goto done; + } + + /* attach proper inode */ + ininfo = rinfo->targeti.in; + vino.ino = le64_to_cpu(ininfo->ino); + vino.snap = le64_to_cpu(ininfo->snapid); + if (!dn->d_inode) { + in = ceph_get_inode(sb, vino); + if (IS_ERR(in)) { + pr_err("fill_trace bad get_inode " + "%llx.%llx\n", vino.ino, vino.snap); + err = PTR_ERR(in); + d_delete(dn); + goto done; + } + dn = splice_dentry(dn, in, &have_lease); + if (IS_ERR(dn)) { + err = PTR_ERR(dn); + goto done; + } + req->r_dentry = dn; /* may have spliced */ + igrab(in); + } else if (ceph_ino(in) == vino.ino && + ceph_snap(in) == vino.snap) { + igrab(in); + } else { + dout(" %p links to %p %llx.%llx, not %llx.%llx\n", + dn, in, ceph_ino(in), ceph_snap(in), + vino.ino, vino.snap); + have_lease = false; + in = NULL; + } + + if (have_lease) + update_dentry_lease(dn, rinfo->dlease, session, + req->r_request_started); + dout(" final dn %p\n", dn); + i++; + } else if (req->r_op == CEPH_MDS_OP_LOOKUPSNAP || + req->r_op == CEPH_MDS_OP_MKSNAP) { + struct dentry *dn = req->r_dentry; + + /* fill out a snapdir LOOKUPSNAP dentry */ + BUG_ON(!dn); + BUG_ON(!req->r_locked_dir); + BUG_ON(ceph_snap(req->r_locked_dir) != CEPH_SNAPDIR); + ininfo = rinfo->targeti.in; + vino.ino = le64_to_cpu(ininfo->ino); + vino.snap = le64_to_cpu(ininfo->snapid); + in = ceph_get_inode(sb, vino); + if (IS_ERR(in)) { + pr_err("fill_inode get_inode badness %llx.%llx\n", + vino.ino, vino.snap); + err = PTR_ERR(in); + d_delete(dn); + goto done; + } + dout(" linking snapped dir %p to dn %p\n", in, dn); + dn = splice_dentry(dn, in, NULL); + if (IS_ERR(dn)) { + err = PTR_ERR(dn); + goto done; + } + req->r_dentry = dn; /* may have spliced */ + igrab(in); + rinfo->head->is_dentry = 1; /* fool notrace handlers */ + } + + if (rinfo->head->is_target) { + vino.ino = le64_to_cpu(rinfo->targeti.in->ino); + vino.snap = le64_to_cpu(rinfo->targeti.in->snapid); + + if (in == NULL || ceph_ino(in) != vino.ino || + ceph_snap(in) != vino.snap) { + in = ceph_get_inode(sb, vino); + if (IS_ERR(in)) { + err = PTR_ERR(in); + goto done; + } + } + req->r_target_inode = in; + + err = fill_inode(in, + &rinfo->targeti, NULL, + session, req->r_request_started, + (le32_to_cpu(rinfo->head->result) == 0) ? + req->r_fmode : -1, + &req->r_caps_reservation); + if (err < 0) { + pr_err("fill_inode badness %p %llx.%llx\n", + in, ceph_vinop(in)); + goto done; + } + } + +done: + dout("fill_trace done err=%d\n", err); + return err; +} + +/* + * Prepopulate our cache with readdir results, leases, etc. + */ +int ceph_readdir_prepopulate(struct ceph_mds_request *req, + struct ceph_mds_session *session) +{ + struct dentry *parent = req->r_dentry; + struct ceph_mds_reply_info_parsed *rinfo = &req->r_reply_info; + struct qstr dname; + struct dentry *dn; + struct inode *in; + int err = 0, i; + struct inode *snapdir = NULL; + struct ceph_mds_request_head *rhead = req->r_request->front.iov_base; + u64 frag = le32_to_cpu(rhead->args.readdir.frag); + struct ceph_dentry_info *di; + + if (le32_to_cpu(rinfo->head->op) == CEPH_MDS_OP_LSSNAP) { + snapdir = ceph_get_snapdir(parent->d_inode); + parent = d_find_alias(snapdir); + dout("readdir_prepopulate %d items under SNAPDIR dn %p\n", + rinfo->dir_nr, parent); + } else { + dout("readdir_prepopulate %d items under dn %p\n", + rinfo->dir_nr, parent); + if (rinfo->dir_dir) + ceph_fill_dirfrag(parent->d_inode, rinfo->dir_dir); + } + + for (i = 0; i < rinfo->dir_nr; i++) { + struct ceph_vino vino; + + dname.name = rinfo->dir_dname[i]; + dname.len = rinfo->dir_dname_len[i]; + dname.hash = full_name_hash(dname.name, dname.len); + + vino.ino = le64_to_cpu(rinfo->dir_in[i].in->ino); + vino.snap = le64_to_cpu(rinfo->dir_in[i].in->snapid); + +retry_lookup: + dn = d_lookup(parent, &dname); + dout("d_lookup on parent=%p name=%.*s got %p\n", + parent, dname.len, dname.name, dn); + + if (!dn) { + dn = d_alloc(parent, &dname); + dout("d_alloc %p '%.*s' = %p\n", parent, + dname.len, dname.name, dn); + if (dn == NULL) { + dout("d_alloc badness\n"); + err = -ENOMEM; + goto out; + } + err = ceph_init_dentry(dn); + if (err < 0) + goto out; + } else if (dn->d_inode && + (ceph_ino(dn->d_inode) != vino.ino || + ceph_snap(dn->d_inode) != vino.snap)) { + dout(" dn %p points to wrong inode %p\n", + dn, dn->d_inode); + d_delete(dn); + dput(dn); + goto retry_lookup; + } else { + /* reorder parent's d_subdirs */ + spin_lock(&dcache_lock); + spin_lock(&dn->d_lock); + list_move(&dn->d_u.d_child, &parent->d_subdirs); + spin_unlock(&dn->d_lock); + spin_unlock(&dcache_lock); + } + + di = dn->d_fsdata; + di->offset = ceph_make_fpos(frag, i + req->r_readdir_offset); + + /* inode */ + if (dn->d_inode) { + in = dn->d_inode; + } else { + in = ceph_get_inode(parent->d_sb, vino); + if (in == NULL) { + dout("new_inode badness\n"); + d_delete(dn); + dput(dn); + err = -ENOMEM; + goto out; + } + dn = splice_dentry(dn, in, NULL); + } + + if (fill_inode(in, &rinfo->dir_in[i], NULL, session, + req->r_request_started, -1, + &req->r_caps_reservation) < 0) { + pr_err("fill_inode badness on %p\n", in); + dput(dn); + continue; + } + update_dentry_lease(dn, rinfo->dir_dlease[i], + req->r_session, req->r_request_started); + dput(dn); + } + req->r_did_prepopulate = true; + +out: + if (snapdir) { + iput(snapdir); + dput(parent); + } + dout("readdir_prepopulate done\n"); + return err; +} + +int ceph_inode_set_size(struct inode *inode, loff_t size) +{ + struct ceph_inode_info *ci = ceph_inode(inode); + int ret = 0; + + spin_lock(&inode->i_lock); + dout("set_size %p %llu -> %llu\n", inode, inode->i_size, size); + inode->i_size = size; + inode->i_blocks = (size + (1 << 9) - 1) >> 9; + + /* tell the MDS if we are approaching max_size */ + if ((size << 1) >= ci->i_max_size && + (ci->i_reported_size << 1) < ci->i_max_size) + ret = 1; + + spin_unlock(&inode->i_lock); + return ret; +} + +/* + * Write back inode data in a worker thread. (This can't be done + * in the message handler context.) + */ +void ceph_inode_writeback(struct work_struct *work) +{ + struct ceph_inode_info *ci = container_of(work, struct ceph_inode_info, + i_wb_work); + struct inode *inode = &ci->vfs_inode; + + dout("writeback %p\n", inode); + filemap_fdatawrite(&inode->i_data); + iput(inode); +} + +/* + * Invalidate inode pages in a worker thread. (This can't be done + * in the message handler context.) + */ +static void ceph_inode_invalidate_pages(struct work_struct *work) +{ + struct ceph_inode_info *ci = container_of(work, struct ceph_inode_info, + i_pg_inv_work); + struct inode *inode = &ci->vfs_inode; + u32 orig_gen; + int check = 0; + + spin_lock(&inode->i_lock); + dout("invalidate_pages %p gen %d revoking %d\n", inode, + ci->i_rdcache_gen, ci->i_rdcache_revoking); + if (ci->i_rdcache_gen == 0 || + ci->i_rdcache_revoking != ci->i_rdcache_gen) { + BUG_ON(ci->i_rdcache_revoking > ci->i_rdcache_gen); + /* nevermind! */ + ci->i_rdcache_revoking = 0; + spin_unlock(&inode->i_lock); + goto out; + } + orig_gen = ci->i_rdcache_gen; + spin_unlock(&inode->i_lock); + + truncate_inode_pages(&inode->i_data, 0); + + spin_lock(&inode->i_lock); + if (orig_gen == ci->i_rdcache_gen) { + dout("invalidate_pages %p gen %d successful\n", inode, + ci->i_rdcache_gen); + ci->i_rdcache_gen = 0; + ci->i_rdcache_revoking = 0; + check = 1; + } else { + dout("invalidate_pages %p gen %d raced, gen now %d\n", + inode, orig_gen, ci->i_rdcache_gen); + } + spin_unlock(&inode->i_lock); + + if (check) + ceph_check_caps(ci, 0, NULL); +out: + iput(inode); +} + + +/* + * called by trunc_wq; take i_mutex ourselves + * + * We also truncate in a separate thread as well. + */ +void ceph_vmtruncate_work(struct work_struct *work) +{ + struct ceph_inode_info *ci = container_of(work, struct ceph_inode_info, + i_vmtruncate_work); + struct inode *inode = &ci->vfs_inode; + + dout("vmtruncate_work %p\n", inode); + mutex_lock(&inode->i_mutex); + __ceph_do_pending_vmtruncate(inode); + mutex_unlock(&inode->i_mutex); + iput(inode); +} + +/* + * called with i_mutex held. + * + * Make sure any pending truncation is applied before doing anything + * that may depend on it. + */ +void __ceph_do_pending_vmtruncate(struct inode *inode) +{ + struct ceph_inode_info *ci = ceph_inode(inode); + u64 to; + int wrbuffer_refs, wake = 0; + +retry: + spin_lock(&inode->i_lock); + if (ci->i_truncate_pending == 0) { + dout("__do_pending_vmtruncate %p none pending\n", inode); + spin_unlock(&inode->i_lock); + return; + } + + /* + * make sure any dirty snapped pages are flushed before we + * possibly truncate them.. so write AND block! + */ + if (ci->i_wrbuffer_ref_head < ci->i_wrbuffer_ref) { + dout("__do_pending_vmtruncate %p flushing snaps first\n", + inode); + spin_unlock(&inode->i_lock); + filemap_write_and_wait_range(&inode->i_data, 0, + inode->i_sb->s_maxbytes); + goto retry; + } + + to = ci->i_truncate_size; + wrbuffer_refs = ci->i_wrbuffer_ref; + dout("__do_pending_vmtruncate %p (%d) to %lld\n", inode, + ci->i_truncate_pending, to); + spin_unlock(&inode->i_lock); + + truncate_inode_pages(inode->i_mapping, to); + + spin_lock(&inode->i_lock); + ci->i_truncate_pending--; + if (ci->i_truncate_pending == 0) + wake = 1; + spin_unlock(&inode->i_lock); + + if (wrbuffer_refs == 0) + ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL); + if (wake) + wake_up(&ci->i_cap_wq); +} + + +/* + * symlinks + */ +static void *ceph_sym_follow_link(struct dentry *dentry, struct nameidata *nd) +{ + struct ceph_inode_info *ci = ceph_inode(dentry->d_inode); + nd_set_link(nd, ci->i_symlink); + return NULL; +} + +static const struct inode_operations ceph_symlink_iops = { + .readlink = generic_readlink, + .follow_link = ceph_sym_follow_link, +}; + +/* + * setattr + */ +int ceph_setattr(struct dentry *dentry, struct iattr *attr) +{ + struct inode *inode = dentry->d_inode; + struct ceph_inode_info *ci = ceph_inode(inode); + struct inode *parent_inode = dentry->d_parent->d_inode; + const unsigned int ia_valid = attr->ia_valid; + struct ceph_mds_request *req; + struct ceph_mds_client *mdsc = &ceph_client(dentry->d_sb)->mdsc; + int issued; + int release = 0, dirtied = 0; + int mask = 0; + int err = 0; + int queue_trunc = 0; + + if (ceph_snap(inode) != CEPH_NOSNAP) + return -EROFS; + + __ceph_do_pending_vmtruncate(inode); + + err = inode_change_ok(inode, attr); + if (err != 0) + return err; + + req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SETATTR, + USE_AUTH_MDS); + if (IS_ERR(req)) + return PTR_ERR(req); + + spin_lock(&inode->i_lock); + issued = __ceph_caps_issued(ci, NULL); + dout("setattr %p issued %s\n", inode, ceph_cap_string(issued)); + + if (ia_valid & ATTR_UID) { + dout("setattr %p uid %d -> %d\n", inode, + inode->i_uid, attr->ia_uid); + if (issued & CEPH_CAP_AUTH_EXCL) { + inode->i_uid = attr->ia_uid; + dirtied |= CEPH_CAP_AUTH_EXCL; + } else if ((issued & CEPH_CAP_AUTH_SHARED) == 0 || + attr->ia_uid != inode->i_uid) { + req->r_args.setattr.uid = cpu_to_le32(attr->ia_uid); + mask |= CEPH_SETATTR_UID; + release |= CEPH_CAP_AUTH_SHARED; + } + } + if (ia_valid & ATTR_GID) { + dout("setattr %p gid %d -> %d\n", inode, + inode->i_gid, attr->ia_gid); + if (issued & CEPH_CAP_AUTH_EXCL) { + inode->i_gid = attr->ia_gid; + dirtied |= CEPH_CAP_AUTH_EXCL; + } else if ((issued & CEPH_CAP_AUTH_SHARED) == 0 || + attr->ia_gid != inode->i_gid) { + req->r_args.setattr.gid = cpu_to_le32(attr->ia_gid); + mask |= CEPH_SETATTR_GID; + release |= CEPH_CAP_AUTH_SHARED; + } + } + if (ia_valid & ATTR_MODE) { + dout("setattr %p mode 0%o -> 0%o\n", inode, inode->i_mode, + attr->ia_mode); + if (issued & CEPH_CAP_AUTH_EXCL) { + inode->i_mode = attr->ia_mode; + dirtied |= CEPH_CAP_AUTH_EXCL; + } else if ((issued & CEPH_CAP_AUTH_SHARED) == 0 || + attr->ia_mode != inode->i_mode) { + req->r_args.setattr.mode = cpu_to_le32(attr->ia_mode); + mask |= CEPH_SETATTR_MODE; + release |= CEPH_CAP_AUTH_SHARED; + } + } + + if (ia_valid & ATTR_ATIME) { + dout("setattr %p atime %ld.%ld -> %ld.%ld\n", inode, + inode->i_atime.tv_sec, inode->i_atime.tv_nsec, + attr->ia_atime.tv_sec, attr->ia_atime.tv_nsec); + if (issued & CEPH_CAP_FILE_EXCL) { + ci->i_time_warp_seq++; + inode->i_atime = attr->ia_atime; + dirtied |= CEPH_CAP_FILE_EXCL; + } else if ((issued & CEPH_CAP_FILE_WR) && + timespec_compare(&inode->i_atime, + &attr->ia_atime) < 0) { + inode->i_atime = attr->ia_atime; + dirtied |= CEPH_CAP_FILE_WR; + } else if ((issued & CEPH_CAP_FILE_SHARED) == 0 || + !timespec_equal(&inode->i_atime, &attr->ia_atime)) { + ceph_encode_timespec(&req->r_args.setattr.atime, + &attr->ia_atime); + mask |= CEPH_SETATTR_ATIME; + release |= CEPH_CAP_FILE_CACHE | CEPH_CAP_FILE_RD | + CEPH_CAP_FILE_WR; + } + } + if (ia_valid & ATTR_MTIME) { + dout("setattr %p mtime %ld.%ld -> %ld.%ld\n", inode, + inode->i_mtime.tv_sec, inode->i_mtime.tv_nsec, + attr->ia_mtime.tv_sec, attr->ia_mtime.tv_nsec); + if (issued & CEPH_CAP_FILE_EXCL) { + ci->i_time_warp_seq++; + inode->i_mtime = attr->ia_mtime; + dirtied |= CEPH_CAP_FILE_EXCL; + } else if ((issued & CEPH_CAP_FILE_WR) && + timespec_compare(&inode->i_mtime, + &attr->ia_mtime) < 0) { + inode->i_mtime = attr->ia_mtime; + dirtied |= CEPH_CAP_FILE_WR; + } else if ((issued & CEPH_CAP_FILE_SHARED) == 0 || + !timespec_equal(&inode->i_mtime, &attr->ia_mtime)) { + ceph_encode_timespec(&req->r_args.setattr.mtime, + &attr->ia_mtime); + mask |= CEPH_SETATTR_MTIME; + release |= CEPH_CAP_FILE_SHARED | CEPH_CAP_FILE_RD | + CEPH_CAP_FILE_WR; + } + } + if (ia_valid & ATTR_SIZE) { + dout("setattr %p size %lld -> %lld\n", inode, + inode->i_size, attr->ia_size); + if (attr->ia_size > inode->i_sb->s_maxbytes) { + err = -EINVAL; + goto out; + } + if ((issued & CEPH_CAP_FILE_EXCL) && + attr->ia_size > inode->i_size) { + inode->i_size = attr->ia_size; + if (attr->ia_size < inode->i_size) { + ci->i_truncate_size = attr->ia_size; + ci->i_truncate_pending++; + queue_trunc = 1; + } + inode->i_blocks = + (attr->ia_size + (1 << 9) - 1) >> 9; + inode->i_ctime = attr->ia_ctime; + ci->i_reported_size = attr->ia_size; + dirtied |= CEPH_CAP_FILE_EXCL; + } else if ((issued & CEPH_CAP_FILE_SHARED) == 0 || + attr->ia_size != inode->i_size) { + req->r_args.setattr.size = cpu_to_le64(attr->ia_size); + req->r_args.setattr.old_size = + cpu_to_le64(inode->i_size); + mask |= CEPH_SETATTR_SIZE; + release |= CEPH_CAP_FILE_SHARED | CEPH_CAP_FILE_RD | + CEPH_CAP_FILE_WR; + } + } + + /* these do nothing */ + if (ia_valid & ATTR_CTIME) { + bool only = (ia_valid & (ATTR_SIZE|ATTR_MTIME|ATTR_ATIME| + ATTR_MODE|ATTR_UID|ATTR_GID)) == 0; + dout("setattr %p ctime %ld.%ld -> %ld.%ld (%s)\n", inode, + inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec, + attr->ia_ctime.tv_sec, attr->ia_ctime.tv_nsec, + only ? "ctime only" : "ignored"); + inode->i_ctime = attr->ia_ctime; + if (only) { + /* + * if kernel wants to dirty ctime but nothing else, + * we need to choose a cap to dirty under, or do + * a almost-no-op setattr + */ + if (issued & CEPH_CAP_AUTH_EXCL) + dirtied |= CEPH_CAP_AUTH_EXCL; + else if (issued & CEPH_CAP_FILE_EXCL) + dirtied |= CEPH_CAP_FILE_EXCL; + else if (issued & CEPH_CAP_XATTR_EXCL) + dirtied |= CEPH_CAP_XATTR_EXCL; + else + mask |= CEPH_SETATTR_CTIME; + } + } + if (ia_valid & ATTR_FILE) + dout("setattr %p ATTR_FILE ... hrm!\n", inode); + + if (dirtied) { + __ceph_mark_dirty_caps(ci, dirtied); + inode->i_ctime = CURRENT_TIME; + } + + release &= issued; + spin_unlock(&inode->i_lock); + + if (queue_trunc) + __ceph_do_pending_vmtruncate(inode); + + if (mask) { + req->r_inode = igrab(inode); + req->r_inode_drop = release; + req->r_args.setattr.mask = cpu_to_le32(mask); + req->r_num_caps = 1; + err = ceph_mdsc_do_request(mdsc, parent_inode, req); + } + dout("setattr %p result=%d (%s locally, %d remote)\n", inode, err, + ceph_cap_string(dirtied), mask); + + ceph_mdsc_put_request(req); + __ceph_do_pending_vmtruncate(inode); + return err; +out: + spin_unlock(&inode->i_lock); + ceph_mdsc_put_request(req); + return err; +} + +/* + * Verify that we have a lease on the given mask. If not, + * do a getattr against an mds. + */ +int ceph_do_getattr(struct inode *inode, int mask) +{ + struct ceph_client *client = ceph_sb_to_client(inode->i_sb); + struct ceph_mds_client *mdsc = &client->mdsc; + struct ceph_mds_request *req; + int err; + + if (ceph_snap(inode) == CEPH_SNAPDIR) { + dout("do_getattr inode %p SNAPDIR\n", inode); + return 0; + } + + dout("do_getattr inode %p mask %s\n", inode, ceph_cap_string(mask)); + if (ceph_caps_issued_mask(ceph_inode(inode), mask, 1)) + return 0; + + req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_GETATTR, USE_ANY_MDS); + if (IS_ERR(req)) + return PTR_ERR(req); + req->r_inode = igrab(inode); + req->r_num_caps = 1; + req->r_args.getattr.mask = cpu_to_le32(mask); + err = ceph_mdsc_do_request(mdsc, NULL, req); + ceph_mdsc_put_request(req); + dout("do_getattr result=%d\n", err); + return err; +} + + +/* + * Check inode permissions. We verify we have a valid value for + * the AUTH cap, then call the generic handler. + */ +int ceph_permission(struct inode *inode, int mask) +{ + int err = ceph_do_getattr(inode, CEPH_CAP_AUTH_SHARED); + + if (!err) + err = generic_permission(inode, mask, NULL); + return err; +} + +/* + * Get all attributes. Hopefully somedata we'll have a statlite() + * and can limit the fields we require to be accurate. + */ +int ceph_getattr(struct vfsmount *mnt, struct dentry *dentry, + struct kstat *stat) +{ + struct inode *inode = dentry->d_inode; + int err; + + err = ceph_do_getattr(inode, CEPH_STAT_CAP_INODE_ALL); + if (!err) { + generic_fillattr(inode, stat); + stat->ino = inode->i_ino; + if (ceph_snap(inode) != CEPH_NOSNAP) + stat->dev = ceph_snap(inode); + else + stat->dev = 0; + if (S_ISDIR(inode->i_mode)) + stat->blksize = 65536; + } + return err; +} diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c new file mode 100644 index 0000000..8eaac04 --- /dev/null +++ b/fs/ceph/xattr.c @@ -0,0 +1,833 @@ +#include "ceph_debug.h" +#include "super.h" +#include "decode.h" + +#include + +static bool ceph_is_valid_xattr(const char *name) +{ + return !strncmp(name, XATTR_SECURITY_PREFIX, + XATTR_SECURITY_PREFIX_LEN) || + !strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) || + !strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN); +} + +/* + * These define virtual xattrs exposing the recursive directory + * statistics and layout metadata. + */ +struct ceph_vxattr_cb { + bool readonly; + char *name; + size_t (*getxattr_cb)(struct ceph_inode_info *ci, char *val, + size_t size); +}; + +/* directories */ + +static size_t ceph_vxattrcb_entries(struct ceph_inode_info *ci, char *val, + size_t size) +{ + return snprintf(val, size, "%lld", ci->i_files + ci->i_subdirs); +} + +static size_t ceph_vxattrcb_files(struct ceph_inode_info *ci, char *val, + size_t size) +{ + return snprintf(val, size, "%lld", ci->i_files); +} + +static size_t ceph_vxattrcb_subdirs(struct ceph_inode_info *ci, char *val, + size_t size) +{ + return snprintf(val, size, "%lld", ci->i_subdirs); +} + +static size_t ceph_vxattrcb_rentries(struct ceph_inode_info *ci, char *val, + size_t size) +{ + return snprintf(val, size, "%lld", ci->i_rfiles + ci->i_rsubdirs); +} + +static size_t ceph_vxattrcb_rfiles(struct ceph_inode_info *ci, char *val, + size_t size) +{ + return snprintf(val, size, "%lld", ci->i_rfiles); +} + +static size_t ceph_vxattrcb_rsubdirs(struct ceph_inode_info *ci, char *val, + size_t size) +{ + return snprintf(val, size, "%lld", ci->i_rsubdirs); +} + +static size_t ceph_vxattrcb_rbytes(struct ceph_inode_info *ci, char *val, + size_t size) +{ + return snprintf(val, size, "%lld", ci->i_rbytes); +} + +static size_t ceph_vxattrcb_rctime(struct ceph_inode_info *ci, char *val, + size_t size) +{ + return snprintf(val, size, "%ld.%ld", (long)ci->i_rctime.tv_sec, + (long)ci->i_rctime.tv_nsec); +} + +static struct ceph_vxattr_cb ceph_dir_vxattrs[] = { + { true, "user.ceph.dir.entries", ceph_vxattrcb_entries}, + { true, "user.ceph.dir.files", ceph_vxattrcb_files}, + { true, "user.ceph.dir.subdirs", ceph_vxattrcb_subdirs}, + { true, "user.ceph.dir.rentries", ceph_vxattrcb_rentries}, + { true, "user.ceph.dir.rfiles", ceph_vxattrcb_rfiles}, + { true, "user.ceph.dir.rsubdirs", ceph_vxattrcb_rsubdirs}, + { true, "user.ceph.dir.rbytes", ceph_vxattrcb_rbytes}, + { true, "user.ceph.dir.rctime", ceph_vxattrcb_rctime}, + { true, NULL, NULL } +}; + +/* files */ + +static size_t ceph_vxattrcb_layout(struct ceph_inode_info *ci, char *val, + size_t size) +{ + return snprintf(val, size, + "chunk_bytes=%lld\nstripe_count=%lld\nobject_size=%lld\n", + (unsigned long long)ceph_file_layout_su(ci->i_layout), + (unsigned long long)ceph_file_layout_stripe_count(ci->i_layout), + (unsigned long long)ceph_file_layout_object_size(ci->i_layout)); +} + +static struct ceph_vxattr_cb ceph_file_vxattrs[] = { + { true, "user.ceph.layout", ceph_vxattrcb_layout}, + { NULL, NULL } +}; + +static struct ceph_vxattr_cb *ceph_inode_vxattrs(struct inode *inode) +{ + if (S_ISDIR(inode->i_mode)) + return ceph_dir_vxattrs; + else if (S_ISREG(inode->i_mode)) + return ceph_file_vxattrs; + return NULL; +} + +static struct ceph_vxattr_cb *ceph_match_vxattr(struct ceph_vxattr_cb *vxattr, + const char *name) +{ + do { + if (strcmp(vxattr->name, name) == 0) + return vxattr; + vxattr++; + } while (vxattr->name); + return NULL; +} + +static int __set_xattr(struct ceph_inode_info *ci, + const char *name, int name_len, + const char *val, int val_len, + int dirty, + int should_free_name, int should_free_val, + struct ceph_inode_xattr **newxattr) +{ + struct rb_node **p; + struct rb_node *parent = NULL; + struct ceph_inode_xattr *xattr = NULL; + int c; + int new = 0; + + p = &ci->i_xattrs.index.rb_node; + while (*p) { + parent = *p; + xattr = rb_entry(parent, struct ceph_inode_xattr, node); + c = strncmp(name, xattr->name, min(name_len, xattr->name_len)); + if (c < 0) + p = &(*p)->rb_left; + else if (c > 0) + p = &(*p)->rb_right; + else { + if (name_len == xattr->name_len) + break; + else if (name_len < xattr->name_len) + p = &(*p)->rb_left; + else + p = &(*p)->rb_right; + } + xattr = NULL; + } + + if (!xattr) { + new = 1; + xattr = *newxattr; + xattr->name = name; + xattr->name_len = name_len; + xattr->should_free_name = should_free_name; + + ci->i_xattrs.count++; + dout("__set_xattr count=%d\n", ci->i_xattrs.count); + } else { + kfree(*newxattr); + *newxattr = NULL; + if (xattr->should_free_val) + kfree((void *)xattr->val); + + if (should_free_name) { + kfree((void *)name); + name = xattr->name; + } + ci->i_xattrs.names_size -= xattr->name_len; + ci->i_xattrs.vals_size -= xattr->val_len; + } + if (!xattr) { + pr_err("__set_xattr ENOMEM on %p %llx.%llx xattr %s=%s\n", + &ci->vfs_inode, ceph_vinop(&ci->vfs_inode), name, + xattr->val); + return -ENOMEM; + } + ci->i_xattrs.names_size += name_len; + ci->i_xattrs.vals_size += val_len; + if (val) + xattr->val = val; + else + xattr->val = ""; + + xattr->val_len = val_len; + xattr->dirty = dirty; + xattr->should_free_val = (val && should_free_val); + + if (new) { + rb_link_node(&xattr->node, parent, p); + rb_insert_color(&xattr->node, &ci->i_xattrs.index); + dout("__set_xattr_val p=%p\n", p); + } + + dout("__set_xattr_val added %llx.%llx xattr %p %s=%.*s\n", + ceph_vinop(&ci->vfs_inode), xattr, name, val_len, val); + + return 0; +} + +static struct ceph_inode_xattr *__get_xattr(struct ceph_inode_info *ci, + const char *name) +{ + struct rb_node **p; + struct rb_node *parent = NULL; + struct ceph_inode_xattr *xattr = NULL; + int c; + + p = &ci->i_xattrs.index.rb_node; + while (*p) { + parent = *p; + xattr = rb_entry(parent, struct ceph_inode_xattr, node); + c = strncmp(name, xattr->name, xattr->name_len); + if (c < 0) + p = &(*p)->rb_left; + else if (c > 0) + p = &(*p)->rb_right; + else { + dout("__get_xattr %s: found %.*s\n", name, + xattr->val_len, xattr->val); + return xattr; + } + } + + dout("__get_xattr %s: not found\n", name); + + return NULL; +} + +static void __free_xattr(struct ceph_inode_xattr *xattr) +{ + BUG_ON(!xattr); + + if (xattr->should_free_name) + kfree((void *)xattr->name); + if (xattr->should_free_val) + kfree((void *)xattr->val); + + kfree(xattr); +} + +static int __remove_xattr(struct ceph_inode_info *ci, + struct ceph_inode_xattr *xattr) +{ + if (!xattr) + return -EOPNOTSUPP; + + rb_erase(&xattr->node, &ci->i_xattrs.index); + + if (xattr->should_free_name) + kfree((void *)xattr->name); + if (xattr->should_free_val) + kfree((void *)xattr->val); + + ci->i_xattrs.names_size -= xattr->name_len; + ci->i_xattrs.vals_size -= xattr->val_len; + ci->i_xattrs.count--; + kfree(xattr); + + return 0; +} + +static int __remove_xattr_by_name(struct ceph_inode_info *ci, + const char *name) +{ + struct rb_node **p; + struct ceph_inode_xattr *xattr; + int err; + + p = &ci->i_xattrs.index.rb_node; + xattr = __get_xattr(ci, name); + err = __remove_xattr(ci, xattr); + return err; +} + +static char *__copy_xattr_names(struct ceph_inode_info *ci, + char *dest) +{ + struct rb_node *p; + struct ceph_inode_xattr *xattr = NULL; + + p = rb_first(&ci->i_xattrs.index); + dout("__copy_xattr_names count=%d\n", ci->i_xattrs.count); + + while (p) { + xattr = rb_entry(p, struct ceph_inode_xattr, node); + memcpy(dest, xattr->name, xattr->name_len); + dest[xattr->name_len] = '\0'; + + dout("dest=%s %p (%s) (%d/%d)\n", dest, xattr, xattr->name, + xattr->name_len, ci->i_xattrs.names_size); + + dest += xattr->name_len + 1; + p = rb_next(p); + } + + return dest; +} + +void __ceph_destroy_xattrs(struct ceph_inode_info *ci) +{ + struct rb_node *p, *tmp; + struct ceph_inode_xattr *xattr = NULL; + + p = rb_first(&ci->i_xattrs.index); + + dout("__ceph_destroy_xattrs p=%p\n", p); + + while (p) { + xattr = rb_entry(p, struct ceph_inode_xattr, node); + tmp = p; + p = rb_next(tmp); + dout("__ceph_destroy_xattrs next p=%p (%.*s)\n", p, + xattr->name_len, xattr->name); + rb_erase(tmp, &ci->i_xattrs.index); + + __free_xattr(xattr); + } + + ci->i_xattrs.names_size = 0; + ci->i_xattrs.vals_size = 0; + ci->i_xattrs.index_version = 0; + ci->i_xattrs.count = 0; + ci->i_xattrs.index = RB_ROOT; +} + +static int __build_xattrs(struct inode *inode) +{ + u32 namelen; + u32 numattr = 0; + void *p, *end; + u32 len; + const char *name, *val; + struct ceph_inode_info *ci = ceph_inode(inode); + int xattr_version; + struct ceph_inode_xattr **xattrs = NULL; + int err; + int i; + + dout("__build_xattrs() len=%d\n", + ci->i_xattrs.blob ? (int)ci->i_xattrs.blob->vec.iov_len : 0); + + if (ci->i_xattrs.index_version >= ci->i_xattrs.version) + return 0; /* already built */ + + __ceph_destroy_xattrs(ci); + +start: + /* updated internal xattr rb tree */ + if (ci->i_xattrs.blob && ci->i_xattrs.blob->vec.iov_len > 4) { + p = ci->i_xattrs.blob->vec.iov_base; + end = p + ci->i_xattrs.blob->vec.iov_len; + ceph_decode_32_safe(&p, end, numattr, bad); + xattr_version = ci->i_xattrs.version; + spin_unlock(&inode->i_lock); + + xattrs = kcalloc(numattr, sizeof(struct ceph_xattr *), + GFP_NOFS); + err = -ENOMEM; + if (!xattrs) + goto bad_lock; + memset(xattrs, 0, numattr*sizeof(struct ceph_xattr *)); + for (i = 0; i < numattr; i++) { + xattrs[i] = kmalloc(sizeof(struct ceph_inode_xattr), + GFP_NOFS); + if (!xattrs[i]) + goto bad_lock; + } + + spin_lock(&inode->i_lock); + if (ci->i_xattrs.version != xattr_version) { + /* lost a race, retry */ + for (i = 0; i < numattr; i++) + kfree(xattrs[i]); + kfree(xattrs); + goto start; + } + err = -EIO; + while (numattr--) { + ceph_decode_32_safe(&p, end, len, bad); + namelen = len; + name = p; + p += len; + ceph_decode_32_safe(&p, end, len, bad); + val = p; + p += len; + + err = __set_xattr(ci, name, namelen, val, len, + 0, 0, 0, &xattrs[numattr]); + + if (err < 0) + goto bad; + } + kfree(xattrs); + } + ci->i_xattrs.index_version = ci->i_xattrs.version; + ci->i_xattrs.dirty = false; + + return err; +bad_lock: + spin_lock(&inode->i_lock); +bad: + if (xattrs) { + for (i = 0; i < numattr; i++) + kfree(xattrs[i]); + kfree(xattrs); + } + ci->i_xattrs.names_size = 0; + return err; +} + +static int __get_required_blob_size(struct ceph_inode_info *ci, int name_size, + int val_size) +{ + /* + * 4 bytes for the length, and additional 4 bytes per each xattr name, + * 4 bytes per each value + */ + int size = 4 + ci->i_xattrs.count*(4 + 4) + + ci->i_xattrs.names_size + + ci->i_xattrs.vals_size; + dout("__get_required_blob_size c=%d names.size=%d vals.size=%d\n", + ci->i_xattrs.count, ci->i_xattrs.names_size, + ci->i_xattrs.vals_size); + + if (name_size) + size += 4 + 4 + name_size + val_size; + + return size; +} + +/* + * If there are dirty xattrs, reencode xattrs into the prealloc_blob + * and swap into place. + */ +void __ceph_build_xattrs_blob(struct ceph_inode_info *ci) +{ + struct rb_node *p; + struct ceph_inode_xattr *xattr = NULL; + void *dest; + + dout("__build_xattrs_blob %p\n", &ci->vfs_inode); + if (ci->i_xattrs.dirty) { + int need = __get_required_blob_size(ci, 0, 0); + + BUG_ON(need > ci->i_xattrs.prealloc_blob->alloc_len); + + p = rb_first(&ci->i_xattrs.index); + dest = ci->i_xattrs.prealloc_blob->vec.iov_base; + + ceph_encode_32(&dest, ci->i_xattrs.count); + while (p) { + xattr = rb_entry(p, struct ceph_inode_xattr, node); + + ceph_encode_32(&dest, xattr->name_len); + memcpy(dest, xattr->name, xattr->name_len); + dest += xattr->name_len; + ceph_encode_32(&dest, xattr->val_len); + memcpy(dest, xattr->val, xattr->val_len); + dest += xattr->val_len; + + p = rb_next(p); + } + + /* adjust buffer len; it may be larger than we need */ + ci->i_xattrs.prealloc_blob->vec.iov_len = + dest - ci->i_xattrs.prealloc_blob->vec.iov_base; + + ceph_buffer_put(ci->i_xattrs.blob); + ci->i_xattrs.blob = ci->i_xattrs.prealloc_blob; + ci->i_xattrs.prealloc_blob = NULL; + ci->i_xattrs.dirty = false; + } +} + +ssize_t ceph_getxattr(struct dentry *dentry, const char *name, void *value, + size_t size) +{ + struct inode *inode = dentry->d_inode; + struct ceph_inode_info *ci = ceph_inode(inode); + struct ceph_vxattr_cb *vxattrs = ceph_inode_vxattrs(inode); + int err; + struct ceph_inode_xattr *xattr; + struct ceph_vxattr_cb *vxattr = NULL; + + if (!ceph_is_valid_xattr(name)) + return -ENODATA; + + /* let's see if a virtual xattr was requested */ + if (vxattrs) + vxattr = ceph_match_vxattr(vxattrs, name); + + spin_lock(&inode->i_lock); + dout("getxattr %p ver=%lld index_ver=%lld\n", inode, + ci->i_xattrs.version, ci->i_xattrs.index_version); + + if (__ceph_caps_issued_mask(ci, CEPH_CAP_XATTR_SHARED, 1) && + (ci->i_xattrs.index_version >= ci->i_xattrs.version)) { + goto get_xattr; + } else { + spin_unlock(&inode->i_lock); + /* get xattrs from mds (if we don't already have them) */ + err = ceph_do_getattr(inode, CEPH_STAT_CAP_XATTR); + if (err) + return err; + } + + spin_lock(&inode->i_lock); + + if (vxattr && vxattr->readonly) { + err = vxattr->getxattr_cb(ci, value, size); + goto out; + } + + err = __build_xattrs(inode); + if (err < 0) + goto out; + +get_xattr: + err = -ENODATA; /* == ENOATTR */ + xattr = __get_xattr(ci, name); + if (!xattr) { + if (vxattr) + err = vxattr->getxattr_cb(ci, value, size); + goto out; + } + + err = -ERANGE; + if (size && size < xattr->val_len) + goto out; + + err = xattr->val_len; + if (size == 0) + goto out; + + memcpy(value, xattr->val, xattr->val_len); + +out: + spin_unlock(&inode->i_lock); + return err; +} + +ssize_t ceph_listxattr(struct dentry *dentry, char *names, size_t size) +{ + struct inode *inode = dentry->d_inode; + struct ceph_inode_info *ci = ceph_inode(inode); + struct ceph_vxattr_cb *vxattrs = ceph_inode_vxattrs(inode); + u32 vir_namelen = 0; + u32 namelen; + int err; + u32 len; + int i; + + spin_lock(&inode->i_lock); + dout("listxattr %p ver=%lld index_ver=%lld\n", inode, + ci->i_xattrs.version, ci->i_xattrs.index_version); + + if (__ceph_caps_issued_mask(ci, CEPH_CAP_XATTR_SHARED, 1) && + (ci->i_xattrs.index_version > ci->i_xattrs.version)) { + goto list_xattr; + } else { + spin_unlock(&inode->i_lock); + err = ceph_do_getattr(inode, CEPH_STAT_CAP_XATTR); + if (err) + return err; + } + + spin_lock(&inode->i_lock); + + err = __build_xattrs(inode); + if (err < 0) + goto out; + +list_xattr: + vir_namelen = 0; + /* include virtual dir xattrs */ + if (vxattrs) + for (i = 0; vxattrs[i].name; i++) + vir_namelen += strlen(vxattrs[i].name) + 1; + /* adding 1 byte per each variable due to the null termination */ + namelen = vir_namelen + ci->i_xattrs.names_size + ci->i_xattrs.count; + err = -ERANGE; + if (size && namelen > size) + goto out; + + err = namelen; + if (size == 0) + goto out; + + names = __copy_xattr_names(ci, names); + + /* virtual xattr names, too */ + if (vxattrs) + for (i = 0; vxattrs[i].name; i++) { + len = sprintf(names, "%s", vxattrs[i].name); + names += len + 1; + } + +out: + spin_unlock(&inode->i_lock); + return err; +} + +static int ceph_sync_setxattr(struct dentry *dentry, const char *name, + const char *value, size_t size, int flags) +{ + struct ceph_client *client = ceph_client(dentry->d_sb); + struct inode *inode = dentry->d_inode; + struct ceph_inode_info *ci = ceph_inode(inode); + struct inode *parent_inode = dentry->d_parent->d_inode; + struct ceph_mds_request *req; + struct ceph_mds_client *mdsc = &client->mdsc; + int err; + int i, nr_pages; + struct page **pages = NULL; + void *kaddr; + + /* copy value into some pages */ + nr_pages = calc_pages_for(0, size); + if (nr_pages) { + pages = kmalloc(sizeof(pages[0])*nr_pages, GFP_NOFS); + if (!pages) + return -ENOMEM; + err = -ENOMEM; + for (i = 0; i < nr_pages; i++) { + pages[i] = alloc_page(GFP_NOFS); + if (!pages[i]) { + nr_pages = i; + goto out; + } + kaddr = kmap(pages[i]); + memcpy(kaddr, value + i*PAGE_CACHE_SIZE, + min(PAGE_CACHE_SIZE, size-i*PAGE_CACHE_SIZE)); + } + } + + dout("setxattr value=%.*s\n", (int)size, value); + + /* do request */ + req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SETXATTR, + USE_AUTH_MDS); + if (IS_ERR(req)) + return PTR_ERR(req); + req->r_inode = igrab(inode); + req->r_inode_drop = CEPH_CAP_XATTR_SHARED; + req->r_num_caps = 1; + req->r_args.setxattr.flags = cpu_to_le32(flags); + req->r_path2 = kstrdup(name, GFP_NOFS); + + req->r_pages = pages; + req->r_num_pages = nr_pages; + req->r_data_len = size; + + dout("xattr.ver (before): %lld\n", ci->i_xattrs.version); + err = ceph_mdsc_do_request(mdsc, parent_inode, req); + ceph_mdsc_put_request(req); + dout("xattr.ver (after): %lld\n", ci->i_xattrs.version); + +out: + if (pages) { + for (i = 0; i < nr_pages; i++) + __free_page(pages[i]); + kfree(pages); + } + return err; +} + +int ceph_setxattr(struct dentry *dentry, const char *name, + const void *value, size_t size, int flags) +{ + struct inode *inode = dentry->d_inode; + struct ceph_inode_info *ci = ceph_inode(inode); + struct ceph_vxattr_cb *vxattrs = ceph_inode_vxattrs(inode); + int err; + int name_len = strlen(name); + int val_len = size; + char *newname = NULL; + char *newval = NULL; + struct ceph_inode_xattr *xattr = NULL; + int issued; + int required_blob_size; + + if (ceph_snap(inode) != CEPH_NOSNAP) + return -EROFS; + + if (!ceph_is_valid_xattr(name)) + return -EOPNOTSUPP; + + if (vxattrs) { + struct ceph_vxattr_cb *vxattr = + ceph_match_vxattr(vxattrs, name); + if (vxattr && vxattr->readonly) + return -EOPNOTSUPP; + } + + /* preallocate memory for xattr name, value, index node */ + err = -ENOMEM; + newname = kmalloc(name_len + 1, GFP_NOFS); + if (!newname) + goto out; + memcpy(newname, name, name_len + 1); + + if (val_len) { + newval = kmalloc(val_len + 1, GFP_NOFS); + if (!newval) + goto out; + memcpy(newval, value, val_len); + newval[val_len] = '\0'; + } + + xattr = kmalloc(sizeof(struct ceph_inode_xattr), GFP_NOFS); + if (!xattr) + goto out; + + spin_lock(&inode->i_lock); +retry: + issued = __ceph_caps_issued(ci, NULL); + if (!(issued & CEPH_CAP_XATTR_EXCL)) + goto do_sync; + __build_xattrs(inode); + + required_blob_size = __get_required_blob_size(ci, name_len, val_len); + + if (!ci->i_xattrs.prealloc_blob || + required_blob_size > ci->i_xattrs.prealloc_blob->alloc_len) { + struct ceph_buffer *blob = NULL; + + spin_unlock(&inode->i_lock); + dout(" preaallocating new blob size=%d\n", required_blob_size); + blob = ceph_buffer_new_alloc(required_blob_size, GFP_NOFS); + if (!blob) + goto out; + spin_lock(&inode->i_lock); + ceph_buffer_put(ci->i_xattrs.prealloc_blob); + ci->i_xattrs.prealloc_blob = blob; + goto retry; + } + + dout("setxattr %p issued %s\n", inode, ceph_cap_string(issued)); + err = __set_xattr(ci, newname, name_len, newval, + val_len, 1, 1, 1, &xattr); + __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL); + ci->i_xattrs.dirty = true; + inode->i_ctime = CURRENT_TIME; + spin_unlock(&inode->i_lock); + + return err; + +do_sync: + spin_unlock(&inode->i_lock); + err = ceph_sync_setxattr(dentry, name, value, size, flags); +out: + kfree(newname); + kfree(newval); + kfree(xattr); + return err; +} + +static int ceph_send_removexattr(struct dentry *dentry, const char *name) +{ + struct ceph_client *client = ceph_client(dentry->d_sb); + struct ceph_mds_client *mdsc = &client->mdsc; + struct inode *inode = dentry->d_inode; + struct inode *parent_inode = dentry->d_parent->d_inode; + struct ceph_mds_request *req; + int err; + + req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_RMXATTR, + USE_AUTH_MDS); + if (IS_ERR(req)) + return PTR_ERR(req); + req->r_inode = igrab(inode); + req->r_inode_drop = CEPH_CAP_XATTR_SHARED; + req->r_num_caps = 1; + req->r_path2 = kstrdup(name, GFP_NOFS); + + err = ceph_mdsc_do_request(mdsc, parent_inode, req); + ceph_mdsc_put_request(req); + return err; +} + +int ceph_removexattr(struct dentry *dentry, const char *name) +{ + struct inode *inode = dentry->d_inode; + struct ceph_inode_info *ci = ceph_inode(inode); + struct ceph_vxattr_cb *vxattrs = ceph_inode_vxattrs(inode); + int issued; + int err; + + if (ceph_snap(inode) != CEPH_NOSNAP) + return -EROFS; + + if (!ceph_is_valid_xattr(name)) + return -EOPNOTSUPP; + + if (vxattrs) { + struct ceph_vxattr_cb *vxattr = + ceph_match_vxattr(vxattrs, name); + if (vxattr && vxattr->readonly) + return -EOPNOTSUPP; + } + + spin_lock(&inode->i_lock); + __build_xattrs(inode); + issued = __ceph_caps_issued(ci, NULL); + dout("removexattr %p issued %s\n", inode, ceph_cap_string(issued)); + + if (!(issued & CEPH_CAP_XATTR_EXCL)) + goto do_sync; + + err = __remove_xattr_by_name(ceph_inode(inode), name); + __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL); + ci->i_xattrs.dirty = true; + inode->i_ctime = CURRENT_TIME; + + spin_unlock(&inode->i_lock); + + return err; +do_sync: + spin_unlock(&inode->i_lock); + err = ceph_send_removexattr(dentry, name); + return err; +} + -- cgit v0.10.2 From 2817b000b02c5f0c05af67c01fb2684e1381d6ef Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 6 Oct 2009 11:31:08 -0700 Subject: ceph: directory operations Directory operations, including lookup, are defined here. We take advantage of lookup intents when possible. For the most part, we just need to build the proper requests for the metadata server(s) and pass things off to the mds_client. The results of most operations are normally incorporated into the client's cache when the reply is parsed by ceph_fill_trace(). However, if the MDS replies without a trace (e.g., when retrying an update after an MDS failure recovery), some operation-specific cleanup may be needed. We can validate cached dentries in two ways. A per-dentry lease may be issued by the MDS, or a per-directory cap may be issued that acts as a lease on the entire directory. In the latter case, a 'gen' value is used to determine which dentries belong to the currently leased directory contents. We normally prepopulate the dcache and icache with readdir results. This makes subsequent lookups and getattrs avoid any server interaction. It also lets us satisfy readdir operation by peeking at the dcache IFF we hold the per-directory cap/lease, previously performed a readdir, and haven't dropped any of the resulting dentries. Signed-off-by: Sage Weil diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c new file mode 100644 index 0000000..7bb8db5 --- /dev/null +++ b/fs/ceph/dir.c @@ -0,0 +1,1212 @@ +#include "ceph_debug.h" + +#include +#include +#include +#include + +#include "super.h" + +/* + * Directory operations: readdir, lookup, create, link, unlink, + * rename, etc. + */ + +/* + * Ceph MDS operations are specified in terms of a base ino and + * relative path. Thus, the client can specify an operation on a + * specific inode (e.g., a getattr due to fstat(2)), or as a path + * relative to, say, the root directory. + * + * Normally, we limit ourselves to strict inode ops (no path component) + * or dentry operations (a single path component relative to an ino). The + * exception to this is open_root_dentry(), which will open the mount + * point by name. + */ + +const struct inode_operations ceph_dir_iops; +const struct file_operations ceph_dir_fops; +struct dentry_operations ceph_dentry_ops; + +/* + * Initialize ceph dentry state. + */ +int ceph_init_dentry(struct dentry *dentry) +{ + struct ceph_dentry_info *di; + + if (dentry->d_fsdata) + return 0; + + if (ceph_snap(dentry->d_parent->d_inode) == CEPH_NOSNAP) + dentry->d_op = &ceph_dentry_ops; + else if (ceph_snap(dentry->d_parent->d_inode) == CEPH_SNAPDIR) + dentry->d_op = &ceph_snapdir_dentry_ops; + else + dentry->d_op = &ceph_snap_dentry_ops; + + di = kmem_cache_alloc(ceph_dentry_cachep, GFP_NOFS); + if (!di) + return -ENOMEM; /* oh well */ + + spin_lock(&dentry->d_lock); + if (dentry->d_fsdata) /* lost a race */ + goto out_unlock; + di->dentry = dentry; + di->lease_session = NULL; + dentry->d_fsdata = di; + dentry->d_time = jiffies; + ceph_dentry_lru_add(dentry); +out_unlock: + spin_unlock(&dentry->d_lock); + return 0; +} + + + +/* + * for readdir, we encode the directory frag and offset within that + * frag into f_pos. + */ +static unsigned fpos_frag(loff_t p) +{ + return p >> 32; +} +static unsigned fpos_off(loff_t p) +{ + return p & 0xffffffff; +} + +/* + * When possible, we try to satisfy a readdir by peeking at the + * dcache. We make this work by carefully ordering dentries on + * d_u.d_child when we initially get results back from the MDS, and + * falling back to a "normal" sync readdir if any dentries in the dir + * are dropped. + * + * I_COMPLETE tells indicates we have all dentries in the dir. It is + * defined IFF we hold CEPH_CAP_FILE_SHARED (which will be revoked by + * the MDS if/when the directory is modified). + */ +static int __dcache_readdir(struct file *filp, + void *dirent, filldir_t filldir) +{ + struct inode *inode = filp->f_dentry->d_inode; + struct ceph_file_info *fi = filp->private_data; + struct dentry *parent = filp->f_dentry; + struct inode *dir = parent->d_inode; + struct list_head *p; + struct dentry *dentry, *last; + struct ceph_dentry_info *di; + int err = 0; + + /* claim ref on last dentry we returned */ + last = fi->dentry; + fi->dentry = NULL; + + dout("__dcache_readdir %p at %llu (last %p)\n", dir, filp->f_pos, + last); + + spin_lock(&dcache_lock); + + /* start at beginning? */ + if (filp->f_pos == 2 || (last && + filp->f_pos < ceph_dentry(last)->offset)) { + if (list_empty(&parent->d_subdirs)) + goto out_unlock; + p = parent->d_subdirs.prev; + dout(" initial p %p/%p\n", p->prev, p->next); + } else { + p = last->d_u.d_child.prev; + } + +more: + dentry = list_entry(p, struct dentry, d_u.d_child); + di = ceph_dentry(dentry); + while (1) { + dout(" p %p/%p d_subdirs %p/%p\n", p->prev, p->next, + parent->d_subdirs.prev, parent->d_subdirs.next); + if (p == &parent->d_subdirs) { + fi->at_end = 1; + goto out_unlock; + } + if (!d_unhashed(dentry) && dentry->d_inode && + filp->f_pos <= di->offset) + break; + dout(" skipping %p %.*s at %llu (%llu)%s%s\n", dentry, + dentry->d_name.len, dentry->d_name.name, di->offset, + filp->f_pos, d_unhashed(dentry) ? " unhashed" : "", + !dentry->d_inode ? " null" : ""); + p = p->prev; + dentry = list_entry(p, struct dentry, d_u.d_child); + di = ceph_dentry(dentry); + } + + atomic_inc(&dentry->d_count); + spin_unlock(&dcache_lock); + spin_unlock(&inode->i_lock); + + dout(" %llu (%llu) dentry %p %.*s %p\n", di->offset, filp->f_pos, + dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_inode); + filp->f_pos = di->offset; + err = filldir(dirent, dentry->d_name.name, + dentry->d_name.len, di->offset, + dentry->d_inode->i_ino, + dentry->d_inode->i_mode >> 12); + + if (last) { + if (err < 0) { + /* remember our position */ + fi->dentry = last; + fi->next_offset = di->offset; + } else { + dput(last); + } + last = NULL; + } + + spin_lock(&inode->i_lock); + spin_lock(&dcache_lock); + + if (err < 0) + goto out_unlock; + + last = dentry; + + p = p->prev; + filp->f_pos++; + + /* make sure a dentry wasn't dropped while we didn't have dcache_lock */ + if ((ceph_inode(dir)->i_ceph_flags & CEPH_I_COMPLETE)) + goto more; + dout(" lost I_COMPLETE on %p; falling back to mds\n", dir); + err = -EAGAIN; + +out_unlock: + spin_unlock(&dcache_lock); + + if (last) { + spin_unlock(&inode->i_lock); + dput(last); + spin_lock(&inode->i_lock); + } + + return err; +} + +/* + * make note of the last dentry we read, so we can + * continue at the same lexicographical point, + * regardless of what dir changes take place on the + * server. + */ +static int note_last_dentry(struct ceph_file_info *fi, const char *name, + int len) +{ + kfree(fi->last_name); + fi->last_name = kmalloc(len+1, GFP_NOFS); + if (!fi->last_name) + return -ENOMEM; + memcpy(fi->last_name, name, len); + fi->last_name[len] = 0; + dout("note_last_dentry '%s'\n", fi->last_name); + return 0; +} + +static int ceph_readdir(struct file *filp, void *dirent, filldir_t filldir) +{ + struct ceph_file_info *fi = filp->private_data; + struct inode *inode = filp->f_dentry->d_inode; + struct ceph_inode_info *ci = ceph_inode(inode); + struct ceph_client *client = ceph_inode_to_client(inode); + struct ceph_mds_client *mdsc = &client->mdsc; + unsigned frag = fpos_frag(filp->f_pos); + int off = fpos_off(filp->f_pos); + int err; + u32 ftype; + struct ceph_mds_reply_info_parsed *rinfo; + const int max_entries = client->mount_args.max_readdir; + + dout("readdir %p filp %p frag %u off %u\n", inode, filp, frag, off); + if (fi->at_end) + return 0; + + /* always start with . and .. */ + if (filp->f_pos == 0) { + /* note dir version at start of readdir so we can tell + * if any dentries get dropped */ + fi->dir_release_count = ci->i_release_count; + + dout("readdir off 0 -> '.'\n"); + if (filldir(dirent, ".", 1, ceph_make_fpos(0, 0), + inode->i_ino, inode->i_mode >> 12) < 0) + return 0; + filp->f_pos = 1; + off = 1; + } + if (filp->f_pos == 1) { + dout("readdir off 1 -> '..'\n"); + if (filldir(dirent, "..", 2, ceph_make_fpos(0, 1), + filp->f_dentry->d_parent->d_inode->i_ino, + inode->i_mode >> 12) < 0) + return 0; + filp->f_pos = 2; + off = 2; + } + + /* can we use the dcache? */ + spin_lock(&inode->i_lock); + if ((filp->f_pos == 2 || fi->dentry) && + !ceph_test_opt(client, NOASYNCREADDIR) && + (ci->i_ceph_flags & CEPH_I_COMPLETE) && + __ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1)) { + err = __dcache_readdir(filp, dirent, filldir); + if (err != -EAGAIN) { + spin_unlock(&inode->i_lock); + return err; + } + } + spin_unlock(&inode->i_lock); + if (fi->dentry) { + err = note_last_dentry(fi, fi->dentry->d_name.name, + fi->dentry->d_name.len); + if (err) + return err; + dput(fi->dentry); + fi->dentry = NULL; + } + + /* proceed with a normal readdir */ + +more: + /* do we have the correct frag content buffered? */ + if (fi->frag != frag || fi->last_readdir == NULL) { + struct ceph_mds_request *req; + int op = ceph_snap(inode) == CEPH_SNAPDIR ? + CEPH_MDS_OP_LSSNAP : CEPH_MDS_OP_READDIR; + + /* discard old result, if any */ + if (fi->last_readdir) + ceph_mdsc_put_request(fi->last_readdir); + + /* requery frag tree, as the frag topology may have changed */ + frag = ceph_choose_frag(ceph_inode(inode), frag, NULL, NULL); + + dout("readdir fetching %llx.%llx frag %x offset '%s'\n", + ceph_vinop(inode), frag, fi->last_name); + req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS); + if (IS_ERR(req)) + return PTR_ERR(req); + req->r_inode = igrab(inode); + req->r_dentry = dget(filp->f_dentry); + /* hints to request -> mds selection code */ + req->r_direct_mode = USE_AUTH_MDS; + req->r_direct_hash = ceph_frag_value(frag); + req->r_direct_is_hash = true; + req->r_path2 = kstrdup(fi->last_name, GFP_NOFS); + req->r_readdir_offset = fi->next_offset; + req->r_args.readdir.frag = cpu_to_le32(frag); + req->r_args.readdir.max_entries = cpu_to_le32(max_entries); + req->r_num_caps = max_entries; + err = ceph_mdsc_do_request(mdsc, NULL, req); + if (err < 0) { + ceph_mdsc_put_request(req); + return err; + } + dout("readdir got and parsed readdir result=%d" + " on frag %x, end=%d, complete=%d\n", err, frag, + (int)req->r_reply_info.dir_end, + (int)req->r_reply_info.dir_complete); + + if (!req->r_did_prepopulate) { + dout("readdir !did_prepopulate"); + fi->dir_release_count--; /* preclude I_COMPLETE */ + } + + /* note next offset and last dentry name */ + fi->offset = fi->next_offset; + fi->last_readdir = req; + + if (req->r_reply_info.dir_end) { + kfree(fi->last_name); + fi->last_name = NULL; + fi->next_offset = 0; + } else { + rinfo = &req->r_reply_info; + err = note_last_dentry(fi, + rinfo->dir_dname[rinfo->dir_nr-1], + rinfo->dir_dname_len[rinfo->dir_nr-1]); + if (err) + return err; + fi->next_offset += rinfo->dir_nr; + } + } + + rinfo = &fi->last_readdir->r_reply_info; + dout("readdir frag %x num %d off %d chunkoff %d\n", frag, + rinfo->dir_nr, off, fi->offset); + while (off - fi->offset >= 0 && off - fi->offset < rinfo->dir_nr) { + u64 pos = ceph_make_fpos(frag, off); + struct ceph_mds_reply_inode *in = + rinfo->dir_in[off - fi->offset].in; + dout("readdir off %d (%d/%d) -> %lld '%.*s' %p\n", + off, off - fi->offset, rinfo->dir_nr, pos, + rinfo->dir_dname_len[off - fi->offset], + rinfo->dir_dname[off - fi->offset], in); + BUG_ON(!in); + ftype = le32_to_cpu(in->mode) >> 12; + if (filldir(dirent, + rinfo->dir_dname[off - fi->offset], + rinfo->dir_dname_len[off - fi->offset], + pos, + le64_to_cpu(in->ino), + ftype) < 0) { + dout("filldir stopping us...\n"); + return 0; + } + off++; + filp->f_pos = pos + 1; + } + + if (fi->last_name) { + ceph_mdsc_put_request(fi->last_readdir); + fi->last_readdir = NULL; + goto more; + } + + /* more frags? */ + if (!ceph_frag_is_rightmost(frag)) { + frag = ceph_frag_next(frag); + off = 0; + filp->f_pos = ceph_make_fpos(frag, off); + dout("readdir next frag is %x\n", frag); + goto more; + } + fi->at_end = 1; + + /* + * if dir_release_count still matches the dir, no dentries + * were released during the whole readdir, and we should have + * the complete dir contents in our cache. + */ + spin_lock(&inode->i_lock); + if (ci->i_release_count == fi->dir_release_count) { + dout(" marking %p complete\n", inode); + ci->i_ceph_flags |= CEPH_I_COMPLETE; + ci->i_max_offset = filp->f_pos; + } + spin_unlock(&inode->i_lock); + + dout("readdir %p filp %p done.\n", inode, filp); + return 0; +} + +static void reset_readdir(struct ceph_file_info *fi) +{ + if (fi->last_readdir) { + ceph_mdsc_put_request(fi->last_readdir); + fi->last_readdir = NULL; + } + kfree(fi->last_name); + fi->next_offset = 2; /* compensate for . and .. */ + if (fi->dentry) { + dput(fi->dentry); + fi->dentry = NULL; + } + fi->at_end = 0; +} + +static loff_t ceph_dir_llseek(struct file *file, loff_t offset, int origin) +{ + struct ceph_file_info *fi = file->private_data; + struct inode *inode = file->f_mapping->host; + loff_t old_offset = offset; + loff_t retval; + + mutex_lock(&inode->i_mutex); + switch (origin) { + case SEEK_END: + offset += inode->i_size + 2; /* FIXME */ + break; + case SEEK_CUR: + offset += file->f_pos; + } + retval = -EINVAL; + if (offset >= 0 && offset <= inode->i_sb->s_maxbytes) { + if (offset != file->f_pos) { + file->f_pos = offset; + file->f_version = 0; + fi->at_end = 0; + } + retval = offset; + + /* + * discard buffered readdir content on seekdir(0), or + * seek to new frag, or seek prior to current chunk. + */ + if (offset == 0 || + fpos_frag(offset) != fpos_frag(old_offset) || + fpos_off(offset) < fi->offset) { + dout("dir_llseek dropping %p content\n", file); + reset_readdir(fi); + } + + /* bump dir_release_count if we did a forward seek */ + if (offset > old_offset) + fi->dir_release_count--; + } + mutex_unlock(&inode->i_mutex); + return retval; +} + +/* + * Process result of a lookup/open request. + * + * Mainly, make sure we return the final req->r_dentry (if it already + * existed) in place of the original VFS-provided dentry when they + * differ. + * + * Gracefully handle the case where the MDS replies with -ENOENT and + * no trace (which it may do, at its discretion, e.g., if it doesn't + * care to issue a lease on the negative dentry). + */ +struct dentry *ceph_finish_lookup(struct ceph_mds_request *req, + struct dentry *dentry, int err) +{ + struct ceph_client *client = ceph_client(dentry->d_sb); + struct inode *parent = dentry->d_parent->d_inode; + + /* .snap dir? */ + if (err == -ENOENT && + ceph_vino(parent).ino != CEPH_INO_ROOT && /* no .snap in root dir */ + strcmp(dentry->d_name.name, client->mount_args.snapdir_name) == 0) { + struct inode *inode = ceph_get_snapdir(parent); + dout("ENOENT on snapdir %p '%.*s', linking to snapdir %p\n", + dentry, dentry->d_name.len, dentry->d_name.name, inode); + d_add(dentry, inode); + err = 0; + } + + if (err == -ENOENT) { + /* no trace? */ + err = 0; + if (!req->r_reply_info.head->is_dentry) { + dout("ENOENT and no trace, dentry %p inode %p\n", + dentry, dentry->d_inode); + if (dentry->d_inode) { + d_drop(dentry); + err = -ENOENT; + } else { + d_add(dentry, NULL); + } + } + } + if (err) + dentry = ERR_PTR(err); + else if (dentry != req->r_dentry) + dentry = dget(req->r_dentry); /* we got spliced */ + else + dentry = NULL; + return dentry; +} + +/* + * Look up a single dir entry. If there is a lookup intent, inform + * the MDS so that it gets our 'caps wanted' value in a single op. + */ +static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry, + struct nameidata *nd) +{ + struct ceph_client *client = ceph_sb_to_client(dir->i_sb); + struct ceph_mds_client *mdsc = &client->mdsc; + struct ceph_mds_request *req; + int op; + int err; + + dout("lookup %p dentry %p '%.*s'\n", + dir, dentry, dentry->d_name.len, dentry->d_name.name); + + if (dentry->d_name.len > NAME_MAX) + return ERR_PTR(-ENAMETOOLONG); + + err = ceph_init_dentry(dentry); + if (err < 0) + return ERR_PTR(err); + + /* open (but not create!) intent? */ + if (nd && + (nd->flags & LOOKUP_OPEN) && + (nd->flags & LOOKUP_CONTINUE) == 0 && /* only open last component */ + !(nd->intent.open.flags & O_CREAT)) { + int mode = nd->intent.open.create_mode & ~current->fs->umask; + return ceph_lookup_open(dir, dentry, nd, mode, 1); + } + + /* can we conclude ENOENT locally? */ + if (dentry->d_inode == NULL) { + struct ceph_inode_info *ci = ceph_inode(dir); + struct ceph_dentry_info *di = ceph_dentry(dentry); + + spin_lock(&dir->i_lock); + dout(" dir %p flags are %d\n", dir, ci->i_ceph_flags); + if (strncmp(dentry->d_name.name, + client->mount_args.snapdir_name, + dentry->d_name.len) && + (ci->i_ceph_flags & CEPH_I_COMPLETE) && + (__ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1))) { + di->offset = ci->i_max_offset++; + spin_unlock(&dir->i_lock); + dout(" dir %p complete, -ENOENT\n", dir); + d_add(dentry, NULL); + di->lease_shared_gen = ci->i_shared_gen; + return NULL; + } + spin_unlock(&dir->i_lock); + } + + op = ceph_snap(dir) == CEPH_SNAPDIR ? + CEPH_MDS_OP_LOOKUPSNAP : CEPH_MDS_OP_LOOKUP; + req = ceph_mdsc_create_request(mdsc, op, USE_ANY_MDS); + if (IS_ERR(req)) + return ERR_PTR(PTR_ERR(req)); + req->r_dentry = dget(dentry); + req->r_num_caps = 2; + /* we only need inode linkage */ + req->r_args.getattr.mask = cpu_to_le32(CEPH_STAT_CAP_INODE); + req->r_locked_dir = dir; + err = ceph_mdsc_do_request(mdsc, NULL, req); + dentry = ceph_finish_lookup(req, dentry, err); + ceph_mdsc_put_request(req); /* will dput(dentry) */ + dout("lookup result=%p\n", dentry); + return dentry; +} + +/* + * If we do a create but get no trace back from the MDS, follow up with + * a lookup (the VFS expects us to link up the provided dentry). + */ +int ceph_handle_notrace_create(struct inode *dir, struct dentry *dentry) +{ + struct dentry *result = ceph_lookup(dir, dentry, NULL); + + if (result && !IS_ERR(result)) { + /* + * We created the item, then did a lookup, and found + * it was already linked to another inode we already + * had in our cache (and thus got spliced). Link our + * dentry to that inode, but don't hash it, just in + * case the VFS wants to dereference it. + */ + BUG_ON(!result->d_inode); + d_instantiate(dentry, result->d_inode); + return 0; + } + return PTR_ERR(result); +} + +static int ceph_mknod(struct inode *dir, struct dentry *dentry, + int mode, dev_t rdev) +{ + struct ceph_client *client = ceph_sb_to_client(dir->i_sb); + struct ceph_mds_client *mdsc = &client->mdsc; + struct ceph_mds_request *req; + int err; + + if (ceph_snap(dir) != CEPH_NOSNAP) + return -EROFS; + + dout("mknod in dir %p dentry %p mode 0%o rdev %d\n", + dir, dentry, mode, rdev); + req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_MKNOD, USE_AUTH_MDS); + if (IS_ERR(req)) { + d_drop(dentry); + return PTR_ERR(req); + } + req->r_dentry = dget(dentry); + req->r_num_caps = 2; + req->r_locked_dir = dir; + req->r_args.mknod.mode = cpu_to_le32(mode); + req->r_args.mknod.rdev = cpu_to_le32(rdev); + req->r_dentry_drop = CEPH_CAP_FILE_SHARED; + req->r_dentry_unless = CEPH_CAP_FILE_EXCL; + err = ceph_mdsc_do_request(mdsc, dir, req); + if (!err && !req->r_reply_info.head->is_dentry) + err = ceph_handle_notrace_create(dir, dentry); + ceph_mdsc_put_request(req); + if (err) + d_drop(dentry); + return err; +} + +static int ceph_create(struct inode *dir, struct dentry *dentry, int mode, + struct nameidata *nd) +{ + dout("create in dir %p dentry %p name '%.*s'\n", + dir, dentry, dentry->d_name.len, dentry->d_name.name); + + if (ceph_snap(dir) != CEPH_NOSNAP) + return -EROFS; + + if (nd) { + BUG_ON((nd->flags & LOOKUP_OPEN) == 0); + dentry = ceph_lookup_open(dir, dentry, nd, mode, 0); + /* hrm, what should i do here if we get aliased? */ + if (IS_ERR(dentry)) + return PTR_ERR(dentry); + return 0; + } + + /* fall back to mknod */ + return ceph_mknod(dir, dentry, (mode & ~S_IFMT) | S_IFREG, 0); +} + +static int ceph_symlink(struct inode *dir, struct dentry *dentry, + const char *dest) +{ + struct ceph_client *client = ceph_sb_to_client(dir->i_sb); + struct ceph_mds_client *mdsc = &client->mdsc; + struct ceph_mds_request *req; + int err; + + if (ceph_snap(dir) != CEPH_NOSNAP) + return -EROFS; + + dout("symlink in dir %p dentry %p to '%s'\n", dir, dentry, dest); + req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SYMLINK, USE_AUTH_MDS); + if (IS_ERR(req)) { + d_drop(dentry); + return PTR_ERR(req); + } + req->r_dentry = dget(dentry); + req->r_num_caps = 2; + req->r_path2 = kstrdup(dest, GFP_NOFS); + req->r_locked_dir = dir; + req->r_dentry_drop = CEPH_CAP_FILE_SHARED; + req->r_dentry_unless = CEPH_CAP_FILE_EXCL; + err = ceph_mdsc_do_request(mdsc, dir, req); + if (!err && !req->r_reply_info.head->is_dentry) + err = ceph_handle_notrace_create(dir, dentry); + ceph_mdsc_put_request(req); + if (err) + d_drop(dentry); + return err; +} + +static int ceph_mkdir(struct inode *dir, struct dentry *dentry, int mode) +{ + struct ceph_client *client = ceph_sb_to_client(dir->i_sb); + struct ceph_mds_client *mdsc = &client->mdsc; + struct ceph_mds_request *req; + int err = -EROFS; + int op; + + if (ceph_snap(dir) == CEPH_SNAPDIR) { + /* mkdir .snap/foo is a MKSNAP */ + op = CEPH_MDS_OP_MKSNAP; + dout("mksnap dir %p snap '%.*s' dn %p\n", dir, + dentry->d_name.len, dentry->d_name.name, dentry); + } else if (ceph_snap(dir) == CEPH_NOSNAP) { + dout("mkdir dir %p dn %p mode 0%o\n", dir, dentry, mode); + op = CEPH_MDS_OP_MKDIR; + } else { + goto out; + } + req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS); + if (IS_ERR(req)) { + err = PTR_ERR(req); + goto out; + } + + req->r_dentry = dget(dentry); + req->r_num_caps = 2; + req->r_locked_dir = dir; + req->r_args.mkdir.mode = cpu_to_le32(mode); + req->r_dentry_drop = CEPH_CAP_FILE_SHARED; + req->r_dentry_unless = CEPH_CAP_FILE_EXCL; + err = ceph_mdsc_do_request(mdsc, dir, req); + if (!err && !req->r_reply_info.head->is_dentry) + err = ceph_handle_notrace_create(dir, dentry); + ceph_mdsc_put_request(req); +out: + if (err < 0) + d_drop(dentry); + return err; +} + +static int ceph_link(struct dentry *old_dentry, struct inode *dir, + struct dentry *dentry) +{ + struct ceph_client *client = ceph_sb_to_client(dir->i_sb); + struct ceph_mds_client *mdsc = &client->mdsc; + struct ceph_mds_request *req; + int err; + + if (ceph_snap(dir) != CEPH_NOSNAP) + return -EROFS; + + dout("link in dir %p old_dentry %p dentry %p\n", dir, + old_dentry, dentry); + req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LINK, USE_AUTH_MDS); + if (IS_ERR(req)) { + d_drop(dentry); + return PTR_ERR(req); + } + req->r_dentry = dget(dentry); + req->r_num_caps = 2; + req->r_old_dentry = dget(old_dentry); /* or inode? hrm. */ + req->r_locked_dir = dir; + req->r_dentry_drop = CEPH_CAP_FILE_SHARED; + req->r_dentry_unless = CEPH_CAP_FILE_EXCL; + err = ceph_mdsc_do_request(mdsc, dir, req); + if (err) + d_drop(dentry); + else if (!req->r_reply_info.head->is_dentry) + d_instantiate(dentry, igrab(old_dentry->d_inode)); + ceph_mdsc_put_request(req); + return err; +} + +/* + * For a soon-to-be unlinked file, drop the AUTH_RDCACHE caps. If it + * looks like the link count will hit 0, drop any other caps (other + * than PIN) we don't specifically want (due to the file still being + * open). + */ +static int drop_caps_for_unlink(struct inode *inode) +{ + struct ceph_inode_info *ci = ceph_inode(inode); + int drop = CEPH_CAP_LINK_SHARED | CEPH_CAP_LINK_EXCL; + + spin_lock(&inode->i_lock); + if (inode->i_nlink == 1) { + drop |= ~(__ceph_caps_wanted(ci) | CEPH_CAP_PIN); + ci->i_ceph_flags |= CEPH_I_NODELAY; + } + spin_unlock(&inode->i_lock); + return drop; +} + +/* + * rmdir and unlink are differ only by the metadata op code + */ +static int ceph_unlink(struct inode *dir, struct dentry *dentry) +{ + struct ceph_client *client = ceph_sb_to_client(dir->i_sb); + struct ceph_mds_client *mdsc = &client->mdsc; + struct inode *inode = dentry->d_inode; + struct ceph_mds_request *req; + int err = -EROFS; + int op; + + if (ceph_snap(dir) == CEPH_SNAPDIR) { + /* rmdir .snap/foo is RMSNAP */ + dout("rmsnap dir %p '%.*s' dn %p\n", dir, dentry->d_name.len, + dentry->d_name.name, dentry); + op = CEPH_MDS_OP_RMSNAP; + } else if (ceph_snap(dir) == CEPH_NOSNAP) { + dout("unlink/rmdir dir %p dn %p inode %p\n", + dir, dentry, inode); + op = ((dentry->d_inode->i_mode & S_IFMT) == S_IFDIR) ? + CEPH_MDS_OP_RMDIR : CEPH_MDS_OP_UNLINK; + } else + goto out; + req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS); + if (IS_ERR(req)) { + err = PTR_ERR(req); + goto out; + } + req->r_dentry = dget(dentry); + req->r_num_caps = 2; + req->r_locked_dir = dir; + req->r_dentry_drop = CEPH_CAP_FILE_SHARED; + req->r_dentry_unless = CEPH_CAP_FILE_EXCL; + req->r_inode_drop = drop_caps_for_unlink(inode); + err = ceph_mdsc_do_request(mdsc, dir, req); + if (!err && !req->r_reply_info.head->is_dentry) + d_delete(dentry); + ceph_mdsc_put_request(req); +out: + return err; +} + +static int ceph_rename(struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry) +{ + struct ceph_client *client = ceph_sb_to_client(old_dir->i_sb); + struct ceph_mds_client *mdsc = &client->mdsc; + struct ceph_mds_request *req; + int err; + + if (ceph_snap(old_dir) != ceph_snap(new_dir)) + return -EXDEV; + if (ceph_snap(old_dir) != CEPH_NOSNAP || + ceph_snap(new_dir) != CEPH_NOSNAP) + return -EROFS; + dout("rename dir %p dentry %p to dir %p dentry %p\n", + old_dir, old_dentry, new_dir, new_dentry); + req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_RENAME, USE_AUTH_MDS); + if (IS_ERR(req)) + return PTR_ERR(req); + req->r_dentry = dget(new_dentry); + req->r_num_caps = 2; + req->r_old_dentry = dget(old_dentry); + req->r_locked_dir = new_dir; + req->r_old_dentry_drop = CEPH_CAP_FILE_SHARED; + req->r_old_dentry_unless = CEPH_CAP_FILE_EXCL; + req->r_dentry_drop = CEPH_CAP_FILE_SHARED; + req->r_dentry_unless = CEPH_CAP_FILE_EXCL; + /* release LINK_RDCACHE on source inode (mds will lock it) */ + req->r_old_inode_drop = CEPH_CAP_LINK_SHARED; + if (new_dentry->d_inode) + req->r_inode_drop = drop_caps_for_unlink(new_dentry->d_inode); + err = ceph_mdsc_do_request(mdsc, old_dir, req); + if (!err && !req->r_reply_info.head->is_dentry) { + /* + * Normally d_move() is done by fill_trace (called by + * do_request, above). If there is no trace, we need + * to do it here. + */ + d_move(old_dentry, new_dentry); + } + ceph_mdsc_put_request(req); + return err; +} + + +/* + * Check if dentry lease is valid. If not, delete the lease. Try to + * renew if the least is more than half up. + */ +static int dentry_lease_is_valid(struct dentry *dentry) +{ + struct ceph_dentry_info *di; + struct ceph_mds_session *s; + int valid = 0; + u32 gen; + unsigned long ttl; + struct ceph_mds_session *session = NULL; + struct inode *dir = NULL; + u32 seq = 0; + + spin_lock(&dentry->d_lock); + di = ceph_dentry(dentry); + if (di && di->lease_session) { + s = di->lease_session; + spin_lock(&s->s_cap_lock); + gen = s->s_cap_gen; + ttl = s->s_cap_ttl; + spin_unlock(&s->s_cap_lock); + + if (di->lease_gen == gen && + time_before(jiffies, dentry->d_time) && + time_before(jiffies, ttl)) { + valid = 1; + if (di->lease_renew_after && + time_after(jiffies, di->lease_renew_after)) { + /* we should renew */ + dir = dentry->d_parent->d_inode; + session = ceph_get_mds_session(s); + seq = di->lease_seq; + di->lease_renew_after = 0; + di->lease_renew_from = jiffies; + } + } else { + __ceph_mdsc_drop_dentry_lease(dentry); + } + } + spin_unlock(&dentry->d_lock); + + if (session) { + ceph_mdsc_lease_send_msg(session, dir, dentry, + CEPH_MDS_LEASE_RENEW, seq); + ceph_put_mds_session(session); + } + dout("dentry_lease_is_valid - dentry %p = %d\n", dentry, valid); + return valid; +} + +/* + * Check if directory-wide content lease/cap is valid. + */ +static int dir_lease_is_valid(struct inode *dir, struct dentry *dentry) +{ + struct ceph_inode_info *ci = ceph_inode(dir); + struct ceph_dentry_info *di = ceph_dentry(dentry); + int valid = 0; + + spin_lock(&dir->i_lock); + if (ci->i_shared_gen == di->lease_shared_gen) + valid = __ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1); + spin_unlock(&dir->i_lock); + dout("dir_lease_is_valid dir %p v%u dentry %p v%u = %d\n", + dir, (unsigned)ci->i_shared_gen, dentry, + (unsigned)di->lease_shared_gen, valid); + return valid; +} + +/* + * Check if cached dentry can be trusted. + */ +static int ceph_d_revalidate(struct dentry *dentry, struct nameidata *nd) +{ + struct inode *dir = dentry->d_parent->d_inode; + + dout("d_revalidate %p '%.*s' inode %p\n", dentry, + dentry->d_name.len, dentry->d_name.name, dentry->d_inode); + + /* always trust cached snapped dentries, snapdir dentry */ + if (ceph_snap(dir) != CEPH_NOSNAP) { + dout("d_revalidate %p '%.*s' inode %p is SNAPPED\n", dentry, + dentry->d_name.len, dentry->d_name.name, dentry->d_inode); + goto out_touch; + } + if (dentry->d_inode && ceph_snap(dentry->d_inode) == CEPH_SNAPDIR) + goto out_touch; + + if (dentry_lease_is_valid(dentry) || + dir_lease_is_valid(dir, dentry)) + goto out_touch; + + dout("d_revalidate %p invalid\n", dentry); + d_drop(dentry); + return 0; +out_touch: + ceph_dentry_lru_touch(dentry); + return 1; +} + +/* + * When a dentry is released, clear the dir I_COMPLETE if it was part + * of the current dir gen. + */ +static void ceph_dentry_release(struct dentry *dentry) +{ + struct ceph_dentry_info *di = ceph_dentry(dentry); + struct inode *parent_inode = dentry->d_parent->d_inode; + + if (parent_inode) { + struct ceph_inode_info *ci = ceph_inode(parent_inode); + + spin_lock(&parent_inode->i_lock); + if (ci->i_shared_gen == di->lease_shared_gen) { + dout(" clearing %p complete (d_release)\n", + parent_inode); + ci->i_ceph_flags &= ~CEPH_I_COMPLETE; + ci->i_release_count++; + } + spin_unlock(&parent_inode->i_lock); + } + if (di) { + ceph_dentry_lru_del(dentry); + if (di->lease_session) + ceph_put_mds_session(di->lease_session); + kmem_cache_free(ceph_dentry_cachep, di); + dentry->d_fsdata = NULL; + } +} + +static int ceph_snapdir_d_revalidate(struct dentry *dentry, + struct nameidata *nd) +{ + /* + * Eventually, we'll want to revalidate snapped metadata + * too... probably... + */ + return 1; +} + + + +/* + * read() on a dir. This weird interface hack only works if mounted + * with '-o dirstat'. + */ +static ssize_t ceph_read_dir(struct file *file, char __user *buf, size_t size, + loff_t *ppos) +{ + struct ceph_file_info *cf = file->private_data; + struct inode *inode = file->f_dentry->d_inode; + struct ceph_inode_info *ci = ceph_inode(inode); + int left; + + if (!ceph_test_opt(ceph_client(inode->i_sb), DIRSTAT)) + return -EISDIR; + + if (!cf->dir_info) { + cf->dir_info = kmalloc(1024, GFP_NOFS); + if (!cf->dir_info) + return -ENOMEM; + cf->dir_info_len = + sprintf(cf->dir_info, + "entries: %20lld\n" + " files: %20lld\n" + " subdirs: %20lld\n" + "rentries: %20lld\n" + " rfiles: %20lld\n" + " rsubdirs: %20lld\n" + "rbytes: %20lld\n" + "rctime: %10ld.%09ld\n", + ci->i_files + ci->i_subdirs, + ci->i_files, + ci->i_subdirs, + ci->i_rfiles + ci->i_rsubdirs, + ci->i_rfiles, + ci->i_rsubdirs, + ci->i_rbytes, + (long)ci->i_rctime.tv_sec, + (long)ci->i_rctime.tv_nsec); + } + + if (*ppos >= cf->dir_info_len) + return 0; + size = min_t(unsigned, size, cf->dir_info_len-*ppos); + left = copy_to_user(buf, cf->dir_info + *ppos, size); + if (left == size) + return -EFAULT; + *ppos += (size - left); + return size - left; +} + +/* + * an fsync() on a dir will wait for any uncommitted directory + * operations to commit. + */ +static int ceph_dir_fsync(struct file *file, struct dentry *dentry, + int datasync) +{ + struct inode *inode = dentry->d_inode; + struct ceph_inode_info *ci = ceph_inode(inode); + struct list_head *head = &ci->i_unsafe_dirops; + struct ceph_mds_request *req; + u64 last_tid; + int ret = 0; + + dout("dir_fsync %p\n", inode); + spin_lock(&ci->i_unsafe_lock); + if (list_empty(head)) + goto out; + + req = list_entry(head->prev, + struct ceph_mds_request, r_unsafe_dir_item); + last_tid = req->r_tid; + + do { + ceph_mdsc_get_request(req); + spin_unlock(&ci->i_unsafe_lock); + dout("dir_fsync %p wait on tid %llu (until %llu)\n", + inode, req->r_tid, last_tid); + if (req->r_timeout) { + ret = wait_for_completion_timeout( + &req->r_safe_completion, req->r_timeout); + if (ret > 0) + ret = 0; + else if (ret == 0) + ret = -EIO; /* timed out */ + } else { + wait_for_completion(&req->r_safe_completion); + } + spin_lock(&ci->i_unsafe_lock); + ceph_mdsc_put_request(req); + + if (ret || list_empty(head)) + break; + req = list_entry(head->next, + struct ceph_mds_request, r_unsafe_dir_item); + } while (req->r_tid < last_tid); +out: + spin_unlock(&ci->i_unsafe_lock); + return ret; +} + +/* + * We maintain a private dentry LRU. + * + * FIXME: this needs to be changed to a per-mds lru to be useful. + */ +void ceph_dentry_lru_add(struct dentry *dn) +{ + struct ceph_dentry_info *di = ceph_dentry(dn); + struct ceph_mds_client *mdsc; + dout("dentry_lru_add %p %p\t%.*s\n", + di, dn, dn->d_name.len, dn->d_name.name); + + if (di) { + mdsc = &ceph_client(dn->d_sb)->mdsc; + spin_lock(&mdsc->dentry_lru_lock); + list_add_tail(&di->lru, &mdsc->dentry_lru); + mdsc->num_dentry++; + spin_unlock(&mdsc->dentry_lru_lock); + } +} + +void ceph_dentry_lru_touch(struct dentry *dn) +{ + struct ceph_dentry_info *di = ceph_dentry(dn); + struct ceph_mds_client *mdsc; + dout("dentry_lru_touch %p %p\t%.*s\n", + di, dn, dn->d_name.len, dn->d_name.name); + + if (di) { + mdsc = &ceph_client(dn->d_sb)->mdsc; + spin_lock(&mdsc->dentry_lru_lock); + list_move_tail(&di->lru, &mdsc->dentry_lru); + spin_unlock(&mdsc->dentry_lru_lock); + } +} + +void ceph_dentry_lru_del(struct dentry *dn) +{ + struct ceph_dentry_info *di = ceph_dentry(dn); + struct ceph_mds_client *mdsc; + + dout("dentry_lru_del %p %p\t%.*s\n", + di, dn, dn->d_name.len, dn->d_name.name); + if (di) { + mdsc = &ceph_client(dn->d_sb)->mdsc; + spin_lock(&mdsc->dentry_lru_lock); + list_del_init(&di->lru); + mdsc->num_dentry--; + spin_unlock(&mdsc->dentry_lru_lock); + } +} + +const struct file_operations ceph_dir_fops = { + .read = ceph_read_dir, + .readdir = ceph_readdir, + .llseek = ceph_dir_llseek, + .open = ceph_open, + .release = ceph_release, + .unlocked_ioctl = ceph_ioctl, + .fsync = ceph_dir_fsync, +}; + +const struct inode_operations ceph_dir_iops = { + .lookup = ceph_lookup, + .permission = ceph_permission, + .getattr = ceph_getattr, + .setattr = ceph_setattr, + .setxattr = ceph_setxattr, + .getxattr = ceph_getxattr, + .listxattr = ceph_listxattr, + .removexattr = ceph_removexattr, + .mknod = ceph_mknod, + .symlink = ceph_symlink, + .mkdir = ceph_mkdir, + .link = ceph_link, + .unlink = ceph_unlink, + .rmdir = ceph_unlink, + .rename = ceph_rename, + .create = ceph_create, +}; + +struct dentry_operations ceph_dentry_ops = { + .d_revalidate = ceph_d_revalidate, + .d_release = ceph_dentry_release, +}; + +struct dentry_operations ceph_snapdir_dentry_ops = { + .d_revalidate = ceph_snapdir_d_revalidate, +}; + +struct dentry_operations ceph_snap_dentry_ops = { +}; -- cgit v0.10.2 From 124e68e74099090e28da5518f73fda878e7e8232 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 6 Oct 2009 11:31:08 -0700 Subject: ceph: file operations File open and close operations, and read and write methods that ensure we have obtained the proper capabilities from the MDS cluster before performing IO on a file. We take references on held capabilities for the duration of the read/write to avoid prematurely releasing them back to the MDS. We implement two main paths for read and write: one that is buffered (and uses generic_aio_{read,write}), and one that is fully synchronous and blocking (operating either on a __user pointer or, if O_DIRECT, directly on user pages). Signed-off-by: Sage Weil diff --git a/fs/ceph/file.c b/fs/ceph/file.c new file mode 100644 index 0000000..1bd57c8 --- /dev/null +++ b/fs/ceph/file.c @@ -0,0 +1,904 @@ +#include "ceph_debug.h" + +#include +#include +#include +#include + +#include "super.h" +#include "mds_client.h" + +/* + * Ceph file operations + * + * Implement basic open/close functionality, and implement + * read/write. + * + * We implement three modes of file I/O: + * - buffered uses the generic_file_aio_{read,write} helpers + * + * - synchronous is used when there is multi-client read/write + * sharing, avoids the page cache, and synchronously waits for an + * ack from the OSD. + * + * - direct io takes the variant of the sync path that references + * user pages directly. + * + * fsync() flushes and waits on dirty pages, but just queues metadata + * for writeback: since the MDS can recover size and mtime there is no + * need to wait for MDS acknowledgement. + */ + + +/* + * Prepare an open request. Preallocate ceph_cap to avoid an + * inopportune ENOMEM later. + */ +static struct ceph_mds_request * +prepare_open_request(struct super_block *sb, int flags, int create_mode) +{ + struct ceph_client *client = ceph_sb_to_client(sb); + struct ceph_mds_client *mdsc = &client->mdsc; + struct ceph_mds_request *req; + int want_auth = USE_ANY_MDS; + int op = (flags & O_CREAT) ? CEPH_MDS_OP_CREATE : CEPH_MDS_OP_OPEN; + + if (flags & (O_WRONLY|O_RDWR|O_CREAT|O_TRUNC)) + want_auth = USE_AUTH_MDS; + + req = ceph_mdsc_create_request(mdsc, op, want_auth); + if (IS_ERR(req)) + goto out; + req->r_fmode = ceph_flags_to_mode(flags); + req->r_args.open.flags = cpu_to_le32(flags); + req->r_args.open.mode = cpu_to_le32(create_mode); + req->r_args.open.preferred = -1; +out: + return req; +} + +/* + * initialize private struct file data. + * if we fail, clean up by dropping fmode reference on the ceph_inode + */ +static int ceph_init_file(struct inode *inode, struct file *file, int fmode) +{ + struct ceph_file_info *cf; + int ret = 0; + + switch (inode->i_mode & S_IFMT) { + case S_IFREG: + case S_IFDIR: + dout("init_file %p %p 0%o (regular)\n", inode, file, + inode->i_mode); + cf = kmem_cache_alloc(ceph_file_cachep, GFP_NOFS | __GFP_ZERO); + if (cf == NULL) { + ceph_put_fmode(ceph_inode(inode), fmode); /* clean up */ + return -ENOMEM; + } + cf->fmode = fmode; + cf->next_offset = 2; + file->private_data = cf; + BUG_ON(inode->i_fop->release != ceph_release); + break; + + case S_IFLNK: + dout("init_file %p %p 0%o (symlink)\n", inode, file, + inode->i_mode); + ceph_put_fmode(ceph_inode(inode), fmode); /* clean up */ + break; + + default: + dout("init_file %p %p 0%o (special)\n", inode, file, + inode->i_mode); + /* + * we need to drop the open ref now, since we don't + * have .release set to ceph_release. + */ + ceph_put_fmode(ceph_inode(inode), fmode); /* clean up */ + BUG_ON(inode->i_fop->release == ceph_release); + + /* call the proper open fop */ + ret = inode->i_fop->open(inode, file); + } + return ret; +} + +/* + * If the filp already has private_data, that means the file was + * already opened by intent during lookup, and we do nothing. + * + * If we already have the requisite capabilities, we can satisfy + * the open request locally (no need to request new caps from the + * MDS). We do, however, need to inform the MDS (asynchronously) + * if our wanted caps set expands. + */ +int ceph_open(struct inode *inode, struct file *file) +{ + struct ceph_inode_info *ci = ceph_inode(inode); + struct ceph_client *client = ceph_sb_to_client(inode->i_sb); + struct ceph_mds_client *mdsc = &client->mdsc; + struct ceph_mds_request *req; + struct ceph_file_info *cf = file->private_data; + struct inode *parent_inode = file->f_dentry->d_parent->d_inode; + int err; + int flags, fmode, wanted; + + if (cf) { + dout("open file %p is already opened\n", file); + return 0; + } + + /* filter out O_CREAT|O_EXCL; vfs did that already. yuck. */ + flags = file->f_flags & ~(O_CREAT|O_EXCL); + if (S_ISDIR(inode->i_mode)) + flags = O_DIRECTORY; /* mds likes to know */ + + dout("open inode %p ino %llx.%llx file %p flags %d (%d)\n", inode, + ceph_vinop(inode), file, flags, file->f_flags); + fmode = ceph_flags_to_mode(flags); + wanted = ceph_caps_for_mode(fmode); + + /* snapped files are read-only */ + if (ceph_snap(inode) != CEPH_NOSNAP && (file->f_mode & FMODE_WRITE)) + return -EROFS; + + /* trivially open snapdir */ + if (ceph_snap(inode) == CEPH_SNAPDIR) { + spin_lock(&inode->i_lock); + __ceph_get_fmode(ci, fmode); + spin_unlock(&inode->i_lock); + return ceph_init_file(inode, file, fmode); + } + + /* + * No need to block if we have any caps. Update wanted set + * asynchronously. + */ + spin_lock(&inode->i_lock); + if (__ceph_is_any_real_caps(ci)) { + int mds_wanted = __ceph_caps_mds_wanted(ci); + int issued = __ceph_caps_issued(ci, NULL); + + dout("open %p fmode %d want %s issued %s using existing\n", + inode, fmode, ceph_cap_string(wanted), + ceph_cap_string(issued)); + __ceph_get_fmode(ci, fmode); + spin_unlock(&inode->i_lock); + + /* adjust wanted? */ + if ((issued & wanted) != wanted && + (mds_wanted & wanted) != wanted && + ceph_snap(inode) != CEPH_SNAPDIR) + ceph_check_caps(ci, 0, NULL); + + return ceph_init_file(inode, file, fmode); + } else if (ceph_snap(inode) != CEPH_NOSNAP && + (ci->i_snap_caps & wanted) == wanted) { + __ceph_get_fmode(ci, fmode); + spin_unlock(&inode->i_lock); + return ceph_init_file(inode, file, fmode); + } + spin_unlock(&inode->i_lock); + + dout("open fmode %d wants %s\n", fmode, ceph_cap_string(wanted)); + req = prepare_open_request(inode->i_sb, flags, 0); + if (IS_ERR(req)) { + err = PTR_ERR(req); + goto out; + } + req->r_inode = igrab(inode); + req->r_num_caps = 1; + err = ceph_mdsc_do_request(mdsc, parent_inode, req); + if (!err) + err = ceph_init_file(inode, file, req->r_fmode); + ceph_mdsc_put_request(req); + dout("open result=%d on %llx.%llx\n", err, ceph_vinop(inode)); +out: + return err; +} + + +/* + * Do a lookup + open with a single request. + * + * If this succeeds, but some subsequent check in the vfs + * may_open() fails, the struct *file gets cleaned up (i.e. + * ceph_release gets called). So fear not! + */ +/* + * flags + * path_lookup_open -> LOOKUP_OPEN + * path_lookup_create -> LOOKUP_OPEN|LOOKUP_CREATE + */ +struct dentry *ceph_lookup_open(struct inode *dir, struct dentry *dentry, + struct nameidata *nd, int mode, + int locked_dir) +{ + struct ceph_client *client = ceph_sb_to_client(dir->i_sb); + struct ceph_mds_client *mdsc = &client->mdsc; + struct file *file = nd->intent.open.file; + struct inode *parent_inode = get_dentry_parent_inode(file->f_dentry); + struct ceph_mds_request *req; + int err; + int flags = nd->intent.open.flags - 1; /* silly vfs! */ + + dout("ceph_lookup_open dentry %p '%.*s' flags %d mode 0%o\n", + dentry, dentry->d_name.len, dentry->d_name.name, flags, mode); + + /* do the open */ + req = prepare_open_request(dir->i_sb, flags, mode); + if (IS_ERR(req)) + return ERR_PTR(PTR_ERR(req)); + req->r_dentry = dget(dentry); + req->r_num_caps = 2; + if (flags & O_CREAT) { + req->r_dentry_drop = CEPH_CAP_FILE_SHARED; + req->r_dentry_unless = CEPH_CAP_FILE_EXCL; + } + req->r_locked_dir = dir; /* caller holds dir->i_mutex */ + err = ceph_mdsc_do_request(mdsc, parent_inode, req); + dentry = ceph_finish_lookup(req, dentry, err); + if (!err && (flags & O_CREAT) && !req->r_reply_info.head->is_dentry) + err = ceph_handle_notrace_create(dir, dentry); + if (!err) + err = ceph_init_file(req->r_dentry->d_inode, file, + req->r_fmode); + ceph_mdsc_put_request(req); + dout("ceph_lookup_open result=%p\n", dentry); + return dentry; +} + +int ceph_release(struct inode *inode, struct file *file) +{ + struct ceph_inode_info *ci = ceph_inode(inode); + struct ceph_file_info *cf = file->private_data; + + dout("release inode %p file %p\n", inode, file); + ceph_put_fmode(ci, cf->fmode); + if (cf->last_readdir) + ceph_mdsc_put_request(cf->last_readdir); + kfree(cf->last_name); + kfree(cf->dir_info); + dput(cf->dentry); + kmem_cache_free(ceph_file_cachep, cf); + return 0; +} + +/* + * build a vector of user pages + */ +static struct page **get_direct_page_vector(const char __user *data, + int num_pages, + loff_t off, size_t len) +{ + struct page **pages; + int rc; + + pages = kmalloc(sizeof(*pages) * num_pages, GFP_NOFS); + if (!pages) + return ERR_PTR(-ENOMEM); + + down_read(¤t->mm->mmap_sem); + rc = get_user_pages(current, current->mm, (unsigned long)data, + num_pages, 0, 0, pages, NULL); + up_read(¤t->mm->mmap_sem); + if (rc < 0) + goto fail; + return pages; + +fail: + kfree(pages); + return ERR_PTR(rc); +} + +static void put_page_vector(struct page **pages, int num_pages) +{ + int i; + + for (i = 0; i < num_pages; i++) + put_page(pages[i]); + kfree(pages); +} + +void ceph_release_page_vector(struct page **pages, int num_pages) +{ + int i; + + for (i = 0; i < num_pages; i++) + __free_pages(pages[i], 0); + kfree(pages); +} + +/* + * allocate a vector new pages + */ +static struct page **alloc_page_vector(int num_pages) +{ + struct page **pages; + int i; + + pages = kmalloc(sizeof(*pages) * num_pages, GFP_NOFS); + if (!pages) + return ERR_PTR(-ENOMEM); + for (i = 0; i < num_pages; i++) { + pages[i] = alloc_page(GFP_NOFS); + if (pages[i] == NULL) { + ceph_release_page_vector(pages, i); + return ERR_PTR(-ENOMEM); + } + } + return pages; +} + +/* + * copy user data into a page vector + */ +static int copy_user_to_page_vector(struct page **pages, + const char __user *data, + loff_t off, size_t len) +{ + int i = 0; + int po = off & ~PAGE_CACHE_MASK; + int left = len; + int l, bad; + + while (left > 0) { + l = min_t(int, PAGE_CACHE_SIZE-po, left); + bad = copy_from_user(page_address(pages[i]) + po, data, l); + if (bad == l) + return -EFAULT; + data += l - bad; + left -= l - bad; + if (po) { + po += l - bad; + if (po == PAGE_CACHE_SIZE) + po = 0; + } + } + return len; +} + +/* + * copy user data from a page vector into a user pointer + */ +static int copy_page_vector_to_user(struct page **pages, char __user *data, + loff_t off, size_t len) +{ + int i = 0; + int po = off & ~PAGE_CACHE_MASK; + int left = len; + int l, bad; + + while (left > 0) { + l = min_t(int, left, PAGE_CACHE_SIZE-po); + bad = copy_to_user(data, page_address(pages[i]) + po, l); + if (bad == l) + return -EFAULT; + data += l - bad; + left -= l - bad; + if (po) { + po += l - bad; + if (po == PAGE_CACHE_SIZE) + po = 0; + } + i++; + } + return len; +} + +/* + * Zero an extent within a page vector. Offset is relative to the + * start of the first page. + */ +static void zero_page_vector_range(int off, int len, struct page **pages) +{ + int i = off >> PAGE_CACHE_SHIFT; + + dout("zero_page_vector_page %u~%u\n", off, len); + BUG_ON(len < PAGE_CACHE_SIZE); + + /* leading partial page? */ + if (off & ~PAGE_CACHE_MASK) { + dout("zeroing %d %p head from %d\n", i, pages[i], + (int)(off & ~PAGE_CACHE_MASK)); + zero_user_segment(pages[i], off & ~PAGE_CACHE_MASK, + PAGE_CACHE_SIZE); + off += PAGE_CACHE_SIZE; + off &= PAGE_CACHE_MASK; + i++; + } + while (len >= PAGE_CACHE_SIZE) { + dout("zeroing %d %p\n", i, pages[i]); + zero_user_segment(pages[i], 0, PAGE_CACHE_SIZE); + off += PAGE_CACHE_SIZE; + len -= PAGE_CACHE_SIZE; + i++; + } + /* trailing partial page? */ + if (len) { + dout("zeroing %d %p tail to %d\n", i, pages[i], (int)len); + zero_user_segment(pages[i], 0, len); + } +} + + +/* + * Read a range of bytes striped over one or more objects. Iterate over + * objects we stripe over. (That's not atomic, but good enough for now.) + * + * If we get a short result from the OSD, check against i_size; we need to + * only return a short read to the caller if we hit EOF. + */ +static int striped_read(struct inode *inode, + u64 off, u64 len, + struct page **pages, int num_pages) +{ + struct ceph_client *client = ceph_inode_to_client(inode); + struct ceph_inode_info *ci = ceph_inode(inode); + u64 pos, this_len; + int page_off = off & ~PAGE_CACHE_SIZE; /* first byte's offset in page */ + int left, pages_left; + int read; + struct page **page_pos; + int ret; + bool hit_stripe, was_short; + + /* + * we may need to do multiple reads. not atomic, unfortunately. + */ + pos = off; + left = len; + page_pos = pages; + pages_left = num_pages; + read = 0; + +more: + this_len = left; + ret = ceph_osdc_readpages(&client->osdc, ceph_vino(inode), + &ci->i_layout, pos, &this_len, + ci->i_truncate_seq, + ci->i_truncate_size, + page_pos, pages_left); + hit_stripe = this_len < left; + was_short = ret >= 0 && ret < this_len; + if (ret == -ENOENT) + ret = 0; + dout("striped_read %llu~%u (read %u) got %d%s%s\n", pos, left, read, + ret, hit_stripe ? " HITSTRIPE" : "", was_short ? " SHORT" : ""); + + if (ret > 0) { + int didpages = + ((pos & ~PAGE_CACHE_MASK) + ret) >> PAGE_CACHE_SHIFT; + + if (read < pos - off) { + dout(" zero gap %llu to %llu\n", off + read, pos); + zero_page_vector_range(page_off + read, + pos - off - read, pages); + } + pos += ret; + read = pos - off; + left -= ret; + page_pos += didpages; + pages_left -= didpages; + + /* hit stripe? */ + if (left && hit_stripe) + goto more; + } + + if (was_short) { + /* was original extent fully inside i_size? */ + if (pos + left <= inode->i_size) { + dout("zero tail\n"); + zero_page_vector_range(page_off + read, len - read, + pages); + goto out; + } + + /* check i_size */ + ret = ceph_do_getattr(inode, CEPH_STAT_CAP_SIZE); + if (ret < 0) + goto out; + + /* hit EOF? */ + if (pos >= inode->i_size) + goto out; + + goto more; + } + +out: + if (ret >= 0) + ret = read; + dout("striped_read returns %d\n", ret); + return ret; +} + +/* + * Completely synchronous read and write methods. Direct from __user + * buffer to osd, or directly to user pages (if O_DIRECT). + * + * If the read spans object boundary, just do multiple reads. + */ +static ssize_t ceph_sync_read(struct file *file, char __user *data, + unsigned len, loff_t *poff) +{ + struct inode *inode = file->f_dentry->d_inode; + struct page **pages; + u64 off = *poff; + int num_pages = calc_pages_for(off, len); + int ret; + + dout("sync_read on file %p %llu~%u %s\n", file, off, len, + (file->f_flags & O_DIRECT) ? "O_DIRECT" : ""); + + if (file->f_flags & O_DIRECT) { + pages = get_direct_page_vector(data, num_pages, off, len); + + /* + * flush any page cache pages in this range. this + * will make concurrent normal and O_DIRECT io slow, + * but it will at least behave sensibly when they are + * in sequence. + */ + filemap_write_and_wait(inode->i_mapping); + } else { + pages = alloc_page_vector(num_pages); + } + if (IS_ERR(pages)) + return PTR_ERR(pages); + + ret = striped_read(inode, off, len, pages, num_pages); + + if (ret >= 0 && (file->f_flags & O_DIRECT) == 0) + ret = copy_page_vector_to_user(pages, data, off, ret); + if (ret >= 0) + *poff = off + ret; + + if (file->f_flags & O_DIRECT) + put_page_vector(pages, num_pages); + else + ceph_release_page_vector(pages, num_pages); + dout("sync_read result %d\n", ret); + return ret; +} + +/* + * Write commit callback, called if we requested both an ACK and + * ONDISK commit reply from the OSD. + */ +static void sync_write_commit(struct ceph_osd_request *req, + struct ceph_msg *msg) +{ + struct ceph_inode_info *ci = ceph_inode(req->r_inode); + + dout("sync_write_commit %p tid %llu\n", req, req->r_tid); + spin_lock(&ci->i_unsafe_lock); + list_del_init(&req->r_unsafe_item); + spin_unlock(&ci->i_unsafe_lock); + ceph_put_cap_refs(ci, CEPH_CAP_FILE_WR); +} + +/* + * Synchronous write, straight from __user pointer or user pages (if + * O_DIRECT). + * + * If write spans object boundary, just do multiple writes. (For a + * correct atomic write, we should e.g. take write locks on all + * objects, rollback on failure, etc.) + */ +static ssize_t ceph_sync_write(struct file *file, const char __user *data, + size_t left, loff_t *offset) +{ + struct inode *inode = file->f_dentry->d_inode; + struct ceph_inode_info *ci = ceph_inode(inode); + struct ceph_client *client = ceph_inode_to_client(inode); + struct ceph_osd_request *req; + struct page **pages; + int num_pages; + long long unsigned pos; + u64 len; + int written = 0; + int flags; + int do_sync = 0; + int check_caps = 0; + int ret; + struct timespec mtime = CURRENT_TIME; + + if (ceph_snap(file->f_dentry->d_inode) != CEPH_NOSNAP) + return -EROFS; + + dout("sync_write on file %p %lld~%u %s\n", file, *offset, + (unsigned)left, (file->f_flags & O_DIRECT) ? "O_DIRECT" : ""); + + if (file->f_flags & O_APPEND) + pos = i_size_read(inode); + else + pos = *offset; + + flags = CEPH_OSD_FLAG_ORDERSNAP | + CEPH_OSD_FLAG_ONDISK | + CEPH_OSD_FLAG_WRITE; + if ((file->f_flags & (O_SYNC|O_DIRECT)) == 0) + flags |= CEPH_OSD_FLAG_ACK; + else + do_sync = 1; + + /* + * we may need to do multiple writes here if we span an object + * boundary. this isn't atomic, unfortunately. :( + */ +more: + len = left; + req = ceph_osdc_new_request(&client->osdc, &ci->i_layout, + ceph_vino(inode), pos, &len, + CEPH_OSD_OP_WRITE, flags, + ci->i_snap_realm->cached_context, + do_sync, + ci->i_truncate_seq, ci->i_truncate_size, + &mtime, false, 2); + if (IS_ERR(req)) + return PTR_ERR(req); + + num_pages = calc_pages_for(pos, len); + + if (file->f_flags & O_DIRECT) { + pages = get_direct_page_vector(data, num_pages, pos, len); + if (IS_ERR(pages)) { + ret = PTR_ERR(pages); + goto out; + } + + /* + * throw out any page cache pages in this range. this + * may block. + */ + truncate_inode_pages_range(inode->i_mapping, pos, pos+len); + } else { + pages = alloc_page_vector(num_pages); + if (IS_ERR(pages)) { + ret = PTR_ERR(pages); + goto out; + } + ret = copy_user_to_page_vector(pages, data, pos, len); + if (ret < 0) { + ceph_release_page_vector(pages, num_pages); + goto out; + } + + if ((file->f_flags & O_SYNC) == 0) { + /* get a second commit callback */ + req->r_safe_callback = sync_write_commit; + req->r_own_pages = 1; + } + } + req->r_pages = pages; + req->r_num_pages = num_pages; + req->r_inode = inode; + + ret = ceph_osdc_start_request(&client->osdc, req, false); + if (!ret) { + if (req->r_safe_callback) { + /* + * Add to inode unsafe list only after we + * start_request so that a tid has been assigned. + */ + spin_lock(&ci->i_unsafe_lock); + list_add(&ci->i_unsafe_writes, &req->r_unsafe_item); + spin_unlock(&ci->i_unsafe_lock); + ceph_get_cap_refs(ci, CEPH_CAP_FILE_WR); + } + ret = ceph_osdc_wait_request(&client->osdc, req); + } + + if (file->f_flags & O_DIRECT) + put_page_vector(pages, num_pages); + else if (file->f_flags & O_SYNC) + ceph_release_page_vector(pages, num_pages); + +out: + ceph_osdc_put_request(req); + if (ret == 0) { + pos += len; + written += len; + left -= len; + if (left) + goto more; + + ret = written; + *offset = pos; + if (pos > i_size_read(inode)) + check_caps = ceph_inode_set_size(inode, pos); + if (check_caps) + ceph_check_caps(ceph_inode(inode), CHECK_CAPS_AUTHONLY, + NULL); + } + return ret; +} + +/* + * Wrap generic_file_aio_read with checks for cap bits on the inode. + * Atomically grab references, so that those bits are not released + * back to the MDS mid-read. + * + * Hmm, the sync read case isn't actually async... should it be? + */ +static ssize_t ceph_aio_read(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos) +{ + struct file *filp = iocb->ki_filp; + loff_t *ppos = &iocb->ki_pos; + size_t len = iov->iov_len; + struct inode *inode = filp->f_dentry->d_inode; + struct ceph_inode_info *ci = ceph_inode(inode); + ssize_t ret; + int got = 0; + + dout("aio_read %p %llx.%llx %llu~%u trying to get caps on %p\n", + inode, ceph_vinop(inode), pos, (unsigned)len, inode); + __ceph_do_pending_vmtruncate(inode); + ret = ceph_get_caps(ci, CEPH_CAP_FILE_RD, CEPH_CAP_FILE_CACHE, + &got, -1); + if (ret < 0) + goto out; + dout("aio_read %p %llx.%llx %llu~%u got cap refs on %s\n", + inode, ceph_vinop(inode), pos, (unsigned)len, + ceph_cap_string(got)); + + if ((got & CEPH_CAP_FILE_CACHE) == 0 || + (iocb->ki_filp->f_flags & O_DIRECT) || + (inode->i_sb->s_flags & MS_SYNCHRONOUS)) + /* hmm, this isn't really async... */ + ret = ceph_sync_read(filp, iov->iov_base, len, ppos); + else + ret = generic_file_aio_read(iocb, iov, nr_segs, pos); + +out: + dout("aio_read %p %llx.%llx dropping cap refs on %s = %d\n", + inode, ceph_vinop(inode), ceph_cap_string(got), (int)ret); + ceph_put_cap_refs(ci, got); + return ret; +} + +/* + * Take cap references to avoid releasing caps to MDS mid-write. + * + * If we are synchronous, and write with an old snap context, the OSD + * may return EOLDSNAPC. In that case, retry the write.. _after_ + * dropping our cap refs and allowing the pending snap to logically + * complete _before_ this write occurs. + * + * If we are near ENOSPC, write synchronously. + */ +static ssize_t ceph_aio_write(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos) +{ + struct file *file = iocb->ki_filp; + struct inode *inode = file->f_dentry->d_inode; + struct ceph_inode_info *ci = ceph_inode(inode); + struct ceph_osd_client *osdc = &ceph_client(inode->i_sb)->osdc; + loff_t endoff = pos + iov->iov_len; + int got = 0; + int ret; + + if (ceph_snap(inode) != CEPH_NOSNAP) + return -EROFS; + +retry_snap: + if (ceph_osdmap_flag(osdc->osdmap, CEPH_OSDMAP_FULL)) + return -ENOSPC; + __ceph_do_pending_vmtruncate(inode); + dout("aio_write %p %llx.%llx %llu~%u getting caps. i_size %llu\n", + inode, ceph_vinop(inode), pos, (unsigned)iov->iov_len, + inode->i_size); + ret = ceph_get_caps(ci, CEPH_CAP_FILE_WR, CEPH_CAP_FILE_BUFFER, + &got, endoff); + if (ret < 0) + goto out; + + dout("aio_write %p %llx.%llx %llu~%u got cap refs on %s\n", + inode, ceph_vinop(inode), pos, (unsigned)iov->iov_len, + ceph_cap_string(got)); + + if ((got & CEPH_CAP_FILE_BUFFER) == 0 || + (iocb->ki_filp->f_flags & O_DIRECT) || + (inode->i_sb->s_flags & MS_SYNCHRONOUS)) { + ret = ceph_sync_write(file, iov->iov_base, iov->iov_len, + &iocb->ki_pos); + } else { + ret = generic_file_aio_write(iocb, iov, nr_segs, pos); + + if ((ret >= 0 || ret == -EIOCBQUEUED) && + ((file->f_flags & O_SYNC) || IS_SYNC(file->f_mapping->host) + || ceph_osdmap_flag(osdc->osdmap, CEPH_OSDMAP_NEARFULL))) + ret = vfs_fsync_range(file, file->f_path.dentry, + pos, pos + ret - 1, 1); + } + if (ret >= 0) { + spin_lock(&inode->i_lock); + __ceph_mark_dirty_caps(ci, CEPH_CAP_FILE_WR); + spin_unlock(&inode->i_lock); + } + +out: + dout("aio_write %p %llx.%llx %llu~%u dropping cap refs on %s\n", + inode, ceph_vinop(inode), pos, (unsigned)iov->iov_len, + ceph_cap_string(got)); + ceph_put_cap_refs(ci, got); + + if (ret == -EOLDSNAPC) { + dout("aio_write %p %llx.%llx %llu~%u got EOLDSNAPC, retrying\n", + inode, ceph_vinop(inode), pos, (unsigned)iov->iov_len); + goto retry_snap; + } + + return ret; +} + +/* + * llseek. be sure to verify file size on SEEK_END. + */ +static loff_t ceph_llseek(struct file *file, loff_t offset, int origin) +{ + struct inode *inode = file->f_mapping->host; + int ret; + + mutex_lock(&inode->i_mutex); + __ceph_do_pending_vmtruncate(inode); + switch (origin) { + case SEEK_END: + ret = ceph_do_getattr(inode, CEPH_STAT_CAP_SIZE); + if (ret < 0) { + offset = ret; + goto out; + } + offset += inode->i_size; + break; + case SEEK_CUR: + /* + * Here we special-case the lseek(fd, 0, SEEK_CUR) + * position-querying operation. Avoid rewriting the "same" + * f_pos value back to the file because a concurrent read(), + * write() or lseek() might have altered it + */ + if (offset == 0) { + offset = file->f_pos; + goto out; + } + offset += file->f_pos; + break; + } + + if (offset < 0 || offset > inode->i_sb->s_maxbytes) { + offset = -EINVAL; + goto out; + } + + /* Special lock needed here? */ + if (offset != file->f_pos) { + file->f_pos = offset; + file->f_version = 0; + } + +out: + mutex_unlock(&inode->i_mutex); + return offset; +} + +const struct file_operations ceph_file_fops = { + .open = ceph_open, + .release = ceph_release, + .llseek = ceph_llseek, + .read = do_sync_read, + .write = do_sync_write, + .aio_read = ceph_aio_read, + .aio_write = ceph_aio_write, + .mmap = ceph_mmap, + .fsync = ceph_fsync, + .splice_read = generic_file_splice_read, + .splice_write = generic_file_splice_write, + .unlocked_ioctl = ceph_ioctl, + .compat_ioctl = ceph_ioctl, +}; + -- cgit v0.10.2 From 1d3576fd10f0d7a104204267b81cf84a07028dad Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 6 Oct 2009 11:31:09 -0700 Subject: ceph: address space operations The ceph address space methods are concerned primarily with managing the dirty page accounting in the inode, which (among other things) must keep track of which snapshot context each page was dirtied in, and ensure that dirty data is written out to the OSDs in snapshort order. A writepage() on a page that is not currently writeable due to snapshot writeback ordering constraints is ignored (it was presumably called from kswapd). Signed-off-by: Sage Weil diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c new file mode 100644 index 0000000..c7d673f --- /dev/null +++ b/fs/ceph/addr.c @@ -0,0 +1,1115 @@ +#include "ceph_debug.h" + +#include +#include +#include +#include +#include /* generic_writepages */ +#include +#include + +#include "super.h" +#include "osd_client.h" + +/* + * Ceph address space ops. + * + * There are a few funny things going on here. + * + * The page->private field is used to reference a struct + * ceph_snap_context for _every_ dirty page. This indicates which + * snapshot the page was logically dirtied in, and thus which snap + * context needs to be associated with the osd write during writeback. + * + * Similarly, struct ceph_inode_info maintains a set of counters to + * count dirty pages on the inode. In the absense of snapshots, + * i_wrbuffer_ref == i_wrbuffer_ref_head == the dirty page count. + * + * When a snapshot is taken (that is, when the client receives + * notification that a snapshot was taken), each inode with caps and + * with dirty pages (dirty pages implies there is a cap) gets a new + * ceph_cap_snap in the i_cap_snaps list (which is sorted in ascending + * order, new snaps go to the tail). The i_wrbuffer_ref_head count is + * moved to capsnap->dirty. (Unless a sync write is currently in + * progress. In that case, the capsnap is said to be "pending", new + * writes cannot start, and the capsnap isn't "finalized" until the + * write completes (or fails) and a final size/mtime for the inode for + * that snap can be settled upon.) i_wrbuffer_ref_head is reset to 0. + * + * On writeback, we must submit writes to the osd IN SNAP ORDER. So, + * we look for the first capsnap in i_cap_snaps and write out pages in + * that snap context _only_. Then we move on to the next capsnap, + * eventually reaching the "live" or "head" context (i.e., pages that + * are not yet snapped) and are writing the most recently dirtied + * pages. + * + * Invalidate and so forth must take care to ensure the dirty page + * accounting is preserved. + */ + + +/* + * Dirty a page. Optimistically adjust accounting, on the assumption + * that we won't race with invalidate. If we do, readjust. + */ +static int ceph_set_page_dirty(struct page *page) +{ + struct address_space *mapping = page->mapping; + struct inode *inode; + struct ceph_inode_info *ci; + int undo = 0; + struct ceph_snap_context *snapc; + + if (unlikely(!mapping)) + return !TestSetPageDirty(page); + + if (TestSetPageDirty(page)) { + dout("%p set_page_dirty %p idx %lu -- already dirty\n", + mapping->host, page, page->index); + return 0; + } + + inode = mapping->host; + ci = ceph_inode(inode); + + /* + * Note that we're grabbing a snapc ref here without holding + * any locks! + */ + snapc = ceph_get_snap_context(ci->i_snap_realm->cached_context); + + /* dirty the head */ + spin_lock(&inode->i_lock); + if (ci->i_wrbuffer_ref_head == 0) + ci->i_head_snapc = ceph_get_snap_context(snapc); + ++ci->i_wrbuffer_ref_head; + if (ci->i_wrbuffer_ref == 0) + igrab(inode); + ++ci->i_wrbuffer_ref; + dout("%p set_page_dirty %p idx %lu head %d/%d -> %d/%d " + "snapc %p seq %lld (%d snaps)\n", + mapping->host, page, page->index, + ci->i_wrbuffer_ref-1, ci->i_wrbuffer_ref_head-1, + ci->i_wrbuffer_ref, ci->i_wrbuffer_ref_head, + snapc, snapc->seq, snapc->num_snaps); + spin_unlock(&inode->i_lock); + + /* now adjust page */ + spin_lock_irq(&mapping->tree_lock); + if (page->mapping) { /* Race with truncate? */ + WARN_ON_ONCE(!PageUptodate(page)); + + if (mapping_cap_account_dirty(mapping)) { + __inc_zone_page_state(page, NR_FILE_DIRTY); + __inc_bdi_stat(mapping->backing_dev_info, + BDI_RECLAIMABLE); + task_io_account_write(PAGE_CACHE_SIZE); + } + radix_tree_tag_set(&mapping->page_tree, + page_index(page), PAGECACHE_TAG_DIRTY); + + /* + * Reference snap context in page->private. Also set + * PagePrivate so that we get invalidatepage callback. + */ + page->private = (unsigned long)snapc; + SetPagePrivate(page); + } else { + dout("ANON set_page_dirty %p (raced truncate?)\n", page); + undo = 1; + } + + spin_unlock_irq(&mapping->tree_lock); + + if (undo) + /* whoops, we failed to dirty the page */ + ceph_put_wrbuffer_cap_refs(ci, 1, snapc); + + __mark_inode_dirty(mapping->host, I_DIRTY_PAGES); + + BUG_ON(!PageDirty(page)); + return 1; +} + +/* + * If we are truncating the full page (i.e. offset == 0), adjust the + * dirty page counters appropriately. Only called if there is private + * data on the page. + */ +static void ceph_invalidatepage(struct page *page, unsigned long offset) +{ + struct inode *inode = page->mapping->host; + struct ceph_inode_info *ci; + struct ceph_snap_context *snapc = (void *)page->private; + + BUG_ON(!PageLocked(page)); + BUG_ON(!page->private); + BUG_ON(!PagePrivate(page)); + BUG_ON(!page->mapping); + + /* + * We can get non-dirty pages here due to races between + * set_page_dirty and truncate_complete_page; just spit out a + * warning, in case we end up with accounting problems later. + */ + if (!PageDirty(page)) + pr_err("%p invalidatepage %p page not dirty\n", inode, page); + + if (offset == 0) + ClearPageChecked(page); + + ci = ceph_inode(inode); + if (offset == 0) { + dout("%p invalidatepage %p idx %lu full dirty page %lu\n", + inode, page, page->index, offset); + ceph_put_wrbuffer_cap_refs(ci, 1, snapc); + ceph_put_snap_context(snapc); + page->private = 0; + ClearPagePrivate(page); + } else { + dout("%p invalidatepage %p idx %lu partial dirty page\n", + inode, page, page->index); + } +} + +/* just a sanity check */ +static int ceph_releasepage(struct page *page, gfp_t g) +{ + struct inode *inode = page->mapping ? page->mapping->host : NULL; + dout("%p releasepage %p idx %lu\n", inode, page, page->index); + WARN_ON(PageDirty(page)); + WARN_ON(page->private); + WARN_ON(PagePrivate(page)); + return 0; +} + +/* + * read a single page, without unlocking it. + */ +static int readpage_nounlock(struct file *filp, struct page *page) +{ + struct inode *inode = filp->f_dentry->d_inode; + struct ceph_inode_info *ci = ceph_inode(inode); + struct ceph_osd_client *osdc = &ceph_inode_to_client(inode)->osdc; + int err = 0; + u64 len = PAGE_CACHE_SIZE; + + dout("readpage inode %p file %p page %p index %lu\n", + inode, filp, page, page->index); + err = ceph_osdc_readpages(osdc, ceph_vino(inode), &ci->i_layout, + page->index << PAGE_CACHE_SHIFT, &len, + ci->i_truncate_seq, ci->i_truncate_size, + &page, 1); + if (err == -ENOENT) + err = 0; + if (err < 0) { + SetPageError(page); + goto out; + } else if (err < PAGE_CACHE_SIZE) { + /* zero fill remainder of page */ + zero_user_segment(page, err, PAGE_CACHE_SIZE); + } + SetPageUptodate(page); + +out: + return err < 0 ? err : 0; +} + +static int ceph_readpage(struct file *filp, struct page *page) +{ + int r = readpage_nounlock(filp, page); + unlock_page(page); + return r; +} + +/* + * Build a vector of contiguous pages from the provided page list. + */ +static struct page **page_vector_from_list(struct list_head *page_list, + unsigned *nr_pages) +{ + struct page **pages; + struct page *page; + int next_index, contig_pages = 0; + + /* build page vector */ + pages = kmalloc(sizeof(*pages) * *nr_pages, GFP_NOFS); + if (!pages) + return ERR_PTR(-ENOMEM); + + BUG_ON(list_empty(page_list)); + next_index = list_entry(page_list->prev, struct page, lru)->index; + list_for_each_entry_reverse(page, page_list, lru) { + if (page->index == next_index) { + dout("readpages page %d %p\n", contig_pages, page); + pages[contig_pages] = page; + contig_pages++; + next_index++; + } else { + break; + } + } + *nr_pages = contig_pages; + return pages; +} + +/* + * Read multiple pages. Leave pages we don't read + unlock in page_list; + * the caller (VM) cleans them up. + */ +static int ceph_readpages(struct file *file, struct address_space *mapping, + struct list_head *page_list, unsigned nr_pages) +{ + struct inode *inode = file->f_dentry->d_inode; + struct ceph_inode_info *ci = ceph_inode(inode); + struct ceph_osd_client *osdc = &ceph_inode_to_client(inode)->osdc; + int rc = 0; + struct page **pages; + struct pagevec pvec; + loff_t offset; + u64 len; + + dout("readpages %p file %p nr_pages %d\n", + inode, file, nr_pages); + + pages = page_vector_from_list(page_list, &nr_pages); + if (IS_ERR(pages)) + return PTR_ERR(pages); + + /* guess read extent */ + offset = pages[0]->index << PAGE_CACHE_SHIFT; + len = nr_pages << PAGE_CACHE_SHIFT; + rc = ceph_osdc_readpages(osdc, ceph_vino(inode), &ci->i_layout, + offset, &len, + ci->i_truncate_seq, ci->i_truncate_size, + pages, nr_pages); + if (rc == -ENOENT) + rc = 0; + if (rc < 0) + goto out; + + /* set uptodate and add to lru in pagevec-sized chunks */ + pagevec_init(&pvec, 0); + for (; !list_empty(page_list) && len > 0; + rc -= PAGE_CACHE_SIZE, len -= PAGE_CACHE_SIZE) { + struct page *page = + list_entry(page_list->prev, struct page, lru); + + list_del(&page->lru); + + if (rc < (int)PAGE_CACHE_SIZE) { + /* zero (remainder of) page */ + int s = rc < 0 ? 0 : rc; + zero_user_segment(page, s, PAGE_CACHE_SIZE); + } + + if (add_to_page_cache(page, mapping, page->index, GFP_NOFS)) { + page_cache_release(page); + dout("readpages %p add_to_page_cache failed %p\n", + inode, page); + continue; + } + dout("readpages %p adding %p idx %lu\n", inode, page, + page->index); + flush_dcache_page(page); + SetPageUptodate(page); + unlock_page(page); + if (pagevec_add(&pvec, page) == 0) + pagevec_lru_add_file(&pvec); /* add to lru */ + } + pagevec_lru_add_file(&pvec); + rc = 0; + +out: + kfree(pages); + return rc; +} + +/* + * Get ref for the oldest snapc for an inode with dirty data... that is, the + * only snap context we are allowed to write back. + * + * Caller holds i_lock. + */ +static struct ceph_snap_context *__get_oldest_context(struct inode *inode, + u64 *snap_size) +{ + struct ceph_inode_info *ci = ceph_inode(inode); + struct ceph_snap_context *snapc = NULL; + struct ceph_cap_snap *capsnap = NULL; + + list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) { + dout(" cap_snap %p snapc %p has %d dirty pages\n", capsnap, + capsnap->context, capsnap->dirty_pages); + if (capsnap->dirty_pages) { + snapc = ceph_get_snap_context(capsnap->context); + if (snap_size) + *snap_size = capsnap->size; + break; + } + } + if (!snapc && ci->i_snap_realm) { + snapc = ceph_get_snap_context(ci->i_snap_realm->cached_context); + dout(" head snapc %p has %d dirty pages\n", + snapc, ci->i_wrbuffer_ref_head); + } + return snapc; +} + +static struct ceph_snap_context *get_oldest_context(struct inode *inode, + u64 *snap_size) +{ + struct ceph_snap_context *snapc = NULL; + + spin_lock(&inode->i_lock); + snapc = __get_oldest_context(inode, snap_size); + spin_unlock(&inode->i_lock); + return snapc; +} + +/* + * Write a single page, but leave the page locked. + * + * If we get a write error, set the page error bit, but still adjust the + * dirty page accounting (i.e., page is no longer dirty). + */ +static int writepage_nounlock(struct page *page, struct writeback_control *wbc) +{ + struct inode *inode; + struct ceph_inode_info *ci; + struct ceph_osd_client *osdc; + loff_t page_off = page->index << PAGE_CACHE_SHIFT; + int len = PAGE_CACHE_SIZE; + loff_t i_size; + int err = 0; + struct ceph_snap_context *snapc; + u64 snap_size = 0; + + dout("writepage %p idx %lu\n", page, page->index); + + if (!page->mapping || !page->mapping->host) { + dout("writepage %p - no mapping\n", page); + return -EFAULT; + } + inode = page->mapping->host; + ci = ceph_inode(inode); + osdc = &ceph_inode_to_client(inode)->osdc; + + /* verify this is a writeable snap context */ + snapc = (void *)page->private; + if (snapc == NULL) { + dout("writepage %p page %p not dirty?\n", inode, page); + goto out; + } + if (snapc != get_oldest_context(inode, &snap_size)) { + dout("writepage %p page %p snapc %p not writeable - noop\n", + inode, page, (void *)page->private); + /* we should only noop if called by kswapd */ + WARN_ON((current->flags & PF_MEMALLOC) == 0); + goto out; + } + + /* is this a partial page at end of file? */ + if (snap_size) + i_size = snap_size; + else + i_size = i_size_read(inode); + if (i_size < page_off + len) + len = i_size - page_off; + + dout("writepage %p page %p index %lu on %llu~%u\n", + inode, page, page->index, page_off, len); + + set_page_writeback(page); + err = ceph_osdc_writepages(osdc, ceph_vino(inode), + &ci->i_layout, snapc, + page_off, len, + ci->i_truncate_seq, ci->i_truncate_size, + &inode->i_mtime, + &page, 1, 0, 0, true); + if (err < 0) { + dout("writepage setting page/mapping error %d %p\n", err, page); + SetPageError(page); + mapping_set_error(&inode->i_data, err); + if (wbc) + wbc->pages_skipped++; + } else { + dout("writepage cleaned page %p\n", page); + err = 0; /* vfs expects us to return 0 */ + } + page->private = 0; + ClearPagePrivate(page); + end_page_writeback(page); + ceph_put_wrbuffer_cap_refs(ci, 1, snapc); + ceph_put_snap_context(snapc); +out: + return err; +} + +static int ceph_writepage(struct page *page, struct writeback_control *wbc) +{ + int err = writepage_nounlock(page, wbc); + unlock_page(page); + return err; +} + + +/* + * lame release_pages helper. release_pages() isn't exported to + * modules. + */ +static void ceph_release_pages(struct page **pages, int num) +{ + struct pagevec pvec; + int i; + + pagevec_init(&pvec, 0); + for (i = 0; i < num; i++) { + if (pagevec_add(&pvec, pages[i]) == 0) + pagevec_release(&pvec); + } + pagevec_release(&pvec); +} + + +/* + * async writeback completion handler. + * + * If we get an error, set the mapping error bit, but not the individual + * page error bits. + */ +static void writepages_finish(struct ceph_osd_request *req, + struct ceph_msg *msg) +{ + struct inode *inode = req->r_inode; + struct ceph_osd_reply_head *replyhead; + struct ceph_osd_op *op; + struct ceph_inode_info *ci = ceph_inode(inode); + unsigned wrote; + loff_t offset = req->r_pages[0]->index << PAGE_CACHE_SHIFT; + struct page *page; + int i; + struct ceph_snap_context *snapc = req->r_snapc; + struct address_space *mapping = inode->i_mapping; + struct writeback_control *wbc = req->r_wbc; + __s32 rc = -EIO; + u64 bytes = 0; + + /* parse reply */ + replyhead = msg->front.iov_base; + WARN_ON(le32_to_cpu(replyhead->num_ops) == 0); + op = (void *)(replyhead + 1); + rc = le32_to_cpu(replyhead->result); + bytes = le64_to_cpu(op->extent.length); + + if (rc >= 0) { + wrote = (bytes + (offset & ~PAGE_CACHE_MASK) + ~PAGE_CACHE_MASK) + >> PAGE_CACHE_SHIFT; + WARN_ON(wrote != req->r_num_pages); + } else { + wrote = 0; + mapping_set_error(mapping, rc); + } + dout("writepages_finish %p rc %d bytes %llu wrote %d (pages)\n", + inode, rc, bytes, wrote); + + /* clean all pages */ + for (i = 0; i < req->r_num_pages; i++) { + page = req->r_pages[i]; + BUG_ON(!page); + WARN_ON(!PageUptodate(page)); + + if (i >= wrote) { + dout("inode %p skipping page %p\n", inode, page); + wbc->pages_skipped++; + } + page->private = 0; + ClearPagePrivate(page); + ceph_put_snap_context(snapc); + dout("unlocking %d %p\n", i, page); + end_page_writeback(page); + unlock_page(page); + } + dout("%p wrote+cleaned %d pages\n", inode, wrote); + ceph_put_wrbuffer_cap_refs(ci, req->r_num_pages, snapc); + + ceph_release_pages(req->r_pages, req->r_num_pages); + if (req->r_pages_from_pool) + mempool_free(req->r_pages, + ceph_client(inode->i_sb)->wb_pagevec_pool); + else + kfree(req->r_pages); + ceph_osdc_put_request(req); +} + +/* + * allocate a page vec, either directly, or if necessary, via a the + * mempool. we avoid the mempool if we can because req->r_num_pages + * may be less than the maximum write size. + */ +static void alloc_page_vec(struct ceph_client *client, + struct ceph_osd_request *req) +{ + req->r_pages = kmalloc(sizeof(struct page *) * req->r_num_pages, + GFP_NOFS); + if (!req->r_pages) { + req->r_pages = mempool_alloc(client->wb_pagevec_pool, GFP_NOFS); + req->r_pages_from_pool = 1; + WARN_ON(!req->r_pages); + } +} + +/* + * initiate async writeback + */ +static int ceph_writepages_start(struct address_space *mapping, + struct writeback_control *wbc) +{ + struct inode *inode = mapping->host; + struct backing_dev_info *bdi = mapping->backing_dev_info; + struct ceph_inode_info *ci = ceph_inode(inode); + struct ceph_client *client = ceph_inode_to_client(inode); + pgoff_t index, start, end; + int range_whole = 0; + int should_loop = 1; + pgoff_t max_pages = 0, max_pages_ever = 0; + struct ceph_snap_context *snapc = NULL, *last_snapc = NULL; + struct pagevec pvec; + int done = 0; + int rc = 0; + unsigned wsize = 1 << inode->i_blkbits; + struct ceph_osd_request *req = NULL; + int do_sync; + u64 snap_size = 0; + + /* + * Include a 'sync' in the OSD request if this is a data + * integrity write (e.g., O_SYNC write or fsync()), or if our + * cap is being revoked. + */ + do_sync = wbc->sync_mode == WB_SYNC_ALL; + if (ceph_caps_revoking(ci, CEPH_CAP_FILE_BUFFER)) + do_sync = 1; + dout("writepages_start %p dosync=%d (mode=%s)\n", + inode, do_sync, + wbc->sync_mode == WB_SYNC_NONE ? "NONE" : + (wbc->sync_mode == WB_SYNC_ALL ? "ALL" : "HOLD")); + + client = ceph_inode_to_client(inode); + if (client->mount_state == CEPH_MOUNT_SHUTDOWN) { + pr_warning("writepage_start %p on forced umount\n", inode); + return -EIO; /* we're in a forced umount, don't write! */ + } + if (client->mount_args.wsize && client->mount_args.wsize < wsize) + wsize = client->mount_args.wsize; + if (wsize < PAGE_CACHE_SIZE) + wsize = PAGE_CACHE_SIZE; + max_pages_ever = wsize >> PAGE_CACHE_SHIFT; + + pagevec_init(&pvec, 0); + + /* ?? */ + if (wbc->nonblocking && bdi_write_congested(bdi)) { + dout(" writepages congested\n"); + wbc->encountered_congestion = 1; + goto out_final; + } + + /* where to start/end? */ + if (wbc->range_cyclic) { + start = mapping->writeback_index; /* Start from prev offset */ + end = -1; + dout(" cyclic, start at %lu\n", start); + } else { + start = wbc->range_start >> PAGE_CACHE_SHIFT; + end = wbc->range_end >> PAGE_CACHE_SHIFT; + if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX) + range_whole = 1; + should_loop = 0; + dout(" not cyclic, %lu to %lu\n", start, end); + } + index = start; + +retry: + /* find oldest snap context with dirty data */ + ceph_put_snap_context(snapc); + snapc = get_oldest_context(inode, &snap_size); + if (!snapc) { + /* hmm, why does writepages get called when there + is no dirty data? */ + dout(" no snap context with dirty data?\n"); + goto out; + } + dout(" oldest snapc is %p seq %lld (%d snaps)\n", + snapc, snapc->seq, snapc->num_snaps); + if (last_snapc && snapc != last_snapc) { + /* if we switched to a newer snapc, restart our scan at the + * start of the original file range. */ + dout(" snapc differs from last pass, restarting at %lu\n", + index); + index = start; + } + last_snapc = snapc; + + while (!done && index <= end) { + unsigned i; + int first; + pgoff_t next; + int pvec_pages, locked_pages; + struct page *page; + int want; + u64 offset, len; + struct ceph_osd_request_head *reqhead; + struct ceph_osd_op *op; + + next = 0; + locked_pages = 0; + max_pages = max_pages_ever; + +get_more_pages: + first = -1; + want = min(end - index, + min((pgoff_t)PAGEVEC_SIZE, + max_pages - (pgoff_t)locked_pages) - 1) + + 1; + pvec_pages = pagevec_lookup_tag(&pvec, mapping, &index, + PAGECACHE_TAG_DIRTY, + want); + dout("pagevec_lookup_tag got %d\n", pvec_pages); + if (!pvec_pages && !locked_pages) + break; + for (i = 0; i < pvec_pages && locked_pages < max_pages; i++) { + page = pvec.pages[i]; + dout("? %p idx %lu\n", page, page->index); + if (locked_pages == 0) + lock_page(page); /* first page */ + else if (!trylock_page(page)) + break; + + /* only dirty pages, or our accounting breaks */ + if (unlikely(!PageDirty(page)) || + unlikely(page->mapping != mapping)) { + dout("!dirty or !mapping %p\n", page); + unlock_page(page); + break; + } + if (!wbc->range_cyclic && page->index > end) { + dout("end of range %p\n", page); + done = 1; + unlock_page(page); + break; + } + if (next && (page->index != next)) { + dout("not consecutive %p\n", page); + unlock_page(page); + break; + } + if (wbc->sync_mode != WB_SYNC_NONE) { + dout("waiting on writeback %p\n", page); + wait_on_page_writeback(page); + } + if ((snap_size && page_offset(page) > snap_size) || + (!snap_size && + page_offset(page) > i_size_read(inode))) { + dout("%p page eof %llu\n", page, snap_size ? + snap_size : i_size_read(inode)); + done = 1; + unlock_page(page); + break; + } + if (PageWriteback(page)) { + dout("%p under writeback\n", page); + unlock_page(page); + break; + } + + /* only if matching snap context */ + if (snapc != (void *)page->private) { + dout("page snapc %p != oldest %p\n", + (void *)page->private, snapc); + unlock_page(page); + if (!locked_pages) + continue; /* keep looking for snap */ + break; + } + + if (!clear_page_dirty_for_io(page)) { + dout("%p !clear_page_dirty_for_io\n", page); + unlock_page(page); + break; + } + + /* ok */ + if (locked_pages == 0) { + /* prepare async write request */ + offset = page->index << PAGE_CACHE_SHIFT; + len = wsize; + req = ceph_osdc_new_request(&client->osdc, + &ci->i_layout, + ceph_vino(inode), + offset, &len, + CEPH_OSD_OP_WRITE, + CEPH_OSD_FLAG_WRITE | + CEPH_OSD_FLAG_ONDISK, + snapc, do_sync, + ci->i_truncate_seq, + ci->i_truncate_size, + &inode->i_mtime, true, 1); + max_pages = req->r_num_pages; + + alloc_page_vec(client, req); + req->r_callback = writepages_finish; + req->r_inode = inode; + req->r_wbc = wbc; + } + + /* note position of first page in pvec */ + if (first < 0) + first = i; + dout("%p will write page %p idx %lu\n", + inode, page, page->index); + set_page_writeback(page); + req->r_pages[locked_pages] = page; + locked_pages++; + next = page->index + 1; + } + + /* did we get anything? */ + if (!locked_pages) + goto release_pvec_pages; + if (i) { + int j; + BUG_ON(!locked_pages || first < 0); + + if (pvec_pages && i == pvec_pages && + locked_pages < max_pages) { + dout("reached end pvec, trying for more\n"); + pagevec_reinit(&pvec); + goto get_more_pages; + } + + /* shift unused pages over in the pvec... we + * will need to release them below. */ + for (j = i; j < pvec_pages; j++) { + dout(" pvec leftover page %p\n", + pvec.pages[j]); + pvec.pages[j-i+first] = pvec.pages[j]; + } + pvec.nr -= i-first; + } + + /* submit the write */ + offset = req->r_pages[0]->index << PAGE_CACHE_SHIFT; + len = min((snap_size ? snap_size : i_size_read(inode)) - offset, + (u64)locked_pages << PAGE_CACHE_SHIFT); + dout("writepages got %d pages at %llu~%llu\n", + locked_pages, offset, len); + + /* revise final length, page count */ + req->r_num_pages = locked_pages; + reqhead = req->r_request->front.iov_base; + op = (void *)(reqhead + 1); + op->extent.length = cpu_to_le64(len); + op->payload_len = cpu_to_le32(len); + req->r_request->hdr.data_len = cpu_to_le32(len); + + ceph_osdc_start_request(&client->osdc, req, true); + req = NULL; + + /* continue? */ + index = next; + wbc->nr_to_write -= locked_pages; + if (wbc->nr_to_write <= 0) + done = 1; + +release_pvec_pages: + dout("pagevec_release on %d pages (%p)\n", (int)pvec.nr, + pvec.nr ? pvec.pages[0] : NULL); + pagevec_release(&pvec); + + if (locked_pages && !done) + goto retry; + } + + if (should_loop && !done) { + /* more to do; loop back to beginning of file */ + dout("writepages looping back to beginning of file\n"); + should_loop = 0; + index = 0; + goto retry; + } + + if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0)) + mapping->writeback_index = index; + +out: + if (req) + ceph_osdc_put_request(req); + if (rc > 0) + rc = 0; /* vfs expects us to return 0 */ + ceph_put_snap_context(snapc); + dout("writepages done, rc = %d\n", rc); +out_final: + return rc; +} + + + +/* + * See if a given @snapc is either writeable, or already written. + */ +static int context_is_writeable_or_written(struct inode *inode, + struct ceph_snap_context *snapc) +{ + struct ceph_snap_context *oldest = get_oldest_context(inode, NULL); + return !oldest || snapc->seq <= oldest->seq; +} + +/* + * We are only allowed to write into/dirty the page if the page is + * clean, or already dirty within the same snap context. + */ +static int ceph_write_begin(struct file *file, struct address_space *mapping, + loff_t pos, unsigned len, unsigned flags, + struct page **pagep, void **fsdata) +{ + struct inode *inode = file->f_dentry->d_inode; + struct ceph_inode_info *ci = ceph_inode(inode); + struct ceph_mds_client *mdsc = &ceph_inode_to_client(inode)->mdsc; + struct page *page; + pgoff_t index = pos >> PAGE_CACHE_SHIFT; + loff_t page_off = pos & PAGE_CACHE_MASK; + int pos_in_page = pos & ~PAGE_CACHE_MASK; + int end_in_page = pos_in_page + len; + loff_t i_size; + struct ceph_snap_context *snapc; + int r; + + /* get a page*/ +retry: + page = grab_cache_page_write_begin(mapping, index, 0); + if (!page) + return -ENOMEM; + *pagep = page; + + dout("write_begin file %p inode %p page %p %d~%d\n", file, + inode, page, (int)pos, (int)len); + +retry_locked: + /* writepages currently holds page lock, but if we change that later, */ + wait_on_page_writeback(page); + + /* check snap context */ + BUG_ON(!ci->i_snap_realm); + down_read(&mdsc->snap_rwsem); + BUG_ON(!ci->i_snap_realm->cached_context); + if (page->private && + (void *)page->private != ci->i_snap_realm->cached_context) { + /* + * this page is already dirty in another (older) snap + * context! is it writeable now? + */ + snapc = get_oldest_context(inode, NULL); + up_read(&mdsc->snap_rwsem); + + if (snapc != (void *)page->private) { + dout(" page %p snapc %p not current or oldest\n", + page, (void *)page->private); + /* + * queue for writeback, and wait for snapc to + * be writeable or written + */ + snapc = ceph_get_snap_context((void *)page->private); + unlock_page(page); + if (ceph_queue_writeback(inode)) + igrab(inode); + wait_event_interruptible(ci->i_cap_wq, + context_is_writeable_or_written(inode, snapc)); + ceph_put_snap_context(snapc); + goto retry; + } + + /* yay, writeable, do it now (without dropping page lock) */ + dout(" page %p snapc %p not current, but oldest\n", + page, snapc); + if (!clear_page_dirty_for_io(page)) + goto retry_locked; + r = writepage_nounlock(page, NULL); + if (r < 0) + goto fail_nosnap; + goto retry_locked; + } + + if (PageUptodate(page)) { + dout(" page %p already uptodate\n", page); + return 0; + } + + /* full page? */ + if (pos_in_page == 0 && len == PAGE_CACHE_SIZE) + return 0; + + /* past end of file? */ + i_size = inode->i_size; /* caller holds i_mutex */ + + if (i_size + len > inode->i_sb->s_maxbytes) { + /* file is too big */ + r = -EINVAL; + goto fail; + } + + if (page_off >= i_size || + (pos_in_page == 0 && (pos+len) >= i_size && + end_in_page - pos_in_page != PAGE_CACHE_SIZE)) { + dout(" zeroing %p 0 - %d and %d - %d\n", + page, pos_in_page, end_in_page, (int)PAGE_CACHE_SIZE); + zero_user_segments(page, + 0, pos_in_page, + end_in_page, PAGE_CACHE_SIZE); + return 0; + } + + /* we need to read it. */ + up_read(&mdsc->snap_rwsem); + r = readpage_nounlock(file, page); + if (r < 0) + goto fail_nosnap; + goto retry_locked; + +fail: + up_read(&mdsc->snap_rwsem); +fail_nosnap: + unlock_page(page); + return r; +} + +/* + * we don't do anything in here that simple_write_end doesn't do + * except adjust dirty page accounting and drop read lock on + * mdsc->snap_rwsem. + */ +static int ceph_write_end(struct file *file, struct address_space *mapping, + loff_t pos, unsigned len, unsigned copied, + struct page *page, void *fsdata) +{ + struct inode *inode = file->f_dentry->d_inode; + struct ceph_mds_client *mdsc = &ceph_inode_to_client(inode)->mdsc; + unsigned from = pos & (PAGE_CACHE_SIZE - 1); + int check_cap = 0; + + dout("write_end file %p inode %p page %p %d~%d (%d)\n", file, + inode, page, (int)pos, (int)copied, (int)len); + + /* zero the stale part of the page if we did a short copy */ + if (copied < len) + zero_user_segment(page, from+copied, len); + + /* did file size increase? */ + /* (no need for i_size_read(); we caller holds i_mutex */ + if (pos+copied > inode->i_size) + check_cap = ceph_inode_set_size(inode, pos+copied); + + if (!PageUptodate(page)) + SetPageUptodate(page); + + set_page_dirty(page); + + unlock_page(page); + up_read(&mdsc->snap_rwsem); + page_cache_release(page); + + if (check_cap) + ceph_check_caps(ceph_inode(inode), CHECK_CAPS_AUTHONLY, NULL); + + return copied; +} + +/* + * we set .direct_IO to indicate direct io is supported, but since we + * intercept O_DIRECT reads and writes early, this function should + * never get called. + */ +static ssize_t ceph_direct_io(int rw, struct kiocb *iocb, + const struct iovec *iov, + loff_t pos, unsigned long nr_segs) +{ + WARN_ON(1); + return -EINVAL; +} + +const struct address_space_operations ceph_aops = { + .readpage = ceph_readpage, + .readpages = ceph_readpages, + .writepage = ceph_writepage, + .writepages = ceph_writepages_start, + .write_begin = ceph_write_begin, + .write_end = ceph_write_end, + .set_page_dirty = ceph_set_page_dirty, + .invalidatepage = ceph_invalidatepage, + .releasepage = ceph_releasepage, + .direct_IO = ceph_direct_io, +}; + + +/* + * vm ops + */ + +/* + * Reuse write_begin here for simplicity. + */ +static int ceph_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) +{ + struct inode *inode = vma->vm_file->f_dentry->d_inode; + struct page *page = vmf->page; + struct ceph_mds_client *mdsc = &ceph_inode_to_client(inode)->mdsc; + loff_t off = page->index << PAGE_CACHE_SHIFT; + loff_t size, len; + struct page *locked_page = NULL; + void *fsdata = NULL; + int ret; + + size = i_size_read(inode); + if (off + PAGE_CACHE_SIZE <= size) + len = PAGE_CACHE_SIZE; + else + len = size & ~PAGE_CACHE_MASK; + + dout("page_mkwrite %p %llu~%llu page %p idx %lu\n", inode, + off, len, page, page->index); + ret = ceph_write_begin(vma->vm_file, inode->i_mapping, off, len, 0, + &locked_page, &fsdata); + WARN_ON(page != locked_page); + if (!ret) { + /* + * doing the following, instead of calling + * ceph_write_end. Note that we keep the + * page locked + */ + set_page_dirty(page); + up_read(&mdsc->snap_rwsem); + page_cache_release(page); + ret = VM_FAULT_LOCKED; + } else { + ret = VM_FAULT_SIGBUS; + } + dout("page_mkwrite %p %llu~%llu = %d\n", inode, off, len, ret); + return ret; +} + +static struct vm_operations_struct ceph_vmops = { + .fault = filemap_fault, + .page_mkwrite = ceph_page_mkwrite, +}; + +int ceph_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct address_space *mapping = file->f_mapping; + + if (!mapping->a_ops->readpage) + return -ENOEXEC; + file_accessed(file); + vma->vm_ops = &ceph_vmops; + vma->vm_flags |= VM_CAN_NONLINEAR; + return 0; +} -- cgit v0.10.2 From 2f2dc053404febedc9c273452d9d518fb31fde72 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 6 Oct 2009 11:31:09 -0700 Subject: ceph: MDS client The MDS (metadata server) client is responsible for submitting requests to the MDS cluster and parsing the response. We decide which MDS to submit each request to based on cached information about the current partition of the directory hierarchy across the cluster. A stateful session is opened with each MDS before we submit requests to it, and a mutex is used to control the ordering of messages within each session. An MDS request may generate two responses. The first indicates the operation was a success and returns any result. A second reply is sent when the operation commits to disk. Note that locking on the MDS ensures that the results of updates are visible only to the updating client before the operation commits. Requests are linked to the containing directory so that an fsync will wait for them to commit. If an MDS fails and/or recovers, we resubmit requests as needed. We also reconnect existing capabilities to a recovering MDS to reestablish that shared session state. Old dentry leases are invalidated. Signed-off-by: Sage Weil diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c new file mode 100644 index 0000000..de8ba4a --- /dev/null +++ b/fs/ceph/mds_client.c @@ -0,0 +1,2912 @@ +#include "ceph_debug.h" + +#include +#include + +#include "mds_client.h" +#include "mon_client.h" +#include "super.h" +#include "messenger.h" +#include "decode.h" + +/* + * A cluster of MDS (metadata server) daemons is responsible for + * managing the file system namespace (the directory hierarchy and + * inodes) and for coordinating shared access to storage. Metadata is + * partitioning hierarchically across a number of servers, and that + * partition varies over time as the cluster adjusts the distribution + * in order to balance load. + * + * The MDS client is primarily responsible to managing synchronous + * metadata requests for operations like open, unlink, and so forth. + * If there is a MDS failure, we find out about it when we (possibly + * request and) receive a new MDS map, and can resubmit affected + * requests. + * + * For the most part, though, we take advantage of a lossless + * communications channel to the MDS, and do not need to worry about + * timing out or resubmitting requests. + * + * We maintain a stateful "session" with each MDS we interact with. + * Within each session, we sent periodic heartbeat messages to ensure + * any capabilities or leases we have been issues remain valid. If + * the session times out and goes stale, our leases and capabilities + * are no longer valid. + */ + +static void __wake_requests(struct ceph_mds_client *mdsc, + struct list_head *head); + +const static struct ceph_connection_operations mds_con_ops; + + +/* + * mds reply parsing + */ + +/* + * parse individual inode info + */ +static int parse_reply_info_in(void **p, void *end, + struct ceph_mds_reply_info_in *info) +{ + int err = -EIO; + + info->in = *p; + *p += sizeof(struct ceph_mds_reply_inode) + + sizeof(*info->in->fragtree.splits) * + le32_to_cpu(info->in->fragtree.nsplits); + + ceph_decode_32_safe(p, end, info->symlink_len, bad); + ceph_decode_need(p, end, info->symlink_len, bad); + info->symlink = *p; + *p += info->symlink_len; + + ceph_decode_32_safe(p, end, info->xattr_len, bad); + ceph_decode_need(p, end, info->xattr_len, bad); + info->xattr_data = *p; + *p += info->xattr_len; + return 0; +bad: + return err; +} + +/* + * parse a normal reply, which may contain a (dir+)dentry and/or a + * target inode. + */ +static int parse_reply_info_trace(void **p, void *end, + struct ceph_mds_reply_info_parsed *info) +{ + int err; + + if (info->head->is_dentry) { + err = parse_reply_info_in(p, end, &info->diri); + if (err < 0) + goto out_bad; + + if (unlikely(*p + sizeof(*info->dirfrag) > end)) + goto bad; + info->dirfrag = *p; + *p += sizeof(*info->dirfrag) + + sizeof(u32)*le32_to_cpu(info->dirfrag->ndist); + if (unlikely(*p > end)) + goto bad; + + ceph_decode_32_safe(p, end, info->dname_len, bad); + ceph_decode_need(p, end, info->dname_len, bad); + info->dname = *p; + *p += info->dname_len; + info->dlease = *p; + *p += sizeof(*info->dlease); + } + + if (info->head->is_target) { + err = parse_reply_info_in(p, end, &info->targeti); + if (err < 0) + goto out_bad; + } + + if (unlikely(*p != end)) + goto bad; + return 0; + +bad: + err = -EIO; +out_bad: + pr_err("problem parsing mds trace %d\n", err); + return err; +} + +/* + * parse readdir results + */ +static int parse_reply_info_dir(void **p, void *end, + struct ceph_mds_reply_info_parsed *info) +{ + u32 num, i = 0; + int err; + + info->dir_dir = *p; + if (*p + sizeof(*info->dir_dir) > end) + goto bad; + *p += sizeof(*info->dir_dir) + + sizeof(u32)*le32_to_cpu(info->dir_dir->ndist); + if (*p > end) + goto bad; + + ceph_decode_need(p, end, sizeof(num) + 2, bad); + ceph_decode_32(p, num); + ceph_decode_8(p, info->dir_end); + ceph_decode_8(p, info->dir_complete); + if (num == 0) + goto done; + + /* alloc large array */ + info->dir_nr = num; + info->dir_in = kcalloc(num, sizeof(*info->dir_in) + + sizeof(*info->dir_dname) + + sizeof(*info->dir_dname_len) + + sizeof(*info->dir_dlease), + GFP_NOFS); + if (info->dir_in == NULL) { + err = -ENOMEM; + goto out_bad; + } + info->dir_dname = (void *)(info->dir_in + num); + info->dir_dname_len = (void *)(info->dir_dname + num); + info->dir_dlease = (void *)(info->dir_dname_len + num); + + while (num) { + /* dentry */ + ceph_decode_need(p, end, sizeof(u32)*2, bad); + ceph_decode_32(p, info->dir_dname_len[i]); + ceph_decode_need(p, end, info->dir_dname_len[i], bad); + info->dir_dname[i] = *p; + *p += info->dir_dname_len[i]; + dout("parsed dir dname '%.*s'\n", info->dir_dname_len[i], + info->dir_dname[i]); + info->dir_dlease[i] = *p; + *p += sizeof(struct ceph_mds_reply_lease); + + /* inode */ + err = parse_reply_info_in(p, end, &info->dir_in[i]); + if (err < 0) + goto out_bad; + i++; + num--; + } + +done: + if (*p != end) + goto bad; + return 0; + +bad: + err = -EIO; +out_bad: + pr_err("problem parsing dir contents %d\n", err); + return err; +} + +/* + * parse entire mds reply + */ +static int parse_reply_info(struct ceph_msg *msg, + struct ceph_mds_reply_info_parsed *info) +{ + void *p, *end; + u32 len; + int err; + + info->head = msg->front.iov_base; + p = msg->front.iov_base + sizeof(struct ceph_mds_reply_head); + end = p + msg->front.iov_len - sizeof(struct ceph_mds_reply_head); + + /* trace */ + ceph_decode_32_safe(&p, end, len, bad); + if (len > 0) { + err = parse_reply_info_trace(&p, p+len, info); + if (err < 0) + goto out_bad; + } + + /* dir content */ + ceph_decode_32_safe(&p, end, len, bad); + if (len > 0) { + err = parse_reply_info_dir(&p, p+len, info); + if (err < 0) + goto out_bad; + } + + /* snap blob */ + ceph_decode_32_safe(&p, end, len, bad); + info->snapblob_len = len; + info->snapblob = p; + p += len; + + if (p != end) + goto bad; + return 0; + +bad: + err = -EIO; +out_bad: + pr_err("mds parse_reply err %d\n", err); + return err; +} + +static void destroy_reply_info(struct ceph_mds_reply_info_parsed *info) +{ + kfree(info->dir_in); +} + + +/* + * sessions + */ +static const char *session_state_name(int s) +{ + switch (s) { + case CEPH_MDS_SESSION_NEW: return "new"; + case CEPH_MDS_SESSION_OPENING: return "opening"; + case CEPH_MDS_SESSION_OPEN: return "open"; + case CEPH_MDS_SESSION_HUNG: return "hung"; + case CEPH_MDS_SESSION_CLOSING: return "closing"; + case CEPH_MDS_SESSION_RECONNECTING: return "reconnecting"; + default: return "???"; + } +} + +static struct ceph_mds_session *get_session(struct ceph_mds_session *s) +{ + if (atomic_inc_not_zero(&s->s_ref)) { + dout("mdsc get_session %p %d -> %d\n", s, + atomic_read(&s->s_ref)-1, atomic_read(&s->s_ref)); + return s; + } else { + dout("mdsc get_session %p 0 -- FAIL", s); + return NULL; + } +} + +void ceph_put_mds_session(struct ceph_mds_session *s) +{ + dout("mdsc put_session %p %d -> %d\n", s, + atomic_read(&s->s_ref), atomic_read(&s->s_ref)-1); + if (atomic_dec_and_test(&s->s_ref)) { + ceph_con_shutdown(&s->s_con); + kfree(s); + } +} + +/* + * called under mdsc->mutex + */ +struct ceph_mds_session *__ceph_lookup_mds_session(struct ceph_mds_client *mdsc, + int mds) +{ + struct ceph_mds_session *session; + + if (mds >= mdsc->max_sessions || mdsc->sessions[mds] == NULL) + return NULL; + session = mdsc->sessions[mds]; + dout("lookup_mds_session %p %d\n", session, + atomic_read(&session->s_ref)); + get_session(session); + return session; +} + +static bool __have_session(struct ceph_mds_client *mdsc, int mds) +{ + if (mds >= mdsc->max_sessions) + return false; + return mdsc->sessions[mds]; +} + +/* + * create+register a new session for given mds. + * called under mdsc->mutex. + */ +static struct ceph_mds_session *register_session(struct ceph_mds_client *mdsc, + int mds) +{ + struct ceph_mds_session *s; + + s = kzalloc(sizeof(*s), GFP_NOFS); + s->s_mdsc = mdsc; + s->s_mds = mds; + s->s_state = CEPH_MDS_SESSION_NEW; + s->s_ttl = 0; + s->s_seq = 0; + mutex_init(&s->s_mutex); + + ceph_con_init(mdsc->client->msgr, &s->s_con); + s->s_con.private = s; + s->s_con.ops = &mds_con_ops; + s->s_con.peer_name.type = CEPH_ENTITY_TYPE_MDS; + s->s_con.peer_name.num = cpu_to_le64(mds); + ceph_con_open(&s->s_con, ceph_mdsmap_get_addr(mdsc->mdsmap, mds)); + + spin_lock_init(&s->s_cap_lock); + s->s_cap_gen = 0; + s->s_cap_ttl = 0; + s->s_renew_requested = 0; + s->s_renew_seq = 0; + INIT_LIST_HEAD(&s->s_caps); + s->s_nr_caps = 0; + atomic_set(&s->s_ref, 1); + INIT_LIST_HEAD(&s->s_waiting); + INIT_LIST_HEAD(&s->s_unsafe); + s->s_num_cap_releases = 0; + INIT_LIST_HEAD(&s->s_cap_releases); + INIT_LIST_HEAD(&s->s_cap_releases_done); + INIT_LIST_HEAD(&s->s_cap_flushing); + INIT_LIST_HEAD(&s->s_cap_snaps_flushing); + + dout("register_session mds%d\n", mds); + if (mds >= mdsc->max_sessions) { + int newmax = 1 << get_count_order(mds+1); + struct ceph_mds_session **sa; + + dout("register_session realloc to %d\n", newmax); + sa = kcalloc(newmax, sizeof(void *), GFP_NOFS); + if (sa == NULL) + return ERR_PTR(-ENOMEM); + if (mdsc->sessions) { + memcpy(sa, mdsc->sessions, + mdsc->max_sessions * sizeof(void *)); + kfree(mdsc->sessions); + } + mdsc->sessions = sa; + mdsc->max_sessions = newmax; + } + mdsc->sessions[mds] = s; + atomic_inc(&s->s_ref); /* one ref to sessions[], one to caller */ + return s; +} + +/* + * called under mdsc->mutex + */ +static void unregister_session(struct ceph_mds_client *mdsc, int mds) +{ + dout("unregister_session mds%d %p\n", mds, mdsc->sessions[mds]); + ceph_put_mds_session(mdsc->sessions[mds]); + mdsc->sessions[mds] = NULL; +} + +/* + * drop session refs in request. + * + * should be last request ref, or hold mdsc->mutex + */ +static void put_request_session(struct ceph_mds_request *req) +{ + if (req->r_session) { + ceph_put_mds_session(req->r_session); + req->r_session = NULL; + } +} + +void ceph_mdsc_put_request(struct ceph_mds_request *req) +{ + dout("mdsc put_request %p %d -> %d\n", req, + atomic_read(&req->r_ref), atomic_read(&req->r_ref)-1); + if (atomic_dec_and_test(&req->r_ref)) { + if (req->r_request) + ceph_msg_put(req->r_request); + if (req->r_reply) { + ceph_msg_put(req->r_reply); + destroy_reply_info(&req->r_reply_info); + } + if (req->r_inode) { + ceph_put_cap_refs(ceph_inode(req->r_inode), + CEPH_CAP_PIN); + iput(req->r_inode); + } + if (req->r_locked_dir) + ceph_put_cap_refs(ceph_inode(req->r_locked_dir), + CEPH_CAP_PIN); + if (req->r_target_inode) + iput(req->r_target_inode); + if (req->r_dentry) + dput(req->r_dentry); + if (req->r_old_dentry) { + ceph_put_cap_refs( + ceph_inode(req->r_old_dentry->d_parent->d_inode), + CEPH_CAP_PIN); + dput(req->r_old_dentry); + } + kfree(req->r_path1); + kfree(req->r_path2); + put_request_session(req); + ceph_unreserve_caps(&req->r_caps_reservation); + kfree(req); + } +} + +/* + * lookup session, bump ref if found. + * + * called under mdsc->mutex. + */ +static struct ceph_mds_request *__lookup_request(struct ceph_mds_client *mdsc, + u64 tid) +{ + struct ceph_mds_request *req; + req = radix_tree_lookup(&mdsc->request_tree, tid); + if (req) + ceph_mdsc_get_request(req); + return req; +} + +/* + * Register an in-flight request, and assign a tid. Link to directory + * are modifying (if any). + * + * Called under mdsc->mutex. + */ +static void __register_request(struct ceph_mds_client *mdsc, + struct ceph_mds_request *req, + struct inode *dir) +{ + req->r_tid = ++mdsc->last_tid; + if (req->r_num_caps) + ceph_reserve_caps(&req->r_caps_reservation, req->r_num_caps); + dout("__register_request %p tid %lld\n", req, req->r_tid); + ceph_mdsc_get_request(req); + radix_tree_insert(&mdsc->request_tree, req->r_tid, (void *)req); + + if (dir) { + struct ceph_inode_info *ci = ceph_inode(dir); + + spin_lock(&ci->i_unsafe_lock); + req->r_unsafe_dir = dir; + list_add_tail(&req->r_unsafe_dir_item, &ci->i_unsafe_dirops); + spin_unlock(&ci->i_unsafe_lock); + } +} + +static void __unregister_request(struct ceph_mds_client *mdsc, + struct ceph_mds_request *req) +{ + dout("__unregister_request %p tid %lld\n", req, req->r_tid); + radix_tree_delete(&mdsc->request_tree, req->r_tid); + ceph_mdsc_put_request(req); + + if (req->r_unsafe_dir) { + struct ceph_inode_info *ci = ceph_inode(req->r_unsafe_dir); + + spin_lock(&ci->i_unsafe_lock); + list_del_init(&req->r_unsafe_dir_item); + spin_unlock(&ci->i_unsafe_lock); + } +} + +/* + * Choose mds to send request to next. If there is a hint set in the + * request (e.g., due to a prior forward hint from the mds), use that. + * Otherwise, consult frag tree and/or caps to identify the + * appropriate mds. If all else fails, choose randomly. + * + * Called under mdsc->mutex. + */ +static int __choose_mds(struct ceph_mds_client *mdsc, + struct ceph_mds_request *req) +{ + struct inode *inode; + struct ceph_inode_info *ci; + struct ceph_cap *cap; + int mode = req->r_direct_mode; + int mds = -1; + u32 hash = req->r_direct_hash; + bool is_hash = req->r_direct_is_hash; + + /* + * is there a specific mds we should try? ignore hint if we have + * no session and the mds is not up (active or recovering). + */ + if (req->r_resend_mds >= 0 && + (__have_session(mdsc, req->r_resend_mds) || + ceph_mdsmap_get_state(mdsc->mdsmap, req->r_resend_mds) > 0)) { + dout("choose_mds using resend_mds mds%d\n", + req->r_resend_mds); + return req->r_resend_mds; + } + + if (mode == USE_RANDOM_MDS) + goto random; + + inode = NULL; + if (req->r_inode) { + inode = req->r_inode; + } else if (req->r_dentry) { + if (req->r_dentry->d_inode) { + inode = req->r_dentry->d_inode; + } else { + inode = req->r_dentry->d_parent->d_inode; + hash = req->r_dentry->d_name.hash; + is_hash = true; + } + } + dout("__choose_mds %p is_hash=%d (%d) mode %d\n", inode, (int)is_hash, + (int)hash, mode); + if (!inode) + goto random; + ci = ceph_inode(inode); + + if (is_hash && S_ISDIR(inode->i_mode)) { + struct ceph_inode_frag frag; + int found; + + ceph_choose_frag(ci, hash, &frag, &found); + if (found) { + if (mode == USE_ANY_MDS && frag.ndist > 0) { + u8 r; + + /* choose a random replica */ + get_random_bytes(&r, 1); + r %= frag.ndist; + mds = frag.dist[r]; + dout("choose_mds %p %llx.%llx " + "frag %u mds%d (%d/%d)\n", + inode, ceph_vinop(inode), + frag.frag, frag.mds, + (int)r, frag.ndist); + return mds; + } + + /* since this file/dir wasn't known to be + * replicated, then we want to look for the + * authoritative mds. */ + mode = USE_AUTH_MDS; + if (frag.mds >= 0) { + /* choose auth mds */ + mds = frag.mds; + dout("choose_mds %p %llx.%llx " + "frag %u mds%d (auth)\n", + inode, ceph_vinop(inode), frag.frag, mds); + return mds; + } + } + } + + spin_lock(&inode->i_lock); + cap = NULL; + if (mode == USE_AUTH_MDS) + cap = ci->i_auth_cap; + if (!cap && !RB_EMPTY_ROOT(&ci->i_caps)) + cap = rb_entry(rb_first(&ci->i_caps), struct ceph_cap, ci_node); + if (!cap) { + spin_unlock(&inode->i_lock); + goto random; + } + mds = cap->session->s_mds; + dout("choose_mds %p %llx.%llx mds%d (%scap %p)\n", + inode, ceph_vinop(inode), mds, + cap == ci->i_auth_cap ? "auth " : "", cap); + spin_unlock(&inode->i_lock); + return mds; + +random: + mds = ceph_mdsmap_get_random_mds(mdsc->mdsmap); + dout("choose_mds chose random mds%d\n", mds); + return mds; +} + + +/* + * session messages + */ +static struct ceph_msg *create_session_msg(u32 op, u64 seq) +{ + struct ceph_msg *msg; + struct ceph_mds_session_head *h; + + msg = ceph_msg_new(CEPH_MSG_CLIENT_SESSION, sizeof(*h), 0, 0, NULL); + if (IS_ERR(msg)) { + pr_err("create_session_msg ENOMEM creating msg\n"); + return ERR_PTR(PTR_ERR(msg)); + } + h = msg->front.iov_base; + h->op = cpu_to_le32(op); + h->seq = cpu_to_le64(seq); + return msg; +} + +/* + * send session open request. + * + * called under mdsc->mutex + */ +static int __open_session(struct ceph_mds_client *mdsc, + struct ceph_mds_session *session) +{ + struct ceph_msg *msg; + int mstate; + int mds = session->s_mds; + int err = 0; + + /* wait for mds to go active? */ + mstate = ceph_mdsmap_get_state(mdsc->mdsmap, mds); + dout("open_session to mds%d (%s)\n", mds, + ceph_mds_state_name(mstate)); + session->s_state = CEPH_MDS_SESSION_OPENING; + session->s_renew_requested = jiffies; + + /* send connect message */ + msg = create_session_msg(CEPH_SESSION_REQUEST_OPEN, session->s_seq); + if (IS_ERR(msg)) { + err = PTR_ERR(msg); + goto out; + } + ceph_con_send(&session->s_con, msg); + +out: + return 0; +} + +/* + * session caps + */ + +/* + * Free preallocated cap messages assigned to this session + */ +static void cleanup_cap_releases(struct ceph_mds_session *session) +{ + struct ceph_msg *msg; + + spin_lock(&session->s_cap_lock); + while (!list_empty(&session->s_cap_releases)) { + msg = list_first_entry(&session->s_cap_releases, + struct ceph_msg, list_head); + list_del_init(&msg->list_head); + ceph_msg_put(msg); + } + while (!list_empty(&session->s_cap_releases_done)) { + msg = list_first_entry(&session->s_cap_releases_done, + struct ceph_msg, list_head); + list_del_init(&msg->list_head); + ceph_msg_put(msg); + } + spin_unlock(&session->s_cap_lock); +} + +/* + * Helper to safely iterate over all caps associated with a session. + * + * caller must hold session s_mutex + */ +static int iterate_session_caps(struct ceph_mds_session *session, + int (*cb)(struct inode *, struct ceph_cap *, + void *), void *arg) +{ + struct ceph_cap *cap, *ncap; + struct inode *inode; + int ret; + + dout("iterate_session_caps %p mds%d\n", session, session->s_mds); + spin_lock(&session->s_cap_lock); + list_for_each_entry_safe(cap, ncap, &session->s_caps, session_caps) { + inode = igrab(&cap->ci->vfs_inode); + if (!inode) + continue; + spin_unlock(&session->s_cap_lock); + ret = cb(inode, cap, arg); + iput(inode); + if (ret < 0) + return ret; + spin_lock(&session->s_cap_lock); + } + spin_unlock(&session->s_cap_lock); + + return 0; +} + +static int remove_session_caps_cb(struct inode *inode, struct ceph_cap *cap, + void *arg) +{ + struct ceph_inode_info *ci = ceph_inode(inode); + dout("removing cap %p, ci is %p, inode is %p\n", + cap, ci, &ci->vfs_inode); + ceph_remove_cap(cap); + return 0; +} + +/* + * caller must hold session s_mutex + */ +static void remove_session_caps(struct ceph_mds_session *session) +{ + dout("remove_session_caps on %p\n", session); + iterate_session_caps(session, remove_session_caps_cb, NULL); + BUG_ON(session->s_nr_caps > 0); + cleanup_cap_releases(session); +} + +/* + * wake up any threads waiting on this session's caps. if the cap is + * old (didn't get renewed on the client reconnect), remove it now. + * + * caller must hold s_mutex. + */ +static int wake_up_session_cb(struct inode *inode, struct ceph_cap *cap, + void *arg) +{ + struct ceph_mds_session *session = arg; + + spin_lock(&inode->i_lock); + if (cap->gen != session->s_cap_gen) { + pr_err("failed reconnect %p %llx.%llx cap %p " + "(gen %d < session %d)\n", inode, ceph_vinop(inode), + cap, cap->gen, session->s_cap_gen); + __ceph_remove_cap(cap, NULL); + } + wake_up(&ceph_inode(inode)->i_cap_wq); + spin_unlock(&inode->i_lock); + return 0; +} + +static void wake_up_session_caps(struct ceph_mds_session *session) +{ + dout("wake_up_session_caps %p mds%d\n", session, session->s_mds); + iterate_session_caps(session, wake_up_session_cb, session); +} + +/* + * Send periodic message to MDS renewing all currently held caps. The + * ack will reset the expiration for all caps from this session. + * + * caller holds s_mutex + */ +static int send_renew_caps(struct ceph_mds_client *mdsc, + struct ceph_mds_session *session) +{ + struct ceph_msg *msg; + int state; + + if (time_after_eq(jiffies, session->s_cap_ttl) && + time_after_eq(session->s_cap_ttl, session->s_renew_requested)) + pr_info("mds%d caps stale\n", session->s_mds); + + /* do not try to renew caps until a recovering mds has reconnected + * with its clients. */ + state = ceph_mdsmap_get_state(mdsc->mdsmap, session->s_mds); + if (state < CEPH_MDS_STATE_RECONNECT) { + dout("send_renew_caps ignoring mds%d (%s)\n", + session->s_mds, ceph_mds_state_name(state)); + return 0; + } + + dout("send_renew_caps to mds%d (%s)\n", session->s_mds, + ceph_mds_state_name(state)); + session->s_renew_requested = jiffies; + msg = create_session_msg(CEPH_SESSION_REQUEST_RENEWCAPS, + ++session->s_renew_seq); + if (IS_ERR(msg)) + return PTR_ERR(msg); + ceph_con_send(&session->s_con, msg); + return 0; +} + +/* + * Note new cap ttl, and any transition from stale -> not stale (fresh?). + */ +static void renewed_caps(struct ceph_mds_client *mdsc, + struct ceph_mds_session *session, int is_renew) +{ + int was_stale; + int wake = 0; + + spin_lock(&session->s_cap_lock); + was_stale = is_renew && (session->s_cap_ttl == 0 || + time_after_eq(jiffies, session->s_cap_ttl)); + + session->s_cap_ttl = session->s_renew_requested + + mdsc->mdsmap->m_session_timeout*HZ; + + if (was_stale) { + if (time_before(jiffies, session->s_cap_ttl)) { + pr_info("mds%d caps renewed\n", session->s_mds); + wake = 1; + } else { + pr_info("mds%d caps still stale\n", session->s_mds); + } + } + dout("renewed_caps mds%d ttl now %lu, was %s, now %s\n", + session->s_mds, session->s_cap_ttl, was_stale ? "stale" : "fresh", + time_before(jiffies, session->s_cap_ttl) ? "stale" : "fresh"); + spin_unlock(&session->s_cap_lock); + + if (wake) + wake_up_session_caps(session); +} + +/* + * send a session close request + */ +static int request_close_session(struct ceph_mds_client *mdsc, + struct ceph_mds_session *session) +{ + struct ceph_msg *msg; + int err = 0; + + dout("request_close_session mds%d state %s seq %lld\n", + session->s_mds, session_state_name(session->s_state), + session->s_seq); + msg = create_session_msg(CEPH_SESSION_REQUEST_CLOSE, session->s_seq); + if (IS_ERR(msg)) + err = PTR_ERR(msg); + else + ceph_con_send(&session->s_con, msg); + return err; +} + +/* + * Called with s_mutex held. + */ +static int __close_session(struct ceph_mds_client *mdsc, + struct ceph_mds_session *session) +{ + if (session->s_state >= CEPH_MDS_SESSION_CLOSING) + return 0; + session->s_state = CEPH_MDS_SESSION_CLOSING; + return request_close_session(mdsc, session); +} + +/* + * Trim old(er) caps. + * + * Because we can't cache an inode without one or more caps, we do + * this indirectly: if a cap is unused, we prune its aliases, at which + * point the inode will hopefully get dropped to. + * + * Yes, this is a bit sloppy. Our only real goal here is to respond to + * memory pressure from the MDS, though, so it needn't be perfect. + */ +static int trim_caps_cb(struct inode *inode, struct ceph_cap *cap, void *arg) +{ + struct ceph_mds_session *session = arg; + struct ceph_inode_info *ci = ceph_inode(inode); + int used, oissued, mine; + + if (session->s_trim_caps <= 0) + return -1; + + spin_lock(&inode->i_lock); + mine = cap->issued | cap->implemented; + used = __ceph_caps_used(ci); + oissued = __ceph_caps_issued_other(ci, cap); + + dout("trim_caps_cb %p cap %p mine %s oissued %s used %s\n", + inode, cap, ceph_cap_string(mine), ceph_cap_string(oissued), + ceph_cap_string(used)); + if (ci->i_dirty_caps) + goto out; /* dirty caps */ + if ((used & ~oissued) & mine) + goto out; /* we need these caps */ + + session->s_trim_caps--; + if (oissued) { + /* we aren't the only cap.. just remove us */ + __ceph_remove_cap(cap, NULL); + } else { + /* try to drop referring dentries */ + spin_unlock(&inode->i_lock); + d_prune_aliases(inode); + dout("trim_caps_cb %p cap %p pruned, count now %d\n", + inode, cap, atomic_read(&inode->i_count)); + return 0; + } + +out: + spin_unlock(&inode->i_lock); + return 0; +} + +/* + * Trim session cap count down to some max number. + */ +static int trim_caps(struct ceph_mds_client *mdsc, + struct ceph_mds_session *session, + int max_caps) +{ + int trim_caps = session->s_nr_caps - max_caps; + + dout("trim_caps mds%d start: %d / %d, trim %d\n", + session->s_mds, session->s_nr_caps, max_caps, trim_caps); + if (trim_caps > 0) { + session->s_trim_caps = trim_caps; + iterate_session_caps(session, trim_caps_cb, session); + dout("trim_caps mds%d done: %d / %d, trimmed %d\n", + session->s_mds, session->s_nr_caps, max_caps, + trim_caps - session->s_trim_caps); + } + return 0; +} + +/* + * Allocate cap_release messages. If there is a partially full message + * in the queue, try to allocate enough to cover it's remainder, so that + * we can send it immediately. + * + * Called under s_mutex. + */ +static int add_cap_releases(struct ceph_mds_client *mdsc, + struct ceph_mds_session *session, + int extra) +{ + struct ceph_msg *msg; + struct ceph_mds_cap_release *head; + int err = -ENOMEM; + + if (extra < 0) + extra = mdsc->client->mount_args.cap_release_safety; + + spin_lock(&session->s_cap_lock); + + if (!list_empty(&session->s_cap_releases)) { + msg = list_first_entry(&session->s_cap_releases, + struct ceph_msg, + list_head); + head = msg->front.iov_base; + extra += CEPH_CAPS_PER_RELEASE - le32_to_cpu(head->num); + } + + while (session->s_num_cap_releases < session->s_nr_caps + extra) { + spin_unlock(&session->s_cap_lock); + msg = ceph_msg_new(CEPH_MSG_CLIENT_CAPRELEASE, PAGE_CACHE_SIZE, + 0, 0, NULL); + if (!msg) + goto out_unlocked; + dout("add_cap_releases %p msg %p now %d\n", session, msg, + (int)msg->front.iov_len); + head = msg->front.iov_base; + head->num = cpu_to_le32(0); + msg->front.iov_len = sizeof(*head); + spin_lock(&session->s_cap_lock); + list_add(&msg->list_head, &session->s_cap_releases); + session->s_num_cap_releases += CEPH_CAPS_PER_RELEASE; + } + + if (!list_empty(&session->s_cap_releases)) { + msg = list_first_entry(&session->s_cap_releases, + struct ceph_msg, + list_head); + head = msg->front.iov_base; + if (head->num) { + dout(" queueing non-full %p (%d)\n", msg, + le32_to_cpu(head->num)); + list_move_tail(&msg->list_head, + &session->s_cap_releases_done); + session->s_num_cap_releases -= + CEPH_CAPS_PER_RELEASE - le32_to_cpu(head->num); + } + } + err = 0; + spin_unlock(&session->s_cap_lock); +out_unlocked: + return err; +} + +/* + * flush all dirty inode data to disk. + * + * returns true if we've flushed through want_flush_seq + */ +static int check_cap_flush(struct ceph_mds_client *mdsc, u64 want_flush_seq) +{ + int mds, ret = 1; + + dout("check_cap_flush want %lld\n", want_flush_seq); + mutex_lock(&mdsc->mutex); + for (mds = 0; ret && mds < mdsc->max_sessions; mds++) { + struct ceph_mds_session *session = mdsc->sessions[mds]; + + if (!session) + continue; + get_session(session); + mutex_unlock(&mdsc->mutex); + + mutex_lock(&session->s_mutex); + if (!list_empty(&session->s_cap_flushing)) { + struct ceph_inode_info *ci = + list_entry(session->s_cap_flushing.next, + struct ceph_inode_info, + i_flushing_item); + struct inode *inode = &ci->vfs_inode; + + spin_lock(&inode->i_lock); + if (ci->i_cap_flush_seq <= want_flush_seq) { + dout("check_cap_flush still flushing %p " + "seq %lld <= %lld to mds%d\n", inode, + ci->i_cap_flush_seq, want_flush_seq, + session->s_mds); + ret = 0; + } + spin_unlock(&inode->i_lock); + } + mutex_unlock(&session->s_mutex); + ceph_put_mds_session(session); + + if (!ret) + return ret; + mutex_lock(&mdsc->mutex); + } + + mutex_unlock(&mdsc->mutex); + dout("check_cap_flush ok, flushed thru %lld\n", want_flush_seq); + return ret; +} + +/* + * called under s_mutex + */ +static void send_cap_releases(struct ceph_mds_client *mdsc, + struct ceph_mds_session *session) +{ + struct ceph_msg *msg; + + dout("send_cap_releases mds%d\n", session->s_mds); + while (1) { + spin_lock(&session->s_cap_lock); + if (list_empty(&session->s_cap_releases_done)) + break; + msg = list_first_entry(&session->s_cap_releases_done, + struct ceph_msg, list_head); + list_del_init(&msg->list_head); + spin_unlock(&session->s_cap_lock); + msg->hdr.front_len = cpu_to_le32(msg->front.iov_len); + dout("send_cap_releases mds%d %p\n", session->s_mds, msg); + ceph_con_send(&session->s_con, msg); + } + spin_unlock(&session->s_cap_lock); +} + +/* + * requests + */ + +/* + * Create an mds request. + */ +struct ceph_mds_request * +ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op, int mode) +{ + struct ceph_mds_request *req = kzalloc(sizeof(*req), GFP_NOFS); + + if (!req) + return ERR_PTR(-ENOMEM); + + req->r_started = jiffies; + req->r_resend_mds = -1; + INIT_LIST_HEAD(&req->r_unsafe_dir_item); + req->r_fmode = -1; + atomic_set(&req->r_ref, 1); /* one for request_tree, one for caller */ + INIT_LIST_HEAD(&req->r_wait); + init_completion(&req->r_completion); + init_completion(&req->r_safe_completion); + INIT_LIST_HEAD(&req->r_unsafe_item); + + req->r_op = op; + req->r_direct_mode = mode; + return req; +} + +/* + * return oldest (lowest) tid in request tree, 0 if none. + * + * called under mdsc->mutex. + */ +static u64 __get_oldest_tid(struct ceph_mds_client *mdsc) +{ + struct ceph_mds_request *first; + if (radix_tree_gang_lookup(&mdsc->request_tree, + (void **)&first, 0, 1) <= 0) + return 0; + return first->r_tid; +} + +/* + * Build a dentry's path. Allocate on heap; caller must kfree. Based + * on build_path_from_dentry in fs/cifs/dir.c. + * + * If @stop_on_nosnap, generate path relative to the first non-snapped + * inode. + * + * Encode hidden .snap dirs as a double /, i.e. + * foo/.snap/bar -> foo//bar + */ +char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *base, + int stop_on_nosnap) +{ + struct dentry *temp; + char *path; + int len, pos; + + if (dentry == NULL) + return ERR_PTR(-EINVAL); + +retry: + len = 0; + for (temp = dentry; !IS_ROOT(temp);) { + struct inode *inode = temp->d_inode; + if (inode && ceph_snap(inode) == CEPH_SNAPDIR) + len++; /* slash only */ + else if (stop_on_nosnap && inode && + ceph_snap(inode) == CEPH_NOSNAP) + break; + else + len += 1 + temp->d_name.len; + temp = temp->d_parent; + if (temp == NULL) { + pr_err("build_path_dentry corrupt dentry %p\n", dentry); + return ERR_PTR(-EINVAL); + } + } + if (len) + len--; /* no leading '/' */ + + path = kmalloc(len+1, GFP_NOFS); + if (path == NULL) + return ERR_PTR(-ENOMEM); + pos = len; + path[pos] = 0; /* trailing null */ + for (temp = dentry; !IS_ROOT(temp) && pos != 0; ) { + struct inode *inode = temp->d_inode; + + if (inode && ceph_snap(inode) == CEPH_SNAPDIR) { + dout("build_path_dentry path+%d: %p SNAPDIR\n", + pos, temp); + } else if (stop_on_nosnap && inode && + ceph_snap(inode) == CEPH_NOSNAP) { + break; + } else { + pos -= temp->d_name.len; + if (pos < 0) + break; + strncpy(path + pos, temp->d_name.name, + temp->d_name.len); + dout("build_path_dentry path+%d: %p '%.*s'\n", + pos, temp, temp->d_name.len, path + pos); + } + if (pos) + path[--pos] = '/'; + temp = temp->d_parent; + if (temp == NULL) { + pr_err("build_path_dentry corrupt dentry\n"); + kfree(path); + return ERR_PTR(-EINVAL); + } + } + if (pos != 0) { + pr_err("build_path_dentry did not end path lookup where " + "expected, namelen is %d, pos is %d\n", len, pos); + /* presumably this is only possible if racing with a + rename of one of the parent directories (we can not + lock the dentries above us to prevent this, but + retrying should be harmless) */ + kfree(path); + goto retry; + } + + *base = ceph_ino(temp->d_inode); + *plen = len; + dout("build_path_dentry on %p %d built %llx '%.*s'\n", + dentry, atomic_read(&dentry->d_count), *base, len, path); + return path; +} + +static int build_dentry_path(struct dentry *dentry, + const char **ppath, int *ppathlen, u64 *pino, + int *pfreepath) +{ + char *path; + + if (ceph_snap(dentry->d_parent->d_inode) == CEPH_NOSNAP) { + *pino = ceph_ino(dentry->d_parent->d_inode); + *ppath = dentry->d_name.name; + *ppathlen = dentry->d_name.len; + return 0; + } + path = ceph_mdsc_build_path(dentry, ppathlen, pino, 1); + if (IS_ERR(path)) + return PTR_ERR(path); + *ppath = path; + *pfreepath = 1; + return 0; +} + +static int build_inode_path(struct inode *inode, + const char **ppath, int *ppathlen, u64 *pino, + int *pfreepath) +{ + struct dentry *dentry; + char *path; + + if (ceph_snap(inode) == CEPH_NOSNAP) { + *pino = ceph_ino(inode); + *ppathlen = 0; + return 0; + } + dentry = d_find_alias(inode); + path = ceph_mdsc_build_path(dentry, ppathlen, pino, 1); + dput(dentry); + if (IS_ERR(path)) + return PTR_ERR(path); + *ppath = path; + *pfreepath = 1; + return 0; +} + +/* + * request arguments may be specified via an inode *, a dentry *, or + * an explicit ino+path. + */ +static int set_request_path_attr(struct inode *rinode, struct dentry *rdentry, + const char *rpath, u64 rino, + const char **ppath, int *pathlen, + u64 *ino, int *freepath) +{ + int r = 0; + + if (rinode) { + r = build_inode_path(rinode, ppath, pathlen, ino, freepath); + dout(" inode %p %llx.%llx\n", rinode, ceph_ino(rinode), + ceph_snap(rinode)); + } else if (rdentry) { + r = build_dentry_path(rdentry, ppath, pathlen, ino, freepath); + dout(" dentry %p %llx/%.*s\n", rdentry, *ino, *pathlen, + *ppath); + } else if (rpath) { + *ino = rino; + *ppath = rpath; + *pathlen = strlen(rpath); + dout(" path %.*s\n", *pathlen, rpath); + } + + return r; +} + +/* + * called under mdsc->mutex + */ +static struct ceph_msg *create_request_message(struct ceph_mds_client *mdsc, + struct ceph_mds_request *req, + int mds) +{ + struct ceph_msg *msg; + struct ceph_mds_request_head *head; + const char *path1 = NULL; + const char *path2 = NULL; + u64 ino1 = 0, ino2 = 0; + int pathlen1 = 0, pathlen2 = 0; + int freepath1 = 0, freepath2 = 0; + int len; + u16 releases; + void *p, *end; + int ret; + + ret = set_request_path_attr(req->r_inode, req->r_dentry, + req->r_path1, req->r_ino1.ino, + &path1, &pathlen1, &ino1, &freepath1); + if (ret < 0) { + msg = ERR_PTR(ret); + goto out; + } + + ret = set_request_path_attr(NULL, req->r_old_dentry, + req->r_path2, req->r_ino2.ino, + &path2, &pathlen2, &ino2, &freepath2); + if (ret < 0) { + msg = ERR_PTR(ret); + goto out_free1; + } + + len = sizeof(*head) + + pathlen1 + pathlen2 + 2*(sizeof(u32) + sizeof(u64)); + + /* calculate (max) length for cap releases */ + len += sizeof(struct ceph_mds_request_release) * + (!!req->r_inode_drop + !!req->r_dentry_drop + + !!req->r_old_inode_drop + !!req->r_old_dentry_drop); + if (req->r_dentry_drop) + len += req->r_dentry->d_name.len; + if (req->r_old_dentry_drop) + len += req->r_old_dentry->d_name.len; + + msg = ceph_msg_new(CEPH_MSG_CLIENT_REQUEST, len, 0, 0, NULL); + if (IS_ERR(msg)) + goto out_free2; + + head = msg->front.iov_base; + p = msg->front.iov_base + sizeof(*head); + end = msg->front.iov_base + msg->front.iov_len; + + head->mdsmap_epoch = cpu_to_le32(mdsc->mdsmap->m_epoch); + head->op = cpu_to_le32(req->r_op); + head->caller_uid = cpu_to_le32(current_fsuid()); + head->caller_gid = cpu_to_le32(current_fsgid()); + head->args = req->r_args; + + ceph_encode_filepath(&p, end, ino1, path1); + ceph_encode_filepath(&p, end, ino2, path2); + + /* cap releases */ + releases = 0; + if (req->r_inode_drop) + releases += ceph_encode_inode_release(&p, + req->r_inode ? req->r_inode : req->r_dentry->d_inode, + mds, req->r_inode_drop, req->r_inode_unless, 0); + if (req->r_dentry_drop) + releases += ceph_encode_dentry_release(&p, req->r_dentry, + mds, req->r_dentry_drop, req->r_dentry_unless); + if (req->r_old_dentry_drop) + releases += ceph_encode_dentry_release(&p, req->r_old_dentry, + mds, req->r_old_dentry_drop, req->r_old_dentry_unless); + if (req->r_old_inode_drop) + releases += ceph_encode_inode_release(&p, + req->r_old_dentry->d_inode, + mds, req->r_old_inode_drop, req->r_old_inode_unless, 0); + head->num_releases = cpu_to_le16(releases); + + BUG_ON(p > end); + msg->front.iov_len = p - msg->front.iov_base; + msg->hdr.front_len = cpu_to_le32(msg->front.iov_len); + + msg->pages = req->r_pages; + msg->nr_pages = req->r_num_pages; + msg->hdr.data_len = cpu_to_le32(req->r_data_len); + msg->hdr.data_off = cpu_to_le16(0); + +out_free2: + if (freepath2) + kfree((char *)path2); +out_free1: + if (freepath1) + kfree((char *)path1); +out: + return msg; +} + +/* + * called under mdsc->mutex if error, under no mutex if + * success. + */ +static void complete_request(struct ceph_mds_client *mdsc, + struct ceph_mds_request *req) +{ + if (req->r_callback) + req->r_callback(mdsc, req); + else + complete(&req->r_completion); +} + +/* + * called under mdsc->mutex + */ +static int __prepare_send_request(struct ceph_mds_client *mdsc, + struct ceph_mds_request *req, + int mds) +{ + struct ceph_mds_request_head *rhead; + struct ceph_msg *msg; + int flags = 0; + + req->r_mds = mds; + req->r_attempts++; + dout("prepare_send_request %p tid %lld %s (attempt %d)\n", req, + req->r_tid, ceph_mds_op_name(req->r_op), req->r_attempts); + + if (req->r_request) { + ceph_msg_put(req->r_request); + req->r_request = NULL; + } + msg = create_request_message(mdsc, req, mds); + if (IS_ERR(msg)) { + req->r_reply = ERR_PTR(PTR_ERR(msg)); + complete_request(mdsc, req); + return -PTR_ERR(msg); + } + req->r_request = msg; + + rhead = msg->front.iov_base; + rhead->tid = cpu_to_le64(req->r_tid); + rhead->oldest_client_tid = cpu_to_le64(__get_oldest_tid(mdsc)); + if (req->r_got_unsafe) + flags |= CEPH_MDS_FLAG_REPLAY; + if (req->r_locked_dir) + flags |= CEPH_MDS_FLAG_WANT_DENTRY; + rhead->flags = cpu_to_le32(flags); + rhead->num_fwd = req->r_num_fwd; + rhead->num_retry = req->r_attempts - 1; + + dout(" r_locked_dir = %p\n", req->r_locked_dir); + + if (req->r_target_inode && req->r_got_unsafe) + rhead->ino = cpu_to_le64(ceph_ino(req->r_target_inode)); + else + rhead->ino = 0; + return 0; +} + +/* + * send request, or put it on the appropriate wait list. + */ +static int __do_request(struct ceph_mds_client *mdsc, + struct ceph_mds_request *req) +{ + struct ceph_mds_session *session = NULL; + int mds = -1; + int err = -EAGAIN; + + if (req->r_reply) + goto out; + + if (req->r_timeout && + time_after_eq(jiffies, req->r_started + req->r_timeout)) { + dout("do_request timed out\n"); + err = -EIO; + goto finish; + } + + mds = __choose_mds(mdsc, req); + if (mds < 0 || + ceph_mdsmap_get_state(mdsc->mdsmap, mds) < CEPH_MDS_STATE_ACTIVE) { + dout("do_request no mds or not active, waiting for map\n"); + list_add(&req->r_wait, &mdsc->waiting_for_map); + goto out; + } + + /* get, open session */ + session = __ceph_lookup_mds_session(mdsc, mds); + if (!session) + session = register_session(mdsc, mds); + dout("do_request mds%d session %p state %s\n", mds, session, + session_state_name(session->s_state)); + if (session->s_state != CEPH_MDS_SESSION_OPEN && + session->s_state != CEPH_MDS_SESSION_HUNG) { + if (session->s_state == CEPH_MDS_SESSION_NEW || + session->s_state == CEPH_MDS_SESSION_CLOSING) + __open_session(mdsc, session); + list_add(&req->r_wait, &session->s_waiting); + goto out_session; + } + + /* send request */ + req->r_session = get_session(session); + req->r_resend_mds = -1; /* forget any previous mds hint */ + + if (req->r_request_started == 0) /* note request start time */ + req->r_request_started = jiffies; + + err = __prepare_send_request(mdsc, req, mds); + if (!err) { + ceph_msg_get(req->r_request); + ceph_con_send(&session->s_con, req->r_request); + } + +out_session: + ceph_put_mds_session(session); +out: + return err; + +finish: + req->r_reply = ERR_PTR(err); + complete_request(mdsc, req); + goto out; +} + +/* + * called under mdsc->mutex + */ +static void __wake_requests(struct ceph_mds_client *mdsc, + struct list_head *head) +{ + struct ceph_mds_request *req, *nreq; + + list_for_each_entry_safe(req, nreq, head, r_wait) { + list_del_init(&req->r_wait); + __do_request(mdsc, req); + } +} + +/* + * Wake up threads with requests pending for @mds, so that they can + * resubmit their requests to a possibly different mds. If @all is set, + * wake up if their requests has been forwarded to @mds, too. + */ +static void kick_requests(struct ceph_mds_client *mdsc, int mds, int all) +{ + struct ceph_mds_request *reqs[10]; + u64 nexttid = 0; + int i, got; + + dout("kick_requests mds%d\n", mds); + while (nexttid <= mdsc->last_tid) { + got = radix_tree_gang_lookup(&mdsc->request_tree, + (void **)&reqs, nexttid, 10); + if (got == 0) + break; + nexttid = reqs[got-1]->r_tid + 1; + for (i = 0; i < got; i++) { + if (reqs[i]->r_got_unsafe) + continue; + if (reqs[i]->r_session && + reqs[i]->r_session->s_mds == mds) { + dout(" kicking tid %llu\n", reqs[i]->r_tid); + put_request_session(reqs[i]); + __do_request(mdsc, reqs[i]); + } + } + } +} + +void ceph_mdsc_submit_request(struct ceph_mds_client *mdsc, + struct ceph_mds_request *req) +{ + dout("submit_request on %p\n", req); + mutex_lock(&mdsc->mutex); + __register_request(mdsc, req, NULL); + __do_request(mdsc, req); + mutex_unlock(&mdsc->mutex); +} + +/* + * Synchrously perform an mds request. Take care of all of the + * session setup, forwarding, retry details. + */ +int ceph_mdsc_do_request(struct ceph_mds_client *mdsc, + struct inode *dir, + struct ceph_mds_request *req) +{ + int err; + + dout("do_request on %p\n", req); + + /* take CAP_PIN refs for r_inode, r_locked_dir, r_old_dentry */ + if (req->r_inode) + ceph_get_cap_refs(ceph_inode(req->r_inode), CEPH_CAP_PIN); + if (req->r_locked_dir) + ceph_get_cap_refs(ceph_inode(req->r_locked_dir), CEPH_CAP_PIN); + if (req->r_old_dentry) + ceph_get_cap_refs( + ceph_inode(req->r_old_dentry->d_parent->d_inode), + CEPH_CAP_PIN); + + /* issue */ + mutex_lock(&mdsc->mutex); + __register_request(mdsc, req, dir); + __do_request(mdsc, req); + + /* wait */ + if (!req->r_reply) { + mutex_unlock(&mdsc->mutex); + if (req->r_timeout) { + err = wait_for_completion_timeout(&req->r_completion, + req->r_timeout); + if (err > 0) + err = 0; + else if (err == 0) + req->r_reply = ERR_PTR(-EIO); + } else { + wait_for_completion(&req->r_completion); + } + mutex_lock(&mdsc->mutex); + } + + if (IS_ERR(req->r_reply)) { + err = PTR_ERR(req->r_reply); + req->r_reply = NULL; + + /* clean up */ + __unregister_request(mdsc, req); + if (!list_empty(&req->r_unsafe_item)) + list_del_init(&req->r_unsafe_item); + complete(&req->r_safe_completion); + } else if (req->r_err) { + err = req->r_err; + } else { + err = le32_to_cpu(req->r_reply_info.head->result); + } + mutex_unlock(&mdsc->mutex); + + dout("do_request %p done, result %d\n", req, err); + return err; +} + +/* + * Handle mds reply. + * + * We take the session mutex and parse and process the reply immediately. + * This preserves the logical ordering of replies, capabilities, etc., sent + * by the MDS as they are applied to our local cache. + */ +static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg) +{ + struct ceph_mds_client *mdsc = session->s_mdsc; + struct ceph_mds_request *req; + struct ceph_mds_reply_head *head = msg->front.iov_base; + struct ceph_mds_reply_info_parsed *rinfo; /* parsed reply info */ + u64 tid; + int err, result; + int mds; + + if (msg->hdr.src.name.type != CEPH_ENTITY_TYPE_MDS) + return; + if (msg->front.iov_len < sizeof(*head)) { + pr_err("mdsc_handle_reply got corrupt (short) reply\n"); + return; + } + + /* get request, session */ + tid = le64_to_cpu(head->tid); + mutex_lock(&mdsc->mutex); + req = __lookup_request(mdsc, tid); + if (!req) { + dout("handle_reply on unknown tid %llu\n", tid); + mutex_unlock(&mdsc->mutex); + return; + } + dout("handle_reply %p\n", req); + mds = le64_to_cpu(msg->hdr.src.name.num); + + /* correct session? */ + if (!req->r_session && req->r_session != session) { + pr_err("mdsc_handle_reply got %llu on session mds%d" + " not mds%d\n", tid, session->s_mds, + req->r_session ? req->r_session->s_mds : -1); + mutex_unlock(&mdsc->mutex); + goto out; + } + + /* dup? */ + if ((req->r_got_unsafe && !head->safe) || + (req->r_got_safe && head->safe)) { + pr_warning("got a dup %s reply on %llu from mds%d\n", + head->safe ? "safe" : "unsafe", tid, mds); + mutex_unlock(&mdsc->mutex); + goto out; + } + + result = le32_to_cpu(head->result); + + /* + * Tolerate 2 consecutive ESTALEs from the same mds. + * FIXME: we should be looking at the cap migrate_seq. + */ + if (result == -ESTALE) { + req->r_direct_mode = USE_AUTH_MDS; + req->r_num_stale++; + if (req->r_num_stale <= 2) { + __do_request(mdsc, req); + mutex_unlock(&mdsc->mutex); + goto out; + } + } else { + req->r_num_stale = 0; + } + + if (head->safe) { + req->r_got_safe = true; + __unregister_request(mdsc, req); + complete(&req->r_safe_completion); + + if (req->r_got_unsafe) { + /* + * We already handled the unsafe response, now do the + * cleanup. No need to examine the response; the MDS + * doesn't include any result info in the safe + * response. And even if it did, there is nothing + * useful we could do with a revised return value. + */ + dout("got safe reply %llu, mds%d\n", tid, mds); + list_del_init(&req->r_unsafe_item); + + /* last unsafe request during umount? */ + if (mdsc->stopping && !__get_oldest_tid(mdsc)) + complete(&mdsc->safe_umount_waiters); + mutex_unlock(&mdsc->mutex); + goto out; + } + } + + BUG_ON(req->r_reply); + + if (!head->safe) { + req->r_got_unsafe = true; + list_add_tail(&req->r_unsafe_item, &req->r_session->s_unsafe); + } + + dout("handle_reply tid %lld result %d\n", tid, result); + rinfo = &req->r_reply_info; + err = parse_reply_info(msg, rinfo); + mutex_unlock(&mdsc->mutex); + + mutex_lock(&session->s_mutex); + if (err < 0) { + pr_err("mdsc_handle_reply got corrupt reply mds%d\n", mds); + goto out_err; + } + + /* snap trace */ + if (rinfo->snapblob_len) { + down_write(&mdsc->snap_rwsem); + ceph_update_snap_trace(mdsc, rinfo->snapblob, + rinfo->snapblob + rinfo->snapblob_len, + le32_to_cpu(head->op) == CEPH_MDS_OP_RMSNAP); + downgrade_write(&mdsc->snap_rwsem); + } else { + down_read(&mdsc->snap_rwsem); + } + + /* insert trace into our cache */ + err = ceph_fill_trace(mdsc->client->sb, req, req->r_session); + if (err == 0) { + if (result == 0 && rinfo->dir_nr) + ceph_readdir_prepopulate(req, req->r_session); + ceph_unreserve_caps(&req->r_caps_reservation); + } + + up_read(&mdsc->snap_rwsem); +out_err: + if (err) { + req->r_err = err; + } else { + req->r_reply = msg; + ceph_msg_get(msg); + } + + add_cap_releases(mdsc, req->r_session, -1); + mutex_unlock(&session->s_mutex); + + /* kick calling process */ + complete_request(mdsc, req); +out: + ceph_mdsc_put_request(req); + return; +} + + + +/* + * handle mds notification that our request has been forwarded. + */ +static void handle_forward(struct ceph_mds_client *mdsc, struct ceph_msg *msg) +{ + struct ceph_mds_request *req; + u64 tid; + u32 next_mds; + u32 fwd_seq; + u8 must_resend; + int err = -EINVAL; + void *p = msg->front.iov_base; + void *end = p + msg->front.iov_len; + int from_mds, state; + + if (msg->hdr.src.name.type != CEPH_ENTITY_TYPE_MDS) + goto bad; + from_mds = le64_to_cpu(msg->hdr.src.name.num); + + ceph_decode_need(&p, end, sizeof(u64)+2*sizeof(u32), bad); + ceph_decode_64(&p, tid); + ceph_decode_32(&p, next_mds); + ceph_decode_32(&p, fwd_seq); + ceph_decode_8(&p, must_resend); + + WARN_ON(must_resend); /* shouldn't happen. */ + + mutex_lock(&mdsc->mutex); + req = __lookup_request(mdsc, tid); + if (!req) { + dout("forward %llu dne\n", tid); + goto out; /* dup reply? */ + } + + state = mdsc->sessions[next_mds]->s_state; + if (fwd_seq <= req->r_num_fwd) { + dout("forward %llu to mds%d - old seq %d <= %d\n", + tid, next_mds, req->r_num_fwd, fwd_seq); + } else { + /* resend. forward race not possible; mds would drop */ + dout("forward %llu to mds%d (we resend)\n", tid, next_mds); + req->r_num_fwd = fwd_seq; + req->r_resend_mds = next_mds; + put_request_session(req); + __do_request(mdsc, req); + } + ceph_mdsc_put_request(req); +out: + mutex_unlock(&mdsc->mutex); + return; + +bad: + pr_err("mdsc_handle_forward decode error err=%d\n", err); +} + +/* + * handle a mds session control message + */ +static void handle_session(struct ceph_mds_session *session, + struct ceph_msg *msg) +{ + struct ceph_mds_client *mdsc = session->s_mdsc; + u32 op; + u64 seq; + int mds; + struct ceph_mds_session_head *h = msg->front.iov_base; + int wake = 0; + + if (msg->hdr.src.name.type != CEPH_ENTITY_TYPE_MDS) + return; + mds = le64_to_cpu(msg->hdr.src.name.num); + + /* decode */ + if (msg->front.iov_len != sizeof(*h)) + goto bad; + op = le32_to_cpu(h->op); + seq = le64_to_cpu(h->seq); + + mutex_lock(&mdsc->mutex); + /* FIXME: this ttl calculation is generous */ + session->s_ttl = jiffies + HZ*mdsc->mdsmap->m_session_autoclose; + mutex_unlock(&mdsc->mutex); + + mutex_lock(&session->s_mutex); + + dout("handle_session mds%d %s %p state %s seq %llu\n", + mds, ceph_session_op_name(op), session, + session_state_name(session->s_state), seq); + + if (session->s_state == CEPH_MDS_SESSION_HUNG) { + session->s_state = CEPH_MDS_SESSION_OPEN; + pr_info("mds%d came back\n", session->s_mds); + } + + switch (op) { + case CEPH_SESSION_OPEN: + session->s_state = CEPH_MDS_SESSION_OPEN; + renewed_caps(mdsc, session, 0); + wake = 1; + if (mdsc->stopping) + __close_session(mdsc, session); + break; + + case CEPH_SESSION_RENEWCAPS: + if (session->s_renew_seq == seq) + renewed_caps(mdsc, session, 1); + break; + + case CEPH_SESSION_CLOSE: + unregister_session(mdsc, mds); + remove_session_caps(session); + wake = 1; /* for good measure */ + complete(&mdsc->session_close_waiters); + kick_requests(mdsc, mds, 0); /* cur only */ + break; + + case CEPH_SESSION_STALE: + pr_info("mds%d caps went stale, renewing\n", + session->s_mds); + spin_lock(&session->s_cap_lock); + session->s_cap_gen++; + session->s_cap_ttl = 0; + spin_unlock(&session->s_cap_lock); + send_renew_caps(mdsc, session); + break; + + case CEPH_SESSION_RECALL_STATE: + trim_caps(mdsc, session, le32_to_cpu(h->max_caps)); + break; + + default: + pr_err("mdsc_handle_session bad op %d mds%d\n", op, mds); + WARN_ON(1); + } + + mutex_unlock(&session->s_mutex); + if (wake) { + mutex_lock(&mdsc->mutex); + __wake_requests(mdsc, &session->s_waiting); + mutex_unlock(&mdsc->mutex); + } + return; + +bad: + pr_err("mdsc_handle_session corrupt message mds%d len %d\n", mds, + (int)msg->front.iov_len); + return; +} + + +/* + * called under session->mutex. + */ +static void replay_unsafe_requests(struct ceph_mds_client *mdsc, + struct ceph_mds_session *session) +{ + struct ceph_mds_request *req, *nreq; + int err; + + dout("replay_unsafe_requests mds%d\n", session->s_mds); + + mutex_lock(&mdsc->mutex); + list_for_each_entry_safe(req, nreq, &session->s_unsafe, r_unsafe_item) { + err = __prepare_send_request(mdsc, req, session->s_mds); + if (!err) { + ceph_msg_get(req->r_request); + ceph_con_send(&session->s_con, req->r_request); + } + } + mutex_unlock(&mdsc->mutex); +} + +/* + * Encode information about a cap for a reconnect with the MDS. + */ +struct encode_caps_data { + void **pp; + void *end; + int *num_caps; +}; + +static int encode_caps_cb(struct inode *inode, struct ceph_cap *cap, + void *arg) +{ + struct ceph_mds_cap_reconnect *rec; + struct ceph_inode_info *ci; + struct encode_caps_data *data = (struct encode_caps_data *)arg; + void *p = *(data->pp); + void *end = data->end; + char *path; + int pathlen, err; + u64 pathbase; + struct dentry *dentry; + + ci = cap->ci; + + dout(" adding %p ino %llx.%llx cap %p %lld %s\n", + inode, ceph_vinop(inode), cap, cap->cap_id, + ceph_cap_string(cap->issued)); + ceph_decode_need(&p, end, sizeof(u64), needmore); + ceph_encode_64(&p, ceph_ino(inode)); + + dentry = d_find_alias(inode); + if (dentry) { + path = ceph_mdsc_build_path(dentry, &pathlen, &pathbase, 0); + if (IS_ERR(path)) { + err = PTR_ERR(path); + BUG_ON(err); + } + } else { + path = NULL; + pathlen = 0; + } + ceph_decode_need(&p, end, pathlen+4, needmore); + ceph_encode_string(&p, end, path, pathlen); + + ceph_decode_need(&p, end, sizeof(*rec), needmore); + rec = p; + p += sizeof(*rec); + BUG_ON(p > end); + spin_lock(&inode->i_lock); + cap->seq = 0; /* reset cap seq */ + cap->issue_seq = 0; /* and issue_seq */ + rec->cap_id = cpu_to_le64(cap->cap_id); + rec->pathbase = cpu_to_le64(pathbase); + rec->wanted = cpu_to_le32(__ceph_caps_wanted(ci)); + rec->issued = cpu_to_le32(cap->issued); + rec->size = cpu_to_le64(inode->i_size); + ceph_encode_timespec(&rec->mtime, &inode->i_mtime); + ceph_encode_timespec(&rec->atime, &inode->i_atime); + rec->snaprealm = cpu_to_le64(ci->i_snap_realm->ino); + spin_unlock(&inode->i_lock); + + kfree(path); + dput(dentry); + (*data->num_caps)++; + *(data->pp) = p; + return 0; +needmore: + return -ENOSPC; +} + + +/* + * If an MDS fails and recovers, clients need to reconnect in order to + * reestablish shared state. This includes all caps issued through + * this session _and_ the snap_realm hierarchy. Because it's not + * clear which snap realms the mds cares about, we send everything we + * know about.. that ensures we'll then get any new info the + * recovering MDS might have. + * + * This is a relatively heavyweight operation, but it's rare. + * + * called with mdsc->mutex held. + */ +static void send_mds_reconnect(struct ceph_mds_client *mdsc, int mds) +{ + struct ceph_mds_session *session; + struct ceph_msg *reply; + int newlen, len = 4 + 1; + void *p, *end; + int err; + int num_caps, num_realms = 0; + int got; + u64 next_snap_ino = 0; + __le32 *pnum_caps, *pnum_realms; + struct encode_caps_data iter_args; + + pr_info("reconnect to recovering mds%d\n", mds); + + /* find session */ + session = __ceph_lookup_mds_session(mdsc, mds); + mutex_unlock(&mdsc->mutex); /* drop lock for duration */ + + if (session) { + mutex_lock(&session->s_mutex); + + session->s_state = CEPH_MDS_SESSION_RECONNECTING; + session->s_seq = 0; + + ceph_con_open(&session->s_con, + ceph_mdsmap_get_addr(mdsc->mdsmap, mds)); + + /* replay unsafe requests */ + replay_unsafe_requests(mdsc, session); + + /* estimate needed space */ + len += session->s_nr_caps * + (100+sizeof(struct ceph_mds_cap_reconnect)); + pr_info("estimating i need %d bytes for %d caps\n", + len, session->s_nr_caps); + } else { + dout("no session for mds%d, will send short reconnect\n", + mds); + } + + down_read(&mdsc->snap_rwsem); + +retry: + /* build reply */ + reply = ceph_msg_new(CEPH_MSG_CLIENT_RECONNECT, len, 0, 0, NULL); + if (IS_ERR(reply)) { + err = PTR_ERR(reply); + pr_err("send_mds_reconnect ENOMEM on %d for mds%d\n", + len, mds); + goto out; + } + p = reply->front.iov_base; + end = p + len; + + if (!session) { + ceph_encode_8(&p, 1); /* session was closed */ + ceph_encode_32(&p, 0); + goto send; + } + dout("session %p state %s\n", session, + session_state_name(session->s_state)); + + /* traverse this session's caps */ + ceph_encode_8(&p, 0); + pnum_caps = p; + ceph_encode_32(&p, session->s_nr_caps); + num_caps = 0; + + iter_args.pp = &p; + iter_args.end = end; + iter_args.num_caps = &num_caps; + err = iterate_session_caps(session, encode_caps_cb, &iter_args); + if (err == -ENOSPC) + goto needmore; + if (err < 0) + goto out; + *pnum_caps = cpu_to_le32(num_caps); + + /* + * snaprealms. we provide mds with the ino, seq (version), and + * parent for all of our realms. If the mds has any newer info, + * it will tell us. + */ + next_snap_ino = 0; + /* save some space for the snaprealm count */ + pnum_realms = p; + ceph_decode_need(&p, end, sizeof(*pnum_realms), needmore); + p += sizeof(*pnum_realms); + num_realms = 0; + while (1) { + struct ceph_snap_realm *realm; + struct ceph_mds_snaprealm_reconnect *sr_rec; + got = radix_tree_gang_lookup(&mdsc->snap_realms, + (void **)&realm, next_snap_ino, 1); + if (!got) + break; + + dout(" adding snap realm %llx seq %lld parent %llx\n", + realm->ino, realm->seq, realm->parent_ino); + ceph_decode_need(&p, end, sizeof(*sr_rec), needmore); + sr_rec = p; + sr_rec->ino = cpu_to_le64(realm->ino); + sr_rec->seq = cpu_to_le64(realm->seq); + sr_rec->parent = cpu_to_le64(realm->parent_ino); + p += sizeof(*sr_rec); + num_realms++; + next_snap_ino = realm->ino + 1; + } + *pnum_realms = cpu_to_le32(num_realms); + +send: + reply->front.iov_len = p - reply->front.iov_base; + reply->hdr.front_len = cpu_to_le32(reply->front.iov_len); + dout("final len was %u (guessed %d)\n", + (unsigned)reply->front.iov_len, len); + ceph_con_send(&session->s_con, reply); + + if (session) { + session->s_state = CEPH_MDS_SESSION_OPEN; + __wake_requests(mdsc, &session->s_waiting); + } + +out: + up_read(&mdsc->snap_rwsem); + if (session) { + mutex_unlock(&session->s_mutex); + ceph_put_mds_session(session); + } + mutex_lock(&mdsc->mutex); + return; + +needmore: + /* + * we need a larger buffer. this doesn't very accurately + * factor in snap realms, but it's safe. + */ + num_caps += num_realms; + newlen = len * ((100 * (session->s_nr_caps+3)) / (num_caps + 1)) / 100; + pr_info("i guessed %d, and did %d of %d caps, retrying with %d\n", + len, num_caps, session->s_nr_caps, newlen); + len = newlen; + ceph_msg_put(reply); + goto retry; +} + + +/* + * compare old and new mdsmaps, kicking requests + * and closing out old connections as necessary + * + * called under mdsc->mutex. + */ +static void check_new_map(struct ceph_mds_client *mdsc, + struct ceph_mdsmap *newmap, + struct ceph_mdsmap *oldmap) +{ + int i; + int oldstate, newstate; + struct ceph_mds_session *s; + + dout("check_new_map new %u old %u\n", + newmap->m_epoch, oldmap->m_epoch); + + for (i = 0; i < oldmap->m_max_mds && i < mdsc->max_sessions; i++) { + if (mdsc->sessions[i] == NULL) + continue; + s = mdsc->sessions[i]; + oldstate = ceph_mdsmap_get_state(oldmap, i); + newstate = ceph_mdsmap_get_state(newmap, i); + + dout("check_new_map mds%d state %s -> %s (session %s)\n", + i, ceph_mds_state_name(oldstate), + ceph_mds_state_name(newstate), + session_state_name(s->s_state)); + + if (memcmp(ceph_mdsmap_get_addr(oldmap, i), + ceph_mdsmap_get_addr(newmap, i), + sizeof(struct ceph_entity_addr))) { + if (s->s_state == CEPH_MDS_SESSION_OPENING) { + /* the session never opened, just close it + * out now */ + __wake_requests(mdsc, &s->s_waiting); + unregister_session(mdsc, i); + } else { + /* just close it */ + mutex_unlock(&mdsc->mutex); + mutex_lock(&s->s_mutex); + mutex_lock(&mdsc->mutex); + ceph_con_close(&s->s_con); + mutex_unlock(&s->s_mutex); + s->s_state = CEPH_MDS_SESSION_RESTARTING; + } + + /* kick any requests waiting on the recovering mds */ + kick_requests(mdsc, i, 1); + } else if (oldstate == newstate) { + continue; /* nothing new with this mds */ + } + + /* + * send reconnect? + */ + if (s->s_state == CEPH_MDS_SESSION_RESTARTING && + newstate >= CEPH_MDS_STATE_RECONNECT) + send_mds_reconnect(mdsc, i); + + /* + * kick requests on any mds that has gone active. + * + * kick requests on cur or forwarder: we may have sent + * the request to mds1, mds1 told us it forwarded it + * to mds2, but then we learn mds1 failed and can't be + * sure it successfully forwarded our request before + * it died. + */ + if (oldstate < CEPH_MDS_STATE_ACTIVE && + newstate >= CEPH_MDS_STATE_ACTIVE) { + kick_requests(mdsc, i, 1); + ceph_kick_flushing_caps(mdsc, s); + } + } +} + + + +/* + * leases + */ + +/* + * caller must hold session s_mutex, dentry->d_lock + */ +void __ceph_mdsc_drop_dentry_lease(struct dentry *dentry) +{ + struct ceph_dentry_info *di = ceph_dentry(dentry); + + ceph_put_mds_session(di->lease_session); + di->lease_session = NULL; +} + +static void handle_lease(struct ceph_mds_client *mdsc, struct ceph_msg *msg) +{ + struct super_block *sb = mdsc->client->sb; + struct inode *inode; + struct ceph_mds_session *session; + struct ceph_inode_info *ci; + struct dentry *parent, *dentry; + struct ceph_dentry_info *di; + int mds; + struct ceph_mds_lease *h = msg->front.iov_base; + struct ceph_vino vino; + int mask; + struct qstr dname; + int release = 0; + + if (msg->hdr.src.name.type != CEPH_ENTITY_TYPE_MDS) + return; + mds = le64_to_cpu(msg->hdr.src.name.num); + dout("handle_lease from mds%d\n", mds); + + /* decode */ + if (msg->front.iov_len < sizeof(*h) + sizeof(u32)) + goto bad; + vino.ino = le64_to_cpu(h->ino); + vino.snap = CEPH_NOSNAP; + mask = le16_to_cpu(h->mask); + dname.name = (void *)h + sizeof(*h) + sizeof(u32); + dname.len = msg->front.iov_len - sizeof(*h) - sizeof(u32); + if (dname.len != get_unaligned_le32(h+1)) + goto bad; + + /* find session */ + mutex_lock(&mdsc->mutex); + session = __ceph_lookup_mds_session(mdsc, mds); + mutex_unlock(&mdsc->mutex); + if (!session) { + pr_err("handle_lease got lease but no session mds%d\n", mds); + return; + } + + mutex_lock(&session->s_mutex); + session->s_seq++; + + /* lookup inode */ + inode = ceph_find_inode(sb, vino); + dout("handle_lease '%s', mask %d, ino %llx %p\n", + ceph_lease_op_name(h->action), mask, vino.ino, inode); + if (inode == NULL) { + dout("handle_lease no inode %llx\n", vino.ino); + goto release; + } + ci = ceph_inode(inode); + + /* dentry */ + parent = d_find_alias(inode); + if (!parent) { + dout("no parent dentry on inode %p\n", inode); + WARN_ON(1); + goto release; /* hrm... */ + } + dname.hash = full_name_hash(dname.name, dname.len); + dentry = d_lookup(parent, &dname); + dput(parent); + if (!dentry) + goto release; + + spin_lock(&dentry->d_lock); + di = ceph_dentry(dentry); + switch (h->action) { + case CEPH_MDS_LEASE_REVOKE: + if (di && di->lease_session == session) { + h->seq = cpu_to_le32(di->lease_seq); + __ceph_mdsc_drop_dentry_lease(dentry); + } + release = 1; + break; + + case CEPH_MDS_LEASE_RENEW: + if (di && di->lease_session == session && + di->lease_gen == session->s_cap_gen && + di->lease_renew_from && + di->lease_renew_after == 0) { + unsigned long duration = + le32_to_cpu(h->duration_ms) * HZ / 1000; + + di->lease_seq = le32_to_cpu(h->seq); + dentry->d_time = di->lease_renew_from + duration; + di->lease_renew_after = di->lease_renew_from + + (duration >> 1); + di->lease_renew_from = 0; + } + break; + } + spin_unlock(&dentry->d_lock); + dput(dentry); + + if (!release) + goto out; + +release: + /* let's just reuse the same message */ + h->action = CEPH_MDS_LEASE_REVOKE_ACK; + ceph_msg_get(msg); + ceph_con_send(&session->s_con, msg); + +out: + iput(inode); + mutex_unlock(&session->s_mutex); + ceph_put_mds_session(session); + return; + +bad: + pr_err("corrupt lease message\n"); +} + +void ceph_mdsc_lease_send_msg(struct ceph_mds_session *session, + struct inode *inode, + struct dentry *dentry, char action, + u32 seq) +{ + struct ceph_msg *msg; + struct ceph_mds_lease *lease; + int len = sizeof(*lease) + sizeof(u32); + int dnamelen = 0; + + dout("lease_send_msg inode %p dentry %p %s to mds%d\n", + inode, dentry, ceph_lease_op_name(action), session->s_mds); + dnamelen = dentry->d_name.len; + len += dnamelen; + + msg = ceph_msg_new(CEPH_MSG_CLIENT_LEASE, len, 0, 0, NULL); + if (IS_ERR(msg)) + return; + lease = msg->front.iov_base; + lease->action = action; + lease->mask = cpu_to_le16(CEPH_LOCK_DN); + lease->ino = cpu_to_le64(ceph_vino(inode).ino); + lease->first = lease->last = cpu_to_le64(ceph_vino(inode).snap); + lease->seq = cpu_to_le32(seq); + put_unaligned_le32(dnamelen, lease + 1); + memcpy((void *)(lease + 1) + 4, dentry->d_name.name, dnamelen); + + /* + * if this is a preemptive lease RELEASE, no need to + * flush request stream, since the actual request will + * soon follow. + */ + msg->more_to_follow = (action == CEPH_MDS_LEASE_RELEASE); + + ceph_con_send(&session->s_con, msg); +} + +/* + * Preemptively release a lease we expect to invalidate anyway. + * Pass @inode always, @dentry is optional. + */ +void ceph_mdsc_lease_release(struct ceph_mds_client *mdsc, struct inode *inode, + struct dentry *dentry, int mask) +{ + struct ceph_dentry_info *di; + struct ceph_mds_session *session; + u32 seq; + + BUG_ON(inode == NULL); + BUG_ON(dentry == NULL); + BUG_ON(mask != CEPH_LOCK_DN); + + /* is dentry lease valid? */ + spin_lock(&dentry->d_lock); + di = ceph_dentry(dentry); + if (!di || !di->lease_session || + di->lease_session->s_mds < 0 || + di->lease_gen != di->lease_session->s_cap_gen || + !time_before(jiffies, dentry->d_time)) { + dout("lease_release inode %p dentry %p -- " + "no lease on %d\n", + inode, dentry, mask); + spin_unlock(&dentry->d_lock); + return; + } + + /* we do have a lease on this dentry; note mds and seq */ + session = ceph_get_mds_session(di->lease_session); + seq = di->lease_seq; + __ceph_mdsc_drop_dentry_lease(dentry); + spin_unlock(&dentry->d_lock); + + dout("lease_release inode %p dentry %p mask %d to mds%d\n", + inode, dentry, mask, session->s_mds); + ceph_mdsc_lease_send_msg(session, inode, dentry, + CEPH_MDS_LEASE_RELEASE, seq); + ceph_put_mds_session(session); +} + +/* + * drop all leases (and dentry refs) in preparation for umount + */ +static void drop_leases(struct ceph_mds_client *mdsc) +{ + int i; + + dout("drop_leases\n"); + mutex_lock(&mdsc->mutex); + for (i = 0; i < mdsc->max_sessions; i++) { + struct ceph_mds_session *s = __ceph_lookup_mds_session(mdsc, i); + if (!s) + continue; + mutex_unlock(&mdsc->mutex); + mutex_lock(&s->s_mutex); + mutex_unlock(&s->s_mutex); + ceph_put_mds_session(s); + mutex_lock(&mdsc->mutex); + } + mutex_unlock(&mdsc->mutex); +} + + + +/* + * delayed work -- periodically trim expired leases, renew caps with mds + */ +static void schedule_delayed(struct ceph_mds_client *mdsc) +{ + int delay = 5; + unsigned hz = round_jiffies_relative(HZ * delay); + schedule_delayed_work(&mdsc->delayed_work, hz); +} + +static void delayed_work(struct work_struct *work) +{ + int i; + struct ceph_mds_client *mdsc = + container_of(work, struct ceph_mds_client, delayed_work.work); + int renew_interval; + int renew_caps; + + dout("mdsc delayed_work\n"); + ceph_check_delayed_caps(mdsc, 0); + + mutex_lock(&mdsc->mutex); + renew_interval = mdsc->mdsmap->m_session_timeout >> 2; + renew_caps = time_after_eq(jiffies, HZ*renew_interval + + mdsc->last_renew_caps); + if (renew_caps) + mdsc->last_renew_caps = jiffies; + + for (i = 0; i < mdsc->max_sessions; i++) { + struct ceph_mds_session *s = __ceph_lookup_mds_session(mdsc, i); + if (s == NULL) + continue; + if (s->s_state == CEPH_MDS_SESSION_CLOSING) { + dout("resending session close request for mds%d\n", + s->s_mds); + request_close_session(mdsc, s); + ceph_put_mds_session(s); + continue; + } + if (s->s_ttl && time_after(jiffies, s->s_ttl)) { + if (s->s_state == CEPH_MDS_SESSION_OPEN) { + s->s_state = CEPH_MDS_SESSION_HUNG; + pr_info("mds%d hung\n", s->s_mds); + } + } + if (s->s_state < CEPH_MDS_SESSION_OPEN) { + /* this mds is failed or recovering, just wait */ + ceph_put_mds_session(s); + continue; + } + mutex_unlock(&mdsc->mutex); + + mutex_lock(&s->s_mutex); + if (renew_caps) + send_renew_caps(mdsc, s); + else + ceph_con_keepalive(&s->s_con); + add_cap_releases(mdsc, s, -1); + send_cap_releases(mdsc, s); + mutex_unlock(&s->s_mutex); + ceph_put_mds_session(s); + + mutex_lock(&mdsc->mutex); + } + mutex_unlock(&mdsc->mutex); + + schedule_delayed(mdsc); +} + + +void ceph_mdsc_init(struct ceph_mds_client *mdsc, struct ceph_client *client) +{ + mdsc->client = client; + mutex_init(&mdsc->mutex); + mdsc->mdsmap = kzalloc(sizeof(*mdsc->mdsmap), GFP_NOFS); + init_completion(&mdsc->safe_umount_waiters); + init_completion(&mdsc->session_close_waiters); + INIT_LIST_HEAD(&mdsc->waiting_for_map); + mdsc->sessions = NULL; + mdsc->max_sessions = 0; + mdsc->stopping = 0; + init_rwsem(&mdsc->snap_rwsem); + INIT_RADIX_TREE(&mdsc->snap_realms, GFP_NOFS); + INIT_LIST_HEAD(&mdsc->snap_empty); + spin_lock_init(&mdsc->snap_empty_lock); + mdsc->last_tid = 0; + INIT_RADIX_TREE(&mdsc->request_tree, GFP_NOFS); + INIT_DELAYED_WORK(&mdsc->delayed_work, delayed_work); + mdsc->last_renew_caps = jiffies; + INIT_LIST_HEAD(&mdsc->cap_delay_list); + spin_lock_init(&mdsc->cap_delay_lock); + INIT_LIST_HEAD(&mdsc->snap_flush_list); + spin_lock_init(&mdsc->snap_flush_lock); + mdsc->cap_flush_seq = 0; + INIT_LIST_HEAD(&mdsc->cap_dirty); + mdsc->num_cap_flushing = 0; + spin_lock_init(&mdsc->cap_dirty_lock); + init_waitqueue_head(&mdsc->cap_flushing_wq); + spin_lock_init(&mdsc->dentry_lru_lock); + INIT_LIST_HEAD(&mdsc->dentry_lru); +} + +/* + * Wait for safe replies on open mds requests. If we time out, drop + * all requests from the tree to avoid dangling dentry refs. + */ +static void wait_requests(struct ceph_mds_client *mdsc) +{ + struct ceph_mds_request *req; + struct ceph_client *client = mdsc->client; + + mutex_lock(&mdsc->mutex); + if (__get_oldest_tid(mdsc)) { + mutex_unlock(&mdsc->mutex); + dout("wait_requests waiting for requests\n"); + wait_for_completion_timeout(&mdsc->safe_umount_waiters, + client->mount_args.mount_timeout * HZ); + mutex_lock(&mdsc->mutex); + + /* tear down remaining requests */ + while (radix_tree_gang_lookup(&mdsc->request_tree, + (void **)&req, 0, 1)) { + dout("wait_requests timed out on tid %llu\n", + req->r_tid); + radix_tree_delete(&mdsc->request_tree, req->r_tid); + ceph_mdsc_put_request(req); + } + } + mutex_unlock(&mdsc->mutex); + dout("wait_requests done\n"); +} + +/* + * called before mount is ro, and before dentries are torn down. + * (hmm, does this still race with new lookups?) + */ +void ceph_mdsc_pre_umount(struct ceph_mds_client *mdsc) +{ + dout("pre_umount\n"); + mdsc->stopping = 1; + + drop_leases(mdsc); + ceph_check_delayed_caps(mdsc, 1); + wait_requests(mdsc); +} + +/* + * wait for all write mds requests to flush. + */ +static void wait_unsafe_requests(struct ceph_mds_client *mdsc, u64 want_tid) +{ + struct ceph_mds_request *req; + u64 next_tid = 0; + int got; + + mutex_lock(&mdsc->mutex); + dout("wait_unsafe_requests want %lld\n", want_tid); + while (1) { + got = radix_tree_gang_lookup(&mdsc->request_tree, (void **)&req, + next_tid, 1); + if (!got) + break; + if (req->r_tid > want_tid) + break; + + next_tid = req->r_tid + 1; + if ((req->r_op & CEPH_MDS_OP_WRITE) == 0) + continue; /* not a write op */ + + ceph_mdsc_get_request(req); + mutex_unlock(&mdsc->mutex); + dout("wait_unsafe_requests wait on %llu (want %llu)\n", + req->r_tid, want_tid); + wait_for_completion(&req->r_safe_completion); + mutex_lock(&mdsc->mutex); + ceph_mdsc_put_request(req); + } + mutex_unlock(&mdsc->mutex); + dout("wait_unsafe_requests done\n"); +} + +void ceph_mdsc_sync(struct ceph_mds_client *mdsc) +{ + u64 want_tid, want_flush; + + dout("sync\n"); + mutex_lock(&mdsc->mutex); + want_tid = mdsc->last_tid; + want_flush = mdsc->cap_flush_seq; + mutex_unlock(&mdsc->mutex); + dout("sync want tid %lld flush_seq %lld\n", want_tid, want_flush); + + ceph_check_delayed_caps(mdsc, 1); + + wait_unsafe_requests(mdsc, want_tid); + wait_event(mdsc->cap_flushing_wq, check_cap_flush(mdsc, want_flush)); +} + + +/* + * called after sb is ro. + */ +void ceph_mdsc_close_sessions(struct ceph_mds_client *mdsc) +{ + struct ceph_mds_session *session; + int i; + int n; + struct ceph_client *client = mdsc->client; + unsigned long started, timeout = client->mount_args.mount_timeout * HZ; + + dout("close_sessions\n"); + + mutex_lock(&mdsc->mutex); + + /* close sessions */ + started = jiffies; + while (time_before(jiffies, started + timeout)) { + dout("closing sessions\n"); + n = 0; + for (i = 0; i < mdsc->max_sessions; i++) { + session = __ceph_lookup_mds_session(mdsc, i); + if (!session) + continue; + mutex_unlock(&mdsc->mutex); + mutex_lock(&session->s_mutex); + __close_session(mdsc, session); + mutex_unlock(&session->s_mutex); + ceph_put_mds_session(session); + mutex_lock(&mdsc->mutex); + n++; + } + if (n == 0) + break; + + if (client->mount_state == CEPH_MOUNT_SHUTDOWN) + break; + + dout("waiting for sessions to close\n"); + mutex_unlock(&mdsc->mutex); + wait_for_completion_timeout(&mdsc->session_close_waiters, + timeout); + mutex_lock(&mdsc->mutex); + } + + /* tear down remaining sessions */ + for (i = 0; i < mdsc->max_sessions; i++) { + if (mdsc->sessions[i]) { + session = get_session(mdsc->sessions[i]); + unregister_session(mdsc, i); + mutex_unlock(&mdsc->mutex); + mutex_lock(&session->s_mutex); + remove_session_caps(session); + mutex_unlock(&session->s_mutex); + ceph_put_mds_session(session); + mutex_lock(&mdsc->mutex); + } + } + + WARN_ON(!list_empty(&mdsc->cap_delay_list)); + + mutex_unlock(&mdsc->mutex); + + ceph_cleanup_empty_realms(mdsc); + + cancel_delayed_work_sync(&mdsc->delayed_work); /* cancel timer */ + + dout("stopped\n"); +} + +void ceph_mdsc_stop(struct ceph_mds_client *mdsc) +{ + dout("stop\n"); + cancel_delayed_work_sync(&mdsc->delayed_work); /* cancel timer */ + if (mdsc->mdsmap) + ceph_mdsmap_destroy(mdsc->mdsmap); + kfree(mdsc->sessions); +} + + +/* + * handle mds map update. + */ +void ceph_mdsc_handle_map(struct ceph_mds_client *mdsc, struct ceph_msg *msg) +{ + u32 epoch; + u32 maplen; + void *p = msg->front.iov_base; + void *end = p + msg->front.iov_len; + struct ceph_mdsmap *newmap, *oldmap; + struct ceph_fsid fsid; + int err = -EINVAL; + + ceph_decode_need(&p, end, sizeof(fsid)+2*sizeof(u32), bad); + ceph_decode_copy(&p, &fsid, sizeof(fsid)); + if (ceph_fsid_compare(&fsid, &mdsc->client->monc.monmap->fsid)) { + pr_err("got mdsmap with wrong fsid\n"); + return; + } + ceph_decode_32(&p, epoch); + ceph_decode_32(&p, maplen); + dout("handle_map epoch %u len %d\n", epoch, (int)maplen); + + /* do we need it? */ + ceph_monc_got_mdsmap(&mdsc->client->monc, epoch); + mutex_lock(&mdsc->mutex); + if (mdsc->mdsmap && epoch <= mdsc->mdsmap->m_epoch) { + dout("handle_map epoch %u <= our %u\n", + epoch, mdsc->mdsmap->m_epoch); + mutex_unlock(&mdsc->mutex); + return; + } + + newmap = ceph_mdsmap_decode(&p, end); + if (IS_ERR(newmap)) { + err = PTR_ERR(newmap); + goto bad_unlock; + } + + /* swap into place */ + if (mdsc->mdsmap) { + oldmap = mdsc->mdsmap; + mdsc->mdsmap = newmap; + check_new_map(mdsc, newmap, oldmap); + ceph_mdsmap_destroy(oldmap); + } else { + mdsc->mdsmap = newmap; /* first mds map */ + } + mdsc->client->sb->s_maxbytes = mdsc->mdsmap->m_max_file_size; + + __wake_requests(mdsc, &mdsc->waiting_for_map); + + mutex_unlock(&mdsc->mutex); + schedule_delayed(mdsc); + return; + +bad_unlock: + mutex_unlock(&mdsc->mutex); +bad: + pr_err("error decoding mdsmap %d\n", err); + return; +} + +static struct ceph_connection *con_get(struct ceph_connection *con) +{ + struct ceph_mds_session *s = con->private; + + if (get_session(s)) { + dout("mdsc con_get %p %d -> %d\n", s, + atomic_read(&s->s_ref) - 1, atomic_read(&s->s_ref)); + return con; + } + dout("mdsc con_get %p FAIL\n", s); + return NULL; +} + +static void con_put(struct ceph_connection *con) +{ + struct ceph_mds_session *s = con->private; + + dout("mdsc con_put %p %d -> %d\n", s, atomic_read(&s->s_ref), + atomic_read(&s->s_ref) - 1); + ceph_put_mds_session(s); +} + +/* + * if the client is unresponsive for long enough, the mds will kill + * the session entirely. + */ +static void peer_reset(struct ceph_connection *con) +{ + struct ceph_mds_session *s = con->private; + + pr_err("mds%d gave us the boot. IMPLEMENT RECONNECT.\n", + s->s_mds); +} + +static void dispatch(struct ceph_connection *con, struct ceph_msg *msg) +{ + struct ceph_mds_session *s = con->private; + struct ceph_mds_client *mdsc = s->s_mdsc; + int type = le16_to_cpu(msg->hdr.type); + + switch (type) { + case CEPH_MSG_MDS_MAP: + ceph_mdsc_handle_map(mdsc, msg); + break; + case CEPH_MSG_CLIENT_SESSION: + handle_session(s, msg); + break; + case CEPH_MSG_CLIENT_REPLY: + handle_reply(s, msg); + break; + case CEPH_MSG_CLIENT_REQUEST_FORWARD: + handle_forward(mdsc, msg); + break; + case CEPH_MSG_CLIENT_CAPS: + ceph_handle_caps(s, msg); + break; + case CEPH_MSG_CLIENT_SNAP: + ceph_handle_snap(mdsc, msg); + break; + case CEPH_MSG_CLIENT_LEASE: + handle_lease(mdsc, msg); + break; + + default: + pr_err("received unknown message type %d %s\n", type, + ceph_msg_type_name(type)); + } + ceph_msg_put(msg); +} + +const static struct ceph_connection_operations mds_con_ops = { + .get = con_get, + .put = con_put, + .dispatch = dispatch, + .peer_reset = peer_reset, + .alloc_msg = ceph_alloc_msg, + .alloc_middle = ceph_alloc_middle, +}; + + + + +/* eof */ diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h new file mode 100644 index 0000000..f566e9c --- /dev/null +++ b/fs/ceph/mds_client.h @@ -0,0 +1,321 @@ +#ifndef _FS_CEPH_MDS_CLIENT_H +#define _FS_CEPH_MDS_CLIENT_H + +#include +#include +#include +#include +#include + +#include "types.h" +#include "messenger.h" +#include "mdsmap.h" + +/* + * Some lock dependencies: + * + * session->s_mutex + * mdsc->mutex + * + * mdsc->snap_rwsem + * + * inode->i_lock + * mdsc->snap_flush_lock + * mdsc->cap_delay_lock + * + */ + +struct ceph_client; +struct ceph_cap; + +/* + * parsed info about a single inode. pointers are into the encoded + * on-wire structures within the mds reply message payload. + */ +struct ceph_mds_reply_info_in { + struct ceph_mds_reply_inode *in; + u32 symlink_len; + char *symlink; + u32 xattr_len; + char *xattr_data; +}; + +/* + * parsed info about an mds reply, including information about the + * target inode and/or its parent directory and dentry, and directory + * contents (for readdir results). + */ +struct ceph_mds_reply_info_parsed { + struct ceph_mds_reply_head *head; + + struct ceph_mds_reply_info_in diri, targeti; + struct ceph_mds_reply_dirfrag *dirfrag; + char *dname; + u32 dname_len; + struct ceph_mds_reply_lease *dlease; + + struct ceph_mds_reply_dirfrag *dir_dir; + int dir_nr; + char **dir_dname; + u32 *dir_dname_len; + struct ceph_mds_reply_lease **dir_dlease; + struct ceph_mds_reply_info_in *dir_in; + u8 dir_complete, dir_end; + + /* encoded blob describing snapshot contexts for certain + operations (e.g., open) */ + void *snapblob; + int snapblob_len; +}; + + +/* + * cap releases are batched and sent to the MDS en masse. + */ +#define CEPH_CAPS_PER_RELEASE ((PAGE_CACHE_SIZE - \ + sizeof(struct ceph_mds_cap_release)) / \ + sizeof(struct ceph_mds_cap_item)) + + +/* + * state associated with each MDS<->client session + */ +enum { + CEPH_MDS_SESSION_NEW = 1, + CEPH_MDS_SESSION_OPENING = 2, + CEPH_MDS_SESSION_OPEN = 3, + CEPH_MDS_SESSION_HUNG = 4, + CEPH_MDS_SESSION_CLOSING = 5, + CEPH_MDS_SESSION_RESTARTING = 6, + CEPH_MDS_SESSION_RECONNECTING = 7, +}; + +struct ceph_mds_session { + struct ceph_mds_client *s_mdsc; + int s_mds; + int s_state; + unsigned long s_ttl; /* time until mds kills us */ + u64 s_seq; /* incoming msg seq # */ + struct mutex s_mutex; /* serialize session messages */ + + struct ceph_connection s_con; + + /* protected by s_cap_lock */ + spinlock_t s_cap_lock; + u32 s_cap_gen; /* inc each time we get mds stale msg */ + unsigned long s_cap_ttl; /* when session caps expire */ + struct list_head s_caps; /* all caps issued by this session */ + int s_nr_caps, s_trim_caps; + int s_num_cap_releases; + struct list_head s_cap_releases; /* waiting cap_release messages */ + struct list_head s_cap_releases_done; /* ready to send */ + + /* protected by mutex */ + struct list_head s_cap_flushing; /* inodes w/ flushing caps */ + struct list_head s_cap_snaps_flushing; + unsigned long s_renew_requested; /* last time we sent a renew req */ + u64 s_renew_seq; + + atomic_t s_ref; + struct list_head s_waiting; /* waiting requests */ + struct list_head s_unsafe; /* unsafe requests */ +}; + +/* + * modes of choosing which MDS to send a request to + */ +enum { + USE_ANY_MDS, + USE_RANDOM_MDS, + USE_AUTH_MDS, /* prefer authoritative mds for this metadata item */ +}; + +struct ceph_mds_request; +struct ceph_mds_client; + +/* + * request completion callback + */ +typedef void (*ceph_mds_request_callback_t) (struct ceph_mds_client *mdsc, + struct ceph_mds_request *req); + +/* + * an in-flight mds request + */ +struct ceph_mds_request { + u64 r_tid; /* transaction id */ + + int r_op; /* mds op code */ + int r_mds; + + /* operation on what? */ + struct inode *r_inode; /* arg1 */ + struct dentry *r_dentry; /* arg1 */ + struct dentry *r_old_dentry; /* arg2: rename from or link from */ + char *r_path1, *r_path2; + struct ceph_vino r_ino1, r_ino2; + + struct inode *r_locked_dir; /* dir (if any) i_mutex locked by vfs */ + struct inode *r_target_inode; /* resulting inode */ + + union ceph_mds_request_args r_args; + int r_fmode; /* file mode, if expecting cap */ + + /* for choosing which mds to send this request to */ + int r_direct_mode; + u32 r_direct_hash; /* choose dir frag based on this dentry hash */ + bool r_direct_is_hash; /* true if r_direct_hash is valid */ + + /* data payload is used for xattr ops */ + struct page **r_pages; + int r_num_pages; + int r_data_len; + + /* what caps shall we drop? */ + int r_inode_drop, r_inode_unless; + int r_dentry_drop, r_dentry_unless; + int r_old_dentry_drop, r_old_dentry_unless; + struct inode *r_old_inode; + int r_old_inode_drop, r_old_inode_unless; + + struct ceph_msg *r_request; /* original request */ + struct ceph_msg *r_reply; + struct ceph_mds_reply_info_parsed r_reply_info; + int r_err; + + unsigned long r_timeout; /* optional. jiffies */ + unsigned long r_started; /* start time to measure timeout against */ + unsigned long r_request_started; /* start time for mds request only, + used to measure lease durations */ + + /* link unsafe requests to parent directory, for fsync */ + struct inode *r_unsafe_dir; + struct list_head r_unsafe_dir_item; + + struct ceph_mds_session *r_session; + + int r_attempts; /* resend attempts */ + int r_num_fwd; /* number of forward attempts */ + int r_num_stale; + int r_resend_mds; /* mds to resend to next, if any*/ + + atomic_t r_ref; + struct list_head r_wait; + struct completion r_completion; + struct completion r_safe_completion; + ceph_mds_request_callback_t r_callback; + struct list_head r_unsafe_item; /* per-session unsafe list item */ + bool r_got_unsafe, r_got_safe; + + bool r_did_prepopulate; + u32 r_readdir_offset; + + struct ceph_cap_reservation r_caps_reservation; + int r_num_caps; +}; + +/* + * mds client state + */ +struct ceph_mds_client { + struct ceph_client *client; + struct mutex mutex; /* all nested structures */ + + struct ceph_mdsmap *mdsmap; + struct completion safe_umount_waiters, session_close_waiters; + struct list_head waiting_for_map; + + struct ceph_mds_session **sessions; /* NULL for mds if no session */ + int max_sessions; /* len of s_mds_sessions */ + int stopping; /* true if shutting down */ + + /* + * snap_rwsem will cover cap linkage into snaprealms, and + * realm snap contexts. (later, we can do per-realm snap + * contexts locks..) the empty list contains realms with no + * references (implying they contain no inodes with caps) that + * should be destroyed. + */ + struct rw_semaphore snap_rwsem; + struct radix_tree_root snap_realms; + struct list_head snap_empty; + spinlock_t snap_empty_lock; /* protect snap_empty */ + + u64 last_tid; /* most recent mds request */ + struct radix_tree_root request_tree; /* pending mds requests */ + struct delayed_work delayed_work; /* delayed work */ + unsigned long last_renew_caps; /* last time we renewed our caps */ + struct list_head cap_delay_list; /* caps with delayed release */ + spinlock_t cap_delay_lock; /* protects cap_delay_list */ + struct list_head snap_flush_list; /* cap_snaps ready to flush */ + spinlock_t snap_flush_lock; + + u64 cap_flush_seq; + struct list_head cap_dirty; /* inodes with dirty caps */ + int num_cap_flushing; /* # caps we are flushing */ + spinlock_t cap_dirty_lock; /* protects above items */ + wait_queue_head_t cap_flushing_wq; + + struct dentry *debugfs_file; + + spinlock_t dentry_lru_lock; + struct list_head dentry_lru; + int num_dentry; +}; + +extern const char *ceph_mds_op_name(int op); + +extern struct ceph_mds_session * +__ceph_lookup_mds_session(struct ceph_mds_client *, int mds); + +static inline struct ceph_mds_session * +ceph_get_mds_session(struct ceph_mds_session *s) +{ + atomic_inc(&s->s_ref); + return s; +} + +extern void ceph_put_mds_session(struct ceph_mds_session *s); + +extern int ceph_send_msg_mds(struct ceph_mds_client *mdsc, + struct ceph_msg *msg, int mds); + +extern void ceph_mdsc_init(struct ceph_mds_client *mdsc, + struct ceph_client *client); +extern void ceph_mdsc_close_sessions(struct ceph_mds_client *mdsc); +extern void ceph_mdsc_stop(struct ceph_mds_client *mdsc); + +extern void ceph_mdsc_sync(struct ceph_mds_client *mdsc); + +extern void ceph_mdsc_lease_release(struct ceph_mds_client *mdsc, + struct inode *inode, + struct dentry *dn, int mask); + +extern struct ceph_mds_request * +ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op, int mode); +extern void ceph_mdsc_submit_request(struct ceph_mds_client *mdsc, + struct ceph_mds_request *req); +extern int ceph_mdsc_do_request(struct ceph_mds_client *mdsc, + struct inode *dir, + struct ceph_mds_request *req); +static inline void ceph_mdsc_get_request(struct ceph_mds_request *req) +{ + atomic_inc(&req->r_ref); +} +extern void ceph_mdsc_put_request(struct ceph_mds_request *req); + +extern void ceph_mdsc_pre_umount(struct ceph_mds_client *mdsc); + +extern char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *base, + int stop_on_nosnap); + +extern void __ceph_mdsc_drop_dentry_lease(struct dentry *dentry); +extern void ceph_mdsc_lease_send_msg(struct ceph_mds_session *session, + struct inode *inode, + struct dentry *dentry, char action, + u32 seq); + +extern void ceph_mdsc_handle_map(struct ceph_mds_client *mdsc, + struct ceph_msg *msg); + +#endif diff --git a/fs/ceph/mdsmap.c b/fs/ceph/mdsmap.c new file mode 100644 index 0000000..15913cbe --- /dev/null +++ b/fs/ceph/mdsmap.c @@ -0,0 +1,166 @@ +#include "ceph_debug.h" + +#include +#include +#include +#include +#include + +#include "mdsmap.h" +#include "messenger.h" +#include "decode.h" + +#include "super.h" + + +/* + * choose a random mds that is "up" (i.e. has a state > 0), or -1. + */ +int ceph_mdsmap_get_random_mds(struct ceph_mdsmap *m) +{ + int n = 0; + int i; + char r; + + /* count */ + for (i = 0; i < m->m_max_mds; i++) + if (m->m_info[i].state > 0) + n++; + if (n == 0) + return -1; + + /* pick */ + get_random_bytes(&r, 1); + n = r % n; + i = 0; + for (i = 0; n > 0; i++, n--) + while (m->m_info[i].state <= 0) + i++; + + return i; +} + +/* + * Decode an MDS map + * + * Ignore any fields we don't care about (there are quite a few of + * them). + */ +struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end) +{ + struct ceph_mdsmap *m; + int i, j, n; + int err = -EINVAL; + u16 version; + + m = kzalloc(sizeof(*m), GFP_NOFS); + if (m == NULL) + return ERR_PTR(-ENOMEM); + + ceph_decode_16_safe(p, end, version, bad); + + ceph_decode_need(p, end, 8*sizeof(u32) + sizeof(u64), bad); + ceph_decode_32(p, m->m_epoch); + ceph_decode_32(p, m->m_client_epoch); + ceph_decode_32(p, m->m_last_failure); + ceph_decode_32(p, m->m_root); + ceph_decode_32(p, m->m_session_timeout); + ceph_decode_32(p, m->m_session_autoclose); + ceph_decode_64(p, m->m_max_file_size); + ceph_decode_32(p, m->m_max_mds); + + m->m_info = kcalloc(m->m_max_mds, sizeof(*m->m_info), GFP_NOFS); + if (m->m_info == NULL) + goto badmem; + + /* pick out active nodes from mds_info (state > 0) */ + ceph_decode_32(p, n); + for (i = 0; i < n; i++) { + u32 namelen; + s32 mds, inc, state; + u64 state_seq; + u8 infoversion; + struct ceph_entity_addr addr; + u32 num_export_targets; + void *pexport_targets = NULL; + + ceph_decode_need(p, end, sizeof(addr) + 1 + sizeof(u32), bad); + *p += sizeof(addr); /* skip addr key */ + ceph_decode_8(p, infoversion); + ceph_decode_32(p, namelen); /* skip mds name */ + *p += namelen; + + ceph_decode_need(p, end, + 5*sizeof(u32) + sizeof(u64) + + sizeof(addr) + sizeof(struct ceph_timespec), + bad); + ceph_decode_32(p, mds); + ceph_decode_32(p, inc); + ceph_decode_32(p, state); + ceph_decode_64(p, state_seq); + ceph_decode_copy(p, &addr, sizeof(addr)); + *p += sizeof(struct ceph_timespec); + *p += sizeof(u32); + ceph_decode_32_safe(p, end, namelen, bad); + *p += sizeof(namelen); + if (infoversion >= 2) { + ceph_decode_32_safe(p, end, num_export_targets, bad); + pexport_targets = *p; + *p += sizeof(num_export_targets * sizeof(u32)); + } else { + num_export_targets = 0; + } + + dout("mdsmap_decode %d/%d mds%d.%d %s %s\n", + i+1, n, mds, inc, pr_addr(&addr.in_addr), + ceph_mds_state_name(state)); + if (mds >= 0 && mds < m->m_max_mds && state > 0) { + m->m_info[mds].state = state; + m->m_info[mds].addr = addr; + m->m_info[mds].num_export_targets = num_export_targets; + if (num_export_targets) { + m->m_info[mds].export_targets = + kcalloc(num_export_targets, sizeof(u32), + GFP_NOFS); + for (j = 0; j < num_export_targets; j++) + ceph_decode_32(&pexport_targets, + m->m_info[mds].export_targets[j]); + } else { + m->m_info[mds].export_targets = NULL; + } + } + } + + /* pg_pools */ + ceph_decode_32_safe(p, end, n, bad); + m->m_num_data_pg_pools = n; + m->m_data_pg_pools = kcalloc(n, sizeof(u32), GFP_NOFS); + if (!m->m_data_pg_pools) + goto badmem; + ceph_decode_need(p, end, sizeof(u32)*(n+1), bad); + for (i = 0; i < n; i++) + ceph_decode_32(p, m->m_data_pg_pools[i]); + ceph_decode_32(p, m->m_cas_pg_pool); + + /* ok, we don't care about the rest. */ + dout("mdsmap_decode success epoch %u\n", m->m_epoch); + return m; + +badmem: + err = -ENOMEM; +bad: + pr_err("corrupt mdsmap\n"); + ceph_mdsmap_destroy(m); + return ERR_PTR(-EINVAL); +} + +void ceph_mdsmap_destroy(struct ceph_mdsmap *m) +{ + int i; + + for (i = 0; i < m->m_max_mds; i++) + kfree(m->m_info[i].export_targets); + kfree(m->m_info); + kfree(m->m_data_pg_pools); + kfree(m); +} diff --git a/fs/ceph/mdsmap.h b/fs/ceph/mdsmap.h new file mode 100644 index 0000000..d317308 --- /dev/null +++ b/fs/ceph/mdsmap.h @@ -0,0 +1,53 @@ +#ifndef _FS_CEPH_MDSMAP_H +#define _FS_CEPH_MDSMAP_H + +#include "types.h" + +/* + * mds map - describe servers in the mds cluster. + * + * we limit fields to those the client actually xcares about + */ +struct ceph_mds_info { + struct ceph_entity_addr addr; + s32 state; + int num_export_targets; + u32 *export_targets; +}; + +struct ceph_mdsmap { + u32 m_epoch, m_client_epoch, m_last_failure; + u32 m_root; + u32 m_session_timeout; /* seconds */ + u32 m_session_autoclose; /* seconds */ + u64 m_max_file_size; + u32 m_max_mds; /* size of m_addr, m_state arrays */ + struct ceph_mds_info *m_info; + + /* which object pools file data can be stored in */ + int m_num_data_pg_pools; + u32 *m_data_pg_pools; + u32 m_cas_pg_pool; +}; + +static inline struct ceph_entity_addr * +ceph_mdsmap_get_addr(struct ceph_mdsmap *m, int w) +{ + if (w >= m->m_max_mds) + return NULL; + return &m->m_info[w].addr; +} + +static inline int ceph_mdsmap_get_state(struct ceph_mdsmap *m, int w) +{ + BUG_ON(w < 0); + if (w >= m->m_max_mds) + return CEPH_MDS_STATE_DNE; + return m->m_info[w].state; +} + +extern int ceph_mdsmap_get_random_mds(struct ceph_mdsmap *m); +extern struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end); +extern void ceph_mdsmap_destroy(struct ceph_mdsmap *m); + +#endif -- cgit v0.10.2 From f24e9980eb860d8600cbe5ef3d2fd9295320d229 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 6 Oct 2009 11:31:10 -0700 Subject: ceph: OSD client The OSD client is responsible for reading and writing data from/to the object storage pool. This includes determining where objects are stored in the cluster, and ensuring that requests are retried or redirected in the event of a node failure or data migration. If an OSD does not respond before a timeout expires, keepalive messages are sent across the lossless, ordered communications channel to ensure that any break in the TCP is discovered. If the session does reset, a reconnection is attempted and affected requests are resent (by the message transport layer). Signed-off-by: Sage Weil diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c new file mode 100644 index 0000000..978593a --- /dev/null +++ b/fs/ceph/osd_client.c @@ -0,0 +1,1294 @@ +#include "ceph_debug.h" + +#include +#include +#include +#include +#include +#include + +#include "super.h" +#include "osd_client.h" +#include "messenger.h" +#include "decode.h" + +const static struct ceph_connection_operations osd_con_ops; + +static void kick_requests(struct ceph_osd_client *osdc, struct ceph_osd *osd); + +/* + * Implement client access to distributed object storage cluster. + * + * All data objects are stored within a cluster/cloud of OSDs, or + * "object storage devices." (Note that Ceph OSDs have _nothing_ to + * do with the T10 OSD extensions to SCSI.) Ceph OSDs are simply + * remote daemons serving up and coordinating consistent and safe + * access to storage. + * + * Cluster membership and the mapping of data objects onto storage devices + * are described by the osd map. + * + * We keep track of pending OSD requests (read, write), resubmit + * requests to different OSDs when the cluster topology/data layout + * change, or retry the affected requests when the communications + * channel with an OSD is reset. + */ + +/* + * calculate the mapping of a file extent onto an object, and fill out the + * request accordingly. shorten extent as necessary if it crosses an + * object boundary. + * + * fill osd op in request message. + */ +static void calc_layout(struct ceph_osd_client *osdc, + struct ceph_vino vino, struct ceph_file_layout *layout, + u64 off, u64 *plen, + struct ceph_osd_request *req) +{ + struct ceph_osd_request_head *reqhead = req->r_request->front.iov_base; + struct ceph_osd_op *op = (void *)(reqhead + 1); + u64 orig_len = *plen; + u64 objoff, objlen; /* extent in object */ + u64 bno; + + reqhead->snapid = cpu_to_le64(vino.snap); + + /* object extent? */ + ceph_calc_file_object_mapping(layout, off, plen, &bno, + &objoff, &objlen); + if (*plen < orig_len) + dout(" skipping last %llu, final file extent %llu~%llu\n", + orig_len - *plen, off, *plen); + + sprintf(req->r_oid, "%llx.%08llx", vino.ino, bno); + req->r_oid_len = strlen(req->r_oid); + + op->extent.offset = cpu_to_le64(objoff); + op->extent.length = cpu_to_le64(objlen); + req->r_num_pages = calc_pages_for(off, *plen); + + dout("calc_layout %s (%d) %llu~%llu (%d pages)\n", + req->r_oid, req->r_oid_len, objoff, objlen, req->r_num_pages); +} + + +/* + * requests + */ +void ceph_osdc_put_request(struct ceph_osd_request *req) +{ + dout("osdc put_request %p %d -> %d\n", req, atomic_read(&req->r_ref), + atomic_read(&req->r_ref)-1); + BUG_ON(atomic_read(&req->r_ref) <= 0); + if (atomic_dec_and_test(&req->r_ref)) { + if (req->r_request) + ceph_msg_put(req->r_request); + if (req->r_reply) + ceph_msg_put(req->r_reply); + if (req->r_own_pages) + ceph_release_page_vector(req->r_pages, + req->r_num_pages); + ceph_put_snap_context(req->r_snapc); + if (req->r_mempool) + mempool_free(req, req->r_osdc->req_mempool); + else + kfree(req); + } +} + +/* + * build new request AND message, calculate layout, and adjust file + * extent as needed. + * + * if the file was recently truncated, we include information about its + * old and new size so that the object can be updated appropriately. (we + * avoid synchronously deleting truncated objects because it's slow.) + * + * if @do_sync, include a 'startsync' command so that the osd will flush + * data quickly. + */ +struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc, + struct ceph_file_layout *layout, + struct ceph_vino vino, + u64 off, u64 *plen, + int opcode, int flags, + struct ceph_snap_context *snapc, + int do_sync, + u32 truncate_seq, + u64 truncate_size, + struct timespec *mtime, + bool use_mempool, int num_reply) +{ + struct ceph_osd_request *req; + struct ceph_msg *msg; + struct ceph_osd_request_head *head; + struct ceph_osd_op *op; + void *p; + int do_trunc = truncate_seq && (off + *plen > truncate_size); + int num_op = 1 + do_sync + do_trunc; + size_t msg_size = sizeof(*head) + num_op*sizeof(*op); + int err, i; + u64 prevofs; + + if (use_mempool) { + req = mempool_alloc(osdc->req_mempool, GFP_NOFS); + memset(req, 0, sizeof(*req)); + } else { + req = kzalloc(sizeof(*req), GFP_NOFS); + } + if (req == NULL) + return ERR_PTR(-ENOMEM); + + err = ceph_msgpool_resv(&osdc->msgpool_op_reply, num_reply); + if (err) { + ceph_osdc_put_request(req); + return ERR_PTR(-ENOMEM); + } + + req->r_osdc = osdc; + req->r_mempool = use_mempool; + atomic_set(&req->r_ref, 1); + init_completion(&req->r_completion); + init_completion(&req->r_safe_completion); + INIT_LIST_HEAD(&req->r_unsafe_item); + req->r_flags = flags; + + WARN_ON((flags & (CEPH_OSD_FLAG_READ|CEPH_OSD_FLAG_WRITE)) == 0); + + /* create message; allow space for oid */ + msg_size += 40; + if (snapc) + msg_size += sizeof(u64) * snapc->num_snaps; + if (use_mempool) + msg = ceph_msgpool_get(&osdc->msgpool_op); + else + msg = ceph_msg_new(CEPH_MSG_OSD_OP, msg_size, 0, 0, NULL); + if (IS_ERR(msg)) { + ceph_msgpool_resv(&osdc->msgpool_op_reply, num_reply); + ceph_osdc_put_request(req); + return ERR_PTR(PTR_ERR(msg)); + } + msg->hdr.type = cpu_to_le16(CEPH_MSG_OSD_OP); + memset(msg->front.iov_base, 0, msg->front.iov_len); + head = msg->front.iov_base; + op = (void *)(head + 1); + p = (void *)(op + num_op); + + req->r_request = msg; + req->r_snapc = ceph_get_snap_context(snapc); + + head->client_inc = cpu_to_le32(1); /* always, for now. */ + head->flags = cpu_to_le32(flags); + if (flags & CEPH_OSD_FLAG_WRITE) + ceph_encode_timespec(&head->mtime, mtime); + head->num_ops = cpu_to_le16(num_op); + op->op = cpu_to_le16(opcode); + + /* calculate max write size */ + calc_layout(osdc, vino, layout, off, plen, req); + req->r_file_layout = *layout; /* keep a copy */ + + if (flags & CEPH_OSD_FLAG_WRITE) { + req->r_request->hdr.data_off = cpu_to_le16(off); + req->r_request->hdr.data_len = cpu_to_le32(*plen); + op->payload_len = cpu_to_le32(*plen); + } + + /* fill in oid */ + head->object_len = cpu_to_le32(req->r_oid_len); + memcpy(p, req->r_oid, req->r_oid_len); + p += req->r_oid_len; + + /* additional ops */ + if (do_trunc) { + op++; + op->op = cpu_to_le16(opcode == CEPH_OSD_OP_READ ? + CEPH_OSD_OP_MASKTRUNC : CEPH_OSD_OP_SETTRUNC); + op->trunc.truncate_seq = cpu_to_le32(truncate_seq); + prevofs = le64_to_cpu((op-1)->extent.offset); + op->trunc.truncate_size = cpu_to_le64(truncate_size - + (off-prevofs)); + } + if (do_sync) { + op++; + op->op = cpu_to_le16(CEPH_OSD_OP_STARTSYNC); + } + if (snapc) { + head->snap_seq = cpu_to_le64(snapc->seq); + head->num_snaps = cpu_to_le32(snapc->num_snaps); + for (i = 0; i < snapc->num_snaps; i++) { + put_unaligned_le64(snapc->snaps[i], p); + p += sizeof(u64); + } + } + + BUG_ON(p > msg->front.iov_base + msg->front.iov_len); + return req; +} + +/* + * We keep osd requests in an rbtree, sorted by ->r_tid. + */ +static void __insert_request(struct ceph_osd_client *osdc, + struct ceph_osd_request *new) +{ + struct rb_node **p = &osdc->requests.rb_node; + struct rb_node *parent = NULL; + struct ceph_osd_request *req = NULL; + + while (*p) { + parent = *p; + req = rb_entry(parent, struct ceph_osd_request, r_node); + if (new->r_tid < req->r_tid) + p = &(*p)->rb_left; + else if (new->r_tid > req->r_tid) + p = &(*p)->rb_right; + else + BUG(); + } + + rb_link_node(&new->r_node, parent, p); + rb_insert_color(&new->r_node, &osdc->requests); +} + +static struct ceph_osd_request *__lookup_request(struct ceph_osd_client *osdc, + u64 tid) +{ + struct ceph_osd_request *req; + struct rb_node *n = osdc->requests.rb_node; + + while (n) { + req = rb_entry(n, struct ceph_osd_request, r_node); + if (tid < req->r_tid) + n = n->rb_left; + else if (tid > req->r_tid) + n = n->rb_right; + else + return req; + } + return NULL; +} + +static struct ceph_osd_request * +__lookup_request_ge(struct ceph_osd_client *osdc, + u64 tid) +{ + struct ceph_osd_request *req; + struct rb_node *n = osdc->requests.rb_node; + + while (n) { + req = rb_entry(n, struct ceph_osd_request, r_node); + if (tid < req->r_tid) { + if (!n->rb_left) + return req; + n = n->rb_left; + } else if (tid > req->r_tid) { + n = n->rb_right; + } else { + return req; + } + } + return NULL; +} + + +/* + * The messaging layer will reconnect to the osd as needed. If the + * session has dropped, the OSD will have dropped the session state, + * and we'll get notified by the messaging layer. If that happens, we + * need to resubmit all requests for that osd. + */ +static void osd_reset(struct ceph_connection *con) +{ + struct ceph_osd *osd = con->private; + struct ceph_osd_client *osdc; + + if (!osd) + return; + dout("osd_reset osd%d\n", osd->o_osd); + osdc = osd->o_osdc; + osd->o_incarnation++; + down_read(&osdc->map_sem); + kick_requests(osdc, osd); + up_read(&osdc->map_sem); +} + +/* + * Track open sessions with osds. + */ +static struct ceph_osd *create_osd(struct ceph_osd_client *osdc) +{ + struct ceph_osd *osd; + + osd = kzalloc(sizeof(*osd), GFP_NOFS); + if (!osd) + return NULL; + + atomic_set(&osd->o_ref, 1); + osd->o_osdc = osdc; + INIT_LIST_HEAD(&osd->o_requests); + osd->o_incarnation = 1; + + ceph_con_init(osdc->client->msgr, &osd->o_con); + osd->o_con.private = osd; + osd->o_con.ops = &osd_con_ops; + osd->o_con.peer_name.type = CEPH_ENTITY_TYPE_OSD; + return osd; +} + +static struct ceph_osd *get_osd(struct ceph_osd *osd) +{ + if (atomic_inc_not_zero(&osd->o_ref)) { + dout("get_osd %p %d -> %d\n", osd, atomic_read(&osd->o_ref)-1, + atomic_read(&osd->o_ref)); + return osd; + } else { + dout("get_osd %p FAIL\n", osd); + return NULL; + } +} + +static void put_osd(struct ceph_osd *osd) +{ + dout("put_osd %p %d -> %d\n", osd, atomic_read(&osd->o_ref), + atomic_read(&osd->o_ref) - 1); + if (atomic_dec_and_test(&osd->o_ref)) { + ceph_con_shutdown(&osd->o_con); + kfree(osd); + } +} + +/* + * remove an osd from our map + */ +static void remove_osd(struct ceph_osd_client *osdc, struct ceph_osd *osd) +{ + dout("remove_osd %p\n", osd); + BUG_ON(!list_empty(&osd->o_requests)); + rb_erase(&osd->o_node, &osdc->osds); + ceph_con_close(&osd->o_con); + put_osd(osd); +} + +/* + * reset osd connect + */ +static int reset_osd(struct ceph_osd_client *osdc, struct ceph_osd *osd) +{ + int ret = 0; + + dout("reset_osd %p osd%d\n", osd, osd->o_osd); + if (list_empty(&osd->o_requests)) { + remove_osd(osdc, osd); + } else { + ceph_con_close(&osd->o_con); + ceph_con_open(&osd->o_con, &osdc->osdmap->osd_addr[osd->o_osd]); + osd->o_incarnation++; + } + return ret; +} + +static void __insert_osd(struct ceph_osd_client *osdc, struct ceph_osd *new) +{ + struct rb_node **p = &osdc->osds.rb_node; + struct rb_node *parent = NULL; + struct ceph_osd *osd = NULL; + + while (*p) { + parent = *p; + osd = rb_entry(parent, struct ceph_osd, o_node); + if (new->o_osd < osd->o_osd) + p = &(*p)->rb_left; + else if (new->o_osd > osd->o_osd) + p = &(*p)->rb_right; + else + BUG(); + } + + rb_link_node(&new->o_node, parent, p); + rb_insert_color(&new->o_node, &osdc->osds); +} + +static struct ceph_osd *__lookup_osd(struct ceph_osd_client *osdc, int o) +{ + struct ceph_osd *osd; + struct rb_node *n = osdc->osds.rb_node; + + while (n) { + osd = rb_entry(n, struct ceph_osd, o_node); + if (o < osd->o_osd) + n = n->rb_left; + else if (o > osd->o_osd) + n = n->rb_right; + else + return osd; + } + return NULL; +} + + +/* + * Register request, assign tid. If this is the first request, set up + * the timeout event. + */ +static void register_request(struct ceph_osd_client *osdc, + struct ceph_osd_request *req) +{ + struct ceph_osd_request_head *head = req->r_request->front.iov_base; + + mutex_lock(&osdc->request_mutex); + req->r_tid = ++osdc->last_tid; + head->tid = cpu_to_le64(req->r_tid); + + dout("register_request %p tid %lld\n", req, req->r_tid); + __insert_request(osdc, req); + ceph_osdc_get_request(req); + osdc->num_requests++; + + req->r_timeout_stamp = + jiffies + osdc->client->mount_args.osd_timeout*HZ; + + if (osdc->num_requests == 1) { + osdc->timeout_tid = req->r_tid; + dout(" timeout on tid %llu at %lu\n", req->r_tid, + req->r_timeout_stamp); + schedule_delayed_work(&osdc->timeout_work, + round_jiffies_relative(req->r_timeout_stamp - jiffies)); + } + mutex_unlock(&osdc->request_mutex); +} + +/* + * called under osdc->request_mutex + */ +static void __unregister_request(struct ceph_osd_client *osdc, + struct ceph_osd_request *req) +{ + dout("__unregister_request %p tid %lld\n", req, req->r_tid); + rb_erase(&req->r_node, &osdc->requests); + osdc->num_requests--; + + list_del_init(&req->r_osd_item); + if (list_empty(&req->r_osd->o_requests)) + remove_osd(osdc, req->r_osd); + req->r_osd = NULL; + + ceph_osdc_put_request(req); + + if (req->r_tid == osdc->timeout_tid) { + if (osdc->num_requests == 0) { + dout("no requests, canceling timeout\n"); + osdc->timeout_tid = 0; + cancel_delayed_work(&osdc->timeout_work); + } else { + req = rb_entry(rb_first(&osdc->requests), + struct ceph_osd_request, r_node); + osdc->timeout_tid = req->r_tid; + dout("rescheduled timeout on tid %llu at %lu\n", + req->r_tid, req->r_timeout_stamp); + schedule_delayed_work(&osdc->timeout_work, + round_jiffies_relative(req->r_timeout_stamp - + jiffies)); + } + } +} + +/* + * Cancel a previously queued request message + */ +static void __cancel_request(struct ceph_osd_request *req) +{ + if (req->r_sent) { + ceph_con_revoke(&req->r_osd->o_con, req->r_request); + req->r_sent = 0; + } +} + +/* + * Pick an osd (the first 'up' osd in the pg), allocate the osd struct + * (as needed), and set the request r_osd appropriately. If there is + * no up osd, set r_osd to NULL. + * + * Return 0 if unchanged, 1 if changed, or negative on error. + * + * Caller should hold map_sem for read and request_mutex. + */ +static int __map_osds(struct ceph_osd_client *osdc, + struct ceph_osd_request *req) +{ + struct ceph_osd_request_head *reqhead = req->r_request->front.iov_base; + union ceph_pg pgid; + int o = -1; + int err; + struct ceph_osd *newosd = NULL; + + dout("map_osds %p tid %lld\n", req, req->r_tid); + err = ceph_calc_object_layout(&reqhead->layout, req->r_oid, + &req->r_file_layout, osdc->osdmap); + if (err) + return err; + pgid.pg64 = le64_to_cpu(reqhead->layout.ol_pgid); + o = ceph_calc_pg_primary(osdc->osdmap, pgid); + + if ((req->r_osd && req->r_osd->o_osd == o && + req->r_sent >= req->r_osd->o_incarnation) || + (req->r_osd == NULL && o == -1)) + return 0; /* no change */ + + dout("map_osds tid %llu pgid %llx pool %d osd%d (was osd%d)\n", + req->r_tid, pgid.pg64, pgid.pg.pool, o, + req->r_osd ? req->r_osd->o_osd : -1); + + if (req->r_osd) { + __cancel_request(req); + list_del_init(&req->r_osd_item); + if (list_empty(&req->r_osd->o_requests)) { + /* try to re-use r_osd if possible */ + newosd = get_osd(req->r_osd); + remove_osd(osdc, newosd); + } + req->r_osd = NULL; + } + + req->r_osd = __lookup_osd(osdc, o); + if (!req->r_osd && o >= 0) { + if (newosd) { + req->r_osd = newosd; + newosd = NULL; + } else { + err = -ENOMEM; + req->r_osd = create_osd(osdc); + if (!req->r_osd) + goto out; + } + + dout("map_osds osd %p is osd%d\n", req->r_osd, o); + req->r_osd->o_osd = o; + req->r_osd->o_con.peer_name.num = cpu_to_le64(o); + __insert_osd(osdc, req->r_osd); + + ceph_con_open(&req->r_osd->o_con, &osdc->osdmap->osd_addr[o]); + } + + if (req->r_osd) + list_add(&req->r_osd_item, &req->r_osd->o_requests); + err = 1; /* osd changed */ + +out: + if (newosd) + put_osd(newosd); + return err; +} + +/* + * caller should hold map_sem (for read) and request_mutex + */ +static int __send_request(struct ceph_osd_client *osdc, + struct ceph_osd_request *req) +{ + struct ceph_osd_request_head *reqhead; + int err; + + err = __map_osds(osdc, req); + if (err < 0) + return err; + if (req->r_osd == NULL) { + dout("send_request %p no up osds in pg\n", req); + ceph_monc_request_next_osdmap(&osdc->client->monc); + return 0; + } + + dout("send_request %p tid %llu to osd%d flags %d\n", + req, req->r_tid, req->r_osd->o_osd, req->r_flags); + + reqhead = req->r_request->front.iov_base; + reqhead->osdmap_epoch = cpu_to_le32(osdc->osdmap->epoch); + reqhead->flags |= cpu_to_le32(req->r_flags); /* e.g., RETRY */ + reqhead->reassert_version = req->r_reassert_version; + + req->r_timeout_stamp = jiffies+osdc->client->mount_args.osd_timeout*HZ; + + ceph_msg_get(req->r_request); /* send consumes a ref */ + ceph_con_send(&req->r_osd->o_con, req->r_request); + req->r_sent = req->r_osd->o_incarnation; + return 0; +} + +/* + * Timeout callback, called every N seconds when 1 or more osd + * requests has been active for more than N seconds. When this + * happens, we ping all OSDs with requests who have timed out to + * ensure any communications channel reset is detected. Reset the + * request timeouts another N seconds in the future as we go. + * Reschedule the timeout event another N seconds in future (unless + * there are no open requests). + */ +static void handle_timeout(struct work_struct *work) +{ + struct ceph_osd_client *osdc = + container_of(work, struct ceph_osd_client, timeout_work.work); + struct ceph_osd_request *req; + struct ceph_osd *osd; + unsigned long timeout = osdc->client->mount_args.osd_timeout * HZ; + unsigned long next_timeout = timeout + jiffies; + struct rb_node *p; + + dout("timeout\n"); + down_read(&osdc->map_sem); + + ceph_monc_request_next_osdmap(&osdc->client->monc); + + mutex_lock(&osdc->request_mutex); + for (p = rb_first(&osdc->requests); p; p = rb_next(p)) { + req = rb_entry(p, struct ceph_osd_request, r_node); + + if (req->r_resend) { + int err; + + dout("osdc resending prev failed %lld\n", req->r_tid); + err = __send_request(osdc, req); + if (err) + dout("osdc failed again on %lld\n", req->r_tid); + else + req->r_resend = false; + continue; + } + } + for (p = rb_first(&osdc->osds); p; p = rb_next(p)) { + osd = rb_entry(p, struct ceph_osd, o_node); + if (list_empty(&osd->o_requests)) + continue; + req = list_first_entry(&osd->o_requests, + struct ceph_osd_request, r_osd_item); + if (time_before(jiffies, req->r_timeout_stamp)) + continue; + + dout(" tid %llu (at least) timed out on osd%d\n", + req->r_tid, osd->o_osd); + req->r_timeout_stamp = next_timeout; + ceph_con_keepalive(&osd->o_con); + } + + if (osdc->timeout_tid) + schedule_delayed_work(&osdc->timeout_work, + round_jiffies_relative(timeout)); + + mutex_unlock(&osdc->request_mutex); + + up_read(&osdc->map_sem); +} + +/* + * handle osd op reply. either call the callback if it is specified, + * or do the completion to wake up the waiting thread. + */ +static void handle_reply(struct ceph_osd_client *osdc, struct ceph_msg *msg) +{ + struct ceph_osd_reply_head *rhead = msg->front.iov_base; + struct ceph_osd_request *req; + u64 tid; + int numops, object_len, flags; + + if (msg->front.iov_len < sizeof(*rhead)) + goto bad; + tid = le64_to_cpu(rhead->tid); + numops = le32_to_cpu(rhead->num_ops); + object_len = le32_to_cpu(rhead->object_len); + if (msg->front.iov_len != sizeof(*rhead) + object_len + + numops * sizeof(struct ceph_osd_op)) + goto bad; + dout("handle_reply %p tid %llu\n", msg, tid); + + /* lookup */ + mutex_lock(&osdc->request_mutex); + req = __lookup_request(osdc, tid); + if (req == NULL) { + dout("handle_reply tid %llu dne\n", tid); + mutex_unlock(&osdc->request_mutex); + return; + } + ceph_osdc_get_request(req); + flags = le32_to_cpu(rhead->flags); + + if (req->r_reply) { + /* + * once we see the message has been received, we don't + * need a ref (which is only needed for revoking + * pages) + */ + ceph_msg_put(req->r_reply); + req->r_reply = NULL; + } + + if (!req->r_got_reply) { + unsigned bytes; + + req->r_result = le32_to_cpu(rhead->result); + bytes = le32_to_cpu(msg->hdr.data_len); + dout("handle_reply result %d bytes %d\n", req->r_result, + bytes); + if (req->r_result == 0) + req->r_result = bytes; + + /* in case this is a write and we need to replay, */ + req->r_reassert_version = rhead->reassert_version; + + req->r_got_reply = 1; + } else if ((flags & CEPH_OSD_FLAG_ONDISK) == 0) { + dout("handle_reply tid %llu dup ack\n", tid); + goto done; + } + + dout("handle_reply tid %llu flags %d\n", tid, flags); + + /* either this is a read, or we got the safe response */ + if ((flags & CEPH_OSD_FLAG_ONDISK) || + ((flags & CEPH_OSD_FLAG_WRITE) == 0)) + __unregister_request(osdc, req); + + mutex_unlock(&osdc->request_mutex); + + if (req->r_callback) + req->r_callback(req, msg); + else + complete(&req->r_completion); + + if (flags & CEPH_OSD_FLAG_ONDISK) { + if (req->r_safe_callback) + req->r_safe_callback(req, msg); + complete(&req->r_safe_completion); /* fsync waiter */ + } + +done: + ceph_osdc_put_request(req); + return; + +bad: + pr_err("corrupt osd_op_reply got %d %d expected %d\n", + (int)msg->front.iov_len, le32_to_cpu(msg->hdr.front_len), + (int)sizeof(*rhead)); +} + + +/* + * Resubmit osd requests whose osd or osd address has changed. Request + * a new osd map if osds are down, or we are otherwise unable to determine + * how to direct a request. + * + * Close connections to down osds. + * + * If @who is specified, resubmit requests for that specific osd. + * + * Caller should hold map_sem for read and request_mutex. + */ +static void kick_requests(struct ceph_osd_client *osdc, + struct ceph_osd *kickosd) +{ + struct ceph_osd_request *req; + struct rb_node *p, *n; + int needmap = 0; + int err; + + dout("kick_requests osd%d\n", kickosd ? kickosd->o_osd : -1); + mutex_lock(&osdc->request_mutex); + if (!kickosd) { + for (p = rb_first(&osdc->osds); p; p = n) { + struct ceph_osd *osd = + rb_entry(p, struct ceph_osd, o_node); + + n = rb_next(p); + if (!ceph_osd_is_up(osdc->osdmap, osd->o_osd) || + !ceph_entity_addr_equal(&osd->o_con.peer_addr, + ceph_osd_addr(osdc->osdmap, + osd->o_osd))) + reset_osd(osdc, osd); + } + } + + for (p = rb_first(&osdc->requests); p; p = rb_next(p)) { + req = rb_entry(p, struct ceph_osd_request, r_node); + + if (req->r_resend) { + dout(" r_resend set on tid %llu\n", req->r_tid); + goto kick; + } + if (req->r_osd && kickosd == req->r_osd) + goto kick; + + err = __map_osds(osdc, req); + if (err == 0) + continue; /* no change */ + if (err < 0) { + /* + * FIXME: really, we should set the request + * error and fail if this isn't a 'nofail' + * request, but that's a fair bit more + * complicated to do. So retry! + */ + dout(" setting r_resend on %llu\n", req->r_tid); + req->r_resend = true; + continue; + } + if (req->r_osd == NULL) { + dout("tid %llu maps to no valid osd\n", req->r_tid); + needmap++; /* request a newer map */ + continue; + } + +kick: + dout("kicking tid %llu osd%d\n", req->r_tid, req->r_osd->o_osd); + req->r_flags |= CEPH_OSD_FLAG_RETRY; + err = __send_request(osdc, req); + if (err) { + dout(" setting r_resend on %llu\n", req->r_tid); + req->r_resend = true; + } + } + mutex_unlock(&osdc->request_mutex); + + if (needmap) { + dout("%d requests for down osds, need new map\n", needmap); + ceph_monc_request_next_osdmap(&osdc->client->monc); + } +} + +/* + * Process updated osd map. + * + * The message contains any number of incremental and full maps, normally + * indicating some sort of topology change in the cluster. Kick requests + * off to different OSDs as needed. + */ +void ceph_osdc_handle_map(struct ceph_osd_client *osdc, struct ceph_msg *msg) +{ + void *p, *end, *next; + u32 nr_maps, maplen; + u32 epoch; + struct ceph_osdmap *newmap = NULL, *oldmap; + int err; + struct ceph_fsid fsid; + + dout("handle_map have %u\n", osdc->osdmap ? osdc->osdmap->epoch : 0); + p = msg->front.iov_base; + end = p + msg->front.iov_len; + + /* verify fsid */ + ceph_decode_need(&p, end, sizeof(fsid), bad); + ceph_decode_copy(&p, &fsid, sizeof(fsid)); + if (ceph_fsid_compare(&fsid, &osdc->client->monc.monmap->fsid)) { + pr_err("got osdmap with wrong fsid, ignoring\n"); + return; + } + + down_write(&osdc->map_sem); + + /* incremental maps */ + ceph_decode_32_safe(&p, end, nr_maps, bad); + dout(" %d inc maps\n", nr_maps); + while (nr_maps > 0) { + ceph_decode_need(&p, end, 2*sizeof(u32), bad); + ceph_decode_32(&p, epoch); + ceph_decode_32(&p, maplen); + ceph_decode_need(&p, end, maplen, bad); + next = p + maplen; + if (osdc->osdmap && osdc->osdmap->epoch+1 == epoch) { + dout("applying incremental map %u len %d\n", + epoch, maplen); + newmap = osdmap_apply_incremental(&p, next, + osdc->osdmap, + osdc->client->msgr); + if (IS_ERR(newmap)) { + err = PTR_ERR(newmap); + goto bad; + } + if (newmap != osdc->osdmap) { + ceph_osdmap_destroy(osdc->osdmap); + osdc->osdmap = newmap; + } + } else { + dout("ignoring incremental map %u len %d\n", + epoch, maplen); + } + p = next; + nr_maps--; + } + if (newmap) + goto done; + + /* full maps */ + ceph_decode_32_safe(&p, end, nr_maps, bad); + dout(" %d full maps\n", nr_maps); + while (nr_maps) { + ceph_decode_need(&p, end, 2*sizeof(u32), bad); + ceph_decode_32(&p, epoch); + ceph_decode_32(&p, maplen); + ceph_decode_need(&p, end, maplen, bad); + if (nr_maps > 1) { + dout("skipping non-latest full map %u len %d\n", + epoch, maplen); + } else if (osdc->osdmap && osdc->osdmap->epoch >= epoch) { + dout("skipping full map %u len %d, " + "older than our %u\n", epoch, maplen, + osdc->osdmap->epoch); + } else { + dout("taking full map %u len %d\n", epoch, maplen); + newmap = osdmap_decode(&p, p+maplen); + if (IS_ERR(newmap)) { + err = PTR_ERR(newmap); + goto bad; + } + oldmap = osdc->osdmap; + osdc->osdmap = newmap; + if (oldmap) + ceph_osdmap_destroy(oldmap); + } + p += maplen; + nr_maps--; + } + +done: + downgrade_write(&osdc->map_sem); + ceph_monc_got_osdmap(&osdc->client->monc, osdc->osdmap->epoch); + if (newmap) + kick_requests(osdc, NULL); + up_read(&osdc->map_sem); + return; + +bad: + pr_err("osdc handle_map corrupt msg\n"); + up_write(&osdc->map_sem); + return; +} + + +/* + * A read request prepares specific pages that data is to be read into. + * When a message is being read off the wire, we call prepare_pages to + * find those pages. + * 0 = success, -1 failure. + */ +static int prepare_pages(struct ceph_connection *con, struct ceph_msg *m, + int want) +{ + struct ceph_osd *osd = con->private; + struct ceph_osd_client *osdc; + struct ceph_osd_reply_head *rhead = m->front.iov_base; + struct ceph_osd_request *req; + u64 tid; + int ret = -1; + int type = le16_to_cpu(m->hdr.type); + + if (!osd) + return -1; + osdc = osd->o_osdc; + + dout("prepare_pages on msg %p want %d\n", m, want); + if (unlikely(type != CEPH_MSG_OSD_OPREPLY)) + return -1; /* hmm! */ + + tid = le64_to_cpu(rhead->tid); + mutex_lock(&osdc->request_mutex); + req = __lookup_request(osdc, tid); + if (!req) { + dout("prepare_pages unknown tid %llu\n", tid); + goto out; + } + dout("prepare_pages tid %llu has %d pages, want %d\n", + tid, req->r_num_pages, want); + if (likely(req->r_num_pages >= want && !req->r_prepared_pages)) { + m->pages = req->r_pages; + m->nr_pages = req->r_num_pages; + req->r_reply = m; /* only for duration of read over socket */ + ceph_msg_get(m); + req->r_prepared_pages = 1; + ret = 0; /* success */ + } +out: + mutex_unlock(&osdc->request_mutex); + return ret; +} + +/* + * Register request, send initial attempt. + */ +int ceph_osdc_start_request(struct ceph_osd_client *osdc, + struct ceph_osd_request *req, + bool nofail) +{ + int rc; + + req->r_request->pages = req->r_pages; + req->r_request->nr_pages = req->r_num_pages; + + register_request(osdc, req); + + down_read(&osdc->map_sem); + mutex_lock(&osdc->request_mutex); + rc = __send_request(osdc, req); + if (rc) { + if (nofail) { + dout("osdc_start_request failed send, marking %lld\n", + req->r_tid); + req->r_resend = true; + rc = 0; + } else { + __unregister_request(osdc, req); + } + } + mutex_unlock(&osdc->request_mutex); + up_read(&osdc->map_sem); + return rc; +} + +/* + * wait for a request to complete + */ +int ceph_osdc_wait_request(struct ceph_osd_client *osdc, + struct ceph_osd_request *req) +{ + int rc; + + rc = wait_for_completion_interruptible(&req->r_completion); + if (rc < 0) { + mutex_lock(&osdc->request_mutex); + __cancel_request(req); + mutex_unlock(&osdc->request_mutex); + dout("wait_request tid %llu timed out\n", req->r_tid); + return rc; + } + + dout("wait_request tid %llu result %d\n", req->r_tid, req->r_result); + return req->r_result; +} + +/* + * sync - wait for all in-flight requests to flush. avoid starvation. + */ +void ceph_osdc_sync(struct ceph_osd_client *osdc) +{ + struct ceph_osd_request *req; + u64 last_tid, next_tid = 0; + + mutex_lock(&osdc->request_mutex); + last_tid = osdc->last_tid; + while (1) { + req = __lookup_request_ge(osdc, next_tid); + if (!req) + break; + if (req->r_tid > last_tid) + break; + + next_tid = req->r_tid + 1; + if ((req->r_flags & CEPH_OSD_FLAG_WRITE) == 0) + continue; + + ceph_osdc_get_request(req); + mutex_unlock(&osdc->request_mutex); + dout("sync waiting on tid %llu (last is %llu)\n", + req->r_tid, last_tid); + wait_for_completion(&req->r_safe_completion); + mutex_lock(&osdc->request_mutex); + ceph_osdc_put_request(req); + } + mutex_unlock(&osdc->request_mutex); + dout("sync done (thru tid %llu)\n", last_tid); +} + +/* + * init, shutdown + */ +int ceph_osdc_init(struct ceph_osd_client *osdc, struct ceph_client *client) +{ + int err; + + dout("init\n"); + osdc->client = client; + osdc->osdmap = NULL; + init_rwsem(&osdc->map_sem); + init_completion(&osdc->map_waiters); + osdc->last_requested_map = 0; + mutex_init(&osdc->request_mutex); + osdc->timeout_tid = 0; + osdc->last_tid = 0; + osdc->osds = RB_ROOT; + osdc->requests = RB_ROOT; + osdc->num_requests = 0; + INIT_DELAYED_WORK(&osdc->timeout_work, handle_timeout); + + osdc->req_mempool = mempool_create_kmalloc_pool(10, + sizeof(struct ceph_osd_request)); + if (!osdc->req_mempool) + return -ENOMEM; + + err = ceph_msgpool_init(&osdc->msgpool_op, 4096, 10, true); + if (err < 0) + return -ENOMEM; + err = ceph_msgpool_init(&osdc->msgpool_op_reply, 512, 0, false); + if (err < 0) + return -ENOMEM; + + return 0; +} + +void ceph_osdc_stop(struct ceph_osd_client *osdc) +{ + cancel_delayed_work_sync(&osdc->timeout_work); + if (osdc->osdmap) { + ceph_osdmap_destroy(osdc->osdmap); + osdc->osdmap = NULL; + } + mempool_destroy(osdc->req_mempool); + ceph_msgpool_destroy(&osdc->msgpool_op); + ceph_msgpool_destroy(&osdc->msgpool_op_reply); +} + +/* + * Read some contiguous pages. If we cross a stripe boundary, shorten + * *plen. Return number of bytes read, or error. + */ +int ceph_osdc_readpages(struct ceph_osd_client *osdc, + struct ceph_vino vino, struct ceph_file_layout *layout, + u64 off, u64 *plen, + u32 truncate_seq, u64 truncate_size, + struct page **pages, int num_pages) +{ + struct ceph_osd_request *req; + int rc = 0; + + dout("readpages on ino %llx.%llx on %llu~%llu\n", vino.ino, + vino.snap, off, *plen); + req = ceph_osdc_new_request(osdc, layout, vino, off, plen, + CEPH_OSD_OP_READ, CEPH_OSD_FLAG_READ, + NULL, 0, truncate_seq, truncate_size, NULL, + false, 1); + if (IS_ERR(req)) + return PTR_ERR(req); + + /* it may be a short read due to an object boundary */ + req->r_pages = pages; + num_pages = calc_pages_for(off, *plen); + req->r_num_pages = num_pages; + + dout("readpages final extent is %llu~%llu (%d pages)\n", + off, *plen, req->r_num_pages); + + rc = ceph_osdc_start_request(osdc, req, false); + if (!rc) + rc = ceph_osdc_wait_request(osdc, req); + + ceph_osdc_put_request(req); + dout("readpages result %d\n", rc); + return rc; +} + +/* + * do a synchronous write on N pages + */ +int ceph_osdc_writepages(struct ceph_osd_client *osdc, struct ceph_vino vino, + struct ceph_file_layout *layout, + struct ceph_snap_context *snapc, + u64 off, u64 len, + u32 truncate_seq, u64 truncate_size, + struct timespec *mtime, + struct page **pages, int num_pages, + int flags, int do_sync, bool nofail) +{ + struct ceph_osd_request *req; + int rc = 0; + + BUG_ON(vino.snap != CEPH_NOSNAP); + req = ceph_osdc_new_request(osdc, layout, vino, off, &len, + CEPH_OSD_OP_WRITE, + flags | CEPH_OSD_FLAG_ONDISK | + CEPH_OSD_FLAG_WRITE, + snapc, do_sync, + truncate_seq, truncate_size, mtime, + nofail, 1); + if (IS_ERR(req)) + return PTR_ERR(req); + + /* it may be a short write due to an object boundary */ + req->r_pages = pages; + req->r_num_pages = calc_pages_for(off, len); + dout("writepages %llu~%llu (%d pages)\n", off, len, + req->r_num_pages); + + rc = ceph_osdc_start_request(osdc, req, nofail); + if (!rc) + rc = ceph_osdc_wait_request(osdc, req); + + ceph_osdc_put_request(req); + if (rc == 0) + rc = len; + dout("writepages result %d\n", rc); + return rc; +} + +/* + * handle incoming message + */ +static void dispatch(struct ceph_connection *con, struct ceph_msg *msg) +{ + struct ceph_osd *osd = con->private; + struct ceph_osd_client *osdc = osd->o_osdc; + int type = le16_to_cpu(msg->hdr.type); + + if (!osd) + return; + + switch (type) { + case CEPH_MSG_OSD_MAP: + ceph_osdc_handle_map(osdc, msg); + break; + case CEPH_MSG_OSD_OPREPLY: + handle_reply(osdc, msg); + break; + + default: + pr_err("received unknown message type %d %s\n", type, + ceph_msg_type_name(type)); + } + ceph_msg_put(msg); +} + +static struct ceph_msg *alloc_msg(struct ceph_connection *con, + struct ceph_msg_header *hdr) +{ + struct ceph_osd *osd = con->private; + struct ceph_osd_client *osdc = osd->o_osdc; + int type = le16_to_cpu(hdr->type); + + switch (type) { + case CEPH_MSG_OSD_OPREPLY: + return ceph_msgpool_get(&osdc->msgpool_op_reply); + } + return ceph_alloc_msg(con, hdr); +} + +/* + * Wrappers to refcount containing ceph_osd struct + */ +static struct ceph_connection *get_osd_con(struct ceph_connection *con) +{ + struct ceph_osd *osd = con->private; + if (get_osd(osd)) + return con; + return NULL; +} + +static void put_osd_con(struct ceph_connection *con) +{ + struct ceph_osd *osd = con->private; + put_osd(osd); +} + +const static struct ceph_connection_operations osd_con_ops = { + .get = get_osd_con, + .put = put_osd_con, + .dispatch = dispatch, + .alloc_msg = alloc_msg, + .peer_reset = osd_reset, + .alloc_middle = ceph_alloc_middle, + .prepare_pages = prepare_pages, +}; diff --git a/fs/ceph/osd_client.h b/fs/ceph/osd_client.h new file mode 100644 index 0000000..9a4addf --- /dev/null +++ b/fs/ceph/osd_client.h @@ -0,0 +1,144 @@ +#ifndef _FS_CEPH_OSD_CLIENT_H +#define _FS_CEPH_OSD_CLIENT_H + +#include +#include +#include + +#include "types.h" +#include "osdmap.h" +#include "messenger.h" + +struct ceph_msg; +struct ceph_snap_context; +struct ceph_osd_request; +struct ceph_osd_client; + +/* + * completion callback for async writepages + */ +typedef void (*ceph_osdc_callback_t)(struct ceph_osd_request *, + struct ceph_msg *); + +/* a given osd we're communicating with */ +struct ceph_osd { + atomic_t o_ref; + struct ceph_osd_client *o_osdc; + int o_osd; + int o_incarnation; + struct rb_node o_node; + struct ceph_connection o_con; + struct list_head o_requests; +}; + +/* an in-flight request */ +struct ceph_osd_request { + u64 r_tid; /* unique for this client */ + struct rb_node r_node; + struct list_head r_osd_item; + struct ceph_osd *r_osd; + + struct ceph_msg *r_request, *r_reply; + int r_result; + int r_flags; /* any additional flags for the osd */ + u32 r_sent; /* >0 if r_request is sending/sent */ + int r_prepared_pages, r_got_reply; + + struct ceph_osd_client *r_osdc; + atomic_t r_ref; + bool r_mempool; + struct completion r_completion, r_safe_completion; + ceph_osdc_callback_t r_callback, r_safe_callback; + struct ceph_eversion r_reassert_version; + struct list_head r_unsafe_item; + + struct inode *r_inode; /* for use by callbacks */ + struct writeback_control *r_wbc; /* ditto */ + + char r_oid[40]; /* object name */ + int r_oid_len; + unsigned long r_timeout_stamp; + bool r_resend; /* msg send failed, needs retry */ + + struct ceph_file_layout r_file_layout; + struct ceph_snap_context *r_snapc; /* snap context for writes */ + unsigned r_num_pages; /* size of page array (follows) */ + struct page **r_pages; /* pages for data payload */ + int r_pages_from_pool; + int r_own_pages; /* if true, i own page list */ +}; + +struct ceph_osd_client { + struct ceph_client *client; + + struct ceph_osdmap *osdmap; /* current map */ + struct rw_semaphore map_sem; + struct completion map_waiters; + u64 last_requested_map; + + struct mutex request_mutex; + struct rb_root osds; /* osds */ + u64 timeout_tid; /* tid of timeout triggering rq */ + u64 last_tid; /* tid of last request */ + struct rb_root requests; /* pending requests */ + int num_requests; + struct delayed_work timeout_work; + struct dentry *debugfs_file; + + mempool_t *req_mempool; + + struct ceph_msgpool msgpool_op; + struct ceph_msgpool msgpool_op_reply; +}; + +extern int ceph_osdc_init(struct ceph_osd_client *osdc, + struct ceph_client *client); +extern void ceph_osdc_stop(struct ceph_osd_client *osdc); + +extern void ceph_osdc_handle_reply(struct ceph_osd_client *osdc, + struct ceph_msg *msg); +extern void ceph_osdc_handle_map(struct ceph_osd_client *osdc, + struct ceph_msg *msg); + +extern struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *, + struct ceph_file_layout *layout, + struct ceph_vino vino, + u64 offset, u64 *len, int op, int flags, + struct ceph_snap_context *snapc, + int do_sync, u32 truncate_seq, + u64 truncate_size, + struct timespec *mtime, + bool use_mempool, int num_reply); + +static inline void ceph_osdc_get_request(struct ceph_osd_request *req) +{ + atomic_inc(&req->r_ref); +} +extern void ceph_osdc_put_request(struct ceph_osd_request *req); + +extern int ceph_osdc_start_request(struct ceph_osd_client *osdc, + struct ceph_osd_request *req, + bool nofail); +extern int ceph_osdc_wait_request(struct ceph_osd_client *osdc, + struct ceph_osd_request *req); +extern void ceph_osdc_sync(struct ceph_osd_client *osdc); + +extern int ceph_osdc_readpages(struct ceph_osd_client *osdc, + struct ceph_vino vino, + struct ceph_file_layout *layout, + u64 off, u64 *plen, + u32 truncate_seq, u64 truncate_size, + struct page **pages, int nr_pages); + +extern int ceph_osdc_writepages(struct ceph_osd_client *osdc, + struct ceph_vino vino, + struct ceph_file_layout *layout, + struct ceph_snap_context *sc, + u64 off, u64 len, + u32 truncate_seq, u64 truncate_size, + struct timespec *mtime, + struct page **pages, int nr_pages, + int flags, int do_sync, bool nofail); + +#endif + diff --git a/fs/ceph/osdmap.c b/fs/ceph/osdmap.c new file mode 100644 index 0000000..e38fe63 --- /dev/null +++ b/fs/ceph/osdmap.c @@ -0,0 +1,875 @@ + +#include + +#include "super.h" +#include "osdmap.h" +#include "crush/hash.h" +#include "crush/mapper.h" +#include "decode.h" +#include "ceph_debug.h" + +char *ceph_osdmap_state_str(char *str, int len, int state) +{ + int flag = 0; + + if (!len) + goto done; + + *str = '\0'; + if (state) { + if (state & CEPH_OSD_EXISTS) { + snprintf(str, len, "exists"); + flag = 1; + } + if (state & CEPH_OSD_UP) { + snprintf(str, len, "%s%s%s", str, (flag ? ", " : ""), + "up"); + flag = 1; + } + } else { + snprintf(str, len, "doesn't exist"); + } +done: + return str; +} + +/* maps */ + +static int calc_bits_of(unsigned t) +{ + int b = 0; + while (t) { + t = t >> 1; + b++; + } + return b; +} + +/* + * the foo_mask is the smallest value 2^n-1 that is >= foo. + */ +static void calc_pg_masks(struct ceph_pg_pool_info *pi) +{ + pi->pg_num_mask = (1 << calc_bits_of(le32_to_cpu(pi->v.pg_num)-1)) - 1; + pi->pgp_num_mask = + (1 << calc_bits_of(le32_to_cpu(pi->v.pgp_num)-1)) - 1; + pi->lpg_num_mask = + (1 << calc_bits_of(le32_to_cpu(pi->v.lpg_num)-1)) - 1; + pi->lpgp_num_mask = + (1 << calc_bits_of(le32_to_cpu(pi->v.lpgp_num)-1)) - 1; +} + +/* + * decode crush map + */ +static int crush_decode_uniform_bucket(void **p, void *end, + struct crush_bucket_uniform *b) +{ + dout("crush_decode_uniform_bucket %p to %p\n", *p, end); + ceph_decode_need(p, end, (1+b->h.size) * sizeof(u32), bad); + ceph_decode_32(p, b->item_weight); + return 0; +bad: + return -EINVAL; +} + +static int crush_decode_list_bucket(void **p, void *end, + struct crush_bucket_list *b) +{ + int j; + dout("crush_decode_list_bucket %p to %p\n", *p, end); + b->item_weights = kcalloc(b->h.size, sizeof(u32), GFP_NOFS); + if (b->item_weights == NULL) + return -ENOMEM; + b->sum_weights = kcalloc(b->h.size, sizeof(u32), GFP_NOFS); + if (b->sum_weights == NULL) + return -ENOMEM; + ceph_decode_need(p, end, 2 * b->h.size * sizeof(u32), bad); + for (j = 0; j < b->h.size; j++) { + ceph_decode_32(p, b->item_weights[j]); + ceph_decode_32(p, b->sum_weights[j]); + } + return 0; +bad: + return -EINVAL; +} + +static int crush_decode_tree_bucket(void **p, void *end, + struct crush_bucket_tree *b) +{ + int j; + dout("crush_decode_tree_bucket %p to %p\n", *p, end); + ceph_decode_32_safe(p, end, b->num_nodes, bad); + b->node_weights = kcalloc(b->num_nodes, sizeof(u32), GFP_NOFS); + if (b->node_weights == NULL) + return -ENOMEM; + ceph_decode_need(p, end, b->num_nodes * sizeof(u32), bad); + for (j = 0; j < b->num_nodes; j++) + ceph_decode_32(p, b->node_weights[j]); + return 0; +bad: + return -EINVAL; +} + +static int crush_decode_straw_bucket(void **p, void *end, + struct crush_bucket_straw *b) +{ + int j; + dout("crush_decode_straw_bucket %p to %p\n", *p, end); + b->item_weights = kcalloc(b->h.size, sizeof(u32), GFP_NOFS); + if (b->item_weights == NULL) + return -ENOMEM; + b->straws = kcalloc(b->h.size, sizeof(u32), GFP_NOFS); + if (b->straws == NULL) + return -ENOMEM; + ceph_decode_need(p, end, 2 * b->h.size * sizeof(u32), bad); + for (j = 0; j < b->h.size; j++) { + ceph_decode_32(p, b->item_weights[j]); + ceph_decode_32(p, b->straws[j]); + } + return 0; +bad: + return -EINVAL; +} + +static struct crush_map *crush_decode(void *pbyval, void *end) +{ + struct crush_map *c; + int err = -EINVAL; + int i, j; + void **p = &pbyval; + void *start = pbyval; + u32 magic; + + dout("crush_decode %p to %p len %d\n", *p, end, (int)(end - *p)); + + c = kzalloc(sizeof(*c), GFP_NOFS); + if (c == NULL) + return ERR_PTR(-ENOMEM); + + ceph_decode_need(p, end, 4*sizeof(u32), bad); + ceph_decode_32(p, magic); + if (magic != CRUSH_MAGIC) { + pr_err("crush_decode magic %x != current %x\n", + (unsigned)magic, (unsigned)CRUSH_MAGIC); + goto bad; + } + ceph_decode_32(p, c->max_buckets); + ceph_decode_32(p, c->max_rules); + ceph_decode_32(p, c->max_devices); + + c->device_parents = kcalloc(c->max_devices, sizeof(u32), GFP_NOFS); + if (c->device_parents == NULL) + goto badmem; + c->bucket_parents = kcalloc(c->max_buckets, sizeof(u32), GFP_NOFS); + if (c->bucket_parents == NULL) + goto badmem; + + c->buckets = kcalloc(c->max_buckets, sizeof(*c->buckets), GFP_NOFS); + if (c->buckets == NULL) + goto badmem; + c->rules = kcalloc(c->max_rules, sizeof(*c->rules), GFP_NOFS); + if (c->rules == NULL) + goto badmem; + + /* buckets */ + for (i = 0; i < c->max_buckets; i++) { + int size = 0; + u32 alg; + struct crush_bucket *b; + + ceph_decode_32_safe(p, end, alg, bad); + if (alg == 0) { + c->buckets[i] = NULL; + continue; + } + dout("crush_decode bucket %d off %x %p to %p\n", + i, (int)(*p-start), *p, end); + + switch (alg) { + case CRUSH_BUCKET_UNIFORM: + size = sizeof(struct crush_bucket_uniform); + break; + case CRUSH_BUCKET_LIST: + size = sizeof(struct crush_bucket_list); + break; + case CRUSH_BUCKET_TREE: + size = sizeof(struct crush_bucket_tree); + break; + case CRUSH_BUCKET_STRAW: + size = sizeof(struct crush_bucket_straw); + break; + default: + goto bad; + } + BUG_ON(size == 0); + b = c->buckets[i] = kzalloc(size, GFP_NOFS); + if (b == NULL) + goto badmem; + + ceph_decode_need(p, end, 4*sizeof(u32), bad); + ceph_decode_32(p, b->id); + ceph_decode_16(p, b->type); + ceph_decode_16(p, b->alg); + ceph_decode_32(p, b->weight); + ceph_decode_32(p, b->size); + + dout("crush_decode bucket size %d off %x %p to %p\n", + b->size, (int)(*p-start), *p, end); + + b->items = kcalloc(b->size, sizeof(__s32), GFP_NOFS); + if (b->items == NULL) + goto badmem; + b->perm = kcalloc(b->size, sizeof(u32), GFP_NOFS); + if (b->perm == NULL) + goto badmem; + b->perm_n = 0; + + ceph_decode_need(p, end, b->size*sizeof(u32), bad); + for (j = 0; j < b->size; j++) + ceph_decode_32(p, b->items[j]); + + switch (b->alg) { + case CRUSH_BUCKET_UNIFORM: + err = crush_decode_uniform_bucket(p, end, + (struct crush_bucket_uniform *)b); + if (err < 0) + goto bad; + break; + case CRUSH_BUCKET_LIST: + err = crush_decode_list_bucket(p, end, + (struct crush_bucket_list *)b); + if (err < 0) + goto bad; + break; + case CRUSH_BUCKET_TREE: + err = crush_decode_tree_bucket(p, end, + (struct crush_bucket_tree *)b); + if (err < 0) + goto bad; + break; + case CRUSH_BUCKET_STRAW: + err = crush_decode_straw_bucket(p, end, + (struct crush_bucket_straw *)b); + if (err < 0) + goto bad; + break; + } + } + + /* rules */ + dout("rule vec is %p\n", c->rules); + for (i = 0; i < c->max_rules; i++) { + u32 yes; + struct crush_rule *r; + + ceph_decode_32_safe(p, end, yes, bad); + if (!yes) { + dout("crush_decode NO rule %d off %x %p to %p\n", + i, (int)(*p-start), *p, end); + c->rules[i] = NULL; + continue; + } + + dout("crush_decode rule %d off %x %p to %p\n", + i, (int)(*p-start), *p, end); + + /* len */ + ceph_decode_32_safe(p, end, yes, bad); +#if BITS_PER_LONG == 32 + if (yes > ULONG_MAX / sizeof(struct crush_rule_step)) + goto bad; +#endif + r = c->rules[i] = kmalloc(sizeof(*r) + + yes*sizeof(struct crush_rule_step), + GFP_NOFS); + if (r == NULL) + goto badmem; + dout(" rule %d is at %p\n", i, r); + r->len = yes; + ceph_decode_copy_safe(p, end, &r->mask, 4, bad); /* 4 u8's */ + ceph_decode_need(p, end, r->len*3*sizeof(u32), bad); + for (j = 0; j < r->len; j++) { + ceph_decode_32(p, r->steps[j].op); + ceph_decode_32(p, r->steps[j].arg1); + ceph_decode_32(p, r->steps[j].arg2); + } + } + + /* ignore trailing name maps. */ + + dout("crush_decode success\n"); + return c; + +badmem: + err = -ENOMEM; +bad: + dout("crush_decode fail %d\n", err); + crush_destroy(c); + return ERR_PTR(err); +} + + +/* + * osd map + */ +void ceph_osdmap_destroy(struct ceph_osdmap *map) +{ + dout("osdmap_destroy %p\n", map); + if (map->crush) + crush_destroy(map->crush); + while (!RB_EMPTY_ROOT(&map->pg_temp)) + rb_erase(rb_first(&map->pg_temp), &map->pg_temp); + kfree(map->osd_state); + kfree(map->osd_weight); + kfree(map->pg_pool); + kfree(map->osd_addr); + kfree(map); +} + +/* + * adjust max osd value. reallocate arrays. + */ +static int osdmap_set_max_osd(struct ceph_osdmap *map, int max) +{ + u8 *state; + struct ceph_entity_addr *addr; + u32 *weight; + + state = kcalloc(max, sizeof(*state), GFP_NOFS); + addr = kcalloc(max, sizeof(*addr), GFP_NOFS); + weight = kcalloc(max, sizeof(*weight), GFP_NOFS); + if (state == NULL || addr == NULL || weight == NULL) { + kfree(state); + kfree(addr); + kfree(weight); + return -ENOMEM; + } + + /* copy old? */ + if (map->osd_state) { + memcpy(state, map->osd_state, map->max_osd*sizeof(*state)); + memcpy(addr, map->osd_addr, map->max_osd*sizeof(*addr)); + memcpy(weight, map->osd_weight, map->max_osd*sizeof(*weight)); + kfree(map->osd_state); + kfree(map->osd_addr); + kfree(map->osd_weight); + } + + map->osd_state = state; + map->osd_weight = weight; + map->osd_addr = addr; + map->max_osd = max; + return 0; +} + +/* + * Insert a new pg_temp mapping + */ +static void __insert_pg_mapping(struct ceph_pg_mapping *new, + struct rb_root *root) +{ + struct rb_node **p = &root->rb_node; + struct rb_node *parent = NULL; + struct ceph_pg_mapping *pg = NULL; + + while (*p) { + parent = *p; + pg = rb_entry(parent, struct ceph_pg_mapping, node); + if (new->pgid < pg->pgid) + p = &(*p)->rb_left; + else if (new->pgid > pg->pgid) + p = &(*p)->rb_right; + else + BUG(); + } + + rb_link_node(&new->node, parent, p); + rb_insert_color(&new->node, root); +} + +/* + * decode a full map. + */ +struct ceph_osdmap *osdmap_decode(void **p, void *end) +{ + struct ceph_osdmap *map; + u16 version; + u32 len, max, i; + int err = -EINVAL; + void *start = *p; + + dout("osdmap_decode %p to %p len %d\n", *p, end, (int)(end - *p)); + + map = kzalloc(sizeof(*map), GFP_NOFS); + if (map == NULL) + return ERR_PTR(-ENOMEM); + map->pg_temp = RB_ROOT; + + ceph_decode_16_safe(p, end, version, bad); + + ceph_decode_need(p, end, 2*sizeof(u64)+6*sizeof(u32), bad); + ceph_decode_copy(p, &map->fsid, sizeof(map->fsid)); + ceph_decode_32(p, map->epoch); + ceph_decode_copy(p, &map->created, sizeof(map->created)); + ceph_decode_copy(p, &map->modified, sizeof(map->modified)); + + ceph_decode_32(p, map->num_pools); + map->pg_pool = kcalloc(map->num_pools, sizeof(*map->pg_pool), + GFP_NOFS); + if (!map->pg_pool) { + err = -ENOMEM; + goto bad; + } + ceph_decode_32_safe(p, end, max, bad); + while (max--) { + ceph_decode_need(p, end, 4+sizeof(map->pg_pool->v), bad); + ceph_decode_32(p, i); + if (i >= map->num_pools) + goto bad; + ceph_decode_copy(p, &map->pg_pool[i].v, + sizeof(map->pg_pool->v)); + calc_pg_masks(&map->pg_pool[i]); + p += le32_to_cpu(map->pg_pool[i].v.num_snaps) * sizeof(u64); + p += le32_to_cpu(map->pg_pool[i].v.num_removed_snap_intervals) + * sizeof(u64) * 2; + } + + ceph_decode_32_safe(p, end, map->flags, bad); + + ceph_decode_32(p, max); + + /* (re)alloc osd arrays */ + err = osdmap_set_max_osd(map, max); + if (err < 0) + goto bad; + dout("osdmap_decode max_osd = %d\n", map->max_osd); + + /* osds */ + err = -EINVAL; + ceph_decode_need(p, end, 3*sizeof(u32) + + map->max_osd*(1 + sizeof(*map->osd_weight) + + sizeof(*map->osd_addr)), bad); + *p += 4; /* skip length field (should match max) */ + ceph_decode_copy(p, map->osd_state, map->max_osd); + + *p += 4; /* skip length field (should match max) */ + for (i = 0; i < map->max_osd; i++) + ceph_decode_32(p, map->osd_weight[i]); + + *p += 4; /* skip length field (should match max) */ + ceph_decode_copy(p, map->osd_addr, map->max_osd*sizeof(*map->osd_addr)); + + /* pg_temp */ + ceph_decode_32_safe(p, end, len, bad); + for (i = 0; i < len; i++) { + int n, j; + u64 pgid; + struct ceph_pg_mapping *pg; + + ceph_decode_need(p, end, sizeof(u32) + sizeof(u64), bad); + ceph_decode_64(p, pgid); + ceph_decode_32(p, n); + ceph_decode_need(p, end, n * sizeof(u32), bad); + pg = kmalloc(sizeof(*pg) + n*sizeof(u32), GFP_NOFS); + if (!pg) { + err = -ENOMEM; + goto bad; + } + pg->pgid = pgid; + pg->len = n; + for (j = 0; j < n; j++) + ceph_decode_32(p, pg->osds[j]); + + __insert_pg_mapping(pg, &map->pg_temp); + dout(" added pg_temp %llx len %d\n", pgid, len); + } + + /* crush */ + ceph_decode_32_safe(p, end, len, bad); + dout("osdmap_decode crush len %d from off 0x%x\n", len, + (int)(*p - start)); + ceph_decode_need(p, end, len, bad); + map->crush = crush_decode(*p, end); + *p += len; + if (IS_ERR(map->crush)) { + err = PTR_ERR(map->crush); + map->crush = NULL; + goto bad; + } + + /* ignore the rest of the map */ + *p = end; + + dout("osdmap_decode done %p %p\n", *p, end); + return map; + +bad: + dout("osdmap_decode fail\n"); + ceph_osdmap_destroy(map); + return ERR_PTR(err); +} + +/* + * decode and apply an incremental map update. + */ +struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, + struct ceph_osdmap *map, + struct ceph_messenger *msgr) +{ + struct ceph_osdmap *newmap = map; + struct crush_map *newcrush = NULL; + struct ceph_fsid fsid; + u32 epoch = 0; + struct ceph_timespec modified; + u32 len, pool; + __s32 new_flags, max; + void *start = *p; + int err = -EINVAL; + u16 version; + struct rb_node *rbp; + + ceph_decode_16_safe(p, end, version, bad); + + ceph_decode_need(p, end, sizeof(fsid)+sizeof(modified)+2*sizeof(u32), + bad); + ceph_decode_copy(p, &fsid, sizeof(fsid)); + ceph_decode_32(p, epoch); + BUG_ON(epoch != map->epoch+1); + ceph_decode_copy(p, &modified, sizeof(modified)); + ceph_decode_32(p, new_flags); + + /* full map? */ + ceph_decode_32_safe(p, end, len, bad); + if (len > 0) { + dout("apply_incremental full map len %d, %p to %p\n", + len, *p, end); + newmap = osdmap_decode(p, min(*p+len, end)); + return newmap; /* error or not */ + } + + /* new crush? */ + ceph_decode_32_safe(p, end, len, bad); + if (len > 0) { + dout("apply_incremental new crush map len %d, %p to %p\n", + len, *p, end); + newcrush = crush_decode(*p, min(*p+len, end)); + if (IS_ERR(newcrush)) + return ERR_PTR(PTR_ERR(newcrush)); + } + + /* new flags? */ + if (new_flags >= 0) + map->flags = new_flags; + + ceph_decode_need(p, end, 5*sizeof(u32), bad); + + /* new max? */ + ceph_decode_32(p, max); + if (max >= 0) { + err = osdmap_set_max_osd(map, max); + if (err < 0) + goto bad; + } + + map->epoch++; + map->modified = map->modified; + if (newcrush) { + if (map->crush) + crush_destroy(map->crush); + map->crush = newcrush; + newcrush = NULL; + } + + /* new_pool */ + ceph_decode_32_safe(p, end, len, bad); + while (len--) { + ceph_decode_32_safe(p, end, pool, bad); + if (pool >= map->num_pools) { + void *pg_pool = kcalloc(pool + 1, + sizeof(*map->pg_pool), + GFP_NOFS); + if (!pg_pool) { + err = -ENOMEM; + goto bad; + } + memcpy(pg_pool, map->pg_pool, + map->num_pools * sizeof(*map->pg_pool)); + kfree(map->pg_pool); + map->pg_pool = pg_pool; + map->num_pools = pool+1; + } + ceph_decode_copy(p, &map->pg_pool[pool].v, + sizeof(map->pg_pool->v)); + calc_pg_masks(&map->pg_pool[pool]); + } + + /* old_pool (ignore) */ + ceph_decode_32_safe(p, end, len, bad); + *p += len * sizeof(u32); + + /* new_up */ + err = -EINVAL; + ceph_decode_32_safe(p, end, len, bad); + while (len--) { + u32 osd; + struct ceph_entity_addr addr; + ceph_decode_32_safe(p, end, osd, bad); + ceph_decode_copy_safe(p, end, &addr, sizeof(addr), bad); + pr_info("osd%d up\n", osd); + BUG_ON(osd >= map->max_osd); + map->osd_state[osd] |= CEPH_OSD_UP; + map->osd_addr[osd] = addr; + } + + /* new_down */ + ceph_decode_32_safe(p, end, len, bad); + while (len--) { + u32 osd; + ceph_decode_32_safe(p, end, osd, bad); + (*p)++; /* clean flag */ + pr_info("ceph osd%d down\n", osd); + if (osd < map->max_osd) + map->osd_state[osd] &= ~CEPH_OSD_UP; + } + + /* new_weight */ + ceph_decode_32_safe(p, end, len, bad); + while (len--) { + u32 osd, off; + ceph_decode_need(p, end, sizeof(u32)*2, bad); + ceph_decode_32(p, osd); + ceph_decode_32(p, off); + pr_info("osd%d weight 0x%x %s\n", osd, off, + off == CEPH_OSD_IN ? "(in)" : + (off == CEPH_OSD_OUT ? "(out)" : "")); + if (osd < map->max_osd) + map->osd_weight[osd] = off; + } + + /* new_pg_temp */ + rbp = rb_first(&map->pg_temp); + ceph_decode_32_safe(p, end, len, bad); + while (len--) { + struct ceph_pg_mapping *pg; + int j; + u64 pgid; + u32 pglen; + ceph_decode_need(p, end, sizeof(u64) + sizeof(u32), bad); + ceph_decode_64(p, pgid); + ceph_decode_32(p, pglen); + + /* remove any? */ + while (rbp && rb_entry(rbp, struct ceph_pg_mapping, + node)->pgid <= pgid) { + struct rb_node *cur = rbp; + rbp = rb_next(rbp); + dout(" removed pg_temp %llx\n", + rb_entry(cur, struct ceph_pg_mapping, node)->pgid); + rb_erase(cur, &map->pg_temp); + } + + if (pglen) { + /* insert */ + ceph_decode_need(p, end, pglen*sizeof(u32), bad); + pg = kmalloc(sizeof(*pg) + sizeof(u32)*pglen, GFP_NOFS); + if (!pg) { + err = -ENOMEM; + goto bad; + } + pg->pgid = pgid; + pg->len = pglen; + for (j = 0; j < len; j++) + ceph_decode_32(p, pg->osds[j]); + __insert_pg_mapping(pg, &map->pg_temp); + dout(" added pg_temp %llx len %d\n", pgid, pglen); + } + } + while (rbp) { + struct rb_node *cur = rbp; + rbp = rb_next(rbp); + dout(" removed pg_temp %llx\n", + rb_entry(cur, struct ceph_pg_mapping, node)->pgid); + rb_erase(cur, &map->pg_temp); + } + + /* ignore the rest */ + *p = end; + return map; + +bad: + pr_err("corrupt inc osdmap epoch %d off %d (%p of %p-%p)\n", + epoch, (int)(*p - start), *p, start, end); + if (newcrush) + crush_destroy(newcrush); + return ERR_PTR(err); +} + + + + +/* + * calculate file layout from given offset, length. + * fill in correct oid, logical length, and object extent + * offset, length. + * + * for now, we write only a single su, until we can + * pass a stride back to the caller. + */ +void ceph_calc_file_object_mapping(struct ceph_file_layout *layout, + u64 off, u64 *plen, + u64 *bno, + u64 *oxoff, u64 *oxlen) +{ + u32 osize = le32_to_cpu(layout->fl_object_size); + u32 su = le32_to_cpu(layout->fl_stripe_unit); + u32 sc = le32_to_cpu(layout->fl_stripe_count); + u32 bl, stripeno, stripepos, objsetno; + u32 su_per_object; + u64 t; + + dout("mapping %llu~%llu osize %u fl_su %u\n", off, *plen, + osize, su); + su_per_object = osize / le32_to_cpu(layout->fl_stripe_unit); + dout("osize %u / su %u = su_per_object %u\n", osize, su, + su_per_object); + + BUG_ON((su & ~PAGE_MASK) != 0); + /* bl = *off / su; */ + t = off; + do_div(t, su); + bl = t; + dout("off %llu / su %u = bl %u\n", off, su, bl); + + stripeno = bl / sc; + stripepos = bl % sc; + objsetno = stripeno / su_per_object; + + *bno = objsetno * sc + stripepos; + dout("objset %u * sc %u = bno %u\n", objsetno, sc, (unsigned)*bno); + /* *oxoff = *off / layout->fl_stripe_unit; */ + t = off; + *oxoff = do_div(t, su); + *oxlen = min_t(u64, *plen, su - *oxoff); + *plen = *oxlen; + + dout(" obj extent %llu~%llu\n", *oxoff, *oxlen); +} + +/* + * calculate an object layout (i.e. pgid) from an oid, + * file_layout, and osdmap + */ +int ceph_calc_object_layout(struct ceph_object_layout *ol, + const char *oid, + struct ceph_file_layout *fl, + struct ceph_osdmap *osdmap) +{ + unsigned num, num_mask; + union ceph_pg pgid; + s32 preferred = (s32)le32_to_cpu(fl->fl_pg_preferred); + int poolid = le32_to_cpu(fl->fl_pg_pool); + struct ceph_pg_pool_info *pool; + + if (poolid >= osdmap->num_pools) + return -EIO; + pool = &osdmap->pg_pool[poolid]; + + if (preferred >= 0) { + num = le32_to_cpu(pool->v.lpg_num); + num_mask = pool->lpg_num_mask; + } else { + num = le32_to_cpu(pool->v.pg_num); + num_mask = pool->pg_num_mask; + } + + pgid.pg64 = 0; /* start with it zeroed out */ + pgid.pg.ps = ceph_full_name_hash(oid, strlen(oid)); + pgid.pg.preferred = preferred; + pgid.pg.pool = le32_to_cpu(fl->fl_pg_pool); + if (preferred >= 0) + dout("calc_object_layout '%s' pgid %d.%xp%d (%llx)\n", oid, + pgid.pg.pool, pgid.pg.ps, (int)preferred, pgid.pg64); + else + dout("calc_object_layout '%s' pgid %d.%x (%llx)\n", oid, + pgid.pg.pool, pgid.pg.ps, pgid.pg64); + + ol->ol_pgid = cpu_to_le64(pgid.pg64); + ol->ol_stripe_unit = fl->fl_object_stripe_unit; + + return 0; +} + +/* + * Calculate raw osd vector for the given pgid. Return pointer to osd + * array, or NULL on failure. + */ +static int *calc_pg_raw(struct ceph_osdmap *osdmap, union ceph_pg pgid, + int *osds, int *num) +{ + struct rb_node *n = osdmap->pg_temp.rb_node; + struct ceph_pg_mapping *pg; + struct ceph_pg_pool_info *pool; + int ruleno; + unsigned pps; /* placement ps */ + + /* pg_temp? */ + while (n) { + pg = rb_entry(n, struct ceph_pg_mapping, node); + if (pgid.pg64 < pg->pgid) + n = n->rb_left; + else if (pgid.pg64 > pg->pgid) + n = n->rb_right; + else { + *num = pg->len; + return pg->osds; + } + } + + /* crush */ + if (pgid.pg.pool >= osdmap->num_pools) + return NULL; + pool = &osdmap->pg_pool[pgid.pg.pool]; + ruleno = crush_find_rule(osdmap->crush, pool->v.crush_ruleset, + pool->v.type, pool->v.size); + if (ruleno < 0) { + pr_err("no crush rule pool %d type %d size %d\n", + pgid.pg.pool, pool->v.type, pool->v.size); + return NULL; + } + + if (pgid.pg.preferred >= 0) + pps = ceph_stable_mod(pgid.pg.ps, + le32_to_cpu(pool->v.lpgp_num), + pool->lpgp_num_mask); + else + pps = ceph_stable_mod(pgid.pg.ps, + le32_to_cpu(pool->v.pgp_num), + pool->pgp_num_mask); + pps += pgid.pg.pool; + *num = crush_do_rule(osdmap->crush, ruleno, pps, osds, + min_t(int, pool->v.size, *num), + pgid.pg.preferred, osdmap->osd_weight); + return osds; +} + +/* + * Return primary osd for given pgid, or -1 if none. + */ +int ceph_calc_pg_primary(struct ceph_osdmap *osdmap, union ceph_pg pgid) +{ + int rawosds[10], *osds; + int i, num = ARRAY_SIZE(rawosds); + + osds = calc_pg_raw(osdmap, pgid, rawosds, &num); + if (!osds) + return -1; + + /* primary is first up osd */ + for (i = 0; i < num; i++) + if (ceph_osd_is_up(osdmap, osds[i])) { + return osds[i]; + break; + } + return -1; +} diff --git a/fs/ceph/osdmap.h b/fs/ceph/osdmap.h new file mode 100644 index 0000000..07127c6 --- /dev/null +++ b/fs/ceph/osdmap.h @@ -0,0 +1,123 @@ +#ifndef _FS_CEPH_OSDMAP_H +#define _FS_CEPH_OSDMAP_H + +#include +#include "types.h" +#include "ceph_fs.h" +#include "crush/crush.h" + +/* + * The osd map describes the current membership of the osd cluster and + * specifies the mapping of objects to placement groups and placement + * groups to (sets of) osds. That is, it completely specifies the + * (desired) distribution of all data objects in the system at some + * point in time. + * + * Each map version is identified by an epoch, which increases monotonically. + * + * The map can be updated either via an incremental map (diff) describing + * the change between two successive epochs, or as a fully encoded map. + */ +struct ceph_pg_pool_info { + struct ceph_pg_pool v; + int pg_num_mask, pgp_num_mask, lpg_num_mask, lpgp_num_mask; +}; + +struct ceph_pg_mapping { + struct rb_node node; + u64 pgid; + int len; + int osds[]; +}; + +struct ceph_osdmap { + struct ceph_fsid fsid; + u32 epoch; + u32 mkfs_epoch; + struct ceph_timespec created, modified; + + u32 flags; /* CEPH_OSDMAP_* */ + + u32 max_osd; /* size of osd_state, _offload, _addr arrays */ + u8 *osd_state; /* CEPH_OSD_* */ + u32 *osd_weight; /* 0 = failed, 0x10000 = 100% normal */ + struct ceph_entity_addr *osd_addr; + + struct rb_root pg_temp; + + u32 num_pools; + struct ceph_pg_pool_info *pg_pool; + + /* the CRUSH map specifies the mapping of placement groups to + * the list of osds that store+replicate them. */ + struct crush_map *crush; +}; + +/* + * file layout helpers + */ +#define ceph_file_layout_su(l) ((__s32)le32_to_cpu((l).fl_stripe_unit)) +#define ceph_file_layout_stripe_count(l) \ + ((__s32)le32_to_cpu((l).fl_stripe_count)) +#define ceph_file_layout_object_size(l) ((__s32)le32_to_cpu((l).fl_object_size)) +#define ceph_file_layout_cas_hash(l) ((__s32)le32_to_cpu((l).fl_cas_hash)) +#define ceph_file_layout_object_su(l) \ + ((__s32)le32_to_cpu((l).fl_object_stripe_unit)) +#define ceph_file_layout_pg_preferred(l) \ + ((__s32)le32_to_cpu((l).fl_pg_preferred)) +#define ceph_file_layout_pg_pool(l) \ + ((__s32)le32_to_cpu((l).fl_pg_pool)) + +static inline unsigned ceph_file_layout_stripe_width(struct ceph_file_layout *l) +{ + return le32_to_cpu(l->fl_stripe_unit) * + le32_to_cpu(l->fl_stripe_count); +} + +/* "period" == bytes before i start on a new set of objects */ +static inline unsigned ceph_file_layout_period(struct ceph_file_layout *l) +{ + return le32_to_cpu(l->fl_object_size) * + le32_to_cpu(l->fl_stripe_count); +} + + +static inline int ceph_osd_is_up(struct ceph_osdmap *map, int osd) +{ + return (osd < map->max_osd) && (map->osd_state[osd] & CEPH_OSD_UP); +} + +static inline bool ceph_osdmap_flag(struct ceph_osdmap *map, int flag) +{ + return map && (map->flags & flag); +} + +extern char *ceph_osdmap_state_str(char *str, int len, int state); + +static inline struct ceph_entity_addr *ceph_osd_addr(struct ceph_osdmap *map, + int osd) +{ + if (osd >= map->max_osd) + return NULL; + return &map->osd_addr[osd]; +} + +extern struct ceph_osdmap *osdmap_decode(void **p, void *end); +extern struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, + struct ceph_osdmap *map, + struct ceph_messenger *msgr); +extern void ceph_osdmap_destroy(struct ceph_osdmap *map); + +/* calculate mapping of a file extent to an object */ +extern void ceph_calc_file_object_mapping(struct ceph_file_layout *layout, + u64 off, u64 *plen, + u64 *bno, u64 *oxoff, u64 *oxlen); + +/* calculate mapping of object to a placement group */ +extern int ceph_calc_object_layout(struct ceph_object_layout *ol, + const char *oid, + struct ceph_file_layout *fl, + struct ceph_osdmap *osdmap); +extern int ceph_calc_pg_primary(struct ceph_osdmap *osdmap, union ceph_pg pgid); + +#endif -- cgit v0.10.2 From 5ecc0a0f8128b1876e8614638deaed49cc8b174c Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 6 Oct 2009 11:31:11 -0700 Subject: ceph: CRUSH mapping algorithm CRUSH is a pseudorandom data distribution function designed to map inputs onto a dynamic hierarchy of devices, while minimizing the extent to which inputs are remapped when the devices are added or removed. It includes some features that are specifically useful for storage, most notably the ability to map each input onto a set of N devices that are separated across administrator-defined failure domains. CRUSH is used to distribute data across the cluster of Ceph storage nodes. More information about CRUSH can be found in this paper: http://www.ssrc.ucsc.edu/Papers/weil-sc06.pdf Signed-off-by: Sage Weil diff --git a/fs/ceph/crush/crush.c b/fs/ceph/crush/crush.c new file mode 100644 index 0000000..13755cd --- /dev/null +++ b/fs/ceph/crush/crush.c @@ -0,0 +1,140 @@ + +#ifdef __KERNEL__ +# include +#else +# include +# include +# define kfree(x) do { if (x) free(x); } while (0) +# define BUG_ON(x) assert(!(x)) +#endif + +#include "crush.h" + +/** + * crush_get_bucket_item_weight - Get weight of an item in given bucket + * @b: bucket pointer + * @p: item index in bucket + */ +int crush_get_bucket_item_weight(struct crush_bucket *b, int p) +{ + if (p >= b->size) + return 0; + + switch (b->alg) { + case CRUSH_BUCKET_UNIFORM: + return ((struct crush_bucket_uniform *)b)->item_weight; + case CRUSH_BUCKET_LIST: + return ((struct crush_bucket_list *)b)->item_weights[p]; + case CRUSH_BUCKET_TREE: + if (p & 1) + return ((struct crush_bucket_tree *)b)->node_weights[p]; + return 0; + case CRUSH_BUCKET_STRAW: + return ((struct crush_bucket_straw *)b)->item_weights[p]; + } + return 0; +} + +/** + * crush_calc_parents - Calculate parent vectors for the given crush map. + * @map: crush_map pointer + */ +void crush_calc_parents(struct crush_map *map) +{ + int i, b, c; + + for (b = 0; b < map->max_buckets; b++) { + if (map->buckets[b] == NULL) + continue; + for (i = 0; i < map->buckets[b]->size; i++) { + c = map->buckets[b]->items[i]; + BUG_ON(c >= map->max_devices || + c < -map->max_buckets); + if (c >= 0) + map->device_parents[c] = map->buckets[b]->id; + else + map->bucket_parents[-1-c] = map->buckets[b]->id; + } + } +} + +void crush_destroy_bucket_uniform(struct crush_bucket_uniform *b) +{ + kfree(b->h.perm); + kfree(b->h.items); + kfree(b); +} + +void crush_destroy_bucket_list(struct crush_bucket_list *b) +{ + kfree(b->item_weights); + kfree(b->sum_weights); + kfree(b->h.perm); + kfree(b->h.items); + kfree(b); +} + +void crush_destroy_bucket_tree(struct crush_bucket_tree *b) +{ + kfree(b->node_weights); + kfree(b); +} + +void crush_destroy_bucket_straw(struct crush_bucket_straw *b) +{ + kfree(b->straws); + kfree(b->item_weights); + kfree(b->h.perm); + kfree(b->h.items); + kfree(b); +} + +void crush_destroy_bucket(struct crush_bucket *b) +{ + switch (b->alg) { + case CRUSH_BUCKET_UNIFORM: + crush_destroy_bucket_uniform((struct crush_bucket_uniform *)b); + break; + case CRUSH_BUCKET_LIST: + crush_destroy_bucket_list((struct crush_bucket_list *)b); + break; + case CRUSH_BUCKET_TREE: + crush_destroy_bucket_tree((struct crush_bucket_tree *)b); + break; + case CRUSH_BUCKET_STRAW: + crush_destroy_bucket_straw((struct crush_bucket_straw *)b); + break; + } +} + +/** + * crush_destroy - Destroy a crush_map + * @map: crush_map pointer + */ +void crush_destroy(struct crush_map *map) +{ + int b; + + /* buckets */ + if (map->buckets) { + for (b = 0; b < map->max_buckets; b++) { + if (map->buckets[b] == NULL) + continue; + crush_destroy_bucket(map->buckets[b]); + } + kfree(map->buckets); + } + + /* rules */ + if (map->rules) { + for (b = 0; b < map->max_rules; b++) + kfree(map->rules[b]); + kfree(map->rules); + } + + kfree(map->bucket_parents); + kfree(map->device_parents); + kfree(map); +} + + diff --git a/fs/ceph/crush/crush.h b/fs/ceph/crush/crush.h new file mode 100644 index 0000000..9ac7e09 --- /dev/null +++ b/fs/ceph/crush/crush.h @@ -0,0 +1,188 @@ +#ifndef _CRUSH_CRUSH_H +#define _CRUSH_CRUSH_H + +#include + +/* + * CRUSH is a pseudo-random data distribution algorithm that + * efficiently distributes input values (typically, data objects) + * across a heterogeneous, structured storage cluster. + * + * The algorithm was originally described in detail in this paper + * (although the algorithm has evolved somewhat since then): + * + * http://www.ssrc.ucsc.edu/Papers/weil-sc06.pdf + * + * LGPL2 + */ + + +#define CRUSH_MAGIC 0x00010000ul /* for detecting algorithm revisions */ + + +#define CRUSH_MAX_DEPTH 10 /* max crush hierarchy depth */ +#define CRUSH_MAX_SET 10 /* max size of a mapping result */ + + +/* + * CRUSH uses user-defined "rules" to describe how inputs should be + * mapped to devices. A rule consists of sequence of steps to perform + * to generate the set of output devices. + */ +struct crush_rule_step { + __u32 op; + __s32 arg1; + __s32 arg2; +}; + +/* step op codes */ +enum { + CRUSH_RULE_NOOP = 0, + CRUSH_RULE_TAKE = 1, /* arg1 = value to start with */ + CRUSH_RULE_CHOOSE_FIRSTN = 2, /* arg1 = num items to pick */ + /* arg2 = type */ + CRUSH_RULE_CHOOSE_INDEP = 3, /* same */ + CRUSH_RULE_EMIT = 4, /* no args */ + CRUSH_RULE_CHOOSE_LEAF_FIRSTN = 6, + CRUSH_RULE_CHOOSE_LEAF_INDEP = 7, +}; + +/* + * for specifying choose num (arg1) relative to the max parameter + * passed to do_rule + */ +#define CRUSH_CHOOSE_N 0 +#define CRUSH_CHOOSE_N_MINUS(x) (-(x)) + +/* + * The rule mask is used to describe what the rule is intended for. + * Given a ruleset and size of output set, we search through the + * rule list for a matching rule_mask. + */ +struct crush_rule_mask { + __u8 ruleset; + __u8 type; + __u8 min_size; + __u8 max_size; +}; + +struct crush_rule { + __u32 len; + struct crush_rule_mask mask; + struct crush_rule_step steps[0]; +}; + +#define crush_rule_size(len) (sizeof(struct crush_rule) + \ + (len)*sizeof(struct crush_rule_step)) + + + +/* + * A bucket is a named container of other items (either devices or + * other buckets). Items within a bucket are chosen using one of a + * few different algorithms. The table summarizes how the speed of + * each option measures up against mapping stability when items are + * added or removed. + * + * Bucket Alg Speed Additions Removals + * ------------------------------------------------ + * uniform O(1) poor poor + * list O(n) optimal poor + * tree O(log n) good good + * straw O(n) optimal optimal + */ +enum { + CRUSH_BUCKET_UNIFORM = 1, + CRUSH_BUCKET_LIST = 2, + CRUSH_BUCKET_TREE = 3, + CRUSH_BUCKET_STRAW = 4 +}; +static inline const char *crush_bucket_alg_name(int alg) +{ + switch (alg) { + case CRUSH_BUCKET_UNIFORM: return "uniform"; + case CRUSH_BUCKET_LIST: return "list"; + case CRUSH_BUCKET_TREE: return "tree"; + case CRUSH_BUCKET_STRAW: return "straw"; + default: return "unknown"; + } +} + +struct crush_bucket { + __s32 id; /* this'll be negative */ + __u16 type; /* non-zero; type=0 is reserved for devices */ + __u16 alg; /* one of CRUSH_BUCKET_* */ + __u32 weight; /* 16-bit fixed point */ + __u32 size; /* num items */ + __s32 *items; + + /* + * cached random permutation: used for uniform bucket and for + * the linear search fallback for the other bucket types. + */ + __u32 perm_x; /* @x for which *perm is defined */ + __u32 perm_n; /* num elements of *perm that are permuted/defined */ + __u32 *perm; +}; + +struct crush_bucket_uniform { + struct crush_bucket h; + __u32 item_weight; /* 16-bit fixed point; all items equally weighted */ +}; + +struct crush_bucket_list { + struct crush_bucket h; + __u32 *item_weights; /* 16-bit fixed point */ + __u32 *sum_weights; /* 16-bit fixed point. element i is sum + of weights 0..i, inclusive */ +}; + +struct crush_bucket_tree { + struct crush_bucket h; /* note: h.size is _tree_ size, not number of + actual items */ + __u8 num_nodes; + __u32 *node_weights; +}; + +struct crush_bucket_straw { + struct crush_bucket h; + __u32 *item_weights; /* 16-bit fixed point */ + __u32 *straws; /* 16-bit fixed point */ +}; + + + +/* + * CRUSH map includes all buckets, rules, etc. + */ +struct crush_map { + struct crush_bucket **buckets; + struct crush_rule **rules; + + /* + * Parent pointers to identify the parent bucket a device or + * bucket in the hierarchy. If an item appears more than + * once, this is the _last_ time it appeared (where buckets + * are processed in bucket id order, from -1 on down to + * -max_buckets. + */ + __u32 *bucket_parents; + __u32 *device_parents; + + __s32 max_buckets; + __u32 max_rules; + __s32 max_devices; +}; + + +/* crush.c */ +extern int crush_get_bucket_item_weight(struct crush_bucket *b, int pos); +extern void crush_calc_parents(struct crush_map *map); +extern void crush_destroy_bucket_uniform(struct crush_bucket_uniform *b); +extern void crush_destroy_bucket_list(struct crush_bucket_list *b); +extern void crush_destroy_bucket_tree(struct crush_bucket_tree *b); +extern void crush_destroy_bucket_straw(struct crush_bucket_straw *b); +extern void crush_destroy_bucket(struct crush_bucket *b); +extern void crush_destroy(struct crush_map *map); + +#endif diff --git a/fs/ceph/crush/hash.h b/fs/ceph/crush/hash.h new file mode 100644 index 0000000..42f3312 --- /dev/null +++ b/fs/ceph/crush/hash.h @@ -0,0 +1,90 @@ +#ifndef _CRUSH_HASH_H +#define _CRUSH_HASH_H + +/* + * Robert Jenkins' function for mixing 32-bit values + * http://burtleburtle.net/bob/hash/evahash.html + * a, b = random bits, c = input and output + */ +#define crush_hashmix(a, b, c) do { \ + a = a-b; a = a-c; a = a^(c>>13); \ + b = b-c; b = b-a; b = b^(a<<8); \ + c = c-a; c = c-b; c = c^(b>>13); \ + a = a-b; a = a-c; a = a^(c>>12); \ + b = b-c; b = b-a; b = b^(a<<16); \ + c = c-a; c = c-b; c = c^(b>>5); \ + a = a-b; a = a-c; a = a^(c>>3); \ + b = b-c; b = b-a; b = b^(a<<10); \ + c = c-a; c = c-b; c = c^(b>>15); \ + } while (0) + +#define crush_hash_seed 1315423911 + +static inline __u32 crush_hash32(__u32 a) +{ + __u32 hash = crush_hash_seed ^ a; + __u32 b = a; + __u32 x = 231232; + __u32 y = 1232; + crush_hashmix(b, x, hash); + crush_hashmix(y, a, hash); + return hash; +} + +static inline __u32 crush_hash32_2(__u32 a, __u32 b) +{ + __u32 hash = crush_hash_seed ^ a ^ b; + __u32 x = 231232; + __u32 y = 1232; + crush_hashmix(a, b, hash); + crush_hashmix(x, a, hash); + crush_hashmix(b, y, hash); + return hash; +} + +static inline __u32 crush_hash32_3(__u32 a, __u32 b, __u32 c) +{ + __u32 hash = crush_hash_seed ^ a ^ b ^ c; + __u32 x = 231232; + __u32 y = 1232; + crush_hashmix(a, b, hash); + crush_hashmix(c, x, hash); + crush_hashmix(y, a, hash); + crush_hashmix(b, x, hash); + crush_hashmix(y, c, hash); + return hash; +} + +static inline __u32 crush_hash32_4(__u32 a, __u32 b, __u32 c, + __u32 d) +{ + __u32 hash = crush_hash_seed ^ a ^ b ^ c ^ d; + __u32 x = 231232; + __u32 y = 1232; + crush_hashmix(a, b, hash); + crush_hashmix(c, d, hash); + crush_hashmix(a, x, hash); + crush_hashmix(y, b, hash); + crush_hashmix(c, x, hash); + crush_hashmix(y, d, hash); + return hash; +} + +static inline __u32 crush_hash32_5(__u32 a, __u32 b, __u32 c, + __u32 d, __u32 e) +{ + __u32 hash = crush_hash_seed ^ a ^ b ^ c ^ d ^ e; + __u32 x = 231232; + __u32 y = 1232; + crush_hashmix(a, b, hash); + crush_hashmix(c, d, hash); + crush_hashmix(e, x, hash); + crush_hashmix(y, a, hash); + crush_hashmix(b, x, hash); + crush_hashmix(y, c, hash); + crush_hashmix(d, x, hash); + crush_hashmix(y, e, hash); + return hash; +} + +#endif diff --git a/fs/ceph/crush/mapper.c b/fs/ceph/crush/mapper.c new file mode 100644 index 0000000..0f0730c --- /dev/null +++ b/fs/ceph/crush/mapper.c @@ -0,0 +1,589 @@ + +#ifdef __KERNEL__ +# include +# include +# include +# include +# ifndef dprintk +# define dprintk(args...) +# endif +#else +# include +# include +# include +# include +# define BUG_ON(x) assert(!(x)) +# define dprintk(args...) /* printf(args) */ +# define kmalloc(x, f) malloc(x) +# define kfree(x) free(x) +#endif + +#include "crush.h" +#include "hash.h" + +/* + * Implement the core CRUSH mapping algorithm. + */ + +/** + * crush_find_rule - find a crush_rule id for a given ruleset, type, and size. + * @map: the crush_map + * @ruleset: the storage ruleset id (user defined) + * @type: storage ruleset type (user defined) + * @size: output set size + */ +int crush_find_rule(struct crush_map *map, int ruleset, int type, int size) +{ + int i; + + for (i = 0; i < map->max_rules; i++) { + if (map->rules[i] && + map->rules[i]->mask.ruleset == ruleset && + map->rules[i]->mask.type == type && + map->rules[i]->mask.min_size <= size && + map->rules[i]->mask.max_size >= size) + return i; + } + return -1; +} + + +/* + * bucket choose methods + * + * For each bucket algorithm, we have a "choose" method that, given a + * crush input @x and replica position (usually, position in output set) @r, + * will produce an item in the bucket. + */ + +/* + * Choose based on a random permutation of the bucket. + * + * We used to use some prime number arithmetic to do this, but it + * wasn't very random, and had some other bad behaviors. Instead, we + * calculate an actual random permutation of the bucket members. + * Since this is expensive, we optimize for the r=0 case, which + * captures the vast majority of calls. + */ +static int bucket_perm_choose(struct crush_bucket *bucket, + int x, int r) +{ + unsigned pr = r % bucket->size; + unsigned i, s; + + /* start a new permutation if @x has changed */ + if (bucket->perm_x != x || bucket->perm_n == 0) { + dprintk("bucket %d new x=%d\n", bucket->id, x); + bucket->perm_x = x; + + /* optimize common r=0 case */ + if (pr == 0) { + s = crush_hash32_3(x, bucket->id, 0) % + bucket->size; + bucket->perm[0] = s; + bucket->perm_n = 0xffff; /* magic value, see below */ + goto out; + } + + for (i = 0; i < bucket->size; i++) + bucket->perm[i] = i; + bucket->perm_n = 0; + } else if (bucket->perm_n == 0xffff) { + /* clean up after the r=0 case above */ + for (i = 1; i < bucket->size; i++) + bucket->perm[i] = i; + bucket->perm[bucket->perm[0]] = 0; + bucket->perm_n = 1; + } + + /* calculate permutation up to pr */ + for (i = 0; i < bucket->perm_n; i++) + dprintk(" perm_choose have %d: %d\n", i, bucket->perm[i]); + while (bucket->perm_n <= pr) { + unsigned p = bucket->perm_n; + /* no point in swapping the final entry */ + if (p < bucket->size - 1) { + i = crush_hash32_3(x, bucket->id, p) % + (bucket->size - p); + if (i) { + unsigned t = bucket->perm[p + i]; + bucket->perm[p + i] = bucket->perm[p]; + bucket->perm[p] = t; + } + dprintk(" perm_choose swap %d with %d\n", p, p+i); + } + bucket->perm_n++; + } + for (i = 0; i < bucket->size; i++) + dprintk(" perm_choose %d: %d\n", i, bucket->perm[i]); + + s = bucket->perm[pr]; +out: + dprintk(" perm_choose %d sz=%d x=%d r=%d (%d) s=%d\n", bucket->id, + bucket->size, x, r, pr, s); + return bucket->items[s]; +} + +/* uniform */ +static int bucket_uniform_choose(struct crush_bucket_uniform *bucket, + int x, int r) +{ + return bucket_perm_choose(&bucket->h, x, r); +} + +/* list */ +static int bucket_list_choose(struct crush_bucket_list *bucket, + int x, int r) +{ + int i; + + for (i = bucket->h.size-1; i >= 0; i--) { + __u64 w = crush_hash32_4(x, bucket->h.items[i], r, + bucket->h.id); + w &= 0xffff; + dprintk("list_choose i=%d x=%d r=%d item %d weight %x " + "sw %x rand %llx", + i, x, r, bucket->h.items[i], bucket->item_weights[i], + bucket->sum_weights[i], w); + w *= bucket->sum_weights[i]; + w = w >> 16; + /*dprintk(" scaled %llx\n", w);*/ + if (w < bucket->item_weights[i]) + return bucket->h.items[i]; + } + + BUG_ON(1); + return 0; +} + + +/* (binary) tree */ +static int height(int n) +{ + int h = 0; + while ((n & 1) == 0) { + h++; + n = n >> 1; + } + return h; +} + +static int left(int x) +{ + int h = height(x); + return x - (1 << (h-1)); +} + +static int right(int x) +{ + int h = height(x); + return x + (1 << (h-1)); +} + +static int terminal(int x) +{ + return x & 1; +} + +static int bucket_tree_choose(struct crush_bucket_tree *bucket, + int x, int r) +{ + int n, l; + __u32 w; + __u64 t; + + /* start at root */ + n = bucket->num_nodes >> 1; + + while (!terminal(n)) { + /* pick point in [0, w) */ + w = bucket->node_weights[n]; + t = (__u64)crush_hash32_4(x, n, r, bucket->h.id) * (__u64)w; + t = t >> 32; + + /* descend to the left or right? */ + l = left(n); + if (t < bucket->node_weights[l]) + n = l; + else + n = right(n); + } + + return bucket->h.items[n >> 1]; +} + + +/* straw */ + +static int bucket_straw_choose(struct crush_bucket_straw *bucket, + int x, int r) +{ + int i; + int high = 0; + __u64 high_draw = 0; + __u64 draw; + + for (i = 0; i < bucket->h.size; i++) { + draw = crush_hash32_3(x, bucket->h.items[i], r); + draw &= 0xffff; + draw *= bucket->straws[i]; + if (i == 0 || draw > high_draw) { + high = i; + high_draw = draw; + } + } + return bucket->h.items[high]; +} + +static int crush_bucket_choose(struct crush_bucket *in, int x, int r) +{ + dprintk("choose %d x=%d r=%d\n", in->id, x, r); + switch (in->alg) { + case CRUSH_BUCKET_UNIFORM: + return bucket_uniform_choose((struct crush_bucket_uniform *)in, + x, r); + case CRUSH_BUCKET_LIST: + return bucket_list_choose((struct crush_bucket_list *)in, + x, r); + case CRUSH_BUCKET_TREE: + return bucket_tree_choose((struct crush_bucket_tree *)in, + x, r); + case CRUSH_BUCKET_STRAW: + return bucket_straw_choose((struct crush_bucket_straw *)in, + x, r); + default: + BUG_ON(1); +/* return in->items[0] */; + } +} + +/* + * true if device is marked "out" (failed, fully offloaded) + * of the cluster + */ +static int is_out(struct crush_map *map, __u32 *weight, int item, int x) +{ + if (weight[item] >= 0x1000) + return 0; + if (weight[item] == 0) + return 1; + if ((crush_hash32_2(x, item) & 0xffff) < weight[item]) + return 0; + return 1; +} + +/** + * crush_choose - choose numrep distinct items of given type + * @map: the crush_map + * @bucket: the bucket we are choose an item from + * @x: crush input value + * @numrep: the number of items to choose + * @type: the type of item to choose + * @out: pointer to output vector + * @outpos: our position in that vector + * @firstn: true if choosing "first n" items, false if choosing "indep" + * @recurse_to_leaf: true if we want one device under each item of given type + * @out2: second output vector for leaf items (if @recurse_to_leaf) + */ +static int crush_choose(struct crush_map *map, + struct crush_bucket *bucket, + __u32 *weight, + int x, int numrep, int type, + int *out, int outpos, + int firstn, int recurse_to_leaf, + int *out2) +{ + int rep; + int ftotal, flocal; + int retry_descent, retry_bucket, skip_rep; + struct crush_bucket *in = bucket; + int r; + int i; + int item; + int itemtype; + int collide, reject; + const int orig_tries = 5; /* attempts before we fall back to search */ + dprintk("choose bucket %d x %d outpos %d\n", bucket->id, x, outpos); + + for (rep = outpos; rep < numrep; rep++) { + /* keep trying until we get a non-out, non-colliding item */ + ftotal = 0; + skip_rep = 0; + do { + retry_descent = 0; + in = bucket; /* initial bucket */ + + /* choose through intervening buckets */ + flocal = 0; + do { + retry_bucket = 0; + r = rep; + if (in->alg == CRUSH_BUCKET_UNIFORM) { + /* be careful */ + if (firstn || numrep >= in->size) + /* r' = r + f_total */ + r += ftotal; + else if (in->size % numrep == 0) + /* r'=r+(n+1)*f_local */ + r += (numrep+1) * + (flocal+ftotal); + else + /* r' = r + n*f_local */ + r += numrep * (flocal+ftotal); + } else { + if (firstn) + /* r' = r + f_total */ + r += ftotal; + else + /* r' = r + n*f_local */ + r += numrep * (flocal+ftotal); + } + + /* bucket choose */ + if (flocal >= (in->size>>1) && + flocal > orig_tries) + item = bucket_perm_choose(in, x, r); + else + item = crush_bucket_choose(in, x, r); + BUG_ON(item >= map->max_devices); + + /* desired type? */ + if (item < 0) + itemtype = map->buckets[-1-item]->type; + else + itemtype = 0; + dprintk(" item %d type %d\n", item, itemtype); + + /* keep going? */ + if (itemtype != type) { + BUG_ON(item >= 0 || + (-1-item) >= map->max_buckets); + in = map->buckets[-1-item]; + continue; + } + + /* collision? */ + collide = 0; + for (i = 0; i < outpos; i++) { + if (out[i] == item) { + collide = 1; + break; + } + } + + if (recurse_to_leaf && + item < 0 && + crush_choose(map, map->buckets[-1-item], + weight, + x, outpos+1, 0, + out2, outpos, + firstn, 0, NULL) <= outpos) { + reject = 1; + } else { + /* out? */ + if (itemtype == 0) + reject = is_out(map, weight, + item, x); + else + reject = 0; + } + + if (reject || collide) { + ftotal++; + flocal++; + + if (collide && flocal < 3) + /* retry locally a few times */ + retry_bucket = 1; + else if (flocal < in->size + orig_tries) + /* exhaustive bucket search */ + retry_bucket = 1; + else if (ftotal < 20) + /* then retry descent */ + retry_descent = 1; + else + /* else give up */ + skip_rep = 1; + dprintk(" reject %d collide %d " + "ftotal %d flocal %d\n", + reject, collide, ftotal, + flocal); + } + } while (retry_bucket); + } while (retry_descent); + + if (skip_rep) { + dprintk("skip rep\n"); + continue; + } + + dprintk("choose got %d\n", item); + out[outpos] = item; + outpos++; + } + + dprintk("choose returns %d\n", outpos); + return outpos; +} + + +/** + * crush_do_rule - calculate a mapping with the given input and rule + * @map: the crush_map + * @ruleno: the rule id + * @x: hash input + * @result: pointer to result vector + * @result_max: maximum result size + * @force: force initial replica choice; -1 for none + */ +int crush_do_rule(struct crush_map *map, + int ruleno, int x, int *result, int result_max, + int force, __u32 *weight) +{ + int result_len; + int force_context[CRUSH_MAX_DEPTH]; + int force_pos = -1; + int a[CRUSH_MAX_SET]; + int b[CRUSH_MAX_SET]; + int c[CRUSH_MAX_SET]; + int recurse_to_leaf; + int *w; + int wsize = 0; + int *o; + int osize; + int *tmp; + struct crush_rule *rule; + int step; + int i, j; + int numrep; + int firstn; + int rc = -1; + + BUG_ON(ruleno >= map->max_rules); + + rule = map->rules[ruleno]; + result_len = 0; + w = a; + o = b; + + /* + * determine hierarchical context of force, if any. note + * that this may or may not correspond to the specific types + * referenced by the crush rule. + */ + if (force >= 0) { + if (force >= map->max_devices || + map->device_parents[force] == 0) { + /*dprintk("CRUSH: forcefed device dne\n");*/ + rc = -1; /* force fed device dne */ + goto out; + } + if (!is_out(map, weight, force, x)) { + while (1) { + force_context[++force_pos] = force; + if (force >= 0) + force = map->device_parents[force]; + else + force = map->bucket_parents[-1-force]; + if (force == 0) + break; + } + } + } + + for (step = 0; step < rule->len; step++) { + firstn = 0; + switch (rule->steps[step].op) { + case CRUSH_RULE_TAKE: + w[0] = rule->steps[step].arg1; + if (force_pos >= 0) { + BUG_ON(force_context[force_pos] != w[0]); + force_pos--; + } + wsize = 1; + break; + + case CRUSH_RULE_CHOOSE_LEAF_FIRSTN: + case CRUSH_RULE_CHOOSE_FIRSTN: + firstn = 1; + case CRUSH_RULE_CHOOSE_LEAF_INDEP: + case CRUSH_RULE_CHOOSE_INDEP: + BUG_ON(wsize == 0); + + recurse_to_leaf = + rule->steps[step].op == + CRUSH_RULE_CHOOSE_LEAF_FIRSTN || + rule->steps[step].op == + CRUSH_RULE_CHOOSE_LEAF_INDEP; + + /* reset output */ + osize = 0; + + for (i = 0; i < wsize; i++) { + /* + * see CRUSH_N, CRUSH_N_MINUS macros. + * basically, numrep <= 0 means relative to + * the provided result_max + */ + numrep = rule->steps[step].arg1; + if (numrep <= 0) { + numrep += result_max; + if (numrep <= 0) + continue; + } + j = 0; + if (osize == 0 && force_pos >= 0) { + /* skip any intermediate types */ + while (force_pos && + force_context[force_pos] < 0 && + rule->steps[step].arg2 != + map->buckets[-1 - + force_context[force_pos]]->type) + force_pos--; + o[osize] = force_context[force_pos]; + if (recurse_to_leaf) + c[osize] = force_context[0]; + j++; + force_pos--; + } + osize += crush_choose(map, + map->buckets[-1-w[i]], + weight, + x, numrep, + rule->steps[step].arg2, + o+osize, j, + firstn, + recurse_to_leaf, c+osize); + } + + if (recurse_to_leaf) + /* copy final _leaf_ values to output set */ + memcpy(o, c, osize*sizeof(*o)); + + /* swap t and w arrays */ + tmp = o; + o = w; + w = tmp; + wsize = osize; + break; + + + case CRUSH_RULE_EMIT: + for (i = 0; i < wsize && result_len < result_max; i++) { + result[result_len] = w[i]; + result_len++; + } + wsize = 0; + break; + + default: + BUG_ON(1); + } + } + rc = result_len; + +out: + return rc; +} + + diff --git a/fs/ceph/crush/mapper.h b/fs/ceph/crush/mapper.h new file mode 100644 index 0000000..98e9004 --- /dev/null +++ b/fs/ceph/crush/mapper.h @@ -0,0 +1,20 @@ +#ifndef _CRUSH_MAPPER_H +#define _CRUSH_MAPPER_H + +/* + * CRUSH functions for find rules and then mapping an input to an + * output set. + * + * LGPL2 + */ + +#include "crush.h" + +extern int crush_find_rule(struct crush_map *map, int pool, int type, int size); +extern int crush_do_rule(struct crush_map *map, + int ruleno, + int x, int *result, int result_max, + int forcefeed, /* -1 for none */ + __u32 *weights); + +#endif -- cgit v0.10.2 From ba75bb98cfb93b62c54af25bf67ff90857264bbe Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 6 Oct 2009 11:31:11 -0700 Subject: ceph: monitor client The monitor cluster is responsible for managing cluster membership and state. The monitor client handles what minimal interaction the Ceph client has with it: checking for updated versions of the MDS and OSD maps, getting statfs() information, and unmounting. Signed-off-by: Sage Weil diff --git a/fs/ceph/mon_client.c b/fs/ceph/mon_client.c new file mode 100644 index 0000000..b0c95ce --- /dev/null +++ b/fs/ceph/mon_client.c @@ -0,0 +1,694 @@ +#include "ceph_debug.h" + +#include +#include +#include + +#include "mon_client.h" +#include "super.h" +#include "decode.h" + +/* + * Interact with Ceph monitor cluster. Handle requests for new map + * versions, and periodically resend as needed. Also implement + * statfs() and umount(). + * + * A small cluster of Ceph "monitors" are responsible for managing critical + * cluster configuration and state information. An odd number (e.g., 3, 5) + * of cmon daemons use a modified version of the Paxos part-time parliament + * algorithm to manage the MDS map (mds cluster membership), OSD map, and + * list of clients who have mounted the file system. + * + * We maintain an open, active session with a monitor at all times in order to + * receive timely MDSMap updates. We periodically send a keepalive byte on the + * TCP socket to ensure we detect a failure. If the connection does break, we + * randomly hunt for a new monitor. Once the connection is reestablished, we + * resend any outstanding requests. + */ + +const static struct ceph_connection_operations mon_con_ops; + +/* + * Decode a monmap blob (e.g., during mount). + */ +struct ceph_monmap *ceph_monmap_decode(void *p, void *end) +{ + struct ceph_monmap *m = NULL; + int i, err = -EINVAL; + struct ceph_fsid fsid; + u32 epoch, num_mon; + u16 version; + + dout("monmap_decode %p %p len %d\n", p, end, (int)(end-p)); + + ceph_decode_16_safe(&p, end, version, bad); + + ceph_decode_need(&p, end, sizeof(fsid) + 2*sizeof(u32), bad); + ceph_decode_copy(&p, &fsid, sizeof(fsid)); + ceph_decode_32(&p, epoch); + + ceph_decode_32(&p, num_mon); + ceph_decode_need(&p, end, num_mon*sizeof(m->mon_inst[0]), bad); + + if (num_mon >= CEPH_MAX_MON) + goto bad; + m = kmalloc(sizeof(*m) + sizeof(m->mon_inst[0])*num_mon, GFP_NOFS); + if (m == NULL) + return ERR_PTR(-ENOMEM); + m->fsid = fsid; + m->epoch = epoch; + m->num_mon = num_mon; + ceph_decode_copy(&p, m->mon_inst, num_mon*sizeof(m->mon_inst[0])); + + if (p != end) + goto bad; + + dout("monmap_decode epoch %d, num_mon %d\n", m->epoch, + m->num_mon); + for (i = 0; i < m->num_mon; i++) + dout("monmap_decode mon%d is %s\n", i, + pr_addr(&m->mon_inst[i].addr.in_addr)); + return m; + +bad: + dout("monmap_decode failed with %d\n", err); + kfree(m); + return ERR_PTR(err); +} + +/* + * return true if *addr is included in the monmap. + */ +int ceph_monmap_contains(struct ceph_monmap *m, struct ceph_entity_addr *addr) +{ + int i; + + for (i = 0; i < m->num_mon; i++) + if (ceph_entity_addr_equal(addr, &m->mon_inst[i].addr)) + return 1; + return 0; +} + +/* + * Close monitor session, if any. + */ +static void __close_session(struct ceph_mon_client *monc) +{ + if (monc->con) { + dout("__close_session closing mon%d\n", monc->cur_mon); + ceph_con_close(monc->con); + monc->cur_mon = -1; + } +} + +/* + * Open a session with a (new) monitor. + */ +static int __open_session(struct ceph_mon_client *monc) +{ + char r; + + if (monc->cur_mon < 0) { + get_random_bytes(&r, 1); + monc->cur_mon = r % monc->monmap->num_mon; + dout("open_session num=%d r=%d -> mon%d\n", + monc->monmap->num_mon, r, monc->cur_mon); + monc->sub_sent = 0; + monc->sub_renew_after = jiffies; /* i.e., expired */ + monc->want_next_osdmap = !!monc->want_next_osdmap; + + dout("open_session mon%d opening\n", monc->cur_mon); + monc->con->peer_name.type = CEPH_ENTITY_TYPE_MON; + monc->con->peer_name.num = cpu_to_le64(monc->cur_mon); + ceph_con_open(monc->con, + &monc->monmap->mon_inst[monc->cur_mon].addr); + } else { + dout("open_session mon%d already open\n", monc->cur_mon); + } + return 0; +} + +static bool __sub_expired(struct ceph_mon_client *monc) +{ + return time_after_eq(jiffies, monc->sub_renew_after); +} + +/* + * Reschedule delayed work timer. + */ +static void __schedule_delayed(struct ceph_mon_client *monc) +{ + unsigned delay; + + if (monc->cur_mon < 0 || monc->want_mount || __sub_expired(monc)) + delay = 10 * HZ; + else + delay = 20 * HZ; + dout("__schedule_delayed after %u\n", delay); + schedule_delayed_work(&monc->delayed_work, delay); +} + +/* + * Send subscribe request for mdsmap and/or osdmap. + */ +static void __send_subscribe(struct ceph_mon_client *monc) +{ + dout("__send_subscribe sub_sent=%u exp=%u want_osd=%d\n", + (unsigned)monc->sub_sent, __sub_expired(monc), + monc->want_next_osdmap); + if ((__sub_expired(monc) && !monc->sub_sent) || + monc->want_next_osdmap == 1) { + struct ceph_msg *msg; + struct ceph_mon_subscribe_item *i; + void *p, *end; + + msg = ceph_msg_new(CEPH_MSG_MON_SUBSCRIBE, 64, 0, 0, NULL); + if (!msg) + return; + + p = msg->front.iov_base; + end = p + msg->front.iov_len; + + dout("__send_subscribe to 'mdsmap' %u+\n", + (unsigned)monc->have_mdsmap); + if (monc->want_next_osdmap) { + dout("__send_subscribe to 'osdmap' %u\n", + (unsigned)monc->have_osdmap); + ceph_encode_32(&p, 2); + ceph_encode_string(&p, end, "osdmap", 6); + i = p; + i->have = cpu_to_le64(monc->have_osdmap); + i->onetime = 1; + p += sizeof(*i); + monc->want_next_osdmap = 2; /* requested */ + } else { + ceph_encode_32(&p, 1); + } + ceph_encode_string(&p, end, "mdsmap", 6); + i = p; + i->have = cpu_to_le64(monc->have_mdsmap); + i->onetime = 0; + p += sizeof(*i); + + msg->front.iov_len = p - msg->front.iov_base; + msg->hdr.front_len = cpu_to_le32(msg->front.iov_len); + ceph_con_send(monc->con, msg); + + monc->sub_sent = jiffies | 1; /* never 0 */ + } +} + +static void handle_subscribe_ack(struct ceph_mon_client *monc, + struct ceph_msg *msg) +{ + unsigned seconds; + void *p = msg->front.iov_base; + void *end = p + msg->front.iov_len; + + ceph_decode_32_safe(&p, end, seconds, bad); + mutex_lock(&monc->mutex); + if (monc->hunting) { + pr_info("mon%d %s session established\n", + monc->cur_mon, pr_addr(&monc->con->peer_addr.in_addr)); + monc->hunting = false; + } + dout("handle_subscribe_ack after %d seconds\n", seconds); + monc->sub_renew_after = monc->sub_sent + seconds*HZ - 1; + monc->sub_sent = 0; + mutex_unlock(&monc->mutex); + return; +bad: + pr_err("got corrupt subscribe-ack msg\n"); +} + +/* + * Keep track of which maps we have + */ +int ceph_monc_got_mdsmap(struct ceph_mon_client *monc, u32 got) +{ + mutex_lock(&monc->mutex); + monc->have_mdsmap = got; + mutex_unlock(&monc->mutex); + return 0; +} + +int ceph_monc_got_osdmap(struct ceph_mon_client *monc, u32 got) +{ + mutex_lock(&monc->mutex); + monc->have_osdmap = got; + monc->want_next_osdmap = 0; + mutex_unlock(&monc->mutex); + return 0; +} + +/* + * Register interest in the next osdmap + */ +void ceph_monc_request_next_osdmap(struct ceph_mon_client *monc) +{ + dout("request_next_osdmap have %u\n", monc->have_osdmap); + mutex_lock(&monc->mutex); + if (!monc->want_next_osdmap) + monc->want_next_osdmap = 1; + if (monc->want_next_osdmap < 2) + __send_subscribe(monc); + mutex_unlock(&monc->mutex); +} + + +/* + * mount + */ +static void __request_mount(struct ceph_mon_client *monc) +{ + struct ceph_msg *msg; + struct ceph_client_mount *h; + int err; + + dout("__request_mount\n"); + err = __open_session(monc); + if (err) + return; + msg = ceph_msg_new(CEPH_MSG_CLIENT_MOUNT, sizeof(*h), 0, 0, NULL); + if (IS_ERR(msg)) + return; + h = msg->front.iov_base; + h->have_version = 0; + ceph_con_send(monc->con, msg); +} + +int ceph_monc_request_mount(struct ceph_mon_client *monc) +{ + if (!monc->con) { + monc->con = kmalloc(sizeof(*monc->con), GFP_KERNEL); + if (!monc->con) + return -ENOMEM; + ceph_con_init(monc->client->msgr, monc->con); + monc->con->private = monc; + monc->con->ops = &mon_con_ops; + } + + mutex_lock(&monc->mutex); + __request_mount(monc); + __schedule_delayed(monc); + mutex_unlock(&monc->mutex); + return 0; +} + +/* + * The monitor responds with mount ack indicate mount success. The + * included client ticket allows the client to talk to MDSs and OSDs. + */ +static void handle_mount_ack(struct ceph_mon_client *monc, struct ceph_msg *msg) +{ + struct ceph_client *client = monc->client; + struct ceph_monmap *monmap = NULL, *old = monc->monmap; + void *p, *end; + s32 result; + u32 len; + s64 cnum; + int err = -EINVAL; + + if (client->whoami >= 0) { + dout("handle_mount_ack - already mounted\n"); + return; + } + + mutex_lock(&monc->mutex); + + dout("handle_mount_ack\n"); + p = msg->front.iov_base; + end = p + msg->front.iov_len; + + ceph_decode_64_safe(&p, end, cnum, bad); + ceph_decode_32_safe(&p, end, result, bad); + ceph_decode_32_safe(&p, end, len, bad); + if (result) { + pr_err("mount denied: %.*s (%d)\n", len, (char *)p, + result); + err = result; + goto out; + } + p += len; + + ceph_decode_32_safe(&p, end, len, bad); + ceph_decode_need(&p, end, len, bad); + monmap = ceph_monmap_decode(p, p + len); + if (IS_ERR(monmap)) { + pr_err("problem decoding monmap, %d\n", + (int)PTR_ERR(monmap)); + err = -EINVAL; + goto out; + } + p += len; + + client->monc.monmap = monmap; + kfree(old); + + client->signed_ticket = NULL; + client->signed_ticket_len = 0; + + monc->want_mount = false; + + client->whoami = cnum; + client->msgr->inst.name.type = CEPH_ENTITY_TYPE_CLIENT; + client->msgr->inst.name.num = cpu_to_le64(cnum); + pr_info("client%lld fsid " FSID_FORMAT "\n", + client->whoami, PR_FSID(&client->monc.monmap->fsid)); + + ceph_debugfs_client_init(client); + __send_subscribe(monc); + + err = 0; + goto out; + +bad: + pr_err("error decoding mount_ack message\n"); +out: + client->mount_err = err; + mutex_unlock(&monc->mutex); + wake_up(&client->mount_wq); +} + + + + +/* + * statfs + */ +static void handle_statfs_reply(struct ceph_mon_client *monc, + struct ceph_msg *msg) +{ + struct ceph_mon_statfs_request *req; + struct ceph_mon_statfs_reply *reply = msg->front.iov_base; + u64 tid; + + if (msg->front.iov_len != sizeof(*reply)) + goto bad; + tid = le64_to_cpu(reply->tid); + dout("handle_statfs_reply %p tid %llu\n", msg, tid); + + mutex_lock(&monc->mutex); + req = radix_tree_lookup(&monc->statfs_request_tree, tid); + if (req) { + *req->buf = reply->st; + req->result = 0; + } + mutex_unlock(&monc->mutex); + if (req) + complete(&req->completion); + return; + +bad: + pr_err("corrupt statfs reply, no tid\n"); +} + +/* + * (re)send a statfs request + */ +static int send_statfs(struct ceph_mon_client *monc, + struct ceph_mon_statfs_request *req) +{ + struct ceph_msg *msg; + struct ceph_mon_statfs *h; + int err; + + dout("send_statfs tid %llu\n", req->tid); + err = __open_session(monc); + if (err) + return err; + msg = ceph_msg_new(CEPH_MSG_STATFS, sizeof(*h), 0, 0, NULL); + if (IS_ERR(msg)) + return PTR_ERR(msg); + req->request = msg; + h = msg->front.iov_base; + h->have_version = 0; + h->fsid = monc->monmap->fsid; + h->tid = cpu_to_le64(req->tid); + ceph_con_send(monc->con, msg); + return 0; +} + +/* + * Do a synchronous statfs(). + */ +int ceph_monc_do_statfs(struct ceph_mon_client *monc, struct ceph_statfs *buf) +{ + struct ceph_mon_statfs_request req; + int err; + + req.buf = buf; + init_completion(&req.completion); + + /* allocate memory for reply */ + err = ceph_msgpool_resv(&monc->msgpool_statfs_reply, 1); + if (err) + return err; + + /* register request */ + mutex_lock(&monc->mutex); + req.tid = ++monc->last_tid; + req.last_attempt = jiffies; + req.delay = BASE_DELAY_INTERVAL; + if (radix_tree_insert(&monc->statfs_request_tree, req.tid, &req) < 0) { + mutex_unlock(&monc->mutex); + pr_err("ENOMEM in do_statfs\n"); + return -ENOMEM; + } + monc->num_statfs_requests++; + mutex_unlock(&monc->mutex); + + /* send request and wait */ + err = send_statfs(monc, &req); + if (!err) + err = wait_for_completion_interruptible(&req.completion); + + mutex_lock(&monc->mutex); + radix_tree_delete(&monc->statfs_request_tree, req.tid); + monc->num_statfs_requests--; + ceph_msgpool_resv(&monc->msgpool_statfs_reply, -1); + mutex_unlock(&monc->mutex); + + if (!err) + err = req.result; + return err; +} + +/* + * Resend pending statfs requests. + */ +static void __resend_statfs(struct ceph_mon_client *monc) +{ + u64 next_tid = 0; + int got; + int did = 0; + struct ceph_mon_statfs_request *req; + + while (1) { + got = radix_tree_gang_lookup(&monc->statfs_request_tree, + (void **)&req, + next_tid, 1); + if (got == 0) + break; + did++; + next_tid = req->tid + 1; + + send_statfs(monc, req); + } +} + +/* + * Delayed work. If we haven't mounted yet, retry. Otherwise, + * renew/retry subscription as needed (in case it is timing out, or we + * got an ENOMEM). And keep the monitor connection alive. + */ +static void delayed_work(struct work_struct *work) +{ + struct ceph_mon_client *monc = + container_of(work, struct ceph_mon_client, delayed_work.work); + + dout("monc delayed_work\n"); + mutex_lock(&monc->mutex); + if (monc->want_mount) { + __request_mount(monc); + } else { + if (__sub_expired(monc)) { + __close_session(monc); + __open_session(monc); /* continue hunting */ + } else { + ceph_con_keepalive(monc->con); + } + } + __send_subscribe(monc); + __schedule_delayed(monc); + mutex_unlock(&monc->mutex); +} + +int ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl) +{ + int err = 0; + + dout("init\n"); + memset(monc, 0, sizeof(*monc)); + monc->client = cl; + monc->monmap = NULL; + mutex_init(&monc->mutex); + + monc->con = NULL; + + /* msg pools */ + err = ceph_msgpool_init(&monc->msgpool_mount_ack, 4096, 1, false); + if (err < 0) + goto out; + err = ceph_msgpool_init(&monc->msgpool_subscribe_ack, 8, 1, false); + if (err < 0) + goto out; + err = ceph_msgpool_init(&monc->msgpool_statfs_reply, + sizeof(struct ceph_mon_statfs_reply), 0, false); + if (err < 0) + goto out; + + monc->cur_mon = -1; + monc->hunting = false; /* not really */ + monc->sub_renew_after = jiffies; + monc->sub_sent = 0; + + INIT_DELAYED_WORK(&monc->delayed_work, delayed_work); + INIT_RADIX_TREE(&monc->statfs_request_tree, GFP_NOFS); + monc->num_statfs_requests = 0; + monc->last_tid = 0; + + monc->have_mdsmap = 0; + monc->have_osdmap = 0; + monc->want_next_osdmap = 1; + monc->want_mount = true; +out: + return err; +} + +void ceph_monc_stop(struct ceph_mon_client *monc) +{ + dout("stop\n"); + cancel_delayed_work_sync(&monc->delayed_work); + + mutex_lock(&monc->mutex); + __close_session(monc); + if (monc->con) { + monc->con->private = NULL; + monc->con->ops->put(monc->con); + monc->con = NULL; + } + mutex_unlock(&monc->mutex); + + ceph_msgpool_destroy(&monc->msgpool_mount_ack); + ceph_msgpool_destroy(&monc->msgpool_subscribe_ack); + ceph_msgpool_destroy(&monc->msgpool_statfs_reply); + + kfree(monc->monmap); +} + + +/* + * handle incoming message + */ +static void dispatch(struct ceph_connection *con, struct ceph_msg *msg) +{ + struct ceph_mon_client *monc = con->private; + int type = le16_to_cpu(msg->hdr.type); + + if (!monc) + return; + + switch (type) { + case CEPH_MSG_CLIENT_MOUNT_ACK: + handle_mount_ack(monc, msg); + break; + + case CEPH_MSG_MON_SUBSCRIBE_ACK: + handle_subscribe_ack(monc, msg); + break; + + case CEPH_MSG_STATFS_REPLY: + handle_statfs_reply(monc, msg); + break; + + case CEPH_MSG_MDS_MAP: + ceph_mdsc_handle_map(&monc->client->mdsc, msg); + break; + + case CEPH_MSG_OSD_MAP: + ceph_osdc_handle_map(&monc->client->osdc, msg); + break; + + default: + pr_err("received unknown message type %d %s\n", type, + ceph_msg_type_name(type)); + } + ceph_msg_put(msg); +} + +/* + * Allocate memory for incoming message + */ +static struct ceph_msg *mon_alloc_msg(struct ceph_connection *con, + struct ceph_msg_header *hdr) +{ + struct ceph_mon_client *monc = con->private; + int type = le16_to_cpu(hdr->type); + + switch (type) { + case CEPH_MSG_CLIENT_MOUNT_ACK: + return ceph_msgpool_get(&monc->msgpool_mount_ack); + case CEPH_MSG_MON_SUBSCRIBE_ACK: + return ceph_msgpool_get(&monc->msgpool_subscribe_ack); + case CEPH_MSG_STATFS_REPLY: + return ceph_msgpool_get(&monc->msgpool_statfs_reply); + } + return ceph_alloc_msg(con, hdr); +} + +/* + * If the monitor connection resets, pick a new monitor and resubmit + * any pending requests. + */ +static void mon_fault(struct ceph_connection *con) +{ + struct ceph_mon_client *monc = con->private; + + if (!monc) + return; + + dout("mon_fault\n"); + mutex_lock(&monc->mutex); + if (!con->private) + goto out; + + if (monc->con && !monc->hunting) + pr_info("mon%d %s session lost, " + "hunting for new mon\n", monc->cur_mon, + pr_addr(&monc->con->peer_addr.in_addr)); + + __close_session(monc); + if (!monc->hunting) { + /* start hunting */ + monc->hunting = true; + if (__open_session(monc) == 0) { + __send_subscribe(monc); + __resend_statfs(monc); + } + } else { + /* already hunting, let's wait a bit */ + __schedule_delayed(monc); + } +out: + mutex_unlock(&monc->mutex); +} + +const static struct ceph_connection_operations mon_con_ops = { + .get = ceph_con_get, + .put = ceph_con_put, + .dispatch = dispatch, + .fault = mon_fault, + .alloc_msg = mon_alloc_msg, + .alloc_middle = ceph_alloc_middle, +}; diff --git a/fs/ceph/mon_client.h b/fs/ceph/mon_client.h new file mode 100644 index 0000000..5258c56 --- /dev/null +++ b/fs/ceph/mon_client.h @@ -0,0 +1,109 @@ +#ifndef _FS_CEPH_MON_CLIENT_H +#define _FS_CEPH_MON_CLIENT_H + +#include +#include + +#include "messenger.h" +#include "msgpool.h" + +struct ceph_client; +struct ceph_mount_args; + +/* + * The monitor map enumerates the set of all monitors. + */ +struct ceph_monmap { + struct ceph_fsid fsid; + u32 epoch; + u32 num_mon; + struct ceph_entity_inst mon_inst[0]; +}; + +struct ceph_mon_client; +struct ceph_mon_statfs_request; + + +/* + * Generic mechanism for resending monitor requests. + */ +typedef void (*ceph_monc_request_func_t)(struct ceph_mon_client *monc, + int newmon); + +/* a pending monitor request */ +struct ceph_mon_request { + struct ceph_mon_client *monc; + struct delayed_work delayed_work; + unsigned long delay; + ceph_monc_request_func_t do_request; +}; + +/* + * statfs() is done a bit differently because we need to get data back + * to the caller + */ +struct ceph_mon_statfs_request { + u64 tid; + int result; + struct ceph_statfs *buf; + struct completion completion; + unsigned long last_attempt, delay; /* jiffies */ + struct ceph_msg *request; /* original request */ +}; + +struct ceph_mon_client { + struct ceph_client *client; + struct ceph_monmap *monmap; + + struct mutex mutex; + struct delayed_work delayed_work; + + bool hunting; + int cur_mon; /* last monitor i contacted */ + unsigned long sub_sent, sub_renew_after; + struct ceph_connection *con; + + /* msg pools */ + struct ceph_msgpool msgpool_mount_ack; + struct ceph_msgpool msgpool_subscribe_ack; + struct ceph_msgpool msgpool_statfs_reply; + + /* pending statfs requests */ + struct radix_tree_root statfs_request_tree; + int num_statfs_requests; + u64 last_tid; + + /* mds/osd map or mount requests */ + bool want_mount; + int want_next_osdmap; /* 1 = want, 2 = want+asked */ + u32 have_osdmap, have_mdsmap; + + struct dentry *debugfs_file; +}; + +extern struct ceph_monmap *ceph_monmap_decode(void *p, void *end); +extern int ceph_monmap_contains(struct ceph_monmap *m, + struct ceph_entity_addr *addr); + +extern int ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl); +extern void ceph_monc_stop(struct ceph_mon_client *monc); + +/* + * The model here is to indicate that we need a new map of at least + * epoch @want, and also call in when we receive a map. We will + * periodically rerequest the map from the monitor cluster until we + * get what we want. + */ +extern int ceph_monc_got_mdsmap(struct ceph_mon_client *monc, u32 have); +extern int ceph_monc_got_osdmap(struct ceph_mon_client *monc, u32 have); + +extern void ceph_monc_request_next_osdmap(struct ceph_mon_client *monc); + +extern int ceph_monc_request_mount(struct ceph_mon_client *monc); + +extern int ceph_monc_do_statfs(struct ceph_mon_client *monc, + struct ceph_statfs *buf); + + + +#endif -- cgit v0.10.2 From a8599bd821d084d04a3290fffae1071624ec00ea Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 6 Oct 2009 11:31:12 -0700 Subject: ceph: capability management The Ceph metadata servers control client access to inode metadata and file data by issuing capabilities, granting clients permission to read and/or write both inode field and file data to OSDs (storage nodes). Each capability consists of a set of bits indicating which operations are allowed. If the client holds a *_SHARED cap, the client has a coherent value that can be safely read from the cached inode. In the case of a *_EXCL (exclusive) or FILE_WR capabilities, the client is allowed to change inode attributes (e.g., file size, mtime), note its dirty state in the ceph_cap, and asynchronously flush that metadata change to the MDS. In the event of a conflicting operation (perhaps by another client), the MDS will revoke the conflicting client capabilities. In order for a client to cache an inode, it must hold a capability with at least one MDS server. When inodes are released, release notifications are batched and periodically sent en masse to the MDS cluster to release server state. Signed-off-by: Sage Weil diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c new file mode 100644 index 0000000..5c7d0e9 --- /dev/null +++ b/fs/ceph/caps.c @@ -0,0 +1,2830 @@ +#include "ceph_debug.h" + +#include +#include +#include +#include +#include + +#include "super.h" +#include "decode.h" +#include "messenger.h" + +/* + * Capability management + * + * The Ceph metadata servers control client access to inode metadata + * and file data by issuing capabilities, granting clients permission + * to read and/or write both inode field and file data to OSDs + * (storage nodes). Each capability consists of a set of bits + * indicating which operations are allowed. + * + * If the client holds a *_SHARED cap, the client has a coherent value + * that can be safely read from the cached inode. + * + * In the case of a *_EXCL (exclusive) or FILE_WR capabilities, the + * client is allowed to change inode attributes (e.g., file size, + * mtime), note its dirty state in the ceph_cap, and asynchronously + * flush that metadata change to the MDS. + * + * In the event of a conflicting operation (perhaps by another + * client), the MDS will revoke the conflicting client capabilities. + * + * In order for a client to cache an inode, it must hold a capability + * with at least one MDS server. When inodes are released, release + * notifications are batched and periodically sent en masse to the MDS + * cluster to release server state. + */ + + +/* + * Generate readable cap strings for debugging output. + */ +#define MAX_CAP_STR 20 +static char cap_str[MAX_CAP_STR][40]; +static DEFINE_SPINLOCK(cap_str_lock); +static int last_cap_str; + +static char *gcap_string(char *s, int c) +{ + if (c & CEPH_CAP_GSHARED) + *s++ = 's'; + if (c & CEPH_CAP_GEXCL) + *s++ = 'x'; + if (c & CEPH_CAP_GCACHE) + *s++ = 'c'; + if (c & CEPH_CAP_GRD) + *s++ = 'r'; + if (c & CEPH_CAP_GWR) + *s++ = 'w'; + if (c & CEPH_CAP_GBUFFER) + *s++ = 'b'; + if (c & CEPH_CAP_GLAZYIO) + *s++ = 'l'; + return s; +} + +const char *ceph_cap_string(int caps) +{ + int i; + char *s; + int c; + + spin_lock(&cap_str_lock); + i = last_cap_str++; + if (last_cap_str == MAX_CAP_STR) + last_cap_str = 0; + spin_unlock(&cap_str_lock); + + s = cap_str[i]; + + if (caps & CEPH_CAP_PIN) + *s++ = 'p'; + + c = (caps >> CEPH_CAP_SAUTH) & 3; + if (c) { + *s++ = 'A'; + s = gcap_string(s, c); + } + + c = (caps >> CEPH_CAP_SLINK) & 3; + if (c) { + *s++ = 'L'; + s = gcap_string(s, c); + } + + c = (caps >> CEPH_CAP_SXATTR) & 3; + if (c) { + *s++ = 'X'; + s = gcap_string(s, c); + } + + c = caps >> CEPH_CAP_SFILE; + if (c) { + *s++ = 'F'; + s = gcap_string(s, c); + } + + if (s == cap_str[i]) + *s++ = '-'; + *s = 0; + return cap_str[i]; +} + +/* + * Cap reservations + * + * Maintain a global pool of preallocated struct ceph_caps, referenced + * by struct ceph_caps_reservations. This ensures that we preallocate + * memory needed to successfully process an MDS response. (If an MDS + * sends us cap information and we fail to process it, we will have + * problems due to the client and MDS being out of sync.) + * + * Reservations are 'owned' by a ceph_cap_reservation context. + */ +static spinlock_t caps_list_lock; +static struct list_head caps_list; /* unused (reserved or unreserved) */ +static int caps_total_count; /* total caps allocated */ +static int caps_use_count; /* in use */ +static int caps_reserve_count; /* unused, reserved */ +static int caps_avail_count; /* unused, unreserved */ + +void __init ceph_caps_init(void) +{ + INIT_LIST_HEAD(&caps_list); + spin_lock_init(&caps_list_lock); +} + +void ceph_caps_finalize(void) +{ + struct ceph_cap *cap; + + spin_lock(&caps_list_lock); + while (!list_empty(&caps_list)) { + cap = list_first_entry(&caps_list, struct ceph_cap, caps_item); + list_del(&cap->caps_item); + kmem_cache_free(ceph_cap_cachep, cap); + } + caps_total_count = 0; + caps_avail_count = 0; + caps_use_count = 0; + caps_reserve_count = 0; + spin_unlock(&caps_list_lock); +} + +int ceph_reserve_caps(struct ceph_cap_reservation *ctx, int need) +{ + int i; + struct ceph_cap *cap; + int have; + int alloc = 0; + LIST_HEAD(newcaps); + int ret = 0; + + dout("reserve caps ctx=%p need=%d\n", ctx, need); + + /* first reserve any caps that are already allocated */ + spin_lock(&caps_list_lock); + if (caps_avail_count >= need) + have = need; + else + have = caps_avail_count; + caps_avail_count -= have; + caps_reserve_count += have; + BUG_ON(caps_total_count != caps_use_count + caps_reserve_count + + caps_avail_count); + spin_unlock(&caps_list_lock); + + for (i = have; i < need; i++) { + cap = kmem_cache_alloc(ceph_cap_cachep, GFP_NOFS); + if (!cap) { + ret = -ENOMEM; + goto out_alloc_count; + } + list_add(&cap->caps_item, &newcaps); + alloc++; + } + BUG_ON(have + alloc != need); + + spin_lock(&caps_list_lock); + caps_total_count += alloc; + caps_reserve_count += alloc; + list_splice(&newcaps, &caps_list); + + BUG_ON(caps_total_count != caps_use_count + caps_reserve_count + + caps_avail_count); + spin_unlock(&caps_list_lock); + + ctx->count = need; + dout("reserve caps ctx=%p %d = %d used + %d resv + %d avail\n", + ctx, caps_total_count, caps_use_count, caps_reserve_count, + caps_avail_count); + return 0; + +out_alloc_count: + /* we didn't manage to reserve as much as we needed */ + pr_warning("reserve caps ctx=%p ENOMEM need=%d got=%d\n", + ctx, need, have); + return ret; +} + +int ceph_unreserve_caps(struct ceph_cap_reservation *ctx) +{ + dout("unreserve caps ctx=%p count=%d\n", ctx, ctx->count); + if (ctx->count) { + spin_lock(&caps_list_lock); + BUG_ON(caps_reserve_count < ctx->count); + caps_reserve_count -= ctx->count; + caps_avail_count += ctx->count; + ctx->count = 0; + dout("unreserve caps %d = %d used + %d resv + %d avail\n", + caps_total_count, caps_use_count, caps_reserve_count, + caps_avail_count); + BUG_ON(caps_total_count != caps_use_count + caps_reserve_count + + caps_avail_count); + spin_unlock(&caps_list_lock); + } + return 0; +} + +static struct ceph_cap *get_cap(struct ceph_cap_reservation *ctx) +{ + struct ceph_cap *cap = NULL; + + /* temporary, until we do something about cap import/export */ + if (!ctx) + return kmem_cache_alloc(ceph_cap_cachep, GFP_NOFS); + + spin_lock(&caps_list_lock); + dout("get_cap ctx=%p (%d) %d = %d used + %d resv + %d avail\n", + ctx, ctx->count, caps_total_count, caps_use_count, + caps_reserve_count, caps_avail_count); + BUG_ON(!ctx->count); + BUG_ON(ctx->count > caps_reserve_count); + BUG_ON(list_empty(&caps_list)); + + ctx->count--; + caps_reserve_count--; + caps_use_count++; + + cap = list_first_entry(&caps_list, struct ceph_cap, caps_item); + list_del(&cap->caps_item); + + BUG_ON(caps_total_count != caps_use_count + caps_reserve_count + + caps_avail_count); + spin_unlock(&caps_list_lock); + return cap; +} + +static void put_cap(struct ceph_cap *cap, + struct ceph_cap_reservation *ctx) +{ + spin_lock(&caps_list_lock); + dout("put_cap ctx=%p (%d) %d = %d used + %d resv + %d avail\n", + ctx, ctx ? ctx->count : 0, caps_total_count, caps_use_count, + caps_reserve_count, caps_avail_count); + caps_use_count--; + /* + * Keep some preallocated caps around, at least enough to do a + * readdir (which needs to preallocate lots of them), to avoid + * lots of free/alloc churn. + */ + if (caps_avail_count >= caps_reserve_count + + ceph_client(cap->ci->vfs_inode.i_sb)->mount_args.max_readdir) { + caps_total_count--; + kmem_cache_free(ceph_cap_cachep, cap); + } else { + if (ctx) { + ctx->count++; + caps_reserve_count++; + } else { + caps_avail_count++; + } + list_add(&cap->caps_item, &caps_list); + } + + BUG_ON(caps_total_count != caps_use_count + caps_reserve_count + + caps_avail_count); + spin_unlock(&caps_list_lock); +} + +void ceph_reservation_status(struct ceph_client *client, + int *total, int *avail, int *used, int *reserved) +{ + if (total) + *total = caps_total_count; + if (avail) + *avail = caps_avail_count; + if (used) + *used = caps_use_count; + if (reserved) + *reserved = caps_reserve_count; +} + +/* + * Find ceph_cap for given mds, if any. + * + * Called with i_lock held. + */ +static struct ceph_cap *__get_cap_for_mds(struct ceph_inode_info *ci, int mds) +{ + struct ceph_cap *cap; + struct rb_node *n = ci->i_caps.rb_node; + + while (n) { + cap = rb_entry(n, struct ceph_cap, ci_node); + if (mds < cap->mds) + n = n->rb_left; + else if (mds > cap->mds) + n = n->rb_right; + else + return cap; + } + return NULL; +} + +/* + * Return id of any MDS with a cap, preferably FILE_WR|WRBUFFER|EXCL, else + * -1. + */ +static int __ceph_get_cap_mds(struct ceph_inode_info *ci, u32 *mseq) +{ + struct ceph_cap *cap; + int mds = -1; + struct rb_node *p; + + /* prefer mds with WR|WRBUFFER|EXCL caps */ + for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) { + cap = rb_entry(p, struct ceph_cap, ci_node); + mds = cap->mds; + if (mseq) + *mseq = cap->mseq; + if (cap->issued & (CEPH_CAP_FILE_WR | + CEPH_CAP_FILE_BUFFER | + CEPH_CAP_FILE_EXCL)) + break; + } + return mds; +} + +int ceph_get_cap_mds(struct inode *inode) +{ + int mds; + spin_lock(&inode->i_lock); + mds = __ceph_get_cap_mds(ceph_inode(inode), NULL); + spin_unlock(&inode->i_lock); + return mds; +} + +/* + * Called under i_lock. + */ +static void __insert_cap_node(struct ceph_inode_info *ci, + struct ceph_cap *new) +{ + struct rb_node **p = &ci->i_caps.rb_node; + struct rb_node *parent = NULL; + struct ceph_cap *cap = NULL; + + while (*p) { + parent = *p; + cap = rb_entry(parent, struct ceph_cap, ci_node); + if (new->mds < cap->mds) + p = &(*p)->rb_left; + else if (new->mds > cap->mds) + p = &(*p)->rb_right; + else + BUG(); + } + + rb_link_node(&new->ci_node, parent, p); + rb_insert_color(&new->ci_node, &ci->i_caps); +} + +/* + * (re)set cap hold timeouts, which control the delayed release + * of unused caps back to the MDS. Should be called on cap use. + */ +static void __cap_set_timeouts(struct ceph_mds_client *mdsc, + struct ceph_inode_info *ci) +{ + struct ceph_mount_args *ma = &mdsc->client->mount_args; + + ci->i_hold_caps_min = round_jiffies(jiffies + + ma->caps_wanted_delay_min * HZ); + ci->i_hold_caps_max = round_jiffies(jiffies + + ma->caps_wanted_delay_max * HZ); + dout("__cap_set_timeouts %p min %lu max %lu\n", &ci->vfs_inode, + ci->i_hold_caps_min - jiffies, ci->i_hold_caps_max - jiffies); +} + +/* + * (Re)queue cap at the end of the delayed cap release list. + * + * If I_FLUSH is set, leave the inode at the front of the list. + * + * Caller holds i_lock + * -> we take mdsc->cap_delay_lock + */ +static void __cap_delay_requeue(struct ceph_mds_client *mdsc, + struct ceph_inode_info *ci) +{ + __cap_set_timeouts(mdsc, ci); + dout("__cap_delay_requeue %p flags %d at %lu\n", &ci->vfs_inode, + ci->i_ceph_flags, ci->i_hold_caps_max); + if (!mdsc->stopping) { + spin_lock(&mdsc->cap_delay_lock); + if (!list_empty(&ci->i_cap_delay_list)) { + if (ci->i_ceph_flags & CEPH_I_FLUSH) + goto no_change; + list_del_init(&ci->i_cap_delay_list); + } + list_add_tail(&ci->i_cap_delay_list, &mdsc->cap_delay_list); +no_change: + spin_unlock(&mdsc->cap_delay_lock); + } +} + +/* + * Queue an inode for immediate writeback. Mark inode with I_FLUSH, + * indicating we should send a cap message to flush dirty metadata + * asap, and move to the front of the delayed cap list. + */ +static void __cap_delay_requeue_front(struct ceph_mds_client *mdsc, + struct ceph_inode_info *ci) +{ + dout("__cap_delay_requeue_front %p\n", &ci->vfs_inode); + spin_lock(&mdsc->cap_delay_lock); + ci->i_ceph_flags |= CEPH_I_FLUSH; + if (!list_empty(&ci->i_cap_delay_list)) + list_del_init(&ci->i_cap_delay_list); + list_add(&ci->i_cap_delay_list, &mdsc->cap_delay_list); + spin_unlock(&mdsc->cap_delay_lock); +} + +/* + * Cancel delayed work on cap. + * + * Caller must hold i_lock. + */ +static void __cap_delay_cancel(struct ceph_mds_client *mdsc, + struct ceph_inode_info *ci) +{ + dout("__cap_delay_cancel %p\n", &ci->vfs_inode); + if (list_empty(&ci->i_cap_delay_list)) + return; + spin_lock(&mdsc->cap_delay_lock); + list_del_init(&ci->i_cap_delay_list); + spin_unlock(&mdsc->cap_delay_lock); +} + +/* + * Common issue checks for add_cap, handle_cap_grant. + */ +static void __check_cap_issue(struct ceph_inode_info *ci, struct ceph_cap *cap, + unsigned issued) +{ + unsigned had = __ceph_caps_issued(ci, NULL); + + /* + * Each time we receive FILE_CACHE anew, we increment + * i_rdcache_gen. + */ + if ((issued & CEPH_CAP_FILE_CACHE) && + (had & CEPH_CAP_FILE_CACHE) == 0) + ci->i_rdcache_gen++; + + /* + * if we are newly issued FILE_SHARED, clear I_COMPLETE; we + * don't know what happened to this directory while we didn't + * have the cap. + */ + if ((issued & CEPH_CAP_FILE_SHARED) && + (had & CEPH_CAP_FILE_SHARED) == 0) { + ci->i_shared_gen++; + if (S_ISDIR(ci->vfs_inode.i_mode)) { + dout(" marking %p NOT complete\n", &ci->vfs_inode); + ci->i_ceph_flags &= ~CEPH_I_COMPLETE; + } + } +} + +/* + * Add a capability under the given MDS session. + * + * Caller should hold session snap_rwsem (read) and s_mutex. + * + * @fmode is the open file mode, if we are opening a file, otherwise + * it is < 0. (This is so we can atomically add the cap and add an + * open file reference to it.) + */ +int ceph_add_cap(struct inode *inode, + struct ceph_mds_session *session, u64 cap_id, + int fmode, unsigned issued, unsigned wanted, + unsigned seq, unsigned mseq, u64 realmino, int flags, + struct ceph_cap_reservation *caps_reservation) +{ + struct ceph_mds_client *mdsc = &ceph_inode_to_client(inode)->mdsc; + struct ceph_inode_info *ci = ceph_inode(inode); + struct ceph_cap *new_cap = NULL; + struct ceph_cap *cap; + int mds = session->s_mds; + int actual_wanted; + + dout("add_cap %p mds%d cap %llx %s seq %d\n", inode, + session->s_mds, cap_id, ceph_cap_string(issued), seq); + + /* + * If we are opening the file, include file mode wanted bits + * in wanted. + */ + if (fmode >= 0) + wanted |= ceph_caps_for_mode(fmode); + +retry: + spin_lock(&inode->i_lock); + cap = __get_cap_for_mds(ci, mds); + if (!cap) { + if (new_cap) { + cap = new_cap; + new_cap = NULL; + } else { + spin_unlock(&inode->i_lock); + new_cap = get_cap(caps_reservation); + if (new_cap == NULL) + return -ENOMEM; + goto retry; + } + + cap->issued = 0; + cap->implemented = 0; + cap->mds = mds; + cap->mds_wanted = 0; + + cap->ci = ci; + __insert_cap_node(ci, cap); + + /* clear out old exporting info? (i.e. on cap import) */ + if (ci->i_cap_exporting_mds == mds) { + ci->i_cap_exporting_issued = 0; + ci->i_cap_exporting_mseq = 0; + ci->i_cap_exporting_mds = -1; + } + + /* add to session cap list */ + cap->session = session; + spin_lock(&session->s_cap_lock); + list_add_tail(&cap->session_caps, &session->s_caps); + session->s_nr_caps++; + spin_unlock(&session->s_cap_lock); + } + + if (!ci->i_snap_realm) { + /* + * add this inode to the appropriate snap realm + */ + struct ceph_snap_realm *realm = ceph_lookup_snap_realm(mdsc, + realmino); + if (realm) { + ceph_get_snap_realm(mdsc, realm); + spin_lock(&realm->inodes_with_caps_lock); + ci->i_snap_realm = realm; + list_add(&ci->i_snap_realm_item, + &realm->inodes_with_caps); + spin_unlock(&realm->inodes_with_caps_lock); + } else { + pr_err("ceph_add_cap: couldn't find snap realm %llx\n", + realmino); + } + } + + __check_cap_issue(ci, cap, issued); + + /* + * If we are issued caps we don't want, or the mds' wanted + * value appears to be off, queue a check so we'll release + * later and/or update the mds wanted value. + */ + actual_wanted = __ceph_caps_wanted(ci); + if ((wanted & ~actual_wanted) || + (issued & ~actual_wanted & CEPH_CAP_ANY_WR)) { + dout(" issued %s, mds wanted %s, actual %s, queueing\n", + ceph_cap_string(issued), ceph_cap_string(wanted), + ceph_cap_string(actual_wanted)); + __cap_delay_requeue(mdsc, ci); + } + + if (flags & CEPH_CAP_FLAG_AUTH) + ci->i_auth_cap = cap; + else if (ci->i_auth_cap == cap) + ci->i_auth_cap = NULL; + + dout("add_cap inode %p (%llx.%llx) cap %p %s now %s seq %d mds%d\n", + inode, ceph_vinop(inode), cap, ceph_cap_string(issued), + ceph_cap_string(issued|cap->issued), seq, mds); + cap->cap_id = cap_id; + cap->issued = issued; + cap->implemented |= issued; + cap->mds_wanted |= wanted; + cap->seq = seq; + cap->issue_seq = seq; + cap->mseq = mseq; + cap->gen = session->s_cap_gen; + + if (fmode >= 0) + __ceph_get_fmode(ci, fmode); + spin_unlock(&inode->i_lock); + wake_up(&ci->i_cap_wq); + return 0; +} + +/* + * Return true if cap has not timed out and belongs to the current + * generation of the MDS session (i.e. has not gone 'stale' due to + * us losing touch with the mds). + */ +static int __cap_is_valid(struct ceph_cap *cap) +{ + unsigned long ttl; + u32 gen; + + spin_lock(&cap->session->s_cap_lock); + gen = cap->session->s_cap_gen; + ttl = cap->session->s_cap_ttl; + spin_unlock(&cap->session->s_cap_lock); + + if (cap->gen < gen || time_after_eq(jiffies, ttl)) { + dout("__cap_is_valid %p cap %p issued %s " + "but STALE (gen %u vs %u)\n", &cap->ci->vfs_inode, + cap, ceph_cap_string(cap->issued), cap->gen, gen); + return 0; + } + + return 1; +} + +/* + * Return set of valid cap bits issued to us. Note that caps time + * out, and may be invalidated in bulk if the client session times out + * and session->s_cap_gen is bumped. + */ +int __ceph_caps_issued(struct ceph_inode_info *ci, int *implemented) +{ + int have = ci->i_snap_caps; + struct ceph_cap *cap; + struct rb_node *p; + + if (implemented) + *implemented = 0; + for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) { + cap = rb_entry(p, struct ceph_cap, ci_node); + if (!__cap_is_valid(cap)) + continue; + dout("__ceph_caps_issued %p cap %p issued %s\n", + &ci->vfs_inode, cap, ceph_cap_string(cap->issued)); + have |= cap->issued; + if (implemented) + *implemented |= cap->implemented; + } + return have; +} + +/* + * Get cap bits issued by caps other than @ocap + */ +int __ceph_caps_issued_other(struct ceph_inode_info *ci, struct ceph_cap *ocap) +{ + int have = ci->i_snap_caps; + struct ceph_cap *cap; + struct rb_node *p; + + for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) { + cap = rb_entry(p, struct ceph_cap, ci_node); + if (cap == ocap) + continue; + if (!__cap_is_valid(cap)) + continue; + have |= cap->issued; + } + return have; +} + +/* + * Move a cap to the end of the LRU (oldest caps at list head, newest + * at list tail). + */ +static void __touch_cap(struct ceph_cap *cap) +{ + struct ceph_mds_session *s = cap->session; + + dout("__touch_cap %p cap %p mds%d\n", &cap->ci->vfs_inode, cap, + s->s_mds); + spin_lock(&s->s_cap_lock); + list_move_tail(&cap->session_caps, &s->s_caps); + spin_unlock(&s->s_cap_lock); +} + +/* + * Check if we hold the given mask. If so, move the cap(s) to the + * front of their respective LRUs. (This is the preferred way for + * callers to check for caps they want.) + */ +int __ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask, int touch) +{ + struct ceph_cap *cap; + struct rb_node *p; + int have = ci->i_snap_caps; + + if ((have & mask) == mask) { + dout("__ceph_caps_issued_mask %p snap issued %s" + " (mask %s)\n", &ci->vfs_inode, + ceph_cap_string(have), + ceph_cap_string(mask)); + return 1; + } + + for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) { + cap = rb_entry(p, struct ceph_cap, ci_node); + if (!__cap_is_valid(cap)) + continue; + if ((cap->issued & mask) == mask) { + dout("__ceph_caps_issued_mask %p cap %p issued %s" + " (mask %s)\n", &ci->vfs_inode, cap, + ceph_cap_string(cap->issued), + ceph_cap_string(mask)); + if (touch) + __touch_cap(cap); + return 1; + } + + /* does a combination of caps satisfy mask? */ + have |= cap->issued; + if ((have & mask) == mask) { + dout("__ceph_caps_issued_mask %p combo issued %s" + " (mask %s)\n", &ci->vfs_inode, + ceph_cap_string(cap->issued), + ceph_cap_string(mask)); + if (touch) { + struct rb_node *q; + + /* touch this + preceeding caps */ + __touch_cap(cap); + for (q = rb_first(&ci->i_caps); q != p; + q = rb_next(q)) { + cap = rb_entry(q, struct ceph_cap, + ci_node); + if (!__cap_is_valid(cap)) + continue; + __touch_cap(cap); + } + } + return 1; + } + } + + return 0; +} + +/* + * Return true if mask caps are currently being revoked by an MDS. + */ +int ceph_caps_revoking(struct ceph_inode_info *ci, int mask) +{ + struct inode *inode = &ci->vfs_inode; + struct ceph_cap *cap; + struct rb_node *p; + int ret = 0; + + spin_lock(&inode->i_lock); + for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) { + cap = rb_entry(p, struct ceph_cap, ci_node); + if (__cap_is_valid(cap) && + (cap->implemented & ~cap->issued & mask)) { + ret = 1; + break; + } + } + spin_unlock(&inode->i_lock); + dout("ceph_caps_revoking %p %s = %d\n", inode, + ceph_cap_string(mask), ret); + return ret; +} + +int __ceph_caps_used(struct ceph_inode_info *ci) +{ + int used = 0; + if (ci->i_pin_ref) + used |= CEPH_CAP_PIN; + if (ci->i_rd_ref) + used |= CEPH_CAP_FILE_RD; + if (ci->i_rdcache_ref || ci->i_rdcache_gen) + used |= CEPH_CAP_FILE_CACHE; + if (ci->i_wr_ref) + used |= CEPH_CAP_FILE_WR; + if (ci->i_wrbuffer_ref) + used |= CEPH_CAP_FILE_BUFFER; + return used; +} + +/* + * wanted, by virtue of open file modes + */ +int __ceph_caps_file_wanted(struct ceph_inode_info *ci) +{ + int want = 0; + int mode; + for (mode = 0; mode < 4; mode++) + if (ci->i_nr_by_mode[mode]) + want |= ceph_caps_for_mode(mode); + return want; +} + +/* + * Return caps we have registered with the MDS(s) as 'wanted'. + */ +int __ceph_caps_mds_wanted(struct ceph_inode_info *ci) +{ + struct ceph_cap *cap; + struct rb_node *p; + int mds_wanted = 0; + + for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) { + cap = rb_entry(p, struct ceph_cap, ci_node); + if (!__cap_is_valid(cap)) + continue; + mds_wanted |= cap->mds_wanted; + } + return mds_wanted; +} + +/* + * called under i_lock + */ +static int __ceph_is_any_caps(struct ceph_inode_info *ci) +{ + return !RB_EMPTY_ROOT(&ci->i_caps) || ci->i_cap_exporting_mds >= 0; +} + +/* + * caller should hold i_lock, and session s_mutex. + * returns true if this is the last cap. if so, caller should iput. + */ +void __ceph_remove_cap(struct ceph_cap *cap, + struct ceph_cap_reservation *ctx) +{ + struct ceph_mds_session *session = cap->session; + struct ceph_inode_info *ci = cap->ci; + struct ceph_mds_client *mdsc = &ceph_client(ci->vfs_inode.i_sb)->mdsc; + + dout("__ceph_remove_cap %p from %p\n", cap, &ci->vfs_inode); + + /* remove from session list */ + spin_lock(&session->s_cap_lock); + list_del_init(&cap->session_caps); + session->s_nr_caps--; + spin_unlock(&session->s_cap_lock); + + /* remove from inode list */ + rb_erase(&cap->ci_node, &ci->i_caps); + cap->session = NULL; + if (ci->i_auth_cap == cap) + ci->i_auth_cap = NULL; + + put_cap(cap, ctx); + + if (!__ceph_is_any_caps(ci) && ci->i_snap_realm) { + struct ceph_snap_realm *realm = ci->i_snap_realm; + spin_lock(&realm->inodes_with_caps_lock); + list_del_init(&ci->i_snap_realm_item); + ci->i_snap_realm_counter++; + ci->i_snap_realm = NULL; + spin_unlock(&realm->inodes_with_caps_lock); + ceph_put_snap_realm(mdsc, realm); + } + if (!__ceph_is_any_real_caps(ci)) + __cap_delay_cancel(mdsc, ci); +} + +/* + * Build and send a cap message to the given MDS. + * + * Caller should be holding s_mutex. + */ +static int send_cap_msg(struct ceph_mds_session *session, + u64 ino, u64 cid, int op, + int caps, int wanted, int dirty, + u32 seq, u64 flush_tid, u32 issue_seq, u32 mseq, + u64 size, u64 max_size, + struct timespec *mtime, struct timespec *atime, + u64 time_warp_seq, + uid_t uid, gid_t gid, mode_t mode, + u64 xattr_version, + struct ceph_buffer *xattrs_buf, + u64 follows) +{ + struct ceph_mds_caps *fc; + struct ceph_msg *msg; + + dout("send_cap_msg %s %llx %llx caps %s wanted %s dirty %s" + " seq %u/%u mseq %u follows %lld size %llu/%llu" + " xattr_ver %llu xattr_len %d\n", ceph_cap_op_name(op), + cid, ino, ceph_cap_string(caps), ceph_cap_string(wanted), + ceph_cap_string(dirty), + seq, issue_seq, mseq, follows, size, max_size, + xattr_version, xattrs_buf ? (int)xattrs_buf->vec.iov_len : 0); + + msg = ceph_msg_new(CEPH_MSG_CLIENT_CAPS, sizeof(*fc), 0, 0, NULL); + if (IS_ERR(msg)) + return PTR_ERR(msg); + + fc = msg->front.iov_base; + + memset(fc, 0, sizeof(*fc)); + + fc->cap_id = cpu_to_le64(cid); + fc->op = cpu_to_le32(op); + fc->seq = cpu_to_le32(seq); + fc->client_tid = cpu_to_le64(flush_tid); + fc->issue_seq = cpu_to_le32(issue_seq); + fc->migrate_seq = cpu_to_le32(mseq); + fc->caps = cpu_to_le32(caps); + fc->wanted = cpu_to_le32(wanted); + fc->dirty = cpu_to_le32(dirty); + fc->ino = cpu_to_le64(ino); + fc->snap_follows = cpu_to_le64(follows); + + fc->size = cpu_to_le64(size); + fc->max_size = cpu_to_le64(max_size); + if (mtime) + ceph_encode_timespec(&fc->mtime, mtime); + if (atime) + ceph_encode_timespec(&fc->atime, atime); + fc->time_warp_seq = cpu_to_le32(time_warp_seq); + + fc->uid = cpu_to_le32(uid); + fc->gid = cpu_to_le32(gid); + fc->mode = cpu_to_le32(mode); + + fc->xattr_version = cpu_to_le64(xattr_version); + if (xattrs_buf) { + msg->middle = ceph_buffer_get(xattrs_buf); + fc->xattr_len = cpu_to_le32(xattrs_buf->vec.iov_len); + msg->hdr.middle_len = cpu_to_le32(xattrs_buf->vec.iov_len); + } + + ceph_con_send(&session->s_con, msg); + return 0; +} + +/* + * Queue cap releases when an inode is dropped from our + * cache. + */ +void ceph_queue_caps_release(struct inode *inode) +{ + struct ceph_inode_info *ci = ceph_inode(inode); + struct rb_node *p; + + spin_lock(&inode->i_lock); + p = rb_first(&ci->i_caps); + while (p) { + struct ceph_cap *cap = rb_entry(p, struct ceph_cap, ci_node); + struct ceph_mds_session *session = cap->session; + struct ceph_msg *msg; + struct ceph_mds_cap_release *head; + struct ceph_mds_cap_item *item; + + spin_lock(&session->s_cap_lock); + BUG_ON(!session->s_num_cap_releases); + msg = list_first_entry(&session->s_cap_releases, + struct ceph_msg, list_head); + + dout(" adding %p release to mds%d msg %p (%d left)\n", + inode, session->s_mds, msg, session->s_num_cap_releases); + + BUG_ON(msg->front.iov_len + sizeof(*item) > PAGE_CACHE_SIZE); + head = msg->front.iov_base; + head->num = cpu_to_le32(le32_to_cpu(head->num) + 1); + item = msg->front.iov_base + msg->front.iov_len; + item->ino = cpu_to_le64(ceph_ino(inode)); + item->cap_id = cpu_to_le64(cap->cap_id); + item->migrate_seq = cpu_to_le32(cap->mseq); + item->seq = cpu_to_le32(cap->issue_seq); + + session->s_num_cap_releases--; + + msg->front.iov_len += sizeof(*item); + if (le32_to_cpu(head->num) == CEPH_CAPS_PER_RELEASE) { + dout(" release msg %p full\n", msg); + list_move_tail(&msg->list_head, + &session->s_cap_releases_done); + } else { + dout(" release msg %p at %d/%d (%d)\n", msg, + (int)le32_to_cpu(head->num), + (int)CEPH_CAPS_PER_RELEASE, + (int)msg->front.iov_len); + } + spin_unlock(&session->s_cap_lock); + p = rb_next(p); + __ceph_remove_cap(cap, NULL); + + } + spin_unlock(&inode->i_lock); +} + +/* + * Send a cap msg on the given inode. Update our caps state, then + * drop i_lock and send the message. + * + * Make note of max_size reported/requested from mds, revoked caps + * that have now been implemented. + * + * Make half-hearted attempt ot to invalidate page cache if we are + * dropping RDCACHE. Note that this will leave behind locked pages + * that we'll then need to deal with elsewhere. + * + * Return non-zero if delayed release, or we experienced an error + * such that the caller should requeue + retry later. + * + * called with i_lock, then drops it. + * caller should hold snap_rwsem (read), s_mutex. + */ +static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap, + int op, int used, int want, int retain, int flushing, + unsigned *pflush_tid) + __releases(cap->ci->vfs_inode->i_lock) +{ + struct ceph_inode_info *ci = cap->ci; + struct inode *inode = &ci->vfs_inode; + u64 cap_id = cap->cap_id; + int held = cap->issued | cap->implemented; + int revoking = cap->implemented & ~cap->issued; + int dropping = cap->issued & ~retain; + int keep; + u64 seq, issue_seq, mseq, time_warp_seq, follows; + u64 size, max_size; + struct timespec mtime, atime; + int wake = 0; + mode_t mode; + uid_t uid; + gid_t gid; + struct ceph_mds_session *session; + u64 xattr_version = 0; + int delayed = 0; + u64 flush_tid = 0; + int i; + int ret; + + dout("__send_cap %p cap %p session %p %s -> %s (revoking %s)\n", + inode, cap, cap->session, + ceph_cap_string(held), ceph_cap_string(held & retain), + ceph_cap_string(revoking)); + BUG_ON((retain & CEPH_CAP_PIN) == 0); + + session = cap->session; + + /* don't release wanted unless we've waited a bit. */ + if ((ci->i_ceph_flags & CEPH_I_NODELAY) == 0 && + time_before(jiffies, ci->i_hold_caps_min)) { + dout(" delaying issued %s -> %s, wanted %s -> %s on send\n", + ceph_cap_string(cap->issued), + ceph_cap_string(cap->issued & retain), + ceph_cap_string(cap->mds_wanted), + ceph_cap_string(want)); + want |= cap->mds_wanted; + retain |= cap->issued; + delayed = 1; + } + ci->i_ceph_flags &= ~(CEPH_I_NODELAY | CEPH_I_FLUSH); + + cap->issued &= retain; /* drop bits we don't want */ + if (cap->implemented & ~cap->issued) { + /* + * Wake up any waiters on wanted -> needed transition. + * This is due to the weird transition from buffered + * to sync IO... we need to flush dirty pages _before_ + * allowing sync writes to avoid reordering. + */ + wake = 1; + } + cap->implemented &= cap->issued | used; + cap->mds_wanted = want; + + if (flushing) { + /* + * assign a tid for flush operations so we can avoid + * flush1 -> dirty1 -> flush2 -> flushack1 -> mark + * clean type races. track latest tid for every bit + * so we can handle flush AxFw, flush Fw, and have the + * first ack clean Ax. + */ + flush_tid = ++ci->i_cap_flush_last_tid; + if (pflush_tid) + *pflush_tid = flush_tid; + dout(" cap_flush_tid %d\n", (int)flush_tid); + for (i = 0; i < CEPH_CAP_BITS; i++) + if (flushing & (1 << i)) + ci->i_cap_flush_tid[i] = flush_tid; + } + + keep = cap->implemented; + seq = cap->seq; + issue_seq = cap->issue_seq; + mseq = cap->mseq; + size = inode->i_size; + ci->i_reported_size = size; + max_size = ci->i_wanted_max_size; + ci->i_requested_max_size = max_size; + mtime = inode->i_mtime; + atime = inode->i_atime; + time_warp_seq = ci->i_time_warp_seq; + follows = ci->i_snap_realm->cached_context->seq; + uid = inode->i_uid; + gid = inode->i_gid; + mode = inode->i_mode; + + if (dropping & CEPH_CAP_XATTR_EXCL) { + __ceph_build_xattrs_blob(ci); + xattr_version = ci->i_xattrs.version + 1; + } + + spin_unlock(&inode->i_lock); + + if (dropping & CEPH_CAP_FILE_CACHE) { + /* invalidate what we can */ + dout("invalidating pages on %p\n", inode); + invalidate_mapping_pages(&inode->i_data, 0, -1); + } + + ret = send_cap_msg(session, ceph_vino(inode).ino, cap_id, + op, keep, want, flushing, seq, flush_tid, issue_seq, mseq, + size, max_size, &mtime, &atime, time_warp_seq, + uid, gid, mode, + xattr_version, + (flushing & CEPH_CAP_XATTR_EXCL) ? ci->i_xattrs.blob : NULL, + follows); + if (ret < 0) { + dout("error sending cap msg, must requeue %p\n", inode); + delayed = 1; + } + + if (wake) + wake_up(&ci->i_cap_wq); + + return delayed; +} + +/* + * When a snapshot is taken, clients accumulate dirty metadata on + * inodes with capabilities in ceph_cap_snaps to describe the file + * state at the time the snapshot was taken. This must be flushed + * asynchronously back to the MDS once sync writes complete and dirty + * data is written out. + * + * Called under i_lock. Takes s_mutex as needed. + */ +void __ceph_flush_snaps(struct ceph_inode_info *ci, + struct ceph_mds_session **psession) +{ + struct inode *inode = &ci->vfs_inode; + int mds; + struct ceph_cap_snap *capsnap; + u32 mseq; + struct ceph_mds_client *mdsc = &ceph_inode_to_client(inode)->mdsc; + struct ceph_mds_session *session = NULL; /* if session != NULL, we hold + session->s_mutex */ + u64 next_follows = 0; /* keep track of how far we've gotten through the + i_cap_snaps list, and skip these entries next time + around to avoid an infinite loop */ + + if (psession) + session = *psession; + + dout("__flush_snaps %p\n", inode); +retry: + list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) { + /* avoid an infiniute loop after retry */ + if (capsnap->follows < next_follows) + continue; + /* + * we need to wait for sync writes to complete and for dirty + * pages to be written out. + */ + if (capsnap->dirty_pages || capsnap->writing) + continue; + + /* pick mds, take s_mutex */ + mds = __ceph_get_cap_mds(ci, &mseq); + if (session && session->s_mds != mds) { + dout("oops, wrong session %p mutex\n", session); + mutex_unlock(&session->s_mutex); + ceph_put_mds_session(session); + session = NULL; + } + if (!session) { + spin_unlock(&inode->i_lock); + mutex_lock(&mdsc->mutex); + session = __ceph_lookup_mds_session(mdsc, mds); + mutex_unlock(&mdsc->mutex); + if (session) { + dout("inverting session/ino locks on %p\n", + session); + mutex_lock(&session->s_mutex); + } + /* + * if session == NULL, we raced against a cap + * deletion. retry, and we'll get a better + * @mds value next time. + */ + spin_lock(&inode->i_lock); + goto retry; + } + + capsnap->flush_tid = ++ci->i_cap_flush_last_tid; + atomic_inc(&capsnap->nref); + if (!list_empty(&capsnap->flushing_item)) + list_del_init(&capsnap->flushing_item); + list_add_tail(&capsnap->flushing_item, + &session->s_cap_snaps_flushing); + spin_unlock(&inode->i_lock); + + dout("flush_snaps %p cap_snap %p follows %lld size %llu\n", + inode, capsnap, next_follows, capsnap->size); + send_cap_msg(session, ceph_vino(inode).ino, 0, + CEPH_CAP_OP_FLUSHSNAP, capsnap->issued, 0, + capsnap->dirty, 0, capsnap->flush_tid, 0, mseq, + capsnap->size, 0, + &capsnap->mtime, &capsnap->atime, + capsnap->time_warp_seq, + capsnap->uid, capsnap->gid, capsnap->mode, + 0, NULL, + capsnap->follows); + + next_follows = capsnap->follows + 1; + ceph_put_cap_snap(capsnap); + + spin_lock(&inode->i_lock); + goto retry; + } + + /* we flushed them all; remove this inode from the queue */ + spin_lock(&mdsc->snap_flush_lock); + list_del_init(&ci->i_snap_flush_item); + spin_unlock(&mdsc->snap_flush_lock); + + if (psession) + *psession = session; + else if (session) { + mutex_unlock(&session->s_mutex); + ceph_put_mds_session(session); + } +} + +static void ceph_flush_snaps(struct ceph_inode_info *ci) +{ + struct inode *inode = &ci->vfs_inode; + + spin_lock(&inode->i_lock); + __ceph_flush_snaps(ci, NULL); + spin_unlock(&inode->i_lock); +} + +/* + * Add dirty inode to the flushing list. Assigned a seq number so we + * can wait for caps to flush without starving. + */ +static void __mark_caps_flushing(struct inode *inode, + struct ceph_mds_session *session) +{ + struct ceph_mds_client *mdsc = &ceph_client(inode->i_sb)->mdsc; + struct ceph_inode_info *ci = ceph_inode(inode); + + BUG_ON(list_empty(&ci->i_dirty_item)); + spin_lock(&mdsc->cap_dirty_lock); + if (list_empty(&ci->i_flushing_item)) { + list_add_tail(&ci->i_flushing_item, &session->s_cap_flushing); + mdsc->num_cap_flushing++; + ci->i_cap_flush_seq = ++mdsc->cap_flush_seq; + dout(" inode %p now flushing seq %lld\n", &ci->vfs_inode, + ci->i_cap_flush_seq); + } + spin_unlock(&mdsc->cap_dirty_lock); +} + +/* + * Swiss army knife function to examine currently used and wanted + * versus held caps. Release, flush, ack revoked caps to mds as + * appropriate. + * + * CHECK_CAPS_NODELAY - caller is delayed work and we should not delay + * cap release further. + * CHECK_CAPS_AUTHONLY - we should only check the auth cap + * CHECK_CAPS_FLUSH - we should flush any dirty caps immediately, without + * further delay. + */ +void ceph_check_caps(struct ceph_inode_info *ci, int flags, + struct ceph_mds_session *session) +{ + struct ceph_client *client = ceph_inode_to_client(&ci->vfs_inode); + struct ceph_mds_client *mdsc = &client->mdsc; + struct inode *inode = &ci->vfs_inode; + struct ceph_cap *cap; + int file_wanted, used; + int took_snap_rwsem = 0; /* true if mdsc->snap_rwsem held */ + int drop_session_lock = session ? 0 : 1; + int want, retain, revoking, flushing = 0; + int mds = -1; /* keep track of how far we've gone through i_caps list + to avoid an infinite loop on retry */ + struct rb_node *p; + int tried_invalidate = 0; + int delayed = 0, sent = 0, force_requeue = 0, num; + int is_delayed = flags & CHECK_CAPS_NODELAY; + + /* if we are unmounting, flush any unused caps immediately. */ + if (mdsc->stopping) + is_delayed = 1; + + spin_lock(&inode->i_lock); + + if (ci->i_ceph_flags & CEPH_I_FLUSH) + flags |= CHECK_CAPS_FLUSH; + + /* flush snaps first time around only */ + if (!list_empty(&ci->i_cap_snaps)) + __ceph_flush_snaps(ci, &session); + goto retry_locked; +retry: + spin_lock(&inode->i_lock); +retry_locked: + file_wanted = __ceph_caps_file_wanted(ci); + used = __ceph_caps_used(ci); + want = file_wanted | used; + + retain = want | CEPH_CAP_PIN; + if (!mdsc->stopping && inode->i_nlink > 0) { + if (want) { + retain |= CEPH_CAP_ANY; /* be greedy */ + } else { + retain |= CEPH_CAP_ANY_SHARED; + /* + * keep RD only if we didn't have the file open RW, + * because then the mds would revoke it anyway to + * journal max_size=0. + */ + if (ci->i_max_size == 0) + retain |= CEPH_CAP_ANY_RD; + } + } + + dout("check_caps %p file_want %s used %s dirty %s flushing %s" + " issued %s retain %s %s%s%s\n", inode, + ceph_cap_string(file_wanted), + ceph_cap_string(used), ceph_cap_string(ci->i_dirty_caps), + ceph_cap_string(ci->i_flushing_caps), + ceph_cap_string(__ceph_caps_issued(ci, NULL)), + ceph_cap_string(retain), + (flags & CHECK_CAPS_AUTHONLY) ? " AUTHONLY" : "", + (flags & CHECK_CAPS_NODELAY) ? " NODELAY" : "", + (flags & CHECK_CAPS_FLUSH) ? " FLUSH" : ""); + + /* + * If we no longer need to hold onto old our caps, and we may + * have cached pages, but don't want them, then try to invalidate. + * If we fail, it's because pages are locked.... try again later. + */ + if ((!is_delayed || mdsc->stopping) && + ci->i_wrbuffer_ref == 0 && /* no dirty pages... */ + ci->i_rdcache_gen && /* may have cached pages */ + file_wanted == 0 && /* no open files */ + !ci->i_truncate_pending && + !tried_invalidate) { + u32 invalidating_gen = ci->i_rdcache_gen; + int ret; + + dout("check_caps trying to invalidate on %p\n", inode); + spin_unlock(&inode->i_lock); + ret = invalidate_inode_pages2(&inode->i_data); + spin_lock(&inode->i_lock); + if (ret == 0 && invalidating_gen == ci->i_rdcache_gen) { + /* success. */ + ci->i_rdcache_gen = 0; + ci->i_rdcache_revoking = 0; + } else { + dout("check_caps failed to invalidate pages\n"); + /* we failed to invalidate pages. check these + caps again later. */ + force_requeue = 1; + __cap_set_timeouts(mdsc, ci); + } + tried_invalidate = 1; + goto retry_locked; + } + + num = 0; + for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) { + cap = rb_entry(p, struct ceph_cap, ci_node); + num++; + + /* avoid looping forever */ + if (mds >= cap->mds || + ((flags & CHECK_CAPS_AUTHONLY) && cap != ci->i_auth_cap)) + continue; + + /* NOTE: no side-effects allowed, until we take s_mutex */ + + revoking = cap->implemented & ~cap->issued; + if (revoking) + dout("mds%d revoking %s\n", cap->mds, + ceph_cap_string(revoking)); + + if (cap == ci->i_auth_cap && + (cap->issued & CEPH_CAP_FILE_WR)) { + /* request larger max_size from MDS? */ + if (ci->i_wanted_max_size > ci->i_max_size && + ci->i_wanted_max_size > ci->i_requested_max_size) { + dout("requesting new max_size\n"); + goto ack; + } + + /* approaching file_max? */ + if ((inode->i_size << 1) >= ci->i_max_size && + (ci->i_reported_size << 1) < ci->i_max_size) { + dout("i_size approaching max_size\n"); + goto ack; + } + } + /* flush anything dirty? */ + if (cap == ci->i_auth_cap && (flags & CHECK_CAPS_FLUSH) && + ci->i_dirty_caps) { + dout("flushing dirty caps\n"); + goto ack; + } + + /* completed revocation? going down and there are no caps? */ + if (revoking && (revoking & used) == 0) { + dout("completed revocation of %s\n", + ceph_cap_string(cap->implemented & ~cap->issued)); + goto ack; + } + + /* want more caps from mds? */ + if (want & ~(cap->mds_wanted | cap->issued)) + goto ack; + + /* things we might delay */ + if ((cap->issued & ~retain) == 0 && + cap->mds_wanted == want) + continue; /* nope, all good */ + + if (is_delayed) + goto ack; + + /* delay? */ + if ((ci->i_ceph_flags & CEPH_I_NODELAY) == 0 && + time_before(jiffies, ci->i_hold_caps_max)) { + dout(" delaying issued %s -> %s, wanted %s -> %s\n", + ceph_cap_string(cap->issued), + ceph_cap_string(cap->issued & retain), + ceph_cap_string(cap->mds_wanted), + ceph_cap_string(want)); + delayed++; + continue; + } + +ack: + if (session && session != cap->session) { + dout("oops, wrong session %p mutex\n", session); + mutex_unlock(&session->s_mutex); + session = NULL; + } + if (!session) { + session = cap->session; + if (mutex_trylock(&session->s_mutex) == 0) { + dout("inverting session/ino locks on %p\n", + session); + spin_unlock(&inode->i_lock); + if (took_snap_rwsem) { + up_read(&mdsc->snap_rwsem); + took_snap_rwsem = 0; + } + mutex_lock(&session->s_mutex); + goto retry; + } + } + /* take snap_rwsem after session mutex */ + if (!took_snap_rwsem) { + if (down_read_trylock(&mdsc->snap_rwsem) == 0) { + dout("inverting snap/in locks on %p\n", + inode); + spin_unlock(&inode->i_lock); + down_read(&mdsc->snap_rwsem); + took_snap_rwsem = 1; + goto retry; + } + took_snap_rwsem = 1; + } + + if (cap == ci->i_auth_cap && ci->i_dirty_caps) { + /* update dirty, flushing bits */ + flushing = ci->i_dirty_caps; + dout(" flushing %s, flushing_caps %s -> %s\n", + ceph_cap_string(flushing), + ceph_cap_string(ci->i_flushing_caps), + ceph_cap_string(ci->i_flushing_caps | flushing)); + ci->i_flushing_caps |= flushing; + ci->i_dirty_caps = 0; + __mark_caps_flushing(inode, session); + } + + mds = cap->mds; /* remember mds, so we don't repeat */ + sent++; + + /* __send_cap drops i_lock */ + delayed += __send_cap(mdsc, cap, CEPH_CAP_OP_UPDATE, used, want, + retain, flushing, NULL); + goto retry; /* retake i_lock and restart our cap scan. */ + } + + /* + * Reschedule delayed caps release if we delayed anything, + * otherwise cancel. + */ + if (delayed && is_delayed) + force_requeue = 1; /* __send_cap delayed release; requeue */ + if (!delayed && !is_delayed) + __cap_delay_cancel(mdsc, ci); + else if (!is_delayed || force_requeue) + __cap_delay_requeue(mdsc, ci); + + spin_unlock(&inode->i_lock); + + if (session && drop_session_lock) + mutex_unlock(&session->s_mutex); + if (took_snap_rwsem) + up_read(&mdsc->snap_rwsem); +} + +/* + * Mark caps dirty. If inode is newly dirty, add to the global dirty + * list. + */ +int __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask) +{ + struct ceph_mds_client *mdsc = &ceph_client(ci->vfs_inode.i_sb)->mdsc; + struct inode *inode = &ci->vfs_inode; + int was = __ceph_caps_dirty(ci); + int dirty = 0; + + dout("__mark_dirty_caps %p %s dirty %s -> %s\n", &ci->vfs_inode, + ceph_cap_string(mask), ceph_cap_string(ci->i_dirty_caps), + ceph_cap_string(ci->i_dirty_caps | mask)); + ci->i_dirty_caps |= mask; + if (!was) { + dout(" inode %p now dirty\n", &ci->vfs_inode); + spin_lock(&mdsc->cap_dirty_lock); + list_add(&ci->i_dirty_item, &mdsc->cap_dirty); + spin_unlock(&mdsc->cap_dirty_lock); + igrab(inode); + dirty |= I_DIRTY_SYNC; + } + if ((was & CEPH_CAP_FILE_BUFFER) && + (mask & CEPH_CAP_FILE_BUFFER)) + dirty |= I_DIRTY_DATASYNC; + if (dirty) + __mark_inode_dirty(inode, dirty); + __cap_delay_requeue(mdsc, ci); + return was; +} + +/* + * Try to flush dirty caps back to the auth mds. + */ +static int try_flush_caps(struct inode *inode, struct ceph_mds_session *session, + unsigned *flush_tid) +{ + struct ceph_mds_client *mdsc = &ceph_client(inode->i_sb)->mdsc; + struct ceph_inode_info *ci = ceph_inode(inode); + int unlock_session = session ? 0 : 1; + int flushing = 0; + +retry: + spin_lock(&inode->i_lock); + if (ci->i_dirty_caps && ci->i_auth_cap) { + struct ceph_cap *cap = ci->i_auth_cap; + int used = __ceph_caps_used(ci); + int want = __ceph_caps_wanted(ci); + int delayed; + + if (!session) { + spin_unlock(&inode->i_lock); + session = cap->session; + mutex_lock(&session->s_mutex); + goto retry; + } + BUG_ON(session != cap->session); + if (cap->session->s_state < CEPH_MDS_SESSION_OPEN) + goto out; + + __mark_caps_flushing(inode, session); + + flushing = ci->i_dirty_caps; + dout(" flushing %s, flushing_caps %s -> %s\n", + ceph_cap_string(flushing), + ceph_cap_string(ci->i_flushing_caps), + ceph_cap_string(ci->i_flushing_caps | flushing)); + ci->i_flushing_caps |= flushing; + ci->i_dirty_caps = 0; + + /* __send_cap drops i_lock */ + delayed = __send_cap(mdsc, cap, CEPH_CAP_OP_FLUSH, used, want, + cap->issued | cap->implemented, flushing, + flush_tid); + if (!delayed) + goto out_unlocked; + + spin_lock(&inode->i_lock); + __cap_delay_requeue(mdsc, ci); + } +out: + spin_unlock(&inode->i_lock); +out_unlocked: + if (session && unlock_session) + mutex_unlock(&session->s_mutex); + return flushing; +} + +/* + * Return true if we've flushed caps through the given flush_tid. + */ +static int caps_are_flushed(struct inode *inode, unsigned tid) +{ + struct ceph_inode_info *ci = ceph_inode(inode); + int dirty, i, ret = 1; + + spin_lock(&inode->i_lock); + dirty = __ceph_caps_dirty(ci); + for (i = 0; i < CEPH_CAP_BITS; i++) + if ((ci->i_flushing_caps & (1 << i)) && + ci->i_cap_flush_tid[i] <= tid) { + /* still flushing this bit */ + ret = 0; + break; + } + spin_unlock(&inode->i_lock); + return ret; +} + +/* + * Wait on any unsafe replies for the given inode. First wait on the + * newest request, and make that the upper bound. Then, if there are + * more requests, keep waiting on the oldest as long as it is still older + * than the original request. + */ +static void sync_write_wait(struct inode *inode) +{ + struct ceph_inode_info *ci = ceph_inode(inode); + struct list_head *head = &ci->i_unsafe_writes; + struct ceph_osd_request *req; + u64 last_tid; + + spin_lock(&ci->i_unsafe_lock); + if (list_empty(head)) + goto out; + + /* set upper bound as _last_ entry in chain */ + req = list_entry(head->prev, struct ceph_osd_request, + r_unsafe_item); + last_tid = req->r_tid; + + do { + ceph_osdc_get_request(req); + spin_unlock(&ci->i_unsafe_lock); + dout("sync_write_wait on tid %llu (until %llu)\n", + req->r_tid, last_tid); + wait_for_completion(&req->r_safe_completion); + spin_lock(&ci->i_unsafe_lock); + ceph_osdc_put_request(req); + + /* + * from here on look at first entry in chain, since we + * only want to wait for anything older than last_tid + */ + if (list_empty(head)) + break; + req = list_entry(head->next, struct ceph_osd_request, + r_unsafe_item); + } while (req->r_tid < last_tid); +out: + spin_unlock(&ci->i_unsafe_lock); +} + +int ceph_fsync(struct file *file, struct dentry *dentry, int datasync) +{ + struct inode *inode = dentry->d_inode; + struct ceph_inode_info *ci = ceph_inode(inode); + unsigned flush_tid; + int ret; + int dirty; + + dout("fsync %p%s\n", inode, datasync ? " datasync" : ""); + sync_write_wait(inode); + + ret = filemap_write_and_wait(inode->i_mapping); + if (ret < 0) + return ret; + + dirty = try_flush_caps(inode, NULL, &flush_tid); + dout("fsync dirty caps are %s\n", ceph_cap_string(dirty)); + + /* + * only wait on non-file metadata writeback (the mds + * can recover size and mtime, so we don't need to + * wait for that) + */ + if (!datasync && (dirty & ~CEPH_CAP_ANY_FILE_WR)) { + dout("fsync waiting for flush_tid %u\n", flush_tid); + ret = wait_event_interruptible(ci->i_cap_wq, + caps_are_flushed(inode, flush_tid)); + } + + dout("fsync %p%s done\n", inode, datasync ? " datasync" : ""); + return ret; +} + +/* + * Flush any dirty caps back to the mds. If we aren't asked to wait, + * queue inode for flush but don't do so immediately, because we can + * get by with fewer MDS messages if we wait for data writeback to + * complete first. + */ +int ceph_write_inode(struct inode *inode, int wait) +{ + struct ceph_inode_info *ci = ceph_inode(inode); + unsigned flush_tid; + int err = 0; + int dirty; + + dout("write_inode %p wait=%d\n", inode, wait); + if (wait) { + dirty = try_flush_caps(inode, NULL, &flush_tid); + if (dirty) + err = wait_event_interruptible(ci->i_cap_wq, + caps_are_flushed(inode, flush_tid)); + } else { + struct ceph_mds_client *mdsc = &ceph_client(inode->i_sb)->mdsc; + + spin_lock(&inode->i_lock); + if (__ceph_caps_dirty(ci)) + __cap_delay_requeue_front(mdsc, ci); + spin_unlock(&inode->i_lock); + } + return err; +} + +/* + * After a recovering MDS goes active, we need to resend any caps + * we were flushing. + * + * Caller holds session->s_mutex. + */ +static void kick_flushing_capsnaps(struct ceph_mds_client *mdsc, + struct ceph_mds_session *session) +{ + struct ceph_cap_snap *capsnap; + + dout("kick_flushing_capsnaps mds%d\n", session->s_mds); + list_for_each_entry(capsnap, &session->s_cap_snaps_flushing, + flushing_item) { + struct ceph_inode_info *ci = capsnap->ci; + struct inode *inode = &ci->vfs_inode; + struct ceph_cap *cap; + + spin_lock(&inode->i_lock); + cap = ci->i_auth_cap; + if (cap && cap->session == session) { + dout("kick_flushing_caps %p cap %p capsnap %p\n", inode, + cap, capsnap); + __ceph_flush_snaps(ci, &session); + } else { + pr_err("%p auth cap %p not mds%d ???\n", inode, + cap, session->s_mds); + spin_unlock(&inode->i_lock); + } + } +} + +void ceph_kick_flushing_caps(struct ceph_mds_client *mdsc, + struct ceph_mds_session *session) +{ + struct ceph_inode_info *ci; + + kick_flushing_capsnaps(mdsc, session); + + dout("kick_flushing_caps mds%d\n", session->s_mds); + list_for_each_entry(ci, &session->s_cap_flushing, i_flushing_item) { + struct inode *inode = &ci->vfs_inode; + struct ceph_cap *cap; + int delayed = 0; + + spin_lock(&inode->i_lock); + cap = ci->i_auth_cap; + if (cap && cap->session == session) { + dout("kick_flushing_caps %p cap %p %s\n", inode, + cap, ceph_cap_string(ci->i_flushing_caps)); + delayed = __send_cap(mdsc, cap, CEPH_CAP_OP_FLUSH, + __ceph_caps_used(ci), + __ceph_caps_wanted(ci), + cap->issued | cap->implemented, + ci->i_flushing_caps, NULL); + if (delayed) { + spin_lock(&inode->i_lock); + __cap_delay_requeue(mdsc, ci); + spin_unlock(&inode->i_lock); + } + } else { + pr_err("%p auth cap %p not mds%d ???\n", inode, + cap, session->s_mds); + spin_unlock(&inode->i_lock); + } + } +} + + +/* + * Take references to capabilities we hold, so that we don't release + * them to the MDS prematurely. + * + * Protected by i_lock. + */ +static void __take_cap_refs(struct ceph_inode_info *ci, int got) +{ + if (got & CEPH_CAP_PIN) + ci->i_pin_ref++; + if (got & CEPH_CAP_FILE_RD) + ci->i_rd_ref++; + if (got & CEPH_CAP_FILE_CACHE) + ci->i_rdcache_ref++; + if (got & CEPH_CAP_FILE_WR) + ci->i_wr_ref++; + if (got & CEPH_CAP_FILE_BUFFER) { + if (ci->i_wrbuffer_ref == 0) + igrab(&ci->vfs_inode); + ci->i_wrbuffer_ref++; + dout("__take_cap_refs %p wrbuffer %d -> %d (?)\n", + &ci->vfs_inode, ci->i_wrbuffer_ref-1, ci->i_wrbuffer_ref); + } +} + +/* + * Try to grab cap references. Specify those refs we @want, and the + * minimal set we @need. Also include the larger offset we are writing + * to (when applicable), and check against max_size here as well. + * Note that caller is responsible for ensuring max_size increases are + * requested from the MDS. + */ +static int try_get_cap_refs(struct ceph_inode_info *ci, int need, int want, + int *got, loff_t endoff, int *check_max, int *err) +{ + struct inode *inode = &ci->vfs_inode; + int ret = 0; + int have, implemented; + + dout("get_cap_refs %p need %s want %s\n", inode, + ceph_cap_string(need), ceph_cap_string(want)); + spin_lock(&inode->i_lock); + + /* make sure we _have_ some caps! */ + if (!__ceph_is_any_caps(ci)) { + dout("get_cap_refs %p no real caps\n", inode); + *err = -EBADF; + ret = 1; + goto out; + } + + if (need & CEPH_CAP_FILE_WR) { + if (endoff >= 0 && endoff > (loff_t)ci->i_max_size) { + dout("get_cap_refs %p endoff %llu > maxsize %llu\n", + inode, endoff, ci->i_max_size); + if (endoff > ci->i_wanted_max_size) { + *check_max = 1; + ret = 1; + } + goto out; + } + /* + * If a sync write is in progress, we must wait, so that we + * can get a final snapshot value for size+mtime. + */ + if (__ceph_have_pending_cap_snap(ci)) { + dout("get_cap_refs %p cap_snap_pending\n", inode); + goto out; + } + } + have = __ceph_caps_issued(ci, &implemented); + + /* + * disallow writes while a truncate is pending + */ + if (ci->i_truncate_pending) + have &= ~CEPH_CAP_FILE_WR; + + if ((have & need) == need) { + /* + * Look at (implemented & ~have & not) so that we keep waiting + * on transition from wanted -> needed caps. This is needed + * for WRBUFFER|WR -> WR to avoid a new WR sync write from + * going before a prior buffered writeback happens. + */ + int not = want & ~(have & need); + int revoking = implemented & ~have; + dout("get_cap_refs %p have %s but not %s (revoking %s)\n", + inode, ceph_cap_string(have), ceph_cap_string(not), + ceph_cap_string(revoking)); + if ((revoking & not) == 0) { + *got = need | (have & want); + __take_cap_refs(ci, *got); + ret = 1; + } + } else { + dout("get_cap_refs %p have %s needed %s\n", inode, + ceph_cap_string(have), ceph_cap_string(need)); + } +out: + spin_unlock(&inode->i_lock); + dout("get_cap_refs %p ret %d got %s\n", inode, + ret, ceph_cap_string(*got)); + return ret; +} + +/* + * Check the offset we are writing up to against our current + * max_size. If necessary, tell the MDS we want to write to + * a larger offset. + */ +static void check_max_size(struct inode *inode, loff_t endoff) +{ + struct ceph_inode_info *ci = ceph_inode(inode); + int check = 0; + + /* do we need to explicitly request a larger max_size? */ + spin_lock(&inode->i_lock); + if ((endoff >= ci->i_max_size || + endoff > (inode->i_size << 1)) && + endoff > ci->i_wanted_max_size) { + dout("write %p at large endoff %llu, req max_size\n", + inode, endoff); + ci->i_wanted_max_size = endoff; + check = 1; + } + spin_unlock(&inode->i_lock); + if (check) + ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL); +} + +/* + * Wait for caps, and take cap references. If we can't get a WR cap + * due to a small max_size, make sure we check_max_size (and possibly + * ask the mds) so we don't get hung up indefinitely. + */ +int ceph_get_caps(struct ceph_inode_info *ci, int need, int want, int *got, + loff_t endoff) +{ + int check_max, ret, err; + +retry: + if (endoff > 0) + check_max_size(&ci->vfs_inode, endoff); + check_max = 0; + err = 0; + ret = wait_event_interruptible(ci->i_cap_wq, + try_get_cap_refs(ci, need, want, + got, endoff, + &check_max, &err)); + if (err) + ret = err; + if (check_max) + goto retry; + return ret; +} + +/* + * Take cap refs. Caller must already know we hold at least one ref + * on the caps in question or we don't know this is safe. + */ +void ceph_get_cap_refs(struct ceph_inode_info *ci, int caps) +{ + spin_lock(&ci->vfs_inode.i_lock); + __take_cap_refs(ci, caps); + spin_unlock(&ci->vfs_inode.i_lock); +} + +/* + * Release cap refs. + * + * If we released the last ref on any given cap, call ceph_check_caps + * to release (or schedule a release). + * + * If we are releasing a WR cap (from a sync write), finalize any affected + * cap_snap, and wake up any waiters. + */ +void ceph_put_cap_refs(struct ceph_inode_info *ci, int had) +{ + struct inode *inode = &ci->vfs_inode; + int last = 0, put = 0, flushsnaps = 0, wake = 0; + struct ceph_cap_snap *capsnap; + + spin_lock(&inode->i_lock); + if (had & CEPH_CAP_PIN) + --ci->i_pin_ref; + if (had & CEPH_CAP_FILE_RD) + if (--ci->i_rd_ref == 0) + last++; + if (had & CEPH_CAP_FILE_CACHE) + if (--ci->i_rdcache_ref == 0) + last++; + if (had & CEPH_CAP_FILE_BUFFER) { + if (--ci->i_wrbuffer_ref == 0) { + last++; + put++; + } + dout("put_cap_refs %p wrbuffer %d -> %d (?)\n", + inode, ci->i_wrbuffer_ref+1, ci->i_wrbuffer_ref); + } + if (had & CEPH_CAP_FILE_WR) + if (--ci->i_wr_ref == 0) { + last++; + if (!list_empty(&ci->i_cap_snaps)) { + capsnap = list_first_entry(&ci->i_cap_snaps, + struct ceph_cap_snap, + ci_item); + if (capsnap->writing) { + capsnap->writing = 0; + flushsnaps = + __ceph_finish_cap_snap(ci, + capsnap); + wake = 1; + } + } + } + spin_unlock(&inode->i_lock); + + dout("put_cap_refs %p had %s %s\n", inode, ceph_cap_string(had), + last ? "last" : ""); + + if (last && !flushsnaps) + ceph_check_caps(ci, 0, NULL); + else if (flushsnaps) + ceph_flush_snaps(ci); + if (wake) + wake_up(&ci->i_cap_wq); + if (put) + iput(inode); +} + +/* + * Release @nr WRBUFFER refs on dirty pages for the given @snapc snap + * context. Adjust per-snap dirty page accounting as appropriate. + * Once all dirty data for a cap_snap is flushed, flush snapped file + * metadata back to the MDS. If we dropped the last ref, call + * ceph_check_caps. + */ +void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr, + struct ceph_snap_context *snapc) +{ + struct inode *inode = &ci->vfs_inode; + int last = 0; + int last_snap = 0; + int found = 0; + struct ceph_cap_snap *capsnap = NULL; + + spin_lock(&inode->i_lock); + ci->i_wrbuffer_ref -= nr; + last = !ci->i_wrbuffer_ref; + + if (ci->i_head_snapc == snapc) { + ci->i_wrbuffer_ref_head -= nr; + if (!ci->i_wrbuffer_ref_head) { + ceph_put_snap_context(ci->i_head_snapc); + ci->i_head_snapc = NULL; + } + dout("put_wrbuffer_cap_refs on %p head %d/%d -> %d/%d %s\n", + inode, + ci->i_wrbuffer_ref+nr, ci->i_wrbuffer_ref_head+nr, + ci->i_wrbuffer_ref, ci->i_wrbuffer_ref_head, + last ? " LAST" : ""); + } else { + list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) { + if (capsnap->context == snapc) { + found = 1; + capsnap->dirty_pages -= nr; + last_snap = !capsnap->dirty_pages; + break; + } + } + BUG_ON(!found); + dout("put_wrbuffer_cap_refs on %p cap_snap %p " + " snap %lld %d/%d -> %d/%d %s%s\n", + inode, capsnap, capsnap->context->seq, + ci->i_wrbuffer_ref+nr, capsnap->dirty_pages + nr, + ci->i_wrbuffer_ref, capsnap->dirty_pages, + last ? " (wrbuffer last)" : "", + last_snap ? " (capsnap last)" : ""); + } + + spin_unlock(&inode->i_lock); + + if (last) { + ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL); + iput(inode); + } else if (last_snap) { + ceph_flush_snaps(ci); + wake_up(&ci->i_cap_wq); + } +} + +/* + * Handle a cap GRANT message from the MDS. (Note that a GRANT may + * actually be a revocation if it specifies a smaller cap set.) + * + * caller holds s_mutex. + * return value: + * 0 - ok + * 1 - check_caps on auth cap only (writeback) + * 2 - check_caps (ack revoke) + */ +static int handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant, + struct ceph_mds_session *session, + struct ceph_cap *cap, + struct ceph_buffer *xattr_buf) + __releases(inode->i_lock) + +{ + struct ceph_inode_info *ci = ceph_inode(inode); + int mds = session->s_mds; + int seq = le32_to_cpu(grant->seq); + int newcaps = le32_to_cpu(grant->caps); + int issued, implemented, used, wanted, dirty; + u64 size = le64_to_cpu(grant->size); + u64 max_size = le64_to_cpu(grant->max_size); + struct timespec mtime, atime, ctime; + int reply = 0; + int wake = 0; + int writeback = 0; + int revoked_rdcache = 0; + int invalidate_async = 0; + int tried_invalidate = 0; + int ret; + + dout("handle_cap_grant inode %p cap %p mds%d seq %d %s\n", + inode, cap, mds, seq, ceph_cap_string(newcaps)); + dout(" size %llu max_size %llu, i_size %llu\n", size, max_size, + inode->i_size); + + /* + * If CACHE is being revoked, and we have no dirty buffers, + * try to invalidate (once). (If there are dirty buffers, we + * will invalidate _after_ writeback.) + */ +restart: + if (((cap->issued & ~newcaps) & CEPH_CAP_FILE_CACHE) && + !ci->i_wrbuffer_ref && !tried_invalidate) { + dout("CACHE invalidation\n"); + spin_unlock(&inode->i_lock); + tried_invalidate = 1; + + ret = invalidate_inode_pages2(&inode->i_data); + spin_lock(&inode->i_lock); + if (ret < 0) { + /* there were locked pages.. invalidate later + in a separate thread. */ + if (ci->i_rdcache_revoking != ci->i_rdcache_gen) { + invalidate_async = 1; + ci->i_rdcache_revoking = ci->i_rdcache_gen; + } + } else { + /* we successfully invalidated those pages */ + revoked_rdcache = 1; + ci->i_rdcache_gen = 0; + ci->i_rdcache_revoking = 0; + } + goto restart; + } + + /* side effects now are allowed */ + + issued = __ceph_caps_issued(ci, &implemented); + issued |= implemented | __ceph_caps_dirty(ci); + + cap->gen = session->s_cap_gen; + + __check_cap_issue(ci, cap, newcaps); + + if ((issued & CEPH_CAP_AUTH_EXCL) == 0) { + inode->i_mode = le32_to_cpu(grant->mode); + inode->i_uid = le32_to_cpu(grant->uid); + inode->i_gid = le32_to_cpu(grant->gid); + dout("%p mode 0%o uid.gid %d.%d\n", inode, inode->i_mode, + inode->i_uid, inode->i_gid); + } + + if ((issued & CEPH_CAP_LINK_EXCL) == 0) + inode->i_nlink = le32_to_cpu(grant->nlink); + + if ((issued & CEPH_CAP_XATTR_EXCL) == 0 && grant->xattr_len) { + int len = le32_to_cpu(grant->xattr_len); + u64 version = le64_to_cpu(grant->xattr_version); + + if (version > ci->i_xattrs.version) { + dout(" got new xattrs v%llu on %p len %d\n", + version, inode, len); + if (ci->i_xattrs.blob) + ceph_buffer_put(ci->i_xattrs.blob); + ci->i_xattrs.blob = ceph_buffer_get(xattr_buf); + ci->i_xattrs.version = version; + } + } + + /* size/ctime/mtime/atime? */ + ceph_fill_file_size(inode, issued, + le32_to_cpu(grant->truncate_seq), + le64_to_cpu(grant->truncate_size), size); + ceph_decode_timespec(&mtime, &grant->mtime); + ceph_decode_timespec(&atime, &grant->atime); + ceph_decode_timespec(&ctime, &grant->ctime); + ceph_fill_file_time(inode, issued, + le32_to_cpu(grant->time_warp_seq), &ctime, &mtime, + &atime); + + /* max size increase? */ + if (max_size != ci->i_max_size) { + dout("max_size %lld -> %llu\n", ci->i_max_size, max_size); + ci->i_max_size = max_size; + if (max_size >= ci->i_wanted_max_size) { + ci->i_wanted_max_size = 0; /* reset */ + ci->i_requested_max_size = 0; + } + wake = 1; + } + + /* check cap bits */ + wanted = __ceph_caps_wanted(ci); + used = __ceph_caps_used(ci); + dirty = __ceph_caps_dirty(ci); + dout(" my wanted = %s, used = %s, dirty %s\n", + ceph_cap_string(wanted), + ceph_cap_string(used), + ceph_cap_string(dirty)); + if (wanted != le32_to_cpu(grant->wanted)) { + dout("mds wanted %s -> %s\n", + ceph_cap_string(le32_to_cpu(grant->wanted)), + ceph_cap_string(wanted)); + grant->wanted = cpu_to_le32(wanted); + } + + cap->seq = seq; + + /* file layout may have changed */ + ci->i_layout = grant->layout; + + /* revocation, grant, or no-op? */ + if (cap->issued & ~newcaps) { + dout("revocation: %s -> %s\n", ceph_cap_string(cap->issued), + ceph_cap_string(newcaps)); + if ((used & ~newcaps) & CEPH_CAP_FILE_BUFFER) + writeback = 1; /* will delay ack */ + else if (dirty & ~newcaps) + reply = 1; /* initiate writeback in check_caps */ + else if (((used & ~newcaps) & CEPH_CAP_FILE_CACHE) == 0 || + revoked_rdcache) + reply = 2; /* send revoke ack in check_caps */ + cap->issued = newcaps; + } else if (cap->issued == newcaps) { + dout("caps unchanged: %s -> %s\n", + ceph_cap_string(cap->issued), ceph_cap_string(newcaps)); + } else { + dout("grant: %s -> %s\n", ceph_cap_string(cap->issued), + ceph_cap_string(newcaps)); + cap->issued = newcaps; + cap->implemented |= newcaps; /* add bits only, to + * avoid stepping on a + * pending revocation */ + wake = 1; + } + + spin_unlock(&inode->i_lock); + if (writeback) { + /* + * queue inode for writeback: we can't actually call + * filemap_write_and_wait, etc. from message handler + * context. + */ + dout("queueing %p for writeback\n", inode); + if (ceph_queue_writeback(inode)) + igrab(inode); + } + if (invalidate_async) { + dout("queueing %p for page invalidation\n", inode); + if (ceph_queue_page_invalidation(inode)) + igrab(inode); + } + if (wake) + wake_up(&ci->i_cap_wq); + return reply; +} + +/* + * Handle FLUSH_ACK from MDS, indicating that metadata we sent to the + * MDS has been safely committed. + */ +static void handle_cap_flush_ack(struct inode *inode, + struct ceph_mds_caps *m, + struct ceph_mds_session *session, + struct ceph_cap *cap) + __releases(inode->i_lock) +{ + struct ceph_inode_info *ci = ceph_inode(inode); + struct ceph_mds_client *mdsc = &ceph_client(inode->i_sb)->mdsc; + unsigned seq = le32_to_cpu(m->seq); + int dirty = le32_to_cpu(m->dirty); + int cleaned = 0; + u64 flush_tid = le64_to_cpu(m->client_tid); + int old_dirty = 0, new_dirty = 0; + int i; + + for (i = 0; i < CEPH_CAP_BITS; i++) + if ((dirty & (1 << i)) && + flush_tid == ci->i_cap_flush_tid[i]) + cleaned |= 1 << i; + + dout("handle_cap_flush_ack inode %p mds%d seq %d on %s cleaned %s," + " flushing %s -> %s\n", + inode, session->s_mds, seq, ceph_cap_string(dirty), + ceph_cap_string(cleaned), ceph_cap_string(ci->i_flushing_caps), + ceph_cap_string(ci->i_flushing_caps & ~cleaned)); + + if (ci->i_flushing_caps == (ci->i_flushing_caps & ~cleaned)) + goto out; + + old_dirty = ci->i_dirty_caps | ci->i_flushing_caps; + ci->i_flushing_caps &= ~cleaned; + new_dirty = ci->i_dirty_caps | ci->i_flushing_caps; + + spin_lock(&mdsc->cap_dirty_lock); + if (ci->i_flushing_caps == 0) { + list_del_init(&ci->i_flushing_item); + if (!list_empty(&session->s_cap_flushing)) + dout(" mds%d still flushing cap on %p\n", + session->s_mds, + &list_entry(session->s_cap_flushing.next, + struct ceph_inode_info, + i_flushing_item)->vfs_inode); + mdsc->num_cap_flushing--; + wake_up(&mdsc->cap_flushing_wq); + dout(" inode %p now !flushing\n", inode); + } + if (old_dirty && !new_dirty) { + dout(" inode %p now clean\n", inode); + list_del_init(&ci->i_dirty_item); + } + spin_unlock(&mdsc->cap_dirty_lock); + wake_up(&ci->i_cap_wq); + +out: + spin_unlock(&inode->i_lock); + if (old_dirty && !new_dirty) + iput(inode); +} + +/* + * Handle FLUSHSNAP_ACK. MDS has flushed snap data to disk and we can + * throw away our cap_snap. + * + * Caller hold s_mutex. + */ +static void handle_cap_flushsnap_ack(struct inode *inode, + struct ceph_mds_caps *m, + struct ceph_mds_session *session) +{ + struct ceph_inode_info *ci = ceph_inode(inode); + u64 follows = le64_to_cpu(m->snap_follows); + u64 flush_tid = le64_to_cpu(m->client_tid); + struct ceph_cap_snap *capsnap; + int drop = 0; + + dout("handle_cap_flushsnap_ack inode %p ci %p mds%d follows %lld\n", + inode, ci, session->s_mds, follows); + + spin_lock(&inode->i_lock); + list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) { + if (capsnap->follows == follows) { + if (capsnap->flush_tid != flush_tid) { + dout(" cap_snap %p follows %lld tid %lld !=" + " %lld\n", capsnap, follows, + flush_tid, capsnap->flush_tid); + break; + } + WARN_ON(capsnap->dirty_pages || capsnap->writing); + dout(" removing cap_snap %p follows %lld\n", + capsnap, follows); + ceph_put_snap_context(capsnap->context); + list_del(&capsnap->ci_item); + list_del(&capsnap->flushing_item); + ceph_put_cap_snap(capsnap); + drop = 1; + break; + } else { + dout(" skipping cap_snap %p follows %lld\n", + capsnap, capsnap->follows); + } + } + spin_unlock(&inode->i_lock); + if (drop) + iput(inode); +} + +/* + * Handle TRUNC from MDS, indicating file truncation. + * + * caller hold s_mutex. + */ +static void handle_cap_trunc(struct inode *inode, + struct ceph_mds_caps *trunc, + struct ceph_mds_session *session) + __releases(inode->i_lock) +{ + struct ceph_inode_info *ci = ceph_inode(inode); + int mds = session->s_mds; + int seq = le32_to_cpu(trunc->seq); + u32 truncate_seq = le32_to_cpu(trunc->truncate_seq); + u64 truncate_size = le64_to_cpu(trunc->truncate_size); + u64 size = le64_to_cpu(trunc->size); + int implemented = 0; + int dirty = __ceph_caps_dirty(ci); + int issued = __ceph_caps_issued(ceph_inode(inode), &implemented); + int queue_trunc = 0; + + issued |= implemented | dirty; + + dout("handle_cap_trunc inode %p mds%d seq %d to %lld seq %d\n", + inode, mds, seq, truncate_size, truncate_seq); + queue_trunc = ceph_fill_file_size(inode, issued, + truncate_seq, truncate_size, size); + spin_unlock(&inode->i_lock); + + if (queue_trunc) + if (queue_work(ceph_client(inode->i_sb)->trunc_wq, + &ci->i_vmtruncate_work)) + igrab(inode); +} + +/* + * Handle EXPORT from MDS. Cap is being migrated _from_ this mds to a + * different one. If we are the most recent migration we've seen (as + * indicated by mseq), make note of the migrating cap bits for the + * duration (until we see the corresponding IMPORT). + * + * caller holds s_mutex + */ +static void handle_cap_export(struct inode *inode, struct ceph_mds_caps *ex, + struct ceph_mds_session *session) +{ + struct ceph_inode_info *ci = ceph_inode(inode); + int mds = session->s_mds; + unsigned mseq = le32_to_cpu(ex->migrate_seq); + struct ceph_cap *cap = NULL, *t; + struct rb_node *p; + int remember = 1; + + dout("handle_cap_export inode %p ci %p mds%d mseq %d\n", + inode, ci, mds, mseq); + + spin_lock(&inode->i_lock); + + /* make sure we haven't seen a higher mseq */ + for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) { + t = rb_entry(p, struct ceph_cap, ci_node); + if (ceph_seq_cmp(t->mseq, mseq) > 0) { + dout(" higher mseq on cap from mds%d\n", + t->session->s_mds); + remember = 0; + } + if (t->session->s_mds == mds) + cap = t; + } + + if (cap) { + if (remember) { + /* make note */ + ci->i_cap_exporting_mds = mds; + ci->i_cap_exporting_mseq = mseq; + ci->i_cap_exporting_issued = cap->issued; + } + __ceph_remove_cap(cap, NULL); + } else { + WARN_ON(!cap); + } + + spin_unlock(&inode->i_lock); +} + +/* + * Handle cap IMPORT. If there are temp bits from an older EXPORT, + * clean them up. + * + * caller holds s_mutex. + */ +static void handle_cap_import(struct ceph_mds_client *mdsc, + struct inode *inode, struct ceph_mds_caps *im, + struct ceph_mds_session *session, + void *snaptrace, int snaptrace_len) +{ + struct ceph_inode_info *ci = ceph_inode(inode); + int mds = session->s_mds; + unsigned issued = le32_to_cpu(im->caps); + unsigned wanted = le32_to_cpu(im->wanted); + unsigned seq = le32_to_cpu(im->seq); + unsigned mseq = le32_to_cpu(im->migrate_seq); + u64 realmino = le64_to_cpu(im->realm); + u64 cap_id = le64_to_cpu(im->cap_id); + + if (ci->i_cap_exporting_mds >= 0 && + ceph_seq_cmp(ci->i_cap_exporting_mseq, mseq) < 0) { + dout("handle_cap_import inode %p ci %p mds%d mseq %d" + " - cleared exporting from mds%d\n", + inode, ci, mds, mseq, + ci->i_cap_exporting_mds); + ci->i_cap_exporting_issued = 0; + ci->i_cap_exporting_mseq = 0; + ci->i_cap_exporting_mds = -1; + } else { + dout("handle_cap_import inode %p ci %p mds%d mseq %d\n", + inode, ci, mds, mseq); + } + + down_write(&mdsc->snap_rwsem); + ceph_update_snap_trace(mdsc, snaptrace, snaptrace+snaptrace_len, + false); + downgrade_write(&mdsc->snap_rwsem); + ceph_add_cap(inode, session, cap_id, -1, + issued, wanted, seq, mseq, realmino, CEPH_CAP_FLAG_AUTH, + NULL /* no caps context */); + try_flush_caps(inode, session, NULL); + up_read(&mdsc->snap_rwsem); +} + +/* + * Handle a caps message from the MDS. + * + * Identify the appropriate session, inode, and call the right handler + * based on the cap op. + */ +void ceph_handle_caps(struct ceph_mds_session *session, + struct ceph_msg *msg) +{ + struct ceph_mds_client *mdsc = session->s_mdsc; + struct super_block *sb = mdsc->client->sb; + struct inode *inode; + struct ceph_cap *cap; + struct ceph_mds_caps *h; + int mds = le64_to_cpu(msg->hdr.src.name.num); + int op; + u32 seq; + struct ceph_vino vino; + u64 cap_id; + u64 size, max_size; + int check_caps = 0; + int r; + + dout("handle_caps from mds%d\n", mds); + + /* decode */ + if (msg->front.iov_len < sizeof(*h)) + goto bad; + h = msg->front.iov_base; + op = le32_to_cpu(h->op); + vino.ino = le64_to_cpu(h->ino); + vino.snap = CEPH_NOSNAP; + cap_id = le64_to_cpu(h->cap_id); + seq = le32_to_cpu(h->seq); + size = le64_to_cpu(h->size); + max_size = le64_to_cpu(h->max_size); + + mutex_lock(&session->s_mutex); + session->s_seq++; + dout(" mds%d seq %lld cap seq %u\n", session->s_mds, session->s_seq, + (unsigned)seq); + + /* lookup ino */ + inode = ceph_find_inode(sb, vino); + dout(" op %s ino %llx.%llx inode %p\n", ceph_cap_op_name(op), vino.ino, + vino.snap, inode); + if (!inode) { + dout(" i don't have ino %llx\n", vino.ino); + goto done; + } + + /* these will work even if we don't have a cap yet */ + switch (op) { + case CEPH_CAP_OP_FLUSHSNAP_ACK: + handle_cap_flushsnap_ack(inode, h, session); + goto done; + + case CEPH_CAP_OP_EXPORT: + handle_cap_export(inode, h, session); + goto done; + + case CEPH_CAP_OP_IMPORT: + handle_cap_import(mdsc, inode, h, session, + msg->middle, + le32_to_cpu(h->snap_trace_len)); + check_caps = 1; /* we may have sent a RELEASE to the old auth */ + goto done; + } + + /* the rest require a cap */ + spin_lock(&inode->i_lock); + cap = __get_cap_for_mds(ceph_inode(inode), mds); + if (!cap) { + dout("no cap on %p ino %llx.%llx from mds%d, releasing\n", + inode, ceph_ino(inode), ceph_snap(inode), mds); + spin_unlock(&inode->i_lock); + goto done; + } + + /* note that each of these drops i_lock for us */ + switch (op) { + case CEPH_CAP_OP_REVOKE: + case CEPH_CAP_OP_GRANT: + r = handle_cap_grant(inode, h, session, cap, msg->middle); + if (r == 1) + ceph_check_caps(ceph_inode(inode), + CHECK_CAPS_NODELAY|CHECK_CAPS_AUTHONLY, + session); + else if (r == 2) + ceph_check_caps(ceph_inode(inode), + CHECK_CAPS_NODELAY, + session); + break; + + case CEPH_CAP_OP_FLUSH_ACK: + handle_cap_flush_ack(inode, h, session, cap); + break; + + case CEPH_CAP_OP_TRUNC: + handle_cap_trunc(inode, h, session); + break; + + default: + spin_unlock(&inode->i_lock); + pr_err("ceph_handle_caps: unknown cap op %d %s\n", op, + ceph_cap_op_name(op)); + } + +done: + mutex_unlock(&session->s_mutex); + + if (check_caps) + ceph_check_caps(ceph_inode(inode), CHECK_CAPS_NODELAY, NULL); + if (inode) + iput(inode); + return; + +bad: + pr_err("ceph_handle_caps: corrupt message\n"); + return; +} + +/* + * Delayed work handler to process end of delayed cap release LRU list. + */ +void ceph_check_delayed_caps(struct ceph_mds_client *mdsc, int flushdirty) +{ + struct ceph_inode_info *ci; + int flags = CHECK_CAPS_NODELAY; + + if (flushdirty) + flags |= CHECK_CAPS_FLUSH; + + dout("check_delayed_caps\n"); + while (1) { + spin_lock(&mdsc->cap_delay_lock); + if (list_empty(&mdsc->cap_delay_list)) + break; + ci = list_first_entry(&mdsc->cap_delay_list, + struct ceph_inode_info, + i_cap_delay_list); + if ((ci->i_ceph_flags & CEPH_I_FLUSH) == 0 && + time_before(jiffies, ci->i_hold_caps_max)) + break; + list_del_init(&ci->i_cap_delay_list); + spin_unlock(&mdsc->cap_delay_lock); + dout("check_delayed_caps on %p\n", &ci->vfs_inode); + ceph_check_caps(ci, flags, NULL); + } + spin_unlock(&mdsc->cap_delay_lock); +} + +/* + * Drop open file reference. If we were the last open file, + * we may need to release capabilities to the MDS (or schedule + * their delayed release). + */ +void ceph_put_fmode(struct ceph_inode_info *ci, int fmode) +{ + struct inode *inode = &ci->vfs_inode; + int last = 0; + + spin_lock(&inode->i_lock); + dout("put_fmode %p fmode %d %d -> %d\n", inode, fmode, + ci->i_nr_by_mode[fmode], ci->i_nr_by_mode[fmode]-1); + BUG_ON(ci->i_nr_by_mode[fmode] == 0); + if (--ci->i_nr_by_mode[fmode] == 0) + last++; + spin_unlock(&inode->i_lock); + + if (last && ci->i_vino.snap == CEPH_NOSNAP) + ceph_check_caps(ci, 0, NULL); +} + +/* + * Helpers for embedding cap and dentry lease releases into mds + * requests. + * + * @force is used by dentry_release (below) to force inclusion of a + * record for the directory inode, even when there aren't any caps to + * drop. + */ +int ceph_encode_inode_release(void **p, struct inode *inode, + int mds, int drop, int unless, int force) +{ + struct ceph_inode_info *ci = ceph_inode(inode); + struct ceph_cap *cap; + struct ceph_mds_request_release *rel = *p; + int ret = 0; + + dout("encode_inode_release %p mds%d drop %s unless %s\n", inode, + mds, ceph_cap_string(drop), ceph_cap_string(unless)); + + spin_lock(&inode->i_lock); + cap = __get_cap_for_mds(ci, mds); + if (cap && __cap_is_valid(cap)) { + if (force || + ((cap->issued & drop) && + (cap->issued & unless) == 0)) { + if ((cap->issued & drop) && + (cap->issued & unless) == 0) { + dout("encode_inode_release %p cap %p %s -> " + "%s\n", inode, cap, + ceph_cap_string(cap->issued), + ceph_cap_string(cap->issued & ~drop)); + cap->issued &= ~drop; + cap->implemented &= ~drop; + if (ci->i_ceph_flags & CEPH_I_NODELAY) { + int wanted = __ceph_caps_wanted(ci); + dout(" wanted %s -> %s (act %s)\n", + ceph_cap_string(cap->mds_wanted), + ceph_cap_string(cap->mds_wanted & + ~wanted), + ceph_cap_string(wanted)); + cap->mds_wanted &= wanted; + } + } else { + dout("encode_inode_release %p cap %p %s" + " (force)\n", inode, cap, + ceph_cap_string(cap->issued)); + } + + rel->ino = cpu_to_le64(ceph_ino(inode)); + rel->cap_id = cpu_to_le64(cap->cap_id); + rel->seq = cpu_to_le32(cap->seq); + rel->issue_seq = cpu_to_le32(cap->issue_seq), + rel->mseq = cpu_to_le32(cap->mseq); + rel->caps = cpu_to_le32(cap->issued); + rel->wanted = cpu_to_le32(cap->mds_wanted); + rel->dname_len = 0; + rel->dname_seq = 0; + *p += sizeof(*rel); + ret = 1; + } else { + dout("encode_inode_release %p cap %p %s\n", + inode, cap, ceph_cap_string(cap->issued)); + } + } + spin_unlock(&inode->i_lock); + return ret; +} + +int ceph_encode_dentry_release(void **p, struct dentry *dentry, + int mds, int drop, int unless) +{ + struct inode *dir = dentry->d_parent->d_inode; + struct ceph_mds_request_release *rel = *p; + struct ceph_dentry_info *di = ceph_dentry(dentry); + int force = 0; + int ret; + + /* + * force an record for the directory caps if we have a dentry lease. + * this is racy (can't take i_lock and d_lock together), but it + * doesn't have to be perfect; the mds will revoke anything we don't + * release. + */ + spin_lock(&dentry->d_lock); + if (di->lease_session && di->lease_session->s_mds == mds) + force = 1; + spin_unlock(&dentry->d_lock); + + ret = ceph_encode_inode_release(p, dir, mds, drop, unless, force); + + spin_lock(&dentry->d_lock); + if (ret && di->lease_session && di->lease_session->s_mds == mds) { + dout("encode_dentry_release %p mds%d seq %d\n", + dentry, mds, (int)di->lease_seq); + rel->dname_len = cpu_to_le32(dentry->d_name.len); + memcpy(*p, dentry->d_name.name, dentry->d_name.len); + *p += dentry->d_name.len; + rel->dname_seq = cpu_to_le32(di->lease_seq); + } + spin_unlock(&dentry->d_lock); + return ret; +} -- cgit v0.10.2 From 963b61eb041e8850807d95f8d7a4c6a454c45000 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 6 Oct 2009 11:31:12 -0700 Subject: ceph: snapshot management Ceph snapshots rely on client cooperation in determining which operations apply to which snapshots, and appropriately flushing snapshotted data and metadata back to the OSD and MDS clusters. Because snapshots apply to subtrees of the file hierarchy and can be created at any time, there is a fair bit of bookkeeping required to make this work. Portions of the hierarchy that belong to the same set of snapshots are described by a single 'snap realm.' A 'snap context' describes the set of snapshots that exist for a given file or directory. Signed-off-by: Sage Weil diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c new file mode 100644 index 0000000..2e3cb40 --- /dev/null +++ b/fs/ceph/snap.c @@ -0,0 +1,897 @@ +#include "ceph_debug.h" + +#include +#include + +#include "super.h" +#include "decode.h" + +/* + * Snapshots in ceph are driven in large part by cooperation from the + * client. In contrast to local file systems or file servers that + * implement snapshots at a single point in the system, ceph's + * distributed access to storage requires clients to help decide + * whether a write logically occurs before or after a recently created + * snapshot. + * + * This provides a perfect instantanous client-wide snapshot. Between + * clients, however, snapshots may appear to be applied at slightly + * different points in time, depending on delays in delivering the + * snapshot notification. + * + * Snapshots are _not_ file system-wide. Instead, each snapshot + * applies to the subdirectory nested beneath some directory. This + * effectively divides the hierarchy into multiple "realms," where all + * of the files contained by each realm share the same set of + * snapshots. An individual realm's snap set contains snapshots + * explicitly created on that realm, as well as any snaps in its + * parent's snap set _after_ the point at which the parent became it's + * parent (due to, say, a rename). Similarly, snaps from prior parents + * during the time intervals during which they were the parent are included. + * + * The client is spared most of this detail, fortunately... it must only + * maintains a hierarchy of realms reflecting the current parent/child + * realm relationship, and for each realm has an explicit list of snaps + * inherited from prior parents. + * + * A snap_realm struct is maintained for realms containing every inode + * with an open cap in the system. (The needed snap realm information is + * provided by the MDS whenever a cap is issued, i.e., on open.) A 'seq' + * version number is used to ensure that as realm parameters change (new + * snapshot, new parent, etc.) the client's realm hierarchy is updated. + * + * The realm hierarchy drives the generation of a 'snap context' for each + * realm, which simply lists the resulting set of snaps for the realm. This + * is attached to any writes sent to OSDs. + */ +/* + * Unfortunately error handling is a bit mixed here. If we get a snap + * update, but don't have enough memory to update our realm hierarchy, + * it's not clear what we can do about it (besides complaining to the + * console). + */ + + +/* + * increase ref count for the realm + * + * caller must hold snap_rwsem for write. + */ +void ceph_get_snap_realm(struct ceph_mds_client *mdsc, + struct ceph_snap_realm *realm) +{ + dout("get_realm %p %d -> %d\n", realm, + atomic_read(&realm->nref), atomic_read(&realm->nref)+1); + /* + * since we _only_ increment realm refs or empty the empty + * list with snap_rwsem held, adjusting the empty list here is + * safe. we do need to protect against concurrent empty list + * additions, however. + */ + if (atomic_read(&realm->nref) == 0) { + spin_lock(&mdsc->snap_empty_lock); + list_del_init(&realm->empty_item); + spin_unlock(&mdsc->snap_empty_lock); + } + + atomic_inc(&realm->nref); +} + +/* + * create and get the realm rooted at @ino and bump its ref count. + * + * caller must hold snap_rwsem for write. + */ +static struct ceph_snap_realm *ceph_create_snap_realm( + struct ceph_mds_client *mdsc, + u64 ino) +{ + struct ceph_snap_realm *realm; + + realm = kzalloc(sizeof(*realm), GFP_NOFS); + if (!realm) + return ERR_PTR(-ENOMEM); + + radix_tree_insert(&mdsc->snap_realms, ino, realm); + + atomic_set(&realm->nref, 0); /* tree does not take a ref */ + realm->ino = ino; + INIT_LIST_HEAD(&realm->children); + INIT_LIST_HEAD(&realm->child_item); + INIT_LIST_HEAD(&realm->empty_item); + INIT_LIST_HEAD(&realm->inodes_with_caps); + spin_lock_init(&realm->inodes_with_caps_lock); + dout("create_snap_realm %llx %p\n", realm->ino, realm); + return realm; +} + +/* + * find and get (if found) the realm rooted at @ino and bump its ref count. + * + * caller must hold snap_rwsem for write. + */ +struct ceph_snap_realm *ceph_lookup_snap_realm(struct ceph_mds_client *mdsc, + u64 ino) +{ + struct ceph_snap_realm *realm; + + realm = radix_tree_lookup(&mdsc->snap_realms, ino); + if (realm) + dout("lookup_snap_realm %llx %p\n", realm->ino, realm); + return realm; +} + +static void __put_snap_realm(struct ceph_mds_client *mdsc, + struct ceph_snap_realm *realm); + +/* + * called with snap_rwsem (write) + */ +static void __destroy_snap_realm(struct ceph_mds_client *mdsc, + struct ceph_snap_realm *realm) +{ + dout("__destroy_snap_realm %p %llx\n", realm, realm->ino); + + radix_tree_delete(&mdsc->snap_realms, realm->ino); + + if (realm->parent) { + list_del_init(&realm->child_item); + __put_snap_realm(mdsc, realm->parent); + } + + kfree(realm->prior_parent_snaps); + kfree(realm->snaps); + ceph_put_snap_context(realm->cached_context); + kfree(realm); +} + +/* + * caller holds snap_rwsem (write) + */ +static void __put_snap_realm(struct ceph_mds_client *mdsc, + struct ceph_snap_realm *realm) +{ + dout("__put_snap_realm %llx %p %d -> %d\n", realm->ino, realm, + atomic_read(&realm->nref), atomic_read(&realm->nref)-1); + if (atomic_dec_and_test(&realm->nref)) + __destroy_snap_realm(mdsc, realm); +} + +/* + * caller needn't hold any locks + */ +void ceph_put_snap_realm(struct ceph_mds_client *mdsc, + struct ceph_snap_realm *realm) +{ + dout("put_snap_realm %llx %p %d -> %d\n", realm->ino, realm, + atomic_read(&realm->nref), atomic_read(&realm->nref)-1); + if (!atomic_dec_and_test(&realm->nref)) + return; + + if (down_write_trylock(&mdsc->snap_rwsem)) { + __destroy_snap_realm(mdsc, realm); + up_write(&mdsc->snap_rwsem); + } else { + spin_lock(&mdsc->snap_empty_lock); + list_add(&mdsc->snap_empty, &realm->empty_item); + spin_unlock(&mdsc->snap_empty_lock); + } +} + +/* + * Clean up any realms whose ref counts have dropped to zero. Note + * that this does not include realms who were created but not yet + * used. + * + * Called under snap_rwsem (write) + */ +static void __cleanup_empty_realms(struct ceph_mds_client *mdsc) +{ + struct ceph_snap_realm *realm; + + spin_lock(&mdsc->snap_empty_lock); + while (!list_empty(&mdsc->snap_empty)) { + realm = list_first_entry(&mdsc->snap_empty, + struct ceph_snap_realm, empty_item); + list_del(&realm->empty_item); + spin_unlock(&mdsc->snap_empty_lock); + __destroy_snap_realm(mdsc, realm); + spin_lock(&mdsc->snap_empty_lock); + } + spin_unlock(&mdsc->snap_empty_lock); +} + +void ceph_cleanup_empty_realms(struct ceph_mds_client *mdsc) +{ + down_write(&mdsc->snap_rwsem); + __cleanup_empty_realms(mdsc); + up_write(&mdsc->snap_rwsem); +} + +/* + * adjust the parent realm of a given @realm. adjust child list, and parent + * pointers, and ref counts appropriately. + * + * return true if parent was changed, 0 if unchanged, <0 on error. + * + * caller must hold snap_rwsem for write. + */ +static int adjust_snap_realm_parent(struct ceph_mds_client *mdsc, + struct ceph_snap_realm *realm, + u64 parentino) +{ + struct ceph_snap_realm *parent; + + if (realm->parent_ino == parentino) + return 0; + + parent = ceph_lookup_snap_realm(mdsc, parentino); + if (IS_ERR(parent)) + return PTR_ERR(parent); + if (!parent) { + parent = ceph_create_snap_realm(mdsc, parentino); + if (IS_ERR(parent)) + return PTR_ERR(parent); + } + dout("adjust_snap_realm_parent %llx %p: %llx %p -> %llx %p\n", + realm->ino, realm, realm->parent_ino, realm->parent, + parentino, parent); + if (realm->parent) { + list_del_init(&realm->child_item); + ceph_put_snap_realm(mdsc, realm->parent); + } + realm->parent_ino = parentino; + realm->parent = parent; + ceph_get_snap_realm(mdsc, parent); + list_add(&realm->child_item, &parent->children); + return 1; +} + + +static int cmpu64_rev(const void *a, const void *b) +{ + if (*(u64 *)a < *(u64 *)b) + return 1; + if (*(u64 *)a > *(u64 *)b) + return -1; + return 0; +} + +/* + * build the snap context for a given realm. + */ +static int build_snap_context(struct ceph_snap_realm *realm) +{ + struct ceph_snap_realm *parent = realm->parent; + struct ceph_snap_context *snapc; + int err = 0; + int i; + int num = realm->num_prior_parent_snaps + realm->num_snaps; + + /* + * build parent context, if it hasn't been built. + * conservatively estimate that all parent snaps might be + * included by us. + */ + if (parent) { + if (!parent->cached_context) { + err = build_snap_context(parent); + if (err) + goto fail; + } + num += parent->cached_context->num_snaps; + } + + /* do i actually need to update? not if my context seq + matches realm seq, and my parents' does to. (this works + because we rebuild_snap_realms() works _downward_ in + hierarchy after each update.) */ + if (realm->cached_context && + realm->cached_context->seq <= realm->seq && + (!parent || + realm->cached_context->seq <= parent->cached_context->seq)) { + dout("build_snap_context %llx %p: %p seq %lld (%d snaps)" + " (unchanged)\n", + realm->ino, realm, realm->cached_context, + realm->cached_context->seq, + realm->cached_context->num_snaps); + return 0; + } + + /* alloc new snap context */ + err = -ENOMEM; + if (num > ULONG_MAX / sizeof(u64) - sizeof(*snapc)) + goto fail; + snapc = kzalloc(sizeof(*snapc) + num*sizeof(u64), GFP_NOFS); + if (!snapc) + goto fail; + atomic_set(&snapc->nref, 1); + + /* build (reverse sorted) snap vector */ + num = 0; + snapc->seq = realm->seq; + if (parent) { + /* include any of parent's snaps occuring _after_ my + parent became my parent */ + for (i = 0; i < parent->cached_context->num_snaps; i++) + if (parent->cached_context->snaps[i] >= + realm->parent_since) + snapc->snaps[num++] = + parent->cached_context->snaps[i]; + if (parent->cached_context->seq > snapc->seq) + snapc->seq = parent->cached_context->seq; + } + memcpy(snapc->snaps + num, realm->snaps, + sizeof(u64)*realm->num_snaps); + num += realm->num_snaps; + memcpy(snapc->snaps + num, realm->prior_parent_snaps, + sizeof(u64)*realm->num_prior_parent_snaps); + num += realm->num_prior_parent_snaps; + + sort(snapc->snaps, num, sizeof(u64), cmpu64_rev, NULL); + snapc->num_snaps = num; + dout("build_snap_context %llx %p: %p seq %lld (%d snaps)\n", + realm->ino, realm, snapc, snapc->seq, snapc->num_snaps); + + if (realm->cached_context) + ceph_put_snap_context(realm->cached_context); + realm->cached_context = snapc; + return 0; + +fail: + /* + * if we fail, clear old (incorrect) cached_context... hopefully + * we'll have better luck building it later + */ + if (realm->cached_context) { + ceph_put_snap_context(realm->cached_context); + realm->cached_context = NULL; + } + pr_err("build_snap_context %llx %p fail %d\n", realm->ino, + realm, err); + return err; +} + +/* + * rebuild snap context for the given realm and all of its children. + */ +static void rebuild_snap_realms(struct ceph_snap_realm *realm) +{ + struct ceph_snap_realm *child; + + dout("rebuild_snap_realms %llx %p\n", realm->ino, realm); + build_snap_context(realm); + + list_for_each_entry(child, &realm->children, child_item) + rebuild_snap_realms(child); +} + + +/* + * helper to allocate and decode an array of snapids. free prior + * instance, if any. + */ +static int dup_array(u64 **dst, __le64 *src, int num) +{ + int i; + + kfree(*dst); + if (num) { + *dst = kcalloc(num, sizeof(u64), GFP_NOFS); + if (!*dst) + return -ENOMEM; + for (i = 0; i < num; i++) + (*dst)[i] = get_unaligned_le64(src + i); + } else { + *dst = NULL; + } + return 0; +} + + +/* + * When a snapshot is applied, the size/mtime inode metadata is queued + * in a ceph_cap_snap (one for each snapshot) until writeback + * completes and the metadata can be flushed back to the MDS. + * + * However, if a (sync) write is currently in-progress when we apply + * the snapshot, we have to wait until the write succeeds or fails + * (and a final size/mtime is known). In this case the + * cap_snap->writing = 1, and is said to be "pending." When the write + * finishes, we __ceph_finish_cap_snap(). + * + * Caller must hold snap_rwsem for read (i.e., the realm topology won't + * change). + */ +void ceph_queue_cap_snap(struct ceph_inode_info *ci, + struct ceph_snap_context *snapc) +{ + struct inode *inode = &ci->vfs_inode; + struct ceph_cap_snap *capsnap; + int used; + + capsnap = kzalloc(sizeof(*capsnap), GFP_NOFS); + if (!capsnap) { + pr_err("ENOMEM allocating ceph_cap_snap on %p\n", inode); + return; + } + + spin_lock(&inode->i_lock); + used = __ceph_caps_used(ci); + if (__ceph_have_pending_cap_snap(ci)) { + /* there is no point in queuing multiple "pending" cap_snaps, + as no new writes are allowed to start when pending, so any + writes in progress now were started before the previous + cap_snap. lucky us. */ + dout("queue_cap_snap %p snapc %p seq %llu used %d" + " already pending\n", inode, snapc, snapc->seq, used); + kfree(capsnap); + } else if (ci->i_wrbuffer_ref_head || (used & CEPH_CAP_FILE_WR)) { + igrab(inode); + + atomic_set(&capsnap->nref, 1); + capsnap->ci = ci; + INIT_LIST_HEAD(&capsnap->ci_item); + INIT_LIST_HEAD(&capsnap->flushing_item); + + capsnap->follows = snapc->seq - 1; + capsnap->context = ceph_get_snap_context(snapc); + capsnap->issued = __ceph_caps_issued(ci, NULL); + capsnap->dirty = __ceph_caps_dirty(ci); + + capsnap->mode = inode->i_mode; + capsnap->uid = inode->i_uid; + capsnap->gid = inode->i_gid; + + /* fixme? */ + capsnap->xattr_blob = NULL; + capsnap->xattr_len = 0; + + /* dirty page count moved from _head to this cap_snap; + all subsequent writes page dirties occur _after_ this + snapshot. */ + capsnap->dirty_pages = ci->i_wrbuffer_ref_head; + ci->i_wrbuffer_ref_head = 0; + ceph_put_snap_context(ci->i_head_snapc); + ci->i_head_snapc = NULL; + list_add_tail(&capsnap->ci_item, &ci->i_cap_snaps); + + if (used & CEPH_CAP_FILE_WR) { + dout("queue_cap_snap %p cap_snap %p snapc %p" + " seq %llu used WR, now pending\n", inode, + capsnap, snapc, snapc->seq); + capsnap->writing = 1; + } else { + /* note mtime, size NOW. */ + __ceph_finish_cap_snap(ci, capsnap); + } + } else { + dout("queue_cap_snap %p nothing dirty|writing\n", inode); + kfree(capsnap); + } + + spin_unlock(&inode->i_lock); +} + +/* + * Finalize the size, mtime for a cap_snap.. that is, settle on final values + * to be used for the snapshot, to be flushed back to the mds. + * + * If capsnap can now be flushed, add to snap_flush list, and return 1. + * + * Caller must hold i_lock. + */ +int __ceph_finish_cap_snap(struct ceph_inode_info *ci, + struct ceph_cap_snap *capsnap) +{ + struct inode *inode = &ci->vfs_inode; + struct ceph_mds_client *mdsc = &ceph_client(inode->i_sb)->mdsc; + + BUG_ON(capsnap->writing); + capsnap->size = inode->i_size; + capsnap->mtime = inode->i_mtime; + capsnap->atime = inode->i_atime; + capsnap->ctime = inode->i_ctime; + capsnap->time_warp_seq = ci->i_time_warp_seq; + if (capsnap->dirty_pages) { + dout("finish_cap_snap %p cap_snap %p snapc %p %llu s=%llu " + "still has %d dirty pages\n", inode, capsnap, + capsnap->context, capsnap->context->seq, + capsnap->size, capsnap->dirty_pages); + return 0; + } + dout("finish_cap_snap %p cap_snap %p snapc %p %llu s=%llu clean\n", + inode, capsnap, capsnap->context, + capsnap->context->seq, capsnap->size); + + spin_lock(&mdsc->snap_flush_lock); + list_add_tail(&ci->i_snap_flush_item, &mdsc->snap_flush_list); + spin_unlock(&mdsc->snap_flush_lock); + return 1; /* caller may want to ceph_flush_snaps */ +} + + +/* + * Parse and apply a snapblob "snap trace" from the MDS. This specifies + * the snap realm parameters from a given realm and all of its ancestors, + * up to the root. + * + * Caller must hold snap_rwsem for write. + */ +int ceph_update_snap_trace(struct ceph_mds_client *mdsc, + void *p, void *e, bool deletion) +{ + struct ceph_mds_snap_realm *ri; /* encoded */ + __le64 *snaps; /* encoded */ + __le64 *prior_parent_snaps; /* encoded */ + struct ceph_snap_realm *realm; + int invalidate = 0; + int err = -ENOMEM; + + dout("update_snap_trace deletion=%d\n", deletion); +more: + ceph_decode_need(&p, e, sizeof(*ri), bad); + ri = p; + p += sizeof(*ri); + ceph_decode_need(&p, e, sizeof(u64)*(le32_to_cpu(ri->num_snaps) + + le32_to_cpu(ri->num_prior_parent_snaps)), bad); + snaps = p; + p += sizeof(u64) * le32_to_cpu(ri->num_snaps); + prior_parent_snaps = p; + p += sizeof(u64) * le32_to_cpu(ri->num_prior_parent_snaps); + + realm = ceph_lookup_snap_realm(mdsc, le64_to_cpu(ri->ino)); + if (IS_ERR(realm)) { + err = PTR_ERR(realm); + goto fail; + } + if (!realm) { + realm = ceph_create_snap_realm(mdsc, le64_to_cpu(ri->ino)); + if (IS_ERR(realm)) { + err = PTR_ERR(realm); + goto fail; + } + } + + if (le64_to_cpu(ri->seq) > realm->seq) { + dout("update_snap_trace updating %llx %p %lld -> %lld\n", + realm->ino, realm, realm->seq, le64_to_cpu(ri->seq)); + /* + * if the realm seq has changed, queue a cap_snap for every + * inode with open caps. we do this _before_ we update + * the realm info so that we prepare for writeback under the + * _previous_ snap context. + * + * ...unless it's a snap deletion! + */ + if (!deletion) { + struct ceph_inode_info *ci; + struct inode *lastinode = NULL; + + spin_lock(&realm->inodes_with_caps_lock); + list_for_each_entry(ci, &realm->inodes_with_caps, + i_snap_realm_item) { + struct inode *inode = igrab(&ci->vfs_inode); + if (!inode) + continue; + spin_unlock(&realm->inodes_with_caps_lock); + if (lastinode) + iput(lastinode); + lastinode = inode; + ceph_queue_cap_snap(ci, realm->cached_context); + spin_lock(&realm->inodes_with_caps_lock); + } + spin_unlock(&realm->inodes_with_caps_lock); + if (lastinode) + iput(lastinode); + dout("update_snap_trace cap_snaps queued\n"); + } + + } else { + dout("update_snap_trace %llx %p seq %lld unchanged\n", + realm->ino, realm, realm->seq); + } + + /* ensure the parent is correct */ + err = adjust_snap_realm_parent(mdsc, realm, le64_to_cpu(ri->parent)); + if (err < 0) + goto fail; + invalidate += err; + + if (le64_to_cpu(ri->seq) > realm->seq) { + /* update realm parameters, snap lists */ + realm->seq = le64_to_cpu(ri->seq); + realm->created = le64_to_cpu(ri->created); + realm->parent_since = le64_to_cpu(ri->parent_since); + + realm->num_snaps = le32_to_cpu(ri->num_snaps); + err = dup_array(&realm->snaps, snaps, realm->num_snaps); + if (err < 0) + goto fail; + + realm->num_prior_parent_snaps = + le32_to_cpu(ri->num_prior_parent_snaps); + err = dup_array(&realm->prior_parent_snaps, prior_parent_snaps, + realm->num_prior_parent_snaps); + if (err < 0) + goto fail; + + invalidate = 1; + } else if (!realm->cached_context) { + invalidate = 1; + } + + dout("done with %llx %p, invalidated=%d, %p %p\n", realm->ino, + realm, invalidate, p, e); + + if (p < e) + goto more; + + /* invalidate when we reach the _end_ (root) of the trace */ + if (invalidate) + rebuild_snap_realms(realm); + + __cleanup_empty_realms(mdsc); + return 0; + +bad: + err = -EINVAL; +fail: + pr_err("update_snap_trace error %d\n", err); + return err; +} + + +/* + * Send any cap_snaps that are queued for flush. Try to carry + * s_mutex across multiple snap flushes to avoid locking overhead. + * + * Caller holds no locks. + */ +static void flush_snaps(struct ceph_mds_client *mdsc) +{ + struct ceph_inode_info *ci; + struct inode *inode; + struct ceph_mds_session *session = NULL; + + dout("flush_snaps\n"); + spin_lock(&mdsc->snap_flush_lock); + while (!list_empty(&mdsc->snap_flush_list)) { + ci = list_first_entry(&mdsc->snap_flush_list, + struct ceph_inode_info, i_snap_flush_item); + inode = &ci->vfs_inode; + igrab(inode); + spin_unlock(&mdsc->snap_flush_lock); + spin_lock(&inode->i_lock); + __ceph_flush_snaps(ci, &session); + spin_unlock(&inode->i_lock); + iput(inode); + spin_lock(&mdsc->snap_flush_lock); + } + spin_unlock(&mdsc->snap_flush_lock); + + if (session) { + mutex_unlock(&session->s_mutex); + ceph_put_mds_session(session); + } + dout("flush_snaps done\n"); +} + + +/* + * Handle a snap notification from the MDS. + * + * This can take two basic forms: the simplest is just a snap creation + * or deletion notification on an existing realm. This should update the + * realm and its children. + * + * The more difficult case is realm creation, due to snap creation at a + * new point in the file hierarchy, or due to a rename that moves a file or + * directory into another realm. + */ +void ceph_handle_snap(struct ceph_mds_client *mdsc, + struct ceph_msg *msg) +{ + struct super_block *sb = mdsc->client->sb; + struct ceph_mds_session *session; + int mds; + u64 split; + int op; + int trace_len; + struct ceph_snap_realm *realm = NULL; + void *p = msg->front.iov_base; + void *e = p + msg->front.iov_len; + struct ceph_mds_snap_head *h; + int num_split_inos, num_split_realms; + __le64 *split_inos = NULL, *split_realms = NULL; + int i; + int locked_rwsem = 0; + + if (msg->hdr.src.name.type != CEPH_ENTITY_TYPE_MDS) + return; + mds = le64_to_cpu(msg->hdr.src.name.num); + + /* decode */ + if (msg->front.iov_len < sizeof(*h)) + goto bad; + h = p; + op = le32_to_cpu(h->op); + split = le64_to_cpu(h->split); /* non-zero if we are splitting an + * existing realm */ + num_split_inos = le32_to_cpu(h->num_split_inos); + num_split_realms = le32_to_cpu(h->num_split_realms); + trace_len = le32_to_cpu(h->trace_len); + p += sizeof(*h); + + dout("handle_snap from mds%d op %s split %llx tracelen %d\n", mds, + ceph_snap_op_name(op), split, trace_len); + + /* find session */ + mutex_lock(&mdsc->mutex); + session = __ceph_lookup_mds_session(mdsc, mds); + mutex_unlock(&mdsc->mutex); + if (!session) { + dout("WTF, got snap but no session for mds%d\n", mds); + return; + } + + mutex_lock(&session->s_mutex); + session->s_seq++; + mutex_unlock(&session->s_mutex); + + down_write(&mdsc->snap_rwsem); + locked_rwsem = 1; + + if (op == CEPH_SNAP_OP_SPLIT) { + struct ceph_mds_snap_realm *ri; + + /* + * A "split" breaks part of an existing realm off into + * a new realm. The MDS provides a list of inodes + * (with caps) and child realms that belong to the new + * child. + */ + split_inos = p; + p += sizeof(u64) * num_split_inos; + split_realms = p; + p += sizeof(u64) * num_split_realms; + ceph_decode_need(&p, e, sizeof(*ri), bad); + /* we will peek at realm info here, but will _not_ + * advance p, as the realm update will occur below in + * ceph_update_snap_trace. */ + ri = p; + + realm = ceph_lookup_snap_realm(mdsc, split); + if (IS_ERR(realm)) + goto out; + if (!realm) { + realm = ceph_create_snap_realm(mdsc, split); + if (IS_ERR(realm)) + goto out; + } + ceph_get_snap_realm(mdsc, realm); + + dout("splitting snap_realm %llx %p\n", realm->ino, realm); + for (i = 0; i < num_split_inos; i++) { + struct ceph_vino vino = { + .ino = le64_to_cpu(split_inos[i]), + .snap = CEPH_NOSNAP, + }; + struct inode *inode = ceph_find_inode(sb, vino); + struct ceph_inode_info *ci; + + if (!inode) + continue; + ci = ceph_inode(inode); + + spin_lock(&inode->i_lock); + if (!ci->i_snap_realm) + goto skip_inode; + /* + * If this inode belongs to a realm that was + * created after our new realm, we experienced + * a race (due to another split notifications + * arriving from a different MDS). So skip + * this inode. + */ + if (ci->i_snap_realm->created > + le64_to_cpu(ri->created)) { + dout(" leaving %p in newer realm %llx %p\n", + inode, ci->i_snap_realm->ino, + ci->i_snap_realm); + goto skip_inode; + } + dout(" will move %p to split realm %llx %p\n", + inode, realm->ino, realm); + /* + * Remove the inode from the realm's inode + * list, but don't add it to the new realm + * yet. We don't want the cap_snap to be + * queued (again) by ceph_update_snap_trace() + * below. Queue it _now_, under the old context. + */ + list_del_init(&ci->i_snap_realm_item); + spin_unlock(&inode->i_lock); + + ceph_queue_cap_snap(ci, + ci->i_snap_realm->cached_context); + + iput(inode); + continue; + +skip_inode: + spin_unlock(&inode->i_lock); + iput(inode); + } + + /* we may have taken some of the old realm's children. */ + for (i = 0; i < num_split_realms; i++) { + struct ceph_snap_realm *child = + ceph_lookup_snap_realm(mdsc, + le64_to_cpu(split_realms[i])); + if (IS_ERR(child)) + continue; + if (!child) + continue; + adjust_snap_realm_parent(mdsc, child, realm->ino); + } + } + + /* + * update using the provided snap trace. if we are deleting a + * snap, we can avoid queueing cap_snaps. + */ + ceph_update_snap_trace(mdsc, p, e, + op == CEPH_SNAP_OP_DESTROY); + + if (op == CEPH_SNAP_OP_SPLIT) { + /* + * ok, _now_ add the inodes into the new realm. + */ + for (i = 0; i < num_split_inos; i++) { + struct ceph_vino vino = { + .ino = le64_to_cpu(split_inos[i]), + .snap = CEPH_NOSNAP, + }; + struct inode *inode = ceph_find_inode(sb, vino); + struct ceph_inode_info *ci; + + if (!inode) + continue; + ci = ceph_inode(inode); + spin_lock(&inode->i_lock); + if (!ci->i_snap_realm) + goto split_skip_inode; + ceph_put_snap_realm(mdsc, ci->i_snap_realm); + spin_lock(&realm->inodes_with_caps_lock); + list_add(&ci->i_snap_realm_item, + &realm->inodes_with_caps); + ci->i_snap_realm = realm; + spin_unlock(&realm->inodes_with_caps_lock); + ceph_get_snap_realm(mdsc, realm); +split_skip_inode: + spin_unlock(&inode->i_lock); + iput(inode); + } + + /* we took a reference when we created the realm, above */ + ceph_put_snap_realm(mdsc, realm); + } + + __cleanup_empty_realms(mdsc); + + up_write(&mdsc->snap_rwsem); + + flush_snaps(mdsc); + return; + +bad: + pr_err("corrupt snap message from mds%d\n", mds); +out: + if (locked_rwsem) + up_write(&mdsc->snap_rwsem); + return; +} + + + -- cgit v0.10.2 From 31b8006e1d79e127a776c9414e3e0b5f9508047e Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 6 Oct 2009 11:31:13 -0700 Subject: ceph: messenger library A generic message passing library is used to communicate with all other components in the Ceph file system. The messenger library provides ordered, reliable delivery of messages between two nodes in the system. This implementation is based on TCP. Signed-off-by: Sage Weil diff --git a/fs/ceph/decode.h b/fs/ceph/decode.h new file mode 100644 index 0000000..fc2769d --- /dev/null +++ b/fs/ceph/decode.h @@ -0,0 +1,136 @@ +#ifndef __CEPH_DECODE_H +#define __CEPH_DECODE_H + +#include + +/* + * in all cases, + * void **p pointer to position pointer + * void *end pointer to end of buffer (last byte + 1) + */ + +/* + * bounds check input. + */ +#define ceph_decode_need(p, end, n, bad) \ + do { \ + if (unlikely(*(p) + (n) > (end))) \ + goto bad; \ + } while (0) + +#define ceph_decode_64(p, v) \ + do { \ + v = get_unaligned_le64(*(p)); \ + *(p) += sizeof(u64); \ + } while (0) +#define ceph_decode_32(p, v) \ + do { \ + v = get_unaligned_le32(*(p)); \ + *(p) += sizeof(u32); \ + } while (0) +#define ceph_decode_16(p, v) \ + do { \ + v = get_unaligned_le16(*(p)); \ + *(p) += sizeof(u16); \ + } while (0) +#define ceph_decode_8(p, v) \ + do { \ + v = *(u8 *)*(p); \ + (*p)++; \ + } while (0) + +#define ceph_decode_copy(p, pv, n) \ + do { \ + memcpy(pv, *(p), n); \ + *(p) += n; \ + } while (0) + +/* bounds check too */ +#define ceph_decode_64_safe(p, end, v, bad) \ + do { \ + ceph_decode_need(p, end, sizeof(u64), bad); \ + ceph_decode_64(p, v); \ + } while (0) +#define ceph_decode_32_safe(p, end, v, bad) \ + do { \ + ceph_decode_need(p, end, sizeof(u32), bad); \ + ceph_decode_32(p, v); \ + } while (0) +#define ceph_decode_16_safe(p, end, v, bad) \ + do { \ + ceph_decode_need(p, end, sizeof(u16), bad); \ + ceph_decode_16(p, v); \ + } while (0) + +#define ceph_decode_copy_safe(p, end, pv, n, bad) \ + do { \ + ceph_decode_need(p, end, n, bad); \ + ceph_decode_copy(p, pv, n); \ + } while (0) + +/* + * struct ceph_timespec <-> struct timespec + */ +#define ceph_decode_timespec(ts, tv) \ + do { \ + (ts)->tv_sec = le32_to_cpu((tv)->tv_sec); \ + (ts)->tv_nsec = le32_to_cpu((tv)->tv_nsec); \ + } while (0) +#define ceph_encode_timespec(tv, ts) \ + do { \ + (tv)->tv_sec = cpu_to_le32((ts)->tv_sec); \ + (tv)->tv_nsec = cpu_to_le32((ts)->tv_nsec); \ + } while (0) + + +/* + * encoders + */ +#define ceph_encode_64(p, v) \ + do { \ + put_unaligned_le64(v, (__le64 *)*(p)); \ + *(p) += sizeof(u64); \ + } while (0) +#define ceph_encode_32(p, v) \ + do { \ + put_unaligned_le32(v, (__le32 *)*(p)); \ + *(p) += sizeof(u32); \ + } while (0) +#define ceph_encode_16(p, v) \ + do { \ + put_unaligned_le16(v), (__le16 *)*(p)); \ + *(p) += sizeof(u16); \ + } while (0) +#define ceph_encode_8(p, v) \ + do { \ + *(u8 *)*(p) = v; \ + (*(p))++; \ + } while (0) + +/* + * filepath, string encoders + */ +static inline void ceph_encode_filepath(void **p, void *end, + u64 ino, const char *path) +{ + u32 len = path ? strlen(path) : 0; + BUG_ON(*p + sizeof(ino) + sizeof(len) + len > end); + ceph_encode_64(p, ino); + ceph_encode_32(p, len); + if (len) + memcpy(*p, path, len); + *p += len; +} + +static inline void ceph_encode_string(void **p, void *end, + const char *s, u32 len) +{ + BUG_ON(*p + sizeof(len) + len > end); + ceph_encode_32(p, len); + if (len) + memcpy(*p, s, len); + *p += len; +} + + +#endif diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c new file mode 100644 index 0000000..63f7f13 --- /dev/null +++ b/fs/ceph/messenger.c @@ -0,0 +1,2019 @@ +#include "ceph_debug.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "super.h" +#include "messenger.h" + +/* + * Ceph uses the messenger to exchange ceph_msg messages with other + * hosts in the system. The messenger provides ordered and reliable + * delivery. We tolerate TCP disconnects by reconnecting (with + * exponential backoff) in the case of a fault (disconnection, bad + * crc, protocol error). Acks allow sent messages to be discarded by + * the sender. + */ + +/* static tag bytes (protocol control messages) */ +static char tag_msg = CEPH_MSGR_TAG_MSG; +static char tag_ack = CEPH_MSGR_TAG_ACK; +static char tag_keepalive = CEPH_MSGR_TAG_KEEPALIVE; + + +static void queue_con(struct ceph_connection *con); +static void con_work(struct work_struct *); +static void ceph_fault(struct ceph_connection *con); + +const char *ceph_name_type_str(int t) +{ + switch (t) { + case CEPH_ENTITY_TYPE_MON: return "mon"; + case CEPH_ENTITY_TYPE_MDS: return "mds"; + case CEPH_ENTITY_TYPE_OSD: return "osd"; + case CEPH_ENTITY_TYPE_CLIENT: return "client"; + case CEPH_ENTITY_TYPE_ADMIN: return "admin"; + default: return "???"; + } +} + +/* + * nicely render a sockaddr as a string. + */ +#define MAX_ADDR_STR 20 +static char addr_str[MAX_ADDR_STR][40]; +static DEFINE_SPINLOCK(addr_str_lock); +static int last_addr_str; + +const char *pr_addr(const struct sockaddr_storage *ss) +{ + int i; + char *s; + struct sockaddr_in *in4 = (void *)ss; + unsigned char *quad = (void *)&in4->sin_addr.s_addr; + struct sockaddr_in6 *in6 = (void *)ss; + + spin_lock(&addr_str_lock); + i = last_addr_str++; + if (last_addr_str == MAX_ADDR_STR) + last_addr_str = 0; + spin_unlock(&addr_str_lock); + s = addr_str[i]; + + switch (ss->ss_family) { + case AF_INET: + sprintf(s, "%u.%u.%u.%u:%u", + (unsigned int)quad[0], + (unsigned int)quad[1], + (unsigned int)quad[2], + (unsigned int)quad[3], + (unsigned int)ntohs(in4->sin_port)); + break; + + case AF_INET6: + sprintf(s, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x:%u", + in6->sin6_addr.s6_addr16[0], + in6->sin6_addr.s6_addr16[1], + in6->sin6_addr.s6_addr16[2], + in6->sin6_addr.s6_addr16[3], + in6->sin6_addr.s6_addr16[4], + in6->sin6_addr.s6_addr16[5], + in6->sin6_addr.s6_addr16[6], + in6->sin6_addr.s6_addr16[7], + (unsigned int)ntohs(in6->sin6_port)); + break; + + default: + sprintf(s, "(unknown sockaddr family %d)", (int)ss->ss_family); + } + + return s; +} + +/* + * work queue for all reading and writing to/from the socket. + */ +struct workqueue_struct *ceph_msgr_wq; + +int __init ceph_msgr_init(void) +{ + ceph_msgr_wq = create_workqueue("ceph-msgr"); + if (IS_ERR(ceph_msgr_wq)) { + int ret = PTR_ERR(ceph_msgr_wq); + pr_err("msgr_init failed to create workqueue: %d\n", ret); + ceph_msgr_wq = NULL; + return ret; + } + return 0; +} + +void ceph_msgr_exit(void) +{ + destroy_workqueue(ceph_msgr_wq); +} + +/* + * socket callback functions + */ + +/* data available on socket, or listen socket received a connect */ +static void ceph_data_ready(struct sock *sk, int count_unused) +{ + struct ceph_connection *con = + (struct ceph_connection *)sk->sk_user_data; + if (sk->sk_state != TCP_CLOSE_WAIT) { + dout("ceph_data_ready on %p state = %lu, queueing work\n", + con, con->state); + queue_con(con); + } +} + +/* socket has buffer space for writing */ +static void ceph_write_space(struct sock *sk) +{ + struct ceph_connection *con = + (struct ceph_connection *)sk->sk_user_data; + + /* only queue to workqueue if there is data we want to write. */ + if (test_bit(WRITE_PENDING, &con->state)) { + dout("ceph_write_space %p queueing write work\n", con); + queue_con(con); + } else { + dout("ceph_write_space %p nothing to write\n", con); + } + + /* since we have our own write_space, clear the SOCK_NOSPACE flag */ + clear_bit(SOCK_NOSPACE, &sk->sk_socket->flags); +} + +/* socket's state has changed */ +static void ceph_state_change(struct sock *sk) +{ + struct ceph_connection *con = + (struct ceph_connection *)sk->sk_user_data; + + dout("ceph_state_change %p state = %lu sk_state = %u\n", + con, con->state, sk->sk_state); + + if (test_bit(CLOSED, &con->state)) + return; + + switch (sk->sk_state) { + case TCP_CLOSE: + dout("ceph_state_change TCP_CLOSE\n"); + case TCP_CLOSE_WAIT: + dout("ceph_state_change TCP_CLOSE_WAIT\n"); + if (test_and_set_bit(SOCK_CLOSED, &con->state) == 0) { + if (test_bit(CONNECTING, &con->state)) + con->error_msg = "connection failed"; + else + con->error_msg = "socket closed"; + queue_con(con); + } + break; + case TCP_ESTABLISHED: + dout("ceph_state_change TCP_ESTABLISHED\n"); + queue_con(con); + break; + } +} + +/* + * set up socket callbacks + */ +static void set_sock_callbacks(struct socket *sock, + struct ceph_connection *con) +{ + struct sock *sk = sock->sk; + sk->sk_user_data = (void *)con; + sk->sk_data_ready = ceph_data_ready; + sk->sk_write_space = ceph_write_space; + sk->sk_state_change = ceph_state_change; +} + + +/* + * socket helpers + */ + +/* + * initiate connection to a remote socket. + */ +static struct socket *ceph_tcp_connect(struct ceph_connection *con) +{ + struct sockaddr *paddr = (struct sockaddr *)&con->peer_addr.in_addr; + struct socket *sock; + int ret; + + BUG_ON(con->sock); + ret = sock_create_kern(AF_INET, SOCK_STREAM, IPPROTO_TCP, &sock); + if (ret) + return ERR_PTR(ret); + con->sock = sock; + sock->sk->sk_allocation = GFP_NOFS; + + set_sock_callbacks(sock, con); + + dout("connect %s\n", pr_addr(&con->peer_addr.in_addr)); + + ret = sock->ops->connect(sock, paddr, sizeof(*paddr), O_NONBLOCK); + if (ret == -EINPROGRESS) { + dout("connect %s EINPROGRESS sk_state = %u\n", + pr_addr(&con->peer_addr.in_addr), + sock->sk->sk_state); + ret = 0; + } + if (ret < 0) { + pr_err("connect %s error %d\n", + pr_addr(&con->peer_addr.in_addr), ret); + sock_release(sock); + con->sock = NULL; + con->error_msg = "connect error"; + } + + if (ret < 0) + return ERR_PTR(ret); + return sock; +} + +static int ceph_tcp_recvmsg(struct socket *sock, void *buf, size_t len) +{ + struct kvec iov = {buf, len}; + struct msghdr msg = { .msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL }; + + return kernel_recvmsg(sock, &msg, &iov, 1, len, msg.msg_flags); +} + +/* + * write something. @more is true if caller will be sending more data + * shortly. + */ +static int ceph_tcp_sendmsg(struct socket *sock, struct kvec *iov, + size_t kvlen, size_t len, int more) +{ + struct msghdr msg = { .msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL }; + + if (more) + msg.msg_flags |= MSG_MORE; + else + msg.msg_flags |= MSG_EOR; /* superfluous, but what the hell */ + + return kernel_sendmsg(sock, &msg, iov, kvlen, len); +} + + +/* + * Shutdown/close the socket for the given connection. + */ +static int con_close_socket(struct ceph_connection *con) +{ + int rc; + + dout("con_close_socket on %p sock %p\n", con, con->sock); + if (!con->sock) + return 0; + set_bit(SOCK_CLOSED, &con->state); + rc = con->sock->ops->shutdown(con->sock, SHUT_RDWR); + sock_release(con->sock); + con->sock = NULL; + clear_bit(SOCK_CLOSED, &con->state); + return rc; +} + +/* + * Reset a connection. Discard all incoming and outgoing messages + * and clear *_seq state. + */ +static void ceph_msg_remove(struct ceph_msg *msg) +{ + list_del_init(&msg->list_head); + ceph_msg_put(msg); +} +static void ceph_msg_remove_list(struct list_head *head) +{ + while (!list_empty(head)) { + struct ceph_msg *msg = list_first_entry(head, struct ceph_msg, + list_head); + ceph_msg_remove(msg); + } +} + +static void reset_connection(struct ceph_connection *con) +{ + /* reset connection, out_queue, msg_ and connect_seq */ + /* discard existing out_queue and msg_seq */ + mutex_lock(&con->out_mutex); + ceph_msg_remove_list(&con->out_queue); + ceph_msg_remove_list(&con->out_sent); + + con->connect_seq = 0; + con->out_seq = 0; + con->out_msg = NULL; + con->in_seq = 0; + mutex_unlock(&con->out_mutex); +} + +/* + * mark a peer down. drop any open connections. + */ +void ceph_con_close(struct ceph_connection *con) +{ + dout("con_close %p peer %s\n", con, pr_addr(&con->peer_addr.in_addr)); + set_bit(CLOSED, &con->state); /* in case there's queued work */ + clear_bit(STANDBY, &con->state); /* avoid connect_seq bump */ + reset_connection(con); + queue_con(con); +} + +/* + * clean up connection state + */ +void ceph_con_shutdown(struct ceph_connection *con) +{ + dout("con_shutdown %p\n", con); + reset_connection(con); + set_bit(DEAD, &con->state); + con_close_socket(con); /* silently ignore errors */ +} + +/* + * Reopen a closed connection, with a new peer address. + */ +void ceph_con_open(struct ceph_connection *con, struct ceph_entity_addr *addr) +{ + dout("con_open %p %s\n", con, pr_addr(&addr->in_addr)); + set_bit(OPENING, &con->state); + clear_bit(CLOSED, &con->state); + memcpy(&con->peer_addr, addr, sizeof(*addr)); + queue_con(con); +} + +/* + * generic get/put + */ +struct ceph_connection *ceph_con_get(struct ceph_connection *con) +{ + dout("con_get %p nref = %d -> %d\n", con, + atomic_read(&con->nref), atomic_read(&con->nref) + 1); + if (atomic_inc_not_zero(&con->nref)) + return con; + return NULL; +} + +void ceph_con_put(struct ceph_connection *con) +{ + dout("con_put %p nref = %d -> %d\n", con, + atomic_read(&con->nref), atomic_read(&con->nref) - 1); + BUG_ON(atomic_read(&con->nref) == 0); + if (atomic_dec_and_test(&con->nref)) { + ceph_con_shutdown(con); + kfree(con); + } +} + +/* + * initialize a new connection. + */ +void ceph_con_init(struct ceph_messenger *msgr, struct ceph_connection *con) +{ + dout("con_init %p\n", con); + memset(con, 0, sizeof(*con)); + atomic_set(&con->nref, 1); + con->msgr = msgr; + mutex_init(&con->out_mutex); + INIT_LIST_HEAD(&con->out_queue); + INIT_LIST_HEAD(&con->out_sent); + INIT_DELAYED_WORK(&con->work, con_work); +} + + +/* + * We maintain a global counter to order connection attempts. Get + * a unique seq greater than @gt. + */ +static u32 get_global_seq(struct ceph_messenger *msgr, u32 gt) +{ + u32 ret; + + spin_lock(&msgr->global_seq_lock); + if (msgr->global_seq < gt) + msgr->global_seq = gt; + ret = ++msgr->global_seq; + spin_unlock(&msgr->global_seq_lock); + return ret; +} + + +/* + * Prepare footer for currently outgoing message, and finish things + * off. Assumes out_kvec* are already valid.. we just add on to the end. + */ +static void prepare_write_message_footer(struct ceph_connection *con, int v) +{ + struct ceph_msg *m = con->out_msg; + + dout("prepare_write_message_footer %p\n", con); + con->out_kvec_is_msg = true; + con->out_kvec[v].iov_base = &m->footer; + con->out_kvec[v].iov_len = sizeof(m->footer); + con->out_kvec_bytes += sizeof(m->footer); + con->out_kvec_left++; + con->out_more = m->more_to_follow; + con->out_msg = NULL; /* we're done with this one */ +} + +/* + * Prepare headers for the next outgoing message. + */ +static void prepare_write_message(struct ceph_connection *con) +{ + struct ceph_msg *m; + int v = 0; + + con->out_kvec_bytes = 0; + con->out_kvec_is_msg = true; + + /* Sneak an ack in there first? If we can get it into the same + * TCP packet that's a good thing. */ + if (con->in_seq > con->in_seq_acked) { + con->in_seq_acked = con->in_seq; + con->out_kvec[v].iov_base = &tag_ack; + con->out_kvec[v++].iov_len = 1; + con->out_temp_ack = cpu_to_le64(con->in_seq_acked); + con->out_kvec[v].iov_base = &con->out_temp_ack; + con->out_kvec[v++].iov_len = sizeof(con->out_temp_ack); + con->out_kvec_bytes = 1 + sizeof(con->out_temp_ack); + } + + /* move message to sending/sent list */ + m = list_first_entry(&con->out_queue, + struct ceph_msg, list_head); + list_move_tail(&m->list_head, &con->out_sent); + con->out_msg = m; /* we don't bother taking a reference here. */ + + m->hdr.seq = cpu_to_le64(++con->out_seq); + + dout("prepare_write_message %p seq %lld type %d len %d+%d+%d %d pgs\n", + m, con->out_seq, le16_to_cpu(m->hdr.type), + le32_to_cpu(m->hdr.front_len), le32_to_cpu(m->hdr.middle_len), + le32_to_cpu(m->hdr.data_len), + m->nr_pages); + BUG_ON(le32_to_cpu(m->hdr.front_len) != m->front.iov_len); + + /* tag + hdr + front + middle */ + con->out_kvec[v].iov_base = &tag_msg; + con->out_kvec[v++].iov_len = 1; + con->out_kvec[v].iov_base = &m->hdr; + con->out_kvec[v++].iov_len = sizeof(m->hdr); + con->out_kvec[v++] = m->front; + if (m->middle) + con->out_kvec[v++] = m->middle->vec; + con->out_kvec_left = v; + con->out_kvec_bytes += 1 + sizeof(m->hdr) + m->front.iov_len + + (m->middle ? m->middle->vec.iov_len : 0); + con->out_kvec_cur = con->out_kvec; + + /* fill in crc (except data pages), footer */ + con->out_msg->hdr.crc = + cpu_to_le32(crc32c(0, (void *)&m->hdr, + sizeof(m->hdr) - sizeof(m->hdr.crc))); + con->out_msg->footer.flags = CEPH_MSG_FOOTER_COMPLETE; + con->out_msg->footer.front_crc = + cpu_to_le32(crc32c(0, m->front.iov_base, m->front.iov_len)); + if (m->middle) + con->out_msg->footer.middle_crc = + cpu_to_le32(crc32c(0, m->middle->vec.iov_base, + m->middle->vec.iov_len)); + else + con->out_msg->footer.middle_crc = 0; + con->out_msg->footer.data_crc = 0; + dout("prepare_write_message front_crc %u data_crc %u\n", + le32_to_cpu(con->out_msg->footer.front_crc), + le32_to_cpu(con->out_msg->footer.middle_crc)); + + /* is there a data payload? */ + if (le32_to_cpu(m->hdr.data_len) > 0) { + /* initialize page iterator */ + con->out_msg_pos.page = 0; + con->out_msg_pos.page_pos = + le16_to_cpu(m->hdr.data_off) & ~PAGE_MASK; + con->out_msg_pos.data_pos = 0; + con->out_msg_pos.did_page_crc = 0; + con->out_more = 1; /* data + footer will follow */ + } else { + /* no, queue up footer too and be done */ + prepare_write_message_footer(con, v); + } + + set_bit(WRITE_PENDING, &con->state); +} + +/* + * Prepare an ack. + */ +static void prepare_write_ack(struct ceph_connection *con) +{ + dout("prepare_write_ack %p %llu -> %llu\n", con, + con->in_seq_acked, con->in_seq); + con->in_seq_acked = con->in_seq; + + con->out_kvec[0].iov_base = &tag_ack; + con->out_kvec[0].iov_len = 1; + con->out_temp_ack = cpu_to_le64(con->in_seq_acked); + con->out_kvec[1].iov_base = &con->out_temp_ack; + con->out_kvec[1].iov_len = sizeof(con->out_temp_ack); + con->out_kvec_left = 2; + con->out_kvec_bytes = 1 + sizeof(con->out_temp_ack); + con->out_kvec_cur = con->out_kvec; + con->out_more = 1; /* more will follow.. eventually.. */ + set_bit(WRITE_PENDING, &con->state); +} + +/* + * Prepare to write keepalive byte. + */ +static void prepare_write_keepalive(struct ceph_connection *con) +{ + dout("prepare_write_keepalive %p\n", con); + con->out_kvec[0].iov_base = &tag_keepalive; + con->out_kvec[0].iov_len = 1; + con->out_kvec_left = 1; + con->out_kvec_bytes = 1; + con->out_kvec_cur = con->out_kvec; + set_bit(WRITE_PENDING, &con->state); +} + +/* + * Connection negotiation. + */ + +/* + * We connected to a peer and are saying hello. + */ +static void prepare_write_connect(struct ceph_messenger *msgr, + struct ceph_connection *con) +{ + int len = strlen(CEPH_BANNER); + unsigned global_seq = get_global_seq(con->msgr, 0); + int proto; + + switch (con->peer_name.type) { + case CEPH_ENTITY_TYPE_MON: + proto = CEPH_MONC_PROTOCOL; + break; + case CEPH_ENTITY_TYPE_OSD: + proto = CEPH_OSDC_PROTOCOL; + break; + case CEPH_ENTITY_TYPE_MDS: + proto = CEPH_MDSC_PROTOCOL; + break; + default: + BUG(); + } + + dout("prepare_write_connect %p cseq=%d gseq=%d proto=%d\n", con, + con->connect_seq, global_seq, proto); + con->out_connect.host_type = cpu_to_le32(CEPH_ENTITY_TYPE_CLIENT); + con->out_connect.connect_seq = cpu_to_le32(con->connect_seq); + con->out_connect.global_seq = cpu_to_le32(global_seq); + con->out_connect.protocol_version = cpu_to_le32(proto); + con->out_connect.flags = 0; + if (test_bit(LOSSYTX, &con->state)) + con->out_connect.flags = CEPH_MSG_CONNECT_LOSSY; + + con->out_kvec[0].iov_base = CEPH_BANNER; + con->out_kvec[0].iov_len = len; + con->out_kvec[1].iov_base = &msgr->inst.addr; + con->out_kvec[1].iov_len = sizeof(msgr->inst.addr); + con->out_kvec[2].iov_base = &con->out_connect; + con->out_kvec[2].iov_len = sizeof(con->out_connect); + con->out_kvec_left = 3; + con->out_kvec_bytes = len + sizeof(msgr->inst.addr) + + sizeof(con->out_connect); + con->out_kvec_cur = con->out_kvec; + con->out_more = 0; + set_bit(WRITE_PENDING, &con->state); +} + +static void prepare_write_connect_retry(struct ceph_messenger *msgr, + struct ceph_connection *con) +{ + dout("prepare_write_connect_retry %p\n", con); + con->out_connect.connect_seq = cpu_to_le32(con->connect_seq); + con->out_connect.global_seq = + cpu_to_le32(get_global_seq(con->msgr, 0)); + + con->out_kvec[0].iov_base = &con->out_connect; + con->out_kvec[0].iov_len = sizeof(con->out_connect); + con->out_kvec_left = 1; + con->out_kvec_bytes = sizeof(con->out_connect); + con->out_kvec_cur = con->out_kvec; + con->out_more = 0; + set_bit(WRITE_PENDING, &con->state); +} + + +/* + * write as much of pending kvecs to the socket as we can. + * 1 -> done + * 0 -> socket full, but more to do + * <0 -> error + */ +static int write_partial_kvec(struct ceph_connection *con) +{ + int ret; + + dout("write_partial_kvec %p %d left\n", con, con->out_kvec_bytes); + while (con->out_kvec_bytes > 0) { + ret = ceph_tcp_sendmsg(con->sock, con->out_kvec_cur, + con->out_kvec_left, con->out_kvec_bytes, + con->out_more); + if (ret <= 0) + goto out; + con->out_kvec_bytes -= ret; + if (con->out_kvec_bytes == 0) + break; /* done */ + while (ret > 0) { + if (ret >= con->out_kvec_cur->iov_len) { + ret -= con->out_kvec_cur->iov_len; + con->out_kvec_cur++; + con->out_kvec_left--; + } else { + con->out_kvec_cur->iov_len -= ret; + con->out_kvec_cur->iov_base += ret; + ret = 0; + break; + } + } + } + con->out_kvec_left = 0; + con->out_kvec_is_msg = false; + ret = 1; +out: + dout("write_partial_kvec %p %d left in %d kvecs ret = %d\n", con, + con->out_kvec_bytes, con->out_kvec_left, ret); + return ret; /* done! */ +} + +/* + * Write as much message data payload as we can. If we finish, queue + * up the footer. + * 1 -> done, footer is now queued in out_kvec[]. + * 0 -> socket full, but more to do + * <0 -> error + */ +static int write_partial_msg_pages(struct ceph_connection *con) +{ + struct ceph_msg *msg = con->out_msg; + unsigned data_len = le32_to_cpu(msg->hdr.data_len); + size_t len; + int crc = con->msgr->nocrc; + int ret; + + dout("write_partial_msg_pages %p msg %p page %d/%d offset %d\n", + con, con->out_msg, con->out_msg_pos.page, con->out_msg->nr_pages, + con->out_msg_pos.page_pos); + + while (con->out_msg_pos.page < con->out_msg->nr_pages) { + struct page *page = NULL; + void *kaddr = NULL; + + /* + * if we are calculating the data crc (the default), we need + * to map the page. if our pages[] has been revoked, use the + * zero page. + */ + if (msg->pages) { + page = msg->pages[con->out_msg_pos.page]; + if (crc) + kaddr = kmap(page); + } else { + page = con->msgr->zero_page; + if (crc) + kaddr = page_address(con->msgr->zero_page); + } + len = min((int)(PAGE_SIZE - con->out_msg_pos.page_pos), + (int)(data_len - con->out_msg_pos.data_pos)); + if (crc && !con->out_msg_pos.did_page_crc) { + void *base = kaddr + con->out_msg_pos.page_pos; + u32 tmpcrc = le32_to_cpu(con->out_msg->footer.data_crc); + + BUG_ON(kaddr == NULL); + con->out_msg->footer.data_crc = + cpu_to_le32(crc32c(tmpcrc, base, len)); + con->out_msg_pos.did_page_crc = 1; + } + + ret = kernel_sendpage(con->sock, page, + con->out_msg_pos.page_pos, len, + MSG_DONTWAIT | MSG_NOSIGNAL | + MSG_MORE); + + if (crc && msg->pages) + kunmap(page); + + if (ret <= 0) + goto out; + + con->out_msg_pos.data_pos += ret; + con->out_msg_pos.page_pos += ret; + if (ret == len) { + con->out_msg_pos.page_pos = 0; + con->out_msg_pos.page++; + con->out_msg_pos.did_page_crc = 0; + } + } + + dout("write_partial_msg_pages %p msg %p done\n", con, msg); + + /* prepare and queue up footer, too */ + if (!crc) + con->out_msg->footer.flags |= CEPH_MSG_FOOTER_NOCRC; + con->out_kvec_bytes = 0; + con->out_kvec_left = 0; + con->out_kvec_cur = con->out_kvec; + prepare_write_message_footer(con, 0); + ret = 1; +out: + return ret; +} + +/* + * write some zeros + */ +static int write_partial_skip(struct ceph_connection *con) +{ + int ret; + + while (con->out_skip > 0) { + struct kvec iov = { + .iov_base = page_address(con->msgr->zero_page), + .iov_len = min(con->out_skip, (int)PAGE_CACHE_SIZE) + }; + + ret = ceph_tcp_sendmsg(con->sock, &iov, 1, iov.iov_len, 1); + if (ret <= 0) + goto out; + con->out_skip -= ret; + } + ret = 1; +out: + return ret; +} + +/* + * Prepare to read connection handshake, or an ack. + */ +static void prepare_read_connect(struct ceph_connection *con) +{ + dout("prepare_read_connect %p\n", con); + con->in_base_pos = 0; +} + +static void prepare_read_ack(struct ceph_connection *con) +{ + dout("prepare_read_ack %p\n", con); + con->in_base_pos = 0; +} + +static void prepare_read_tag(struct ceph_connection *con) +{ + dout("prepare_read_tag %p\n", con); + con->in_base_pos = 0; + con->in_tag = CEPH_MSGR_TAG_READY; +} + +/* + * Prepare to read a message. + */ +static int prepare_read_message(struct ceph_connection *con) +{ + dout("prepare_read_message %p\n", con); + BUG_ON(con->in_msg != NULL); + con->in_base_pos = 0; + con->in_front_crc = con->in_middle_crc = con->in_data_crc = 0; + return 0; +} + + +static int read_partial(struct ceph_connection *con, + int *to, int size, void *object) +{ + *to += size; + while (con->in_base_pos < *to) { + int left = *to - con->in_base_pos; + int have = size - left; + int ret = ceph_tcp_recvmsg(con->sock, object + have, left); + if (ret <= 0) + return ret; + con->in_base_pos += ret; + } + return 1; +} + + +/* + * Read all or part of the connect-side handshake on a new connection + */ +static int read_partial_connect(struct ceph_connection *con) +{ + int ret, to = 0; + + dout("read_partial_connect %p at %d\n", con, con->in_base_pos); + + /* peer's banner */ + ret = read_partial(con, &to, strlen(CEPH_BANNER), con->in_banner); + if (ret <= 0) + goto out; + ret = read_partial(con, &to, sizeof(con->actual_peer_addr), + &con->actual_peer_addr); + if (ret <= 0) + goto out; + ret = read_partial(con, &to, sizeof(con->peer_addr_for_me), + &con->peer_addr_for_me); + if (ret <= 0) + goto out; + ret = read_partial(con, &to, sizeof(con->in_reply), &con->in_reply); + if (ret <= 0) + goto out; + + dout("read_partial_connect %p connect_seq = %u, global_seq = %u\n", + con, le32_to_cpu(con->in_reply.connect_seq), + le32_to_cpu(con->in_reply.global_seq)); +out: + return ret; +} + +/* + * Verify the hello banner looks okay. + */ +static int verify_hello(struct ceph_connection *con) +{ + if (memcmp(con->in_banner, CEPH_BANNER, strlen(CEPH_BANNER))) { + pr_err("connect to/from %s has bad banner\n", + pr_addr(&con->peer_addr.in_addr)); + con->error_msg = "protocol error, bad banner"; + return -1; + } + return 0; +} + +static bool addr_is_blank(struct sockaddr_storage *ss) +{ + switch (ss->ss_family) { + case AF_INET: + return ((struct sockaddr_in *)ss)->sin_addr.s_addr == 0; + case AF_INET6: + return + ((struct sockaddr_in6 *)ss)->sin6_addr.s6_addr32[0] == 0 && + ((struct sockaddr_in6 *)ss)->sin6_addr.s6_addr32[1] == 0 && + ((struct sockaddr_in6 *)ss)->sin6_addr.s6_addr32[2] == 0 && + ((struct sockaddr_in6 *)ss)->sin6_addr.s6_addr32[3] == 0; + } + return false; +} + +static int addr_port(struct sockaddr_storage *ss) +{ + switch (ss->ss_family) { + case AF_INET: + return ((struct sockaddr_in *)ss)->sin_port; + case AF_INET6: + return ((struct sockaddr_in6 *)ss)->sin6_port; + } + return 0; +} + +static void addr_set_port(struct sockaddr_storage *ss, int p) +{ + switch (ss->ss_family) { + case AF_INET: + ((struct sockaddr_in *)ss)->sin_port = htons(p); + case AF_INET6: + ((struct sockaddr_in6 *)ss)->sin6_port = htons(p); + } +} + +/* + * Parse an ip[:port] list into an addr array. Use the default + * monitor port if a port isn't specified. + */ +int ceph_parse_ips(const char *c, const char *end, + struct ceph_entity_addr *addr, + int max_count, int *count) +{ + int i; + const char *p = c; + + dout("parse_ips on '%.*s'\n", (int)(end-c), c); + for (i = 0; i < max_count; i++) { + const char *ipend; + struct sockaddr_storage *ss = &addr[i].in_addr; + struct sockaddr_in *in4 = (void *)ss; + struct sockaddr_in6 *in6 = (void *)ss; + int port; + + memset(ss, 0, sizeof(*ss)); + if (in4_pton(p, end - p, (u8 *)&in4->sin_addr.s_addr, + ',', &ipend)) { + ss->ss_family = AF_INET; + } else if (in6_pton(p, end - p, (u8 *)&in6->sin6_addr.s6_addr, + ',', &ipend)) { + ss->ss_family = AF_INET6; + } else { + goto bad; + } + p = ipend; + + /* port? */ + if (p < end && *p == ':') { + port = 0; + p++; + while (p < end && *p >= '0' && *p <= '9') { + port = (port * 10) + (*p - '0'); + p++; + } + if (port > 65535 || port == 0) + goto bad; + } else { + port = CEPH_MON_PORT; + } + + addr_set_port(ss, port); + + dout("parse_ips got %s\n", pr_addr(ss)); + + if (p == end) + break; + if (*p != ',') + goto bad; + p++; + } + + if (p != end) + goto bad; + + if (count) + *count = i + 1; + return 0; + +bad: + pr_err("parse_ips bad ip '%s'\n", c); + return -EINVAL; +} + +static int process_connect(struct ceph_connection *con) +{ + dout("process_connect on %p tag %d\n", con, (int)con->in_tag); + + if (verify_hello(con) < 0) + return -1; + + /* + * Make sure the other end is who we wanted. note that the other + * end may not yet know their ip address, so if it's 0.0.0.0, give + * them the benefit of the doubt. + */ + if (!ceph_entity_addr_is_local(&con->peer_addr, + &con->actual_peer_addr) && + !(addr_is_blank(&con->actual_peer_addr.in_addr) && + con->actual_peer_addr.nonce == con->peer_addr.nonce)) { + pr_err("wrong peer, want %s/%d, " + "got %s/%d, wtf\n", + pr_addr(&con->peer_addr.in_addr), + con->peer_addr.nonce, + pr_addr(&con->actual_peer_addr.in_addr), + con->actual_peer_addr.nonce); + con->error_msg = "protocol error, wrong peer"; + return -1; + } + + /* + * did we learn our address? + */ + if (addr_is_blank(&con->msgr->inst.addr.in_addr)) { + int port = addr_port(&con->msgr->inst.addr.in_addr); + + memcpy(&con->msgr->inst.addr.in_addr, + &con->peer_addr_for_me.in_addr, + sizeof(con->peer_addr_for_me.in_addr)); + addr_set_port(&con->msgr->inst.addr.in_addr, port); + dout("process_connect learned my addr is %s\n", + pr_addr(&con->msgr->inst.addr.in_addr)); + } + + switch (con->in_reply.tag) { + case CEPH_MSGR_TAG_BADPROTOVER: + dout("process_connect got BADPROTOVER my %d != their %d\n", + le32_to_cpu(con->out_connect.protocol_version), + le32_to_cpu(con->in_reply.protocol_version)); + pr_err("%s%lld %s protocol version mismatch," + " my %d != server's %d\n", + ENTITY_NAME(con->peer_name), + pr_addr(&con->peer_addr.in_addr), + le32_to_cpu(con->out_connect.protocol_version), + le32_to_cpu(con->in_reply.protocol_version)); + con->error_msg = "protocol version mismatch"; + if (con->ops->bad_proto) + con->ops->bad_proto(con); + reset_connection(con); + set_bit(CLOSED, &con->state); /* in case there's queued work */ + return -1; + + + case CEPH_MSGR_TAG_RESETSESSION: + /* + * If we connected with a large connect_seq but the peer + * has no record of a session with us (no connection, or + * connect_seq == 0), they will send RESETSESION to indicate + * that they must have reset their session, and may have + * dropped messages. + */ + dout("process_connect got RESET peer seq %u\n", + le32_to_cpu(con->in_connect.connect_seq)); + pr_err("%s%lld %s connection reset\n", + ENTITY_NAME(con->peer_name), + pr_addr(&con->peer_addr.in_addr)); + reset_connection(con); + prepare_write_connect_retry(con->msgr, con); + prepare_read_connect(con); + + /* Tell ceph about it. */ + pr_info("reset on %s%lld\n", ENTITY_NAME(con->peer_name)); + if (con->ops->peer_reset) + con->ops->peer_reset(con); + break; + + case CEPH_MSGR_TAG_RETRY_SESSION: + /* + * If we sent a smaller connect_seq than the peer has, try + * again with a larger value. + */ + dout("process_connect got RETRY my seq = %u, peer_seq = %u\n", + le32_to_cpu(con->out_connect.connect_seq), + le32_to_cpu(con->in_connect.connect_seq)); + con->connect_seq = le32_to_cpu(con->in_connect.connect_seq); + prepare_write_connect_retry(con->msgr, con); + prepare_read_connect(con); + break; + + case CEPH_MSGR_TAG_RETRY_GLOBAL: + /* + * If we sent a smaller global_seq than the peer has, try + * again with a larger value. + */ + dout("process_connect got RETRY_GLOBAL my %u, peer_gseq = %u\n", + con->peer_global_seq, + le32_to_cpu(con->in_connect.global_seq)); + get_global_seq(con->msgr, + le32_to_cpu(con->in_connect.global_seq)); + prepare_write_connect_retry(con->msgr, con); + prepare_read_connect(con); + break; + + case CEPH_MSGR_TAG_READY: + clear_bit(CONNECTING, &con->state); + if (con->in_reply.flags & CEPH_MSG_CONNECT_LOSSY) + set_bit(LOSSYRX, &con->state); + con->peer_global_seq = le32_to_cpu(con->in_reply.global_seq); + con->connect_seq++; + dout("process_connect got READY gseq %d cseq %d (%d)\n", + con->peer_global_seq, + le32_to_cpu(con->in_reply.connect_seq), + con->connect_seq); + WARN_ON(con->connect_seq != + le32_to_cpu(con->in_reply.connect_seq)); + + con->delay = 0; /* reset backoff memory */ + prepare_read_tag(con); + break; + + case CEPH_MSGR_TAG_WAIT: + /* + * If there is a connection race (we are opening + * connections to each other), one of us may just have + * to WAIT. This shouldn't happen if we are the + * client. + */ + pr_err("process_connect peer connecting WAIT\n"); + + default: + pr_err("connect protocol error, will retry\n"); + con->error_msg = "protocol error, garbage tag during connect"; + return -1; + } + return 0; +} + + +/* + * read (part of) an ack + */ +static int read_partial_ack(struct ceph_connection *con) +{ + int to = 0; + + return read_partial(con, &to, sizeof(con->in_temp_ack), + &con->in_temp_ack); +} + + +/* + * We can finally discard anything that's been acked. + */ +static void process_ack(struct ceph_connection *con) +{ + struct ceph_msg *m; + u64 ack = le64_to_cpu(con->in_temp_ack); + u64 seq; + + mutex_lock(&con->out_mutex); + while (!list_empty(&con->out_sent)) { + m = list_first_entry(&con->out_sent, struct ceph_msg, + list_head); + seq = le64_to_cpu(m->hdr.seq); + if (seq > ack) + break; + dout("got ack for seq %llu type %d at %p\n", seq, + le16_to_cpu(m->hdr.type), m); + ceph_msg_remove(m); + } + mutex_unlock(&con->out_mutex); + prepare_read_tag(con); +} + + + + + + +/* + * read (part of) a message. + */ +static int read_partial_message(struct ceph_connection *con) +{ + struct ceph_msg *m = con->in_msg; + void *p; + int ret; + int to, want, left; + unsigned front_len, middle_len, data_len, data_off; + int datacrc = con->msgr->nocrc; + + dout("read_partial_message con %p msg %p\n", con, m); + + /* header */ + while (con->in_base_pos < sizeof(con->in_hdr)) { + left = sizeof(con->in_hdr) - con->in_base_pos; + ret = ceph_tcp_recvmsg(con->sock, + (char *)&con->in_hdr + con->in_base_pos, + left); + if (ret <= 0) + return ret; + con->in_base_pos += ret; + if (con->in_base_pos == sizeof(con->in_hdr)) { + u32 crc = crc32c(0, (void *)&con->in_hdr, + sizeof(con->in_hdr) - sizeof(con->in_hdr.crc)); + if (crc != le32_to_cpu(con->in_hdr.crc)) { + pr_err("read_partial_message bad hdr " + " crc %u != expected %u\n", + crc, con->in_hdr.crc); + return -EBADMSG; + } + } + } + + front_len = le32_to_cpu(con->in_hdr.front_len); + if (front_len > CEPH_MSG_MAX_FRONT_LEN) + return -EIO; + middle_len = le32_to_cpu(con->in_hdr.middle_len); + if (middle_len > CEPH_MSG_MAX_DATA_LEN) + return -EIO; + data_len = le32_to_cpu(con->in_hdr.data_len); + if (data_len > CEPH_MSG_MAX_DATA_LEN) + return -EIO; + + /* allocate message? */ + if (!con->in_msg) { + dout("got hdr type %d front %d data %d\n", con->in_hdr.type, + con->in_hdr.front_len, con->in_hdr.data_len); + con->in_msg = con->ops->alloc_msg(con, &con->in_hdr); + if (!con->in_msg) { + /* skip this message */ + dout("alloc_msg returned NULL, skipping message\n"); + con->in_base_pos = -front_len - middle_len - data_len - + sizeof(m->footer); + con->in_tag = CEPH_MSGR_TAG_READY; + return 0; + } + if (IS_ERR(con->in_msg)) { + ret = PTR_ERR(con->in_msg); + con->in_msg = NULL; + con->error_msg = "out of memory for incoming message"; + return ret; + } + m = con->in_msg; + m->front.iov_len = 0; /* haven't read it yet */ + memcpy(&m->hdr, &con->in_hdr, sizeof(con->in_hdr)); + } + + /* front */ + while (m->front.iov_len < front_len) { + BUG_ON(m->front.iov_base == NULL); + left = front_len - m->front.iov_len; + ret = ceph_tcp_recvmsg(con->sock, (char *)m->front.iov_base + + m->front.iov_len, left); + if (ret <= 0) + return ret; + m->front.iov_len += ret; + if (m->front.iov_len == front_len) + con->in_front_crc = crc32c(0, m->front.iov_base, + m->front.iov_len); + } + + /* middle */ + while (middle_len > 0 && (!m->middle || + m->middle->vec.iov_len < middle_len)) { + if (m->middle == NULL) { + ret = -EOPNOTSUPP; + if (con->ops->alloc_middle) + ret = con->ops->alloc_middle(con, m); + if (ret < 0) { + dout("alloc_middle failed, skipping payload\n"); + con->in_base_pos = -middle_len - data_len + - sizeof(m->footer); + ceph_msg_put(con->in_msg); + con->in_msg = NULL; + con->in_tag = CEPH_MSGR_TAG_READY; + return 0; + } + m->middle->vec.iov_len = 0; + } + left = middle_len - m->middle->vec.iov_len; + ret = ceph_tcp_recvmsg(con->sock, + (char *)m->middle->vec.iov_base + + m->middle->vec.iov_len, left); + if (ret <= 0) + return ret; + m->middle->vec.iov_len += ret; + if (m->middle->vec.iov_len == middle_len) + con->in_middle_crc = crc32c(0, m->middle->vec.iov_base, + m->middle->vec.iov_len); + } + + /* (page) data */ + data_off = le16_to_cpu(m->hdr.data_off); + if (data_len == 0) + goto no_data; + + if (m->nr_pages == 0) { + con->in_msg_pos.page = 0; + con->in_msg_pos.page_pos = data_off & ~PAGE_MASK; + con->in_msg_pos.data_pos = 0; + /* find pages for data payload */ + want = calc_pages_for(data_off & ~PAGE_MASK, data_len); + ret = -1; + if (con->ops->prepare_pages) + ret = con->ops->prepare_pages(con, m, want); + if (ret < 0) { + dout("%p prepare_pages failed, skipping payload\n", m); + con->in_base_pos = -data_len - sizeof(m->footer); + ceph_msg_put(con->in_msg); + con->in_msg = NULL; + con->in_tag = CEPH_MSGR_TAG_READY; + return 0; + } + BUG_ON(m->nr_pages < want); + } + while (con->in_msg_pos.data_pos < data_len) { + left = min((int)(data_len - con->in_msg_pos.data_pos), + (int)(PAGE_SIZE - con->in_msg_pos.page_pos)); + BUG_ON(m->pages == NULL); + p = kmap(m->pages[con->in_msg_pos.page]); + ret = ceph_tcp_recvmsg(con->sock, p + con->in_msg_pos.page_pos, + left); + if (ret > 0 && datacrc) + con->in_data_crc = + crc32c(con->in_data_crc, + p + con->in_msg_pos.page_pos, ret); + kunmap(m->pages[con->in_msg_pos.page]); + if (ret <= 0) + return ret; + con->in_msg_pos.data_pos += ret; + con->in_msg_pos.page_pos += ret; + if (con->in_msg_pos.page_pos == PAGE_SIZE) { + con->in_msg_pos.page_pos = 0; + con->in_msg_pos.page++; + } + } + +no_data: + /* footer */ + to = sizeof(m->hdr) + sizeof(m->footer); + while (con->in_base_pos < to) { + left = to - con->in_base_pos; + ret = ceph_tcp_recvmsg(con->sock, (char *)&m->footer + + (con->in_base_pos - sizeof(m->hdr)), + left); + if (ret <= 0) + return ret; + con->in_base_pos += ret; + } + dout("read_partial_message got msg %p %d (%u) + %d (%u) + %d (%u)\n", + m, front_len, m->footer.front_crc, middle_len, + m->footer.middle_crc, data_len, m->footer.data_crc); + + /* crc ok? */ + if (con->in_front_crc != le32_to_cpu(m->footer.front_crc)) { + pr_err("read_partial_message %p front crc %u != exp. %u\n", + m, con->in_front_crc, m->footer.front_crc); + return -EBADMSG; + } + if (con->in_middle_crc != le32_to_cpu(m->footer.middle_crc)) { + pr_err("read_partial_message %p middle crc %u != exp %u\n", + m, con->in_middle_crc, m->footer.middle_crc); + return -EBADMSG; + } + if (datacrc && + (m->footer.flags & CEPH_MSG_FOOTER_NOCRC) == 0 && + con->in_data_crc != le32_to_cpu(m->footer.data_crc)) { + pr_err("read_partial_message %p data crc %u != exp. %u\n", m, + con->in_data_crc, le32_to_cpu(m->footer.data_crc)); + return -EBADMSG; + } + + return 1; /* done! */ +} + +/* + * Process message. This happens in the worker thread. The callback should + * be careful not to do anything that waits on other incoming messages or it + * may deadlock. + */ +static void process_message(struct ceph_connection *con) +{ + struct ceph_msg *msg = con->in_msg; + + con->in_msg = NULL; + + /* if first message, set peer_name */ + if (con->peer_name.type == 0) + con->peer_name = msg->hdr.src.name; + + mutex_lock(&con->out_mutex); + con->in_seq++; + mutex_unlock(&con->out_mutex); + + dout("===== %p %llu from %s%lld %d=%s len %d+%d (%u %u %u) =====\n", + msg, le64_to_cpu(msg->hdr.seq), + ENTITY_NAME(msg->hdr.src.name), + le16_to_cpu(msg->hdr.type), + ceph_msg_type_name(le16_to_cpu(msg->hdr.type)), + le32_to_cpu(msg->hdr.front_len), + le32_to_cpu(msg->hdr.data_len), + con->in_front_crc, con->in_middle_crc, con->in_data_crc); + con->ops->dispatch(con, msg); + prepare_read_tag(con); +} + + +/* + * Write something to the socket. Called in a worker thread when the + * socket appears to be writeable and we have something ready to send. + */ +static int try_write(struct ceph_connection *con) +{ + struct ceph_messenger *msgr = con->msgr; + int ret = 1; + + dout("try_write start %p state %lu nref %d\n", con, con->state, + atomic_read(&con->nref)); + + mutex_lock(&con->out_mutex); +more: + dout("try_write out_kvec_bytes %d\n", con->out_kvec_bytes); + + /* open the socket first? */ + if (con->sock == NULL) { + /* + * if we were STANDBY and are reconnecting _this_ + * connection, bump connect_seq now. Always bump + * global_seq. + */ + if (test_and_clear_bit(STANDBY, &con->state)) + con->connect_seq++; + + prepare_write_connect(msgr, con); + prepare_read_connect(con); + set_bit(CONNECTING, &con->state); + + con->in_tag = CEPH_MSGR_TAG_READY; + dout("try_write initiating connect on %p new state %lu\n", + con, con->state); + con->sock = ceph_tcp_connect(con); + if (IS_ERR(con->sock)) { + con->sock = NULL; + con->error_msg = "connect error"; + ret = -1; + goto out; + } + } + +more_kvec: + /* kvec data queued? */ + if (con->out_skip) { + ret = write_partial_skip(con); + if (ret <= 0) + goto done; + if (ret < 0) { + dout("try_write write_partial_skip err %d\n", ret); + goto done; + } + } + if (con->out_kvec_left) { + ret = write_partial_kvec(con); + if (ret <= 0) + goto done; + if (ret < 0) { + dout("try_write write_partial_kvec err %d\n", ret); + goto done; + } + } + + /* msg pages? */ + if (con->out_msg) { + ret = write_partial_msg_pages(con); + if (ret == 1) + goto more_kvec; /* we need to send the footer, too! */ + if (ret == 0) + goto done; + if (ret < 0) { + dout("try_write write_partial_msg_pages err %d\n", + ret); + goto done; + } + } + + if (!test_bit(CONNECTING, &con->state)) { + /* is anything else pending? */ + if (!list_empty(&con->out_queue)) { + prepare_write_message(con); + goto more; + } + if (con->in_seq > con->in_seq_acked) { + prepare_write_ack(con); + goto more; + } + if (test_and_clear_bit(KEEPALIVE_PENDING, &con->state)) { + prepare_write_keepalive(con); + goto more; + } + } + + /* Nothing to do! */ + clear_bit(WRITE_PENDING, &con->state); + dout("try_write nothing else to write.\n"); +done: + ret = 0; +out: + mutex_unlock(&con->out_mutex); + dout("try_write done on %p\n", con); + return ret; +} + + + +/* + * Read what we can from the socket. + */ +static int try_read(struct ceph_connection *con) +{ + struct ceph_messenger *msgr; + int ret = -1; + + if (!con->sock) + return 0; + + if (test_bit(STANDBY, &con->state)) + return 0; + + dout("try_read start on %p\n", con); + msgr = con->msgr; + +more: + dout("try_read tag %d in_base_pos %d\n", (int)con->in_tag, + con->in_base_pos); + if (test_bit(CONNECTING, &con->state)) { + dout("try_read connecting\n"); + ret = read_partial_connect(con); + if (ret <= 0) + goto done; + if (process_connect(con) < 0) { + ret = -1; + goto out; + } + goto more; + } + + if (con->in_base_pos < 0) { + /* + * skipping + discarding content. + * + * FIXME: there must be a better way to do this! + */ + static char buf[1024]; + int skip = min(1024, -con->in_base_pos); + dout("skipping %d / %d bytes\n", skip, -con->in_base_pos); + ret = ceph_tcp_recvmsg(con->sock, buf, skip); + if (ret <= 0) + goto done; + con->in_base_pos += ret; + if (con->in_base_pos) + goto more; + } + if (con->in_tag == CEPH_MSGR_TAG_READY) { + /* + * what's next? + */ + ret = ceph_tcp_recvmsg(con->sock, &con->in_tag, 1); + if (ret <= 0) + goto done; + dout("try_read got tag %d\n", (int)con->in_tag); + switch (con->in_tag) { + case CEPH_MSGR_TAG_MSG: + prepare_read_message(con); + break; + case CEPH_MSGR_TAG_ACK: + prepare_read_ack(con); + break; + case CEPH_MSGR_TAG_CLOSE: + set_bit(CLOSED, &con->state); /* fixme */ + goto done; + default: + goto bad_tag; + } + } + if (con->in_tag == CEPH_MSGR_TAG_MSG) { + ret = read_partial_message(con); + if (ret <= 0) { + switch (ret) { + case -EBADMSG: + con->error_msg = "bad crc"; + ret = -EIO; + goto out; + case -EIO: + con->error_msg = "io error"; + goto out; + default: + goto done; + } + } + if (con->in_tag == CEPH_MSGR_TAG_READY) + goto more; + process_message(con); + goto more; + } + if (con->in_tag == CEPH_MSGR_TAG_ACK) { + ret = read_partial_ack(con); + if (ret <= 0) + goto done; + process_ack(con); + goto more; + } + +done: + ret = 0; +out: + dout("try_read done on %p\n", con); + return ret; + +bad_tag: + pr_err("try_read bad con->in_tag = %d\n", (int)con->in_tag); + con->error_msg = "protocol error, garbage tag"; + ret = -1; + goto out; +} + + +/* + * Atomically queue work on a connection. Bump @con reference to + * avoid races with connection teardown. + * + * There is some trickery going on with QUEUED and BUSY because we + * only want a _single_ thread operating on each connection at any + * point in time, but we want to use all available CPUs. + * + * The worker thread only proceeds if it can atomically set BUSY. It + * clears QUEUED and does it's thing. When it thinks it's done, it + * clears BUSY, then rechecks QUEUED.. if it's set again, it loops + * (tries again to set BUSY). + * + * To queue work, we first set QUEUED, _then_ if BUSY isn't set, we + * try to queue work. If that fails (work is already queued, or BUSY) + * we give up (work also already being done or is queued) but leave QUEUED + * set so that the worker thread will loop if necessary. + */ +static void queue_con(struct ceph_connection *con) +{ + if (test_bit(DEAD, &con->state)) { + dout("queue_con %p ignoring: DEAD\n", + con); + return; + } + + if (!con->ops->get(con)) { + dout("queue_con %p ref count 0\n", con); + return; + } + + set_bit(QUEUED, &con->state); + if (test_bit(BUSY, &con->state)) { + dout("queue_con %p - already BUSY\n", con); + con->ops->put(con); + } else if (!queue_work(ceph_msgr_wq, &con->work.work)) { + dout("queue_con %p - already queued\n", con); + con->ops->put(con); + } else { + dout("queue_con %p\n", con); + } +} + +/* + * Do some work on a connection. Drop a connection ref when we're done. + */ +static void con_work(struct work_struct *work) +{ + struct ceph_connection *con = container_of(work, struct ceph_connection, + work.work); + int backoff = 0; + +more: + if (test_and_set_bit(BUSY, &con->state) != 0) { + dout("con_work %p BUSY already set\n", con); + goto out; + } + dout("con_work %p start, clearing QUEUED\n", con); + clear_bit(QUEUED, &con->state); + + if (test_bit(CLOSED, &con->state)) { /* e.g. if we are replaced */ + dout("con_work CLOSED\n"); + con_close_socket(con); + goto done; + } + if (test_and_clear_bit(OPENING, &con->state)) { + /* reopen w/ new peer */ + dout("con_work OPENING\n"); + con_close_socket(con); + } + + if (test_and_clear_bit(SOCK_CLOSED, &con->state) || + try_read(con) < 0 || + try_write(con) < 0) { + backoff = 1; + ceph_fault(con); /* error/fault path */ + } + +done: + clear_bit(BUSY, &con->state); + dout("con->state=%lu\n", con->state); + if (test_bit(QUEUED, &con->state)) { + if (!backoff) { + dout("con_work %p QUEUED reset, looping\n", con); + goto more; + } + dout("con_work %p QUEUED reset, but just faulted\n", con); + clear_bit(QUEUED, &con->state); + } + dout("con_work %p done\n", con); + +out: + con->ops->put(con); +} + + +/* + * Generic error/fault handler. A retry mechanism is used with + * exponential backoff + */ +static void ceph_fault(struct ceph_connection *con) +{ + pr_err("%s%lld %s %s\n", ENTITY_NAME(con->peer_name), + pr_addr(&con->peer_addr.in_addr), con->error_msg); + dout("fault %p state %lu to peer %s\n", + con, con->state, pr_addr(&con->peer_addr.in_addr)); + + if (test_bit(LOSSYTX, &con->state)) { + dout("fault on LOSSYTX channel\n"); + goto out; + } + + clear_bit(BUSY, &con->state); /* to avoid an improbable race */ + + con_close_socket(con); + con->in_msg = NULL; + + /* If there are no messages in the queue, place the connection + * in a STANDBY state (i.e., don't try to reconnect just yet). */ + mutex_lock(&con->out_mutex); + if (list_empty(&con->out_queue) && !con->out_keepalive_pending) { + dout("fault setting STANDBY\n"); + set_bit(STANDBY, &con->state); + mutex_unlock(&con->out_mutex); + goto out; + } + + /* Requeue anything that hasn't been acked, and retry after a + * delay. */ + list_splice_init(&con->out_sent, &con->out_queue); + mutex_unlock(&con->out_mutex); + + if (con->delay == 0) + con->delay = BASE_DELAY_INTERVAL; + else if (con->delay < MAX_DELAY_INTERVAL) + con->delay *= 2; + + /* explicitly schedule work to try to reconnect again later. */ + dout("fault queueing %p delay %lu\n", con, con->delay); + con->ops->get(con); + if (queue_delayed_work(ceph_msgr_wq, &con->work, + round_jiffies_relative(con->delay)) == 0) + con->ops->put(con); + +out: + if (con->ops->fault) + con->ops->fault(con); +} + + + +/* + * create a new messenger instance + */ +struct ceph_messenger *ceph_messenger_create(struct ceph_entity_addr *myaddr) +{ + struct ceph_messenger *msgr; + + msgr = kzalloc(sizeof(*msgr), GFP_KERNEL); + if (msgr == NULL) + return ERR_PTR(-ENOMEM); + + spin_lock_init(&msgr->global_seq_lock); + + /* the zero page is needed if a request is "canceled" while the message + * is being written over the socket */ + msgr->zero_page = alloc_page(GFP_KERNEL | __GFP_ZERO); + if (!msgr->zero_page) { + kfree(msgr); + return ERR_PTR(-ENOMEM); + } + kmap(msgr->zero_page); + + if (myaddr) + msgr->inst.addr = *myaddr; + + /* select a random nonce */ + get_random_bytes(&msgr->inst.addr.nonce, + sizeof(msgr->inst.addr.nonce)); + + dout("messenger_create %p\n", msgr); + return msgr; +} + +void ceph_messenger_destroy(struct ceph_messenger *msgr) +{ + dout("destroy %p\n", msgr); + kunmap(msgr->zero_page); + __free_page(msgr->zero_page); + kfree(msgr); + dout("destroyed messenger %p\n", msgr); +} + +/* + * Queue up an outgoing message on the given connection. + */ +void ceph_con_send(struct ceph_connection *con, struct ceph_msg *msg) +{ + if (test_bit(CLOSED, &con->state)) { + dout("con_send %p closed, dropping %p\n", con, msg); + ceph_msg_put(msg); + return; + } + + /* set src+dst */ + msg->hdr.src = con->msgr->inst; + msg->hdr.orig_src = con->msgr->inst; + msg->hdr.dst_erank = con->peer_addr.erank; + + /* queue */ + mutex_lock(&con->out_mutex); + BUG_ON(!list_empty(&msg->list_head)); + list_add_tail(&msg->list_head, &con->out_queue); + dout("----- %p to %s%lld %d=%s len %d+%d+%d -----\n", msg, + ENTITY_NAME(con->peer_name), le16_to_cpu(msg->hdr.type), + ceph_msg_type_name(le16_to_cpu(msg->hdr.type)), + le32_to_cpu(msg->hdr.front_len), + le32_to_cpu(msg->hdr.middle_len), + le32_to_cpu(msg->hdr.data_len)); + mutex_unlock(&con->out_mutex); + + /* if there wasn't anything waiting to send before, queue + * new work */ + if (test_and_set_bit(WRITE_PENDING, &con->state) == 0) + queue_con(con); +} + +/* + * Revoke a message that was previously queued for send + */ +void ceph_con_revoke(struct ceph_connection *con, struct ceph_msg *msg) +{ + mutex_lock(&con->out_mutex); + if (!list_empty(&msg->list_head)) { + dout("con_revoke %p msg %p\n", con, msg); + list_del_init(&msg->list_head); + ceph_msg_put(msg); + msg->hdr.seq = 0; + if (con->out_msg == msg) + con->out_msg = NULL; + if (con->out_kvec_is_msg) { + con->out_skip = con->out_kvec_bytes; + con->out_kvec_is_msg = false; + } + } else { + dout("con_revoke %p msg %p - not queued (sent?)\n", con, msg); + } + mutex_unlock(&con->out_mutex); +} + +/* + * Queue a keepalive byte to ensure the tcp connection is alive. + */ +void ceph_con_keepalive(struct ceph_connection *con) +{ + if (test_and_set_bit(KEEPALIVE_PENDING, &con->state) == 0 && + test_and_set_bit(WRITE_PENDING, &con->state) == 0) + queue_con(con); +} + + +/* + * construct a new message with given type, size + * the new msg has a ref count of 1. + */ +struct ceph_msg *ceph_msg_new(int type, int front_len, + int page_len, int page_off, struct page **pages) +{ + struct ceph_msg *m; + + m = kmalloc(sizeof(*m), GFP_NOFS); + if (m == NULL) + goto out; + atomic_set(&m->nref, 1); + INIT_LIST_HEAD(&m->list_head); + + m->hdr.type = cpu_to_le16(type); + m->hdr.front_len = cpu_to_le32(front_len); + m->hdr.middle_len = 0; + m->hdr.data_len = cpu_to_le32(page_len); + m->hdr.data_off = cpu_to_le16(page_off); + m->hdr.priority = cpu_to_le16(CEPH_MSG_PRIO_DEFAULT); + m->footer.front_crc = 0; + m->footer.middle_crc = 0; + m->footer.data_crc = 0; + m->front_max = front_len; + m->front_is_vmalloc = false; + m->more_to_follow = false; + m->pool = NULL; + + /* front */ + if (front_len) { + if (front_len > PAGE_CACHE_SIZE) { + m->front.iov_base = __vmalloc(front_len, GFP_NOFS, + PAGE_KERNEL); + m->front_is_vmalloc = true; + } else { + m->front.iov_base = kmalloc(front_len, GFP_NOFS); + } + if (m->front.iov_base == NULL) { + pr_err("msg_new can't allocate %d bytes\n", + front_len); + goto out2; + } + } else { + m->front.iov_base = NULL; + } + m->front.iov_len = front_len; + + /* middle */ + m->middle = NULL; + + /* data */ + m->nr_pages = calc_pages_for(page_off, page_len); + m->pages = pages; + + dout("ceph_msg_new %p page %d~%d -> %d\n", m, page_off, page_len, + m->nr_pages); + return m; + +out2: + ceph_msg_put(m); +out: + pr_err("msg_new can't create type %d len %d\n", type, front_len); + return ERR_PTR(-ENOMEM); +} + +/* + * Generic message allocator, for incoming messages. + */ +struct ceph_msg *ceph_alloc_msg(struct ceph_connection *con, + struct ceph_msg_header *hdr) +{ + int type = le16_to_cpu(hdr->type); + int front_len = le32_to_cpu(hdr->front_len); + struct ceph_msg *msg = ceph_msg_new(type, front_len, 0, 0, NULL); + + if (!msg) { + pr_err("unable to allocate msg type %d len %d\n", + type, front_len); + return ERR_PTR(-ENOMEM); + } + return msg; +} + +/* + * Allocate "middle" portion of a message, if it is needed and wasn't + * allocated by alloc_msg. This allows us to read a small fixed-size + * per-type header in the front and then gracefully fail (i.e., + * propagate the error to the caller based on info in the front) when + * the middle is too large. + */ +int ceph_alloc_middle(struct ceph_connection *con, struct ceph_msg *msg) +{ + int type = le16_to_cpu(msg->hdr.type); + int middle_len = le32_to_cpu(msg->hdr.middle_len); + + dout("alloc_middle %p type %d %s middle_len %d\n", msg, type, + ceph_msg_type_name(type), middle_len); + BUG_ON(!middle_len); + BUG_ON(msg->middle); + + msg->middle = ceph_buffer_new_alloc(middle_len, GFP_NOFS); + if (!msg->middle) + return -ENOMEM; + return 0; +} + + +/* + * Free a generically kmalloc'd message. + */ +void ceph_msg_kfree(struct ceph_msg *m) +{ + dout("msg_kfree %p\n", m); + if (m->front_is_vmalloc) + vfree(m->front.iov_base); + else + kfree(m->front.iov_base); + kfree(m); +} + +/* + * Drop a msg ref. Destroy as needed. + */ +void ceph_msg_put(struct ceph_msg *m) +{ + dout("ceph_msg_put %p %d -> %d\n", m, atomic_read(&m->nref), + atomic_read(&m->nref)-1); + if (atomic_read(&m->nref) <= 0) { + pr_err("bad ceph_msg_put on %p %llu %d=%s %d+%d\n", + m, le64_to_cpu(m->hdr.seq), + le16_to_cpu(m->hdr.type), + ceph_msg_type_name(le16_to_cpu(m->hdr.type)), + le32_to_cpu(m->hdr.front_len), + le32_to_cpu(m->hdr.data_len)); + WARN_ON(1); + } + if (atomic_dec_and_test(&m->nref)) { + dout("ceph_msg_put last one on %p\n", m); + WARN_ON(!list_empty(&m->list_head)); + + /* drop middle, data, if any */ + if (m->middle) { + ceph_buffer_put(m->middle); + m->middle = NULL; + } + m->nr_pages = 0; + m->pages = NULL; + + if (m->pool) + ceph_msgpool_put(m->pool, m); + else + ceph_msg_kfree(m); + } +} diff --git a/fs/ceph/messenger.h b/fs/ceph/messenger.h new file mode 100644 index 0000000..dcd98b6 --- /dev/null +++ b/fs/ceph/messenger.h @@ -0,0 +1,243 @@ +#ifndef __FS_CEPH_MESSENGER_H +#define __FS_CEPH_MESSENGER_H + +#include +#include +#include +#include +#include +#include + +#include "types.h" +#include "buffer.h" + +struct ceph_msg; +struct ceph_connection; + +extern struct workqueue_struct *ceph_msgr_wq; /* receive work queue */ + +/* + * Ceph defines these callbacks for handling connection events. + */ +struct ceph_connection_operations { + struct ceph_connection *(*get)(struct ceph_connection *); + void (*put)(struct ceph_connection *); + + /* handle an incoming message. */ + void (*dispatch) (struct ceph_connection *con, struct ceph_msg *m); + + /* protocol version mismatch */ + void (*bad_proto) (struct ceph_connection *con); + + /* there was some error on the socket (disconnect, whatever) */ + void (*fault) (struct ceph_connection *con); + + /* a remote host as terminated a message exchange session, and messages + * we sent (or they tried to send us) may be lost. */ + void (*peer_reset) (struct ceph_connection *con); + + struct ceph_msg * (*alloc_msg) (struct ceph_connection *con, + struct ceph_msg_header *hdr); + int (*alloc_middle) (struct ceph_connection *con, + struct ceph_msg *msg); + /* an incoming message has a data payload; tell me what pages I + * should read the data into. */ + int (*prepare_pages) (struct ceph_connection *con, struct ceph_msg *m, + int want); +}; + +extern const char *ceph_name_type_str(int t); + +/* use format string %s%d */ +#define ENTITY_NAME(n) ceph_name_type_str((n).type), le64_to_cpu((n).num) + +struct ceph_messenger { + struct ceph_entity_inst inst; /* my name+address */ + struct page *zero_page; /* used in certain error cases */ + + bool nocrc; + + /* + * the global_seq counts connections i (attempt to) initiate + * in order to disambiguate certain connect race conditions. + */ + u32 global_seq; + spinlock_t global_seq_lock; +}; + +/* + * a single message. it contains a header (src, dest, message type, etc.), + * footer (crc values, mainly), a "front" message body, and possibly a + * data payload (stored in some number of pages). + */ +struct ceph_msg { + struct ceph_msg_header hdr; /* header */ + struct ceph_msg_footer footer; /* footer */ + struct kvec front; /* unaligned blobs of message */ + struct ceph_buffer *middle; + struct page **pages; /* data payload. NOT OWNER. */ + unsigned nr_pages; /* size of page array */ + struct list_head list_head; + atomic_t nref; + bool front_is_vmalloc; + bool more_to_follow; + int front_max; + + struct ceph_msgpool *pool; +}; + +struct ceph_msg_pos { + int page, page_pos; /* which page; offset in page */ + int data_pos; /* offset in data payload */ + int did_page_crc; /* true if we've calculated crc for current page */ +}; + +/* ceph connection fault delay defaults, for exponential backoff */ +#define BASE_DELAY_INTERVAL (HZ/2) +#define MAX_DELAY_INTERVAL (5 * 60 * HZ) + +/* + * ceph_connection state bit flags + * + * QUEUED and BUSY are used together to ensure that only a single + * thread is currently opening, reading or writing data to the socket. + */ +#define LOSSYTX 0 /* we can close channel or drop messages on errors */ +#define LOSSYRX 1 /* peer may reset/drop messages */ +#define CONNECTING 2 +#define KEEPALIVE_PENDING 3 +#define WRITE_PENDING 4 /* we have data ready to send */ +#define QUEUED 5 /* there is work queued on this connection */ +#define BUSY 6 /* work is being done */ +#define STANDBY 8 /* no outgoing messages, socket closed. we keep + * the ceph_connection around to maintain shared + * state with the peer. */ +#define CLOSED 10 /* we've closed the connection */ +#define SOCK_CLOSED 11 /* socket state changed to closed */ +#define REGISTERED 12 /* connection appears in con_tree */ +#define OPENING 13 /* open connection w/ (possibly new) peer */ +#define DEAD 14 /* dead, about to kfree */ + +/* + * A single connection with another host. + * + * We maintain a queue of outgoing messages, and some session state to + * ensure that we can preserve the lossless, ordered delivery of + * messages in the case of a TCP disconnect. + */ +struct ceph_connection { + void *private; + atomic_t nref; + + const struct ceph_connection_operations *ops; + + struct ceph_messenger *msgr; + struct socket *sock; + unsigned long state; /* connection state (see flags above) */ + const char *error_msg; /* error message, if any */ + + struct ceph_entity_addr peer_addr; /* peer address */ + struct ceph_entity_name peer_name; /* peer name */ + struct ceph_entity_addr peer_addr_for_me; + u32 connect_seq; /* identify the most recent connection + attempt for this connection, client */ + u32 peer_global_seq; /* peer's global seq for this connection */ + + /* out queue */ + struct mutex out_mutex; + struct list_head out_queue; + struct list_head out_sent; /* sending or sent but unacked */ + u64 out_seq; /* last message queued for send */ + u64 out_seq_sent; /* last message sent */ + bool out_keepalive_pending; + + u64 in_seq, in_seq_acked; /* last message received, acked */ + + /* connection negotiation temps */ + char in_banner[CEPH_BANNER_MAX_LEN]; + union { + struct { /* outgoing connection */ + struct ceph_msg_connect out_connect; + struct ceph_msg_connect_reply in_reply; + }; + struct { /* incoming */ + struct ceph_msg_connect in_connect; + struct ceph_msg_connect_reply out_reply; + }; + }; + struct ceph_entity_addr actual_peer_addr; + + /* message out temps */ + struct ceph_msg *out_msg; /* sending message (== tail of + out_sent) */ + struct ceph_msg_pos out_msg_pos; + + struct kvec out_kvec[8], /* sending header/footer data */ + *out_kvec_cur; + int out_kvec_left; /* kvec's left in out_kvec */ + int out_skip; /* skip this many bytes */ + int out_kvec_bytes; /* total bytes left */ + bool out_kvec_is_msg; /* kvec refers to out_msg */ + int out_more; /* there is more data after the kvecs */ + __le64 out_temp_ack; /* for writing an ack */ + + /* message in temps */ + struct ceph_msg_header in_hdr; + struct ceph_msg *in_msg; + struct ceph_msg_pos in_msg_pos; + u32 in_front_crc, in_middle_crc, in_data_crc; /* calculated crc */ + + char in_tag; /* protocol control byte */ + int in_base_pos; /* bytes read */ + __le64 in_temp_ack; /* for reading an ack */ + + struct delayed_work work; /* send|recv work */ + unsigned long delay; /* current delay interval */ +}; + + +extern const char *pr_addr(const struct sockaddr_storage *ss); +extern int ceph_parse_ips(const char *c, const char *end, + struct ceph_entity_addr *addr, + int max_count, int *count); + + +extern int ceph_msgr_init(void); +extern void ceph_msgr_exit(void); + +extern struct ceph_messenger *ceph_messenger_create( + struct ceph_entity_addr *myaddr); +extern void ceph_messenger_destroy(struct ceph_messenger *); + +extern void ceph_con_init(struct ceph_messenger *msgr, + struct ceph_connection *con); +extern void ceph_con_shutdown(struct ceph_connection *con); +extern void ceph_con_open(struct ceph_connection *con, + struct ceph_entity_addr *addr); +extern void ceph_con_close(struct ceph_connection *con); +extern void ceph_con_send(struct ceph_connection *con, struct ceph_msg *msg); +extern void ceph_con_revoke(struct ceph_connection *con, struct ceph_msg *msg); +extern void ceph_con_keepalive(struct ceph_connection *con); +extern struct ceph_connection *ceph_con_get(struct ceph_connection *con); +extern void ceph_con_put(struct ceph_connection *con); + +extern struct ceph_msg *ceph_msg_new(int type, int front_len, + int page_len, int page_off, + struct page **pages); +extern void ceph_msg_kfree(struct ceph_msg *m); + +extern struct ceph_msg *ceph_alloc_msg(struct ceph_connection *con, + struct ceph_msg_header *hdr); +extern int ceph_alloc_middle(struct ceph_connection *con, struct ceph_msg *msg); + + +static inline struct ceph_msg *ceph_msg_get(struct ceph_msg *msg) +{ + dout("ceph_msg_get %p %d -> %d\n", msg, atomic_read(&msg->nref), + atomic_read(&msg->nref)+1); + atomic_inc(&msg->nref); + return msg; +} +extern void ceph_msg_put(struct ceph_msg *msg); + +#endif -- cgit v0.10.2 From 8fc91fd85950d106883852c6d215614ec28cc92d Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 6 Oct 2009 11:31:13 -0700 Subject: ceph: message pools The msgpool is a basic mempool_t-like structure to preallocate messages we expect to receive over the wire. This ensures we have the necessary memory preallocated to process replies to requests, or to process unsolicited messages from various servers. Signed-off-by: Sage Weil diff --git a/fs/ceph/msgpool.c b/fs/ceph/msgpool.c new file mode 100644 index 0000000..39d4d7e --- /dev/null +++ b/fs/ceph/msgpool.c @@ -0,0 +1,167 @@ +#include "ceph_debug.h" + +#include +#include +#include +#include + +#include "msgpool.h" + +/* + * We use msg pools to preallocate memory for messages we expect to + * receive over the wire, to avoid getting ourselves into OOM + * conditions at unexpected times. We take use a few different + * strategies: + * + * - for request/response type interactions, we preallocate the + * memory needed for the response when we generate the request. + * + * - for messages we can receive at any time from the MDS, we preallocate + * a pool of messages we can re-use. + * + * - for writeback, we preallocate some number of messages to use for + * requests and their replies, so that we always make forward + * progress. + * + * The msgpool behaves like a mempool_t, but keeps preallocated + * ceph_msgs strung together on a list_head instead of using a pointer + * vector. This avoids vector reallocation when we adjust the number + * of preallocated items (which happens frequently). + */ + + +/* + * Allocate or release as necessary to meet our target pool size. + */ +static int __fill_msgpool(struct ceph_msgpool *pool) +{ + struct ceph_msg *msg; + + while (pool->num < pool->min) { + dout("fill_msgpool %p %d/%d allocating\n", pool, pool->num, + pool->min); + spin_unlock(&pool->lock); + msg = ceph_msg_new(0, pool->front_len, 0, 0, NULL); + spin_lock(&pool->lock); + if (IS_ERR(msg)) + return PTR_ERR(msg); + msg->pool = pool; + list_add(&msg->list_head, &pool->msgs); + pool->num++; + } + while (pool->num > pool->min) { + msg = list_first_entry(&pool->msgs, struct ceph_msg, list_head); + dout("fill_msgpool %p %d/%d releasing %p\n", pool, pool->num, + pool->min, msg); + list_del_init(&msg->list_head); + pool->num--; + ceph_msg_kfree(msg); + } + return 0; +} + +int ceph_msgpool_init(struct ceph_msgpool *pool, + int front_len, int min, bool blocking) +{ + int ret; + + dout("msgpool_init %p front_len %d min %d\n", pool, front_len, min); + spin_lock_init(&pool->lock); + pool->front_len = front_len; + INIT_LIST_HEAD(&pool->msgs); + pool->num = 0; + pool->min = min; + pool->blocking = blocking; + init_waitqueue_head(&pool->wait); + + spin_lock(&pool->lock); + ret = __fill_msgpool(pool); + spin_unlock(&pool->lock); + return ret; +} + +void ceph_msgpool_destroy(struct ceph_msgpool *pool) +{ + dout("msgpool_destroy %p\n", pool); + spin_lock(&pool->lock); + pool->min = 0; + __fill_msgpool(pool); + spin_unlock(&pool->lock); +} + +int ceph_msgpool_resv(struct ceph_msgpool *pool, int delta) +{ + int ret; + + spin_lock(&pool->lock); + dout("msgpool_resv %p delta %d\n", pool, delta); + pool->min += delta; + ret = __fill_msgpool(pool); + spin_unlock(&pool->lock); + return ret; +} + +struct ceph_msg *ceph_msgpool_get(struct ceph_msgpool *pool) +{ + wait_queue_t wait; + struct ceph_msg *msg; + + if (pool->blocking) { + /* mempool_t behavior; first try to alloc */ + msg = ceph_msg_new(0, pool->front_len, 0, 0, NULL); + if (!IS_ERR(msg)) + return msg; + } + + while (1) { + spin_lock(&pool->lock); + if (likely(pool->num)) { + msg = list_entry(pool->msgs.next, struct ceph_msg, + list_head); + list_del_init(&msg->list_head); + pool->num--; + dout("msgpool_get %p got %p, now %d/%d\n", pool, msg, + pool->num, pool->min); + spin_unlock(&pool->lock); + return msg; + } + pr_err("msgpool_get %p now %d/%d, %s\n", pool, pool->num, + pool->min, pool->blocking ? "waiting" : "failing"); + spin_unlock(&pool->lock); + + if (!pool->blocking) { + WARN_ON(1); + + /* maybe we can allocate it now? */ + msg = ceph_msg_new(0, pool->front_len, 0, 0, NULL); + if (!IS_ERR(msg)) + return msg; + + return ERR_PTR(-ENOMEM); + } + + init_wait(&wait); + prepare_to_wait(&pool->wait, &wait, TASK_UNINTERRUPTIBLE); + schedule(); + finish_wait(&pool->wait, &wait); + } +} + +void ceph_msgpool_put(struct ceph_msgpool *pool, struct ceph_msg *msg) +{ + spin_lock(&pool->lock); + if (pool->num < pool->min) { + ceph_msg_get(msg); /* retake a single ref */ + list_add(&msg->list_head, &pool->msgs); + pool->num++; + dout("msgpool_put %p reclaim %p, now %d/%d\n", pool, msg, + pool->num, pool->min); + spin_unlock(&pool->lock); + wake_up(&pool->wait); + } else { + dout("msgpool_put %p drop %p, at %d/%d\n", pool, msg, + pool->num, pool->min); + spin_unlock(&pool->lock); + ceph_msg_kfree(msg); + } +} diff --git a/fs/ceph/msgpool.h b/fs/ceph/msgpool.h new file mode 100644 index 0000000..07a2dec --- /dev/null +++ b/fs/ceph/msgpool.h @@ -0,0 +1,26 @@ +#ifndef _FS_CEPH_MSGPOOL +#define _FS_CEPH_MSGPOOL + +#include "messenger.h" + +/* + * we use memory pools for preallocating messages we may receive, to + * avoid unexpected OOM conditions. + */ +struct ceph_msgpool { + spinlock_t lock; + int front_len; /* preallocated payload size */ + struct list_head msgs; /* msgs in the pool; each has 1 ref */ + int num, min; /* cur, min # msgs in the pool */ + bool blocking; + wait_queue_head_t wait; +}; + +extern int ceph_msgpool_init(struct ceph_msgpool *pool, + int front_len, int size, bool blocking); +extern void ceph_msgpool_destroy(struct ceph_msgpool *pool); +extern int ceph_msgpool_resv(struct ceph_msgpool *, int delta); +extern struct ceph_msg *ceph_msgpool_get(struct ceph_msgpool *); +extern void ceph_msgpool_put(struct ceph_msgpool *, struct ceph_msg *); + +#endif -- cgit v0.10.2 From a8e63b7d51cce4557ee7bcd8f51be5cae8547d20 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 6 Oct 2009 11:31:13 -0700 Subject: ceph: nfs re-export support Basic NFS re-export support is included. This mostly works. However, Ceph's MDS design precludes the ability to generate a (small) filehandle that will be valid forever, so this is of limited utility. Signed-off-by: Sage Weil diff --git a/fs/ceph/export.c b/fs/ceph/export.c new file mode 100644 index 0000000..fc68e39 --- /dev/null +++ b/fs/ceph/export.c @@ -0,0 +1,223 @@ +#include "ceph_debug.h" + +#include +#include + +#include "super.h" + +/* + * NFS export support + * + * NFS re-export of a ceph mount is, at present, only semireliable. + * The basic issue is that the Ceph architectures doesn't lend itself + * well to generating filehandles that will remain valid forever. + * + * So, we do our best. If you're lucky, your inode will be in the + * client's cache. If it's not, and you have a connectable fh, then + * the MDS server may be able to find it for you. Otherwise, you get + * ESTALE. + * + * There are ways to this more reliable, but in the non-connectable fh + * case, we won't every work perfectly, and in the connectable case, + * some changes are needed on the MDS side to work better. + */ + +/* + * Basic fh + */ +struct ceph_nfs_fh { + u64 ino; +} __attribute__ ((packed)); + +/* + * Larger 'connectable' fh that includes parent ino and name hash. + * Use this whenever possible, as it works more reliably. + */ +struct ceph_nfs_confh { + u64 ino, parent_ino; + u32 parent_name_hash; +} __attribute__ ((packed)); + +static int ceph_encode_fh(struct dentry *dentry, u32 *rawfh, int *max_len, + int connectable) +{ + struct ceph_nfs_fh *fh = (void *)rawfh; + struct ceph_nfs_confh *cfh = (void *)rawfh; + struct dentry *parent = dentry->d_parent; + struct inode *inode = dentry->d_inode; + int type; + + /* don't re-export snaps */ + if (ceph_snap(inode) != CEPH_NOSNAP) + return -EINVAL; + + if (*max_len >= sizeof(*cfh)) { + dout("encode_fh %p connectable\n", dentry); + cfh->ino = ceph_ino(dentry->d_inode); + cfh->parent_ino = ceph_ino(parent->d_inode); + cfh->parent_name_hash = parent->d_name.hash; + *max_len = sizeof(*cfh); + type = 2; + } else if (*max_len > sizeof(*fh)) { + if (connectable) + return -ENOSPC; + dout("encode_fh %p\n", dentry); + fh->ino = ceph_ino(dentry->d_inode); + *max_len = sizeof(*fh); + type = 1; + } else { + return -ENOSPC; + } + return type; +} + +/* + * convert regular fh to dentry + * + * FIXME: we should try harder by querying the mds for the ino. + */ +static struct dentry *__fh_to_dentry(struct super_block *sb, + struct ceph_nfs_fh *fh) +{ + struct inode *inode; + struct dentry *dentry; + struct ceph_vino vino; + int err; + + dout("__fh_to_dentry %llx\n", fh->ino); + vino.ino = fh->ino; + vino.snap = CEPH_NOSNAP; + inode = ceph_find_inode(sb, vino); + if (!inode) + return ERR_PTR(-ESTALE); + + dentry = d_obtain_alias(inode); + if (!dentry) { + pr_err("fh_to_dentry %llx -- inode %p but ENOMEM\n", + fh->ino, inode); + iput(inode); + return ERR_PTR(-ENOMEM); + } + err = ceph_init_dentry(dentry); + + if (err < 0) { + iput(inode); + return ERR_PTR(err); + } + dout("__fh_to_dentry %llx %p dentry %p\n", fh->ino, inode, dentry); + return dentry; +} + +/* + * convert connectable fh to dentry + */ +static struct dentry *__cfh_to_dentry(struct super_block *sb, + struct ceph_nfs_confh *cfh) +{ + struct ceph_mds_client *mdsc = &ceph_client(sb)->mdsc; + struct inode *inode; + struct dentry *dentry; + struct ceph_vino vino; + int err; + + dout("__cfh_to_dentry %llx (%llx/%x)\n", + cfh->ino, cfh->parent_ino, cfh->parent_name_hash); + + vino.ino = cfh->ino; + vino.snap = CEPH_NOSNAP; + inode = ceph_find_inode(sb, vino); + if (!inode) { + struct ceph_mds_request *req; + + req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LOOKUPHASH, + USE_ANY_MDS); + if (IS_ERR(req)) + return ERR_PTR(PTR_ERR(req)); + + req->r_ino1 = vino; + req->r_ino2.ino = cfh->parent_ino; + req->r_ino2.snap = CEPH_NOSNAP; + req->r_path2 = kmalloc(16, GFP_NOFS); + snprintf(req->r_path2, 16, "%d", cfh->parent_name_hash); + req->r_num_caps = 1; + err = ceph_mdsc_do_request(mdsc, NULL, req); + ceph_mdsc_put_request(req); + inode = ceph_find_inode(sb, vino); + if (!inode) + return ERR_PTR(err ? err : -ESTALE); + } + + dentry = d_obtain_alias(inode); + if (!dentry) { + pr_err("cfh_to_dentry %llx -- inode %p but ENOMEM\n", + cfh->ino, inode); + iput(inode); + return ERR_PTR(-ENOMEM); + } + err = ceph_init_dentry(dentry); + if (err < 0) { + iput(inode); + return ERR_PTR(err); + } + dout("__cfh_to_dentry %llx %p dentry %p\n", cfh->ino, inode, dentry); + return dentry; +} + +static struct dentry *ceph_fh_to_dentry(struct super_block *sb, struct fid *fid, + int fh_len, int fh_type) +{ + if (fh_type == 1) + return __fh_to_dentry(sb, (struct ceph_nfs_fh *)fid->raw); + else + return __cfh_to_dentry(sb, (struct ceph_nfs_confh *)fid->raw); +} + +/* + * get parent, if possible. + * + * FIXME: we could do better by querying the mds to discover the + * parent. + */ +static struct dentry *ceph_fh_to_parent(struct super_block *sb, + struct fid *fid, + int fh_len, int fh_type) +{ + struct ceph_nfs_confh *cfh = (void *)fid->raw; + struct ceph_vino vino; + struct inode *inode; + struct dentry *dentry; + int err; + + if (fh_type == 1) + return ERR_PTR(-ESTALE); + + pr_debug("fh_to_parent %llx/%d\n", cfh->parent_ino, + cfh->parent_name_hash); + + vino.ino = cfh->ino; + vino.snap = CEPH_NOSNAP; + inode = ceph_find_inode(sb, vino); + if (!inode) + return ERR_PTR(-ESTALE); + + dentry = d_obtain_alias(inode); + if (!dentry) { + pr_err("fh_to_parent %llx -- inode %p but ENOMEM\n", + cfh->ino, inode); + iput(inode); + return ERR_PTR(-ENOMEM); + } + err = ceph_init_dentry(dentry); + if (err < 0) { + iput(inode); + return ERR_PTR(err); + } + dout("fh_to_parent %llx %p dentry %p\n", cfh->ino, inode, dentry); + return dentry; +} + +const struct export_operations ceph_export_ops = { + .encode_fh = ceph_encode_fh, + .fh_to_dentry = ceph_fh_to_dentry, + .fh_to_parent = ceph_fh_to_parent, +}; -- cgit v0.10.2 From 8f4e91dee2a245e4be6942f4a8d83a769e13a47d Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 6 Oct 2009 11:31:14 -0700 Subject: ceph: ioctls A few Ceph ioctls for getting and setting file layout (striping) parameters, and learning the identity and network address of the OSD a given region of a file is stored on. Signed-off-by: Sage Weil diff --git a/Documentation/ioctl/ioctl-number.txt b/Documentation/ioctl/ioctl-number.txt index 9473749..91cfdd7 100644 --- a/Documentation/ioctl/ioctl-number.txt +++ b/Documentation/ioctl/ioctl-number.txt @@ -182,6 +182,7 @@ Code Seq# Include File Comments 0x90 00 drivers/cdrom/sbpcd.h 0x93 60-7F linux/auto_fs.h +0x97 00-7F fs/ceph/ioctl.h Ceph file system 0x99 00-0F 537-Addinboard driver 0xA0 all linux/sdp/sdp.h Industrial Device Project diff --git a/fs/ceph/ioctl.c b/fs/ceph/ioctl.c new file mode 100644 index 0000000..e4f99ef --- /dev/null +++ b/fs/ceph/ioctl.c @@ -0,0 +1,157 @@ +#include + +#include "ioctl.h" +#include "super.h" +#include "ceph_debug.h" + + +/* + * ioctls + */ + +/* + * get and set the file layout + */ +static long ceph_ioctl_get_layout(struct file *file, void __user *arg) +{ + struct ceph_inode_info *ci = ceph_inode(file->f_dentry->d_inode); + struct ceph_ioctl_layout l; + int err; + + err = ceph_do_getattr(file->f_dentry->d_inode, CEPH_STAT_CAP_LAYOUT); + if (!err) { + l.stripe_unit = ceph_file_layout_su(ci->i_layout); + l.stripe_count = ceph_file_layout_stripe_count(ci->i_layout); + l.object_size = ceph_file_layout_object_size(ci->i_layout); + l.data_pool = le32_to_cpu(ci->i_layout.fl_pg_pool); + if (copy_to_user(arg, &l, sizeof(l))) + return -EFAULT; + } + + return err; +} + +static long ceph_ioctl_set_layout(struct file *file, void __user *arg) +{ + struct inode *inode = file->f_dentry->d_inode; + struct inode *parent_inode = file->f_dentry->d_parent->d_inode; + struct ceph_mds_client *mdsc = &ceph_sb_to_client(inode->i_sb)->mdsc; + struct ceph_mds_request *req; + struct ceph_ioctl_layout l; + int err, i; + + /* copy and validate */ + if (copy_from_user(&l, arg, sizeof(l))) + return -EFAULT; + + if ((l.object_size & ~PAGE_MASK) || + (l.stripe_unit & ~PAGE_MASK) || + !l.stripe_unit || + (l.object_size && + (unsigned)l.object_size % (unsigned)l.stripe_unit)) + return -EINVAL; + + /* make sure it's a valid data pool */ + if (l.data_pool > 0) { + mutex_lock(&mdsc->mutex); + err = -EINVAL; + for (i = 0; i < mdsc->mdsmap->m_num_data_pg_pools; i++) + if (mdsc->mdsmap->m_data_pg_pools[i] == l.data_pool) { + err = 0; + break; + } + mutex_unlock(&mdsc->mutex); + if (err) + return err; + } + + req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SETLAYOUT, + USE_AUTH_MDS); + if (IS_ERR(req)) + return PTR_ERR(req); + req->r_inode = igrab(inode); + req->r_inode_drop = CEPH_CAP_FILE_SHARED | CEPH_CAP_FILE_EXCL; + + req->r_args.setlayout.layout.fl_stripe_unit = + cpu_to_le32(l.stripe_unit); + req->r_args.setlayout.layout.fl_stripe_count = + cpu_to_le32(l.stripe_count); + req->r_args.setlayout.layout.fl_object_size = + cpu_to_le32(l.object_size); + req->r_args.setlayout.layout.fl_pg_pool = cpu_to_le32(l.data_pool); + req->r_args.setlayout.layout.fl_pg_preferred = cpu_to_le32((s32)-1); + + err = ceph_mdsc_do_request(mdsc, parent_inode, req); + ceph_mdsc_put_request(req); + return err; +} + +/* + * Return object name, size/offset information, and location (OSD + * number, network address) for a given file offset. + */ +static long ceph_ioctl_get_dataloc(struct file *file, void __user *arg) +{ + struct ceph_ioctl_dataloc dl; + struct inode *inode = file->f_dentry->d_inode; + struct ceph_inode_info *ci = ceph_inode(inode); + struct ceph_osd_client *osdc = &ceph_client(inode->i_sb)->osdc; + u64 len = 1, olen; + u64 tmp; + struct ceph_object_layout ol; + union ceph_pg pgid; + + /* copy and validate */ + if (copy_from_user(&dl, arg, sizeof(dl))) + return -EFAULT; + + down_read(&osdc->map_sem); + ceph_calc_file_object_mapping(&ci->i_layout, dl.file_offset, &len, + &dl.object_no, &dl.object_offset, &olen); + dl.file_offset -= dl.object_offset; + dl.object_size = ceph_file_layout_object_size(ci->i_layout); + dl.block_size = ceph_file_layout_su(ci->i_layout); + + /* block_offset = object_offset % block_size */ + tmp = dl.object_offset; + dl.block_offset = do_div(tmp, dl.block_size); + + snprintf(dl.object_name, sizeof(dl.object_name), "%llx.%08llx", + ceph_ino(inode), dl.object_no); + ceph_calc_object_layout(&ol, dl.object_name, &ci->i_layout, + osdc->osdmap); + + pgid.pg64 = le64_to_cpu(ol.ol_pgid); + dl.osd = ceph_calc_pg_primary(osdc->osdmap, pgid); + if (dl.osd >= 0) { + struct ceph_entity_addr *a = + ceph_osd_addr(osdc->osdmap, dl.osd); + if (a) + memcpy(&dl.osd_addr, &a->in_addr, sizeof(dl.osd_addr)); + } else { + memset(&dl.osd_addr, 0, sizeof(dl.osd_addr)); + } + up_read(&osdc->map_sem); + + /* send result back to user */ + if (copy_to_user(arg, &dl, sizeof(dl))) + return -EFAULT; + + return 0; +} + +long ceph_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + dout("ioctl file %p cmd %u arg %lu\n", file, cmd, arg); + switch (cmd) { + case CEPH_IOC_GET_LAYOUT: + return ceph_ioctl_get_layout(file, (void __user *)arg); + + case CEPH_IOC_SET_LAYOUT: + return ceph_ioctl_set_layout(file, (void __user *)arg); + + case CEPH_IOC_GET_DATALOC: + return ceph_ioctl_get_dataloc(file, (void __user *)arg); + } + return -ENOTTY; +} diff --git a/fs/ceph/ioctl.h b/fs/ceph/ioctl.h new file mode 100644 index 0000000..3c511da --- /dev/null +++ b/fs/ceph/ioctl.h @@ -0,0 +1,39 @@ +#ifndef FS_CEPH_IOCTL_H +#define FS_CEPH_IOCTL_H + +#include +#include + +#define CEPH_IOCTL_MAGIC 0x97 + +/* just use u64 to align sanely on all archs */ +struct ceph_ioctl_layout { + __u64 stripe_unit, stripe_count, object_size; + __u64 data_pool; +}; + +#define CEPH_IOC_GET_LAYOUT _IOR(CEPH_IOCTL_MAGIC, 1, \ + struct ceph_ioctl_layout) +#define CEPH_IOC_SET_LAYOUT _IOW(CEPH_IOCTL_MAGIC, 2, \ + struct ceph_ioctl_layout) + +/* + * Extract identity, address of the OSD and object storing a given + * file offset. + */ +struct ceph_ioctl_dataloc { + __u64 file_offset; /* in+out: file offset */ + __u64 object_offset; /* out: offset in object */ + __u64 object_no; /* out: object # */ + __u64 object_size; /* out: object size */ + char object_name[64]; /* out: object name */ + __u64 block_offset; /* out: offset in block */ + __u64 block_size; /* out: block length */ + __s64 osd; /* out: osd # */ + struct sockaddr_storage osd_addr; /* out: osd address */ +}; + +#define CEPH_IOC_GET_DATALOC _IOWR(CEPH_IOCTL_MAGIC, 3, \ + struct ceph_ioctl_dataloc) + +#endif -- cgit v0.10.2 From 76aa844d5b2fb8c839180d3f5874e333b297e5fd Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 6 Oct 2009 11:31:14 -0700 Subject: ceph: debugfs Basic state information is available via /sys/kernel/debug/ceph, including instances of the client, fsids, current monitor, mds and osd maps, outstanding server requests, and hooks to adjust debug levels. Signed-off-by: Sage Weil diff --git a/fs/ceph/debugfs.c b/fs/ceph/debugfs.c new file mode 100644 index 0000000..9edbad3 --- /dev/null +++ b/fs/ceph/debugfs.c @@ -0,0 +1,425 @@ +#include "ceph_debug.h" + +#include +#include +#include +#include + +#include "super.h" +#include "mds_client.h" + +/* + * Implement /sys/kernel/debug/ceph fun + * + * /sys/kernel/debug/ceph/client* - an instance of the ceph client + * .../osdmap - current osdmap + * .../mdsmap - current mdsmap + * .../monmap - current monmap + * .../osdc - active osd requests + * .../mdsc - active mds requests + * .../monc - mon client state + * .../dentry_lru - dump contents of dentry lru + * .../caps - expose cap (reservation) stats + */ + +static struct dentry *ceph_debugfs_dir; + +static int monmap_show(struct seq_file *s, void *p) +{ + int i; + struct ceph_client *client = s->private; + + if (client->monc.monmap == NULL) + return 0; + + seq_printf(s, "epoch %d\n", client->monc.monmap->epoch); + for (i = 0; i < client->monc.monmap->num_mon; i++) { + struct ceph_entity_inst *inst = + &client->monc.monmap->mon_inst[i]; + + seq_printf(s, "\t%s%lld\t%s\n", + ENTITY_NAME(inst->name), + pr_addr(&inst->addr.in_addr)); + } + return 0; +} + +static int mdsmap_show(struct seq_file *s, void *p) +{ + int i; + struct ceph_client *client = s->private; + + if (client->mdsc.mdsmap == NULL) + return 0; + seq_printf(s, "epoch %d\n", client->mdsc.mdsmap->m_epoch); + seq_printf(s, "root %d\n", client->mdsc.mdsmap->m_root); + seq_printf(s, "session_timeout %d\n", + client->mdsc.mdsmap->m_session_timeout); + seq_printf(s, "session_autoclose %d\n", + client->mdsc.mdsmap->m_session_autoclose); + for (i = 0; i < client->mdsc.mdsmap->m_max_mds; i++) { + struct ceph_entity_addr *addr = + &client->mdsc.mdsmap->m_info[i].addr; + int state = client->mdsc.mdsmap->m_info[i].state; + + seq_printf(s, "\tmds%d\t%s\t(%s)\n", i, pr_addr(&addr->in_addr), + ceph_mds_state_name(state)); + } + return 0; +} + +static int osdmap_show(struct seq_file *s, void *p) +{ + int i; + struct ceph_client *client = s->private; + + if (client->osdc.osdmap == NULL) + return 0; + seq_printf(s, "epoch %d\n", client->osdc.osdmap->epoch); + seq_printf(s, "flags%s%s\n", + (client->osdc.osdmap->flags & CEPH_OSDMAP_NEARFULL) ? + " NEARFULL" : "", + (client->osdc.osdmap->flags & CEPH_OSDMAP_FULL) ? + " FULL" : ""); + for (i = 0; i < client->osdc.osdmap->num_pools; i++) { + struct ceph_pg_pool_info *pool = + &client->osdc.osdmap->pg_pool[i]; + seq_printf(s, "pg_pool %d pg_num %d / %d, lpg_num %d / %d\n", + i, pool->v.pg_num, pool->pg_num_mask, + pool->v.lpg_num, pool->lpg_num_mask); + } + for (i = 0; i < client->osdc.osdmap->max_osd; i++) { + struct ceph_entity_addr *addr = + &client->osdc.osdmap->osd_addr[i]; + int state = client->osdc.osdmap->osd_state[i]; + char sb[64]; + + seq_printf(s, "\tosd%d\t%s\t%3d%%\t(%s)\n", + i, pr_addr(&addr->in_addr), + ((client->osdc.osdmap->osd_weight[i]*100) >> 16), + ceph_osdmap_state_str(sb, sizeof(sb), state)); + } + return 0; +} + +static int monc_show(struct seq_file *s, void *p) +{ + struct ceph_client *client = s->private; + struct ceph_mon_statfs_request *req; + u64 nexttid = 0; + int got; + struct ceph_mon_client *monc = &client->monc; + + mutex_lock(&monc->mutex); + + if (monc->have_mdsmap) + seq_printf(s, "have mdsmap %u\n", (unsigned)monc->have_mdsmap); + if (monc->have_osdmap) + seq_printf(s, "have osdmap %u\n", (unsigned)monc->have_osdmap); + if (monc->want_next_osdmap) + seq_printf(s, "want next osdmap\n"); + + while (nexttid < monc->last_tid) { + got = radix_tree_gang_lookup(&monc->statfs_request_tree, + (void **)&req, nexttid, 1); + if (got == 0) + break; + nexttid = req->tid + 1; + + seq_printf(s, "%lld statfs\n", req->tid); + } + mutex_unlock(&monc->mutex); + + return 0; +} + +static int mdsc_show(struct seq_file *s, void *p) +{ + struct ceph_client *client = s->private; + struct ceph_mds_request *req; + u64 nexttid = 0; + int got; + struct ceph_mds_client *mdsc = &client->mdsc; + int pathlen; + u64 pathbase; + char *path; + + mutex_lock(&mdsc->mutex); + while (nexttid < mdsc->last_tid) { + got = radix_tree_gang_lookup(&mdsc->request_tree, + (void **)&req, nexttid, 1); + if (got == 0) + break; + nexttid = req->r_tid + 1; + + if (req->r_request) + seq_printf(s, "%lld\tmds%d\t", req->r_tid, req->r_mds); + else + seq_printf(s, "%lld\t(no request)\t", req->r_tid); + + seq_printf(s, "%s", ceph_mds_op_name(req->r_op)); + + if (req->r_got_unsafe) + seq_printf(s, "\t(unsafe)"); + else + seq_printf(s, "\t"); + + if (req->r_inode) { + seq_printf(s, " #%llx", ceph_ino(req->r_inode)); + } else if (req->r_dentry) { + path = ceph_mdsc_build_path(req->r_dentry, &pathlen, + &pathbase, 0); + spin_lock(&req->r_dentry->d_lock); + seq_printf(s, " #%llx/%.*s (%s)", + ceph_ino(req->r_dentry->d_parent->d_inode), + req->r_dentry->d_name.len, + req->r_dentry->d_name.name, + path ? path : ""); + spin_unlock(&req->r_dentry->d_lock); + kfree(path); + } else if (req->r_path1) { + seq_printf(s, " #%llx/%s", req->r_ino1.ino, + req->r_path1); + } + + if (req->r_old_dentry) { + path = ceph_mdsc_build_path(req->r_old_dentry, &pathlen, + &pathbase, 0); + spin_lock(&req->r_old_dentry->d_lock); + seq_printf(s, " #%llx/%.*s (%s)", + ceph_ino(req->r_old_dentry->d_parent->d_inode), + req->r_old_dentry->d_name.len, + req->r_old_dentry->d_name.name, + path ? path : ""); + spin_unlock(&req->r_old_dentry->d_lock); + kfree(path); + } else if (req->r_path2) { + if (req->r_ino2.ino) + seq_printf(s, " #%llx/%s", req->r_ino2.ino, + req->r_path2); + else + seq_printf(s, " %s", req->r_path2); + } + + seq_printf(s, "\n"); + } + mutex_unlock(&mdsc->mutex); + + return 0; +} + +static int osdc_show(struct seq_file *s, void *pp) +{ + struct ceph_client *client = s->private; + struct ceph_osd_client *osdc = &client->osdc; + struct rb_node *p; + + mutex_lock(&osdc->request_mutex); + for (p = rb_first(&osdc->requests); p; p = rb_next(p)) { + struct ceph_osd_request *req; + struct ceph_osd_request_head *head; + struct ceph_osd_op *op; + int num_ops; + int opcode, olen; + int i; + + req = rb_entry(p, struct ceph_osd_request, r_node); + + seq_printf(s, "%lld\tosd%d\t", req->r_tid, + req->r_osd ? req->r_osd->o_osd : -1); + + head = req->r_request->front.iov_base; + op = (void *)(head + 1); + + num_ops = le16_to_cpu(head->num_ops); + olen = le32_to_cpu(head->object_len); + seq_printf(s, "%.*s", olen, + (const char *)(head->ops + num_ops)); + + if (req->r_reassert_version.epoch) + seq_printf(s, "\t%u'%llu", + (unsigned)le32_to_cpu(req->r_reassert_version.epoch), + le64_to_cpu(req->r_reassert_version.version)); + else + seq_printf(s, "\t"); + + for (i = 0; i < num_ops; i++) { + opcode = le16_to_cpu(op->op); + seq_printf(s, "\t%s", ceph_osd_op_name(opcode)); + op++; + } + + seq_printf(s, "\n"); + } + mutex_unlock(&osdc->request_mutex); + return 0; +} + +static int caps_show(struct seq_file *s, void *p) +{ + struct ceph_client *client = p; + int total, avail, used, reserved; + + ceph_reservation_status(client, &total, &avail, &used, &reserved); + seq_printf(s, "total\t\t%d\n" + "avail\t\t%d\n" + "used\t\t%d\n" + "reserved\t%d\n", + total, avail, used, reserved); + return 0; +} + +static int dentry_lru_show(struct seq_file *s, void *ptr) +{ + struct ceph_client *client = s->private; + struct ceph_mds_client *mdsc = &client->mdsc; + struct ceph_dentry_info *di; + + spin_lock(&mdsc->dentry_lru_lock); + list_for_each_entry(di, &mdsc->dentry_lru, lru) { + struct dentry *dentry = di->dentry; + seq_printf(s, "%p %p\t%.*s\n", + di, dentry, dentry->d_name.len, dentry->d_name.name); + } + spin_unlock(&mdsc->dentry_lru_lock); + + return 0; +} + +#define DEFINE_SHOW_FUNC(name) \ +static int name##_open(struct inode *inode, struct file *file) \ +{ \ + struct seq_file *sf; \ + int ret; \ + \ + ret = single_open(file, name, NULL); \ + sf = file->private_data; \ + sf->private = inode->i_private; \ + return ret; \ +} \ + \ +static const struct file_operations name##_fops = { \ + .open = name##_open, \ + .read = seq_read, \ + .llseek = seq_lseek, \ + .release = single_release, \ +}; + +DEFINE_SHOW_FUNC(monmap_show) +DEFINE_SHOW_FUNC(mdsmap_show) +DEFINE_SHOW_FUNC(osdmap_show) +DEFINE_SHOW_FUNC(monc_show) +DEFINE_SHOW_FUNC(mdsc_show) +DEFINE_SHOW_FUNC(osdc_show) +DEFINE_SHOW_FUNC(dentry_lru_show) +DEFINE_SHOW_FUNC(caps_show) + +int __init ceph_debugfs_init(void) +{ + ceph_debugfs_dir = debugfs_create_dir("ceph", NULL); + if (!ceph_debugfs_dir) + return -ENOMEM; + return 0; +} + +void ceph_debugfs_cleanup(void) +{ + debugfs_remove(ceph_debugfs_dir); +} + +int ceph_debugfs_client_init(struct ceph_client *client) +{ + int ret = 0; + char name[80]; + + snprintf(name, sizeof(name), FSID_FORMAT ".client%lld", + PR_FSID(&client->monc.monmap->fsid), client->whoami); + + client->debugfs_dir = debugfs_create_dir(name, ceph_debugfs_dir); + if (!client->debugfs_dir) + goto out; + + client->monc.debugfs_file = debugfs_create_file("monc", + 0600, + client->debugfs_dir, + client, + &monc_show_fops); + if (!client->monc.debugfs_file) + goto out; + + client->mdsc.debugfs_file = debugfs_create_file("mdsc", + 0600, + client->debugfs_dir, + client, + &mdsc_show_fops); + if (!client->mdsc.debugfs_file) + goto out; + + client->osdc.debugfs_file = debugfs_create_file("osdc", + 0600, + client->debugfs_dir, + client, + &osdc_show_fops); + if (!client->osdc.debugfs_file) + goto out; + + client->debugfs_monmap = debugfs_create_file("monmap", + 0600, + client->debugfs_dir, + client, + &monmap_show_fops); + if (!client->debugfs_monmap) + goto out; + + client->debugfs_mdsmap = debugfs_create_file("mdsmap", + 0600, + client->debugfs_dir, + client, + &mdsmap_show_fops); + if (!client->debugfs_mdsmap) + goto out; + + client->debugfs_osdmap = debugfs_create_file("osdmap", + 0600, + client->debugfs_dir, + client, + &osdmap_show_fops); + if (!client->debugfs_osdmap) + goto out; + + client->debugfs_dentry_lru = debugfs_create_file("dentry_lru", + 0600, + client->debugfs_dir, + client, + &dentry_lru_show_fops); + if (!client->debugfs_dentry_lru) + goto out; + + client->debugfs_caps = debugfs_create_file("caps", + 0400, + client->debugfs_dir, + client, + &caps_show_fops); + if (!client->debugfs_caps) + goto out; + + return 0; + +out: + ceph_debugfs_client_cleanup(client); + return ret; +} + +void ceph_debugfs_client_cleanup(struct ceph_client *client) +{ + debugfs_remove(client->debugfs_caps); + debugfs_remove(client->debugfs_dentry_lru); + debugfs_remove(client->debugfs_osdmap); + debugfs_remove(client->debugfs_mdsmap); + debugfs_remove(client->debugfs_monmap); + debugfs_remove(client->osdc.debugfs_file); + debugfs_remove(client->mdsc.debugfs_file); + debugfs_remove(client->monc.debugfs_file); + debugfs_remove(client->debugfs_dir); +} + -- cgit v0.10.2 From 9030aaf9bf0a1eee47a154c316c789e959638b0f Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 6 Oct 2009 11:31:15 -0700 Subject: ceph: Kconfig, Makefile Kconfig options and Makefile. Signed-off-by: Sage Weil diff --git a/MAINTAINERS b/MAINTAINERS index c450f3a..9b680ff 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1294,6 +1294,15 @@ F: arch/powerpc/include/asm/spu*.h F: arch/powerpc/oprofile/*cell* F: arch/powerpc/platforms/cell/ +CEPH DISTRIBUTED FILE SYSTEM CLIENT +M: Sage Weil +L: ceph-devel@lists.sourceforge.net +W: http://ceph.newdream.net/ +T: git git://ceph.newdream.net/linux-ceph-client.git +S: Supported +F: Documentation/filesystems/ceph.txt +F: fs/ceph + CERTIFIED WIRELESS USB (WUSB) SUBSYSTEM: M: David Vrabel L: linux-usb@vger.kernel.org diff --git a/fs/Kconfig b/fs/Kconfig index d4bf8ca..ca68709 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -234,6 +234,7 @@ config NFS_COMMON source "net/sunrpc/Kconfig" source "fs/smbfs/Kconfig" +source "fs/ceph/Kconfig" source "fs/cifs/Kconfig" source "fs/ncpfs/Kconfig" source "fs/coda/Kconfig" diff --git a/fs/Makefile b/fs/Makefile index af6d047..5ef73a0 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -124,3 +124,4 @@ obj-$(CONFIG_OCFS2_FS) += ocfs2/ obj-$(CONFIG_BTRFS_FS) += btrfs/ obj-$(CONFIG_GFS2_FS) += gfs2/ obj-$(CONFIG_EXOFS_FS) += exofs/ +obj-$(CONFIG_CEPH_FS) += ceph/ diff --git a/fs/ceph/Kconfig b/fs/ceph/Kconfig new file mode 100644 index 0000000..bc1fbd9 --- /dev/null +++ b/fs/ceph/Kconfig @@ -0,0 +1,26 @@ +config CEPH_FS + tristate "Ceph distributed file system (EXPERIMENTAL)" + depends on INET && EXPERIMENTAL + select LIBCRC32C + help + Choose Y or M here to include support for mounting the + experimental Ceph distributed file system. Ceph is an extremely + scalable file system designed to provide high performance, + reliable access to petabytes of storage. + + More information at http://ceph.newdream.net/. + + If unsure, say N. + +config CEPH_FS_PRETTYDEBUG + bool "Include file:line in ceph debug output" + depends on CEPH_FS + default n + help + If you say Y here, debug output will include a filename and + line to aid debugging. This icnreases kernel size and slows + execution slightly when debug call sites are enabled (e.g., + via CONFIG_DYNAMIC_DEBUG). + + If unsure, say N. + diff --git a/fs/ceph/Makefile b/fs/ceph/Makefile new file mode 100644 index 0000000..7da6d69 --- /dev/null +++ b/fs/ceph/Makefile @@ -0,0 +1,36 @@ +# +# Makefile for CEPH filesystem. +# + +ifneq ($(KERNELRELEASE),) + +obj-$(CONFIG_CEPH_FS) += ceph.o + +ceph-objs := super.o inode.o dir.o file.o addr.o ioctl.o \ + export.o caps.o snap.o xattr.o \ + messenger.o msgpool.o buffer.o \ + mds_client.o mdsmap.o \ + mon_client.o \ + osd_client.o osdmap.o crush/crush.o crush/mapper.o \ + debugfs.o \ + ceph_fs.o ceph_strings.o ceph_frag.o + +else +#Otherwise we were called directly from the command +# line; invoke the kernel build system. + +KERNELDIR ?= /lib/modules/$(shell uname -r)/build +PWD := $(shell pwd) + +default: all + +all: + $(MAKE) -C $(KERNELDIR) M=$(PWD) CONFIG_CEPH_FS=m modules + +modules_install: + $(MAKE) -C $(KERNELDIR) M=$(PWD) CONFIG_CEPH_FS=m modules_install + +clean: + $(MAKE) -C $(KERNELDIR) M=$(PWD) clean + +endif -- cgit v0.10.2 From e324b8f991679a43e09dd13500bf1988c0bfc0ea Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 6 Oct 2009 12:20:56 -0700 Subject: ceph: document shared files in README Document files shared between kernel and user code trees. Signed-off-by: Sage Weil diff --git a/fs/ceph/README b/fs/ceph/README new file mode 100644 index 0000000..231a1df --- /dev/null +++ b/fs/ceph/README @@ -0,0 +1,17 @@ +# +# The following files are shared by (and manually synchronized +# between) the Ceph userland and kernel client. +# +# userland kernel +src/include/ceph_fs.h fs/ceph/ceph_fs.h +src/include/ceph_fs.cc fs/ceph/ceph_fs.c +src/include/msgr.h fs/ceph/msgr.h +src/include/rados.h fs/ceph/rados.h +src/include/ceph_strings.cc fs/ceph/ceph_strings.c +src/include/ceph_frag.h fs/ceph/ceph_frag.h +src/include/ceph_frag.cc fs/ceph/ceph_frag.c +src/crush/crush.c fs/ceph/crush/crush.c +src/crush/crush.h fs/ceph/crush/crush.h +src/crush/mapper.c fs/ceph/crush/mapper.c +src/crush/mapper.h fs/ceph/crush/mapper.h +src/crush/hash.h fs/ceph/crush/hash.h -- cgit v0.10.2 From fa0b72e9e2900ee87886aaf8bc4c4701be1e081d Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 7 Oct 2009 10:59:10 -0700 Subject: ceph: show meaningful version on module load Kill the old git revision; print the ceph version and protocol versions instead. Signed-off-by: Sage Weil diff --git a/fs/ceph/ceph_ver.h b/fs/ceph/ceph_ver.h deleted file mode 100644 index 66c3727..0000000 --- a/fs/ceph/ceph_ver.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __CEPH_VERSION_H -#define __CEPH_VERSION_H - -#define CEPH_GIT_VER 335cd8f952b457095ea2a66aee3db50efb63c91d - -#endif diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 0723fb6..b3404a3 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -16,7 +16,6 @@ #include #include -#include "ceph_ver.h" #include "decode.h" #include "super.h" #include "mon_client.h" @@ -903,7 +902,9 @@ static int __init init_ceph(void) if (ret) goto out_icache; - pr_info("loaded (%s)\n", STRINGIFY(CEPH_GIT_VER)); + pr_info("loaded %d.%d.%d (mon/mds/osd proto %d/%d/%d)\n", + CEPH_VERSION_MAJOR, CEPH_VERSION_MINOR, CEPH_VERSION_PATCH, + CEPH_MONC_PROTOCOL, CEPH_MDSC_PROTOCOL, CEPH_OSDC_PROTOCOL); return 0; out_icache: -- cgit v0.10.2 From b195befd9acb514dd2afb722e63fdd880ed63217 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 7 Oct 2009 10:59:30 -0700 Subject: ceph: include preferred_osd in file layout virtual xattr Signed-off-by: Sage Weil diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c index 8eaac04..65b3a84 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c @@ -91,11 +91,18 @@ static struct ceph_vxattr_cb ceph_dir_vxattrs[] = { static size_t ceph_vxattrcb_layout(struct ceph_inode_info *ci, char *val, size_t size) { - return snprintf(val, size, + int ret; + + ret = snprintf(val, size, "chunk_bytes=%lld\nstripe_count=%lld\nobject_size=%lld\n", (unsigned long long)ceph_file_layout_su(ci->i_layout), (unsigned long long)ceph_file_layout_stripe_count(ci->i_layout), (unsigned long long)ceph_file_layout_object_size(ci->i_layout)); + if (ceph_file_layout_pg_preferred(ci->i_layout)) + ret += snprintf(val + ret, size, "preferred_osd=%lld\n", + (unsigned long long)ceph_file_layout_pg_preferred( + ci->i_layout)); + return ret; } static struct ceph_vxattr_cb ceph_file_vxattrs[] = { -- cgit v0.10.2 From b28813a61d6ffe05ad353a86965607bb7a7fd60f Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 7 Oct 2009 10:59:34 -0700 Subject: ceph: gracefully avoid empty crush buckets This avoids a divide by zero when the input and/or map are malformed. Signed-off-by: Sage Weil diff --git a/fs/ceph/crush/mapper.c b/fs/ceph/crush/mapper.c index 0f0730c..c268393 100644 --- a/fs/ceph/crush/mapper.c +++ b/fs/ceph/crush/mapper.c @@ -299,7 +299,7 @@ static int crush_choose(struct crush_map *map, struct crush_bucket *in = bucket; int r; int i; - int item; + int item = 0; int itemtype; int collide, reject; const int orig_tries = 5; /* attempts before we fall back to search */ @@ -316,6 +316,7 @@ static int crush_choose(struct crush_map *map, /* choose through intervening buckets */ flocal = 0; do { + collide = 0; retry_bucket = 0; r = rep; if (in->alg == CRUSH_BUCKET_UNIFORM) { @@ -340,6 +341,10 @@ static int crush_choose(struct crush_map *map, } /* bucket choose */ + if (in->size == 0) { + reject = 1; + goto reject; + } if (flocal >= (in->size>>1) && flocal > orig_tries) item = bucket_perm_choose(in, x, r); @@ -363,7 +368,6 @@ static int crush_choose(struct crush_map *map, } /* collision? */ - collide = 0; for (i = 0; i < outpos; i++) { if (out[i] == item) { collide = 1; @@ -388,6 +392,7 @@ static int crush_choose(struct crush_map *map, reject = 0; } +reject: if (reject || collide) { ftotal++; flocal++; -- cgit v0.10.2 From e251e288082d5e89604eee1fef0c31bed1fe8f02 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 7 Oct 2009 16:38:19 -0700 Subject: ceph: fix mdsmap decoding when multiple mds's are present A misplaced sizeof() around namelen was throwing things off. Signed-off-by: Sage Weil diff --git a/fs/ceph/mdsmap.c b/fs/ceph/mdsmap.c index 15913cbe..09180d8 100644 --- a/fs/ceph/mdsmap.c +++ b/fs/ceph/mdsmap.c @@ -85,28 +85,28 @@ struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end) void *pexport_targets = NULL; ceph_decode_need(p, end, sizeof(addr) + 1 + sizeof(u32), bad); - *p += sizeof(addr); /* skip addr key */ + ceph_decode_copy(p, &addr, sizeof(addr)); ceph_decode_8(p, infoversion); ceph_decode_32(p, namelen); /* skip mds name */ *p += namelen; ceph_decode_need(p, end, - 5*sizeof(u32) + sizeof(u64) + + 4*sizeof(u32) + sizeof(u64) + sizeof(addr) + sizeof(struct ceph_timespec), bad); ceph_decode_32(p, mds); ceph_decode_32(p, inc); ceph_decode_32(p, state); ceph_decode_64(p, state_seq); - ceph_decode_copy(p, &addr, sizeof(addr)); + *p += sizeof(addr); *p += sizeof(struct ceph_timespec); *p += sizeof(u32); ceph_decode_32_safe(p, end, namelen, bad); - *p += sizeof(namelen); + *p += namelen; if (infoversion >= 2) { ceph_decode_32_safe(p, end, num_export_targets, bad); pexport_targets = *p; - *p += sizeof(num_export_targets * sizeof(u32)); + *p += num_export_targets * sizeof(u32); } else { num_export_targets = 0; } -- cgit v0.10.2 From 0656d11ba6ffa3dee0e8916a1903f96185651217 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 8 Oct 2009 10:25:46 -0700 Subject: ceph: renew mon subscription before it expires Be conservative: renew subscription once half the interval has expired. Do not reuse sub expiration to control hunting. Signed-off-by: Sage Weil diff --git a/fs/ceph/mon_client.c b/fs/ceph/mon_client.c index b0c95ce..9c34df1 100644 --- a/fs/ceph/mon_client.c +++ b/fs/ceph/mon_client.c @@ -213,7 +213,7 @@ static void handle_subscribe_ack(struct ceph_mon_client *monc, monc->hunting = false; } dout("handle_subscribe_ack after %d seconds\n", seconds); - monc->sub_renew_after = monc->sub_sent + seconds*HZ - 1; + monc->sub_renew_after = monc->sub_sent + (seconds >> 1)*HZ - 1; monc->sub_sent = 0; mutex_unlock(&monc->mutex); return; @@ -512,7 +512,7 @@ static void delayed_work(struct work_struct *work) if (monc->want_mount) { __request_mount(monc); } else { - if (__sub_expired(monc)) { + if (monc->hunting) { __close_session(monc); __open_session(monc); /* continue hunting */ } else { -- cgit v0.10.2 From c1ea8823be69ebebaface912142190e910711984 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 8 Oct 2009 16:55:47 -0700 Subject: ceph: fix osd request submission race The osd request submission path registers the request, drops and retakes the request_mutex, then sends it to the OSD. A racing kick_requests could sent it during that interval, causing the same msg to be sent twice and BUGing in the msgr. Fix by only sending the message if it hasn't been touched by other threads. Signed-off-by: Sage Weil diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index 978593a..d14019d 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -837,7 +837,8 @@ static void kick_requests(struct ceph_osd_client *osdc, } kick: - dout("kicking tid %llu osd%d\n", req->r_tid, req->r_osd->o_osd); + dout("kicking %p tid %llu osd%d\n", req, req->r_tid, + req->r_osd->o_osd); req->r_flags |= CEPH_OSD_FLAG_RETRY; err = __send_request(osdc, req); if (err) { @@ -1016,7 +1017,7 @@ int ceph_osdc_start_request(struct ceph_osd_client *osdc, struct ceph_osd_request *req, bool nofail) { - int rc; + int rc = 0; req->r_request->pages = req->r_pages; req->r_request->nr_pages = req->r_num_pages; @@ -1025,15 +1026,22 @@ int ceph_osdc_start_request(struct ceph_osd_client *osdc, down_read(&osdc->map_sem); mutex_lock(&osdc->request_mutex); - rc = __send_request(osdc, req); - if (rc) { - if (nofail) { - dout("osdc_start_request failed send, marking %lld\n", - req->r_tid); - req->r_resend = true; - rc = 0; - } else { - __unregister_request(osdc, req); + /* + * a racing kick_requests() may have sent the message for us + * while we dropped request_mutex above, so only send now if + * the request still han't been touched yet. + */ + if (req->r_sent == 0) { + rc = __send_request(osdc, req); + if (rc) { + if (nofail) { + dout("osdc_start_request failed send, " + " marking %lld\n", req->r_tid); + req->r_resend = true; + rc = 0; + } else { + __unregister_request(osdc, req); + } } } mutex_unlock(&osdc->request_mutex); -- cgit v0.10.2 From 0ba6478df7c6bef0f4b2625554545f941f89fb97 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 8 Oct 2009 16:57:16 -0700 Subject: ceph: revoke osd request message on request completion If an osd has failed or returned and a request has been sent twice, it's possible to get a reply and unregister the request while the request message is queued for delivery. Since the message references the caller's page vector, we need to revoke it before completing. Signed-off-by: Sage Weil diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index d14019d..0aea8af 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -469,10 +469,15 @@ static void __unregister_request(struct ceph_osd_client *osdc, rb_erase(&req->r_node, &osdc->requests); osdc->num_requests--; - list_del_init(&req->r_osd_item); - if (list_empty(&req->r_osd->o_requests)) - remove_osd(osdc, req->r_osd); - req->r_osd = NULL; + if (req->r_osd) { + /* make sure the original request isn't in flight. */ + ceph_con_revoke(&req->r_osd->o_con, req->r_request); + + list_del_init(&req->r_osd_item); + if (list_empty(&req->r_osd->o_requests)) + remove_osd(osdc, req->r_osd); + req->r_osd = NULL; + } ceph_osdc_put_request(req); -- cgit v0.10.2 From 991abb6ecfc8edf9863aa6a3f43249e63f9d4d4e Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 8 Oct 2009 22:22:37 -0700 Subject: ceph: fail gracefully on corrupt osdmap (bad pg_temp mapping) Return an error and report a corrupt map instead of crying BUG(). Signed-off-by: Sage Weil diff --git a/fs/ceph/osdmap.c b/fs/ceph/osdmap.c index e38fe63..342e5f8 100644 --- a/fs/ceph/osdmap.c +++ b/fs/ceph/osdmap.c @@ -366,8 +366,8 @@ static int osdmap_set_max_osd(struct ceph_osdmap *map, int max) /* * Insert a new pg_temp mapping */ -static void __insert_pg_mapping(struct ceph_pg_mapping *new, - struct rb_root *root) +static int __insert_pg_mapping(struct ceph_pg_mapping *new, + struct rb_root *root) { struct rb_node **p = &root->rb_node; struct rb_node *parent = NULL; @@ -381,11 +381,12 @@ static void __insert_pg_mapping(struct ceph_pg_mapping *new, else if (new->pgid > pg->pgid) p = &(*p)->rb_right; else - BUG(); + return -EEXIST; } rb_link_node(&new->node, parent, p); rb_insert_color(&new->node, root); + return 0; } /* @@ -481,7 +482,9 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end) for (j = 0; j < n; j++) ceph_decode_32(p, pg->osds[j]); - __insert_pg_mapping(pg, &map->pg_temp); + err = __insert_pg_mapping(pg, &map->pg_temp); + if (err) + goto bad; dout(" added pg_temp %llx len %d\n", pgid, len); } @@ -681,7 +684,9 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, pg->len = pglen; for (j = 0; j < len; j++) ceph_decode_32(p, pg->osds[j]); - __insert_pg_mapping(pg, &map->pg_temp); + err = __insert_pg_mapping(pg, &map->pg_temp); + if (err) + goto bad; dout(" added pg_temp %llx len %d\n", pgid, pglen); } } -- cgit v0.10.2 From 81b024e70fed635a2cf5a4bf911db1649bb005f5 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 9 Oct 2009 10:29:18 -0700 Subject: ceph: reset osd session on fault, not peer_reset The peer_reset just takes longer (until we reconnect and discover the osd dropped the session... which it will). Signed-off-by: Sage Weil diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index 0aea8af..4a8b4f0 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -294,10 +294,7 @@ __lookup_request_ge(struct ceph_osd_client *osdc, /* - * The messaging layer will reconnect to the osd as needed. If the - * session has dropped, the OSD will have dropped the session state, - * and we'll get notified by the messaging layer. If that happens, we - * need to resubmit all requests for that osd. + * If the osd connection drops, we need to resubmit all requests. */ static void osd_reset(struct ceph_connection *con) { @@ -1301,7 +1298,7 @@ const static struct ceph_connection_operations osd_con_ops = { .put = put_osd_con, .dispatch = dispatch, .alloc_msg = alloc_msg, - .peer_reset = osd_reset, + .fault = osd_reset, .alloc_middle = ceph_alloc_middle, .prepare_pages = prepare_pages, }; -- cgit v0.10.2 From 266673db423e6ab247170d6c6d72ec36e530a911 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 9 Oct 2009 10:31:32 -0700 Subject: ceph: cancel osd requests before resending them This ensures we don't submit the same request twice if we are kicking a specific osd (as with an osd_reset), or when we hit a transient error and resend. Signed-off-by: Sage Weil diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index 4a8b4f0..8e33928 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -813,10 +813,13 @@ static void kick_requests(struct ceph_osd_client *osdc, if (req->r_resend) { dout(" r_resend set on tid %llu\n", req->r_tid); + __cancel_request(req); goto kick; } - if (req->r_osd && kickosd == req->r_osd) + if (req->r_osd && kickosd == req->r_osd) { + __cancel_request(req); goto kick; + } err = __map_osds(osdc, req); if (err == 0) -- cgit v0.10.2 From 13e38c8ae771d73bf6d1f0f98e35f99c0f0d48ff Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 9 Oct 2009 16:36:34 -0700 Subject: ceph: update to mon client protocol v15 The mon request headers now include session_mon information that must be properly initialized. Signed-off-by: Sage Weil diff --git a/fs/ceph/ceph_fs.h b/fs/ceph/ceph_fs.h index 21ed51b..acf24c6 100644 --- a/fs/ceph/ceph_fs.h +++ b/fs/ceph/ceph_fs.h @@ -37,10 +37,10 @@ */ #define CEPH_OSD_PROTOCOL 7 /* cluster internal */ #define CEPH_MDS_PROTOCOL 9 /* cluster internal */ -#define CEPH_MON_PROTOCOL 4 /* cluster internal */ +#define CEPH_MON_PROTOCOL 5 /* cluster internal */ #define CEPH_OSDC_PROTOCOL 20 /* server/client */ #define CEPH_MDSC_PROTOCOL 29 /* server/client */ -#define CEPH_MONC_PROTOCOL 14 /* server/client */ +#define CEPH_MONC_PROTOCOL 15 /* server/client */ #define CEPH_INO_ROOT 1 @@ -118,9 +118,14 @@ struct ceph_file_layout { #define CEPH_MSG_OSD_OP 42 #define CEPH_MSG_OSD_OPREPLY 43 +struct ceph_mon_request_header { + __le64 have_version; + __le16 session_mon; + __le64 session_mon_tid; +} __attribute__ ((packed)); struct ceph_mon_statfs { - __le64 have_version; + struct ceph_mon_request_header monhdr; struct ceph_fsid fsid; __le64 tid; } __attribute__ ((packed)); @@ -138,22 +143,22 @@ struct ceph_mon_statfs_reply { } __attribute__ ((packed)); struct ceph_osd_getmap { - __le64 have_version; + struct ceph_mon_request_header monhdr; struct ceph_fsid fsid; __le32 start; } __attribute__ ((packed)); struct ceph_mds_getmap { - __le64 have_version; + struct ceph_mon_request_header monhdr; struct ceph_fsid fsid; } __attribute__ ((packed)); struct ceph_client_mount { - __le64 have_version; + struct ceph_mon_request_header monhdr; } __attribute__ ((packed)); struct ceph_mon_subscribe_item { - __le64 have; + __le64 have_version; __le64 have; __u8 onetime; } __attribute__ ((packed)); diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index 63f7f13..b48abc0 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -857,7 +857,7 @@ out: static int verify_hello(struct ceph_connection *con) { if (memcmp(con->in_banner, CEPH_BANNER, strlen(CEPH_BANNER))) { - pr_err("connect to/from %s has bad banner\n", + pr_err("connect to %s got bad banner\n", pr_addr(&con->peer_addr.in_addr)); con->error_msg = "protocol error, bad banner"; return -1; diff --git a/fs/ceph/mon_client.c b/fs/ceph/mon_client.c index 9c34df1..dc698ca 100644 --- a/fs/ceph/mon_client.c +++ b/fs/ceph/mon_client.c @@ -273,7 +273,9 @@ static void __request_mount(struct ceph_mon_client *monc) if (IS_ERR(msg)) return; h = msg->front.iov_base; - h->have_version = 0; + h->monhdr.have_version = 0; + h->monhdr.session_mon = cpu_to_le16(-1); + h->monhdr.session_mon_tid = 0; ceph_con_send(monc->con, msg); } @@ -422,7 +424,9 @@ static int send_statfs(struct ceph_mon_client *monc, return PTR_ERR(msg); req->request = msg; h = msg->front.iov_base; - h->have_version = 0; + h->monhdr.have_version = 0; + h->monhdr.session_mon = cpu_to_le16(-1); + h->monhdr.session_mon_tid = 0; h->fsid = monc->monmap->fsid; h->tid = cpu_to_le64(req->tid); ceph_con_send(monc->con, msg); -- cgit v0.10.2 From 752727a1b21a462d6ef634d552f180ae692f8947 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 9 Oct 2009 16:38:45 -0700 Subject: ceph: add file layout validation This tracks updates to code shared with userspace. Signed-off-by: Sage Weil diff --git a/fs/ceph/ceph_fs.c b/fs/ceph/ceph_fs.c index 9371ff1..a950b40 100644 --- a/fs/ceph/ceph_fs.c +++ b/fs/ceph/ceph_fs.c @@ -3,6 +3,30 @@ */ #include "types.h" +/* + * return true if @layout appears to be valid + */ +int ceph_file_layout_is_valid(const struct ceph_file_layout *layout) +{ + __u32 su = le32_to_cpu(layout->fl_stripe_unit); + __u32 sc = le32_to_cpu(layout->fl_stripe_count); + __u32 os = le32_to_cpu(layout->fl_object_size); + + /* stripe unit, object size must be non-zero, 64k increment */ + if (!su || (su & (CEPH_MIN_STRIPE_UNIT-1))) + return 0; + if (!os || (os & (CEPH_MIN_STRIPE_UNIT-1))) + return 0; + /* object size must be a multiple of stripe unit */ + if (os < su || os % su) + return 0; + /* stripe count must be non-zero */ + if (!sc) + return 0; + return 1; +} + + int ceph_flags_to_mode(int flags) { #ifdef O_DIRECTORY /* fixme */ diff --git a/fs/ceph/ceph_fs.h b/fs/ceph/ceph_fs.h index acf24c6..b3bbab1 100644 --- a/fs/ceph/ceph_fs.h +++ b/fs/ceph/ceph_fs.h @@ -72,7 +72,9 @@ struct ceph_file_layout { __le32 fl_pg_pool; /* namespace, crush ruleset, rep level */ } __attribute__ ((packed)); +#define CEPH_MIN_STRIPE_UNIT 65536 +int ceph_file_layout_is_valid(const struct ceph_file_layout *layout); /********************************************* -- cgit v0.10.2 From 8fc57da4d32767cc6096ecaed24636dabefd1dbc Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 12 Oct 2009 10:28:13 -0700 Subject: ceph: ignore trailing data in monamp This lets us extend the format more easily. Signed-off-by: Sage Weil diff --git a/fs/ceph/mon_client.c b/fs/ceph/mon_client.c index dc698ca..d6c8e78 100644 --- a/fs/ceph/mon_client.c +++ b/fs/ceph/mon_client.c @@ -60,9 +60,6 @@ struct ceph_monmap *ceph_monmap_decode(void *p, void *end) m->num_mon = num_mon; ceph_decode_copy(&p, m->mon_inst, num_mon*sizeof(m->mon_inst[0])); - if (p != end) - goto bad; - dout("monmap_decode epoch %d, num_mon %d\n", m->epoch, m->num_mon); for (i = 0; i < m->num_mon; i++) -- cgit v0.10.2 From 572033069dbc2cff8d4a2d2b34c576e1813fda70 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 9 Oct 2009 21:52:34 -0700 Subject: ceph: remove unused CEPH_MSG_{OSD,MDS}_GETMAP Signed-off-by: Sage Weil diff --git a/fs/ceph/ceph_fs.h b/fs/ceph/ceph_fs.h index b3bbab1..56af192 100644 --- a/fs/ceph/ceph_fs.h +++ b/fs/ceph/ceph_fs.h @@ -100,7 +100,6 @@ int ceph_file_layout_is_valid(const struct ceph_file_layout *layout); #define CEPH_MSG_MON_SUBSCRIBE_ACK 16 /* client <-> mds */ -#define CEPH_MSG_MDS_GETMAP 20 #define CEPH_MSG_MDS_MAP 21 #define CEPH_MSG_CLIENT_SESSION 22 @@ -115,7 +114,6 @@ int ceph_file_layout_is_valid(const struct ceph_file_layout *layout); #define CEPH_MSG_CLIENT_CAPRELEASE 0x313 /* osd */ -#define CEPH_MSG_OSD_GETMAP 40 #define CEPH_MSG_OSD_MAP 41 #define CEPH_MSG_OSD_OP 42 #define CEPH_MSG_OSD_OPREPLY 43 diff --git a/fs/ceph/super.c b/fs/ceph/super.c index b3404a3..442a990 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -231,7 +231,6 @@ const char *ceph_msg_type_name(int type) case CEPH_MSG_CLIENT_MOUNT_ACK: return "client_mount_ack"; case CEPH_MSG_STATFS: return "statfs"; case CEPH_MSG_STATFS_REPLY: return "statfs_reply"; - case CEPH_MSG_MDS_GETMAP: return "mds_getmap"; case CEPH_MSG_MDS_MAP: return "mds_map"; case CEPH_MSG_CLIENT_SESSION: return "client_session"; case CEPH_MSG_CLIENT_RECONNECT: return "client_reconnect"; @@ -242,7 +241,6 @@ const char *ceph_msg_type_name(int type) case CEPH_MSG_CLIENT_CAPRELEASE: return "client_cap_release"; case CEPH_MSG_CLIENT_SNAP: return "client_snap"; case CEPH_MSG_CLIENT_LEASE: return "client_lease"; - case CEPH_MSG_OSD_GETMAP: return "osd_getmap"; case CEPH_MSG_OSD_MAP: return "osd_map"; case CEPH_MSG_OSD_OP: return "osd_op"; case CEPH_MSG_OSD_OPREPLY: return "osd_opreply"; -- cgit v0.10.2 From 535bbb530764b1b2b3b732837f0e61e1baae7109 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 13 Oct 2009 12:55:26 -0700 Subject: ceph: add version field to message header This makes it easier for individual message types to indicate their particular encoding, and make future changes backward compatible. Signed-off-by: Sage Weil diff --git a/fs/ceph/msgr.h b/fs/ceph/msgr.h index 73921ae..9abc879 100644 --- a/fs/ceph/msgr.h +++ b/fs/ceph/msgr.h @@ -21,7 +21,7 @@ * whenever the wire protocol changes. try to keep this string length * constant. */ -#define CEPH_BANNER "ceph v021" +#define CEPH_BANNER "ceph v022" #define CEPH_BANNER_MAX_LEN 30 @@ -125,6 +125,7 @@ struct ceph_msg_header { __le64 seq; /* message seq# for this session */ __le16 type; /* message type */ __le16 priority; /* priority. higher value == higher priority */ + __le16 version; /* version of message encoding */ __le32 front_len; /* bytes in main payload */ __le32 middle_len;/* bytes in middle payload */ -- cgit v0.10.2 From c89136ea4253c73e89e97f5138bb22d97ad9f564 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 14 Oct 2009 09:59:09 -0700 Subject: ceph: convert encode/decode macros to inlines This avoids the fugly pass by reference and makes the code a bit easier to read. Signed-off-by: Sage Weil diff --git a/fs/ceph/decode.h b/fs/ceph/decode.h index fc2769d..91179fb 100644 --- a/fs/ceph/decode.h +++ b/fs/ceph/decode.h @@ -3,12 +3,44 @@ #include +#include "types.h" + /* * in all cases, * void **p pointer to position pointer * void *end pointer to end of buffer (last byte + 1) */ +static inline u64 ceph_decode_64(void **p) +{ + u64 v = get_unaligned_le64(*p); + *p += sizeof(u64); + return v; +} +static inline u32 ceph_decode_32(void **p) +{ + u32 v = get_unaligned_le32(*p); + *p += sizeof(u32); + return v; +} +static inline u16 ceph_decode_16(void **p) +{ + u16 v = get_unaligned_le16(*p); + *p += sizeof(u16); + return v; +} +static inline u8 ceph_decode_8(void **p) +{ + u8 v = *(u8 *)*p; + (*p)++; + return v; +} +static inline void ceph_decode_copy(void **p, void *pv, size_t n) +{ + memcpy(pv, *p, n); + *p += n; +} + /* * bounds check input. */ @@ -18,48 +50,20 @@ goto bad; \ } while (0) -#define ceph_decode_64(p, v) \ - do { \ - v = get_unaligned_le64(*(p)); \ - *(p) += sizeof(u64); \ - } while (0) -#define ceph_decode_32(p, v) \ - do { \ - v = get_unaligned_le32(*(p)); \ - *(p) += sizeof(u32); \ - } while (0) -#define ceph_decode_16(p, v) \ - do { \ - v = get_unaligned_le16(*(p)); \ - *(p) += sizeof(u16); \ - } while (0) -#define ceph_decode_8(p, v) \ - do { \ - v = *(u8 *)*(p); \ - (*p)++; \ - } while (0) - -#define ceph_decode_copy(p, pv, n) \ - do { \ - memcpy(pv, *(p), n); \ - *(p) += n; \ - } while (0) - -/* bounds check too */ #define ceph_decode_64_safe(p, end, v, bad) \ do { \ ceph_decode_need(p, end, sizeof(u64), bad); \ - ceph_decode_64(p, v); \ + v = ceph_decode_64(p); \ } while (0) #define ceph_decode_32_safe(p, end, v, bad) \ do { \ ceph_decode_need(p, end, sizeof(u32), bad); \ - ceph_decode_32(p, v); \ + v = ceph_decode_32(p); \ } while (0) #define ceph_decode_16_safe(p, end, v, bad) \ do { \ ceph_decode_need(p, end, sizeof(u16), bad); \ - ceph_decode_16(p, v); \ + v = ceph_decode_16(p); \ } while (0) #define ceph_decode_copy_safe(p, end, pv, n, bad) \ @@ -71,41 +75,42 @@ /* * struct ceph_timespec <-> struct timespec */ -#define ceph_decode_timespec(ts, tv) \ - do { \ - (ts)->tv_sec = le32_to_cpu((tv)->tv_sec); \ - (ts)->tv_nsec = le32_to_cpu((tv)->tv_nsec); \ - } while (0) -#define ceph_encode_timespec(tv, ts) \ - do { \ - (tv)->tv_sec = cpu_to_le32((ts)->tv_sec); \ - (tv)->tv_nsec = cpu_to_le32((ts)->tv_nsec); \ - } while (0) - +static inline void ceph_decode_timespec(struct timespec *ts, + struct ceph_timespec *tv) +{ + ts->tv_sec = le32_to_cpu(tv->tv_sec); + ts->tv_nsec = le32_to_cpu(tv->tv_nsec); +} +static inline void ceph_encode_timespec(struct ceph_timespec *tv, + struct timespec *ts) +{ + tv->tv_sec = cpu_to_le32(ts->tv_sec); + tv->tv_nsec = cpu_to_le32(ts->tv_nsec); +} /* * encoders */ -#define ceph_encode_64(p, v) \ - do { \ - put_unaligned_le64(v, (__le64 *)*(p)); \ - *(p) += sizeof(u64); \ - } while (0) -#define ceph_encode_32(p, v) \ - do { \ - put_unaligned_le32(v, (__le32 *)*(p)); \ - *(p) += sizeof(u32); \ - } while (0) -#define ceph_encode_16(p, v) \ - do { \ - put_unaligned_le16(v), (__le16 *)*(p)); \ - *(p) += sizeof(u16); \ - } while (0) -#define ceph_encode_8(p, v) \ - do { \ - *(u8 *)*(p) = v; \ - (*(p))++; \ - } while (0) +static inline void ceph_encode_64(void **p, u64 v) +{ + put_unaligned_le64(v, (__le64 *)*p); + *p += sizeof(u64); +} +static inline void ceph_encode_32(void **p, u32 v) +{ + put_unaligned_le32(v, (__le32 *)*p); + *p += sizeof(u32); +} +static inline void ceph_encode_16(void **p, u16 v) +{ + put_unaligned_le16(v, (__le16 *)*p); + *p += sizeof(u16); +} +static inline void ceph_encode_8(void **p, u8 v) +{ + *(u8 *)*p = v; + (*p)++; +} /* * filepath, string encoders diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index de8ba4a..2b19da3 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -136,9 +136,9 @@ static int parse_reply_info_dir(void **p, void *end, goto bad; ceph_decode_need(p, end, sizeof(num) + 2, bad); - ceph_decode_32(p, num); - ceph_decode_8(p, info->dir_end); - ceph_decode_8(p, info->dir_complete); + num = ceph_decode_32(p); + info->dir_end = ceph_decode_8(p); + info->dir_complete = ceph_decode_8(p); if (num == 0) goto done; @@ -160,7 +160,7 @@ static int parse_reply_info_dir(void **p, void *end, while (num) { /* dentry */ ceph_decode_need(p, end, sizeof(u32)*2, bad); - ceph_decode_32(p, info->dir_dname_len[i]); + info->dir_dname_len[i] = ceph_decode_32(p); ceph_decode_need(p, end, info->dir_dname_len[i], bad); info->dir_dname[i] = *p; *p += info->dir_dname_len[i]; @@ -1791,10 +1791,10 @@ static void handle_forward(struct ceph_mds_client *mdsc, struct ceph_msg *msg) from_mds = le64_to_cpu(msg->hdr.src.name.num); ceph_decode_need(&p, end, sizeof(u64)+2*sizeof(u32), bad); - ceph_decode_64(&p, tid); - ceph_decode_32(&p, next_mds); - ceph_decode_32(&p, fwd_seq); - ceph_decode_8(&p, must_resend); + tid = ceph_decode_64(&p); + next_mds = ceph_decode_32(&p); + fwd_seq = ceph_decode_32(&p); + must_resend = ceph_decode_8(&p); WARN_ON(must_resend); /* shouldn't happen. */ @@ -2783,8 +2783,8 @@ void ceph_mdsc_handle_map(struct ceph_mds_client *mdsc, struct ceph_msg *msg) pr_err("got mdsmap with wrong fsid\n"); return; } - ceph_decode_32(&p, epoch); - ceph_decode_32(&p, maplen); + epoch = ceph_decode_32(&p); + maplen = ceph_decode_32(&p); dout("handle_map epoch %u len %d\n", epoch, (int)maplen); /* do we need it? */ diff --git a/fs/ceph/mdsmap.c b/fs/ceph/mdsmap.c index 09180d8..80daea0 100644 --- a/fs/ceph/mdsmap.c +++ b/fs/ceph/mdsmap.c @@ -60,21 +60,21 @@ struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end) ceph_decode_16_safe(p, end, version, bad); ceph_decode_need(p, end, 8*sizeof(u32) + sizeof(u64), bad); - ceph_decode_32(p, m->m_epoch); - ceph_decode_32(p, m->m_client_epoch); - ceph_decode_32(p, m->m_last_failure); - ceph_decode_32(p, m->m_root); - ceph_decode_32(p, m->m_session_timeout); - ceph_decode_32(p, m->m_session_autoclose); - ceph_decode_64(p, m->m_max_file_size); - ceph_decode_32(p, m->m_max_mds); + m->m_epoch = ceph_decode_32(p); + m->m_client_epoch = ceph_decode_32(p); + m->m_last_failure = ceph_decode_32(p); + m->m_root = ceph_decode_32(p); + m->m_session_timeout = ceph_decode_32(p); + m->m_session_autoclose = ceph_decode_32(p); + m->m_max_file_size = ceph_decode_64(p); + m->m_max_mds = ceph_decode_32(p); m->m_info = kcalloc(m->m_max_mds, sizeof(*m->m_info), GFP_NOFS); if (m->m_info == NULL) goto badmem; /* pick out active nodes from mds_info (state > 0) */ - ceph_decode_32(p, n); + n = ceph_decode_32(p); for (i = 0; i < n; i++) { u32 namelen; s32 mds, inc, state; @@ -86,18 +86,18 @@ struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end) ceph_decode_need(p, end, sizeof(addr) + 1 + sizeof(u32), bad); ceph_decode_copy(p, &addr, sizeof(addr)); - ceph_decode_8(p, infoversion); - ceph_decode_32(p, namelen); /* skip mds name */ + infoversion = ceph_decode_8(p); + namelen = ceph_decode_32(p); /* skip mds name */ *p += namelen; ceph_decode_need(p, end, 4*sizeof(u32) + sizeof(u64) + sizeof(addr) + sizeof(struct ceph_timespec), bad); - ceph_decode_32(p, mds); - ceph_decode_32(p, inc); - ceph_decode_32(p, state); - ceph_decode_64(p, state_seq); + mds = ceph_decode_32(p); + inc = ceph_decode_32(p); + state = ceph_decode_32(p); + state_seq = ceph_decode_64(p); *p += sizeof(addr); *p += sizeof(struct ceph_timespec); *p += sizeof(u32); @@ -123,8 +123,8 @@ struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end) kcalloc(num_export_targets, sizeof(u32), GFP_NOFS); for (j = 0; j < num_export_targets; j++) - ceph_decode_32(&pexport_targets, - m->m_info[mds].export_targets[j]); + m->m_info[mds].export_targets[j] = + ceph_decode_32(&pexport_targets); } else { m->m_info[mds].export_targets = NULL; } @@ -139,8 +139,8 @@ struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end) goto badmem; ceph_decode_need(p, end, sizeof(u32)*(n+1), bad); for (i = 0; i < n; i++) - ceph_decode_32(p, m->m_data_pg_pools[i]); - ceph_decode_32(p, m->m_cas_pg_pool); + m->m_data_pg_pools[i] = ceph_decode_32(p); + m->m_cas_pg_pool = ceph_decode_32(p); /* ok, we don't care about the rest. */ dout("mdsmap_decode success epoch %u\n", m->m_epoch); diff --git a/fs/ceph/mon_client.c b/fs/ceph/mon_client.c index d6c8e78..bea2be90 100644 --- a/fs/ceph/mon_client.c +++ b/fs/ceph/mon_client.c @@ -45,9 +45,9 @@ struct ceph_monmap *ceph_monmap_decode(void *p, void *end) ceph_decode_need(&p, end, sizeof(fsid) + 2*sizeof(u32), bad); ceph_decode_copy(&p, &fsid, sizeof(fsid)); - ceph_decode_32(&p, epoch); + epoch = ceph_decode_32(&p); - ceph_decode_32(&p, num_mon); + num_mon = ceph_decode_32(&p); ceph_decode_need(&p, end, num_mon*sizeof(m->mon_inst[0]), bad); if (num_mon >= CEPH_MAX_MON) diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index 8e33928..bbd9a5d 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -894,8 +894,8 @@ void ceph_osdc_handle_map(struct ceph_osd_client *osdc, struct ceph_msg *msg) dout(" %d inc maps\n", nr_maps); while (nr_maps > 0) { ceph_decode_need(&p, end, 2*sizeof(u32), bad); - ceph_decode_32(&p, epoch); - ceph_decode_32(&p, maplen); + epoch = ceph_decode_32(&p); + maplen = ceph_decode_32(&p); ceph_decode_need(&p, end, maplen, bad); next = p + maplen; if (osdc->osdmap && osdc->osdmap->epoch+1 == epoch) { @@ -927,8 +927,8 @@ void ceph_osdc_handle_map(struct ceph_osd_client *osdc, struct ceph_msg *msg) dout(" %d full maps\n", nr_maps); while (nr_maps) { ceph_decode_need(&p, end, 2*sizeof(u32), bad); - ceph_decode_32(&p, epoch); - ceph_decode_32(&p, maplen); + epoch = ceph_decode_32(&p); + maplen = ceph_decode_32(&p); ceph_decode_need(&p, end, maplen, bad); if (nr_maps > 1) { dout("skipping non-latest full map %u len %d\n", diff --git a/fs/ceph/osdmap.c b/fs/ceph/osdmap.c index 342e5f8..6f0aeff 100644 --- a/fs/ceph/osdmap.c +++ b/fs/ceph/osdmap.c @@ -67,7 +67,7 @@ static int crush_decode_uniform_bucket(void **p, void *end, { dout("crush_decode_uniform_bucket %p to %p\n", *p, end); ceph_decode_need(p, end, (1+b->h.size) * sizeof(u32), bad); - ceph_decode_32(p, b->item_weight); + b->item_weight = ceph_decode_32(p); return 0; bad: return -EINVAL; @@ -86,8 +86,8 @@ static int crush_decode_list_bucket(void **p, void *end, return -ENOMEM; ceph_decode_need(p, end, 2 * b->h.size * sizeof(u32), bad); for (j = 0; j < b->h.size; j++) { - ceph_decode_32(p, b->item_weights[j]); - ceph_decode_32(p, b->sum_weights[j]); + b->item_weights[j] = ceph_decode_32(p); + b->sum_weights[j] = ceph_decode_32(p); } return 0; bad: @@ -105,7 +105,7 @@ static int crush_decode_tree_bucket(void **p, void *end, return -ENOMEM; ceph_decode_need(p, end, b->num_nodes * sizeof(u32), bad); for (j = 0; j < b->num_nodes; j++) - ceph_decode_32(p, b->node_weights[j]); + b->node_weights[j] = ceph_decode_32(p); return 0; bad: return -EINVAL; @@ -124,8 +124,8 @@ static int crush_decode_straw_bucket(void **p, void *end, return -ENOMEM; ceph_decode_need(p, end, 2 * b->h.size * sizeof(u32), bad); for (j = 0; j < b->h.size; j++) { - ceph_decode_32(p, b->item_weights[j]); - ceph_decode_32(p, b->straws[j]); + b->item_weights[j] = ceph_decode_32(p); + b->straws[j] = ceph_decode_32(p); } return 0; bad: @@ -148,15 +148,15 @@ static struct crush_map *crush_decode(void *pbyval, void *end) return ERR_PTR(-ENOMEM); ceph_decode_need(p, end, 4*sizeof(u32), bad); - ceph_decode_32(p, magic); + magic = ceph_decode_32(p); if (magic != CRUSH_MAGIC) { pr_err("crush_decode magic %x != current %x\n", (unsigned)magic, (unsigned)CRUSH_MAGIC); goto bad; } - ceph_decode_32(p, c->max_buckets); - ceph_decode_32(p, c->max_rules); - ceph_decode_32(p, c->max_devices); + c->max_buckets = ceph_decode_32(p); + c->max_rules = ceph_decode_32(p); + c->max_devices = ceph_decode_32(p); c->device_parents = kcalloc(c->max_devices, sizeof(u32), GFP_NOFS); if (c->device_parents == NULL) @@ -208,11 +208,11 @@ static struct crush_map *crush_decode(void *pbyval, void *end) goto badmem; ceph_decode_need(p, end, 4*sizeof(u32), bad); - ceph_decode_32(p, b->id); - ceph_decode_16(p, b->type); - ceph_decode_16(p, b->alg); - ceph_decode_32(p, b->weight); - ceph_decode_32(p, b->size); + b->id = ceph_decode_32(p); + b->type = ceph_decode_16(p); + b->alg = ceph_decode_16(p); + b->weight = ceph_decode_32(p); + b->size = ceph_decode_32(p); dout("crush_decode bucket size %d off %x %p to %p\n", b->size, (int)(*p-start), *p, end); @@ -227,7 +227,7 @@ static struct crush_map *crush_decode(void *pbyval, void *end) ceph_decode_need(p, end, b->size*sizeof(u32), bad); for (j = 0; j < b->size; j++) - ceph_decode_32(p, b->items[j]); + b->items[j] = ceph_decode_32(p); switch (b->alg) { case CRUSH_BUCKET_UNIFORM: @@ -290,9 +290,9 @@ static struct crush_map *crush_decode(void *pbyval, void *end) ceph_decode_copy_safe(p, end, &r->mask, 4, bad); /* 4 u8's */ ceph_decode_need(p, end, r->len*3*sizeof(u32), bad); for (j = 0; j < r->len; j++) { - ceph_decode_32(p, r->steps[j].op); - ceph_decode_32(p, r->steps[j].arg1); - ceph_decode_32(p, r->steps[j].arg2); + r->steps[j].op = ceph_decode_32(p); + r->steps[j].arg1 = ceph_decode_32(p); + r->steps[j].arg2 = ceph_decode_32(p); } } @@ -411,11 +411,11 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end) ceph_decode_need(p, end, 2*sizeof(u64)+6*sizeof(u32), bad); ceph_decode_copy(p, &map->fsid, sizeof(map->fsid)); - ceph_decode_32(p, map->epoch); + map->epoch = ceph_decode_32(p); ceph_decode_copy(p, &map->created, sizeof(map->created)); ceph_decode_copy(p, &map->modified, sizeof(map->modified)); - ceph_decode_32(p, map->num_pools); + map->num_pools = ceph_decode_32(p); map->pg_pool = kcalloc(map->num_pools, sizeof(*map->pg_pool), GFP_NOFS); if (!map->pg_pool) { @@ -425,7 +425,7 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end) ceph_decode_32_safe(p, end, max, bad); while (max--) { ceph_decode_need(p, end, 4+sizeof(map->pg_pool->v), bad); - ceph_decode_32(p, i); + i = ceph_decode_32(p); if (i >= map->num_pools) goto bad; ceph_decode_copy(p, &map->pg_pool[i].v, @@ -438,7 +438,7 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end) ceph_decode_32_safe(p, end, map->flags, bad); - ceph_decode_32(p, max); + max = ceph_decode_32(p); /* (re)alloc osd arrays */ err = osdmap_set_max_osd(map, max); @@ -456,7 +456,7 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end) *p += 4; /* skip length field (should match max) */ for (i = 0; i < map->max_osd; i++) - ceph_decode_32(p, map->osd_weight[i]); + map->osd_weight[i] = ceph_decode_32(p); *p += 4; /* skip length field (should match max) */ ceph_decode_copy(p, map->osd_addr, map->max_osd*sizeof(*map->osd_addr)); @@ -469,8 +469,8 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end) struct ceph_pg_mapping *pg; ceph_decode_need(p, end, sizeof(u32) + sizeof(u64), bad); - ceph_decode_64(p, pgid); - ceph_decode_32(p, n); + pgid = ceph_decode_64(p); + n = ceph_decode_32(p); ceph_decode_need(p, end, n * sizeof(u32), bad); pg = kmalloc(sizeof(*pg) + n*sizeof(u32), GFP_NOFS); if (!pg) { @@ -480,7 +480,7 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end) pg->pgid = pgid; pg->len = n; for (j = 0; j < n; j++) - ceph_decode_32(p, pg->osds[j]); + pg->osds[j] = ceph_decode_32(p); err = __insert_pg_mapping(pg, &map->pg_temp); if (err) @@ -537,10 +537,10 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, ceph_decode_need(p, end, sizeof(fsid)+sizeof(modified)+2*sizeof(u32), bad); ceph_decode_copy(p, &fsid, sizeof(fsid)); - ceph_decode_32(p, epoch); + epoch = ceph_decode_32(p); BUG_ON(epoch != map->epoch+1); ceph_decode_copy(p, &modified, sizeof(modified)); - ceph_decode_32(p, new_flags); + new_flags = ceph_decode_32(p); /* full map? */ ceph_decode_32_safe(p, end, len, bad); @@ -568,7 +568,7 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, ceph_decode_need(p, end, 5*sizeof(u32), bad); /* new max? */ - ceph_decode_32(p, max); + max = ceph_decode_32(p); if (max >= 0) { err = osdmap_set_max_osd(map, max); if (err < 0) @@ -641,8 +641,8 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, while (len--) { u32 osd, off; ceph_decode_need(p, end, sizeof(u32)*2, bad); - ceph_decode_32(p, osd); - ceph_decode_32(p, off); + osd = ceph_decode_32(p); + off = ceph_decode_32(p); pr_info("osd%d weight 0x%x %s\n", osd, off, off == CEPH_OSD_IN ? "(in)" : (off == CEPH_OSD_OUT ? "(out)" : "")); @@ -659,8 +659,8 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, u64 pgid; u32 pglen; ceph_decode_need(p, end, sizeof(u64) + sizeof(u32), bad); - ceph_decode_64(p, pgid); - ceph_decode_32(p, pglen); + pgid = ceph_decode_64(p); + pglen = ceph_decode_32(p); /* remove any? */ while (rbp && rb_entry(rbp, struct ceph_pg_mapping, @@ -683,7 +683,7 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, pg->pgid = pgid; pg->len = pglen; for (j = 0; j < len; j++) - ceph_decode_32(p, pg->osds[j]); + pg->osds[j] = ceph_decode_32(p); err = __insert_pg_mapping(pg, &map->pg_temp); if (err) goto bad; -- cgit v0.10.2 From f2cf418cec8d61df0651a0140a92a8c75246e14f Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 14 Oct 2009 14:09:07 -0700 Subject: ceph: initialize sb->s_bdi, bdi_unregister after kill_anon_super Writeback doesn't work without the bdi set, and writeback on umount doesn't work if we unregister the bdi too early. Signed-off-by: Sage Weil diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 442a990..7f7d475 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -97,6 +97,7 @@ static int ceph_syncfs(struct super_block *sb, int wait) dout("sync_fs %d\n", wait); ceph_osdc_sync(&ceph_client(sb)->osdc); ceph_mdsc_sync(&ceph_client(sb)->mdsc); + dout("sync_fs %d done\n", wait); return 0; } @@ -777,6 +778,7 @@ static int ceph_init_bdi(struct super_block *sb, struct ceph_client *client) err = bdi_init(&client->backing_dev_info); if (err < 0) return err; + sb->s_bdi = &client->backing_dev_info; /* set ra_pages based on rsize mount option? */ if (client->mount_args.rsize >= PAGE_CACHE_SIZE) @@ -861,8 +863,8 @@ static void ceph_kill_sb(struct super_block *s) struct ceph_client *client = ceph_sb_to_client(s); dout("kill_sb %p\n", s); ceph_mdsc_pre_umount(&client->mdsc); - bdi_unregister(&client->backing_dev_info); kill_anon_super(s); /* will call put_super after sb is r/o */ + bdi_unregister(&client->backing_dev_info); bdi_destroy(&client->backing_dev_info); ceph_destroy_client(client); } -- cgit v0.10.2 From cdc35f96277314bbfeefd0505410cabd69aebd8d Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 14 Oct 2009 14:24:19 -0700 Subject: ceph: move generic flushing code into helper Both callers of __mark_caps_flushing() do the same work; move it into the helper. Signed-off-by: Sage Weil diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 5c7d0e9..111439d 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -1272,16 +1272,30 @@ static void ceph_flush_snaps(struct ceph_inode_info *ci) /* * Add dirty inode to the flushing list. Assigned a seq number so we * can wait for caps to flush without starving. + * + * Called under i_lock. */ -static void __mark_caps_flushing(struct inode *inode, +static int __mark_caps_flushing(struct inode *inode, struct ceph_mds_session *session) { struct ceph_mds_client *mdsc = &ceph_client(inode->i_sb)->mdsc; struct ceph_inode_info *ci = ceph_inode(inode); - + int flushing; + + BUG_ON(ci->i_dirty_caps == 0); BUG_ON(list_empty(&ci->i_dirty_item)); + + flushing = ci->i_dirty_caps; + dout("__mark_caps_flushing flushing %s, flushing_caps %s -> %s\n", + ceph_cap_string(flushing), + ceph_cap_string(ci->i_flushing_caps), + ceph_cap_string(ci->i_flushing_caps | flushing)); + ci->i_flushing_caps |= flushing; + ci->i_dirty_caps = 0; + spin_lock(&mdsc->cap_dirty_lock); if (list_empty(&ci->i_flushing_item)) { + list_del_init(&ci->i_dirty_item); list_add_tail(&ci->i_flushing_item, &session->s_cap_flushing); mdsc->num_cap_flushing++; ci->i_cap_flush_seq = ++mdsc->cap_flush_seq; @@ -1289,6 +1303,8 @@ static void __mark_caps_flushing(struct inode *inode, ci->i_cap_flush_seq); } spin_unlock(&mdsc->cap_dirty_lock); + + return flushing; } /* @@ -1504,17 +1520,8 @@ ack: took_snap_rwsem = 1; } - if (cap == ci->i_auth_cap && ci->i_dirty_caps) { - /* update dirty, flushing bits */ - flushing = ci->i_dirty_caps; - dout(" flushing %s, flushing_caps %s -> %s\n", - ceph_cap_string(flushing), - ceph_cap_string(ci->i_flushing_caps), - ceph_cap_string(ci->i_flushing_caps | flushing)); - ci->i_flushing_caps |= flushing; - ci->i_dirty_caps = 0; - __mark_caps_flushing(inode, session); - } + if (cap == ci->i_auth_cap && ci->i_dirty_caps) + flushing = __mark_caps_flushing(inode, session); mds = cap->mds; /* remember mds, so we don't repeat */ sent++; @@ -1605,15 +1612,7 @@ retry: if (cap->session->s_state < CEPH_MDS_SESSION_OPEN) goto out; - __mark_caps_flushing(inode, session); - - flushing = ci->i_dirty_caps; - dout(" flushing %s, flushing_caps %s -> %s\n", - ceph_cap_string(flushing), - ceph_cap_string(ci->i_flushing_caps), - ceph_cap_string(ci->i_flushing_caps | flushing)); - ci->i_flushing_caps |= flushing; - ci->i_dirty_caps = 0; + flushing = __mark_caps_flushing(inode, session); /* __send_cap drops i_lock */ delayed = __send_cap(mdsc, cap, CEPH_CAP_OP_FLUSH, used, want, -- cgit v0.10.2 From afcdaea3f2a78ce4873bd7e98a6d603bda23d167 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 14 Oct 2009 14:27:38 -0700 Subject: ceph: flush dirty caps via the cap_dirty list Previously we were flushing dirty caps by passing an extra flag when traversing the delayed caps list. Besides being a bit ugly, that can also miss caps that are dirty but didn't result in a cap requeue: notably, mark_caps_dirty(). Separate the flushing into a separate helper, and traverse the cap_dirty list. This also brings i_dirty_item in line with i_dirty_caps: we are on the list IFF caps != 0. We carry an inode ref IFF dirty_caps|flushing_caps != 0. Lose the unused return value from __ceph_mark_caps_dirty(). Signed-off-by: Sage Weil diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 111439d..40b8d34 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -997,7 +997,7 @@ void ceph_queue_caps_release(struct inode *inode) if (le32_to_cpu(head->num) == CEPH_CAPS_PER_RELEASE) { dout(" release msg %p full\n", msg); list_move_tail(&msg->list_head, - &session->s_cap_releases_done); + &session->s_cap_releases_done); } else { dout(" release msg %p at %d/%d (%d)\n", msg, (int)le32_to_cpu(head->num), @@ -1292,14 +1292,20 @@ static int __mark_caps_flushing(struct inode *inode, ceph_cap_string(ci->i_flushing_caps | flushing)); ci->i_flushing_caps |= flushing; ci->i_dirty_caps = 0; + dout(" inode %p now !dirty\n", inode); spin_lock(&mdsc->cap_dirty_lock); + list_del_init(&ci->i_dirty_item); + + ci->i_cap_flush_seq = ++mdsc->cap_flush_seq; if (list_empty(&ci->i_flushing_item)) { - list_del_init(&ci->i_dirty_item); list_add_tail(&ci->i_flushing_item, &session->s_cap_flushing); mdsc->num_cap_flushing++; - ci->i_cap_flush_seq = ++mdsc->cap_flush_seq; - dout(" inode %p now flushing seq %lld\n", &ci->vfs_inode, + dout(" inode %p now flushing seq %lld\n", inode, + ci->i_cap_flush_seq); + } else { + list_move_tail(&ci->i_flushing_item, &session->s_cap_flushing); + dout(" inode %p now flushing (more) seq %lld\n", inode, ci->i_cap_flush_seq); } spin_unlock(&mdsc->cap_dirty_lock); @@ -1555,32 +1561,33 @@ ack: * Mark caps dirty. If inode is newly dirty, add to the global dirty * list. */ -int __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask) +void __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask) { struct ceph_mds_client *mdsc = &ceph_client(ci->vfs_inode.i_sb)->mdsc; struct inode *inode = &ci->vfs_inode; - int was = __ceph_caps_dirty(ci); + int was_dirty = ci->i_dirty_caps; int dirty = 0; dout("__mark_dirty_caps %p %s dirty %s -> %s\n", &ci->vfs_inode, ceph_cap_string(mask), ceph_cap_string(ci->i_dirty_caps), ceph_cap_string(ci->i_dirty_caps | mask)); ci->i_dirty_caps |= mask; - if (!was) { + if (!was_dirty) { dout(" inode %p now dirty\n", &ci->vfs_inode); spin_lock(&mdsc->cap_dirty_lock); list_add(&ci->i_dirty_item, &mdsc->cap_dirty); spin_unlock(&mdsc->cap_dirty_lock); - igrab(inode); - dirty |= I_DIRTY_SYNC; + if (ci->i_flushing_caps == 0) { + igrab(inode); + dirty |= I_DIRTY_SYNC; + } } - if ((was & CEPH_CAP_FILE_BUFFER) && + if (((was_dirty | ci->i_flushing_caps) & CEPH_CAP_FILE_BUFFER) && (mask & CEPH_CAP_FILE_BUFFER)) dirty |= I_DIRTY_DATASYNC; if (dirty) __mark_inode_dirty(inode, dirty); __cap_delay_requeue(mdsc, ci); - return was; } /* @@ -2327,7 +2334,7 @@ static void handle_cap_flush_ack(struct inode *inode, int dirty = le32_to_cpu(m->dirty); int cleaned = 0; u64 flush_tid = le64_to_cpu(m->client_tid); - int old_dirty = 0, new_dirty = 0; + int drop = 0; int i; for (i = 0; i < CEPH_CAP_BITS; i++) @@ -2344,9 +2351,7 @@ static void handle_cap_flush_ack(struct inode *inode, if (ci->i_flushing_caps == (ci->i_flushing_caps & ~cleaned)) goto out; - old_dirty = ci->i_dirty_caps | ci->i_flushing_caps; ci->i_flushing_caps &= ~cleaned; - new_dirty = ci->i_dirty_caps | ci->i_flushing_caps; spin_lock(&mdsc->cap_dirty_lock); if (ci->i_flushing_caps == 0) { @@ -2360,17 +2365,19 @@ static void handle_cap_flush_ack(struct inode *inode, mdsc->num_cap_flushing--; wake_up(&mdsc->cap_flushing_wq); dout(" inode %p now !flushing\n", inode); - } - if (old_dirty && !new_dirty) { - dout(" inode %p now clean\n", inode); - list_del_init(&ci->i_dirty_item); + + if (ci->i_dirty_caps == 0) { + dout(" inode %p now clean\n", inode); + BUG_ON(!list_empty(&ci->i_dirty_item)); + drop = 1; + } } spin_unlock(&mdsc->cap_dirty_lock); wake_up(&ci->i_cap_wq); out: spin_unlock(&inode->i_lock); - if (old_dirty && !new_dirty) + if (drop) iput(inode); } @@ -2676,14 +2683,11 @@ bad: /* * Delayed work handler to process end of delayed cap release LRU list. */ -void ceph_check_delayed_caps(struct ceph_mds_client *mdsc, int flushdirty) +void ceph_check_delayed_caps(struct ceph_mds_client *mdsc) { struct ceph_inode_info *ci; int flags = CHECK_CAPS_NODELAY; - if (flushdirty) - flags |= CHECK_CAPS_FLUSH; - dout("check_delayed_caps\n"); while (1) { spin_lock(&mdsc->cap_delay_lock); @@ -2704,6 +2708,32 @@ void ceph_check_delayed_caps(struct ceph_mds_client *mdsc, int flushdirty) } /* + * Flush all dirty caps to the mds + */ +void ceph_flush_dirty_caps(struct ceph_mds_client *mdsc) +{ + struct ceph_inode_info *ci; + struct inode *inode; + + dout("flush_dirty_caps\n"); + spin_lock(&mdsc->cap_dirty_lock); + while (!list_empty(&mdsc->cap_dirty)) { + ci = list_first_entry(&mdsc->cap_dirty, + struct ceph_inode_info, + i_dirty_item); + inode = igrab(&ci->vfs_inode); + spin_unlock(&mdsc->cap_dirty_lock); + if (inode) { + ceph_check_caps(ci, CHECK_CAPS_NODELAY|CHECK_CAPS_FLUSH, + NULL); + iput(inode); + } + spin_lock(&mdsc->cap_dirty_lock); + } + spin_unlock(&mdsc->cap_dirty_lock); +} + +/* * Drop open file reference. If we were the last open file, * we may need to release capabilities to the MDS (or schedule * their delayed release). diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 2b19da3..12d66c0 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -2504,7 +2504,7 @@ static void delayed_work(struct work_struct *work) int renew_caps; dout("mdsc delayed_work\n"); - ceph_check_delayed_caps(mdsc, 0); + ceph_check_delayed_caps(mdsc); mutex_lock(&mdsc->mutex); renew_interval = mdsc->mdsmap->m_session_timeout >> 2; @@ -2627,7 +2627,7 @@ void ceph_mdsc_pre_umount(struct ceph_mds_client *mdsc) mdsc->stopping = 1; drop_leases(mdsc); - ceph_check_delayed_caps(mdsc, 1); + ceph_flush_dirty_caps(mdsc); wait_requests(mdsc); } @@ -2677,7 +2677,7 @@ void ceph_mdsc_sync(struct ceph_mds_client *mdsc) mutex_unlock(&mdsc->mutex); dout("sync want tid %lld flush_seq %lld\n", want_tid, want_flush); - ceph_check_delayed_caps(mdsc, 1); + ceph_flush_dirty_caps(mdsc); wait_unsafe_requests(mdsc, want_tid); wait_event(mdsc->cap_flushing_wq, check_cap_flush(mdsc, want_flush)); diff --git a/fs/ceph/super.h b/fs/ceph/super.h index cfd39ef..0bbf58a 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -524,7 +524,7 @@ static inline int __ceph_caps_dirty(struct ceph_inode_info *ci) { return ci->i_dirty_caps | ci->i_flushing_caps; } -extern int __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask); +extern void __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask); extern int ceph_caps_revoking(struct ceph_inode_info *ci, int mask); extern int __ceph_caps_used(struct ceph_inode_info *ci); @@ -814,8 +814,8 @@ extern void __ceph_flush_snaps(struct ceph_inode_info *ci, struct ceph_mds_session **psession); extern void ceph_check_caps(struct ceph_inode_info *ci, int flags, struct ceph_mds_session *session); -extern void ceph_check_delayed_caps(struct ceph_mds_client *mdsc, - int flushdirty); +extern void ceph_check_delayed_caps(struct ceph_mds_client *mdsc); +extern void ceph_flush_dirty_caps(struct ceph_mds_client *mdsc); extern int ceph_encode_inode_release(void **p, struct inode *inode, int mds, int drop, int unless, int force); -- cgit v0.10.2 From 07bd10fb9853a41a7f0bb271721cca97d15eccae Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 14 Oct 2009 17:26:40 -0700 Subject: ceph: correct subscribe_ack msgpool payload size Defined a struct for the SUBSCRIBE_ACK, and use that to size the msgpool. Signed-off-by: Sage Weil diff --git a/fs/ceph/ceph_fs.h b/fs/ceph/ceph_fs.h index 56af192..9b16e2e 100644 --- a/fs/ceph/ceph_fs.h +++ b/fs/ceph/ceph_fs.h @@ -162,6 +162,11 @@ struct ceph_mon_subscribe_item { __u8 onetime; } __attribute__ ((packed)); +struct ceph_mon_subscribe_ack { + __le32 duration; /* seconds */ + struct ceph_fsid fsid; +} __attribute__ ((packed)); + /* * mds states * > 0 -> in diff --git a/fs/ceph/mon_client.c b/fs/ceph/mon_client.c index bea2be90..d52e529 100644 --- a/fs/ceph/mon_client.c +++ b/fs/ceph/mon_client.c @@ -199,10 +199,12 @@ static void handle_subscribe_ack(struct ceph_mon_client *monc, struct ceph_msg *msg) { unsigned seconds; - void *p = msg->front.iov_base; - void *end = p + msg->front.iov_len; + struct ceph_mon_subscribe_ack *h = msg->front.iov_base; + + if (msg->front.iov_len < sizeof(*h)) + goto bad; + seconds = le32_to_cpu(h->duration); - ceph_decode_32_safe(&p, end, seconds, bad); mutex_lock(&monc->mutex); if (monc->hunting) { pr_info("mon%d %s session established\n", @@ -541,7 +543,8 @@ int ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl) err = ceph_msgpool_init(&monc->msgpool_mount_ack, 4096, 1, false); if (err < 0) goto out; - err = ceph_msgpool_init(&monc->msgpool_subscribe_ack, 8, 1, false); + err = ceph_msgpool_init(&monc->msgpool_subscribe_ack, + sizeof(struct ceph_mon_subscribe_ack), 1, false); if (err < 0) goto out; err = ceph_msgpool_init(&monc->msgpool_statfs_reply, -- cgit v0.10.2 From 8f3bc053c610826a657714649ea596f07875db2e Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 14 Oct 2009 17:36:07 -0700 Subject: ceph: warn on allocation from msgpool with larger front_len Pass the front_len we need when pulling a message off a msgpool, and WARN if it is greater than the pool's size. Then try to allocate a new message (to continue without failing). Signed-off-by: Sage Weil diff --git a/fs/ceph/mon_client.c b/fs/ceph/mon_client.c index d52e529..e6e954c 100644 --- a/fs/ceph/mon_client.c +++ b/fs/ceph/mon_client.c @@ -639,14 +639,15 @@ static struct ceph_msg *mon_alloc_msg(struct ceph_connection *con, { struct ceph_mon_client *monc = con->private; int type = le16_to_cpu(hdr->type); + int front = le32_to_cpu(hdr->front_len); switch (type) { case CEPH_MSG_CLIENT_MOUNT_ACK: - return ceph_msgpool_get(&monc->msgpool_mount_ack); + return ceph_msgpool_get(&monc->msgpool_mount_ack, front); case CEPH_MSG_MON_SUBSCRIBE_ACK: - return ceph_msgpool_get(&monc->msgpool_subscribe_ack); + return ceph_msgpool_get(&monc->msgpool_subscribe_ack, front); case CEPH_MSG_STATFS_REPLY: - return ceph_msgpool_get(&monc->msgpool_statfs_reply); + return ceph_msgpool_get(&monc->msgpool_statfs_reply, front); } return ceph_alloc_msg(con, hdr); } diff --git a/fs/ceph/msgpool.c b/fs/ceph/msgpool.c index 39d4d7e..7599b33 100644 --- a/fs/ceph/msgpool.c +++ b/fs/ceph/msgpool.c @@ -101,14 +101,28 @@ int ceph_msgpool_resv(struct ceph_msgpool *pool, int delta) return ret; } -struct ceph_msg *ceph_msgpool_get(struct ceph_msgpool *pool) +struct ceph_msg *ceph_msgpool_get(struct ceph_msgpool *pool, int front_len) { wait_queue_t wait; struct ceph_msg *msg; + if (front_len && front_len > pool->front_len) { + pr_err("msgpool_get pool %p need front %d, pool size is %d\n", + pool, front_len, pool->front_len); + WARN_ON(1); + + /* try to alloc a fresh message */ + msg = ceph_msg_new(0, front_len, 0, 0, NULL); + if (!IS_ERR(msg)) + return msg; + } + + if (!front_len) + front_len = pool->front_len; + if (pool->blocking) { /* mempool_t behavior; first try to alloc */ - msg = ceph_msg_new(0, pool->front_len, 0, 0, NULL); + msg = ceph_msg_new(0, front_len, 0, 0, NULL); if (!IS_ERR(msg)) return msg; } @@ -133,7 +147,7 @@ struct ceph_msg *ceph_msgpool_get(struct ceph_msgpool *pool) WARN_ON(1); /* maybe we can allocate it now? */ - msg = ceph_msg_new(0, pool->front_len, 0, 0, NULL); + msg = ceph_msg_new(0, front_len, 0, 0, NULL); if (!IS_ERR(msg)) return msg; diff --git a/fs/ceph/msgpool.h b/fs/ceph/msgpool.h index 07a2dec..bc834bf 100644 --- a/fs/ceph/msgpool.h +++ b/fs/ceph/msgpool.h @@ -20,7 +20,8 @@ extern int ceph_msgpool_init(struct ceph_msgpool *pool, int front_len, int size, bool blocking); extern void ceph_msgpool_destroy(struct ceph_msgpool *pool); extern int ceph_msgpool_resv(struct ceph_msgpool *, int delta); -extern struct ceph_msg *ceph_msgpool_get(struct ceph_msgpool *); +extern struct ceph_msg *ceph_msgpool_get(struct ceph_msgpool *, + int front_len); extern void ceph_msgpool_put(struct ceph_msgpool *, struct ceph_msg *); #endif diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index bbd9a5d..0a25405 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -161,7 +161,7 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc, if (snapc) msg_size += sizeof(u64) * snapc->num_snaps; if (use_mempool) - msg = ceph_msgpool_get(&osdc->msgpool_op); + msg = ceph_msgpool_get(&osdc->msgpool_op, 0); else msg = ceph_msg_new(CEPH_MSG_OSD_OP, msg_size, 0, 0, NULL); if (IS_ERR(msg)) { @@ -1271,10 +1271,11 @@ static struct ceph_msg *alloc_msg(struct ceph_connection *con, struct ceph_osd *osd = con->private; struct ceph_osd_client *osdc = osd->o_osdc; int type = le16_to_cpu(hdr->type); + int front = le32_to_cpu(hdr->front_len); switch (type) { case CEPH_MSG_OSD_OPREPLY: - return ceph_msgpool_get(&osdc->msgpool_op_reply); + return ceph_msgpool_get(&osdc->msgpool_op_reply, front); } return ceph_alloc_msg(con, hdr); } -- cgit v0.10.2 From 76e3b390d41db9d69e254a09dd1aedd3e6aac25f Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 15 Oct 2009 18:13:53 -0700 Subject: ceph: move dirty caps code around Cleanup only. Signed-off-by: Sage Weil diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 40b8d34..7d16618 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -1270,6 +1270,41 @@ static void ceph_flush_snaps(struct ceph_inode_info *ci) } /* + * Mark caps dirty. If inode is newly dirty, add to the global dirty + * list. + */ +void __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask) +{ + struct ceph_mds_client *mdsc = &ceph_client(ci->vfs_inode.i_sb)->mdsc; + struct inode *inode = &ci->vfs_inode; + int was = ci->i_dirty_caps; + int dirty = 0; + + dout("__mark_dirty_caps %p %s dirty %s -> %s\n", &ci->vfs_inode, + ceph_cap_string(mask), ceph_cap_string(was), + ceph_cap_string(was | mask)); + ci->i_dirty_caps |= mask; + if (was == 0) { + dout(" inode %p now dirty\n", &ci->vfs_inode); + BUG_ON(!list_empty(&ci->i_dirty_item)); + spin_lock(&mdsc->cap_dirty_lock); + list_add(&ci->i_dirty_item, &mdsc->cap_dirty); + spin_unlock(&mdsc->cap_dirty_lock); + if (ci->i_flushing_caps == 0) { + igrab(inode); + dirty |= I_DIRTY_SYNC; + } + } + BUG_ON(list_empty(&ci->i_dirty_item)); + if (((was | ci->i_flushing_caps) & CEPH_CAP_FILE_BUFFER) && + (mask & CEPH_CAP_FILE_BUFFER)) + dirty |= I_DIRTY_DATASYNC; + if (dirty) + __mark_inode_dirty(inode, dirty); + __cap_delay_requeue(mdsc, ci); +} + +/* * Add dirty inode to the flushing list. Assigned a seq number so we * can wait for caps to flush without starving. * @@ -1558,39 +1593,6 @@ ack: } /* - * Mark caps dirty. If inode is newly dirty, add to the global dirty - * list. - */ -void __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask) -{ - struct ceph_mds_client *mdsc = &ceph_client(ci->vfs_inode.i_sb)->mdsc; - struct inode *inode = &ci->vfs_inode; - int was_dirty = ci->i_dirty_caps; - int dirty = 0; - - dout("__mark_dirty_caps %p %s dirty %s -> %s\n", &ci->vfs_inode, - ceph_cap_string(mask), ceph_cap_string(ci->i_dirty_caps), - ceph_cap_string(ci->i_dirty_caps | mask)); - ci->i_dirty_caps |= mask; - if (!was_dirty) { - dout(" inode %p now dirty\n", &ci->vfs_inode); - spin_lock(&mdsc->cap_dirty_lock); - list_add(&ci->i_dirty_item, &mdsc->cap_dirty); - spin_unlock(&mdsc->cap_dirty_lock); - if (ci->i_flushing_caps == 0) { - igrab(inode); - dirty |= I_DIRTY_SYNC; - } - } - if (((was_dirty | ci->i_flushing_caps) & CEPH_CAP_FILE_BUFFER) && - (mask & CEPH_CAP_FILE_BUFFER)) - dirty |= I_DIRTY_DATASYNC; - if (dirty) - __mark_inode_dirty(inode, dirty); - __cap_delay_requeue(mdsc, ci); -} - -/* * Try to flush dirty caps back to the auth mds. */ static int try_flush_caps(struct inode *inode, struct ceph_mds_session *session, @@ -2370,6 +2372,8 @@ static void handle_cap_flush_ack(struct inode *inode, dout(" inode %p now clean\n", inode); BUG_ON(!list_empty(&ci->i_dirty_item)); drop = 1; + } else { + BUG_ON(list_empty(&ci->i_dirty_item)); } } spin_unlock(&mdsc->cap_dirty_lock); -- cgit v0.10.2 From 8fa9765576875200a7412a5300b5f0537211f038 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 16 Oct 2009 14:44:35 -0700 Subject: ceph: enable readahead Initialized bdi->ra_pages to enable readahead. Use 512KB default. Signed-off-by: Sage Weil diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 7f7d475..ab950fc 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -327,6 +327,7 @@ static int parse_mount_args(struct ceph_client *client, args->mount_timeout = CEPH_MOUNT_TIMEOUT_DEFAULT; /* seconds */ args->caps_wanted_delay_min = CEPH_CAPS_WANTED_DELAY_MIN_DEFAULT; args->caps_wanted_delay_max = CEPH_CAPS_WANTED_DELAY_MAX_DEFAULT; + args->rsize = CEPH_MOUNT_RSIZE_DEFAULT; args->snapdir_name = kstrdup(CEPH_SNAPDIRNAME_DEFAULT, GFP_KERNEL); args->cap_release_safety = CEPH_CAPS_PER_RELEASE * 4; args->max_readdir = 1024; diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 0bbf58a..75556e9 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -69,7 +69,7 @@ struct ceph_mount_args { * defaults */ #define CEPH_MOUNT_TIMEOUT_DEFAULT 60 -#define CEPH_MOUNT_RSIZE_DEFAULT (128*1024) /* readahead */ +#define CEPH_MOUNT_RSIZE_DEFAULT (512*1024) /* readahead */ #define CEPH_MSG_MAX_FRONT_LEN (16*1024*1024) #define CEPH_MSG_MAX_DATA_LEN (16*1024*1024) -- cgit v0.10.2 From ee7fdfaff7702bd209e3a013b2fc4643233f5465 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 19 Oct 2009 11:41:51 -0700 Subject: ceph: include preferred osd in placement seed Mix the preferred osd (if any) into the placement seed that is fed into the CRUSH object placement calculation. This prevents all the placement pgs from peering with the same osds. Rev the osd client protocol with this change. Signed-off-by: Sage Weil diff --git a/fs/ceph/ceph_fs.h b/fs/ceph/ceph_fs.h index 9b16e2e..f8f27e2 100644 --- a/fs/ceph/ceph_fs.h +++ b/fs/ceph/ceph_fs.h @@ -38,7 +38,7 @@ #define CEPH_OSD_PROTOCOL 7 /* cluster internal */ #define CEPH_MDS_PROTOCOL 9 /* cluster internal */ #define CEPH_MON_PROTOCOL 5 /* cluster internal */ -#define CEPH_OSDC_PROTOCOL 20 /* server/client */ +#define CEPH_OSDC_PROTOCOL 21 /* server/client */ #define CEPH_MDSC_PROTOCOL 29 /* server/client */ #define CEPH_MONC_PROTOCOL 15 /* server/client */ diff --git a/fs/ceph/osdmap.c b/fs/ceph/osdmap.c index 6f0aeff..72d75a2 100644 --- a/fs/ceph/osdmap.c +++ b/fs/ceph/osdmap.c @@ -791,6 +791,8 @@ int ceph_calc_object_layout(struct ceph_object_layout *ol, pgid.pg64 = 0; /* start with it zeroed out */ pgid.pg.ps = ceph_full_name_hash(oid, strlen(oid)); pgid.pg.preferred = preferred; + if (preferred >= 0) + pgid.pg.ps += preferred; pgid.pg.pool = le32_to_cpu(fl->fl_pg_pool); if (preferred >= 0) dout("calc_object_layout '%s' pgid %d.%xp%d (%llx)\n", oid, -- cgit v0.10.2 From bb097ffaf833a40335b6dd5e4fa6f5ed0b223bdc Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 19 Oct 2009 16:17:31 -0700 Subject: ceph: v0.17 of client Signed-off-by: Sage Weil diff --git a/fs/ceph/ceph_fs.h b/fs/ceph/ceph_fs.h index f8f27e2..ae52382 100644 --- a/fs/ceph/ceph_fs.h +++ b/fs/ceph/ceph_fs.h @@ -19,8 +19,8 @@ * Ceph release version */ #define CEPH_VERSION_MAJOR 0 -#define CEPH_VERSION_MINOR 16 -#define CEPH_VERSION_PATCH 1 +#define CEPH_VERSION_MINOR 17 +#define CEPH_VERSION_PATCH 0 #define _CEPH_STRINGIFY(x) #x #define CEPH_STRINGIFY(x) _CEPH_STRINGIFY(x) -- cgit v0.10.2 From 232d4b01319767b3ffa5d08962a81c805962be49 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 21 Oct 2009 11:21:49 -0700 Subject: ceph: move directory size logic to ceph_getattr We can't fill i_size with rbytes at the fill_file_size stage without adding additional checks for directories. Notably, we want st_blocks to remain 0 on directories so that 'du' still works. Fill in i_blocks, i_size specially in ceph_getattr instead. Signed-off-by: Sage Weil diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 6097af7..036873c 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -568,8 +568,6 @@ static int fill_inode(struct inode *inode, queue_trunc = ceph_fill_file_size(inode, issued, le32_to_cpu(info->truncate_seq), le64_to_cpu(info->truncate_size), - S_ISDIR(inode->i_mode) ? - ci->i_rbytes : le64_to_cpu(info->size)); ceph_fill_file_time(inode, issued, le32_to_cpu(info->time_warp_seq), @@ -1603,6 +1601,7 @@ int ceph_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) { struct inode *inode = dentry->d_inode; + struct ceph_inode_info *ci = ceph_inode(inode); int err; err = ceph_do_getattr(inode, CEPH_STAT_CAP_INODE_ALL); @@ -1613,8 +1612,11 @@ int ceph_getattr(struct vfsmount *mnt, struct dentry *dentry, stat->dev = ceph_snap(inode); else stat->dev = 0; - if (S_ISDIR(inode->i_mode)) + if (S_ISDIR(inode->i_mode)) { + stat->size = ci->i_rbytes; + stat->blocks = 0; stat->blksize = 65536; + } } return err; } -- cgit v0.10.2 From ecb19c4649d7396737eb0d91a475661fe9d7c028 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 22 Oct 2009 10:53:02 -0700 Subject: ceph: remove small mon addr limit; use CEPH_MAX_MON where appropriate Get rid of separate max mon limit; use the system limit instead. This allows mounts when there are lots of mon addrs provided by mount.ceph (as with a host with lots of A/AAAA records). Signed-off-by: Sage Weil diff --git a/fs/ceph/super.c b/fs/ceph/super.c index ab950fc..8191625 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -314,7 +314,7 @@ static int parse_mount_args(struct ceph_client *client, int err; substring_t argstr[MAX_OPT_ARGS]; int num_mon; - struct ceph_entity_addr mon_addr[CEPH_MAX_MON_MOUNT_ADDR]; + struct ceph_entity_addr mon_addr[CEPH_MAX_MON]; int i; dout("parse_mount_args dev_name '%s'\n", dev_name); @@ -344,7 +344,7 @@ static int parse_mount_args(struct ceph_client *client, /* get mon ip(s) */ err = ceph_parse_ips(dev_name, *path, mon_addr, - CEPH_MAX_MON_MOUNT_ADDR, &num_mon); + CEPH_MAX_MON, &num_mon); if (err < 0) return err; diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 75556e9..3af42d9 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -47,8 +47,6 @@ (!!((client)->mount_args.flags & CEPH_OPT_##opt)) -#define CEPH_MAX_MON_MOUNT_ADDR 5 - struct ceph_mount_args { int sb_flags; int flags; -- cgit v0.10.2 From 7b813c46021e8f4909772a5bbfb5212bd140764c Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 26 Oct 2009 22:07:53 -0700 Subject: ceph: reduce parse_mount_args stack usage Since we've increased the max mon count, we shouldn't put the addr array on the parse_mount_args stack. Put it on the heap instead. Signed-off-by: Sage Weil diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 8191625..deb51bd 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -314,12 +314,16 @@ static int parse_mount_args(struct ceph_client *client, int err; substring_t argstr[MAX_OPT_ARGS]; int num_mon; - struct ceph_entity_addr mon_addr[CEPH_MAX_MON]; + struct ceph_entity_addr *mon_addr; int i; dout("parse_mount_args dev_name '%s'\n", dev_name); memset(args, 0, sizeof(*args)); + mon_addr = kcalloc(CEPH_MAX_MON, sizeof(*mon_addr), GFP_KERNEL); + if (!mon_addr) + return -ENOMEM; + /* start with defaults */ args->sb_flags = flags; args->flags = CEPH_OPT_DEFAULT; @@ -333,27 +337,29 @@ static int parse_mount_args(struct ceph_client *client, args->max_readdir = 1024; /* ip1[:port1][,ip2[:port2]...]:/subdir/in/fs */ + err = -EINVAL; if (!dev_name) - return -EINVAL; + goto out; *path = strstr(dev_name, ":/"); if (*path == NULL) { pr_err("device name is missing path (no :/ in %s)\n", dev_name); - return -EINVAL; + goto out; } /* get mon ip(s) */ err = ceph_parse_ips(dev_name, *path, mon_addr, CEPH_MAX_MON, &num_mon); if (err < 0) - return err; + goto out; /* build initial monmap */ + err = -ENOMEM; client->monc.monmap = kzalloc(sizeof(*client->monc.monmap) + num_mon*sizeof(client->monc.monmap->mon_inst[0]), GFP_KERNEL); if (!client->monc.monmap) - return -ENOMEM; + goto out; for (i = 0; i < num_mon; i++) { client->monc.monmap->mon_inst[i].addr = mon_addr[i]; client->monc.monmap->mon_inst[i].addr.erank = 0; @@ -374,11 +380,11 @@ static int parse_mount_args(struct ceph_client *client, int token, intval, ret; if (!*c) continue; + err = -EINVAL; token = match_token((char *)c, arg_tokens, argstr); if (token < 0) { pr_err("bad mount option at '%s'\n", c); - return -EINVAL; - + goto out; } if (token < Opt_ip) { ret = match_int(&argstr[0], &intval); @@ -468,8 +474,11 @@ static int parse_mount_args(struct ceph_client *client, BUG_ON(token); } } + err = 0; - return 0; +out: + kfree(mon_addr); + return err; } static void release_mount_args(struct ceph_mount_args *args) -- cgit v0.10.2 From 6ca874e92d5e50beb8e351dfd8121947bafc79ec Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 26 Oct 2009 22:06:22 -0700 Subject: ceph: silence uninitialized variable warning Signed-off-by: Sage Weil diff --git a/fs/ceph/super.c b/fs/ceph/super.c index deb51bd..924e6ca 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -808,7 +808,7 @@ static int ceph_get_sb(struct file_system_type *fs_type, struct ceph_client *client; int err; int (*compare_super)(struct super_block *, void *) = ceph_compare_super; - const char *path; + const char *path = 0; dout("ceph_get_sb\n"); -- cgit v0.10.2 From e53c2fe075feda1fd4f009956ac026dc24c3a199 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 27 Oct 2009 10:19:28 -0700 Subject: ceph: fix, clean up string mount arg parsing Clearly demark int and string argument options, and do not try to convert string arguments to ints. Signed-off-by: Sage Weil diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 924e6ca..b094f50 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -264,9 +264,11 @@ enum { Opt_caps_wanted_delay_min, Opt_caps_wanted_delay_max, Opt_readdir_max_entries, + Opt_last_int, /* int args above */ Opt_snapdirname, Opt_secret, + Opt_last_string, /* string args above */ Opt_ip, Opt_noshare, @@ -386,14 +388,19 @@ static int parse_mount_args(struct ceph_client *client, pr_err("bad mount option at '%s'\n", c); goto out; } - if (token < Opt_ip) { + if (token < Opt_last_int) { ret = match_int(&argstr[0], &intval); if (ret < 0) { pr_err("bad mount option arg (not int) " "at '%s'\n", c); continue; } - dout("got token %d intval %d\n", token, intval); + dout("got int token %d val %d\n", token, intval); + } else if (token > Opt_last_int && token < Opt_last_string) { + dout("got string token %d val %s\n", token, + argstr[0].from); + } else { + dout("got token %d\n", token); } switch (token) { case Opt_fsidmajor: -- cgit v0.10.2 From 6b8051855d983db8480ff1ea1b02ef2b49203c22 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 27 Oct 2009 11:50:50 -0700 Subject: ceph: allocate and parse mount args before client instance This simplifies much of the error handling during mount. It also means that we have the mount args before client creation, and we can initialize based on those options. Signed-off-by: Sage Weil diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index c7d673f..bf53581 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c @@ -600,8 +600,8 @@ static int ceph_writepages_start(struct address_space *mapping, pr_warning("writepage_start %p on forced umount\n", inode); return -EIO; /* we're in a forced umount, don't write! */ } - if (client->mount_args.wsize && client->mount_args.wsize < wsize) - wsize = client->mount_args.wsize; + if (client->mount_args->wsize && client->mount_args->wsize < wsize) + wsize = client->mount_args->wsize; if (wsize < PAGE_CACHE_SIZE) wsize = PAGE_CACHE_SIZE; max_pages_ever = wsize >> PAGE_CACHE_SHIFT; diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 7d16618..8b863db 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -270,7 +270,7 @@ static void put_cap(struct ceph_cap *cap, * lots of free/alloc churn. */ if (caps_avail_count >= caps_reserve_count + - ceph_client(cap->ci->vfs_inode.i_sb)->mount_args.max_readdir) { + ceph_client(cap->ci->vfs_inode.i_sb)->mount_args->max_readdir) { caps_total_count--; kmem_cache_free(ceph_cap_cachep, cap); } else { @@ -388,7 +388,7 @@ static void __insert_cap_node(struct ceph_inode_info *ci, static void __cap_set_timeouts(struct ceph_mds_client *mdsc, struct ceph_inode_info *ci) { - struct ceph_mount_args *ma = &mdsc->client->mount_args; + struct ceph_mount_args *ma = mdsc->client->mount_args; ci->i_hold_caps_min = round_jiffies(jiffies + ma->caps_wanted_delay_min * HZ); diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 7bb8db5..4f74679 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c @@ -225,7 +225,7 @@ static int ceph_readdir(struct file *filp, void *dirent, filldir_t filldir) int err; u32 ftype; struct ceph_mds_reply_info_parsed *rinfo; - const int max_entries = client->mount_args.max_readdir; + const int max_entries = client->mount_args->max_readdir; dout("readdir %p filp %p frag %u off %u\n", inode, filp, frag, off); if (fi->at_end) @@ -479,7 +479,8 @@ struct dentry *ceph_finish_lookup(struct ceph_mds_request *req, /* .snap dir? */ if (err == -ENOENT && ceph_vino(parent).ino != CEPH_INO_ROOT && /* no .snap in root dir */ - strcmp(dentry->d_name.name, client->mount_args.snapdir_name) == 0) { + strcmp(dentry->d_name.name, + client->mount_args->snapdir_name) == 0) { struct inode *inode = ceph_get_snapdir(parent); dout("ENOENT on snapdir %p '%.*s', linking to snapdir %p\n", dentry, dentry->d_name.len, dentry->d_name.name, inode); @@ -550,7 +551,7 @@ static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry, spin_lock(&dir->i_lock); dout(" dir %p flags are %d\n", dir, ci->i_ceph_flags); if (strncmp(dentry->d_name.name, - client->mount_args.snapdir_name, + client->mount_args->snapdir_name, dentry->d_name.len) && (ci->i_ceph_flags & CEPH_I_COMPLETE) && (__ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1))) { diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 12d66c0..210cb66 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -943,7 +943,7 @@ static int add_cap_releases(struct ceph_mds_client *mdsc, int err = -ENOMEM; if (extra < 0) - extra = mdsc->client->mount_args.cap_release_safety; + extra = mdsc->client->mount_args->cap_release_safety; spin_lock(&session->s_cap_lock); @@ -2601,7 +2601,7 @@ static void wait_requests(struct ceph_mds_client *mdsc) mutex_unlock(&mdsc->mutex); dout("wait_requests waiting for requests\n"); wait_for_completion_timeout(&mdsc->safe_umount_waiters, - client->mount_args.mount_timeout * HZ); + client->mount_args->mount_timeout * HZ); mutex_lock(&mdsc->mutex); /* tear down remaining requests */ @@ -2693,7 +2693,7 @@ void ceph_mdsc_close_sessions(struct ceph_mds_client *mdsc) int i; int n; struct ceph_client *client = mdsc->client; - unsigned long started, timeout = client->mount_args.mount_timeout * HZ; + unsigned long started, timeout = client->mount_args->mount_timeout * HZ; dout("close_sessions\n"); diff --git a/fs/ceph/mon_client.c b/fs/ceph/mon_client.c index e6e954c..61263c9 100644 --- a/fs/ceph/mon_client.c +++ b/fs/ceph/mon_client.c @@ -527,6 +527,40 @@ static void delayed_work(struct work_struct *work) mutex_unlock(&monc->mutex); } +/* + * On startup, we build a temporary monmap populated with the IPs + * provided by mount(2). + */ +static int build_initial_monmap(struct ceph_mon_client *monc) +{ + struct ceph_mount_args *args = monc->client->mount_args; + struct ceph_entity_addr *mon_addr = args->mon_addr; + int num_mon = args->num_mon; + int i; + + /* build initial monmap */ + monc->monmap = kzalloc(sizeof(*monc->monmap) + + num_mon*sizeof(monc->monmap->mon_inst[0]), + GFP_KERNEL); + if (!monc->monmap) + return -ENOMEM; + for (i = 0; i < num_mon; i++) { + monc->monmap->mon_inst[i].addr = mon_addr[i]; + monc->monmap->mon_inst[i].addr.erank = 0; + monc->monmap->mon_inst[i].addr.nonce = 0; + monc->monmap->mon_inst[i].name.type = + CEPH_ENTITY_TYPE_MON; + monc->monmap->mon_inst[i].name.num = cpu_to_le64(i); + } + monc->monmap->num_mon = num_mon; + + /* release addr memory */ + kfree(args->mon_addr); + args->mon_addr = NULL; + args->num_mon = 0; + return 0; +} + int ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl) { int err = 0; @@ -537,6 +571,10 @@ int ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl) monc->monmap = NULL; mutex_init(&monc->mutex); + err = build_initial_monmap(monc); + if (err) + goto out; + monc->con = NULL; /* msg pools */ diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index 0a25405..7dc0f62 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -444,7 +444,7 @@ static void register_request(struct ceph_osd_client *osdc, osdc->num_requests++; req->r_timeout_stamp = - jiffies + osdc->client->mount_args.osd_timeout*HZ; + jiffies + osdc->client->mount_args->osd_timeout*HZ; if (osdc->num_requests == 1) { osdc->timeout_tid = req->r_tid; @@ -609,7 +609,7 @@ static int __send_request(struct ceph_osd_client *osdc, reqhead->flags |= cpu_to_le32(req->r_flags); /* e.g., RETRY */ reqhead->reassert_version = req->r_reassert_version; - req->r_timeout_stamp = jiffies+osdc->client->mount_args.osd_timeout*HZ; + req->r_timeout_stamp = jiffies+osdc->client->mount_args->osd_timeout*HZ; ceph_msg_get(req->r_request); /* send consumes a ref */ ceph_con_send(&req->r_osd->o_con, req->r_request); @@ -632,7 +632,7 @@ static void handle_timeout(struct work_struct *work) container_of(work, struct ceph_osd_client, timeout_work.work); struct ceph_osd_request *req; struct ceph_osd *osd; - unsigned long timeout = osdc->client->mount_args.osd_timeout * HZ; + unsigned long timeout = osdc->client->mount_args->osd_timeout * HZ; unsigned long next_timeout = timeout + jiffies; struct rb_node *p; diff --git a/fs/ceph/super.c b/fs/ceph/super.c index b094f50..9b7815d 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -110,7 +110,7 @@ static int ceph_syncfs(struct super_block *sb, int wait) static int ceph_show_options(struct seq_file *m, struct vfsmount *mnt) { struct ceph_client *client = ceph_sb_to_client(mnt->mnt_sb); - struct ceph_mount_args *args = &client->mount_args; + struct ceph_mount_args *args = client->mount_args; if (args->flags & CEPH_OPT_FSID) seq_printf(m, ",fsidmajor=%llu,fsidminor%llu", @@ -307,24 +307,24 @@ static match_table_t arg_tokens = { }; -static int parse_mount_args(struct ceph_client *client, - int flags, char *options, const char *dev_name, - const char **path) +static struct ceph_mount_args *parse_mount_args(int flags, char *options, + const char *dev_name, + const char **path) { - struct ceph_mount_args *args = &client->mount_args; + struct ceph_mount_args *args; const char *c; - int err; + int err = -ENOMEM; substring_t argstr[MAX_OPT_ARGS]; - int num_mon; - struct ceph_entity_addr *mon_addr; - int i; - dout("parse_mount_args dev_name '%s'\n", dev_name); - memset(args, 0, sizeof(*args)); + args = kzalloc(sizeof(*args), GFP_KERNEL); + if (!args) + return ERR_PTR(-ENOMEM); + args->mon_addr = kcalloc(CEPH_MAX_MON, sizeof(*args->mon_addr), + GFP_KERNEL); + if (!args->mon_addr) + goto out; - mon_addr = kcalloc(CEPH_MAX_MON, sizeof(*mon_addr), GFP_KERNEL); - if (!mon_addr) - return -ENOMEM; + dout("parse_mount_args %p, dev_name '%s'\n", args, dev_name); /* start with defaults */ args->sb_flags = flags; @@ -350,29 +350,11 @@ static int parse_mount_args(struct ceph_client *client, } /* get mon ip(s) */ - err = ceph_parse_ips(dev_name, *path, mon_addr, - CEPH_MAX_MON, &num_mon); + err = ceph_parse_ips(dev_name, *path, args->mon_addr, + CEPH_MAX_MON, &args->num_mon); if (err < 0) goto out; - /* build initial monmap */ - err = -ENOMEM; - client->monc.monmap = kzalloc(sizeof(*client->monc.monmap) + - num_mon*sizeof(client->monc.monmap->mon_inst[0]), - GFP_KERNEL); - if (!client->monc.monmap) - goto out; - for (i = 0; i < num_mon; i++) { - client->monc.monmap->mon_inst[i].addr = mon_addr[i]; - client->monc.monmap->mon_inst[i].addr.erank = 0; - client->monc.monmap->mon_inst[i].addr.nonce = 0; - client->monc.monmap->mon_inst[i].name.type = - CEPH_ENTITY_TYPE_MON; - client->monc.monmap->mon_inst[i].name.num = cpu_to_le64(i); - } - client->monc.monmap->num_mon = num_mon; - memset(&args->my_addr.in_addr, 0, sizeof(args->my_addr.in_addr)); - /* path on server */ *path += 2; dout("server path '%s'\n", *path); @@ -415,7 +397,7 @@ static int parse_mount_args(struct ceph_client *client, &args->my_addr, 1, NULL); if (err < 0) - return err; + goto out; args->flags |= CEPH_OPT_MYIP; break; @@ -481,25 +463,28 @@ static int parse_mount_args(struct ceph_client *client, BUG_ON(token); } } - err = 0; + return args; out: - kfree(mon_addr); - return err; + kfree(args->mon_addr); + kfree(args); + return ERR_PTR(err); } -static void release_mount_args(struct ceph_mount_args *args) +static void destroy_mount_args(struct ceph_mount_args *args) { + dout("destroy_mount_args %p\n", args); kfree(args->snapdir_name); args->snapdir_name = NULL; kfree(args->secret); args->secret = NULL; + kfree(args); } /* * create a fresh client instance */ -static struct ceph_client *ceph_create_client(void) +static struct ceph_client *ceph_create_client(struct ceph_mount_args *args) { struct ceph_client *client; int err = -ENOMEM; @@ -515,6 +500,7 @@ static struct ceph_client *ceph_create_client(void) client->sb = NULL; client->mount_state = CEPH_MOUNT_MOUNTING; client->whoami = -1; + client->mount_args = args; client->msgr = NULL; @@ -577,7 +563,7 @@ static void ceph_destroy_client(struct ceph_client *client) if (client->wb_pagevec_pool) mempool_destroy(client->wb_pagevec_pool); - release_mount_args(&client->mount_args); + destroy_mount_args(client->mount_args); kfree(client); dout("destroy_client %p done\n", client); @@ -613,7 +599,7 @@ static struct dentry *open_root_dentry(struct ceph_client *client, req->r_ino1.ino = CEPH_INO_ROOT; req->r_ino1.snap = CEPH_NOSNAP; req->r_started = started; - req->r_timeout = client->mount_args.mount_timeout * HZ; + req->r_timeout = client->mount_args->mount_timeout * HZ; req->r_args.getattr.mask = cpu_to_le32(CEPH_STAT_CAP_INODE); req->r_num_caps = 2; err = ceph_mdsc_do_request(mdsc, NULL, req); @@ -641,7 +627,7 @@ static int ceph_mount(struct ceph_client *client, struct vfsmount *mnt, { struct ceph_entity_addr *myaddr = NULL; int err; - unsigned long timeout = client->mount_args.mount_timeout * HZ; + unsigned long timeout = client->mount_args->mount_timeout * HZ; unsigned long started = jiffies; /* note the start time */ struct dentry *root; @@ -651,7 +637,7 @@ static int ceph_mount(struct ceph_client *client, struct vfsmount *mnt, /* initialize the messenger */ if (client->msgr == NULL) { if (ceph_test_opt(client, MYIP)) - myaddr = &client->mount_args.my_addr; + myaddr = &client->mount_args->my_addr; client->msgr = ceph_messenger_create(myaddr); if (IS_ERR(client->msgr)) { err = PTR_ERR(client->msgr); @@ -727,7 +713,7 @@ static int ceph_set_super(struct super_block *s, void *data) dout("set_super %p data %p\n", s, data); - s->s_flags = client->mount_args.sb_flags; + s->s_flags = client->mount_args->sb_flags; s->s_maxbytes = 1ULL << 40; /* temp value until we get mdsmap */ s->s_fs_info = client; @@ -756,7 +742,7 @@ fail: static int ceph_compare_super(struct super_block *sb, void *data) { struct ceph_client *new = data; - struct ceph_mount_args *args = &new->mount_args; + struct ceph_mount_args *args = new->mount_args; struct ceph_client *other = ceph_sb_to_client(sb); int i; @@ -778,7 +764,7 @@ static int ceph_compare_super(struct super_block *sb, void *data) } dout("mon ip matches existing sb %p\n", sb); } - if (args->sb_flags != other->mount_args.sb_flags) { + if (args->sb_flags != other->mount_args->sb_flags) { dout("flags differ\n"); return 0; } @@ -798,9 +784,9 @@ static int ceph_init_bdi(struct super_block *sb, struct ceph_client *client) sb->s_bdi = &client->backing_dev_info; /* set ra_pages based on rsize mount option? */ - if (client->mount_args.rsize >= PAGE_CACHE_SIZE) + if (client->mount_args->rsize >= PAGE_CACHE_SIZE) client->backing_dev_info.ra_pages = - (client->mount_args.rsize + PAGE_CACHE_SIZE - 1) + (client->mount_args->rsize + PAGE_CACHE_SIZE - 1) >> PAGE_SHIFT; err = bdi_register_dev(&client->backing_dev_info, sb->s_dev); @@ -816,19 +802,23 @@ static int ceph_get_sb(struct file_system_type *fs_type, int err; int (*compare_super)(struct super_block *, void *) = ceph_compare_super; const char *path = 0; + struct ceph_mount_args *args; dout("ceph_get_sb\n"); + args = parse_mount_args(flags, data, dev_name, &path); + if (IS_ERR(args)) { + err = PTR_ERR(args); + goto out_final; + } /* create client (which we may/may not use) */ - client = ceph_create_client(); - if (IS_ERR(client)) - return PTR_ERR(client); - - err = parse_mount_args(client, flags, data, dev_name, &path); - if (err < 0) - goto out; + client = ceph_create_client(args); + if (IS_ERR(client)) { + err = PTR_ERR(client); + goto out_final; + } - if (client->mount_args.flags & CEPH_OPT_NOSHARE) + if (client->mount_args->flags & CEPH_OPT_NOSHARE) compare_super = NULL; sb = sget(fs_type, compare_super, ceph_set_super, client); if (IS_ERR(sb)) { @@ -846,7 +836,7 @@ static int ceph_get_sb(struct file_system_type *fs_type, /* set up mempools */ err = -ENOMEM; client->wb_pagevec_pool = mempool_create_kmalloc_pool(10, - client->mount_args.wsize >> PAGE_CACHE_SHIFT); + client->mount_args->wsize >> PAGE_CACHE_SHIFT); if (!client->wb_pagevec_pool) goto out_splat; diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 3af42d9..a3d4943 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -42,13 +42,15 @@ #define CEPH_OPT_DEFAULT (CEPH_OPT_RBYTES) #define ceph_set_opt(client, opt) \ - (client)->mount_args.flags |= CEPH_OPT_##opt; + (client)->mount_args->flags |= CEPH_OPT_##opt; #define ceph_test_opt(client, opt) \ - (!!((client)->mount_args.flags & CEPH_OPT_##opt)) + (!!((client)->mount_args->flags & CEPH_OPT_##opt)) struct ceph_mount_args { int sb_flags; + int num_mon; + struct ceph_entity_addr *mon_addr; int flags; int mount_timeout; int caps_wanted_delay_min, caps_wanted_delay_max; @@ -115,7 +117,7 @@ struct ceph_client { struct dentry *debugfs_dir, *debugfs_dentry_lru, *debugfs_caps; struct mutex mount_mutex; /* serialize mount attempts */ - struct ceph_mount_args mount_args; + struct ceph_mount_args *mount_args; struct ceph_fsid fsid; struct super_block *sb; -- cgit v0.10.2 From fbbccec9c6218cbc9ff47c6d88bfc6b52079e3ea Mon Sep 17 00:00:00 2001 From: Noah Watkins Date: Wed, 28 Oct 2009 11:54:49 -0700 Subject: ceph: replace list_entry with container_of Usage of non-list.h list_entry function for container_of functionality replaced with direct use of container_of. Signed-off-by: Noah Watkins Signed-off-by: Sage Weil diff --git a/fs/ceph/super.h b/fs/ceph/super.h index a3d4943..05947b9 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -364,7 +364,7 @@ struct ceph_inode_info { static inline struct ceph_inode_info *ceph_inode(struct inode *inode) { - return list_entry(inode, struct ceph_inode_info, vfs_inode); + return container_of(inode, struct ceph_inode_info, vfs_inode); } static inline void ceph_i_clear(struct inode *inode, unsigned mask) -- cgit v0.10.2 From 35e054a66e07f508aa7cfabc7db1757379093689 Mon Sep 17 00:00:00 2001 From: Noah Watkins Date: Wed, 28 Oct 2009 14:04:48 -0700 Subject: ceph: remove redundant use of le32_to_cpu Using stripe unit size calculated and saved on the stack to avoid a redundant call to le32_to_cpu. Signed-off-by: Noah Watkins Signed-off-by: Sage Weil diff --git a/fs/ceph/osdmap.c b/fs/ceph/osdmap.c index 72d75a2..60012e0 100644 --- a/fs/ceph/osdmap.c +++ b/fs/ceph/osdmap.c @@ -735,7 +735,7 @@ void ceph_calc_file_object_mapping(struct ceph_file_layout *layout, dout("mapping %llu~%llu osize %u fl_su %u\n", off, *plen, osize, su); - su_per_object = osize / le32_to_cpu(layout->fl_stripe_unit); + su_per_object = osize / su; dout("osize %u / su %u = su_per_object %u\n", osize, su, su_per_object); -- cgit v0.10.2 From 5600f5ebd318f7af6f4b19a29f08d18bb85264e5 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 28 Oct 2009 14:57:25 -0700 Subject: ceph: correct comment to match striping calculation The object extent offset is the file offset _modulo_ the stripe unit. The code was correct, the comment was wrong. Reported-by: Noah Watkins Signed-off-by: Sage Weil diff --git a/fs/ceph/osdmap.c b/fs/ceph/osdmap.c index 60012e0..a9a4143 100644 --- a/fs/ceph/osdmap.c +++ b/fs/ceph/osdmap.c @@ -752,7 +752,7 @@ void ceph_calc_file_object_mapping(struct ceph_file_layout *layout, *bno = objsetno * sc + stripepos; dout("objset %u * sc %u = bno %u\n", objsetno, sc, (unsigned)*bno); - /* *oxoff = *off / layout->fl_stripe_unit; */ + /* *oxoff = *off % layout->fl_stripe_unit; */ t = off; *oxoff = do_div(t, su); *oxlen = min_t(u64, *plen, su - *oxoff); -- cgit v0.10.2 From 645a102581b3639836b17d147c35d574fd6e8267 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 28 Oct 2009 15:15:05 -0700 Subject: ceph: fix object striping calculation for non-default striping schemes We were incorrectly calculationing of object offset. If we have multiple stripe units per object, we need to shift to the start of the current su in addition to the offset within the su. Also rename bno to ono (object number) to avoid some variable naming confusion. Signed-off-by: Sage Weil diff --git a/fs/ceph/osdmap.c b/fs/ceph/osdmap.c index a9a4143..5a5520c 100644 --- a/fs/ceph/osdmap.c +++ b/fs/ceph/osdmap.c @@ -723,7 +723,7 @@ bad: */ void ceph_calc_file_object_mapping(struct ceph_file_layout *layout, u64 off, u64 *plen, - u64 *bno, + u64 *ono, u64 *oxoff, u64 *oxlen) { u32 osize = le32_to_cpu(layout->fl_object_size); @@ -750,11 +750,14 @@ void ceph_calc_file_object_mapping(struct ceph_file_layout *layout, stripepos = bl % sc; objsetno = stripeno / su_per_object; - *bno = objsetno * sc + stripepos; - dout("objset %u * sc %u = bno %u\n", objsetno, sc, (unsigned)*bno); - /* *oxoff = *off % layout->fl_stripe_unit; */ + *ono = objsetno * sc + stripepos; + dout("objset %u * sc %u = ono %u\n", objsetno, sc, (unsigned)*ono); + + /* *oxoff = *off % layout->fl_stripe_unit; # offset in su */ t = off; *oxoff = do_div(t, su); + *oxoff += (stripeno % su_per_object) * su; + *oxlen = min_t(u64, *plen, su - *oxoff); *plen = *oxlen; -- cgit v0.10.2 From ff1d1f7179363209b7f1493ea39b666f50d05cf4 Mon Sep 17 00:00:00 2001 From: Noah Watkins Date: Fri, 30 Oct 2009 12:57:30 -0700 Subject: ceph: fix intra strip unit length calculation Commit 645a102581b3639836b17d147c35d574fd6e8267 fixes calculation of object offset for layouts with multiple stripes per object. This updates the calculation of the length written to take into account multiple stripes per object. Signed-off-by: Noah Watkins Signed-off-by: Sage Weil diff --git a/fs/ceph/osdmap.c b/fs/ceph/osdmap.c index 5a5520c..d62e111 100644 --- a/fs/ceph/osdmap.c +++ b/fs/ceph/osdmap.c @@ -731,7 +731,7 @@ void ceph_calc_file_object_mapping(struct ceph_file_layout *layout, u32 sc = le32_to_cpu(layout->fl_stripe_count); u32 bl, stripeno, stripepos, objsetno; u32 su_per_object; - u64 t; + u64 t, su_offset; dout("mapping %llu~%llu osize %u fl_su %u\n", off, *plen, osize, su); @@ -755,10 +755,15 @@ void ceph_calc_file_object_mapping(struct ceph_file_layout *layout, /* *oxoff = *off % layout->fl_stripe_unit; # offset in su */ t = off; - *oxoff = do_div(t, su); - *oxoff += (stripeno % su_per_object) * su; - - *oxlen = min_t(u64, *plen, su - *oxoff); + su_offset = do_div(t, su); + *oxoff = su_offset + (stripeno % su_per_object) * su; + + /* + * Calculate the length of the extent being written to the selected + * object. This is the minimum of the full length requested (plen) or + * the remainder of the current stripe being written to. + */ + *oxlen = min_t(u64, *plen, su - su_offset); *plen = *oxlen; dout(" obj extent %llu~%llu\n", *oxoff, *oxlen); -- cgit v0.10.2 From 63ff78b25c4b204075b5b98afcac6ad3639d43fe Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Sun, 1 Nov 2009 17:51:15 -0800 Subject: ceph: fix uninitialized err variable Fixes warning fs/ceph/xattr.c: In function '__build_xattrs': fs/ceph/xattr.c:353: warning: 'err' may be used uninitialized in this function Signed-off-by: Sage Weil diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c index 65b3a84..1a48a55 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c @@ -350,7 +350,7 @@ static int __build_xattrs(struct inode *inode) struct ceph_inode_info *ci = ceph_inode(inode); int xattr_version; struct ceph_inode_xattr **xattrs = NULL; - int err; + int err = 0; int i; dout("__build_xattrs() len=%d\n", -- cgit v0.10.2 From 33aa96e7430d215e2ee779f65cdad0f6d4571fe1 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Sun, 1 Nov 2009 17:53:24 -0800 Subject: crush: always return a value from crush_bucket_choose Even when we encounter a corrupt bucket. We still BUG(). This fixes the warning fs/ceph/crush/mapper.c: In function 'crush_choose': fs/ceph/crush/mapper.c:352: warning: control may reach end of non-void function 'crush_bucket_choose' being inlined Signed-off-by: Sage Weil diff --git a/fs/ceph/crush/mapper.c b/fs/ceph/crush/mapper.c index c268393..54f3f40 100644 --- a/fs/ceph/crush/mapper.c +++ b/fs/ceph/crush/mapper.c @@ -253,7 +253,7 @@ static int crush_bucket_choose(struct crush_bucket *in, int x, int r) x, r); default: BUG_ON(1); -/* return in->items[0] */; + return in->items[0]; } } -- cgit v0.10.2 From 859e7b149362475672e2a996f29b8f45cbb34d82 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 2 Nov 2009 09:32:47 -0800 Subject: ceph: init/destroy bdi in client create/destroy helpers This keeps bdi setup/teardown in line with client life cycle. Signed-off-by: Sage Weil diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 9b7815d..0ae40ba 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -508,10 +508,14 @@ static struct ceph_client *ceph_create_client(struct ceph_mount_args *args) client->signed_ticket = NULL; client->signed_ticket_len = 0; + err = bdi_init(&client->backing_dev_info); + if (err < 0) + goto fail; + err = -ENOMEM; client->wb_wq = create_workqueue("ceph-writeback"); if (client->wb_wq == NULL) - goto fail; + goto fail_bdi; client->pg_inv_wq = create_singlethread_workqueue("ceph-pg-invalid"); if (client->pg_inv_wq == NULL) goto fail_wb_wq; @@ -537,6 +541,8 @@ fail_pg_inv_wq: destroy_workqueue(client->pg_inv_wq); fail_wb_wq: destroy_workqueue(client->wb_wq); +fail_bdi: + bdi_destroy(&client->backing_dev_info); fail: kfree(client); return ERR_PTR(err); @@ -774,13 +780,10 @@ static int ceph_compare_super(struct super_block *sb, void *data) /* * construct our own bdi so we can control readahead, etc. */ -static int ceph_init_bdi(struct super_block *sb, struct ceph_client *client) +static int ceph_register_bdi(struct super_block *sb, struct ceph_client *client) { int err; - err = bdi_init(&client->backing_dev_info); - if (err < 0) - return err; sb->s_bdi = &client->backing_dev_info; /* set ra_pages based on rsize mount option? */ @@ -840,7 +843,7 @@ static int ceph_get_sb(struct file_system_type *fs_type, if (!client->wb_pagevec_pool) goto out_splat; - err = ceph_init_bdi(sb, client); + err = ceph_register_bdi(sb, client); if (err < 0) goto out_splat; } -- cgit v0.10.2 From 63f2d211954b790fea0a9caeae605c7956535af6 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 3 Nov 2009 15:17:56 -0800 Subject: ceph: use fixed endian encoding for ceph_entity_addr We exchange struct ceph_entity_addr over the wire and store it on disk. The sockaddr_storage.ss_family field, however, is host endianness. So, fix ss_family endianness to big endian when sending/receiving over the wire. Signed-off-by: Sage Weil diff --git a/fs/ceph/decode.h b/fs/ceph/decode.h index 91179fb..a382aec 100644 --- a/fs/ceph/decode.h +++ b/fs/ceph/decode.h @@ -76,19 +76,31 @@ static inline void ceph_decode_copy(void **p, void *pv, size_t n) * struct ceph_timespec <-> struct timespec */ static inline void ceph_decode_timespec(struct timespec *ts, - struct ceph_timespec *tv) + const struct ceph_timespec *tv) { ts->tv_sec = le32_to_cpu(tv->tv_sec); ts->tv_nsec = le32_to_cpu(tv->tv_nsec); } static inline void ceph_encode_timespec(struct ceph_timespec *tv, - struct timespec *ts) + const struct timespec *ts) { tv->tv_sec = cpu_to_le32(ts->tv_sec); tv->tv_nsec = cpu_to_le32(ts->tv_nsec); } /* + * sockaddr_storage <-> ceph_sockaddr + */ +static inline void ceph_encode_addr(struct ceph_entity_addr *a) +{ + a->in_addr.ss_family = htons(a->in_addr.ss_family); +} +static inline void ceph_decode_addr(struct ceph_entity_addr *a) +{ + a->in_addr.ss_family = ntohs(a->in_addr.ss_family); +} + +/* * encoders */ static inline void ceph_encode_64(void **p, u64 v) diff --git a/fs/ceph/mdsmap.c b/fs/ceph/mdsmap.c index 80daea0..4226c81 100644 --- a/fs/ceph/mdsmap.c +++ b/fs/ceph/mdsmap.c @@ -86,6 +86,7 @@ struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end) ceph_decode_need(p, end, sizeof(addr) + 1 + sizeof(u32), bad); ceph_decode_copy(p, &addr, sizeof(addr)); + ceph_decode_addr(&addr); infoversion = ceph_decode_8(p); namelen = ceph_decode_32(p); /* skip mds name */ *p += namelen; diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index b48abc0..6ff44bb 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -12,6 +12,7 @@ #include "super.h" #include "messenger.h" +#include "decode.h" /* * Ceph uses the messenger to exchange ceph_msg messages with other @@ -97,6 +98,12 @@ const char *pr_addr(const struct sockaddr_storage *ss) return s; } +static void encode_my_addr(struct ceph_messenger *msgr) +{ + memcpy(&msgr->my_enc_addr, &msgr->inst.addr, sizeof(msgr->my_enc_addr)); + ceph_encode_addr(&msgr->my_enc_addr); +} + /* * work queue for all reading and writing to/from the socket. */ @@ -590,12 +597,12 @@ static void prepare_write_connect(struct ceph_messenger *msgr, con->out_kvec[0].iov_base = CEPH_BANNER; con->out_kvec[0].iov_len = len; - con->out_kvec[1].iov_base = &msgr->inst.addr; - con->out_kvec[1].iov_len = sizeof(msgr->inst.addr); + con->out_kvec[1].iov_base = &msgr->my_enc_addr; + con->out_kvec[1].iov_len = sizeof(msgr->my_enc_addr); con->out_kvec[2].iov_base = &con->out_connect; con->out_kvec[2].iov_len = sizeof(con->out_connect); con->out_kvec_left = 3; - con->out_kvec_bytes = len + sizeof(msgr->inst.addr) + + con->out_kvec_bytes = len + sizeof(msgr->my_enc_addr) + sizeof(con->out_connect); con->out_kvec_cur = con->out_kvec; con->out_more = 0; @@ -976,6 +983,9 @@ static int process_connect(struct ceph_connection *con) if (verify_hello(con) < 0) return -1; + ceph_decode_addr(&con->actual_peer_addr); + ceph_decode_addr(&con->peer_addr_for_me); + /* * Make sure the other end is who we wanted. note that the other * end may not yet know their ip address, so if it's 0.0.0.0, give @@ -1005,6 +1015,7 @@ static int process_connect(struct ceph_connection *con) &con->peer_addr_for_me.in_addr, sizeof(con->peer_addr_for_me.in_addr)); addr_set_port(&con->msgr->inst.addr.in_addr, port); + encode_my_addr(con->msgr); dout("process_connect learned my addr is %s\n", pr_addr(&con->msgr->inst.addr.in_addr)); } @@ -1780,6 +1791,7 @@ struct ceph_messenger *ceph_messenger_create(struct ceph_entity_addr *myaddr) /* select a random nonce */ get_random_bytes(&msgr->inst.addr.nonce, sizeof(msgr->inst.addr.nonce)); + encode_my_addr(msgr); dout("messenger_create %p\n", msgr); return msgr; @@ -1806,8 +1818,9 @@ void ceph_con_send(struct ceph_connection *con, struct ceph_msg *msg) } /* set src+dst */ - msg->hdr.src = con->msgr->inst; - msg->hdr.orig_src = con->msgr->inst; + msg->hdr.src.name = con->msgr->inst.name; + msg->hdr.src.addr = con->msgr->my_enc_addr; + msg->hdr.orig_src = msg->hdr.src; msg->hdr.dst_erank = con->peer_addr.erank; /* queue */ diff --git a/fs/ceph/messenger.h b/fs/ceph/messenger.h index dcd98b6..e016fa7 100644 --- a/fs/ceph/messenger.h +++ b/fs/ceph/messenger.h @@ -53,6 +53,7 @@ extern const char *ceph_name_type_str(int t); struct ceph_messenger { struct ceph_entity_inst inst; /* my name+address */ + struct ceph_entity_addr my_enc_addr; struct page *zero_page; /* used in certain error cases */ bool nocrc; diff --git a/fs/ceph/mon_client.c b/fs/ceph/mon_client.c index 61263c9..95b76e7 100644 --- a/fs/ceph/mon_client.c +++ b/fs/ceph/mon_client.c @@ -59,6 +59,8 @@ struct ceph_monmap *ceph_monmap_decode(void *p, void *end) m->epoch = epoch; m->num_mon = num_mon; ceph_decode_copy(&p, m->mon_inst, num_mon*sizeof(m->mon_inst[0])); + for (i = 0; i < num_mon; i++) + ceph_decode_addr(&m->mon_inst[i].addr); dout("monmap_decode epoch %d, num_mon %d\n", m->epoch, m->num_mon); diff --git a/fs/ceph/msgr.h b/fs/ceph/msgr.h index 9abc879..8e3ea2e 100644 --- a/fs/ceph/msgr.h +++ b/fs/ceph/msgr.h @@ -21,7 +21,7 @@ * whenever the wire protocol changes. try to keep this string length * constant. */ -#define CEPH_BANNER "ceph v022" +#define CEPH_BANNER "ceph v023" #define CEPH_BANNER_MAX_LEN 30 diff --git a/fs/ceph/osdmap.c b/fs/ceph/osdmap.c index d62e111..cd7bb26 100644 --- a/fs/ceph/osdmap.c +++ b/fs/ceph/osdmap.c @@ -460,6 +460,8 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end) *p += 4; /* skip length field (should match max) */ ceph_decode_copy(p, map->osd_addr, map->max_osd*sizeof(*map->osd_addr)); + for (i = 0; i < map->max_osd; i++) + ceph_decode_addr(&map->osd_addr[i]); /* pg_temp */ ceph_decode_32_safe(p, end, len, bad); @@ -619,6 +621,7 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, struct ceph_entity_addr addr; ceph_decode_32_safe(p, end, osd, bad); ceph_decode_copy_safe(p, end, &addr, sizeof(addr), bad); + ceph_decode_addr(&addr); pr_info("osd%d up\n", osd); BUG_ON(osd >= map->max_osd); map->osd_state[osd] |= CEPH_OSD_UP; -- cgit v0.10.2 From 51042122d4f85e0f8ee577a4230f172fcc57c456 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 4 Nov 2009 11:39:12 -0800 Subject: ceph: fix endian conversions for ceph_pg The endian conversions don't quite work with the old union ceph_pg. Just make it a regular struct, and make each field __le. This is simpler and it has the added bonus of actually working. Signed-off-by: Sage Weil diff --git a/fs/ceph/ioctl.c b/fs/ceph/ioctl.c index e4f99ef..4c33e19 100644 --- a/fs/ceph/ioctl.c +++ b/fs/ceph/ioctl.c @@ -99,7 +99,7 @@ static long ceph_ioctl_get_dataloc(struct file *file, void __user *arg) u64 len = 1, olen; u64 tmp; struct ceph_object_layout ol; - union ceph_pg pgid; + struct ceph_pg pgid; /* copy and validate */ if (copy_from_user(&dl, arg, sizeof(dl))) @@ -121,7 +121,7 @@ static long ceph_ioctl_get_dataloc(struct file *file, void __user *arg) ceph_calc_object_layout(&ol, dl.object_name, &ci->i_layout, osdc->osdmap); - pgid.pg64 = le64_to_cpu(ol.ol_pgid); + pgid = ol.ol_pgid; dl.osd = ceph_calc_pg_primary(osdc->osdmap, pgid); if (dl.osd >= 0) { struct ceph_entity_addr *a = diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index 7dc0f62..7db14ba 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -520,7 +520,7 @@ static int __map_osds(struct ceph_osd_client *osdc, struct ceph_osd_request *req) { struct ceph_osd_request_head *reqhead = req->r_request->front.iov_base; - union ceph_pg pgid; + struct ceph_pg pgid; int o = -1; int err; struct ceph_osd *newosd = NULL; @@ -530,7 +530,7 @@ static int __map_osds(struct ceph_osd_client *osdc, &req->r_file_layout, osdc->osdmap); if (err) return err; - pgid.pg64 = le64_to_cpu(reqhead->layout.ol_pgid); + pgid = reqhead->layout.ol_pgid; o = ceph_calc_pg_primary(osdc->osdmap, pgid); if ((req->r_osd && req->r_osd->o_osd == o && @@ -538,8 +538,8 @@ static int __map_osds(struct ceph_osd_client *osdc, (req->r_osd == NULL && o == -1)) return 0; /* no change */ - dout("map_osds tid %llu pgid %llx pool %d osd%d (was osd%d)\n", - req->r_tid, pgid.pg64, pgid.pg.pool, o, + dout("map_osds tid %llu pgid %d.%x osd%d (was osd%d)\n", + req->r_tid, le32_to_cpu(pgid.pool), le16_to_cpu(pgid.ps), o, req->r_osd ? req->r_osd->o_osd : -1); if (req->r_osd) { diff --git a/fs/ceph/osdmap.c b/fs/ceph/osdmap.c index cd7bb26..8b0cd11 100644 --- a/fs/ceph/osdmap.c +++ b/fs/ceph/osdmap.c @@ -366,19 +366,33 @@ static int osdmap_set_max_osd(struct ceph_osdmap *map, int max) /* * Insert a new pg_temp mapping */ +static int pgid_cmp(struct ceph_pg l, struct ceph_pg r) +{ + u64 a = *(u64 *)&l; + u64 b = *(u64 *)&r; + + if (a < b) + return -1; + if (a > b) + return 1; + return 0; +} + static int __insert_pg_mapping(struct ceph_pg_mapping *new, struct rb_root *root) { struct rb_node **p = &root->rb_node; struct rb_node *parent = NULL; struct ceph_pg_mapping *pg = NULL; + int c; while (*p) { parent = *p; pg = rb_entry(parent, struct ceph_pg_mapping, node); - if (new->pgid < pg->pgid) + c = pgid_cmp(new->pgid, pg->pgid); + if (c < 0) p = &(*p)->rb_left; - else if (new->pgid > pg->pgid) + else if (c > 0) p = &(*p)->rb_right; else return -EEXIST; @@ -467,11 +481,11 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end) ceph_decode_32_safe(p, end, len, bad); for (i = 0; i < len; i++) { int n, j; - u64 pgid; + struct ceph_pg pgid; struct ceph_pg_mapping *pg; ceph_decode_need(p, end, sizeof(u32) + sizeof(u64), bad); - pgid = ceph_decode_64(p); + ceph_decode_copy(p, &pgid, sizeof(pgid)); n = ceph_decode_32(p); ceph_decode_need(p, end, n * sizeof(u32), bad); pg = kmalloc(sizeof(*pg) + n*sizeof(u32), GFP_NOFS); @@ -487,7 +501,7 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end) err = __insert_pg_mapping(pg, &map->pg_temp); if (err) goto bad; - dout(" added pg_temp %llx len %d\n", pgid, len); + dout(" added pg_temp %llx len %d\n", *(u64 *)&pgid, len); } /* crush */ @@ -659,19 +673,20 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, while (len--) { struct ceph_pg_mapping *pg; int j; - u64 pgid; + struct ceph_pg pgid; u32 pglen; ceph_decode_need(p, end, sizeof(u64) + sizeof(u32), bad); - pgid = ceph_decode_64(p); + ceph_decode_copy(p, &pgid, sizeof(pgid)); pglen = ceph_decode_32(p); /* remove any? */ - while (rbp && rb_entry(rbp, struct ceph_pg_mapping, - node)->pgid <= pgid) { + while (rbp && pgid_cmp(rb_entry(rbp, struct ceph_pg_mapping, + node)->pgid, pgid) <= 0) { struct rb_node *cur = rbp; rbp = rb_next(rbp); dout(" removed pg_temp %llx\n", - rb_entry(cur, struct ceph_pg_mapping, node)->pgid); + *(u64 *)&rb_entry(cur, struct ceph_pg_mapping, + node)->pgid); rb_erase(cur, &map->pg_temp); } @@ -690,14 +705,16 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, err = __insert_pg_mapping(pg, &map->pg_temp); if (err) goto bad; - dout(" added pg_temp %llx len %d\n", pgid, pglen); + dout(" added pg_temp %llx len %d\n", *(u64 *)&pgid, + pglen); } } while (rbp) { struct rb_node *cur = rbp; rbp = rb_next(rbp); dout(" removed pg_temp %llx\n", - rb_entry(cur, struct ceph_pg_mapping, node)->pgid); + *(u64 *)&rb_entry(cur, struct ceph_pg_mapping, + node)->pgid); rb_erase(cur, &map->pg_temp); } @@ -782,16 +799,19 @@ int ceph_calc_object_layout(struct ceph_object_layout *ol, struct ceph_osdmap *osdmap) { unsigned num, num_mask; - union ceph_pg pgid; + struct ceph_pg pgid; s32 preferred = (s32)le32_to_cpu(fl->fl_pg_preferred); int poolid = le32_to_cpu(fl->fl_pg_pool); struct ceph_pg_pool_info *pool; + unsigned ps; if (poolid >= osdmap->num_pools) return -EIO; - pool = &osdmap->pg_pool[poolid]; + pool = &osdmap->pg_pool[poolid]; + ps = ceph_full_name_hash(oid, strlen(oid)); if (preferred >= 0) { + ps += preferred; num = le32_to_cpu(pool->v.lpg_num); num_mask = pool->lpg_num_mask; } else { @@ -799,22 +819,17 @@ int ceph_calc_object_layout(struct ceph_object_layout *ol, num_mask = pool->pg_num_mask; } - pgid.pg64 = 0; /* start with it zeroed out */ - pgid.pg.ps = ceph_full_name_hash(oid, strlen(oid)); - pgid.pg.preferred = preferred; - if (preferred >= 0) - pgid.pg.ps += preferred; - pgid.pg.pool = le32_to_cpu(fl->fl_pg_pool); + pgid.ps = cpu_to_le16(ps); + pgid.preferred = cpu_to_le16(preferred); + pgid.pool = fl->fl_pg_pool; if (preferred >= 0) - dout("calc_object_layout '%s' pgid %d.%xp%d (%llx)\n", oid, - pgid.pg.pool, pgid.pg.ps, (int)preferred, pgid.pg64); + dout("calc_object_layout '%s' pgid %d.%xp%d\n", oid, poolid, ps, + (int)preferred); else - dout("calc_object_layout '%s' pgid %d.%x (%llx)\n", oid, - pgid.pg.pool, pgid.pg.ps, pgid.pg64); + dout("calc_object_layout '%s' pgid %d.%x\n", oid, poolid, ps); - ol->ol_pgid = cpu_to_le64(pgid.pg64); + ol->ol_pgid = pgid; ol->ol_stripe_unit = fl->fl_object_stripe_unit; - return 0; } @@ -822,21 +837,24 @@ int ceph_calc_object_layout(struct ceph_object_layout *ol, * Calculate raw osd vector for the given pgid. Return pointer to osd * array, or NULL on failure. */ -static int *calc_pg_raw(struct ceph_osdmap *osdmap, union ceph_pg pgid, +static int *calc_pg_raw(struct ceph_osdmap *osdmap, struct ceph_pg pgid, int *osds, int *num) { struct rb_node *n = osdmap->pg_temp.rb_node; struct ceph_pg_mapping *pg; struct ceph_pg_pool_info *pool; int ruleno; - unsigned pps; /* placement ps */ + unsigned poolid, ps, pps; + int preferred; + int c; /* pg_temp? */ while (n) { pg = rb_entry(n, struct ceph_pg_mapping, node); - if (pgid.pg64 < pg->pgid) + c = pgid_cmp(pgid, pg->pgid); + if (c < 0) n = n->rb_left; - else if (pgid.pg64 > pg->pgid) + else if (c > 0) n = n->rb_right; else { *num = pg->len; @@ -845,36 +863,40 @@ static int *calc_pg_raw(struct ceph_osdmap *osdmap, union ceph_pg pgid, } /* crush */ - if (pgid.pg.pool >= osdmap->num_pools) + poolid = le32_to_cpu(pgid.pool); + ps = le16_to_cpu(pgid.ps); + preferred = (s16)le16_to_cpu(pgid.preferred); + + if (poolid >= osdmap->num_pools) return NULL; - pool = &osdmap->pg_pool[pgid.pg.pool]; + pool = &osdmap->pg_pool[poolid]; ruleno = crush_find_rule(osdmap->crush, pool->v.crush_ruleset, pool->v.type, pool->v.size); if (ruleno < 0) { pr_err("no crush rule pool %d type %d size %d\n", - pgid.pg.pool, pool->v.type, pool->v.size); + poolid, pool->v.type, pool->v.size); return NULL; } - if (pgid.pg.preferred >= 0) - pps = ceph_stable_mod(pgid.pg.ps, + if (preferred >= 0) + pps = ceph_stable_mod(ps, le32_to_cpu(pool->v.lpgp_num), pool->lpgp_num_mask); else - pps = ceph_stable_mod(pgid.pg.ps, + pps = ceph_stable_mod(ps, le32_to_cpu(pool->v.pgp_num), pool->pgp_num_mask); - pps += pgid.pg.pool; + pps += poolid; *num = crush_do_rule(osdmap->crush, ruleno, pps, osds, min_t(int, pool->v.size, *num), - pgid.pg.preferred, osdmap->osd_weight); + preferred, osdmap->osd_weight); return osds; } /* * Return primary osd for given pgid, or -1 if none. */ -int ceph_calc_pg_primary(struct ceph_osdmap *osdmap, union ceph_pg pgid) +int ceph_calc_pg_primary(struct ceph_osdmap *osdmap, struct ceph_pg pgid) { int rawosds[10], *osds; int i, num = ARRAY_SIZE(rawosds); diff --git a/fs/ceph/osdmap.h b/fs/ceph/osdmap.h index 07127c6..c4af841 100644 --- a/fs/ceph/osdmap.h +++ b/fs/ceph/osdmap.h @@ -25,7 +25,7 @@ struct ceph_pg_pool_info { struct ceph_pg_mapping { struct rb_node node; - u64 pgid; + struct ceph_pg pgid; int len; int osds[]; }; @@ -118,6 +118,7 @@ extern int ceph_calc_object_layout(struct ceph_object_layout *ol, const char *oid, struct ceph_file_layout *fl, struct ceph_osdmap *osdmap); -extern int ceph_calc_pg_primary(struct ceph_osdmap *osdmap, union ceph_pg pgid); +extern int ceph_calc_pg_primary(struct ceph_osdmap *osdmap, + struct ceph_pg pgid); #endif diff --git a/fs/ceph/rados.h b/fs/ceph/rados.h index a48cf4a..85bdef7 100644 --- a/fs/ceph/rados.h +++ b/fs/ceph/rados.h @@ -55,13 +55,10 @@ struct ceph_timespec { * placement group. * we encode this into one __le64. */ -union ceph_pg { - __u64 pg64; - struct { - __s16 preferred; /* preferred primary osd */ - __u16 ps; /* placement seed */ - __u32 pool; /* object pool */ - } __attribute__ ((packed)) pg; +struct ceph_pg { + __le16 preferred; /* preferred primary osd */ + __le16 ps; /* placement seed */ + __le32 pool; /* object pool */ } __attribute__ ((packed)); /* @@ -117,7 +114,7 @@ static inline int ceph_stable_mod(int x, int b, int bmask) * object layout - how a given object should be stored. */ struct ceph_object_layout { - __le64 ol_pgid; /* raw pg, with _full_ ps precision. */ + struct ceph_pg ol_pgid; /* raw pg, with _full_ ps precision. */ __le32 ol_stripe_unit; /* for per-object parity, if any */ } __attribute__ ((packed)); -- cgit v0.10.2 From 6a18be16f7513ea8a4923c161ce073987932cbdb Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 4 Nov 2009 11:40:05 -0800 Subject: ceph: fix sparse endian warning Use the __le macro, even though for -1 it doesn't matter. Signed-off-by: Sage Weil diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 1bd57c8..fc8aff4 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -52,7 +52,7 @@ prepare_open_request(struct super_block *sb, int flags, int create_mode) req->r_fmode = ceph_flags_to_mode(flags); req->r_args.open.flags = cpu_to_le32(flags); req->r_args.open.mode = cpu_to_le32(create_mode); - req->r_args.open.preferred = -1; + req->r_args.open.preferred = cpu_to_le32(-1); out: return req; } diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 0ae40ba..1ac7b07 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -804,7 +804,7 @@ static int ceph_get_sb(struct file_system_type *fs_type, struct ceph_client *client; int err; int (*compare_super)(struct super_block *, void *) = ceph_compare_super; - const char *path = 0; + const char *path = NULL; struct ceph_mount_args *args; dout("ceph_get_sb\n"); -- cgit v0.10.2 From f28bcfbe660a3246621a367020054d4f1a179cd9 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 4 Nov 2009 11:46:35 -0800 Subject: ceph: convert port endianness The port is informational only, but we should make it correct. Signed-off-by: Sage Weil diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index 6ff44bb..5cc3748 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -891,9 +891,9 @@ static int addr_port(struct sockaddr_storage *ss) { switch (ss->ss_family) { case AF_INET: - return ((struct sockaddr_in *)ss)->sin_port; + return ntohs(((struct sockaddr_in *)ss)->sin_port); case AF_INET6: - return ((struct sockaddr_in6 *)ss)->sin6_port; + return ntohs(((struct sockaddr_in6 *)ss)->sin6_port); } return 0; } -- cgit v0.10.2 From 1bdb70e59026838a79f77c440f8fe480a66e65e8 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 6 Nov 2009 13:57:49 -0800 Subject: ceph: clean up 'osd%d down' console msg No ceph prefix. Signed-off-by: Sage Weil diff --git a/fs/ceph/osdmap.c b/fs/ceph/osdmap.c index 8b0cd11..a025555 100644 --- a/fs/ceph/osdmap.c +++ b/fs/ceph/osdmap.c @@ -648,7 +648,7 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, u32 osd; ceph_decode_32_safe(p, end, osd, bad); (*p)++; /* clean flag */ - pr_info("ceph osd%d down\n", osd); + pr_info("osd%d down\n", osd); if (osd < map->max_osd) map->osd_state[osd] &= ~CEPH_OSD_UP; } -- cgit v0.10.2 From c6cf726316abd613cfb7c325d950f3629f964ec6 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 6 Nov 2009 16:39:26 -0800 Subject: ceph: make CRUSH hash functions non-inline These are way to big to be inline. I missed crush/* when doing the inline audit for akpm's review. Signed-off-by: Sage Weil diff --git a/fs/ceph/Makefile b/fs/ceph/Makefile index 7da6d69..8bad70a 100644 --- a/fs/ceph/Makefile +++ b/fs/ceph/Makefile @@ -11,7 +11,7 @@ ceph-objs := super.o inode.o dir.o file.o addr.o ioctl.o \ messenger.o msgpool.o buffer.o \ mds_client.o mdsmap.o \ mon_client.o \ - osd_client.o osdmap.o crush/crush.o crush/mapper.o \ + osd_client.o osdmap.o crush/crush.o crush/mapper.o crush/hash.o \ debugfs.o \ ceph_fs.o ceph_strings.o ceph_frag.o diff --git a/fs/ceph/README b/fs/ceph/README index 231a1df..660e000 100644 --- a/fs/ceph/README +++ b/fs/ceph/README @@ -15,3 +15,4 @@ src/crush/crush.h fs/ceph/crush/crush.h src/crush/mapper.c fs/ceph/crush/mapper.c src/crush/mapper.h fs/ceph/crush/mapper.h src/crush/hash.h fs/ceph/crush/hash.h +src/crush/hash.c fs/ceph/crush/hash.c diff --git a/fs/ceph/crush/crush.c b/fs/ceph/crush/crush.c index 13755cd..fabd302 100644 --- a/fs/ceph/crush/crush.c +++ b/fs/ceph/crush/crush.c @@ -10,6 +10,17 @@ #include "crush.h" +const char *crush_bucket_alg_name(int alg) +{ + switch (alg) { + case CRUSH_BUCKET_UNIFORM: return "uniform"; + case CRUSH_BUCKET_LIST: return "list"; + case CRUSH_BUCKET_TREE: return "tree"; + case CRUSH_BUCKET_STRAW: return "straw"; + default: return "unknown"; + } +} + /** * crush_get_bucket_item_weight - Get weight of an item in given bucket * @b: bucket pointer diff --git a/fs/ceph/crush/crush.h b/fs/ceph/crush/crush.h index 9ac7e09..92c6b3c 100644 --- a/fs/ceph/crush/crush.h +++ b/fs/ceph/crush/crush.h @@ -97,16 +97,7 @@ enum { CRUSH_BUCKET_TREE = 3, CRUSH_BUCKET_STRAW = 4 }; -static inline const char *crush_bucket_alg_name(int alg) -{ - switch (alg) { - case CRUSH_BUCKET_UNIFORM: return "uniform"; - case CRUSH_BUCKET_LIST: return "list"; - case CRUSH_BUCKET_TREE: return "tree"; - case CRUSH_BUCKET_STRAW: return "straw"; - default: return "unknown"; - } -} +extern const char *crush_bucket_alg_name(int alg); struct crush_bucket { __s32 id; /* this'll be negative */ diff --git a/fs/ceph/crush/hash.c b/fs/ceph/crush/hash.c new file mode 100644 index 0000000..b438c5d --- /dev/null +++ b/fs/ceph/crush/hash.c @@ -0,0 +1,86 @@ + +#include + +/* + * Robert Jenkins' function for mixing 32-bit values + * http://burtleburtle.net/bob/hash/evahash.html + * a, b = random bits, c = input and output + */ +#define crush_hashmix(a, b, c) do { \ + a = a-b; a = a-c; a = a^(c>>13); \ + b = b-c; b = b-a; b = b^(a<<8); \ + c = c-a; c = c-b; c = c^(b>>13); \ + a = a-b; a = a-c; a = a^(c>>12); \ + b = b-c; b = b-a; b = b^(a<<16); \ + c = c-a; c = c-b; c = c^(b>>5); \ + a = a-b; a = a-c; a = a^(c>>3); \ + b = b-c; b = b-a; b = b^(a<<10); \ + c = c-a; c = c-b; c = c^(b>>15); \ + } while (0) + +#define crush_hash_seed 1315423911 + +__u32 crush_hash32(__u32 a) +{ + __u32 hash = crush_hash_seed ^ a; + __u32 b = a; + __u32 x = 231232; + __u32 y = 1232; + crush_hashmix(b, x, hash); + crush_hashmix(y, a, hash); + return hash; +} + +__u32 crush_hash32_2(__u32 a, __u32 b) +{ + __u32 hash = crush_hash_seed ^ a ^ b; + __u32 x = 231232; + __u32 y = 1232; + crush_hashmix(a, b, hash); + crush_hashmix(x, a, hash); + crush_hashmix(b, y, hash); + return hash; +} + +__u32 crush_hash32_3(__u32 a, __u32 b, __u32 c) +{ + __u32 hash = crush_hash_seed ^ a ^ b ^ c; + __u32 x = 231232; + __u32 y = 1232; + crush_hashmix(a, b, hash); + crush_hashmix(c, x, hash); + crush_hashmix(y, a, hash); + crush_hashmix(b, x, hash); + crush_hashmix(y, c, hash); + return hash; +} + +__u32 crush_hash32_4(__u32 a, __u32 b, __u32 c, __u32 d) +{ + __u32 hash = crush_hash_seed ^ a ^ b ^ c ^ d; + __u32 x = 231232; + __u32 y = 1232; + crush_hashmix(a, b, hash); + crush_hashmix(c, d, hash); + crush_hashmix(a, x, hash); + crush_hashmix(y, b, hash); + crush_hashmix(c, x, hash); + crush_hashmix(y, d, hash); + return hash; +} + +__u32 crush_hash32_5(__u32 a, __u32 b, __u32 c, __u32 d, __u32 e) +{ + __u32 hash = crush_hash_seed ^ a ^ b ^ c ^ d ^ e; + __u32 x = 231232; + __u32 y = 1232; + crush_hashmix(a, b, hash); + crush_hashmix(c, d, hash); + crush_hashmix(e, x, hash); + crush_hashmix(y, a, hash); + crush_hashmix(b, x, hash); + crush_hashmix(y, c, hash); + crush_hashmix(d, x, hash); + crush_hashmix(y, e, hash); + return hash; +} diff --git a/fs/ceph/crush/hash.h b/fs/ceph/crush/hash.h index 42f3312..9ce89f8 100644 --- a/fs/ceph/crush/hash.h +++ b/fs/ceph/crush/hash.h @@ -1,90 +1,12 @@ #ifndef _CRUSH_HASH_H #define _CRUSH_HASH_H -/* - * Robert Jenkins' function for mixing 32-bit values - * http://burtleburtle.net/bob/hash/evahash.html - * a, b = random bits, c = input and output - */ -#define crush_hashmix(a, b, c) do { \ - a = a-b; a = a-c; a = a^(c>>13); \ - b = b-c; b = b-a; b = b^(a<<8); \ - c = c-a; c = c-b; c = c^(b>>13); \ - a = a-b; a = a-c; a = a^(c>>12); \ - b = b-c; b = b-a; b = b^(a<<16); \ - c = c-a; c = c-b; c = c^(b>>5); \ - a = a-b; a = a-c; a = a^(c>>3); \ - b = b-c; b = b-a; b = b^(a<<10); \ - c = c-a; c = c-b; c = c^(b>>15); \ - } while (0) - -#define crush_hash_seed 1315423911 - -static inline __u32 crush_hash32(__u32 a) -{ - __u32 hash = crush_hash_seed ^ a; - __u32 b = a; - __u32 x = 231232; - __u32 y = 1232; - crush_hashmix(b, x, hash); - crush_hashmix(y, a, hash); - return hash; -} - -static inline __u32 crush_hash32_2(__u32 a, __u32 b) -{ - __u32 hash = crush_hash_seed ^ a ^ b; - __u32 x = 231232; - __u32 y = 1232; - crush_hashmix(a, b, hash); - crush_hashmix(x, a, hash); - crush_hashmix(b, y, hash); - return hash; -} - -static inline __u32 crush_hash32_3(__u32 a, __u32 b, __u32 c) -{ - __u32 hash = crush_hash_seed ^ a ^ b ^ c; - __u32 x = 231232; - __u32 y = 1232; - crush_hashmix(a, b, hash); - crush_hashmix(c, x, hash); - crush_hashmix(y, a, hash); - crush_hashmix(b, x, hash); - crush_hashmix(y, c, hash); - return hash; -} - -static inline __u32 crush_hash32_4(__u32 a, __u32 b, __u32 c, - __u32 d) -{ - __u32 hash = crush_hash_seed ^ a ^ b ^ c ^ d; - __u32 x = 231232; - __u32 y = 1232; - crush_hashmix(a, b, hash); - crush_hashmix(c, d, hash); - crush_hashmix(a, x, hash); - crush_hashmix(y, b, hash); - crush_hashmix(c, x, hash); - crush_hashmix(y, d, hash); - return hash; -} - -static inline __u32 crush_hash32_5(__u32 a, __u32 b, __u32 c, - __u32 d, __u32 e) -{ - __u32 hash = crush_hash_seed ^ a ^ b ^ c ^ d ^ e; - __u32 x = 231232; - __u32 y = 1232; - crush_hashmix(a, b, hash); - crush_hashmix(c, d, hash); - crush_hashmix(e, x, hash); - crush_hashmix(y, a, hash); - crush_hashmix(b, x, hash); - crush_hashmix(y, c, hash); - crush_hashmix(d, x, hash); - crush_hashmix(y, e, hash); - return hash; -} +extern __u32 crush_hash32(__u32 a); +extern __u32 crush_hash32_2(__u32 a, __u32 b); +extern __u32 crush_hash32_3(__u32 a, __u32 b, __u32 c); +extern __u32 crush_hash32_4(__u32 a, __u32 b, __u32 c, + __u32 d); +extern __u32 crush_hash32_5(__u32 a, __u32 b, __u32 c, + __u32 d, __u32 e); #endif -- cgit v0.10.2 From cfbbcd24a6bfd794295ee7ad76dfbff40ad6b934 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 6 Nov 2009 16:44:05 -0800 Subject: ceph: use strong hash function for mapping objects to pgs We were using the (weak) dcache hash function, but it was leaving lower bits consecutive for consecutive (inode) objects. We really want to make the object to pg mapping random and uniform, so use a proper hash function here. This is Robert Jenkin's public domain hash function (with some minor cleanup): http://burtleburtle.net/bob/hash/evahash.html This is a protocol revision. Signed-off-by: Sage Weil diff --git a/fs/ceph/ceph_fs.c b/fs/ceph/ceph_fs.c index a950b40..b3ecf1b 100644 --- a/fs/ceph/ceph_fs.c +++ b/fs/ceph/ceph_fs.c @@ -73,32 +73,79 @@ int ceph_caps_for_mode(int mode) return 0; } -/* Name hashing routines. Initial hash value */ -/* Hash courtesy of the R5 hash in reiserfs modulo sign bits */ -#define ceph_init_name_hash() 0 - -/* partial hash update function. Assume roughly 4 bits per character */ -static unsigned long ceph_partial_name_hash(unsigned long c, - unsigned long prevhash) -{ - return (prevhash + (c << 4) + (c >> 4)) * 11; -} - /* - * Finally: cut down the number of bits to a int value (and try to avoid - * losing bits) + * Robert Jenkin's hash function. + * http://burtleburtle.net/bob/hash/evahash.html + * This is in the public domain. */ -static unsigned long ceph_end_name_hash(unsigned long hash) -{ - return hash & 0xffffffff; -} +#define mix(a, b, c) \ + do { \ + a = a - b; a = a - c; a = a ^ (c >> 13); \ + b = b - c; b = b - a; b = b ^ (a << 8); \ + c = c - a; c = c - b; c = c ^ (b >> 13); \ + a = a - b; a = a - c; a = a ^ (c >> 12); \ + b = b - c; b = b - a; b = b ^ (a << 16); \ + c = c - a; c = c - b; c = c ^ (b >> 5); \ + a = a - b; a = a - c; a = a ^ (c >> 3); \ + b = b - c; b = b - a; b = b ^ (a << 10); \ + c = c - a; c = c - b; c = c ^ (b >> 15); \ + } while (0) -/* Compute the hash for a name string. */ -unsigned int ceph_full_name_hash(const char *name, unsigned int len) +unsigned int ceph_full_name_hash(const char *str, unsigned int length) { - unsigned long hash = ceph_init_name_hash(); - while (len--) - hash = ceph_partial_name_hash(*name++, hash); - return ceph_end_name_hash(hash); + const unsigned char *k = (const unsigned char *)str; + __u32 a, b, c; /* the internal state */ + __u32 len; /* how many key bytes still need mixing */ + + /* Set up the internal state */ + len = length; + a = 0x9e3779b9; /* the golden ratio; an arbitrary value */ + b = a; + c = 0; /* variable initialization of internal state */ + + /* handle most of the key */ + while (len >= 12) { + a = a + (k[0] + ((__u32)k[1] << 8) + ((__u32)k[2] << 16) + + ((__u32)k[3] << 24)); + b = b + (k[4] + ((__u32)k[5] << 8) + ((__u32)k[6] << 16) + + ((__u32)k[7] << 24)); + c = c + (k[8] + ((__u32)k[9] << 8) + ((__u32)k[10] << 16) + + ((__u32)k[11] << 24)); + mix(a, b, c); + k = k + 12; + len = len - 12; + } + + /* handle the last 11 bytes */ + c = c + length; + switch (len) { /* all the case statements fall through */ + case 11: + c = c + ((__u32)k[10] << 24); + case 10: + c = c + ((__u32)k[9] << 16); + case 9: + c = c + ((__u32)k[8] << 8); + /* the first byte of c is reserved for the length */ + case 8: + b = b + ((__u32)k[7] << 24); + case 7: + b = b + ((__u32)k[6] << 16); + case 6: + b = b + ((__u32)k[5] << 8); + case 5: + b = b + k[4]; + case 4: + a = a + ((__u32)k[3] << 24); + case 3: + a = a + ((__u32)k[2] << 16); + case 2: + a = a + ((__u32)k[1] << 8); + case 1: + a = a + k[0]; + /* case 0: nothing left to add */ + } + mix(a, b, c); + + return c; } diff --git a/fs/ceph/ceph_fs.h b/fs/ceph/ceph_fs.h index ae52382..25fc537 100644 --- a/fs/ceph/ceph_fs.h +++ b/fs/ceph/ceph_fs.h @@ -38,7 +38,7 @@ #define CEPH_OSD_PROTOCOL 7 /* cluster internal */ #define CEPH_MDS_PROTOCOL 9 /* cluster internal */ #define CEPH_MON_PROTOCOL 5 /* cluster internal */ -#define CEPH_OSDC_PROTOCOL 21 /* server/client */ +#define CEPH_OSDC_PROTOCOL 22 /* server/client */ #define CEPH_MDSC_PROTOCOL 29 /* server/client */ #define CEPH_MONC_PROTOCOL 15 /* server/client */ -- cgit v0.10.2 From 1654dd0cf5ee1827322aca156af7d96d757201c7 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 6 Nov 2009 21:55:25 -0800 Subject: ceph: make object hash a pg_pool property The object will be hashed to a placement seed (ps) based on the pg_pool's hash function. This allows new hashes to be introduced into an existing object store, or selection of a hash appropriate to the objects that will be stored in a particular pool. Signed-off-by: Sage Weil diff --git a/fs/ceph/Makefile b/fs/ceph/Makefile index 8bad70a..bdd3e6f 100644 --- a/fs/ceph/Makefile +++ b/fs/ceph/Makefile @@ -13,7 +13,7 @@ ceph-objs := super.o inode.o dir.o file.o addr.o ioctl.o \ mon_client.o \ osd_client.o osdmap.o crush/crush.o crush/mapper.o crush/hash.o \ debugfs.o \ - ceph_fs.o ceph_strings.o ceph_frag.o + ceph_fs.o ceph_strings.o ceph_hash.o ceph_frag.o else #Otherwise we were called directly from the command diff --git a/fs/ceph/README b/fs/ceph/README index 660e000..18352fa 100644 --- a/fs/ceph/README +++ b/fs/ceph/README @@ -10,6 +10,8 @@ src/include/rados.h fs/ceph/rados.h src/include/ceph_strings.cc fs/ceph/ceph_strings.c src/include/ceph_frag.h fs/ceph/ceph_frag.h src/include/ceph_frag.cc fs/ceph/ceph_frag.c +src/include/ceph_hash.h fs/ceph/ceph_hash.h +src/include/ceph_hash.cc fs/ceph/ceph_hash.c src/crush/crush.c fs/ceph/crush/crush.c src/crush/crush.h fs/ceph/crush/crush.h src/crush/mapper.c fs/ceph/crush/mapper.c diff --git a/fs/ceph/ceph_fs.c b/fs/ceph/ceph_fs.c index b3ecf1b..79d76bc 100644 --- a/fs/ceph/ceph_fs.c +++ b/fs/ceph/ceph_fs.c @@ -72,80 +72,3 @@ int ceph_caps_for_mode(int mode) } return 0; } - -/* - * Robert Jenkin's hash function. - * http://burtleburtle.net/bob/hash/evahash.html - * This is in the public domain. - */ -#define mix(a, b, c) \ - do { \ - a = a - b; a = a - c; a = a ^ (c >> 13); \ - b = b - c; b = b - a; b = b ^ (a << 8); \ - c = c - a; c = c - b; c = c ^ (b >> 13); \ - a = a - b; a = a - c; a = a ^ (c >> 12); \ - b = b - c; b = b - a; b = b ^ (a << 16); \ - c = c - a; c = c - b; c = c ^ (b >> 5); \ - a = a - b; a = a - c; a = a ^ (c >> 3); \ - b = b - c; b = b - a; b = b ^ (a << 10); \ - c = c - a; c = c - b; c = c ^ (b >> 15); \ - } while (0) - -unsigned int ceph_full_name_hash(const char *str, unsigned int length) -{ - const unsigned char *k = (const unsigned char *)str; - __u32 a, b, c; /* the internal state */ - __u32 len; /* how many key bytes still need mixing */ - - /* Set up the internal state */ - len = length; - a = 0x9e3779b9; /* the golden ratio; an arbitrary value */ - b = a; - c = 0; /* variable initialization of internal state */ - - /* handle most of the key */ - while (len >= 12) { - a = a + (k[0] + ((__u32)k[1] << 8) + ((__u32)k[2] << 16) + - ((__u32)k[3] << 24)); - b = b + (k[4] + ((__u32)k[5] << 8) + ((__u32)k[6] << 16) + - ((__u32)k[7] << 24)); - c = c + (k[8] + ((__u32)k[9] << 8) + ((__u32)k[10] << 16) + - ((__u32)k[11] << 24)); - mix(a, b, c); - k = k + 12; - len = len - 12; - } - - /* handle the last 11 bytes */ - c = c + length; - switch (len) { /* all the case statements fall through */ - case 11: - c = c + ((__u32)k[10] << 24); - case 10: - c = c + ((__u32)k[9] << 16); - case 9: - c = c + ((__u32)k[8] << 8); - /* the first byte of c is reserved for the length */ - case 8: - b = b + ((__u32)k[7] << 24); - case 7: - b = b + ((__u32)k[6] << 16); - case 6: - b = b + ((__u32)k[5] << 8); - case 5: - b = b + k[4]; - case 4: - a = a + ((__u32)k[3] << 24); - case 3: - a = a + ((__u32)k[2] << 16); - case 2: - a = a + ((__u32)k[1] << 8); - case 1: - a = a + k[0]; - /* case 0: nothing left to add */ - } - mix(a, b, c); - - return c; -} - diff --git a/fs/ceph/ceph_fs.h b/fs/ceph/ceph_fs.h index 25fc537..36becb0 100644 --- a/fs/ceph/ceph_fs.h +++ b/fs/ceph/ceph_fs.h @@ -49,8 +49,6 @@ #define CEPH_MAX_MON 31 -unsigned int ceph_full_name_hash(const char *name, unsigned int len); - /* * ceph_file_layout - describe data layout for a file/inode diff --git a/fs/ceph/ceph_hash.c b/fs/ceph/ceph_hash.c new file mode 100644 index 0000000..ac8be54 --- /dev/null +++ b/fs/ceph/ceph_hash.c @@ -0,0 +1,118 @@ + +#include "types.h" + +/* + * Robert Jenkin's hash function. + * http://burtleburtle.net/bob/hash/evahash.html + * This is in the public domain. + */ +#define mix(a, b, c) \ + do { \ + a = a - b; a = a - c; a = a ^ (c >> 13); \ + b = b - c; b = b - a; b = b ^ (a << 8); \ + c = c - a; c = c - b; c = c ^ (b >> 13); \ + a = a - b; a = a - c; a = a ^ (c >> 12); \ + b = b - c; b = b - a; b = b ^ (a << 16); \ + c = c - a; c = c - b; c = c ^ (b >> 5); \ + a = a - b; a = a - c; a = a ^ (c >> 3); \ + b = b - c; b = b - a; b = b ^ (a << 10); \ + c = c - a; c = c - b; c = c ^ (b >> 15); \ + } while (0) + +unsigned ceph_str_hash_rjenkins(const char *str, unsigned length) +{ + const unsigned char *k = (const unsigned char *)str; + __u32 a, b, c; /* the internal state */ + __u32 len; /* how many key bytes still need mixing */ + + /* Set up the internal state */ + len = length; + a = 0x9e3779b9; /* the golden ratio; an arbitrary value */ + b = a; + c = 0; /* variable initialization of internal state */ + + /* handle most of the key */ + while (len >= 12) { + a = a + (k[0] + ((__u32)k[1] << 8) + ((__u32)k[2] << 16) + + ((__u32)k[3] << 24)); + b = b + (k[4] + ((__u32)k[5] << 8) + ((__u32)k[6] << 16) + + ((__u32)k[7] << 24)); + c = c + (k[8] + ((__u32)k[9] << 8) + ((__u32)k[10] << 16) + + ((__u32)k[11] << 24)); + mix(a, b, c); + k = k + 12; + len = len - 12; + } + + /* handle the last 11 bytes */ + c = c + length; + switch (len) { /* all the case statements fall through */ + case 11: + c = c + ((__u32)k[10] << 24); + case 10: + c = c + ((__u32)k[9] << 16); + case 9: + c = c + ((__u32)k[8] << 8); + /* the first byte of c is reserved for the length */ + case 8: + b = b + ((__u32)k[7] << 24); + case 7: + b = b + ((__u32)k[6] << 16); + case 6: + b = b + ((__u32)k[5] << 8); + case 5: + b = b + k[4]; + case 4: + a = a + ((__u32)k[3] << 24); + case 3: + a = a + ((__u32)k[2] << 16); + case 2: + a = a + ((__u32)k[1] << 8); + case 1: + a = a + k[0]; + /* case 0: nothing left to add */ + } + mix(a, b, c); + + return c; +} + +/* + * linux dcache hash + */ +unsigned ceph_str_hash_linux(const char *str, unsigned length) +{ + unsigned long hash = 0; + unsigned char c; + + while (length-- > 0) { + c = *str++; + hash = (hash + (c << 4) + (c >> 4)) * 11; + } + return hash; +} + + +unsigned ceph_str_hash(int type, const char *s, unsigned len) +{ + switch (type) { + case CEPH_STR_HASH_LINUX: + return ceph_str_hash_linux(s, len); + case CEPH_STR_HASH_RJENKINS: + return ceph_str_hash_rjenkins(s, len); + default: + return -1; + } +} + +const char *ceph_str_hash_name(int type) +{ + switch (type) { + case CEPH_STR_HASH_LINUX: + return "linux"; + case CEPH_STR_HASH_RJENKINS: + return "rjenkins"; + default: + return "unknown"; + } +} diff --git a/fs/ceph/ceph_hash.h b/fs/ceph/ceph_hash.h new file mode 100644 index 0000000..5ac470c --- /dev/null +++ b/fs/ceph/ceph_hash.h @@ -0,0 +1,13 @@ +#ifndef _FS_CEPH_HASH_H +#define _FS_CEPH_HASH_H + +#define CEPH_STR_HASH_LINUX 0x1 /* linux dcache hash */ +#define CEPH_STR_HASH_RJENKINS 0x2 /* robert jenkins' */ + +extern unsigned ceph_str_hash_linux(const char *s, unsigned len); +extern unsigned ceph_str_hash_rjenkins(const char *s, unsigned len); + +extern unsigned ceph_str_hash(int type, const char *s, unsigned len); +extern const char *ceph_str_hash_name(int type); + +#endif diff --git a/fs/ceph/osdmap.c b/fs/ceph/osdmap.c index a025555..6847827 100644 --- a/fs/ceph/osdmap.c +++ b/fs/ceph/osdmap.c @@ -809,7 +809,7 @@ int ceph_calc_object_layout(struct ceph_object_layout *ol, return -EIO; pool = &osdmap->pg_pool[poolid]; - ps = ceph_full_name_hash(oid, strlen(oid)); + ps = ceph_str_hash(pool->v.object_hash, oid, strlen(oid)); if (preferred >= 0) { ps += preferred; num = le32_to_cpu(pool->v.lpg_num); diff --git a/fs/ceph/rados.h b/fs/ceph/rados.h index 85bdef7..fb23ff9 100644 --- a/fs/ceph/rados.h +++ b/fs/ceph/rados.h @@ -84,6 +84,7 @@ struct ceph_pg_pool { __u8 type; /* CEPH_PG_TYPE_* */ __u8 size; /* number of osds in each pg */ __u8 crush_ruleset; /* crush placement rule */ + __u8 object_hash; /* hash mapping object name to ps */ __le32 pg_num, pgp_num; /* number of pg's */ __le32 lpg_num, lpgp_num; /* number of localized pg's */ __le32 last_change; /* most recent epoch changed */ diff --git a/fs/ceph/types.h b/fs/ceph/types.h index 8a51456..28b35a0 100644 --- a/fs/ceph/types.h +++ b/fs/ceph/types.h @@ -9,6 +9,7 @@ #include "ceph_fs.h" #include "ceph_frag.h" +#include "ceph_hash.h" /* * Identify inodes by both their ino AND snapshot id (a u64). -- cgit v0.10.2 From fb690390e305ea51e1883b105c7d3c52d7100ba5 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Sat, 7 Nov 2009 20:18:22 -0800 Subject: ceph: make CRUSH hash function a bucket property Make the integer hash function a property of the bucket it is used on. This allows us to gracefully add support for new hash functions without starting from scatch. Signed-off-by: Sage Weil diff --git a/fs/ceph/crush/crush.h b/fs/ceph/crush/crush.h index 92c6b3c..dcd7e75 100644 --- a/fs/ceph/crush/crush.h +++ b/fs/ceph/crush/crush.h @@ -102,7 +102,8 @@ extern const char *crush_bucket_alg_name(int alg); struct crush_bucket { __s32 id; /* this'll be negative */ __u16 type; /* non-zero; type=0 is reserved for devices */ - __u16 alg; /* one of CRUSH_BUCKET_* */ + __u8 alg; /* one of CRUSH_BUCKET_* */ + __u8 hash; /* which hash function to use, CRUSH_HASH_* */ __u32 weight; /* 16-bit fixed point */ __u32 size; /* num items */ __s32 *items; diff --git a/fs/ceph/crush/hash.c b/fs/ceph/crush/hash.c index b438c5d..5873aed 100644 --- a/fs/ceph/crush/hash.c +++ b/fs/ceph/crush/hash.c @@ -1,5 +1,6 @@ #include +#include "hash.h" /* * Robert Jenkins' function for mixing 32-bit values @@ -20,7 +21,7 @@ #define crush_hash_seed 1315423911 -__u32 crush_hash32(__u32 a) +static __u32 crush_hash32_rjenkins1(__u32 a) { __u32 hash = crush_hash_seed ^ a; __u32 b = a; @@ -31,7 +32,7 @@ __u32 crush_hash32(__u32 a) return hash; } -__u32 crush_hash32_2(__u32 a, __u32 b) +static __u32 crush_hash32_rjenkins1_2(__u32 a, __u32 b) { __u32 hash = crush_hash_seed ^ a ^ b; __u32 x = 231232; @@ -42,7 +43,7 @@ __u32 crush_hash32_2(__u32 a, __u32 b) return hash; } -__u32 crush_hash32_3(__u32 a, __u32 b, __u32 c) +static __u32 crush_hash32_rjenkins1_3(__u32 a, __u32 b, __u32 c) { __u32 hash = crush_hash_seed ^ a ^ b ^ c; __u32 x = 231232; @@ -55,7 +56,7 @@ __u32 crush_hash32_3(__u32 a, __u32 b, __u32 c) return hash; } -__u32 crush_hash32_4(__u32 a, __u32 b, __u32 c, __u32 d) +static __u32 crush_hash32_rjenkins1_4(__u32 a, __u32 b, __u32 c, __u32 d) { __u32 hash = crush_hash_seed ^ a ^ b ^ c ^ d; __u32 x = 231232; @@ -69,7 +70,8 @@ __u32 crush_hash32_4(__u32 a, __u32 b, __u32 c, __u32 d) return hash; } -__u32 crush_hash32_5(__u32 a, __u32 b, __u32 c, __u32 d, __u32 e) +static __u32 crush_hash32_rjenkins1_5(__u32 a, __u32 b, __u32 c, __u32 d, + __u32 e) { __u32 hash = crush_hash_seed ^ a ^ b ^ c ^ d ^ e; __u32 x = 231232; @@ -84,3 +86,64 @@ __u32 crush_hash32_5(__u32 a, __u32 b, __u32 c, __u32 d, __u32 e) crush_hashmix(y, e, hash); return hash; } + + +__u32 crush_hash32(int type, __u32 a) +{ + switch (type) { + case CRUSH_HASH_RJENKINS1: + return crush_hash32_rjenkins1(a); + default: + return 0; + } +} + +__u32 crush_hash32_2(int type, __u32 a, __u32 b) +{ + switch (type) { + case CRUSH_HASH_RJENKINS1: + return crush_hash32_rjenkins1_2(a, b); + default: + return 0; + } +} + +__u32 crush_hash32_3(int type, __u32 a, __u32 b, __u32 c) +{ + switch (type) { + case CRUSH_HASH_RJENKINS1: + return crush_hash32_rjenkins1_3(a, b, c); + default: + return 0; + } +} + +__u32 crush_hash32_4(int type, __u32 a, __u32 b, __u32 c, __u32 d) +{ + switch (type) { + case CRUSH_HASH_RJENKINS1: + return crush_hash32_rjenkins1_4(a, b, c, d); + default: + return 0; + } +} + +__u32 crush_hash32_5(int type, __u32 a, __u32 b, __u32 c, __u32 d, __u32 e) +{ + switch (type) { + case CRUSH_HASH_RJENKINS1: + return crush_hash32_rjenkins1_5(a, b, c, d, e); + default: + return 0; + } +} + +const char *crush_hash_name(int type) +{ + switch (type) { + case CRUSH_HASH_RJENKINS1: + return "rjenkins1"; + default: + return "unknown"; + } +} diff --git a/fs/ceph/crush/hash.h b/fs/ceph/crush/hash.h index 9ce89f8..ff48e110 100644 --- a/fs/ceph/crush/hash.h +++ b/fs/ceph/crush/hash.h @@ -1,12 +1,17 @@ #ifndef _CRUSH_HASH_H #define _CRUSH_HASH_H -extern __u32 crush_hash32(__u32 a); -extern __u32 crush_hash32_2(__u32 a, __u32 b); -extern __u32 crush_hash32_3(__u32 a, __u32 b, __u32 c); -extern __u32 crush_hash32_4(__u32 a, __u32 b, __u32 c, - __u32 d); -extern __u32 crush_hash32_5(__u32 a, __u32 b, __u32 c, - __u32 d, __u32 e); +#define CRUSH_HASH_RJENKINS1 0 + +#define CRUSH_HASH_DEFAULT CRUSH_HASH_RJENKINS1 + +extern const char *crush_hash_name(int type); + +extern __u32 crush_hash32(int type, __u32 a); +extern __u32 crush_hash32_2(int type, __u32 a, __u32 b); +extern __u32 crush_hash32_3(int type, __u32 a, __u32 b, __u32 c); +extern __u32 crush_hash32_4(int type, __u32 a, __u32 b, __u32 c, __u32 d); +extern __u32 crush_hash32_5(int type, __u32 a, __u32 b, __u32 c, __u32 d, + __u32 e); #endif diff --git a/fs/ceph/crush/mapper.c b/fs/ceph/crush/mapper.c index 54f3f40..2523d44 100644 --- a/fs/ceph/crush/mapper.c +++ b/fs/ceph/crush/mapper.c @@ -78,7 +78,7 @@ static int bucket_perm_choose(struct crush_bucket *bucket, /* optimize common r=0 case */ if (pr == 0) { - s = crush_hash32_3(x, bucket->id, 0) % + s = crush_hash32_3(bucket->hash, x, bucket->id, 0) % bucket->size; bucket->perm[0] = s; bucket->perm_n = 0xffff; /* magic value, see below */ @@ -103,7 +103,7 @@ static int bucket_perm_choose(struct crush_bucket *bucket, unsigned p = bucket->perm_n; /* no point in swapping the final entry */ if (p < bucket->size - 1) { - i = crush_hash32_3(x, bucket->id, p) % + i = crush_hash32_3(bucket->hash, x, bucket->id, p) % (bucket->size - p); if (i) { unsigned t = bucket->perm[p + i]; @@ -138,8 +138,8 @@ static int bucket_list_choose(struct crush_bucket_list *bucket, int i; for (i = bucket->h.size-1; i >= 0; i--) { - __u64 w = crush_hash32_4(x, bucket->h.items[i], r, - bucket->h.id); + __u64 w = crush_hash32_4(bucket->h.hash,x, bucket->h.items[i], + r, bucket->h.id); w &= 0xffff; dprintk("list_choose i=%d x=%d r=%d item %d weight %x " "sw %x rand %llx", @@ -198,7 +198,8 @@ static int bucket_tree_choose(struct crush_bucket_tree *bucket, while (!terminal(n)) { /* pick point in [0, w) */ w = bucket->node_weights[n]; - t = (__u64)crush_hash32_4(x, n, r, bucket->h.id) * (__u64)w; + t = (__u64)crush_hash32_4(bucket->h.hash, x, n, r, + bucket->h.id) * (__u64)w; t = t >> 32; /* descend to the left or right? */ @@ -224,7 +225,7 @@ static int bucket_straw_choose(struct crush_bucket_straw *bucket, __u64 draw; for (i = 0; i < bucket->h.size; i++) { - draw = crush_hash32_3(x, bucket->h.items[i], r); + draw = crush_hash32_3(bucket->h.hash, x, bucket->h.items[i], r); draw &= 0xffff; draw *= bucket->straws[i]; if (i == 0 || draw > high_draw) { @@ -267,7 +268,8 @@ static int is_out(struct crush_map *map, __u32 *weight, int item, int x) return 0; if (weight[item] == 0) return 1; - if ((crush_hash32_2(x, item) & 0xffff) < weight[item]) + if ((crush_hash32_2(CRUSH_HASH_RJENKINS1, x, item) & 0xffff) + < weight[item]) return 0; return 1; } diff --git a/fs/ceph/osdmap.c b/fs/ceph/osdmap.c index 6847827..8c994c7 100644 --- a/fs/ceph/osdmap.c +++ b/fs/ceph/osdmap.c @@ -210,7 +210,8 @@ static struct crush_map *crush_decode(void *pbyval, void *end) ceph_decode_need(p, end, 4*sizeof(u32), bad); b->id = ceph_decode_32(p); b->type = ceph_decode_16(p); - b->alg = ceph_decode_16(p); + b->alg = ceph_decode_8(p); + b->hash = ceph_decode_8(p); b->weight = ceph_decode_32(p); b->size = ceph_decode_32(p); -- cgit v0.10.2 From 685f9a5d14194fc35db73e5e7370740ccc14b64a Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 9 Nov 2009 12:05:48 -0800 Subject: ceph: do not confuse stale and dead (unreconnected) caps We were using the cap_gen to track both stale caps (caps that timed out due to temporarily losing touch with the mds) and dead caps that did not reconnect after an MDS failure. Introduce a recon_gen counter to track reconnections to restarted MDSs and kill dead caps based on that instead. Rename gen to cap_gen while we're at it to make it more clear which is which. Signed-off-by: Sage Weil diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 8b863db..775e6f6 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -609,7 +609,8 @@ retry: cap->seq = seq; cap->issue_seq = seq; cap->mseq = mseq; - cap->gen = session->s_cap_gen; + cap->cap_gen = session->s_cap_gen; + cap->recon_gen = session->s_recon_gen; if (fmode >= 0) __ceph_get_fmode(ci, fmode); @@ -626,17 +627,25 @@ retry: static int __cap_is_valid(struct ceph_cap *cap) { unsigned long ttl; - u32 gen; + u32 gen, recon_gen; spin_lock(&cap->session->s_cap_lock); gen = cap->session->s_cap_gen; + recon_gen = cap->session->s_recon_gen; ttl = cap->session->s_cap_ttl; spin_unlock(&cap->session->s_cap_lock); - if (cap->gen < gen || time_after_eq(jiffies, ttl)) { + if (cap->recon_gen != recon_gen) { + dout("__cap_is_valid %p cap %p issued %s " + "but DEAD (recon_gen %u vs %u)\n", &cap->ci->vfs_inode, + cap, ceph_cap_string(cap->issued), cap->recon_gen, + recon_gen); + return 0; + } + if (cap->cap_gen < gen || time_after_eq(jiffies, ttl)) { dout("__cap_is_valid %p cap %p issued %s " "but STALE (gen %u vs %u)\n", &cap->ci->vfs_inode, - cap, ceph_cap_string(cap->issued), cap->gen, gen); + cap, ceph_cap_string(cap->issued), cap->cap_gen, gen); return 0; } @@ -2203,7 +2212,8 @@ restart: issued = __ceph_caps_issued(ci, &implemented); issued |= implemented | __ceph_caps_dirty(ci); - cap->gen = session->s_cap_gen; + cap->cap_gen = session->s_cap_gen; + cap->recon_gen = session->s_recon_gen; __check_cap_issue(ci, cap, newcaps); diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 210cb66..828417a 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -329,6 +329,7 @@ static struct ceph_mds_session *register_session(struct ceph_mds_client *mdsc, ceph_con_open(&s->s_con, ceph_mdsmap_get_addr(mdsc->mdsmap, mds)); spin_lock_init(&s->s_cap_lock); + s->s_recon_gen = 0; s->s_cap_gen = 0; s->s_cap_ttl = 0; s->s_renew_requested = 0; @@ -738,10 +739,11 @@ static int wake_up_session_cb(struct inode *inode, struct ceph_cap *cap, struct ceph_mds_session *session = arg; spin_lock(&inode->i_lock); - if (cap->gen != session->s_cap_gen) { + if (cap->recon_gen != session->s_recon_gen) { pr_err("failed reconnect %p %llx.%llx cap %p " - "(gen %d < session %d)\n", inode, ceph_vinop(inode), - cap, cap->gen, session->s_cap_gen); + "(recon_gen %d < session %d)\n", inode, + ceph_vinop(inode), cap, + cap->recon_gen, session->s_recon_gen); __ceph_remove_cap(cap, NULL); } wake_up(&ceph_inode(inode)->i_cap_wq); @@ -2050,6 +2052,7 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc, int mds) session->s_state = CEPH_MDS_SESSION_RECONNECTING; session->s_seq = 0; + session->s_recon_gen++; ceph_con_open(&session->s_con, ceph_mdsmap_get_addr(mdsc->mdsmap, mds)); diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h index f566e9c..c0846b1 100644 --- a/fs/ceph/mds_client.h +++ b/fs/ceph/mds_client.h @@ -98,6 +98,8 @@ struct ceph_mds_session { u64 s_seq; /* incoming msg seq # */ struct mutex s_mutex; /* serialize session messages */ + int s_recon_gen; /* inc on reconnect to recovered mds */ + struct ceph_connection s_con; /* protected by s_cap_lock */ diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 05947b9..2579355 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -169,7 +169,9 @@ struct ceph_cap { int issued; /* latest, from the mds */ int implemented; /* implemented superset of issued (for revocation) */ int mds_wanted; - u32 seq, issue_seq, mseq, gen; + u32 seq, issue_seq, mseq; + u32 cap_gen; /* active/stale cycle */ + u32 recon_gen; /* mds restart reconnect cycle */ unsigned long last_used; struct list_head caps_item; }; -- cgit v0.10.2 From eed0ef2caf928327332da54d23579debe629d5bc Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 10 Nov 2009 14:34:36 -0800 Subject: ceph: separate banner and connect during handshake into distinct stages We need to make sure we only swab the address during the banner once. So break process_banner out of process_connect, and clean up the surrounding code so that these are distinct phases of the handshake. Signed-off-by: Sage Weil diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index 5cc3748..e389656 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -564,10 +564,26 @@ static void prepare_write_keepalive(struct ceph_connection *con) /* * We connected to a peer and are saying hello. */ -static void prepare_write_connect(struct ceph_messenger *msgr, - struct ceph_connection *con) +static void prepare_write_banner(struct ceph_messenger *msgr, + struct ceph_connection *con) { int len = strlen(CEPH_BANNER); + + con->out_kvec[0].iov_base = CEPH_BANNER; + con->out_kvec[0].iov_len = len; + con->out_kvec[1].iov_base = &msgr->my_enc_addr; + con->out_kvec[1].iov_len = sizeof(msgr->my_enc_addr); + con->out_kvec_left = 2; + con->out_kvec_bytes = len + sizeof(msgr->my_enc_addr); + con->out_kvec_cur = con->out_kvec; + con->out_more = 0; + set_bit(WRITE_PENDING, &con->state); +} + +static void prepare_write_connect(struct ceph_messenger *msgr, + struct ceph_connection *con, + int after_banner) +{ unsigned global_seq = get_global_seq(con->msgr, 0); int proto; @@ -595,32 +611,14 @@ static void prepare_write_connect(struct ceph_messenger *msgr, if (test_bit(LOSSYTX, &con->state)) con->out_connect.flags = CEPH_MSG_CONNECT_LOSSY; - con->out_kvec[0].iov_base = CEPH_BANNER; - con->out_kvec[0].iov_len = len; - con->out_kvec[1].iov_base = &msgr->my_enc_addr; - con->out_kvec[1].iov_len = sizeof(msgr->my_enc_addr); - con->out_kvec[2].iov_base = &con->out_connect; - con->out_kvec[2].iov_len = sizeof(con->out_connect); - con->out_kvec_left = 3; - con->out_kvec_bytes = len + sizeof(msgr->my_enc_addr) + - sizeof(con->out_connect); - con->out_kvec_cur = con->out_kvec; - con->out_more = 0; - set_bit(WRITE_PENDING, &con->state); -} - -static void prepare_write_connect_retry(struct ceph_messenger *msgr, - struct ceph_connection *con) -{ - dout("prepare_write_connect_retry %p\n", con); - con->out_connect.connect_seq = cpu_to_le32(con->connect_seq); - con->out_connect.global_seq = - cpu_to_le32(get_global_seq(con->msgr, 0)); - - con->out_kvec[0].iov_base = &con->out_connect; - con->out_kvec[0].iov_len = sizeof(con->out_connect); - con->out_kvec_left = 1; - con->out_kvec_bytes = sizeof(con->out_connect); + if (!after_banner) { + con->out_kvec_left = 0; + con->out_kvec_bytes = 0; + } + con->out_kvec[con->out_kvec_left].iov_base = &con->out_connect; + con->out_kvec[con->out_kvec_left].iov_len = sizeof(con->out_connect); + con->out_kvec_left++; + con->out_kvec_bytes += sizeof(con->out_connect); con->out_kvec_cur = con->out_kvec; con->out_more = 0; set_bit(WRITE_PENDING, &con->state); @@ -778,6 +776,12 @@ out: /* * Prepare to read connection handshake, or an ack. */ +static void prepare_read_banner(struct ceph_connection *con) +{ + dout("prepare_read_banner %p\n", con); + con->in_base_pos = 0; +} + static void prepare_read_connect(struct ceph_connection *con) { dout("prepare_read_connect %p\n", con); @@ -829,11 +833,11 @@ static int read_partial(struct ceph_connection *con, /* * Read all or part of the connect-side handshake on a new connection */ -static int read_partial_connect(struct ceph_connection *con) +static int read_partial_banner(struct ceph_connection *con) { int ret, to = 0; - dout("read_partial_connect %p at %d\n", con, con->in_base_pos); + dout("read_partial_banner %p at %d\n", con, con->in_base_pos); /* peer's banner */ ret = read_partial(con, &to, strlen(CEPH_BANNER), con->in_banner); @@ -847,6 +851,16 @@ static int read_partial_connect(struct ceph_connection *con) &con->peer_addr_for_me); if (ret <= 0) goto out; +out: + return ret; +} + +static int read_partial_connect(struct ceph_connection *con) +{ + int ret, to = 0; + + dout("read_partial_connect %p at %d\n", con, con->in_base_pos); + ret = read_partial(con, &to, sizeof(con->in_reply), &con->in_reply); if (ret <= 0) goto out; @@ -856,6 +870,7 @@ static int read_partial_connect(struct ceph_connection *con) le32_to_cpu(con->in_reply.global_seq)); out: return ret; + } /* @@ -976,9 +991,9 @@ bad: return -EINVAL; } -static int process_connect(struct ceph_connection *con) +static int process_banner(struct ceph_connection *con) { - dout("process_connect on %p tag %d\n", con, (int)con->in_tag); + dout("process_banner on %p\n", con); if (verify_hello(con) < 0) return -1; @@ -1016,10 +1031,19 @@ static int process_connect(struct ceph_connection *con) sizeof(con->peer_addr_for_me.in_addr)); addr_set_port(&con->msgr->inst.addr.in_addr, port); encode_my_addr(con->msgr); - dout("process_connect learned my addr is %s\n", + dout("process_banner learned my addr is %s\n", pr_addr(&con->msgr->inst.addr.in_addr)); } + set_bit(NEGOTIATING, &con->state); + prepare_read_connect(con); + return 0; +} + +static int process_connect(struct ceph_connection *con) +{ + dout("process_connect on %p tag %d\n", con, (int)con->in_tag); + switch (con->in_reply.tag) { case CEPH_MSGR_TAG_BADPROTOVER: dout("process_connect got BADPROTOVER my %d != their %d\n", @@ -1053,7 +1077,7 @@ static int process_connect(struct ceph_connection *con) ENTITY_NAME(con->peer_name), pr_addr(&con->peer_addr.in_addr)); reset_connection(con); - prepare_write_connect_retry(con->msgr, con); + prepare_write_connect(con->msgr, con, 0); prepare_read_connect(con); /* Tell ceph about it. */ @@ -1071,7 +1095,7 @@ static int process_connect(struct ceph_connection *con) le32_to_cpu(con->out_connect.connect_seq), le32_to_cpu(con->in_connect.connect_seq)); con->connect_seq = le32_to_cpu(con->in_connect.connect_seq); - prepare_write_connect_retry(con->msgr, con); + prepare_write_connect(con->msgr, con, 0); prepare_read_connect(con); break; @@ -1080,19 +1104,17 @@ static int process_connect(struct ceph_connection *con) * If we sent a smaller global_seq than the peer has, try * again with a larger value. */ - dout("process_connect got RETRY_GLOBAL my %u, peer_gseq = %u\n", + dout("process_connect got RETRY_GLOBAL my %u peer_gseq %u\n", con->peer_global_seq, le32_to_cpu(con->in_connect.global_seq)); get_global_seq(con->msgr, le32_to_cpu(con->in_connect.global_seq)); - prepare_write_connect_retry(con->msgr, con); + prepare_write_connect(con->msgr, con, 0); prepare_read_connect(con); break; case CEPH_MSGR_TAG_READY: clear_bit(CONNECTING, &con->state); - if (con->in_reply.flags & CEPH_MSG_CONNECT_LOSSY) - set_bit(LOSSYRX, &con->state); con->peer_global_seq = le32_to_cpu(con->in_reply.global_seq); con->connect_seq++; dout("process_connect got READY gseq %d cseq %d (%d)\n", @@ -1420,9 +1442,11 @@ more: if (test_and_clear_bit(STANDBY, &con->state)) con->connect_seq++; - prepare_write_connect(msgr, con); - prepare_read_connect(con); + prepare_write_banner(msgr, con); + prepare_write_connect(msgr, con, 1); + prepare_read_banner(con); set_bit(CONNECTING, &con->state); + clear_bit(NEGOTIATING, &con->state); con->in_tag = CEPH_MSGR_TAG_READY; dout("try_write initiating connect on %p new state %lu\n", @@ -1521,7 +1545,16 @@ more: dout("try_read tag %d in_base_pos %d\n", (int)con->in_tag, con->in_base_pos); if (test_bit(CONNECTING, &con->state)) { - dout("try_read connecting\n"); + if (!test_bit(NEGOTIATING, &con->state)) { + dout("try_read connecting\n"); + ret = read_partial_banner(con); + if (ret <= 0) + goto done; + if (process_banner(con) < 0) { + ret = -1; + goto out; + } + } ret = read_partial_connect(con); if (ret <= 0) goto done; diff --git a/fs/ceph/messenger.h b/fs/ceph/messenger.h index e016fa7..80f7e1e 100644 --- a/fs/ceph/messenger.h +++ b/fs/ceph/messenger.h @@ -104,8 +104,8 @@ struct ceph_msg_pos { * thread is currently opening, reading or writing data to the socket. */ #define LOSSYTX 0 /* we can close channel or drop messages on errors */ -#define LOSSYRX 1 /* peer may reset/drop messages */ -#define CONNECTING 2 +#define CONNECTING 1 +#define NEGOTIATING 2 #define KEEPALIVE_PENDING 3 #define WRITE_PENDING 4 /* we have data ready to send */ #define QUEUED 5 /* there is work queued on this connection */ -- cgit v0.10.2 From cdac830313fa6bf2831693af80fefe4aaac11b7d Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 10 Nov 2009 16:02:23 -0800 Subject: ceph: remove recon_gen logic We don't get an explicit affirmative confirmation that our caps reconnect, nor do we necessarily want to pay that cost. So, take all this code out for now. Signed-off-by: Sage Weil diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 775e6f6..d8132b6 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -610,7 +610,6 @@ retry: cap->issue_seq = seq; cap->mseq = mseq; cap->cap_gen = session->s_cap_gen; - cap->recon_gen = session->s_recon_gen; if (fmode >= 0) __ceph_get_fmode(ci, fmode); @@ -627,21 +626,13 @@ retry: static int __cap_is_valid(struct ceph_cap *cap) { unsigned long ttl; - u32 gen, recon_gen; + u32 gen; spin_lock(&cap->session->s_cap_lock); gen = cap->session->s_cap_gen; - recon_gen = cap->session->s_recon_gen; ttl = cap->session->s_cap_ttl; spin_unlock(&cap->session->s_cap_lock); - if (cap->recon_gen != recon_gen) { - dout("__cap_is_valid %p cap %p issued %s " - "but DEAD (recon_gen %u vs %u)\n", &cap->ci->vfs_inode, - cap, ceph_cap_string(cap->issued), cap->recon_gen, - recon_gen); - return 0; - } if (cap->cap_gen < gen || time_after_eq(jiffies, ttl)) { dout("__cap_is_valid %p cap %p issued %s " "but STALE (gen %u vs %u)\n", &cap->ci->vfs_inode, @@ -2213,7 +2204,6 @@ restart: issued |= implemented | __ceph_caps_dirty(ci); cap->cap_gen = session->s_cap_gen; - cap->recon_gen = session->s_recon_gen; __check_cap_issue(ci, cap, newcaps); diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 828417a..aad10d9 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -329,7 +329,6 @@ static struct ceph_mds_session *register_session(struct ceph_mds_client *mdsc, ceph_con_open(&s->s_con, ceph_mdsmap_get_addr(mdsc->mdsmap, mds)); spin_lock_init(&s->s_cap_lock); - s->s_recon_gen = 0; s->s_cap_gen = 0; s->s_cap_ttl = 0; s->s_renew_requested = 0; @@ -736,25 +735,14 @@ static void remove_session_caps(struct ceph_mds_session *session) static int wake_up_session_cb(struct inode *inode, struct ceph_cap *cap, void *arg) { - struct ceph_mds_session *session = arg; - - spin_lock(&inode->i_lock); - if (cap->recon_gen != session->s_recon_gen) { - pr_err("failed reconnect %p %llx.%llx cap %p " - "(recon_gen %d < session %d)\n", inode, - ceph_vinop(inode), cap, - cap->recon_gen, session->s_recon_gen); - __ceph_remove_cap(cap, NULL); - } wake_up(&ceph_inode(inode)->i_cap_wq); - spin_unlock(&inode->i_lock); return 0; } static void wake_up_session_caps(struct ceph_mds_session *session) { dout("wake_up_session_caps %p mds%d\n", session, session->s_mds); - iterate_session_caps(session, wake_up_session_cb, session); + iterate_session_caps(session, wake_up_session_cb, NULL); } /* @@ -2052,7 +2040,6 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc, int mds) session->s_state = CEPH_MDS_SESSION_RECONNECTING; session->s_seq = 0; - session->s_recon_gen++; ceph_con_open(&session->s_con, ceph_mdsmap_get_addr(mdsc->mdsmap, mds)); diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h index c0846b1..f566e9c 100644 --- a/fs/ceph/mds_client.h +++ b/fs/ceph/mds_client.h @@ -98,8 +98,6 @@ struct ceph_mds_session { u64 s_seq; /* incoming msg seq # */ struct mutex s_mutex; /* serialize session messages */ - int s_recon_gen; /* inc on reconnect to recovered mds */ - struct ceph_connection s_con; /* protected by s_cap_lock */ diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 2579355..06b62c02 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -171,7 +171,6 @@ struct ceph_cap { int mds_wanted; u32 seq, issue_seq, mseq; u32 cap_gen; /* active/stale cycle */ - u32 recon_gen; /* mds restart reconnect cycle */ unsigned long last_used; struct list_head caps_item; }; -- cgit v0.10.2 From 09b8a7d2af83ae96dc052f9708e50140d06a9b6c Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 11 Nov 2009 15:21:27 -0800 Subject: ceph: exclude snapdir from readdir results It was hidden from sync readdir, but not the cached dcache version. Signed-off-by: Sage Weil diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 4f74679..32ef543 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c @@ -131,6 +131,7 @@ more: goto out_unlock; } if (!d_unhashed(dentry) && dentry->d_inode && + ceph_snap(dentry->d_inode) != CEPH_SNAPDIR && filp->f_pos <= di->offset) break; dout(" skipping %p %.*s at %llu (%llu)%s%s\n", dentry, -- cgit v0.10.2 From b377ff13b31778c19203f3089d14080beb40a692 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 11 Nov 2009 15:22:37 -0800 Subject: ceph: initialize i_size/i_rbytes on snapdir Signed-off-by: Sage Weil diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 036873c..074ee42 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -62,6 +62,7 @@ struct inode *ceph_get_snapdir(struct inode *parent) .snap = CEPH_SNAPDIR, }; struct inode *inode = ceph_get_inode(parent->i_sb, vino); + struct ceph_inode_info *ci = ceph_inode(inode); BUG_ON(!S_ISDIR(parent->i_mode)); if (IS_ERR(inode)) @@ -71,7 +72,8 @@ struct inode *ceph_get_snapdir(struct inode *parent) inode->i_gid = parent->i_gid; inode->i_op = &ceph_dir_iops; inode->i_fop = &ceph_dir_fops; - ceph_inode(inode)->i_snap_caps = CEPH_CAP_PIN; /* so we can open */ + ci->i_snap_caps = CEPH_CAP_PIN; /* so we can open */ + ci->i_rbytes = 0; return inode; } -- cgit v0.10.2 From fef320ff8887c702cde7ca6b8dbfff3a341d49fe Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 11 Nov 2009 15:50:12 -0800 Subject: ceph: pr_info when mds reconnect completes This helps the user know what's going on during the (involved) reconnect process. They already see when the mds fails and reconnect starts. Signed-off-by: Sage Weil diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index aad10d9..44cac57 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -2234,6 +2234,7 @@ static void check_new_map(struct ceph_mds_client *mdsc, */ if (oldstate < CEPH_MDS_STATE_ACTIVE && newstate >= CEPH_MDS_STATE_ACTIVE) { + pr_info("mds%d reconnect completed\n", s->s_mds); kick_requests(mdsc, i, 1); ceph_kick_flushing_caps(mdsc, s); } -- cgit v0.10.2 From 039934b895c89c2bb40aa5132efe00e60b70efca Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 12 Nov 2009 15:05:52 -0800 Subject: ceph: build cleanly without CONFIG_DEBUG_FS Signed-off-by: Sage Weil diff --git a/fs/ceph/debugfs.c b/fs/ceph/debugfs.c index 9edbad3..9b20206 100644 --- a/fs/ceph/debugfs.c +++ b/fs/ceph/debugfs.c @@ -8,6 +8,8 @@ #include "super.h" #include "mds_client.h" +#ifdef CONFIG_DEBUG_FS + /* * Implement /sys/kernel/debug/ceph fun * @@ -423,3 +425,24 @@ void ceph_debugfs_client_cleanup(struct ceph_client *client) debugfs_remove(client->debugfs_dir); } +#else // CONFIG_DEBUG_FS + +int __init ceph_debugfs_init(void) +{ + return 0; +} + +void ceph_debugfs_cleanup(void) +{ +} + +int ceph_debugfs_client_init(struct ceph_client *client) +{ + return 0; +} + +void ceph_debugfs_client_cleanup(struct ceph_client *client) +{ +} + +#endif // CONFIG_DEBUG_FS diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h index f566e9c..0751b82 100644 --- a/fs/ceph/mds_client.h +++ b/fs/ceph/mds_client.h @@ -256,7 +256,9 @@ struct ceph_mds_client { spinlock_t cap_dirty_lock; /* protects above items */ wait_queue_head_t cap_flushing_wq; +#ifdef CONFIG_DEBUG_FS struct dentry *debugfs_file; +#endif spinlock_t dentry_lru_lock; struct list_head dentry_lru; diff --git a/fs/ceph/mon_client.h b/fs/ceph/mon_client.h index 5258c56..9f6db45 100644 --- a/fs/ceph/mon_client.h +++ b/fs/ceph/mon_client.h @@ -78,7 +78,9 @@ struct ceph_mon_client { int want_next_osdmap; /* 1 = want, 2 = want+asked */ u32 have_osdmap, have_mdsmap; +#ifdef CONFIG_DEBUG_FS struct dentry *debugfs_file; +#endif }; extern struct ceph_monmap *ceph_monmap_decode(void *p, void *end); diff --git a/fs/ceph/osd_client.h b/fs/ceph/osd_client.h index 9a4addf..766c8dc 100644 --- a/fs/ceph/osd_client.h +++ b/fs/ceph/osd_client.h @@ -83,7 +83,9 @@ struct ceph_osd_client { struct rb_root requests; /* pending requests */ int num_requests; struct delayed_work timeout_work; +#ifdef CONFIG_DEBUG_FS struct dentry *debugfs_file; +#endif mempool_t *req_mempool; diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 06b62c02..8aa1ffb 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -112,9 +112,11 @@ static inline unsigned long time_sub(unsigned long a, unsigned long b) */ struct ceph_client { __s64 whoami; /* my client number */ +#ifdef CONFIG_DEBUG_FS struct dentry *debugfs_monmap; struct dentry *debugfs_mdsmap, *debugfs_osdmap; struct dentry *debugfs_dir, *debugfs_dentry_lru, *debugfs_caps; +#endif struct mutex mount_mutex; /* serialize mount attempts */ struct ceph_mount_args *mount_args; -- cgit v0.10.2 From 11ea8eda064aa4dc6e44a6dade1891b69ebd5255 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 12 Nov 2009 15:07:24 -0800 Subject: ceph: fix page invalidation deadlock We occasionally want to make a best-effort attempt to invalidate cache pages without fear of blocking. If this fails, we fall back to an async invalidate in another thread. Use invalidate_mapping_pages instead of invalidate_inode_page2, as that will skip locked pages, and not deadlock. Signed-off-by: Sage Weil diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index d8132b6..9dd1106 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -1440,7 +1440,7 @@ retry_locked: dout("check_caps trying to invalidate on %p\n", inode); spin_unlock(&inode->i_lock); - ret = invalidate_inode_pages2(&inode->i_data); + ret = invalidate_mapping_pages(&inode->i_data, 0, -1); spin_lock(&inode->i_lock); if (ret == 0 && invalidating_gen == ci->i_rdcache_gen) { /* success. */ @@ -2180,7 +2180,7 @@ restart: spin_unlock(&inode->i_lock); tried_invalidate = 1; - ret = invalidate_inode_pages2(&inode->i_data); + ret = invalidate_mapping_pages(&inode->i_data, 0, -1); spin_lock(&inode->i_lock); if (ret < 0) { /* there were locked pages.. invalidate later -- cgit v0.10.2 From 42ce56e50d948fc7c1c8c3a749ee5a21a7e134f6 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 18 Nov 2009 11:22:36 -0800 Subject: ceph: remove bad calls to ceph_con_shutdown We want to ceph_con_close when we're done with the connection, before the ref count reaches 0. Once it does, do not call ceph_con_shutdown, as that takes the con mutex and may sleep, and besides that is unnecessary. Signed-off-by: Sage Weil diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 44cac57..fdecf99 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -274,10 +274,8 @@ void ceph_put_mds_session(struct ceph_mds_session *s) { dout("mdsc put_session %p %d -> %d\n", s, atomic_read(&s->s_ref), atomic_read(&s->s_ref)-1); - if (atomic_dec_and_test(&s->s_ref)) { - ceph_con_shutdown(&s->s_con); + if (atomic_dec_and_test(&s->s_ref)) kfree(s); - } } /* @@ -326,7 +324,6 @@ static struct ceph_mds_session *register_session(struct ceph_mds_client *mdsc, s->s_con.ops = &mds_con_ops; s->s_con.peer_name.type = CEPH_ENTITY_TYPE_MDS; s->s_con.peer_name.num = cpu_to_le64(mds); - ceph_con_open(&s->s_con, ceph_mdsmap_get_addr(mdsc->mdsmap, mds)); spin_lock_init(&s->s_cap_lock); s->s_cap_gen = 0; @@ -352,7 +349,7 @@ static struct ceph_mds_session *register_session(struct ceph_mds_client *mdsc, dout("register_session realloc to %d\n", newmax); sa = kcalloc(newmax, sizeof(void *), GFP_NOFS); if (sa == NULL) - return ERR_PTR(-ENOMEM); + goto fail_realloc; if (mdsc->sessions) { memcpy(sa, mdsc->sessions, mdsc->max_sessions * sizeof(void *)); @@ -363,17 +360,26 @@ static struct ceph_mds_session *register_session(struct ceph_mds_client *mdsc, } mdsc->sessions[mds] = s; atomic_inc(&s->s_ref); /* one ref to sessions[], one to caller */ + + ceph_con_open(&s->s_con, ceph_mdsmap_get_addr(mdsc->mdsmap, mds)); + return s; + +fail_realloc: + kfree(s); + return ERR_PTR(-ENOMEM); } /* * called under mdsc->mutex */ -static void unregister_session(struct ceph_mds_client *mdsc, int mds) +static void unregister_session(struct ceph_mds_client *mdsc, + struct ceph_mds_session *s) { - dout("unregister_session mds%d %p\n", mds, mdsc->sessions[mds]); - ceph_put_mds_session(mdsc->sessions[mds]); - mdsc->sessions[mds] = NULL; + dout("unregister_session mds%d %p\n", s->s_mds, s); + mdsc->sessions[s->s_mds] = NULL; + ceph_con_close(&s->s_con); + ceph_put_mds_session(s); } /* @@ -1870,7 +1876,7 @@ static void handle_session(struct ceph_mds_session *session, break; case CEPH_SESSION_CLOSE: - unregister_session(mdsc, mds); + unregister_session(mdsc, session); remove_session_caps(session); wake = 1; /* for good measure */ complete(&mdsc->session_close_waiters); @@ -2199,7 +2205,7 @@ static void check_new_map(struct ceph_mds_client *mdsc, /* the session never opened, just close it * out now */ __wake_requests(mdsc, &s->s_waiting); - unregister_session(mdsc, i); + unregister_session(mdsc, s); } else { /* just close it */ mutex_unlock(&mdsc->mutex); @@ -2724,7 +2730,7 @@ void ceph_mdsc_close_sessions(struct ceph_mds_client *mdsc) for (i = 0; i < mdsc->max_sessions; i++) { if (mdsc->sessions[i]) { session = get_session(mdsc->sessions[i]); - unregister_session(mdsc, i); + unregister_session(mdsc, session); mutex_unlock(&mdsc->mutex); mutex_lock(&session->s_mutex); remove_session_caps(session); diff --git a/fs/ceph/messenger.h b/fs/ceph/messenger.h index 80f7e1e..4bd85c3 100644 --- a/fs/ceph/messenger.h +++ b/fs/ceph/messenger.h @@ -212,7 +212,6 @@ extern void ceph_messenger_destroy(struct ceph_messenger *); extern void ceph_con_init(struct ceph_messenger *msgr, struct ceph_connection *con); -extern void ceph_con_shutdown(struct ceph_connection *con); extern void ceph_con_open(struct ceph_connection *con, struct ceph_entity_addr *addr); extern void ceph_con_close(struct ceph_connection *con); diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index 7db14ba..bcb9fe6 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -350,10 +350,8 @@ static void put_osd(struct ceph_osd *osd) { dout("put_osd %p %d -> %d\n", osd, atomic_read(&osd->o_ref), atomic_read(&osd->o_ref) - 1); - if (atomic_dec_and_test(&osd->o_ref)) { - ceph_con_shutdown(&osd->o_con); + if (atomic_dec_and_test(&osd->o_ref)) kfree(osd); - } } /* -- cgit v0.10.2 From 71ececdacae24be333c534869cb1b06357f0e215 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 18 Nov 2009 11:27:06 -0800 Subject: ceph: remove unnecessary ceph_con_shutdown We require that ceph_con_close be called before we drop the connection, so this is unneeded. Just BUG if con->sock != NULL. Signed-off-by: Sage Weil diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index e389656..d8a6a56 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -340,17 +340,6 @@ void ceph_con_close(struct ceph_connection *con) } /* - * clean up connection state - */ -void ceph_con_shutdown(struct ceph_connection *con) -{ - dout("con_shutdown %p\n", con); - reset_connection(con); - set_bit(DEAD, &con->state); - con_close_socket(con); /* silently ignore errors */ -} - -/* * Reopen a closed connection, with a new peer address. */ void ceph_con_open(struct ceph_connection *con, struct ceph_entity_addr *addr) @@ -380,7 +369,7 @@ void ceph_con_put(struct ceph_connection *con) atomic_read(&con->nref), atomic_read(&con->nref) - 1); BUG_ON(atomic_read(&con->nref) == 0); if (atomic_dec_and_test(&con->nref)) { - ceph_con_shutdown(con); + BUG_ON(con->sock); kfree(con); } } -- cgit v0.10.2 From 5f44f142601bf94c448e2d463f0f18fd159da164 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 18 Nov 2009 14:52:18 -0800 Subject: ceph: handle errors during osd client init Unwind initializing if we get ENOMEM during client initialization. Signed-off-by: Sage Weil diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index fdecf99..69feeb1 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -2552,7 +2552,7 @@ static void delayed_work(struct work_struct *work) } -void ceph_mdsc_init(struct ceph_mds_client *mdsc, struct ceph_client *client) +int ceph_mdsc_init(struct ceph_mds_client *mdsc, struct ceph_client *client) { mdsc->client = client; mutex_init(&mdsc->mutex); @@ -2582,6 +2582,7 @@ void ceph_mdsc_init(struct ceph_mds_client *mdsc, struct ceph_client *client) init_waitqueue_head(&mdsc->cap_flushing_wq); spin_lock_init(&mdsc->dentry_lru_lock); INIT_LIST_HEAD(&mdsc->dentry_lru); + return 0; } /* diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h index 0751b82..7c43948 100644 --- a/fs/ceph/mds_client.h +++ b/fs/ceph/mds_client.h @@ -282,7 +282,7 @@ extern void ceph_put_mds_session(struct ceph_mds_session *s); extern int ceph_send_msg_mds(struct ceph_mds_client *mdsc, struct ceph_msg *msg, int mds); -extern void ceph_mdsc_init(struct ceph_mds_client *mdsc, +extern int ceph_mdsc_init(struct ceph_mds_client *mdsc, struct ceph_client *client); extern void ceph_mdsc_close_sessions(struct ceph_mds_client *mdsc); extern void ceph_mdsc_stop(struct ceph_mds_client *mdsc); diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index bcb9fe6..0a16c4f 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -1127,19 +1127,26 @@ int ceph_osdc_init(struct ceph_osd_client *osdc, struct ceph_client *client) osdc->num_requests = 0; INIT_DELAYED_WORK(&osdc->timeout_work, handle_timeout); + err = -ENOMEM; osdc->req_mempool = mempool_create_kmalloc_pool(10, sizeof(struct ceph_osd_request)); if (!osdc->req_mempool) - return -ENOMEM; + goto out; err = ceph_msgpool_init(&osdc->msgpool_op, 4096, 10, true); if (err < 0) - return -ENOMEM; + goto out_mempool; err = ceph_msgpool_init(&osdc->msgpool_op_reply, 512, 0, false); if (err < 0) - return -ENOMEM; - + goto out_msgpool; return 0; + +out_msgpool: + ceph_msgpool_destroy(&osdc->msgpool_op); +out_mempool: + mempool_destroy(osdc->req_mempool); +out: + return err; } void ceph_osdc_stop(struct ceph_osd_client *osdc) diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 1ac7b07..fe0a596 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -530,9 +530,13 @@ static struct ceph_client *ceph_create_client(struct ceph_mount_args *args) err = ceph_osdc_init(&client->osdc, client); if (err < 0) goto fail_monc; - ceph_mdsc_init(&client->mdsc, client); + err = ceph_mdsc_init(&client->mdsc, client); + if (err < 0) + goto fail_osdc; return client; +fail_osdc: + ceph_osdc_stop(&client->osdc); fail_monc: ceph_monc_stop(&client->monc); fail_trunc_wq: -- cgit v0.10.2 From 4e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bc Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 18 Nov 2009 16:19:57 -0800 Subject: ceph: negotiate authentication protocol; implement AUTH_NONE protocol When we open a monitor session, we send an initial AUTH message listing the auth protocols we support, our entity name, and (possibly) a previously assigned global_id. The monitor chooses a protocol and responds with an initial message. Initially implement AUTH_NONE, a dummy protocol that provides no security, but works within the new framework. It generates 'authorizers' that are used when connecting to (mds, osd) services that simply state our entity name and global_id. This is a wire protocol change. Signed-off-by: Sage Weil diff --git a/fs/ceph/Makefile b/fs/ceph/Makefile index bdd3e6f..827629c8 100644 --- a/fs/ceph/Makefile +++ b/fs/ceph/Makefile @@ -13,6 +13,7 @@ ceph-objs := super.o inode.o dir.o file.o addr.o ioctl.o \ mon_client.o \ osd_client.o osdmap.o crush/crush.o crush/mapper.o crush/hash.o \ debugfs.o \ + auth.o auth_none.o \ ceph_fs.o ceph_strings.o ceph_hash.o ceph_frag.o else diff --git a/fs/ceph/auth.c b/fs/ceph/auth.c new file mode 100644 index 0000000..c4d1eee --- /dev/null +++ b/fs/ceph/auth.c @@ -0,0 +1,220 @@ +#include "ceph_debug.h" + +#include +#include + +#include "types.h" +#include "auth_none.h" +#include "decode.h" +#include "super.h" + +#include "messenger.h" + +/* + * get protocol handler + */ +static u32 supported_protocols[] = { + CEPH_AUTH_NONE +}; + +int ceph_auth_init_protocol(struct ceph_auth_client *ac, int protocol) +{ + switch (protocol) { + case CEPH_AUTH_NONE: + return ceph_auth_none_init(ac); + default: + return -ENOENT; + } +} + +/* + * setup, teardown. + */ +struct ceph_auth_client *ceph_auth_init(const char *name, const char *secret) +{ + struct ceph_auth_client *ac; + int ret; + + dout("auth_init name '%s' secret '%s'\n", name, secret); + + ret = -ENOMEM; + ac = kzalloc(sizeof(*ac), GFP_NOFS); + if (!ac) + goto out; + + ac->negotiating = true; + if (name) + ac->name = name; + else + ac->name = CEPH_AUTH_NAME_DEFAULT; + dout("auth_init name %s secret %s\n", ac->name, secret); + ac->secret = secret; + return ac; + +out: + return ERR_PTR(ret); +} + +void ceph_auth_destroy(struct ceph_auth_client *ac) +{ + dout("auth_destroy %p\n", ac); + if (ac->ops) + ac->ops->destroy(ac); + kfree(ac); +} + +/* + * Reset occurs when reconnecting to the monitor. + */ +void ceph_auth_reset(struct ceph_auth_client *ac) +{ + dout("auth_reset %p\n", ac); + if (ac->ops && !ac->negotiating) + ac->ops->reset(ac); + ac->negotiating = true; +} + +int ceph_entity_name_encode(const char *name, void **p, void *end) +{ + int len = strlen(name); + + if (*p + 2*sizeof(u32) + len > end) + return -ERANGE; + ceph_encode_32(p, CEPH_ENTITY_TYPE_CLIENT); + ceph_encode_32(p, len); + ceph_encode_copy(p, name, len); + return 0; +} + +/* + * Initiate protocol negotiation with monitor. Include entity name + * and list supported protocols. + */ +int ceph_auth_build_hello(struct ceph_auth_client *ac, void *buf, size_t len) +{ + struct ceph_mon_request_header *monhdr = buf; + void *p = monhdr + 1, *end = buf + len, *lenp; + int i, num; + int ret; + + dout("auth_build_hello\n"); + monhdr->have_version = 0; + monhdr->session_mon = cpu_to_le16(-1); + monhdr->session_mon_tid = 0; + + ceph_encode_32(&p, 0); /* no protocol, yet */ + + lenp = p; + p += sizeof(u32); + + num = ARRAY_SIZE(supported_protocols); + ceph_encode_32(&p, num); + for (i = 0; i < num; i++) + ceph_encode_32(&p, supported_protocols[i]); + + ret = ceph_entity_name_encode(ac->name, &p, end); + if (ret < 0) + return ret; + ceph_decode_need(&p, end, sizeof(u64), bad); + ceph_encode_64(&p, ac->global_id); + + ceph_encode_32(&lenp, p - lenp - sizeof(u32)); + return p - buf; + +bad: + return -ERANGE; +} + +/* + * Handle auth message from monitor. + */ +int ceph_handle_auth_reply(struct ceph_auth_client *ac, + void *buf, size_t len, + void *reply_buf, size_t reply_len) +{ + void *p = buf; + void *end = buf + len; + int protocol; + s32 result; + u64 global_id; + void *payload, *payload_end; + int payload_len; + char *result_msg; + int result_msg_len; + int ret = -EINVAL; + + dout("handle_auth_reply %p %p\n", p, end); + ceph_decode_need(&p, end, sizeof(u32) * 3 + sizeof(u64), bad); + protocol = ceph_decode_32(&p); + result = ceph_decode_32(&p); + global_id = ceph_decode_64(&p); + payload_len = ceph_decode_32(&p); + payload = p; + p += payload_len; + ceph_decode_need(&p, end, sizeof(u32), bad); + result_msg_len = ceph_decode_32(&p); + result_msg = p; + p += result_msg_len; + if (p != end) + goto bad; + + dout(" result %d '%.*s' gid %llu len %d\n", result, result_msg_len, + result_msg, global_id, payload_len); + + payload_end = payload + payload_len; + + if (global_id && ac->global_id != global_id) { + dout(" set global_id %lld -> %lld\n", ac->global_id, global_id); + ac->global_id = global_id; + } + + if (ac->negotiating) { + /* set up (new) protocol handler? */ + if (ac->protocol && ac->protocol != protocol) { + ac->ops->destroy(ac); + ac->protocol = 0; + ac->ops = NULL; + } + if (ac->protocol != protocol) { + ret = ceph_auth_init_protocol(ac, protocol); + if (ret) { + pr_err("error %d on auth protocol %d init\n", + ret, protocol); + goto out; + } + } + } + + ret = ac->ops->handle_reply(ac, result, payload, payload_end); + if (ret == -EAGAIN) { + struct ceph_mon_request_header *monhdr = reply_buf; + void *p = reply_buf + 1; + void *end = reply_buf + reply_len; + + monhdr->have_version = 0; + monhdr->session_mon = cpu_to_le16(-1); + monhdr->session_mon_tid = 0; + + ceph_encode_32(&p, ac->protocol); + + ret = ac->ops->build_request(ac, p + sizeof(u32), end); + if (ret < 0) { + pr_err("error %d building request\n", ret); + goto out; + } + dout(" built request %d bytes\n", ret); + ceph_encode_32(&p, ret); + return p + ret - reply_buf; + } else if (ret) { + pr_err("authentication error %d\n", ret); + return ret; + } + return 0; + +bad: + pr_err("failed to decode auth msg\n"); +out: + return ret; +} + + diff --git a/fs/ceph/auth.h b/fs/ceph/auth.h new file mode 100644 index 0000000..4d8cdf6 --- /dev/null +++ b/fs/ceph/auth.h @@ -0,0 +1,77 @@ +#ifndef _FS_CEPH_AUTH_H +#define _FS_CEPH_AUTH_H + +#include "types.h" +#include "buffer.h" + +/* + * Abstract interface for communicating with the authenticate module. + * There is some handshake that takes place between us and the monitor + * to acquire the necessary keys. These are used to generate an + * 'authorizer' that we use when connecting to a service (mds, osd). + */ + +struct ceph_auth_client; +struct ceph_authorizer; + +struct ceph_auth_client_ops { + /* + * true if we are authenticated and can connect to + * services. + */ + int (*is_authenticated)(struct ceph_auth_client *ac); + + /* + * build requests and process replies during monitor + * handshake. if handle_reply returns -EAGAIN, we build + * another request. + */ + int (*build_request)(struct ceph_auth_client *ac, void *buf, void *end); + int (*handle_reply)(struct ceph_auth_client *ac, int result, + void *buf, void *end); + + /* + * Create authorizer for connecting to a service, and verify + * the response to authenticate the service. + */ + int (*create_authorizer)(struct ceph_auth_client *ac, int peer_type, + struct ceph_authorizer **a, + void **buf, size_t *len, + void **reply_buf, size_t *reply_len); + int (*verify_authorizer_reply)(struct ceph_auth_client *ac, + struct ceph_authorizer *a, size_t len); + void (*destroy_authorizer)(struct ceph_auth_client *ac, + struct ceph_authorizer *a); + + /* reset when we (re)connect to a monitor */ + void (*reset)(struct ceph_auth_client *ac); + + void (*destroy)(struct ceph_auth_client *ac); +}; + +struct ceph_auth_client { + u32 protocol; /* CEPH_AUTH_* */ + void *private; /* for use by protocol implementation */ + const struct ceph_auth_client_ops *ops; /* null iff protocol==0 */ + + bool negotiating; /* true if negotiating protocol */ + const char *name; /* entity name */ + u64 global_id; /* our unique id in system */ + const char *secret; /* our secret key */ + unsigned want_keys; /* which services we want */ +}; + +extern struct ceph_auth_client *ceph_auth_init(const char *name, + const char *secret); +extern void ceph_auth_destroy(struct ceph_auth_client *ac); + +extern void ceph_auth_reset(struct ceph_auth_client *ac); + +extern int ceph_auth_build_hello(struct ceph_auth_client *ac, + void *buf, size_t len); +extern int ceph_handle_auth_reply(struct ceph_auth_client *ac, + void *buf, size_t len, + void *reply_buf, size_t reply_len); +extern int ceph_entity_name_encode(const char *name, void **p, void *end); + +#endif diff --git a/fs/ceph/auth_none.c b/fs/ceph/auth_none.c new file mode 100644 index 0000000..631017e --- /dev/null +++ b/fs/ceph/auth_none.c @@ -0,0 +1,120 @@ + +#include "ceph_debug.h" + +#include +#include +#include + +#include "auth_none.h" +#include "auth.h" +#include "decode.h" + +static void reset(struct ceph_auth_client *ac) +{ + struct ceph_auth_none_info *xi = ac->private; + + xi->starting = true; + xi->built_authorizer = false; +} + +static void destroy(struct ceph_auth_client *ac) +{ + kfree(ac->private); + ac->private = NULL; +} + +static int is_authenticated(struct ceph_auth_client *ac) +{ + struct ceph_auth_none_info *xi = ac->private; + + return !xi->starting; +} + +/* + * the generic auth code decode the global_id, and we carry no actual + * authenticate state, so nothing happens here. + */ +static int handle_reply(struct ceph_auth_client *ac, int result, + void *buf, void *end) +{ + struct ceph_auth_none_info *xi = ac->private; + + xi->starting = false; + return result; +} + +/* + * build an 'authorizer' with our entity_name and global_id. we can + * reuse a single static copy since it is identical for all services + * we connect to. + */ +static int ceph_auth_none_create_authorizer( + struct ceph_auth_client *ac, int peer_type, + struct ceph_authorizer **a, + void **buf, size_t *len, + void **reply_buf, size_t *reply_len) +{ + struct ceph_auth_none_info *ai = ac->private; + struct ceph_none_authorizer *au = &ai->au; + void *p, *end; + int ret; + + if (!ai->built_authorizer) { + p = au->buf; + end = p + sizeof(au->buf); + ret = ceph_entity_name_encode(ac->name, &p, end - 8); + if (ret < 0) + goto bad; + ceph_decode_need(&p, end, sizeof(u64), bad2); + ceph_encode_64(&p, ac->global_id); + au->buf_len = p - (void *)au->buf; + ai->built_authorizer = true; + dout("built authorizer len %d\n", au->buf_len); + } + + *a = (struct ceph_authorizer *)au; + *buf = au->buf; + *len = au->buf_len; + *reply_buf = au->reply_buf; + *reply_len = sizeof(au->reply_buf); + return 0; + +bad2: + ret = -ERANGE; +bad: + return ret; +} + +static void ceph_auth_none_destroy_authorizer(struct ceph_auth_client *ac, + struct ceph_authorizer *a) +{ + /* nothing to do */ +} + +static const struct ceph_auth_client_ops ceph_auth_none_ops = { + .reset = reset, + .destroy = destroy, + .is_authenticated = is_authenticated, + .handle_reply = handle_reply, + .create_authorizer = ceph_auth_none_create_authorizer, + .destroy_authorizer = ceph_auth_none_destroy_authorizer, +}; + +int ceph_auth_none_init(struct ceph_auth_client *ac) +{ + struct ceph_auth_none_info *xi; + + dout("ceph_auth_none_init %p\n", ac); + xi = kzalloc(sizeof(*xi), GFP_NOFS); + if (!xi) + return -ENOMEM; + + xi->starting = true; + xi->built_authorizer = false; + + ac->protocol = CEPH_AUTH_NONE; + ac->private = xi; + ac->ops = &ceph_auth_none_ops; + return 0; +} + diff --git a/fs/ceph/auth_none.h b/fs/ceph/auth_none.h new file mode 100644 index 0000000..56c0553 --- /dev/null +++ b/fs/ceph/auth_none.h @@ -0,0 +1,28 @@ +#ifndef _FS_CEPH_AUTH_NONE_H +#define _FS_CEPH_AUTH_NONE_H + +#include "auth.h" + +/* + * null security mode. + * + * we use a single static authorizer that simply encodes our entity name + * and global id. + */ + +struct ceph_none_authorizer { + char buf[128]; + int buf_len; + char reply_buf[0]; +}; + +struct ceph_auth_none_info { + bool starting; + bool built_authorizer; + struct ceph_none_authorizer au; /* we only need one; it's static */ +}; + +extern int ceph_auth_none_init(struct ceph_auth_client *ac); + +#endif + diff --git a/fs/ceph/ceph_fs.h b/fs/ceph/ceph_fs.h index 36becb0..1e96a9a 100644 --- a/fs/ceph/ceph_fs.h +++ b/fs/ceph/ceph_fs.h @@ -75,6 +75,16 @@ struct ceph_file_layout { int ceph_file_layout_is_valid(const struct ceph_file_layout *layout); +/* crypto algorithms */ +#define CEPH_CRYPTO_NONE 0x0 +#define CEPH_CRYPTO_AES 0x1 + +/* security/authentication protocols */ +#define CEPH_AUTH_UNKNOWN 0x0 +#define CEPH_AUTH_NONE 0x1 +#define CEPH_AUTH_CEPHX 0x2 + + /********************************************* * message layer */ @@ -90,12 +100,12 @@ int ceph_file_layout_is_valid(const struct ceph_file_layout *layout); /* client <-> monitor */ #define CEPH_MSG_MON_MAP 4 #define CEPH_MSG_MON_GET_MAP 5 -#define CEPH_MSG_CLIENT_MOUNT 10 -#define CEPH_MSG_CLIENT_MOUNT_ACK 11 #define CEPH_MSG_STATFS 13 #define CEPH_MSG_STATFS_REPLY 14 #define CEPH_MSG_MON_SUBSCRIBE 15 #define CEPH_MSG_MON_SUBSCRIBE_ACK 16 +#define CEPH_MSG_AUTH 17 +#define CEPH_MSG_AUTH_REPLY 18 /* client <-> mds */ #define CEPH_MSG_MDS_MAP 21 diff --git a/fs/ceph/ceph_strings.c b/fs/ceph/ceph_strings.c index 90d19d9..8e4be6a 100644 --- a/fs/ceph/ceph_strings.c +++ b/fs/ceph/ceph_strings.c @@ -3,6 +3,19 @@ */ #include "types.h" +const char *ceph_entity_type_name(int type) +{ + switch (type) { + case CEPH_ENTITY_TYPE_MDS: return "mds"; + case CEPH_ENTITY_TYPE_OSD: return "osd"; + case CEPH_ENTITY_TYPE_MON: return "mon"; + case CEPH_ENTITY_TYPE_CLIENT: return "client"; + case CEPH_ENTITY_TYPE_ADMIN: return "admin"; + case CEPH_ENTITY_TYPE_AUTH: return "auth"; + default: return "unknown"; + } +} + const char *ceph_osd_op_name(int op) { switch (op) { diff --git a/fs/ceph/decode.h b/fs/ceph/decode.h index a382aec..10de848 100644 --- a/fs/ceph/decode.h +++ b/fs/ceph/decode.h @@ -98,6 +98,7 @@ static inline void ceph_encode_addr(struct ceph_entity_addr *a) static inline void ceph_decode_addr(struct ceph_entity_addr *a) { a->in_addr.ss_family = ntohs(a->in_addr.ss_family); + WARN_ON(a->in_addr.ss_family == 512); } /* @@ -123,6 +124,11 @@ static inline void ceph_encode_8(void **p, u8 v) *(u8 *)*p = v; (*p)++; } +static inline void ceph_encode_copy(void **p, const void *s, int len) +{ + memcpy(*p, s, len); + *p += len; +} /* * filepath, string encoders diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 69feeb1..8a28515 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -8,6 +8,7 @@ #include "super.h" #include "messenger.h" #include "decode.h" +#include "auth.h" /* * A cluster of MDS (metadata server) daemons is responsible for @@ -274,8 +275,12 @@ void ceph_put_mds_session(struct ceph_mds_session *s) { dout("mdsc put_session %p %d -> %d\n", s, atomic_read(&s->s_ref), atomic_read(&s->s_ref)-1); - if (atomic_dec_and_test(&s->s_ref)) + if (atomic_dec_and_test(&s->s_ref)) { + if (s->s_authorizer) + s->s_mdsc->client->monc.auth->ops->destroy_authorizer( + s->s_mdsc->client->monc.auth, s->s_authorizer); kfree(s); + } } /* @@ -2777,9 +2782,15 @@ void ceph_mdsc_handle_map(struct ceph_mds_client *mdsc, struct ceph_msg *msg) ceph_decode_need(&p, end, sizeof(fsid)+2*sizeof(u32), bad); ceph_decode_copy(&p, &fsid, sizeof(fsid)); - if (ceph_fsid_compare(&fsid, &mdsc->client->monc.monmap->fsid)) { - pr_err("got mdsmap with wrong fsid\n"); - return; + if (mdsc->client->monc.have_fsid) { + if (ceph_fsid_compare(&fsid, + &mdsc->client->monc.monmap->fsid)) { + pr_err("got mdsmap with wrong fsid\n"); + return; + } + } else { + ceph_fsid_set(&mdsc->client->monc.monmap->fsid, &fsid); + mdsc->client->monc.have_fsid = true; } epoch = ceph_decode_32(&p); maplen = ceph_decode_32(&p); @@ -2895,10 +2906,60 @@ static void dispatch(struct ceph_connection *con, struct ceph_msg *msg) ceph_msg_put(msg); } +/* + * authentication + */ +static int get_authorizer(struct ceph_connection *con, + void **buf, int *len, int *proto, + void **reply_buf, int *reply_len, int force_new) +{ + struct ceph_mds_session *s = con->private; + struct ceph_mds_client *mdsc = s->s_mdsc; + struct ceph_auth_client *ac = mdsc->client->monc.auth; + int ret = 0; + + if (force_new && s->s_authorizer) { + ac->ops->destroy_authorizer(ac, s->s_authorizer); + s->s_authorizer = NULL; + } + if (s->s_authorizer == NULL) { + if (ac->ops->create_authorizer) { + ret = ac->ops->create_authorizer( + ac, CEPH_ENTITY_TYPE_MDS, + &s->s_authorizer, + &s->s_authorizer_buf, + &s->s_authorizer_buf_len, + &s->s_authorizer_reply_buf, + &s->s_authorizer_reply_buf_len); + if (ret) + return ret; + } + } + + *proto = ac->protocol; + *buf = s->s_authorizer_buf; + *len = s->s_authorizer_buf_len; + *reply_buf = s->s_authorizer_reply_buf; + *reply_len = s->s_authorizer_reply_buf_len; + return 0; +} + + +static int verify_authorizer_reply(struct ceph_connection *con, int len) +{ + struct ceph_mds_session *s = con->private; + struct ceph_mds_client *mdsc = s->s_mdsc; + struct ceph_auth_client *ac = mdsc->client->monc.auth; + + return ac->ops->verify_authorizer_reply(ac, s->s_authorizer, len); +} + const static struct ceph_connection_operations mds_con_ops = { .get = con_get, .put = con_put, .dispatch = dispatch, + .get_authorizer = get_authorizer, + .verify_authorizer_reply = verify_authorizer_reply, .peer_reset = peer_reset, .alloc_msg = ceph_alloc_msg, .alloc_middle = ceph_alloc_middle, diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h index 7c43948..9faa1b2 100644 --- a/fs/ceph/mds_client.h +++ b/fs/ceph/mds_client.h @@ -100,6 +100,10 @@ struct ceph_mds_session { struct ceph_connection s_con; + struct ceph_authorizer *s_authorizer; + void *s_authorizer_buf, *s_authorizer_reply_buf; + size_t s_authorizer_buf_len, s_authorizer_reply_buf_len; + /* protected by s_cap_lock */ spinlock_t s_cap_lock; u32 s_cap_gen; /* inc each time we get mds stale msg */ diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index d8a6a56..0b16748 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -550,6 +550,27 @@ static void prepare_write_keepalive(struct ceph_connection *con) * Connection negotiation. */ +static void prepare_connect_authorizer(struct ceph_connection *con) +{ + void *auth_buf; + int auth_len = 0; + int auth_protocol = 0; + + if (con->ops->get_authorizer) + con->ops->get_authorizer(con, &auth_buf, &auth_len, + &auth_protocol, &con->auth_reply_buf, + &con->auth_reply_buf_len, + con->auth_retry); + + con->out_connect.authorizer_protocol = cpu_to_le32(auth_protocol); + con->out_connect.authorizer_len = cpu_to_le32(auth_len); + + con->out_kvec[con->out_kvec_left].iov_base = auth_buf; + con->out_kvec[con->out_kvec_left].iov_len = auth_len; + con->out_kvec_left++; + con->out_kvec_bytes += auth_len; +} + /* * We connected to a peer and are saying hello. */ @@ -592,6 +613,7 @@ static void prepare_write_connect(struct ceph_messenger *msgr, dout("prepare_write_connect %p cseq=%d gseq=%d proto=%d\n", con, con->connect_seq, global_seq, proto); + con->out_connect.host_type = cpu_to_le32(CEPH_ENTITY_TYPE_CLIENT); con->out_connect.connect_seq = cpu_to_le32(con->connect_seq); con->out_connect.global_seq = cpu_to_le32(global_seq); @@ -611,6 +633,8 @@ static void prepare_write_connect(struct ceph_messenger *msgr, con->out_kvec_cur = con->out_kvec; con->out_more = 0; set_bit(WRITE_PENDING, &con->state); + + prepare_connect_authorizer(con); } @@ -777,6 +801,13 @@ static void prepare_read_connect(struct ceph_connection *con) con->in_base_pos = 0; } +static void prepare_read_connect_retry(struct ceph_connection *con) +{ + dout("prepare_read_connect_retry %p\n", con); + con->in_base_pos = strlen(CEPH_BANNER) + sizeof(con->actual_peer_addr) + + sizeof(con->peer_addr_for_me); +} + static void prepare_read_ack(struct ceph_connection *con) { dout("prepare_read_ack %p\n", con); @@ -853,9 +884,14 @@ static int read_partial_connect(struct ceph_connection *con) ret = read_partial(con, &to, sizeof(con->in_reply), &con->in_reply); if (ret <= 0) goto out; + ret = read_partial(con, &to, le32_to_cpu(con->in_reply.authorizer_len), + con->auth_reply_buf); + if (ret <= 0) + goto out; - dout("read_partial_connect %p connect_seq = %u, global_seq = %u\n", - con, le32_to_cpu(con->in_reply.connect_seq), + dout("read_partial_connect %p tag %d, con_seq = %u, g_seq = %u\n", + con, (int)con->in_reply.tag, + le32_to_cpu(con->in_reply.connect_seq), le32_to_cpu(con->in_reply.global_seq)); out: return ret; @@ -1051,6 +1087,20 @@ static int process_connect(struct ceph_connection *con) set_bit(CLOSED, &con->state); /* in case there's queued work */ return -1; + case CEPH_MSGR_TAG_BADAUTHORIZER: + con->auth_retry++; + dout("process_connect %p got BADAUTHORIZER attempt %d\n", con, + con->auth_retry); + if (con->auth_retry == 2) { + con->error_msg = "connect authorization failure"; + reset_connection(con); + set_bit(CLOSED, &con->state); + return -1; + } + con->auth_retry = 1; + prepare_write_connect(con->msgr, con, 0); + prepare_read_connect_retry(con); + break; case CEPH_MSGR_TAG_RESETSESSION: /* diff --git a/fs/ceph/messenger.h b/fs/ceph/messenger.h index 4bd85c3..f9c9f64 100644 --- a/fs/ceph/messenger.h +++ b/fs/ceph/messenger.h @@ -26,6 +26,12 @@ struct ceph_connection_operations { /* handle an incoming message. */ void (*dispatch) (struct ceph_connection *con, struct ceph_msg *m); + /* authorize an outgoing connection */ + int (*get_authorizer) (struct ceph_connection *con, + void **buf, int *len, int *proto, + void **reply_buf, int *reply_len, int force_new); + int (*verify_authorizer_reply) (struct ceph_connection *con, int len); + /* protocol version mismatch */ void (*bad_proto) (struct ceph_connection *con); @@ -144,6 +150,10 @@ struct ceph_connection { attempt for this connection, client */ u32 peer_global_seq; /* peer's global seq for this connection */ + int auth_retry; /* true if we need a newer authorizer */ + void *auth_reply_buf; /* where to put the authorizer reply */ + int auth_reply_buf_len; + /* out queue */ struct mutex out_mutex; struct list_head out_queue; diff --git a/fs/ceph/mon_client.c b/fs/ceph/mon_client.c index 95b76e7..017d5ae 100644 --- a/fs/ceph/mon_client.c +++ b/fs/ceph/mon_client.c @@ -6,6 +6,7 @@ #include "mon_client.h" #include "super.h" +#include "auth.h" #include "decode.h" /* @@ -38,6 +39,10 @@ struct ceph_monmap *ceph_monmap_decode(void *p, void *end) struct ceph_fsid fsid; u32 epoch, num_mon; u16 version; + u32 len; + + ceph_decode_32_safe(&p, end, len, bad); + ceph_decode_need(&p, end, len, bad); dout("monmap_decode %p %p len %d\n", p, end, (int)(end-p)); @@ -95,8 +100,10 @@ static void __close_session(struct ceph_mon_client *monc) { if (monc->con) { dout("__close_session closing mon%d\n", monc->cur_mon); + ceph_con_revoke(monc->con, monc->m_auth); ceph_con_close(monc->con); monc->cur_mon = -1; + ceph_auth_reset(monc->auth); } } @@ -106,6 +113,7 @@ static void __close_session(struct ceph_mon_client *monc) static int __open_session(struct ceph_mon_client *monc) { char r; + int ret; if (monc->cur_mon < 0) { get_random_bytes(&r, 1); @@ -121,6 +129,15 @@ static int __open_session(struct ceph_mon_client *monc) monc->con->peer_name.num = cpu_to_le64(monc->cur_mon); ceph_con_open(monc->con, &monc->monmap->mon_inst[monc->cur_mon].addr); + + /* initiatiate authentication handshake */ + ret = ceph_auth_build_hello(monc->auth, + monc->m_auth->front.iov_base, + monc->m_auth->front_max); + monc->m_auth->front.iov_len = ret; + monc->m_auth->hdr.front_len = cpu_to_le32(ret); + ceph_msg_get(monc->m_auth); /* keep our ref */ + ceph_con_send(monc->con, monc->m_auth); } else { dout("open_session mon%d already open\n", monc->cur_mon); } @@ -139,7 +156,7 @@ static void __schedule_delayed(struct ceph_mon_client *monc) { unsigned delay; - if (monc->cur_mon < 0 || monc->want_mount || __sub_expired(monc)) + if (monc->cur_mon < 0 || __sub_expired(monc)) delay = 10 * HZ; else delay = 20 * HZ; @@ -161,7 +178,7 @@ static void __send_subscribe(struct ceph_mon_client *monc) struct ceph_mon_subscribe_item *i; void *p, *end; - msg = ceph_msg_new(CEPH_MSG_MON_SUBSCRIBE, 64, 0, 0, NULL); + msg = ceph_msg_new(CEPH_MSG_MON_SUBSCRIBE, 96, 0, 0, NULL); if (!msg) return; @@ -173,7 +190,7 @@ static void __send_subscribe(struct ceph_mon_client *monc) if (monc->want_next_osdmap) { dout("__send_subscribe to 'osdmap' %u\n", (unsigned)monc->have_osdmap); - ceph_encode_32(&p, 2); + ceph_encode_32(&p, 3); ceph_encode_string(&p, end, "osdmap", 6); i = p; i->have = cpu_to_le64(monc->have_osdmap); @@ -181,13 +198,18 @@ static void __send_subscribe(struct ceph_mon_client *monc) p += sizeof(*i); monc->want_next_osdmap = 2; /* requested */ } else { - ceph_encode_32(&p, 1); + ceph_encode_32(&p, 2); } ceph_encode_string(&p, end, "mdsmap", 6); i = p; i->have = cpu_to_le64(monc->have_mdsmap); i->onetime = 0; p += sizeof(*i); + ceph_encode_string(&p, end, "monmap", 6); + i = p; + i->have = 0; + i->onetime = 0; + p += sizeof(*i); msg->front.iov_len = p - msg->front.iov_base; msg->hdr.front_len = cpu_to_le32(msg->front.iov_len); @@ -256,7 +278,7 @@ void ceph_monc_request_next_osdmap(struct ceph_mon_client *monc) mutex_unlock(&monc->mutex); } - +#if 0 /* * mount */ @@ -264,12 +286,8 @@ static void __request_mount(struct ceph_mon_client *monc) { struct ceph_msg *msg; struct ceph_client_mount *h; - int err; dout("__request_mount\n"); - err = __open_session(monc); - if (err) - return; msg = ceph_msg_new(CEPH_MSG_CLIENT_MOUNT, sizeof(*h), 0, 0, NULL); if (IS_ERR(msg)) return; @@ -279,8 +297,12 @@ static void __request_mount(struct ceph_mon_client *monc) h->monhdr.session_mon_tid = 0; ceph_con_send(monc->con, msg); } +#endif -int ceph_monc_request_mount(struct ceph_mon_client *monc) +/* + * + */ +int ceph_monc_open_session(struct ceph_mon_client *monc) { if (!monc->con) { monc->con = kmalloc(sizeof(*monc->con), GFP_KERNEL); @@ -292,12 +314,14 @@ int ceph_monc_request_mount(struct ceph_mon_client *monc) } mutex_lock(&monc->mutex); - __request_mount(monc); + __open_session(monc); __schedule_delayed(monc); mutex_unlock(&monc->mutex); return 0; } +#if 0 + /* * The monitor responds with mount ack indicate mount success. The * included client ticket allows the client to talk to MDSs and OSDs. @@ -372,9 +396,65 @@ out: mutex_unlock(&monc->mutex); wake_up(&client->mount_wq); } +#endif + +/* + * The monitor responds with mount ack indicate mount success. The + * included client ticket allows the client to talk to MDSs and OSDs. + */ +static void ceph_monc_handle_map(struct ceph_mon_client *monc, struct ceph_msg *msg) +{ + struct ceph_client *client = monc->client; + struct ceph_monmap *monmap = NULL, *old = monc->monmap; + void *p, *end; + + mutex_lock(&monc->mutex); + + dout("handle_monmap\n"); + p = msg->front.iov_base; + end = p + msg->front.iov_len; + + monmap = ceph_monmap_decode(p, end); + if (IS_ERR(monmap)) { + pr_err("problem decoding monmap, %d\n", + (int)PTR_ERR(monmap)); + return; + } + if (monc->have_fsid && + ceph_fsid_compare(&monmap->fsid, &monc->monmap->fsid)) { + print_hex_dump(KERN_ERR, "monmap->fsid: ", DUMP_PREFIX_NONE, 16, 1, + (void *)&monmap->fsid, 16, 0); + print_hex_dump(KERN_ERR, "monc->monmap->fsid: ", DUMP_PREFIX_NONE, 16, 1, + (void *)&monc->monmap->fsid, 16, 0); + + pr_err("fsid mismatch, got a previous map with different fsid"); + kfree(monmap); + return; + } + + client->monc.monmap = monmap; + client->monc.have_fsid = true; + kfree(old); + + mutex_unlock(&monc->mutex); + wake_up(&client->mount_wq); +} + +/* + * init client info after authentication + */ +static void __init_authenticated_client(struct ceph_mon_client *monc) +{ + struct ceph_client *client = monc->client; + client->signed_ticket = NULL; + client->signed_ticket_len = 0; + client->msgr->inst.name.type = CEPH_ENTITY_TYPE_CLIENT; + client->msgr->inst.name.num = monc->auth->global_id; + ceph_debugfs_client_init(client); +} /* * statfs @@ -414,12 +494,8 @@ static int send_statfs(struct ceph_mon_client *monc, { struct ceph_msg *msg; struct ceph_mon_statfs *h; - int err; dout("send_statfs tid %llu\n", req->tid); - err = __open_session(monc); - if (err) - return err; msg = ceph_msg_new(CEPH_MSG_STATFS, sizeof(*h), 0, 0, NULL); if (IS_ERR(msg)) return PTR_ERR(msg); @@ -514,17 +590,14 @@ static void delayed_work(struct work_struct *work) dout("monc delayed_work\n"); mutex_lock(&monc->mutex); - if (monc->want_mount) { - __request_mount(monc); + if (monc->hunting) { + __close_session(monc); + __open_session(monc); /* continue hunting */ } else { - if (monc->hunting) { - __close_session(monc); - __open_session(monc); /* continue hunting */ - } else { - ceph_con_keepalive(monc->con); - } + ceph_con_keepalive(monc->con); + if (monc->auth->ops->is_authenticated(monc->auth)) + __send_subscribe(monc); } - __send_subscribe(monc); __schedule_delayed(monc); mutex_unlock(&monc->mutex); } @@ -555,6 +628,7 @@ static int build_initial_monmap(struct ceph_mon_client *monc) monc->monmap->mon_inst[i].name.num = cpu_to_le64(i); } monc->monmap->num_mon = num_mon; + monc->have_fsid = false; /* release addr memory */ kfree(args->mon_addr); @@ -579,21 +653,37 @@ int ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl) monc->con = NULL; + /* authentication */ + monc->auth = ceph_auth_init(cl->mount_args->name, + cl->mount_args->secret); + if (IS_ERR(monc->auth)) + return PTR_ERR(monc->auth); + monc->auth->want_keys = + CEPH_ENTITY_TYPE_AUTH | CEPH_ENTITY_TYPE_MON | + CEPH_ENTITY_TYPE_OSD | CEPH_ENTITY_TYPE_MDS; + /* msg pools */ - err = ceph_msgpool_init(&monc->msgpool_mount_ack, 4096, 1, false); - if (err < 0) - goto out; err = ceph_msgpool_init(&monc->msgpool_subscribe_ack, sizeof(struct ceph_mon_subscribe_ack), 1, false); if (err < 0) - goto out; + goto out_monmap; err = ceph_msgpool_init(&monc->msgpool_statfs_reply, sizeof(struct ceph_mon_statfs_reply), 0, false); if (err < 0) - goto out; + goto out_pool1; + err = ceph_msgpool_init(&monc->msgpool_auth_reply, 4096, 1, false); + if (err < 0) + goto out_pool2; + + monc->m_auth = ceph_msg_new(CEPH_MSG_AUTH, 4096, 0, 0, NULL); + if (IS_ERR(monc->m_auth)) { + err = PTR_ERR(monc->m_auth); + monc->m_auth = NULL; + goto out_pool3; + } monc->cur_mon = -1; - monc->hunting = false; /* not really */ + monc->hunting = true; monc->sub_renew_after = jiffies; monc->sub_sent = 0; @@ -605,7 +695,16 @@ int ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl) monc->have_mdsmap = 0; monc->have_osdmap = 0; monc->want_next_osdmap = 1; - monc->want_mount = true; + return 0; + +out_pool3: + ceph_msgpool_destroy(&monc->msgpool_auth_reply); +out_pool2: + ceph_msgpool_destroy(&monc->msgpool_subscribe_ack); +out_pool1: + ceph_msgpool_destroy(&monc->msgpool_statfs_reply); +out_monmap: + kfree(monc->monmap); out: return err; } @@ -624,14 +723,44 @@ void ceph_monc_stop(struct ceph_mon_client *monc) } mutex_unlock(&monc->mutex); - ceph_msgpool_destroy(&monc->msgpool_mount_ack); + ceph_auth_destroy(monc->auth); + + ceph_msg_put(monc->m_auth); ceph_msgpool_destroy(&monc->msgpool_subscribe_ack); ceph_msgpool_destroy(&monc->msgpool_statfs_reply); + ceph_msgpool_destroy(&monc->msgpool_auth_reply); kfree(monc->monmap); } +static void handle_auth_reply(struct ceph_mon_client *monc, + struct ceph_msg *msg) +{ + int ret; + + mutex_lock(&monc->mutex); + ret = ceph_handle_auth_reply(monc->auth, msg->front.iov_base, + msg->front.iov_len, + monc->m_auth->front.iov_base, + monc->m_auth->front_max); + if (ret < 0) { + monc->client->mount_err = ret; + wake_up(&monc->client->mount_wq); + } else if (ret > 0) { + monc->m_auth->front.iov_len = ret; + monc->m_auth->hdr.front_len = cpu_to_le32(ret); + ceph_msg_get(monc->m_auth); /* keep our ref */ + ceph_con_send(monc->con, monc->m_auth); + } else if (monc->auth->ops->is_authenticated(monc->auth)) { + dout("authenticated, starting session\n"); + __init_authenticated_client(monc); + __send_subscribe(monc); + __resend_statfs(monc); + } + mutex_unlock(&monc->mutex); +} + /* * handle incoming message */ @@ -644,8 +773,8 @@ static void dispatch(struct ceph_connection *con, struct ceph_msg *msg) return; switch (type) { - case CEPH_MSG_CLIENT_MOUNT_ACK: - handle_mount_ack(monc, msg); + case CEPH_MSG_AUTH_REPLY: + handle_auth_reply(monc, msg); break; case CEPH_MSG_MON_SUBSCRIBE_ACK: @@ -656,6 +785,10 @@ static void dispatch(struct ceph_connection *con, struct ceph_msg *msg) handle_statfs_reply(monc, msg); break; + case CEPH_MSG_MON_MAP: + ceph_monc_handle_map(monc, msg); + break; + case CEPH_MSG_MDS_MAP: ceph_mdsc_handle_map(&monc->client->mdsc, msg); break; @@ -682,12 +815,12 @@ static struct ceph_msg *mon_alloc_msg(struct ceph_connection *con, int front = le32_to_cpu(hdr->front_len); switch (type) { - case CEPH_MSG_CLIENT_MOUNT_ACK: - return ceph_msgpool_get(&monc->msgpool_mount_ack, front); case CEPH_MSG_MON_SUBSCRIBE_ACK: return ceph_msgpool_get(&monc->msgpool_subscribe_ack, front); case CEPH_MSG_STATFS_REPLY: return ceph_msgpool_get(&monc->msgpool_statfs_reply, front); + case CEPH_MSG_AUTH_REPLY: + return ceph_msgpool_get(&monc->msgpool_auth_reply, front); } return ceph_alloc_msg(con, hdr); } @@ -717,10 +850,7 @@ static void mon_fault(struct ceph_connection *con) if (!monc->hunting) { /* start hunting */ monc->hunting = true; - if (__open_session(monc) == 0) { - __send_subscribe(monc); - __resend_statfs(monc); - } + __open_session(monc); } else { /* already hunting, let's wait a bit */ __schedule_delayed(monc); diff --git a/fs/ceph/mon_client.h b/fs/ceph/mon_client.h index 9f6db45..c75b533 100644 --- a/fs/ceph/mon_client.h +++ b/fs/ceph/mon_client.h @@ -9,6 +9,7 @@ struct ceph_client; struct ceph_mount_args; +struct ceph_auth_client; /* * The monitor map enumerates the set of all monitors. @@ -58,23 +59,26 @@ struct ceph_mon_client { struct mutex mutex; struct delayed_work delayed_work; + struct ceph_auth_client *auth; + struct ceph_msg *m_auth; + bool hunting; int cur_mon; /* last monitor i contacted */ unsigned long sub_sent, sub_renew_after; struct ceph_connection *con; + bool have_fsid; /* msg pools */ - struct ceph_msgpool msgpool_mount_ack; struct ceph_msgpool msgpool_subscribe_ack; struct ceph_msgpool msgpool_statfs_reply; + struct ceph_msgpool msgpool_auth_reply; /* pending statfs requests */ struct radix_tree_root statfs_request_tree; int num_statfs_requests; u64 last_tid; - /* mds/osd map or mount requests */ - bool want_mount; + /* mds/osd map */ int want_next_osdmap; /* 1 = want, 2 = want+asked */ u32 have_osdmap, have_mdsmap; @@ -101,11 +105,11 @@ extern int ceph_monc_got_osdmap(struct ceph_mon_client *monc, u32 have); extern void ceph_monc_request_next_osdmap(struct ceph_mon_client *monc); -extern int ceph_monc_request_mount(struct ceph_mon_client *monc); - extern int ceph_monc_do_statfs(struct ceph_mon_client *monc, struct ceph_statfs *buf); +extern int ceph_monc_open_session(struct ceph_mon_client *monc); + #endif diff --git a/fs/ceph/msgr.h b/fs/ceph/msgr.h index 8e3ea2e..c758e8f 100644 --- a/fs/ceph/msgr.h +++ b/fs/ceph/msgr.h @@ -21,7 +21,7 @@ * whenever the wire protocol changes. try to keep this string length * constant. */ -#define CEPH_BANNER "ceph v023" +#define CEPH_BANNER "ceph v024" #define CEPH_BANNER_MAX_LEN 30 @@ -46,11 +46,16 @@ struct ceph_entity_name { __le64 num; } __attribute__ ((packed)); -#define CEPH_ENTITY_TYPE_MON 1 -#define CEPH_ENTITY_TYPE_MDS 2 -#define CEPH_ENTITY_TYPE_OSD 3 -#define CEPH_ENTITY_TYPE_CLIENT 4 -#define CEPH_ENTITY_TYPE_ADMIN 5 +#define CEPH_ENTITY_TYPE_MON 0x01 +#define CEPH_ENTITY_TYPE_MDS 0x02 +#define CEPH_ENTITY_TYPE_OSD 0x04 +#define CEPH_ENTITY_TYPE_CLIENT 0x08 +#define CEPH_ENTITY_TYPE_ADMIN 0x10 +#define CEPH_ENTITY_TYPE_AUTH 0x20 + +#define CEPH_ENTITY_TYPE_ANY 0xFF + +extern const char *ceph_entity_type_name(int type); /* * entity_addr -- network address @@ -94,6 +99,7 @@ struct ceph_entity_inst { #define CEPH_MSGR_TAG_ACK 8 /* message ack */ #define CEPH_MSGR_TAG_KEEPALIVE 9 /* just a keepalive byte! */ #define CEPH_MSGR_TAG_BADPROTOVER 10 /* bad protocol version */ +#define CEPH_MSGR_TAG_BADAUTHORIZER 11 /* bad authorizer */ /* @@ -104,6 +110,8 @@ struct ceph_msg_connect { __le32 global_seq; /* count connections initiated by this host */ __le32 connect_seq; /* count connections initiated in this session */ __le32 protocol_version; + __le32 authorizer_protocol; + __le32 authorizer_len; __u8 flags; /* CEPH_MSG_CONNECT_* */ } __attribute__ ((packed)); @@ -112,6 +120,7 @@ struct ceph_msg_connect_reply { __le32 global_seq; __le32 connect_seq; __le32 protocol_version; + __le32 authorizer_len; __u8 flags; } __attribute__ ((packed)); diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index 0a16c4f..ca0ee68 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -11,6 +11,7 @@ #include "osd_client.h" #include "messenger.h" #include "decode.h" +#include "auth.h" const static struct ceph_connection_operations osd_con_ops; @@ -331,6 +332,7 @@ static struct ceph_osd *create_osd(struct ceph_osd_client *osdc) osd->o_con.private = osd; osd->o_con.ops = &osd_con_ops; osd->o_con.peer_name.type = CEPH_ENTITY_TYPE_OSD; + return osd; } @@ -880,9 +882,15 @@ void ceph_osdc_handle_map(struct ceph_osd_client *osdc, struct ceph_msg *msg) /* verify fsid */ ceph_decode_need(&p, end, sizeof(fsid), bad); ceph_decode_copy(&p, &fsid, sizeof(fsid)); - if (ceph_fsid_compare(&fsid, &osdc->client->monc.monmap->fsid)) { - pr_err("got osdmap with wrong fsid, ignoring\n"); - return; + if (osdc->client->monc.have_fsid) { + if (ceph_fsid_compare(&fsid, + &osdc->client->monc.monmap->fsid)) { + pr_err("got osdmap with wrong fsid, ignoring\n"); + return; + } + } else { + ceph_fsid_set(&osdc->client->monc.monmap->fsid, &fsid); + osdc->client->monc.have_fsid = true; } down_write(&osdc->map_sem); @@ -1302,10 +1310,59 @@ static void put_osd_con(struct ceph_connection *con) put_osd(osd); } +/* + * authentication + */ +static int get_authorizer(struct ceph_connection *con, + void **buf, int *len, int *proto, + void **reply_buf, int *reply_len, int force_new) +{ + struct ceph_osd *o = con->private; + struct ceph_osd_client *osdc = o->o_osdc; + struct ceph_auth_client *ac = osdc->client->monc.auth; + int ret = 0; + + if (force_new && o->o_authorizer) { + ac->ops->destroy_authorizer(ac, o->o_authorizer); + o->o_authorizer = NULL; + } + if (o->o_authorizer == NULL) { + ret = ac->ops->create_authorizer( + ac, CEPH_ENTITY_TYPE_OSD, + &o->o_authorizer, + &o->o_authorizer_buf, + &o->o_authorizer_buf_len, + &o->o_authorizer_reply_buf, + &o->o_authorizer_reply_buf_len); + if (ret) + return ret; + } + + *proto = ac->protocol; + *buf = o->o_authorizer_buf; + *len = o->o_authorizer_buf_len; + *reply_buf = o->o_authorizer_reply_buf; + *reply_len = o->o_authorizer_reply_buf_len; + return 0; +} + + +static int verify_authorizer_reply(struct ceph_connection *con, int len) +{ + struct ceph_osd *o = con->private; + struct ceph_osd_client *osdc = o->o_osdc; + struct ceph_auth_client *ac = osdc->client->monc.auth; + + return ac->ops->verify_authorizer_reply(ac, o->o_authorizer, len); +} + + const static struct ceph_connection_operations osd_con_ops = { .get = get_osd_con, .put = put_osd_con, .dispatch = dispatch, + .get_authorizer = get_authorizer, + .verify_authorizer_reply = verify_authorizer_reply, .alloc_msg = alloc_msg, .fault = osd_reset, .alloc_middle = ceph_alloc_middle, diff --git a/fs/ceph/osd_client.h b/fs/ceph/osd_client.h index 766c8dc..3d4ae65 100644 --- a/fs/ceph/osd_client.h +++ b/fs/ceph/osd_client.h @@ -13,6 +13,7 @@ struct ceph_msg; struct ceph_snap_context; struct ceph_osd_request; struct ceph_osd_client; +struct ceph_authorizer; /* * completion callback for async writepages @@ -29,6 +30,9 @@ struct ceph_osd { struct rb_node o_node; struct ceph_connection o_con; struct list_head o_requests; + struct ceph_authorizer *o_authorizer; + void *o_authorizer_buf, *o_authorizer_reply_buf; + size_t o_authorizer_buf_len, o_authorizer_reply_buf_len; }; /* an in-flight request */ diff --git a/fs/ceph/rados.h b/fs/ceph/rados.h index fb23ff9..12bfb2f 100644 --- a/fs/ceph/rados.h +++ b/fs/ceph/rados.h @@ -157,7 +157,6 @@ struct ceph_eversion { #define CEPH_OSD_OP_MODE_WR 0x2000 #define CEPH_OSD_OP_MODE_RMW 0x3000 #define CEPH_OSD_OP_MODE_SUB 0x4000 -#define CEPH_OSD_OP_MODE_EXEC 0x8000 #define CEPH_OSD_OP_TYPE 0x0f00 #define CEPH_OSD_OP_TYPE_LOCK 0x0100 @@ -285,6 +284,7 @@ enum { CEPH_OSD_FLAG_BALANCE_READS = 256, CEPH_OSD_FLAG_PARALLELEXEC = 512, /* execute op in parallel */ CEPH_OSD_FLAG_PGOP = 1024, /* pg op, no object */ + CEPH_OSD_FLAG_EXEC = 2048, /* op may exec */ }; enum { diff --git a/fs/ceph/super.c b/fs/ceph/super.c index fe0a596..c901395 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -128,6 +128,8 @@ static int ceph_show_options(struct seq_file *m, struct vfsmount *mnt) seq_puts(m, ",noasyncreaddir"); if (strcmp(args->snapdir_name, CEPH_SNAPDIRNAME_DEFAULT)) seq_printf(m, ",snapdirname=%s", args->snapdir_name); + if (args->name) + seq_printf(m, ",name=%s", args->name); if (args->secret) seq_puts(m, ",secret="); return 0; @@ -224,12 +226,12 @@ const char *ceph_msg_type_name(int type) switch (type) { case CEPH_MSG_SHUTDOWN: return "shutdown"; case CEPH_MSG_PING: return "ping"; + case CEPH_MSG_AUTH: return "auth"; + case CEPH_MSG_AUTH_REPLY: return "auth_reply"; case CEPH_MSG_MON_MAP: return "mon_map"; case CEPH_MSG_MON_GET_MAP: return "mon_get_map"; case CEPH_MSG_MON_SUBSCRIBE: return "mon_subscribe"; case CEPH_MSG_MON_SUBSCRIBE_ACK: return "mon_subscribe_ack"; - case CEPH_MSG_CLIENT_MOUNT: return "client_mount"; - case CEPH_MSG_CLIENT_MOUNT_ACK: return "client_mount_ack"; case CEPH_MSG_STATFS: return "statfs"; case CEPH_MSG_STATFS_REPLY: return "statfs_reply"; case CEPH_MSG_MDS_MAP: return "mds_map"; @@ -267,6 +269,7 @@ enum { Opt_last_int, /* int args above */ Opt_snapdirname, + Opt_name, Opt_secret, Opt_last_string, /* string args above */ @@ -293,6 +296,7 @@ static match_table_t arg_tokens = { {Opt_readdir_max_entries, "readdir_max_entries=%d"}, /* int args above */ {Opt_snapdirname, "snapdirname=%s"}, + {Opt_name, "name=%s"}, {Opt_secret, "secret=%s"}, /* string args above */ {Opt_ip, "ip=%s"}, @@ -407,6 +411,11 @@ static struct ceph_mount_args *parse_mount_args(int flags, char *options, argstr[0].to-argstr[0].from, GFP_KERNEL); break; + case Opt_name: + args->name = kstrndup(argstr[0].from, + argstr[0].to-argstr[0].from, + GFP_KERNEL); + break; case Opt_secret: args->secret = kstrndup(argstr[0].from, argstr[0].to-argstr[0].from, @@ -476,6 +485,8 @@ static void destroy_mount_args(struct ceph_mount_args *args) dout("destroy_mount_args %p\n", args); kfree(args->snapdir_name); args->snapdir_name = NULL; + kfree(args->name); + args->name = NULL; kfree(args->secret); args->secret = NULL; kfree(args); @@ -657,27 +668,23 @@ static int ceph_mount(struct ceph_client *client, struct vfsmount *mnt, client->msgr->nocrc = ceph_test_opt(client, NOCRC); } - /* send mount request, and wait for mon, mds, and osd maps */ - err = ceph_monc_request_mount(&client->monc); + /* open session, and wait for mon, mds, and osd maps */ + err = ceph_monc_open_session(&client->monc); if (err < 0) goto out; - while (!have_mon_map(client) && !client->mount_err) { + while (!have_mon_map(client)) { err = -EIO; if (timeout && time_after_eq(jiffies, started + timeout)) goto out; /* wait */ - dout("mount waiting for mount\n"); - err = wait_event_interruptible_timeout(client->mount_wq, - client->mount_err || have_mon_map(client), + dout("mount waiting for mon_map\n"); + err = wait_event_interruptible_timeout(client->mount_wq, /* FIXME */ + have_mon_map(client), timeout); if (err == -EINTR || err == -ERESTARTSYS) goto out; - if (client->mount_err) { - err = client->mount_err; - goto out; - } } dout("mount opening root\n"); @@ -795,7 +802,6 @@ static int ceph_register_bdi(struct super_block *sb, struct ceph_client *client) client->backing_dev_info.ra_pages = (client->mount_args->rsize + PAGE_CACHE_SIZE - 1) >> PAGE_SHIFT; - err = bdi_register_dev(&client->backing_dev_info, sb->s_dev); return err; } diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 8aa1ffb..e0e8130 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -61,6 +61,7 @@ struct ceph_mount_args { int max_readdir; /* max readdir size */ int osd_timeout; char *snapdir_name; /* default ".snap" */ + char *name; char *secret; int cap_release_safety; }; @@ -75,6 +76,7 @@ struct ceph_mount_args { #define CEPH_MSG_MAX_DATA_LEN (16*1024*1024) #define CEPH_SNAPDIRNAME_DEFAULT ".snap" +#define CEPH_AUTH_NAME_DEFAULT "guest" /* * Delay telling the MDS we no longer want caps, in case we reopen -- cgit v0.10.2 From b9bfb93ce2b1ef668254f0b9e16fcc5246d65d8e Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 18 Nov 2009 15:08:44 -0800 Subject: ceph: move mempool creation to ceph_create_client Signed-off-by: Sage Weil diff --git a/fs/ceph/super.c b/fs/ceph/super.c index c901395..df05617 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -534,10 +534,18 @@ static struct ceph_client *ceph_create_client(struct ceph_mount_args *args) if (client->trunc_wq == NULL) goto fail_pg_inv_wq; + /* set up mempools */ + err = -ENOMEM; + client->wb_pagevec_pool = mempool_create_kmalloc_pool(10, + client->mount_args->wsize >> PAGE_CACHE_SHIFT); + if (!client->wb_pagevec_pool) + goto fail_trunc_wq; + + /* subsystems */ err = ceph_monc_init(&client->monc, client); if (err < 0) - goto fail_trunc_wq; + goto fail_mempool; err = ceph_osdc_init(&client->osdc, client); if (err < 0) goto fail_monc; @@ -550,6 +558,8 @@ fail_osdc: ceph_osdc_stop(&client->osdc); fail_monc: ceph_monc_stop(&client->monc); +fail_mempool: + mempool_destroy(client->wb_pagevec_pool); fail_trunc_wq: destroy_workqueue(client->trunc_wq); fail_pg_inv_wq: @@ -581,8 +591,7 @@ static void ceph_destroy_client(struct ceph_client *client) if (client->msgr) ceph_messenger_destroy(client->msgr); - if (client->wb_pagevec_pool) - mempool_destroy(client->wb_pagevec_pool); + mempool_destroy(client->wb_pagevec_pool); destroy_mount_args(client->mount_args); @@ -845,14 +854,6 @@ static int ceph_get_sb(struct file_system_type *fs_type, dout("get_sb got existing client %p\n", client); } else { dout("get_sb using new client %p\n", client); - - /* set up mempools */ - err = -ENOMEM; - client->wb_pagevec_pool = mempool_create_kmalloc_pool(10, - client->mount_args->wsize >> PAGE_CACHE_SHIFT); - if (!client->wb_pagevec_pool) - goto out_splat; - err = ceph_register_bdi(sb, client); if (err < 0) goto out_splat; -- cgit v0.10.2 From cfea1cf42b614583c02727d5bffd5a2384e92bda Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 18 Nov 2009 16:50:55 -0800 Subject: ceph: small cleanup in hash function Signed-off-by: Sage Weil diff --git a/fs/ceph/ceph_hash.c b/fs/ceph/ceph_hash.c index ac8be54..1c44e43 100644 --- a/fs/ceph/ceph_hash.c +++ b/fs/ceph/ceph_hash.c @@ -85,7 +85,7 @@ unsigned ceph_str_hash_linux(const char *str, unsigned length) unsigned long hash = 0; unsigned char c; - while (length-- > 0) { + while (length--) { c = *str++; hash = (hash + (c << 4) + (c >> 4)) * 11; } -- cgit v0.10.2 From 0743304d871559cb4c7c066357de2caa60e94c2f Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 18 Nov 2009 16:50:41 -0800 Subject: ceph: fix debugfs entry, simplify fsid checks We may first learn our fsid from any of the mon, osd, or mds maps (whichever the monitor sends first). Consolidate checks in a single helper. Initialize the client debugfs entry then, since we need the fsid (and global_id) for the directory name. Also remove dead mount code. Signed-off-by: Sage Weil diff --git a/fs/ceph/debugfs.c b/fs/ceph/debugfs.c index 9b20206..b90fc3e 100644 --- a/fs/ceph/debugfs.c +++ b/fs/ceph/debugfs.c @@ -7,6 +7,8 @@ #include "super.h" #include "mds_client.h" +#include "mon_client.h" +#include "auth.h" #ifdef CONFIG_DEBUG_FS @@ -335,7 +337,7 @@ int ceph_debugfs_client_init(struct ceph_client *client) char name[80]; snprintf(name, sizeof(name), FSID_FORMAT ".client%lld", - PR_FSID(&client->monc.monmap->fsid), client->whoami); + PR_FSID(&client->fsid), client->monc.auth->global_id); client->debugfs_dir = debugfs_create_dir(name, ceph_debugfs_dir); if (!client->debugfs_dir) diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 8a28515..8d95b0f 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -2782,16 +2782,8 @@ void ceph_mdsc_handle_map(struct ceph_mds_client *mdsc, struct ceph_msg *msg) ceph_decode_need(&p, end, sizeof(fsid)+2*sizeof(u32), bad); ceph_decode_copy(&p, &fsid, sizeof(fsid)); - if (mdsc->client->monc.have_fsid) { - if (ceph_fsid_compare(&fsid, - &mdsc->client->monc.monmap->fsid)) { - pr_err("got mdsmap with wrong fsid\n"); - return; - } - } else { - ceph_fsid_set(&mdsc->client->monc.monmap->fsid, &fsid); - mdsc->client->monc.have_fsid = true; - } + if (ceph_check_fsid(mdsc->client, &fsid) < 0) + return; epoch = ceph_decode_32(&p); maplen = ceph_decode_32(&p); dout("handle_map epoch %u len %d\n", epoch, (int)maplen); diff --git a/fs/ceph/mon_client.c b/fs/ceph/mon_client.c index 017d5ae..b742b3b 100644 --- a/fs/ceph/mon_client.c +++ b/fs/ceph/mon_client.c @@ -320,89 +320,12 @@ int ceph_monc_open_session(struct ceph_mon_client *monc) return 0; } -#if 0 - -/* - * The monitor responds with mount ack indicate mount success. The - * included client ticket allows the client to talk to MDSs and OSDs. - */ -static void handle_mount_ack(struct ceph_mon_client *monc, struct ceph_msg *msg) -{ - struct ceph_client *client = monc->client; - struct ceph_monmap *monmap = NULL, *old = monc->monmap; - void *p, *end; - s32 result; - u32 len; - s64 cnum; - int err = -EINVAL; - - if (client->whoami >= 0) { - dout("handle_mount_ack - already mounted\n"); - return; - } - - mutex_lock(&monc->mutex); - - dout("handle_mount_ack\n"); - p = msg->front.iov_base; - end = p + msg->front.iov_len; - - ceph_decode_64_safe(&p, end, cnum, bad); - ceph_decode_32_safe(&p, end, result, bad); - ceph_decode_32_safe(&p, end, len, bad); - if (result) { - pr_err("mount denied: %.*s (%d)\n", len, (char *)p, - result); - err = result; - goto out; - } - p += len; - - ceph_decode_32_safe(&p, end, len, bad); - ceph_decode_need(&p, end, len, bad); - monmap = ceph_monmap_decode(p, p + len); - if (IS_ERR(monmap)) { - pr_err("problem decoding monmap, %d\n", - (int)PTR_ERR(monmap)); - err = -EINVAL; - goto out; - } - p += len; - - client->monc.monmap = monmap; - kfree(old); - - client->signed_ticket = NULL; - client->signed_ticket_len = 0; - - monc->want_mount = false; - - client->whoami = cnum; - client->msgr->inst.name.type = CEPH_ENTITY_TYPE_CLIENT; - client->msgr->inst.name.num = cpu_to_le64(cnum); - pr_info("client%lld fsid " FSID_FORMAT "\n", - client->whoami, PR_FSID(&client->monc.monmap->fsid)); - - ceph_debugfs_client_init(client); - __send_subscribe(monc); - - err = 0; - goto out; - -bad: - pr_err("error decoding mount_ack message\n"); -out: - client->mount_err = err; - mutex_unlock(&monc->mutex); - wake_up(&client->mount_wq); -} -#endif - /* * The monitor responds with mount ack indicate mount success. The * included client ticket allows the client to talk to MDSs and OSDs. */ -static void ceph_monc_handle_map(struct ceph_mon_client *monc, struct ceph_msg *msg) +static void ceph_monc_handle_map(struct ceph_mon_client *monc, + struct ceph_msg *msg) { struct ceph_client *client = monc->client; struct ceph_monmap *monmap = NULL, *old = monc->monmap; @@ -420,42 +343,19 @@ static void ceph_monc_handle_map(struct ceph_mon_client *monc, struct ceph_msg * (int)PTR_ERR(monmap)); return; } - if (monc->have_fsid && - ceph_fsid_compare(&monmap->fsid, &monc->monmap->fsid)) { - print_hex_dump(KERN_ERR, "monmap->fsid: ", DUMP_PREFIX_NONE, 16, 1, - (void *)&monmap->fsid, 16, 0); - print_hex_dump(KERN_ERR, "monc->monmap->fsid: ", DUMP_PREFIX_NONE, 16, 1, - (void *)&monc->monmap->fsid, 16, 0); - - pr_err("fsid mismatch, got a previous map with different fsid"); + + if (ceph_check_fsid(monc->client, &monmap->fsid) < 0) { kfree(monmap); return; } client->monc.monmap = monmap; - client->monc.have_fsid = true; kfree(old); mutex_unlock(&monc->mutex); wake_up(&client->mount_wq); } - -/* - * init client info after authentication - */ -static void __init_authenticated_client(struct ceph_mon_client *monc) -{ - struct ceph_client *client = monc->client; - - client->signed_ticket = NULL; - client->signed_ticket_len = 0; - client->msgr->inst.name.type = CEPH_ENTITY_TYPE_CLIENT; - client->msgr->inst.name.num = monc->auth->global_id; - - ceph_debugfs_client_init(client); -} - /* * statfs */ @@ -754,7 +654,10 @@ static void handle_auth_reply(struct ceph_mon_client *monc, ceph_con_send(monc->con, monc->m_auth); } else if (monc->auth->ops->is_authenticated(monc->auth)) { dout("authenticated, starting session\n"); - __init_authenticated_client(monc); + + monc->client->msgr->inst.name.type = CEPH_ENTITY_TYPE_CLIENT; + monc->client->msgr->inst.name.num = monc->auth->global_id; + __send_subscribe(monc); __resend_statfs(monc); } diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index ca0ee68..d63f192 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -882,16 +882,8 @@ void ceph_osdc_handle_map(struct ceph_osd_client *osdc, struct ceph_msg *msg) /* verify fsid */ ceph_decode_need(&p, end, sizeof(fsid), bad); ceph_decode_copy(&p, &fsid, sizeof(fsid)); - if (osdc->client->monc.have_fsid) { - if (ceph_fsid_compare(&fsid, - &osdc->client->monc.monmap->fsid)) { - pr_err("got osdmap with wrong fsid, ignoring\n"); - return; - } - } else { - ceph_fsid_set(&osdc->client->monc.monmap->fsid, &fsid); - osdc->client->monc.have_fsid = true; - } + if (ceph_check_fsid(osdc->client, &fsid) < 0) + return; down_write(&osdc->map_sem); diff --git a/fs/ceph/super.c b/fs/ceph/super.c index df05617..3df6d4a 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -19,6 +19,7 @@ #include "decode.h" #include "super.h" #include "mon_client.h" +#include "auth.h" /* * Ceph superblock operations @@ -510,14 +511,11 @@ static struct ceph_client *ceph_create_client(struct ceph_mount_args *args) client->sb = NULL; client->mount_state = CEPH_MOUNT_MOUNTING; - client->whoami = -1; client->mount_args = args; client->msgr = NULL; client->mount_err = 0; - client->signed_ticket = NULL; - client->signed_ticket_len = 0; err = bdi_init(&client->backing_dev_info); if (err < 0) @@ -582,8 +580,6 @@ static void ceph_destroy_client(struct ceph_client *client) ceph_monc_stop(&client->monc); ceph_osdc_stop(&client->osdc); - kfree(client->signed_ticket); - ceph_debugfs_client_cleanup(client); destroy_workqueue(client->wb_wq); destroy_workqueue(client->pg_inv_wq); @@ -600,6 +596,32 @@ static void ceph_destroy_client(struct ceph_client *client) } /* + * Initially learn our fsid, or verify an fsid matches. + */ +int ceph_check_fsid(struct ceph_client *client, struct ceph_fsid *fsid) +{ + if (client->have_fsid) { + if (ceph_fsid_compare(&client->fsid, fsid)) { + print_hex_dump(KERN_ERR, "this fsid: ", + DUMP_PREFIX_NONE, 16, 1, + (void *)fsid, 16, 0); + print_hex_dump(KERN_ERR, " old fsid: ", + DUMP_PREFIX_NONE, 16, 1, + (void *)&client->fsid, 16, 0); + pr_err("fsid mismatch\n"); + return -1; + } + } else { + pr_info("client%lld fsid " FSID_FORMAT "\n", + client->monc.auth->global_id, PR_FSID(fsid)); + memcpy(&client->fsid, fsid, sizeof(*fsid)); + ceph_debugfs_client_init(client); + client->have_fsid = true; + } + return 0; +} + +/* * true if we have the mon map (and have thus joined the cluster) */ static int have_mon_map(struct ceph_client *client) diff --git a/fs/ceph/super.h b/fs/ceph/super.h index e0e8130..de5e324 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -113,16 +113,11 @@ static inline unsigned long time_sub(unsigned long a, unsigned long b) * mounting the same ceph filesystem/cluster. */ struct ceph_client { - __s64 whoami; /* my client number */ -#ifdef CONFIG_DEBUG_FS - struct dentry *debugfs_monmap; - struct dentry *debugfs_mdsmap, *debugfs_osdmap; - struct dentry *debugfs_dir, *debugfs_dentry_lru, *debugfs_caps; -#endif + struct ceph_fsid fsid; + bool have_fsid; struct mutex mount_mutex; /* serialize mount attempts */ struct ceph_mount_args *mount_args; - struct ceph_fsid fsid; struct super_block *sb; @@ -130,8 +125,6 @@ struct ceph_client { wait_queue_head_t mount_wq; int mount_err; - void *signed_ticket; /* our keys to the kingdom */ - int signed_ticket_len; struct ceph_messenger *msgr; /* messenger instance */ struct ceph_mon_client monc; @@ -145,6 +138,12 @@ struct ceph_client { struct workqueue_struct *trunc_wq; struct backing_dev_info backing_dev_info; + +#ifdef CONFIG_DEBUG_FS + struct dentry *debugfs_monmap; + struct dentry *debugfs_mdsmap, *debugfs_osdmap; + struct dentry *debugfs_dir, *debugfs_dentry_lru, *debugfs_caps; +#endif }; static inline struct ceph_client *ceph_client(struct super_block *sb) @@ -735,6 +734,7 @@ extern struct kmem_cache *ceph_dentry_cachep; extern struct kmem_cache *ceph_file_cachep; extern const char *ceph_msg_type_name(int type); +extern int ceph_check_fsid(struct ceph_client *client, struct ceph_fsid *fsid); #define FSID_FORMAT "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-" \ "%02x%02x%02x%02x%02x%02x" -- cgit v0.10.2 From 94045e115ee72aee3b17295791da07078f2f778c Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 19 Nov 2009 15:31:50 -0800 Subject: ceph: decode updated mdsmap format The mds map now uses the global_id as the 'key' (instead of the addr, which was a poor choice). This is protocol change. Signed-off-by: Sage Weil diff --git a/fs/ceph/ceph_fs.h b/fs/ceph/ceph_fs.h index 1e96a9a..4e5f49c 100644 --- a/fs/ceph/ceph_fs.h +++ b/fs/ceph/ceph_fs.h @@ -39,7 +39,7 @@ #define CEPH_MDS_PROTOCOL 9 /* cluster internal */ #define CEPH_MON_PROTOCOL 5 /* cluster internal */ #define CEPH_OSDC_PROTOCOL 22 /* server/client */ -#define CEPH_MDSC_PROTOCOL 29 /* server/client */ +#define CEPH_MDSC_PROTOCOL 30 /* server/client */ #define CEPH_MONC_PROTOCOL 15 /* server/client */ diff --git a/fs/ceph/mdsmap.c b/fs/ceph/mdsmap.c index 4226c81..cad8d25 100644 --- a/fs/ceph/mdsmap.c +++ b/fs/ceph/mdsmap.c @@ -76,6 +76,7 @@ struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end) /* pick out active nodes from mds_info (state > 0) */ n = ceph_decode_32(p); for (i = 0; i < n; i++) { + u64 global_id; u32 namelen; s32 mds, inc, state; u64 state_seq; @@ -84,10 +85,10 @@ struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end) u32 num_export_targets; void *pexport_targets = NULL; - ceph_decode_need(p, end, sizeof(addr) + 1 + sizeof(u32), bad); - ceph_decode_copy(p, &addr, sizeof(addr)); - ceph_decode_addr(&addr); + ceph_decode_need(p, end, sizeof(u64)*2 + 1 + sizeof(u32), bad); + global_id = ceph_decode_64(p); infoversion = ceph_decode_8(p); + *p += sizeof(u64); namelen = ceph_decode_32(p); /* skip mds name */ *p += namelen; @@ -99,7 +100,8 @@ struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end) inc = ceph_decode_32(p); state = ceph_decode_32(p); state_seq = ceph_decode_64(p); - *p += sizeof(addr); + ceph_decode_copy(p, &addr, sizeof(addr)); + ceph_decode_addr(&addr); *p += sizeof(struct ceph_timespec); *p += sizeof(u32); ceph_decode_32_safe(p, end, namelen, bad); @@ -112,10 +114,11 @@ struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end) num_export_targets = 0; } - dout("mdsmap_decode %d/%d mds%d.%d %s %s\n", - i+1, n, mds, inc, pr_addr(&addr.in_addr), + dout("mdsmap_decode %d/%d %lld mds%d.%d %s %s\n", + i+1, n, global_id, mds, inc, pr_addr(&addr.in_addr), ceph_mds_state_name(state)); if (mds >= 0 && mds < m->m_max_mds && state > 0) { + m->m_info[mds].global_id = global_id; m->m_info[mds].state = state; m->m_info[mds].addr = addr; m->m_info[mds].num_export_targets = num_export_targets; diff --git a/fs/ceph/mdsmap.h b/fs/ceph/mdsmap.h index d317308..eacc131 100644 --- a/fs/ceph/mdsmap.h +++ b/fs/ceph/mdsmap.h @@ -9,6 +9,7 @@ * we limit fields to those the client actually xcares about */ struct ceph_mds_info { + u64 global_id; struct ceph_entity_addr addr; s32 state; int num_export_targets; -- cgit v0.10.2 From dc14657c9c946f25b84a98e9ffa41b812a70699e Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Fri, 20 Nov 2009 13:59:13 -0800 Subject: ceph: mount fails immediately on error Signed-off-by: Yehuda Sadeh diff --git a/fs/ceph/auth.c b/fs/ceph/auth.c index c4d1eee..32f2e2a 100644 --- a/fs/ceph/auth.c +++ b/fs/ceph/auth.c @@ -169,6 +169,11 @@ int ceph_handle_auth_reply(struct ceph_auth_client *ac, } if (ac->negotiating) { + /* server does not support our protocols? */ + if (!protocol && result < 0) { + ret = result; + goto out; + } /* set up (new) protocol handler? */ if (ac->protocol && ac->protocol != protocol) { ac->ops->destroy(ac); diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 3df6d4a..a828943 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -712,10 +712,14 @@ static int ceph_mount(struct ceph_client *client, struct vfsmount *mnt, /* wait */ dout("mount waiting for mon_map\n"); err = wait_event_interruptible_timeout(client->mount_wq, /* FIXME */ - have_mon_map(client), + have_mon_map(client) || (client->mount_err < 0), timeout); if (err == -EINTR || err == -ERESTARTSYS) goto out; + if (client->mount_err < 0) { + err = client->mount_err; + goto out; + } } dout("mount opening root\n"); -- cgit v0.10.2 From 0dc2570fab222affe7739b88b5ed04c511d433dc Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 20 Nov 2009 13:43:45 -0800 Subject: ceph: reset requested max_size after mds reconnect The max_size increase request to the MDS can get lost during an MDS restart and reconnect. Reset our requested value after the MDS recovers, so that any blocked writes will re-request a larger max_size upon waking. Also, explicit wake session caps after the reconnect. Normally the cap renewal catches this, but not in the cases where the caps didn't go stale in the first place, which would leave writers waiting on max_size asleep. Signed-off-by: Sage Weil diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 8d95b0f..7da8369 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -746,14 +746,24 @@ static void remove_session_caps(struct ceph_mds_session *session) static int wake_up_session_cb(struct inode *inode, struct ceph_cap *cap, void *arg) { - wake_up(&ceph_inode(inode)->i_cap_wq); + struct ceph_inode_info *ci = ceph_inode(inode); + + wake_up(&ci->i_cap_wq); + if (arg) { + spin_lock(&inode->i_lock); + ci->i_wanted_max_size = 0; + ci->i_requested_max_size = 0; + spin_unlock(&inode->i_lock); + } return 0; } -static void wake_up_session_caps(struct ceph_mds_session *session) +static void wake_up_session_caps(struct ceph_mds_session *session, + int reconnect) { dout("wake_up_session_caps %p mds%d\n", session, session->s_mds); - iterate_session_caps(session, wake_up_session_cb, NULL); + iterate_session_caps(session, wake_up_session_cb, + (void *)(unsigned long)reconnect); } /* @@ -794,6 +804,8 @@ static int send_renew_caps(struct ceph_mds_client *mdsc, /* * Note new cap ttl, and any transition from stale -> not stale (fresh?). + * + * Called under session->s_mutex */ static void renewed_caps(struct ceph_mds_client *mdsc, struct ceph_mds_session *session, int is_renew) @@ -822,7 +834,7 @@ static void renewed_caps(struct ceph_mds_client *mdsc, spin_unlock(&session->s_cap_lock); if (wake) - wake_up_session_caps(session); + wake_up_session_caps(session, 0); } /* @@ -2248,6 +2260,7 @@ static void check_new_map(struct ceph_mds_client *mdsc, pr_info("mds%d reconnect completed\n", s->s_mds); kick_requests(mdsc, i, 1); ceph_kick_flushing_caps(mdsc, s); + wake_up_session_caps(s, 1); } } } -- cgit v0.10.2 From 03c677e1d189ff62891d9f278c55bb798a418b81 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 20 Nov 2009 15:14:15 -0800 Subject: ceph: reset msgr backoff during open, not after successful handshake Reset the backoff delay when we reopen the connection, so that the delays for any initial connection problems are reasonable. We were resetting only after a successful handshake, which was of limited utility. Signed-off-by: Sage Weil diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index 0b16748..45cec31 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -348,6 +348,7 @@ void ceph_con_open(struct ceph_connection *con, struct ceph_entity_addr *addr) set_bit(OPENING, &con->state); clear_bit(CLOSED, &con->state); memcpy(&con->peer_addr, addr, sizeof(*addr)); + con->delay = 0; /* reset backoff memory */ queue_con(con); } @@ -1162,8 +1163,6 @@ static int process_connect(struct ceph_connection *con) con->connect_seq); WARN_ON(con->connect_seq != le32_to_cpu(con->in_reply.connect_seq)); - - con->delay = 0; /* reset backoff memory */ prepare_read_tag(con); break; -- cgit v0.10.2 From b19a29af74c09553b9fef95cdf6e9af3df65f544 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 20 Nov 2009 14:44:18 -0800 Subject: ceph: remove dead code Left over from mount/auth protocol changes. Signed-off-by: Sage Weil diff --git a/fs/ceph/mon_client.c b/fs/ceph/mon_client.c index b742b3b..9ff2da6 100644 --- a/fs/ceph/mon_client.c +++ b/fs/ceph/mon_client.c @@ -278,27 +278,6 @@ void ceph_monc_request_next_osdmap(struct ceph_mon_client *monc) mutex_unlock(&monc->mutex); } -#if 0 -/* - * mount - */ -static void __request_mount(struct ceph_mon_client *monc) -{ - struct ceph_msg *msg; - struct ceph_client_mount *h; - - dout("__request_mount\n"); - msg = ceph_msg_new(CEPH_MSG_CLIENT_MOUNT, sizeof(*h), 0, 0, NULL); - if (IS_ERR(msg)) - return; - h = msg->front.iov_base; - h->monhdr.have_version = 0; - h->monhdr.session_mon = cpu_to_le16(-1); - h->monhdr.session_mon_tid = 0; - ceph_con_send(monc->con, msg); -} -#endif - /* * */ -- cgit v0.10.2 From 60d877334f7d9f5f2417ea4a83c1def769286102 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 21 Nov 2009 12:53:08 +0100 Subject: fs/ceph: introduce missing kfree Error handling code following a kmalloc should free the allocated data. The semantic match that finds this problem is as follows: (http://www.emn.fr/x-info/coccinelle/) // @r exists@ local idexpression x; statement S; expression E; identifier f,f1,l; position p1,p2; expression *ptr != NULL; @@ x@p1 = \(kmalloc\|kzalloc\|kcalloc\)(...); ... if (x == NULL) S <... when != x when != if (...) { <+...x...+> } ( x->f1 = E | (x->f1 == NULL || ...) | f(...,x->f1,...) ) ...> ( return \(0\|<+...x...+>\|ptr\); | return@p2 ...; ) @script:python@ p1 << r.p1; p2 << r.p2; @@ print "* file: %s kmalloc %s return %s" % (p1[0].file,p1[0].line,p2[0].line) // Signed-off-by: Julia Lawall Signed-off-by: Sage Weil diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c index 1a48a55..04769a3 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c @@ -655,8 +655,10 @@ static int ceph_sync_setxattr(struct dentry *dentry, const char *name, /* do request */ req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SETXATTR, USE_AUTH_MDS); - if (IS_ERR(req)) - return PTR_ERR(req); + if (IS_ERR(req)) { + err = PTR_ERR(req); + goto out; + } req->r_inode = igrab(inode); req->r_inode_drop = CEPH_CAP_XATTR_SHARED; req->r_num_caps = 1; -- cgit v0.10.2 From 32c895e776a0dd2cb701d60fbd6440280c09ce35 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 21 Nov 2009 16:53:16 +0100 Subject: fs/ceph: Move a dereference below a NULL test If the NULL test is necessary, then the dereference should be moved below the NULL test. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/). // @@ type T; expression E; identifier i,fld; statement S; @@ - T i = E->fld; + T i; ... when != E when != i if (E == NULL) S + i = E->fld; // Signed-off-by: Julia Lawall Signed-off-by: Sage Weil diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index d63f192..5d30d59 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -1249,11 +1249,12 @@ int ceph_osdc_writepages(struct ceph_osd_client *osdc, struct ceph_vino vino, static void dispatch(struct ceph_connection *con, struct ceph_msg *msg) { struct ceph_osd *osd = con->private; - struct ceph_osd_client *osdc = osd->o_osdc; + struct ceph_osd_client *osdc; int type = le16_to_cpu(msg->hdr.type); if (!osd) return; + osdc = osd->o_osdc; switch (type) { case CEPH_MSG_OSD_MAP: -- cgit v0.10.2 From 75eb3592811028e5b01835126483d115532a3aa1 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Sat, 21 Nov 2009 13:08:14 -0800 Subject: ceph: remove useless IS_ERR checks ceph_lookup_snap_realm either returns a valid pointer or NULL; there is no need to check IS_ERR(result). Reported-by: Julia Lawall Signed-off-by: Sage Weil diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c index 2e3cb40..52f46a1 100644 --- a/fs/ceph/snap.c +++ b/fs/ceph/snap.c @@ -226,8 +226,6 @@ static int adjust_snap_realm_parent(struct ceph_mds_client *mdsc, return 0; parent = ceph_lookup_snap_realm(mdsc, parentino); - if (IS_ERR(parent)) - return PTR_ERR(parent); if (!parent) { parent = ceph_create_snap_realm(mdsc, parentino); if (IS_ERR(parent)) @@ -541,10 +539,6 @@ more: p += sizeof(u64) * le32_to_cpu(ri->num_prior_parent_snaps); realm = ceph_lookup_snap_realm(mdsc, le64_to_cpu(ri->ino)); - if (IS_ERR(realm)) { - err = PTR_ERR(realm); - goto fail; - } if (!realm) { realm = ceph_create_snap_realm(mdsc, le64_to_cpu(ri->ino)); if (IS_ERR(realm)) { @@ -762,8 +756,6 @@ void ceph_handle_snap(struct ceph_mds_client *mdsc, ri = p; realm = ceph_lookup_snap_realm(mdsc, split); - if (IS_ERR(realm)) - goto out; if (!realm) { realm = ceph_create_snap_realm(mdsc, split); if (IS_ERR(realm)) @@ -829,8 +821,6 @@ skip_inode: struct ceph_snap_realm *child = ceph_lookup_snap_realm(mdsc, le64_to_cpu(split_realms[i])); - if (IS_ERR(child)) - continue; if (!child) continue; adjust_snap_realm_parent(mdsc, child, realm->ino); -- cgit v0.10.2 From 34b43a56b9b103a7a820032177131532d9dbdbe8 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 1 Dec 2009 12:23:54 -0800 Subject: ceph: plug leak of request_mutex Fix leak of osd client request_mutex on receiving dup ack. Signed-off-by: Sage Weil diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index 5d30d59..d600073 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -739,6 +739,7 @@ static void handle_reply(struct ceph_osd_client *osdc, struct ceph_msg *msg) req->r_got_reply = 1; } else if ((flags & CEPH_OSD_FLAG_ONDISK) == 0) { dout("handle_reply tid %llu dup ack\n", tid); + mutex_unlock(&osdc->request_mutex); goto done; } -- cgit v0.10.2 From 50b885b96c903e420a1eac54dd27626244704a06 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 1 Dec 2009 14:12:07 -0800 Subject: ceph: whitespace cleanup Signed-off-by: Sage Weil diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 9dd1106..9b9ce14 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -1316,7 +1316,7 @@ static int __mark_caps_flushing(struct inode *inode, struct ceph_mds_client *mdsc = &ceph_client(inode->i_sb)->mdsc; struct ceph_inode_info *ci = ceph_inode(inode); int flushing; - + BUG_ON(ci->i_dirty_caps == 0); BUG_ON(list_empty(&ci->i_dirty_item)); diff --git a/fs/ceph/ceph_hash.c b/fs/ceph/ceph_hash.c index 1c44e43..bd57001 100644 --- a/fs/ceph/ceph_hash.c +++ b/fs/ceph/ceph_hash.c @@ -82,14 +82,14 @@ unsigned ceph_str_hash_rjenkins(const char *str, unsigned length) */ unsigned ceph_str_hash_linux(const char *str, unsigned length) { - unsigned long hash = 0; + unsigned long hash = 0; unsigned char c; - while (length--) { + while (length--) { c = *str++; hash = (hash + (c << 4) + (c >> 4)) * 11; } - return hash; + return hash; } @@ -105,7 +105,7 @@ unsigned ceph_str_hash(int type, const char *s, unsigned len) } } -const char *ceph_str_hash_name(int type) +const char *ceph_str_hash_name(int type) { switch (type) { case CEPH_STR_HASH_LINUX: diff --git a/fs/ceph/crush/mapper.c b/fs/ceph/crush/mapper.c index 2523d44..9ba54ef 100644 --- a/fs/ceph/crush/mapper.c +++ b/fs/ceph/crush/mapper.c @@ -254,7 +254,7 @@ static int crush_bucket_choose(struct crush_bucket *in, int x, int r) x, r); default: BUG_ON(1); - return in->items[0]; + return in->items[0]; } } diff --git a/fs/ceph/mon_client.c b/fs/ceph/mon_client.c index 9ff2da6..1dd0dc2 100644 --- a/fs/ceph/mon_client.c +++ b/fs/ceph/mon_client.c @@ -279,7 +279,7 @@ void ceph_monc_request_next_osdmap(struct ceph_mon_client *monc) } /* - * + * */ int ceph_monc_open_session(struct ceph_mon_client *monc) { diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index d600073..d639c74 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -1308,8 +1308,8 @@ static void put_osd_con(struct ceph_connection *con) * authentication */ static int get_authorizer(struct ceph_connection *con, - void **buf, int *len, int *proto, - void **reply_buf, int *reply_len, int force_new) + void **buf, int *len, int *proto, + void **reply_buf, int *reply_len, int force_new) { struct ceph_osd *o = con->private; struct ceph_osd_client *osdc = o->o_osdc; -- cgit v0.10.2 From 1d1de9160e0d8aff0d67a21137b62e63ffd6f184 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 2 Dec 2009 11:54:25 -0800 Subject: ceph: hide /.ceph from readdir results We need to skip /.ceph in (cached) readdir results, and exclude "/.ceph" from the cached ENOENT lookup check. Signed-off-by: Sage Weil diff --git a/fs/ceph/ceph_fs.h b/fs/ceph/ceph_fs.h index 4e5f49c..699196a 100644 --- a/fs/ceph/ceph_fs.h +++ b/fs/ceph/ceph_fs.h @@ -44,6 +44,7 @@ #define CEPH_INO_ROOT 1 +#define CEPH_INO_CEPH 2 /* hidden .ceph dir */ /* arbitrary limit on max # of monitors (cluster of 3 is typical) */ #define CEPH_MAX_MON 31 diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 32ef543..89ce3ba 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c @@ -132,6 +132,7 @@ more: } if (!d_unhashed(dentry) && dentry->d_inode && ceph_snap(dentry->d_inode) != CEPH_SNAPDIR && + ceph_ino(dentry->d_inode) != CEPH_INO_CEPH && filp->f_pos <= di->offset) break; dout(" skipping %p %.*s at %llu (%llu)%s%s\n", dentry, @@ -512,6 +513,12 @@ struct dentry *ceph_finish_lookup(struct ceph_mds_request *req, return dentry; } +static int is_root_ceph_dentry(struct inode *inode, struct dentry *dentry) +{ + return ceph_ino(inode) == CEPH_INO_ROOT && + strncmp(dentry->d_name.name, ".ceph", 5) == 0; +} + /* * Look up a single dir entry. If there is a lookup intent, inform * the MDS so that it gets our 'caps wanted' value in a single op. @@ -554,6 +561,7 @@ static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry, if (strncmp(dentry->d_name.name, client->mount_args->snapdir_name, dentry->d_name.len) && + !is_root_ceph_dentry(dir, dentry) && (ci->i_ceph_flags & CEPH_I_COMPLETE) && (__ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1))) { di->offset = ci->i_max_offset++; -- cgit v0.10.2 From 33d4909ccc094b8262667bccdd52e01458bee0df Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 2 Dec 2009 14:42:39 -0800 Subject: ceph: allow preferred osd to be get/set via layout ioctl There is certainly no reason not to report this. The only real downside to allowing the user to set it is that you don't get default values by zeroing the layout struct (the default is -1). Signed-off-by: Sage Weil diff --git a/fs/ceph/ioctl.c b/fs/ceph/ioctl.c index 4c33e19..8a5bcae 100644 --- a/fs/ceph/ioctl.c +++ b/fs/ceph/ioctl.c @@ -24,6 +24,8 @@ static long ceph_ioctl_get_layout(struct file *file, void __user *arg) l.stripe_count = ceph_file_layout_stripe_count(ci->i_layout); l.object_size = ceph_file_layout_object_size(ci->i_layout); l.data_pool = le32_to_cpu(ci->i_layout.fl_pg_pool); + l.preferred_osd = + (s32)le32_to_cpu(ci->i_layout.fl_pg_preferred); if (copy_to_user(arg, &l, sizeof(l))) return -EFAULT; } @@ -79,7 +81,8 @@ static long ceph_ioctl_set_layout(struct file *file, void __user *arg) req->r_args.setlayout.layout.fl_object_size = cpu_to_le32(l.object_size); req->r_args.setlayout.layout.fl_pg_pool = cpu_to_le32(l.data_pool); - req->r_args.setlayout.layout.fl_pg_preferred = cpu_to_le32((s32)-1); + req->r_args.setlayout.layout.fl_pg_preferred = + cpu_to_le32(l.preferred_osd); err = ceph_mdsc_do_request(mdsc, parent_inode, req); ceph_mdsc_put_request(req); diff --git a/fs/ceph/ioctl.h b/fs/ceph/ioctl.h index 3c511da..25e4f1a 100644 --- a/fs/ceph/ioctl.h +++ b/fs/ceph/ioctl.h @@ -10,6 +10,7 @@ struct ceph_ioctl_layout { __u64 stripe_unit, stripe_count, object_size; __u64 data_pool; + __s64 preferred_osd; }; #define CEPH_IOC_GET_LAYOUT _IOR(CEPH_IOCTL_MAGIC, 1, \ -- cgit v0.10.2 From fb99f8810965b7e5a00e9754bd7bf556b00ba0c2 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 3 Dec 2009 15:04:08 -0800 Subject: ceph: update MAINTAINERS entry with correct git URL Signed-off-by: Sage Weil diff --git a/MAINTAINERS b/MAINTAINERS index 9b680ff..6fc10aa 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1298,7 +1298,7 @@ CEPH DISTRIBUTED FILE SYSTEM CLIENT M: Sage Weil L: ceph-devel@lists.sourceforge.net W: http://ceph.newdream.net/ -T: git git://ceph.newdream.net/linux-ceph-client.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client.git S: Supported F: Documentation/filesystems/ceph.txt F: fs/ceph -- cgit v0.10.2 From 2f2ffd35822688a3650e503197b8724f47312748 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 4 Dec 2009 10:27:17 -0800 Subject: ceph: mark v0.18 release Signed-off-by: Sage Weil diff --git a/fs/ceph/ceph_fs.h b/fs/ceph/ceph_fs.h index 699196a..e2fd024 100644 --- a/fs/ceph/ceph_fs.h +++ b/fs/ceph/ceph_fs.h @@ -19,7 +19,7 @@ * Ceph release version */ #define CEPH_VERSION_MAJOR 0 -#define CEPH_VERSION_MINOR 17 +#define CEPH_VERSION_MINOR 18 #define CEPH_VERSION_PATCH 0 #define _CEPH_STRINGIFY(x) #x -- cgit v0.10.2 From dd26d857a7bf1b5b734a23180c19eac3e46db944 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Sat, 5 Dec 2009 10:13:33 -0800 Subject: ceph: use kref for ceph_buffer Signed-off-by: Sage Weil diff --git a/fs/ceph/buffer.c b/fs/ceph/buffer.c index cf9aacc..847c5da 100644 --- a/fs/ceph/buffer.c +++ b/fs/ceph/buffer.c @@ -9,13 +9,25 @@ struct ceph_buffer *ceph_buffer_new(gfp_t gfp) b = kmalloc(sizeof(*b), gfp); if (!b) return NULL; - atomic_set(&b->nref, 1); + kref_init(&b->kref); b->vec.iov_base = NULL; b->vec.iov_len = 0; b->alloc_len = 0; return b; } +void ceph_buffer_release(struct kref *kref) +{ + struct ceph_buffer *b = container_of(kref, struct ceph_buffer, kref); + if (b->vec.iov_base) { + if (b->is_vmalloc) + vfree(b->vec.iov_base); + else + kfree(b->vec.iov_base); + } + kfree(b); +} + int ceph_buffer_alloc(struct ceph_buffer *b, int len, gfp_t gfp) { b->vec.iov_base = kmalloc(len, gfp | __GFP_NOWARN); diff --git a/fs/ceph/buffer.h b/fs/ceph/buffer.h index 16b1930..3f541a1 100644 --- a/fs/ceph/buffer.h +++ b/fs/ceph/buffer.h @@ -1,6 +1,7 @@ #ifndef __FS_CEPH_BUFFER_H #define __FS_CEPH_BUFFER_H +#include #include #include #include @@ -13,7 +14,7 @@ * sizes. */ struct ceph_buffer { - atomic_t nref; + struct kref kref; struct kvec vec; size_t alloc_len; bool is_vmalloc; @@ -24,21 +25,16 @@ int ceph_buffer_alloc(struct ceph_buffer *b, int len, gfp_t gfp); static inline struct ceph_buffer *ceph_buffer_get(struct ceph_buffer *b) { - atomic_inc(&b->nref); + kref_get(&b->kref); return b; } +void ceph_buffer_release(struct kref *kref); + static inline void ceph_buffer_put(struct ceph_buffer *b) { - if (b && atomic_dec_and_test(&b->nref)) { - if (b->vec.iov_base) { - if (b->is_vmalloc) - vfree(b->vec.iov_base); - else - kfree(b->vec.iov_base); - } - kfree(b); - } + if (b) + kref_put(&b->kref, ceph_buffer_release); } static inline struct ceph_buffer *ceph_buffer_new_alloc(int len, gfp_t gfp) -- cgit v0.10.2 From b6c1d5b81ea0841ae9d3ce2cda319ab986b081cf Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 7 Dec 2009 12:17:17 -0800 Subject: ceph: simplify ceph_buffer interface We never allocate the ceph_buffer and buffer separtely, so use a single constructor. Disallow put on NULL buffer; make the caller check. Signed-off-by: Sage Weil diff --git a/fs/ceph/buffer.c b/fs/ceph/buffer.c index 847c5da..2576bd4 100644 --- a/fs/ceph/buffer.c +++ b/fs/ceph/buffer.c @@ -2,23 +2,38 @@ #include "ceph_debug.h" #include "buffer.h" -struct ceph_buffer *ceph_buffer_new(gfp_t gfp) +struct ceph_buffer *ceph_buffer_new(size_t len, gfp_t gfp) { struct ceph_buffer *b; b = kmalloc(sizeof(*b), gfp); if (!b) return NULL; + + b->vec.iov_base = kmalloc(len, gfp | __GFP_NOWARN); + if (b->vec.iov_base) { + b->is_vmalloc = false; + } else { + b->vec.iov_base = __vmalloc(len, gfp, PAGE_KERNEL); + if (!b->vec.iov_base) { + kfree(b); + return NULL; + } + b->is_vmalloc = true; + } + kref_init(&b->kref); - b->vec.iov_base = NULL; - b->vec.iov_len = 0; - b->alloc_len = 0; + b->alloc_len = len; + b->vec.iov_len = len; + dout("buffer_new %p\n", b); return b; } void ceph_buffer_release(struct kref *kref) { struct ceph_buffer *b = container_of(kref, struct ceph_buffer, kref); + + dout("buffer_release %p\n", b); if (b->vec.iov_base) { if (b->is_vmalloc) vfree(b->vec.iov_base); diff --git a/fs/ceph/buffer.h b/fs/ceph/buffer.h index 3f541a1..47b9514 100644 --- a/fs/ceph/buffer.h +++ b/fs/ceph/buffer.h @@ -20,8 +20,8 @@ struct ceph_buffer { bool is_vmalloc; }; -struct ceph_buffer *ceph_buffer_new(gfp_t gfp); -int ceph_buffer_alloc(struct ceph_buffer *b, int len, gfp_t gfp); +extern struct ceph_buffer *ceph_buffer_new(size_t len, gfp_t gfp); +extern void ceph_buffer_release(struct kref *kref); static inline struct ceph_buffer *ceph_buffer_get(struct ceph_buffer *b) { @@ -29,23 +29,9 @@ static inline struct ceph_buffer *ceph_buffer_get(struct ceph_buffer *b) return b; } -void ceph_buffer_release(struct kref *kref); - static inline void ceph_buffer_put(struct ceph_buffer *b) { - if (b) - kref_put(&b->kref, ceph_buffer_release); -} - -static inline struct ceph_buffer *ceph_buffer_new_alloc(int len, gfp_t gfp) -{ - struct ceph_buffer *b = ceph_buffer_new(gfp); - - if (b && ceph_buffer_alloc(b, len, gfp) < 0) { - ceph_buffer_put(b); - b = NULL; - } - return b; + kref_put(&b->kref, ceph_buffer_release); } #endif diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 074ee42..db68468 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -383,8 +383,10 @@ void ceph_destroy_inode(struct inode *inode) } __ceph_destroy_xattrs(ci); - ceph_buffer_put(ci->i_xattrs.blob); - ceph_buffer_put(ci->i_xattrs.prealloc_blob); + if (ci->i_xattrs.blob) + ceph_buffer_put(ci->i_xattrs.blob); + if (ci->i_xattrs.prealloc_blob) + ceph_buffer_put(ci->i_xattrs.prealloc_blob); kmem_cache_free(ceph_inode_cachep, ci); } @@ -526,7 +528,7 @@ static int fill_inode(struct inode *inode, * bytes are the xattr count). */ if (iinfo->xattr_len > 4) { - xattr_blob = ceph_buffer_new_alloc(iinfo->xattr_len, GFP_NOFS); + xattr_blob = ceph_buffer_new(iinfo->xattr_len, GFP_NOFS); if (!xattr_blob) pr_err("fill_inode ENOMEM xattr blob %d bytes\n", iinfo->xattr_len); @@ -715,7 +717,8 @@ no_change: err = 0; out: - ceph_buffer_put(xattr_blob); + if (xattr_blob) + ceph_buffer_put(xattr_blob); return err; } diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index 45cec31..bf76210 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -2047,7 +2047,7 @@ int ceph_alloc_middle(struct ceph_connection *con, struct ceph_msg *msg) BUG_ON(!middle_len); BUG_ON(msg->middle); - msg->middle = ceph_buffer_new_alloc(middle_len, GFP_NOFS); + msg->middle = ceph_buffer_new(middle_len, GFP_NOFS); if (!msg->middle) return -ENOMEM; return 0; diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c index 04769a3..37d6ce6 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c @@ -482,7 +482,8 @@ void __ceph_build_xattrs_blob(struct ceph_inode_info *ci) ci->i_xattrs.prealloc_blob->vec.iov_len = dest - ci->i_xattrs.prealloc_blob->vec.iov_base; - ceph_buffer_put(ci->i_xattrs.blob); + if (ci->i_xattrs.blob) + ceph_buffer_put(ci->i_xattrs.blob); ci->i_xattrs.blob = ci->i_xattrs.prealloc_blob; ci->i_xattrs.prealloc_blob = NULL; ci->i_xattrs.dirty = false; @@ -745,11 +746,12 @@ retry: spin_unlock(&inode->i_lock); dout(" preaallocating new blob size=%d\n", required_blob_size); - blob = ceph_buffer_new_alloc(required_blob_size, GFP_NOFS); + blob = ceph_buffer_new(required_blob_size, GFP_NOFS); if (!blob) goto out; spin_lock(&inode->i_lock); - ceph_buffer_put(ci->i_xattrs.prealloc_blob); + if (ci->i_xattrs.prealloc_blob) + ceph_buffer_put(ci->i_xattrs.prealloc_blob); ci->i_xattrs.prealloc_blob = blob; goto retry; } -- cgit v0.10.2 From 153c8e6bf7ffee561e046e60b26ef6486c6fc9f2 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 7 Dec 2009 12:31:09 -0800 Subject: ceph: use kref for struct ceph_mds_request Signed-off-by: Sage Weil diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 7da8369..739093f 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -400,41 +400,40 @@ static void put_request_session(struct ceph_mds_request *req) } } -void ceph_mdsc_put_request(struct ceph_mds_request *req) -{ - dout("mdsc put_request %p %d -> %d\n", req, - atomic_read(&req->r_ref), atomic_read(&req->r_ref)-1); - if (atomic_dec_and_test(&req->r_ref)) { - if (req->r_request) - ceph_msg_put(req->r_request); - if (req->r_reply) { - ceph_msg_put(req->r_reply); - destroy_reply_info(&req->r_reply_info); - } - if (req->r_inode) { - ceph_put_cap_refs(ceph_inode(req->r_inode), - CEPH_CAP_PIN); - iput(req->r_inode); - } - if (req->r_locked_dir) - ceph_put_cap_refs(ceph_inode(req->r_locked_dir), - CEPH_CAP_PIN); - if (req->r_target_inode) - iput(req->r_target_inode); - if (req->r_dentry) - dput(req->r_dentry); - if (req->r_old_dentry) { - ceph_put_cap_refs( - ceph_inode(req->r_old_dentry->d_parent->d_inode), - CEPH_CAP_PIN); - dput(req->r_old_dentry); - } - kfree(req->r_path1); - kfree(req->r_path2); - put_request_session(req); - ceph_unreserve_caps(&req->r_caps_reservation); - kfree(req); +void ceph_mdsc_release_request(struct kref *kref) +{ + struct ceph_mds_request *req = container_of(kref, + struct ceph_mds_request, + r_kref); + if (req->r_request) + ceph_msg_put(req->r_request); + if (req->r_reply) { + ceph_msg_put(req->r_reply); + destroy_reply_info(&req->r_reply_info); + } + if (req->r_inode) { + ceph_put_cap_refs(ceph_inode(req->r_inode), + CEPH_CAP_PIN); + iput(req->r_inode); + } + if (req->r_locked_dir) + ceph_put_cap_refs(ceph_inode(req->r_locked_dir), + CEPH_CAP_PIN); + if (req->r_target_inode) + iput(req->r_target_inode); + if (req->r_dentry) + dput(req->r_dentry); + if (req->r_old_dentry) { + ceph_put_cap_refs( + ceph_inode(req->r_old_dentry->d_parent->d_inode), + CEPH_CAP_PIN); + dput(req->r_old_dentry); } + kfree(req->r_path1); + kfree(req->r_path2); + put_request_session(req); + ceph_unreserve_caps(&req->r_caps_reservation); + kfree(req); } /* @@ -1097,7 +1096,7 @@ ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op, int mode) req->r_resend_mds = -1; INIT_LIST_HEAD(&req->r_unsafe_dir_item); req->r_fmode = -1; - atomic_set(&req->r_ref, 1); /* one for request_tree, one for caller */ + kref_init(&req->r_kref); INIT_LIST_HEAD(&req->r_wait); init_completion(&req->r_completion); init_completion(&req->r_safe_completion); diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h index 9faa1b2..41af5ca 100644 --- a/fs/ceph/mds_client.h +++ b/fs/ceph/mds_client.h @@ -2,6 +2,7 @@ #define _FS_CEPH_MDS_CLIENT_H #include +#include #include #include #include @@ -203,7 +204,7 @@ struct ceph_mds_request { int r_num_stale; int r_resend_mds; /* mds to resend to next, if any*/ - atomic_t r_ref; + struct kref r_kref; struct list_head r_wait; struct completion r_completion; struct completion r_safe_completion; @@ -306,9 +307,13 @@ extern int ceph_mdsc_do_request(struct ceph_mds_client *mdsc, struct ceph_mds_request *req); static inline void ceph_mdsc_get_request(struct ceph_mds_request *req) { - atomic_inc(&req->r_ref); + kref_get(&req->r_kref); +} +extern void ceph_mdsc_release_request(struct kref *kref); +static inline void ceph_mdsc_put_request(struct ceph_mds_request *req) +{ + kref_put(&req->r_kref, ceph_mdsc_release_request); } -extern void ceph_mdsc_put_request(struct ceph_mds_request *req); extern void ceph_mdsc_pre_umount(struct ceph_mds_client *mdsc); -- cgit v0.10.2 From 415e49a9c4faf1a1480b1497da2037608e5aa2c5 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 7 Dec 2009 13:37:03 -0800 Subject: ceph: use kref for ceph_osd_request Signed-off-by: Sage Weil diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index d639c74..67ef8ab 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -77,25 +77,24 @@ static void calc_layout(struct ceph_osd_client *osdc, /* * requests */ -void ceph_osdc_put_request(struct ceph_osd_request *req) +void ceph_osdc_release_request(struct kref *kref) { - dout("osdc put_request %p %d -> %d\n", req, atomic_read(&req->r_ref), - atomic_read(&req->r_ref)-1); - BUG_ON(atomic_read(&req->r_ref) <= 0); - if (atomic_dec_and_test(&req->r_ref)) { - if (req->r_request) - ceph_msg_put(req->r_request); - if (req->r_reply) - ceph_msg_put(req->r_reply); - if (req->r_own_pages) - ceph_release_page_vector(req->r_pages, - req->r_num_pages); - ceph_put_snap_context(req->r_snapc); - if (req->r_mempool) - mempool_free(req, req->r_osdc->req_mempool); - else - kfree(req); - } + struct ceph_osd_request *req = container_of(kref, + struct ceph_osd_request, + r_kref); + + if (req->r_request) + ceph_msg_put(req->r_request); + if (req->r_reply) + ceph_msg_put(req->r_reply); + if (req->r_own_pages) + ceph_release_page_vector(req->r_pages, + req->r_num_pages); + ceph_put_snap_context(req->r_snapc); + if (req->r_mempool) + mempool_free(req, req->r_osdc->req_mempool); + else + kfree(req); } /* @@ -149,7 +148,7 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc, req->r_osdc = osdc; req->r_mempool = use_mempool; - atomic_set(&req->r_ref, 1); + kref_init(&req->r_kref); init_completion(&req->r_completion); init_completion(&req->r_safe_completion); INIT_LIST_HEAD(&req->r_unsafe_item); diff --git a/fs/ceph/osd_client.h b/fs/ceph/osd_client.h index 3d4ae65..20ee618 100644 --- a/fs/ceph/osd_client.h +++ b/fs/ceph/osd_client.h @@ -2,6 +2,7 @@ #define _FS_CEPH_OSD_CLIENT_H #include +#include #include #include @@ -49,7 +50,7 @@ struct ceph_osd_request { int r_prepared_pages, r_got_reply; struct ceph_osd_client *r_osdc; - atomic_t r_ref; + struct kref r_kref; bool r_mempool; struct completion r_completion, r_safe_completion; ceph_osdc_callback_t r_callback, r_safe_callback; @@ -118,9 +119,13 @@ extern struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *, static inline void ceph_osdc_get_request(struct ceph_osd_request *req) { - atomic_inc(&req->r_ref); + kref_get(&req->r_kref); +} +extern void ceph_osdc_release_request(struct kref *kref); +static inline void ceph_osdc_put_request(struct ceph_osd_request *req) +{ + kref_put(&req->r_kref, ceph_osdc_release_request); } -extern void ceph_osdc_put_request(struct ceph_osd_request *req); extern int ceph_osdc_start_request(struct ceph_osd_client *osdc, struct ceph_osd_request *req, -- cgit v0.10.2 From c2e552e76e2c6907ca50cd9a4b747a2e2e8c615e Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 7 Dec 2009 15:55:05 -0800 Subject: ceph: use kref for ceph_msg Signed-off-by: Sage Weil diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index bf76210..b0571b0 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -1958,7 +1958,7 @@ struct ceph_msg *ceph_msg_new(int type, int front_len, m = kmalloc(sizeof(*m), GFP_NOFS); if (m == NULL) goto out; - atomic_set(&m->nref, 1); + kref_init(&m->kref); INIT_LIST_HEAD(&m->list_head); m->hdr.type = cpu_to_le16(type); @@ -2070,34 +2070,23 @@ void ceph_msg_kfree(struct ceph_msg *m) /* * Drop a msg ref. Destroy as needed. */ -void ceph_msg_put(struct ceph_msg *m) -{ - dout("ceph_msg_put %p %d -> %d\n", m, atomic_read(&m->nref), - atomic_read(&m->nref)-1); - if (atomic_read(&m->nref) <= 0) { - pr_err("bad ceph_msg_put on %p %llu %d=%s %d+%d\n", - m, le64_to_cpu(m->hdr.seq), - le16_to_cpu(m->hdr.type), - ceph_msg_type_name(le16_to_cpu(m->hdr.type)), - le32_to_cpu(m->hdr.front_len), - le32_to_cpu(m->hdr.data_len)); - WARN_ON(1); - } - if (atomic_dec_and_test(&m->nref)) { - dout("ceph_msg_put last one on %p\n", m); - WARN_ON(!list_empty(&m->list_head)); - - /* drop middle, data, if any */ - if (m->middle) { - ceph_buffer_put(m->middle); - m->middle = NULL; - } - m->nr_pages = 0; - m->pages = NULL; +void ceph_msg_last_put(struct kref *kref) +{ + struct ceph_msg *m = container_of(kref, struct ceph_msg, kref); - if (m->pool) - ceph_msgpool_put(m->pool, m); - else - ceph_msg_kfree(m); + dout("ceph_msg_put last one on %p\n", m); + WARN_ON(!list_empty(&m->list_head)); + + /* drop middle, data, if any */ + if (m->middle) { + ceph_buffer_put(m->middle); + m->middle = NULL; } + m->nr_pages = 0; + m->pages = NULL; + + if (m->pool) + ceph_msgpool_put(m->pool, m); + else + ceph_msg_kfree(m); } diff --git a/fs/ceph/messenger.h b/fs/ceph/messenger.h index f9c9f64..981b7c0 100644 --- a/fs/ceph/messenger.h +++ b/fs/ceph/messenger.h @@ -1,6 +1,7 @@ #ifndef __FS_CEPH_MESSENGER_H #define __FS_CEPH_MESSENGER_H +#include #include #include #include @@ -85,7 +86,7 @@ struct ceph_msg { struct page **pages; /* data payload. NOT OWNER. */ unsigned nr_pages; /* size of page array */ struct list_head list_head; - atomic_t nref; + struct kref kref; bool front_is_vmalloc; bool more_to_follow; int front_max; @@ -243,11 +244,13 @@ extern int ceph_alloc_middle(struct ceph_connection *con, struct ceph_msg *msg); static inline struct ceph_msg *ceph_msg_get(struct ceph_msg *msg) { - dout("ceph_msg_get %p %d -> %d\n", msg, atomic_read(&msg->nref), - atomic_read(&msg->nref)+1); - atomic_inc(&msg->nref); + kref_get(&msg->kref); return msg; } -extern void ceph_msg_put(struct ceph_msg *msg); +extern void ceph_msg_last_put(struct kref *kref); +static inline void ceph_msg_put(struct ceph_msg *msg) +{ + kref_put(&msg->kref, ceph_msg_last_put); +} #endif diff --git a/fs/ceph/msgpool.c b/fs/ceph/msgpool.c index 7599b33..ad5482c 100644 --- a/fs/ceph/msgpool.c +++ b/fs/ceph/msgpool.c @@ -165,7 +165,7 @@ void ceph_msgpool_put(struct ceph_msgpool *pool, struct ceph_msg *msg) { spin_lock(&pool->lock); if (pool->num < pool->min) { - ceph_msg_get(msg); /* retake a single ref */ + kref_set(&msg->kref, 1); /* retake a single ref */ list_add(&msg->list_head, &pool->msgs); pool->num++; dout("msgpool_put %p reclaim %p, now %d/%d\n", pool, msg, -- cgit v0.10.2 From 767ea5c33a360ce88da24e296e802dace5821799 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 9 Dec 2009 12:34:01 -0800 Subject: ceph: do not feed bad device ids to crush Do not feed bad (large) device ids to CRUSH. Signed-off-by: Sage Weil diff --git a/fs/ceph/osdmap.c b/fs/ceph/osdmap.c index 8c994c7..be5318a 100644 --- a/fs/ceph/osdmap.c +++ b/fs/ceph/osdmap.c @@ -868,6 +868,11 @@ static int *calc_pg_raw(struct ceph_osdmap *osdmap, struct ceph_pg pgid, ps = le16_to_cpu(pgid.ps); preferred = (s16)le16_to_cpu(pgid.preferred); + /* don't forcefeed bad device ids to crush */ + if (preferred >= osdmap->max_osd || + preferred >= osdmap->crush->max_devices) + preferred = -1; + if (poolid >= osdmap->num_pools) return NULL; pool = &osdmap->pg_pool[poolid]; -- cgit v0.10.2 From d4a780ce8821a37dd135f15b6150a5bfc5604f29 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 11 Dec 2009 08:55:23 -0800 Subject: ceph: fix leak of monc mutex Fix leak of monc mutex on ENOMEM or bad fsid when receiving new mon map. Audited all other users. Signed-off-by: Sage Weil diff --git a/fs/ceph/mon_client.c b/fs/ceph/mon_client.c index 1dd0dc2..a76da5e 100644 --- a/fs/ceph/mon_client.c +++ b/fs/ceph/mon_client.c @@ -320,17 +320,18 @@ static void ceph_monc_handle_map(struct ceph_mon_client *monc, if (IS_ERR(monmap)) { pr_err("problem decoding monmap, %d\n", (int)PTR_ERR(monmap)); - return; + goto out; } if (ceph_check_fsid(monc->client, &monmap->fsid) < 0) { kfree(monmap); - return; + goto out; } client->monc.monmap = monmap; kfree(old); +out: mutex_unlock(&monc->mutex); wake_up(&client->mount_wq); } -- cgit v0.10.2 From c86a2930ccbd90d77c54d04b5c2bbec95b989e40 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 14 Dec 2009 14:04:30 -0800 Subject: ceph: carry explicit msg reference for currently sending message Carry a ceph_msg reference for connection->out_msg. This will allow us to make out_sent optional. Signed-off-by: Sage Weil diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index b0571b0..96fd556 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -322,7 +322,10 @@ static void reset_connection(struct ceph_connection *con) con->connect_seq = 0; con->out_seq = 0; - con->out_msg = NULL; + if (con->out_msg) { + ceph_msg_put(con->out_msg); + con->out_msg = NULL; + } con->in_seq = 0; mutex_unlock(&con->out_mutex); } @@ -423,7 +426,7 @@ static void prepare_write_message_footer(struct ceph_connection *con, int v) con->out_kvec_bytes += sizeof(m->footer); con->out_kvec_left++; con->out_more = m->more_to_follow; - con->out_msg = NULL; /* we're done with this one */ + con->out_msg_done = true; } /* @@ -436,6 +439,7 @@ static void prepare_write_message(struct ceph_connection *con) con->out_kvec_bytes = 0; con->out_kvec_is_msg = true; + con->out_msg_done = false; /* Sneak an ack in there first? If we can get it into the same * TCP packet that's a good thing. */ @@ -452,8 +456,9 @@ static void prepare_write_message(struct ceph_connection *con) /* move message to sending/sent list */ m = list_first_entry(&con->out_queue, struct ceph_msg, list_head); + con->out_msg = m; + ceph_msg_get(m); list_move_tail(&m->list_head, &con->out_sent); - con->out_msg = m; /* we don't bother taking a reference here. */ m->hdr.seq = cpu_to_le64(++con->out_seq); @@ -1521,6 +1526,12 @@ more_kvec: /* msg pages? */ if (con->out_msg) { + if (con->out_msg_done) { + ceph_msg_put(con->out_msg); + con->out_msg = NULL; /* we're done with this one */ + goto do_next; + } + ret = write_partial_msg_pages(con); if (ret == 1) goto more_kvec; /* we need to send the footer, too! */ @@ -1533,6 +1544,7 @@ more_kvec: } } +do_next: if (!test_bit(CONNECTING, &con->state)) { /* is anything else pending? */ if (!list_empty(&con->out_queue)) { @@ -1923,8 +1935,10 @@ void ceph_con_revoke(struct ceph_connection *con, struct ceph_msg *msg) list_del_init(&msg->list_head); ceph_msg_put(msg); msg->hdr.seq = 0; - if (con->out_msg == msg) + if (con->out_msg == msg) { + ceph_msg_put(con->out_msg); con->out_msg = NULL; + } if (con->out_kvec_is_msg) { con->out_skip = con->out_kvec_bytes; con->out_kvec_is_msg = false; diff --git a/fs/ceph/messenger.h b/fs/ceph/messenger.h index 981b7c0..eff5cb5 100644 --- a/fs/ceph/messenger.h +++ b/fs/ceph/messenger.h @@ -182,6 +182,7 @@ struct ceph_connection { /* message out temps */ struct ceph_msg *out_msg; /* sending message (== tail of out_sent) */ + bool out_msg_done; struct ceph_msg_pos out_msg_pos; struct kvec out_kvec[8], /* sending header/footer data */ -- cgit v0.10.2 From 5e095e8b40b0402ad3bcadc5b8d84c38b26c30b2 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 14 Dec 2009 14:30:34 -0800 Subject: ceph: plug msg leak in con_fault Signed-off-by: Sage Weil diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index 96fd556..98519bd 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -1434,8 +1434,9 @@ no_data: */ static void process_message(struct ceph_connection *con) { - struct ceph_msg *msg = con->in_msg; + struct ceph_msg *msg; + msg = con->in_msg; con->in_msg = NULL; /* if first message, set peer_name */ @@ -1810,7 +1811,11 @@ static void ceph_fault(struct ceph_connection *con) clear_bit(BUSY, &con->state); /* to avoid an improbable race */ con_close_socket(con); - con->in_msg = NULL; + + if (con->in_msg) { + ceph_msg_put(con->in_msg); + con->in_msg = NULL; + } /* If there are no messages in the queue, place the connection * in a STANDBY state (i.e., don't try to reconnect just yet). */ -- cgit v0.10.2 From 92ac41d0a4ab26fb68d3f841332e5d1f15d79123 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 14 Dec 2009 14:56:56 -0800 Subject: ceph: detect lossy state of connection The server indicates whether a connection is lossy; set our LOSSYTX bit appropriately. Do not set lossy bit on outgoing connections. Signed-off-by: Sage Weil diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index 98519bd..986d8fb 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -625,8 +625,6 @@ static void prepare_write_connect(struct ceph_messenger *msgr, con->out_connect.global_seq = cpu_to_le32(global_seq); con->out_connect.protocol_version = cpu_to_le32(proto); con->out_connect.flags = 0; - if (test_bit(LOSSYTX, &con->state)) - con->out_connect.flags = CEPH_MSG_CONNECT_LOSSY; if (!after_banner) { con->out_kvec_left = 0; @@ -1168,6 +1166,10 @@ static int process_connect(struct ceph_connection *con) con->connect_seq); WARN_ON(con->connect_seq != le32_to_cpu(con->in_reply.connect_seq)); + + if (con->in_reply.flags & CEPH_MSG_CONNECT_LOSSY) + set_bit(LOSSYTX, &con->state); + prepare_read_tag(con); break; -- cgit v0.10.2 From b3d1dbbdd5670d8a9fb01f7dfb1cac522ff6795a Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 14 Dec 2009 14:58:11 -0800 Subject: ceph: don't save sent messages on lossy connections For lossy connections we drop all state on socket errors, so there is no reason to keep sent ceph_msg's around. Signed-off-by: Sage Weil diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index 986d8fb..d5eef76 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -453,12 +453,16 @@ static void prepare_write_message(struct ceph_connection *con) con->out_kvec_bytes = 1 + sizeof(con->out_temp_ack); } - /* move message to sending/sent list */ m = list_first_entry(&con->out_queue, struct ceph_msg, list_head); con->out_msg = m; - ceph_msg_get(m); - list_move_tail(&m->list_head, &con->out_sent); + if (test_bit(LOSSYTX, &con->state)) { + /* put message on sent list */ + ceph_msg_get(m); + list_move_tail(&m->list_head, &con->out_sent); + } else { + list_del_init(&m->list_head); + } m->hdr.seq = cpu_to_le64(++con->out_seq); -- cgit v0.10.2 From 93c20d98c29ccefa039c3843ccc37122caaf3d31 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Tue, 15 Dec 2009 09:50:36 -0800 Subject: ceph: fix msgpool reservation leak Signed-off-by: Yehuda Sadeh diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index 67ef8ab..63482ef 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -145,6 +145,7 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc, ceph_osdc_put_request(req); return ERR_PTR(-ENOMEM); } + req->r_num_prealloc_reply = num_reply; req->r_osdc = osdc; req->r_mempool = use_mempool; @@ -165,7 +166,7 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc, else msg = ceph_msg_new(CEPH_MSG_OSD_OP, msg_size, 0, 0, NULL); if (IS_ERR(msg)) { - ceph_msgpool_resv(&osdc->msgpool_op_reply, num_reply); + ceph_msgpool_resv(&osdc->msgpool_op_reply, -num_reply); ceph_osdc_put_request(req); return ERR_PTR(PTR_ERR(msg)); } @@ -465,6 +466,8 @@ static void __unregister_request(struct ceph_osd_client *osdc, rb_erase(&req->r_node, &osdc->requests); osdc->num_requests--; + ceph_msgpool_resv(&osdc->msgpool_op_reply, -req->r_num_prealloc_reply); + if (req->r_osd) { /* make sure the original request isn't in flight. */ ceph_con_revoke(&req->r_osd->o_con, req->r_request); diff --git a/fs/ceph/osd_client.h b/fs/ceph/osd_client.h index 20ee618..2e4cfd1 100644 --- a/fs/ceph/osd_client.h +++ b/fs/ceph/osd_client.h @@ -48,6 +48,7 @@ struct ceph_osd_request { int r_flags; /* any additional flags for the osd */ u32 r_sent; /* >0 if r_request is sending/sent */ int r_prepared_pages, r_got_reply; + int r_num_prealloc_reply; struct ceph_osd_client *r_osdc; struct kref r_kref; -- cgit v0.10.2 From 9ec7cab14e6de732d4e7c355fe67c5810c32c758 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 14 Dec 2009 15:13:47 -0800 Subject: ceph: hex dump corrupt server data to KERN_DEBUG Also, print fsid using standard format, NOT hex dump. Signed-off-by: Sage Weil diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 9b9ce14..dfb509f 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -2681,6 +2681,7 @@ done: bad: pr_err("ceph_handle_caps: corrupt message\n"); + ceph_msg_dump(msg); return; } diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 739093f..29a93fe 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -1650,6 +1650,7 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg) return; if (msg->front.iov_len < sizeof(*head)) { pr_err("mdsc_handle_reply got corrupt (short) reply\n"); + ceph_msg_dump(msg); return; } @@ -1740,6 +1741,7 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg) mutex_lock(&session->s_mutex); if (err < 0) { pr_err("mdsc_handle_reply got corrupt reply mds%d\n", mds); + ceph_msg_dump(msg); goto out_err; } @@ -1929,6 +1931,7 @@ static void handle_session(struct ceph_mds_session *session, bad: pr_err("mdsc_handle_session corrupt message mds%d len %d\n", mds, (int)msg->front.iov_len); + ceph_msg_dump(msg); return; } @@ -2394,6 +2397,7 @@ out: bad: pr_err("corrupt lease message\n"); + ceph_msg_dump(msg); } void ceph_mdsc_lease_send_msg(struct ceph_mds_session *session, diff --git a/fs/ceph/mdsmap.c b/fs/ceph/mdsmap.c index cad8d25..c4c498e 100644 --- a/fs/ceph/mdsmap.c +++ b/fs/ceph/mdsmap.c @@ -49,6 +49,7 @@ int ceph_mdsmap_get_random_mds(struct ceph_mdsmap *m) struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end) { struct ceph_mdsmap *m; + const void *start = *p; int i, j, n; int err = -EINVAL; u16 version; @@ -154,6 +155,9 @@ badmem: err = -ENOMEM; bad: pr_err("corrupt mdsmap\n"); + print_hex_dump(KERN_DEBUG, "mdsmap: ", + DUMP_PREFIX_OFFSET, 16, 1, + start, end - start, true); ceph_mdsmap_destroy(m); return ERR_PTR(-EINVAL); } diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index d5eef76..b10f88c 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -2115,3 +2115,23 @@ void ceph_msg_last_put(struct kref *kref) else ceph_msg_kfree(m); } + +void ceph_msg_dump(struct ceph_msg *msg) +{ + pr_debug("msg_dump %p (front_max %d nr_pages %d)\n", msg, + msg->front_max, msg->nr_pages); + print_hex_dump(KERN_DEBUG, "header: ", + DUMP_PREFIX_OFFSET, 16, 1, + &msg->hdr, sizeof(msg->hdr), true); + print_hex_dump(KERN_DEBUG, " front: ", + DUMP_PREFIX_OFFSET, 16, 1, + msg->front.iov_base, msg->front.iov_len, true); + if (msg->middle) + print_hex_dump(KERN_DEBUG, "middle: ", + DUMP_PREFIX_OFFSET, 16, 1, + msg->middle->vec.iov_base, + msg->middle->vec.iov_len, true); + print_hex_dump(KERN_DEBUG, "footer: ", + DUMP_PREFIX_OFFSET, 16, 1, + &msg->footer, sizeof(msg->footer), true); +} diff --git a/fs/ceph/messenger.h b/fs/ceph/messenger.h index eff5cb5..e04c214 100644 --- a/fs/ceph/messenger.h +++ b/fs/ceph/messenger.h @@ -254,4 +254,6 @@ static inline void ceph_msg_put(struct ceph_msg *msg) kref_put(&msg->kref, ceph_msg_last_put); } +extern void ceph_msg_dump(struct ceph_msg *msg); + #endif diff --git a/fs/ceph/mon_client.c b/fs/ceph/mon_client.c index a76da5e..775a9c0 100644 --- a/fs/ceph/mon_client.c +++ b/fs/ceph/mon_client.c @@ -242,6 +242,7 @@ static void handle_subscribe_ack(struct ceph_mon_client *monc, return; bad: pr_err("got corrupt subscribe-ack msg\n"); + ceph_msg_dump(msg); } /* @@ -364,6 +365,7 @@ static void handle_statfs_reply(struct ceph_mon_client *monc, bad: pr_err("corrupt statfs reply, no tid\n"); + ceph_msg_dump(msg); } /* diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index 63482ef..4bfe880 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -773,6 +773,7 @@ bad: pr_err("corrupt osd_op_reply got %d %d expected %d\n", (int)msg->front.iov_len, le32_to_cpu(msg->hdr.front_len), (int)sizeof(*rhead)); + ceph_msg_dump(msg); } @@ -964,6 +965,7 @@ done: bad: pr_err("osdc handle_map corrupt msg\n"); + ceph_msg_dump(msg); up_write(&osdc->map_sem); return; } diff --git a/fs/ceph/osdmap.c b/fs/ceph/osdmap.c index be5318a..8c8ffe5 100644 --- a/fs/ceph/osdmap.c +++ b/fs/ceph/osdmap.c @@ -726,6 +726,9 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, bad: pr_err("corrupt inc osdmap epoch %d off %d (%p of %p-%p)\n", epoch, (int)(*p - start), *p, start, end); + print_hex_dump(KERN_DEBUG, "osdmap: ", + DUMP_PREFIX_OFFSET, 16, 1, + start, end - start, true); if (newcrush) crush_destroy(newcrush); return ERR_PTR(err); diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c index 52f46a1..dcf18d9 100644 --- a/fs/ceph/snap.c +++ b/fs/ceph/snap.c @@ -877,6 +877,7 @@ split_skip_inode: bad: pr_err("corrupt snap message from mds%d\n", mds); + ceph_msg_dump(msg); out: if (locked_rwsem) up_write(&mdsc->snap_rwsem); diff --git a/fs/ceph/super.c b/fs/ceph/super.c index a828943..6d02a16 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -602,13 +602,8 @@ int ceph_check_fsid(struct ceph_client *client, struct ceph_fsid *fsid) { if (client->have_fsid) { if (ceph_fsid_compare(&client->fsid, fsid)) { - print_hex_dump(KERN_ERR, "this fsid: ", - DUMP_PREFIX_NONE, 16, 1, - (void *)fsid, 16, 0); - print_hex_dump(KERN_ERR, " old fsid: ", - DUMP_PREFIX_NONE, 16, 1, - (void *)&client->fsid, 16, 0); - pr_err("fsid mismatch\n"); + pr_err("bad fsid, had " FSID_FORMAT " got " FSID_FORMAT, + PR_FSID(&client->fsid), PR_FSID(fsid)); return -1; } } else { -- cgit v0.10.2 From cf3e5c409b5d66ec66207092a3f7e3e2c42c0f3f Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 11 Dec 2009 09:48:05 -0800 Subject: ceph: plug leak of incoming message during connection fault/close If we explicitly close a connection, or there is a socket error, we need to drop any partially received message. Signed-off-by: Sage Weil diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index b10f88c..b12604e 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -320,6 +320,11 @@ static void reset_connection(struct ceph_connection *con) ceph_msg_remove_list(&con->out_queue); ceph_msg_remove_list(&con->out_sent); + if (con->in_msg) { + ceph_msg_put(con->in_msg); + con->in_msg = NULL; + } + con->connect_seq = 0; con->out_seq = 0; if (con->out_msg) { @@ -1288,7 +1293,7 @@ static int read_partial_message(struct ceph_connection *con) con->in_msg = con->ops->alloc_msg(con, &con->in_hdr); if (!con->in_msg) { /* skip this message */ - dout("alloc_msg returned NULL, skipping message\n"); + pr_err("alloc_msg returned NULL, skipping message\n"); con->in_base_pos = -front_len - middle_len - data_len - sizeof(m->footer); con->in_tag = CEPH_MSGR_TAG_READY; @@ -1327,7 +1332,7 @@ static int read_partial_message(struct ceph_connection *con) if (con->ops->alloc_middle) ret = con->ops->alloc_middle(con, m); if (ret < 0) { - dout("alloc_middle failed, skipping payload\n"); + pr_err("alloc_middle fail skipping payload\n"); con->in_base_pos = -middle_len - data_len - sizeof(m->footer); ceph_msg_put(con->in_msg); @@ -1498,6 +1503,7 @@ more: set_bit(CONNECTING, &con->state); clear_bit(NEGOTIATING, &con->state); + BUG_ON(con->in_msg); con->in_tag = CEPH_MSGR_TAG_READY; dout("try_write initiating connect on %p new state %lu\n", con, con->state); -- cgit v0.10.2 From e2885f06ce31d82b556be021acfa2eba160f29cc Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 15 Dec 2009 10:27:48 -0800 Subject: ceph: make mds ops interruptible Signed-off-by: Sage Weil diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 29a93fe..d7cecc3 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -1597,14 +1597,17 @@ int ceph_mdsc_do_request(struct ceph_mds_client *mdsc, if (!req->r_reply) { mutex_unlock(&mdsc->mutex); if (req->r_timeout) { - err = wait_for_completion_timeout(&req->r_completion, - req->r_timeout); - if (err > 0) - err = 0; - else if (err == 0) + err = (long)wait_for_completion_interruptible_timeout( + &req->r_completion, req->r_timeout); + if (err == 0) req->r_reply = ERR_PTR(-EIO); + else if (err < 0) + req->r_reply = ERR_PTR(err); } else { - wait_for_completion(&req->r_completion); + err = wait_for_completion_interruptible( + &req->r_completion); + if (err) + req->r_reply = ERR_PTR(err); } mutex_lock(&mdsc->mutex); } -- cgit v0.10.2 From 06edf046dd68ccbc7cf5f70f957a31702d0e7596 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 15 Dec 2009 14:44:32 -0800 Subject: ceph: include link to bdi in debugfs Signed-off-by: Sage Weil diff --git a/fs/ceph/debugfs.c b/fs/ceph/debugfs.c index b90fc3e..441484a 100644 --- a/fs/ceph/debugfs.c +++ b/fs/ceph/debugfs.c @@ -1,5 +1,6 @@ #include "ceph_debug.h" +#include #include #include #include @@ -24,6 +25,7 @@ * .../monc - mon client state * .../dentry_lru - dump contents of dentry lru * .../caps - expose cap (reservation) stats + * .../bdi - symlink to ../../bdi/something */ static struct dentry *ceph_debugfs_dir; @@ -407,6 +409,10 @@ int ceph_debugfs_client_init(struct ceph_client *client) if (!client->debugfs_caps) goto out; + sprintf(name, "../../bdi/%s", dev_name(client->sb->s_bdi->dev)); + client->debugfs_bdi = debugfs_create_symlink("bdi", client->debugfs_dir, + name); + return 0; out: @@ -416,6 +422,7 @@ out: void ceph_debugfs_client_cleanup(struct ceph_client *client) { + debugfs_remove(client->debugfs_bdi); debugfs_remove(client->debugfs_caps); debugfs_remove(client->debugfs_dentry_lru); debugfs_remove(client->debugfs_osdmap); diff --git a/fs/ceph/super.h b/fs/ceph/super.h index de5e324..2304bd2 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -143,6 +143,7 @@ struct ceph_client { struct dentry *debugfs_monmap; struct dentry *debugfs_mdsmap, *debugfs_osdmap; struct dentry *debugfs_dir, *debugfs_dentry_lru, *debugfs_caps; + struct dentry *debugfs_bdi; #endif }; -- cgit v0.10.2 From 169e16ce816ca417286daf1db25de424a9d65a0c Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Wed, 16 Dec 2009 14:22:17 -0800 Subject: ceph: remove unaccessible code Signed-off-by: Yehuda Sadeh diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index b12604e..2e4e977 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -1531,10 +1531,6 @@ more_kvec: ret = write_partial_kvec(con); if (ret <= 0) goto done; - if (ret < 0) { - dout("try_write write_partial_kvec err %d\n", ret); - goto done; - } } /* msg pages? */ -- cgit v0.10.2 From dbd646a851713bec5bfff40ecf624b2e78518fe5 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Wed, 16 Dec 2009 14:51:06 -0800 Subject: ceph: writepage grabs and releases inode Fixes a deadlock that is triggered due to kswapd, while the page was locked and the iput couldn't tear down the address space. Signed-off-by: Yehuda Sadeh diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index bf53581..d0cdceb 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c @@ -448,8 +448,13 @@ out: static int ceph_writepage(struct page *page, struct writeback_control *wbc) { - int err = writepage_nounlock(page, wbc); + int err; + struct inode *inode = page->mapping->host; + BUG_ON(!inode); + igrab(inode); + err = writepage_nounlock(page, wbc); unlock_page(page); + iput(inode); return err; } -- cgit v0.10.2 From 2baba25019ec564cd247af74013873d69a0b8190 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Fri, 18 Dec 2009 13:51:57 -0800 Subject: ceph: writeback congestion control Set bdi congestion bit when amount of write data in flight exceeds adjustable threshold. Signed-off-by: Yehuda Sadeh Signed-off-by: Sage Weil diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index d0cdceb..a6850a1 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c @@ -47,6 +47,12 @@ * accounting is preserved. */ +#define CONGESTION_ON_THRESH(congestion_kb) (congestion_kb >> (PAGE_SHIFT-10)) +#define CONGESTION_OFF_THRESH(congestion_kb) \ + (CONGESTION_ON_THRESH(congestion_kb) - \ + (CONGESTION_ON_THRESH(congestion_kb) >> 2)) + + /* * Dirty a page. Optimistically adjust accounting, on the assumption @@ -377,6 +383,7 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc) { struct inode *inode; struct ceph_inode_info *ci; + struct ceph_client *client; struct ceph_osd_client *osdc; loff_t page_off = page->index << PAGE_CACHE_SHIFT; int len = PAGE_CACHE_SIZE; @@ -384,6 +391,7 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc) int err = 0; struct ceph_snap_context *snapc; u64 snap_size = 0; + long writeback_stat; dout("writepage %p idx %lu\n", page, page->index); @@ -393,7 +401,8 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc) } inode = page->mapping->host; ci = ceph_inode(inode); - osdc = &ceph_inode_to_client(inode)->osdc; + client = ceph_inode_to_client(inode); + osdc = &client->osdc; /* verify this is a writeable snap context */ snapc = (void *)page->private; @@ -420,6 +429,11 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc) dout("writepage %p page %p index %lu on %llu~%u\n", inode, page, page->index, page_off, len); + writeback_stat = atomic_long_inc_return(&client->writeback_count); + if (writeback_stat > + CONGESTION_ON_THRESH(client->mount_args->congestion_kb)) + set_bdi_congested(&client->backing_dev_info, BLK_RW_ASYNC); + set_page_writeback(page); err = ceph_osdc_writepages(osdc, ceph_vino(inode), &ci->i_layout, snapc, @@ -499,6 +513,8 @@ static void writepages_finish(struct ceph_osd_request *req, struct writeback_control *wbc = req->r_wbc; __s32 rc = -EIO; u64 bytes = 0; + struct ceph_client *client = ceph_inode_to_client(inode); + long writeback_stat; /* parse reply */ replyhead = msg->front.iov_base; @@ -524,6 +540,13 @@ static void writepages_finish(struct ceph_osd_request *req, BUG_ON(!page); WARN_ON(!PageUptodate(page)); + writeback_stat = + atomic_long_dec_return(&client->writeback_count); + if (writeback_stat < + CONGESTION_OFF_THRESH(client->mount_args->congestion_kb)) + clear_bdi_congested(&client->backing_dev_info, + BLK_RW_ASYNC); + if (i >= wrote) { dout("inode %p skipping page %p\n", inode, page); wbc->pages_skipped++; @@ -666,6 +689,7 @@ retry: u64 offset, len; struct ceph_osd_request_head *reqhead; struct ceph_osd_op *op; + long writeback_stat; next = 0; locked_pages = 0; @@ -773,6 +797,12 @@ get_more_pages: first = i; dout("%p will write page %p idx %lu\n", inode, page, page->index); + + writeback_stat = atomic_long_inc_return(&client->writeback_count); + if (writeback_stat > CONGESTION_ON_THRESH(client->mount_args->congestion_kb)) { + set_bdi_congested(&client->backing_dev_info, BLK_RW_ASYNC); + } + set_page_writeback(page); req->r_pages[locked_pages] = page; locked_pages++; @@ -998,7 +1028,8 @@ static int ceph_write_end(struct file *file, struct address_space *mapping, struct page *page, void *fsdata) { struct inode *inode = file->f_dentry->d_inode; - struct ceph_mds_client *mdsc = &ceph_inode_to_client(inode)->mdsc; + struct ceph_client *client = ceph_inode_to_client(inode); + struct ceph_mds_client *mdsc = &client->mdsc; unsigned from = pos & (PAGE_CACHE_SIZE - 1); int check_cap = 0; diff --git a/fs/ceph/debugfs.c b/fs/ceph/debugfs.c index 441484a..22d3b47 100644 --- a/fs/ceph/debugfs.c +++ b/fs/ceph/debugfs.c @@ -320,6 +320,30 @@ DEFINE_SHOW_FUNC(osdc_show) DEFINE_SHOW_FUNC(dentry_lru_show) DEFINE_SHOW_FUNC(caps_show) +static int congestion_kb_set(void *data, u64 val) +{ + struct ceph_client *client = (struct ceph_client *)data; + + if (client) + client->mount_args->congestion_kb = (int)val; + + return 0; +} + +static int congestion_kb_get(void *data, u64 *val) +{ + struct ceph_client *client = (struct ceph_client *)data; + + if (client) + *val = (u64)client->mount_args->congestion_kb; + + return 0; +} + + +DEFINE_SIMPLE_ATTRIBUTE(congestion_kb_fops, congestion_kb_get, + congestion_kb_set, "%llu\n"); + int __init ceph_debugfs_init(void) { ceph_debugfs_dir = debugfs_create_dir("ceph", NULL); @@ -409,6 +433,14 @@ int ceph_debugfs_client_init(struct ceph_client *client) if (!client->debugfs_caps) goto out; + client->debugfs_congestion_kb = debugfs_create_file("writeback_congestion_kb", + 0600, + client->debugfs_dir, + client, + &congestion_kb_fops); + if (!client->debugfs_congestion_kb) + goto out; + sprintf(name, "../../bdi/%s", dev_name(client->sb->s_bdi->dev)); client->debugfs_bdi = debugfs_create_symlink("bdi", client->debugfs_dir, name); @@ -431,6 +463,7 @@ void ceph_debugfs_client_cleanup(struct ceph_client *client) debugfs_remove(client->osdc.debugfs_file); debugfs_remove(client->mdsc.debugfs_file); debugfs_remove(client->monc.debugfs_file); + debugfs_remove(client->debugfs_congestion_kb); debugfs_remove(client->debugfs_dir); } diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 6d02a16..b9cb8ce 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -150,6 +150,35 @@ static void ceph_inode_init_once(void *foo) inode_init_once(&ci->vfs_inode); } +static int default_congestion_kb(void) +{ + int congestion_kb; + + /* + * Copied from NFS + * + * congestion size, scale with available memory. + * + * 64MB: 8192k + * 128MB: 11585k + * 256MB: 16384k + * 512MB: 23170k + * 1GB: 32768k + * 2GB: 46340k + * 4GB: 65536k + * 8GB: 92681k + * 16GB: 131072k + * + * This allows larger machines to have larger/more transfers. + * Limit the default to 256M + */ + congestion_kb = (16*int_sqrt(totalram_pages)) << (PAGE_SHIFT-10); + if (congestion_kb > 256*1024) + congestion_kb = 256*1024; + + return congestion_kb; +} + static int __init init_caches(void) { ceph_inode_cachep = kmem_cache_create("ceph_inode_info", @@ -267,6 +296,7 @@ enum { Opt_caps_wanted_delay_min, Opt_caps_wanted_delay_max, Opt_readdir_max_entries, + Opt_congestion_kb, Opt_last_int, /* int args above */ Opt_snapdirname, @@ -295,6 +325,7 @@ static match_table_t arg_tokens = { {Opt_caps_wanted_delay_min, "caps_wanted_delay_min=%d"}, {Opt_caps_wanted_delay_max, "caps_wanted_delay_max=%d"}, {Opt_readdir_max_entries, "readdir_max_entries=%d"}, + {Opt_congestion_kb, "write_congestion_kb=%d"}, /* int args above */ {Opt_snapdirname, "snapdirname=%s"}, {Opt_name, "name=%s"}, @@ -342,6 +373,7 @@ static struct ceph_mount_args *parse_mount_args(int flags, char *options, args->snapdir_name = kstrdup(CEPH_SNAPDIRNAME_DEFAULT, GFP_KERNEL); args->cap_release_safety = CEPH_CAPS_PER_RELEASE * 4; args->max_readdir = 1024; + args->congestion_kb = default_congestion_kb(); /* ip1[:port1][,ip2[:port2]...]:/subdir/in/fs */ err = -EINVAL; @@ -445,6 +477,9 @@ static struct ceph_mount_args *parse_mount_args(int flags, char *options, case Opt_readdir_max_entries: args->max_readdir = intval; break; + case Opt_congestion_kb: + args->congestion_kb = intval; + break; case Opt_noshare: args->flags |= CEPH_OPT_NOSHARE; @@ -516,6 +551,7 @@ static struct ceph_client *ceph_create_client(struct ceph_mount_args *args) client->msgr = NULL; client->mount_err = 0; + atomic_long_set(&client->writeback_count, 0); err = bdi_init(&client->backing_dev_info); if (err < 0) diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 2304bd2..62d9ae4 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -59,6 +59,7 @@ struct ceph_mount_args { int wsize; int rsize; /* max readahead */ int max_readdir; /* max readdir size */ + int congestion_kb; /* max readdir size */ int osd_timeout; char *snapdir_name; /* default ".snap" */ char *name; @@ -136,6 +137,7 @@ struct ceph_client { struct workqueue_struct *wb_wq; struct workqueue_struct *pg_inv_wq; struct workqueue_struct *trunc_wq; + atomic_long_t writeback_count; struct backing_dev_info backing_dev_info; @@ -143,6 +145,7 @@ struct ceph_client { struct dentry *debugfs_monmap; struct dentry *debugfs_mdsmap, *debugfs_osdmap; struct dentry *debugfs_dir, *debugfs_dentry_lru, *debugfs_caps; + struct dentry *debugfs_congestion_kb; struct dentry *debugfs_bdi; #endif }; -- cgit v0.10.2 From c4a29f26d50bea65809ca670992108a33aa2efa6 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 21 Dec 2009 11:42:18 -0800 Subject: ceph: ensure rename target dentry fails revalidation This works around a bug in vfs_rename_dir() that rehashes the target dentry. Ensure such dentries always fail revalidation by timing out the dentry lease and kicking it out of the current directory lease gen. This can be reverted when the vfs bug is fixed. Signed-off-by: Sage Weil diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index db68468..8774b28 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -939,6 +939,10 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req, req->r_old_dentry->d_name.len, req->r_old_dentry->d_name.name, dn, dn->d_name.len, dn->d_name.name); + /* ensure target dentry is invalidated, despite + rehashing bug in vfs_rename_dir */ + dn->d_time = jiffies; + ceph_dentry(dn)->lease_shared_gen = 0; /* take overwritten dentry's readdir offset */ ceph_dentry(req->r_old_dentry)->offset = ceph_dentry(dn)->offset; -- cgit v0.10.2 From 5de7bf8afa87f75af5ef3d6f9fce3e171cac834c Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 21 Dec 2009 11:48:44 -0800 Subject: ceph: do not drop lease during revalidate We need to hold session s_mutex for __ceph_mdsc_drop_dentry_lease(), which we don't, so skip it. It was purely an optimization. Signed-off-by: Sage Weil diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 89ce3ba..fde839c 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c @@ -920,8 +920,6 @@ static int dentry_lease_is_valid(struct dentry *dentry) di->lease_renew_after = 0; di->lease_renew_from = jiffies; } - } else { - __ceph_mdsc_drop_dentry_lease(dentry); } } spin_unlock(&dentry->d_lock); -- cgit v0.10.2 From 30dc6381bbac213987be6fe0b0fb89868ff1f2c0 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 21 Dec 2009 14:49:37 -0800 Subject: ceph: fix error paths for corrupt osdmap messages Both osdmap_decode() and osdmap_apply_incremental() should never return NULL. Signed-off-by: Sage Weil diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index 4bfe880..b474b3a 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -910,6 +910,7 @@ void ceph_osdc_handle_map(struct ceph_osd_client *osdc, struct ceph_msg *msg) err = PTR_ERR(newmap); goto bad; } + BUG_ON(!newmap); if (newmap != osdc->osdmap) { ceph_osdmap_destroy(osdc->osdmap); osdc->osdmap = newmap; @@ -946,6 +947,7 @@ void ceph_osdc_handle_map(struct ceph_osd_client *osdc, struct ceph_msg *msg) err = PTR_ERR(newmap); goto bad; } + BUG_ON(!newmap); oldmap = osdc->osdmap; osdc->osdmap = newmap; if (oldmap) diff --git a/fs/ceph/osdmap.c b/fs/ceph/osdmap.c index 8c8ffe5..a941630 100644 --- a/fs/ceph/osdmap.c +++ b/fs/ceph/osdmap.c @@ -200,6 +200,7 @@ static struct crush_map *crush_decode(void *pbyval, void *end) size = sizeof(struct crush_bucket_straw); break; default: + err = -EINVAL; goto bad; } BUG_ON(size == 0); @@ -278,6 +279,7 @@ static struct crush_map *crush_decode(void *pbyval, void *end) /* len */ ceph_decode_32_safe(p, end, yes, bad); #if BITS_PER_LONG == 32 + err = -EINVAL; if (yes > ULONG_MAX / sizeof(struct crush_rule_step)) goto bad; #endif @@ -489,11 +491,10 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end) ceph_decode_copy(p, &pgid, sizeof(pgid)); n = ceph_decode_32(p); ceph_decode_need(p, end, n * sizeof(u32), bad); + err = -ENOMEM; pg = kmalloc(sizeof(*pg) + n*sizeof(u32), GFP_NOFS); - if (!pg) { - err = -ENOMEM; + if (!pg) goto bad; - } pg->pgid = pgid; pg->len = n; for (j = 0; j < n; j++) @@ -564,8 +565,7 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, if (len > 0) { dout("apply_incremental full map len %d, %p to %p\n", len, *p, end); - newmap = osdmap_decode(p, min(*p+len, end)); - return newmap; /* error or not */ + return osdmap_decode(p, min(*p+len, end)); } /* new crush? */ @@ -809,6 +809,7 @@ int ceph_calc_object_layout(struct ceph_object_layout *ol, struct ceph_pg_pool_info *pool; unsigned ps; + BUG_ON(!osdmap); if (poolid >= osdmap->num_pools) return -EIO; -- cgit v0.10.2 From 7067f797b8409f1e10ec95ac2c1e17a200173d13 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 21 Dec 2009 16:02:37 -0800 Subject: ceph: fix incremental osdmap pg_temp decoding bug An incremental pg_temp wasn't being decoded properly (wrong bound on for loop). Also remove unused local variable, while we're at it. Signed-off-by: Sage Weil diff --git a/fs/ceph/osdmap.c b/fs/ceph/osdmap.c index a941630..0dbd606 100644 --- a/fs/ceph/osdmap.c +++ b/fs/ceph/osdmap.c @@ -538,7 +538,6 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, struct ceph_osdmap *map, struct ceph_messenger *msgr) { - struct ceph_osdmap *newmap = map; struct crush_map *newcrush = NULL; struct ceph_fsid fsid; u32 epoch = 0; @@ -701,7 +700,7 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, } pg->pgid = pgid; pg->len = pglen; - for (j = 0; j < len; j++) + for (j = 0; j < pglen; j++) pg->osds[j] = ceph_decode_32(p); err = __insert_pg_mapping(pg, &map->pg_temp); if (err) -- cgit v0.10.2 From 5dacf09121ffb2e5fc7d15b78cae0b77042a1935 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 21 Dec 2009 20:40:34 -0800 Subject: ceph: do not touch_caps while iterating over caps list Avoid confusing iterate_session_caps(), flag the session while we are iterating so that __touch_cap does not rearrange items on the list. All other modifiers of session->s_caps do so under the protection of s_mutex. Signed-off-by: Sage Weil diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index dfb509f..93c1afe 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -697,10 +697,15 @@ static void __touch_cap(struct ceph_cap *cap) { struct ceph_mds_session *s = cap->session; - dout("__touch_cap %p cap %p mds%d\n", &cap->ci->vfs_inode, cap, - s->s_mds); spin_lock(&s->s_cap_lock); - list_move_tail(&cap->session_caps, &s->s_caps); + if (!s->s_iterating_caps) { + dout("__touch_cap %p cap %p mds%d\n", &cap->ci->vfs_inode, cap, + s->s_mds); + list_move_tail(&cap->session_caps, &s->s_caps); + } else { + dout("__touch_cap %p cap %p mds%d NOP, iterating over caps\n", + &cap->ci->vfs_inode, cap, s->s_mds); + } spin_unlock(&s->s_cap_lock); } diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index d7cecc3..63ca3b1 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -337,10 +337,12 @@ static struct ceph_mds_session *register_session(struct ceph_mds_client *mdsc, s->s_renew_seq = 0; INIT_LIST_HEAD(&s->s_caps); s->s_nr_caps = 0; + s->s_trim_caps = 0; atomic_set(&s->s_ref, 1); INIT_LIST_HEAD(&s->s_waiting); INIT_LIST_HEAD(&s->s_unsafe); s->s_num_cap_releases = 0; + s->s_iterating_caps = false; INIT_LIST_HEAD(&s->s_cap_releases); INIT_LIST_HEAD(&s->s_cap_releases_done); INIT_LIST_HEAD(&s->s_cap_flushing); @@ -699,6 +701,7 @@ static int iterate_session_caps(struct ceph_mds_session *session, dout("iterate_session_caps %p mds%d\n", session, session->s_mds); spin_lock(&session->s_cap_lock); + session->s_iterating_caps = true; list_for_each_entry_safe(cap, ncap, &session->s_caps, session_caps) { inode = igrab(&cap->ci->vfs_inode); if (!inode) @@ -706,13 +709,15 @@ static int iterate_session_caps(struct ceph_mds_session *session, spin_unlock(&session->s_cap_lock); ret = cb(inode, cap, arg); iput(inode); - if (ret < 0) - return ret; spin_lock(&session->s_cap_lock); + if (ret < 0) + goto out; } + ret = 0; +out: + session->s_iterating_caps = false; spin_unlock(&session->s_cap_lock); - - return 0; + return ret; } static int remove_session_caps_cb(struct inode *inode, struct ceph_cap *cap, @@ -935,6 +940,7 @@ static int trim_caps(struct ceph_mds_client *mdsc, dout("trim_caps mds%d done: %d / %d, trimmed %d\n", session->s_mds, session->s_nr_caps, max_caps, trim_caps - session->s_trim_caps); + session->s_trim_caps = 0; } return 0; } diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h index 41af5ca..b1c2025 100644 --- a/fs/ceph/mds_client.h +++ b/fs/ceph/mds_client.h @@ -114,6 +114,7 @@ struct ceph_mds_session { int s_num_cap_releases; struct list_head s_cap_releases; /* waiting cap_release messages */ struct list_head s_cap_releases_done; /* ready to send */ + bool s_iterating_caps; /* protected by mutex */ struct list_head s_cap_flushing; /* inodes w/ flushing caps */ -- cgit v0.10.2 From e0e3271074e1ebd0b80a912a457ce03c971bcd66 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 21 Dec 2009 21:04:26 -0800 Subject: ceph: only unregister registered bdi Signed-off-by: Sage Weil diff --git a/fs/ceph/super.c b/fs/ceph/super.c index b9cb8ce..cd81c84 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -942,7 +942,8 @@ static void ceph_kill_sb(struct super_block *s) dout("kill_sb %p\n", s); ceph_mdsc_pre_umount(&client->mdsc); kill_anon_super(s); /* will call put_super after sb is r/o */ - bdi_unregister(&client->backing_dev_info); + if (s->s_bdi == &client->backing_dev_info) + bdi_unregister(&client->backing_dev_info); bdi_destroy(&client->backing_dev_info); ceph_destroy_client(client); } -- cgit v0.10.2 From 529cfcc46ffa2cbe4d07641c11e65f67fe7b66e4 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 22 Dec 2009 10:29:39 -0800 Subject: ceph: unregister canceled/timed out osd requests Canceled or timed out osd requests were getting left in the request list and never deallocated (until umount). Unregister if they are canceled (control-c) or time out. Signed-off-by: Sage Weil diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index b474b3a..a1800fb 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -1071,8 +1071,9 @@ int ceph_osdc_wait_request(struct ceph_osd_client *osdc, if (rc < 0) { mutex_lock(&osdc->request_mutex); __cancel_request(req); + __unregister_request(osdc, req); mutex_unlock(&osdc->request_mutex); - dout("wait_request tid %llu timed out\n", req->r_tid); + dout("wait_request tid %llu canceled/timed out\n", req->r_tid); return rc; } -- cgit v0.10.2 From ec302645f4a9bd9ec757c30d185557e1c0972c1a Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 22 Dec 2009 10:43:42 -0800 Subject: ceph: use connection mutex to protect read and write stages Use a single mutex (previously out_mutex) to protect both read and write activity from concurrent ceph_con_* calls. Drop the mutex when doing callbacks to avoid nested locking (the callback may need to call something like ceph_con_close). Signed-off-by: Sage Weil diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index 2e4e977..c03b418 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -316,7 +316,6 @@ static void reset_connection(struct ceph_connection *con) { /* reset connection, out_queue, msg_ and connect_seq */ /* discard existing out_queue and msg_seq */ - mutex_lock(&con->out_mutex); ceph_msg_remove_list(&con->out_queue); ceph_msg_remove_list(&con->out_sent); @@ -332,7 +331,6 @@ static void reset_connection(struct ceph_connection *con) con->out_msg = NULL; } con->in_seq = 0; - mutex_unlock(&con->out_mutex); } /* @@ -343,7 +341,9 @@ void ceph_con_close(struct ceph_connection *con) dout("con_close %p peer %s\n", con, pr_addr(&con->peer_addr.in_addr)); set_bit(CLOSED, &con->state); /* in case there's queued work */ clear_bit(STANDBY, &con->state); /* avoid connect_seq bump */ + mutex_lock(&con->mutex); reset_connection(con); + mutex_unlock(&con->mutex); queue_con(con); } @@ -392,7 +392,7 @@ void ceph_con_init(struct ceph_messenger *msgr, struct ceph_connection *con) memset(con, 0, sizeof(*con)); atomic_set(&con->nref, 1); con->msgr = msgr; - mutex_init(&con->out_mutex); + mutex_init(&con->mutex); INIT_LIST_HEAD(&con->out_queue); INIT_LIST_HEAD(&con->out_sent); INIT_DELAYED_WORK(&con->work, con_work); @@ -571,11 +571,13 @@ static void prepare_connect_authorizer(struct ceph_connection *con) int auth_len = 0; int auth_protocol = 0; + mutex_unlock(&con->mutex); if (con->ops->get_authorizer) con->ops->get_authorizer(con, &auth_buf, &auth_len, &auth_protocol, &con->auth_reply_buf, &con->auth_reply_buf_len, con->auth_retry); + mutex_lock(&con->mutex); con->out_connect.authorizer_protocol = cpu_to_le32(auth_protocol); con->out_connect.authorizer_len = cpu_to_le32(auth_len); @@ -1094,10 +1096,13 @@ static int process_connect(struct ceph_connection *con) le32_to_cpu(con->out_connect.protocol_version), le32_to_cpu(con->in_reply.protocol_version)); con->error_msg = "protocol version mismatch"; - if (con->ops->bad_proto) - con->ops->bad_proto(con); reset_connection(con); set_bit(CLOSED, &con->state); /* in case there's queued work */ + + mutex_unlock(&con->mutex); + if (con->ops->bad_proto) + con->ops->bad_proto(con); + mutex_lock(&con->mutex); return -1; case CEPH_MSGR_TAG_BADAUTHORIZER: @@ -1133,9 +1138,11 @@ static int process_connect(struct ceph_connection *con) prepare_read_connect(con); /* Tell ceph about it. */ + mutex_unlock(&con->mutex); pr_info("reset on %s%lld\n", ENTITY_NAME(con->peer_name)); if (con->ops->peer_reset) con->ops->peer_reset(con); + mutex_lock(&con->mutex); break; case CEPH_MSGR_TAG_RETRY_SESSION: @@ -1221,7 +1228,6 @@ static void process_ack(struct ceph_connection *con) u64 ack = le64_to_cpu(con->in_temp_ack); u64 seq; - mutex_lock(&con->out_mutex); while (!list_empty(&con->out_sent)) { m = list_first_entry(&con->out_sent, struct ceph_msg, list_head); @@ -1232,7 +1238,6 @@ static void process_ack(struct ceph_connection *con) le16_to_cpu(m->hdr.type), m); ceph_msg_remove(m); } - mutex_unlock(&con->out_mutex); prepare_read_tag(con); } @@ -1366,8 +1371,10 @@ static int read_partial_message(struct ceph_connection *con) /* find pages for data payload */ want = calc_pages_for(data_off & ~PAGE_MASK, data_len); ret = -1; + mutex_unlock(&con->mutex); if (con->ops->prepare_pages) ret = con->ops->prepare_pages(con, m, want); + mutex_lock(&con->mutex); if (ret < 0) { dout("%p prepare_pages failed, skipping payload\n", m); con->in_base_pos = -data_len - sizeof(m->footer); @@ -1454,9 +1461,8 @@ static void process_message(struct ceph_connection *con) if (con->peer_name.type == 0) con->peer_name = msg->hdr.src.name; - mutex_lock(&con->out_mutex); con->in_seq++; - mutex_unlock(&con->out_mutex); + mutex_unlock(&con->mutex); dout("===== %p %llu from %s%lld %d=%s len %d+%d (%u %u %u) =====\n", msg, le64_to_cpu(msg->hdr.seq), @@ -1467,6 +1473,8 @@ static void process_message(struct ceph_connection *con) le32_to_cpu(msg->hdr.data_len), con->in_front_crc, con->in_middle_crc, con->in_data_crc); con->ops->dispatch(con, msg); + + mutex_lock(&con->mutex); prepare_read_tag(con); } @@ -1483,7 +1491,7 @@ static int try_write(struct ceph_connection *con) dout("try_write start %p state %lu nref %d\n", con, con->state, atomic_read(&con->nref)); - mutex_lock(&con->out_mutex); + mutex_lock(&con->mutex); more: dout("try_write out_kvec_bytes %d\n", con->out_kvec_bytes); @@ -1576,7 +1584,7 @@ do_next: done: ret = 0; out: - mutex_unlock(&con->out_mutex); + mutex_unlock(&con->mutex); dout("try_write done on %p\n", con); return ret; } @@ -1600,6 +1608,8 @@ static int try_read(struct ceph_connection *con) dout("try_read start on %p\n", con); msgr = con->msgr; + mutex_lock(&con->mutex); + more: dout("try_read tag %d in_base_pos %d\n", (int)con->in_tag, con->in_base_pos); @@ -1693,6 +1703,7 @@ more: done: ret = 0; out: + mutex_unlock(&con->mutex); dout("try_read done on %p\n", con); return ret; @@ -1818,6 +1829,8 @@ static void ceph_fault(struct ceph_connection *con) clear_bit(BUSY, &con->state); /* to avoid an improbable race */ + mutex_lock(&con->mutex); + con_close_socket(con); if (con->in_msg) { @@ -1827,24 +1840,24 @@ static void ceph_fault(struct ceph_connection *con) /* If there are no messages in the queue, place the connection * in a STANDBY state (i.e., don't try to reconnect just yet). */ - mutex_lock(&con->out_mutex); if (list_empty(&con->out_queue) && !con->out_keepalive_pending) { dout("fault setting STANDBY\n"); set_bit(STANDBY, &con->state); - mutex_unlock(&con->out_mutex); + mutex_unlock(&con->mutex); goto out; } /* Requeue anything that hasn't been acked, and retry after a * delay. */ list_splice_init(&con->out_sent, &con->out_queue); - mutex_unlock(&con->out_mutex); if (con->delay == 0) con->delay = BASE_DELAY_INTERVAL; else if (con->delay < MAX_DELAY_INTERVAL) con->delay *= 2; + mutex_unlock(&con->mutex); + /* explicitly schedule work to try to reconnect again later. */ dout("fault queueing %p delay %lu\n", con, con->delay); con->ops->get(con); @@ -1920,7 +1933,7 @@ void ceph_con_send(struct ceph_connection *con, struct ceph_msg *msg) msg->hdr.dst_erank = con->peer_addr.erank; /* queue */ - mutex_lock(&con->out_mutex); + mutex_lock(&con->mutex); BUG_ON(!list_empty(&msg->list_head)); list_add_tail(&msg->list_head, &con->out_queue); dout("----- %p to %s%lld %d=%s len %d+%d+%d -----\n", msg, @@ -1929,7 +1942,7 @@ void ceph_con_send(struct ceph_connection *con, struct ceph_msg *msg) le32_to_cpu(msg->hdr.front_len), le32_to_cpu(msg->hdr.middle_len), le32_to_cpu(msg->hdr.data_len)); - mutex_unlock(&con->out_mutex); + mutex_unlock(&con->mutex); /* if there wasn't anything waiting to send before, queue * new work */ @@ -1942,7 +1955,7 @@ void ceph_con_send(struct ceph_connection *con, struct ceph_msg *msg) */ void ceph_con_revoke(struct ceph_connection *con, struct ceph_msg *msg) { - mutex_lock(&con->out_mutex); + mutex_lock(&con->mutex); if (!list_empty(&msg->list_head)) { dout("con_revoke %p msg %p\n", con, msg); list_del_init(&msg->list_head); @@ -1959,7 +1972,7 @@ void ceph_con_revoke(struct ceph_connection *con, struct ceph_msg *msg) } else { dout("con_revoke %p msg %p - not queued (sent?)\n", con, msg); } - mutex_unlock(&con->out_mutex); + mutex_unlock(&con->mutex); } /* diff --git a/fs/ceph/messenger.h b/fs/ceph/messenger.h index e04c214..94b55de 100644 --- a/fs/ceph/messenger.h +++ b/fs/ceph/messenger.h @@ -155,8 +155,9 @@ struct ceph_connection { void *auth_reply_buf; /* where to put the authorizer reply */ int auth_reply_buf_len; + struct mutex mutex; + /* out queue */ - struct mutex out_mutex; struct list_head out_queue; struct list_head out_sent; /* sending or sent but unacked */ u64 out_seq; /* last message queued for send */ -- cgit v0.10.2 From 350b1c32ea58d29e25d63fc25e92dd48f9339546 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 22 Dec 2009 10:45:45 -0800 Subject: ceph: control access to page vector for incoming data When we issue an OSD read, we specify a vector of pages that the data is to be read into. The request may be sent multiple times, to multiple OSDs, if the osdmap changes, which means we can get more than one reply. Only read data into the page vector if the reply is coming from the OSD we last sent the request to. Keep track of which connection is using the vector by taking a reference. If another connection was already using the vector before and a new reply comes in on the right connection, revoke the pages from the other connection. Signed-off-by: Sage Weil diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index c03b418..506b638 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -1976,6 +1976,35 @@ void ceph_con_revoke(struct ceph_connection *con, struct ceph_msg *msg) } /* + * Revoke a page vector that we may be reading data into + */ +void ceph_con_revoke_pages(struct ceph_connection *con, struct page **pages) +{ + mutex_lock(&con->mutex); + if (con->in_msg && con->in_msg->pages == pages) { + unsigned data_len = le32_to_cpu(con->in_hdr.data_len); + + /* skip rest of message */ + dout("con_revoke_pages %p msg %p pages %p revoked\n", con, + con->in_msg, pages); + if (con->in_msg_pos.data_pos < data_len) + con->in_base_pos = con->in_msg_pos.data_pos - data_len; + else + con->in_base_pos = con->in_base_pos - + sizeof(struct ceph_msg_header) - + sizeof(struct ceph_msg_footer); + con->in_msg->pages = NULL; + ceph_msg_put(con->in_msg); + con->in_msg = NULL; + con->in_tag = CEPH_MSGR_TAG_READY; + } else { + dout("con_revoke_pages %p msg %p pages %p no-op\n", + con, con->in_msg, pages); + } + mutex_unlock(&con->mutex); +} + +/* * Queue a keepalive byte to ensure the tcp connection is alive. */ void ceph_con_keepalive(struct ceph_connection *con) diff --git a/fs/ceph/messenger.h b/fs/ceph/messenger.h index 94b55de..7e2aab1 100644 --- a/fs/ceph/messenger.h +++ b/fs/ceph/messenger.h @@ -230,6 +230,8 @@ extern void ceph_con_open(struct ceph_connection *con, extern void ceph_con_close(struct ceph_connection *con); extern void ceph_con_send(struct ceph_connection *con, struct ceph_msg *msg); extern void ceph_con_revoke(struct ceph_connection *con, struct ceph_msg *msg); +extern void ceph_con_revoke_pages(struct ceph_connection *con, + struct page **pages); extern void ceph_con_keepalive(struct ceph_connection *con); extern struct ceph_connection *ceph_con_get(struct ceph_connection *con); extern void ceph_con_put(struct ceph_connection *con); diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index a1800fb..374f001 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -87,6 +87,13 @@ void ceph_osdc_release_request(struct kref *kref) ceph_msg_put(req->r_request); if (req->r_reply) ceph_msg_put(req->r_reply); + if (req->r_con_filling_pages) { + dout("release_request revoking pages %p from con %p\n", + req->r_pages, req->r_con_filling_pages); + ceph_con_revoke_pages(req->r_con_filling_pages, + req->r_pages); + ceph_con_put(req->r_con_filling_pages); + } if (req->r_own_pages) ceph_release_page_vector(req->r_pages, req->r_num_pages); @@ -687,7 +694,8 @@ static void handle_timeout(struct work_struct *work) * handle osd op reply. either call the callback if it is specified, * or do the completion to wake up the waiting thread. */ -static void handle_reply(struct ceph_osd_client *osdc, struct ceph_msg *msg) +static void handle_reply(struct ceph_osd_client *osdc, struct ceph_msg *msg, + struct ceph_connection *con) { struct ceph_osd_reply_head *rhead = msg->front.iov_base; struct ceph_osd_request *req; @@ -715,6 +723,16 @@ static void handle_reply(struct ceph_osd_client *osdc, struct ceph_msg *msg) ceph_osdc_get_request(req); flags = le32_to_cpu(rhead->flags); + /* + * if this connection filled our pages, drop our reference now, to + * avoid a (safe but slower) revoke later. + */ + if (req->r_con_filling_pages == con && req->r_pages == msg->pages) { + dout(" got pages, dropping con_filling_pages ref %p\n", con); + req->r_con_filling_pages = NULL; + ceph_con_put(con); + } + if (req->r_reply) { /* * once we see the message has been received, we don't @@ -1007,14 +1025,20 @@ static int prepare_pages(struct ceph_connection *con, struct ceph_msg *m, } dout("prepare_pages tid %llu has %d pages, want %d\n", tid, req->r_num_pages, want); - if (likely(req->r_num_pages >= want && !req->r_prepared_pages)) { - m->pages = req->r_pages; - m->nr_pages = req->r_num_pages; - req->r_reply = m; /* only for duration of read over socket */ - ceph_msg_get(m); - req->r_prepared_pages = 1; - ret = 0; /* success */ + if (unlikely(req->r_num_pages < want)) + goto out; + + if (req->r_con_filling_pages) { + dout("revoking pages %p from old con %p\n", req->r_pages, + req->r_con_filling_pages); + ceph_con_revoke_pages(req->r_con_filling_pages, req->r_pages); + ceph_con_put(req->r_con_filling_pages); } + req->r_con_filling_pages = ceph_con_get(con); + req->r_reply = ceph_msg_get(m); /* for duration of read over socket */ + m->pages = req->r_pages; + m->nr_pages = req->r_num_pages; + ret = 0; /* success */ out: mutex_unlock(&osdc->request_mutex); return ret; @@ -1269,7 +1293,7 @@ static void dispatch(struct ceph_connection *con, struct ceph_msg *msg) ceph_osdc_handle_map(osdc, msg); break; case CEPH_MSG_OSD_OPREPLY: - handle_reply(osdc, msg); + handle_reply(osdc, msg, con); break; default: diff --git a/fs/ceph/osd_client.h b/fs/ceph/osd_client.h index 2e4cfd1..8fef71c 100644 --- a/fs/ceph/osd_client.h +++ b/fs/ceph/osd_client.h @@ -43,11 +43,13 @@ struct ceph_osd_request { struct list_head r_osd_item; struct ceph_osd *r_osd; + struct ceph_connection *r_con_filling_pages; + struct ceph_msg *r_request, *r_reply; int r_result; int r_flags; /* any additional flags for the osd */ u32 r_sent; /* >0 if r_request is sending/sent */ - int r_prepared_pages, r_got_reply; + int r_got_reply; int r_num_prealloc_reply; struct ceph_osd_client *r_osdc; -- cgit v0.10.2 From 0cf90ab5b075821940873e73cdbfeb8edc3dabe8 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 22 Dec 2009 10:45:18 -0800 Subject: ceph: more informative msgpool errors Signed-off-by: Sage Weil diff --git a/fs/ceph/msgpool.c b/fs/ceph/msgpool.c index ad5482c..2f04e0f 100644 --- a/fs/ceph/msgpool.c +++ b/fs/ceph/msgpool.c @@ -140,7 +140,7 @@ struct ceph_msg *ceph_msgpool_get(struct ceph_msgpool *pool, int front_len) return msg; } pr_err("msgpool_get %p now %d/%d, %s\n", pool, pool->num, - pool->min, pool->blocking ? "waiting" : "failing"); + pool->min, pool->blocking ? "waiting" : "may fail"); spin_unlock(&pool->lock); if (!pool->blocking) { @@ -151,6 +151,7 @@ struct ceph_msg *ceph_msgpool_get(struct ceph_msgpool *pool, int front_len) if (!IS_ERR(msg)) return msg; + pr_err("msgpool_get %p empty + alloc failed\n", pool); return ERR_PTR(-ENOMEM); } -- cgit v0.10.2 From 6df058c025ce343052c5516b1d8a9a7e73cddd64 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 22 Dec 2009 11:24:33 -0800 Subject: ceph: include transaction id in ceph_msg_header (protocol change) Many (most?) message types include a transaction id. By including it in the fixed size header, we always have it available even when we are unable to allocate memory for the (larger, variable sized) message body. This will allow us to error out the appropriate request instead of (silently) dropping the reply. Signed-off-by: Sage Weil diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 93c1afe..847ae64 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -922,14 +922,14 @@ static int send_cap_msg(struct ceph_mds_session *session, if (IS_ERR(msg)) return PTR_ERR(msg); - fc = msg->front.iov_base; + msg->hdr.tid = cpu_to_le64(flush_tid); + fc = msg->front.iov_base; memset(fc, 0, sizeof(*fc)); fc->cap_id = cpu_to_le64(cid); fc->op = cpu_to_le32(op); fc->seq = cpu_to_le32(seq); - fc->client_tid = cpu_to_le64(flush_tid); fc->issue_seq = cpu_to_le32(issue_seq); fc->migrate_seq = cpu_to_le32(mseq); fc->caps = cpu_to_le32(caps); @@ -2329,7 +2329,7 @@ restart: * Handle FLUSH_ACK from MDS, indicating that metadata we sent to the * MDS has been safely committed. */ -static void handle_cap_flush_ack(struct inode *inode, +static void handle_cap_flush_ack(struct inode *inode, u64 flush_tid, struct ceph_mds_caps *m, struct ceph_mds_session *session, struct ceph_cap *cap) @@ -2340,7 +2340,6 @@ static void handle_cap_flush_ack(struct inode *inode, unsigned seq = le32_to_cpu(m->seq); int dirty = le32_to_cpu(m->dirty); int cleaned = 0; - u64 flush_tid = le64_to_cpu(m->client_tid); int drop = 0; int i; @@ -2396,13 +2395,12 @@ out: * * Caller hold s_mutex. */ -static void handle_cap_flushsnap_ack(struct inode *inode, +static void handle_cap_flushsnap_ack(struct inode *inode, u64 flush_tid, struct ceph_mds_caps *m, struct ceph_mds_session *session) { struct ceph_inode_info *ci = ceph_inode(inode); u64 follows = le64_to_cpu(m->snap_follows); - u64 flush_tid = le64_to_cpu(m->client_tid); struct ceph_cap_snap *capsnap; int drop = 0; @@ -2587,12 +2585,14 @@ void ceph_handle_caps(struct ceph_mds_session *session, struct ceph_vino vino; u64 cap_id; u64 size, max_size; + u64 tid; int check_caps = 0; int r; dout("handle_caps from mds%d\n", mds); /* decode */ + tid = le64_to_cpu(msg->hdr.tid); if (msg->front.iov_len < sizeof(*h)) goto bad; h = msg->front.iov_base; @@ -2621,7 +2621,7 @@ void ceph_handle_caps(struct ceph_mds_session *session, /* these will work even if we don't have a cap yet */ switch (op) { case CEPH_CAP_OP_FLUSHSNAP_ACK: - handle_cap_flushsnap_ack(inode, h, session); + handle_cap_flushsnap_ack(inode, tid, h, session); goto done; case CEPH_CAP_OP_EXPORT: @@ -2662,7 +2662,7 @@ void ceph_handle_caps(struct ceph_mds_session *session, break; case CEPH_CAP_OP_FLUSH_ACK: - handle_cap_flush_ack(inode, h, session, cap); + handle_cap_flush_ack(inode, tid, h, session, cap); break; case CEPH_CAP_OP_TRUNC: diff --git a/fs/ceph/ceph_fs.h b/fs/ceph/ceph_fs.h index e2fd024..e87dfa6 100644 --- a/fs/ceph/ceph_fs.h +++ b/fs/ceph/ceph_fs.h @@ -35,7 +35,7 @@ * internal cluster protocols separately from the public, * client-facing protocol. */ -#define CEPH_OSD_PROTOCOL 7 /* cluster internal */ +#define CEPH_OSD_PROTOCOL 8 /* cluster internal */ #define CEPH_MDS_PROTOCOL 9 /* cluster internal */ #define CEPH_MON_PROTOCOL 5 /* cluster internal */ #define CEPH_OSDC_PROTOCOL 22 /* server/client */ @@ -136,7 +136,6 @@ struct ceph_mon_request_header { struct ceph_mon_statfs { struct ceph_mon_request_header monhdr; struct ceph_fsid fsid; - __le64 tid; } __attribute__ ((packed)); struct ceph_statfs { @@ -146,7 +145,6 @@ struct ceph_statfs { struct ceph_mon_statfs_reply { struct ceph_fsid fsid; - __le64 tid; __le64 version; struct ceph_statfs st; } __attribute__ ((packed)); @@ -333,7 +331,7 @@ union ceph_mds_request_args { #define CEPH_MDS_FLAG_WANT_DENTRY 2 /* want dentry in reply */ struct ceph_mds_request_head { - __le64 tid, oldest_client_tid; + __le64 oldest_client_tid; __le32 mdsmap_epoch; /* on client */ __le32 flags; /* CEPH_MDS_FLAG_* */ __u8 num_retry, num_fwd; /* count retry, fwd attempts */ @@ -356,7 +354,6 @@ struct ceph_mds_request_release { /* client reply */ struct ceph_mds_reply_head { - __le64 tid; __le32 op; __le32 result; __le32 mdsmap_epoch; @@ -542,7 +539,6 @@ struct ceph_mds_caps { __le32 migrate_seq; __le64 snap_follows; __le32 snap_trace_len; - __le64 client_tid; /* for FLUSH(SNAP) -> FLUSH(SNAP)_ACK */ /* authlock */ __le32 uid, gid, mode; diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 63ca3b1..ec884e2 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -1339,6 +1339,8 @@ static struct ceph_msg *create_request_message(struct ceph_mds_client *mdsc, if (IS_ERR(msg)) goto out_free2; + msg->hdr.tid = cpu_to_le64(req->r_tid); + head = msg->front.iov_base; p = msg->front.iov_base + sizeof(*head); end = msg->front.iov_base + msg->front.iov_len; @@ -1431,7 +1433,6 @@ static int __prepare_send_request(struct ceph_mds_client *mdsc, req->r_request = msg; rhead = msg->front.iov_base; - rhead->tid = cpu_to_le64(req->r_tid); rhead->oldest_client_tid = cpu_to_le64(__get_oldest_tid(mdsc)); if (req->r_got_unsafe) flags |= CEPH_MDS_FLAG_REPLAY; @@ -1664,7 +1665,7 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg) } /* get request, session */ - tid = le64_to_cpu(head->tid); + tid = le64_to_cpu(msg->hdr.tid); mutex_lock(&mdsc->mutex); req = __lookup_request(mdsc, tid); if (!req) { diff --git a/fs/ceph/mon_client.c b/fs/ceph/mon_client.c index 775a9c0..bb94006 100644 --- a/fs/ceph/mon_client.c +++ b/fs/ceph/mon_client.c @@ -349,7 +349,7 @@ static void handle_statfs_reply(struct ceph_mon_client *monc, if (msg->front.iov_len != sizeof(*reply)) goto bad; - tid = le64_to_cpu(reply->tid); + tid = le64_to_cpu(msg->hdr.tid); dout("handle_statfs_reply %p tid %llu\n", msg, tid); mutex_lock(&monc->mutex); @@ -382,12 +382,12 @@ static int send_statfs(struct ceph_mon_client *monc, if (IS_ERR(msg)) return PTR_ERR(msg); req->request = msg; + msg->hdr.tid = cpu_to_le64(req->tid); h = msg->front.iov_base; h->monhdr.have_version = 0; h->monhdr.session_mon = cpu_to_le16(-1); h->monhdr.session_mon_tid = 0; h->fsid = monc->monmap->fsid; - h->tid = cpu_to_le64(req->tid); ceph_con_send(monc->con, msg); return 0; } diff --git a/fs/ceph/msgr.h b/fs/ceph/msgr.h index c758e8f..e46d8b8 100644 --- a/fs/ceph/msgr.h +++ b/fs/ceph/msgr.h @@ -21,7 +21,7 @@ * whenever the wire protocol changes. try to keep this string length * constant. */ -#define CEPH_BANNER "ceph v024" +#define CEPH_BANNER "ceph v025" #define CEPH_BANNER_MAX_LEN 30 @@ -132,6 +132,7 @@ struct ceph_msg_connect_reply { */ struct ceph_msg_header { __le64 seq; /* message seq# for this session */ + __le64 tid; /* transaction id */ __le16 type; /* message type */ __le16 priority; /* priority. higher value == higher priority */ __le16 version; /* version of message encoding */ diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index 374f001..a0aac43 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -439,11 +439,9 @@ static struct ceph_osd *__lookup_osd(struct ceph_osd_client *osdc, int o) static void register_request(struct ceph_osd_client *osdc, struct ceph_osd_request *req) { - struct ceph_osd_request_head *head = req->r_request->front.iov_base; - mutex_lock(&osdc->request_mutex); req->r_tid = ++osdc->last_tid; - head->tid = cpu_to_le64(req->r_tid); + req->r_request->hdr.tid = cpu_to_le64(req->r_tid); dout("register_request %p tid %lld\n", req, req->r_tid); __insert_request(osdc, req); @@ -702,9 +700,9 @@ static void handle_reply(struct ceph_osd_client *osdc, struct ceph_msg *msg, u64 tid; int numops, object_len, flags; + tid = le64_to_cpu(msg->hdr.tid); if (msg->front.iov_len < sizeof(*rhead)) goto bad; - tid = le64_to_cpu(rhead->tid); numops = le32_to_cpu(rhead->num_ops); object_len = le32_to_cpu(rhead->object_len); if (msg->front.iov_len != sizeof(*rhead) + object_len + @@ -1002,7 +1000,6 @@ static int prepare_pages(struct ceph_connection *con, struct ceph_msg *m, { struct ceph_osd *osd = con->private; struct ceph_osd_client *osdc; - struct ceph_osd_reply_head *rhead = m->front.iov_base; struct ceph_osd_request *req; u64 tid; int ret = -1; @@ -1016,7 +1013,7 @@ static int prepare_pages(struct ceph_connection *con, struct ceph_msg *m, if (unlikely(type != CEPH_MSG_OSD_OPREPLY)) return -1; /* hmm! */ - tid = le64_to_cpu(rhead->tid); + tid = le64_to_cpu(m->hdr.tid); mutex_lock(&osdc->request_mutex); req = __lookup_request(osdc, tid); if (!req) { diff --git a/fs/ceph/rados.h b/fs/ceph/rados.h index 12bfb2f..c5614d4 100644 --- a/fs/ceph/rados.h +++ b/fs/ceph/rados.h @@ -331,7 +331,6 @@ struct ceph_osd_op { * ceph_osd_op object operations. */ struct ceph_osd_request_head { - __le64 tid; /* transaction id */ __le32 client_inc; /* client incarnation */ struct ceph_object_layout layout; /* pgid */ __le32 osdmap_epoch; /* client's osdmap epoch */ @@ -352,7 +351,6 @@ struct ceph_osd_request_head { } __attribute__ ((packed)); struct ceph_osd_reply_head { - __le64 tid; /* transaction id */ __le32 client_inc; /* client incarnation */ __le32 flags; struct ceph_object_layout layout; -- cgit v0.10.2 From 04a419f908b5291ff7e8ffd7aa351fa0ac0c08af Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 23 Dec 2009 09:30:21 -0800 Subject: ceph: add feature bits to connection handshake (protocol change) Define supported and required feature set. Fail connection if the server requires features we do not support (TAG_FEATURES), or if the server does not support features we require. Signed-off-by: Sage Weil diff --git a/fs/ceph/ceph_fs.h b/fs/ceph/ceph_fs.h index e87dfa6..db3fed3 100644 --- a/fs/ceph/ceph_fs.h +++ b/fs/ceph/ceph_fs.h @@ -50,6 +50,12 @@ #define CEPH_MAX_MON 31 +/* + * feature bits + */ +#define CEPH_FEATURE_SUPPORTED 0 +#define CEPH_FEATURE_REQUIRED 0 + /* * ceph_file_layout - describe data layout for a file/inode diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index fde839c..5107384 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c @@ -1135,9 +1135,9 @@ void ceph_dentry_lru_add(struct dentry *dn) { struct ceph_dentry_info *di = ceph_dentry(dn); struct ceph_mds_client *mdsc; - dout("dentry_lru_add %p %p\t%.*s\n", - di, dn, dn->d_name.len, dn->d_name.name); + dout("dentry_lru_add %p %p '%.*s'\n", di, dn, + dn->d_name.len, dn->d_name.name); if (di) { mdsc = &ceph_client(dn->d_sb)->mdsc; spin_lock(&mdsc->dentry_lru_lock); @@ -1151,9 +1151,9 @@ void ceph_dentry_lru_touch(struct dentry *dn) { struct ceph_dentry_info *di = ceph_dentry(dn); struct ceph_mds_client *mdsc; - dout("dentry_lru_touch %p %p\t%.*s\n", - di, dn, dn->d_name.len, dn->d_name.name); + dout("dentry_lru_touch %p %p '%.*s'\n", di, dn, + dn->d_name.len, dn->d_name.name); if (di) { mdsc = &ceph_client(dn->d_sb)->mdsc; spin_lock(&mdsc->dentry_lru_lock); @@ -1167,8 +1167,8 @@ void ceph_dentry_lru_del(struct dentry *dn) struct ceph_dentry_info *di = ceph_dentry(dn); struct ceph_mds_client *mdsc; - dout("dentry_lru_del %p %p\t%.*s\n", - di, dn, dn->d_name.len, dn->d_name.name); + dout("dentry_lru_del %p %p '%.*s'\n", di, dn, + dn->d_name.len, dn->d_name.name); if (di) { mdsc = &ceph_client(dn->d_sb)->mdsc; spin_lock(&mdsc->dentry_lru_lock); diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index 506b638..68052f6 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -631,6 +631,7 @@ static void prepare_write_connect(struct ceph_messenger *msgr, dout("prepare_write_connect %p cseq=%d gseq=%d proto=%d\n", con, con->connect_seq, global_seq, proto); + con->out_connect.features = CEPH_FEATURE_SUPPORTED; con->out_connect.host_type = cpu_to_le32(CEPH_ENTITY_TYPE_CLIENT); con->out_connect.connect_seq = cpu_to_le32(con->connect_seq); con->out_connect.global_seq = cpu_to_le32(global_seq); @@ -1080,15 +1081,37 @@ static int process_banner(struct ceph_connection *con) return 0; } +static void fail_protocol(struct ceph_connection *con) +{ + reset_connection(con); + set_bit(CLOSED, &con->state); /* in case there's queued work */ + + mutex_unlock(&con->mutex); + if (con->ops->bad_proto) + con->ops->bad_proto(con); + mutex_lock(&con->mutex); +} + static int process_connect(struct ceph_connection *con) { + u64 sup_feat = CEPH_FEATURE_SUPPORTED; + u64 req_feat = CEPH_FEATURE_REQUIRED; + u64 server_feat = le64_to_cpu(con->in_reply.features); + dout("process_connect on %p tag %d\n", con, (int)con->in_tag); switch (con->in_reply.tag) { + case CEPH_MSGR_TAG_FEATURES: + pr_err("%s%lld %s feature set mismatch," + " my %llx < server's %llx, missing %llx\n", + ENTITY_NAME(con->peer_name), + pr_addr(&con->peer_addr.in_addr), + sup_feat, server_feat, server_feat & ~sup_feat); + con->error_msg = "missing required protocol features"; + fail_protocol(con); + return -1; + case CEPH_MSGR_TAG_BADPROTOVER: - dout("process_connect got BADPROTOVER my %d != their %d\n", - le32_to_cpu(con->out_connect.protocol_version), - le32_to_cpu(con->in_reply.protocol_version)); pr_err("%s%lld %s protocol version mismatch," " my %d != server's %d\n", ENTITY_NAME(con->peer_name), @@ -1096,13 +1119,7 @@ static int process_connect(struct ceph_connection *con) le32_to_cpu(con->out_connect.protocol_version), le32_to_cpu(con->in_reply.protocol_version)); con->error_msg = "protocol version mismatch"; - reset_connection(con); - set_bit(CLOSED, &con->state); /* in case there's queued work */ - - mutex_unlock(&con->mutex); - if (con->ops->bad_proto) - con->ops->bad_proto(con); - mutex_lock(&con->mutex); + fail_protocol(con); return -1; case CEPH_MSGR_TAG_BADAUTHORIZER: @@ -1173,6 +1190,16 @@ static int process_connect(struct ceph_connection *con) break; case CEPH_MSGR_TAG_READY: + if (req_feat & ~server_feat) { + pr_err("%s%lld %s protocol feature mismatch," + " my required %llx > server's %llx, need %llx\n", + ENTITY_NAME(con->peer_name), + pr_addr(&con->peer_addr.in_addr), + req_feat, server_feat, req_feat & ~server_feat); + con->error_msg = "missing required protocol features"; + fail_protocol(con); + return -1; + } clear_bit(CONNECTING, &con->state); con->peer_global_seq = le32_to_cpu(con->in_reply.global_seq); con->connect_seq++; diff --git a/fs/ceph/msgr.h b/fs/ceph/msgr.h index e46d8b8..be83f93 100644 --- a/fs/ceph/msgr.h +++ b/fs/ceph/msgr.h @@ -21,7 +21,7 @@ * whenever the wire protocol changes. try to keep this string length * constant. */ -#define CEPH_BANNER "ceph v025" +#define CEPH_BANNER "ceph v026" #define CEPH_BANNER_MAX_LEN 30 @@ -100,12 +100,14 @@ struct ceph_entity_inst { #define CEPH_MSGR_TAG_KEEPALIVE 9 /* just a keepalive byte! */ #define CEPH_MSGR_TAG_BADPROTOVER 10 /* bad protocol version */ #define CEPH_MSGR_TAG_BADAUTHORIZER 11 /* bad authorizer */ +#define CEPH_MSGR_TAG_FEATURES 12 /* insufficient features */ /* * connection negotiation */ struct ceph_msg_connect { + __le64 features; /* supported feature bits */ __le32 host_type; /* CEPH_ENTITY_TYPE_* */ __le32 global_seq; /* count connections initiated by this host */ __le32 connect_seq; /* count connections initiated in this session */ @@ -117,6 +119,7 @@ struct ceph_msg_connect { struct ceph_msg_connect_reply { __u8 tag; + __le64 features; /* feature bits for this session */ __le32 global_seq; __le32 connect_seq; __le32 protocol_version; -- cgit v0.10.2 From 58bb3b374b07a2a43315213f00a48a5ffd6d0915 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 23 Dec 2009 12:12:31 -0800 Subject: ceph: support ceph_pagelist for message payload The ceph_pagelist is a simple list of whole pages, strung together via their lru list_head. It facilitates encoding to a "buffer" of unknown size. Allow its use in place of the ceph_msg page vector. This will be used to fix the huge buffer preallocation woes of MDS reconnection. Signed-off-by: Sage Weil diff --git a/fs/ceph/Makefile b/fs/ceph/Makefile index 827629c8..47caf2f 100644 --- a/fs/ceph/Makefile +++ b/fs/ceph/Makefile @@ -8,7 +8,7 @@ obj-$(CONFIG_CEPH_FS) += ceph.o ceph-objs := super.o inode.o dir.o file.o addr.o ioctl.o \ export.o caps.o snap.o xattr.o \ - messenger.o msgpool.o buffer.o \ + messenger.o msgpool.o buffer.o pagelist.o \ mds_client.o mdsmap.o \ mon_client.o \ osd_client.o osdmap.o crush/crush.o crush/mapper.o crush/hash.o \ diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index 68052f6..c1106e8 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -13,6 +13,7 @@ #include "super.h" #include "messenger.h" #include "decode.h" +#include "pagelist.h" /* * Ceph uses the messenger to exchange ceph_msg messages with other @@ -728,6 +729,11 @@ static int write_partial_msg_pages(struct ceph_connection *con) page = msg->pages[con->out_msg_pos.page]; if (crc) kaddr = kmap(page); + } else if (msg->pagelist) { + page = list_first_entry(&msg->pagelist->head, + struct page, lru); + if (crc) + kaddr = kmap(page); } else { page = con->msgr->zero_page; if (crc) @@ -750,7 +756,7 @@ static int write_partial_msg_pages(struct ceph_connection *con) MSG_DONTWAIT | MSG_NOSIGNAL | MSG_MORE); - if (crc && msg->pages) + if (crc && (msg->pages || msg->pagelist)) kunmap(page); if (ret <= 0) @@ -762,6 +768,9 @@ static int write_partial_msg_pages(struct ceph_connection *con) con->out_msg_pos.page_pos = 0; con->out_msg_pos.page++; con->out_msg_pos.did_page_crc = 0; + if (msg->pagelist) + list_move_tail(&page->lru, + &msg->pagelist->head); } } @@ -1051,13 +1060,13 @@ static int process_banner(struct ceph_connection *con) &con->actual_peer_addr) && !(addr_is_blank(&con->actual_peer_addr.in_addr) && con->actual_peer_addr.nonce == con->peer_addr.nonce)) { - pr_err("wrong peer, want %s/%d, " - "got %s/%d, wtf\n", + pr_warning("wrong peer, want %s/%d, " + "got %s/%d\n", pr_addr(&con->peer_addr.in_addr), con->peer_addr.nonce, pr_addr(&con->actual_peer_addr.in_addr), con->actual_peer_addr.nonce); - con->error_msg = "protocol error, wrong peer"; + con->error_msg = "wrong peer at address"; return -1; } @@ -2096,6 +2105,7 @@ struct ceph_msg *ceph_msg_new(int type, int front_len, /* data */ m->nr_pages = calc_pages_for(page_off, page_len); m->pages = pages; + m->pagelist = NULL; dout("ceph_msg_new %p page %d~%d -> %d\n", m, page_off, page_len, m->nr_pages); @@ -2181,6 +2191,12 @@ void ceph_msg_last_put(struct kref *kref) m->nr_pages = 0; m->pages = NULL; + if (m->pagelist) { + ceph_pagelist_release(m->pagelist); + kfree(m->pagelist); + m->pagelist = NULL; + } + if (m->pool) ceph_msgpool_put(m->pool, m); else diff --git a/fs/ceph/messenger.h b/fs/ceph/messenger.h index 7e2aab1..a7b6841 100644 --- a/fs/ceph/messenger.h +++ b/fs/ceph/messenger.h @@ -85,6 +85,7 @@ struct ceph_msg { struct ceph_buffer *middle; struct page **pages; /* data payload. NOT OWNER. */ unsigned nr_pages; /* size of page array */ + struct ceph_pagelist *pagelist; /* instead of pages */ struct list_head list_head; struct kref kref; bool front_is_vmalloc; diff --git a/fs/ceph/pagelist.c b/fs/ceph/pagelist.c new file mode 100644 index 0000000..370e936 --- /dev/null +++ b/fs/ceph/pagelist.c @@ -0,0 +1,54 @@ + +#include +#include + +#include "pagelist.h" + +int ceph_pagelist_release(struct ceph_pagelist *pl) +{ + if (pl->mapped_tail) + kunmap(pl->mapped_tail); + while (!list_empty(&pl->head)) { + struct page *page = list_first_entry(&pl->head, struct page, + lru); + list_del(&page->lru); + __free_page(page); + } + return 0; +} + +static int ceph_pagelist_addpage(struct ceph_pagelist *pl) +{ + struct page *page = alloc_page(GFP_NOFS); + if (!page) + return -ENOMEM; + pl->room += PAGE_SIZE; + list_add_tail(&page->lru, &pl->head); + if (pl->mapped_tail) + kunmap(pl->mapped_tail); + pl->mapped_tail = kmap(page); + return 0; +} + +int ceph_pagelist_append(struct ceph_pagelist *pl, void *buf, size_t len) +{ + while (pl->room < len) { + size_t bit = pl->room; + int ret; + + memcpy(pl->mapped_tail + (pl->length & ~PAGE_CACHE_MASK), + buf, bit); + pl->length += bit; + pl->room -= bit; + buf += bit; + len -= bit; + ret = ceph_pagelist_addpage(pl); + if (ret) + return ret; + } + + memcpy(pl->mapped_tail + (pl->length & ~PAGE_CACHE_MASK), buf, len); + pl->length += len; + pl->room -= len; + return 0; +} diff --git a/fs/ceph/pagelist.h b/fs/ceph/pagelist.h new file mode 100644 index 0000000..e8a4187 --- /dev/null +++ b/fs/ceph/pagelist.h @@ -0,0 +1,54 @@ +#ifndef __FS_CEPH_PAGELIST_H +#define __FS_CEPH_PAGELIST_H + +#include + +struct ceph_pagelist { + struct list_head head; + void *mapped_tail; + size_t length; + size_t room; +}; + +static inline void ceph_pagelist_init(struct ceph_pagelist *pl) +{ + INIT_LIST_HEAD(&pl->head); + pl->mapped_tail = NULL; + pl->length = 0; + pl->room = 0; +} +extern int ceph_pagelist_release(struct ceph_pagelist *pl); + +extern int ceph_pagelist_append(struct ceph_pagelist *pl, void *d, size_t l); + +static inline int ceph_pagelist_encode_64(struct ceph_pagelist *pl, u64 v) +{ + __le64 ev = cpu_to_le64(v); + return ceph_pagelist_append(pl, &ev, sizeof(ev)); +} +static inline int ceph_pagelist_encode_32(struct ceph_pagelist *pl, u32 v) +{ + __le32 ev = cpu_to_le32(v); + return ceph_pagelist_append(pl, &ev, sizeof(ev)); +} +static inline int ceph_pagelist_encode_16(struct ceph_pagelist *pl, u16 v) +{ + __le16 ev = cpu_to_le16(v); + return ceph_pagelist_append(pl, &ev, sizeof(ev)); +} +static inline int ceph_pagelist_encode_8(struct ceph_pagelist *pl, u8 v) +{ + return ceph_pagelist_append(pl, &v, 1); +} +static inline int ceph_pagelist_encode_string(struct ceph_pagelist *pl, + char *s, size_t len) +{ + int ret = ceph_pagelist_encode_32(pl, len); + if (ret) + return ret; + if (len) + return ceph_pagelist_append(pl, s, len); + return 0; +} + +#endif -- cgit v0.10.2 From 93cea5bebf91319095db866163a7e35c3e77d8f2 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 23 Dec 2009 12:21:51 -0800 Subject: ceph: use ceph_pagelist for mds reconnect message; change encoding (protocol change) Use the ceph_pagelist to encode the MDS reconnect message. We change the message encoding (protocol change!) at the same time to make our life easier (we don't know how many snaprealms we have when we start encoding). An empty message implies the session is closed/does not exist. Signed-off-by: Sage Weil diff --git a/fs/ceph/ceph_fs.h b/fs/ceph/ceph_fs.h index db3fed3..d0f2557 100644 --- a/fs/ceph/ceph_fs.h +++ b/fs/ceph/ceph_fs.h @@ -39,7 +39,7 @@ #define CEPH_MDS_PROTOCOL 9 /* cluster internal */ #define CEPH_MON_PROTOCOL 5 /* cluster internal */ #define CEPH_OSDC_PROTOCOL 22 /* server/client */ -#define CEPH_MDSC_PROTOCOL 30 /* server/client */ +#define CEPH_MDSC_PROTOCOL 31 /* server/client */ #define CEPH_MONC_PROTOCOL 15 /* server/client */ diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index ec884e2..6e08f48 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -9,6 +9,7 @@ #include "messenger.h" #include "decode.h" #include "auth.h" +#include "pagelist.h" /* * A cluster of MDS (metadata server) daemons is responsible for @@ -1971,20 +1972,12 @@ static void replay_unsafe_requests(struct ceph_mds_client *mdsc, /* * Encode information about a cap for a reconnect with the MDS. */ -struct encode_caps_data { - void **pp; - void *end; - int *num_caps; -}; - static int encode_caps_cb(struct inode *inode, struct ceph_cap *cap, void *arg) { - struct ceph_mds_cap_reconnect *rec; + struct ceph_mds_cap_reconnect rec; struct ceph_inode_info *ci; - struct encode_caps_data *data = (struct encode_caps_data *)arg; - void *p = *(data->pp); - void *end = data->end; + struct ceph_pagelist *pagelist = arg; char *path; int pathlen, err; u64 pathbase; @@ -1995,8 +1988,9 @@ static int encode_caps_cb(struct inode *inode, struct ceph_cap *cap, dout(" adding %p ino %llx.%llx cap %p %lld %s\n", inode, ceph_vinop(inode), cap, cap->cap_id, ceph_cap_string(cap->issued)); - ceph_decode_need(&p, end, sizeof(u64), needmore); - ceph_encode_64(&p, ceph_ino(inode)); + err = ceph_pagelist_encode_64(pagelist, ceph_ino(inode)); + if (err) + return err; dentry = d_find_alias(inode); if (dentry) { @@ -2009,33 +2003,29 @@ static int encode_caps_cb(struct inode *inode, struct ceph_cap *cap, path = NULL; pathlen = 0; } - ceph_decode_need(&p, end, pathlen+4, needmore); - ceph_encode_string(&p, end, path, pathlen); + err = ceph_pagelist_encode_string(pagelist, path, pathlen); + if (err) + goto out; - ceph_decode_need(&p, end, sizeof(*rec), needmore); - rec = p; - p += sizeof(*rec); - BUG_ON(p > end); spin_lock(&inode->i_lock); cap->seq = 0; /* reset cap seq */ cap->issue_seq = 0; /* and issue_seq */ - rec->cap_id = cpu_to_le64(cap->cap_id); - rec->pathbase = cpu_to_le64(pathbase); - rec->wanted = cpu_to_le32(__ceph_caps_wanted(ci)); - rec->issued = cpu_to_le32(cap->issued); - rec->size = cpu_to_le64(inode->i_size); - ceph_encode_timespec(&rec->mtime, &inode->i_mtime); - ceph_encode_timespec(&rec->atime, &inode->i_atime); - rec->snaprealm = cpu_to_le64(ci->i_snap_realm->ino); + rec.cap_id = cpu_to_le64(cap->cap_id); + rec.pathbase = cpu_to_le64(pathbase); + rec.wanted = cpu_to_le32(__ceph_caps_wanted(ci)); + rec.issued = cpu_to_le32(cap->issued); + rec.size = cpu_to_le64(inode->i_size); + ceph_encode_timespec(&rec.mtime, &inode->i_mtime); + ceph_encode_timespec(&rec.atime, &inode->i_atime); + rec.snaprealm = cpu_to_le64(ci->i_snap_realm->ino); spin_unlock(&inode->i_lock); + err = ceph_pagelist_append(pagelist, &rec, sizeof(rec)); + +out: kfree(path); dput(dentry); - (*data->num_caps)++; - *(data->pp) = p; - return 0; -needmore: - return -ENOSPC; + return err; } @@ -2053,19 +2043,26 @@ needmore: */ static void send_mds_reconnect(struct ceph_mds_client *mdsc, int mds) { - struct ceph_mds_session *session; + struct ceph_mds_session *session = NULL; struct ceph_msg *reply; - int newlen, len = 4 + 1; - void *p, *end; int err; - int num_caps, num_realms = 0; int got; u64 next_snap_ino = 0; - __le32 *pnum_caps, *pnum_realms; - struct encode_caps_data iter_args; + struct ceph_pagelist *pagelist; pr_info("reconnect to recovering mds%d\n", mds); + pagelist = kmalloc(sizeof(*pagelist), GFP_NOFS); + if (!pagelist) + goto fail_nopagelist; + ceph_pagelist_init(pagelist); + + reply = ceph_msg_new(CEPH_MSG_CLIENT_RECONNECT, 0, 0, 0, NULL); + if (IS_ERR(reply)) { + err = PTR_ERR(reply); + goto fail_nomsg; + } + /* find session */ session = __ceph_lookup_mds_session(mdsc, mds); mutex_unlock(&mdsc->mutex); /* drop lock for duration */ @@ -2081,12 +2078,6 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc, int mds) /* replay unsafe requests */ replay_unsafe_requests(mdsc, session); - - /* estimate needed space */ - len += session->s_nr_caps * - (100+sizeof(struct ceph_mds_cap_reconnect)); - pr_info("estimating i need %d bytes for %d caps\n", - len, session->s_nr_caps); } else { dout("no session for mds%d, will send short reconnect\n", mds); @@ -2094,41 +2085,18 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc, int mds) down_read(&mdsc->snap_rwsem); -retry: - /* build reply */ - reply = ceph_msg_new(CEPH_MSG_CLIENT_RECONNECT, len, 0, 0, NULL); - if (IS_ERR(reply)) { - err = PTR_ERR(reply); - pr_err("send_mds_reconnect ENOMEM on %d for mds%d\n", - len, mds); - goto out; - } - p = reply->front.iov_base; - end = p + len; - - if (!session) { - ceph_encode_8(&p, 1); /* session was closed */ - ceph_encode_32(&p, 0); + if (!session) goto send; - } dout("session %p state %s\n", session, session_state_name(session->s_state)); /* traverse this session's caps */ - ceph_encode_8(&p, 0); - pnum_caps = p; - ceph_encode_32(&p, session->s_nr_caps); - num_caps = 0; - - iter_args.pp = &p; - iter_args.end = end; - iter_args.num_caps = &num_caps; - err = iterate_session_caps(session, encode_caps_cb, &iter_args); - if (err == -ENOSPC) - goto needmore; + err = ceph_pagelist_encode_32(pagelist, session->s_nr_caps); + if (err) + goto fail; + err = iterate_session_caps(session, encode_caps_cb, pagelist); if (err < 0) goto out; - *pnum_caps = cpu_to_le32(num_caps); /* * snaprealms. we provide mds with the ino, seq (version), and @@ -2136,14 +2104,9 @@ retry: * it will tell us. */ next_snap_ino = 0; - /* save some space for the snaprealm count */ - pnum_realms = p; - ceph_decode_need(&p, end, sizeof(*pnum_realms), needmore); - p += sizeof(*pnum_realms); - num_realms = 0; while (1) { struct ceph_snap_realm *realm; - struct ceph_mds_snaprealm_reconnect *sr_rec; + struct ceph_mds_snaprealm_reconnect sr_rec; got = radix_tree_gang_lookup(&mdsc->snap_realms, (void **)&realm, next_snap_ino, 1); if (!got) @@ -2151,22 +2114,19 @@ retry: dout(" adding snap realm %llx seq %lld parent %llx\n", realm->ino, realm->seq, realm->parent_ino); - ceph_decode_need(&p, end, sizeof(*sr_rec), needmore); - sr_rec = p; - sr_rec->ino = cpu_to_le64(realm->ino); - sr_rec->seq = cpu_to_le64(realm->seq); - sr_rec->parent = cpu_to_le64(realm->parent_ino); - p += sizeof(*sr_rec); - num_realms++; + sr_rec.ino = cpu_to_le64(realm->ino); + sr_rec.seq = cpu_to_le64(realm->seq); + sr_rec.parent = cpu_to_le64(realm->parent_ino); + err = ceph_pagelist_append(pagelist, &sr_rec, sizeof(sr_rec)); + if (err) + goto fail; next_snap_ino = realm->ino + 1; } - *pnum_realms = cpu_to_le32(num_realms); send: - reply->front.iov_len = p - reply->front.iov_base; - reply->hdr.front_len = cpu_to_le32(reply->front.iov_len); - dout("final len was %u (guessed %d)\n", - (unsigned)reply->front.iov_len, len); + reply->pagelist = pagelist; + reply->hdr.data_len = cpu_to_le32(pagelist->length); + reply->nr_pages = calc_pages_for(0, pagelist->length); ceph_con_send(&session->s_con, reply); if (session) { @@ -2183,18 +2143,14 @@ out: mutex_lock(&mdsc->mutex); return; -needmore: - /* - * we need a larger buffer. this doesn't very accurately - * factor in snap realms, but it's safe. - */ - num_caps += num_realms; - newlen = len * ((100 * (session->s_nr_caps+3)) / (num_caps + 1)) / 100; - pr_info("i guessed %d, and did %d of %d caps, retrying with %d\n", - len, num_caps, session->s_nr_caps, newlen); - len = newlen; +fail: ceph_msg_put(reply); - goto retry; +fail_nomsg: + ceph_pagelist_release(pagelist); + kfree(pagelist); +fail_nopagelist: + pr_err("ENOMEM preparing reconnect for mds%d\n", mds); + goto out; } -- cgit v0.10.2 From 9593bd07ec8eaaa30aba4281b2b3273282fc344f Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 24 Dec 2009 00:02:16 -0800 Subject: sony-laptop - remove private workqueue, use keventd instead If we reschedule work instead of having work function sleep for 10 msecs between reads from kfifo we can safely use the main workqueue (keventd) and not bother with creating driver-private one. Signed-off-by: Dmitry Torokhov Signed-off-by: Len Brown diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index 5af5334..c42d35b 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c @@ -145,7 +145,6 @@ struct sony_laptop_input_s { struct input_dev *key_dev; struct kfifo fifo; spinlock_t fifo_lock; - struct workqueue_struct *wq; }; static struct sony_laptop_input_s sony_laptop_input = { @@ -301,18 +300,28 @@ static int sony_laptop_input_keycode_map[] = { /* release buttons after a short delay if pressed */ static void do_sony_laptop_release_key(struct work_struct *work) { + struct delayed_work *dwork = + container_of(work, struct delayed_work, work); struct sony_laptop_keypress kp; + unsigned long flags; + + spin_lock_irqsave(&sony_laptop_input.fifo_lock, flags); - while (kfifo_out_locked(&sony_laptop_input.fifo, (unsigned char *)&kp, - sizeof(kp), &sony_laptop_input.fifo_lock) - == sizeof(kp)) { - msleep(10); + if (kfifo_out(&sony_laptop_input.fifo, + (unsigned char *)&kp, sizeof(kp)) == sizeof(kp)) { input_report_key(kp.dev, kp.key, 0); input_sync(kp.dev); } + + /* If there is something in the fifo schedule next release. */ + if (kfifo_len(&sony_laptop_input.fifo) != 0) + schedule_delayed_work(dwork, msecs_to_jiffies(10)); + + spin_unlock_irqrestore(&sony_laptop_input.fifo_lock, flags); } -static DECLARE_WORK(sony_laptop_release_key_work, - do_sony_laptop_release_key); + +static DECLARE_DELAYED_WORK(sony_laptop_release_key_work, + do_sony_laptop_release_key); /* forward event to the input subsystem */ static void sony_laptop_report_input_event(u8 event) @@ -366,13 +375,13 @@ static void sony_laptop_report_input_event(u8 event) /* we emit the scancode so we can always remap the key */ input_event(kp.dev, EV_MSC, MSC_SCAN, event); input_sync(kp.dev); - kfifo_in_locked(&sony_laptop_input.fifo, - (unsigned char *)&kp, sizeof(kp), - &sony_laptop_input.fifo_lock); - if (!work_pending(&sony_laptop_release_key_work)) - queue_work(sony_laptop_input.wq, - &sony_laptop_release_key_work); + /* schedule key release */ + kfifo_in_locked(&sony_laptop_input.fifo, + (unsigned char *)&kp, sizeof(kp), + &sony_laptop_input.fifo_lock); + schedule_delayed_work(&sony_laptop_release_key_work, + msecs_to_jiffies(10)); } else dprintk("unknown input event %.2x\n", event); } @@ -390,27 +399,18 @@ static int sony_laptop_setup_input(struct acpi_device *acpi_device) /* kfifo */ spin_lock_init(&sony_laptop_input.fifo_lock); - error = - kfifo_alloc(&sony_laptop_input.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL); + error = kfifo_alloc(&sony_laptop_input.fifo, + SONY_LAPTOP_BUF_SIZE, GFP_KERNEL); if (error) { printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n"); goto err_dec_users; } - /* init workqueue */ - sony_laptop_input.wq = create_singlethread_workqueue("sony-laptop"); - if (!sony_laptop_input.wq) { - printk(KERN_ERR DRV_PFX - "Unable to create workqueue.\n"); - error = -ENXIO; - goto err_free_kfifo; - } - /* input keys */ key_dev = input_allocate_device(); if (!key_dev) { error = -ENOMEM; - goto err_destroy_wq; + goto err_free_kfifo; } key_dev->name = "Sony Vaio Keys"; @@ -473,9 +473,6 @@ err_unregister_keydev: err_free_keydev: input_free_device(key_dev); -err_destroy_wq: - destroy_workqueue(sony_laptop_input.wq); - err_free_kfifo: kfifo_free(&sony_laptop_input.fifo); @@ -486,12 +483,23 @@ err_dec_users: static void sony_laptop_remove_input(void) { - /* cleanup only after the last user has gone */ + struct sony_laptop_keypress kp = { NULL }; + + /* Cleanup only after the last user has gone */ if (!atomic_dec_and_test(&sony_laptop_input.users)) return; - /* flush workqueue first */ - flush_workqueue(sony_laptop_input.wq); + cancel_delayed_work_sync(&sony_laptop_release_key_work); + + /* + * Generate key-up events for remaining keys. Note that we don't + * need locking since nobody is adding new events to the kfifo. + */ + while (kfifo_out(&sony_laptop_input.fifo, + (unsigned char *)&kp, sizeof(kp)) == sizeof(kp)) { + input_report_key(kp.dev, kp.key, 0); + input_sync(kp.dev); + } /* destroy input devs */ input_unregister_device(sony_laptop_input.key_dev); @@ -502,7 +510,6 @@ static void sony_laptop_remove_input(void) sony_laptop_input.jog_dev = NULL; } - destroy_workqueue(sony_laptop_input.wq); kfifo_free(&sony_laptop_input.fifo); } -- cgit v0.10.2 From c45bc9d62c39202b401d1bf7bb2812abb88798a1 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 24 Dec 2009 00:02:23 -0800 Subject: sony-laptop - simplify keymap initialization Also use input_set_capability() helper instead of manipulating bits directly. Signed-off-by: Dmitry Torokhov Signed-off-by: Len Brown diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index c42d35b..b7aa959 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c @@ -419,18 +419,15 @@ static int sony_laptop_setup_input(struct acpi_device *acpi_device) key_dev->dev.parent = &acpi_device->dev; /* Initialize the Input Drivers: special keys */ - set_bit(EV_KEY, key_dev->evbit); - set_bit(EV_MSC, key_dev->evbit); - set_bit(MSC_SCAN, key_dev->mscbit); + input_set_capability(key_dev, EV_MSC, MSC_SCAN); + + __set_bit(EV_KEY, key_dev->evbit); key_dev->keycodesize = sizeof(sony_laptop_input_keycode_map[0]); key_dev->keycodemax = ARRAY_SIZE(sony_laptop_input_keycode_map); key_dev->keycode = &sony_laptop_input_keycode_map; - for (i = 0; i < ARRAY_SIZE(sony_laptop_input_keycode_map); i++) { - if (sony_laptop_input_keycode_map[i] != KEY_RESERVED) { - set_bit(sony_laptop_input_keycode_map[i], - key_dev->keybit); - } - } + for (i = 0; i < ARRAY_SIZE(sony_laptop_input_keycode_map); i++) + __set_bit(sony_laptop_input_keycode_map[i], key_dev->keybit); + __clear_bit(KEY_RESERVED, key_dev->keybit); error = input_register_device(key_dev); if (error) @@ -450,9 +447,8 @@ static int sony_laptop_setup_input(struct acpi_device *acpi_device) jog_dev->id.vendor = PCI_VENDOR_ID_SONY; key_dev->dev.parent = &acpi_device->dev; - jog_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); - jog_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_MIDDLE); - jog_dev->relbit[0] = BIT_MASK(REL_WHEEL); + input_set_capability(jog_dev, EV_KEY, BTN_MIDDLE); + input_set_capability(jog_dev, EV_REL, REL_WHEEL); error = input_register_device(jog_dev); if (error) -- cgit v0.10.2 From cffdde993a016bedbc2f5eb60d00c3a766ffb612 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 24 Dec 2009 00:02:30 -0800 Subject: sony-laptop - switch from workqueue to a timer The function that is executing in workqueue context does not need to sleep so let's switch to a timer which is more lightweight. Signed-off-by: Dmitry Torokhov Signed-off-by: Len Brown diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index b7aa959..cc7172e 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c @@ -145,6 +145,7 @@ struct sony_laptop_input_s { struct input_dev *key_dev; struct kfifo fifo; spinlock_t fifo_lock; + struct timer_list release_key_timer; }; static struct sony_laptop_input_s sony_laptop_input = { @@ -298,10 +299,8 @@ static int sony_laptop_input_keycode_map[] = { }; /* release buttons after a short delay if pressed */ -static void do_sony_laptop_release_key(struct work_struct *work) +static void do_sony_laptop_release_key(unsigned long unused) { - struct delayed_work *dwork = - container_of(work, struct delayed_work, work); struct sony_laptop_keypress kp; unsigned long flags; @@ -315,14 +314,12 @@ static void do_sony_laptop_release_key(struct work_struct *work) /* If there is something in the fifo schedule next release. */ if (kfifo_len(&sony_laptop_input.fifo) != 0) - schedule_delayed_work(dwork, msecs_to_jiffies(10)); + mod_timer(&sony_laptop_input.release_key_timer, + jiffies + msecs_to_jiffies(10)); spin_unlock_irqrestore(&sony_laptop_input.fifo_lock, flags); } -static DECLARE_DELAYED_WORK(sony_laptop_release_key_work, - do_sony_laptop_release_key); - /* forward event to the input subsystem */ static void sony_laptop_report_input_event(u8 event) { @@ -380,8 +377,8 @@ static void sony_laptop_report_input_event(u8 event) kfifo_in_locked(&sony_laptop_input.fifo, (unsigned char *)&kp, sizeof(kp), &sony_laptop_input.fifo_lock); - schedule_delayed_work(&sony_laptop_release_key_work, - msecs_to_jiffies(10)); + mod_timer(&sony_laptop_input.release_key_timer, + jiffies + msecs_to_jiffies(10)); } else dprintk("unknown input event %.2x\n", event); } @@ -406,6 +403,9 @@ static int sony_laptop_setup_input(struct acpi_device *acpi_device) goto err_dec_users; } + setup_timer(&sony_laptop_input.release_key_timer, + do_sony_laptop_release_key, 0); + /* input keys */ key_dev = input_allocate_device(); if (!key_dev) { @@ -485,7 +485,7 @@ static void sony_laptop_remove_input(void) if (!atomic_dec_and_test(&sony_laptop_input.users)) return; - cancel_delayed_work_sync(&sony_laptop_release_key_work); + del_timer_sync(&sony_laptop_input.release_key_timer); /* * Generate key-up events for remaining keys. Note that we don't -- cgit v0.10.2 From 0c99c5288eb9b1bbc9684b0ec0fd7efc578749b3 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 17 Dec 2009 16:02:08 +0800 Subject: ACPI: Disable explicit power state retrieval on fans If the ACPI power state can be got both directly and indirectly, we prefer to get it indirectly. https://bugzilla.redhat.com/show_bug.cgi?id=531916 describes a system with a _PSC method for the fan that always returns "on". There's no benefit in us always requesting the state of the fan when performing transitions - we want to do everything we can to ensure that the fan turns on when it should do, not risk hardware damage by believing the hardware when it tells us the fan is already on. Given that the Leading Other OS(tm) works fine on this machine, it seems likely that it behaves in much this way. inspired-by: Matthew Garrett Signed-off-by: Zhang Rui Signed-off-by: Len Brown diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index cf761b9..ae9226d 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -190,16 +190,16 @@ int acpi_bus_get_power(acpi_handle handle, int *state) * Get the device's power state either directly (via _PSC) or * indirectly (via power resources). */ - if (device->power.flags.explicit_get) { + if (device->power.flags.power_resources) { + result = acpi_power_get_inferred_state(device); + if (result) + return result; + } else if (device->power.flags.explicit_get) { status = acpi_evaluate_integer(device->handle, "_PSC", NULL, &psc); if (ACPI_FAILURE(status)) return -ENODEV; device->power.state = (int)psc; - } else if (device->power.flags.power_resources) { - result = acpi_power_get_inferred_state(device); - if (result) - return result; } *state = device->power.state; -- cgit v0.10.2 From 6a4ef48103a78a46b80e07fcd8ac4edda0c7128f Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Thu, 31 Dec 2009 12:04:58 -0800 Subject: ceph: fix copy_user_to_page_vector() The function was broken in the case where there was more than one page involved, broke the ceph sync_write case. Signed-off-by: Yehuda Sadeh Signed-off-by: Sage Weil diff --git a/fs/ceph/file.c b/fs/ceph/file.c index fc8aff4..2d88c80 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -350,10 +350,10 @@ static int copy_user_to_page_vector(struct page **pages, return -EFAULT; data += l - bad; left -= l - bad; - if (po) { - po += l - bad; - if (po == PAGE_CACHE_SIZE) - po = 0; + po += l - bad; + if (po == PAGE_CACHE_SIZE) { + po = 0; + i++; } } return len; -- cgit v0.10.2 From 145434bee45bd353f9a93e9b411f7aa7cc677c08 Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Mon, 11 Jan 2010 13:46:31 +0000 Subject: uwb: wlp: refactor wlp_get_() macros Refactor the wlp_get_() macros to call a common function. This save over 4k of space and remove a spurious uninitialized variable warning with some versions of gcc. Signed-off-by: David Vrabel diff --git a/drivers/uwb/wlp/messages.c b/drivers/uwb/wlp/messages.c index aa42fce..7516486 100644 --- a/drivers/uwb/wlp/messages.c +++ b/drivers/uwb/wlp/messages.c @@ -259,6 +259,63 @@ out: } +static ssize_t wlp_get_attribute(struct wlp *wlp, u16 type_code, + struct wlp_attr_hdr *attr_hdr, void *value, ssize_t value_len, + ssize_t buflen) +{ + struct device *dev = &wlp->rc->uwb_dev.dev; + ssize_t attr_len = sizeof(*attr_hdr) + value_len; + if (buflen < 0) + return -EINVAL; + if (buflen < attr_len) { + dev_err(dev, "WLP: Not enough space in buffer to parse" + " attribute field. Need %d, received %zu\n", + (int)attr_len, buflen); + return -EIO; + } + if (wlp_check_attr_hdr(wlp, attr_hdr, type_code, value_len) < 0) { + dev_err(dev, "WLP: Header verification failed. \n"); + return -EINVAL; + } + memcpy(value, (void *)attr_hdr + sizeof(*attr_hdr), value_len); + return attr_len; +} + +static ssize_t wlp_vget_attribute(struct wlp *wlp, u16 type_code, + struct wlp_attr_hdr *attr_hdr, void *value, ssize_t max_value_len, + ssize_t buflen) +{ + struct device *dev = &wlp->rc->uwb_dev.dev; + size_t len; + if (buflen < 0) + return -EINVAL; + if (buflen < sizeof(*attr_hdr)) { + dev_err(dev, "WLP: Not enough space in buffer to parse" + " header.\n"); + return -EIO; + } + if (le16_to_cpu(attr_hdr->type) != type_code) { + dev_err(dev, "WLP: Unexpected attribute type. Got %u, " + "expected %u.\n", le16_to_cpu(attr_hdr->type), + type_code); + return -EINVAL; + } + len = le16_to_cpu(attr_hdr->length); + if (len > max_value_len) { + dev_err(dev, "WLP: Attribute larger than maximum " + "allowed. Received %zu, max is %d.\n", len, + (int)max_value_len); + return -EFBIG; + } + if (buflen < sizeof(*attr_hdr) + len) { + dev_err(dev, "WLP: Not enough space in buffer to parse " + "variable data.\n"); + return -EIO; + } + memcpy(value, (void *)attr_hdr + sizeof(*attr_hdr), len); + return sizeof(*attr_hdr) + len; +} + /** * Get value of attribute from fixed size attribute field. * @@ -274,22 +331,8 @@ out: ssize_t wlp_get_##name(struct wlp *wlp, struct wlp_attr_##name *attr, \ type *value, ssize_t buflen) \ { \ - struct device *dev = &wlp->rc->uwb_dev.dev; \ - if (buflen < 0) \ - return -EINVAL; \ - if (buflen < sizeof(*attr)) { \ - dev_err(dev, "WLP: Not enough space in buffer to parse" \ - " attribute field. Need %d, received %zu\n", \ - (int)sizeof(*attr), buflen); \ - return -EIO; \ - } \ - if (wlp_check_attr_hdr(wlp, &attr->hdr, type_code, \ - sizeof(attr->name)) < 0) { \ - dev_err(dev, "WLP: Header verification failed. \n"); \ - return -EINVAL; \ - } \ - *value = attr->name; \ - return sizeof(*attr); \ + return wlp_get_attribute(wlp, (type_code), &attr->hdr, \ + value, sizeof(*value), buflen); \ } #define wlp_get_sparse(type, type_code, name) \ @@ -313,35 +356,8 @@ static ssize_t wlp_get_##name(struct wlp *wlp, \ struct wlp_attr_##name *attr, \ type_val *value, ssize_t buflen) \ { \ - struct device *dev = &wlp->rc->uwb_dev.dev; \ - size_t len; \ - if (buflen < 0) \ - return -EINVAL; \ - if (buflen < sizeof(*attr)) { \ - dev_err(dev, "WLP: Not enough space in buffer to parse" \ - " header.\n"); \ - return -EIO; \ - } \ - if (le16_to_cpu(attr->hdr.type) != type_code) { \ - dev_err(dev, "WLP: Unexpected attribute type. Got %u, " \ - "expected %u.\n", le16_to_cpu(attr->hdr.type), \ - type_code); \ - return -EINVAL; \ - } \ - len = le16_to_cpu(attr->hdr.length); \ - if (len > max) { \ - dev_err(dev, "WLP: Attribute larger than maximum " \ - "allowed. Received %zu, max is %d.\n", len, \ - (int)max); \ - return -EFBIG; \ - } \ - if (buflen < sizeof(*attr) + len) { \ - dev_err(dev, "WLP: Not enough space in buffer to parse "\ - "variable data.\n"); \ - return -EIO; \ - } \ - memcpy(value, (void *) attr + sizeof(*attr), len); \ - return sizeof(*attr) + len; \ + return wlp_vget_attribute(wlp, (type_code), &attr->hdr, \ + value, (max), buflen); \ } wlp_get(u8, WLP_ATTR_WLP_VER, version) -- cgit v0.10.2 From 34446d05dd255b34518c76d2b8760161e63fe0c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20N=C3=A9meth?= Date: Tue, 12 Jan 2010 08:49:14 +0100 Subject: uwb: make USB device id table constant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The id_table field of the struct usb_device_id is constant in so it is worth to make the initialization data also constant. Signed-off-by: Márton Németh Signed-off-by: David Vrabel diff --git a/drivers/uwb/hwa-rc.c b/drivers/uwb/hwa-rc.c index e7eeb63..b409c228f 100644 --- a/drivers/uwb/hwa-rc.c +++ b/drivers/uwb/hwa-rc.c @@ -891,7 +891,7 @@ static int hwarc_post_reset(struct usb_interface *iface) } /** USB device ID's that we handle */ -static struct usb_device_id hwarc_id_table[] = { +static const struct usb_device_id hwarc_id_table[] = { /* D-Link DUB-1210 */ { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3d02, 0xe0, 0x01, 0x02), .driver_info = WUSB_QUIRK_WHCI_CMD_EVT }, diff --git a/drivers/uwb/i1480/dfu/usb.c b/drivers/uwb/i1480/dfu/usb.c index 0bb665a..08f9a7b 100644 --- a/drivers/uwb/i1480/dfu/usb.c +++ b/drivers/uwb/i1480/dfu/usb.c @@ -430,7 +430,7 @@ error: /** USB device ID's that we handle */ -static struct usb_device_id i1480_usb_id_table[] = { +static const struct usb_device_id i1480_usb_id_table[] = { i1480_USB_DEV(0x8086, 0xdf3b), i1480_USB_DEV(0x15a9, 0x0005), i1480_USB_DEV(0x07d1, 0x3802), -- cgit v0.10.2 From 35fb2a816a06ded2a3ff83d896c34b83c8e1d556 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 13 Jan 2010 23:41:50 +0000 Subject: uwb: declare MODULE_FIRMWARE() in i1480 DFU driver Signed-off-by: Ben Hutchings Signed-off-by: David Vrabel diff --git a/drivers/uwb/i1480/dfu/usb.c b/drivers/uwb/i1480/dfu/usb.c index 08f9a7b..a6a9375 100644 --- a/drivers/uwb/i1480/dfu/usb.c +++ b/drivers/uwb/i1480/dfu/usb.c @@ -413,6 +413,10 @@ error: return result; } +MODULE_FIRMWARE("i1480-pre-phy-0.0.bin"); +MODULE_FIRMWARE("i1480-usb-0.0.bin"); +MODULE_FIRMWARE("i1480-phy-0.0.bin"); + #define i1480_USB_DEV(v, p) \ { \ .match_flags = USB_DEVICE_ID_MATCH_DEVICE \ -- cgit v0.10.2 From 4baa75ef0ed29adae03fcbbaa9aca1511a5a8cc9 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Thu, 7 Jan 2010 15:36:32 -0800 Subject: ceph: change dentry offset and position after splice_dentry This fixes a bug, where we had the parent list have dentries with offsets that are not monotonically increasing, which caused the ceph dcache_readdir to skip entries. Signed-off-by: Yehuda Sadeh Signed-off-by: Sage Weil diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 8774b28..518beb6 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -817,6 +817,33 @@ out: } /* + * Set dentry's directory position based on the current dir's max, and + * order it in d_subdirs, so that dcache_readdir behaves. + */ +static void ceph_set_dentry_offset(struct dentry *dn) +{ + struct dentry *dir = dn->d_parent; + struct inode *inode = dn->d_parent->d_inode; + struct ceph_dentry_info *di; + + BUG_ON(!inode); + + di = ceph_dentry(dn); + + spin_lock(&inode->i_lock); + di->offset = ceph_inode(inode)->i_max_offset++; + spin_unlock(&inode->i_lock); + + spin_lock(&dcache_lock); + spin_lock(&dn->d_lock); + list_move_tail(&dir->d_subdirs, &dn->d_u.d_child); + dout("set_dentry_offset %p %lld (%p %p)\n", dn, di->offset, + dn->d_u.d_child.prev, dn->d_u.d_child.next); + spin_unlock(&dn->d_lock); + spin_unlock(&dcache_lock); +} + +/* * Incorporate results into the local cache. This is either just * one inode, or a directory, dentry, and possibly linked-to inode (e.g., * after a lookup). @@ -987,6 +1014,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req, goto done; } req->r_dentry = dn; /* may have spliced */ + ceph_set_dentry_offset(dn); igrab(in); } else if (ceph_ino(in) == vino.ino && ceph_snap(in) == vino.snap) { @@ -1029,6 +1057,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req, err = PTR_ERR(dn); goto done; } + ceph_set_dentry_offset(dn); req->r_dentry = dn; /* may have spliced */ igrab(in); rinfo->head->is_dentry = 1; /* fool notrace handlers */ -- cgit v0.10.2 From 103e2d3ae57d38d18aaac1b327266c1407499ac1 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 7 Jan 2010 16:12:36 -0800 Subject: ceph: remove unused erank field The ceph_entity_addr erank field is obsolete; remove it. Get rid of trivial addr comparison helpers while we're at it. Signed-off-by: Sage Weil diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index c1106e8..1360708 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -1056,16 +1056,15 @@ static int process_banner(struct ceph_connection *con) * end may not yet know their ip address, so if it's 0.0.0.0, give * them the benefit of the doubt. */ - if (!ceph_entity_addr_is_local(&con->peer_addr, - &con->actual_peer_addr) && + if (memcmp(&con->peer_addr, &con->actual_peer_addr, + sizeof(con->peer_addr)) != 0 && !(addr_is_blank(&con->actual_peer_addr.in_addr) && con->actual_peer_addr.nonce == con->peer_addr.nonce)) { - pr_warning("wrong peer, want %s/%d, " - "got %s/%d\n", - pr_addr(&con->peer_addr.in_addr), - con->peer_addr.nonce, - pr_addr(&con->actual_peer_addr.in_addr), - con->actual_peer_addr.nonce); + pr_warning("wrong peer, want %s/%lld, got %s/%lld\n", + pr_addr(&con->peer_addr.in_addr), + le64_to_cpu(con->peer_addr.nonce), + pr_addr(&con->actual_peer_addr.in_addr), + le64_to_cpu(con->actual_peer_addr.nonce)); con->error_msg = "wrong peer at address"; return -1; } @@ -1934,8 +1933,7 @@ struct ceph_messenger *ceph_messenger_create(struct ceph_entity_addr *myaddr) msgr->inst.addr = *myaddr; /* select a random nonce */ - get_random_bytes(&msgr->inst.addr.nonce, - sizeof(msgr->inst.addr.nonce)); + get_random_bytes(&msgr->inst.addr.nonce, sizeof(msgr->inst.addr.nonce)); encode_my_addr(msgr); dout("messenger_create %p\n", msgr); @@ -1966,7 +1964,6 @@ void ceph_con_send(struct ceph_connection *con, struct ceph_msg *msg) msg->hdr.src.name = con->msgr->inst.name; msg->hdr.src.addr = con->msgr->my_enc_addr; msg->hdr.orig_src = msg->hdr.src; - msg->hdr.dst_erank = con->peer_addr.erank; /* queue */ mutex_lock(&con->mutex); diff --git a/fs/ceph/mon_client.c b/fs/ceph/mon_client.c index bb94006..223e8bc 100644 --- a/fs/ceph/mon_client.c +++ b/fs/ceph/mon_client.c @@ -88,7 +88,7 @@ int ceph_monmap_contains(struct ceph_monmap *m, struct ceph_entity_addr *addr) int i; for (i = 0; i < m->num_mon; i++) - if (ceph_entity_addr_equal(addr, &m->mon_inst[i].addr)) + if (memcmp(addr, &m->mon_inst[i].addr, sizeof(*addr)) == 0) return 1; return 0; } @@ -503,7 +503,6 @@ static int build_initial_monmap(struct ceph_mon_client *monc) return -ENOMEM; for (i = 0; i < num_mon; i++) { monc->monmap->mon_inst[i].addr = mon_addr[i]; - monc->monmap->mon_inst[i].addr.erank = 0; monc->monmap->mon_inst[i].addr.nonce = 0; monc->monmap->mon_inst[i].name.type = CEPH_ENTITY_TYPE_MON; diff --git a/fs/ceph/msgr.h b/fs/ceph/msgr.h index be83f93..40b6189 100644 --- a/fs/ceph/msgr.h +++ b/fs/ceph/msgr.h @@ -61,24 +61,10 @@ extern const char *ceph_entity_type_name(int type); * entity_addr -- network address */ struct ceph_entity_addr { - __le32 erank; /* entity's rank in process */ - __le32 nonce; /* unique id for process (e.g. pid) */ + __le64 nonce; /* unique id for process (e.g. pid) */ struct sockaddr_storage in_addr; } __attribute__ ((packed)); -static inline bool ceph_entity_addr_is_local(const struct ceph_entity_addr *a, - const struct ceph_entity_addr *b) -{ - return a->nonce == b->nonce && - memcmp(&a->in_addr, &b->in_addr, sizeof(a->in_addr)) == 0; -} - -static inline bool ceph_entity_addr_equal(const struct ceph_entity_addr *a, - const struct ceph_entity_addr *b) -{ - return memcmp(a, b, sizeof(*a)) == 0; -} - struct ceph_entity_inst { struct ceph_entity_name name; struct ceph_entity_addr addr; @@ -147,7 +133,7 @@ struct ceph_msg_header { receiver: mask against ~PAGE_MASK */ struct ceph_entity_inst src, orig_src; - __le32 dst_erank; + __le32 reserved; __le32 crc; /* header crc32c */ } __attribute__ ((packed)); diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index a0aac43..80b868f 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -821,9 +821,10 @@ static void kick_requests(struct ceph_osd_client *osdc, n = rb_next(p); if (!ceph_osd_is_up(osdc->osdmap, osd->o_osd) || - !ceph_entity_addr_equal(&osd->o_con.peer_addr, - ceph_osd_addr(osdc->osdmap, - osd->o_osd))) + memcmp(&osd->o_con.peer_addr, + ceph_osd_addr(osdc->osdmap, + osd->o_osd), + sizeof(struct ceph_entity_addr)) != 0) reset_osd(osdc, osd); } } -- cgit v0.10.2 From 7740a42f816790583bd8a9079337772d511af3a3 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 8 Jan 2010 15:58:25 -0800 Subject: ceph: display pgid in debugfs osd request dump Signed-off-by: Sage Weil diff --git a/fs/ceph/debugfs.c b/fs/ceph/debugfs.c index 22d3b47..fba44b2 100644 --- a/fs/ceph/debugfs.c +++ b/fs/ceph/debugfs.c @@ -231,8 +231,10 @@ static int osdc_show(struct seq_file *s, void *pp) req = rb_entry(p, struct ceph_osd_request, r_node); - seq_printf(s, "%lld\tosd%d\t", req->r_tid, - req->r_osd ? req->r_osd->o_osd : -1); + seq_printf(s, "%lld\tosd%d\t%d.%x\t", req->r_tid, + req->r_osd ? req->r_osd->o_osd : -1, + le32_to_cpu(req->r_pgid.pool), + le16_to_cpu(req->r_pgid.ps)); head = req->r_request->front.iov_base; op = (void *)(head + 1); diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index 80b868f..8417e21 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -538,6 +538,8 @@ static int __map_osds(struct ceph_osd_client *osdc, if (err) return err; pgid = reqhead->layout.ol_pgid; + req->r_pgid = pgid; + o = ceph_calc_pg_primary(osdc->osdmap, pgid); if ((req->r_osd && req->r_osd->o_osd == o && diff --git a/fs/ceph/osd_client.h b/fs/ceph/osd_client.h index 8fef71c..4162c68 100644 --- a/fs/ceph/osd_client.h +++ b/fs/ceph/osd_client.h @@ -42,6 +42,7 @@ struct ceph_osd_request { struct rb_node r_node; struct list_head r_osd_item; struct ceph_osd *r_osd; + struct ceph_pg r_pgid; struct ceph_connection *r_con_filling_pages; -- cgit v0.10.2 From 7b3bcc4a1a7cd2d53b403ca29d06ceb5fa617eb7 Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Thu, 15 Oct 2009 14:31:24 +0400 Subject: ACPI: Battery: Add bit flags Signed-off-by: Alexey Starikovskiy Signed-off-by: Len Brown diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index cada73f..b2b48f8 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -88,10 +88,13 @@ static const struct acpi_device_id battery_device_ids[] = { MODULE_DEVICE_TABLE(acpi, battery_device_ids); -/* For buggy DSDTs that report negative 16-bit values for either charging - * or discharging current and/or report 0 as 65536 due to bad math. - */ -#define QUIRK_SIGNED16_CURRENT 0x0001 +enum { + ACPI_BATTERY_ALARM_PRESENT, + /* For buggy DSDTs that report negative 16-bit values for either charging + * or discharging current and/or report 0 as 65536 due to bad math. + */ + ACPI_BATTERY_QUIRK_SIGNED16_CURRENT, +}; struct acpi_battery { struct mutex lock; @@ -118,8 +121,7 @@ struct acpi_battery { char oem_info[32]; int state; int power_unit; - u8 alarm_present; - long quirks; + unsigned long flags; }; #define to_acpi_battery(x) container_of(x, struct acpi_battery, bat); @@ -399,7 +401,7 @@ static int acpi_battery_get_state(struct acpi_battery *battery) battery->update_time = jiffies; kfree(buffer.pointer); - if ((battery->quirks & QUIRK_SIGNED16_CURRENT) && + if (test_bit(ACPI_BATTERY_QUIRK_SIGNED16_CURRENT, &battery->flags) && battery->rate_now != -1) battery->rate_now = abs((s16)battery->rate_now); @@ -412,7 +414,8 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery) union acpi_object arg0 = { .type = ACPI_TYPE_INTEGER }; struct acpi_object_list arg_list = { 1, &arg0 }; - if (!acpi_battery_present(battery)|| !battery->alarm_present) + if (!acpi_battery_present(battery)|| + !test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags)) return -ENODEV; arg0.integer.value = battery->alarm; @@ -437,10 +440,10 @@ static int acpi_battery_init_alarm(struct acpi_battery *battery) /* See if alarms are supported, and if so, set default */ status = acpi_get_handle(battery->device->handle, "_BTP", &handle); if (ACPI_FAILURE(status)) { - battery->alarm_present = 0; + clear_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags); return 0; } - battery->alarm_present = 1; + set_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags); if (!battery->alarm) battery->alarm = battery->design_capacity_warning; return acpi_battery_set_alarm(battery); @@ -510,9 +513,8 @@ static void sysfs_remove_battery(struct acpi_battery *battery) static void acpi_battery_quirks(struct acpi_battery *battery) { - battery->quirks = 0; if (dmi_name_in_vendors("Acer") && battery->power_unit) { - battery->quirks |= QUIRK_SIGNED16_CURRENT; + set_bit(ACPI_BATTERY_QUIRK_SIGNED16_CURRENT, &battery->flags); } } -- cgit v0.10.2 From c955fe8e0bdd7be7a6bc2d49245d570a816f7cc5 Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Thu, 15 Oct 2009 14:31:30 +0400 Subject: POWER: Add support for cycle_count Signed-off-by: Alexey Starikovskiy Signed-off-by: Len Brown diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c index c790e0c..ff05e61 100644 --- a/drivers/power/power_supply_sysfs.c +++ b/drivers/power/power_supply_sysfs.c @@ -99,6 +99,7 @@ static struct device_attribute power_supply_attrs[] = { POWER_SUPPLY_ATTR(present), POWER_SUPPLY_ATTR(online), POWER_SUPPLY_ATTR(technology), + POWER_SUPPLY_ATTR(cycle_count), POWER_SUPPLY_ATTR(voltage_max), POWER_SUPPLY_ATTR(voltage_min), POWER_SUPPLY_ATTR(voltage_max_design), diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h index b5d096d..ebd2b8f 100644 --- a/include/linux/power_supply.h +++ b/include/linux/power_supply.h @@ -82,6 +82,7 @@ enum power_supply_property { POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_ONLINE, POWER_SUPPLY_PROP_TECHNOLOGY, + POWER_SUPPLY_PROP_CYCLE_COUNT, POWER_SUPPLY_PROP_VOLTAGE_MAX, POWER_SUPPLY_PROP_VOLTAGE_MIN, POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, -- cgit v0.10.2 From 16698857fba1b10af4890055272975adf5686e83 Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Thu, 15 Oct 2009 14:31:37 +0400 Subject: ACPI: SBS: Export cycle_count Signed-off-by: Alexey Starikovskiy Signed-off-by: Len Brown diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index 52b9db8..38412ec 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c @@ -217,6 +217,9 @@ static int acpi_sbs_battery_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_TECHNOLOGY: val->intval = acpi_battery_technology(battery); break; + case POWER_SUPPLY_PROP_CYCLE_COUNT: + val->intval = battery->cycle_count; + break; case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: val->intval = battery->design_voltage * acpi_battery_vscale(battery) * 1000; @@ -276,6 +279,7 @@ static enum power_supply_property sbs_charge_battery_props[] = { POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_TECHNOLOGY, + POWER_SUPPLY_PROP_CYCLE_COUNT, POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, POWER_SUPPLY_PROP_VOLTAGE_NOW, POWER_SUPPLY_PROP_CURRENT_NOW, @@ -560,6 +564,7 @@ static int acpi_battery_read_info(struct seq_file *seq, void *offset) battery->design_voltage * acpi_battery_vscale(battery)); seq_printf(seq, "design capacity warning: unknown\n"); seq_printf(seq, "design capacity low: unknown\n"); + seq_printf(seq, "cycle count: %i\n", battery->cycle_count); seq_printf(seq, "capacity granularity 1: unknown\n"); seq_printf(seq, "capacity granularity 2: unknown\n"); seq_printf(seq, "model number: %s\n", battery->device_name); -- cgit v0.10.2 From c67fcd670b55e89e0c129fbf7fae854bd1f8bfa6 Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Thu, 15 Oct 2009 14:31:44 +0400 Subject: ACPI: Battery: Add support for _BIX extended info method Signed-off-by: Alexey Starikovskiy Signed-off-by: Len Brown diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index b2b48f8..1ca0ea7 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -54,6 +54,7 @@ #define ACPI_BATTERY_DEVICE_NAME "Battery" #define ACPI_BATTERY_NOTIFY_STATUS 0x80 #define ACPI_BATTERY_NOTIFY_INFO 0x81 +#define ACPI_BATTERY_NOTIFY_THRESHOLD 0x82 #define _COMPONENT ACPI_BATTERY_COMPONENT @@ -90,9 +91,11 @@ MODULE_DEVICE_TABLE(acpi, battery_device_ids); enum { ACPI_BATTERY_ALARM_PRESENT, - /* For buggy DSDTs that report negative 16-bit values for either charging - * or discharging current and/or report 0 as 65536 due to bad math. - */ + ACPI_BATTERY_XINFO_PRESENT, + /* For buggy DSDTs that report negative 16-bit values for either + * charging or discharging current and/or report 0 as 65536 + * due to bad math. + */ ACPI_BATTERY_QUIRK_SIGNED16_CURRENT, }; @@ -112,6 +115,12 @@ struct acpi_battery { int design_voltage; int design_capacity_warning; int design_capacity_low; + int cycle_count; + int measurement_accuracy; + int max_sampling_time; + int min_sampling_time; + int max_averaging_interval; + int min_averaging_interval; int capacity_granularity_1; int capacity_granularity_2; int alarm; @@ -200,6 +209,9 @@ static int acpi_battery_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_TECHNOLOGY: val->intval = acpi_battery_technology(battery); break; + case POWER_SUPPLY_PROP_CYCLE_COUNT: + val->intval = battery->cycle_count; + break; case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: val->intval = battery->design_voltage * 1000; break; @@ -241,6 +253,7 @@ static enum power_supply_property charge_battery_props[] = { POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_TECHNOLOGY, + POWER_SUPPLY_PROP_CYCLE_COUNT, POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, POWER_SUPPLY_PROP_VOLTAGE_NOW, POWER_SUPPLY_PROP_CURRENT_NOW, @@ -256,6 +269,7 @@ static enum power_supply_property energy_battery_props[] = { POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_TECHNOLOGY, + POWER_SUPPLY_PROP_CYCLE_COUNT, POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, POWER_SUPPLY_PROP_VOLTAGE_NOW, POWER_SUPPLY_PROP_CURRENT_NOW, @@ -307,6 +321,28 @@ static struct acpi_offsets info_offsets[] = { {offsetof(struct acpi_battery, oem_info), 1}, }; +static struct acpi_offsets extended_info_offsets[] = { + {offsetof(struct acpi_battery, power_unit), 0}, + {offsetof(struct acpi_battery, design_capacity), 0}, + {offsetof(struct acpi_battery, full_charge_capacity), 0}, + {offsetof(struct acpi_battery, technology), 0}, + {offsetof(struct acpi_battery, design_voltage), 0}, + {offsetof(struct acpi_battery, design_capacity_warning), 0}, + {offsetof(struct acpi_battery, design_capacity_low), 0}, + {offsetof(struct acpi_battery, cycle_count), 0}, + {offsetof(struct acpi_battery, measurement_accuracy), 0}, + {offsetof(struct acpi_battery, max_sampling_time), 0}, + {offsetof(struct acpi_battery, min_sampling_time), 0}, + {offsetof(struct acpi_battery, max_averaging_interval), 0}, + {offsetof(struct acpi_battery, min_averaging_interval), 0}, + {offsetof(struct acpi_battery, capacity_granularity_1), 0}, + {offsetof(struct acpi_battery, capacity_granularity_2), 0}, + {offsetof(struct acpi_battery, model_number), 1}, + {offsetof(struct acpi_battery, serial_number), 1}, + {offsetof(struct acpi_battery, type), 1}, + {offsetof(struct acpi_battery, oem_info), 1}, +}; + static int extract_package(struct acpi_battery *battery, union acpi_object *package, struct acpi_offsets *offsets, int num) @@ -352,22 +388,29 @@ static int acpi_battery_get_info(struct acpi_battery *battery) { int result = -EFAULT; acpi_status status = 0; + char *name = test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags)? + "_BIX" : "_BIF"; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; if (!acpi_battery_present(battery)) return 0; mutex_lock(&battery->lock); - status = acpi_evaluate_object(battery->device->handle, "_BIF", - NULL, &buffer); + status = acpi_evaluate_object(battery->device->handle, name, + NULL, &buffer); mutex_unlock(&battery->lock); if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF")); + ACPI_EXCEPTION((AE_INFO, status, "Evaluating %s", name)); return -ENODEV; } - - result = extract_package(battery, buffer.pointer, - info_offsets, ARRAY_SIZE(info_offsets)); + if (test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags)) + result = extract_package(battery, buffer.pointer, + extended_info_offsets, + ARRAY_SIZE(extended_info_offsets)); + else + result = extract_package(battery, buffer.pointer, + info_offsets, ARRAY_SIZE(info_offsets)); kfree(buffer.pointer); return result; } @@ -414,7 +457,7 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery) union acpi_object arg0 = { .type = ACPI_TYPE_INTEGER }; struct acpi_object_list arg_list = { 1, &arg0 }; - if (!acpi_battery_present(battery)|| + if (!acpi_battery_present(battery) || !test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags)) return -ENODEV; @@ -592,6 +635,7 @@ static int acpi_battery_print_info(struct seq_file *seq, int result) seq_printf(seq, "design capacity low: %d %sh\n", battery->design_capacity_low, acpi_battery_units(battery)); + seq_printf(seq, "cycle count: %i\n", battery->cycle_count); seq_printf(seq, "capacity granularity 1: %d %sh\n", battery->capacity_granularity_1, acpi_battery_units(battery)); @@ -843,6 +887,7 @@ static int acpi_battery_add(struct acpi_device *device) { int result = 0; struct acpi_battery *battery = NULL; + acpi_handle handle; if (!device) return -EINVAL; battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL); @@ -853,6 +898,9 @@ static int acpi_battery_add(struct acpi_device *device) strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); device->driver_data = battery; mutex_init(&battery->lock); + if (ACPI_SUCCESS(acpi_get_handle(battery->device->handle, + "_BIX", &handle))) + set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags); acpi_battery_update(battery); #ifdef CONFIG_ACPI_PROCFS_POWER result = acpi_battery_add_fs(device); -- cgit v0.10.2 From ec7384ec23dc5a9ea8733e90438e16b6066bfe1b Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Wed, 20 Jan 2010 15:16:41 -0800 Subject: ceph: remove duplicate variable initialization The variable client is initialized twice to the same (side effect-free) expression. Drop one initialization. A simplified version of the semantic match that finds this problem is: (http://coccinelle.lip6.fr/) // @forall@ idexpression *x; identifier f!=ERR_PTR; @@ x = f(...) ... when != x ( x = f(...,<+...x...+>,...) | * x = f(...) ) // Signed-off-by: Julia Lawall Signed-off-by: Sage Weil diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index a6850a1..a3bd9de 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c @@ -596,7 +596,7 @@ static int ceph_writepages_start(struct address_space *mapping, struct inode *inode = mapping->host; struct backing_dev_info *bdi = mapping->backing_dev_info; struct ceph_inode_info *ci = ceph_inode(inode); - struct ceph_client *client = ceph_inode_to_client(inode); + struct ceph_client *client; pgoff_t index, start, end; int range_whole = 0; int should_loop = 1; -- cgit v0.10.2 From 3ea25f9441fc0951ada649105f2c57a59536b539 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 25 Jan 2010 11:18:17 -0800 Subject: ceph: mark MDS CREATE as a write op CEPH_MDS_OP_CREATE was not correctly marked as a write operation. Signed-off-by: Sage Weil diff --git a/fs/ceph/ceph_fs.h b/fs/ceph/ceph_fs.h index d0f2557..d8923fe 100644 --- a/fs/ceph/ceph_fs.h +++ b/fs/ceph/ceph_fs.h @@ -39,7 +39,7 @@ #define CEPH_MDS_PROTOCOL 9 /* cluster internal */ #define CEPH_MON_PROTOCOL 5 /* cluster internal */ #define CEPH_OSDC_PROTOCOL 22 /* server/client */ -#define CEPH_MDSC_PROTOCOL 31 /* server/client */ +#define CEPH_MDSC_PROTOCOL 32 /* server/client */ #define CEPH_MONC_PROTOCOL 15 /* server/client */ @@ -271,7 +271,7 @@ enum { CEPH_MDS_OP_RMDIR = 0x01221, CEPH_MDS_OP_SYMLINK = 0x01222, - CEPH_MDS_OP_CREATE = 0x00301, + CEPH_MDS_OP_CREATE = 0x01301, CEPH_MDS_OP_OPEN = 0x00302, CEPH_MDS_OP_READDIR = 0x00305, -- cgit v0.10.2 From 5b1daecd59f95eb24dc629407ed80369c9929520 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 25 Jan 2010 11:33:08 -0800 Subject: ceph: properly handle aborted mds requests Previously, if the MDS request was interrupted, we would unregister the request and ignore any reply. This could cause the caps or other cache state to become out of sync. (For instance, aborting dbench and doing rm -r on clients would complain about a non-empty directory because the client didn't realize it's aborted file create request completed.) Even we don't unregister, we still can't process the reply normally because we are no longer holding the caller's locks (like the dir i_mutex). So, mark aborted operations with r_aborted, and in the reply handler, be sure to process all the caps. Do not process the namespace changes, though, since we no longer will hold the dir i_mutex. The dentry lease state can also be ignored as it's more forgiving. Signed-off-by: Sage Weil diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 518beb6..71e107f 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -915,6 +915,16 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req, } if (rinfo->head->is_dentry) { + struct inode *dir = req->r_locked_dir; + + err = fill_inode(dir, &rinfo->diri, rinfo->dirfrag, + session, req->r_request_started, -1, + &req->r_caps_reservation); + if (err < 0) + return err; + } + + if (rinfo->head->is_dentry && !req->r_aborted) { /* * lookup link rename : null -> possibly existing inode * mknod symlink mkdir : null -> new inode @@ -932,12 +942,6 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req, BUG_ON(ceph_snap(dir) != le64_to_cpu(rinfo->diri.in->snapid)); - err = fill_inode(dir, &rinfo->diri, rinfo->dirfrag, - session, req->r_request_started, -1, - &req->r_caps_reservation); - if (err < 0) - return err; - /* do we have a lease on the whole dir? */ have_dir_cap = (le32_to_cpu(rinfo->diri.in->cap.caps) & diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 6e08f48..623c67c 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -1624,11 +1624,29 @@ int ceph_mdsc_do_request(struct ceph_mds_client *mdsc, err = PTR_ERR(req->r_reply); req->r_reply = NULL; - /* clean up */ - __unregister_request(mdsc, req); - if (!list_empty(&req->r_unsafe_item)) - list_del_init(&req->r_unsafe_item); - complete(&req->r_safe_completion); + if (err == -ERESTARTSYS) { + /* aborted */ + req->r_aborted = true; + + if (req->r_locked_dir && + (req->r_op & CEPH_MDS_OP_WRITE)) { + struct ceph_inode_info *ci = + ceph_inode(req->r_locked_dir); + + dout("aborted, clearing I_COMPLETE on %p\n", + req->r_locked_dir); + spin_lock(&req->r_locked_dir->i_lock); + ci->i_ceph_flags &= ~CEPH_I_COMPLETE; + ci->i_release_count++; + spin_unlock(&req->r_locked_dir->i_lock); + } + } else { + /* clean up this request */ + __unregister_request(mdsc, req); + if (!list_empty(&req->r_unsafe_item)) + list_del_init(&req->r_unsafe_item); + complete(&req->r_safe_completion); + } } else if (req->r_err) { err = req->r_err; } else { diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h index b1c2025..ee71495 100644 --- a/fs/ceph/mds_client.h +++ b/fs/ceph/mds_client.h @@ -188,6 +188,7 @@ struct ceph_mds_request { struct ceph_msg *r_reply; struct ceph_mds_reply_info_parsed r_reply_info; int r_err; + bool r_aborted; unsigned long r_timeout; /* optional. jiffies */ unsigned long r_started; /* start time to measure timeout against */ -- cgit v0.10.2 From 2450418c47b7998ad55a73f23707b1e21c371eef Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Fri, 8 Jan 2010 13:58:34 -0800 Subject: ceph: allocate middle of message before stating to read Both front and middle parts of the message are now being allocated at the ceph_alloc_msg(). Signed-off-by: Yehuda Sadeh diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 623c67c..93998a0 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -2953,8 +2953,6 @@ const static struct ceph_connection_operations mds_con_ops = { .get_authorizer = get_authorizer, .verify_authorizer_reply = verify_authorizer_reply, .peer_reset = peer_reset, - .alloc_msg = ceph_alloc_msg, - .alloc_middle = ceph_alloc_middle, }; diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index 1360708..25de15c 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -1279,8 +1279,34 @@ static void process_ack(struct ceph_connection *con) +static int read_partial_message_section(struct ceph_connection *con, + struct kvec *section, unsigned int sec_len, + u32 *crc) +{ + int left; + int ret; + + BUG_ON(!section); + + while (section->iov_len < sec_len) { + BUG_ON(section->iov_base == NULL); + left = sec_len - section->iov_len; + ret = ceph_tcp_recvmsg(con->sock, (char *)section->iov_base + + section->iov_len, left); + if (ret <= 0) + return ret; + section->iov_len += ret; + if (section->iov_len == sec_len) + *crc = crc32c(0, section->iov_base, + section->iov_len); + } + return 1; +} +static struct ceph_msg *ceph_alloc_msg(struct ceph_connection *con, + struct ceph_msg_header *hdr, + int *skip); /* * read (part of) a message. */ @@ -1292,6 +1318,7 @@ static int read_partial_message(struct ceph_connection *con) int to, want, left; unsigned front_len, middle_len, data_len, data_off; int datacrc = con->msgr->nocrc; + int skip; dout("read_partial_message con %p msg %p\n", con, m); @@ -1315,7 +1342,6 @@ static int read_partial_message(struct ceph_connection *con) } } } - front_len = le32_to_cpu(con->in_hdr.front_len); if (front_len > CEPH_MSG_MAX_FRONT_LEN) return -EIO; @@ -1330,8 +1356,8 @@ static int read_partial_message(struct ceph_connection *con) if (!con->in_msg) { dout("got hdr type %d front %d data %d\n", con->in_hdr.type, con->in_hdr.front_len, con->in_hdr.data_len); - con->in_msg = con->ops->alloc_msg(con, &con->in_hdr); - if (!con->in_msg) { + con->in_msg = ceph_alloc_msg(con, &con->in_hdr, &skip); + if (skip) { /* skip this message */ pr_err("alloc_msg returned NULL, skipping message\n"); con->in_base_pos = -front_len - middle_len - data_len - @@ -1342,56 +1368,28 @@ static int read_partial_message(struct ceph_connection *con) if (IS_ERR(con->in_msg)) { ret = PTR_ERR(con->in_msg); con->in_msg = NULL; - con->error_msg = "out of memory for incoming message"; + con->error_msg = "error allocating memory for incoming message"; return ret; } m = con->in_msg; m->front.iov_len = 0; /* haven't read it yet */ + if (m->middle) + m->middle->vec.iov_len = 0; memcpy(&m->hdr, &con->in_hdr, sizeof(con->in_hdr)); } /* front */ - while (m->front.iov_len < front_len) { - BUG_ON(m->front.iov_base == NULL); - left = front_len - m->front.iov_len; - ret = ceph_tcp_recvmsg(con->sock, (char *)m->front.iov_base + - m->front.iov_len, left); - if (ret <= 0) - return ret; - m->front.iov_len += ret; - if (m->front.iov_len == front_len) - con->in_front_crc = crc32c(0, m->front.iov_base, - m->front.iov_len); - } + ret = read_partial_message_section(con, &m->front, front_len, + &con->in_front_crc); + if (ret <= 0) + return ret; /* middle */ - while (middle_len > 0 && (!m->middle || - m->middle->vec.iov_len < middle_len)) { - if (m->middle == NULL) { - ret = -EOPNOTSUPP; - if (con->ops->alloc_middle) - ret = con->ops->alloc_middle(con, m); - if (ret < 0) { - pr_err("alloc_middle fail skipping payload\n"); - con->in_base_pos = -middle_len - data_len - - sizeof(m->footer); - ceph_msg_put(con->in_msg); - con->in_msg = NULL; - con->in_tag = CEPH_MSGR_TAG_READY; - return 0; - } - m->middle->vec.iov_len = 0; - } - left = middle_len - m->middle->vec.iov_len; - ret = ceph_tcp_recvmsg(con->sock, - (char *)m->middle->vec.iov_base + - m->middle->vec.iov_len, left); + if (m->middle) { + ret = read_partial_message_section(con, &m->middle->vec, middle_len, + &con->in_middle_crc); if (ret <= 0) return ret; - m->middle->vec.iov_len += ret; - if (m->middle->vec.iov_len == middle_len) - con->in_middle_crc = crc32c(0, m->middle->vec.iov_base, - m->middle->vec.iov_len); } /* (page) data */ @@ -2116,31 +2114,13 @@ out: } /* - * Generic message allocator, for incoming messages. - */ -struct ceph_msg *ceph_alloc_msg(struct ceph_connection *con, - struct ceph_msg_header *hdr) -{ - int type = le16_to_cpu(hdr->type); - int front_len = le32_to_cpu(hdr->front_len); - struct ceph_msg *msg = ceph_msg_new(type, front_len, 0, 0, NULL); - - if (!msg) { - pr_err("unable to allocate msg type %d len %d\n", - type, front_len); - return ERR_PTR(-ENOMEM); - } - return msg; -} - -/* * Allocate "middle" portion of a message, if it is needed and wasn't * allocated by alloc_msg. This allows us to read a small fixed-size * per-type header in the front and then gracefully fail (i.e., * propagate the error to the caller based on info in the front) when * the middle is too large. */ -int ceph_alloc_middle(struct ceph_connection *con, struct ceph_msg *msg) +static int ceph_alloc_middle(struct ceph_connection *con, struct ceph_msg *msg) { int type = le16_to_cpu(msg->hdr.type); int middle_len = le32_to_cpu(msg->hdr.middle_len); @@ -2156,6 +2136,48 @@ int ceph_alloc_middle(struct ceph_connection *con, struct ceph_msg *msg) return 0; } +/* + * Generic message allocator, for incoming messages. + */ +static struct ceph_msg *ceph_alloc_msg(struct ceph_connection *con, + struct ceph_msg_header *hdr, + int *skip) +{ + int type = le16_to_cpu(hdr->type); + int front_len = le32_to_cpu(hdr->front_len); + int middle_len = le32_to_cpu(hdr->middle_len); + struct ceph_msg *msg = NULL; + int ret; + + if (con->ops->alloc_msg) { + msg = con->ops->alloc_msg(con, hdr, skip); + if (IS_ERR(msg)) + return msg; + + if (*skip) + return NULL; + } + if (!msg) { + *skip = 0; + msg = ceph_msg_new(type, front_len, 0, 0, NULL); + if (!msg) { + pr_err("unable to allocate msg type %d len %d\n", + type, front_len); + return ERR_PTR(-ENOMEM); + } + } + + if (middle_len) { + ret = ceph_alloc_middle(con, msg); + + if (ret < 0) { + ceph_msg_put(msg); + return msg; + } + } + return msg; +} + /* * Free a generically kmalloc'd message. diff --git a/fs/ceph/messenger.h b/fs/ceph/messenger.h index a7b6841..b6bec590 100644 --- a/fs/ceph/messenger.h +++ b/fs/ceph/messenger.h @@ -44,9 +44,8 @@ struct ceph_connection_operations { void (*peer_reset) (struct ceph_connection *con); struct ceph_msg * (*alloc_msg) (struct ceph_connection *con, - struct ceph_msg_header *hdr); - int (*alloc_middle) (struct ceph_connection *con, - struct ceph_msg *msg); + struct ceph_msg_header *hdr, + int *skip); /* an incoming message has a data payload; tell me what pages I * should read the data into. */ int (*prepare_pages) (struct ceph_connection *con, struct ceph_msg *m, @@ -242,10 +241,6 @@ extern struct ceph_msg *ceph_msg_new(int type, int front_len, struct page **pages); extern void ceph_msg_kfree(struct ceph_msg *m); -extern struct ceph_msg *ceph_alloc_msg(struct ceph_connection *con, - struct ceph_msg_header *hdr); -extern int ceph_alloc_middle(struct ceph_connection *con, struct ceph_msg *msg); - static inline struct ceph_msg *ceph_msg_get(struct ceph_msg *msg) { diff --git a/fs/ceph/mon_client.c b/fs/ceph/mon_client.c index 223e8bc..6c00b37 100644 --- a/fs/ceph/mon_client.c +++ b/fs/ceph/mon_client.c @@ -692,21 +692,33 @@ static void dispatch(struct ceph_connection *con, struct ceph_msg *msg) * Allocate memory for incoming message */ static struct ceph_msg *mon_alloc_msg(struct ceph_connection *con, - struct ceph_msg_header *hdr) + struct ceph_msg_header *hdr, + int *skip) { struct ceph_mon_client *monc = con->private; int type = le16_to_cpu(hdr->type); - int front = le32_to_cpu(hdr->front_len); + int front_len = le32_to_cpu(hdr->front_len); + struct ceph_msg *m; + *skip = 0; switch (type) { case CEPH_MSG_MON_SUBSCRIBE_ACK: - return ceph_msgpool_get(&monc->msgpool_subscribe_ack, front); + m = ceph_msgpool_get(&monc->msgpool_subscribe_ack, front_len); + break; case CEPH_MSG_STATFS_REPLY: - return ceph_msgpool_get(&monc->msgpool_statfs_reply, front); + m = ceph_msgpool_get(&monc->msgpool_statfs_reply, front_len); + break; case CEPH_MSG_AUTH_REPLY: - return ceph_msgpool_get(&monc->msgpool_auth_reply, front); + m = ceph_msgpool_get(&monc->msgpool_auth_reply, front_len); + break; + default: + return NULL; } - return ceph_alloc_msg(con, hdr); + + if (!m) + *skip = 1; + + return m; } /* @@ -749,5 +761,4 @@ const static struct ceph_connection_operations mon_con_ops = { .dispatch = dispatch, .fault = mon_fault, .alloc_msg = mon_alloc_msg, - .alloc_middle = ceph_alloc_middle, }; diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index 8417e21..545e936 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -1304,18 +1304,28 @@ static void dispatch(struct ceph_connection *con, struct ceph_msg *msg) } static struct ceph_msg *alloc_msg(struct ceph_connection *con, - struct ceph_msg_header *hdr) + struct ceph_msg_header *hdr, + int *skip) { struct ceph_osd *osd = con->private; struct ceph_osd_client *osdc = osd->o_osdc; int type = le16_to_cpu(hdr->type); int front = le32_to_cpu(hdr->front_len); + struct ceph_msg *m; + *skip = 0; switch (type) { case CEPH_MSG_OSD_OPREPLY: - return ceph_msgpool_get(&osdc->msgpool_op_reply, front); + m = ceph_msgpool_get(&osdc->msgpool_op_reply, front); + break; + default: + return NULL; } - return ceph_alloc_msg(con, hdr); + + if (!m) + *skip = 1; + + return m; } /* @@ -1390,6 +1400,5 @@ const static struct ceph_connection_operations osd_con_ops = { .verify_authorizer_reply = verify_authorizer_reply, .alloc_msg = alloc_msg, .fault = osd_reset, - .alloc_middle = ceph_alloc_middle, .prepare_pages = prepare_pages, }; -- cgit v0.10.2 From 9d7f0f139edfdce1a1539b100c617fd9182b0829 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Mon, 11 Jan 2010 10:32:02 -0800 Subject: ceph: refactor messages data section allocation Signed-off-by: Yehuda Sadeh diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index 25de15c..e8742cc 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -1315,7 +1315,7 @@ static int read_partial_message(struct ceph_connection *con) struct ceph_msg *m = con->in_msg; void *p; int ret; - int to, want, left; + int to, left; unsigned front_len, middle_len, data_len, data_off; int datacrc = con->msgr->nocrc; int skip; @@ -1351,6 +1351,7 @@ static int read_partial_message(struct ceph_connection *con) data_len = le32_to_cpu(con->in_hdr.data_len); if (data_len > CEPH_MSG_MAX_DATA_LEN) return -EIO; + data_off = le16_to_cpu(con->in_hdr.data_off); /* allocate message? */ if (!con->in_msg) { @@ -1375,7 +1376,10 @@ static int read_partial_message(struct ceph_connection *con) m->front.iov_len = 0; /* haven't read it yet */ if (m->middle) m->middle->vec.iov_len = 0; - memcpy(&m->hdr, &con->in_hdr, sizeof(con->in_hdr)); + + con->in_msg_pos.page = 0; + con->in_msg_pos.page_pos = data_off & ~PAGE_MASK; + con->in_msg_pos.data_pos = 0; } /* front */ @@ -1393,31 +1397,6 @@ static int read_partial_message(struct ceph_connection *con) } /* (page) data */ - data_off = le16_to_cpu(m->hdr.data_off); - if (data_len == 0) - goto no_data; - - if (m->nr_pages == 0) { - con->in_msg_pos.page = 0; - con->in_msg_pos.page_pos = data_off & ~PAGE_MASK; - con->in_msg_pos.data_pos = 0; - /* find pages for data payload */ - want = calc_pages_for(data_off & ~PAGE_MASK, data_len); - ret = -1; - mutex_unlock(&con->mutex); - if (con->ops->prepare_pages) - ret = con->ops->prepare_pages(con, m, want); - mutex_lock(&con->mutex); - if (ret < 0) { - dout("%p prepare_pages failed, skipping payload\n", m); - con->in_base_pos = -data_len - sizeof(m->footer); - ceph_msg_put(con->in_msg); - con->in_msg = NULL; - con->in_tag = CEPH_MSGR_TAG_READY; - return 0; - } - BUG_ON(m->nr_pages < want); - } while (con->in_msg_pos.data_pos < data_len) { left = min((int)(data_len - con->in_msg_pos.data_pos), (int)(PAGE_SIZE - con->in_msg_pos.page_pos)); @@ -1440,7 +1419,6 @@ static int read_partial_message(struct ceph_connection *con) } } -no_data: /* footer */ to = sizeof(m->hdr) + sizeof(m->footer); while (con->in_base_pos < to) { @@ -2136,6 +2114,25 @@ static int ceph_alloc_middle(struct ceph_connection *con, struct ceph_msg *msg) return 0; } +static int ceph_alloc_data_section(struct ceph_connection *con, struct ceph_msg *msg) +{ + int ret; + int want; + int data_len = le32_to_cpu(msg->hdr.data_len); + unsigned data_off = le16_to_cpu(msg->hdr.data_off); + + want = calc_pages_for(data_off & ~PAGE_MASK, data_len); + ret = -1; + mutex_unlock(&con->mutex); + if (con->ops->prepare_pages) + ret = con->ops->prepare_pages(con, msg, want); + mutex_lock(&con->mutex); + + BUG_ON(msg->nr_pages < want); + + return ret; +} + /* * Generic message allocator, for incoming messages. */ @@ -2146,6 +2143,7 @@ static struct ceph_msg *ceph_alloc_msg(struct ceph_connection *con, int type = le16_to_cpu(hdr->type); int front_len = le32_to_cpu(hdr->front_len); int middle_len = le32_to_cpu(hdr->middle_len); + int data_len = le32_to_cpu(hdr->data_len); struct ceph_msg *msg = NULL; int ret; @@ -2166,6 +2164,7 @@ static struct ceph_msg *ceph_alloc_msg(struct ceph_connection *con, return ERR_PTR(-ENOMEM); } } + memcpy(&msg->hdr, &con->in_hdr, sizeof(con->in_hdr)); if (middle_len) { ret = ceph_alloc_middle(con, msg); @@ -2175,6 +2174,18 @@ static struct ceph_msg *ceph_alloc_msg(struct ceph_connection *con, return msg; } } + + if (data_len) { + ret = ceph_alloc_data_section(con, msg); + + if (ret < 0) { + *skip = 1; + ceph_msg_put(msg); + return NULL; + } + } + + return msg; } -- cgit v0.10.2 From 0547a9b30a5ac8680325752b61d3ffa9d4971b6e Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Mon, 11 Jan 2010 14:47:13 -0800 Subject: ceph: alloc message data pages and check if tid exists Now doing it in the same callback that is also responsible for allocating the 'front' part of the message. If we get a message that we haven't got a corresponding tid for, mark it for skipping. Moving the mutex unlock/lock from the osd alloc_msg callback to the calling function in the messenger. Signed-off-by: Yehuda Sadeh diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index e8742cc..f708803 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -2114,25 +2114,6 @@ static int ceph_alloc_middle(struct ceph_connection *con, struct ceph_msg *msg) return 0; } -static int ceph_alloc_data_section(struct ceph_connection *con, struct ceph_msg *msg) -{ - int ret; - int want; - int data_len = le32_to_cpu(msg->hdr.data_len); - unsigned data_off = le16_to_cpu(msg->hdr.data_off); - - want = calc_pages_for(data_off & ~PAGE_MASK, data_len); - ret = -1; - mutex_unlock(&con->mutex); - if (con->ops->prepare_pages) - ret = con->ops->prepare_pages(con, msg, want); - mutex_lock(&con->mutex); - - BUG_ON(msg->nr_pages < want); - - return ret; -} - /* * Generic message allocator, for incoming messages. */ @@ -2143,12 +2124,13 @@ static struct ceph_msg *ceph_alloc_msg(struct ceph_connection *con, int type = le16_to_cpu(hdr->type); int front_len = le32_to_cpu(hdr->front_len); int middle_len = le32_to_cpu(hdr->middle_len); - int data_len = le32_to_cpu(hdr->data_len); struct ceph_msg *msg = NULL; int ret; if (con->ops->alloc_msg) { + mutex_unlock(&con->mutex); msg = con->ops->alloc_msg(con, hdr, skip); + mutex_lock(&con->mutex); if (IS_ERR(msg)) return msg; @@ -2175,17 +2157,6 @@ static struct ceph_msg *ceph_alloc_msg(struct ceph_connection *con, } } - if (data_len) { - ret = ceph_alloc_data_section(con, msg); - - if (ret < 0) { - *skip = 1; - ceph_msg_put(msg); - return NULL; - } - } - - return msg; } diff --git a/fs/ceph/messenger.h b/fs/ceph/messenger.h index b6bec590..dca2d32 100644 --- a/fs/ceph/messenger.h +++ b/fs/ceph/messenger.h @@ -46,10 +46,6 @@ struct ceph_connection_operations { struct ceph_msg * (*alloc_msg) (struct ceph_connection *con, struct ceph_msg_header *hdr, int *skip); - /* an incoming message has a data payload; tell me what pages I - * should read the data into. */ - int (*prepare_pages) (struct ceph_connection *con, struct ceph_msg *m, - int want); }; extern const char *ceph_name_type_str(int t); diff --git a/fs/ceph/mon_client.c b/fs/ceph/mon_client.c index 6c00b37..3f7ae7f 100644 --- a/fs/ceph/mon_client.c +++ b/fs/ceph/mon_client.c @@ -701,6 +701,7 @@ static struct ceph_msg *mon_alloc_msg(struct ceph_connection *con, struct ceph_msg *m; *skip = 0; + switch (type) { case CEPH_MSG_MON_SUBSCRIBE_ACK: m = ceph_msgpool_get(&monc->msgpool_subscribe_ack, front_len); diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index 545e936..44abe29 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -998,31 +998,26 @@ bad: * find those pages. * 0 = success, -1 failure. */ -static int prepare_pages(struct ceph_connection *con, struct ceph_msg *m, - int want) +static int prepare_pages(struct ceph_connection *con, + struct ceph_msg_header *hdr, + struct ceph_osd_request *req, + u64 tid, + struct ceph_msg *m) { struct ceph_osd *osd = con->private; struct ceph_osd_client *osdc; - struct ceph_osd_request *req; - u64 tid; int ret = -1; - int type = le16_to_cpu(m->hdr.type); + int data_len = le32_to_cpu(hdr->data_len); + unsigned data_off = le16_to_cpu(hdr->data_off); + + int want = calc_pages_for(data_off & ~PAGE_MASK, data_len); if (!osd) return -1; + osdc = osd->o_osdc; dout("prepare_pages on msg %p want %d\n", m, want); - if (unlikely(type != CEPH_MSG_OSD_OPREPLY)) - return -1; /* hmm! */ - - tid = le64_to_cpu(m->hdr.tid); - mutex_lock(&osdc->request_mutex); - req = __lookup_request(osdc, tid); - if (!req) { - dout("prepare_pages unknown tid %llu\n", tid); - goto out; - } dout("prepare_pages tid %llu has %d pages, want %d\n", tid, req->r_num_pages, want); if (unlikely(req->r_num_pages < want)) @@ -1040,7 +1035,8 @@ static int prepare_pages(struct ceph_connection *con, struct ceph_msg *m, m->nr_pages = req->r_num_pages; ret = 0; /* success */ out: - mutex_unlock(&osdc->request_mutex); + BUG_ON(ret < 0 || m->nr_pages < want); + return ret; } @@ -1311,19 +1307,42 @@ static struct ceph_msg *alloc_msg(struct ceph_connection *con, struct ceph_osd_client *osdc = osd->o_osdc; int type = le16_to_cpu(hdr->type); int front = le32_to_cpu(hdr->front_len); + int data_len = le32_to_cpu(hdr->data_len); struct ceph_msg *m; + struct ceph_osd_request *req; + u64 tid; + int err; *skip = 0; - switch (type) { - case CEPH_MSG_OSD_OPREPLY: - m = ceph_msgpool_get(&osdc->msgpool_op_reply, front); - break; - default: + if (type != CEPH_MSG_OSD_OPREPLY) return NULL; - } - if (!m) + tid = le64_to_cpu(hdr->tid); + mutex_lock(&osdc->request_mutex); + req = __lookup_request(osdc, tid); + if (!req) { + *skip = 1; + m = NULL; + dout("prepare_pages unknown tid %llu\n", tid); + goto out; + } + m = ceph_msgpool_get(&osdc->msgpool_op_reply, front); + if (!m) { *skip = 1; + goto out; + } + + if (data_len > 0) { + err = prepare_pages(con, hdr, req, tid, m); + if (err < 0) { + *skip = 1; + ceph_msg_put(m); + m = ERR_PTR(err); + } + } + +out: + mutex_unlock(&osdc->request_mutex); return m; } @@ -1400,5 +1419,4 @@ const static struct ceph_connection_operations osd_con_ops = { .verify_authorizer_reply = verify_authorizer_reply, .alloc_msg = alloc_msg, .fault = osd_reset, - .prepare_pages = prepare_pages, }; -- cgit v0.10.2 From 0d59ab81c3d3adf466c3fd37d7fb6d46b05d1fd4 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Wed, 13 Jan 2010 17:03:23 -0800 Subject: ceph: keep reserved replies on the request structure This includes treating all the data preallocation and revokation at the same place, not having to have a special case for the reserved pages. Signed-off-by: Yehuda Sadeh diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index f708803..81bc779 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -1985,30 +1985,30 @@ void ceph_con_revoke(struct ceph_connection *con, struct ceph_msg *msg) } /* - * Revoke a page vector that we may be reading data into + * Revoke a message that we may be reading data into */ -void ceph_con_revoke_pages(struct ceph_connection *con, struct page **pages) +void ceph_con_revoke_message(struct ceph_connection *con, struct ceph_msg *msg) { mutex_lock(&con->mutex); - if (con->in_msg && con->in_msg->pages == pages) { + if (con->in_msg && con->in_msg == msg) { + unsigned front_len = le32_to_cpu(con->in_hdr.front_len); + unsigned middle_len = le32_to_cpu(con->in_hdr.middle_len); unsigned data_len = le32_to_cpu(con->in_hdr.data_len); /* skip rest of message */ - dout("con_revoke_pages %p msg %p pages %p revoked\n", con, - con->in_msg, pages); - if (con->in_msg_pos.data_pos < data_len) - con->in_base_pos = con->in_msg_pos.data_pos - data_len; - else + dout("con_revoke_pages %p msg %p revoked\n", con, msg); con->in_base_pos = con->in_base_pos - sizeof(struct ceph_msg_header) - + front_len - + middle_len - + data_len - sizeof(struct ceph_msg_footer); - con->in_msg->pages = NULL; ceph_msg_put(con->in_msg); con->in_msg = NULL; con->in_tag = CEPH_MSGR_TAG_READY; } else { dout("con_revoke_pages %p msg %p pages %p no-op\n", - con, con->in_msg, pages); + con, con->in_msg, msg); } mutex_unlock(&con->mutex); } diff --git a/fs/ceph/messenger.h b/fs/ceph/messenger.h index dca2d32..c26a3d8 100644 --- a/fs/ceph/messenger.h +++ b/fs/ceph/messenger.h @@ -226,8 +226,8 @@ extern void ceph_con_open(struct ceph_connection *con, extern void ceph_con_close(struct ceph_connection *con); extern void ceph_con_send(struct ceph_connection *con, struct ceph_msg *msg); extern void ceph_con_revoke(struct ceph_connection *con, struct ceph_msg *msg); -extern void ceph_con_revoke_pages(struct ceph_connection *con, - struct page **pages); +extern void ceph_con_revoke_message(struct ceph_connection *con, + struct ceph_msg *msg); extern void ceph_con_keepalive(struct ceph_connection *con); extern struct ceph_connection *ceph_con_get(struct ceph_connection *con); extern void ceph_con_put(struct ceph_connection *con); diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index 44abe29..df21068 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -13,6 +13,8 @@ #include "decode.h" #include "auth.h" +#define OSD_REPLY_RESERVE_FRONT_LEN 512 + const static struct ceph_connection_operations osd_con_ops; static void kick_requests(struct ceph_osd_client *osdc, struct ceph_osd *osd); @@ -73,6 +75,16 @@ static void calc_layout(struct ceph_osd_client *osdc, req->r_oid, req->r_oid_len, objoff, objlen, req->r_num_pages); } +static void remove_replies(struct ceph_osd_request *req) +{ + int i; + int max = ARRAY_SIZE(req->replies); + + for (i=0; ireplies[i]) + ceph_msg_put(req->replies[i]); + } +} /* * requests @@ -87,12 +99,13 @@ void ceph_osdc_release_request(struct kref *kref) ceph_msg_put(req->r_request); if (req->r_reply) ceph_msg_put(req->r_reply); - if (req->r_con_filling_pages) { + remove_replies(req); + if (req->r_con_filling_msg) { dout("release_request revoking pages %p from con %p\n", - req->r_pages, req->r_con_filling_pages); - ceph_con_revoke_pages(req->r_con_filling_pages, - req->r_pages); - ceph_con_put(req->r_con_filling_pages); + req->r_pages, req->r_con_filling_msg); + ceph_con_revoke_message(req->r_con_filling_msg, + req->r_reply); + ceph_con_put(req->r_con_filling_msg); } if (req->r_own_pages) ceph_release_page_vector(req->r_pages, @@ -104,6 +117,60 @@ void ceph_osdc_release_request(struct kref *kref) kfree(req); } +static int alloc_replies(struct ceph_osd_request *req, int num_reply) +{ + int i; + int max = ARRAY_SIZE(req->replies); + + BUG_ON(num_reply > max); + + for (i=0; ireplies[i] = ceph_msg_new(0, OSD_REPLY_RESERVE_FRONT_LEN, 0, 0, NULL); + if (IS_ERR(req->replies[i])) { + int j; + int err = PTR_ERR(req->replies[i]); + for (j = 0; j<=i; j++) { + ceph_msg_put(req->replies[j]); + } + return err; + } + } + + for (; ireplies[i] = NULL; + } + + req->cur_reply = 0; + + return 0; +} + +static struct ceph_msg *__get_next_reply(struct ceph_connection *con, + struct ceph_osd_request *req, + int front_len) +{ + struct ceph_msg *reply; + if (req->r_con_filling_msg) { + dout("revoking reply msg %p from old con %p\n", req->r_reply, + req->r_con_filling_msg); + ceph_con_revoke_message(req->r_con_filling_msg, req->r_reply); + ceph_con_put(req->r_con_filling_msg); + req->cur_reply = 0; + } + reply = req->replies[req->cur_reply]; + if (!reply || front_len > OSD_REPLY_RESERVE_FRONT_LEN) { + /* maybe we can allocate it now? */ + reply = ceph_msg_new(0, front_len, 0, 0, NULL); + if (!reply || IS_ERR(reply)) { + pr_err(" reply alloc failed, front_len=%d\n", front_len); + return ERR_PTR(-ENOMEM); + } + } + req->r_con_filling_msg = ceph_con_get(con); + req->r_reply = ceph_msg_get(reply); /* for duration of read over socket */ + return ceph_msg_get(reply); +} + /* * build new request AND message, calculate layout, and adjust file * extent as needed. @@ -147,7 +214,7 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc, if (req == NULL) return ERR_PTR(-ENOMEM); - err = ceph_msgpool_resv(&osdc->msgpool_op_reply, num_reply); + err = alloc_replies(req, num_reply); if (err) { ceph_osdc_put_request(req); return ERR_PTR(-ENOMEM); @@ -173,7 +240,6 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc, else msg = ceph_msg_new(CEPH_MSG_OSD_OP, msg_size, 0, 0, NULL); if (IS_ERR(msg)) { - ceph_msgpool_resv(&osdc->msgpool_op_reply, -num_reply); ceph_osdc_put_request(req); return ERR_PTR(PTR_ERR(msg)); } @@ -471,8 +537,6 @@ static void __unregister_request(struct ceph_osd_client *osdc, rb_erase(&req->r_node, &osdc->requests); osdc->num_requests--; - ceph_msgpool_resv(&osdc->msgpool_op_reply, -req->r_num_prealloc_reply); - if (req->r_osd) { /* make sure the original request isn't in flight. */ ceph_con_revoke(&req->r_osd->o_con, req->r_request); @@ -724,12 +788,12 @@ static void handle_reply(struct ceph_osd_client *osdc, struct ceph_msg *msg, flags = le32_to_cpu(rhead->flags); /* - * if this connection filled our pages, drop our reference now, to + * if this connection filled our message, drop our reference now, to * avoid a (safe but slower) revoke later. */ - if (req->r_con_filling_pages == con && req->r_pages == msg->pages) { - dout(" got pages, dropping con_filling_pages ref %p\n", con); - req->r_con_filling_pages = NULL; + if (req->r_con_filling_msg == con && req->r_reply == msg) { + dout(" got pages, dropping con_filling_msg ref %p\n", con); + req->r_con_filling_msg = NULL; ceph_con_put(con); } @@ -998,7 +1062,7 @@ bad: * find those pages. * 0 = success, -1 failure. */ -static int prepare_pages(struct ceph_connection *con, +static int __prepare_pages(struct ceph_connection *con, struct ceph_msg_header *hdr, struct ceph_osd_request *req, u64 tid, @@ -1017,20 +1081,10 @@ static int prepare_pages(struct ceph_connection *con, osdc = osd->o_osdc; - dout("prepare_pages on msg %p want %d\n", m, want); - dout("prepare_pages tid %llu has %d pages, want %d\n", + dout("__prepare_pages on msg %p tid %llu, has %d pages, want %d\n", m, tid, req->r_num_pages, want); if (unlikely(req->r_num_pages < want)) goto out; - - if (req->r_con_filling_pages) { - dout("revoking pages %p from old con %p\n", req->r_pages, - req->r_con_filling_pages); - ceph_con_revoke_pages(req->r_con_filling_pages, req->r_pages); - ceph_con_put(req->r_con_filling_pages); - } - req->r_con_filling_pages = ceph_con_get(con); - req->r_reply = ceph_msg_get(m); /* for duration of read over socket */ m->pages = req->r_pages; m->nr_pages = req->r_num_pages; ret = 0; /* success */ @@ -1164,13 +1218,8 @@ int ceph_osdc_init(struct ceph_osd_client *osdc, struct ceph_client *client) err = ceph_msgpool_init(&osdc->msgpool_op, 4096, 10, true); if (err < 0) goto out_mempool; - err = ceph_msgpool_init(&osdc->msgpool_op_reply, 512, 0, false); - if (err < 0) - goto out_msgpool; return 0; -out_msgpool: - ceph_msgpool_destroy(&osdc->msgpool_op); out_mempool: mempool_destroy(osdc->req_mempool); out: @@ -1186,7 +1235,6 @@ void ceph_osdc_stop(struct ceph_osd_client *osdc) } mempool_destroy(osdc->req_mempool); ceph_msgpool_destroy(&osdc->msgpool_op); - ceph_msgpool_destroy(&osdc->msgpool_op_reply); } /* @@ -1323,17 +1371,17 @@ static struct ceph_msg *alloc_msg(struct ceph_connection *con, if (!req) { *skip = 1; m = NULL; - dout("prepare_pages unknown tid %llu\n", tid); + dout("alloc_msg unknown tid %llu\n", tid); goto out; } - m = ceph_msgpool_get(&osdc->msgpool_op_reply, front); - if (!m) { + m = __get_next_reply(con, req, front); + if (!m || IS_ERR(m)) { *skip = 1; goto out; } if (data_len > 0) { - err = prepare_pages(con, hdr, req, tid, m); + err = __prepare_pages(con, hdr, req, tid, m); if (err < 0) { *skip = 1; ceph_msg_put(m); diff --git a/fs/ceph/osd_client.h b/fs/ceph/osd_client.h index 4162c68..8d533d9 100644 --- a/fs/ceph/osd_client.h +++ b/fs/ceph/osd_client.h @@ -44,7 +44,7 @@ struct ceph_osd_request { struct ceph_osd *r_osd; struct ceph_pg r_pgid; - struct ceph_connection *r_con_filling_pages; + struct ceph_connection *r_con_filling_msg; struct ceph_msg *r_request, *r_reply; int r_result; @@ -75,6 +75,9 @@ struct ceph_osd_request { struct page **r_pages; /* pages for data payload */ int r_pages_from_pool; int r_own_pages; /* if true, i own page list */ + + struct ceph_msg *replies[2]; + int cur_reply; }; struct ceph_osd_client { @@ -98,8 +101,7 @@ struct ceph_osd_client { mempool_t *req_mempool; - struct ceph_msgpool msgpool_op; - struct ceph_msgpool msgpool_op_reply; + struct ceph_msgpool msgpool_op; }; extern int ceph_osdc_init(struct ceph_osd_client *osdc, -- cgit v0.10.2 From 361be8601d78e488b5249032cc4e779b81d7928e Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 25 Jan 2010 16:03:02 -0800 Subject: ceph: precede encoded ceph_pg_pool struct with version Signed-off-by: Sage Weil diff --git a/fs/ceph/ceph_fs.h b/fs/ceph/ceph_fs.h index d8923fe..f3bfc3c 100644 --- a/fs/ceph/ceph_fs.h +++ b/fs/ceph/ceph_fs.h @@ -38,7 +38,7 @@ #define CEPH_OSD_PROTOCOL 8 /* cluster internal */ #define CEPH_MDS_PROTOCOL 9 /* cluster internal */ #define CEPH_MON_PROTOCOL 5 /* cluster internal */ -#define CEPH_OSDC_PROTOCOL 22 /* server/client */ +#define CEPH_OSDC_PROTOCOL 23 /* server/client */ #define CEPH_MDSC_PROTOCOL 32 /* server/client */ #define CEPH_MONC_PROTOCOL 15 /* server/client */ diff --git a/fs/ceph/osdmap.c b/fs/ceph/osdmap.c index 0dbd606..a143c51 100644 --- a/fs/ceph/osdmap.c +++ b/fs/ceph/osdmap.c @@ -414,6 +414,7 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end) struct ceph_osdmap *map; u16 version; u32 len, max, i; + u8 ev; int err = -EINVAL; void *start = *p; @@ -441,10 +442,11 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end) } ceph_decode_32_safe(p, end, max, bad); while (max--) { - ceph_decode_need(p, end, 4+sizeof(map->pg_pool->v), bad); + ceph_decode_need(p, end, 4+1+sizeof(map->pg_pool->v), bad); i = ceph_decode_32(p); if (i >= map->num_pools) goto bad; + ev = ceph_decode_8(p); /* encoding version */ ceph_decode_copy(p, &map->pg_pool[i].v, sizeof(map->pg_pool->v)); calc_pg_masks(&map->pg_pool[i]); @@ -603,6 +605,8 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, /* new_pool */ ceph_decode_32_safe(p, end, len, bad); while (len--) { + __u8 ev; + ceph_decode_32_safe(p, end, pool, bad); if (pool >= map->num_pools) { void *pg_pool = kcalloc(pool + 1, @@ -618,6 +622,8 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, map->pg_pool = pg_pool; map->num_pools = pool+1; } + ceph_decode_need(p, end, 1 + sizeof(map->pg_pool->v), bad); + ev = ceph_decode_8(p); /* encoding version */ ceph_decode_copy(p, &map->pg_pool[pool].v, sizeof(map->pg_pool->v)); calc_pg_masks(&map->pg_pool[pool]); -- cgit v0.10.2 From ac8839d7b264d0fa478fca7c4f9b6bb833540a80 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 27 Jan 2010 14:28:10 -0800 Subject: ceph: include type in ceph_entity_addr, filepath Include a type/version in ceph_entity_addr and filepath. Include extra byte in filepath encoding as necessary. Signed-off-by: Sage Weil diff --git a/fs/ceph/decode.h b/fs/ceph/decode.h index 10de848..b90a33b 100644 --- a/fs/ceph/decode.h +++ b/fs/ceph/decode.h @@ -138,6 +138,7 @@ static inline void ceph_encode_filepath(void **p, void *end, { u32 len = path ? strlen(path) : 0; BUG_ON(*p + sizeof(ino) + sizeof(len) + len > end); + ceph_encode_8(p, 1); ceph_encode_64(p, ino); ceph_encode_32(p, len); if (len) diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 93998a0..4e3e8b2 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -1325,7 +1325,7 @@ static struct ceph_msg *create_request_message(struct ceph_mds_client *mdsc, } len = sizeof(*head) + - pathlen1 + pathlen2 + 2*(sizeof(u32) + sizeof(u64)); + pathlen1 + pathlen2 + 2*(1 + sizeof(u32) + sizeof(u64)); /* calculate (max) length for cap releases */ len += sizeof(struct ceph_mds_request_release) * diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index 81bc779..e4e8d44 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -1909,6 +1909,7 @@ struct ceph_messenger *ceph_messenger_create(struct ceph_entity_addr *myaddr) msgr->inst.addr = *myaddr; /* select a random nonce */ + msgr->inst.addr.type = 0; get_random_bytes(&msgr->inst.addr.nonce, sizeof(msgr->inst.addr.nonce)); encode_my_addr(msgr); diff --git a/fs/ceph/msgr.h b/fs/ceph/msgr.h index 40b6189..8aaab41 100644 --- a/fs/ceph/msgr.h +++ b/fs/ceph/msgr.h @@ -21,7 +21,7 @@ * whenever the wire protocol changes. try to keep this string length * constant. */ -#define CEPH_BANNER "ceph v026" +#define CEPH_BANNER "ceph v027" #define CEPH_BANNER_MAX_LEN 30 @@ -61,7 +61,8 @@ extern const char *ceph_entity_type_name(int type); * entity_addr -- network address */ struct ceph_entity_addr { - __le64 nonce; /* unique id for process (e.g. pid) */ + __le32 type; + __le32 nonce; /* unique id for process (e.g. pid) */ struct sockaddr_storage in_addr; } __attribute__ ((packed)); -- cgit v0.10.2 From 0f26c4b21b684825a6dd41f2bc04d48ff62d72f8 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Fri, 29 Jan 2010 11:01:11 -0800 Subject: ceph: remove unreachable code We never truncate to a smaller size without contacting the MDS. Signed-off-by: Yehuda Sadeh Signed-off-by: Sage Weil diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 71e107f..a4f573a 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -1396,7 +1396,6 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr) int release = 0, dirtied = 0; int mask = 0; int err = 0; - int queue_trunc = 0; if (ceph_snap(inode) != CEPH_NOSNAP) return -EROFS; @@ -1510,11 +1509,6 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr) if ((issued & CEPH_CAP_FILE_EXCL) && attr->ia_size > inode->i_size) { inode->i_size = attr->ia_size; - if (attr->ia_size < inode->i_size) { - ci->i_truncate_size = attr->ia_size; - ci->i_truncate_pending++; - queue_trunc = 1; - } inode->i_blocks = (attr->ia_size + (1 << 9) - 1) >> 9; inode->i_ctime = attr->ia_ctime; @@ -1567,9 +1561,6 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr) release &= issued; spin_unlock(&inode->i_lock); - if (queue_trunc) - __ceph_do_pending_vmtruncate(inode); - if (mask) { req->r_inode = igrab(inode); req->r_inode_drop = release; -- cgit v0.10.2 From d7eecb483cc29e929bbc5515b8def830d7fc6ad2 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Thu, 28 Jan 2010 16:13:01 +0800 Subject: jfs_dmap.[ch]: trivial typo fix: s/heigth/height/g MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Mack Signed-off-by: Dave Kleikamp Cc: Jiri Kosina Cc: André Goddard Rosa Cc: jfs-discussion@lists.sourceforge.net diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c index d9b031c..7e19d2f 100644 --- a/fs/jfs/jfs_dmap.c +++ b/fs/jfs/jfs_dmap.c @@ -195,7 +195,7 @@ int dbMount(struct inode *ipbmap) bmp->db_maxag = le32_to_cpu(dbmp_le->dn_maxag); bmp->db_agpref = le32_to_cpu(dbmp_le->dn_agpref); bmp->db_aglevel = le32_to_cpu(dbmp_le->dn_aglevel); - bmp->db_agheigth = le32_to_cpu(dbmp_le->dn_agheigth); + bmp->db_agheight = le32_to_cpu(dbmp_le->dn_agheight); bmp->db_agwidth = le32_to_cpu(dbmp_le->dn_agwidth); bmp->db_agstart = le32_to_cpu(dbmp_le->dn_agstart); bmp->db_agl2size = le32_to_cpu(dbmp_le->dn_agl2size); @@ -287,7 +287,7 @@ int dbSync(struct inode *ipbmap) dbmp_le->dn_maxag = cpu_to_le32(bmp->db_maxag); dbmp_le->dn_agpref = cpu_to_le32(bmp->db_agpref); dbmp_le->dn_aglevel = cpu_to_le32(bmp->db_aglevel); - dbmp_le->dn_agheigth = cpu_to_le32(bmp->db_agheigth); + dbmp_le->dn_agheight = cpu_to_le32(bmp->db_agheight); dbmp_le->dn_agwidth = cpu_to_le32(bmp->db_agwidth); dbmp_le->dn_agstart = cpu_to_le32(bmp->db_agstart); dbmp_le->dn_agl2size = cpu_to_le32(bmp->db_agl2size); @@ -1440,7 +1440,7 @@ dbAllocAG(struct bmap * bmp, int agno, s64 nblocks, int l2nb, s64 * results) * tree index of this allocation group within the control page. */ agperlev = - (1 << (L2LPERCTL - (bmp->db_agheigth << 1))) / bmp->db_agwidth; + (1 << (L2LPERCTL - (bmp->db_agheight << 1))) / bmp->db_agwidth; ti = bmp->db_agstart + bmp->db_agwidth * (agno & (agperlev - 1)); /* dmap control page trees fan-out by 4 and a single allocation @@ -1459,7 +1459,7 @@ dbAllocAG(struct bmap * bmp, int agno, s64 nblocks, int l2nb, s64 * results) * the subtree to find the leftmost leaf that describes this * free space. */ - for (k = bmp->db_agheigth; k > 0; k--) { + for (k = bmp->db_agheight; k > 0; k--) { for (n = 0, m = (ti << 2) + 1; n < 4; n++) { if (l2nb <= dcp->stree[m + n]) { ti = m + n; @@ -3606,7 +3606,7 @@ void dbFinalizeBmap(struct inode *ipbmap) } /* - * compute db_aglevel, db_agheigth, db_width, db_agstart: + * compute db_aglevel, db_agheight, db_width, db_agstart: * an ag is covered in aglevel dmapctl summary tree, * at agheight level height (from leaf) with agwidth number of nodes * each, which starts at agstart index node of the smmary tree node @@ -3615,9 +3615,9 @@ void dbFinalizeBmap(struct inode *ipbmap) bmp->db_aglevel = BMAPSZTOLEV(bmp->db_agsize); l2nl = bmp->db_agl2size - (L2BPERDMAP + bmp->db_aglevel * L2LPERCTL); - bmp->db_agheigth = l2nl >> 1; - bmp->db_agwidth = 1 << (l2nl - (bmp->db_agheigth << 1)); - for (i = 5 - bmp->db_agheigth, bmp->db_agstart = 0, n = 1; i > 0; + bmp->db_agheight = l2nl >> 1; + bmp->db_agwidth = 1 << (l2nl - (bmp->db_agheight << 1)); + for (i = 5 - bmp->db_agheight, bmp->db_agstart = 0, n = 1; i > 0; i--) { bmp->db_agstart += n; n <<= 2; diff --git a/fs/jfs/jfs_dmap.h b/fs/jfs/jfs_dmap.h index 1a6eb41..6dcb906 100644 --- a/fs/jfs/jfs_dmap.h +++ b/fs/jfs/jfs_dmap.h @@ -210,7 +210,7 @@ struct dbmap_disk { __le32 dn_maxag; /* 4: max active alloc group number */ __le32 dn_agpref; /* 4: preferred alloc group (hint) */ __le32 dn_aglevel; /* 4: dmapctl level holding the AG */ - __le32 dn_agheigth; /* 4: height in dmapctl of the AG */ + __le32 dn_agheight; /* 4: height in dmapctl of the AG */ __le32 dn_agwidth; /* 4: width in dmapctl of the AG */ __le32 dn_agstart; /* 4: start tree index at AG height */ __le32 dn_agl2size; /* 4: l2 num of blks per alloc group */ @@ -229,7 +229,7 @@ struct dbmap { int dn_maxag; /* max active alloc group number */ int dn_agpref; /* preferred alloc group (hint) */ int dn_aglevel; /* dmapctl level holding the AG */ - int dn_agheigth; /* height in dmapctl of the AG */ + int dn_agheight; /* height in dmapctl of the AG */ int dn_agwidth; /* width in dmapctl of the AG */ int dn_agstart; /* start tree index at AG height */ int dn_agl2size; /* l2 num of blks per alloc group */ @@ -255,7 +255,7 @@ struct bmap { #define db_agsize db_bmap.dn_agsize #define db_agl2size db_bmap.dn_agl2size #define db_agwidth db_bmap.dn_agwidth -#define db_agheigth db_bmap.dn_agheigth +#define db_agheight db_bmap.dn_agheight #define db_agstart db_bmap.dn_agstart #define db_numag db_bmap.dn_numag #define db_maxlevel db_bmap.dn_maxlevel -- cgit v0.10.2 From 0c948992a00d478c17042f4790b7d6b35299cf94 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Mon, 1 Feb 2010 16:10:45 -0800 Subject: ceph: always send truncation info with read and write osd ops This fixes a bug where the read/write ops arrive the osd after a following truncation request. Signed-off-by: Yehuda Sadeh Signed-off-by: Sage Weil diff --git a/fs/ceph/ceph_fs.h b/fs/ceph/ceph_fs.h index f3bfc3c..004aae5 100644 --- a/fs/ceph/ceph_fs.h +++ b/fs/ceph/ceph_fs.h @@ -38,7 +38,7 @@ #define CEPH_OSD_PROTOCOL 8 /* cluster internal */ #define CEPH_MDS_PROTOCOL 9 /* cluster internal */ #define CEPH_MON_PROTOCOL 5 /* cluster internal */ -#define CEPH_OSDC_PROTOCOL 23 /* server/client */ +#define CEPH_OSDC_PROTOCOL 24 /* server/client */ #define CEPH_MDSC_PROTOCOL 32 /* server/client */ #define CEPH_MONC_PROTOCOL 15 /* server/client */ diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index df21068..944759b 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -199,11 +199,9 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc, struct ceph_osd_request_head *head; struct ceph_osd_op *op; void *p; - int do_trunc = truncate_seq && (off + *plen > truncate_size); - int num_op = 1 + do_sync + do_trunc; + int num_op = 1 + do_sync; size_t msg_size = sizeof(*head) + num_op*sizeof(*op); int err, i; - u64 prevofs; if (use_mempool) { req = mempool_alloc(osdc->req_mempool, GFP_NOFS); @@ -268,22 +266,14 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc, req->r_request->hdr.data_len = cpu_to_le32(*plen); op->payload_len = cpu_to_le32(*plen); } + op->extent.truncate_size = cpu_to_le64(truncate_size); + op->extent.truncate_seq = cpu_to_le32(truncate_seq); /* fill in oid */ head->object_len = cpu_to_le32(req->r_oid_len); memcpy(p, req->r_oid, req->r_oid_len); p += req->r_oid_len; - /* additional ops */ - if (do_trunc) { - op++; - op->op = cpu_to_le16(opcode == CEPH_OSD_OP_READ ? - CEPH_OSD_OP_MASKTRUNC : CEPH_OSD_OP_SETTRUNC); - op->trunc.truncate_seq = cpu_to_le32(truncate_seq); - prevofs = le64_to_cpu((op-1)->extent.offset); - op->trunc.truncate_size = cpu_to_le64(truncate_size - - (off-prevofs)); - } if (do_sync) { op++; op->op = cpu_to_le16(CEPH_OSD_OP_STARTSYNC); diff --git a/fs/ceph/rados.h b/fs/ceph/rados.h index c5614d4..123fd84 100644 --- a/fs/ceph/rados.h +++ b/fs/ceph/rados.h @@ -304,16 +304,14 @@ struct ceph_osd_op { union { struct { __le64 offset, length; + __le64 truncate_size; + __le32 truncate_seq; } __attribute__ ((packed)) extent; struct { __le32 name_len; __le32 value_len; } __attribute__ ((packed)) xattr; struct { - __le64 truncate_size; - __le32 truncate_seq; - } __attribute__ ((packed)) trunc; - struct { __u8 class_len; __u8 method_len; __u8 argc; -- cgit v0.10.2 From 79788c698b290426320e60374ed1324e4b5c69eb Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 2 Feb 2010 16:34:04 -0800 Subject: ceph: release all pages after successful osd write response We release all the pages, even if the osd response was different than the number of pages written. This could only happen due to truncation that arrives the osd in different order, for which we want the pages released anyway. Signed-off-by: Yehuda Sadeh Signed-off-by: Sage Weil diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index a3bd9de..8065dc9 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c @@ -524,9 +524,13 @@ static void writepages_finish(struct ceph_osd_request *req, bytes = le64_to_cpu(op->extent.length); if (rc >= 0) { - wrote = (bytes + (offset & ~PAGE_CACHE_MASK) + ~PAGE_CACHE_MASK) - >> PAGE_CACHE_SHIFT; - WARN_ON(wrote != req->r_num_pages); + /* + * Assume we wrote the pages we originally sent. The + * osd might reply with fewer pages if our writeback + * raced with a truncation and was adjusted at the osd, + * so don't believe the reply. + */ + wrote = req->r_num_pages; } else { wrote = 0; mapping_set_error(mapping, rc); -- cgit v0.10.2 From c7e337d6490d6f2f5e66ddf1b04d00b0dbd10108 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 2 Feb 2010 16:11:19 -0800 Subject: ceph: buffer decoding helpers Helper for decoding into a ceph_buffer, and other misc decoding helpers we will need. Signed-off-by: Yehuda Sadeh Signed-off-by: Sage Weil diff --git a/fs/ceph/buffer.c b/fs/ceph/buffer.c index 2576bd4..b98086c 100644 --- a/fs/ceph/buffer.c +++ b/fs/ceph/buffer.c @@ -1,6 +1,7 @@ #include "ceph_debug.h" #include "buffer.h" +#include "decode.h" struct ceph_buffer *ceph_buffer_new(size_t len, gfp_t gfp) { @@ -59,3 +60,19 @@ int ceph_buffer_alloc(struct ceph_buffer *b, int len, gfp_t gfp) return 0; } +int ceph_decode_buffer(struct ceph_buffer **b, void **p, void *end) +{ + size_t len; + + ceph_decode_need(p, end, sizeof(u32), bad); + len = ceph_decode_32(p); + dout("decode_buffer len %d\n", (int)len); + ceph_decode_need(p, end, len, bad); + *b = ceph_buffer_new(len, GFP_NOFS); + if (!*b) + return -ENOMEM; + ceph_decode_copy(p, (*b)->vec.iov_base, len); + return 0; +bad: + return -EINVAL; +} diff --git a/fs/ceph/buffer.h b/fs/ceph/buffer.h index 47b9514..58d1901 100644 --- a/fs/ceph/buffer.h +++ b/fs/ceph/buffer.h @@ -34,4 +34,6 @@ static inline void ceph_buffer_put(struct ceph_buffer *b) kref_put(&b->kref, ceph_buffer_release); } +extern int ceph_decode_buffer(struct ceph_buffer **b, void **p, void *end); + #endif diff --git a/fs/ceph/decode.h b/fs/ceph/decode.h index b90a33b..65b3e02 100644 --- a/fs/ceph/decode.h +++ b/fs/ceph/decode.h @@ -2,6 +2,7 @@ #define __CEPH_DECODE_H #include +#include #include "types.h" @@ -65,6 +66,11 @@ static inline void ceph_decode_copy(void **p, void *pv, size_t n) ceph_decode_need(p, end, sizeof(u16), bad); \ v = ceph_decode_16(p); \ } while (0) +#define ceph_decode_8_safe(p, end, v, bad) \ + do { \ + ceph_decode_need(p, end, sizeof(u8), bad); \ + v = ceph_decode_8(p); \ + } while (0) #define ceph_decode_copy_safe(p, end, pv, n, bad) \ do { \ @@ -156,5 +162,33 @@ static inline void ceph_encode_string(void **p, void *end, *p += len; } +#define ceph_encode_need(p, end, n, bad) \ + do { \ + if (unlikely(*(p) + (n) > (end))) \ + goto bad; \ + } while (0) + +#define ceph_encode_64_safe(p, end, v, bad) \ + do { \ + ceph_encode_need(p, end, sizeof(u64), bad); \ + ceph_encode_64(p, v); \ + } while (0) +#define ceph_encode_32_safe(p, end, v, bad) \ + do { \ + ceph_encode_need(p, end, sizeof(u32), bad); \ + ceph_encode_32(p, v); \ + } while (0) +#define ceph_encode_16_safe(p, end, v, bad) \ + do { \ + ceph_encode_need(p, end, sizeof(u16), bad); \ + ceph_encode_16(p, v); \ + } while (0) + +#define ceph_encode_copy_safe(p, end, pv, n, bad) \ + do { \ + ceph_encode_need(p, end, n, bad); \ + ceph_encode_copy(p, pv, n); \ + } while (0) + #endif -- cgit v0.10.2 From 8b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 2 Feb 2010 16:07:07 -0800 Subject: ceph: aes crypto and base64 encode/decode helpers Helpers to encrypt/decrypt AES and base64. Signed-off-by: Yehuda Sadeh Signed-off-by: Sage Weil diff --git a/fs/ceph/Kconfig b/fs/ceph/Kconfig index bc1fbd9..04b8280 100644 --- a/fs/ceph/Kconfig +++ b/fs/ceph/Kconfig @@ -2,6 +2,7 @@ config CEPH_FS tristate "Ceph distributed file system (EXPERIMENTAL)" depends on INET && EXPERIMENTAL select LIBCRC32C + select CONFIG_CRYPTO_AES help Choose Y or M here to include support for mounting the experimental Ceph distributed file system. Ceph is an extremely diff --git a/fs/ceph/Makefile b/fs/ceph/Makefile index 47caf2f..85a588e 100644 --- a/fs/ceph/Makefile +++ b/fs/ceph/Makefile @@ -14,6 +14,7 @@ ceph-objs := super.o inode.o dir.o file.o addr.o ioctl.o \ osd_client.o osdmap.o crush/crush.o crush/mapper.o crush/hash.o \ debugfs.o \ auth.o auth_none.o \ + crypto.o armor.o \ ceph_fs.o ceph_strings.o ceph_hash.o ceph_frag.o else diff --git a/fs/ceph/armor.c b/fs/ceph/armor.c new file mode 100644 index 0000000..67b2c03 --- /dev/null +++ b/fs/ceph/armor.c @@ -0,0 +1,99 @@ + +#include + +/* + * base64 encode/decode. + */ + +const char *pem_key = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +static int encode_bits(int c) +{ + return pem_key[c]; +} + +static int decode_bits(char c) +{ + if (c >= 'A' && c <= 'Z') + return c - 'A'; + if (c >= 'a' && c <= 'z') + return c - 'a' + 26; + if (c >= '0' && c <= '9') + return c - '0' + 52; + if (c == '+') + return 62; + if (c == '/') + return 63; + if (c == '=') + return 0; /* just non-negative, please */ + return -EINVAL; +} + +int ceph_armor(char *dst, const char *src, const char *end) +{ + int olen = 0; + int line = 0; + + while (src < end) { + unsigned char a, b, c; + + a = *src++; + *dst++ = encode_bits(a >> 2); + if (src < end) { + b = *src++; + *dst++ = encode_bits(((a & 3) << 4) | (b >> 4)); + if (src < end) { + c = *src++; + *dst++ = encode_bits(((b & 15) << 2) | + (c >> 6)); + *dst++ = encode_bits(c & 63); + } else { + *dst++ = encode_bits((b & 15) << 2); + *dst++ = '='; + } + } else { + *dst++ = encode_bits(((a & 3) << 4)); + *dst++ = '='; + *dst++ = '='; + } + olen += 4; + line += 4; + if (line == 64) { + line = 0; + *(dst++) = '\n'; + olen++; + } + } + return olen; +} + +int ceph_unarmor(char *dst, const char *src, const char *end) +{ + int olen = 0; + + while (src < end) { + int a, b, c, d; + + if (src < end && src[0] == '\n') + src++; + if (src + 4 > end) + return -EINVAL; + a = decode_bits(src[0]); + b = decode_bits(src[1]); + c = decode_bits(src[2]); + d = decode_bits(src[3]); + if (a < 0 || b < 0 || c < 0 || d < 0) + return -EINVAL; + + *dst++ = (a << 2) | (b >> 4); + if (src[2] == '=') + return olen + 1; + *dst++ = ((b & 15) << 4) | (c >> 2); + if (src[3] == '=') + return olen + 2; + *dst++ = ((c & 3) << 6) | d; + olen += 3; + src += 4; + } + return olen; +} diff --git a/fs/ceph/crypto.c b/fs/ceph/crypto.c new file mode 100644 index 0000000..291ac28 --- /dev/null +++ b/fs/ceph/crypto.c @@ -0,0 +1,408 @@ + +#include "ceph_debug.h" + +#include +#include +#include + +#include "crypto.h" +#include "decode.h" + +int ceph_crypto_key_encode(struct ceph_crypto_key *key, void **p, void *end) +{ + if (*p + sizeof(u16) + sizeof(key->created) + + sizeof(u16) + key->len > end) + return -ERANGE; + ceph_encode_16(p, key->type); + ceph_encode_copy(p, &key->created, sizeof(key->created)); + ceph_encode_16(p, key->len); + ceph_encode_copy(p, key->key, key->len); + return 0; +} + +int ceph_crypto_key_decode(struct ceph_crypto_key *key, void **p, void *end) +{ + ceph_decode_need(p, end, 2*sizeof(u16) + sizeof(key->created), bad); + key->type = ceph_decode_16(p); + ceph_decode_copy(p, &key->created, sizeof(key->created)); + key->len = ceph_decode_16(p); + ceph_decode_need(p, end, key->len, bad); + key->key = kmalloc(key->len, GFP_NOFS); + if (!key->key) + return -ENOMEM; + ceph_decode_copy(p, key->key, key->len); + return 0; + +bad: + dout("failed to decode crypto key\n"); + return -EINVAL; +} + +int ceph_crypto_key_unarmor(struct ceph_crypto_key *key, const char *inkey) +{ + int inlen = strlen(inkey); + int blen = inlen * 3 / 4; + void *buf, *p; + int ret; + + dout("crypto_key_unarmor %s\n", inkey); + buf = kmalloc(blen, GFP_NOFS); + if (!buf) + return -ENOMEM; + blen = ceph_unarmor(buf, inkey, inkey+inlen); + if (blen < 0) { + kfree(buf); + return blen; + } + + p = buf; + ret = ceph_crypto_key_decode(key, &p, p + blen); + kfree(buf); + if (ret) + return ret; + dout("crypto_key_unarmor key %p type %d len %d\n", key, + key->type, key->len); + return 0; +} + + + +#define AES_KEY_SIZE 16 + +static struct crypto_blkcipher *ceph_crypto_alloc_cipher(void) +{ + return crypto_alloc_blkcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC); +} + +const u8 *aes_iv = "cephsageyudagreg"; + +int ceph_aes_encrypt(const void *key, int key_len, void *dst, size_t *dst_len, + const void *src, size_t src_len) +{ + struct scatterlist sg_in[2], sg_out[1]; + struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher(); + struct blkcipher_desc desc = { .tfm = tfm, .flags = 0 }; + int ret; + void *iv; + int ivsize; + size_t zero_padding = (0x10 - (src_len & 0x0f)); + char pad[16]; + + if (IS_ERR(tfm)) + return PTR_ERR(tfm); + + memset(pad, zero_padding, zero_padding); + + *dst_len = src_len + zero_padding; + + crypto_blkcipher_setkey((void *)tfm, key, key_len); + sg_init_table(sg_in, 2); + sg_set_buf(&sg_in[0], src, src_len); + sg_set_buf(&sg_in[1], pad, zero_padding); + sg_init_table(sg_out, 1); + sg_set_buf(sg_out, dst, *dst_len); + iv = crypto_blkcipher_crt(tfm)->iv; + ivsize = crypto_blkcipher_ivsize(tfm); + + memcpy(iv, aes_iv, ivsize); + /* + print_hex_dump(KERN_ERR, "enc key: ", DUMP_PREFIX_NONE, 16, 1, + key, key_len, 1); + print_hex_dump(KERN_ERR, "enc src: ", DUMP_PREFIX_NONE, 16, 1, + src, src_len, 1); + print_hex_dump(KERN_ERR, "enc pad: ", DUMP_PREFIX_NONE, 16, 1, + pad, zero_padding, 1); + */ + ret = crypto_blkcipher_encrypt(&desc, sg_out, sg_in, + src_len + zero_padding); + crypto_free_blkcipher(tfm); + if (ret < 0) + pr_err("ceph_aes_crypt failed %d\n", ret); + /* + print_hex_dump(KERN_ERR, "enc out: ", DUMP_PREFIX_NONE, 16, 1, + dst, *dst_len, 1); + */ + return 0; +} + +int ceph_aes_encrypt2(const void *key, int key_len, void *dst, size_t *dst_len, + const void *src1, size_t src1_len, + const void *src2, size_t src2_len) +{ + struct scatterlist sg_in[3], sg_out[1]; + struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher(); + struct blkcipher_desc desc = { .tfm = tfm, .flags = 0 }; + int ret; + void *iv; + int ivsize; + size_t zero_padding = (0x10 - ((src1_len + src2_len) & 0x0f)); + char pad[16]; + + if (IS_ERR(tfm)) + return PTR_ERR(tfm); + + memset(pad, zero_padding, zero_padding); + + *dst_len = src1_len + src2_len + zero_padding; + + crypto_blkcipher_setkey((void *)tfm, key, key_len); + sg_init_table(sg_in, 3); + sg_set_buf(&sg_in[0], src1, src1_len); + sg_set_buf(&sg_in[1], src2, src2_len); + sg_set_buf(&sg_in[2], pad, zero_padding); + sg_init_table(sg_out, 1); + sg_set_buf(sg_out, dst, *dst_len); + iv = crypto_blkcipher_crt(tfm)->iv; + ivsize = crypto_blkcipher_ivsize(tfm); + + memcpy(iv, aes_iv, ivsize); + /* + print_hex_dump(KERN_ERR, "enc key: ", DUMP_PREFIX_NONE, 16, 1, + key, key_len, 1); + print_hex_dump(KERN_ERR, "enc src1: ", DUMP_PREFIX_NONE, 16, 1, + src1, src1_len, 1); + print_hex_dump(KERN_ERR, "enc src2: ", DUMP_PREFIX_NONE, 16, 1, + src2, src2_len, 1); + print_hex_dump(KERN_ERR, "enc pad: ", DUMP_PREFIX_NONE, 16, 1, + pad, zero_padding, 1); + */ + ret = crypto_blkcipher_encrypt(&desc, sg_out, sg_in, + src1_len + src2_len + zero_padding); + crypto_free_blkcipher(tfm); + if (ret < 0) + pr_err("ceph_aes_crypt2 failed %d\n", ret); + /* + print_hex_dump(KERN_ERR, "enc out: ", DUMP_PREFIX_NONE, 16, 1, + dst, *dst_len, 1); + */ + return 0; +} + +int ceph_aes_decrypt(const void *key, int key_len, void *dst, size_t *dst_len, + const void *src, size_t src_len) +{ + struct scatterlist sg_in[1], sg_out[2]; + struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher(); + struct blkcipher_desc desc = { .tfm = tfm }; + char pad[16]; + void *iv; + int ivsize; + int ret; + int last_byte; + + if (IS_ERR(tfm)) + return PTR_ERR(tfm); + + crypto_blkcipher_setkey((void *)tfm, key, key_len); + sg_init_table(sg_in, 1); + sg_init_table(sg_out, 2); + sg_set_buf(sg_in, src, src_len); + sg_set_buf(&sg_out[0], dst, *dst_len); + sg_set_buf(&sg_out[1], pad, sizeof(pad)); + + iv = crypto_blkcipher_crt(tfm)->iv; + ivsize = crypto_blkcipher_ivsize(tfm); + + memcpy(iv, aes_iv, ivsize); + + /* + print_hex_dump(KERN_ERR, "dec key: ", DUMP_PREFIX_NONE, 16, 1, + key, key_len, 1); + print_hex_dump(KERN_ERR, "dec in: ", DUMP_PREFIX_NONE, 16, 1, + src, src_len, 1); + */ + + ret = crypto_blkcipher_decrypt(&desc, sg_out, sg_in, src_len); + crypto_free_blkcipher(tfm); + if (ret < 0) { + pr_err("ceph_aes_decrypt failed %d\n", ret); + return ret; + } + + if (src_len <= *dst_len) + last_byte = ((char *)dst)[src_len - 1]; + else + last_byte = pad[src_len - *dst_len - 1]; + if (last_byte <= 16 && src_len >= last_byte) { + *dst_len = src_len - last_byte; + } else { + pr_err("ceph_aes_decrypt got bad padding %d on src len %d\n", + last_byte, (int)src_len); + return -EPERM; /* bad padding */ + } + /* + print_hex_dump(KERN_ERR, "dec out: ", DUMP_PREFIX_NONE, 16, 1, + dst, *dst_len, 1); + */ + return 0; +} + +int ceph_aes_decrypt2(const void *key, int key_len, + void *dst1, size_t *dst1_len, + void *dst2, size_t *dst2_len, + const void *src, size_t src_len) +{ + struct scatterlist sg_in[1], sg_out[3]; + struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher(); + struct blkcipher_desc desc = { .tfm = tfm }; + char pad[16]; + void *iv; + int ivsize; + int ret; + int last_byte; + + if (IS_ERR(tfm)) + return PTR_ERR(tfm); + + sg_init_table(sg_in, 1); + sg_set_buf(sg_in, src, src_len); + sg_init_table(sg_out, 3); + sg_set_buf(&sg_out[0], dst1, *dst1_len); + sg_set_buf(&sg_out[1], dst2, *dst2_len); + sg_set_buf(&sg_out[2], pad, sizeof(pad)); + + crypto_blkcipher_setkey((void *)tfm, key, key_len); + iv = crypto_blkcipher_crt(tfm)->iv; + ivsize = crypto_blkcipher_ivsize(tfm); + + memcpy(iv, aes_iv, ivsize); + + /* + print_hex_dump(KERN_ERR, "dec key: ", DUMP_PREFIX_NONE, 16, 1, + key, key_len, 1); + print_hex_dump(KERN_ERR, "dec in: ", DUMP_PREFIX_NONE, 16, 1, + src, src_len, 1); + */ + + ret = crypto_blkcipher_decrypt(&desc, sg_out, sg_in, src_len); + crypto_free_blkcipher(tfm); + if (ret < 0) { + pr_err("ceph_aes_decrypt failed %d\n", ret); + return ret; + } + + if (src_len <= *dst1_len) + last_byte = ((char *)dst1)[src_len - 1]; + else if (src_len <= *dst1_len + *dst2_len) + last_byte = ((char *)dst2)[src_len - *dst1_len - 1]; + else + last_byte = pad[src_len - *dst1_len - *dst2_len - 1]; + if (last_byte <= 16 && src_len >= last_byte) { + src_len -= last_byte; + } else { + pr_err("ceph_aes_decrypt got bad padding %d on src len %d\n", + last_byte, (int)src_len); + return -EPERM; /* bad padding */ + } + + if (src_len < *dst1_len) { + *dst1_len = src_len; + *dst2_len = 0; + } else { + *dst2_len = src_len - *dst1_len; + } + /* + print_hex_dump(KERN_ERR, "dec out1: ", DUMP_PREFIX_NONE, 16, 1, + dst1, *dst1_len, 1); + print_hex_dump(KERN_ERR, "dec out2: ", DUMP_PREFIX_NONE, 16, 1, + dst2, *dst2_len, 1); + */ + + return 0; +} + + +int ceph_decrypt(struct ceph_crypto_key *secret, void *dst, size_t *dst_len, + const void *src, size_t src_len) +{ + switch (secret->type) { + case CEPH_CRYPTO_NONE: + if (*dst_len < src_len) + return -ERANGE; + memcpy(dst, src, src_len); + *dst_len = src_len; + return 0; + + case CEPH_CRYPTO_AES: + return ceph_aes_decrypt(secret->key, secret->len, dst, + dst_len, src, src_len); + + default: + return -EINVAL; + } +} + +int ceph_decrypt2(struct ceph_crypto_key *secret, + void *dst1, size_t *dst1_len, + void *dst2, size_t *dst2_len, + const void *src, size_t src_len) +{ + size_t t; + + switch (secret->type) { + case CEPH_CRYPTO_NONE: + if (*dst1_len + *dst2_len < src_len) + return -ERANGE; + t = min(*dst1_len, src_len); + memcpy(dst1, src, t); + *dst1_len = t; + src += t; + src_len -= t; + if (src_len) { + t = min(*dst2_len, src_len); + memcpy(dst2, src, t); + *dst2_len = t; + } + return 0; + + case CEPH_CRYPTO_AES: + return ceph_aes_decrypt2(secret->key, secret->len, + dst1, dst1_len, dst2, dst2_len, + src, src_len); + + default: + return -EINVAL; + } +} + +int ceph_encrypt(struct ceph_crypto_key *secret, void *dst, size_t *dst_len, + const void *src, size_t src_len) +{ + switch (secret->type) { + case CEPH_CRYPTO_NONE: + if (*dst_len < src_len) + return -ERANGE; + memcpy(dst, src, src_len); + *dst_len = src_len; + return 0; + + case CEPH_CRYPTO_AES: + return ceph_aes_encrypt(secret->key, secret->len, dst, + dst_len, src, src_len); + + default: + return -EINVAL; + } +} + +int ceph_encrypt2(struct ceph_crypto_key *secret, void *dst, size_t *dst_len, + const void *src1, size_t src1_len, + const void *src2, size_t src2_len) +{ + switch (secret->type) { + case CEPH_CRYPTO_NONE: + if (*dst_len < src1_len + src2_len) + return -ERANGE; + memcpy(dst, src1, src1_len); + memcpy(dst + src1_len, src2, src2_len); + *dst_len = src1_len + src2_len; + return 0; + + case CEPH_CRYPTO_AES: + return ceph_aes_encrypt2(secret->key, secret->len, dst, dst_len, + src1, src1_len, src2, src2_len); + + default: + return -EINVAL; + } +} diff --git a/fs/ceph/crypto.h b/fs/ceph/crypto.h new file mode 100644 index 0000000..40b502e --- /dev/null +++ b/fs/ceph/crypto.h @@ -0,0 +1,48 @@ +#ifndef _FS_CEPH_CRYPTO_H +#define _FS_CEPH_CRYPTO_H + +#include "types.h" +#include "buffer.h" + +/* + * cryptographic secret + */ +struct ceph_crypto_key { + int type; + struct ceph_timespec created; + int len; + void *key; +}; + +static inline void ceph_crypto_key_destroy(struct ceph_crypto_key *key) +{ + kfree(key->key); +} + +extern int ceph_crypto_key_encode(struct ceph_crypto_key *key, + void **p, void *end); +extern int ceph_crypto_key_decode(struct ceph_crypto_key *key, + void **p, void *end); +extern int ceph_crypto_key_unarmor(struct ceph_crypto_key *key, const char *in); + +/* crypto.c */ +extern int ceph_decrypt(struct ceph_crypto_key *secret, + void *dst, size_t *dst_len, + const void *src, size_t src_len); +extern int ceph_encrypt(struct ceph_crypto_key *secret, + void *dst, size_t *dst_len, + const void *src, size_t src_len); +extern int ceph_decrypt2(struct ceph_crypto_key *secret, + void *dst1, size_t *dst1_len, + void *dst2, size_t *dst2_len, + const void *src, size_t src_len); +extern int ceph_encrypt2(struct ceph_crypto_key *secret, + void *dst, size_t *dst_len, + const void *src1, size_t src1_len, + const void *src2, size_t src2_len); + +/* armor.c */ +extern int ceph_armor(char *dst, const void *src, const void *end); +extern int ceph_unarmor(void *dst, const char *src, const char *end); + +#endif -- cgit v0.10.2 From 9bd2e6f8ba71facf1cadb7154a7e0e4d345a6aba Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 2 Feb 2010 16:21:06 -0800 Subject: ceph: allow renewal of auth credentials Add infrastructure to allow the mon_client to periodically renew its auth credentials. Also add a messenger callback that will force such a renewal if a peer rejects our authenticator. Signed-off-by: Yehuda Sadeh Signed-off-by: Sage Weil diff --git a/fs/ceph/auth.c b/fs/ceph/auth.c index 32f2e2a..d5872d4 100644 --- a/fs/ceph/auth.c +++ b/fs/ceph/auth.c @@ -125,6 +125,30 @@ bad: return -ERANGE; } +int ceph_build_auth_request(struct ceph_auth_client *ac, + void *msg_buf, size_t msg_len) +{ + struct ceph_mon_request_header *monhdr = msg_buf; + void *p = monhdr + 1; + void *end = msg_buf + msg_len; + int ret; + + monhdr->have_version = 0; + monhdr->session_mon = cpu_to_le16(-1); + monhdr->session_mon_tid = 0; + + ceph_encode_32(&p, ac->protocol); + + ret = ac->ops->build_request(ac, p + sizeof(u32), end); + if (ret < 0) { + pr_err("error %d building request\n", ret); + return ret; + } + dout(" built request %d bytes\n", ret); + ceph_encode_32(&p, ret); + return p + ret - msg_buf; +} + /* * Handle auth message from monitor. */ @@ -188,28 +212,13 @@ int ceph_handle_auth_reply(struct ceph_auth_client *ac, goto out; } } + + ac->negotiating = false; } ret = ac->ops->handle_reply(ac, result, payload, payload_end); if (ret == -EAGAIN) { - struct ceph_mon_request_header *monhdr = reply_buf; - void *p = reply_buf + 1; - void *end = reply_buf + reply_len; - - monhdr->have_version = 0; - monhdr->session_mon = cpu_to_le16(-1); - monhdr->session_mon_tid = 0; - - ceph_encode_32(&p, ac->protocol); - - ret = ac->ops->build_request(ac, p + sizeof(u32), end); - if (ret < 0) { - pr_err("error %d building request\n", ret); - goto out; - } - dout(" built request %d bytes\n", ret); - ceph_encode_32(&p, ret); - return p + ret - reply_buf; + return ceph_build_auth_request(ac, reply_buf, reply_len); } else if (ret) { pr_err("authentication error %d\n", ret); return ret; @@ -222,4 +231,20 @@ out: return ret; } +int ceph_build_auth(struct ceph_auth_client *ac, + void *msg_buf, size_t msg_len) +{ + if (!ac->protocol) + return ceph_auth_build_hello(ac, msg_buf, msg_len); + BUG_ON(!ac->ops); + if (!ac->ops->is_authenticated(ac)) + return ceph_build_auth_request(ac, msg_buf, msg_len); + return 0; +} +int ceph_auth_is_authenticated(struct ceph_auth_client *ac) +{ + if (!ac->ops) + return 0; + return ac->ops->is_authenticated(ac); +} diff --git a/fs/ceph/auth.h b/fs/ceph/auth.h index 4d8cdf6..ca4f57c 100644 --- a/fs/ceph/auth.h +++ b/fs/ceph/auth.h @@ -42,6 +42,8 @@ struct ceph_auth_client_ops { struct ceph_authorizer *a, size_t len); void (*destroy_authorizer)(struct ceph_auth_client *ac, struct ceph_authorizer *a); + void (*invalidate_authorizer)(struct ceph_auth_client *ac, + int peer_type); /* reset when we (re)connect to a monitor */ void (*reset)(struct ceph_auth_client *ac); @@ -74,4 +76,9 @@ extern int ceph_handle_auth_reply(struct ceph_auth_client *ac, void *reply_buf, size_t reply_len); extern int ceph_entity_name_encode(const char *name, void **p, void *end); +extern int ceph_build_auth(struct ceph_auth_client *ac, + void *msg_buf, size_t msg_len); + +extern int ceph_auth_is_authenticated(struct ceph_auth_client *ac); + #endif diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 4e3e8b2..aa8506b 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -2946,12 +2946,25 @@ static int verify_authorizer_reply(struct ceph_connection *con, int len) return ac->ops->verify_authorizer_reply(ac, s->s_authorizer, len); } +static int invalidate_authorizer(struct ceph_connection *con) +{ + struct ceph_mds_session *s = con->private; + struct ceph_mds_client *mdsc = s->s_mdsc; + struct ceph_auth_client *ac = mdsc->client->monc.auth; + + if (ac->ops->invalidate_authorizer) + ac->ops->invalidate_authorizer(ac, CEPH_ENTITY_TYPE_MDS); + + return ceph_monc_validate_auth(&mdsc->client->monc); +} + const static struct ceph_connection_operations mds_con_ops = { .get = con_get, .put = con_put, .dispatch = dispatch, .get_authorizer = get_authorizer, .verify_authorizer_reply = verify_authorizer_reply, + .invalidate_authorizer = invalidate_authorizer, .peer_reset = peer_reset, }; diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index e4e8d44..c434178 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -1849,6 +1849,15 @@ static void ceph_fault(struct ceph_connection *con) con->in_msg = NULL; } + /* + * in case we faulted due to authentication, invalidate our + * current tickets so that we can get new ones. + */ + if (con->auth_retry && con->ops->invalidate_authorizer) { + dout("calling invalidate_authorizer()\n"); + con->ops->invalidate_authorizer(con); + } + /* If there are no messages in the queue, place the connection * in a STANDBY state (i.e., don't try to reconnect just yet). */ if (list_empty(&con->out_queue) && !con->out_keepalive_pending) { diff --git a/fs/ceph/messenger.h b/fs/ceph/messenger.h index c26a3d8..c973537 100644 --- a/fs/ceph/messenger.h +++ b/fs/ceph/messenger.h @@ -32,6 +32,7 @@ struct ceph_connection_operations { void **buf, int *len, int *proto, void **reply_buf, int *reply_len, int force_new); int (*verify_authorizer_reply) (struct ceph_connection *con, int len); + int (*invalidate_authorizer)(struct ceph_connection *con); /* protocol version mismatch */ void (*bad_proto) (struct ceph_connection *con); diff --git a/fs/ceph/mon_client.c b/fs/ceph/mon_client.c index 3f7ae7f..fec41a0 100644 --- a/fs/ceph/mon_client.c +++ b/fs/ceph/mon_client.c @@ -29,6 +29,8 @@ const static struct ceph_connection_operations mon_con_ops; +static int __validate_auth(struct ceph_mon_client *monc); + /* * Decode a monmap blob (e.g., during mount). */ @@ -103,6 +105,7 @@ static void __close_session(struct ceph_mon_client *monc) ceph_con_revoke(monc->con, monc->m_auth); ceph_con_close(monc->con); monc->cur_mon = -1; + monc->pending_auth = 0; ceph_auth_reset(monc->auth); } } @@ -334,7 +337,7 @@ static void ceph_monc_handle_map(struct ceph_mon_client *monc, out: mutex_unlock(&monc->mutex); - wake_up(&client->mount_wq); + wake_up(&client->auth_wq); } /* @@ -477,6 +480,11 @@ static void delayed_work(struct work_struct *work) __open_session(monc); /* continue hunting */ } else { ceph_con_keepalive(monc->con); + mutex_unlock(&monc->mutex); + + __validate_auth(monc); + + mutex_lock(&monc->mutex); if (monc->auth->ops->is_authenticated(monc->auth)) __send_subscribe(monc); } @@ -557,6 +565,7 @@ int ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl) goto out_pool2; monc->m_auth = ceph_msg_new(CEPH_MSG_AUTH, 4096, 0, 0, NULL); + monc->pending_auth = 0; if (IS_ERR(monc->m_auth)) { err = PTR_ERR(monc->m_auth); monc->m_auth = NULL; @@ -614,6 +623,15 @@ void ceph_monc_stop(struct ceph_mon_client *monc) kfree(monc->monmap); } +static void __send_prepared_auth_request(struct ceph_mon_client *monc, int len) +{ + monc->pending_auth = 1; + monc->m_auth->front.iov_len = len; + monc->m_auth->hdr.front_len = cpu_to_le32(len); + ceph_msg_get(monc->m_auth); /* keep our ref */ + ceph_con_send(monc->con, monc->m_auth); +} + static void handle_auth_reply(struct ceph_mon_client *monc, struct ceph_msg *msg) @@ -621,18 +639,16 @@ static void handle_auth_reply(struct ceph_mon_client *monc, int ret; mutex_lock(&monc->mutex); + monc->pending_auth = 0; ret = ceph_handle_auth_reply(monc->auth, msg->front.iov_base, msg->front.iov_len, monc->m_auth->front.iov_base, monc->m_auth->front_max); if (ret < 0) { - monc->client->mount_err = ret; - wake_up(&monc->client->mount_wq); + monc->client->auth_err = ret; + wake_up(&monc->client->auth_wq); } else if (ret > 0) { - monc->m_auth->front.iov_len = ret; - monc->m_auth->hdr.front_len = cpu_to_le32(ret); - ceph_msg_get(monc->m_auth); /* keep our ref */ - ceph_con_send(monc->con, monc->m_auth); + __send_prepared_auth_request(monc, ret); } else if (monc->auth->ops->is_authenticated(monc->auth)) { dout("authenticated, starting session\n"); @@ -645,6 +661,31 @@ static void handle_auth_reply(struct ceph_mon_client *monc, mutex_unlock(&monc->mutex); } +static int __validate_auth(struct ceph_mon_client *monc) +{ + int ret; + + if (monc->pending_auth) + return 0; + + ret = ceph_build_auth(monc->auth, monc->m_auth->front.iov_base, + monc->m_auth->front_max); + if (ret <= 0) + return ret; /* either an error, or no need to authenticate */ + __send_prepared_auth_request(monc, ret); + return 0; +} + +int ceph_monc_validate_auth(struct ceph_mon_client *monc) +{ + int ret; + + mutex_lock(&monc->mutex); + ret = __validate_auth(monc); + mutex_unlock(&monc->mutex); + return ret; +} + /* * handle incoming message */ diff --git a/fs/ceph/mon_client.h b/fs/ceph/mon_client.h index c75b533..5ca8e48 100644 --- a/fs/ceph/mon_client.h +++ b/fs/ceph/mon_client.h @@ -61,6 +61,7 @@ struct ceph_mon_client { struct ceph_auth_client *auth; struct ceph_msg *m_auth; + int pending_auth; bool hunting; int cur_mon; /* last monitor i contacted */ @@ -110,6 +111,8 @@ extern int ceph_monc_do_statfs(struct ceph_mon_client *monc, extern int ceph_monc_open_session(struct ceph_mon_client *monc); +extern int ceph_monc_validate_auth(struct ceph_mon_client *monc); + #endif diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index 944759b..35c8afe 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -1448,6 +1448,17 @@ static int verify_authorizer_reply(struct ceph_connection *con, int len) return ac->ops->verify_authorizer_reply(ac, o->o_authorizer, len); } +static int invalidate_authorizer(struct ceph_connection *con) +{ + struct ceph_osd *o = con->private; + struct ceph_osd_client *osdc = o->o_osdc; + struct ceph_auth_client *ac = osdc->client->monc.auth; + + if (ac->ops->invalidate_authorizer) + ac->ops->invalidate_authorizer(ac, CEPH_ENTITY_TYPE_OSD); + + return ceph_monc_validate_auth(&osdc->client->monc); +} const static struct ceph_connection_operations osd_con_ops = { .get = get_osd_con, @@ -1455,6 +1466,7 @@ const static struct ceph_connection_operations osd_con_ops = { .dispatch = dispatch, .get_authorizer = get_authorizer, .verify_authorizer_reply = verify_authorizer_reply, + .invalidate_authorizer = invalidate_authorizer, .alloc_msg = alloc_msg, .fault = osd_reset, }; diff --git a/fs/ceph/super.c b/fs/ceph/super.c index cd81c84..3a25489 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -542,7 +542,7 @@ static struct ceph_client *ceph_create_client(struct ceph_mount_args *args) mutex_init(&client->mount_mutex); - init_waitqueue_head(&client->mount_wq); + init_waitqueue_head(&client->auth_wq); client->sb = NULL; client->mount_state = CEPH_MOUNT_MOUNTING; @@ -550,7 +550,7 @@ static struct ceph_client *ceph_create_client(struct ceph_mount_args *args) client->msgr = NULL; - client->mount_err = 0; + client->auth_err = 0; atomic_long_set(&client->writeback_count, 0); err = bdi_init(&client->backing_dev_info); @@ -742,13 +742,13 @@ static int ceph_mount(struct ceph_client *client, struct vfsmount *mnt, /* wait */ dout("mount waiting for mon_map\n"); - err = wait_event_interruptible_timeout(client->mount_wq, /* FIXME */ - have_mon_map(client) || (client->mount_err < 0), + err = wait_event_interruptible_timeout(client->auth_wq, + have_mon_map(client) || (client->auth_err < 0), timeout); if (err == -EINTR || err == -ERESTARTSYS) goto out; - if (client->mount_err < 0) { - err = client->mount_err; + if (client->auth_err < 0) { + err = client->auth_err; goto out; } } diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 62d9ae4..770f7b5 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -123,9 +123,9 @@ struct ceph_client { struct super_block *sb; unsigned long mount_state; - wait_queue_head_t mount_wq; + wait_queue_head_t auth_wq; - int mount_err; + int auth_err; struct ceph_messenger *msgr; /* messenger instance */ struct ceph_mon_client monc; -- cgit v0.10.2 From 07c8739c521cb029d0f3549556aae2d304513978 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 4 Feb 2010 09:42:20 -0800 Subject: ceph: add struct version to auth encoding Inlucde struct version in encoding. This will streamline future protocol changes. Signed-off-by: Sage Weil diff --git a/fs/ceph/auth.c b/fs/ceph/auth.c index d5872d4..b34ce0e 100644 --- a/fs/ceph/auth.c +++ b/fs/ceph/auth.c @@ -107,8 +107,11 @@ int ceph_auth_build_hello(struct ceph_auth_client *ac, void *buf, size_t len) lenp = p; p += sizeof(u32); + ceph_decode_need(&p, end, 1 + sizeof(u32), bad); + ceph_encode_8(&p, 1); num = ARRAY_SIZE(supported_protocols); ceph_encode_32(&p, num); + ceph_decode_need(&p, end, num * sizeof(u32), bad); for (i = 0; i < num; i++) ceph_encode_32(&p, supported_protocols[i]); diff --git a/fs/ceph/auth_none.c b/fs/ceph/auth_none.c index 631017e..b4ef6f0 100644 --- a/fs/ceph/auth_none.c +++ b/fs/ceph/auth_none.c @@ -62,6 +62,7 @@ static int ceph_auth_none_create_authorizer( if (!ai->built_authorizer) { p = au->buf; end = p + sizeof(au->buf); + ceph_encode_8(&p, 1); ret = ceph_entity_name_encode(ac->name, &p, end - 8); if (ret < 0) goto bad; -- cgit v0.10.2 From ec0994e48ea2aebf62ff08376227f3a9ccf46262 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 2 Feb 2010 16:25:35 -0800 Subject: ceph: add support for auth_x authentication protocol The auth_x protocol implements support for a kerberos-like mutual authentication infrastructure used by Ceph. We do not simply use vanilla kerberos because of scalability and performance issues when dealing with a large cluster of nodes providing a single logical service. Auth_x provides mutual authentication of client and server and protects against replay and man in the middle attacks. It does not encrypt the full session over the wire, however, so data payload may still be snooped. Signed-off-by: Yehuda Sadeh Signed-off-by: Sage Weil diff --git a/fs/ceph/Makefile b/fs/ceph/Makefile index 85a588e..6a660e6 100644 --- a/fs/ceph/Makefile +++ b/fs/ceph/Makefile @@ -15,6 +15,7 @@ ceph-objs := super.o inode.o dir.o file.o addr.o ioctl.o \ debugfs.o \ auth.o auth_none.o \ crypto.o armor.o \ + auth_x.o \ ceph_fs.o ceph_strings.o ceph_hash.o ceph_frag.o else diff --git a/fs/ceph/auth.c b/fs/ceph/auth.c index b34ce0e..abb204f 100644 --- a/fs/ceph/auth.c +++ b/fs/ceph/auth.c @@ -5,6 +5,7 @@ #include "types.h" #include "auth_none.h" +#include "auth_x.h" #include "decode.h" #include "super.h" @@ -14,7 +15,8 @@ * get protocol handler */ static u32 supported_protocols[] = { - CEPH_AUTH_NONE + CEPH_AUTH_NONE, + CEPH_AUTH_CEPHX }; int ceph_auth_init_protocol(struct ceph_auth_client *ac, int protocol) @@ -22,6 +24,8 @@ int ceph_auth_init_protocol(struct ceph_auth_client *ac, int protocol) switch (protocol) { case CEPH_AUTH_NONE: return ceph_auth_none_init(ac); + case CEPH_AUTH_CEPHX: + return ceph_x_init(ac); default: return -ENOENT; } diff --git a/fs/ceph/auth_x.c b/fs/ceph/auth_x.c new file mode 100644 index 0000000..f031842 --- /dev/null +++ b/fs/ceph/auth_x.c @@ -0,0 +1,656 @@ + +#include "ceph_debug.h" + +#include +#include +#include + +#include "auth_x.h" +#include "auth_x_protocol.h" +#include "crypto.h" +#include "auth.h" +#include "decode.h" + +struct kmem_cache *ceph_x_ticketbuf_cachep; + +#define TEMP_TICKET_BUF_LEN 256 + +static void ceph_x_validate_tickets(struct ceph_auth_client *ac, int *pneed); + +static int ceph_x_is_authenticated(struct ceph_auth_client *ac) +{ + struct ceph_x_info *xi = ac->private; + int need; + + ceph_x_validate_tickets(ac, &need); + dout("ceph_x_is_authenticated want=%d need=%d have=%d\n", + ac->want_keys, need, xi->have_keys); + return (ac->want_keys & xi->have_keys) == ac->want_keys; +} + +static int ceph_x_encrypt(struct ceph_crypto_key *secret, + void *ibuf, int ilen, void *obuf, size_t olen) +{ + struct ceph_x_encrypt_header head = { + .struct_v = 1, + .magic = cpu_to_le64(CEPHX_ENC_MAGIC) + }; + size_t len = olen - sizeof(u32); + int ret; + + ret = ceph_encrypt2(secret, obuf + sizeof(u32), &len, + &head, sizeof(head), ibuf, ilen); + if (ret) + return ret; + ceph_encode_32(&obuf, len); + return len + sizeof(u32); +} + +static int ceph_x_decrypt(struct ceph_crypto_key *secret, + void **p, void *end, void *obuf, size_t olen) +{ + struct ceph_x_encrypt_header head; + size_t head_len = sizeof(head); + int len, ret; + + len = ceph_decode_32(p); + if (*p + len > end) + return -EINVAL; + + dout("ceph_x_decrypt len %d\n", len); + ret = ceph_decrypt2(secret, &head, &head_len, obuf, &olen, + *p, len); + if (ret) + return ret; + if (head.struct_v != 1 || le64_to_cpu(head.magic) != CEPHX_ENC_MAGIC) + return -EPERM; + *p += len; + return olen; +} + +/* + * get existing (or insert new) ticket handler + */ +struct ceph_x_ticket_handler *get_ticket_handler(struct ceph_auth_client *ac, + int service) +{ + struct ceph_x_ticket_handler *th; + struct ceph_x_info *xi = ac->private; + struct rb_node *parent = NULL, **p = &xi->ticket_handlers.rb_node; + + while (*p) { + parent = *p; + th = rb_entry(parent, struct ceph_x_ticket_handler, node); + if (service < th->service) + p = &(*p)->rb_left; + else if (service > th->service) + p = &(*p)->rb_right; + else + return th; + } + + /* add it */ + th = kzalloc(sizeof(*th), GFP_NOFS); + if (!th) + return ERR_PTR(-ENOMEM); + th->service = service; + rb_link_node(&th->node, parent, p); + rb_insert_color(&th->node, &xi->ticket_handlers); + return th; +} + +static void remove_ticket_handler(struct ceph_auth_client *ac, + struct ceph_x_ticket_handler *th) +{ + struct ceph_x_info *xi = ac->private; + + dout("remove_ticket_handler %p %d\n", th, th->service); + rb_erase(&th->node, &xi->ticket_handlers); + ceph_crypto_key_destroy(&th->session_key); + if (th->ticket_blob) + ceph_buffer_put(th->ticket_blob); + kfree(th); +} + +static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac, + struct ceph_crypto_key *secret, + void *buf, void *end) +{ + struct ceph_x_info *xi = ac->private; + int num; + void *p = buf; + int ret; + char *dbuf; + char *ticket_buf; + u8 struct_v; + + dbuf = kmem_cache_alloc(ceph_x_ticketbuf_cachep, GFP_NOFS | GFP_ATOMIC); + if (!dbuf) + return -ENOMEM; + + ret = -ENOMEM; + ticket_buf = kmem_cache_alloc(ceph_x_ticketbuf_cachep, + GFP_NOFS | GFP_ATOMIC); + if (!ticket_buf) + goto out_dbuf; + + ceph_decode_need(&p, end, 1 + sizeof(u32), bad); + struct_v = ceph_decode_8(&p); + if (struct_v != 1) + goto bad; + num = ceph_decode_32(&p); + dout("%d tickets\n", num); + while (num--) { + int type; + u8 struct_v; + struct ceph_x_ticket_handler *th; + void *dp, *dend; + int dlen; + char is_enc; + struct timespec validity; + struct ceph_crypto_key old_key; + void *tp, *tpend; + + ceph_decode_need(&p, end, sizeof(u32) + 1, bad); + + type = ceph_decode_32(&p); + dout(" ticket type %d %s\n", type, ceph_entity_type_name(type)); + + struct_v = ceph_decode_8(&p); + if (struct_v != 1) + goto bad; + + th = get_ticket_handler(ac, type); + if (IS_ERR(th)) { + ret = PTR_ERR(th); + goto out; + } + + /* blob for me */ + dlen = ceph_x_decrypt(secret, &p, end, dbuf, + TEMP_TICKET_BUF_LEN); + if (dlen <= 0) { + ret = dlen; + goto out; + } + dout(" decrypted %d bytes\n", dlen); + dend = dbuf + dlen; + dp = dbuf; + + struct_v = ceph_decode_8(&dp); + if (struct_v != 1) + goto bad; + + memcpy(&old_key, &th->session_key, sizeof(old_key)); + ret = ceph_crypto_key_decode(&th->session_key, &dp, dend); + if (ret) + goto out; + + ceph_decode_copy(&dp, &th->validity, sizeof(th->validity)); + ceph_decode_timespec(&validity, &th->validity); + th->expires = get_seconds() + validity.tv_sec; + th->renew_after = th->expires - (validity.tv_sec / 4); + dout(" expires=%lu renew_after=%lu\n", th->expires, + th->renew_after); + + /* ticket blob for service */ + ceph_decode_8_safe(&p, end, is_enc, bad); + tp = ticket_buf; + if (is_enc) { + /* encrypted */ + dout(" encrypted ticket\n"); + dlen = ceph_x_decrypt(&old_key, &p, end, ticket_buf, + TEMP_TICKET_BUF_LEN); + if (dlen < 0) { + ret = dlen; + goto out; + } + dlen = ceph_decode_32(&tp); + } else { + /* unencrypted */ + ceph_decode_32_safe(&p, end, dlen, bad); + ceph_decode_need(&p, end, dlen, bad); + ceph_decode_copy(&p, ticket_buf, dlen); + } + tpend = tp + dlen; + dout(" ticket blob is %d bytes\n", dlen); + ceph_decode_need(&tp, tpend, 1 + sizeof(u64), bad); + struct_v = ceph_decode_8(&tp); + th->secret_id = ceph_decode_64(&tp); + ret = ceph_decode_buffer(&th->ticket_blob, &tp, tpend); + if (ret) + goto out; + dout(" got ticket service %d (%s) secret_id %lld len %d\n", + type, ceph_entity_type_name(type), th->secret_id, + (int)th->ticket_blob->vec.iov_len); + xi->have_keys |= th->service; + } + + ret = 0; +out: + kmem_cache_free(ceph_x_ticketbuf_cachep, ticket_buf); +out_dbuf: + kmem_cache_free(ceph_x_ticketbuf_cachep, dbuf); + return ret; + +bad: + ret = -EINVAL; + goto out; +} + +static int ceph_x_build_authorizer(struct ceph_auth_client *ac, + struct ceph_x_ticket_handler *th, + struct ceph_x_authorizer *au) +{ + int len; + struct ceph_x_authorize_a *msg_a; + struct ceph_x_authorize_b msg_b; + void *p, *end; + int ret; + int ticket_blob_len = + (th->ticket_blob ? th->ticket_blob->vec.iov_len : 0); + + dout("build_authorizer for %s %p\n", + ceph_entity_type_name(th->service), au); + + len = sizeof(*msg_a) + sizeof(msg_b) + sizeof(u32) + + ticket_blob_len + 16; + dout(" need len %d\n", len); + if (au->buf && au->buf->alloc_len < len) { + ceph_buffer_put(au->buf); + au->buf = NULL; + } + if (!au->buf) { + au->buf = ceph_buffer_new(len, GFP_NOFS); + if (!au->buf) + return -ENOMEM; + } + au->service = th->service; + + msg_a = au->buf->vec.iov_base; + msg_a->struct_v = 1; + msg_a->global_id = cpu_to_le64(ac->global_id); + msg_a->service_id = cpu_to_le32(th->service); + msg_a->ticket_blob.struct_v = 1; + msg_a->ticket_blob.secret_id = cpu_to_le64(th->secret_id); + msg_a->ticket_blob.blob_len = cpu_to_le32(ticket_blob_len); + if (ticket_blob_len) { + memcpy(msg_a->ticket_blob.blob, th->ticket_blob->vec.iov_base, + th->ticket_blob->vec.iov_len); + } + dout(" th %p secret_id %lld %lld\n", th, th->secret_id, + le64_to_cpu(msg_a->ticket_blob.secret_id)); + + p = msg_a + 1; + p += ticket_blob_len; + end = au->buf->vec.iov_base + au->buf->vec.iov_len; + + get_random_bytes(&au->nonce, sizeof(au->nonce)); + msg_b.struct_v = 1; + msg_b.nonce = cpu_to_le64(au->nonce); + ret = ceph_x_encrypt(&th->session_key, &msg_b, sizeof(msg_b), + p, end - p); + if (ret < 0) + goto out_buf; + p += ret; + au->buf->vec.iov_len = p - au->buf->vec.iov_base; + dout(" built authorizer nonce %llx len %d\n", au->nonce, + (int)au->buf->vec.iov_len); + return 0; + +out_buf: + ceph_buffer_put(au->buf); + au->buf = NULL; + return ret; +} + +static int ceph_x_encode_ticket(struct ceph_x_ticket_handler *th, + void **p, void *end) +{ + ceph_decode_need(p, end, 1 + sizeof(u64), bad); + ceph_encode_8(p, 1); + ceph_encode_64(p, th->secret_id); + if (th->ticket_blob) { + const char *buf = th->ticket_blob->vec.iov_base; + u32 len = th->ticket_blob->vec.iov_len; + + ceph_encode_32_safe(p, end, len, bad); + ceph_encode_copy_safe(p, end, buf, len, bad); + } else { + ceph_encode_32_safe(p, end, 0, bad); + } + + return 0; +bad: + return -ERANGE; +} + +static void ceph_x_validate_tickets(struct ceph_auth_client *ac, int *pneed) +{ + int want = ac->want_keys; + struct ceph_x_info *xi = ac->private; + int service; + + *pneed = ac->want_keys & ~(xi->have_keys); + + for (service = 1; service <= want; service <<= 1) { + struct ceph_x_ticket_handler *th; + + if (!(ac->want_keys & service)) + continue; + + if (*pneed & service) + continue; + + th = get_ticket_handler(ac, service); + + if (!th) { + *pneed |= service; + continue; + } + + if (get_seconds() >= th->renew_after) + *pneed |= service; + if (get_seconds() >= th->expires) + xi->have_keys &= ~service; + } +} + + +static int ceph_x_build_request(struct ceph_auth_client *ac, + void *buf, void *end) +{ + struct ceph_x_info *xi = ac->private; + int need; + struct ceph_x_request_header *head = buf; + int ret; + struct ceph_x_ticket_handler *th = + get_ticket_handler(ac, CEPH_ENTITY_TYPE_AUTH); + + ceph_x_validate_tickets(ac, &need); + + dout("build_request want %x have %x need %x\n", + ac->want_keys, xi->have_keys, need); + + if (need & CEPH_ENTITY_TYPE_AUTH) { + struct ceph_x_authenticate *auth = (void *)(head + 1); + void *p = auth + 1; + struct ceph_x_challenge_blob tmp; + char tmp_enc[40]; + u64 *u; + + if (p > end) + return -ERANGE; + + dout(" get_auth_session_key\n"); + head->op = cpu_to_le16(CEPHX_GET_AUTH_SESSION_KEY); + + /* encrypt and hash */ + get_random_bytes(&auth->client_challenge, sizeof(u64)); + tmp.client_challenge = auth->client_challenge; + tmp.server_challenge = cpu_to_le64(xi->server_challenge); + ret = ceph_x_encrypt(&xi->secret, &tmp, sizeof(tmp), + tmp_enc, sizeof(tmp_enc)); + if (ret < 0) + return ret; + + auth->struct_v = 1; + auth->key = 0; + for (u = (u64 *)tmp_enc; u + 1 <= (u64 *)(tmp_enc + ret); u++) + auth->key ^= *u; + dout(" server_challenge %llx client_challenge %llx key %llx\n", + xi->server_challenge, le64_to_cpu(auth->client_challenge), + le64_to_cpu(auth->key)); + + /* now encode the old ticket if exists */ + ret = ceph_x_encode_ticket(th, &p, end); + if (ret < 0) + return ret; + + return p - buf; + } + + if (need) { + void *p = head + 1; + struct ceph_x_service_ticket_request *req; + + if (p > end) + return -ERANGE; + head->op = cpu_to_le16(CEPHX_GET_PRINCIPAL_SESSION_KEY); + + BUG_ON(!th); + ret = ceph_x_build_authorizer(ac, th, &xi->auth_authorizer); + if (ret) + return ret; + ceph_encode_copy(&p, xi->auth_authorizer.buf->vec.iov_base, + xi->auth_authorizer.buf->vec.iov_len); + + req = p; + req->keys = cpu_to_le32(need); + p += sizeof(*req); + return p - buf; + } + + return 0; +} + +static int ceph_x_handle_reply(struct ceph_auth_client *ac, int result, + void *buf, void *end) +{ + struct ceph_x_info *xi = ac->private; + struct ceph_x_reply_header *head = buf; + struct ceph_x_ticket_handler *th; + int len = end - buf; + int op; + int ret; + + if (result) + return result; /* XXX hmm? */ + + if (xi->starting) { + /* it's a hello */ + struct ceph_x_server_challenge *sc = buf; + + if (len != sizeof(*sc)) + return -EINVAL; + xi->server_challenge = le64_to_cpu(sc->server_challenge); + dout("handle_reply got server challenge %llx\n", + xi->server_challenge); + xi->starting = false; + xi->have_keys &= ~CEPH_ENTITY_TYPE_AUTH; + return -EAGAIN; + } + + op = le32_to_cpu(head->op); + result = le32_to_cpu(head->result); + dout("handle_reply op %d result %d\n", op, result); + switch (op) { + case CEPHX_GET_AUTH_SESSION_KEY: + /* verify auth key */ + ret = ceph_x_proc_ticket_reply(ac, &xi->secret, + buf + sizeof(*head), end); + break; + + case CEPHX_GET_PRINCIPAL_SESSION_KEY: + th = get_ticket_handler(ac, CEPH_ENTITY_TYPE_AUTH); + BUG_ON(!th); + ret = ceph_x_proc_ticket_reply(ac, &th->session_key, + buf + sizeof(*head), end); + break; + + default: + return -EINVAL; + } + if (ret) + return ret; + if (ac->want_keys == xi->have_keys) + return 0; + return -EAGAIN; +} + +static int ceph_x_create_authorizer( + struct ceph_auth_client *ac, int peer_type, + struct ceph_authorizer **a, + void **buf, size_t *len, + void **reply_buf, size_t *reply_len) +{ + struct ceph_x_authorizer *au; + struct ceph_x_ticket_handler *th; + int ret; + + th = get_ticket_handler(ac, peer_type); + if (IS_ERR(th)) + return PTR_ERR(th); + + au = kzalloc(sizeof(*au), GFP_NOFS); + if (!au) + return -ENOMEM; + + ret = ceph_x_build_authorizer(ac, th, au); + if (ret) { + kfree(au); + return ret; + } + + *a = (struct ceph_authorizer *)au; + *buf = au->buf->vec.iov_base; + *len = au->buf->vec.iov_len; + *reply_buf = au->reply_buf; + *reply_len = sizeof(au->reply_buf); + return 0; +} + +static int ceph_x_verify_authorizer_reply(struct ceph_auth_client *ac, + struct ceph_authorizer *a, size_t len) +{ + struct ceph_x_authorizer *au = (void *)a; + struct ceph_x_ticket_handler *th; + int ret = 0; + struct ceph_x_authorize_reply reply; + void *p = au->reply_buf; + void *end = p + sizeof(au->reply_buf); + + th = get_ticket_handler(ac, au->service); + if (!th) + return -EIO; /* hrm! */ + ret = ceph_x_decrypt(&th->session_key, &p, end, &reply, sizeof(reply)); + if (ret < 0) + return ret; + if (ret != sizeof(reply)) + return -EPERM; + + if (au->nonce + 1 != le64_to_cpu(reply.nonce_plus_one)) + ret = -EPERM; + else + ret = 0; + dout("verify_authorizer_reply nonce %llx got %llx ret %d\n", + au->nonce, le64_to_cpu(reply.nonce_plus_one), ret); + return ret; +} + +static void ceph_x_destroy_authorizer(struct ceph_auth_client *ac, + struct ceph_authorizer *a) +{ + struct ceph_x_authorizer *au = (void *)a; + + ceph_buffer_put(au->buf); + kfree(au); +} + + +static void ceph_x_reset(struct ceph_auth_client *ac) +{ + struct ceph_x_info *xi = ac->private; + + dout("reset\n"); + xi->starting = true; + xi->server_challenge = 0; +} + +static void ceph_x_destroy(struct ceph_auth_client *ac) +{ + struct ceph_x_info *xi = ac->private; + struct rb_node *p; + + dout("ceph_x_destroy %p\n", ac); + ceph_crypto_key_destroy(&xi->secret); + + while ((p = rb_first(&xi->ticket_handlers)) != NULL) { + struct ceph_x_ticket_handler *th = + rb_entry(p, struct ceph_x_ticket_handler, node); + remove_ticket_handler(ac, th); + } + + kmem_cache_destroy(ceph_x_ticketbuf_cachep); + + kfree(ac->private); + ac->private = NULL; +} + +static void ceph_x_invalidate_authorizer(struct ceph_auth_client *ac, + int peer_type) +{ + struct ceph_x_ticket_handler *th; + + th = get_ticket_handler(ac, peer_type); + if (th && !IS_ERR(th)) + remove_ticket_handler(ac, th); +} + + +static const struct ceph_auth_client_ops ceph_x_ops = { + .is_authenticated = ceph_x_is_authenticated, + .build_request = ceph_x_build_request, + .handle_reply = ceph_x_handle_reply, + .create_authorizer = ceph_x_create_authorizer, + .verify_authorizer_reply = ceph_x_verify_authorizer_reply, + .destroy_authorizer = ceph_x_destroy_authorizer, + .invalidate_authorizer = ceph_x_invalidate_authorizer, + .reset = ceph_x_reset, + .destroy = ceph_x_destroy, +}; + + +int ceph_x_init(struct ceph_auth_client *ac) +{ + struct ceph_x_info *xi; + int ret; + + dout("ceph_x_init %p\n", ac); + xi = kzalloc(sizeof(*xi), GFP_NOFS); + if (!xi) + return -ENOMEM; + + ret = -ENOMEM; + ceph_x_ticketbuf_cachep = kmem_cache_create("ceph_x_ticketbuf", + TEMP_TICKET_BUF_LEN, 8, + (SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD), + NULL); + if (!ceph_x_ticketbuf_cachep) + goto done_nomem; + ret = -EINVAL; + if (!ac->secret) { + pr_err("no secret set (for auth_x protocol)\n"); + goto done_nomem; + } + + ret = ceph_crypto_key_unarmor(&xi->secret, ac->secret); + if (ret) + goto done_nomem; + + xi->starting = true; + xi->ticket_handlers = RB_ROOT; + + ac->protocol = CEPH_AUTH_CEPHX; + ac->private = xi; + ac->ops = &ceph_x_ops; + return 0; + +done_nomem: + kfree(xi); + if (ceph_x_ticketbuf_cachep) + kmem_cache_destroy(ceph_x_ticketbuf_cachep); + return ret; +} + + diff --git a/fs/ceph/auth_x.h b/fs/ceph/auth_x.h new file mode 100644 index 0000000..ff6f818 --- /dev/null +++ b/fs/ceph/auth_x.h @@ -0,0 +1,49 @@ +#ifndef _FS_CEPH_AUTH_X_H +#define _FS_CEPH_AUTH_X_H + +#include + +#include "crypto.h" +#include "auth.h" +#include "auth_x_protocol.h" + +/* + * Handle ticket for a single service. + */ +struct ceph_x_ticket_handler { + struct rb_node node; + unsigned service; + + struct ceph_crypto_key session_key; + struct ceph_timespec validity; + + u64 secret_id; + struct ceph_buffer *ticket_blob; + + unsigned long renew_after, expires; +}; + + +struct ceph_x_authorizer { + struct ceph_buffer *buf; + unsigned service; + u64 nonce; + char reply_buf[128]; /* big enough for encrypted blob */ +}; + +struct ceph_x_info { + struct ceph_crypto_key secret; + + bool starting; + u64 server_challenge; + + unsigned have_keys; + struct rb_root ticket_handlers; + + struct ceph_x_authorizer auth_authorizer; +}; + +extern int ceph_x_init(struct ceph_auth_client *ac); + +#endif + diff --git a/fs/ceph/auth_x_protocol.h b/fs/ceph/auth_x_protocol.h new file mode 100644 index 0000000..671d305 --- /dev/null +++ b/fs/ceph/auth_x_protocol.h @@ -0,0 +1,90 @@ +#ifndef __FS_CEPH_AUTH_X_PROTOCOL +#define __FS_CEPH_AUTH_X_PROTOCOL + +#define CEPHX_GET_AUTH_SESSION_KEY 0x0100 +#define CEPHX_GET_PRINCIPAL_SESSION_KEY 0x0200 +#define CEPHX_GET_ROTATING_KEY 0x0400 + +/* common bits */ +struct ceph_x_ticket_blob { + __u8 struct_v; + __le64 secret_id; + __le32 blob_len; + char blob[]; +} __attribute__ ((packed)); + + +/* common request/reply headers */ +struct ceph_x_request_header { + __le16 op; +} __attribute__ ((packed)); + +struct ceph_x_reply_header { + __le16 op; + __le32 result; +} __attribute__ ((packed)); + + +/* authenticate handshake */ + +/* initial hello (no reply header) */ +struct ceph_x_server_challenge { + __u8 struct_v; + __le64 server_challenge; +} __attribute__ ((packed)); + +struct ceph_x_authenticate { + __u8 struct_v; + __le64 client_challenge; + __le64 key; + /* ticket blob */ +} __attribute__ ((packed)); + +struct ceph_x_service_ticket_request { + __u8 struct_v; + __le32 keys; +} __attribute__ ((packed)); + +struct ceph_x_challenge_blob { + __le64 server_challenge; + __le64 client_challenge; +} __attribute__ ((packed)); + + + +/* authorize handshake */ + +/* + * The authorizer consists of two pieces: + * a - service id, ticket blob + * b - encrypted with session key + */ +struct ceph_x_authorize_a { + __u8 struct_v; + __le64 global_id; + __le32 service_id; + struct ceph_x_ticket_blob ticket_blob; +} __attribute__ ((packed)); + +struct ceph_x_authorize_b { + __u8 struct_v; + __le64 nonce; +} __attribute__ ((packed)); + +struct ceph_x_authorize_reply { + __u8 struct_v; + __le64 nonce_plus_one; +} __attribute__ ((packed)); + + +/* + * encyption bundle + */ +#define CEPHX_ENC_MAGIC 0xff009cad8826aa55ull + +struct ceph_x_encrypt_header { + __u8 struct_v; + __le64 magic; +} __attribute__ ((packed)); + +#endif -- cgit v0.10.2 From b056c8769d1da6a6a80ce780a4b8957b70434a41 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Wed, 3 Feb 2010 10:47:48 -0800 Subject: ceph: remove unused variable Signed-off-by: Yehuda Sadeh Signed-off-by: Sage Weil diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index 8065dc9..92f4821 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c @@ -505,7 +505,6 @@ static void writepages_finish(struct ceph_osd_request *req, struct ceph_osd_op *op; struct ceph_inode_info *ci = ceph_inode(inode); unsigned wrote; - loff_t offset = req->r_pages[0]->index << PAGE_CACHE_SHIFT; struct page *page; int i; struct ceph_snap_context *snapc = req->r_snapc; -- cgit v0.10.2 From f5a2041bd96c9f05ff10172b9c814c14f247084e Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Wed, 3 Feb 2010 11:00:26 -0800 Subject: ceph: put unused osd connections on lru Instead of removing osd connection immediately when the requests list is empty, put the osd connection on an lru. Only if that osd has not been used for more than a specified time, will it be removed. Signed-off-by: Yehuda Sadeh Signed-off-by: Sage Weil diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index 35c8afe..7f8a26f 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -389,6 +389,7 @@ static struct ceph_osd *create_osd(struct ceph_osd_client *osdc) atomic_set(&osd->o_ref, 1); osd->o_osdc = osdc; INIT_LIST_HEAD(&osd->o_requests); + INIT_LIST_HEAD(&osd->o_osd_lru); osd->o_incarnation = 1; ceph_con_init(osdc->client->msgr, &osd->o_con); @@ -422,25 +423,56 @@ static void put_osd(struct ceph_osd *osd) /* * remove an osd from our map */ -static void remove_osd(struct ceph_osd_client *osdc, struct ceph_osd *osd) +static void __remove_osd(struct ceph_osd_client *osdc, struct ceph_osd *osd) { - dout("remove_osd %p\n", osd); + dout("__remove_osd %p\n", osd); BUG_ON(!list_empty(&osd->o_requests)); rb_erase(&osd->o_node, &osdc->osds); + list_del_init(&osd->o_osd_lru); ceph_con_close(&osd->o_con); put_osd(osd); } +static void __move_osd_to_lru(struct ceph_osd_client *osdc, + struct ceph_osd *osd) +{ + dout("__move_osd_to_lru %p\n", osd); + BUG_ON(!list_empty(&osd->o_osd_lru)); + list_add_tail(&osd->o_osd_lru, &osdc->osd_lru); + osd->lru_ttl = jiffies + osdc->client->mount_args->osd_idle_ttl * HZ; +} + +static void __remove_osd_from_lru(struct ceph_osd *osd) +{ + dout("__remove_osd_from_lru %p\n", osd); + if (!list_empty(&osd->o_osd_lru)) + list_del_init(&osd->o_osd_lru); +} + +static void remove_old_osds(struct ceph_osd_client *osdc, int remove_all) +{ + struct ceph_osd *osd, *nosd; + + dout("__remove_old_osds %p\n", osdc); + mutex_lock(&osdc->request_mutex); + list_for_each_entry_safe(osd, nosd, &osdc->osd_lru, o_osd_lru) { + if (!remove_all && time_before(jiffies, osd->lru_ttl)) + break; + __remove_osd(osdc, osd); + } + mutex_unlock(&osdc->request_mutex); +} + /* * reset osd connect */ -static int reset_osd(struct ceph_osd_client *osdc, struct ceph_osd *osd) +static int __reset_osd(struct ceph_osd_client *osdc, struct ceph_osd *osd) { int ret = 0; - dout("reset_osd %p osd%d\n", osd, osd->o_osd); + dout("__reset_osd %p osd%d\n", osd, osd->o_osd); if (list_empty(&osd->o_requests)) { - remove_osd(osdc, osd); + __remove_osd(osdc, osd); } else { ceph_con_close(&osd->o_con); ceph_con_open(&osd->o_con, &osdc->osdmap->osd_addr[osd->o_osd]); @@ -533,7 +565,7 @@ static void __unregister_request(struct ceph_osd_client *osdc, list_del_init(&req->r_osd_item); if (list_empty(&req->r_osd->o_requests)) - remove_osd(osdc, req->r_osd); + __move_osd_to_lru(osdc, req->r_osd); req->r_osd = NULL; } @@ -611,7 +643,7 @@ static int __map_osds(struct ceph_osd_client *osdc, if (list_empty(&req->r_osd->o_requests)) { /* try to re-use r_osd if possible */ newosd = get_osd(req->r_osd); - remove_osd(osdc, newosd); + __remove_osd(osdc, newosd); } req->r_osd = NULL; } @@ -636,8 +668,10 @@ static int __map_osds(struct ceph_osd_client *osdc, ceph_con_open(&req->r_osd->o_con, &osdc->osdmap->osd_addr[o]); } - if (req->r_osd) + if (req->r_osd) { + __remove_osd_from_lru(req->r_osd); list_add(&req->r_osd_item, &req->r_osd->o_requests); + } err = 1; /* osd changed */ out: @@ -744,6 +778,23 @@ static void handle_timeout(struct work_struct *work) up_read(&osdc->map_sem); } +static void handle_osds_timeout(struct work_struct *work) +{ + struct ceph_osd_client *osdc = + container_of(work, struct ceph_osd_client, + osds_timeout_work.work); + unsigned long delay = + osdc->client->mount_args->osd_idle_ttl * HZ >> 2; + + dout("osds timeout\n"); + down_read(&osdc->map_sem); + remove_old_osds(osdc, 0); + up_read(&osdc->map_sem); + + schedule_delayed_work(&osdc->osds_timeout_work, + round_jiffies_relative(delay)); +} + /* * handle osd op reply. either call the callback if it is specified, * or do the completion to wake up the waiting thread. @@ -881,7 +932,7 @@ static void kick_requests(struct ceph_osd_client *osdc, ceph_osd_addr(osdc->osdmap, osd->o_osd), sizeof(struct ceph_entity_addr)) != 0) - reset_osd(osdc, osd); + __reset_osd(osdc, osd); } } @@ -1195,9 +1246,14 @@ int ceph_osdc_init(struct ceph_osd_client *osdc, struct ceph_client *client) osdc->timeout_tid = 0; osdc->last_tid = 0; osdc->osds = RB_ROOT; + INIT_LIST_HEAD(&osdc->osd_lru); osdc->requests = RB_ROOT; osdc->num_requests = 0; INIT_DELAYED_WORK(&osdc->timeout_work, handle_timeout); + INIT_DELAYED_WORK(&osdc->osds_timeout_work, handle_osds_timeout); + + schedule_delayed_work(&osdc->osds_timeout_work, + round_jiffies_relative(osdc->client->mount_args->osd_idle_ttl * HZ)); err = -ENOMEM; osdc->req_mempool = mempool_create_kmalloc_pool(10, @@ -1219,10 +1275,12 @@ out: void ceph_osdc_stop(struct ceph_osd_client *osdc) { cancel_delayed_work_sync(&osdc->timeout_work); + cancel_delayed_work_sync(&osdc->osds_timeout_work); if (osdc->osdmap) { ceph_osdmap_destroy(osdc->osdmap); osdc->osdmap = NULL; } + remove_old_osds(osdc, 1); mempool_destroy(osdc->req_mempool); ceph_msgpool_destroy(&osdc->msgpool_op); } diff --git a/fs/ceph/osd_client.h b/fs/ceph/osd_client.h index 8d533d9..70f31b6 100644 --- a/fs/ceph/osd_client.h +++ b/fs/ceph/osd_client.h @@ -31,9 +31,11 @@ struct ceph_osd { struct rb_node o_node; struct ceph_connection o_con; struct list_head o_requests; + struct list_head o_osd_lru; struct ceph_authorizer *o_authorizer; void *o_authorizer_buf, *o_authorizer_reply_buf; size_t o_authorizer_buf_len, o_authorizer_reply_buf_len; + unsigned long lru_ttl; }; /* an in-flight request */ @@ -90,11 +92,13 @@ struct ceph_osd_client { struct mutex request_mutex; struct rb_root osds; /* osds */ + struct list_head osd_lru; /* idle osds */ u64 timeout_tid; /* tid of timeout triggering rq */ u64 last_tid; /* tid of last request */ struct rb_root requests; /* pending requests */ int num_requests; struct delayed_work timeout_work; + struct delayed_work osds_timeout_work; #ifdef CONFIG_DEBUG_FS struct dentry *debugfs_file; #endif diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 3a25489..39aaf29 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -293,6 +293,7 @@ enum { Opt_rsize, Opt_osdtimeout, Opt_mount_timeout, + Opt_osd_idle_ttl, Opt_caps_wanted_delay_min, Opt_caps_wanted_delay_max, Opt_readdir_max_entries, @@ -322,6 +323,7 @@ static match_table_t arg_tokens = { {Opt_rsize, "rsize=%d"}, {Opt_osdtimeout, "osdtimeout=%d"}, {Opt_mount_timeout, "mount_timeout=%d"}, + {Opt_osd_idle_ttl, "osd_idle_ttl=%d"}, {Opt_caps_wanted_delay_min, "caps_wanted_delay_min=%d"}, {Opt_caps_wanted_delay_max, "caps_wanted_delay_max=%d"}, {Opt_readdir_max_entries, "readdir_max_entries=%d"}, @@ -367,6 +369,7 @@ static struct ceph_mount_args *parse_mount_args(int flags, char *options, args->flags = CEPH_OPT_DEFAULT; args->osd_timeout = 5; /* seconds */ args->mount_timeout = CEPH_MOUNT_TIMEOUT_DEFAULT; /* seconds */ + args->osd_idle_ttl = CEPH_OSD_IDLE_TTL_DEFAULT; /* seconds */ args->caps_wanted_delay_min = CEPH_CAPS_WANTED_DELAY_MIN_DEFAULT; args->caps_wanted_delay_max = CEPH_CAPS_WANTED_DELAY_MAX_DEFAULT; args->rsize = CEPH_MOUNT_RSIZE_DEFAULT; diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 770f7b5..3930fb6 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -53,6 +53,7 @@ struct ceph_mount_args { struct ceph_entity_addr *mon_addr; int flags; int mount_timeout; + int osd_idle_ttl; int caps_wanted_delay_min, caps_wanted_delay_max; struct ceph_fsid fsid; struct ceph_entity_addr my_addr; @@ -71,6 +72,7 @@ struct ceph_mount_args { * defaults */ #define CEPH_MOUNT_TIMEOUT_DEFAULT 60 +#define CEPH_OSD_IDLE_TTL_DEFAULT 60 #define CEPH_MOUNT_RSIZE_DEFAULT (512*1024) /* readahead */ #define CEPH_MSG_MAX_FRONT_LEN (16*1024*1024) -- cgit v0.10.2 From 02f90c61096ec3ad691e808a4aa7ca5a06e550ec Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 4 Feb 2010 16:18:10 -0800 Subject: ceph: add uid field to ceph_pg_pool Also verify encoding version as we go. Signed-off-by: Sage Weil diff --git a/fs/ceph/osdmap.c b/fs/ceph/osdmap.c index a143c51..a6afe38 100644 --- a/fs/ceph/osdmap.c +++ b/fs/ceph/osdmap.c @@ -426,6 +426,11 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end) map->pg_temp = RB_ROOT; ceph_decode_16_safe(p, end, version, bad); + if (version > CEPH_OSDMAP_VERSION) { + pr_warning("got unknown v %d > %d of osdmap\n", version, + CEPH_OSDMAP_VERSION); + goto bad; + } ceph_decode_need(p, end, 2*sizeof(u64)+6*sizeof(u32), bad); ceph_decode_copy(p, &map->fsid, sizeof(map->fsid)); @@ -447,6 +452,11 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end) if (i >= map->num_pools) goto bad; ev = ceph_decode_8(p); /* encoding version */ + if (ev > CEPH_PG_POOL_VERSION) { + pr_warning("got unknown v %d > %d of ceph_pg_pool\n", + ev, CEPH_PG_POOL_VERSION); + goto bad; + } ceph_decode_copy(p, &map->pg_pool[i].v, sizeof(map->pg_pool->v)); calc_pg_masks(&map->pg_pool[i]); @@ -552,6 +562,11 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, struct rb_node *rbp; ceph_decode_16_safe(p, end, version, bad); + if (version > CEPH_OSDMAP_INC_VERSION) { + pr_warning("got unknown v %d > %d of inc osdmap\n", version, + CEPH_OSDMAP_INC_VERSION); + goto bad; + } ceph_decode_need(p, end, sizeof(fsid)+sizeof(modified)+2*sizeof(u32), bad); @@ -624,6 +639,11 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, } ceph_decode_need(p, end, 1 + sizeof(map->pg_pool->v), bad); ev = ceph_decode_8(p); /* encoding version */ + if (ev > CEPH_PG_POOL_VERSION) { + pr_warning("got unknown v %d > %d of ceph_pg_pool\n", + ev, CEPH_PG_POOL_VERSION); + goto bad; + } ceph_decode_copy(p, &map->pg_pool[pool].v, sizeof(map->pg_pool->v)); calc_pg_masks(&map->pg_pool[pool]); diff --git a/fs/ceph/rados.h b/fs/ceph/rados.h index 123fd84..1f4c786 100644 --- a/fs/ceph/rados.h +++ b/fs/ceph/rados.h @@ -9,6 +9,12 @@ #include "msgr.h" /* + * osdmap encoding versions + */ +#define CEPH_OSDMAP_INC_VERSION 3 +#define CEPH_OSDMAP_VERSION 3 + +/* * fs id */ struct ceph_fsid { @@ -80,6 +86,7 @@ struct ceph_pg { */ #define CEPH_PG_TYPE_REP 1 #define CEPH_PG_TYPE_RAID4 2 +#define CEPH_PG_POOL_VERSION 2 struct ceph_pg_pool { __u8 type; /* CEPH_PG_TYPE_* */ __u8 size; /* number of osds in each pg */ @@ -92,6 +99,7 @@ struct ceph_pg_pool { __le32 snap_epoch; /* epoch of last snap */ __le32 num_snaps; __le32 num_removed_snap_intervals; + __le64 uid; } __attribute__ ((packed)); /* -- cgit v0.10.2 From 972f0d3ab1a15cb5d790dd8c53903066084b28f2 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Thu, 4 Feb 2010 13:41:41 -0800 Subject: ceph: fix short synchronous reads Zeroing of holes was not done correctly: page_off was miscalculated and zeroing the tail didn't not adjust the 'read' value to include the zeroed portion. Signed-off-by: Yehuda Sadeh Signed-off-by: Sage Weil diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 2d88c80..43bd2f2 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -395,23 +395,22 @@ static void zero_page_vector_range(int off, int len, struct page **pages) { int i = off >> PAGE_CACHE_SHIFT; + off &= ~PAGE_CACHE_MASK; + dout("zero_page_vector_page %u~%u\n", off, len); - BUG_ON(len < PAGE_CACHE_SIZE); /* leading partial page? */ - if (off & ~PAGE_CACHE_MASK) { + if (off) { + int end = min((int)PAGE_CACHE_SIZE, off + len); dout("zeroing %d %p head from %d\n", i, pages[i], - (int)(off & ~PAGE_CACHE_MASK)); - zero_user_segment(pages[i], off & ~PAGE_CACHE_MASK, - PAGE_CACHE_SIZE); - off += PAGE_CACHE_SIZE; - off &= PAGE_CACHE_MASK; + (int)off); + zero_user_segment(pages[i], off, end); + len -= (end - off); i++; } while (len >= PAGE_CACHE_SIZE) { dout("zeroing %d %p\n", i, pages[i]); zero_user_segment(pages[i], 0, PAGE_CACHE_SIZE); - off += PAGE_CACHE_SIZE; len -= PAGE_CACHE_SIZE; i++; } @@ -437,7 +436,7 @@ static int striped_read(struct inode *inode, struct ceph_client *client = ceph_inode_to_client(inode); struct ceph_inode_info *ci = ceph_inode(inode); u64 pos, this_len; - int page_off = off & ~PAGE_CACHE_SIZE; /* first byte's offset in page */ + int page_off = off & ~PAGE_CACHE_MASK; /* first byte's offset in page */ int left, pages_left; int read; struct page **page_pos; @@ -493,6 +492,7 @@ more: dout("zero tail\n"); zero_page_vector_range(page_off + read, len - read, pages); + read = len; goto out; } -- cgit v0.10.2 From 4af6b2257ee0eb8f4bf3b1dc8acb643c0e8a887f Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Tue, 9 Feb 2010 11:02:51 -0800 Subject: ceph: refactor ceph_write_begin, fix ceph_page_mkwrite Originally ceph_page_mkwrite called ceph_write_begin, hoping that the returned locked page would be the page that it was requested to mkwrite. Factored out relevant part of ceph_page_mkwrite and we lock the right page anyway. Signed-off-by: Yehuda Sadeh Signed-off-by: Sage Weil diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index 92f4821..89c5ff3 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c @@ -907,15 +907,13 @@ static int context_is_writeable_or_written(struct inode *inode, * We are only allowed to write into/dirty the page if the page is * clean, or already dirty within the same snap context. */ -static int ceph_write_begin(struct file *file, struct address_space *mapping, - loff_t pos, unsigned len, unsigned flags, - struct page **pagep, void **fsdata) +static int ceph_update_writeable_page(struct file *file, + loff_t pos, unsigned len, + struct page *page) { struct inode *inode = file->f_dentry->d_inode; struct ceph_inode_info *ci = ceph_inode(inode); struct ceph_mds_client *mdsc = &ceph_inode_to_client(inode)->mdsc; - struct page *page; - pgoff_t index = pos >> PAGE_CACHE_SHIFT; loff_t page_off = pos & PAGE_CACHE_MASK; int pos_in_page = pos & ~PAGE_CACHE_MASK; int end_in_page = pos_in_page + len; @@ -923,16 +921,6 @@ static int ceph_write_begin(struct file *file, struct address_space *mapping, struct ceph_snap_context *snapc; int r; - /* get a page*/ -retry: - page = grab_cache_page_write_begin(mapping, index, 0); - if (!page) - return -ENOMEM; - *pagep = page; - - dout("write_begin file %p inode %p page %p %d~%d\n", file, - inode, page, (int)pos, (int)len); - retry_locked: /* writepages currently holds page lock, but if we change that later, */ wait_on_page_writeback(page); @@ -964,7 +952,7 @@ retry_locked: wait_event_interruptible(ci->i_cap_wq, context_is_writeable_or_written(inode, snapc)); ceph_put_snap_context(snapc); - goto retry; + return -EAGAIN; } /* yay, writeable, do it now (without dropping page lock) */ @@ -1022,6 +1010,35 @@ fail_nosnap: } /* + * We are only allowed to write into/dirty the page if the page is + * clean, or already dirty within the same snap context. + */ +static int ceph_write_begin(struct file *file, struct address_space *mapping, + loff_t pos, unsigned len, unsigned flags, + struct page **pagep, void **fsdata) +{ + struct inode *inode = file->f_dentry->d_inode; + struct page *page; + pgoff_t index = pos >> PAGE_CACHE_SHIFT; + int r; + + do { + /* get a page*/ + page = grab_cache_page_write_begin(mapping, index, 0); + if (!page) + return -ENOMEM; + *pagep = page; + + dout("write_begin file %p inode %p page %p %d~%d\n", file, + inode, page, (int)pos, (int)len); + + r = ceph_update_writeable_page(file, pos, len, page); + } while (r == -EAGAIN); + + return r; +} + +/* * we don't do anything in here that simple_write_end doesn't do * except adjust dirty page accounting and drop read lock on * mdsc->snap_rwsem. @@ -1104,8 +1121,6 @@ static int ceph_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) struct ceph_mds_client *mdsc = &ceph_inode_to_client(inode)->mdsc; loff_t off = page->index << PAGE_CACHE_SHIFT; loff_t size, len; - struct page *locked_page = NULL; - void *fsdata = NULL; int ret; size = i_size_read(inode); @@ -1116,23 +1131,30 @@ static int ceph_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) dout("page_mkwrite %p %llu~%llu page %p idx %lu\n", inode, off, len, page, page->index); - ret = ceph_write_begin(vma->vm_file, inode->i_mapping, off, len, 0, - &locked_page, &fsdata); - WARN_ON(page != locked_page); - if (!ret) { - /* - * doing the following, instead of calling - * ceph_write_end. Note that we keep the - * page locked - */ + + lock_page(page); + + ret = VM_FAULT_NOPAGE; + if ((off > size) || + (page->mapping != inode->i_mapping)) + goto out; + + ret = ceph_update_writeable_page(vma->vm_file, off, len, page); + if (ret == 0) { + /* success. we'll keep the page locked. */ set_page_dirty(page); up_read(&mdsc->snap_rwsem); - page_cache_release(page); ret = VM_FAULT_LOCKED; } else { - ret = VM_FAULT_SIGBUS; + if (ret == -ENOMEM) + ret = VM_FAULT_OOM; + else + ret = VM_FAULT_SIGBUS; } +out: dout("page_mkwrite %p %llu~%llu = %d\n", inode, off, len, ret); + if (ret != VM_FAULT_LOCKED) + unlock_page(page); return ret; } -- cgit v0.10.2 From 3d497d858ae6e5f23a28783030aecc69074e102d Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Tue, 9 Feb 2010 11:08:40 -0800 Subject: ceph: fix truncation when not holding caps A truncation should occur when either we have the specified caps for the file, or (in cases where we are not the only ones referencing the file) when it is mapped or when it is opened. The latter two cases were not handled. Signed-off-by: Yehuda Sadeh Signed-off-by: Sage Weil diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index a4f573a..af85f2d 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -416,9 +416,17 @@ int ceph_fill_file_size(struct inode *inode, int issued, dout("truncate_seq %u -> %u\n", ci->i_truncate_seq, truncate_seq); ci->i_truncate_seq = truncate_seq; - if (issued & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_RD| + /* + * If we hold relevant caps, or in the case where we're + * not the only client referencing this file and we + * don't hold those caps, then we need to check whether + * the file is either opened or mmaped + */ + if ((issued & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_RD| CEPH_CAP_FILE_WR|CEPH_CAP_FILE_BUFFER| - CEPH_CAP_FILE_EXCL)) { + CEPH_CAP_FILE_EXCL)) || + mapping_mapped(inode->i_mapping) || + __ceph_caps_file_wanted(ci)) { ci->i_truncate_pending++; queue_trunc = 1; } -- cgit v0.10.2 From 29065a513aa4c7e4b46b77cbcd25f814a4ca0bfe Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Tue, 9 Feb 2010 11:14:41 -0800 Subject: ceph: sync read/write considers page cache In the cases where we either do a sync read or a write, we need to make sure that everything in the page cache is flushed. In the case of a sync write we invalidate the relevant pages, so that subsequent read/write reflects the new data written. Signed-off-by: Yehuda Sadeh Signed-off-by: Sage Weil diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 43bd2f2..bbf1ccf 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -409,7 +409,7 @@ static void zero_page_vector_range(int off, int len, struct page **pages) i++; } while (len >= PAGE_CACHE_SIZE) { - dout("zeroing %d %p\n", i, pages[i]); + dout("zeroing %d %p len=%d\n", i, pages[i], len); zero_user_segment(pages[i], 0, PAGE_CACHE_SIZE); len -= PAGE_CACHE_SIZE; i++; @@ -542,13 +542,16 @@ static ssize_t ceph_sync_read(struct file *file, char __user *data, * but it will at least behave sensibly when they are * in sequence. */ - filemap_write_and_wait(inode->i_mapping); } else { pages = alloc_page_vector(num_pages); } if (IS_ERR(pages)) return PTR_ERR(pages); + ret = filemap_write_and_wait(inode->i_mapping); + if (ret < 0) + goto done; + ret = striped_read(inode, off, len, pages, num_pages); if (ret >= 0 && (file->f_flags & O_DIRECT) == 0) @@ -556,6 +559,7 @@ static ssize_t ceph_sync_read(struct file *file, char __user *data, if (ret >= 0) *poff = off + ret; +done: if (file->f_flags & O_DIRECT) put_page_vector(pages, num_pages); else @@ -617,6 +621,16 @@ static ssize_t ceph_sync_write(struct file *file, const char __user *data, else pos = *offset; + ret = filemap_write_and_wait_range(inode->i_mapping, pos, pos + left); + if (ret < 0) + return ret; + + ret = invalidate_inode_pages2_range(inode->i_mapping, + pos >> PAGE_CACHE_SHIFT, + (pos + left) >> PAGE_CACHE_SHIFT); + if (ret < 0) + dout("invalidate_inode_pages2_range returned %d\n", ret); + flags = CEPH_OSD_FLAG_ORDERSNAP | CEPH_OSD_FLAG_ONDISK | CEPH_OSD_FLAG_WRITE; -- cgit v0.10.2 From cbd03635913a86afb7c2cfc0058932956b05b51e Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 9 Feb 2010 13:41:18 -0800 Subject: ceph: cap revocation fixes Try to invalidate pages in ceph_check_caps() if FILE_CACHE is being revoked. If we fail, queue an immediate async invalidate if FILE_CACHE is being revoked. (If it's not being revoked, we just queue the caps for later evaluation later, as per the old behavior.) Signed-off-by: Sage Weil diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 847ae64..822f7d3 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -1374,12 +1374,13 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags, int file_wanted, used; int took_snap_rwsem = 0; /* true if mdsc->snap_rwsem held */ int drop_session_lock = session ? 0 : 1; - int want, retain, revoking, flushing = 0; + int issued, implemented, want, retain, revoking, flushing = 0; int mds = -1; /* keep track of how far we've gone through i_caps list to avoid an infinite loop on retry */ struct rb_node *p; int tried_invalidate = 0; int delayed = 0, sent = 0, force_requeue = 0, num; + int queue_invalidate = 0; int is_delayed = flags & CHECK_CAPS_NODELAY; /* if we are unmounting, flush any unused caps immediately. */ @@ -1401,6 +1402,8 @@ retry_locked: file_wanted = __ceph_caps_file_wanted(ci); used = __ceph_caps_used(ci); want = file_wanted | used; + issued = __ceph_caps_issued(ci, &implemented); + revoking = implemented & ~issued; retain = want | CEPH_CAP_PIN; if (!mdsc->stopping && inode->i_nlink > 0) { @@ -1419,11 +1422,11 @@ retry_locked: } dout("check_caps %p file_want %s used %s dirty %s flushing %s" - " issued %s retain %s %s%s%s\n", inode, + " issued %s revoking %s retain %s %s%s%s\n", inode, ceph_cap_string(file_wanted), ceph_cap_string(used), ceph_cap_string(ci->i_dirty_caps), ceph_cap_string(ci->i_flushing_caps), - ceph_cap_string(__ceph_caps_issued(ci, NULL)), + ceph_cap_string(issued), ceph_cap_string(revoking), ceph_cap_string(retain), (flags & CHECK_CAPS_AUTHONLY) ? " AUTHONLY" : "", (flags & CHECK_CAPS_NODELAY) ? " NODELAY" : "", @@ -1437,7 +1440,8 @@ retry_locked: if ((!is_delayed || mdsc->stopping) && ci->i_wrbuffer_ref == 0 && /* no dirty pages... */ ci->i_rdcache_gen && /* may have cached pages */ - file_wanted == 0 && /* no open files */ + (file_wanted == 0 || /* no open files */ + (revoking & CEPH_CAP_FILE_CACHE)) && /* or revoking cache */ !ci->i_truncate_pending && !tried_invalidate) { u32 invalidating_gen = ci->i_rdcache_gen; @@ -1451,6 +1455,10 @@ retry_locked: /* success. */ ci->i_rdcache_gen = 0; ci->i_rdcache_revoking = 0; + } else if (revoking & CEPH_CAP_FILE_CACHE) { + dout("check_caps queuing invalidate\n"); + queue_invalidate = 1; + ci->i_rdcache_revoking = ci->i_rdcache_gen; } else { dout("check_caps failed to invalidate pages\n"); /* we failed to invalidate pages. check these @@ -1476,7 +1484,7 @@ retry_locked: revoking = cap->implemented & ~cap->issued; if (revoking) - dout("mds%d revoking %s\n", cap->mds, + dout(" mds%d revoking %s\n", cap->mds, ceph_cap_string(revoking)); if (cap == ci->i_auth_cap && @@ -1591,6 +1599,10 @@ ack: spin_unlock(&inode->i_lock); + if (queue_invalidate) + if (ceph_queue_page_invalidation(inode)) + igrab(inode); + if (session && drop_session_lock) mutex_unlock(&session->s_mutex); if (took_snap_rwsem) -- cgit v0.10.2 From 68c283236a1e0772e1a469dd2ffc17afc300b07b Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 9 Feb 2010 13:41:47 -0800 Subject: ceph: do not retain caps that are being revoked Never retain caps in __send_cap() that are being revoked. Signed-off-by: Sage Weil diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 822f7d3..7f4841c 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -1042,10 +1042,7 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap, struct ceph_inode_info *ci = cap->ci; struct inode *inode = &ci->vfs_inode; u64 cap_id = cap->cap_id; - int held = cap->issued | cap->implemented; - int revoking = cap->implemented & ~cap->issued; - int dropping = cap->issued & ~retain; - int keep; + int held, revoking, dropping, keep; u64 seq, issue_seq, mseq, time_warp_seq, follows; u64 size, max_size; struct timespec mtime, atime; @@ -1060,6 +1057,11 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap, int i; int ret; + held = cap->issued | cap->implemented; + revoking = cap->implemented & ~cap->issued; + retain &= ~revoking; + dropping = cap->issued & ~retain; + dout("__send_cap %p cap %p session %p %s -> %s (revoking %s)\n", inode, cap, cap->session, ceph_cap_string(held), ceph_cap_string(held & retain), -- cgit v0.10.2 From 6a026589ba333185c466c906376fe022a27a53f9 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 9 Feb 2010 14:04:02 -0800 Subject: ceph: fix sync read eof check deadlock If a sync read gets a short result from the OSD, it may need to do a getattr to see if it is short due to reaching end-of-file. The getattr was being done while holding a reference to FILE_RD, which can lead to a deadlock if the MDS is revoking that capability bit and can't process the getattr until it does. We fix this by setting a flag if EOF size validation is needed, and doing the getattr in ceph_aio_read, after the RD cap ref is dropped. If the read needs to be continued, we loop and continue traversing the file. Signed-off-by: Sage Weil diff --git a/fs/ceph/file.c b/fs/ceph/file.c index bbf1ccf..2c4ae44 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -431,7 +431,8 @@ static void zero_page_vector_range(int off, int len, struct page **pages) */ static int striped_read(struct inode *inode, u64 off, u64 len, - struct page **pages, int num_pages) + struct page **pages, int num_pages, + int *checkeof) { struct ceph_client *client = ceph_inode_to_client(inode); struct ceph_inode_info *ci = ceph_inode(inode); @@ -497,15 +498,7 @@ more: } /* check i_size */ - ret = ceph_do_getattr(inode, CEPH_STAT_CAP_SIZE); - if (ret < 0) - goto out; - - /* hit EOF? */ - if (pos >= inode->i_size) - goto out; - - goto more; + *checkeof = 1; } out: @@ -522,7 +515,7 @@ out: * If the read spans object boundary, just do multiple reads. */ static ssize_t ceph_sync_read(struct file *file, char __user *data, - unsigned len, loff_t *poff) + unsigned len, loff_t *poff, int *checkeof) { struct inode *inode = file->f_dentry->d_inode; struct page **pages; @@ -552,7 +545,7 @@ static ssize_t ceph_sync_read(struct file *file, char __user *data, if (ret < 0) goto done; - ret = striped_read(inode, off, len, pages, num_pages); + ret = striped_read(inode, off, len, pages, num_pages, checkeof); if (ret >= 0 && (file->f_flags & O_DIRECT) == 0) ret = copy_page_vector_to_user(pages, data, off, ret); @@ -746,11 +739,14 @@ static ssize_t ceph_aio_read(struct kiocb *iocb, const struct iovec *iov, size_t len = iov->iov_len; struct inode *inode = filp->f_dentry->d_inode; struct ceph_inode_info *ci = ceph_inode(inode); + void *base = iov->iov_base; ssize_t ret; int got = 0; + int checkeof = 0, read = 0; dout("aio_read %p %llx.%llx %llu~%u trying to get caps on %p\n", inode, ceph_vinop(inode), pos, (unsigned)len, inode); +again: __ceph_do_pending_vmtruncate(inode); ret = ceph_get_caps(ci, CEPH_CAP_FILE_RD, CEPH_CAP_FILE_CACHE, &got, -1); @@ -764,7 +760,7 @@ static ssize_t ceph_aio_read(struct kiocb *iocb, const struct iovec *iov, (iocb->ki_filp->f_flags & O_DIRECT) || (inode->i_sb->s_flags & MS_SYNCHRONOUS)) /* hmm, this isn't really async... */ - ret = ceph_sync_read(filp, iov->iov_base, len, ppos); + ret = ceph_sync_read(filp, base, len, ppos, &checkeof); else ret = generic_file_aio_read(iocb, iov, nr_segs, pos); @@ -772,6 +768,23 @@ out: dout("aio_read %p %llx.%llx dropping cap refs on %s = %d\n", inode, ceph_vinop(inode), ceph_cap_string(got), (int)ret); ceph_put_cap_refs(ci, got); + + if (checkeof && ret >= 0) { + int statret = ceph_do_getattr(inode, CEPH_STAT_CAP_SIZE); + + /* hit EOF or hole? */ + if (statret == 0 && *ppos < inode->i_size) { + dout("aio_read sync_read hit hole, reading more\n"); + read += ret; + base += ret; + len -= ret; + checkeof = 0; + goto again; + } + } + if (ret >= 0) + ret += read; + return ret; } -- cgit v0.10.2 From 3c6f6b79a64db7f1c7abf09d693db3b0066784fb Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 9 Feb 2010 15:24:44 -0800 Subject: ceph: cleanup async writeback, truncation, invalidate helpers Grab inode ref in helper. Make work functions static, with consistent naming. Signed-off-by: Sage Weil diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index 89c5ff3..71f5ad1 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c @@ -947,8 +947,7 @@ retry_locked: */ snapc = ceph_get_snap_context((void *)page->private); unlock_page(page); - if (ceph_queue_writeback(inode)) - igrab(inode); + ceph_queue_writeback(inode); wait_event_interruptible(ci->i_cap_wq, context_is_writeable_or_written(inode, snapc)); ceph_put_snap_context(snapc); diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 7f4841c..68ee781 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -1602,8 +1602,7 @@ ack: spin_unlock(&inode->i_lock); if (queue_invalidate) - if (ceph_queue_page_invalidation(inode)) - igrab(inode); + ceph_queue_invalidate(inode); if (session && drop_session_lock) mutex_unlock(&session->s_mutex); @@ -2178,7 +2177,7 @@ static int handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant, int wake = 0; int writeback = 0; int revoked_rdcache = 0; - int invalidate_async = 0; + int queue_invalidate = 0; int tried_invalidate = 0; int ret; @@ -2205,7 +2204,7 @@ restart: /* there were locked pages.. invalidate later in a separate thread. */ if (ci->i_rdcache_revoking != ci->i_rdcache_gen) { - invalidate_async = 1; + queue_invalidate = 1; ci->i_rdcache_revoking = ci->i_rdcache_gen; } } else { @@ -2319,21 +2318,15 @@ restart: } spin_unlock(&inode->i_lock); - if (writeback) { + if (writeback) /* * queue inode for writeback: we can't actually call * filemap_write_and_wait, etc. from message handler * context. */ - dout("queueing %p for writeback\n", inode); - if (ceph_queue_writeback(inode)) - igrab(inode); - } - if (invalidate_async) { - dout("queueing %p for page invalidation\n", inode); - if (ceph_queue_page_invalidation(inode)) - igrab(inode); - } + ceph_queue_writeback(inode); + if (queue_invalidate) + ceph_queue_invalidate(inode); if (wake) wake_up(&ci->i_cap_wq); return reply; @@ -2479,9 +2472,7 @@ static void handle_cap_trunc(struct inode *inode, spin_unlock(&inode->i_lock); if (queue_trunc) - if (queue_work(ceph_client(inode->i_sb)->trunc_wq, - &ci->i_vmtruncate_work)) - igrab(inode); + ceph_queue_vmtruncate(inode); } /* diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index af85f2d..58bdff0 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -28,7 +28,9 @@ static const struct inode_operations ceph_symlink_iops; -static void ceph_inode_invalidate_pages(struct work_struct *work); +static void ceph_invalidate_work(struct work_struct *work); +static void ceph_writeback_work(struct work_struct *work); +static void ceph_vmtruncate_work(struct work_struct *work); /* * find or create an inode, given the ceph ino number @@ -357,8 +359,8 @@ struct inode *ceph_alloc_inode(struct super_block *sb) INIT_LIST_HEAD(&ci->i_snap_realm_item); INIT_LIST_HEAD(&ci->i_snap_flush_item); - INIT_WORK(&ci->i_wb_work, ceph_inode_writeback); - INIT_WORK(&ci->i_pg_inv_work, ceph_inode_invalidate_pages); + INIT_WORK(&ci->i_wb_work, ceph_writeback_work); + INIT_WORK(&ci->i_pg_inv_work, ceph_invalidate_work); INIT_WORK(&ci->i_vmtruncate_work, ceph_vmtruncate_work); @@ -675,9 +677,7 @@ no_change: /* queue truncate if we saw i_size decrease */ if (queue_trunc) - if (queue_work(ceph_client(inode->i_sb)->trunc_wq, - &ci->i_vmtruncate_work)) - igrab(inode); + ceph_queue_vmtruncate(inode); /* populate frag tree */ /* FIXME: move me up, if/when version reflects fragtree changes */ @@ -1243,7 +1243,18 @@ int ceph_inode_set_size(struct inode *inode, loff_t size) * Write back inode data in a worker thread. (This can't be done * in the message handler context.) */ -void ceph_inode_writeback(struct work_struct *work) +void ceph_queue_writeback(struct inode *inode) +{ + if (queue_work(ceph_inode_to_client(inode)->wb_wq, + &ceph_inode(inode)->i_wb_work)) { + dout("ceph_queue_invalidate %p\n", inode); + igrab(inode); + } else { + dout("ceph_queue_invalidate %p failed\n", inode); + } +} + +static void ceph_writeback_work(struct work_struct *work) { struct ceph_inode_info *ci = container_of(work, struct ceph_inode_info, i_wb_work); @@ -1255,10 +1266,24 @@ void ceph_inode_writeback(struct work_struct *work) } /* + * queue an async invalidation + */ +void ceph_queue_invalidate(struct inode *inode) +{ + if (queue_work(ceph_inode_to_client(inode)->pg_inv_wq, + &ceph_inode(inode)->i_pg_inv_work)) { + dout("ceph_queue_invalidate %p\n", inode); + igrab(inode); + } else { + dout("ceph_queue_invalidate %p failed\n", inode); + } +} + +/* * Invalidate inode pages in a worker thread. (This can't be done * in the message handler context.) */ -static void ceph_inode_invalidate_pages(struct work_struct *work) +static void ceph_invalidate_work(struct work_struct *work) { struct ceph_inode_info *ci = container_of(work, struct ceph_inode_info, i_pg_inv_work); @@ -1307,7 +1332,7 @@ out: * * We also truncate in a separate thread as well. */ -void ceph_vmtruncate_work(struct work_struct *work) +static void ceph_vmtruncate_work(struct work_struct *work) { struct ceph_inode_info *ci = container_of(work, struct ceph_inode_info, i_vmtruncate_work); @@ -1321,6 +1346,24 @@ void ceph_vmtruncate_work(struct work_struct *work) } /* + * Queue an async vmtruncate. If we fail to queue work, we will handle + * the truncation the next time we call __ceph_do_pending_vmtruncate. + */ +void ceph_queue_vmtruncate(struct inode *inode) +{ + struct ceph_inode_info *ci = ceph_inode(inode); + + if (queue_work(ceph_client(inode->i_sb)->trunc_wq, + &ci->i_vmtruncate_work)) { + dout("ceph_queue_vmtruncate %p\n", inode); + igrab(inode); + } else { + dout("ceph_queue_vmtruncate %p failed, pending=%d\n", + inode, ci->i_truncate_pending); + } +} + +/* * called with i_mutex held. * * Make sure any pending truncation is applied before doing anything diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 3930fb6..b2adfcc 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -573,18 +573,6 @@ static inline struct ceph_client *ceph_sb_to_client(struct super_block *sb) return (struct ceph_client *)sb->s_fs_info; } -static inline int ceph_queue_writeback(struct inode *inode) -{ - return queue_work(ceph_inode_to_client(inode)->wb_wq, - &ceph_inode(inode)->i_wb_work); -} - -static inline int ceph_queue_page_invalidation(struct inode *inode) -{ - return queue_work(ceph_inode_to_client(inode)->pg_inv_wq, - &ceph_inode(inode)->i_pg_inv_work); -} - /* * we keep buffered readdir results attached to file->private_data @@ -772,10 +760,11 @@ extern int ceph_readdir_prepopulate(struct ceph_mds_request *req, extern int ceph_inode_holds_cap(struct inode *inode, int mask); extern int ceph_inode_set_size(struct inode *inode, loff_t size); -extern void ceph_inode_writeback(struct work_struct *work); -extern void ceph_vmtruncate_work(struct work_struct *work); extern void __ceph_do_pending_vmtruncate(struct inode *inode); -extern void __ceph_queue_vmtruncate(struct inode *inode); +extern void ceph_queue_vmtruncate(struct inode *inode); + +extern void ceph_queue_invalidate(struct inode *inode); +extern void ceph_queue_writeback(struct inode *inode); extern int ceph_do_getattr(struct inode *inode, int mask); extern int ceph_permission(struct inode *inode, int mask); -- cgit v0.10.2 From 0840d8af3e6e40bcd5f2366698eb2755f88acfea Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 9 Feb 2010 15:44:16 -0800 Subject: ceph: invalidate pages even if truncate is pending There is no reason not to invalidate pages when a truncate is pending. Both throw out page cache pages. Signed-off-by: Sage Weil diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 68ee781..20b28dc 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -1444,7 +1444,6 @@ retry_locked: ci->i_rdcache_gen && /* may have cached pages */ (file_wanted == 0 || /* no open files */ (revoking & CEPH_CAP_FILE_CACHE)) && /* or revoking cache */ - !ci->i_truncate_pending && !tried_invalidate) { u32 invalidating_gen = ci->i_rdcache_gen; int ret; -- cgit v0.10.2 From 8031049147c58d9d8b6226c3ac31a9d72d053e25 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 9 Feb 2010 16:43:11 -0800 Subject: ceph: remove bogus invalidate_mapping_pages We were invalidating mapping pages when dropping FILE_CACHE in __send_cap(). But ceph_check_caps attempts to invalidate already, and also checks for success, so we should never get to this point. Signed-off-by: Sage Weil diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 20b28dc..ab9b571 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -1137,12 +1137,6 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap, spin_unlock(&inode->i_lock); - if (dropping & CEPH_CAP_FILE_CACHE) { - /* invalidate what we can */ - dout("invalidating pages on %p\n", inode); - invalidate_mapping_pages(&inode->i_data, 0, -1); - } - ret = send_cap_msg(session, ceph_vino(inode).ino, cap_id, op, keep, want, flushing, seq, flush_tid, issue_seq, mseq, size, max_size, &mtime, &atime, time_warp_seq, -- cgit v0.10.2 From 6c5d1a49e5e88ee831117f4b2375829933ad15da Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Sat, 13 Feb 2010 20:29:31 -0800 Subject: ceph: fix msgr to keep sent messages until acked The test was backwards from commit b3d1dbbd: keep the message if the connection _isn't_ lossy. This allows the client to continue when the TCP connection drops for some reason (network glitch) but both ends survive. Signed-off-by: Sage Weil diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index c434178..44bdaf4 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -463,11 +463,11 @@ static void prepare_write_message(struct ceph_connection *con) struct ceph_msg, list_head); con->out_msg = m; if (test_bit(LOSSYTX, &con->state)) { + list_del_init(&m->list_head); + } else { /* put message on sent list */ ceph_msg_get(m); list_move_tail(&m->list_head, &con->out_sent); - } else { - list_del_init(&m->list_head); } m->hdr.seq = cpu_to_le64(++con->out_seq); -- cgit v0.10.2 From 153a008bf7915ea9127341409170cb197d111282 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 15 Feb 2010 12:11:51 -0800 Subject: ceph: reset osd connections after fault A single osd connection fault (e.g. tcp disconnect) wasn't reopening the connection, which causes all current and future requests for that osd to hang. Signed-off-by: Sage Weil diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index 7f8a26f..fa0f737 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -369,7 +369,6 @@ static void osd_reset(struct ceph_connection *con) return; dout("osd_reset osd%d\n", osd->o_osd); osdc = osd->o_osdc; - osd->o_incarnation++; down_read(&osdc->map_sem); kick_requests(osdc, osd); up_read(&osdc->map_sem); @@ -921,7 +920,9 @@ static void kick_requests(struct ceph_osd_client *osdc, dout("kick_requests osd%d\n", kickosd ? kickosd->o_osd : -1); mutex_lock(&osdc->request_mutex); - if (!kickosd) { + if (kickosd) { + __reset_osd(osdc, kickosd); + } else { for (p = rb_first(&osdc->osds); p; p = n) { struct ceph_osd *osd = rb_entry(p, struct ceph_osd, o_node); -- cgit v0.10.2 From 0e026445fb36852d3102cb8bb24868765fe5816a Mon Sep 17 00:00:00 2001 From: Len Brown Date: Tue, 16 Feb 2010 03:01:42 -0500 Subject: ACPI: delete unused acpi_evaluate_string() Roel found a logic issue in the #if 0 acpi_evaluate_string(): - || (element->type != ACPI_TYPE_BUFFER) + && (element->type != ACPI_TYPE_BUFFER) delete the dead code. pointed-out-by: Roel Kluin Signed-off-by: Len Brown diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 811fec1..592dffb 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c @@ -289,51 +289,6 @@ acpi_evaluate_integer(acpi_handle handle, EXPORT_SYMBOL(acpi_evaluate_integer); -#if 0 -acpi_status -acpi_evaluate_string(acpi_handle handle, - acpi_string pathname, - acpi_object_list * arguments, acpi_string * data) -{ - acpi_status status = AE_OK; - acpi_object *element = NULL; - acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - - - if (!data) - return AE_BAD_PARAMETER; - - status = acpi_evaluate_object(handle, pathname, arguments, &buffer); - if (ACPI_FAILURE(status)) { - acpi_util_eval_error(handle, pathname, status); - return status; - } - - element = (acpi_object *) buffer.pointer; - - if ((element->type != ACPI_TYPE_STRING) - || (element->type != ACPI_TYPE_BUFFER) - || !element->string.length) { - acpi_util_eval_error(handle, pathname, AE_BAD_DATA); - return AE_BAD_DATA; - } - - *data = kzalloc(element->string.length + 1, GFP_KERNEL); - if (!data) { - printk(KERN_ERR PREFIX "Memory allocation\n"); - return -ENOMEM; - } - - memcpy(*data, element->string.pointer, element->string.length); - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Return value [%s]\n", *data)); - - kfree(buffer.pointer); - - return AE_OK; -} -#endif - acpi_status acpi_evaluate_reference(acpi_handle handle, acpi_string pathname, -- cgit v0.10.2 From ded180e7ebfc324b36a94931f99d0705dcd8da29 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 2 Feb 2010 14:37:55 -0800 Subject: ACPI: remove superfluous NULL pointer check from acpi_processor_get_throttling_info() Dan's list contains: drivers/acpi/processor_throttling.c +1139 acpi_processor_get_throttling_info(11) warning: variable derefenced before check 'pr' acpi_processor_get_throttling_info() is never called with pr == NULL. [ bart: the potential NULL pointer dereference was finally fixed in (much later than mine) commit 5cfa245 but my patch is still valid ] Reported-by: Dan Carpenter Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Andrew Morton Signed-off-by: Len Brown diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index 1c5d7a8..649b2b9 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c @@ -1133,9 +1133,6 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr) int result = 0; struct acpi_processor_throttling *pthrottling; - if (!pr) - return -EINVAL; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "pblk_address[0x%08x] duty_offset[%d] duty_width[%d]\n", pr->throttling.address, -- cgit v0.10.2 From 38bcb37a6f63fcdfcc0dd0af3ec5c03a4b7be48e Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 2 Feb 2010 14:37:56 -0800 Subject: ACPICA: fix acpi_ex_release_mutex() comment trivial, leftover from my NULL pointer dereference patch which got 'superseded' by commit fbc3be2 Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Andrew Morton Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/exmutex.c b/drivers/acpi/acpica/exmutex.c index 3c456bd..c4a47dd 100644 --- a/drivers/acpi/acpica/exmutex.c +++ b/drivers/acpi/acpica/exmutex.c @@ -375,8 +375,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, return_ACPI_STATUS(AE_AML_MUTEX_NOT_ACQUIRED); } - /* Must have a valid thread ID */ - + /* Must have a valid thread. */ if (!walk_state->thread) { ACPI_ERROR((AE_INFO, "Cannot release Mutex [%4.4s], null thread info", -- cgit v0.10.2 From c13f3d378f77ce3176628ade452b0e461242faf3 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Mon, 15 Feb 2010 11:33:04 +0900 Subject: x86/gart: Unexport gart_iommu_aperture I wrongly exported gart_iommu_aperture in the commit 42590a75019a50012f25a962246498dead428433. It's not necessary so let's unexport it. Signed-off-by: FUJITA Tomonori Cc: Joerg Roedel LKML-Reference: <20100215113241P.fujita.tomonori@lab.ntt.co.jp> Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c index f147a95..3704997 100644 --- a/arch/x86/kernel/aperture_64.c +++ b/arch/x86/kernel/aperture_64.c @@ -31,7 +31,6 @@ #include int gart_iommu_aperture; -EXPORT_SYMBOL_GPL(gart_iommu_aperture); int gart_iommu_aperture_disabled __initdata; int gart_iommu_aperture_allowed __initdata; -- cgit v0.10.2 From e2663ab60de59d20fa33da3528f6d5359f8eb003 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 16 Feb 2010 22:01:03 -0800 Subject: ceph: allow connection to be reopened by fault callback Fix the messenger to allow a ceph_con_open() during the fault callback. Previously the work wasn't getting queued on the connection because the fault path avoids requeued work (normally spurious). Loop on reopening by checking for the OPENING state bit. This fixes OSD reconnects when a TCP connection drops. Signed-off-by: Sage Weil diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index 44bdaf4..acf383f 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -1808,7 +1808,7 @@ done: clear_bit(BUSY, &con->state); dout("con->state=%lu\n", con->state); if (test_bit(QUEUED, &con->state)) { - if (!backoff) { + if (!backoff || test_bit(OPENING, &con->state)) { dout("con_work %p QUEUED reset, looping\n", con); goto more; } -- cgit v0.10.2 From 91e45ce38946a8efa21fefbc65d023ca3c0b434f Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 15 Feb 2010 12:05:09 -0800 Subject: ceph: cancel delayed work when closing connection This ensures that if/when we reopen the connection, we can requeue work on the connection immediately, without waiting for an old timer to expire. Queue new delayed work inside con->mutex to avoid any race. This fixes problems with clients failing to reconnect to the MDS due to the client_reconnect message arriving too late (due to waiting for an old delayed work timeout to expire). Signed-off-by: Sage Weil diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index acf383f..ca2ad0e 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -344,6 +344,7 @@ void ceph_con_close(struct ceph_connection *con) clear_bit(STANDBY, &con->state); /* avoid connect_seq bump */ mutex_lock(&con->mutex); reset_connection(con); + cancel_delayed_work(&con->work); mutex_unlock(&con->mutex); queue_con(con); } @@ -1841,6 +1842,8 @@ static void ceph_fault(struct ceph_connection *con) clear_bit(BUSY, &con->state); /* to avoid an improbable race */ mutex_lock(&con->mutex); + if (test_bit(CLOSED, &con->state)) + goto out_unlock; con_close_socket(con); @@ -1876,8 +1879,6 @@ static void ceph_fault(struct ceph_connection *con) else if (con->delay < MAX_DELAY_INTERVAL) con->delay *= 2; - mutex_unlock(&con->mutex); - /* explicitly schedule work to try to reconnect again later. */ dout("fault queueing %p delay %lu\n", con, con->delay); con->ops->get(con); @@ -1885,6 +1886,8 @@ static void ceph_fault(struct ceph_connection *con) round_jiffies_relative(con->delay)) == 0) con->ops->put(con); +out_unlock: + mutex_unlock(&con->mutex); out: if (con->ops->fault) con->ops->fault(con); -- cgit v0.10.2 From 44ca18f2682eb1cfbed153849adedb79e3e19790 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 15 Feb 2010 12:08:46 -0800 Subject: ceph: use rbtree for mds requests The rbtree is a more appropriate data structure than a radix_tree. It avoids extra memory usage and simplifies the code. It also fixes a bug where the debugfs 'mdsc' file wasn't including the most recent mds request. Signed-off-by: Sage Weil diff --git a/fs/ceph/debugfs.c b/fs/ceph/debugfs.c index fba44b2..cd5dd80 100644 --- a/fs/ceph/debugfs.c +++ b/fs/ceph/debugfs.c @@ -142,21 +142,16 @@ static int monc_show(struct seq_file *s, void *p) static int mdsc_show(struct seq_file *s, void *p) { struct ceph_client *client = s->private; - struct ceph_mds_request *req; - u64 nexttid = 0; - int got; struct ceph_mds_client *mdsc = &client->mdsc; + struct ceph_mds_request *req; + struct rb_node *rp; int pathlen; u64 pathbase; char *path; mutex_lock(&mdsc->mutex); - while (nexttid < mdsc->last_tid) { - got = radix_tree_gang_lookup(&mdsc->request_tree, - (void **)&req, nexttid, 1); - if (got == 0) - break; - nexttid = req->r_tid + 1; + for (rp = rb_first(&mdsc->request_tree); rp; rp = rb_next(rp)) { + req = rb_entry(rp, struct ceph_mds_request, r_node); if (req->r_request) seq_printf(s, "%lld\tmds%d\t", req->r_tid, req->r_mds); diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index aa8506b..81840d6 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -255,6 +255,7 @@ static const char *session_state_name(int s) case CEPH_MDS_SESSION_OPEN: return "open"; case CEPH_MDS_SESSION_HUNG: return "hung"; case CEPH_MDS_SESSION_CLOSING: return "closing"; + case CEPH_MDS_SESSION_RESTARTING: return "restarting"; case CEPH_MDS_SESSION_RECONNECTING: return "reconnecting"; default: return "???"; } @@ -448,10 +449,42 @@ static struct ceph_mds_request *__lookup_request(struct ceph_mds_client *mdsc, u64 tid) { struct ceph_mds_request *req; - req = radix_tree_lookup(&mdsc->request_tree, tid); - if (req) - ceph_mdsc_get_request(req); - return req; + struct rb_node *n = mdsc->request_tree.rb_node; + + while (n) { + req = rb_entry(n, struct ceph_mds_request, r_node); + if (tid < req->r_tid) + n = n->rb_left; + else if (tid > req->r_tid) + n = n->rb_right; + else { + ceph_mdsc_get_request(req); + return req; + } + } + return NULL; +} + +static void __insert_request(struct ceph_mds_client *mdsc, + struct ceph_mds_request *new) +{ + struct rb_node **p = &mdsc->request_tree.rb_node; + struct rb_node *parent = NULL; + struct ceph_mds_request *req = NULL; + + while (*p) { + parent = *p; + req = rb_entry(parent, struct ceph_mds_request, r_node); + if (new->r_tid < req->r_tid) + p = &(*p)->rb_left; + else if (new->r_tid > req->r_tid) + p = &(*p)->rb_right; + else + BUG(); + } + + rb_link_node(&new->r_node, parent, p); + rb_insert_color(&new->r_node, &mdsc->request_tree); } /* @@ -469,7 +502,7 @@ static void __register_request(struct ceph_mds_client *mdsc, ceph_reserve_caps(&req->r_caps_reservation, req->r_num_caps); dout("__register_request %p tid %lld\n", req, req->r_tid); ceph_mdsc_get_request(req); - radix_tree_insert(&mdsc->request_tree, req->r_tid, (void *)req); + __insert_request(mdsc, req); if (dir) { struct ceph_inode_info *ci = ceph_inode(dir); @@ -485,7 +518,7 @@ static void __unregister_request(struct ceph_mds_client *mdsc, struct ceph_mds_request *req) { dout("__unregister_request %p tid %lld\n", req, req->r_tid); - radix_tree_delete(&mdsc->request_tree, req->r_tid); + rb_erase(&req->r_node, &mdsc->request_tree); ceph_mdsc_put_request(req); if (req->r_unsafe_dir) { @@ -1115,17 +1148,25 @@ ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op, int mode) } /* - * return oldest (lowest) tid in request tree, 0 if none. + * return oldest (lowest) request, tid in request tree, 0 if none. * * called under mdsc->mutex. */ +static struct ceph_mds_request *__get_oldest_req(struct ceph_mds_client *mdsc) +{ + if (RB_EMPTY_ROOT(&mdsc->request_tree)) + return NULL; + return rb_entry(rb_first(&mdsc->request_tree), + struct ceph_mds_request, r_node); +} + static u64 __get_oldest_tid(struct ceph_mds_client *mdsc) { - struct ceph_mds_request *first; - if (radix_tree_gang_lookup(&mdsc->request_tree, - (void **)&first, 0, 1) <= 0) - return 0; - return first->r_tid; + struct ceph_mds_request *req = __get_oldest_req(mdsc); + + if (req) + return req->r_tid; + return 0; } /* @@ -1540,26 +1581,19 @@ static void __wake_requests(struct ceph_mds_client *mdsc, */ static void kick_requests(struct ceph_mds_client *mdsc, int mds, int all) { - struct ceph_mds_request *reqs[10]; - u64 nexttid = 0; - int i, got; + struct ceph_mds_request *req; + struct rb_node *p; dout("kick_requests mds%d\n", mds); - while (nexttid <= mdsc->last_tid) { - got = radix_tree_gang_lookup(&mdsc->request_tree, - (void **)&reqs, nexttid, 10); - if (got == 0) - break; - nexttid = reqs[got-1]->r_tid + 1; - for (i = 0; i < got; i++) { - if (reqs[i]->r_got_unsafe) - continue; - if (reqs[i]->r_session && - reqs[i]->r_session->s_mds == mds) { - dout(" kicking tid %llu\n", reqs[i]->r_tid); - put_request_session(reqs[i]); - __do_request(mdsc, reqs[i]); - } + for (p = rb_first(&mdsc->request_tree); p; p = rb_next(p)) { + req = rb_entry(p, struct ceph_mds_request, r_node); + if (req->r_got_unsafe) + continue; + if (req->r_session && + req->r_session->s_mds == mds) { + dout(" kicking tid %llu\n", req->r_tid); + put_request_session(req); + __do_request(mdsc, req); } } } @@ -1748,7 +1782,7 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg) list_del_init(&req->r_unsafe_item); /* last unsafe request during umount? */ - if (mdsc->stopping && !__get_oldest_tid(mdsc)) + if (mdsc->stopping && !__get_oldest_req(mdsc)) complete(&mdsc->safe_umount_waiters); mutex_unlock(&mdsc->mutex); goto out; @@ -2573,7 +2607,7 @@ int ceph_mdsc_init(struct ceph_mds_client *mdsc, struct ceph_client *client) INIT_LIST_HEAD(&mdsc->snap_empty); spin_lock_init(&mdsc->snap_empty_lock); mdsc->last_tid = 0; - INIT_RADIX_TREE(&mdsc->request_tree, GFP_NOFS); + mdsc->request_tree = RB_ROOT; INIT_DELAYED_WORK(&mdsc->delayed_work, delayed_work); mdsc->last_renew_caps = jiffies; INIT_LIST_HEAD(&mdsc->cap_delay_list); @@ -2600,20 +2634,19 @@ static void wait_requests(struct ceph_mds_client *mdsc) struct ceph_client *client = mdsc->client; mutex_lock(&mdsc->mutex); - if (__get_oldest_tid(mdsc)) { + if (__get_oldest_req(mdsc)) { mutex_unlock(&mdsc->mutex); + dout("wait_requests waiting for requests\n"); wait_for_completion_timeout(&mdsc->safe_umount_waiters, client->mount_args->mount_timeout * HZ); - mutex_lock(&mdsc->mutex); /* tear down remaining requests */ - while (radix_tree_gang_lookup(&mdsc->request_tree, - (void **)&req, 0, 1)) { + mutex_lock(&mdsc->mutex); + while ((req = __get_oldest_req(mdsc))) { dout("wait_requests timed out on tid %llu\n", req->r_tid); - radix_tree_delete(&mdsc->request_tree, req->r_tid); - ceph_mdsc_put_request(req); + __unregister_request(mdsc, req); } } mutex_unlock(&mdsc->mutex); @@ -2639,31 +2672,29 @@ void ceph_mdsc_pre_umount(struct ceph_mds_client *mdsc) */ static void wait_unsafe_requests(struct ceph_mds_client *mdsc, u64 want_tid) { - struct ceph_mds_request *req; - u64 next_tid = 0; - int got; + struct ceph_mds_request *req = NULL; + struct rb_node *n; mutex_lock(&mdsc->mutex); dout("wait_unsafe_requests want %lld\n", want_tid); - while (1) { - got = radix_tree_gang_lookup(&mdsc->request_tree, (void **)&req, - next_tid, 1); - if (!got) - break; - if (req->r_tid > want_tid) + req = __get_oldest_req(mdsc); + while (req && req->r_tid <= want_tid) { + if ((req->r_op & CEPH_MDS_OP_WRITE)) { + /* write op */ + ceph_mdsc_get_request(req); + mutex_unlock(&mdsc->mutex); + dout("wait_unsafe_requests wait on %llu (want %llu)\n", + req->r_tid, want_tid); + wait_for_completion(&req->r_safe_completion); + mutex_lock(&mdsc->mutex); + n = rb_next(&req->r_node); + ceph_mdsc_put_request(req); + } else { + n = rb_next(&req->r_node); + } + if (!n) break; - - next_tid = req->r_tid + 1; - if ((req->r_op & CEPH_MDS_OP_WRITE) == 0) - continue; /* not a write op */ - - ceph_mdsc_get_request(req); - mutex_unlock(&mdsc->mutex); - dout("wait_unsafe_requests wait on %llu (want %llu)\n", - req->r_tid, want_tid); - wait_for_completion(&req->r_safe_completion); - mutex_lock(&mdsc->mutex); - ceph_mdsc_put_request(req); + req = rb_entry(n, struct ceph_mds_request, r_node); } mutex_unlock(&mdsc->mutex); dout("wait_unsafe_requests done\n"); diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h index ee71495..98f09cd 100644 --- a/fs/ceph/mds_client.h +++ b/fs/ceph/mds_client.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include "types.h" @@ -150,6 +151,7 @@ typedef void (*ceph_mds_request_callback_t) (struct ceph_mds_client *mdsc, */ struct ceph_mds_request { u64 r_tid; /* transaction id */ + struct rb_node r_node; int r_op; /* mds op code */ int r_mds; @@ -249,7 +251,7 @@ struct ceph_mds_client { spinlock_t snap_empty_lock; /* protect snap_empty */ u64 last_tid; /* most recent mds request */ - struct radix_tree_root request_tree; /* pending mds requests */ + struct rb_root request_tree; /* pending mds requests */ struct delayed_work delayed_work; /* delayed work */ unsigned long last_renew_caps; /* last time we renewed our caps */ struct list_head cap_delay_list; /* caps with delayed release */ -- cgit v0.10.2 From a105f00cf17d711e876b3dc67e15f9a89b7de5a3 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 15 Feb 2010 14:37:55 -0800 Subject: ceph: use rbtree for snap_realms Switch from radix tree to rbtree for snap realms. This is much more appropriate given that realm keys are few and far between. Signed-off-by: Sage Weil diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 81840d6..02834ce 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -2097,9 +2097,8 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc, int mds) { struct ceph_mds_session *session = NULL; struct ceph_msg *reply; + struct rb_node *p; int err; - int got; - u64 next_snap_ino = 0; struct ceph_pagelist *pagelist; pr_info("reconnect to recovering mds%d\n", mds); @@ -2155,14 +2154,10 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc, int mds) * parent for all of our realms. If the mds has any newer info, * it will tell us. */ - next_snap_ino = 0; - while (1) { - struct ceph_snap_realm *realm; + for (p = rb_first(&mdsc->snap_realms); p; p = rb_next(p)) { + struct ceph_snap_realm *realm = + rb_entry(p, struct ceph_snap_realm, node); struct ceph_mds_snaprealm_reconnect sr_rec; - got = radix_tree_gang_lookup(&mdsc->snap_realms, - (void **)&realm, next_snap_ino, 1); - if (!got) - break; dout(" adding snap realm %llx seq %lld parent %llx\n", realm->ino, realm->seq, realm->parent_ino); @@ -2172,7 +2167,6 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc, int mds) err = ceph_pagelist_append(pagelist, &sr_rec, sizeof(sr_rec)); if (err) goto fail; - next_snap_ino = realm->ino + 1; } send: @@ -2603,7 +2597,7 @@ int ceph_mdsc_init(struct ceph_mds_client *mdsc, struct ceph_client *client) mdsc->max_sessions = 0; mdsc->stopping = 0; init_rwsem(&mdsc->snap_rwsem); - INIT_RADIX_TREE(&mdsc->snap_realms, GFP_NOFS); + mdsc->snap_realms = RB_ROOT; INIT_LIST_HEAD(&mdsc->snap_empty); spin_lock_init(&mdsc->snap_empty_lock); mdsc->last_tid = 0; diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h index 98f09cd..9d6b901 100644 --- a/fs/ceph/mds_client.h +++ b/fs/ceph/mds_client.h @@ -5,7 +5,6 @@ #include #include #include -#include #include #include @@ -246,7 +245,7 @@ struct ceph_mds_client { * should be destroyed. */ struct rw_semaphore snap_rwsem; - struct radix_tree_root snap_realms; + struct rb_root snap_realms; struct list_head snap_empty; spinlock_t snap_empty_lock; /* protect snap_empty */ diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c index dcf18d9..49d0c4c 100644 --- a/fs/ceph/snap.c +++ b/fs/ceph/snap.c @@ -1,6 +1,5 @@ #include "ceph_debug.h" -#include #include #include "super.h" @@ -77,6 +76,28 @@ void ceph_get_snap_realm(struct ceph_mds_client *mdsc, atomic_inc(&realm->nref); } +static void __insert_snap_realm(struct rb_root *root, + struct ceph_snap_realm *new) +{ + struct rb_node **p = &root->rb_node; + struct rb_node *parent = NULL; + struct ceph_snap_realm *r = NULL; + + while (*p) { + parent = *p; + r = rb_entry(parent, struct ceph_snap_realm, node); + if (new->ino < r->ino) + p = &(*p)->rb_left; + else if (new->ino > r->ino) + p = &(*p)->rb_right; + else + BUG(); + } + + rb_link_node(&new->node, parent, p); + rb_insert_color(&new->node, root); +} + /* * create and get the realm rooted at @ino and bump its ref count. * @@ -92,8 +113,6 @@ static struct ceph_snap_realm *ceph_create_snap_realm( if (!realm) return ERR_PTR(-ENOMEM); - radix_tree_insert(&mdsc->snap_realms, ino, realm); - atomic_set(&realm->nref, 0); /* tree does not take a ref */ realm->ino = ino; INIT_LIST_HEAD(&realm->children); @@ -101,24 +120,34 @@ static struct ceph_snap_realm *ceph_create_snap_realm( INIT_LIST_HEAD(&realm->empty_item); INIT_LIST_HEAD(&realm->inodes_with_caps); spin_lock_init(&realm->inodes_with_caps_lock); + __insert_snap_realm(&mdsc->snap_realms, realm); dout("create_snap_realm %llx %p\n", realm->ino, realm); return realm; } /* - * find and get (if found) the realm rooted at @ino and bump its ref count. + * lookup the realm rooted at @ino. * * caller must hold snap_rwsem for write. */ struct ceph_snap_realm *ceph_lookup_snap_realm(struct ceph_mds_client *mdsc, u64 ino) { - struct ceph_snap_realm *realm; - - realm = radix_tree_lookup(&mdsc->snap_realms, ino); - if (realm) - dout("lookup_snap_realm %llx %p\n", realm->ino, realm); - return realm; + struct rb_node *n = mdsc->snap_realms.rb_node; + struct ceph_snap_realm *r; + + while (n) { + r = rb_entry(n, struct ceph_snap_realm, node); + if (ino < r->ino) + n = n->rb_left; + else if (ino > r->ino) + n = n->rb_right; + else { + dout("lookup_snap_realm %llx %p\n", r->ino, r); + return r; + } + } + return NULL; } static void __put_snap_realm(struct ceph_mds_client *mdsc, @@ -132,7 +161,7 @@ static void __destroy_snap_realm(struct ceph_mds_client *mdsc, { dout("__destroy_snap_realm %p %llx\n", realm, realm->ino); - radix_tree_delete(&mdsc->snap_realms, realm->ino); + rb_erase(&realm->node, &mdsc->snap_realms); if (realm->parent) { list_del_init(&realm->child_item); diff --git a/fs/ceph/super.h b/fs/ceph/super.h index b2adfcc..1f39287 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -656,6 +656,8 @@ static inline void ceph_put_snap_context(struct ceph_snap_context *sc) struct ceph_snap_realm { u64 ino; atomic_t nref; + struct rb_node node; + u64 created, seq; u64 parent_ino; u64 parent_since; /* snapid when our current parent became so */ -- cgit v0.10.2 From 85ff03f6bfef7d5b59ab3aefd4773f497ffad8a4 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 15 Feb 2010 14:47:28 -0800 Subject: ceph: use rbtree for mon statfs requests An rbtree is lighter weight, particularly given we will generally have very few in-flight statfs requests. Signed-off-by: Sage Weil diff --git a/fs/ceph/debugfs.c b/fs/ceph/debugfs.c index cd5dd80..b58bd91 100644 --- a/fs/ceph/debugfs.c +++ b/fs/ceph/debugfs.c @@ -112,9 +112,8 @@ static int monc_show(struct seq_file *s, void *p) { struct ceph_client *client = s->private; struct ceph_mon_statfs_request *req; - u64 nexttid = 0; - int got; struct ceph_mon_client *monc = &client->monc; + struct rb_node *rp; mutex_lock(&monc->mutex); @@ -125,17 +124,12 @@ static int monc_show(struct seq_file *s, void *p) if (monc->want_next_osdmap) seq_printf(s, "want next osdmap\n"); - while (nexttid < monc->last_tid) { - got = radix_tree_gang_lookup(&monc->statfs_request_tree, - (void **)&req, nexttid, 1); - if (got == 0) - break; - nexttid = req->tid + 1; - + for (rp = rb_first(&monc->statfs_request_tree); rp; rp = rb_next(rp)) { + req = rb_entry(rp, struct ceph_mon_statfs_request, node); seq_printf(s, "%lld statfs\n", req->tid); } - mutex_unlock(&monc->mutex); + mutex_unlock(&monc->mutex); return 0; } diff --git a/fs/ceph/mon_client.c b/fs/ceph/mon_client.c index fec41a0..542276e 100644 --- a/fs/ceph/mon_client.c +++ b/fs/ceph/mon_client.c @@ -343,6 +343,46 @@ out: /* * statfs */ +static struct ceph_mon_statfs_request *__lookup_statfs( + struct ceph_mon_client *monc, u64 tid) +{ + struct ceph_mon_statfs_request *req; + struct rb_node *n = monc->statfs_request_tree.rb_node; + + while (n) { + req = rb_entry(n, struct ceph_mon_statfs_request, node); + if (tid < req->tid) + n = n->rb_left; + else if (tid > req->tid) + n = n->rb_right; + else + return req; + } + return NULL; +} + +static void __insert_statfs(struct ceph_mon_client *monc, + struct ceph_mon_statfs_request *new) +{ + struct rb_node **p = &monc->statfs_request_tree.rb_node; + struct rb_node *parent = NULL; + struct ceph_mon_statfs_request *req = NULL; + + while (*p) { + parent = *p; + req = rb_entry(parent, struct ceph_mon_statfs_request, node); + if (new->tid < req->tid) + p = &(*p)->rb_left; + else if (new->tid > req->tid) + p = &(*p)->rb_right; + else + BUG(); + } + + rb_link_node(&new->node, parent, p); + rb_insert_color(&new->node, &monc->statfs_request_tree); +} + static void handle_statfs_reply(struct ceph_mon_client *monc, struct ceph_msg *msg) { @@ -356,7 +396,7 @@ static void handle_statfs_reply(struct ceph_mon_client *monc, dout("handle_statfs_reply %p tid %llu\n", msg, tid); mutex_lock(&monc->mutex); - req = radix_tree_lookup(&monc->statfs_request_tree, tid); + req = __lookup_statfs(monc, tid); if (req) { *req->buf = reply->st; req->result = 0; @@ -416,11 +456,7 @@ int ceph_monc_do_statfs(struct ceph_mon_client *monc, struct ceph_statfs *buf) req.tid = ++monc->last_tid; req.last_attempt = jiffies; req.delay = BASE_DELAY_INTERVAL; - if (radix_tree_insert(&monc->statfs_request_tree, req.tid, &req) < 0) { - mutex_unlock(&monc->mutex); - pr_err("ENOMEM in do_statfs\n"); - return -ENOMEM; - } + __insert_statfs(monc, &req); monc->num_statfs_requests++; mutex_unlock(&monc->mutex); @@ -430,7 +466,7 @@ int ceph_monc_do_statfs(struct ceph_mon_client *monc, struct ceph_statfs *buf) err = wait_for_completion_interruptible(&req.completion); mutex_lock(&monc->mutex); - radix_tree_delete(&monc->statfs_request_tree, req.tid); + rb_erase(&req.node, &monc->statfs_request_tree); monc->num_statfs_requests--; ceph_msgpool_resv(&monc->msgpool_statfs_reply, -1); mutex_unlock(&monc->mutex); @@ -445,20 +481,11 @@ int ceph_monc_do_statfs(struct ceph_mon_client *monc, struct ceph_statfs *buf) */ static void __resend_statfs(struct ceph_mon_client *monc) { - u64 next_tid = 0; - int got; - int did = 0; struct ceph_mon_statfs_request *req; + struct rb_node *p; - while (1) { - got = radix_tree_gang_lookup(&monc->statfs_request_tree, - (void **)&req, - next_tid, 1); - if (got == 0) - break; - did++; - next_tid = req->tid + 1; - + for (p = rb_first(&monc->statfs_request_tree); p; p = rb_next(p)) { + req = rb_entry(p, struct ceph_mon_statfs_request, node); send_statfs(monc, req); } } @@ -578,7 +605,7 @@ int ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl) monc->sub_sent = 0; INIT_DELAYED_WORK(&monc->delayed_work, delayed_work); - INIT_RADIX_TREE(&monc->statfs_request_tree, GFP_NOFS); + monc->statfs_request_tree = RB_ROOT; monc->num_statfs_requests = 0; monc->last_tid = 0; diff --git a/fs/ceph/mon_client.h b/fs/ceph/mon_client.h index 5ca8e48..b958ad5 100644 --- a/fs/ceph/mon_client.h +++ b/fs/ceph/mon_client.h @@ -2,7 +2,7 @@ #define _FS_CEPH_MON_CLIENT_H #include -#include +#include #include "messenger.h" #include "msgpool.h" @@ -45,6 +45,7 @@ struct ceph_mon_request { */ struct ceph_mon_statfs_request { u64 tid; + struct rb_node node; int result; struct ceph_statfs *buf; struct completion completion; @@ -75,7 +76,7 @@ struct ceph_mon_client { struct ceph_msgpool msgpool_auth_reply; /* pending statfs requests */ - struct radix_tree_root statfs_request_tree; + struct rb_root statfs_request_tree; int num_statfs_requests; u64 last_tid; -- cgit v0.10.2 From 5ce6e9dbe6805ab8ee67e21936d17f431adc63c6 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 15 Feb 2010 16:22:28 -0800 Subject: ceph: fix authentication races, auth_none oops Call __validate_auth() under monc->mutex, and use helper for initial hello so that the pending_auth flag is set. This fixes possible races in which we have an authentication request (hello or otherwise) pending and send another one. In particular, with auth_none, we _never_ want to call ceph_build_auth() from __validate_auth(), since the ->build_request() method is NULL. Signed-off-by: Sage Weil diff --git a/fs/ceph/mon_client.c b/fs/ceph/mon_client.c index 542276e..40d7d90 100644 --- a/fs/ceph/mon_client.c +++ b/fs/ceph/mon_client.c @@ -96,6 +96,18 @@ int ceph_monmap_contains(struct ceph_monmap *m, struct ceph_entity_addr *addr) } /* + * Send an auth request. + */ +static void __send_prepared_auth_request(struct ceph_mon_client *monc, int len) +{ + monc->pending_auth = 1; + monc->m_auth->front.iov_len = len; + monc->m_auth->hdr.front_len = cpu_to_le32(len); + ceph_msg_get(monc->m_auth); /* keep our ref */ + ceph_con_send(monc->con, monc->m_auth); +} + +/* * Close monitor session, if any. */ static void __close_session(struct ceph_mon_client *monc) @@ -137,10 +149,7 @@ static int __open_session(struct ceph_mon_client *monc) ret = ceph_auth_build_hello(monc->auth, monc->m_auth->front.iov_base, monc->m_auth->front_max); - monc->m_auth->front.iov_len = ret; - monc->m_auth->hdr.front_len = cpu_to_le32(ret); - ceph_msg_get(monc->m_auth); /* keep our ref */ - ceph_con_send(monc->con, monc->m_auth); + __send_prepared_auth_request(monc, ret); } else { dout("open_session mon%d already open\n", monc->cur_mon); } @@ -507,11 +516,9 @@ static void delayed_work(struct work_struct *work) __open_session(monc); /* continue hunting */ } else { ceph_con_keepalive(monc->con); - mutex_unlock(&monc->mutex); __validate_auth(monc); - mutex_lock(&monc->mutex); if (monc->auth->ops->is_authenticated(monc->auth)) __send_subscribe(monc); } @@ -650,16 +657,6 @@ void ceph_monc_stop(struct ceph_mon_client *monc) kfree(monc->monmap); } -static void __send_prepared_auth_request(struct ceph_mon_client *monc, int len) -{ - monc->pending_auth = 1; - monc->m_auth->front.iov_len = len; - monc->m_auth->hdr.front_len = cpu_to_le32(len); - ceph_msg_get(monc->m_auth); /* keep our ref */ - ceph_con_send(monc->con, monc->m_auth); -} - - static void handle_auth_reply(struct ceph_mon_client *monc, struct ceph_msg *msg) { -- cgit v0.10.2 From 85ccce43a3fc15a40ded6ae1603e3f68a17f4d24 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 17 Feb 2010 10:02:43 -0800 Subject: ceph: clean up readdir caps reservation Use a global counter for the minimum number of allocated caps instead of hard coding a check against readdir_max. This takes into account multiple client instances, and avoids examining the superblock mount options when a cap is dropped. Signed-off-by: Sage Weil diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index ab9b571..f94b56f 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -128,6 +128,7 @@ static int caps_total_count; /* total caps allocated */ static int caps_use_count; /* in use */ static int caps_reserve_count; /* unused, reserved */ static int caps_avail_count; /* unused, unreserved */ +static int caps_min_count; /* keep at least this many (unreserved) */ void __init ceph_caps_init(void) { @@ -149,6 +150,15 @@ void ceph_caps_finalize(void) caps_avail_count = 0; caps_use_count = 0; caps_reserve_count = 0; + caps_min_count = 0; + spin_unlock(&caps_list_lock); +} + +void ceph_adjust_min_caps(int delta) +{ + spin_lock(&caps_list_lock); + caps_min_count += delta; + BUG_ON(caps_min_count < 0); spin_unlock(&caps_list_lock); } @@ -265,12 +275,10 @@ static void put_cap(struct ceph_cap *cap, caps_reserve_count, caps_avail_count); caps_use_count--; /* - * Keep some preallocated caps around, at least enough to do a - * readdir (which needs to preallocate lots of them), to avoid - * lots of free/alloc churn. + * Keep some preallocated caps around (ceph_min_count), to + * avoid lots of free/alloc churn. */ - if (caps_avail_count >= caps_reserve_count + - ceph_client(cap->ci->vfs_inode.i_sb)->mount_args->max_readdir) { + if (caps_avail_count >= caps_reserve_count + caps_min_count) { caps_total_count--; kmem_cache_free(ceph_cap_cachep, cap); } else { @@ -289,7 +297,8 @@ static void put_cap(struct ceph_cap *cap, } void ceph_reservation_status(struct ceph_client *client, - int *total, int *avail, int *used, int *reserved) + int *total, int *avail, int *used, int *reserved, + int *min) { if (total) *total = caps_total_count; @@ -299,6 +308,8 @@ void ceph_reservation_status(struct ceph_client *client, *used = caps_use_count; if (reserved) *reserved = caps_reserve_count; + if (min) + *min = caps_min_count; } /* diff --git a/fs/ceph/debugfs.c b/fs/ceph/debugfs.c index b58bd91..1a47b5c 100644 --- a/fs/ceph/debugfs.c +++ b/fs/ceph/debugfs.c @@ -255,14 +255,15 @@ static int osdc_show(struct seq_file *s, void *pp) static int caps_show(struct seq_file *s, void *p) { struct ceph_client *client = p; - int total, avail, used, reserved; + int total, avail, used, reserved, min; - ceph_reservation_status(client, &total, &avail, &used, &reserved); + ceph_reservation_status(client, &total, &avail, &used, &reserved, &min); seq_printf(s, "total\t\t%d\n" - "avail\t\t%d\n" - "used\t\t%d\n" - "reserved\t%d\n", - total, avail, used, reserved); + "avail\t\t%d\n" + "used\t\t%d\n" + "reserved\t%d\n" + "min\t%d\n", + total, avail, used, reserved, min); return 0; } diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 39aaf29..74953be 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -578,6 +578,9 @@ static struct ceph_client *ceph_create_client(struct ceph_mount_args *args) if (!client->wb_pagevec_pool) goto fail_trunc_wq; + /* caps */ + client->min_caps = args->max_readdir; + ceph_adjust_min_caps(client->min_caps); /* subsystems */ err = ceph_monc_init(&client->monc, client); @@ -619,6 +622,8 @@ static void ceph_destroy_client(struct ceph_client *client) ceph_monc_stop(&client->monc); ceph_osdc_stop(&client->osdc); + ceph_adjust_min_caps(-client->min_caps); + ceph_debugfs_client_cleanup(client); destroy_workqueue(client->wb_wq); destroy_workqueue(client->pg_inv_wq); diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 1f39287..3b5faf9 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -129,6 +129,8 @@ struct ceph_client { int auth_err; + int min_caps; /* min caps i added */ + struct ceph_messenger *msgr; /* messenger instance */ struct ceph_mon_client monc; struct ceph_mds_client mdsc; @@ -557,11 +559,12 @@ extern int __ceph_caps_mds_wanted(struct ceph_inode_info *ci); extern void ceph_caps_init(void); extern void ceph_caps_finalize(void); +extern void ceph_adjust_min_caps(int delta); extern int ceph_reserve_caps(struct ceph_cap_reservation *ctx, int need); extern int ceph_unreserve_caps(struct ceph_cap_reservation *ctx); extern void ceph_reservation_status(struct ceph_client *client, int *total, int *avail, int *used, - int *reserved); + int *reserved, int *min); static inline struct ceph_client *ceph_inode_to_client(struct inode *inode) { -- cgit v0.10.2 From 7c1332b8cb5b27656cf6ab1f5fe808a8eb8bb2c0 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 16 Feb 2010 11:39:45 -0800 Subject: ceph: fix iterate_caps removal race We need to be able to iterate over all caps on a session with a possibly slow callback on each cap. To allow this, we used to prevent cap reordering while we were iterating. However, we were not safe from races with removal: removing the 'next' cap would make the next pointer from list_for_each_entry_safe be invalid, and cause a lock up or similar badness. Instead, we keep an iterator pointer in the session pointing to the current cap. As before, we avoid reordering. For removal, if the cap isn't the current cap we are iterating over, we are fine. If it is, we clear cap->ci (to mark the cap as pending removal) but leave it in the session list. In iterate_caps, we can safely finish removal and get the next cap pointer. While we're at it, clean up put_cap to not take a cap reservation context, as it was never used. Signed-off-by: Sage Weil diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index f94b56f..4958a2e 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -266,12 +266,11 @@ static struct ceph_cap *get_cap(struct ceph_cap_reservation *ctx) return cap; } -static void put_cap(struct ceph_cap *cap, - struct ceph_cap_reservation *ctx) +void ceph_put_cap(struct ceph_cap *cap) { spin_lock(&caps_list_lock); - dout("put_cap ctx=%p (%d) %d = %d used + %d resv + %d avail\n", - ctx, ctx ? ctx->count : 0, caps_total_count, caps_use_count, + dout("put_cap %p %d = %d used + %d resv + %d avail\n", + cap, caps_total_count, caps_use_count, caps_reserve_count, caps_avail_count); caps_use_count--; /* @@ -282,12 +281,7 @@ static void put_cap(struct ceph_cap *cap, caps_total_count--; kmem_cache_free(ceph_cap_cachep, cap); } else { - if (ctx) { - ctx->count++; - caps_reserve_count++; - } else { - caps_avail_count++; - } + caps_avail_count++; list_add(&cap->caps_item, &caps_list); } @@ -709,7 +703,7 @@ static void __touch_cap(struct ceph_cap *cap) struct ceph_mds_session *s = cap->session; spin_lock(&s->s_cap_lock); - if (!s->s_iterating_caps) { + if (s->s_cap_iterator == NULL) { dout("__touch_cap %p cap %p mds%d\n", &cap->ci->vfs_inode, cap, s->s_mds); list_move_tail(&cap->session_caps, &s->s_caps); @@ -865,8 +859,7 @@ static int __ceph_is_any_caps(struct ceph_inode_info *ci) * caller should hold i_lock, and session s_mutex. * returns true if this is the last cap. if so, caller should iput. */ -void __ceph_remove_cap(struct ceph_cap *cap, - struct ceph_cap_reservation *ctx) +void __ceph_remove_cap(struct ceph_cap *cap) { struct ceph_mds_session *session = cap->session; struct ceph_inode_info *ci = cap->ci; @@ -874,19 +867,27 @@ void __ceph_remove_cap(struct ceph_cap *cap, dout("__ceph_remove_cap %p from %p\n", cap, &ci->vfs_inode); - /* remove from session list */ - spin_lock(&session->s_cap_lock); - list_del_init(&cap->session_caps); - session->s_nr_caps--; - spin_unlock(&session->s_cap_lock); - /* remove from inode list */ rb_erase(&cap->ci_node, &ci->i_caps); - cap->session = NULL; + cap->ci = NULL; if (ci->i_auth_cap == cap) ci->i_auth_cap = NULL; - put_cap(cap, ctx); + /* remove from session list */ + spin_lock(&session->s_cap_lock); + if (session->s_cap_iterator == cap) { + /* not yet, we are iterating over this very cap */ + dout("__ceph_remove_cap delaying %p removal from session %p\n", + cap, cap->session); + } else { + list_del_init(&cap->session_caps); + session->s_nr_caps--; + cap->session = NULL; + } + spin_unlock(&session->s_cap_lock); + + if (cap->session == NULL) + ceph_put_cap(cap); if (!__ceph_is_any_caps(ci) && ci->i_snap_realm) { struct ceph_snap_realm *realm = ci->i_snap_realm; @@ -1022,7 +1023,7 @@ void ceph_queue_caps_release(struct inode *inode) } spin_unlock(&session->s_cap_lock); p = rb_next(p); - __ceph_remove_cap(cap, NULL); + __ceph_remove_cap(cap); } spin_unlock(&inode->i_lock); @@ -2521,7 +2522,7 @@ static void handle_cap_export(struct inode *inode, struct ceph_mds_caps *ex, ci->i_cap_exporting_mseq = mseq; ci->i_cap_exporting_issued = cap->issued; } - __ceph_remove_cap(cap, NULL); + __ceph_remove_cap(cap); } else { WARN_ON(!cap); } diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 02834ce..124c0c1 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -344,7 +344,7 @@ static struct ceph_mds_session *register_session(struct ceph_mds_client *mdsc, INIT_LIST_HEAD(&s->s_waiting); INIT_LIST_HEAD(&s->s_unsafe); s->s_num_cap_releases = 0; - s->s_iterating_caps = false; + s->s_cap_iterator = NULL; INIT_LIST_HEAD(&s->s_cap_releases); INIT_LIST_HEAD(&s->s_cap_releases_done); INIT_LIST_HEAD(&s->s_cap_flushing); @@ -729,28 +729,61 @@ static int iterate_session_caps(struct ceph_mds_session *session, int (*cb)(struct inode *, struct ceph_cap *, void *), void *arg) { - struct ceph_cap *cap, *ncap; - struct inode *inode; + struct list_head *p; + struct ceph_cap *cap; + struct inode *inode, *last_inode = NULL; + struct ceph_cap *old_cap = NULL; int ret; dout("iterate_session_caps %p mds%d\n", session, session->s_mds); spin_lock(&session->s_cap_lock); - session->s_iterating_caps = true; - list_for_each_entry_safe(cap, ncap, &session->s_caps, session_caps) { + p = session->s_caps.next; + while (p != &session->s_caps) { + cap = list_entry(p, struct ceph_cap, session_caps); inode = igrab(&cap->ci->vfs_inode); - if (!inode) + if (!inode) { + p = p->next; continue; + } + session->s_cap_iterator = cap; spin_unlock(&session->s_cap_lock); + + if (last_inode) { + iput(last_inode); + last_inode = NULL; + } + if (old_cap) { + ceph_put_cap(old_cap); + old_cap = NULL; + } + ret = cb(inode, cap, arg); - iput(inode); + last_inode = inode; + spin_lock(&session->s_cap_lock); + p = p->next; + if (cap->ci == NULL) { + dout("iterate_session_caps finishing cap %p removal\n", + cap); + BUG_ON(cap->session != session); + list_del_init(&cap->session_caps); + session->s_nr_caps--; + cap->session = NULL; + old_cap = cap; /* put_cap it w/o locks held */ + } if (ret < 0) goto out; } ret = 0; out: - session->s_iterating_caps = false; + session->s_cap_iterator = NULL; spin_unlock(&session->s_cap_lock); + + if (last_inode) + iput(last_inode); + if (old_cap) + ceph_put_cap(old_cap); + return ret; } @@ -942,7 +975,7 @@ static int trim_caps_cb(struct inode *inode, struct ceph_cap *cap, void *arg) session->s_trim_caps--; if (oissued) { /* we aren't the only cap.. just remove us */ - __ceph_remove_cap(cap, NULL); + __ceph_remove_cap(cap); } else { /* try to drop referring dentries */ spin_unlock(&inode->i_lock); diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h index 9d6b901..961cc6f 100644 --- a/fs/ceph/mds_client.h +++ b/fs/ceph/mds_client.h @@ -114,7 +114,7 @@ struct ceph_mds_session { int s_num_cap_releases; struct list_head s_cap_releases; /* waiting cap_release messages */ struct list_head s_cap_releases_done; /* ready to send */ - bool s_iterating_caps; + struct ceph_cap *s_cap_iterator; /* protected by mutex */ struct list_head s_cap_flushing; /* inodes w/ flushing caps */ diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 3b5faf9..384f0e2 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -795,15 +795,15 @@ extern int ceph_add_cap(struct inode *inode, int fmode, unsigned issued, unsigned wanted, unsigned cap, unsigned seq, u64 realmino, int flags, struct ceph_cap_reservation *caps_reservation); -extern void __ceph_remove_cap(struct ceph_cap *cap, - struct ceph_cap_reservation *ctx); +extern void __ceph_remove_cap(struct ceph_cap *cap); static inline void ceph_remove_cap(struct ceph_cap *cap) { struct inode *inode = &cap->ci->vfs_inode; spin_lock(&inode->i_lock); - __ceph_remove_cap(cap, NULL); + __ceph_remove_cap(cap); spin_unlock(&inode->i_lock); } +extern void ceph_put_cap(struct ceph_cap *cap); extern void ceph_queue_caps_release(struct inode *inode); extern int ceph_write_inode(struct inode *inode, int unused); -- cgit v0.10.2 From 9794b146fa7b93f8ab74fb62d67fdefad760769f Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 16 Feb 2010 15:53:32 -0800 Subject: ceph: fix memory leak when destroying osdmap with pg_temp mappings Also move _lookup_pg_mapping into a helper. Signed-off-by: Sage Weil diff --git a/fs/ceph/osdmap.c b/fs/ceph/osdmap.c index a6afe38..443fdcd 100644 --- a/fs/ceph/osdmap.c +++ b/fs/ceph/osdmap.c @@ -321,8 +321,13 @@ void ceph_osdmap_destroy(struct ceph_osdmap *map) dout("osdmap_destroy %p\n", map); if (map->crush) crush_destroy(map->crush); - while (!RB_EMPTY_ROOT(&map->pg_temp)) - rb_erase(rb_first(&map->pg_temp), &map->pg_temp); + while (!RB_EMPTY_ROOT(&map->pg_temp)) { + struct ceph_pg_mapping *pg = + rb_entry(rb_first(&map->pg_temp), + struct ceph_pg_mapping, node); + rb_erase(&pg->node, &map->pg_temp); + kfree(pg); + } kfree(map->osd_state); kfree(map->osd_weight); kfree(map->pg_pool); @@ -367,7 +372,8 @@ static int osdmap_set_max_osd(struct ceph_osdmap *map, int max) } /* - * Insert a new pg_temp mapping + * rbtree of pg_mapping for handling pg_temp (explicit mapping of pgid + * to a set of osds) */ static int pgid_cmp(struct ceph_pg l, struct ceph_pg r) { @@ -406,6 +412,26 @@ static int __insert_pg_mapping(struct ceph_pg_mapping *new, return 0; } +static struct ceph_pg_mapping *__lookup_pg_mapping(struct rb_root *root, + struct ceph_pg pgid) +{ + struct rb_node *n = root->rb_node; + struct ceph_pg_mapping *pg; + int c; + + while (n) { + pg = rb_entry(n, struct ceph_pg_mapping, node); + c = pgid_cmp(pgid, pg->pgid); + if (c < 0) + n = n->rb_left; + else if (c > 0) + n = n->rb_right; + else + return pg; + } + return NULL; +} + /* * decode a full map. */ @@ -870,26 +896,17 @@ int ceph_calc_object_layout(struct ceph_object_layout *ol, static int *calc_pg_raw(struct ceph_osdmap *osdmap, struct ceph_pg pgid, int *osds, int *num) { - struct rb_node *n = osdmap->pg_temp.rb_node; struct ceph_pg_mapping *pg; struct ceph_pg_pool_info *pool; int ruleno; unsigned poolid, ps, pps; int preferred; - int c; /* pg_temp? */ - while (n) { - pg = rb_entry(n, struct ceph_pg_mapping, node); - c = pgid_cmp(pgid, pg->pgid); - if (c < 0) - n = n->rb_left; - else if (c > 0) - n = n->rb_right; - else { - *num = pg->len; - return pg->osds; - } + pg = __lookup_pg_mapping(&osdmap->pg_temp, pgid); + if (pg) { + *num = pg->len; + return pg->osds; } /* crush */ -- cgit v0.10.2 From 4fc51be8fa7043ff9a1e34fef0e99214373332ac Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 16 Feb 2010 15:55:03 -0800 Subject: ceph: use rbtree for pg pools; decode new osdmap format Since we can now create and destroy pg pools, the pool ids will be sparse, and an array no longer makes sense for looking up by pool id. Use an rbtree instead. The OSDMap encoding also no longer has a max pool count (previously used to allocate the array). There is a new pool_max, that is the largest pool id we've ever used, although we don't actually need it in the client. Signed-off-by: Sage Weil diff --git a/fs/ceph/debugfs.c b/fs/ceph/debugfs.c index 1a47b5c..e159f14 100644 --- a/fs/ceph/debugfs.c +++ b/fs/ceph/debugfs.c @@ -78,6 +78,7 @@ static int osdmap_show(struct seq_file *s, void *p) { int i; struct ceph_client *client = s->private; + struct rb_node *n; if (client->osdc.osdmap == NULL) return 0; @@ -87,11 +88,11 @@ static int osdmap_show(struct seq_file *s, void *p) " NEARFULL" : "", (client->osdc.osdmap->flags & CEPH_OSDMAP_FULL) ? " FULL" : ""); - for (i = 0; i < client->osdc.osdmap->num_pools; i++) { + for (n = rb_first(&client->osdc.osdmap->pg_pools); n; n = rb_next(n)) { struct ceph_pg_pool_info *pool = - &client->osdc.osdmap->pg_pool[i]; + rb_entry(n, struct ceph_pg_pool_info, node); seq_printf(s, "pg_pool %d pg_num %d / %d, lpg_num %d / %d\n", - i, pool->v.pg_num, pool->pg_num_mask, + pool->id, pool->v.pg_num, pool->pg_num_mask, pool->v.lpg_num, pool->lpg_num_mask); } for (i = 0; i < client->osdc.osdmap->max_osd; i++) { diff --git a/fs/ceph/osdmap.c b/fs/ceph/osdmap.c index 443fdcd..34b5696 100644 --- a/fs/ceph/osdmap.c +++ b/fs/ceph/osdmap.c @@ -328,9 +328,15 @@ void ceph_osdmap_destroy(struct ceph_osdmap *map) rb_erase(&pg->node, &map->pg_temp); kfree(pg); } + while (!RB_EMPTY_ROOT(&map->pg_pools)) { + struct ceph_pg_pool_info *pi = + rb_entry(rb_first(&map->pg_pools), + struct ceph_pg_pool_info, node); + rb_erase(&pi->node, &map->pg_pools); + kfree(pi); + } kfree(map->osd_state); kfree(map->osd_weight); - kfree(map->pg_pool); kfree(map->osd_addr); kfree(map); } @@ -433,6 +439,48 @@ static struct ceph_pg_mapping *__lookup_pg_mapping(struct rb_root *root, } /* + * rbtree of pg pool info + */ +static int __insert_pg_pool(struct rb_root *root, struct ceph_pg_pool_info *new) +{ + struct rb_node **p = &root->rb_node; + struct rb_node *parent = NULL; + struct ceph_pg_pool_info *pi = NULL; + + while (*p) { + parent = *p; + pi = rb_entry(parent, struct ceph_pg_pool_info, node); + if (new->id < pi->id) + p = &(*p)->rb_left; + else if (new->id > pi->id) + p = &(*p)->rb_right; + else + return -EEXIST; + } + + rb_link_node(&new->node, parent, p); + rb_insert_color(&new->node, root); + return 0; +} + +static struct ceph_pg_pool_info *__lookup_pg_pool(struct rb_root *root, int id) +{ + struct ceph_pg_pool_info *pi; + struct rb_node *n = root->rb_node; + + while (n) { + pi = rb_entry(n, struct ceph_pg_pool_info, node); + if (id < pi->id) + n = n->rb_left; + else if (id > pi->id) + n = n->rb_right; + else + return pi; + } + return NULL; +} + +/* * decode a full map. */ struct ceph_osdmap *osdmap_decode(void **p, void *end) @@ -443,6 +491,7 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end) u8 ev; int err = -EINVAL; void *start = *p; + struct ceph_pg_pool_info *pi; dout("osdmap_decode %p to %p len %d\n", *p, end, (int)(end - *p)); @@ -464,32 +513,27 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end) ceph_decode_copy(p, &map->created, sizeof(map->created)); ceph_decode_copy(p, &map->modified, sizeof(map->modified)); - map->num_pools = ceph_decode_32(p); - map->pg_pool = kcalloc(map->num_pools, sizeof(*map->pg_pool), - GFP_NOFS); - if (!map->pg_pool) { - err = -ENOMEM; - goto bad; - } ceph_decode_32_safe(p, end, max, bad); while (max--) { - ceph_decode_need(p, end, 4+1+sizeof(map->pg_pool->v), bad); - i = ceph_decode_32(p); - if (i >= map->num_pools) + ceph_decode_need(p, end, 4 + 1 + sizeof(pi->v), bad); + pi = kmalloc(sizeof(*pi), GFP_NOFS); + if (!pi) goto bad; + pi->id = ceph_decode_32(p); ev = ceph_decode_8(p); /* encoding version */ if (ev > CEPH_PG_POOL_VERSION) { pr_warning("got unknown v %d > %d of ceph_pg_pool\n", ev, CEPH_PG_POOL_VERSION); goto bad; } - ceph_decode_copy(p, &map->pg_pool[i].v, - sizeof(map->pg_pool->v)); - calc_pg_masks(&map->pg_pool[i]); - p += le32_to_cpu(map->pg_pool[i].v.num_snaps) * sizeof(u64); - p += le32_to_cpu(map->pg_pool[i].v.num_removed_snap_intervals) + ceph_decode_copy(p, &pi->v, sizeof(pi->v)); + __insert_pg_pool(&map->pg_pools, pi); + calc_pg_masks(pi); + p += le32_to_cpu(pi->v.num_snaps) * sizeof(u64); + p += le32_to_cpu(pi->v.num_removed_snap_intervals) * sizeof(u64) * 2; } + ceph_decode_32_safe(p, end, map->pool_max, bad); ceph_decode_32_safe(p, end, map->flags, bad); @@ -581,7 +625,7 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, u32 epoch = 0; struct ceph_timespec modified; u32 len, pool; - __s32 new_flags, max; + __s32 new_pool_max, new_flags, max; void *start = *p; int err = -EINVAL; u16 version; @@ -600,6 +644,7 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, epoch = ceph_decode_32(p); BUG_ON(epoch != map->epoch+1); ceph_decode_copy(p, &modified, sizeof(modified)); + new_pool_max = ceph_decode_32(p); new_flags = ceph_decode_32(p); /* full map? */ @@ -623,6 +668,8 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, /* new flags? */ if (new_flags >= 0) map->flags = new_flags; + if (new_pool_max >= 0) + map->pool_max = new_pool_max; ceph_decode_need(p, end, 5*sizeof(u32), bad); @@ -647,37 +694,42 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, ceph_decode_32_safe(p, end, len, bad); while (len--) { __u8 ev; + struct ceph_pg_pool_info *pi; ceph_decode_32_safe(p, end, pool, bad); - if (pool >= map->num_pools) { - void *pg_pool = kcalloc(pool + 1, - sizeof(*map->pg_pool), - GFP_NOFS); - if (!pg_pool) { - err = -ENOMEM; - goto bad; - } - memcpy(pg_pool, map->pg_pool, - map->num_pools * sizeof(*map->pg_pool)); - kfree(map->pg_pool); - map->pg_pool = pg_pool; - map->num_pools = pool+1; - } - ceph_decode_need(p, end, 1 + sizeof(map->pg_pool->v), bad); + ceph_decode_need(p, end, 1 + sizeof(pi->v), bad); ev = ceph_decode_8(p); /* encoding version */ if (ev > CEPH_PG_POOL_VERSION) { pr_warning("got unknown v %d > %d of ceph_pg_pool\n", ev, CEPH_PG_POOL_VERSION); goto bad; } - ceph_decode_copy(p, &map->pg_pool[pool].v, - sizeof(map->pg_pool->v)); - calc_pg_masks(&map->pg_pool[pool]); + pi = __lookup_pg_pool(&map->pg_pools, pool); + if (!pi) { + pi = kmalloc(sizeof(*pi), GFP_NOFS); + if (!pi) { + err = -ENOMEM; + goto bad; + } + pi->id = pool; + __insert_pg_pool(&map->pg_pools, pi); + } + ceph_decode_copy(p, &pi->v, sizeof(pi->v)); + calc_pg_masks(pi); } - /* old_pool (ignore) */ + /* old_pool */ ceph_decode_32_safe(p, end, len, bad); - *p += len * sizeof(u32); + while (len--) { + struct ceph_pg_pool_info *pi; + + ceph_decode_32_safe(p, end, pool, bad); + pi = __lookup_pg_pool(&map->pg_pools, pool); + if (pi) { + rb_erase(&pi->node, &map->pg_pools); + kfree(pi); + } + } /* new_up */ err = -EINVAL; @@ -861,10 +913,10 @@ int ceph_calc_object_layout(struct ceph_object_layout *ol, unsigned ps; BUG_ON(!osdmap); - if (poolid >= osdmap->num_pools) - return -EIO; - pool = &osdmap->pg_pool[poolid]; + pool = __lookup_pg_pool(&osdmap->pg_pools, poolid); + if (!pool) + return -EIO; ps = ceph_str_hash(pool->v.object_hash, oid, strlen(oid)); if (preferred >= 0) { ps += preferred; @@ -919,9 +971,9 @@ static int *calc_pg_raw(struct ceph_osdmap *osdmap, struct ceph_pg pgid, preferred >= osdmap->crush->max_devices) preferred = -1; - if (poolid >= osdmap->num_pools) + pool = __lookup_pg_pool(&osdmap->pg_pools, poolid); + if (!pool) return NULL; - pool = &osdmap->pg_pool[poolid]; ruleno = crush_find_rule(osdmap->crush, pool->v.crush_ruleset, pool->v.type, pool->v.size); if (ruleno < 0) { diff --git a/fs/ceph/osdmap.h b/fs/ceph/osdmap.h index c4af841..1fb55af 100644 --- a/fs/ceph/osdmap.h +++ b/fs/ceph/osdmap.h @@ -19,6 +19,8 @@ * the change between two successive epochs, or as a fully encoded map. */ struct ceph_pg_pool_info { + struct rb_node node; + int id; struct ceph_pg_pool v; int pg_num_mask, pgp_num_mask, lpg_num_mask, lpgp_num_mask; }; @@ -44,9 +46,8 @@ struct ceph_osdmap { struct ceph_entity_addr *osd_addr; struct rb_root pg_temp; - - u32 num_pools; - struct ceph_pg_pool_info *pg_pool; + struct rb_root pg_pools; + u32 pool_max; /* the CRUSH map specifies the mapping of placement groups to * the list of osds that store+replicate them. */ diff --git a/fs/ceph/rados.h b/fs/ceph/rados.h index 1f4c786..26ac8b8 100644 --- a/fs/ceph/rados.h +++ b/fs/ceph/rados.h @@ -11,8 +11,8 @@ /* * osdmap encoding versions */ -#define CEPH_OSDMAP_INC_VERSION 3 -#define CEPH_OSDMAP_VERSION 3 +#define CEPH_OSDMAP_INC_VERSION 4 +#define CEPH_OSDMAP_VERSION 4 /* * fs id -- cgit v0.10.2 From a17d6473cc9eb64a5b41c568310aa73824ebaa64 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 17 Feb 2010 13:56:07 -0800 Subject: ceph: v0.19 release Signed-off-by: Sage Weil diff --git a/fs/ceph/ceph_fs.h b/fs/ceph/ceph_fs.h index 004aae5..0c2241e 100644 --- a/fs/ceph/ceph_fs.h +++ b/fs/ceph/ceph_fs.h @@ -19,7 +19,7 @@ * Ceph release version */ #define CEPH_VERSION_MAJOR 0 -#define CEPH_VERSION_MINOR 18 +#define CEPH_VERSION_MINOR 19 #define CEPH_VERSION_PATCH 0 #define _CEPH_STRINGIFY(x) #x -- cgit v0.10.2 From 2c27c9a57c93a0757b9b4b0e7dc1abeaf1db1ce2 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 17 Feb 2010 15:45:51 -0800 Subject: ceph: fix typo in ceph_queue_writeback debug output Signed-off-by: Sage Weil diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 58bdff0..d7d5d49 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -1247,10 +1247,10 @@ void ceph_queue_writeback(struct inode *inode) { if (queue_work(ceph_inode_to_client(inode)->wb_wq, &ceph_inode(inode)->i_wb_work)) { - dout("ceph_queue_invalidate %p\n", inode); + dout("ceph_queue_writeback %p\n", inode); igrab(inode); } else { - dout("ceph_queue_invalidate %p failed\n", inode); + dout("ceph_queue_writeback %p failed\n", inode); } } -- cgit v0.10.2 From 8b7ef6d8f16274da42344cd50746ddb1c93c25ea Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Tue, 16 Feb 2010 22:55:51 +0100 Subject: ACPI thermal: Check for thermal zone requirement ACPI spec says (11.5 Thermal Zone Interface Requirements): A thermal zone must contain at least one trip point (critical, near critical, active, or passive) Check this once at init time. Signed-off-by: Thomas Renninger Tested-by: clarkt@cnsp.com Signed-off-by: Len Brown diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 9073ada..e9f28e0 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -575,7 +575,23 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) static int acpi_thermal_get_trip_points(struct acpi_thermal *tz) { - return acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT); + int i, valid, ret = acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT); + + if (ret) + return ret; + + valid = tz->trips.critical.flags.valid | + tz->trips.hot.flags.valid | + tz->trips.passive.flags.valid; + + for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) + valid |= tz->trips.active[i].flags.valid; + + if (!valid) { + printk(KERN_WARNING FW_BUG "No valid trip found\n"); + return -ENODEV; + } + return 0; } static void acpi_thermal_check(void *data) -- cgit v0.10.2 From 5ecad6fd7bfd30b3eaea51345f546b81de7a6473 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 17 Feb 2010 10:43:37 -0800 Subject: ceph: fix check for invalidate_mapping_pages success We need to know whether there was any page left behind, and not the return value (the total number of pages invalidated). Look at the mapping to see if we were successful or not. Move it all into a helper to simplify the two callers. Signed-off-by: Yehuda Sadeh Signed-off-by: Sage Weil diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 4958a2e..e1e6df0 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -1362,6 +1362,41 @@ static int __mark_caps_flushing(struct inode *inode, } /* + * try to invalidate mapping pages without blocking. + */ +static int mapping_is_empty(struct address_space *mapping) +{ + struct page *page = find_get_page(mapping, 0); + + if (!page) + return 1; + + put_page(page); + return 0; +} + +static int try_nonblocking_invalidate(struct inode *inode) +{ + struct ceph_inode_info *ci = ceph_inode(inode); + u32 invalidating_gen = ci->i_rdcache_gen; + + spin_unlock(&inode->i_lock); + invalidate_mapping_pages(&inode->i_data, 0, -1); + spin_lock(&inode->i_lock); + + if (mapping_is_empty(&inode->i_data) && + invalidating_gen == ci->i_rdcache_gen) { + /* success. */ + dout("try_nonblocking_invalidate %p success\n", inode); + ci->i_rdcache_gen = 0; + ci->i_rdcache_revoking = 0; + return 0; + } + dout("try_nonblocking_invalidate %p failed\n", inode); + return -1; +} + +/* * Swiss army knife function to examine currently used and wanted * versus held caps. Release, flush, ack revoked caps to mds as * appropriate. @@ -1451,27 +1486,19 @@ retry_locked: (file_wanted == 0 || /* no open files */ (revoking & CEPH_CAP_FILE_CACHE)) && /* or revoking cache */ !tried_invalidate) { - u32 invalidating_gen = ci->i_rdcache_gen; - int ret; - dout("check_caps trying to invalidate on %p\n", inode); - spin_unlock(&inode->i_lock); - ret = invalidate_mapping_pages(&inode->i_data, 0, -1); - spin_lock(&inode->i_lock); - if (ret == 0 && invalidating_gen == ci->i_rdcache_gen) { - /* success. */ - ci->i_rdcache_gen = 0; - ci->i_rdcache_revoking = 0; - } else if (revoking & CEPH_CAP_FILE_CACHE) { - dout("check_caps queuing invalidate\n"); - queue_invalidate = 1; - ci->i_rdcache_revoking = ci->i_rdcache_gen; - } else { - dout("check_caps failed to invalidate pages\n"); - /* we failed to invalidate pages. check these - caps again later. */ - force_requeue = 1; - __cap_set_timeouts(mdsc, ci); + if (try_nonblocking_invalidate(inode) < 0) { + if (revoking & CEPH_CAP_FILE_CACHE) { + dout("check_caps queuing invalidate\n"); + queue_invalidate = 1; + ci->i_rdcache_revoking = ci->i_rdcache_gen; + } else { + dout("check_caps failed to invalidate pages\n"); + /* we failed to invalidate pages. check these + caps again later. */ + force_requeue = 1; + __cap_set_timeouts(mdsc, ci); + } } tried_invalidate = 1; goto retry_locked; @@ -2184,7 +2211,6 @@ static int handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant, int revoked_rdcache = 0; int queue_invalidate = 0; int tried_invalidate = 0; - int ret; dout("handle_cap_grant inode %p cap %p mds%d seq %d %s\n", inode, cap, mds, seq, ceph_cap_string(newcaps)); @@ -2199,24 +2225,16 @@ static int handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant, restart: if (((cap->issued & ~newcaps) & CEPH_CAP_FILE_CACHE) && !ci->i_wrbuffer_ref && !tried_invalidate) { - dout("CACHE invalidation\n"); - spin_unlock(&inode->i_lock); tried_invalidate = 1; - - ret = invalidate_mapping_pages(&inode->i_data, 0, -1); - spin_lock(&inode->i_lock); - if (ret < 0) { + if (try_nonblocking_invalidate(inode) == 0) { + revoked_rdcache = 1; + } else { /* there were locked pages.. invalidate later in a separate thread. */ if (ci->i_rdcache_revoking != ci->i_rdcache_gen) { queue_invalidate = 1; ci->i_rdcache_revoking = ci->i_rdcache_gen; } - } else { - /* we successfully invalidated those pages */ - revoked_rdcache = 1; - ci->i_rdcache_gen = 0; - ci->i_rdcache_revoking = 0; } goto restart; } -- cgit v0.10.2 From e63dc5c780ba32d6d8b3662eecce2b8d96489b41 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Fri, 19 Feb 2010 00:07:01 +0000 Subject: ceph: remove page upon writeback completion if lost cache cap This page should have been removed earlier when the cache cap was revoked, but a writeback was in flight, so it was skipped. We truncate it here just as the writeback finishes, while it's still locked. Signed-off-by: Yehuda Sadeh Signed-off-by: Sage Weil diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index 71f5ad1..25360d5 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c @@ -514,6 +514,7 @@ static void writepages_finish(struct ceph_osd_request *req, u64 bytes = 0; struct ceph_client *client = ceph_inode_to_client(inode); long writeback_stat; + unsigned issued = __ceph_caps_issued(ci, NULL); /* parse reply */ replyhead = msg->front.iov_base; @@ -559,6 +560,16 @@ static void writepages_finish(struct ceph_osd_request *req, ceph_put_snap_context(snapc); dout("unlocking %d %p\n", i, page); end_page_writeback(page); + + /* + * We lost the cache cap, need to truncate the page before + * it is unlocked, otherwise we'd truncate it later in the + * page truncation thread, possibly losing some data that + * raced its way in + */ + if ((issued & CEPH_CAP_FILE_CACHE) == 0) + generic_error_remove_page(inode->i_mapping, page); + unlock_page(page); } dout("%p wrote+cleaned %d pages\n", inode, wrote); -- cgit v0.10.2 From c9af9fb68e01eb2c2165e1bc45cfeeed510c64e6 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Fri, 19 Feb 2010 00:10:11 +0000 Subject: ceph: don't truncate dirty pages in invalidate work thread Instead of truncating the whole range of pages, we skip those pages that are dirty or in the middle of writeback. Those pages will be cleared later when the writeback completes. Signed-off-by: Yehuda Sadeh Signed-off-by: Sage Weil diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index d7d5d49..7abe1ae 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "super.h" #include "decode.h" @@ -1280,6 +1281,49 @@ void ceph_queue_invalidate(struct inode *inode) } /* + * invalidate any pages that are not dirty or under writeback. this + * includes pages that are clean and mapped. + */ +static void ceph_invalidate_nondirty_pages(struct address_space *mapping) +{ + struct pagevec pvec; + pgoff_t next = 0; + int i; + + pagevec_init(&pvec, 0); + while (pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) { + for (i = 0; i < pagevec_count(&pvec); i++) { + struct page *page = pvec.pages[i]; + pgoff_t index; + int skip_page = + (PageDirty(page) || PageWriteback(page)); + + if (!skip_page) + skip_page = !trylock_page(page); + + /* + * We really shouldn't be looking at the ->index of an + * unlocked page. But we're not allowed to lock these + * pages. So we rely upon nobody altering the ->index + * of this (pinned-by-us) page. + */ + index = page->index; + if (index > next) + next = index; + next++; + + if (skip_page) + continue; + + generic_error_remove_page(mapping, page); + unlock_page(page); + } + pagevec_release(&pvec); + cond_resched(); + } +} + +/* * Invalidate inode pages in a worker thread. (This can't be done * in the message handler context.) */ @@ -1305,7 +1349,7 @@ static void ceph_invalidate_work(struct work_struct *work) orig_gen = ci->i_rdcache_gen; spin_unlock(&inode->i_lock); - truncate_inode_pages(&inode->i_data, 0); + ceph_invalidate_nondirty_pages(inode->i_mapping); spin_lock(&inode->i_lock); if (orig_gen == ci->i_rdcache_gen) { -- cgit v0.10.2 From bcd2cbd10ce31c950a40c08d7f601f8ff23537b8 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Fri, 19 Feb 2010 00:12:21 +0000 Subject: ceph: cleanup redundant code in handle_cap_grant There is no state in local vars that requires us to loop after temporarily dropping i_lock. Signed-off-by: Yehuda Sadeh Signed-off-by: Sage Weil diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index e1e6df0..289f6c6 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -2210,7 +2210,6 @@ static int handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant, int writeback = 0; int revoked_rdcache = 0; int queue_invalidate = 0; - int tried_invalidate = 0; dout("handle_cap_grant inode %p cap %p mds%d seq %d %s\n", inode, cap, mds, seq, ceph_cap_string(newcaps)); @@ -2222,10 +2221,8 @@ static int handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant, * try to invalidate (once). (If there are dirty buffers, we * will invalidate _after_ writeback.) */ -restart: if (((cap->issued & ~newcaps) & CEPH_CAP_FILE_CACHE) && - !ci->i_wrbuffer_ref && !tried_invalidate) { - tried_invalidate = 1; + !ci->i_wrbuffer_ref) { if (try_nonblocking_invalidate(inode) == 0) { revoked_rdcache = 1; } else { @@ -2236,7 +2233,6 @@ restart: ci->i_rdcache_revoking = ci->i_rdcache_gen; } } - goto restart; } /* side effects now are allowed */ -- cgit v0.10.2 From 281ff33b7c1b1ba2a5f9b03425e5f692a94913fa Mon Sep 17 00:00:00 2001 From: Suresh Siddha Date: Thu, 18 Feb 2010 11:51:40 -0800 Subject: x86_64, cpa: Don't work hard in preserving kernel 2M mappings when using 4K already We currently enforce the !RW mapping for the kernel mapping that maps holes between different text, rodata and data sections. However, kernel identity mappings will have different RWX permissions to the pages mapping to text and to the pages padding (which are freed) the text, rodata sections. Hence kernel identity mappings will be broken to smaller pages. For 64-bit, kernel text and kernel identity mappings are different, so we can enable protection checks that come with CONFIG_DEBUG_RODATA, as well as retain 2MB large page mappings for kernel text. Konrad reported a boot failure with the Linux Xen paravirt guest because of this. In this paravirt guest case, the kernel text mapping and the kernel identity mapping share the same page-table pages. Thus forcing the !RW mapping for some of the kernel mappings also cause the kernel identity mappings to be read-only resulting in the boot failure. Linux Xen paravirt guest also uses 4k mappings and don't use 2M mapping. Fix this issue and retain large page performance advantage for native kernels by not working hard and not enforcing !RW for the kernel text mapping, if the current mapping is already using small page mapping. Reported-by: Konrad Rzeszutek Wilk Signed-off-by: Suresh Siddha LKML-Reference: <1266522700.2909.34.camel@sbs-t61.sc.intel.com> Tested-by: Konrad Rzeszutek Wilk Cc: stable@kernel.org [2.6.32, 2.6.33] Signed-off-by: H. Peter Anvin diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 1d4eb93..cf07c26 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -291,8 +291,29 @@ static inline pgprot_t static_protections(pgprot_t prot, unsigned long address, */ if (kernel_set_to_readonly && within(address, (unsigned long)_text, - (unsigned long)__end_rodata_hpage_align)) - pgprot_val(forbidden) |= _PAGE_RW; + (unsigned long)__end_rodata_hpage_align)) { + unsigned int level; + + /* + * Don't enforce the !RW mapping for the kernel text mapping, + * if the current mapping is already using small page mapping. + * No need to work hard to preserve large page mappings in this + * case. + * + * This also fixes the Linux Xen paravirt guest boot failure + * (because of unexpected read-only mappings for kernel identity + * mappings). In this paravirt guest case, the kernel text + * mapping and the kernel identity mapping share the same + * page-table pages. Thus we can't really use different + * protections for the kernel text and identity mappings. Also, + * these shared mappings are made of small page mappings. + * Thus this don't enforce !RW mapping for small page kernel + * text mapping logic will help Linux Xen parvirt guest boot + * aswell. + */ + if (lookup_address(address, &level) && (level != PG_LEVEL_4K)) + pgprot_val(forbidden) |= _PAGE_RW; + } #endif prot = __pgprot(pgprot_val(prot) & ~pgprot_val(forbidden)); -- cgit v0.10.2 From fa80945269f312bc609e8384302f58b03c916e12 Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Sat, 20 Feb 2010 11:44:27 +0100 Subject: ACPI thermal: Don't invalidate thermal zone if critical trip point is bad V2: Corrected integer/long conversion. Some BIOSes return a negative value for the critical trip point. Especially since Windows 2006... We currently invalidate the whole thermal zone in this case. But it may still be needed for cooling, also without critical trip point. This patch invalidates the critical trip point if no _CRT function is found or if it returns negative values, but does not invalidate the whole thermal zone in this case. Reference: http://bugzilla.novell.com/show_bug.cgi?id=531547 Signed-off-by: Thomas Renninger Tested-by: clarkt@cnsp.com Acked-by: Zhang Rui Signed-off-by: Len Brown diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 9073ada..77b8e1e 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -368,7 +368,7 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) int valid = 0; int i; - /* Critical Shutdown (required) */ + /* Critical Shutdown */ if (flag & ACPI_TRIPS_CRITICAL) { status = acpi_evaluate_integer(tz->device->handle, "_CRT", NULL, &tmp); @@ -379,17 +379,19 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) * Below zero (Celsius) values clearly aren't right for sure.. * ... so lets discard those as invalid. */ - if (ACPI_FAILURE(status) || - tz->trips.critical.temperature <= 2732) { + if (ACPI_FAILURE(status)) { + tz->trips.critical.flags.valid = 0; + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "No critical threshold\n")); + } else if (tmp <= 2732) { + printk(KERN_WARNING FW_BUG "Invalid critical threshold " + "(%llu)\n", tmp); tz->trips.critical.flags.valid = 0; - ACPI_EXCEPTION((AE_INFO, status, - "No or invalid critical threshold")); - return -ENODEV; } else { tz->trips.critical.flags.valid = 1; ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Found critical threshold [%lu]\n", - tz->trips.critical.temperature)); + "Found critical threshold [%lu]\n", + tz->trips.critical.temperature)); } if (tz->trips.critical.flags.valid == 1) { if (crt == -1) { -- cgit v0.10.2 From 5b3a4db3e4009aff918abb1353eb3f4925393a7b Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 19 Feb 2010 21:43:23 -0800 Subject: ceph: fix up unexpected message handling Fix skipping of unexpected message types from osd, mon. Clean up pr_info and debug output. Signed-off-by: Sage Weil diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index ca2ad0e..fdda707 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -1361,7 +1361,7 @@ static int read_partial_message(struct ceph_connection *con) con->in_msg = ceph_alloc_msg(con, &con->in_hdr, &skip); if (skip) { /* skip this message */ - pr_err("alloc_msg returned NULL, skipping message\n"); + dout("alloc_msg returned NULL, skipping message\n"); con->in_base_pos = -front_len - middle_len - data_len - sizeof(m->footer); con->in_tag = CEPH_MSGR_TAG_READY; @@ -1370,7 +1370,8 @@ static int read_partial_message(struct ceph_connection *con) if (IS_ERR(con->in_msg)) { ret = PTR_ERR(con->in_msg); con->in_msg = NULL; - con->error_msg = "error allocating memory for incoming message"; + con->error_msg = + "error allocating memory for incoming message"; return ret; } m = con->in_msg; diff --git a/fs/ceph/mon_client.c b/fs/ceph/mon_client.c index 40d7d90..890597c 100644 --- a/fs/ceph/mon_client.c +++ b/fs/ceph/mon_client.c @@ -763,7 +763,7 @@ static struct ceph_msg *mon_alloc_msg(struct ceph_connection *con, struct ceph_mon_client *monc = con->private; int type = le16_to_cpu(hdr->type); int front_len = le32_to_cpu(hdr->front_len); - struct ceph_msg *m; + struct ceph_msg *m = NULL; *skip = 0; @@ -777,13 +777,17 @@ static struct ceph_msg *mon_alloc_msg(struct ceph_connection *con, case CEPH_MSG_AUTH_REPLY: m = ceph_msgpool_get(&monc->msgpool_auth_reply, front_len); break; - default: - return NULL; + case CEPH_MSG_MON_MAP: + case CEPH_MSG_MDS_MAP: + case CEPH_MSG_OSD_MAP: + m = ceph_msg_new(type, front_len, 0, 0, NULL); + break; } - if (!m) + if (!m) { + pr_info("alloc_msg unknown type %d\n", type); *skip = 1; - + } return m; } diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index fa0f737..ffd819c 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -1396,31 +1396,30 @@ static void dispatch(struct ceph_connection *con, struct ceph_msg *msg) ceph_msg_put(msg); } -static struct ceph_msg *alloc_msg(struct ceph_connection *con, +/* + * lookup and return message for incoming reply + */ +static struct ceph_msg *get_reply(struct ceph_connection *con, struct ceph_msg_header *hdr, int *skip) { struct ceph_osd *osd = con->private; struct ceph_osd_client *osdc = osd->o_osdc; - int type = le16_to_cpu(hdr->type); - int front = le32_to_cpu(hdr->front_len); - int data_len = le32_to_cpu(hdr->data_len); struct ceph_msg *m; struct ceph_osd_request *req; + int front = le32_to_cpu(hdr->front_len); + int data_len = le32_to_cpu(hdr->data_len); u64 tid; int err; - *skip = 0; - if (type != CEPH_MSG_OSD_OPREPLY) - return NULL; - tid = le64_to_cpu(hdr->tid); mutex_lock(&osdc->request_mutex); req = __lookup_request(osdc, tid); if (!req) { *skip = 1; m = NULL; - dout("alloc_msg unknown tid %llu\n", tid); + pr_info("alloc_msg unknown tid %llu from osd%d\n", tid, + osd->o_osd); goto out; } m = __get_next_reply(con, req, front); @@ -1437,11 +1436,33 @@ static struct ceph_msg *alloc_msg(struct ceph_connection *con, m = ERR_PTR(err); } } + *skip = 0; out: mutex_unlock(&osdc->request_mutex); - return m; + +} + +static struct ceph_msg *alloc_msg(struct ceph_connection *con, + struct ceph_msg_header *hdr, + int *skip) +{ + struct ceph_osd *osd = con->private; + int type = le16_to_cpu(hdr->type); + int front = le32_to_cpu(hdr->front_len); + + switch (type) { + case CEPH_MSG_OSD_MAP: + return ceph_msg_new(type, front, 0, 0, NULL); + case CEPH_MSG_OSD_OPREPLY: + return get_reply(con, hdr, skip); + default: + pr_info("alloc_msg unexpected msg type %d from osd%d\n", type, + osd->o_osd); + *skip = 1; + return NULL; + } } /* -- cgit v0.10.2 From 4ce1e9adabbad8f2c45ceeeb6de56cc368484297 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Mon, 22 Feb 2010 17:17:44 +0300 Subject: ceph: move dereference after NULL test Signed-off-by: Alexander Beregalov Signed-off-by: Sage Weil diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index 25360d5..23bb0ce 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c @@ -144,7 +144,7 @@ static int ceph_set_page_dirty(struct page *page) */ static void ceph_invalidatepage(struct page *page, unsigned long offset) { - struct inode *inode = page->mapping->host; + struct inode *inode; struct ceph_inode_info *ci; struct ceph_snap_context *snapc = (void *)page->private; @@ -153,6 +153,8 @@ static void ceph_invalidatepage(struct page *page, unsigned long offset) BUG_ON(!PagePrivate(page)); BUG_ON(!page->mapping); + inode = page->mapping->host; + /* * We can get non-dirty pages here due to races between * set_page_dirty and truncate_complete_page; just spit out a -- cgit v0.10.2 From a6369741c48815fedfce7072b7a9cd98b5bafd56 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 22 Feb 2010 13:59:00 -0800 Subject: ceph: fix comments, locking in destroy_inode The destroy_inode path needs no inode locks since there are no inode references. Update __ceph_remove_cap comment to reflect that it is called without cap->session->s_mutex in this case. Signed-off-by: Sage Weil diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 289f6c6..b6154ff 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -856,8 +856,8 @@ static int __ceph_is_any_caps(struct ceph_inode_info *ci) } /* - * caller should hold i_lock, and session s_mutex. - * returns true if this is the last cap. if so, caller should iput. + * caller should hold i_lock. + * caller will not hold session s_mutex if called from destroy_inode. */ void __ceph_remove_cap(struct ceph_cap *cap) { @@ -974,15 +974,14 @@ static int send_cap_msg(struct ceph_mds_session *session, } /* - * Queue cap releases when an inode is dropped from our - * cache. + * Queue cap releases when an inode is dropped from our cache. Since + * inode is about to be destroyed, there is no need for i_lock. */ void ceph_queue_caps_release(struct inode *inode) { struct ceph_inode_info *ci = ceph_inode(inode); struct rb_node *p; - spin_lock(&inode->i_lock); p = rb_first(&ci->i_caps); while (p) { struct ceph_cap *cap = rb_entry(p, struct ceph_cap, ci_node); @@ -1024,9 +1023,7 @@ void ceph_queue_caps_release(struct inode *inode) spin_unlock(&session->s_cap_lock); p = rb_next(p); __ceph_remove_cap(cap); - } - spin_unlock(&inode->i_lock); } /* -- cgit v0.10.2 From 2600d2dd5085ab6fb09540226138a60055abf335 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 22 Feb 2010 15:12:16 -0800 Subject: ceph: drop messages on unregistered mds sessions; cleanup Verify the mds session is currently registered before handling incoming messages. Clean up message handlers to pull mds out of session->s_mds instead of less trustworthy src field. Clean up con_{get,put} debug output. Signed-off-by: Sage Weil diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index b6154ff..bb84616 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -2600,7 +2600,7 @@ void ceph_handle_caps(struct ceph_mds_session *session, struct inode *inode; struct ceph_cap *cap; struct ceph_mds_caps *h; - int mds = le64_to_cpu(msg->hdr.src.name.num); + int mds = session->s_mds; int op; u32 seq; struct ceph_vino vino; diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 124c0c1..4d00ea2 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -309,6 +309,15 @@ static bool __have_session(struct ceph_mds_client *mdsc, int mds) return mdsc->sessions[mds]; } +static int __verify_registered_session(struct ceph_mds_client *mdsc, + struct ceph_mds_session *s) +{ + if (s->s_mds >= mdsc->max_sessions || + mdsc->sessions[s->s_mds] != s) + return -ENOENT; + return 0; +} + /* * create+register a new session for given mds. * called under mdsc->mutex. @@ -382,10 +391,11 @@ fail_realloc: /* * called under mdsc->mutex */ -static void unregister_session(struct ceph_mds_client *mdsc, +static void __unregister_session(struct ceph_mds_client *mdsc, struct ceph_mds_session *s) { - dout("unregister_session mds%d %p\n", s->s_mds, s); + dout("__unregister_session mds%d %p\n", s->s_mds, s); + BUG_ON(mdsc->sessions[s->s_mds] != s); mdsc->sessions[s->s_mds] = NULL; ceph_con_close(&s->s_con); ceph_put_mds_session(s); @@ -1740,10 +1750,8 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg) struct ceph_mds_reply_info_parsed *rinfo; /* parsed reply info */ u64 tid; int err, result; - int mds; + int mds = session->s_mds; - if (msg->hdr.src.name.type != CEPH_ENTITY_TYPE_MDS) - return; if (msg->front.iov_len < sizeof(*head)) { pr_err("mdsc_handle_reply got corrupt (short) reply\n"); ceph_msg_dump(msg); @@ -1760,7 +1768,6 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg) return; } dout("handle_reply %p\n", req); - mds = le64_to_cpu(msg->hdr.src.name.num); /* correct session? */ if (!req->r_session && req->r_session != session) { @@ -1884,7 +1891,9 @@ out: /* * handle mds notification that our request has been forwarded. */ -static void handle_forward(struct ceph_mds_client *mdsc, struct ceph_msg *msg) +static void handle_forward(struct ceph_mds_client *mdsc, + struct ceph_mds_session *session, + struct ceph_msg *msg) { struct ceph_mds_request *req; u64 tid; @@ -1894,11 +1903,7 @@ static void handle_forward(struct ceph_mds_client *mdsc, struct ceph_msg *msg) int err = -EINVAL; void *p = msg->front.iov_base; void *end = p + msg->front.iov_len; - int from_mds, state; - - if (msg->hdr.src.name.type != CEPH_ENTITY_TYPE_MDS) - goto bad; - from_mds = le64_to_cpu(msg->hdr.src.name.num); + int state; ceph_decode_need(&p, end, sizeof(u64)+2*sizeof(u32), bad); tid = ceph_decode_64(&p); @@ -1915,6 +1920,9 @@ static void handle_forward(struct ceph_mds_client *mdsc, struct ceph_msg *msg) goto out; /* dup reply? */ } + if (next_mds >= mdsc->max_sessions) + goto out; + state = mdsc->sessions[next_mds]->s_state; if (fwd_seq <= req->r_num_fwd) { dout("forward %llu to mds%d - old seq %d <= %d\n", @@ -1945,14 +1953,10 @@ static void handle_session(struct ceph_mds_session *session, struct ceph_mds_client *mdsc = session->s_mdsc; u32 op; u64 seq; - int mds; + int mds = session->s_mds; struct ceph_mds_session_head *h = msg->front.iov_base; int wake = 0; - if (msg->hdr.src.name.type != CEPH_ENTITY_TYPE_MDS) - return; - mds = le64_to_cpu(msg->hdr.src.name.num); - /* decode */ if (msg->front.iov_len != sizeof(*h)) goto bad; @@ -1960,6 +1964,8 @@ static void handle_session(struct ceph_mds_session *session, seq = le64_to_cpu(h->seq); mutex_lock(&mdsc->mutex); + if (op == CEPH_SESSION_CLOSE) + __unregister_session(mdsc, session); /* FIXME: this ttl calculation is generous */ session->s_ttl = jiffies + HZ*mdsc->mdsmap->m_session_autoclose; mutex_unlock(&mdsc->mutex); @@ -1990,7 +1996,6 @@ static void handle_session(struct ceph_mds_session *session, break; case CEPH_SESSION_CLOSE: - unregister_session(mdsc, session); remove_session_caps(session); wake = 1; /* for good measure */ complete(&mdsc->session_close_waiters); @@ -2269,7 +2274,7 @@ static void check_new_map(struct ceph_mds_client *mdsc, /* the session never opened, just close it * out now */ __wake_requests(mdsc, &s->s_waiting); - unregister_session(mdsc, s); + __unregister_session(mdsc, s); } else { /* just close it */ mutex_unlock(&mdsc->mutex); @@ -2329,24 +2334,22 @@ void __ceph_mdsc_drop_dentry_lease(struct dentry *dentry) di->lease_session = NULL; } -static void handle_lease(struct ceph_mds_client *mdsc, struct ceph_msg *msg) +static void handle_lease(struct ceph_mds_client *mdsc, + struct ceph_mds_session *session, + struct ceph_msg *msg) { struct super_block *sb = mdsc->client->sb; struct inode *inode; - struct ceph_mds_session *session; struct ceph_inode_info *ci; struct dentry *parent, *dentry; struct ceph_dentry_info *di; - int mds; + int mds = session->s_mds; struct ceph_mds_lease *h = msg->front.iov_base; struct ceph_vino vino; int mask; struct qstr dname; int release = 0; - if (msg->hdr.src.name.type != CEPH_ENTITY_TYPE_MDS) - return; - mds = le64_to_cpu(msg->hdr.src.name.num); dout("handle_lease from mds%d\n", mds); /* decode */ @@ -2360,15 +2363,6 @@ static void handle_lease(struct ceph_mds_client *mdsc, struct ceph_msg *msg) if (dname.len != get_unaligned_le32(h+1)) goto bad; - /* find session */ - mutex_lock(&mdsc->mutex); - session = __ceph_lookup_mds_session(mdsc, mds); - mutex_unlock(&mdsc->mutex); - if (!session) { - pr_err("handle_lease got lease but no session mds%d\n", mds); - return; - } - mutex_lock(&session->s_mutex); session->s_seq++; @@ -2437,7 +2431,6 @@ release: out: iput(inode); mutex_unlock(&session->s_mutex); - ceph_put_mds_session(session); return; bad: @@ -2794,7 +2787,7 @@ void ceph_mdsc_close_sessions(struct ceph_mds_client *mdsc) for (i = 0; i < mdsc->max_sessions; i++) { if (mdsc->sessions[i]) { session = get_session(mdsc->sessions[i]); - unregister_session(mdsc, session); + __unregister_session(mdsc, session); mutex_unlock(&mdsc->mutex); mutex_lock(&session->s_mutex); remove_session_caps(session); @@ -2891,8 +2884,7 @@ static struct ceph_connection *con_get(struct ceph_connection *con) struct ceph_mds_session *s = con->private; if (get_session(s)) { - dout("mdsc con_get %p %d -> %d\n", s, - atomic_read(&s->s_ref) - 1, atomic_read(&s->s_ref)); + dout("mdsc con_get %p ok (%d)\n", s, atomic_read(&s->s_ref)); return con; } dout("mdsc con_get %p FAIL\n", s); @@ -2903,9 +2895,8 @@ static void con_put(struct ceph_connection *con) { struct ceph_mds_session *s = con->private; - dout("mdsc con_put %p %d -> %d\n", s, atomic_read(&s->s_ref), - atomic_read(&s->s_ref) - 1); ceph_put_mds_session(s); + dout("mdsc con_put %p (%d)\n", s, atomic_read(&s->s_ref)); } /* @@ -2926,6 +2917,13 @@ static void dispatch(struct ceph_connection *con, struct ceph_msg *msg) struct ceph_mds_client *mdsc = s->s_mdsc; int type = le16_to_cpu(msg->hdr.type); + mutex_lock(&mdsc->mutex); + if (__verify_registered_session(mdsc, s) < 0) { + mutex_unlock(&mdsc->mutex); + goto out; + } + mutex_unlock(&mdsc->mutex); + switch (type) { case CEPH_MSG_MDS_MAP: ceph_mdsc_handle_map(mdsc, msg); @@ -2937,22 +2935,23 @@ static void dispatch(struct ceph_connection *con, struct ceph_msg *msg) handle_reply(s, msg); break; case CEPH_MSG_CLIENT_REQUEST_FORWARD: - handle_forward(mdsc, msg); + handle_forward(mdsc, s, msg); break; case CEPH_MSG_CLIENT_CAPS: ceph_handle_caps(s, msg); break; case CEPH_MSG_CLIENT_SNAP: - ceph_handle_snap(mdsc, msg); + ceph_handle_snap(mdsc, s, msg); break; case CEPH_MSG_CLIENT_LEASE: - handle_lease(mdsc, msg); + handle_lease(mdsc, s, msg); break; default: pr_err("received unknown message type %d %s\n", type, ceph_msg_type_name(type)); } +out: ceph_msg_put(msg); } diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c index 49d0c4c..bf2a5f3 100644 --- a/fs/ceph/snap.c +++ b/fs/ceph/snap.c @@ -713,11 +713,11 @@ static void flush_snaps(struct ceph_mds_client *mdsc) * directory into another realm. */ void ceph_handle_snap(struct ceph_mds_client *mdsc, + struct ceph_mds_session *session, struct ceph_msg *msg) { struct super_block *sb = mdsc->client->sb; - struct ceph_mds_session *session; - int mds; + int mds = session->s_mds; u64 split; int op; int trace_len; @@ -730,10 +730,6 @@ void ceph_handle_snap(struct ceph_mds_client *mdsc, int i; int locked_rwsem = 0; - if (msg->hdr.src.name.type != CEPH_ENTITY_TYPE_MDS) - return; - mds = le64_to_cpu(msg->hdr.src.name.num); - /* decode */ if (msg->front.iov_len < sizeof(*h)) goto bad; @@ -749,15 +745,6 @@ void ceph_handle_snap(struct ceph_mds_client *mdsc, dout("handle_snap from mds%d op %s split %llx tracelen %d\n", mds, ceph_snap_op_name(op), split, trace_len); - /* find session */ - mutex_lock(&mdsc->mutex); - session = __ceph_lookup_mds_session(mdsc, mds); - mutex_unlock(&mdsc->mutex); - if (!session) { - dout("WTF, got snap but no session for mds%d\n", mds); - return; - } - mutex_lock(&session->s_mutex); session->s_seq++; mutex_unlock(&session->s_mutex); diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 384f0e2..ff7aaa3 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -707,6 +707,7 @@ extern void ceph_put_snap_realm(struct ceph_mds_client *mdsc, extern int ceph_update_snap_trace(struct ceph_mds_client *m, void *p, void *e, bool deletion); extern void ceph_handle_snap(struct ceph_mds_client *mdsc, + struct ceph_mds_session *session, struct ceph_msg *msg); extern void ceph_queue_cap_snap(struct ceph_inode_info *ci, struct ceph_snap_context *snapc); -- cgit v0.10.2 From a1ea787c7b6ec036d169d84e08cca7b6e399ba70 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 23 Feb 2010 14:02:44 -0800 Subject: ceph: fix client_request_forward decoding The tid is in the message header, not body. Broken since 6df058c0. No need to look at next mds session; just mark the request and be done. (The old error path was broken too, but now it's gone.) Signed-off-by: Sage Weil diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 4d00ea2..bec8a7a 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -1896,17 +1896,15 @@ static void handle_forward(struct ceph_mds_client *mdsc, struct ceph_msg *msg) { struct ceph_mds_request *req; - u64 tid; + u64 tid = le64_to_cpu(msg->hdr.tid); u32 next_mds; u32 fwd_seq; u8 must_resend; int err = -EINVAL; void *p = msg->front.iov_base; void *end = p + msg->front.iov_len; - int state; - ceph_decode_need(&p, end, sizeof(u64)+2*sizeof(u32), bad); - tid = ceph_decode_64(&p); + ceph_decode_need(&p, end, 2*sizeof(u32), bad); next_mds = ceph_decode_32(&p); fwd_seq = ceph_decode_32(&p); must_resend = ceph_decode_8(&p); @@ -1920,10 +1918,6 @@ static void handle_forward(struct ceph_mds_client *mdsc, goto out; /* dup reply? */ } - if (next_mds >= mdsc->max_sessions) - goto out; - - state = mdsc->sessions[next_mds]->s_state; if (fwd_seq <= req->r_num_fwd) { dout("forward %llu to mds%d - old seq %d <= %d\n", tid, next_mds, req->r_num_fwd, fwd_seq); -- cgit v0.10.2 From 88d892a37fc231ab2aa3b1c40ca9d67224616594 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Tue, 23 Feb 2010 18:16:23 +0000 Subject: ceph: don't clobber write return value when using O_SYNC Signed-off-by: Yehuda Sadeh Signed-off-by: Sage Weil diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 2c4ae44..88932c9 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -807,7 +807,7 @@ static ssize_t ceph_aio_write(struct kiocb *iocb, const struct iovec *iov, struct ceph_osd_client *osdc = &ceph_client(inode->i_sb)->osdc; loff_t endoff = pos + iov->iov_len; int got = 0; - int ret; + int ret, err; if (ceph_snap(inode) != CEPH_NOSNAP) return -EROFS; @@ -838,9 +838,12 @@ retry_snap: if ((ret >= 0 || ret == -EIOCBQUEUED) && ((file->f_flags & O_SYNC) || IS_SYNC(file->f_mapping->host) - || ceph_osdmap_flag(osdc->osdmap, CEPH_OSDMAP_NEARFULL))) - ret = vfs_fsync_range(file, file->f_path.dentry, + || ceph_osdmap_flag(osdc->osdmap, CEPH_OSDMAP_NEARFULL))) { + err = vfs_fsync_range(file, file->f_path.dentry, pos, pos + ret - 1, 1); + if (err < 0) + ret = err; + } } if (ret >= 0) { spin_lock(&inode->i_lock); -- cgit v0.10.2 From bcf59e2c4dea780e4abf48d5e673f5d79f9ee064 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 23 Feb 2010 15:04:23 +0300 Subject: uwb: remove duplicate cpu_to_le16() These parameters should be passed as cpu endian because we change it to little endian inside usb_control_msg(). On x86 cpu_to_le16() doesn't do anything so either way works but I think the original code would break on big endian systems. I removed the masks as well because that usb_control_msg() parameters are __u16 so we already only use the lower bits. Signed-off-by: Dan Carpenter Signed-off-by: David Vrabel diff --git a/drivers/uwb/i1480/dfu/usb.c b/drivers/uwb/i1480/dfu/usb.c index a6a9375..a99e211 100644 --- a/drivers/uwb/i1480/dfu/usb.c +++ b/drivers/uwb/i1480/dfu/usb.c @@ -120,8 +120,7 @@ int i1480_usb_write(struct i1480 *i1480, u32 memory_address, result = usb_control_msg( i1480_usb->usb_dev, usb_sndctrlpipe(i1480_usb->usb_dev, 0), 0xf0, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - cpu_to_le16(memory_address & 0xffff), - cpu_to_le16((memory_address >> 16) & 0xffff), + memory_address, (memory_address >> 16), i1480->cmd_buf, buffer_size, 100 /* FIXME: arbitrary */); if (result < 0) break; @@ -166,8 +165,7 @@ int i1480_usb_read(struct i1480 *i1480, u32 addr, size_t size) result = usb_control_msg( i1480_usb->usb_dev, usb_rcvctrlpipe(i1480_usb->usb_dev, 0), 0xf0, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - cpu_to_le16(itr_addr & 0xffff), - cpu_to_le16((itr_addr >> 16) & 0xffff), + itr_addr, (itr_addr >> 16), i1480->cmd_buf + itr, itr_size, 100 /* FIXME: arbitrary */); if (result < 0) { -- cgit v0.10.2 From 161fd65ac934608345aed35226fc889ea3b0b500 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 25 Feb 2010 12:38:57 -0800 Subject: ceph: invalidate_authorizer without con->mutex held This fixes lock ABBA inversion, as the ->invalidate_authorizer() op may need to take a lock (or even call back into the messenger). Signed-off-by: Sage Weil diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index fdda707..9ea7b76 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -1853,14 +1853,6 @@ static void ceph_fault(struct ceph_connection *con) con->in_msg = NULL; } - /* - * in case we faulted due to authentication, invalidate our - * current tickets so that we can get new ones. - */ - if (con->auth_retry && con->ops->invalidate_authorizer) { - dout("calling invalidate_authorizer()\n"); - con->ops->invalidate_authorizer(con); - } /* If there are no messages in the queue, place the connection * in a STANDBY state (i.e., don't try to reconnect just yet). */ @@ -1890,6 +1882,15 @@ static void ceph_fault(struct ceph_connection *con) out_unlock: mutex_unlock(&con->mutex); out: + /* + * in case we faulted due to authentication, invalidate our + * current tickets so that we can get new ones. + */ + if (con->auth_retry && con->ops->invalidate_authorizer) { + dout("calling invalidate_authorizer()\n"); + con->ops->invalidate_authorizer(con); + } + if (con->ops->fault) con->ops->fault(con); } -- cgit v0.10.2 From e80a52d14f868059e8ec790c9fae88cdb8a1df98 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 25 Feb 2010 12:40:45 -0800 Subject: ceph: fix connection fault STANDBY check Move any out_sent messages to out_queue _before_ checking if out_queue is empty and going to STANDBY, or else we may drop something that was never acked. And clean up the code a bit (less goto). Signed-off-by: Sage Weil diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index 9ea7b76..0ddc2c7 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -1853,32 +1853,27 @@ static void ceph_fault(struct ceph_connection *con) con->in_msg = NULL; } + /* Requeue anything that hasn't been acked */ + list_splice_init(&con->out_sent, &con->out_queue); /* If there are no messages in the queue, place the connection * in a STANDBY state (i.e., don't try to reconnect just yet). */ if (list_empty(&con->out_queue) && !con->out_keepalive_pending) { dout("fault setting STANDBY\n"); set_bit(STANDBY, &con->state); - mutex_unlock(&con->mutex); - goto out; + } else { + /* retry after a delay. */ + if (con->delay == 0) + con->delay = BASE_DELAY_INTERVAL; + else if (con->delay < MAX_DELAY_INTERVAL) + con->delay *= 2; + dout("fault queueing %p delay %lu\n", con, con->delay); + con->ops->get(con); + if (queue_delayed_work(ceph_msgr_wq, &con->work, + round_jiffies_relative(con->delay)) == 0) + con->ops->put(con); } - /* Requeue anything that hasn't been acked, and retry after a - * delay. */ - list_splice_init(&con->out_sent, &con->out_queue); - - if (con->delay == 0) - con->delay = BASE_DELAY_INTERVAL; - else if (con->delay < MAX_DELAY_INTERVAL) - con->delay *= 2; - - /* explicitly schedule work to try to reconnect again later. */ - dout("fault queueing %p delay %lu\n", con, con->delay); - con->ops->get(con); - if (queue_delayed_work(ceph_msgr_wq, &con->work, - round_jiffies_relative(con->delay)) == 0) - con->ops->put(con); - out_unlock: mutex_unlock(&con->mutex); out: -- cgit v0.10.2 From c99eb1c7263a44e63161a041a778b345b5cf0b6a Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 26 Feb 2010 09:37:33 -0800 Subject: ceph: remove fragile __map_osds optimization We used to try to avoid freeing and then reallocating the osd struct. This is a bit fragile due to potential interactions with other references (beyond o_requests), and may be the cause of this crash: [120633.442358] BUG: unable to handle kernel NULL pointer dereference at (null) [120633.443292] IP: [] rb_erase+0x11d/0x277 [120633.443292] PGD f7ff3067 PUD f7f53067 PMD 0 [120633.443292] Oops: 0000 [#1] PREEMPT SMP [120633.443292] last sysfs file: /sys/kernel/uevent_seqnum [120633.443292] CPU 1 [120633.443292] Modules linked in: ceph fan ac battery psmouse ehci_hcd ide_pci_generic ohci_hcd thermal processor button [120633.443292] Pid: 3023, comm: ceph-msgr/1 Not tainted 2.6.32-rc2 #12 H8SSL [120633.443292] RIP: 0010:[] [] rb_erase+0x11d/0x277 [120633.443292] RSP: 0018:ffff8800f7b13a50 EFLAGS: 00010246 [120633.443292] RAX: ffff880022907819 RBX: ffff880022907818 RCX: 0000000000000000 [120633.443292] RDX: ffff8800f7b13a80 RSI: ffff8800f587eb48 RDI: 0000000000000000 [120633.443292] RBP: ffff8800f7b13a60 R08: 0000000000000000 R09: 0000000000000004 [120633.443292] R10: 0000000000000000 R11: ffff8800c4441000 R12: ffff8800f587eb48 [120633.443292] R13: ffff8800f58eaa00 R14: ffff8800f413c000 R15: 0000000000000001 [120633.443292] FS: 00007fbef6e226e0(0000) GS:ffff880009200000(0000) knlGS:0000000000000000 [120633.443292] CS: 0010 DS: 0018 ES: 0018 CR0: 000000008005003b [120633.443292] CR2: 0000000000000000 CR3: 00000000f7c53000 CR4: 00000000000006e0 [120633.443292] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [120633.443292] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 [120633.443292] Process ceph-msgr/1 (pid: 3023, threadinfo ffff8800f7b12000, task ffff8800f5858b40) [120633.443292] Stack: [120633.443292] ffff8800f413c000 ffff8800f587e9c0 ffff8800f7b13a80 ffffffffa0098a86 [120633.443292] <0> 00000000000006f1 0000000000000000 ffff8800f7b13af0 ffffffffa009959b [120633.443292] <0> ffff8800f413c000 ffff880022a68400 ffff880022a68400 ffff8800f587e9c0 [120633.443292] Call Trace: [120633.443292] [] __remove_osd+0x4d/0xbc [ceph] [120633.443292] [] __map_osds+0x199/0x4fa [ceph] [120633.443292] [] ? __send_request+0xf8/0x186 [ceph] [120633.443292] [] kick_requests+0x169/0x3cb [ceph] [120633.443292] [] ceph_osdc_handle_map+0x370/0x522 [ceph] Since we're probably screwed anyway if a small kmalloc is failing, don't bother with trying to be clever here. Signed-off-by: Sage Weil diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index ffd819c..3a631f2 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -615,7 +615,6 @@ static int __map_osds(struct ceph_osd_client *osdc, struct ceph_pg pgid; int o = -1; int err; - struct ceph_osd *newosd = NULL; dout("map_osds %p tid %lld\n", req, req->r_tid); err = ceph_calc_object_layout(&reqhead->layout, req->r_oid, @@ -639,25 +638,15 @@ static int __map_osds(struct ceph_osd_client *osdc, if (req->r_osd) { __cancel_request(req); list_del_init(&req->r_osd_item); - if (list_empty(&req->r_osd->o_requests)) { - /* try to re-use r_osd if possible */ - newosd = get_osd(req->r_osd); - __remove_osd(osdc, newosd); - } req->r_osd = NULL; } req->r_osd = __lookup_osd(osdc, o); if (!req->r_osd && o >= 0) { - if (newosd) { - req->r_osd = newosd; - newosd = NULL; - } else { - err = -ENOMEM; - req->r_osd = create_osd(osdc); - if (!req->r_osd) - goto out; - } + err = -ENOMEM; + req->r_osd = create_osd(osdc); + if (!req->r_osd) + goto out; dout("map_osds osd %p is osd%d\n", req->r_osd, o); req->r_osd->o_osd = o; @@ -674,8 +663,6 @@ static int __map_osds(struct ceph_osd_client *osdc, err = 1; /* osd changed */ out: - if (newosd) - put_osd(newosd); return err; } -- cgit v0.10.2 From 080af17e9c6360c5a835528e8de3141a46273ed2 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 25 Feb 2010 16:40:07 -0800 Subject: ceph: remove bogus mds forward warning The must_resend flag is always true, not false. In any case, we can just ignore it anyway. Signed-off-by: Sage Weil diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index bec8a7a..a260010 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -1899,7 +1899,6 @@ static void handle_forward(struct ceph_mds_client *mdsc, u64 tid = le64_to_cpu(msg->hdr.tid); u32 next_mds; u32 fwd_seq; - u8 must_resend; int err = -EINVAL; void *p = msg->front.iov_base; void *end = p + msg->front.iov_len; @@ -1907,14 +1906,11 @@ static void handle_forward(struct ceph_mds_client *mdsc, ceph_decode_need(&p, end, 2*sizeof(u32), bad); next_mds = ceph_decode_32(&p); fwd_seq = ceph_decode_32(&p); - must_resend = ceph_decode_8(&p); - - WARN_ON(must_resend); /* shouldn't happen. */ mutex_lock(&mdsc->mutex); req = __lookup_request(mdsc, tid); if (!req) { - dout("forward %llu dne\n", tid); + dout("forward %llu to mds%d - req dne\n", tid, next_mds); goto out; /* dup reply? */ } -- cgit v0.10.2 From 44ee63587dce85593c22497140db16f4e5027860 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 17 Feb 2010 10:50:50 +0900 Subject: percpu: Add __percpu sparse annotations to hw_breakpoint Add __percpu sparse annotations to hw_breakpoint. These annotations are to make sparse consider percpu variables to be in a different address space and warn if accessed without going through percpu accessors. This patch doesn't affect normal builds. In kernel/hw_breakpoint.c, per_cpu(nr_task_bp_pinned, cpu)'s will trigger spurious noderef related warnings from sparse. Changing it to &per_cpu(nr_task_bp_pinned[0], cpu) will work around the problem but deemed to ugly by the maintainer. Leave it alone until better solution can be found. Signed-off-by: Tejun Heo Cc: Stephen Rothwell Cc: K.Prasad LKML-Reference: <4B7B4B7A.9050902@kernel.org> Signed-off-by: Frederic Weisbecker diff --git a/include/linux/hw_breakpoint.h b/include/linux/hw_breakpoint.h index 5977b72..c70d27a 100644 --- a/include/linux/hw_breakpoint.h +++ b/include/linux/hw_breakpoint.h @@ -66,14 +66,14 @@ register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr, perf_overflow_handler_t triggered, int cpu); -extern struct perf_event ** +extern struct perf_event * __percpu * register_wide_hw_breakpoint(struct perf_event_attr *attr, perf_overflow_handler_t triggered); extern int register_perf_hw_breakpoint(struct perf_event *bp); extern int __register_perf_hw_breakpoint(struct perf_event *bp); extern void unregister_hw_breakpoint(struct perf_event *bp); -extern void unregister_wide_hw_breakpoint(struct perf_event **cpu_events); +extern void unregister_wide_hw_breakpoint(struct perf_event * __percpu *cpu_events); extern int dbg_reserve_bp_slot(struct perf_event *bp); extern int dbg_release_bp_slot(struct perf_event *bp); @@ -100,7 +100,7 @@ static inline struct perf_event * register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr, perf_overflow_handler_t triggered, int cpu) { return NULL; } -static inline struct perf_event ** +static inline struct perf_event * __percpu * register_wide_hw_breakpoint(struct perf_event_attr *attr, perf_overflow_handler_t triggered) { return NULL; } static inline int @@ -109,7 +109,7 @@ static inline int __register_perf_hw_breakpoint(struct perf_event *bp) { return -ENOSYS; } static inline void unregister_hw_breakpoint(struct perf_event *bp) { } static inline void -unregister_wide_hw_breakpoint(struct perf_event **cpu_events) { } +unregister_wide_hw_breakpoint(struct perf_event * __percpu *cpu_events) { } static inline int reserve_bp_slot(struct perf_event *bp) {return -ENOSYS; } static inline void release_bp_slot(struct perf_event *bp) { } diff --git a/kernel/hw_breakpoint.c b/kernel/hw_breakpoint.c index 967e6614..6542eac 100644 --- a/kernel/hw_breakpoint.c +++ b/kernel/hw_breakpoint.c @@ -413,17 +413,17 @@ EXPORT_SYMBOL_GPL(unregister_hw_breakpoint); * * @return a set of per_cpu pointers to perf events */ -struct perf_event ** +struct perf_event * __percpu * register_wide_hw_breakpoint(struct perf_event_attr *attr, perf_overflow_handler_t triggered) { - struct perf_event **cpu_events, **pevent, *bp; + struct perf_event * __percpu *cpu_events, **pevent, *bp; long err; int cpu; cpu_events = alloc_percpu(typeof(*cpu_events)); if (!cpu_events) - return ERR_PTR(-ENOMEM); + return (void __percpu __force *)ERR_PTR(-ENOMEM); get_online_cpus(); for_each_online_cpu(cpu) { @@ -451,7 +451,7 @@ fail: put_online_cpus(); free_percpu(cpu_events); - return ERR_PTR(err); + return (void __percpu __force *)ERR_PTR(err); } EXPORT_SYMBOL_GPL(register_wide_hw_breakpoint); @@ -459,7 +459,7 @@ EXPORT_SYMBOL_GPL(register_wide_hw_breakpoint); * unregister_wide_hw_breakpoint - unregister a wide breakpoint in the kernel * @cpu_events: the per cpu set of events to unregister */ -void unregister_wide_hw_breakpoint(struct perf_event **cpu_events) +void unregister_wide_hw_breakpoint(struct perf_event * __percpu *cpu_events) { int cpu; struct perf_event **pevent; diff --git a/samples/hw_breakpoint/data_breakpoint.c b/samples/hw_breakpoint/data_breakpoint.c index c69cbe9..bd0f337 100644 --- a/samples/hw_breakpoint/data_breakpoint.c +++ b/samples/hw_breakpoint/data_breakpoint.c @@ -34,7 +34,7 @@ #include #include -struct perf_event **sample_hbp; +struct perf_event * __percpu *sample_hbp; static char ksym_name[KSYM_NAME_LEN] = "pid_max"; module_param_string(ksym, ksym_name, KSYM_NAME_LEN, S_IRUGO); @@ -61,8 +61,8 @@ static int __init hw_break_module_init(void) attr.bp_type = HW_BREAKPOINT_W | HW_BREAKPOINT_R; sample_hbp = register_wide_hw_breakpoint(&attr, sample_hbp_handler); - if (IS_ERR(sample_hbp)) { - ret = PTR_ERR(sample_hbp); + if (IS_ERR((void __force *)sample_hbp)) { + ret = PTR_ERR((void __force *)sample_hbp); goto fail; } -- cgit v0.10.2 From 84c6f88fc8265d7a712d7d6ed8fc1a878dfc84d1 Mon Sep 17 00:00:00 2001 From: Hitoshi Mitake Date: Thu, 4 Feb 2010 16:08:15 +0900 Subject: perf lock: Fix and add misc documentally things I've forgot to add 'perf lock' line to command-list.txt, so users of perf could not find perf lock when they type 'perf'. Fixing command-list.txt requires document (tools/perf/Documentation/perf-lock.txt). But perf lock is too much "under construction" to write a stable document, so this is something like pseudo document for now. And I wrote description of perf lock at help section of CONFIG_LOCK_STAT, this will navigate users of lock trace events. Signed-off-by: Hitoshi Mitake Cc: Peter Zijlstra Cc: Paul Mackerras Cc: Arnaldo Carvalho de Melo LKML-Reference: <1265267295-8388-1-git-send-email-mitake@dcl.info.waseda.ac.jp> Signed-off-by: Frederic Weisbecker diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 25c3ed5..65f964e 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -520,6 +520,12 @@ config LOCK_STAT For more details, see Documentation/lockstat.txt + You can analyze lock events with "perf lock", subcommand of perf. + If you want to use "perf lock", you need to turn on CONFIG_EVENT_TRACING. + + CONFIG_LOCK_STAT defines "contended" and "acquired" lock events. + (CONFIG_LOCKDEP defines "acquire" and "release" events.) + config DEBUG_LOCKDEP bool "Lock dependency engine debugging" depends on DEBUG_KERNEL && LOCKDEP diff --git a/tools/perf/Documentation/perf-lock.txt b/tools/perf/Documentation/perf-lock.txt new file mode 100644 index 0000000..b317102 --- /dev/null +++ b/tools/perf/Documentation/perf-lock.txt @@ -0,0 +1,29 @@ +perf-lock(1) +============ + +NAME +---- +perf-lock - Analyze lock events + +SYNOPSIS +-------- +[verse] +'perf lock' {record|report|trace} + +DESCRIPTION +----------- +You can analyze various lock behaviours +and statistics with this 'perf lock' command. + + 'perf lock record ' records lock events + between start and end . And this command + produces the file "perf.data" which contains tracing + results of lock events. + + 'perf lock trace' shows raw lock events. + + 'perf lock report' reports statistical data. + +SEE ALSO +-------- +linkperf:perf[1] diff --git a/tools/perf/command-list.txt b/tools/perf/command-list.txt index 9afcff2..db6ee94 100644 --- a/tools/perf/command-list.txt +++ b/tools/perf/command-list.txt @@ -18,3 +18,4 @@ perf-top mainporcelain common perf-trace mainporcelain common perf-probe mainporcelain common perf-kmem mainporcelain common +perf-lock mainporcelain common -- cgit v0.10.2 From b67577dfb45580c498bfdb1bc76c00c3b2ad6310 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Wed, 3 Feb 2010 09:09:33 +0100 Subject: perf lock: Drop the buffers multiplexing dependency We need to deal with time ordered events to build a correct state machine of lock events. This is why we multiplex the lock events buffers. But the ordering is done from the kernel, on the tracing fast path, leading to high contention between cpus. Without multiplexing, the events appears in a weak order. If we have four events, each split per cpu, perf record will read the events buffers in the following order: [ CPU0 ev0, CPU0 ev1, CPU0 ev3, CPU0 ev4, CPU1 ev0, CPU1 ev0....] To handle a post processing reordering, we could just read and sort the whole in memory, but it just doesn't scale with high amounts of events: lock events can fill huge amounts in few times. Basically we need to sort in memory and find a "grace period" point when we know that a given slice of previously sorted events can be committed for post-processing, so that we can unload the memory usage step by step and keep a scalable sorting list. There is no strong rules about how to define such "grace period". What does this patch is: We define a FLUSH_PERIOD value that defines a grace period in seconds. We want to have a slice of events covering 2 * FLUSH_PERIOD in our sorted list. If FLUSH_PERIOD is big enough, it ensures every events that occured in the first half of the timeslice have all been buffered and there are none remaining and there won't be further to put inside this first timeslice. Then once we reach the 2 * FLUSH_PERIOD timeslice, we flush the first half to be gentle with the memory (the second half can still get new events in the middle, so wait another period to flush it) FLUSH_PERIOD is defined to 5 seconds. Say the first event started on time t0. We can safely assume that at the time we are processing events of t0 + 10 seconds, ther won't be anymore events to read from perf.data that occured between t0 and t0 + 5 seconds. Hence we can safely flush the first half. To point out funky bugs, we have a guardian that checks a new event timestamp is not below the last event's timestamp flushed and that displays a warning in this case. Signed-off-by: Frederic Weisbecker Cc: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: Steven Rostedt Cc: Paul Mackerras Cc: Hitoshi Mitake Cc: Li Zefan Cc: Lai Jiangshan Cc: Masami Hiramatsu Cc: Jens Axboe diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index fb9ab2a..e12c844 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -460,6 +460,150 @@ process_raw_event(void *data, int cpu, process_lock_release_event(data, event, cpu, timestamp, thread); } +struct raw_event_queue { + u64 timestamp; + int cpu; + void *data; + struct thread *thread; + struct list_head list; +}; + +static LIST_HEAD(raw_event_head); + +#define FLUSH_PERIOD (5 * NSEC_PER_SEC) + +static u64 flush_limit = ULLONG_MAX; +static u64 last_flush = 0; +struct raw_event_queue *last_inserted; + +static void flush_raw_event_queue(u64 limit) +{ + struct raw_event_queue *tmp, *iter; + + list_for_each_entry_safe(iter, tmp, &raw_event_head, list) { + if (iter->timestamp > limit) + return; + + if (iter == last_inserted) + last_inserted = NULL; + + process_raw_event(iter->data, iter->cpu, iter->timestamp, + iter->thread); + + last_flush = iter->timestamp; + list_del(&iter->list); + free(iter->data); + free(iter); + } +} + +static void __queue_raw_event_end(struct raw_event_queue *new) +{ + struct raw_event_queue *iter; + + list_for_each_entry_reverse(iter, &raw_event_head, list) { + if (iter->timestamp < new->timestamp) { + list_add(&new->list, &iter->list); + return; + } + } + + list_add(&new->list, &raw_event_head); +} + +static void __queue_raw_event_before(struct raw_event_queue *new, + struct raw_event_queue *iter) +{ + list_for_each_entry_continue_reverse(iter, &raw_event_head, list) { + if (iter->timestamp < new->timestamp) { + list_add(&new->list, &iter->list); + return; + } + } + + list_add(&new->list, &raw_event_head); +} + +static void __queue_raw_event_after(struct raw_event_queue *new, + struct raw_event_queue *iter) +{ + list_for_each_entry_continue(iter, &raw_event_head, list) { + if (iter->timestamp > new->timestamp) { + list_add_tail(&new->list, &iter->list); + return; + } + } + list_add_tail(&new->list, &raw_event_head); +} + +/* The queue is ordered by time */ +static void __queue_raw_event(struct raw_event_queue *new) +{ + if (!last_inserted) { + __queue_raw_event_end(new); + return; + } + + /* + * Most of the time the current event has a timestamp + * very close to the last event inserted, unless we just switched + * to another event buffer. Having a sorting based on a list and + * on the last inserted event that is close to the current one is + * probably more efficient than an rbtree based sorting. + */ + if (last_inserted->timestamp >= new->timestamp) + __queue_raw_event_before(new, last_inserted); + else + __queue_raw_event_after(new, last_inserted); +} + +static void queue_raw_event(void *data, int raw_size, int cpu, + u64 timestamp, struct thread *thread) +{ + struct raw_event_queue *new; + + if (flush_limit == ULLONG_MAX) + flush_limit = timestamp + FLUSH_PERIOD; + + if (timestamp < last_flush) { + printf("Warning: Timestamp below last timeslice flush\n"); + return; + } + + new = malloc(sizeof(*new)); + if (!new) + die("Not enough memory\n"); + + new->timestamp = timestamp; + new->cpu = cpu; + new->thread = thread; + + new->data = malloc(raw_size); + if (!new->data) + die("Not enough memory\n"); + + memcpy(new->data, data, raw_size); + + __queue_raw_event(new); + last_inserted = new; + + /* + * We want to have a slice of events covering 2 * FLUSH_PERIOD + * If FLUSH_PERIOD is big enough, it ensures every events that occured + * in the first half of the timeslice have all been buffered and there + * are none remaining (we need that because of the weakly ordered + * event recording we have). Then once we reach the 2 * FLUSH_PERIOD + * timeslice, we flush the first half to be gentle with the memory + * (the second half can still get new events in the middle, so wait + * another period to flush it) + */ + if (new->timestamp > flush_limit && + new->timestamp - flush_limit > FLUSH_PERIOD) { + flush_limit += FLUSH_PERIOD; + flush_raw_event_queue(flush_limit); + } +} + static int process_sample_event(event_t *event, struct perf_session *session) { struct thread *thread; @@ -480,7 +624,7 @@ static int process_sample_event(event_t *event, struct perf_session *session) if (profile_cpu != -1 && profile_cpu != (int) data.cpu) return 0; - process_raw_event(data.raw_data, data.cpu, data.time, thread); + queue_raw_event(data.raw_data, data.raw_size, data.cpu, data.time, thread); return 0; } @@ -576,6 +720,7 @@ static void __cmd_report(void) setup_pager(); select_key(); read_events(); + flush_raw_event_queue(ULLONG_MAX); sort_result(); print_result(); } @@ -608,7 +753,6 @@ static const char *record_args[] = { "record", "-a", "-R", - "-M", "-f", "-m", "1024", "-c", "1", -- cgit v0.10.2 From dd8b1cf681eab40bc5afb67bdd06b2ca341f5669 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Sat, 27 Feb 2010 17:10:39 +0100 Subject: perf: Remove pointless breakpoint union Remove pointless union in the breakpoint field of hw_perf_event. Signed-off-by: Frederic Weisbecker Cc: Peter Zijlstra Cc: Paul Mackerras diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 7b18b4f..04f06b4 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -487,9 +487,8 @@ struct hw_perf_event { struct hrtimer hrtimer; }; #ifdef CONFIG_HAVE_HW_BREAKPOINT - union { /* breakpoint */ - struct arch_hw_breakpoint info; - }; + /* breakpoint */ + struct arch_hw_breakpoint info; #endif }; atomic64_t prev_count; diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 65f964e..4dc24cc 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -520,11 +520,13 @@ config LOCK_STAT For more details, see Documentation/lockstat.txt - You can analyze lock events with "perf lock", subcommand of perf. - If you want to use "perf lock", you need to turn on CONFIG_EVENT_TRACING. + This also enables lock events required by "perf lock", + subcommand of perf. + If you want to use "perf lock", you also need to turn on + CONFIG_EVENT_TRACING. CONFIG_LOCK_STAT defines "contended" and "acquired" lock events. - (CONFIG_LOCKDEP defines "acquire" and "release" events.) + (CONFIG_LOCKDEP defines "acquire" and "release" events.) config DEBUG_LOCKDEP bool "Lock dependency engine debugging" -- cgit v0.10.2 From 3d083407a16698de86b42aee0da2ffb280b5cb7e Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Sat, 27 Feb 2010 17:24:15 +0100 Subject: x86/hw-breakpoints: Remove the name field Remove the name field from the arch_hw_breakpoint. We never deal with target symbols in the arch level, neither do we need to ever store it. It's a legacy for the previous version of the x86 breakpoint backend. Let's remove it. Signed-off-by: Frederic Weisbecker Cc: K.Prasad Cc: Linus Torvalds diff --git a/arch/x86/include/asm/hw_breakpoint.h b/arch/x86/include/asm/hw_breakpoint.h index 0675a7c..2a1bd8f 100644 --- a/arch/x86/include/asm/hw_breakpoint.h +++ b/arch/x86/include/asm/hw_breakpoint.h @@ -10,7 +10,6 @@ * (display/resolving) */ struct arch_hw_breakpoint { - char *name; /* Contains name of the symbol to set bkpt */ unsigned long address; u8 len; u8 type; diff --git a/arch/x86/kernel/hw_breakpoint.c b/arch/x86/kernel/hw_breakpoint.c index dca2802..41e08df 100644 --- a/arch/x86/kernel/hw_breakpoint.c +++ b/arch/x86/kernel/hw_breakpoint.c @@ -344,13 +344,6 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp, } /* - * For kernel-addresses, either the address or symbol name can be - * specified. - */ - if (info->name) - info->address = (unsigned long) - kallsyms_lookup_name(info->name); - /* * Check that the low-order bits of the address are appropriate * for the alignment implied by len. */ -- cgit v0.10.2 From 622ea685f1fafdf84d612440535c84341f0860b8 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Sat, 27 Feb 2010 14:53:07 -0800 Subject: rcu: Fix holdoff for accelerated GPs for last non-dynticked CPU Make the holdoff only happen when the full number of attempts have been made. Signed-off-by: Paul E. McKenney Cc: laijs@cn.fujitsu.com Cc: dipankar@in.ibm.com Cc: mathieu.desnoyers@polymtl.ca Cc: josh@joshtriplett.org Cc: dvhltc@us.ibm.com Cc: niv@us.ibm.com Cc: peterz@infradead.org Cc: rostedt@goodmis.org Cc: Valdis.Kletnieks@vt.edu Cc: dhowells@redhat.com LKML-Reference: <1267311188-16603-1-git-send-email-paulmck@linux.vnet.ibm.com> Signed-off-by: Ingo Molnar diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h index 464ad2c..79b53bd 100644 --- a/kernel/rcutree_plugin.h +++ b/kernel/rcutree_plugin.h @@ -1010,6 +1010,10 @@ int rcu_needs_cpu(int cpu) int c = 0; int thatcpu; + /* Check for being in the holdoff period. */ + if (per_cpu(rcu_dyntick_holdoff, cpu) == jiffies) + return rcu_needs_cpu_quick_check(cpu); + /* Don't bother unless we are the last non-dyntick-idle CPU. */ for_each_cpu_not(thatcpu, nohz_cpu_mask) if (thatcpu != cpu) { @@ -1041,10 +1045,8 @@ int rcu_needs_cpu(int cpu) } /* If RCU callbacks are still pending, RCU still needs this CPU. */ - if (c) { + if (c) raise_softirq(RCU_SOFTIRQ); - per_cpu(rcu_dyntick_holdoff, cpu) = jiffies; - } return c; } -- cgit v0.10.2 From 1883c79a57a5fe25309007590cccb1b2782c41b2 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Sat, 27 Feb 2010 14:53:08 -0800 Subject: rcu: Make task_subsys_state() RCU-lockdep checks handle boot-time use It is apparently legal to invoke task_subsys_state() without RCU protection during early boot time. After all, there are no concurrent tasks, so there can be no grace periods completing concurrently. But this does need an Acked-by from the cgroups folks. Located-by: Ingo Molnar Signed-off-by: Paul E. McKenney Cc: laijs@cn.fujitsu.com Cc: dipankar@in.ibm.com Cc: mathieu.desnoyers@polymtl.ca Cc: josh@joshtriplett.org Cc: dvhltc@us.ibm.com Cc: niv@us.ibm.com Cc: peterz@infradead.org Cc: rostedt@goodmis.org Cc: Valdis.Kletnieks@vt.edu Cc: dhowells@redhat.com LKML-Reference: <1267311188-16603-2-git-send-email-paulmck@linux.vnet.ibm.com> Signed-off-by: Ingo Molnar diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index c9bbcb2..a73e1ce 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -489,6 +489,7 @@ static inline struct cgroup_subsys_state *task_subsys_state( { return rcu_dereference_check(task->cgroups->subsys[subsys_id], rcu_read_lock_held() || + !rcu_scheduler_active || cgroup_lock_is_held()); } -- cgit v0.10.2 From ae1f30384baef4056438d81b305a6a5199b0d16c Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Sun, 28 Feb 2010 19:42:38 +0100 Subject: tracing: Include irqflags headers from trace clock trace_clock.c includes spinlock.h, which ends up including asm/system.h, which in turn includes linux/irqflags.h in x86. So the definition of raw_local_irq_save is luckily covered there, but this is not the case in parisc: tip/kernel/trace/trace_clock.c:86: error: implicit declaration of function 'raw_local_irq_save' tip/kernel/trace/trace_clock.c:112: error: implicit declaration of function 'raw_local_irq_restore' We need to include linux/irqflags.h directly from trace_clock.c to avoid such build error. Signed-off-by: Frederic Weisbecker Cc: Steven Rostedt Cc: Robert Richter Cc: Peter Zijlstra Signed-off-by: Ingo Molnar diff --git a/kernel/trace/trace_clock.c b/kernel/trace/trace_clock.c index 84a3a7b..6fbfb8f 100644 --- a/kernel/trace/trace_clock.c +++ b/kernel/trace/trace_clock.c @@ -13,6 +13,7 @@ * Tracer plugins will chose a default from these clocks. */ #include +#include #include #include #include -- cgit v0.10.2 From 1e259e0a9982078896f3404240096cbea01daca4 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Sun, 28 Feb 2010 20:51:15 +0100 Subject: hw-breakpoints: Remove stub unthrottle callback We support event unthrottling in breakpoint events. It means that if we have more than sysctl_perf_event_sample_rate/HZ, perf will throttle, ignoring subsequent events until the next tick. So if ptrace exceeds this max rate, it will omit events, which breaks the ptrace determinism that is supposed to report every triggered breakpoints. This is likely to happen if we set sysctl_perf_event_sample_rate to 1. This patch removes support for unthrottling in breakpoint events to break throttling and restore ptrace determinism. Signed-off-by: Frederic Weisbecker Cc: 2.6.33.x Cc: Peter Zijlstra Cc: K.Prasad Cc: Paul Mackerras diff --git a/arch/x86/kernel/hw_breakpoint.c b/arch/x86/kernel/hw_breakpoint.c index bb6006e..1e8cead 100644 --- a/arch/x86/kernel/hw_breakpoint.c +++ b/arch/x86/kernel/hw_breakpoint.c @@ -531,8 +531,3 @@ void hw_breakpoint_pmu_read(struct perf_event *bp) { /* TODO */ } - -void hw_breakpoint_pmu_unthrottle(struct perf_event *bp) -{ - /* TODO */ -} diff --git a/kernel/hw_breakpoint.c b/kernel/hw_breakpoint.c index 967e6614..4d99512 100644 --- a/kernel/hw_breakpoint.c +++ b/kernel/hw_breakpoint.c @@ -489,5 +489,4 @@ struct pmu perf_ops_bp = { .enable = arch_install_hw_breakpoint, .disable = arch_uninstall_hw_breakpoint, .read = hw_breakpoint_pmu_read, - .unthrottle = hw_breakpoint_pmu_unthrottle }; -- cgit v0.10.2 From 90a6501f94aedd7fb40f5556334843194fb598be Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Sun, 28 Feb 2010 08:32:18 -0800 Subject: sched, rcu: Fix rcu_dereference() for RCU-lockdep Make rcu_dereference() of runqueue data structures be rcu_dereference_sched(). Located-by: Ingo Molnar Signed-off-by: Paul E. McKenney Cc: laijs@cn.fujitsu.com Cc: dipankar@in.ibm.com Cc: mathieu.desnoyers@polymtl.ca Cc: josh@joshtriplett.org Cc: dvhltc@us.ibm.com Cc: niv@us.ibm.com Cc: peterz@infradead.org Cc: rostedt@goodmis.org Cc: Valdis.Kletnieks@vt.edu Cc: dhowells@redhat.com LKML-Reference: <20100228163218.GD6846@linux.vnet.ibm.com> Signed-off-by: Ingo Molnar diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 3e1fd96..5a5ea2c 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c @@ -3476,7 +3476,7 @@ static void run_rebalance_domains(struct softirq_action *h) static inline int on_null_domain(int cpu) { - return !rcu_dereference(cpu_rq(cpu)->sd); + return !rcu_dereference_sched(cpu_rq(cpu)->sd); } /* -- cgit v0.10.2 From 1d6040f17d12a65b9f7ab4cb9fd6d721206b79ec Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Thu, 25 Feb 2010 19:40:46 +0100 Subject: perf, x86: make IBS macros available in perf_event.h This patch moves code from oprofile to perf_event.h to make it also available for usage by perf. Signed-off-by: Robert Richter diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h index befd172..4933ccd 100644 --- a/arch/x86/include/asm/perf_event.h +++ b/arch/x86/include/asm/perf_event.h @@ -117,6 +117,16 @@ union cpuid10_edx { */ #define X86_PMC_IDX_FIXED_BTS (X86_PMC_IDX_FIXED + 16) +/* IbsFetchCtl bits/masks */ +#define IBS_FETCH_RAND_EN (1ULL<<57) +#define IBS_FETCH_VAL (1ULL<<49) +#define IBS_FETCH_ENABLE (1ULL<<48) +#define IBS_FETCH_CNT_MASK 0xFFFF0000ULL + +/* IbsOpCtl bits */ +#define IBS_OP_CNT_CTL (1ULL<<19) +#define IBS_OP_VAL (1ULL<<18) +#define IBS_OP_ENABLE (1ULL<<17) #ifdef CONFIG_PERF_EVENTS extern void init_hw_perf_events(void); diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c index 6a58256..c671749 100644 --- a/arch/x86/oprofile/op_model_amd.c +++ b/arch/x86/oprofile/op_model_amd.c @@ -46,17 +46,6 @@ static unsigned long reset_value[NUM_VIRT_COUNTERS]; -/* IbsFetchCtl bits/masks */ -#define IBS_FETCH_RAND_EN (1ULL<<57) -#define IBS_FETCH_VAL (1ULL<<49) -#define IBS_FETCH_ENABLE (1ULL<<48) -#define IBS_FETCH_CNT_MASK 0xFFFF0000ULL - -/* IbsOpCtl bits */ -#define IBS_OP_CNT_CTL (1ULL<<19) -#define IBS_OP_VAL (1ULL<<18) -#define IBS_OP_ENABLE (1ULL<<17) - #define IBS_FETCH_SIZE 6 #define IBS_OP_SIZE 12 -- cgit v0.10.2 From a163b1099dc7016704043c7fc572ae42519f08f7 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Thu, 25 Feb 2010 19:43:07 +0100 Subject: perf, x86: add some IBS macros to perf_event.h Signed-off-by: Robert Richter diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h index 4933ccd..c7f60e1 100644 --- a/arch/x86/include/asm/perf_event.h +++ b/arch/x86/include/asm/perf_event.h @@ -121,12 +121,14 @@ union cpuid10_edx { #define IBS_FETCH_RAND_EN (1ULL<<57) #define IBS_FETCH_VAL (1ULL<<49) #define IBS_FETCH_ENABLE (1ULL<<48) -#define IBS_FETCH_CNT_MASK 0xFFFF0000ULL +#define IBS_FETCH_CNT 0xFFFF0000ULL +#define IBS_FETCH_MAX_CNT 0x0000FFFFULL /* IbsOpCtl bits */ #define IBS_OP_CNT_CTL (1ULL<<19) #define IBS_OP_VAL (1ULL<<18) #define IBS_OP_ENABLE (1ULL<<17) +#define IBS_OP_MAX_CNT 0x0000FFFFULL #ifdef CONFIG_PERF_EVENTS extern void init_hw_perf_events(void); diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c index c671749..8ddb9fa 100644 --- a/arch/x86/oprofile/op_model_amd.c +++ b/arch/x86/oprofile/op_model_amd.c @@ -279,7 +279,7 @@ op_amd_handle_ibs(struct pt_regs * const regs, oprofile_write_commit(&entry); /* reenable the IRQ */ - ctl &= ~(IBS_FETCH_VAL | IBS_FETCH_CNT_MASK); + ctl &= ~(IBS_FETCH_VAL | IBS_FETCH_CNT); ctl |= IBS_FETCH_ENABLE; wrmsrl(MSR_AMD64_IBSFETCHCTL, ctl); } @@ -319,7 +319,7 @@ static inline void op_amd_start_ibs(void) return; if (ibs_config.fetch_enabled) { - val = (ibs_config.max_cnt_fetch >> 4) & 0xFFFF; + val = (ibs_config.max_cnt_fetch >> 4) & IBS_FETCH_MAX_CNT; val |= ibs_config.rand_en ? IBS_FETCH_RAND_EN : 0; val |= IBS_FETCH_ENABLE; wrmsrl(MSR_AMD64_IBSFETCHCTL, val); @@ -341,7 +341,7 @@ static inline void op_amd_start_ibs(void) * avoid underflows. */ ibs_op_ctl = min(ibs_op_ctl + IBS_RANDOM_MAXCNT_OFFSET, - 0xFFFFULL); + IBS_OP_MAX_CNT); } if (ibs_caps & IBS_CAPS_OPCNT && ibs_config.dispatched_ops) ibs_op_ctl |= IBS_OP_CNT_CTL; -- cgit v0.10.2 From 339d3261aa3eb0e12f68ef868e042c1ca03628f7 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 6 Feb 2010 09:42:39 +0100 Subject: x86/amd-iommu: Remove double NULL check in check_device dev was tested just above, so drop the second test. Signed-off-by: Julia Lawall Signed-off-by: Joerg Roedel diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index adb0ba0..2c4a501 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c @@ -118,7 +118,7 @@ static bool check_device(struct device *dev) return false; /* No device or no PCI device */ - if (!dev || dev->bus != &pci_bus_type) + if (dev->bus != &pci_bus_type) return false; devid = get_device_id(dev); -- cgit v0.10.2 From 5d214fe6e808a8caa9cb6f610c0190d3f50ac570 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Mon, 8 Feb 2010 14:44:49 +0100 Subject: x86/amd-iommu: Protect IOMMU-API map/unmap path This patch introduces a mutex to lock page table updates in the IOMMU-API path. We can't use the spin_lock here because this patch might sleep. Signed-off-by: Joerg Roedel diff --git a/arch/x86/include/asm/amd_iommu_types.h b/arch/x86/include/asm/amd_iommu_types.h index ba19ad4..5e46e78 100644 --- a/arch/x86/include/asm/amd_iommu_types.h +++ b/arch/x86/include/asm/amd_iommu_types.h @@ -21,6 +21,7 @@ #define _ASM_X86_AMD_IOMMU_TYPES_H #include +#include #include #include @@ -237,6 +238,7 @@ struct protection_domain { struct list_head list; /* for list of all protection domains */ struct list_head dev_list; /* List of all devices in this domain */ spinlock_t lock; /* mostly used to lock the page table*/ + struct mutex api_lock; /* protect page tables in the iommu-api path */ u16 id; /* the domain id written to the device table */ int mode; /* paging mode (0-6 levels) */ u64 *pt_root; /* page table root pointer */ diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index 2c4a501..b97f2f1 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c @@ -2327,6 +2327,7 @@ static struct protection_domain *protection_domain_alloc(void) return NULL; spin_lock_init(&domain->lock); + mutex_init(&domain->api_lock); domain->id = domain_id_alloc(); if (!domain->id) goto out_err; @@ -2456,6 +2457,8 @@ static int amd_iommu_map_range(struct iommu_domain *dom, iova &= PAGE_MASK; paddr &= PAGE_MASK; + mutex_lock(&domain->api_lock); + for (i = 0; i < npages; ++i) { ret = iommu_map_page(domain, iova, paddr, prot, PM_MAP_4k); if (ret) @@ -2465,6 +2468,8 @@ static int amd_iommu_map_range(struct iommu_domain *dom, paddr += PAGE_SIZE; } + mutex_unlock(&domain->api_lock); + return 0; } @@ -2477,12 +2482,16 @@ static void amd_iommu_unmap_range(struct iommu_domain *dom, iova &= PAGE_MASK; + mutex_lock(&domain->api_lock); + for (i = 0; i < npages; ++i) { iommu_unmap_page(domain, iova, PM_MAP_4k); iova += PAGE_SIZE; } iommu_flush_tlb_pde(domain); + + mutex_unlock(&domain->api_lock); } static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom, -- cgit v0.10.2 From 04e856c072b84042bb56c487c2868638bb3f78db Mon Sep 17 00:00:00 2001 From: Chris Wright Date: Wed, 17 Feb 2010 08:51:20 -0800 Subject: x86/amd-iommu: Pt mode fix for domain_destroy After a guest is shutdown, assigned devices are not properly returned to the pt domain. This can leave the device using stale cached IOMMU data, and result in a non-functional device after it's re-bound to the host driver. For example, I see this upon rebinding: AMD-Vi: Event logged [IO_PAGE_FAULT device=02:00.0 domain=0x0000 address=0x000000007e2a8000 flags=0x0050] AMD-Vi: Event logged [IO_PAGE_FAULT device=02:00.0 domain=0x0000 address=0x000000007e2a8040 flags=0x0050] AMD-Vi: Event logged [IO_PAGE_FAULT device=02:00.0 domain=0x0000 address=0x000000007e2a8080 flags=0x0050] AMD-Vi: Event logged [IO_PAGE_FAULT device=02:00.0 domain=0x0000 address=0x000000007e2a80c0 flags=0x0050] 0000:02:00.0: eth2: Detected Hardware Unit Hang: ... The amd_iommu_destroy_domain() function calls do_detach() which doesn't reattach the pt domain to the device. Use __detach_device() instead. Cc: stable@kernel.org Signed-off-by: Chris Wright Signed-off-by: Joerg Roedel diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index b97f2f1..0c04254 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c @@ -2298,7 +2298,7 @@ static void cleanup_domain(struct protection_domain *domain) list_for_each_entry_safe(dev_data, next, &domain->dev_list, list) { struct device *dev = dev_data->dev; - do_detach(dev); + __detach_device(dev); atomic_set(&dev_data->bind, 0); } -- cgit v0.10.2 From 3551a708f35fc712af43aeb7f541512c5cfc4936 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Mon, 1 Mar 2010 13:52:19 +0100 Subject: x86/amd-iommu: Report errors in acpi parsing functions upstream Since acpi_table_parse ignores the return values of the parsing function this patch introduces a workaround and reports these errors upstream via a global variable. Signed-off-by: Joerg Roedel diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c index 9dc91b4..feaf471 100644 --- a/arch/x86/kernel/amd_iommu_init.c +++ b/arch/x86/kernel/amd_iommu_init.c @@ -138,9 +138,9 @@ int amd_iommus_present; bool amd_iommu_np_cache __read_mostly; /* - * Set to true if ACPI table parsing and hardware intialization went properly + * The ACPI table parsing functions set this variable on an error */ -static bool amd_iommu_initialized; +static int __initdata amd_iommu_init_err; /* * List of protection domains - used during resume @@ -391,9 +391,11 @@ static int __init find_last_devid_acpi(struct acpi_table_header *table) */ for (i = 0; i < table->length; ++i) checksum += p[i]; - if (checksum != 0) + if (checksum != 0) { /* ACPI table corrupt */ - return -ENODEV; + amd_iommu_init_err = -ENODEV; + return 0; + } p += IVRS_HEADER_LENGTH; @@ -920,11 +922,16 @@ static int __init init_iommu_all(struct acpi_table_header *table) h->mmio_phys); iommu = kzalloc(sizeof(struct amd_iommu), GFP_KERNEL); - if (iommu == NULL) - return -ENOMEM; + if (iommu == NULL) { + amd_iommu_init_err = -ENOMEM; + return 0; + } + ret = init_iommu_one(iommu, h); - if (ret) - return ret; + if (ret) { + amd_iommu_init_err = ret; + return 0; + } break; default: break; @@ -934,8 +941,6 @@ static int __init init_iommu_all(struct acpi_table_header *table) } WARN_ON(p != end); - amd_iommu_initialized = true; - return 0; } @@ -1211,6 +1216,10 @@ static int __init amd_iommu_init(void) if (acpi_table_parse("IVRS", find_last_devid_acpi) != 0) return -ENODEV; + ret = amd_iommu_init_err; + if (ret) + goto out; + dev_table_size = tbl_size(DEV_TABLE_ENTRY_SIZE); alias_table_size = tbl_size(ALIAS_TABLE_ENTRY_SIZE); rlookup_table_size = tbl_size(RLOOKUP_TABLE_ENTRY_SIZE); @@ -1270,12 +1279,19 @@ static int __init amd_iommu_init(void) if (acpi_table_parse("IVRS", init_iommu_all) != 0) goto free; - if (!amd_iommu_initialized) + if (amd_iommu_init_err) { + ret = amd_iommu_init_err; goto free; + } if (acpi_table_parse("IVRS", init_memory_definitions) != 0) goto free; + if (amd_iommu_init_err) { + ret = amd_iommu_init_err; + goto free; + } + ret = sysdev_class_register(&amd_iommu_sysdev_class); if (ret) goto free; -- cgit v0.10.2 From bb1165d6882f423f90fc7007a88c6c993b7c2ac4 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Mon, 1 Mar 2010 14:21:23 +0100 Subject: perf, x86: rename macro in ARCH_PERFMON_EVENTSEL_ENABLE For consistency reasons this patch renames ARCH_PERFMON_EVENTSEL0_ENABLE to ARCH_PERFMON_EVENTSEL_ENABLE. The following is performed: $ sed -i -e s/ARCH_PERFMON_EVENTSEL0_ENABLE/ARCH_PERFMON_EVENTSEL_ENABLE/g \ arch/x86/include/asm/perf_event.h arch/x86/kernel/cpu/perf_event.c \ arch/x86/kernel/cpu/perf_event_p6.c \ arch/x86/kernel/cpu/perfctr-watchdog.c \ arch/x86/oprofile/op_model_amd.c arch/x86/oprofile/op_model_ppro.c Signed-off-by: Robert Richter diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h index c7f60e1..80e6936 100644 --- a/arch/x86/include/asm/perf_event.h +++ b/arch/x86/include/asm/perf_event.h @@ -18,7 +18,7 @@ #define MSR_ARCH_PERFMON_EVENTSEL0 0x186 #define MSR_ARCH_PERFMON_EVENTSEL1 0x187 -#define ARCH_PERFMON_EVENTSEL0_ENABLE (1 << 22) +#define ARCH_PERFMON_EVENTSEL_ENABLE (1 << 22) #define ARCH_PERFMON_EVENTSEL_ANY (1 << 21) #define ARCH_PERFMON_EVENTSEL_INT (1 << 20) #define ARCH_PERFMON_EVENTSEL_OS (1 << 17) diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 641ccb9..6531b4b 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -553,9 +553,9 @@ static void x86_pmu_disable_all(void) if (!test_bit(idx, cpuc->active_mask)) continue; rdmsrl(x86_pmu.eventsel + idx, val); - if (!(val & ARCH_PERFMON_EVENTSEL0_ENABLE)) + if (!(val & ARCH_PERFMON_EVENTSEL_ENABLE)) continue; - val &= ~ARCH_PERFMON_EVENTSEL0_ENABLE; + val &= ~ARCH_PERFMON_EVENTSEL_ENABLE; wrmsrl(x86_pmu.eventsel + idx, val); } } @@ -590,7 +590,7 @@ static void x86_pmu_enable_all(void) continue; val = event->hw.config; - val |= ARCH_PERFMON_EVENTSEL0_ENABLE; + val |= ARCH_PERFMON_EVENTSEL_ENABLE; wrmsrl(x86_pmu.eventsel + idx, val); } } @@ -853,7 +853,7 @@ void hw_perf_enable(void) static inline void __x86_pmu_enable_event(struct hw_perf_event *hwc, int idx) { (void)checking_wrmsrl(hwc->config_base + idx, - hwc->config | ARCH_PERFMON_EVENTSEL0_ENABLE); + hwc->config | ARCH_PERFMON_EVENTSEL_ENABLE); } static inline void x86_pmu_disable_event(struct hw_perf_event *hwc, int idx) diff --git a/arch/x86/kernel/cpu/perf_event_p6.c b/arch/x86/kernel/cpu/perf_event_p6.c index 1ca5ba0..a4e67b9 100644 --- a/arch/x86/kernel/cpu/perf_event_p6.c +++ b/arch/x86/kernel/cpu/perf_event_p6.c @@ -62,7 +62,7 @@ static void p6_pmu_disable_all(void) /* p6 only has one enable register */ rdmsrl(MSR_P6_EVNTSEL0, val); - val &= ~ARCH_PERFMON_EVENTSEL0_ENABLE; + val &= ~ARCH_PERFMON_EVENTSEL_ENABLE; wrmsrl(MSR_P6_EVNTSEL0, val); } @@ -72,7 +72,7 @@ static void p6_pmu_enable_all(void) /* p6 only has one enable register */ rdmsrl(MSR_P6_EVNTSEL0, val); - val |= ARCH_PERFMON_EVENTSEL0_ENABLE; + val |= ARCH_PERFMON_EVENTSEL_ENABLE; wrmsrl(MSR_P6_EVNTSEL0, val); } @@ -83,7 +83,7 @@ p6_pmu_disable_event(struct hw_perf_event *hwc, int idx) u64 val = P6_NOP_EVENT; if (cpuc->enabled) - val |= ARCH_PERFMON_EVENTSEL0_ENABLE; + val |= ARCH_PERFMON_EVENTSEL_ENABLE; (void)checking_wrmsrl(hwc->config_base + idx, val); } @@ -95,7 +95,7 @@ static void p6_pmu_enable_event(struct hw_perf_event *hwc, int idx) val = hwc->config; if (cpuc->enabled) - val |= ARCH_PERFMON_EVENTSEL0_ENABLE; + val |= ARCH_PERFMON_EVENTSEL_ENABLE; (void)checking_wrmsrl(hwc->config_base + idx, val); } diff --git a/arch/x86/kernel/cpu/perfctr-watchdog.c b/arch/x86/kernel/cpu/perfctr-watchdog.c index 74f4e85..fb329e9 100644 --- a/arch/x86/kernel/cpu/perfctr-watchdog.c +++ b/arch/x86/kernel/cpu/perfctr-watchdog.c @@ -680,7 +680,7 @@ static int setup_intel_arch_watchdog(unsigned nmi_hz) cpu_nmi_set_wd_enabled(); apic_write(APIC_LVTPC, APIC_DM_NMI); - evntsel |= ARCH_PERFMON_EVENTSEL0_ENABLE; + evntsel |= ARCH_PERFMON_EVENTSEL_ENABLE; wrmsr(evntsel_msr, evntsel, 0); intel_arch_wd_ops.checkbit = 1ULL << (eax.split.bit_width - 1); return 1; diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c index 8ddb9fa..090cbbe 100644 --- a/arch/x86/oprofile/op_model_amd.c +++ b/arch/x86/oprofile/op_model_amd.c @@ -171,7 +171,7 @@ static void op_amd_setup_ctrs(struct op_x86_model_spec const *model, continue; } rdmsrl(msrs->controls[i].addr, val); - if (val & ARCH_PERFMON_EVENTSEL0_ENABLE) + if (val & ARCH_PERFMON_EVENTSEL_ENABLE) op_x86_warn_in_use(i); val &= model->reserved; wrmsrl(msrs->controls[i].addr, val); @@ -398,7 +398,7 @@ static void op_amd_start(struct op_msrs const * const msrs) if (!reset_value[op_x86_phys_to_virt(i)]) continue; rdmsrl(msrs->controls[i].addr, val); - val |= ARCH_PERFMON_EVENTSEL0_ENABLE; + val |= ARCH_PERFMON_EVENTSEL_ENABLE; wrmsrl(msrs->controls[i].addr, val); } @@ -418,7 +418,7 @@ static void op_amd_stop(struct op_msrs const * const msrs) if (!reset_value[op_x86_phys_to_virt(i)]) continue; rdmsrl(msrs->controls[i].addr, val); - val &= ~ARCH_PERFMON_EVENTSEL0_ENABLE; + val &= ~ARCH_PERFMON_EVENTSEL_ENABLE; wrmsrl(msrs->controls[i].addr, val); } diff --git a/arch/x86/oprofile/op_model_ppro.c b/arch/x86/oprofile/op_model_ppro.c index 5d1727b..2bf90fa 100644 --- a/arch/x86/oprofile/op_model_ppro.c +++ b/arch/x86/oprofile/op_model_ppro.c @@ -88,7 +88,7 @@ static void ppro_setup_ctrs(struct op_x86_model_spec const *model, continue; } rdmsrl(msrs->controls[i].addr, val); - if (val & ARCH_PERFMON_EVENTSEL0_ENABLE) + if (val & ARCH_PERFMON_EVENTSEL_ENABLE) op_x86_warn_in_use(i); val &= model->reserved; wrmsrl(msrs->controls[i].addr, val); @@ -166,7 +166,7 @@ static void ppro_start(struct op_msrs const * const msrs) for (i = 0; i < num_counters; ++i) { if (reset_value[i]) { rdmsrl(msrs->controls[i].addr, val); - val |= ARCH_PERFMON_EVENTSEL0_ENABLE; + val |= ARCH_PERFMON_EVENTSEL_ENABLE; wrmsrl(msrs->controls[i].addr, val); } } @@ -184,7 +184,7 @@ static void ppro_stop(struct op_msrs const * const msrs) if (!reset_value[i]) continue; rdmsrl(msrs->controls[i].addr, val); - val &= ~ARCH_PERFMON_EVENTSEL0_ENABLE; + val &= ~ARCH_PERFMON_EVENTSEL_ENABLE; wrmsrl(msrs->controls[i].addr, val); } } -- cgit v0.10.2 From 1679f876a641d209e7b22e43ebda0693c71003cf Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 26 Feb 2010 13:55:51 -0800 Subject: ceph: reset bits on connection close Clear LOSSYTX bit, so that if/when we reconnect, said reconnect will retry on failure. Clear _PENDING bits too, to avoid polluting subsequent connection state. Drop unused REGISTERED bit. Signed-off-by: Sage Weil diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index 0ddc2c7..bf4590c 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -342,6 +342,9 @@ void ceph_con_close(struct ceph_connection *con) dout("con_close %p peer %s\n", con, pr_addr(&con->peer_addr.in_addr)); set_bit(CLOSED, &con->state); /* in case there's queued work */ clear_bit(STANDBY, &con->state); /* avoid connect_seq bump */ + clear_bit(LOSSYTX, &con->state); /* so we retry next connect */ + clear_bit(KEEPALIVE_PENDING, &con->state); + clear_bit(WRITE_PENDING, &con->state); mutex_lock(&con->mutex); reset_connection(con); cancel_delayed_work(&con->work); diff --git a/fs/ceph/messenger.h b/fs/ceph/messenger.h index c973537..4caaa59 100644 --- a/fs/ceph/messenger.h +++ b/fs/ceph/messenger.h @@ -119,7 +119,6 @@ struct ceph_msg_pos { * state with the peer. */ #define CLOSED 10 /* we've closed the connection */ #define SOCK_CLOSED 11 /* socket state changed to closed */ -#define REGISTERED 12 /* connection appears in con_tree */ #define OPENING 13 /* open connection w/ (possibly new) peer */ #define DEAD 14 /* dead, about to kfree */ -- cgit v0.10.2 From c16e786927b977cb880873214bbd815e8d5ec4ba Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 1 Mar 2010 13:02:00 -0800 Subject: ceph: use single osd op reply msg Use a single ceph_msg for the osd reply, even when we are getting multiple replies. Signed-off-by: Sage Weil diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index 3a631f2..ffe1f40 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -13,7 +13,8 @@ #include "decode.h" #include "auth.h" -#define OSD_REPLY_RESERVE_FRONT_LEN 512 +#define OSD_OP_FRONT_LEN 4096 +#define OSD_OPREPLY_FRONT_LEN 512 const static struct ceph_connection_operations osd_con_ops; @@ -75,17 +76,6 @@ static void calc_layout(struct ceph_osd_client *osdc, req->r_oid, req->r_oid_len, objoff, objlen, req->r_num_pages); } -static void remove_replies(struct ceph_osd_request *req) -{ - int i; - int max = ARRAY_SIZE(req->replies); - - for (i=0; ireplies[i]) - ceph_msg_put(req->replies[i]); - } -} - /* * requests */ @@ -99,7 +89,6 @@ void ceph_osdc_release_request(struct kref *kref) ceph_msg_put(req->r_request); if (req->r_reply) ceph_msg_put(req->r_reply); - remove_replies(req); if (req->r_con_filling_msg) { dout("release_request revoking pages %p from con %p\n", req->r_pages, req->r_con_filling_msg); @@ -117,60 +106,6 @@ void ceph_osdc_release_request(struct kref *kref) kfree(req); } -static int alloc_replies(struct ceph_osd_request *req, int num_reply) -{ - int i; - int max = ARRAY_SIZE(req->replies); - - BUG_ON(num_reply > max); - - for (i=0; ireplies[i] = ceph_msg_new(0, OSD_REPLY_RESERVE_FRONT_LEN, 0, 0, NULL); - if (IS_ERR(req->replies[i])) { - int j; - int err = PTR_ERR(req->replies[i]); - for (j = 0; j<=i; j++) { - ceph_msg_put(req->replies[j]); - } - return err; - } - } - - for (; ireplies[i] = NULL; - } - - req->cur_reply = 0; - - return 0; -} - -static struct ceph_msg *__get_next_reply(struct ceph_connection *con, - struct ceph_osd_request *req, - int front_len) -{ - struct ceph_msg *reply; - if (req->r_con_filling_msg) { - dout("revoking reply msg %p from old con %p\n", req->r_reply, - req->r_con_filling_msg); - ceph_con_revoke_message(req->r_con_filling_msg, req->r_reply); - ceph_con_put(req->r_con_filling_msg); - req->cur_reply = 0; - } - reply = req->replies[req->cur_reply]; - if (!reply || front_len > OSD_REPLY_RESERVE_FRONT_LEN) { - /* maybe we can allocate it now? */ - reply = ceph_msg_new(0, front_len, 0, 0, NULL); - if (!reply || IS_ERR(reply)) { - pr_err(" reply alloc failed, front_len=%d\n", front_len); - return ERR_PTR(-ENOMEM); - } - } - req->r_con_filling_msg = ceph_con_get(con); - req->r_reply = ceph_msg_get(reply); /* for duration of read over socket */ - return ceph_msg_get(reply); -} - /* * build new request AND message, calculate layout, and adjust file * extent as needed. @@ -201,7 +136,7 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc, void *p; int num_op = 1 + do_sync; size_t msg_size = sizeof(*head) + num_op*sizeof(*op); - int err, i; + int i; if (use_mempool) { req = mempool_alloc(osdc->req_mempool, GFP_NOFS); @@ -212,13 +147,6 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc, if (req == NULL) return ERR_PTR(-ENOMEM); - err = alloc_replies(req, num_reply); - if (err) { - ceph_osdc_put_request(req); - return ERR_PTR(-ENOMEM); - } - req->r_num_prealloc_reply = num_reply; - req->r_osdc = osdc; req->r_mempool = use_mempool; kref_init(&req->r_kref); @@ -229,7 +157,19 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc, WARN_ON((flags & (CEPH_OSD_FLAG_READ|CEPH_OSD_FLAG_WRITE)) == 0); - /* create message; allow space for oid */ + /* create reply message */ + if (use_mempool) + msg = ceph_msgpool_get(&osdc->msgpool_op_reply, 0); + else + msg = ceph_msg_new(CEPH_MSG_OSD_OPREPLY, + OSD_OPREPLY_FRONT_LEN, 0, 0, NULL); + if (IS_ERR(msg)) { + ceph_osdc_put_request(req); + return ERR_PTR(PTR_ERR(msg)); + } + req->r_reply = msg; + + /* create request message; allow space for oid */ msg_size += 40; if (snapc) msg_size += sizeof(u64) * snapc->num_snaps; @@ -819,21 +759,11 @@ static void handle_reply(struct ceph_osd_client *osdc, struct ceph_msg *msg, * avoid a (safe but slower) revoke later. */ if (req->r_con_filling_msg == con && req->r_reply == msg) { - dout(" got pages, dropping con_filling_msg ref %p\n", con); + dout(" dropping con_filling_msg ref %p\n", con); req->r_con_filling_msg = NULL; ceph_con_put(con); } - if (req->r_reply) { - /* - * once we see the message has been received, we don't - * need a ref (which is only needed for revoking - * pages) - */ - ceph_msg_put(req->r_reply); - req->r_reply = NULL; - } - if (!req->r_got_reply) { unsigned bytes; @@ -1249,11 +1179,17 @@ int ceph_osdc_init(struct ceph_osd_client *osdc, struct ceph_client *client) if (!osdc->req_mempool) goto out; - err = ceph_msgpool_init(&osdc->msgpool_op, 4096, 10, true); + err = ceph_msgpool_init(&osdc->msgpool_op, OSD_OP_FRONT_LEN, 10, true); if (err < 0) goto out_mempool; + err = ceph_msgpool_init(&osdc->msgpool_op_reply, + OSD_OPREPLY_FRONT_LEN, 10, true); + if (err < 0) + goto out_msgpool; return 0; +out_msgpool: + ceph_msgpool_destroy(&osdc->msgpool_op); out_mempool: mempool_destroy(osdc->req_mempool); out: @@ -1271,6 +1207,7 @@ void ceph_osdc_stop(struct ceph_osd_client *osdc) remove_old_osds(osdc, 1); mempool_destroy(osdc->req_mempool); ceph_msgpool_destroy(&osdc->msgpool_op); + ceph_msgpool_destroy(&osdc->msgpool_op_reply); } /* @@ -1405,16 +1342,29 @@ static struct ceph_msg *get_reply(struct ceph_connection *con, if (!req) { *skip = 1; m = NULL; - pr_info("alloc_msg unknown tid %llu from osd%d\n", tid, + pr_info("get_reply unknown tid %llu from osd%d\n", tid, osd->o_osd); goto out; } - m = __get_next_reply(con, req, front); - if (!m || IS_ERR(m)) { - *skip = 1; - goto out; + + if (req->r_con_filling_msg) { + dout("get_reply revoking msg %p from old con %p\n", + req->r_reply, req->r_con_filling_msg); + ceph_con_revoke_message(req->r_con_filling_msg, req->r_reply); + ceph_con_put(req->r_con_filling_msg); } + if (front > req->r_reply->front.iov_len) { + pr_warning("get_reply front %d > preallocated %d\n", + front, (int)req->r_reply->front.iov_len); + m = ceph_msg_new(CEPH_MSG_OSD_OPREPLY, front, 0, 0, NULL); + if (IS_ERR(m)) + goto out; + ceph_msg_put(req->r_reply); + req->r_reply = m; + } + m = ceph_msg_get(req->r_reply); + if (data_len > 0) { err = __prepare_pages(con, hdr, req, tid, m); if (err < 0) { @@ -1424,6 +1374,8 @@ static struct ceph_msg *get_reply(struct ceph_connection *con, } } *skip = 0; + req->r_con_filling_msg = ceph_con_get(con); + dout("get_reply tid %lld %p\n", tid, m); out: mutex_unlock(&osdc->request_mutex); diff --git a/fs/ceph/osd_client.h b/fs/ceph/osd_client.h index 70f31b6..f256eba 100644 --- a/fs/ceph/osd_client.h +++ b/fs/ceph/osd_client.h @@ -53,7 +53,6 @@ struct ceph_osd_request { int r_flags; /* any additional flags for the osd */ u32 r_sent; /* >0 if r_request is sending/sent */ int r_got_reply; - int r_num_prealloc_reply; struct ceph_osd_client *r_osdc; struct kref r_kref; @@ -77,9 +76,6 @@ struct ceph_osd_request { struct page **r_pages; /* pages for data payload */ int r_pages_from_pool; int r_own_pages; /* if true, i own page list */ - - struct ceph_msg *replies[2]; - int cur_reply; }; struct ceph_osd_client { @@ -106,6 +102,7 @@ struct ceph_osd_client { mempool_t *req_mempool; struct ceph_msgpool msgpool_op; + struct ceph_msgpool msgpool_op_reply; }; extern int ceph_osdc_init(struct ceph_osd_client *osdc, -- cgit v0.10.2 From 70edb55bdfa8922c8ad40bc5a67abb6d9fee8d47 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 1 Mar 2010 13:20:50 -0800 Subject: ceph: fix snaptrace decoding on cap migration between mds This was simply broken. Apparently at some point we thought about putting the snaptrace in the middle section, but didn't. Signed-off-by: Sage Weil diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index bb84616..9afa8d3 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -2608,6 +2608,7 @@ void ceph_handle_caps(struct ceph_mds_session *session, u64 size, max_size; u64 tid; int check_caps = 0; + void *snaptrace; int r; dout("handle_caps from mds%d\n", mds); @@ -2617,6 +2618,7 @@ void ceph_handle_caps(struct ceph_mds_session *session, if (msg->front.iov_len < sizeof(*h)) goto bad; h = msg->front.iov_base; + snaptrace = h + 1; op = le32_to_cpu(h->op); vino.ino = le64_to_cpu(h->ino); vino.snap = CEPH_NOSNAP; @@ -2651,8 +2653,7 @@ void ceph_handle_caps(struct ceph_mds_session *session, case CEPH_CAP_OP_IMPORT: handle_cap_import(mdsc, inode, h, session, - msg->middle, - le32_to_cpu(h->snap_trace_len)); + snaptrace, le32_to_cpu(h->snap_trace_len)); check_caps = 1; /* we may have sent a RELEASE to the old auth */ goto done; } -- cgit v0.10.2 From 3ca02ef96e119d36bc1752baeae7dd0c59c2f325 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 1 Mar 2010 15:25:00 -0800 Subject: ceph: reset front len on return to msgpool; BUG on mismatched front iov Reset msg front len when a message is returned to the pool: the caller may have changed it. BUG if we try to send a message with a hdr.front_len that doesn't match the front iov. Signed-off-by: Sage Weil diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index bf4590c..781656a 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -1954,6 +1954,8 @@ void ceph_con_send(struct ceph_connection *con, struct ceph_msg *msg) msg->hdr.src.addr = con->msgr->my_enc_addr; msg->hdr.orig_src = msg->hdr.src; + BUG_ON(msg->front.iov_len != le32_to_cpu(msg->hdr.front_len)); + /* queue */ mutex_lock(&con->mutex); BUG_ON(!list_empty(&msg->list_head)); diff --git a/fs/ceph/msgpool.c b/fs/ceph/msgpool.c index 2f04e0f..ca3b44a 100644 --- a/fs/ceph/msgpool.c +++ b/fs/ceph/msgpool.c @@ -166,6 +166,10 @@ void ceph_msgpool_put(struct ceph_msgpool *pool, struct ceph_msg *msg) { spin_lock(&pool->lock); if (pool->num < pool->min) { + /* reset msg front_len; user may have changed it */ + msg->front.iov_len = pool->front_len; + msg->hdr.front_len = cpu_to_le32(pool->front_len); + kref_set(&msg->kref, 1); /* retake a single ref */ list_add(&msg->list_head, &pool->msgs); pool->num++; -- cgit v0.10.2 From 6f863e712d4114e8ae2f02de64ebeac0546ebaa0 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 1 Mar 2010 15:26:41 -0800 Subject: ceph: set osd request message front length correctly We didn't set the front length correctly. When messages used the message pool we ended up with the conservative max (4 KB), and the rest of the time the slightly less conservative estimate. Even though the OSD ignores the extra data, set it to the right value to avoid sending extra data over the network. Signed-off-by: Yehuda Sadeh Signed-off-by: Sage Weil diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index ffe1f40..c4763bf 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -228,6 +228,9 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc, } BUG_ON(p > msg->front.iov_base + msg->front.iov_len); + msg_size = p - msg->front.iov_base; + msg->front.iov_len = msg_size; + msg->hdr.front_len = cpu_to_le32(msg_size); return req; } -- cgit v0.10.2 From 195d3ce2cc9a8ec69827f6369c41b269345b9988 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 1 Mar 2010 09:57:54 -0800 Subject: ceph: return EBADF if waiting for caps on closed file Verify the file is actually open for the given caps when we are waiting for caps. This ensures we will wake up and return EBADF if another thread closes the file out from under us. Note that EBADF is also the correct return code from write(2) when called on a file handle opened for reading (although the vfs should catch that). Signed-off-by: Sage Weil diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 9afa8d3..06f1979 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -1923,14 +1923,17 @@ static int try_get_cap_refs(struct ceph_inode_info *ci, int need, int want, struct inode *inode = &ci->vfs_inode; int ret = 0; int have, implemented; + int file_wanted; dout("get_cap_refs %p need %s want %s\n", inode, ceph_cap_string(need), ceph_cap_string(want)); spin_lock(&inode->i_lock); - /* make sure we _have_ some caps! */ - if (!__ceph_is_any_caps(ci)) { - dout("get_cap_refs %p no real caps\n", inode); + /* make sure file is actually open */ + file_wanted = __ceph_caps_file_wanted(ci); + if ((file_wanted & need) == 0) { + dout("try_get_cap_refs need %s file_wanted %s, EBADF\n", + ceph_cap_string(need), ceph_cap_string(file_wanted)); *err = -EBADF; ret = 1; goto out; diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 88932c9..5d2af84 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -262,6 +262,9 @@ int ceph_release(struct inode *inode, struct file *file) kfree(cf->dir_info); dput(cf->dentry); kmem_cache_free(ceph_file_cachep, cf); + + /* wake up anyone waiting for caps on this inode */ + wake_up(&ci->i_cap_wq); return 0; } -- cgit v0.10.2 From e53a8fd773065628b24605b289a9a40ee4a35d83 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 1 Mar 2010 14:50:05 -0800 Subject: ceph: fix osdmap decoding when pools include (removed) snaps Add missing pointer dereference (p is a void **). Signed-off-by: Sage Weil diff --git a/fs/ceph/osdmap.c b/fs/ceph/osdmap.c index 34b5696..b83f269 100644 --- a/fs/ceph/osdmap.c +++ b/fs/ceph/osdmap.c @@ -529,8 +529,8 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end) ceph_decode_copy(p, &pi->v, sizeof(pi->v)); __insert_pg_pool(&map->pg_pools, pi); calc_pg_masks(pi); - p += le32_to_cpu(pi->v.num_snaps) * sizeof(u64); - p += le32_to_cpu(pi->v.num_removed_snap_intervals) + *p += le32_to_cpu(pi->v.num_snaps) * sizeof(u64); + *p += le32_to_cpu(pi->v.num_removed_snap_intervals) * sizeof(u64) * 2; } ceph_decode_32_safe(p, end, map->pool_max, bad); -- cgit v0.10.2 From 7af8f1e4aa86720840d3318e4dc225c3c7e5a6d0 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 1 Mar 2010 15:17:34 -0800 Subject: ceph: include migrating caps in issued set We should include caps that are mid-migration (we've received the EXPORT, but not the IMPORT) in the issued caps set. Signed-off-by: Sage Weil diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 06f1979..295b7e54 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -655,7 +655,7 @@ static int __cap_is_valid(struct ceph_cap *cap) */ int __ceph_caps_issued(struct ceph_inode_info *ci, int *implemented) { - int have = ci->i_snap_caps; + int have = ci->i_snap_caps | ci->i_cap_exporting_issued; struct ceph_cap *cap; struct rb_node *p; -- cgit v0.10.2 From e9964c102312967a4bc1fd501cb628c4a3b19034 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 1 Mar 2010 15:16:56 -0800 Subject: ceph: fix flush_dirty_caps race with caps migration The flush_dirty_caps() used to loop over the first entry of the cap_dirty dirty list on the assumption that after calling ceph_check_caps() it would be removed from the list. This isn't true for caps that are being migrated between MDSs, where we've received the EXPORT but not the IMPORT. Instead, do a safe list iteration, and pin the next inode on the list via the CEPH_I_NOFLUSH flag. Signed-off-by: Sage Weil diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 295b7e54..8b89b91 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -1573,6 +1573,11 @@ retry_locked: } ack: + if (ci->i_ceph_flags & CEPH_I_NOFLUSH) { + dout(" skipping %p I_NOFLUSH set\n", inode); + continue; + } + if (session && session != cap->session) { dout("oops, wrong session %p mutex\n", session); mutex_unlock(&session->s_mutex); @@ -1652,6 +1657,10 @@ static int try_flush_caps(struct inode *inode, struct ceph_mds_session *session, retry: spin_lock(&inode->i_lock); + if (ci->i_ceph_flags & CEPH_I_NOFLUSH) { + dout("try_flush_caps skipping %p I_NOFLUSH set\n", inode); + goto out; + } if (ci->i_dirty_caps && ci->i_auth_cap) { struct ceph_cap *cap = ci->i_auth_cap; int used = __ceph_caps_used(ci); @@ -2747,16 +2756,38 @@ void ceph_check_delayed_caps(struct ceph_mds_client *mdsc) */ void ceph_flush_dirty_caps(struct ceph_mds_client *mdsc) { - struct ceph_inode_info *ci; - struct inode *inode; + struct ceph_inode_info *ci, *nci = NULL; + struct inode *inode, *ninode = NULL; + struct list_head *p, *n; dout("flush_dirty_caps\n"); spin_lock(&mdsc->cap_dirty_lock); - while (!list_empty(&mdsc->cap_dirty)) { - ci = list_first_entry(&mdsc->cap_dirty, - struct ceph_inode_info, - i_dirty_item); - inode = igrab(&ci->vfs_inode); + list_for_each_safe(p, n, &mdsc->cap_dirty) { + if (nci) { + ci = nci; + inode = ninode; + ci->i_ceph_flags &= ~CEPH_I_NOFLUSH; + dout("flush_dirty_caps inode %p (was next inode)\n", + inode); + } else { + ci = list_entry(p, struct ceph_inode_info, + i_dirty_item); + inode = igrab(&ci->vfs_inode); + BUG_ON(!inode); + dout("flush_dirty_caps inode %p\n", inode); + } + if (n != &mdsc->cap_dirty) { + nci = list_entry(n, struct ceph_inode_info, + i_dirty_item); + ninode = igrab(&nci->vfs_inode); + BUG_ON(!ninode); + nci->i_ceph_flags |= CEPH_I_NOFLUSH; + dout("flush_dirty_caps next inode %p, noflush\n", + ninode); + } else { + nci = NULL; + ninode = NULL; + } spin_unlock(&mdsc->cap_dirty_lock); if (inode) { ceph_check_caps(ci, CHECK_CAPS_NODELAY|CHECK_CAPS_FLUSH, diff --git a/fs/ceph/super.h b/fs/ceph/super.h index ff7aaa3..6a778f2 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -289,6 +289,7 @@ struct ceph_inode_xattrs_info { #define CEPH_I_COMPLETE 1 /* we have complete directory cached */ #define CEPH_I_NODELAY 4 /* do not delay cap release */ #define CEPH_I_FLUSH 8 /* do not delay flush of dirty metadata */ +#define CEPH_I_NOFLUSH 16 /* do not flush dirty caps */ struct ceph_inode_info { struct ceph_vino i_vino; /* ceph ino + snap */ -- cgit v0.10.2 From 57e413d95b0f92b9a5569408ddc3441e0f20e856 Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Mon, 1 Mar 2010 23:50:24 -0800 Subject: Input: wacom - replace WACOM_PKGLEN_PENABLED Replacing WACOM_PKGLEN_PENABLED with WACOM_PKGLEN_GRAPHIRE since they both represent the same value, 8. This value will be used for both Tablet PC and Bamboo with touch devices. Signed-off-by: Ping Cheng Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index a1770e6..8b5d287 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c @@ -371,7 +371,7 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi } else if (pen) { /* penabled only accepts exact bytes of data */ if (features->type == TABLETPC2FG) - features->pktlen = WACOM_PKGLEN_PENABLED; + features->pktlen = WACOM_PKGLEN_GRAPHIRE; features->device_type = BTN_TOOL_PEN; features->x_max = wacom_le16_to_cpu(&report[i + 3]); @@ -410,7 +410,7 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi } else if (pen) { /* penabled only accepts exact bytes of data */ if (features->type == TABLETPC2FG) - features->pktlen = WACOM_PKGLEN_PENABLED; + features->pktlen = WACOM_PKGLEN_GRAPHIRE; features->device_type = BTN_TOOL_PEN; features->y_max = wacom_le16_to_cpu(&report[i + 3]); diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 3d81443..4a852d8 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c @@ -1028,7 +1028,7 @@ static const struct wacom_features wacom_features_0x93 = static const struct wacom_features wacom_features_0x9A = { "Wacom ISDv4 9A", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }; static const struct wacom_features wacom_features_0x9F = - { "Wacom ISDv4 9F", WACOM_PKGLEN_PENABLED, 26202, 16325, 255, 0, TABLETPC }; + { "Wacom ISDv4 9F", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }; static const struct wacom_features wacom_features_0xE2 = { "Wacom ISDv4 E2", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, 0, TABLETPC2FG }; static const struct wacom_features wacom_features_0xE3 = diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h index 8590b1e..b50cf04 100644 --- a/drivers/input/tablet/wacom_wac.h +++ b/drivers/input/tablet/wacom_wac.h @@ -17,7 +17,6 @@ #define WACOM_PKGLEN_GRAPHIRE 8 #define WACOM_PKGLEN_BBFUN 9 #define WACOM_PKGLEN_INTUOS 10 -#define WACOM_PKGLEN_PENABLED 8 #define WACOM_PKGLEN_TPC1FG 5 #define WACOM_PKGLEN_TPC2FG 14 -- cgit v0.10.2 From 14be1f7454ea96ee614467a49cf018a1a383b189 Mon Sep 17 00:00:00 2001 From: Dimitri Sivanich Date: Mon, 1 Mar 2010 11:48:15 -0600 Subject: x86: Fix sched_clock_cpu for systems with unsynchronized TSC On UV systems, the TSC is not synchronized across blades. The sched_clock_cpu() function is returning values that can go backwards (I've seen as much as 8 seconds) when switching between cpus. As each cpu comes up, early_init_intel() will currently set the sched_clock_stable flag true. When mark_tsc_unstable() runs, it clears the flag, but this only occurs once (the first time a cpu comes up whose TSC is not synchronized with cpu 0). After this, early_init_intel() will set the flag again as the next cpu comes up. Only set sched_clock_stable if tsc has not been marked unstable. Signed-off-by: Dimitri Sivanich Acked-by: Venkatesh Pallipadi Acked-by: Peter Zijlstra LKML-Reference: <20100301174815.GC8224@sgi.com> Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 879666f..7e1cca1 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -70,7 +70,8 @@ static void __cpuinit early_init_intel(struct cpuinfo_x86 *c) if (c->x86_power & (1 << 8)) { set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC); - sched_clock_stable = 1; + if (!check_tsc_unstable()) + sched_clock_stable = 1; } /* -- cgit v0.10.2 From 320ebf09cbb6d01954c9a060266aa8e0d27f4638 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 2 Mar 2010 12:35:37 +0100 Subject: perf, x86: Restrict the ANY flag The ANY flag can show SMT data of another task (like 'top'), so we want to disable it when system-wide profiling is disabled. Signed-off-by: Peter Zijlstra LKML-Reference: Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 6531b4b..aab2e1c 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -503,6 +503,9 @@ static int __hw_perf_event_init(struct perf_event *event) */ if (attr->type == PERF_TYPE_RAW) { hwc->config |= x86_pmu.raw_event(attr->config); + if ((hwc->config & ARCH_PERFMON_EVENTSEL_ANY) && + perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN)) + return -EACCES; return 0; } diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 04f06b4..90e0521 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -857,6 +857,21 @@ extern int sysctl_perf_event_paranoid; extern int sysctl_perf_event_mlock; extern int sysctl_perf_event_sample_rate; +static inline bool perf_paranoid_tracepoint_raw(void) +{ + return sysctl_perf_event_paranoid > -1; +} + +static inline bool perf_paranoid_cpu(void) +{ + return sysctl_perf_event_paranoid > 0; +} + +static inline bool perf_paranoid_kernel(void) +{ + return sysctl_perf_event_paranoid > 1; +} + extern void perf_event_init(void); extern void perf_tp_event(int event_id, u64 addr, u64 count, void *record, int entry_size); extern void perf_bp_event(struct perf_event *event, void *data); diff --git a/kernel/perf_event.c b/kernel/perf_event.c index a661e79..482d5e1 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c @@ -56,21 +56,6 @@ static atomic_t nr_task_events __read_mostly; */ int sysctl_perf_event_paranoid __read_mostly = 1; -static inline bool perf_paranoid_tracepoint_raw(void) -{ - return sysctl_perf_event_paranoid > -1; -} - -static inline bool perf_paranoid_cpu(void) -{ - return sysctl_perf_event_paranoid > 0; -} - -static inline bool perf_paranoid_kernel(void) -{ - return sysctl_perf_event_paranoid > 1; -} - int sysctl_perf_event_mlock __read_mostly = 512; /* 'free' kb per user */ /* -- cgit v0.10.2 From b622d644c7d61a5cb95b74e7b143c263bed21f0a Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 1 Feb 2010 15:36:30 +0100 Subject: perf_events, x86: Fixup fixed counter constraints Patch 1da53e0230 ("perf_events, x86: Improve x86 event scheduling") lost us one of the fixed purpose counters and then ed8777fc13 ("perf_events, x86: Fix event constraint masks") broke it even further. Widen the fixed event mask to event+umask and specify the full config for each of the 3 fixed purpose counters. Then let the init code fill out the placement for the GP regs based on the cpuid info. Signed-off-by: Peter Zijlstra Cc: Stephane Eranian LKML-Reference: Signed-off-by: Ingo Molnar diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h index 80e6936..db6109a 100644 --- a/arch/x86/include/asm/perf_event.h +++ b/arch/x86/include/asm/perf_event.h @@ -50,7 +50,7 @@ INTEL_ARCH_INV_MASK| \ INTEL_ARCH_EDGE_MASK|\ INTEL_ARCH_UNIT_MASK|\ - INTEL_ARCH_EVTSEL_MASK) + INTEL_ARCH_EVENT_MASK) #define ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL 0x3c #define ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK (0x00 << 8) diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index aab2e1c..bfc43fa 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -73,10 +73,10 @@ struct debug_store { struct event_constraint { union { unsigned long idxmsk[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; - u64 idxmsk64[1]; + u64 idxmsk64; }; - int code; - int cmask; + u64 code; + u64 cmask; int weight; }; @@ -103,7 +103,7 @@ struct cpu_hw_events { }; #define __EVENT_CONSTRAINT(c, n, m, w) {\ - { .idxmsk64[0] = (n) }, \ + { .idxmsk64 = (n) }, \ .code = (c), \ .cmask = (m), \ .weight = (w), \ @@ -116,7 +116,7 @@ struct cpu_hw_events { EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVTSEL_MASK) #define FIXED_EVENT_CONSTRAINT(c, n) \ - EVENT_CONSTRAINT(c, n, INTEL_ARCH_FIXED_MASK) + EVENT_CONSTRAINT(c, (1ULL << (32+n)), INTEL_ARCH_FIXED_MASK) #define EVENT_CONSTRAINT_END \ EVENT_CONSTRAINT(0, 0, 0) @@ -615,8 +615,8 @@ static int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign) bitmap_zero(used_mask, X86_PMC_IDX_MAX); for (i = 0; i < n; i++) { - constraints[i] = - x86_pmu.get_event_constraints(cpuc, cpuc->event_list[i]); + c = x86_pmu.get_event_constraints(cpuc, cpuc->event_list[i]); + constraints[i] = c; } /* @@ -1350,6 +1350,7 @@ static void __init pmu_check_apic(void) void __init init_hw_perf_events(void) { + struct event_constraint *c; int err; pr_info("Performance Events: "); @@ -1398,6 +1399,16 @@ void __init init_hw_perf_events(void) __EVENT_CONSTRAINT(0, (1ULL << x86_pmu.num_events) - 1, 0, x86_pmu.num_events); + if (x86_pmu.event_constraints) { + for_each_event_constraint(c, x86_pmu.event_constraints) { + if (c->cmask != INTEL_ARCH_FIXED_MASK) + continue; + + c->idxmsk64 |= (1ULL << x86_pmu.num_events) - 1; + c->weight += x86_pmu.num_events; + } + } + pr_info("... version: %d\n", x86_pmu.version); pr_info("... bit width: %d\n", x86_pmu.event_bits); pr_info("... generic registers: %d\n", x86_pmu.num_events); diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index cf6590c..4fbdfe5 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -1,7 +1,7 @@ #ifdef CONFIG_CPU_SUP_INTEL /* - * Intel PerfMon v3. Used on Core2 and later. + * Intel PerfMon, used on Core and later. */ static const u64 intel_perfmon_event_map[] = { @@ -27,8 +27,14 @@ static struct event_constraint intel_core_event_constraints[] = static struct event_constraint intel_core2_event_constraints[] = { - FIXED_EVENT_CONSTRAINT(0xc0, (0x3|(1ULL<<32))), /* INSTRUCTIONS_RETIRED */ - FIXED_EVENT_CONSTRAINT(0x3c, (0x3|(1ULL<<33))), /* UNHALTED_CORE_CYCLES */ + FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */ + FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */ + /* + * Core2 has Fixed Counter 2 listed as CPU_CLK_UNHALTED.REF and event + * 0x013c as CPU_CLK_UNHALTED.BUS and specifies there is a fixed + * ratio between these counters. + */ + /* FIXED_EVENT_CONSTRAINT(0x013c, 2), CPU_CLK_UNHALTED.REF */ INTEL_EVENT_CONSTRAINT(0x10, 0x1), /* FP_COMP_OPS_EXE */ INTEL_EVENT_CONSTRAINT(0x11, 0x2), /* FP_ASSIST */ INTEL_EVENT_CONSTRAINT(0x12, 0x2), /* MUL */ @@ -37,14 +43,16 @@ static struct event_constraint intel_core2_event_constraints[] = INTEL_EVENT_CONSTRAINT(0x18, 0x1), /* IDLE_DURING_DIV */ INTEL_EVENT_CONSTRAINT(0x19, 0x2), /* DELAYED_BYPASS */ INTEL_EVENT_CONSTRAINT(0xa1, 0x1), /* RS_UOPS_DISPATCH_CYCLES */ + INTEL_EVENT_CONSTRAINT(0xc9, 0x1), /* ITLB_MISS_RETIRED (T30-9) */ INTEL_EVENT_CONSTRAINT(0xcb, 0x1), /* MEM_LOAD_RETIRED */ EVENT_CONSTRAINT_END }; static struct event_constraint intel_nehalem_event_constraints[] = { - FIXED_EVENT_CONSTRAINT(0xc0, (0xf|(1ULL<<32))), /* INSTRUCTIONS_RETIRED */ - FIXED_EVENT_CONSTRAINT(0x3c, (0xf|(1ULL<<33))), /* UNHALTED_CORE_CYCLES */ + FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */ + FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */ + /* FIXED_EVENT_CONSTRAINT(0x013c, 2), CPU_CLK_UNHALTED.REF */ INTEL_EVENT_CONSTRAINT(0x40, 0x3), /* L1D_CACHE_LD */ INTEL_EVENT_CONSTRAINT(0x41, 0x3), /* L1D_CACHE_ST */ INTEL_EVENT_CONSTRAINT(0x42, 0x3), /* L1D_CACHE_LOCK */ @@ -58,8 +66,9 @@ static struct event_constraint intel_nehalem_event_constraints[] = static struct event_constraint intel_westmere_event_constraints[] = { - FIXED_EVENT_CONSTRAINT(0xc0, (0xf|(1ULL<<32))), /* INSTRUCTIONS_RETIRED */ - FIXED_EVENT_CONSTRAINT(0x3c, (0xf|(1ULL<<33))), /* UNHALTED_CORE_CYCLES */ + FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */ + FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */ + /* FIXED_EVENT_CONSTRAINT(0x013c, 2), CPU_CLK_UNHALTED.REF */ INTEL_EVENT_CONSTRAINT(0x51, 0x3), /* L1D */ INTEL_EVENT_CONSTRAINT(0x60, 0x1), /* OFFCORE_REQUESTS_OUTSTANDING */ INTEL_EVENT_CONSTRAINT(0x63, 0x3), /* CACHE_LOCK_CYCLES */ @@ -68,8 +77,9 @@ static struct event_constraint intel_westmere_event_constraints[] = static struct event_constraint intel_gen_event_constraints[] = { - FIXED_EVENT_CONSTRAINT(0xc0, (0x3|(1ULL<<32))), /* INSTRUCTIONS_RETIRED */ - FIXED_EVENT_CONSTRAINT(0x3c, (0x3|(1ULL<<33))), /* UNHALTED_CORE_CYCLES */ + FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */ + FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */ + /* FIXED_EVENT_CONSTRAINT(0x013c, 2), CPU_CLK_UNHALTED.REF */ EVENT_CONSTRAINT_END }; @@ -935,7 +945,7 @@ static __init int intel_pmu_init(void) x86_pmu.event_constraints = intel_nehalem_event_constraints; pr_cont("Nehalem/Corei7 events, "); break; - case 28: + case 28: /* Atom */ memcpy(hw_cache_event_ids, atom_hw_cache_event_ids, sizeof(hw_cache_event_ids)); @@ -951,6 +961,7 @@ static __init int intel_pmu_init(void) x86_pmu.event_constraints = intel_westmere_event_constraints; pr_cont("Westmere events, "); break; + default: /* * default constraints for v2 and up -- cgit v0.10.2 From 6630125419ef37ff8781713c5e9d416f2a4ba357 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 2 Mar 2010 15:25:38 -0300 Subject: perf archive: Don't try to collect files without a build-id MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To avoid these error: [root@doppio ~]# perf archive tar: .build-id/00/00000000000000000000000000000000000000: Cannot stat: No such file or directory tar: .build-id/00/00000000000000000000000000000000000000: Cannot stat: No such file or directory tar: .build-id/00/00000000000000000000000000000000000000: Cannot stat: No such file or directory tar: .build-id/00/00000000000000000000000000000000000000: Cannot stat: No such file or directory tar: Exiting with failure status due to previous errors [root@doppio ~]# More work is needed to support archiving symtabs for binaries without a build-id, perhaps creating a perf.data UUID + adding build-ids for the binaries copied into the cache and then have this perf.data session UUID be a directory with symlinks to the by now calculated build-id of the files inside it. Or just do an extra pass and insert the calculated build-ids in the perf.data header. Reported-by: Ingo Molnar Signed-off-by: Arnaldo Carvalho de Melo Cc: Frédéric Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Paul Mackerras Signed-off-by: Ingo Molnar diff --git a/tools/perf/perf-archive.sh b/tools/perf/perf-archive.sh index 45fbe2f..910468e 100644 --- a/tools/perf/perf-archive.sh +++ b/tools/perf/perf-archive.sh @@ -9,8 +9,9 @@ fi DEBUGDIR=~/.debug/ BUILDIDS=$(mktemp /tmp/perf-archive-buildids.XXXXXX) +NOBUILDID=0000000000000000000000000000000000000000 -perf buildid-list -i $PERF_DATA --with-hits > $BUILDIDS +perf buildid-list -i $PERF_DATA --with-hits | grep -v "^$NOBUILDID " > $BUILDIDS if [ ! -s $BUILDIDS ] ; then echo "perf archive: no build-ids found" rm -f $BUILDIDS -- cgit v0.10.2 From 6510b8917948283005a125c8337d3312a8a0561c Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 26 Feb 2010 15:10:28 +0100 Subject: airo: return from set_wep_key() when key length is zero Even if keylen == 0 is a bug and should not really happen, better avoid possibility of passing bad value to firmware. Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 698d567..dc5018a 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -5255,7 +5255,8 @@ static int set_wep_key(struct airo_info *ai, u16 index, const char *key, WepKeyRid wkr; int rc; - WARN_ON(keylen == 0); + if (WARN_ON(keylen == 0)) + return -1; memset(&wkr, 0, sizeof(wkr)); wkr.len = cpu_to_le16(sizeof(wkr)); -- cgit v0.10.2 From 3082a2b7b1af1b1508c1c3fa589566064f926f40 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Tue, 16 Feb 2010 16:36:25 -0500 Subject: rfkill: Add support for KEY_RFKILL Add support for handling KEY_RFKILL in the rfkill input module. This simply toggles the state of all rfkill devices. The comment in rfkill.h is also updated to reflect that RFKILL_TYPE_ALL may be used inside the kernel. Signed-off-by: Matthew Garrett Acked-by: Marcel Holtmann Signed-off-by: John W. Linville diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h index 97059d0..4f82326 100644 --- a/include/linux/rfkill.h +++ b/include/linux/rfkill.h @@ -29,7 +29,7 @@ /** * enum rfkill_type - type of rfkill switch. * - * @RFKILL_TYPE_ALL: toggles all switches (userspace only) + * @RFKILL_TYPE_ALL: toggles all switches (requests only - not a switch type) * @RFKILL_TYPE_WLAN: switch is on a 802.11 wireless network device. * @RFKILL_TYPE_BLUETOOTH: switch is on a bluetooth device. * @RFKILL_TYPE_UWB: switch is on a ultra wideband device. diff --git a/net/rfkill/input.c b/net/rfkill/input.c index a7295ad..3713d7e 100644 --- a/net/rfkill/input.c +++ b/net/rfkill/input.c @@ -212,6 +212,9 @@ static void rfkill_event(struct input_handle *handle, unsigned int type, case KEY_WIMAX: rfkill_schedule_toggle(RFKILL_TYPE_WIMAX); break; + case KEY_RFKILL: + rfkill_schedule_toggle(RFKILL_TYPE_ALL); + break; } } else if (type == EV_SW && code == SW_RFKILL_ALL) rfkill_schedule_evsw_rfkillall(data); @@ -295,6 +298,11 @@ static const struct input_device_id rfkill_ids[] = { .keybit = { [BIT_WORD(KEY_WIMAX)] = BIT_MASK(KEY_WIMAX) }, }, { + .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT, + .evbit = { BIT_MASK(EV_KEY) }, + .keybit = { [BIT_WORD(KEY_RFKILL)] = BIT_MASK(KEY_RFKILL) }, + }, + { .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_SWBIT, .evbit = { BIT(EV_SW) }, .swbit = { [BIT_WORD(SW_RFKILL_ALL)] = BIT_MASK(SW_RFKILL_ALL) }, -- cgit v0.10.2 From 86baf712295a00d664da8566186b67041c89b15b Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 27 Feb 2010 09:12:34 +0300 Subject: zd1211rw: fix potential array underflow The first chunk fixes a debugging assert to print a warning about array underflows. The second chunk corrects a potential array underflow. I also removed an assert in the second chunk because it can no longer happen. Signed-off-by: Dan Carpenter Acked-by: Benoit Papillault Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 2d555cc..e240996 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -350,7 +350,7 @@ static void zd_mac_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, first_idx = info->status.rates[0].idx; ZD_ASSERT(0<=first_idx && first_idxcount); + ZD_ASSERT(1 <= retry && retry <= retries->count); info->status.rates[0].idx = retries->rate[0]; info->status.rates[0].count = 1; // (retry > 1 ? 2 : 1); @@ -360,7 +360,7 @@ static void zd_mac_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, info->status.rates[i].count = 1; // ((i==retry-1) && success ? 1:2); } for (; istatus.rates[i].idx = retries->rate[retry-1]; + info->status.rates[i].idx = retries->rate[retry - 1]; info->status.rates[i].count = 1; // (success ? 1:2); } if (istatus.rates[0].idx; ZD_ASSERT(0<=first_idx && first_idx retries->count) { + if (retry <= 0 || retry > retries->count) continue; - } - ZD_ASSERT(0<=retry && retry<=retries->count); - final_idx = retries->rate[retry-1]; + final_idx = retries->rate[retry - 1]; final_rate = zd_rates[final_idx].hw_value; if (final_rate != tx_status->rate) { -- cgit v0.10.2 From a9f042cbe5284f34ccff15f3084477e11b39b17b Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Sun, 28 Feb 2010 00:56:24 +0800 Subject: ath9k: fix lockdep warning when unloading module Since txq->axq_lock may be hold in softirq context, it must be acquired with spin_lock_bh() instead of spin_lock() if softieq is enabled. The patch fixes the lockdep warning below when unloading ath9k modules. ================================= [ INFO: inconsistent lock state ] 2.6.33-wl #12 --------------------------------- inconsistent {IN-SOFTIRQ-W} -> {SOFTIRQ-ON-W} usage. rmmod/3642 [HC0[0]:SC0[0]:HE1:SE1] takes: (&(&txq->axq_lock)->rlock){+.?...}, at: [] ath_tx_node_cleanup+0x62/0x180 [ath9k] {IN-SOFTIRQ-W} state was registered at: [] __lock_acquire+0x2f6/0xd35 [] lock_acquire+0xcd/0xf1 [] _raw_spin_lock_bh+0x3b/0x6e [] spin_lock_bh+0xe/0x10 [ath9k] [] ath_tx_tasklet+0xcd/0x391 [ath9k] [] ath9k_tasklet+0x70/0xc8 [ath9k] [] tasklet_action+0x8c/0xf4 [] __do_softirq+0xf8/0x1cd [] call_softirq+0x1c/0x30 [] do_softirq+0x4b/0xa3 [] irq_exit+0x4a/0x8c [] do_IRQ+0xac/0xc3 [] ret_from_intr+0x0/0x16 [] cpuidle_idle_call+0x9e/0xf8 [] cpu_idle+0x62/0x9d [] rest_init+0x7e/0x80 [] start_kernel+0x3e8/0x3f3 [] x86_64_start_reservations+0xa7/0xab [] x86_64_start_kernel+0xf8/0x107 irq event stamp: 42037 hardirqs last enabled at (42037): [] _raw_spin_unlock_irqrestore+0x47/0x56 hardirqs last disabled at (42036): [] _raw_spin_lock_irqsave+0x2b/0x88 softirqs last enabled at (42000): [] spin_unlock_bh+0xe/0x10 [ath9k] softirqs last disabled at (41998): [] _raw_spin_lock_bh+0x18/0x6e other info that might help us debug this: 4 locks held by rmmod/3642: #0: (rtnl_mutex){+.+.+.}, at: [] rtnl_lock+0x17/0x19 #1: (&wdev->mtx){+.+.+.}, at: [] cfg80211_netdev_notifier_call+0x28d/0x46d [cfg80211] #2: (&ifmgd->mtx){+.+.+.}, at: [] ieee80211_mgd_deauth+0x3f/0x17e [mac80211] #3: (&local->sta_mtx){+.+.+.}, at: [] sta_info_destroy_addr+0x2b/0x5e [mac80211] stack backtrace: Pid: 3642, comm: rmmod Not tainted 2.6.33-wl #12 Call Trace: [] valid_state+0x178/0x18b [] ? save_stack_trace+0x2f/0x4c [] ? check_usage_backwards+0x0/0x88 [] mark_lock+0x113/0x230 [] __lock_acquire+0x36a/0xd35 [] ? native_sched_clock+0x2d/0x5f [] ? ath_tx_node_cleanup+0x62/0x180 [ath9k] [] lock_acquire+0xcd/0xf1 [] ? ath_tx_node_cleanup+0x62/0x180 [ath9k] [] ? trace_hardirqs_off+0xd/0xf [] _raw_spin_lock+0x36/0x69 [] ? ath_tx_node_cleanup+0x62/0x180 [ath9k] [] ath_tx_node_cleanup+0x62/0x180 [ath9k] [] ? trace_hardirqs_on+0xd/0xf [] ath9k_sta_remove+0x22/0x26 [ath9k] [] __sta_info_destroy+0x1ad/0x38c [mac80211] [] sta_info_destroy_addr+0x3e/0x5e [mac80211] [] ieee80211_set_disassoc+0x175/0x180 [mac80211] [] ieee80211_mgd_deauth+0x58/0x17e [mac80211] [] ? __mutex_lock_common+0x37f/0x3a4 [] ? cfg80211_netdev_notifier_call+0x28d/0x46d [cfg80211] [] ieee80211_deauth+0x1e/0x20 [mac80211] [] __cfg80211_mlme_deauth+0x130/0x13f [cfg80211] [] ? cfg80211_netdev_notifier_call+0x28d/0x46d [cfg80211] [] ? trace_hardirqs_off+0xd/0xf [] __cfg80211_disconnect+0x111/0x189 [cfg80211] [] cfg80211_netdev_notifier_call+0x2ce/0x46d [cfg80211] [] notifier_call_chain+0x37/0x63 [] raw_notifier_call_chain+0x14/0x16 [] call_netdevice_notifiers+0x1b/0x1d [] dev_close+0x6a/0xa6 [] rollback_registered_many+0xb6/0x2f4 [] unregister_netdevice_many+0x1b/0x66 [] ieee80211_remove_interfaces+0xc5/0xd0 [mac80211] [] ieee80211_unregister_hw+0x47/0xe8 [mac80211] [] ath9k_deinit_device+0x7a/0x9b [ath9k] [] ath_pci_remove+0x38/0x76 [ath9k] [] pci_device_remove+0x2d/0x51 [] __device_release_driver+0x7b/0xd1 [] driver_detach+0x98/0xbe [] bus_remove_driver+0x94/0xb7 [] driver_unregister+0x6c/0x74 [] pci_unregister_driver+0x46/0xad [] ath_pci_exit+0x15/0x17 [ath9k] [] ath9k_exit+0xe/0x2f [ath9k] [] sys_delete_module+0x1c7/0x236 [] ? retint_swapgs+0x13/0x1b [] ? trace_hardirqs_on_caller+0x119/0x144 [] ? audit_syscall_entry+0x11e/0x14a [] system_call_fastpath+0x16/0x1b wlan1: deauthenticating from 00:23:cd:e1:f9:b2 by local choice (reason=3) PM: Removing info for No Bus:wlan1 cfg80211: Calling CRDA to update world regulatory domain PM: Removing info for No Bus:rfkill2 PM: Removing info for No Bus:phy1 ath9k 0000:16:00.0: PCI INT A disabled Signed-off-by: Ming Lei Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 47294f9..b2c8207 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -2258,7 +2258,7 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an) if (ATH_TXQ_SETUP(sc, i)) { txq = &sc->tx.txq[i]; - spin_lock(&txq->axq_lock); + spin_lock_bh(&txq->axq_lock); list_for_each_entry_safe(ac, ac_tmp, &txq->axq_acq, list) { @@ -2279,7 +2279,7 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an) } } - spin_unlock(&txq->axq_lock); + spin_unlock_bh(&txq->axq_lock); } } } -- cgit v0.10.2 From 9c87ba6734422034fccb938da1039ed63da1395c Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sun, 28 Feb 2010 12:13:46 +0200 Subject: mac80211: Fix reassociation processing (within ESS roaming) Commit e1dd33f60ced091114e4aacf141e0d03b88d3e13 changed cfg80211 to allow association commands while in associated state to enable support for roaming within an ESS. However, this was not enough to resolve all cases with mac80211 which needs some additional handling of the reassociation case to clear internal state with the BSS that was in use previously. This patch makes ieee80211_mgd_assoc() accept a valid reassociation command and clean the association state with the previous BSS. This fixes roaming between BSSes in an ESS when using wpa_supplicant with -Dnl80211. Signed-off-by: Jouni Malinen Cc: stable@kernel.org Signed-off-by: John W. Linville diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 41812a1..5a26876 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1893,8 +1893,20 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, mutex_lock(&ifmgd->mtx); if (ifmgd->associated) { - mutex_unlock(&ifmgd->mtx); - return -EALREADY; + if (!req->prev_bssid || + memcmp(req->prev_bssid, ifmgd->associated->bssid, + ETH_ALEN)) { + /* + * We are already associated and the request was not a + * reassociation request from the current BSS, so + * reject it. + */ + mutex_unlock(&ifmgd->mtx); + return -EALREADY; + } + + /* Trying to reassociate - clear previous association state */ + ieee80211_set_disassoc(sdata); } mutex_unlock(&ifmgd->mtx); -- cgit v0.10.2 From 51b2853fd91a3c8fd9f3adc1549569d2c1dc2a2d Mon Sep 17 00:00:00 2001 From: Bryan Polk Date: Mon, 1 Mar 2010 12:23:28 -0500 Subject: rt2x00: Add USB ID for CEIVA adapter to rt73usb This adds support for CEIVA USB wireless adapters to the rt73usb driver. Signed-off-by: Bryan Polk Acked-by: Ivo van Doorn Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index f39a8ed..47f3e4a 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -2352,6 +2352,8 @@ static struct usb_device_id rt73usb_device_table[] = { { USB_DEVICE(0x0411, 0x00f4), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x0411, 0x0116), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x0411, 0x0119), USB_DEVICE_DATA(&rt73usb_ops) }, + /* CEIVA */ + { USB_DEVICE(0x178d, 0x02be), USB_DEVICE_DATA(&rt73usb_ops) }, /* CNet */ { USB_DEVICE(0x1371, 0x9022), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x1371, 0x9032), USB_DEVICE_DATA(&rt73usb_ops) }, -- cgit v0.10.2 From 6e93d7195e75741e9ebe23ca5591977d0b39ecc0 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Tue, 2 Mar 2010 16:34:49 +0100 Subject: rt2x00: fix rt2800pci compilation with SoC Compiling rt2800pci with CONFIG_RT2800PCI_SOC fails with "... rt2880pci.c: error: incompatible type for argument 2 of 'rt2x00soc_probe'". Fix this by using &rt2800pci_ops instead of rt2800pci_ops. Signed-off-by: Helmut Schaa Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index aca8c12..91cce2d 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -1225,7 +1225,7 @@ MODULE_LICENSE("GPL"); #ifdef CONFIG_RT2800PCI_SOC static int rt2800soc_probe(struct platform_device *pdev) { - return rt2x00soc_probe(pdev, rt2800pci_ops); + return rt2x00soc_probe(pdev, &rt2800pci_ops); } static struct platform_driver rt2800soc_driver = { -- cgit v0.10.2 From 535765179fd4e8af26b69d2240d7ec33702a370a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 23 Dec 2009 13:15:30 +0100 Subject: ar9170: load firmware asynchronously This converts ar9170 to load firmware asynchronously out of ->probe() and only register with mac80211 when all firmware has been loaded successfully. If, on the other hand, any firmware fails to load, it will now unbind from the device. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/ar9170/ar9170.h b/drivers/net/wireless/ath/ar9170/ar9170.h index 8c8ce67..dc662b7 100644 --- a/drivers/net/wireless/ath/ar9170/ar9170.h +++ b/drivers/net/wireless/ath/ar9170/ar9170.h @@ -166,6 +166,7 @@ struct ar9170 { struct ath_common common; struct mutex mutex; enum ar9170_device_state state; + bool registered; unsigned long bad_hw_nagger; int (*open)(struct ar9170 *); diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c index 8a964f1..f4650fc 100644 --- a/drivers/net/wireless/ath/ar9170/main.c +++ b/drivers/net/wireless/ath/ar9170/main.c @@ -2701,7 +2701,8 @@ int ar9170_register(struct ar9170 *ar, struct device *pdev) dev_info(pdev, "Atheros AR9170 is registered as '%s'\n", wiphy_name(ar->hw->wiphy)); - return err; + ar->registered = true; + return 0; err_unreg: ieee80211_unregister_hw(ar->hw); @@ -2712,11 +2713,14 @@ err_out: void ar9170_unregister(struct ar9170 *ar) { + if (ar->registered) { #ifdef CONFIG_AR9170_LEDS - ar9170_unregister_leds(ar); + ar9170_unregister_leds(ar); #endif /* CONFIG_AR9170_LEDS */ - kfree_skb(ar->rx_failover); ieee80211_unregister_hw(ar->hw); + } + + kfree_skb(ar->rx_failover); mutex_destroy(&ar->mutex); } diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c index 0f36118..4e30197 100644 --- a/drivers/net/wireless/ath/ar9170/usb.c +++ b/drivers/net/wireless/ath/ar9170/usb.c @@ -582,43 +582,6 @@ static int ar9170_usb_upload(struct ar9170_usb *aru, const void *data, return 0; } -static int ar9170_usb_request_firmware(struct ar9170_usb *aru) -{ - int err = 0; - - err = request_firmware(&aru->firmware, "ar9170.fw", - &aru->udev->dev); - if (!err) { - aru->init_values = NULL; - return 0; - } - - if (aru->req_one_stage_fw) { - dev_err(&aru->udev->dev, "ar9170.fw firmware file " - "not found and is required for this device\n"); - return -EINVAL; - } - - dev_err(&aru->udev->dev, "ar9170.fw firmware file " - "not found, trying old firmware...\n"); - - err = request_firmware(&aru->init_values, "ar9170-1.fw", - &aru->udev->dev); - if (err) { - dev_err(&aru->udev->dev, "file with init values not found.\n"); - return err; - } - - err = request_firmware(&aru->firmware, "ar9170-2.fw", &aru->udev->dev); - if (err) { - release_firmware(aru->init_values); - dev_err(&aru->udev->dev, "firmware file not found.\n"); - return err; - } - - return err; -} - static int ar9170_usb_reset(struct ar9170_usb *aru) { int ret, lock = (aru->intf->condition != USB_INTERFACE_BINDING); @@ -757,6 +720,103 @@ err_out: return err; } +static void ar9170_usb_firmware_failed(struct ar9170_usb *aru) +{ + struct device *parent = aru->udev->dev.parent; + + /* unbind anything failed */ + if (parent) + down(&parent->sem); + device_release_driver(&aru->udev->dev); + if (parent) + up(&parent->sem); +} + +static void ar9170_usb_firmware_finish(const struct firmware *fw, void *context) +{ + struct ar9170_usb *aru = context; + int err; + + aru->firmware = fw; + + if (!fw) { + dev_err(&aru->udev->dev, "firmware file not found.\n"); + goto err_freefw; + } + + err = ar9170_usb_init_device(aru); + if (err) + goto err_freefw; + + err = ar9170_usb_open(&aru->common); + if (err) + goto err_unrx; + + err = ar9170_register(&aru->common, &aru->udev->dev); + + ar9170_usb_stop(&aru->common); + if (err) + goto err_unrx; + + return; + + err_unrx: + ar9170_usb_cancel_urbs(aru); + + err_freefw: + ar9170_usb_firmware_failed(aru); +} + +static void ar9170_usb_firmware_inits(const struct firmware *fw, + void *context) +{ + struct ar9170_usb *aru = context; + int err; + + if (!fw) { + dev_err(&aru->udev->dev, "file with init values not found.\n"); + ar9170_usb_firmware_failed(aru); + return; + } + + aru->init_values = fw; + + /* ok so we have the init values -- get code for two-stage */ + + err = request_firmware_nowait(THIS_MODULE, 1, "ar9170-2.fw", + &aru->udev->dev, GFP_KERNEL, aru, + ar9170_usb_firmware_finish); + if (err) + ar9170_usb_firmware_failed(aru); +} + +static void ar9170_usb_firmware_step2(const struct firmware *fw, void *context) +{ + struct ar9170_usb *aru = context; + int err; + + if (fw) { + ar9170_usb_firmware_finish(fw, context); + return; + } + + if (aru->req_one_stage_fw) { + dev_err(&aru->udev->dev, "ar9170.fw firmware file " + "not found and is required for this device\n"); + ar9170_usb_firmware_failed(aru); + return; + } + + dev_err(&aru->udev->dev, "ar9170.fw firmware file " + "not found, trying old firmware...\n"); + + err = request_firmware_nowait(THIS_MODULE, 1, "ar9170-1.fw", + &aru->udev->dev, GFP_KERNEL, aru, + ar9170_usb_firmware_inits); + if (err) + ar9170_usb_firmware_failed(aru); +} + static bool ar9170_requires_one_stage(const struct usb_device_id *id) { if (!id->driver_info) @@ -814,33 +874,9 @@ static int ar9170_usb_probe(struct usb_interface *intf, if (err) goto err_freehw; - err = ar9170_usb_request_firmware(aru); - if (err) - goto err_freehw; - - err = ar9170_usb_init_device(aru); - if (err) - goto err_freefw; - - err = ar9170_usb_open(ar); - if (err) - goto err_unrx; - - err = ar9170_register(ar, &udev->dev); - - ar9170_usb_stop(ar); - if (err) - goto err_unrx; - - return 0; - -err_unrx: - ar9170_usb_cancel_urbs(aru); - -err_freefw: - release_firmware(aru->init_values); - release_firmware(aru->firmware); - + return request_firmware_nowait(THIS_MODULE, 1, "ar9170.fw", + &aru->udev->dev, GFP_KERNEL, aru, + ar9170_usb_firmware_step2); err_freehw: usb_set_intfdata(intf, NULL); usb_put_dev(udev); @@ -860,12 +896,12 @@ static void ar9170_usb_disconnect(struct usb_interface *intf) ar9170_unregister(&aru->common); ar9170_usb_cancel_urbs(aru); - release_firmware(aru->init_values); - release_firmware(aru->firmware); - usb_put_dev(aru->udev); usb_set_intfdata(intf, NULL); ieee80211_free_hw(aru->common.hw); + + release_firmware(aru->init_values); + release_firmware(aru->firmware); } #ifdef CONFIG_PM -- cgit v0.10.2 From b08dfd0435333818a03b38867c556ebcbb3abc02 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 29 Jan 2010 11:54:56 -0800 Subject: iwlwifi: load firmware asynchronously before mac80211 registration At the wireless summit in Portland we discussed a way of loading firmware asynchronously from ->probe() before registration to mac80211, in order to register with the wireless subsystems with complete information in cases where firmware is required to know parameters. This is not yet the case in iwlwifi, but for some new features we're working on it will be the case since those will only be supported by new firmware images. Hence, to start with, convert iwlwifi to load firmware asynchronously from probe, unbinding the device when firmware loading fails, and only registering with the wireless subsystems after firmware has been loaded successfully. Future patches will hook into this to register the new firmware capabilities, depending on the firmware API version. Signed-off-by: Johannes Berg Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 6aeb82b..47b0214 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1463,59 +1463,66 @@ static void iwl_nic_start(struct iwl_priv *priv) } +static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); +static int iwl_mac_setup_register(struct iwl_priv *priv); + +static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first) +{ + const char *name_pre = priv->cfg->fw_name_pre; + + if (first) + priv->fw_index = priv->cfg->ucode_api_max; + else + priv->fw_index--; + + if (priv->fw_index < priv->cfg->ucode_api_min) { + IWL_ERR(priv, "no suitable firmware found!\n"); + return -ENOENT; + } + + sprintf(priv->firmware_name, "%s%d%s", + name_pre, priv->fw_index, ".ucode"); + + IWL_DEBUG_INFO(priv, "attempting to load firmware '%s'\n", + priv->firmware_name); + + return request_firmware_nowait(THIS_MODULE, 1, priv->firmware_name, + &priv->pci_dev->dev, GFP_KERNEL, priv, + iwl_ucode_callback); +} + /** - * iwl_read_ucode - Read uCode images from disk file. + * iwl_ucode_callback - callback when firmware was loaded * - * Copy into buffers for card to fetch via bus-mastering + * If loaded successfully, copies the firmware into buffers + * for the card to fetch (via DMA). */ -static int iwl_read_ucode(struct iwl_priv *priv) +static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) { + struct iwl_priv *priv = context; struct iwl_ucode_header *ucode; - int ret = -EINVAL, index; - const struct firmware *ucode_raw; - const char *name_pre = priv->cfg->fw_name_pre; const unsigned int api_max = priv->cfg->ucode_api_max; const unsigned int api_min = priv->cfg->ucode_api_min; - char buf[25]; u8 *src; size_t len; u32 api_ver, build; u32 inst_size, data_size, init_size, init_data_size, boot_size; + int err; u16 eeprom_ver; - /* Ask kernel firmware_class module to get the boot firmware off disk. - * request_firmware() is synchronous, file is in memory on return. */ - for (index = api_max; index >= api_min; index--) { - sprintf(buf, "%s%d%s", name_pre, index, ".ucode"); - ret = request_firmware(&ucode_raw, buf, &priv->pci_dev->dev); - if (ret < 0) { - IWL_ERR(priv, "%s firmware file req failed: %d\n", - buf, ret); - if (ret == -ENOENT) - continue; - else - goto error; - } else { - if (index < api_max) - IWL_ERR(priv, "Loaded firmware %s, " - "which is deprecated. " - "Please use API v%u instead.\n", - buf, api_max); - - IWL_DEBUG_INFO(priv, "Got firmware '%s' file (%zd bytes) from disk\n", - buf, ucode_raw->size); - break; - } + if (!ucode_raw) { + IWL_ERR(priv, "request for firmware file '%s' failed.\n", + priv->firmware_name); + goto try_again; } - if (ret < 0) - goto error; + IWL_DEBUG_INFO(priv, "Loaded firmware file '%s' (%zd bytes).\n", + priv->firmware_name, ucode_raw->size); /* Make sure that we got at least the v1 header! */ if (ucode_raw->size < priv->cfg->ops->ucode->get_header_size(1)) { IWL_ERR(priv, "File size way too small!\n"); - ret = -EINVAL; - goto err_release; + goto try_again; } /* Data from ucode file: header followed by uCode images */ @@ -1540,10 +1547,9 @@ static int iwl_read_ucode(struct iwl_priv *priv) IWL_ERR(priv, "Driver unable to support your firmware API. " "Driver supports v%u, firmware is v%u.\n", api_max, api_ver); - priv->ucode_ver = 0; - ret = -EINVAL; - goto err_release; + goto try_again; } + if (api_ver != api_max) IWL_ERR(priv, "Firmware has old API version. Expected v%u, " "got v%u. New firmware can be obtained " @@ -1585,6 +1591,12 @@ static int iwl_read_ucode(struct iwl_priv *priv) IWL_DEBUG_INFO(priv, "f/w package hdr boot inst size = %u\n", boot_size); + /* + * For any of the failures below (before allocating pci memory) + * we will try to load a version with a smaller API -- maybe the + * user just got a corrupted version of the latest API. + */ + /* Verify size of file vs. image size info in file's header */ if (ucode_raw->size != priv->cfg->ops->ucode->get_header_size(api_ver) + @@ -1594,41 +1606,35 @@ static int iwl_read_ucode(struct iwl_priv *priv) IWL_DEBUG_INFO(priv, "uCode file size %d does not match expected size\n", (int)ucode_raw->size); - ret = -EINVAL; - goto err_release; + goto try_again; } /* Verify that uCode images will fit in card's SRAM */ if (inst_size > priv->hw_params.max_inst_size) { IWL_DEBUG_INFO(priv, "uCode instr len %d too large to fit in\n", inst_size); - ret = -EINVAL; - goto err_release; + goto try_again; } if (data_size > priv->hw_params.max_data_size) { IWL_DEBUG_INFO(priv, "uCode data len %d too large to fit in\n", data_size); - ret = -EINVAL; - goto err_release; + goto try_again; } if (init_size > priv->hw_params.max_inst_size) { IWL_INFO(priv, "uCode init instr len %d too large to fit in\n", init_size); - ret = -EINVAL; - goto err_release; + goto try_again; } if (init_data_size > priv->hw_params.max_data_size) { IWL_INFO(priv, "uCode init data len %d too large to fit in\n", init_data_size); - ret = -EINVAL; - goto err_release; + goto try_again; } if (boot_size > priv->hw_params.max_bsm_size) { IWL_INFO(priv, "uCode boot instr len %d too large to fit in\n", boot_size); - ret = -EINVAL; - goto err_release; + goto try_again; } /* Allocate ucode buffers for card's bus-master loading ... */ @@ -1712,20 +1718,36 @@ static int iwl_read_ucode(struct iwl_priv *priv) IWL_DEBUG_INFO(priv, "Copying (but not loading) boot instr len %Zd\n", len); memcpy(priv->ucode_boot.v_addr, src, len); + /************************************************** + * This is still part of probe() in a sense... + * + * 9. Setup and register with mac80211 and debugfs + **************************************************/ + err = iwl_mac_setup_register(priv); + if (err) + goto out_unbind; + + err = iwl_dbgfs_register(priv, DRV_NAME); + if (err) + IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); + /* We have our copies now, allow OS release its copies */ release_firmware(ucode_raw); - return 0; + return; + + try_again: + /* try next, if any */ + if (iwl_request_firmware(priv, false)) + goto out_unbind; + release_firmware(ucode_raw); + return; err_pci_alloc: IWL_ERR(priv, "failed to allocate pci memory\n"); - ret = -ENOMEM; iwl_dealloc_ucode_pci(priv); - - err_release: + out_unbind: + device_release_driver(&priv->pci_dev->dev); release_firmware(ucode_raw); - - error: - return ret; } static const char *desc_lookup_text[] = { @@ -2667,21 +2689,7 @@ static int iwl_mac_start(struct ieee80211_hw *hw) /* we should be verifying the device is ready to be opened */ mutex_lock(&priv->mutex); - - /* fetch ucode file from disk, alloc and copy to bus-master buffers ... - * ucode filename and max sizes are card-specific. */ - - if (!priv->ucode_code.len) { - ret = iwl_read_ucode(priv); - if (ret) { - IWL_ERR(priv, "Could not read microcode: %d\n", ret); - mutex_unlock(&priv->mutex); - return ret; - } - } - ret = __iwl_up(priv); - mutex_unlock(&priv->mutex); if (ret) @@ -3654,17 +3662,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) iwl_power_initialize(priv); iwl_tt_initialize(priv); - /************************************************** - * 9. Setup and register with mac80211 and debugfs - **************************************************/ - err = iwl_mac_setup_register(priv); + err = iwl_request_firmware(priv, true); if (err) goto out_remove_sysfs; - err = iwl_dbgfs_register(priv, DRV_NAME); - if (err) - IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); - return 0; out_remove_sysfs: diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index ab891b9..6054c5f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1132,6 +1132,7 @@ struct iwl_priv { u8 rev_id; /* uCode images, save to reload in case of failure */ + int fw_index; /* firmware we're trying to load */ u32 ucode_ver; /* version of ucode, copy of iwl_ucode.ver */ struct fw_desc ucode_code; /* runtime inst */ @@ -1142,6 +1143,7 @@ struct iwl_priv { struct fw_desc ucode_boot; /* bootstrap inst */ enum ucode_type ucode_type; u8 ucode_write_complete; /* the image write is complete */ + char firmware_name[25]; struct iwl_rxon_time_cmd rxon_timing; -- cgit v0.10.2 From ac91d85456372a90af5b85eb6620fd2efb1e431b Mon Sep 17 00:00:00 2001 From: Lai Jiangshan Date: Tue, 2 Mar 2010 17:54:50 +0800 Subject: tracing: Fix warning in s_next of trace file ops This warning in s_next() can be triggered by lseek(): [] ? s_next+0x77/0x80 [] warn_slowpath_common+0x81/0xa0 [] ? s_next+0x77/0x80 [] warn_slowpath_null+0x1a/0x20 [] s_next+0x77/0x80 [] traverse+0x117/0x200 [] seq_lseek+0xa3/0x120 [] ? seq_lseek+0x0/0x120 [] vfs_llseek+0x41/0x50 [] sys_llseek+0x66/0xa0 [] sysenter_do_call+0x12/0x26 The iterator "leftover" variable is zeroed in the opening of the trace file. But lseek can call s_start() which will call s_next() without reseting the "leftover" variable back to zero, which might trigger the WARN_ON_ONCE(iter->leftover) that is in s_next(). Cc: stable@kernel.org Signed-off-by: Lai Jiangshan LKML-Reference: <4B8CE06A.9090207@cn.fujitsu.com> Signed-off-by: Steven Rostedt diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 032c57c..5edf410 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1703,6 +1703,7 @@ static void *s_start(struct seq_file *m, loff_t *pos) ftrace_enable_cpu(); + iter->leftover = 0; for (p = iter; p && l < *pos; p = s_next(m, p, &l)) ; -- cgit v0.10.2 From 29044ad1509ecc229f1d5a31aeed7a8dc61a71c4 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Wed, 3 Mar 2010 02:25:22 +0100 Subject: x86/stacktrace: Don't dereference bad frame pointers Callers of a stacktrace might pass bad frame pointers. Those are usually checked for safety in stack walking helpers before any dereferencing, but this is not the case when we need to go through one more frame pointer that backlinks the irq stack to the previous one, as we don't have any reliable address boudaries to compare this frame pointer against. This raises crashes when we record callchains for ftrace events with perf because we don't use the right helpers to capture registers there. We get wrong frame pointers as we call task_pt_regs() even on kernel threads, which is a wrong thing as it gives us the initial state of any kernel threads freshly created. This is even not what we want for user tasks. What we want is a hot snapshot of registers when the ftrace event triggers, not the state before a task entered the kernel. This requires more thoughts to do it correctly though. So first put a guardian to ensure the given frame pointer can be dereferenced to avoid crashes. We'll think about how to fix the callers in a subsequent patch. Signed-off-by: Frederic Weisbecker Cc: Ingo Molnar Cc: Thomas Gleixner Cc: H. Peter Anvin Cc: Peter Zijlstra Cc: Paul Mackerras Cc: Steven Rostedt Cc: 2.6.33.x Cc: Arnaldo Carvalho de Melo diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c index 0ad9597..a6c906c 100644 --- a/arch/x86/kernel/dumpstack_64.c +++ b/arch/x86/kernel/dumpstack_64.c @@ -125,9 +125,15 @@ fixup_bp_irq_link(unsigned long bp, unsigned long *stack, { #ifdef CONFIG_FRAME_POINTER struct stack_frame *frame = (struct stack_frame *)bp; + unsigned long next; - if (!in_irq_stack(stack, irq_stack, irq_stack_end)) - return (unsigned long)frame->next_frame; + if (!in_irq_stack(stack, irq_stack, irq_stack_end)) { + if (!probe_kernel_address(&frame->next_frame, next)) + return next; + else + WARN_ONCE(1, "Perf: bad frame pointer = %p in " + "callchain\n", &frame->next_frame); + } #endif return bp; } -- cgit v0.10.2 From 87c1e12b5eeb7b30b4b41291bef8e0b41fc3dde9 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 2 Mar 2010 02:51:56 +0000 Subject: ipsec: Fix bogus bundle flowi When I merged the bundle creation code, I introduced a bogus flowi value in the bundle. Instead of getting from the caller, it was instead set to the flow in the route object, which is totally different. The end result is that the bundles we created never match, and we instead end up with an ever growing bundle list. Thanks to Jamal for find this problem. Reported-by: Jamal Hadi Salim Signed-off-by: Herbert Xu Acked-by: Steffen Klassert Acked-by: Jamal Hadi Salim Signed-off-by: David S. Miller diff --git a/include/net/xfrm.h b/include/net/xfrm.h index a7df327..d74e080 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -275,7 +275,8 @@ struct xfrm_policy_afinfo { struct dst_entry *dst, int nfheader_len); int (*fill_dst)(struct xfrm_dst *xdst, - struct net_device *dev); + struct net_device *dev, + struct flowi *fl); }; extern int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo); diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 67107d6..e4a1483 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c @@ -91,11 +91,12 @@ static int xfrm4_init_path(struct xfrm_dst *path, struct dst_entry *dst, return 0; } -static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev) +static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, + struct flowi *fl) { struct rtable *rt = (struct rtable *)xdst->route; - xdst->u.rt.fl = rt->fl; + xdst->u.rt.fl = *fl; xdst->u.dst.dev = dev; dev_hold(dev); diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index dbdc696..ae18165 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c @@ -116,7 +116,8 @@ static int xfrm6_init_path(struct xfrm_dst *path, struct dst_entry *dst, return 0; } -static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev) +static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, + struct flowi *fl) { struct rt6_info *rt = (struct rt6_info*)xdst->route; diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 34a5ef8..843e066 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -1372,7 +1372,8 @@ static inline int xfrm_init_path(struct xfrm_dst *path, struct dst_entry *dst, return err; } -static inline int xfrm_fill_dst(struct xfrm_dst *xdst, struct net_device *dev) +static inline int xfrm_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, + struct flowi *fl) { struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(xdst->u.dst.ops->family); @@ -1381,7 +1382,7 @@ static inline int xfrm_fill_dst(struct xfrm_dst *xdst, struct net_device *dev) if (!afinfo) return -EINVAL; - err = afinfo->fill_dst(xdst, dev); + err = afinfo->fill_dst(xdst, dev, fl); xfrm_policy_put_afinfo(afinfo); @@ -1486,7 +1487,7 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy, for (dst_prev = dst0; dst_prev != dst; dst_prev = dst_prev->child) { struct xfrm_dst *xdst = (struct xfrm_dst *)dst_prev; - err = xfrm_fill_dst(xdst, dev); + err = xfrm_fill_dst(xdst, dev, fl); if (err) goto free_dst; -- cgit v0.10.2 From 48a29516e8b0b8cd59f5afec90a14f49dd9cf967 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 2 Mar 2010 22:46:10 +0000 Subject: cpmac: use after free The original code dereferenced "cpmac_mii" after calling "mdiobus_free(cpmac_mii);" Signed-off-by: Dan Carpenter Reviewed-by: Jiri Pirko Signed-off-by: David S. Miller diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c index b85c81f..9d48942 100644 --- a/drivers/net/cpmac.c +++ b/drivers/net/cpmac.c @@ -1290,8 +1290,8 @@ void __devexit cpmac_exit(void) { platform_driver_unregister(&cpmac_driver); mdiobus_unregister(cpmac_mii); - mdiobus_free(cpmac_mii); iounmap(cpmac_mii->priv); + mdiobus_free(cpmac_mii); } module_init(cpmac_init); -- cgit v0.10.2 From 9fe969345b10931319b3f1e7034fbdeb786de234 Mon Sep 17 00:00:00 2001 From: Sarveshwar Bandi Date: Tue, 2 Mar 2010 22:37:28 +0000 Subject: be2net: download NCSI section during firmware update Adding code to update NCSI section while updating firmware on the controller. Signed-off-by: Sarveshwar Bandi Signed-off-by: David S. Miller diff --git a/drivers/net/benet/be_hw.h b/drivers/net/benet/be_hw.h index 5ffb149..2d4a4b8 100644 --- a/drivers/net/benet/be_hw.h +++ b/drivers/net/benet/be_hw.h @@ -114,8 +114,7 @@ #define IMG_TYPE_ISCSI_BACKUP 9 #define IMG_TYPE_FCOE_FW_ACTIVE 10 #define IMG_TYPE_FCOE_FW_BACKUP 11 -#define IMG_TYPE_NCSI_BITFILE 13 -#define IMG_TYPE_NCSI_8051 14 +#define IMG_TYPE_NCSI_FW 13 #define FLASHROM_OPER_FLASH 1 #define FLASHROM_OPER_SAVE 2 @@ -127,6 +126,7 @@ #define FLASH_IMAGE_MAX_SIZE_g3 (2097152) /* Max fw image size */ #define FLASH_BIOS_IMAGE_MAX_SIZE_g3 (524288) /* Max OPTION ROM img sz */ #define FLASH_REDBOOT_IMAGE_MAX_SIZE_g3 (1048576) /* Max Redboot image sz */ +#define FLASH_NCSI_IMAGE_MAX_SIZE_g3 (262144) /* Max NSCI image sz */ #define FLASH_NCSI_MAGIC (0x16032009) #define FLASH_NCSI_DISABLED (0) @@ -144,6 +144,7 @@ #define FLASH_FCoE_BIOS_START_g2 (524288) #define FLASH_REDBOOT_START_g2 (0) +#define FLASH_NCSI_START_g3 (15990784) #define FLASH_iSCSI_PRIMARY_IMAGE_START_g3 (2097152) #define FLASH_iSCSI_BACKUP_IMAGE_START_g3 (4194304) #define FLASH_FCoE_PRIMARY_IMAGE_START_g3 (6291456) diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index a703ed8..22f787f 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -1880,8 +1880,9 @@ static int be_flash_data(struct be_adapter *adapter, const u8 *p = fw->data; struct be_cmd_write_flashrom *req = flash_cmd->va; struct flash_comp *pflashcomp; + int num_comp; - struct flash_comp gen3_flash_types[8] = { + struct flash_comp gen3_flash_types[9] = { { FLASH_iSCSI_PRIMARY_IMAGE_START_g3, IMG_TYPE_ISCSI_ACTIVE, FLASH_IMAGE_MAX_SIZE_g3}, { FLASH_REDBOOT_START_g3, IMG_TYPE_REDBOOT, @@ -1897,7 +1898,9 @@ static int be_flash_data(struct be_adapter *adapter, { FLASH_FCoE_PRIMARY_IMAGE_START_g3, IMG_TYPE_FCOE_FW_ACTIVE, FLASH_IMAGE_MAX_SIZE_g3}, { FLASH_FCoE_BACKUP_IMAGE_START_g3, IMG_TYPE_FCOE_FW_BACKUP, - FLASH_IMAGE_MAX_SIZE_g3} + FLASH_IMAGE_MAX_SIZE_g3}, + { FLASH_NCSI_START_g3, IMG_TYPE_NCSI_FW, + FLASH_NCSI_IMAGE_MAX_SIZE_g3} }; struct flash_comp gen2_flash_types[8] = { { FLASH_iSCSI_PRIMARY_IMAGE_START_g2, IMG_TYPE_ISCSI_ACTIVE, @@ -1921,11 +1924,16 @@ static int be_flash_data(struct be_adapter *adapter, if (adapter->generation == BE_GEN3) { pflashcomp = gen3_flash_types; filehdr_size = sizeof(struct flash_file_hdr_g3); + num_comp = 9; } else { pflashcomp = gen2_flash_types; filehdr_size = sizeof(struct flash_file_hdr_g2); + num_comp = 8; } - for (i = 0; i < 8; i++) { + for (i = 0; i < num_comp; i++) { + if ((pflashcomp[i].optype == IMG_TYPE_NCSI_FW) && + memcmp(adapter->fw_ver, "3.102.148.0", 11) < 0) + continue; if ((pflashcomp[i].optype == IMG_TYPE_REDBOOT) && (!be_flash_redboot(adapter, fw->data, pflashcomp[i].offset, pflashcomp[i].size, -- cgit v0.10.2 From 1162563f82b434e3099c9e6c1bbdba846d792f0d Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Tue, 2 Mar 2010 20:40:01 +0000 Subject: af_packet: move strict addr_len check right before dev_[mc/unicast]_[add/del] My previous patch 914c8ad2d18b62ad1420f518c0cab0b0b90ab308 incorrectly changed the length check in packet_mc_add to be more strict. The problem is that userspace is not filling this field (and it stays zeroed) in case of setting PACKET_MR_PROMISC or PACKET_MR_ALLMULTI. So move the strict check to the point in path where the addr_len must be set correctly. Signed-off-by: Jiri Pirko Reported-by: Pavel Roskin Signed-off-by: David S. Miller diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 031a5e6..1612d41 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -1688,6 +1688,8 @@ static int packet_dev_mc(struct net_device *dev, struct packet_mclist *i, { switch (i->type) { case PACKET_MR_MULTICAST: + if (i->alen != dev->addr_len) + return -EINVAL; if (what > 0) return dev_mc_add(dev, i->addr, i->alen, 0); else @@ -1700,6 +1702,8 @@ static int packet_dev_mc(struct net_device *dev, struct packet_mclist *i, return dev_set_allmulti(dev, what); break; case PACKET_MR_UNICAST: + if (i->alen != dev->addr_len) + return -EINVAL; if (what > 0) return dev_unicast_add(dev, i->addr); else @@ -1734,7 +1738,7 @@ static int packet_mc_add(struct sock *sk, struct packet_mreq_max *mreq) goto done; err = -EINVAL; - if (mreq->mr_alen != dev->addr_len) + if (mreq->mr_alen > dev->addr_len) goto done; err = -ENOBUFS; -- cgit v0.10.2 From d4612cb86ed8db8956b6b19435f8a30de6c67ffe Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 2 Mar 2010 15:48:23 +0000 Subject: Bluetooth: Use single_open() for inquiry cache within debugfs The inquiry cache information in debugfs should be using seq_file support and not allocating memory on the stack for the string. Since the usage of these information is really seldom, using single_open() for it is good enough. Signed-off-by: Marcel Holtmann Signed-off-by: David S. Miller diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index 1a79a6c..cafb55b 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -405,20 +406,11 @@ static struct device_type bt_host = { .release = bt_host_release, }; -static int inquiry_cache_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t inquiry_cache_read(struct file *file, char __user *userbuf, - size_t count, loff_t *ppos) +static int inquiry_cache_show(struct seq_file *f, void *p) { - struct hci_dev *hdev = file->private_data; + struct hci_dev *hdev = f->private; struct inquiry_cache *cache = &hdev->inq_cache; struct inquiry_entry *e; - char buf[4096]; - int n = 0; hci_dev_lock_bh(hdev); @@ -426,23 +418,30 @@ static ssize_t inquiry_cache_read(struct file *file, char __user *userbuf, struct inquiry_data *data = &e->data; bdaddr_t bdaddr; baswap(&bdaddr, &data->bdaddr); - n += sprintf(buf + n, "%s %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n", - batostr(&bdaddr), - data->pscan_rep_mode, data->pscan_period_mode, - data->pscan_mode, data->dev_class[2], - data->dev_class[1], data->dev_class[0], - __le16_to_cpu(data->clock_offset), - data->rssi, data->ssp_mode, e->timestamp); + seq_printf(f, "%s %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n", + batostr(&bdaddr), + data->pscan_rep_mode, data->pscan_period_mode, + data->pscan_mode, data->dev_class[2], + data->dev_class[1], data->dev_class[0], + __le16_to_cpu(data->clock_offset), + data->rssi, data->ssp_mode, e->timestamp); } hci_dev_unlock_bh(hdev); - return simple_read_from_buffer(userbuf, count, ppos, buf, n); + return 0; +} + +static int inquiry_cache_open(struct inode *inode, struct file *file) +{ + return single_open(file, inquiry_cache_show, inode->i_private); } static const struct file_operations inquiry_cache_fops = { - .open = inquiry_cache_open, - .read = inquiry_cache_read, + .open = inquiry_cache_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, }; int hci_register_sysfs(struct hci_dev *hdev) -- cgit v0.10.2 From bf829370a8d664d87a61697c8a0d6d780c336aa4 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 2 Mar 2010 22:22:41 +0000 Subject: cassini: fix off by one There are only 6 link_modes. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index 7cbcfb0..9bd155e 100644 --- a/drivers/net/cassini.c +++ b/drivers/net/cassini.c @@ -5072,7 +5072,7 @@ static int __devinit cas_init_one(struct pci_dev *pdev, INIT_WORK(&cp->reset_task, cas_reset_task); /* Default link parameters */ - if (link_mode >= 0 && link_mode <= 6) + if (link_mode >= 0 && link_mode < 6) cp->link_cntl = link_modes[link_mode]; else cp->link_cntl = BMCR_ANENABLE; -- cgit v0.10.2 From 4d27b87785a743fdae653d395a3a4e763269c53c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 2 Mar 2010 21:07:24 +0000 Subject: davinci_emac: off by one This off by one error was found by smatch. drivers/net/davinci_emac.c +2390 emac_dev_open(13) error: buffer overflow 'priv->mac_addr' 6 <= 6 Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index 1ac9440..32960b9 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c @@ -2385,7 +2385,7 @@ static int emac_dev_open(struct net_device *ndev) struct emac_priv *priv = netdev_priv(ndev); netif_carrier_off(ndev); - for (cnt = 0; cnt <= ETH_ALEN; cnt++) + for (cnt = 0; cnt < ETH_ALEN; cnt++) ndev->dev_addr[cnt] = priv->mac_addr[cnt]; /* Configuration items */ -- cgit v0.10.2 From 4d63cb4d8638fdf2e3bf874936335a08e3b5d8fe Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Wed, 3 Mar 2010 01:09:21 -0800 Subject: bnx2x: Removed FW 5.2.7 Removed FW 5.2.7. Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller diff --git a/firmware/bnx2x-e1-5.2.7.0.fw.ihex b/firmware/bnx2x-e1-5.2.7.0.fw.ihex deleted file mode 100644 index a99c41c..0000000 --- a/firmware/bnx2x-e1-5.2.7.0.fw.ihex +++ /dev/null @@ -1,10178 +0,0 @@ -:10000000000028B0000000600000068800002918E9 -:100010000000161400002FA800000098000045C042 -:10002000000073C400004660000000CC0000BA2845 -:10003000000099A00000BAF800000094000154A04C -:10004000000057BC00015538000000B80001ACF8B2 -:100050000000CE2C0001ADB80000000400027BE8D7 -:10006000020400480000000F020400540000004594 -:1000700002040058000000840204005C0000000636 -:100080000204007000000004020400780000000078 -:100090000204007C121700000204008022170000F6 -:1000A00002040084321700000604008800000005E6 -:1000B0000204009C12150000020400A0221500009A -:1000C000020400A432150000060400A80000000489 -:1000D000020400B802100000020400BC001000007E -:1000E000020400C010100000020400C42010000030 -:1000F000020400C830100000060400CC0000000418 -:10010000020400DC00100000020400E012140000F1 -:10011000020400E422140000020400E8321400008B -:10012000060400EC000000040104012400000000AB -:1001300001040128000000000104012C000000005F -:10014000010401300000000002040004000000FF70 -:1001500002040008000000FF0204000C000000FF81 -:1001600002040010000000FF02040014000000FF61 -:1001700002040018000000FF0204001C000000FF41 -:1001800002040020000000FF020400240000003EE2 -:1001900002040028000000000204002C0000003FC0 -:1001A000020400300000003F020400340000003F61 -:1001B00002040038000000000204003C0000003F80 -:1001C000020400400000003F020400440000003F21 -:1001D00002042008000004110204200C00000400A6 -:1001E000020420100000040402042014000004197A -:1001F0000204201C0000FFFF020420200000FFFF7B -:10020000020420240000FFFF020420280000FFFF5A -:1002100006042038000000020204204000000034E0 -:100220000204204400000035060420480000007C41 -:100230000204223807FFFFFF0204223C0000003FB7 -:100240000204224007FFFFFF020422440000000FC7 -:1002500001042248000000000104224C00000000BC -:10026000010422500000000001042254000000009C -:1002700001042258000000000104225C000000007C -:10028000010422600000000001042264000000005C -:1002900001042268000000000104226C000000003C -:1002A000010422700000000001042274000000001C -:1002B00001042278000000000104227C00000000FC -:1002C000020424BC000000010C042000000003E82C -:1002D0000A042000000000010B0420000000000AB6 -:1002E0000205004400000020020500480000003222 -:1002F000020500900215002002050094021500205E -:1003000002050098000000300205009C0810000063 -:10031000020500A000000033020500A40000003028 -:10032000020500A800000031020500AC0000000238 -:10033000020500B000000005020500B40000000640 -:10034000020500B800000002020500BC0000000227 -:10035000020500C000000000020500C40000000506 -:10036000020500C800000002020500CC00000002E7 -:10037000020500D000000002020500D400000001C8 -:1003800002050114000000010205011C000000012B -:100390000205012000000002020502040000000125 -:1003A0000205020C0000004002050210000000409F -:1003B0000205021C000000200205022000000013BC -:1003C0000205022400000020060502400000000A89 -:1003D0000405028000200000020500500000000714 -:1003E0000205005400000007020500580000000844 -:1003F0000205005C00000008060500600000000423 -:10040000020500D800000006020500E00000000D13 -:10041000020500E40000002D020500E800000007CE -:10042000020500EC00000027020500F000000007B4 -:10043000020500F400000027020500F80000000794 -:10044000020500FC00000027020500040000000176 -:1004500002050008000000010205000C0000000178 -:100460000205001000000001020500140000000158 -:1004700002050018000000010205001C0000000138 -:100480000205002000000001020500240000000118 -:1004900002050028000000010205002C00000001F8 -:1004A00002050030000000010205003400000001D8 -:1004B00002050038000000010205003C00000001B8 -:1004C00002050040000000010406100002000020A8 -:1004D000020600DC00000001010600D80000000058 -:1004E0000406020000030220020600DC00000000F7 -:1004F00002060068000000B802060078000001143F -:10050000010600B800000000010600C8000000005D -:100510000206006C000000B80206007C0000011416 -:10052000010600BC00000000010600CC0000000035 -:100530000718040000960000081807600014022342 -:10054000071C000034C50000071C800034DB0D329E -:10055000071D00000A1D1A69081D14405D78022558 -:100560000118000000000000011800040000000055 -:1005700001180008000000000118000C0000000035 -:100580000118001000000000011800140000000015 -:1005900002180020000000010218002400000002E0 -:1005A00002180028000000030218002C00000000C0 -:1005B000021800300000000402180034000000019E -:1005C00002180038000000000218003C0000000182 -:1005D000021800400000000402180044000000005F -:1005E00002180048000000010218004C000000033F -:1005F0000218005000000000021800540000000122 -:1006000002180058000000040218005C00000000FE -:1006100002180060000000010218006400000003DE -:1006200002180068000000000218006C00000001C1 -:10063000021800700000000402180074000000009E -:1006400002180078000000040218007C000000037B -:100650000618008000000002021800A400003FFFFE -:10066000021800A8000003FF021802240000000086 -:1006700002180234000000000218024C00000000C2 -:10068000021802E4000000FF061810000000040039 -:10069000021B8BC000000001021B80000000003420 -:1006A000021B804000000018021B80800000000C2C -:1006B000021B80C0000000200C1B83000007A1204B -:1006C0000A1B8300000001380B1B83000000138805 -:1006D000021B83C0000001F4061A2000000000B2D3 -:1006E000061A23C800000181041A29CC0001022740 -:1006F000061A1020000000C8061A100000000002B0 -:10070000061A1E3800000002061A1E300000000201 -:10071000061A080000000002061A0808000000027D -:10072000061A081000000004041A1FB00005022871 -:10073000041A4CB00008022D061A22C8000000203E -:10074000061A400000000124021A4920000000009F -:10075000061A14000000000A061A145000000006D1 -:10076000061A150000000002041A150800050235DB -:10077000061A151C00000009061A15800000001456 -:10078000061A09C000000048061A0800000000020E -:10079000061A08200000000E041A1FB00002023AD8 -:1007A000061A2C2800000002061A23480000002028 -:1007B000061A449000000124021A49240000000097 -:1007C000061A14280000000A061A14680000000621 -:1007D000061A154000000002041A15480005023CE4 -:1007E000061A155C00000009061A15D00000001456 -:1007F000061A0AE000000048061A08080000000275 -:10080000061A08580000000E041A1FB80002024120 -:10081000061A2C30000000020200A2800000000135 -:100820000200A294071D29110200A29800000000F6 -:100830000200A29C009C04240200A2A00000000070 -:100840000200A2A4000002090200A4FCFF000000B4 -:10085000020100B400000001020100B80000000124 -:10086000020100DC000000010201010000000001A3 -:1008700002010104000000010201007C00300000C0 -:1008800002010084000000280201008C000000002A -:1008900002010130000000040201025C00000001BE -:1008A000020103280000000002010554000000308E -:1008B000020100C400000001020100CC00000001A0 -:1008C000020100F800000001020100F00000000138 -:1008D00002010080003000000201008800000028B2 -:1008E0000201009000000000020101340000000439 -:1008F000020102DC000000010201032C00000000E4 -:100900000201056400000030020100C8000000017F -:10091000020100D000000001020100FC0000000103 -:10092000020100F400000001020C10000000002091 -:10093000020C200800000A11020C200C00000A0022 -:10094000020C201000000A04020C201C0000FFFF13 -:10095000020C20200000FFFF020C20240000FFFFFB -:10096000020C20280000FFFF060C203800000002C7 -:10097000020C204000000034020C2044000000352E -:10098000020C204800000020020C204C0000002136 -:10099000020C205000000022020C20540000002312 -:1009A000020C205800000024020C205C00000025EE -:1009B000020C206000000026020C206400000027CA -:1009C000020C206800000028020C206C00000029A6 -:1009D000020C20700000002A020C20740000002B82 -:1009E000060C207800000056020C21D00000000107 -:1009F000020C21D400000001020C21D800000001EB -:100A0000020C21DC00000001020C21E000000001CA -:100A1000020C21E400000001020C21E800000001AA -:100A2000020C21EC00000001020C21F0000000018A -:100A3000020C21F400000001060C21F80000001057 -:100A4000020C223807FFFFFF020C223C0000003F8F -:100A5000020C224007FFFFFF020C22440000000F9F -:100A6000010C224800000000010C224C0000000094 -:100A7000010C225000000000010C22540000000074 -:100A8000010C225800000000010C225C0000000054 -:100A9000010C226000000000010C22640000000034 -:100AA000010C226800000000010C226C0000000014 -:100AB000010C227000000000010C227400000000F4 -:100AC000010C227800000000010C227C00000000D4 -:100AD000020C24BC000000010C0C2000000003E804 -:100AE0000A0C2000000000010B0C20000000000A8E -:100AF000020C400800000365020C400C0000035487 -:100B0000020C401000000358020C40140000037552 -:100B1000020C401C0000FFFF020C40200000FFFF01 -:100B2000020C40240000FFFF020C40280000FFFFE1 -:100B3000020C403800000046020C403C000000055A -:100B4000060C40400000005E020C41B800000001AD -:100B5000060C41BC0000001F020C423807FFFFFFDB -:100B6000020C423C0000003F020C424007FFFFFF26 -:100B7000020C42440000000F010C4248000000003B -:100B8000010C424C00000000010C4250000000002B -:100B9000010C425400000000010C4258000000000B -:100BA000010C425C00000000010C426000000000EB -:100BB000010C426400000000010C426800000000CB -:100BC000010C426C00000000010C427000000000AB -:100BD000010C427400000000010C4278000000008B -:100BE000010C427C00000000010C4280000000006B -:100BF000020C44C0000000010C0C4000000003E89F -:100C00000A0C4000000000010B0C40000000000A2C -:100C1000020D004400000032020D008C021500207D -:100C2000020D009002150020020D00940810000033 -:100C3000020D009800000033020D009C000000022D -:100C4000020D00A000000000020D00A4000000053D -:100C5000020D00A800000005060D00AC0000000217 -:100C6000020D00B400000002020D00B800000003F5 -:100C7000020D00BC00000002020D00C000000001D7 -:100C8000020D00C800000002020D00CC00000002AE -:100C9000020D010800000001020D015C00000001CE -:100CA000020D016400000001020D01680000000255 -:100CB000020D020400000001020D020C00000020E1 -:100CC000020D021000000040020D0214000000405E -:100CD000020D022000000003020D02240000001893 -:100CE000060D028000000012040D030000240243E0 -:100CF000020D004C00000001020D00500000000237 -:100D0000020D005400000008020D00580000000809 -:100D1000060D005C00000004020D00C40000000489 -:100D2000020D011400000009020D01180000002945 -:100D3000020D011C0000000A020D01200000002A23 -:100D4000020D012400000007020D01280000002709 -:100D5000020D012C00000007020D013000000027E9 -:100D6000020D01340000000C020D01380000002CBF -:100D7000020D013C0000000C020D01400000002C9F -:100D8000020D01440000000C020D01480000002C7F -:100D9000020D000400000001020D00080000000127 -:100DA000020D000C00000001020D00100000000107 -:100DB000020D001400000001020D001800000001E7 -:100DC000020D001C00000001020D002000000001C7 -:100DD000020D002400000001020D002800000001A7 -:100DE000020D002C00000001020D00300000000187 -:100DF000020D003400000001020D00380000000167 -:100E0000020D003C00000001020E004C0000003208 -:100E1000020E009402150020020E00980215002018 -:100E2000020E009C00000030020E00A0081000001E -:100E3000020E00A400000033020E00A800000030E3 -:100E4000020E00AC00000031020E00B000000002F3 -:100E5000020E00B400000004020E00B80000000002 -:100E6000020E00BC00000002020E00C000000002E2 -:100E7000020E00C400000000020E00C800000002C4 -:100E8000020E00CC00000007020E00D0000000029D -:100E9000020E00D400000002020E00D80000000183 -:100EA000020E00E400000001020E014400000001F7 -:100EB000020E014C00000001020E01500000000271 -:100EC000020E020400000001020E020C00000040AD -:100ED000020E021000000040020E021C000000047E -:100EE000020E022000000020020E02240000000E6C -:100EF000020E02280000001B060E03000000001274 -:100F0000040E0280001B0267020E00540000000C59 -:100F1000020E005800000009020E005C0000000FE5 -:100F2000020E006000000010060E006400000004C5 -:100F3000020E00DC00000003020E01100000000F92 -:100F4000020E01140000002F020E01180000000E16 -:100F5000020E011C0000002E020E00040000000121 -:100F6000020E000800000001020E000C000000014B -:100F7000020E001000000001020E0014000000012B -:100F8000020E001800000001020E001C000000010B -:100F9000020E002000000001020E002400000001EB -:100FA000020E002800000001020E002C00000001CB -:100FB000020E003000000001020E003400000001AB -:100FC000020E003800000001020E003C000000018B -:100FD000020E004000000001020E0044000000016B -:100FE0000730040000CA00000830076800130282BE -:100FF00007340000336100000734800037270CD924 -:10100000073500002F111AA30835708051F00284B3 -:10101000013000000000000001300004000000006A -:1010200001300008000000000130000C000000004A -:10103000013000100000000001300014000000002A -:1010400002300020000000010230002400000002F5 -:1010500002300028000000030230002C00000000D5 -:1010600002300030000000040230003400000001B3 -:1010700002300038000000000230003C0000000197 -:101080000230004000000004023000440000000074 -:1010900002300048000000010230004C0000000354 -:1010A0000230005000000000023000540000000137 -:1010B00002300058000000040230005C0000000014 -:1010C00002300060000000010230006400000003F4 -:1010D00002300068000000000230006C00000001D7 -:1010E00002300070000000040230007400000000B4 -:1010F00002300078000000040230007C0000000391 -:101100000630008000000002023000A400003FFF13 -:10111000023000A8000003FF02300224000000009B -:1011200002300234000000000230024C00000000D7 -:10113000023002E40000FFFF06302000000008003B -:1011400002338BC000000001023380000000001A4F -:10115000023380400000004E023380800000001007 -:10116000023380C0000000200C3383000007A12060 -:101170000A338300000001380B338300000013881A -:10118000023383C0000001F40C3383801DCD650061 -:101190000A3383800004C4B40B338380004C4B407B -:1011A00006321AA0000000C206321020000000C85B -:1011B0000632100000000002063214000000004059 -:1011C00006325098000000040632508000000005EE -:1011D00004325094000102860632500000000020C4 -:1011E00004322830000202870233080001000000A8 -:1011F00004330C00001002890233080000000000D4 -:1012000004330C400010029906321500000000B4AF -:1012100002321DC80000000006324000000000D865 -:10122000063217D0000000B402321DCC00000000CE -:1012300006324360000000D807200400009200003E -:1012400008200780001002A9072400002CD100000C -:10125000072480002AE50B350824DC6062DA02AB43 -:101260000120000000000000012000040000000038 -:1012700001200008000000000120000C0000000018 -:1012800001200010000000000120001400000000F8 -:1012900002200020000000010220002400000002C3 -:1012A00002200028000000030220002C00000000A3 -:1012B0000220003000000004022000340000000181 -:1012C00002200038000000000220003C0000000165 -:1012D0000220004000000004022000440000000042 -:1012E00002200048000000010220004C0000000322 -:1012F0000220005000000000022000540000000105 -:1013000002200058000000040220005C00000000E1 -:1013100002200060000000010220006400000003C1 -:1013200002200068000000000220006C00000001A4 -:101330000220007000000004022000740000000081 -:1013400002200078000000040220007C000000035E -:101350000620008000000002022000A400003FFFE1 -:10136000022000A8000003FF022002240000000069 -:1013700002200234000000000220024C00000000A5 -:10138000022002E40000FFFF062020000000080009 -:1013900002238BC000000001022380000000001027 -:1013A00002238040000000120223808000000030F1 -:1013B000022380C00000000E022383C0000001F45D -:1013C000062250000000004206221020000000C843 -:1013D000062210000000000206222000000000C0CB -:1013E000062225C00000024004222EC8000802ADDB -:1013F00002230800013FFFFF04230C00001002B588 -:10140000022308000000000004230C40001002C565 -:1014100006223040000000A00622354000000010E7 -:10142000062236C000000030062240000000020004 -:10143000062235C00000002006223840000000309F -:1014400006223000000000080222511800000000AF -:10145000062223000000000E0622241000000030A7 -:10146000062232C0000000A00622358000000010D5 -:1014700006223780000000300622480000000200EB -:10148000062236400000002006223900000000300D -:1014900006223020000000080222511C000000003B -:1014A000062223380000000E062224D0000000305F -:1014B00002161000000000280217000800000002B9 -:1014C0000217002C000000030217003C000000047B -:1014D0000217004400000008021700480000000244 -:1014E0000217004C0000009002170050000000900E -:1014F00002170054008000900217005808140000E2 -:10150000021700600000008A0217006400000080DB -:1015100002170068000000810217006C00000080C4 -:10152000021700700000000602170078000007D0C4 -:101530000217007C0000076C02170038007C1004C2 -:10154000021700040000000F0616402400000002ED -:10155000021640700000001C021642080000000144 -:101560000216421000000001021642200000000195 -:10157000021642280000000102164230000000015D -:10158000021642380000000102164260000000010D -:101590000C16401C0003D0900A16401C0000009C52 -:1015A0000B16401C000009C4021640300000000861 -:1015B000021640340000000C0216403800000010F3 -:1015C0000216404400000020021640000000000106 -:1015D000021640D800000001021640080000000179 -:1015E0000216400C0000000102164010000000012D -:1015F00002164240000000000216424800000000AF -:101600000616427000000002021642500000000060 -:101610000216425800000000061642800000000238 -:1016200002166008000006140216600C0000060096 -:1016300002166010000006040216601C0000FFFF86 -:10164000021660200000FFFF021660240000FFFF6A -:10165000021660280000FFFF02166038000000201C -:101660000216603C000000200216604000000034BA -:101670000216604400000035021660480000002396 -:101680000216604C00000024021660500000002585 -:101690000216605400000026021660580000002761 -:1016A0000216605C00000029021660600000002A3B -:1016B000021660640000002B021660680000002C17 -:1016C0000216606C0000002D0616607000000052CB -:1016D000021661B800000001061661BC0000001F80 -:1016E0000216623807FFFFFF0216623C0000003F4F -:1016F0000216624007FFFFFF021662440000000F5F -:1017000001166248000000000116624C0000000053 -:101710000116625000000000011662540000000033 -:1017200001166258000000000116625C0000000013 -:1017300001166260000000000116626400000000F3 -:1017400001166268000000000116626C00000000D3 -:1017500001166270000000000116627400000000B3 -:1017600001166278000000000116627C0000000093 -:10177000021664BC000000010C166000000003E8C3 -:101780000A166000000000010B1660000000000A4D -:10179000021680400000000602168044000000058A -:1017A000021680480000000A0216804C0000000566 -:1017B0000216805400000002021680CC00000004D3 -:1017C000021680D000000004021680D4000000043D -:1017D000021680D800000004021680DC000000041D -:1017E000021680E000000004021680E400000004FD -:1017F000021680E8000000040216880400000004BD -:10180000021680300000007C021680340000003D8B -:10181000021680380000003F0216803C0000009C49 -:10182000021680F000000007061680F40000000594 -:101830000216880C01010101021681080000000057 -:101840000216810C00000004021681100000000442 -:1018500002168114000000020216881008012004FC -:1018600002168118000000050216811C0000000508 -:1018700002168120000000050216812400000005E8 -:101880000216882C2008100102168128000000088A -:101890000216812C000000060216813000000007AD -:1018A0000216813400000000021688300101012078 -:1018B0000616813800000004021688340101010177 -:1018C0000616814800000004021688380101010153 -:1018D00006168158000000040216883C010101012F -:1018E00006168168000000030216817400000001E2 -:1018F00002168840010101010216817800000001F2 -:101900000216817C000000010216818000000001A7 -:1019100002168184000000010216884401010101C1 -:1019200002168188000000010216818C000000046C -:10193000021681900000000402168194000000024B -:10194000021688480801200402168198000000054C -:101950000216819C00000005021681A0000000050F -:10196000021681A400000005021688142008100148 -:10197000021681A800000008021681AC00000006D3 -:10198000021681B000000007021681B400000001B9 -:101990000216881801010120021681B8000000011A -:1019A000021681BC00000001021681C00000000187 -:1019B000021681C4000000010216881C0101010109 -:1019C000021681C800000001021681CC000000014F -:1019D000021681D000000001021681D4000000012F -:1019E0000216882001010101021681D800000001C1 -:1019F000021681DC00000001021681E000000001F7 -:101A0000021681E400000001021688240101010190 -:101A1000021681E800000001021681EC00000001BE -:101A2000021681F000000001021688280101010160 -:101A300002168240FFFF003F0616824400000002AB -:101A40000216824CFFFF003F021682500000010088 -:101A5000021682540000010006168258000000029F -:101A600002168260000000C002168264000000C0FE -:101A70000216826800001E000216826C00001E0022 -:101A800002168270000040000216827400004000BE -:101A900002168278000080000216827C000080001E -:101AA00002168280000020000216828400002000BE -:101AB0000616828800000007021682A400000001BA -:101AC000061682A80000000A021681F400000C0825 -:101AD000021681F800000040021681FC000001009F -:101AE0000216820000000020021682040000001787 -:101AF00002168208000000800216820C000002001C -:101B0000021682100000000002168218FFFF01FF7B -:101B100002168214FFFF01FF0216823C0000001330 -:101B2000021680900000013F021680600000014014 -:101B30000216806400000140061680680000000262 -:101B400002168070000000C00616807400000007B6 -:101B50000216809C00000048021680A00000004889 -:101B6000061680A400000002021680AC00000048A7 -:101B7000061680B0000000070216823800008000C0 -:101B800002168234000025E40216809400007FFFD4 -:101B900002168220000000070216821C00000007C7 -:101BA000021682280000000002168224FFFFFFFFB9 -:101BB00002168230000000000216822CFFFFFFFF99 -:101BC000021680EC000000FF02140000000000017B -:101BD0000214000C0000000102140040000000018B -:101BE0000214004400007FFF0214000C00000000FB -:101BF00002140000000000000214006C000000004D -:101C00000214000400000001021400300000000172 -:101C100002140004000000000214005C0000000038 -:101C2000021400080000000102140034000000014A -:101C30000214000800000000021400600000000010 -:101C40000202005800000032020200A0031500202A -:101C5000020200A403150020020200A801000030C7 -:101C6000020200AC08100000020200B000000033C5 -:101C7000020200B400000030020200B8000000318F -:101C8000020200BC00000003020200C000000006C7 -:101C9000020200C400000003020200C800000003AA -:101CA000020200CC00000002020200D0000000008E -:101CB000020200D400000002020200DC000000006A -:101CC000020200E000000006020200E4000000043E -:101CD000020200E800000002020200EC0000000224 -:101CE000020200F000000001020200FC00000006F9 -:101CF0000202012000000000020201340000000284 -:101D0000020201B0000000010202020C000000010A -:101D10000202021400000001020202180000000288 -:101D200002020404000000010202040C0000004052 -:101D300002020410000000400202041C0000000423 -:101D4000020204200000002002020424000000021D -:101D5000020204280000001F060205000000001215 -:101D600004020480001F02D5020200600000000F80 -:101D70000202006400000007020200680000000B7D -:101D80000202006C0000000E060200700000000459 -:101D9000020200F40000000402020004000000013E -:101DA00002020008000000010202000C0000000115 -:101DB00002020010000000010202001400000001F5 -:101DC00002020018000000010202001C00000001D5 -:101DD00002020020000000010202002400000001B5 -:101DE00002020028000000010202002C0000000195 -:101DF0000202003000000001020200340000000175 -:101E000002020038000000010202003C0000000154 -:101E10000202004000000001020200440000000134 -:101E200002020048000000010202004C0000000114 -:101E3000020200500000000102020108000000C878 -:101E40000202011800000002020201C400000000AA -:101E5000020201CC00000000020201D400000002D6 -:101E6000020201DC00000002020201E4000000FFA7 -:101E7000020201EC000000FF0202010C000000C899 -:101E80000202011C00000002020201C80000000062 -:101E9000020201D000000000020201D8000000028E -:101EA000020201E000000002020201E8000000FF5F -:101EB000020201F0000000FF0728040000B5000046 -:101EC00008280768001302F4072C000035D300002F -:101ED000072C80003A3E0D75072D00003B541C0571 -:101EE000072D800022BC2ADB082DC770471202F69E -:101EF000012800000000000001280004000000008C -:101F000001280008000000000128000C000000006B -:101F1000012800100000000001280014000000004B -:101F20000228002000000001022800240000000216 -:101F300002280028000000030228002C00000000F6 -:101F400002280030000000040228003400000001D4 -:101F500002280038000000000228003C00000001B8 -:101F60000228004000000004022800440000000095 -:101F700002280048000000010228004C0000000375 -:101F80000228005000000000022800540000000158 -:101F900002280058000000040228005C0000000035 -:101FA0000228006000000001022800640000000315 -:101FB00002280068000000000228006C00000001F8 -:101FC00002280070000000040228007400000000D5 -:101FD00002280078000000040228007C00000003B2 -:101FE0000628008000000002022800A400003FFF35 -:101FF000022800A8000003FF0228022400000000BD -:1020000002280234000000000228024C00000000F8 -:10201000022802E40000FFFF06282000000008005C -:10202000022B8BC000000001022B8000000000008A -:10203000022B804000000018022B80800000000C62 -:10204000022B80C0000000660C2B83000007A1203B -:102050000A2B8300000001380B2B8300000013883B -:10206000022B83C0000001F40C2B8340000001F41C -:102070000A2B8340000000000B2B8340000000056A -:102080000A2B83800004C4B40C2B83801DCD650013 -:102090000B2B8380004C4B40062A3C400000000480 -:1020A000042A3C50000202F8062A300000000048D2 -:1020B000062A1020000000C8062A100000000002B6 -:1020C000062A31280000008E022A33680000000032 -:1020D000042A3370000202FA042A3A70000402FC57 -:1020E000042A3D0000020300042A15000002030236 -:1020F000062A150800000100022A197000000000DD -:10210000022A197800000000042A19600002030462 -:10211000062A4AC000000002062A4B000000000404 -:10212000042A1F4800020306022B080000000000DA -:10213000042B0C0000100308022B08000100000013 -:10214000042B0C4000080318022B080002000000BA -:10215000042B0C6000080320062A3A8000000014BB -:10216000062A3B2000000024062A14000000000A72 -:10217000062A145000000006062A3378000000D812 -:10218000022A3A3800000000042A3C5800020328C2 -:10219000042A3C680010032A062A5020000000028E -:1021A000062A503000000002062A500000000002FB -:1021B000062A501000000002022A504000000000D1 -:1021C000062A50480000000E022A50B80000000104 -:1021D000042A4AC80002033A062A4B1000000042B3 -:1021E000062A4D2000000004062A3AD00000001400 -:1021F000062A3BB000000024062A14280000000A2A -:10220000062A146800000006062A36D8000000D806 -:10221000022A3A3C00000000042A3C600002033C11 -:10222000042A3CA80010033E062A502800000002A1 -:10223000062A503800000002062A5008000000025A -:10224000062A501800000002022A50440000000034 -:10225000062A50800000000E022A50BC0000000137 -:10226000042A4AD00002034E062A4C1800000042FD -:10227000062A4D3000000004021010080000000182 -:102280000210101000000264021010000003D000C1 -:10229000021010040000003D091018000200035055 -:1022A00009101100002005500610118000000002E6 -:1022B0000910118800060570061011A00000001812 -:1022C000021010100000000006102400000000E0C2 -:1022D0000210201C0000000002102020000000015D -:1022E000021020C0000000010210200400000001C4 -:1022F000021020080000000109103C0000050576CE -:1023000009103C200005057B0910380000050580F8 -:1023100002104028000000100210404400003FFF5F -:102320000210405800280000021040840084924AA5 -:1023300002104058000000000610806800000004F1 -:1023400002108000000010800610802800000002AB -:102350000210803800000010021080400000FFFFD3 -:10236000021080440000FFFF0210805000000000B7 -:102370000210810000000000061081200000000211 -:1023800002108008000002B502108010000000005A -:10239000061082000000004A021081080001FFFFC1 -:1023A00006108140000000020210800000001A8028 -:1023B0000610900000000024061091200000004A42 -:1023C000061093700000004A061095C00000004AF5 -:1023D000021080040000108006108030000000020F -:1023E0000210803C00000010021080480000FFFF37 -:1023F0000210804C0000FFFF02108054000000001B -:102400000210810400000000061081280000000274 -:102410000210800C000002B50210801400000000C1 -:10242000061084000000004A0210810C0001FFFF2A -:1024300006108148000000020210800400001A808B -:102440000610909000000024061092480000004AF8 -:10245000061094980000004A061096E80000004A12 -:102460000212049000E383400212051400003C10A5 -:10247000021205200000000202120494FFFFFFFF79 -:1024800002120498FFFFFFFF0212049CFFFFFFFFF0 -:10249000021204A0FFFFFFFF021204A4FFFFFFFFD0 -:1024A000021204A8FFFFFFFF021204ACFFFFFFFFB0 -:1024B000021204B0FFFFFFFF021204B8FFFFFFFF8C -:1024C000021204BCFFFFFFFF021204C0FFFFFFFF68 -:1024D000021204C4FFFFFFFF021204C8FFFFFFFF48 -:1024E000021204CCFFFFFFFF021204D0FFFFFFFF28 -:1024F000021204DCFFFFFFFF021204E0FFFFFFFFF8 -:10250000021204E4FFFFFFFF021204E8FFFFFFFFD7 -:10251000021204ECFFFFFFFF021204F0FFFFFFFFB7 -:10252000021204F4FFFFFFFF021204F8FFFFFFFF97 -:10253000021204FCFFFFFFFF02120500FFFFFFFF76 -:1025400002120504FFFFFFFF02120508FFFFFFFF55 -:102550000212050CFFFFFFFF02120510FFFFFFFF35 -:10256000021204D4FFFF3330021204D8FFFF3340BD -:10257000021204B4F00030000212039000000008C0 -:102580000212039C00000008061203A000000002D3 -:10259000021203BC00000004021203C40000000485 -:1025A000021203D000000000021203DC0000000051 -:1025B0000212036C00000001021203680000003FD9 -:1025C000021201BC00000040021201C00000180805 -:1025D000021201C400000803021201C8000008032F -:1025E000021201CC00000040021201D000000003E2 -:1025F000021201D400000803021201D800000803EF -:10260000021201DC00000803021201E000010003D5 -:10261000021201E400000803021201E800000803AE -:10262000021201EC00000003021201F0000000039E -:10263000021201F400000003021201F8000000037E -:10264000021201FC0000000302120200000000035D -:10265000021202040000000302120208000000033C -:102660000212020C0000000302120210000000031C -:1026700002120214000000030212021800000003FC -:102680000212021C000000030212022000000003DC -:102690000212022400000003021202280000240398 -:1026A0000212022C0000002F02120230000000096A -:1026B00002120234000000190212023800000184E4 -:1026C0000212023C000001830212024000000306D5 -:1026D0000212024400000019021202480000000623 -:1026E0000212024C00000306021202500000030610 -:1026F00002120254000003060212025800000C8667 -:102700000212025C000003060212026000000306CF -:1027100002120264000000060212026800000006B5 -:102720000212026C00000006021202700000000695 -:102730000212027400000006021202780000000675 -:102740000212027C00000006021202800000000655 -:102750000212028400000006021202880000000635 -:102760000212028C00000006021202900000000615 -:1027700002120294000000060212029800000006F5 -:102780000212029C00000006021202A000000306D2 -:10279000021202A400000013021202A800000006A8 -:1027A000021202B000001004021202B40000100471 -:1027B0000212032400106440021203280010644037 -:1027C000021201B0000000010600A0000000001687 -:1027D0000200A06CBF5C00000200A070FFF51FEFBC -:1027E0000200A0740000FFFF0200A078500003E088 -:1027F0000200A07C000000000200A0800000A000F9 -:102800000600A084000000050200A0980FE0000070 -:102810000600A09C000000140200A0EC555400002B -:102820000200A0F0555555550200A0F40000555582 -:102830000200A0F8000000000200A0FC55540000B7 -:102840000200A100555555550200A1040000555540 -:102850000200A108000000000200A22C00000000FD -:102860000600A230000000030200A0600000000784 -:102870000200A10CBF5C00000200A110FFF51FEFD9 -:102880000200A1140000FFFF0200A118500003E0A5 -:102890000200A11C000000000200A1200000A00016 -:1028A0000600A124000000050200A1380FE000008E -:1028B0000600A13C000000140200A18C5554000049 -:1028C0000200A190555555550200A19400005555A0 -:1028D0000200A198000000000200A19C55540000D5 -:1028E0000200A1A0555555550200A1A40000555560 -:1028F0000200A1A8000000000200A23C00000000AD -:102900000600A240000000030200A06400000007CF -:1029100000000000000000000000002E0000000089 -:1029200000000000000000000000000000000000A7 -:102930000000000000000000000000000000000097 -:102940000000000000000000000000000000000087 -:102950000000000000000000000000000000000077 -:102960000000000000000000000000000000000067 -:10297000002E0050000000000000000000000000D9 -:102980000000000000000000000000000000000047 -:102990000000000000000000000000000050008D5A -:1029A0000000000000000000000000000000000027 -:1029B0000000000000000000000000000000000017 -:1029C0000000000000000000008D009200920096C0 -:1029D0000096009A000000000000000000000000C7 -:1029E00000000000000000000000000000000000E7 -:1029F00000000000009A00DB00DB00E900E900F7BE -:102A000000000000000000000000000000000000C6 -:102A100000000000000000000000000000000000B6 -:102A200000000000000000000000000000000000A6 -:102A30000000000000000000000000000000000096 -:102A40000000000000000000000000000000000086 -:102A50000000000000000000000000000000000076 -:102A60000000000000000000000000000000000066 -:102A70000000000000000000000000000000000056 -:102A80000000000000000000000000000000000046 -:102A90000000000000000000000000000000000036 -:102AA0000000000000000000000000000000000026 -:102AB0000000000000000000000000000000000016 -:102AC0000000000000000000000000000000000006 -:102AD00000F700FE00000000000000000000000001 -:102AE00000000000000000000000000000000000E6 -:102AF00000000000000000000000000000000000D6 -:102B000000000000000000000000000000000000C5 -:102B100000000000000000000000000000000000B5 -:102B2000000000000000000000FE01030103010E90 -:102B3000010E01190000000000000000000000006C -:102B40000000000000000000000000000000000085 -:102B50000000000000000000000000000000000075 -:102B60000000000000000000000000000000000065 -:102B70000000000000000000000000000000000055 -:102B80000119011A00000000000000000000000010 -:102B90000000000000000000000000000000000035 -:102BA000000000000000000000000000011A0152B7 -:102BB0000000000000000000000000000000000015 -:102BC0000000000000000000000000000000000005 -:102BD000000000000000000001520176000000002B -:102BE00000000000000000000000000000000000E5 -:102BF00000000000000000000000000000000000D5 -:102C000000000000017601B5000000000000000097 -:102C100000000000000000000000000000000000B4 -:102C200000000000000000000000000000000000A4 -:102C300001B501F0000000000000000000000000ED -:102C40000000000000000000000000000000000084 -:102C500000000000000000000000000001F002354C -:102C6000023502380238023B00000000000000007C -:102C70000000000000000000000000000000000054 -:102C80000000000000000000023B02760276028095 -:102C90000280028A00000000000000000000000026 -:102CA0000000000000000000000000000000000024 -:102CB00000000000028A028B0000000000000000FB -:102CC0000000000000000000000000000000000004 -:102CD00000000000000000000000000000000000F4 -:102CE000028B029D000000000000000000000000B8 -:102CF00000000000000000000000000000000000D4 -:102D0000000000000000000000000000029D02B270 -:102D100002B202B502B502B80000000000000000D7 -:102D200000000000000000000000000000000000A3 -:102D3000000000000000000002B802E600000000F1 -:102D40000000000000000000000000000000000083 -:102D50000000000000000000000000000000000073 -:102D60000000000002E6036D00000000000000000B -:102D70000000000000000000000000000000000053 -:102D80000000000000000000000000000000000043 -:102D9000036D0374037403780378037C0000000060 -:102DA0000000000000000000000000000000000023 -:102DB000000000000000000000000000037C03BBD6 -:102DC00003BB03C303C303CB0000000000000000EB -:102DD00000000000000000000000000000000000F3 -:102DE000000000000000000003CB041F041F04319A -:102DF0000431044300000000000000000000000057 -:102E000000000000000000000000000000000000C2 -:102E1000000000000443044D00000000000000001A -:102E200000000000000000000000000000000000A2 -:102E30000000000000000000000000000000000092 -:102E4000044D0453000000000000000000000000DA -:102E50000000000000000000000000000000000072 -:102E600000000000000000000000000004530456B1 -:102E70000000000000000000000000000000000052 -:102E80000000000000000000000000000000000042 -:102E900000000000000000000456045B0000000079 -:102EA0000000000000000000000000000000000022 -:102EB0000000000000000000000000000000000012 -:102EC00000000000045B045C045C046E046E04807B -:102ED00000000000000000000000000000000000F2 -:102EE00000000000000000000000000000000000E2 -:102EF000048004ED0000000000000000000000005D -:102F000000000000000000000000000000000000C1 -:102F100000000000000000000000000004ED04EECE -:102F200004EE050205020516000000000000000086 -:102F30000000000000000000000000000000000091 -:102F40000000000000000000000000000000000081 -:102F50000000000000000000000000000000000071 -:102F60000000000000000000000000000000000061 -:102F70000000000000000000000000000000000051 -:102F80000000000000000000000000000000000041 -:102F90000000000000000000000000000000000031 -:102FA000000000000000000000010000000204C05A -:102FB0000003098000040E4000051300000617C03E -:102FC00000071C800008214000092600000A2AC0D2 -:102FD000000B2F80000C3440000D3900000E3DC066 -:102FE000000F42800010474000114C00001250C0FA -:102FF0000013558000145A4000155F00001663C08E -:103000000017688000186D4000197200001A76C021 -:10301000001B7B80001C8040001D8500001E89C0B5 -:10302000001F8E8000209340000020000000400020 -:1030300000006000000080000000A0000000C00050 -:103040000000E0000001000000012000000140003D -:1030500000016000000180000001A0000001C0002C -:103060000001E00000020000000220000002400019 -:1030700000026000000280000002A0000002C00008 -:103080000002E000000300000003200000034000F5 -:1030900000036000000380000003A0000003C000E4 -:1030A0000003E000000400000004200000044000D1 -:1030B00000046000000480000004A0000004C000C0 -:1030C0000004E000000500000005200000054000AD -:1030D00000056000000580000005A0000005C0009C -:1030E0000005E00000060000000620000006400089 -:1030F00000066000000680000006A0000006C00078 -:103100000006E00000070000000720000007400064 -:1031100000076000000780000007A0000007C00053 -:103120000007E00000080000000820000008400040 -:1031300000086000000880000008A0000008C0002F -:103140000008E0000009000000092000000940001C -:1031500000096000000980000009A0000009C0000B -:103160000009E000000A0000000A2000000A4000F8 -:10317000000A6000000A8000000AA000000AC000E7 -:10318000000AE000000B0000000B2000000B4000D4 -:10319000000B6000000B8000000BA000000BC000C3 -:1031A000000BE000000C0000000C2000000C4000B0 -:1031B000000C6000000C8000000CA000000CC0009F -:1031C000000CE000000D0000000D2000000D40008C -:1031D000000D6000000D8000000DA000000DC0007B -:1031E000000DE000000E0000000E2000000E400068 -:1031F000000E6000000E8000000EA000000EC00057 -:10320000000EE000000F0000000F2000000F400043 -:10321000000F6000000F8000000FA000000FC00032 -:10322000000FE0000010000000102000001040001F -:1032300000106000001080000010A0000010C0000E -:103240000010E000001100000011200000114000FB -:1032500000116000001180000011A0000011C000EA -:103260000011E000001200000012200000124000D7 -:1032700000126000001280000012A0000012C000C6 -:103280000012E000001300000013200000134000B3 -:1032900000136000001380000013A0000013C000A2 -:1032A0000013E0000014000000142000001440008F -:1032B00000146000001480000014A0000014C0007E -:1032C0000014E0000015000000152000001540006B -:1032D00000156000001580000015A0000015C0005A -:1032E0000015E00000160000001620000016400047 -:1032F00000166000001680000016A0000016C00036 -:103300000016E00000170000001720000017400022 -:1033100000176000001780000017A0000017C00011 -:103320000017E000001800000018200000184000FE -:1033300000186000001880000018A0000018C000ED -:103340000018E000001900000019200000194000DA -:1033500000196000001980000019A0000019C000C9 -:103360000019E000001A0000001A2000001A4000B6 -:10337000001A6000001A8000001AA000001AC000A5 -:10338000001AE000001B0000001B2000001B400092 -:10339000001B6000001B8000001BA000001BC00081 -:1033A000001BE000001C0000001C2000001C40006E -:1033B000001C6000001C8000001CA000001CC0005D -:1033C000001CE000001D0000001D2000001D40004A -:1033D000001D6000001D8000001DA000001DC00039 -:1033E000001DE000001E0000001E2000001E400026 -:1033F000001E6000001E8000001EA000001EC00015 -:10340000001EE000001F0000001F2000001F400001 -:10341000001F6000001F8000001FA000001FC000F0 -:10342000001FE000002000000020200000204000DD -:1034300000206000002080000020A0000020C000CC -:103440000020E000002100000021200000214000B9 -:1034500000216000002180000021A0000021C000A8 -:103460000021E00000220000002220000022400095 -:1034700000226000002280000022A0000022C00084 -:103480000022E00000230000002320000023400071 -:1034900000236000002380000023A0000023C00060 -:1034A0000023E0000024000000242000002440004D -:1034B00000246000002480000024A0000024C0003C -:1034C0000024E00000250000002520000025400029 -:1034D00000256000002580000025A0000025C00018 -:1034E0000025E00000260000002620000026400005 -:1034F00000266000002680000026A0000026C000F4 -:103500000026E000002700000027200000274000E0 -:1035100000276000002780000027A0000027C000CF -:103520000027E000002800000028200000284000BC -:1035300000286000002880000028A0000028C000AB -:103540000028E00000290000002920000029400098 -:1035500000296000002980000029A0000029C00087 -:103560000029E000002A0000002A2000002A400074 -:10357000002A6000002A8000002AA000002AC00063 -:10358000002AE000002B0000002B2000002B400050 -:10359000002B6000002B8000002BA000002BC0003F -:1035A000002BE000002C0000002C2000002C40002C -:1035B000002C6000002C8000002CA000002CC0001B -:1035C000002CE000002D0000002D2000002D400008 -:1035D000002D6000002D8000002DA000002DC000F7 -:1035E000002DE000002E0000002E2000002E4000E4 -:1035F000002E6000002E8000002EA000002EC000D3 -:10360000002EE000002F0000002F2000002F4000BF -:10361000002F6000002F8000002FA000002FC000AE -:10362000002FE0000030000000302000003040009B -:1036300000306000003080000030A0000030C0008A -:103640000030E00000310000003120000031400077 -:1036500000316000003180000031A0000031C00066 -:103660000031E00000320000003220000032400053 -:1036700000326000003280000032A0000032C00042 -:103680000032E0000033000000332000003340002F -:1036900000336000003380000033A0000033C0001E -:1036A0000033E0000034000000342000003440000B -:1036B00000346000003480000034A0000034C000FA -:1036C0000034E000003500000035200000354000E7 -:1036D00000356000003580000035A0000035C000D6 -:1036E0000035E000003600000036200000364000C3 -:1036F00000366000003680000036A0000036C000B2 -:103700000036E0000037000000372000003740009E -:1037100000376000003780000037A0000037C0008D -:103720000037E0000038000000382000003840007A -:1037300000386000003880000038A0000038C00069 -:103740000038E00000390000003920000039400056 -:1037500000396000003980000039A0000039C00045 -:103760000039E000003A0000003A2000003A400032 -:10377000003A6000003A8000003AA000003AC00021 -:10378000003AE000003B0000003B2000003B40000E -:10379000003B6000003B8000003BA000003BC000FD -:1037A000003BE000003C0000003C2000003C4000EA -:1037B000003C6000003C8000003CA000003CC000D9 -:1037C000003CE000003D0000003D2000003D4000C6 -:1037D000003D6000003D8000003DA000003DC000B5 -:1037E000003DE000003E0000003E2000003E4000A2 -:1037F000003E6000003E8000003EA000003EC00091 -:10380000003EE000003F0000003F2000003F40007D -:10381000003F6000003F8000003FA000003FC0006C -:10382000003FE000003FE00100000000000001FF59 -:103830000000020000007FF800007FF80000026F27 -:1038400000001500000000010000000300BEBC20C5 -:103850000000000300BEBC2000000001FFFFFFFFCE -:10386000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 -:10387000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 -:1038800000000000FFFFFFFF00000000FFFFFFFF40 -:103890000000000300BEBC20FFFFFFFF000000008F -:1038A000FFFFFFFF00000000FFFFFFFF000000031D -:1038B00000BEBC2000002000000040C0000061806D -:1038C000000082400000A3000000C3C00000E480AC -:1038D0000001054000012600000146C0000167808C -:1038E000000188400001A9000001C9C00001EA8070 -:1038F00000020B4000022C0000024CC000026D8050 -:1039000000028E400002AF000002CFC00002F08033 -:103910000003114000033200000352C00003738013 -:10392000000394400003B5000003D5C00003F680F7 -:103930000004174000043800000458C000047980D7 -:1039400000049A400000800000010380000187000D -:1039500000020A8000028E0000031180000395001F -:103960000004188000049C0000051F800005A300CF -:10397000000626800006AA0000072D800007B1007F -:10398000000834800008B80000093B800009BF002F -:10399000000A4280000AC600000B4980000BCD00DF -:1039A000000C5080000CD400000D5780000DDB008F -:1039B00000007FF800007FF800000174000015008F -:1039C0000000190000000000FFFFFFFF40000000A2 -:1039D00040000000400000004000000040000000E7 -:1039E00040000000400000004000000040000000D7 -:1039F00040000000400000004000000040000000C7 -:103A000040000000400000004000000040000000B6 -:103A100040000000400000004000000040000000A6 -:103A20004000000040000000400000004000000096 -:103A30004000000040000000400000004000000086 -:103A400040000000400000004000000000007FF83F -:103A500000007FF80000050900003500FFFFFFFFB0 -:103A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 -:103A7000FFFFFFFFFFFFFFFFFFFFFFFF4000000012 -:103A80004000000040000000400000004000000036 -:103A90004000000040000000400000004000000026 -:103AA0004000000040000000400000004000000016 -:103AB0004000000040000000400000004000000006 -:103AC00040000000400000004000000040000000F6 -:103AD00040000000400000004000000040000000E6 -:103AE00040000000400000004000000040000000D6 -:103AF00040000000400000004000000000001000F6 -:103B000000002080000031000000418000005200D1 -:103B100000006280000073000000838000009400B9 -:103B20000000A4800000B5000000C5800000D600A1 -:103B30000000E6800000F700000107800001180087 -:103B400000012880000139000001498000015A006D -:103B500000016A8000017B0000018B8000019C0055 -:103B60000001AC800001BD000001CD800001DE003D -:103B70000001EE800001FF0000007FF800007FF8E8 -:103B8000000004480000150010000000000028ADEF -:103B9000000000000001000100070205CCCCCCC1F0 -:103BA000FFFFFFFFFFFFFFFF7058103C0000000009 -:103BB0000000000000000001CCCC0201CCCCCCCC39 -:103BC00000000000FFFFFFFF400000004000000079 -:103BD00040000000400000004000000040000000E5 -:103BE00040000000400000004000000040000000D5 -:103BF00040000000400000004000000040000000C5 -:103C000040000000400000004000000040000000B4 -:103C100040000000400000004000000040000000A4 -:103C20004000000040000000400000004000000094 -:103C30004000000040000000400000004000000084 -:103C40004000000040000000000E01B7011600D641 -:103C50000000FFFF000000000000FFFF0000000068 -:103C60000000FFFF000000000000FFFF0000000058 -:103C70000000FFFF000000000000FFFF0000000048 -:103C80000000FFFF000000000000FFFF0000000038 -:103C90000010000000000000007201BB012300F3CF -:103CA0000000FFFF000000000000FFFF0000000018 -:103CB0000000FFFF000000000000FFFF0000000008 -:103CC0000000FFFF000000000000FFFF00000000F8 -:103CD0000000FFFF000000000000FFFF00000000E8 -:103CE0000010000000000000FFFFFFF3318FFFFF16 -:103CF0000C30C30CC30C30C3CF3CF300F3CF3CF308 -:103D00000000CF3CCDCDCDCDFFFFFFF130EFFFFF69 -:103D10000C30C30CC30C30C3CF3CF300F3CF3CF3E7 -:103D20000001CF3CCDCDCDCDFFFFFFF6305FFFFFD3 -:103D30000C30C30CC30C30C3CF3CF300F3CF3CF3C7 -:103D40000002CF3CCDCDCDCDFFFFF4061CBFFFFF61 -:103D50000C30C305C30C30C3CF300014F3CF3CF399 -:103D60000004CF3CCDCDCDCDFFFFFFF2304FFFFFA4 -:103D70000C30C30CC30C30C3CF3CF300F3CF3CF387 -:103D80000008CF3CCDCDCDCDFFFFFFFA302FFFFF98 -:103D90000C30C30CC30C30C3CF3CF300F3CF3CF367 -:103DA0000010CF3CCDCDCDCDFFFFFFF731EFFFFFB2 -:103DB0000C30C30CC30C30C3CF3CF300F3CF3CF347 -:103DC0000020CF3CCDCDCDCDFFFFFFF5302FFFFF45 -:103DD0000C30C30CC30C30C3CF3CF300F3CF3CF327 -:103DE0000040CF3CCDCDCDCDFFFFFFF3318FFFFFA6 -:103DF0000C30C30CC30C30C3CF3CF300F3CF3CF307 -:103E00000000CF3CCDCDCDCDFFFFFFF1310FFFFF47 -:103E10000C30C30CC30C30C3CF3CF300F3CF3CF3E6 -:103E20000001CF3CCDCDCDCDFFFFFFF6305FFFFFD2 -:103E30000C30C30CC30C30C3CF3CF300F3CF3CF3C6 -:103E40000002CF3CCDCDCDCDFFFFF4061CBFFFFF60 -:103E50000C30C305C30C30C3CF300014F3CF3CF398 -:103E60000004CF3CCDCDCDCDFFFFFFF2304FFFFFA3 -:103E70000C30C30CC30C30C3CF3CF300F3CF3CF386 -:103E80000008CF3CCDCDCDCDFFFFFFFA302FFFFF97 -:103E90000C30C30CC30C30C3CF3CF300F3CF3CF366 -:103EA0000010CF3CCDCDCDCDFFFFFFF730EFFFFFB2 -:103EB0000C30C30CC30C30C3CF3CF300F3CF3CF346 -:103EC0000020CF3CCDCDCDCDFFFFFFF5304FFFFF24 -:103ED0000C30C30CC30C30C3CF3CF300F3CF3CF326 -:103EE0000040CF3CCDCDCDCDFFFFFFF331EFFFFF45 -:103EF0000C30C30CC30C30C3CF3CF300F3CF3CF306 -:103F00000000CF3CCDCDCDCDFFFFFFF1310FFFFF46 -:103F10000C30C30CC30C30C3CF3CF300F3CF3CF3E5 -:103F20000001CF3CCDCDCDCDFFFFFFF6305FFFFFD1 -:103F30000C30C30CC30C30C3CF3CF300F3CF3CF3C5 -:103F40000002CF3CCDCDCDCDFFFFF4061CBFFFFF5F -:103F50000C30C305C30C30C3CF300014F3CF3CF397 -:103F60000004CF3CCDCDCDCDFFFFFFF2304FFFFFA2 -:103F70000C30C30CC30C30C3CF3CF300F3CF3CF385 -:103F80000008CF3CCDCDCDCDFFFFFFFA302FFFFF96 -:103F90000C30C30CC30C30C3CF3CF300F3CF3CF365 -:103FA0000010CF3CCDCDCDCDFFFFFF97056FFFFFBC -:103FB0000C30C30CC30C30C3CF3CC000F3CF3CF378 -:103FC0000020CF3CCDCDCDCDFFFFFFF5310FFFFF62 -:103FD0000C30C30CC30C30C3CF3CF300F3CF3CF325 -:103FE0000040CF3CCDCDCDCDFFFFFFF3320FFFFF23 -:103FF0000C30C30CC30C30C3CF3CF300F3CF3CF305 -:104000000000CF3CCDCDCDCDFFFFFFF1310FFFFF45 -:104010000C30C30CC30C30C3CF3CF300F3CF3CF3E4 -:104020000001CF3CCDCDCDCDFFFFFFF6305FFFFFD0 -:104030000C30C30CC30C30C3CF3CF300F3CF3CF3C4 -:104040000002CF3CCDCDCDCDFFFFF4061CBFFFFF5E -:104050000C30C305C30C30C3CF300014F3CF3CF396 -:104060000004CF3CCDCDCDCDFFFFFFF2304FFFFFA1 -:104070000C30C30CC30C30C3CF3CF300F3CF3CF384 -:104080000008CF3CCDCDCDCDFFFFFF8A042FFFFF31 -:104090000C30C30CC30C30C3CF3CC000F3CF3CF397 -:1040A0000010CF3CCDCDCDCDFFFFFF9705CFFFFF5B -:1040B0000C30C30CC30C30C3CF3CC000F3CF3CF377 -:1040C0000020CF3CCDCDCDCDFFFFFFF5310FFFFF61 -:1040D0000C30C30CC30C30C3CF3CF300F3CF3CF324 -:1040E0000040CF3CCDCDCDCDFFFFFFF3300FFFFF24 -:1040F0000C30C30CC30C30C3CF3CF300F3CF3CF304 -:104100000000CF3CCDCDCDCDFFFFFFF1300FFFFF45 -:104110000C30C30CC30C30C3CF3CF300F3CF3CF3E3 -:104120000001CF3CCDCDCDCDFFFFFFF6305FFFFFCF -:104130000C30C30CC30C30C3CF3CF300F3CF3CF3C3 -:104140000002CF3CCDCDCDCDFFFFF4061CBFFFFF5D -:104150000C30C305C30C30C3CF300014F3CF3CF395 -:104160000004CF3CCDCDCDCDFFFFFFF2304FFFFFA0 -:104170000C30C30CC30C30C3CF3CF300F3CF3CF383 -:104180000008CF3CCDCDCDCDFFFFFFFA302FFFFF94 -:104190000C30C30CC30C30C3CF3CF300F3CF3CF363 -:1041A0000010CF3CCDCDCDCDFFFFFF97040FFFFF1B -:1041B0000C30C30CC30C30C3CF3CC000F3CF3CF376 -:1041C0000020CF3CCDCDCDCDFFFFFFF5300FFFFF61 -:1041D0000C30C30CC30C30C3CF3CF300F3CF3CF323 -:1041E0000040CF3CCDCDCDCDFFFFFFFF30CFFFFF57 -:1041F0000C30C30CC30C30C3CF3CF3CCF3CF3CF337 -:104200000000CF3CCDCDCDCDFFFFFFFF30CFFFFF76 -:104210000C30C30CC30C30C3CF3CF3CCF3CF3CF316 -:104220000001CF3CCDCDCDCDFFFFFFFF30CFFFFF55 -:104230000C30C30CC30C30C3CF3CF3CCF3CF3CF3F6 -:104240000002CF3CCDCDCDCDFFFFFFFF30CFFFFF34 -:104250000C30C30CC30C30C3CF3CF3CCF3CF3CF3D6 -:104260000004CF3CCDCDCDCDFFFFFFFF30CFFFFF12 -:104270000C30C30CC30C30C3CF3CF3CCF3CF3CF3B6 -:104280000008CF3CCDCDCDCDFFFFFFFF30CFFFFFEE -:104290000C30C30CC30C30C3CF3CF3CCF3CF3CF396 -:1042A0000010CF3CCDCDCDCDFFFFFFFF30CFFFFFC6 -:1042B0000C30C30CC30C30C3CF3CF3CCF3CF3CF376 -:1042C0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF96 -:1042D0000C30C30CC30C30C3CF3CF3CCF3CF3CF356 -:1042E0000040CF3CCDCDCDCDFFFFFFFF30CFFFFF56 -:1042F0000C30C30CC30C30C3CF3CF3CCF3CF3CF336 -:104300000000CF3CCDCDCDCDFFFFFFFF30CFFFFF75 -:104310000C30C30CC30C30C3CF3CF3CCF3CF3CF315 -:104320000001CF3CCDCDCDCDFFFFFFFF30CFFFFF54 -:104330000C30C30CC30C30C3CF3CF3CCF3CF3CF3F5 -:104340000002CF3CCDCDCDCDFFFFFFFF30CFFFFF33 -:104350000C30C30CC30C30C3CF3CF3CCF3CF3CF3D5 -:104360000004CF3CCDCDCDCDFFFFFFFF30CFFFFF11 -:104370000C30C30CC30C30C3CF3CF3CCF3CF3CF3B5 -:104380000008CF3CCDCDCDCDFFFFFFFF30CFFFFFED -:104390000C30C30CC30C30C3CF3CF3CCF3CF3CF395 -:1043A0000010CF3CCDCDCDCDFFFFFFFF30CFFFFFC5 -:1043B0000C30C30CC30C30C3CF3CF3CCF3CF3CF375 -:1043C0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF95 -:1043D0000C30C30CC30C30C3CF3CF3CCF3CF3CF355 -:1043E0000040CF3CCDCDCDCDFFFFFFFF30CFFFFF55 -:1043F0000C30C30CC30C30C3CF3CF3CCF3CF3CF335 -:104400000000CF3CCDCDCDCDFFFFFFFF30CFFFFF74 -:104410000C30C30CC30C30C3CF3CF3CCF3CF3CF314 -:104420000001CF3CCDCDCDCDFFFFFFFF30CFFFFF53 -:104430000C30C30CC30C30C3CF3CF3CCF3CF3CF3F4 -:104440000002CF3CCDCDCDCDFFFFFFFF30CFFFFF32 -:104450000C30C30CC30C30C3CF3CF3CCF3CF3CF3D4 -:104460000004CF3CCDCDCDCDFFFFFFFF30CFFFFF10 -:104470000C30C30CC30C30C3CF3CF3CCF3CF3CF3B4 -:104480000008CF3CCDCDCDCDFFFFFFFF30CFFFFFEC -:104490000C30C30CC30C30C3CF3CF3CCF3CF3CF394 -:1044A0000010CF3CCDCDCDCDFFFFFFFF30CFFFFFC4 -:1044B0000C30C30CC30C30C3CF3CF3CCF3CF3CF374 -:1044C0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF94 -:1044D0000C30C30CC30C30C3CF3CF3CCF3CF3CF354 -:1044E0000040CF3CCDCDCDCD000C0000000700C07A -:1044F00000028130000B81580002021000010230DE -:10450000000F024000010330000C0000000800C052 -:1045100000028140000B816800020220000102407D -:1045200000070250000202C0000F0000000800F067 -:1045300000028170000B819800020250000102709D -:10454000000B828000080338001000000008010002 -:1045500000028180000B81A80002026000018280BD -:10456000000E82980008038000028000000B802863 -:10457000000200E0000101000000811000000118AD -:10458000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC6B -:1045900000002000CCCCCCCCCCCCCCCCCCCCCCCC6B -:1045A000CCCCCCCC00002000CCCCCCCCCCCCCCCC5B -:1045B000CCCCCCCCCCCCCCCC00002000000000007B -:1045C0001F8B080000000000000BFB51CFC0F00360 -:1045D0008A7BD81818F67020F843015F646260B8CF -:1045E0000CC45781588099812198918121849178B8 -:1045F000FD19A208F63B210606296106860841A09E -:1046000079C208F1D3403576220C0C8C22107E2B17 -:1046100090E612A58EFB071AEF94C214DB26816088 -:10462000EFC2228F8C77A3C98B4AA2F2F710D03F3A -:10463000D0F895222A5F5601429741C55FA3C9CBA6 -:1046400041E56F41FDF54611BBB9B7A1F2009CB43D -:10465000B6A260030000000000000000000000009F -:104660001F8B080000000000000BED7D0B7854D577 -:10467000B5F03E73CE9C9949662627214F1E6112E4 -:1046800020028638BC0228F73A212140A575A055A2 -:10469000D1A21D3040C85B8A5E5ADB2F130831025D -:1046A000DAE08F8A16EDF0AAA8A80123450B7478EA -:1046B0008A5E6F6FB06A69B5DE888A8A3C22AD4A2D -:1046C000EF6D7FFFB5D6DE3B73CE6402D8AFF7FE49 -:1046D000F7BFDF1F3FBFC33E7B9FBDD75EAFBDD6D9 -:1046E000DA6BEFB1DB1C4CBF96B1AFF00F9EF53625 -:1046F000C65846ECF9A89D7D2FE866AC60BD6F8575 -:104700003B1DDEEFCEDB91EC632C67CF5A650ABC14 -:10471000CFD9D0A6CC2F8C7D1F7041E57878BF7B98 -:10472000AD5202EF735E6B53E6E1D361639DD09EA1 -:1047300069BE14864F16602C93B1211399F80BB8FB -:10474000738A191B88FF842ECE1BC98C8D632C6F36 -:10475000A52D1256E07DA87226F332B619E0CA499B -:1047600083EFD4BFECB763DB06ED44979331A7E644 -:10477000D4BECA672C770EB331780E5EC6DFE3DF96 -:1047800057F07F5ED85A1EC24CE53C2C7BD24FC2FC -:1047900090CCC33C5FA989E0EDD683A362F394CFAC -:1047A0000D8DBE4CB7D6FBBD7C2EB9E363FD1EF864 -:1047B000FA716C3794B1485CFBDAB0AEB1ABE0098A -:1047C00008682FECFDFD4C56528C74B88D4DA167D6 -:1047D000BDE6BB09F1527FD4CEC200777DC3C9725A -:1047E0002CB3DD0A1B96D7FBFB51CC4EF428618A13 -:1047F0007612E7EB655E9C9F5AE37BB81CF0DC9079 -:104800001C28C37E1F490ED153BECF9E3F3D3B04A3 -:10481000F0942E2A0C33A0FBF9F58ADF019F7FA4C8 -:1048200044743BD0A3FA3B0D45D3A0DD9B7AE83A14 -:10483000FC6E911A6DB1C3F8B5731B0A8002AC53BC -:10484000E7FC337877C9271AD06D3063E19434A43C -:104850000B63274C74C0BF13C34559ED1B8F977A68 -:1048600056603F1AF612A1F9CAF779E1A34386C64A -:104870008DC78A091E867032D6A524A2EBE0174B9D -:104880008E6A457D8FF79F3F8F309743C01DD2B70B -:10489000D6A34796037E4B5FB047AF057AD46E54DC -:1048A000220E28DBF6B902489FB35BA00C74897A0C -:1048B000746A7FC67052B9DED179FF3550EE7E4101 -:1048C000659BB0DBE1493694BB930276360ECA8015 -:1048D0008F852E5EACDDB8FF36ECAF72B783B99032 -:1048E0009E2F2EFAD635505E04FC864D6AB736E907 -:1048F000FDA1BC38A2B463F9DC1446FC114ED323ED -:104900005B61BC73DECECC1B405E4E353A990F40E6 -:1049100059E1E9CCFC0EF051556447397E57B55D3D -:10492000F123DA4B5FD87A2407E7F524F015F0512C -:10493000F5B664E693F883FF4FC254AE85FA25308E -:104940004F94FF45ACAD9CA938FE5ADDE789E1EBF9 -:1049500054A341E3F4C8D393300E7C57F7ACE2C7BD -:1049600029D6D95808E5EAEC8BAE399BDD38BF264D -:10497000BDC083F3BA47C7768B22F376A1CAAA8A51 -:104980006CD4CBA1BE6AC3467D6121E20DF45E21E9 -:10499000C2D5CF0AD77A3580F85D92EADCA4027ED0 -:1049A000983B903D3B01FF9C6A043556102B57A164 -:1049B0007C933E89E8B34CEDCB9554E2D7EA6D2A5F -:1049C000F359F889D33F7C8CD33FBCD713D99A17BE -:1049D000A3DF1283EB4949BF25A9829E5A77712232 -:1049E00078EE477A003C6D882F78AE11F07927B3C6 -:1049F000120DE8E20D30436197E6CF363B9BC7606E -:104A0000ECD7D982803609CA3ABB83F91933B4DAB4 -:104A1000401994FFC282AFE17C18F3FB8280E71655 -:104A200085CDC1791F4660613E2D393AE1AF6D6A8F -:104A3000F166551130A76379E1CF57E5D1F76FD013 -:104A4000F71A7C3FAAEFEF8DF28996EF8DF24AF9C3 -:104A5000FD3BD88E392FFE7D5BF9D5D6F1CBABE48B -:104A6000F71FD0F8EE8BC36F4C9B6C1D7F5A0D7DEA -:104A70005FEFE0F4EA4E75463641B9D9E50F684874 -:104A8000378D45F1BD9656B009DBA9921F58674096 -:104A900085EFDDDB53C7AC6266BE98F2271CCF03FF -:104AA000D262E68B948949167E4C0DA459CAD093E4 -:104AB00071F2CA981E0A789D048FDE5F277D51D25D -:104AC000DF49F0DEB5CF45E5BBAEE6F0DED5DF4D24 -:104AD000728630B01C28EBA1AB0CD37A04702A2C60 -:104AE0009BB1CF95904B196F7EEFB3E1FB249535C9 -:104AF000E07C921C8CF4D13D79C59BC326FCB40E9E -:104B000002FA42395DD1391E055EEF19B4307B9E41 -:104B1000699C9641FA9C4D85FCFDED6E1C2F98A971 -:104B2000A01ED4BB0B0C77EF711CF9132DE3387367 -:104B30002B699CBCB8711CB99571E338E76C12EF16 -:104B4000C538432E36CE3DF9575BE7935B45E314FA -:104B5000C5CF27B72A6E9C243E1F782FC6F123FEAF -:104B6000FA9CCF90C9D6F90CAEA171AEC171C69BAB -:104B7000E633B8266E1C378D83EF711C30A47C2C75 -:104B80000BE8EEE85E48F4FF958BEC05DD117A0248 -:104B9000FB656FBB18E9131F8C9B857A0516679020 -:104BA0005F4D49A371BE4802FABBCD74E6FA889EF8 -:104BB000A07F16081059042002FD532778B462FB29 -:104BC000ACDC267CEE2ECD9E8776C93A8F7F188886 -:104BD000CED9DDA5FAED09EC9B056DF6935D16FEC9 -:104BE000157A6F0A1BDE00E377A0B231954F82FE83 -:104BF00062A0B74E80FEC2E747C23EFD00F41BD361 -:104C0000CDF036D13C4E6A1C8F2737F075E48BB55A -:104C1000C7EC60ECE1306F1402DC378A692C680362 -:104C2000E3CF2467F5821EDD2F3A229B881E810187 -:104C300036E073B6BE1FE04AB4033BF30FC21E85D5 -:104C4000BF0136B0656F69DD71189BBDA5CC1BB483 -:104C500004E63BA763AD7D0094CFDABB6EF3BB4D9A -:104C6000FDCCB19FC0793BE13FECE7E690DD629F70 -:104C70007EB7D25ABE35CE5EAD51F2053DC4B8BE48 -:104C8000881DE975632687E7567C8EC16A83E875BF -:104C90009BC1BF95F0D4DF6D67515A8FBA3258214E -:104CA000E22383ECA2905C57E2E0BBCDEE0C0481E2 -:104CB0009EB7FD40253CC6C3DBB52F3960037BA9F9 -:104CC0006BFD1FED687F5F0AFEEF2DB3D6B3301F7B -:104CD0004FE255F2C14D734AFA7D606A77736846B8 -:104CE000BF0F4CFCF2DDCA5996F2AD0D375BDA7F8F -:104CF0006FD93C4BFDBCF0624BFDEDAD7758CA0B54 -:104D0000DA7E6069BF687D93A57E71E45E4B7DF5B8 -:104D1000B6B596726DFB2396F6F5BB375AEA6DFB76 -:104D2000465C8FF2B8E24D95A17DF6B9FBE4FD68D3 -:104D30005F7D6E687E6C5387BC0672F8716336F1D6 -:104D4000F7A9461F3DCFEE1EEB447BBC3E09E4199C -:104D5000D6FA7DCA1FC2AD93518F407BD0E1079434 -:104D6000F7C361709E5E517CC4F7EA7A9D45815518 -:104D70001596D6C3D7DD6AAC5EEB82FAB17DD7ABB0 -:104D8000EBB584F55A9796B0DF734A7701DA77E18D -:104D9000DF3918DA817DD90FF03700D78BBEEA4FA3 -:104DA000DB5865BB49EF9C546CC407372A534EA2AD -:104DB0007EAED1B9BCD7ECCC9982FE608D1E2D6839 -:104DC000705F64BC7600260BFBC9A7792D8E0C881A -:104DD000C92FD16F8845EE97B2D087A89F4FEF5764 -:104DE00049CFB2E8C1DC6F8FC2F10327F13DDB9DF3 -:104DF00041EBE35B8D817E1F803F77BC713A3D7F45 -:104E0000DF18ECF701E89A771AE750F9DDC6103D94 -:104E1000BB1A2BE979A2B181EA3F685C46E5938D24 -:104E2000617A7EDCD84ACF538D6D547FBA713D953F -:104E3000CF3646E8D9E307087B94A50BFB4FD8EBA8 -:104E4000B07250F9BC98830AFFE67EAB3F1BE5FACF -:104E5000BCFB8B02B473CF1F07C324817F289FF153 -:104E6000FCD637FD02B4DE2F8C00FDC7F6AE7725E9 -:104E700071FAB86C6C3A03FD73EF309D69307ED2E5 -:104E8000AFAE247B19DE6B8CF465C43FCB93A07F5F -:104E90009C73D6A5E9D4C31F8FFE4731C61F6E147D -:104EA000FA30E9A0DAC0E9B6D98F7433E18FDB6557 -:104EB0002F087D1E8747B2E5727AE3F34C86C467FC -:104EC000672EC601D629C11136E083F31D0E9AD78D -:104ED000F93DC91186DF627064D2C5F0C6E1A8DE73 -:104EE000E632CCFAA1B63DD5B0EA8B1CC3AC2FCECE -:104EF0001FDDEC45B95F926D333E188BFC1110FC41 -:104F0000C1F94EF65FDB9E67B82DFD58CBE7DB9409 -:104F1000E9E80781724FF94E02FF403E9764EBC605 -:104F20000720DFA7B60D49C171C18F33709CD38DA7 -:104F300086C1C7CD36CC7C59B32C89DA4BF8FAEA56 -:104F4000F7EF0D1F5A06EF3B19A1FEAB215FDFCF34 -:104F500066DA9F289EC3F6D8BFC075C701FF7F459C -:104F6000F1008DCAB2DFFA7635ECB80ADF6FB78C84 -:104F700007DFF9A40F8DEB55DF74D7D849535CA038 -:104F80000EC720FFC849740E418F29D0DF39CDDD0F -:104F9000AAC038D36D3EAAAF17FC58EBECD243F051 -:104FA000EA4C07A7475FE39C6A3CEAD3407F543A48 -:104FB000C12383712ADB4794A17E3CD3B122330401 -:104FC0007C5BAD9EBF2B98E0FB569BC2E189D8BBB2 -:104FD000BB4CF3917114C6A05F670C7EE4F493A6FA -:104FE00072BCBE96CF07B05FE08FBAEDC7CAAF0103 -:104FF000F8EB767FA6231CD36DA1076C19B1F92BB2 -:10500000387FE8A76ADB7B3ACEEF637BB8E0EE8BB4 -:10501000E8A9DE70BAB3296E27E10BB34EB463E69C -:10502000F7C4157D37BD0DA2F9C93FDBD92A8083AE -:10503000FD055A41BD5DD456B0A017F135BFA39A06 -:10504000E28B9FD8A4DDD4568CFC7186D9A6E3FCF4 -:10505000CEB0D7BD634DF8EBB071BB9FB5723B26A8 -:105060000CFF213C60CF5AEC9A45EBADE5856C76A0 -:1050700026EA8D85EBEC2C02285A8C7691E40F9869 -:10508000F7161BB77717B18616B4E73407F70FE6A4 -:105090001B4C1B0070D5FEE2B162B4FB7F69B311FB -:1050A0007D649C61711A87BB2A3DA207A0FEFD8E1C -:1050B000B1375E83DCE788B4E0BACC52987F2BEB43 -:1050C0008DCFDB5BADF05D0AFE7878195B6E8143B6 -:1050D000F62BE150B729814802BE7B45F29DD023D3 -:1050E00069AAD5CECF8A2BBF6313F14B95A948E7A8 -:1050F0003386336C4BA17A7F14E3233B1DFE1540AE -:10510000DF3B6DC12ED4CF6017143153BB3B6D21F3 -:105110007A7F5A796D21DAA74C8B16A17F0F6B8AA3 -:1051200086FCA00B7E5093BC45188FF530583F414C -:105130002E1D081FF4D3E2A99CC98A30FE0A720A08 -:10514000FDDDE72D3FAA40D9E5EE60D89F23DB1AAD -:105150005F76F9ACE57AFC07D26138A3384EF2707D -:105160006B3D2C580CF9CDE3B7BEFFF71E3C4589CB -:105170006FBDC4D2F074BAA32A8CCF266AA7CD76AD -:10518000739D93C34F7E39B45F2AECF93AE60B5313 -:105190009C389BF3C1D219368267A9C7E70F43BD7C -:1051A000A20518CA1FC6AACDEB58FD0510B97EA6E8 -:1051B000B2D6AD235FD65FD05804F47D912DE45173 -:1051C000C723FE0264E73A01595F01C89A7BBAC55A -:1051D000EE6503D3C4FA3AD030CBEB40A4F3F81811 -:1051E0009DA55EB00BBD08FA224BCD403DD85D4E6B -:1051F0007E09EB223D21DBE9B17603118EBEDAB9DF -:1052000062EDF212F557FB8B67768501FF55CF3DB6 -:10521000E805E2B34FB4B64C3FBCAFD9BAD28B7CF1 -:10522000FCB116F6E2BC3F89A8D313F1F38DAA2294 -:10523000FCB1805B417F58D0E9D453ABBF8578FF88 -:1052400062ABDDC026F5DB1C510710B1AE6331E760 -:10525000A76D8EF778F99ECF909EF5BBADF256F50F -:10526000C4839918EF040C71BF9145C97EAEDBF27F -:105270006139DA23F5AC9BF444FC7738FE85345A67 -:10528000BFE6E929BDEBE5FE4BBDE0FBFA8ED59FFD -:10529000A95E2C5BE5BB52F823D3544F3AC5952643 -:1052A000B0094837890716E1F6F08A271F2E7A0FD2 -:1052B000E038BDE59FBD8A256EC4F5C3F9F6DB7FF6 -:1052C000F692AF6FBD7E56F8F3B1EF22F49D6F37C3 -:1052D000B7DFD91EFEACB147BDE82FD56CB4FB419A -:1052E0003259CD339B7FFE28F2F5EF1C1467A87E60 -:1052F000E6F05B5743B97A873D7D269F865BC98C74 -:10530000D1A31EFE5F362686FFAAE70FEBBE51FC37 -:10531000FD8FD26274A8DEB15F67A37AE3ADB47D7E -:10532000BFDEE54E408FF6F7CAD1DE5EF1E4973A74 -:10533000CAD527FB149695D7FBFBCA8D87C99E4318 -:105340003C11FD047D7AE8D58B4ED16FBD348EDAE9 -:1053500019B87EF545A791B8F665101F3FFB12C638 -:10536000EF7FEFF0E3FC2B9FFDBE17E7F191D6C076 -:10537000F9F9B195990118B7D21ECE34E8C9DF57B3 -:105380003E7E27F1D9A2637766523C8005726CB4E9 -:10539000868673707E0B36DC40F35BC842C46F9523 -:1053A0008FA9C108C6B334367D470279784DC8C38A -:1053B000479B1CB8F6B08F50C1A27FF8BA4AFB04D5 -:1053C0008CDD41F1863BE53E045B42E5CF9D9C4E82 -:1053D0009B559B8C6F382D7CBAE59E4EA4CFA9417E -:1053E000812C8C4F021EC2025F0AEA1DF5D8D42C14 -:1053F0004E1FE6D38AC577A0174BF13DB6EFB40731 -:105400005C4596EFC43AC6C75F2AC607B893D01E5C -:10541000FB2813EC9B04F3FB52957A19EC0D137FD8 -:1054200099E49ACBF9967BB95C4B398FCC9A8EF57F -:105430007F7A83CB0F7E87EB3AC015CDA2FAFDDFD2 -:1054400051480F385834913C6FB10B79B6D6CBFD2B -:1054500049805BC3F529C627D07F1AE19FECB4854C -:10546000EBE03B935EAEC7F1A89D1E7B6F5AD7174A -:1054700009F97F5915FBA342FED9062EF77DDBBD46 -:1054800061EE1FD8233F7F14E515E413D7999A677F -:10549000EC419CF7A7DB0FBE750BF0F5A7ED524E64 -:1054A000AD7A335E4E2B778E6789E4F453B79F2530 -:1054B0009453789F504EDD5DC4C7FFD97A53E2ED17 -:1054C0006C9CDE947AB02FFCC5EBC135AA2FA11ECF -:1054D00084BF3758716FBE93FC26F9ACEAE9DAC194 -:1054E000143792FC28F9AD871F25BFC5CFD38AB7E3 -:1054F000F8FA1785BE9174B62F67610FC64BF7AAED -:10550000E45F9F03985A80BEE7B6E74530EEBCD211 -:10551000C5E317E78C6E6F1A3C57A6F2727786DEEA -:1055200082FA41BEEF76F1F8F6B960B737D5E457A5 -:10553000BCB747F5FAA0BE2BC2A627F23740F3123C -:105540001C5DACAF7A1E0F9EAABA7397A1DFDEA6D0 -:10555000D27E7645D34D5EDC073EB767C84F503FDD -:105560002D78050C4C80F71CDA812938BD808679AE -:1055700009B70B7A7FCCC20F4D86F9DDBE87FB0BD6 -:10558000156BE2EC7BF7521DF50DD8F727AC716D6A -:10559000CE3755A29FCA0DD6FA2AB686E85615C749 -:1055A0004721E1074ED0041F8D66A3851FC6E31770 -:1055B000425F4D550B7F8276C6B9A33CAE787E8F95 -:1055C0004AF83FBF5D8960DC87E2BB9390FEDD3A1D -:1055D00033F9CBA791DFF4BEE5F8F40B7F28BE1BAF -:1055E0009AD4EC7ABBE8A7F03CBDEB7705BFC4F2D8 -:1055F0002F7E9BFB36EBDDBE74DF9F69FFF8DC3E40 -:1056000007C1716EDFCBB97763F925871FE13CB71E -:10561000DC41FB67E17D9EC830AC1F04F4C67573A6 -:10562000EF97455DB4EE34139DE66B7CBFE3FC9EC3 -:10563000FF7857C1FC833D0E1FCEA37E1FCF0BA961 -:105640007FC9457197737BBF2C0EB9FF7EF3A9D339 -:105650005988F8CFC3E6EC447E4DE5FB00F5BF9CCE -:10566000B4B909F7C33BF6EBB8BF52FAABBF16A10A -:105670007E39B793DB0967ED5D8FE33E68AD367425 -:10568000B91DE51E6DB6FE6077DA174C091726C204 -:105690000BC7C339C003CE0BF052897AB12F7C34CB -:1056A0006BDCDFFCEF878FCF6EC3F16BF64C20B95C -:1056B00089E14509F0F79E8853A1F9F3F7FBBE2C69 -:1056C00042BBE7D3F6265AC72F35EFCDFFE3E6AD51 -:1056D000442F67DE07FE9BF3FF748DAF4BF172D052 -:1056E0009BCF7F7117959FF5F809DECB94FF13FFD1 -:1056F000D3E8BE13E8EEBD34DD15FB7FD7795F8AB2 -:10570000EEAF08BA7B0CCC2B38B7F7AF142F97F35A -:10571000BFD4BC7DFF8FCE5BDA3FAB6CFEB67C683E -:10572000BF86453B7D00E7CAE1B3DB30CC046E4267 -:1057300030913D12B473FF4855781C860DE27121FB -:1057400026FC094A01F3611C6521D9759ABB85ECD9 -:105750004CA6F93B03808F5523E7FB2957838D39EE -:105760001EC2F2C0C97E8A6FC6F955CD0A0B2860E9 -:10577000EF6923BF7114ED7CFB705BD45144CFF70C -:10578000F0798F8863D90DDDE24FB8E3FC0197CF44 -:105790005AEF10FD39D998B67CCC53706B4604C6CD -:1057A0007797B4D17CDCC3186B33ED033A98E97B6F -:1057B000E8AF1003B026FBF1EBE2AFA9077F633A35 -:1057C0000388BF11368A6B51521FE1C31F59457EB2 -:1057D00026F71F63F86CE9443C6A0CFC3F3E3FF23D -:1057E0001B99F01735D18536DC167059DB09BFE8F7 -:1057F00092F4E1F4C8AD11F45962A187C47F02BAF2 -:1058000058E821F1FB75E9124F8F78BC7FC7CEE3D2 -:105810006DF174B2E47764703F240A7EC8CBDB3745 -:1058200053BCE3CC53EF7D0BDB57FF52654EE8E7EB -:10583000EC760F8BA2FC6A111DFDA9AA0E35619CA6 -:1058400057DAE5D5CF7968BCAA9D8EC84CF8BE6AF8 -:10585000D7FB4564372DEF3E3200E3024F299C7E93 -:10586000E1AE22DCB7ABD2B87F10DFDF063B8F0B97 -:105870009C7E31790EC61F946D3C5FB1AAFD26BB9C -:10588000C3C46FFFCBCEF35EA11DC973F84985D6A3 -:105890009BDEF071BFE0F4930A876FB73D82798F8A -:1058A00055DB36EA21F42BB77D4671ECD2E79EF149 -:1058B0007691BFA85AFDE76D2AD1139E44BF783F69 -:1058C000B6AEA396FC84BA76E127C6F951D5CFEDE2 -:1058D000DD1506D4543FFF8417E32FA73AB77AC9E2 -:1058E0003FDDC6FD4FCDAD25F64F2FE597B6DF9BCB -:1058F000D02F3D85FF007F62BF3DCE9FDFD6EFF208 -:10590000F62F9FF9FC718C939EDEF9E9E30877CDC1 -:10591000FFFEE3E368DFB37D2E632BCCB7FEA93730 -:1059200029DE24BF7B5BC8E9D9412C9C03EDCEFE68 -:10593000CE41F92367F77E948BFEDCD91D7FCE44E0 -:10594000BF7EE9DEA95938EFA52F9466B104F22E87 -:105950009FC89791CB8813C6D3E160C741F243CE6D -:105960001C7790DFD7135F68AFE5F11A9F882B6C27 -:105970004F1C8795FE705DC7FBE53C3E26FCE24B65 -:10598000C511DE003A5E7519F4DA2EE24471F43A7C -:1059900083FF00BA7C1947AFCF59E86739B80FD9F0 -:1059A000D1AFCF3842F432F024E3BB47EC019B8EF9 -:1059B00072B033B9874E33914ECF7C9E8BF1F08F0E -:1059C000EDDD64F774EF7518E8DF57EDFD2DC9C5FF -:1059D000D9178E51FC948938EB59D6F3C7E3628A04 -:1059E00098DF160F8F3F087C637CC2E7A5F7220E75 -:1059F000C1F955C627FA8A4B4CD045DE93883BD770 -:105A00006E795B6771711E6522D2E93D4B7C5CCE7D -:105A10003BBE3F03F130C11C5F4B1CF7917E738C82 -:105A20004E3CAE26E36767378AB81BBC1F3806FDBD -:105A3000411EC7A88F28BF6509E450C6D7C6E871C4 -:105A40007218B9BCB8DAA5E0FD5BF1314CE7EB8325 -:105A5000C4CBE9BF24D6C3DFD4B95C4FB78566EAAF -:105A6000A6FDECEF897D16892F09EF69918777FAFA -:105A70002995E2412DED07499FC6CB735D1FE720B5 -:105A80006ED379BCB56EF7FE22D43BA70FBC487C21 -:105A900057B7FD3D3D0CFD1CD9F6BCCEED49CEE718 -:105AA000A8A723263D7DFAD9FD453CEEC7F36EE35A -:105AB000FBAF16FDD7EFB1F65FBFFD334BFFD5E16E -:105AC00076DAFFBAD438A7B4C04D38DF539D768656 -:105AD000FAEE54BB3A3D92C80ED4ED967DD0966353 -:105AE0003AAD57E35E4FA2FCDCA5C7A6BF9D82FB83 -:105AF00074206668FF763471BEEAF8716000D2A542 -:105B0000E3D82D2AAE1BBB108F263BB8F88D8652EA -:105B10000FC86BF13BC171C856F17A60C2719B0529 -:105B20006E18270BF57133F483F9F4983F84FBA3C7 -:105B3000AAB77C3AC2A31A36C39570FDE4FDD9DD3D -:105B4000418676B9DDB0E62B67CF1671B4A8356F04 -:105B50003D5B67C3711F9CD992FCB81FB064446061 -:105B6000F461CCAB5F904D71E29C6FF3EFCE18EE19 -:105B7000B0EDAAD8BE6DF205E81FF3606C91B57365 -:105B8000E1BB64AD5DC17D007832A4CB9DB6D0266B -:105B90003D03DBE9CC07AAF1715DD128FF429C7B74 -:105BA00091FDC9767DED07CB7348AA807F88D80F19 -:105BB0001EC4BA14DC0FDEE0E1E79106BBD3E9BCFA -:105BC000D16661B7F970DF15DB3558D7ED4B9E47CD -:105BD0006AB596D34B4BEE18EC073F58BFAB540356 -:105BE0007D907E53C98E0106EE4BAF2BC5BCFBF4F6 -:105BF000274A46E740798EA3A88CEAFFB564742E45 -:105C000094BFDF3AA98CEAAB15CA0BDCAB77978659 -:105C1000DD31F9CC00E316F32D406E0FA0DC9E09B8 -:105C20009E6EC1DADA1BBED0F9791816C4F90F9A44 -:105C3000C8E73FD0FDCE0E9CEF605B5713F2DFCF7D -:105C4000F67E998AED7CCCA0791AACD9C07D7978A2 -:105C500035F1AB8BE4FFC4E7C1487E7F2E39F41BDE -:105C600084E3DEF9C31F2E479D5AE3273E8ADF27D0 -:105C700066463AD1A542D005E1749AF2902BF12400 -:105C800002E99B3203C751C235EA57577E7D784EF1 -:105C90004A7E11E7C04CE7A43E41381F490ED1337C -:105CA000FE9CD4013DF829F253CEC20BB908BF3C8B -:105CB000FF54BAC84D7181F37B58C491407EE473A0 -:105CC0005323CBD086F65DFFA623F4671C37FF571E -:105CD000BE9D47A1BFAB2A743FA6AE5DB56C5C8686 -:105CE0003696F109A13D21E8968DB444F9BA8BF1BD -:105CF00073390E25807EE3B9EF1BA47F0756CC24B1 -:105D0000FFE25C725E3BE64F9CBB9BE701C00AAFC3 -:105D1000A01C0CDA931245FF07F8F88B383EFEC240 -:105D2000BACE58C73DF7956F7717F56788FEC0D094 -:105D3000C944B9E17FE7546E679F6BF4111C60168C -:105D4000EEC7F5F472C7CB7658CFE901DEFB3B4CCA -:105D500078CF75F449BF3C07A71F3DE3E9B7D0D919 -:105D6000908B725C156C2F47D7F4A385771523535E -:105D7000BFA987AEC0F635733A8FF09CA18602DCCE -:105D800067EB4D5F7E1E2B73CFBC263BC62B903E30 -:105D9000BEDE74BC6A993F43EB67A1EB5884FFAA4F -:105DA0003D9FD9107E49CF87459E7FFCF7FFE85085 -:105DB000C4B8354D768C93ECD6C99E8D6F371D0FC8 -:105DC000558D8F958B9CC5346E968DC73B7AB7E702 -:105DD000EB5FAC5F279DCBEA8B1F8B0CDE1FE0FFD8 -:105DE0001B66FC7FAB6FFCCFC276807F7A7E0DFC9A -:105DF000DF84EDFBC2BFB4A3AB855EA8C67D14E013 -:105E0000A30F03B33387C2F8E5AA9BE460F156956C -:105E1000E40FDACFCCC98CE991C5931AF6E37C176D -:105E20003FA610BF568873A69F8ABCFEF87CA88543 -:105E300073C2B4BFD32B2F2A12E7D7C5E5BBD7C790 -:105E4000F87630CF53E3E7B6542117A58B0A53D029 -:105E50001EDA67F7FD2BD9D9AFA86C5302FC6F444B -:105E60002633D1755083CD9227CB2A522DFD962D06 -:105E70002AA47DEF251EDF45FDAAC1CBACEB765EE3 -:105E8000D87ACE6848ABF59CD1B0B6FE96F657AC42 -:105E9000CFB7D48F888CB4D45FB96D8CA53CAAFDE4 -:105EA0006A4BFBAB764FB1944747BF61693FF6E859 -:105EB0006C4B797CE72D96F6138ECFB7D44FEAAAB8 -:105EC000B2D45FF3F1124BF91FBA7F68B5536C8CF3 -:105ED000F4234B52485F1E6A9C988BF9D86C9C52F5 -:105EE00086F82C15F98487EED06D86179F0536034A -:105EF000F4D681053369DD3F744766C047CFE200C1 -:105F0000FA354C9D3C2E51BEE6546352AE392FAA51 -:105F1000D469B7E8B7A986B5BCCB21F6FD0673BE38 -:105F2000F9659C7CD91B2647C13264FD170FCDC291 -:105F3000F140CEF6093DB7EFB2F45C6643319641CD -:105F4000CE0E25923326D6D912C14FF00CE8981FF9 -:105F500059E6A1F538802F7DF43EAC81BC4C71FA36 -:105F6000071EC679D9FCE9C88465738287787F6289 -:105F70005D66C36D5F675D96729E6D13F96B693CDC -:105F80007FED91050529CC84DF3F386CC28E6EE32E -:105F90004FE3A8AB276F35DFFCFEE324CD942FA79A -:105FA0002C9A49F922D97DE8453D3B7FC616D0C7DA -:105FB0007A8E8F9EF27DCB1C5BC23CB06EA147A552 -:105FC000BD3522666F75233DCE64BFFE10E629D530 -:105FD000CDED267B2BDBD676C7119CD7ABAA885F8D -:105FE000FAF8F92A61272F98F1C01D47705FFA5F10 -:105FF00086917E92E36C689C3E43339D231FD88735 -:10600000DF74A593C3F378E3F0191594B76DF0F33B -:10601000A2A2FFDC706D39DACD8345BEE943B6C478 -:10602000F92E6ED14F16921CE135DC24276716BE7F -:10603000E3D5601E8FC2EAE5C47DDBAB3A8BB91DA8 -:1060400016F0E339D4DCE8AD0F61FBDC6C8DF25D5A -:10605000E3C7CF9A1B6ACD83F935A7D9FC6E2A779F -:106060002BD8DEF123C6FA41FBE6FFAD123CCD078B -:106070002651FE87C3DDC0703F55CEEB60DAA384A6 -:106080001FB52399D64126F6C565BCF5F3EC8A4EBB -:10609000B4373E5F67A7F13E87391AD0FFE71D2A64 -:1060A000EDBB1E494B8ADAA0ACB67A68FDCE45DB63 -:1060B00013DA2FECF0447C7931BC68EB27D37918E4 -:1060C000C7403EFFE63477C49D47F34EC7794B384F -:1060D000E5BC07F5E1679608B873AEE839A7C1904B -:1060E0008F5543A37E17A4F2739891C689825ED61A -:1060F000F9B464CFBEFE663C3FF486CA3035C4D7DF -:10610000D546F35F08F3C7786F3C7ECFF8F2BEB098 -:10611000A9046709C2A9AE2FA779503BF8AEF6676C -:106120000A7B340FF930349DE8DADF46E7027BD989 -:10613000074E2E5F339C3C2F57CF2E98B1A51F3EA4 -:1061400087925C7CD3D9E7BA1F74727D44CFAF715C -:10615000BF00ADFF521FA9019BB073B95EEAB19FAA -:10616000F4D0779D19B1B29AF2A322ECB76FFB6C11 -:10617000C77E1DED333723FB59EACDBEEC33B4CBDC -:1061800090DFA45DB6386E9E30BF1A31BF9A44F3DB -:10619000EBA56F6F699076CD12E745ECCA0C3DB167 -:1061A0003E7A52D0A1DED019C59B688D02BDB3D80E -:1061B00046E78D99167199CF976F704ABB6ECF7E67 -:1061C0001DF10CF3463C6783FF5C4E7AC79E302F6F -:1061D000FC52FE48FEEAC29D47B13FB07311FAF38C -:1061E0006DBE94B48BD817F665AFBACC787DC02954 -:1061F000F2B963787C50E0F1C184784C073CDA2C2A -:10620000F6E1AE021FE1F1A7CE8BD88767BEFD6E27 -:1062100031AE476705BEEA7AFC5CAE9FFBC32285C0 -:10622000F1AA5ACC5F76F232EE07ADC0263998DF7C -:106230001C7C02FBAFDF6D3D77F863278F9331370E -:106240003F372BFBCB14FA1EFCEA7FFCD0477AFFCA -:106250009F703E31FFBAAB18FDAB152F5C91827673 -:1062600059D9AE9B0D7C9E4F1F4AEBD9995D8E008C -:10627000C279268DE7EB9DD935E108C61F3E6D3CFE -:106280009A6FD6F7679E3D566C877ECEEC3C56AC37 -:10629000517E70C46217D67EF59B623C8725F3AAB7 -:1062A0007BF8C5C9D789752E1ED7C8C8D45B305FA7 -:1062B000FC42522AE1EBC14CDBFD89E235A83E6984 -:1062C000DFDEA3D33EE59211BE156E8CD7E41994A0 -:1062D00087BB4209E42CC07D96594E3FEE03A4E7EC -:1062E000B3E1792988C21073033E1D87DAE8B869E3 -:1062F00052A7B11FCD2319C7D14AB9BEEDBE41A7E0 -:10630000BCB164CDF7F05C2867CFD168BD93711D37 -:1063100047323F972CE33A3DF0BC62A77568495E6F -:10632000A8AD04BE5B32298DBEF3CE7A8BF8E59C16 -:10633000CF16B6E37CB46E8AEFFCA47178C650C069 -:10634000A391639B4136CD5F005BA6FC7FAFC6C2C5 -:106350002960DFAC06FE1F0AFCDFD1E8A4F62D6041 -:106360001F1A69744F42EC9E0F93DCEC6C34A8DD6D -:10637000CF1BB3E9BB071A7DF4ECB12318FF8ECA1B -:1063800009F4EB7FD6F3BE467E9F882CFF711CD8A4 -:106390006940EFF4094055C04BBA387F2EEB1F6DB2 -:1063A0007C6548D950810CC067FF1A63E3AA8BC093 -:1063B0009BEE88A4E211E32B5D2C5C3611F3FCBA52 -:1063C000EF2F4FC5F311F794958D003CE2FEF6D503 -:1063D000402AD703CD783E35A7C6D78471BF9CDD50 -:1063E0004A3BAE5F39BBD796E03E02B4A37383B29B -:1063F000DF0C17D773C9071F51F247E1E602DF9799 -:10640000677B932389CE978E73713DE777F1FDC14A -:10641000D5625FBD7B969BF462F24117F14BCE9E35 -:106420002B697FCFDDC7BE727C3FC907FF4C71600F -:10643000B7D2B61FF729D9026E7F4A7EEAEB3B6CD2 -:10644000AF5F46FB737E8DE2C260F6D2FCCECC1A03 -:1064500048F8C6F6663D7E4E4F6C9705049E56DAA8 -:1064600013C7E935C6C719D7D94DFB99786F13E221 -:106470003BE78D3605FDF5330ACFC7E80FF8D8099D -:10648000E59CC96D74AFD373CE50B90BBEFB93714D -:10649000BC602580E32AFC7D2E7E27F1A116E94E03 -:1064A000D427397BDEE3E77C6C5D3AE6BF2DBAF793 -:1064B000798A3FAA7A308F9757AEC4F8648637B886 -:1064C00011F984859F2F3B047CF2A038B78C6F5064 -:1064D000EFAD768972B8BD39007CB2DACECB8BEEE7 -:1064E0007D8EF866B53DB818CF3D63B919FA5F9D4A -:1064F000DA9E6D83B2BBE999E6A383B02CDB3FD370 -:106500001C9E0C76A84BEAE7600EE2BDA76C4079B2 -:1065100094A9ACF13273F2A79C5FEDC13F1F190043 -:10652000FC52B787DF73D383B7DD6B155C8F7EDEDC -:1065300078D4D7AC093991FA03D6F92BB219F929D5 -:106540007A4489E42B78DF476BA6395FE5BBC98ABB -:10655000885BC0F7E6F863DCB9363A2A83EB73331D -:10656000CF0B89A7EB9B49256D4919781E35B44A95 -:10657000453DF88CDDA0BCFA2E8DF4F6699957DF05 -:1065800060277BB0469C73B52F0FAD1A817271AB3B -:10659000E6C7F842755E5B09DA43D52FE6F99B58EA -:1065A0002C4FB73AB53D738C3B96A72BCB2B445C55 -:1065B0002A2BB52135B510F763D6E6E27E491D6B6F -:1065C000BBED8708EF6B2A437EFF64FFA414BC7702 -:1065D000A816CA1807ABED38A687A0DDD549FCBEC2 -:1065E0009BBA0EE01B37BF872650C0D846CD484225 -:1065F0003DFFF340C348348937BB7E5DE6FA07C6EA -:106600009EC80F1848E75FDD7BBCD98965DD18C1DE -:106610004663F9DF9A91CFAA47DB28CF9285FFED39 -:106620005060A8D8EF8572AB6BD05473DC3B479CAD -:1066300033ACDFE0A6F360B02E6F42FEAE5B6F0BB3 -:10664000E3FE99CDD949E7807EE562823ED6F353D9 -:10665000EB14AE0FC30B783C75E98CB46FD0F9A97D -:1066600095F946F82271DDCA0B49744E4A96AF4E31 -:10667000F251FF955A98F6912A2F78E97CD5DF6F71 -:106680003CA7E5BC56EFF1DC048F1CAF26361ED1CB -:10669000F5E098571F1A0A745BBAC36E7398F86EC8 -:1066A000E90EB13FEF0A64613F193AC733437F10E7 -:1066B000788DEEB8E1E5B0960DFA5FCA77F87C7395 -:1066C000D964A45BAC9E59E53F80FEF87D49B2FCDD -:1066D0001FCD650313B44F8A6B9F2FFB575762FF83 -:1066E000F1F06424C5CA4E68AFFDD5D15346F8D643 -:1066F000DAE2FA4B9365F74A1C5FF255EBBDE98786 -:10670000C3C057F7A5B695A0FEEF5EC07C788F1684 -:10671000F2ABDFA46F5B5D5CAE2B2FE45BE81DC3C7 -:106720007B81852E1F35665BF63D17CD5D4AFBB339 -:10673000AD2E412F16E6E76C360C6011533CE8FF96 -:10674000C3F1B7C271751F70FCE37F311C3ECB787B -:106750003138865AE0FB5BE1D87463C137F2A0C9D7 -:10676000834AD8998FEBC28F795E9C9A5AE66BC2A6 -:106770007D991F6B14D71FC678BE4BBEC68E6A6349 -:10678000507EDA02180761CBB9BD02EF5BED63689A -:106790001D227F61C81EC73CCCDBC8AF0C2CC627AE -:1067A0001B5848FB3E729F948938A1DCE71966B0FC -:1067B00012BCF7EF44D23C5AA7F28373AB31AEAEB2 -:1067C0007AC625E17AF8A02D12C6F1C20FF0F13297 -:1067D0006C917627DA4BDEA106AE77195EAEFFD854 -:1067E000AA425AFF36D9F247DE0170AC544A925E93 -:1067F000413CA7E6537C1CDFE33D3B9BC4BAA5A606 -:10680000FA0D5CA73689756B85D0EFF27D725A70F0 -:106810001EDA113F59356DAA7312EAA1406B3F5839 -:106820006FEE5F356D65F6245C6F7CF94E585FEE58 -:106830004F9AB6D20993D9D4E4EB6FA4C6CAC3FE6B -:106840000AAB35E989692B03A0779ADD4BAAD0CE34 -:1068500081FAC3E8273E9126F50EAFCF977A0AF565 -:1068600012E831B5A9A71C46BD94DFA377A691DE37 -:10687000D9F2B84AE5A5301EDA31308F30DE0FD6B6 -:106880003D4C23FFC805B02441D935229FF6CF6087 -:10689000DE2C09FDFF11BC5EEE77E8C36CB4DF812E -:1068A000ED118FAE1CDE5E9FC5CF4BEB1E37F96D31 -:1068B00072FF4415FB7749224F453166911FEC5C0E -:1068C000336609FA51CEA1D6FD693D2E9F458DCF85 -:1068D0006F7147C9EE6A4B12F1EB7E2C9BEE4D10A7 -:1068E000EFC1521E83CFCC9B9B4BE83E3D0F333014 -:1068F0009F3A3B1465667B493E1DB08EFA4C72E3AD -:1069000070B340A27C8A85C9DC1E765FD0B89FA890 -:10691000807D83EBA847D8E1C23EB2CB7B8EE2D626 -:106920005D692FD9C57D7A4B674CC9C27349AA3BB3 -:10693000E0443B67BF3186F66954E6BFBEC464EFEE -:10694000344767507C5233020CED9C57859DA31A47 -:106950007E66B6735A1AC10187B56A737101DD5F2D -:10696000F3A82BEA1C82F47DD0E647BD71704C552C -:1069700058C1F8E4324672BAB938730AEE336CD4AF -:106980008229B7A2BCBC01E3F938DDF83EF70A055D -:10699000E3E99F3B8329A80FEE4B65163FEAFA64B3 -:1069A000EE8F6C4DE2FA47FA092D004F14E0D02E1D -:1069B0008CA4FB7C460BBB549F5B46F1324C03C25C -:1069C000F8A78335840D77ECBE3A47B6CD92FFA881 -:1069D0005D28A278E2D6243E8E1CF71E71DFA02C23 -:1069E0003B59038F1B038F27F2DF6A059C0EB0878C -:1069F0007C649FC4EDFFF7B68FC85E91F4E9B15394 -:106A0000147E2EB42FFBA8FE82CDA26763E7D97552 -:106A1000D2CB67C57D01320FC42DF4594B76A8ED5A -:106A20009ABCD8FD009AC8075923EE0560D95AB719 -:106A3000F91C7E32C663A0BE59E48524C79DEB775E -:106A4000B99792BFE01AAE59CE81395988BE73F812 -:106A5000ACEFB5ECF8FB02C23D796094B7A8B14742 -:106A600014BA1C80DBBB03441ED699E47729DE08E8 -:106A7000F6EE4127ED4BF073A2321EF675EDE357AB -:106A8000D1AE22BF70FA68EC7711AE4718CF66C15D -:106A90001CBEE9D8CE286F28C9DFC5F89D63646F96 -:106AA000A952CF859F6F463F2AC36CDF99ECB52B67 -:106AB000573FDFDC5C487E079517DDDB467A70A523 -:106AC0004B96575319D6AB28FA3D6C97C387FC04F5 -:106AD000DF07506ED88D05642FABF9E0D202DC657C -:106AE00078FF21EE0FEC726C427B16FCDAF92E5324 -:106AF0009CEC8CE7782E2B4CD85FD8D25FEED7EB8E -:106B00000FC6EFC03C23595FE65D1F55F9773EFC89 -:106B10008E0DEC7C370CFD3FF88283EE2591F72C2F -:106B2000C7F3EB9464EEBFA3DE30E773EA732B0286 -:106B3000C89C523E1DD949963C7029AFDA85E124A4 -:106B40009FF2BB5793F8FEB1A60528AEA65D282498 -:106B5000F9DF2AE8DAD2685C629CB43EC61943FDCC -:106B6000F43D4EB1D0134CEC8F6986F91E99BEE40A -:106B7000357E3F305EBFC9A7D46FFB44FFF392ADB3 -:106B8000F1E5AAF5ED4790857E680B55248FC7BCCB -:106B9000AF77BCB814D7D8A245286F77F67E5F8749 -:106BA00093FBBE8813146CBBE300B26B4372684363 -:106BB0001294AB92C53E4036AC6B2AAE5B3C6FE99B -:106BC00011ACC7FC8690EFE1A9A8A7669553FCFA23 -:106BD000B9E4E06FF0BB7B671753AC40C2BDBA911C -:106BE000E7DB497DE9467C417B87D6C0E39EEE40EA -:106BF00014ED8B0792DF9CAA211F6A5C0E96AD3EB6 -:106C0000B012E3224ECD4F7CE574DB7CB8BE3BC1B5 -:106C1000BFC375AFC96DA378D20ABC07380FCF1BAD -:106C2000CC34505E9778F2B3D845F4A3762153E87C -:106C30005FEBBD3A7FFF71D2E9FB5EF7F71C9C1456 -:106C4000C5FE343FA3FC1944C2FB26BD2AD7F5F884 -:106C5000EFE2FB97F894F8756821C2AB8E76430299 -:106C6000B89E4CB6EEDB6649FD99FA564114DED665 -:106C70002A5D5EB44F402F3E897C5237AAFBD78AEB -:106C80008FF46926B767C2F2BE02CBFD48322EAF41 -:106C9000BAB95D23E15FF2CA834EF3BE533CBCF147 -:106CA000EBA5BBD09A9FE11C9814775F70131F4728 -:106CB0000B12DFD827079C28274DC61803ED9566D1 -:106CC000CDF7DB00E595D8C96E063BDC32BE7CDE35 -:106CD00027EE073E26ECA8F87A8FB84F39FEFD67FD -:106CE000C27EB86FFFCDA487FBA21F1EA846FA7A0A -:106CF000F29981E773EC025EEF25FAED8B8FEEDF00 -:106D0000CFE3BADA4467045DACF8F1547B3080E736 -:106D1000C9D4D18CEC5D75101F1F6869605CD83BCD -:106D20002E8D0D37ADB3F70E9DCDEF77CE30E87CCD -:106D30009FEAB10513D999124F8792E53D159C6FD3 -:106D4000B225DF0CFB3DDD836EE29BEE447C7328B5 -:106D500099EB2B84C34CCF7B87E66725A24F4C2F42 -:106D600072BEBA145F7488FB126B1137E0DFD488EF -:106D7000F3F6A7C53D41F393C57D4106B78BE5FD0D -:106D8000171D5A2019EDAAF93DFBD4013A9752E399 -:106D90000AA44C42BE3CC6EDDE8F4AF8BD651FD941 -:106DA000032988E78F8EA94A13EDF3F3BC40996756 -:106DB000F591DDB77A24D4DFFE5335D044D5567B28 -:106DC000EE340B8CFD17B46F77ABB47F94F7C03CF7 -:106DD0007514B4AF00430FF9687EA93B8CEB6FC705 -:106DE000EF1BDE453D74FBE30EDF7218E7D0FAB10E -:106DF0005F60F9E41A8FCF4171B27C05EF155FBA7D -:106E000036CFA0FDA3654CD81943CB4B8732F6147F -:106E1000FE53C69D9D74CFB8A80FB694C1FC4666BC -:106E200074D8DC0053C41D6CC1734E2B9B82D9E80F -:106E3000FF5DBFA6A005E38F999981CE6B411FAF7F -:106E40005833BC1CFDC18E47457FE1112DE8EFFD95 -:106E5000D216CA53A0FEA93553CA292F7788ECFF52 -:106E600046AA9FFFB32BBE386E204E2BCB31665601 -:106E70003C57C2535B5E0ABA7DC164595EA2633956 -:106E80003D9959E260F6983F4971B68E1EFFF1AE0A -:106E9000728C83DD3EA5A15483FEF33C3F6A290436 -:106EA000D198D0566204F0CA5CCF03E5C919786B5B -:106EB0005EA01AD793919E75E5389FF47ED6FED3D7 -:106EC00055114F65EB5BB0BF1EF8C2DB5A30BE2ACE -:106ED000DBBF7EDF5B2DE18131BEFF56EC7EA56F0F -:106EE000BA33E8DEBA231862CB5DD6ADF37C5E918F -:106EF0007F33B0AB88E71589F2F02E9E772DCBD982 -:106F0000BCDCB13CF13AFF132F97B78EA4C4F53F18 -:106F100076737D0170939E4F39CE02DB13C8518585 -:106F2000DB4DED0E839DE74C8BC9D3F50EC6266273 -:106F30007E9393C329FB89FFFE6E310E0B5F9F8604 -:106F40007C3C53F0F910BFC2F394762747F0F71852 -:106F5000C0CBD2BE0DF3D926E211DB5CEC7BB36073 -:106F6000E8CC2416C27B7332FA41B990BE0FEC70A4 -:106F7000C7FA7B8D8B309B3A24B805FB9B9A9533DF -:106F80007A455EAC1F80BBD939C602B736310DEBEE -:106F9000C3FD314ED283CF423E0FE013C2170CF334 -:106FA00034FE7E4047E7C87CD4BF2331E9C6A4E75E -:106FB0008B3B67D3799AA55EB13FE2E3DF6794F23A -:106FC000BC97EE1793F9FD99CECE02F37ED6C36E31 -:106FD000916770CFCC87E91C74A79DD1F9851D25D9 -:106FE00017CD3BACC1B89CC96EACD1A2E48FD560C3 -:106FF0005C6E2CF6F71A9D3FC47E7C22FE8C71B528 -:107000008C1589E92FD7C19A0B060BF7EBAD2F63CF -:10701000FDA7B3F0D84BCF2BD69FD56FECDD9F2EBD -:10702000E2F802EF9AC0BB9E18CE7D924F01DF3688 -:10703000137F2D10FC26F703CFEE1AB1C9BCFF2A2F -:10704000CF0D817E7E1A7F1F21DC9944FE4AB11646 -:10705000B80EDB1777A6D1FE80E40FC91792AE1DDC -:10706000690D146FE97E44A1735CF1701D9670ADDB -:10707000E7F7F665CD0DA9E67BC6A53C40FF1DA24E -:10708000FF7113497E1EE3F20072732BCA2FDEC319 -:1070900082F3F07715997F8F40C25F84BC389EE8F9 -:1070A000C8F1FF824BE4AF70BCF5C67FFF4BD03315 -:1070B00097E859DC7980E659D387DC5679BD3C8F57 -:1070C000ED78D4EB83766304FF77B4BF4FF78A750E -:1070D000EC5699E2E3F346BD55DCA38FC7BF3C05F0 -:1070E000F471564F19F4A50FE9D0A33FA34E67AC36 -:1070F000FD77BDE3A735A3BE14F7F6A6AB7834370A -:1071000006C79FDCDCBE9A184A1CC76AF07A2C7A44 -:10711000EC916553D8FB30FFABDD3CFF6A625798BA -:107120007E5747CA75BC9EEAE7E174343CFF97F48A -:1071300094EB127ACA25F5147F7F186DDE31B8BE44 -:10714000761529603757D80299E87F7D70EC8774EF -:107150003E6591C8CF1985F939B86E1E0FD2BAF2C3 -:107160000956F23C9D819E0CCCD7B6E6E9B02DFCC9 -:107170005C6B3C5FC5F8282CEC370187580FAE7765 -:10718000743DCBE3195679966580B3CE36C454EF7F -:10719000E6EB96A403D0BB99EE3916727C6257D603 -:1071A00046D4B7AF7B789E4DFA90C0689CBF944B95 -:1071B0005857059FD8BE37DBCDF5C6EC04FC3BD94C -:1071C000C3F5EC82F59C6F3AFEBDF43AC47BC7EB85 -:1071D00069A9CB4D7AA24CC8B1EC57EA21F99DAC14 -:1071E0009F22FA9BE6E17251E6E67C877024CA276B -:1071F0002833ADAFC43FAD9C7F60BE61337FBF2EEF -:10720000FA8DE153ACAB02CFB53AE017F0B7CD1E23 -:10721000EE8FF949C59D36EAAF62B787F2322BDAB5 -:10722000391E2BDAF6DBAA4DF889EF6FA987CBD18F -:1072300046710FED611BF01BE2DDCDE13BBB2B87FF -:10724000F4E7220FB71B2EBD6E5C9E9ED928F2314B -:1072500080BE94BF58FBD2808D563DCDFB4BEF17BF -:107260005A81E7F0D21F667ECC29033C45F1DCFF52 -:10727000171EA177F4808EE76DBB1F61B41F3F6CB2 -:107280006E60B40FCAF541F71805FA2B68E37AB8B7 -:10729000781DD83128774EB92EBCB2DD3CDEDD1E1C -:1072A0008FE51C61C57A8EBF6160FF3C8D4FE8E7BA -:1072B00059B2E3393C271E6ABF06E34EF2FB564142 -:1072C000FF4BC1578CF08D8BC187FD53FE8A3BB8B5 -:1072D0001CFBADFBCDCE01E67E1FECE977FE14175B -:1072E000EAF9B5B0EE9074860EE2B98B8A3DA90634 -:1072F000DE9300F26C437F478E5BA1C9DFCBE92AA6 -:10730000C67BC20B7AC69174FDDD33E6F96FF6B821 -:10731000FFAEF4EDD043349FEE1D00AF2F86978E65 -:10732000F679CB5DB84E1C677E5C2724BCC3E6763D -:1073300079315FA45EAC1F305F1BFA2FE93FF5B1D6 -:107340001588B7CE29744F423C5F4B3A0D675C7E7F -:10735000A49F361C03FC50DEE32912FA87919F7B21 -:10736000E2A5BD4FF37B2D385DEAE7723A767942AC -:107370005F7832627208FA9CEE2FAE58D7A38FDA8C -:10738000F9FBCEDCB980CF5F7BA49C5BE9921E6CDD -:1073900077D125B382AFCFBC382AB28AD399C6EF52 -:1073A00068F7441405CFD13634A1BF2DF504C2636C -:1073B000CE5792F0F4D091011D47C5DE0F9BCBFB59 -:1073C000AB0779473EAA511B941C85F400C557B3FF -:1073D000500F4039AB9DB7637BF8FD0D124F353729 -:1073E00041A7E077FE9BA790E621F19535376AAB80 -:1073F00029C47CE503833F30D1F9A8D82F40BCCC09 -:10740000267F83EBEB1A353810FD5696E5A073A85E -:10741000B00E917E39EC629A0BFA7B199EB82E4D14 -:1074200055EFA0734253872824C7A00164BC877E10 -:107430008FEBFA6B9379DED65FBE3F14E79991CC60 -:10744000F910FA718A7E9CB40E8AF5E05F73C1AEC2 -:1074500053627AF9B0A2503F87FFE1CA4D2B9418CE -:107460005F627F683F1D56660DA4F5B22343240773 -:107470007559F2C97AAF675DB9586FF617D1BF8BEE -:10748000F99BCA3DD380A7264C6F8FE295D34D61FF -:1074900075DA3FC1B853C1DF74A1FEF472BE3E9CE1 -:1074A0001756BD08D73085EE573E92142AE4F7F4FC -:1074B000F2713245DC2653E42BA3BD80CF8897EBD5 -:1074C000FF9129FCF903F1CCF4268EF3AC13F5F50A -:1074D000E25EEB552589F3D9067A154BBCE57AB106 -:1074E0006F81F7FF7AB9DF29F26CF93E07D8F7848C -:1074F000DFD27BE6D2BEDDE79D37A4F0FB1BB83EB2 -:10750000F85009FCFA26059F41BA3F2FFCA64AF91C -:10751000EF1F18012FE637D52625CEC32E11F3AB6A -:1075200015F3FFA891DFB7B000F7D3407F8CF5F2D9 -:10753000792C6AFB7639D27BD13A85F6D3E4BEBD8D -:10754000A46FE506D5124F5F80FB69FDFE163FCAAA -:10755000DF871F35CEE247C971E3FDA9138DD996A8 -:10756000B8FFFCB621E29E0BDEFE76E627B86F6F11 -:107570001D60D9FF63AD1997770F28F84FE184F0AC -:10758000E9A46FE5FB138D4E1636C3F1F150CA7BAB -:1075900018E80DDD8CF48DC191CCC26638D864FE3C -:1075A000BB572E1E77053B9CFB2FF0DCE8263B9D4E -:1075B000EEA9ED898381FE3052501F95CCF38E8F5A -:1075C000F90D52BE6A2627F61FC6093F779C9BFB22 -:1075D000C729C7A53F9DE443BD28EDF1F8EF1A7A0E -:1075E000F8D66A4F5E2AFE00FC1B36FB47F1FDB65B -:1075F000887EBF3EBFE4F7C12F05FF257E77F1E40B -:1076000010C5F7F0F221CC45995066F5831EF5F2CE -:10761000F5FC516F327D2FEDEA8AB9D6768F63BBC8 -:10762000F1F84CBEAC788ED97E5786A0FEE3FDC93A -:10763000DFDDC93BF53AE57FFE0EFD44E8EF584A31 -:10764000602BF2C71A912FBFF1AF07B36F477BE8EA -:107650005FECB45F5FF2D8D21598CFEC6E570C3A5E -:107660007FB4DB2A0FDF5CD63EB802F0D12EE8549F -:10767000E3E7F3A8F147F5A16ECCAFE6E30F6CDFCB -:10768000AF68267E1B58C9DBBDE4B55BE233FBB0B7 -:107690000CFDECF11AD26FD93F231DDB0734B40384 -:1076A000FAE3EFDD003CFD1B18D9D1FDC729D4FF5B -:1076B00037C76D54F0F7B7E43C5B6DB30A0DF8AE15 -:1076C0003533D98FEBCD00237408E5ABE69D681404 -:1076D00097C709EF746AE85F8D320287F1BD9C9706 -:1076E0004F35FAA3DD9EFC0E87AFAD27AEC4D71B86 -:1076F000C6560B3B7413B7C7547694717B9CD6F572 -:10770000CCE5C369DD93F3C94C13EB46260B61FE50 -:1077100031B46F253BC5C9D7FDCCE5FCF7F2243D5C -:10772000637EE68831E8670E5913D5E6C3772F6D7F -:10773000B025BC5FE37D817798C7BBE6795C4A5F83 -:10774000C976F63EE28C92DF93A727F6DF19BB9F3E -:10775000EA4B1E4BBF85E4B259A7FB1025FE471923 -:10776000C1CF109EFEED1B15C4CD0991577062D597 -:10777000D30ADA91DF5FCC0C35013FF5C8EBB29D3F -:10778000832B4C7A13FA277A6C8CCB1397F116570C -:107790000AF77FE61B4196329EF276C97F5EBC8572 -:1077A000FFEE469FF8B84C7C2995DC2EAF99C37F3D -:1077B00077B4E4318DE85DDDCC7F77B066FB0E3ABF -:1077C00067C77EC4FC28EF35ED3B940A18B77AFBF7 -:1077D0000E6581097F036A22945F7D8547EE3B44F5 -:1077E000C96E8EE76B8C17A09D72C4C5E5FD7489C8 -:1077F0003B8CFB10A7EDA11A6C773A27D98FFB942D -:1078000012DF2FEF9846F71D78763AA2F86CB56D27 -:10781000CA7642BBD691BA1FF96894111A86784984 -:10782000D3821DF87D6ABAC78FFB183E071B43EB56 -:10783000F565E261421C3F4CF81197939B52BC42A4 -:107840002E18E53D5D9BE291F613E9A723763E8F66 -:107850009D8CC31BF106C6A5201F1EE5BF9BD0BF94 -:1078600026AA60BE48FCB8317E0A5C8DF05F3E9C63 -:10787000ED3AEAF56AA1674A1EDBA2BC6F827B067D -:107880001A55C89FDB372A1827837AD233D09E61D6 -:107890005E52FFEDDC2FAD86FA0526BD22E7914052 -:1078A000BF04713EEE773A0F71FD12E5FB0202DE76 -:1078B000787ACE4DF1D1F8E5601ED07B3D3C1CFDC1 -:1078C000E223F949D49F94F778F99C2BF8BCFF8602 -:1078D0002D8ACD4DFB2764474AF864BB6329534288 -:1078E00088AF09D33B090FB51B349ACF543D38F408 -:1078F0000E933CD4A5703BEEC04DEFD2FD3FEB7E26 -:10790000718CF8B116FC69F227DA8EE937E0BA1209 -:107910007E52C5FDAEEBB849C21E12F7625DD7C1FB -:10792000F56F6DC70E0DEF91947C9A77EA00DDA795 -:1079300055DBEE60E84701FF2D45FCC4F3A9C48F79 -:10794000D4AF7DD113F410F793C2BA88E785F2D093 -:10795000CF91FA3922EC51E6E6EFD78A79C5F827BC -:10796000D49262D1AF2E928BBC53630E605E66AD33 -:107970005FA1F392E9A5E277C84C7099FDBE78FD4E -:107980008871C320F7E373679BCEA9F5E879F1FD11 -:107990003AA4377F1FE5EF593EAED712FE78FA457D -:1079A00053B85E4FC0678FE13CE2D731B9AEE73DD7 -:1079B000BE53C3FB9224FF5C877437F1CFF6147E6D -:1079C000EFEEF6148DFA7FA884EF3B3E64E7EBD729 -:1079D000434D4ECAA37CF9669ED7E5B9458FE2F3C5 -:1079E000B06D7E0DD61FEECFE168B52DA773772061 -:1079F00097CF205D0FDCE4655C3F727DB8EE79AE19 -:107A0000CF6AC26EF2736B42DFA9A07CD774979FD6 -:107A1000EE010D1DD26FF0F4E62BDFCEFDF4FBC7B7 -:107A2000D7B573F99374007D4AFC25E541E23586AC -:107A30004F8E77294F921E11B9CF03FCC2ED23EE72 -:107A400057158A739195CEC011BB0FFD161E7F2D61 -:107A500014E72365FC75BEA04B912DF81ACEB357E1 -:107A6000FCF532FD83EA65AF8EC0DF0FABCA3E4A3C -:107A70004F29B7E0BF5AE4FB6D41F703C25F3C21D9 -:107A8000F444F5B87692CBEA0F1A489EDDD3B95E7E -:107A900073BF63D5C78CDD27E6BB86BE9B9ADC5ED1 -:107AA0008EFBC7537FA618E8D7F705E7223C2F8641 -:107AB0007EDE8683DE79885FF13B52F25CCD1F85E6 -:107AC000DE39BD4D15BFABD9A05FCCFEBE547F2CB7 -:107AD000FA8642F79A08DFF0F4F6D2491FA27FBA7D -:107AE0002D857EE7E4D3EDDFFEC187E9F83B22D7A1 -:107AF000FAD14E485F1124FEE9CE70F937F178ECE7 -:107B0000748C5735B51FF4E2399C4F9EBE6A0CEA5F -:107B1000ED2483CBFDA9E7D5658897FF0324F17B8E -:107B20003E008000000000001F8B080000000000E5 -:107B3000000BD57D097854D5D9F0B973670B9949F5 -:107B400066924C36B24C02045412262161916D9219 -:107B50001016599CB014906D640901421220ED87F3 -:107B6000D57E190CA5C823355A1770EB049762B55A -:107B70003568B441830E0808553F47848A15EC8860 -:107B80001441423245DBE25F5AFFF3BEE79CCCDC96 -:107B90003B1350BFDAE7FFC3E3733CF7DC7B96F798 -:107BA000BCFBFB9E3377FEEAF9B1A38A0959ED9538 -:107BB000120D8490CE5DBFFC577A1221D54FD65955 -:107BC000245A6F7AF6757DC04488C6DBC29EEF8A60 -:107BD000B7C07BE79FB8772C194CDB5B9BB0FDF3FC -:107BE000275AB0BEFF57CFBFF67FE87B35AE3807C8 -:107BF000BCF7F98BFBF4F0BCC6AD75B6D292B80FEA -:107C0000E8679B69E9794626C9844C21ECEFC1DD20 -:107C1000FBF4F67C5A6FA5A3D2EFC95CBD77400E8A -:107C2000FDAE75B776A909DEF0125242C7FDD5E266 -:107C3000916EA8B7DB08490B3DDFA2271E63022D1A -:107C4000FB101243CB0BA5268F144FD75566DA02D3 -:107C5000E585DFC4CCF5D2EF6AF5813C2BCC6730EB -:107C600071423DD5A2C1EF6B5AD7EA6A4DF83DF695 -:107C7000F3071D2150E6130F393B88AE9F9027BFB5 -:107C80001E0AE3FD96101BBE3722A68890390B3ED4 -:107C900091603EB183EB75AB719ECFB276BAEAF0DC -:107CA000F6610D743C3AEED7F0372E5416594C3825 -:107CB0003E05087E97DE56996187F527191CB07E30 -:107CC000B1BEF46A7793993EBFA9C1ED90ED84BC33 -:107CD00072EEE884BEB4FEAB41D250195E97A5C5E2 -:107CE0002EDA7FADC784E3ACD950463EA5F31D0F15 -:107CF000BB48BF4FB690A41BE97A2AB424C9042517 -:107D000021C77445D0FF53D86E371027A178607F04 -:107D10007DCE531BE9270FEADC6925D0CF16BFDEE5 -:107D20000EE5936CFEF47B8BA908FBB3DC08DF1B2C -:107D3000C93AF8AE7BE3D4A4AD12F6EBD72584E6BE -:107D40004D48306B763EEBAF18E034C93317DE2771 -:107D5000763DAEEF737805F7D153B0301FCA6D6C26 -:107D6000BE1AE2067C49D6D312E1EACEA9A478B3C2 -:107D7000C452BAD052122A93FBB076355C5B78FBC2 -:107D800027162796645722212323DF13A580FFFEA1 -:107D9000395DFA001DF7FE573F41BCAD05BC85F1CA -:107DA000DD67F4B00E81B7CBE013BA0F0FEEF90424 -:107DB000F17659BB84F0A96D2FD52FA5E58546270F -:107DC000F9544BEB1CFF1E94025580D79E3D319613 -:107DD000A7289CBA047E367F7256A6CF73DBD3ECFD -:107DE000123CDFC3F0F4A046E301381DDC79434BBD -:107DF00093143ECF8D081FA99A209DD4D613AF812E -:107E0000B6973ED6707432ADAFA9260E039D57AD1E -:107E10000A8F721E3FBD19F0C55A438A63ECB0CE7B -:107E20008F27F4A5FDD7D69012A0D3F4F1CE3D5004 -:107E300027ED121900F56AD73218FFA6A4950E99FE -:107E4000F66F1DEF6A83F16E4A1AE390697F0F6641 -:107E5000B66E36D2764F05B13C0570D0359769695C -:107E6000FDC10ABB854292C2EDC954682783F48ED6 -:107E7000A7008FDDCB6AA0BFDAD4F90EC09308FA51 -:107E8000DFB37110CCB7D6DEC71143DF9FD22E21EE -:107E90005E118F89C0FC6B297CA13EC53BCA0BF3E8 -:107EA000B9C8E127E0D8A5F32F82F975BD64201E7B -:107EB000DA3E653CC357EBF856E41F6FEE997858ED -:107EC0002A08E1A5F965830FEA095A8BE400BE444C -:107ED000661A603E4BF97C9A7564B18B7E679DC4CF -:107EE000FAE977B784FCE259A0271B941A5EEA39B5 -:107EF0009E37B3D2E22970517CB8C8F71FD184F6FF -:107F0000BB9AE3CB9A653EA4A79AE7587F490667D8 -:107F1000E1FA30FC4D2A2748C7BB62C8E24AFA7C26 -:107F20009795956A7C7D8FD375CEE3EB70DF97D202 -:107F30007D877D4DBF9B3E07B851BC00B8D17D44C5 -:107F40003CB8296905EEDBD2BBA55B701F3DC308B9 -:107F5000D46D896C9DEAFE8FF3F5ED8A71154BB4F3 -:107F6000BFA0CDECD829C17C9C9A18A8175A1D3BFC -:107F7000097CEF7A12C6B3A5C4389AC2F81521AEAF -:107F8000620D1DE75CB299EDB7F75DED8C7CA04703 -:107F90003BB6DB64E223C87F48AE2B3FF45D453F30 -:107FA000D65F05EF6F6AB3A780E43278205C383C77 -:107FB000BC1BFBCC0DE7A71F717878AF2373816FD3 -:107FC0001CD4139311FAB7D071687FC93B473DB1F8 -:107FD00015E7D784EB3A60B1605991E82AAEA7FD66 -:107FE000D9FAB91A002E629D6A782CE1F0D83F6761 -:107FF00051A106F07896C9017477FFABD212C46B19 -:108000008F911225E03DA34342F703E882B8B5B84B -:108010001FB5F52E6F74BCAF443AAB4D8A71C4489E -:1080200088F74E947F1E9397E13D937FB19398BC60 -:10803000023E59991FC90F049F01F906F82CE8A2C6 -:10804000766C200FF6F79BF2952E1DA3F32E0A07F0 -:10805000A0234137E65718BD6CDD682F85F6AD9437 -:10806000EEC3F7FB90DE83F47B28B78F03FA8579A4 -:10807000BACC21FEDED7E28AB752F8D56A7C9BB52E -:1080800039217E5CFBCA5D79EE28F827F8B151CB27 -:10809000F89CD11BEB65FDB2F18C14DCE6222C3D83 -:1080A000208F623730F8A8FBC9B50AF96AB49CA1E1 -:1080B000727C3ADDA4F87E844CD2B873613E6B8C3E -:1080C0008143746749D686A01EE6910CB20BE8671F -:1080D00067AC17F856723271BF10A5DF242BE3038B -:1080E000625F9A13181D25C7B1F7C75A995E516888 -:1080F00065783991BF2FE62FF0DFAE717F42E4DE65 -:10810000E598F88ECE0BDBC57CE8F75B0893BF38AB -:10811000DFE43BF3766E0DDB8F101D5D5704FBD45F -:10812000EF6E9F768929348E90A7EAFD87F903FDCB -:10813000C07A2A07F7FE5EF33E468F6A7C9CCEF536 -:10814000299395B0F774BEBF225DAD35939D30BFC6 -:10815000EDC49948E755F7DA40460FCE601EF4FFAC -:108160006682FB19D88FE1E3399ED3E733E8F3D574 -:108170005AE231D03D59BD4BE70D1819CD7C4DFF6A -:108180001B97C0FAEF361B3D32C5F30F13DC0BAD66 -:10819000B4EE29230E1FC8A51F53FE01F4477C250A -:1081A000C05FEA48200EE05C2BFBF308DDFF2BB13B -:1081B000EE25F0FE698D3F0B9E1312407C3D191396 -:1081C0005740687F6D7A5FE67FC1BC8FC86427ED3A -:1081D000E712714E81755CF26B123C741DA7DADFF9 -:1081E000FFCDABF4AB85AF5E5C783B40696BECA236 -:1081F0004768B9C0A8316A8786E071D21C9DBFFE6E -:1082000098E385AD89E95DC18D062FC047FDDEE4A9 -:1082100004F65EDDE574E2490C7FCEF8689D36A871 -:108220000715B2EE7216F1D0714F6948756B143DA7 -:10823000F39495F1AF368AFAD1DA4F733CDBA5237C -:1082400079DB613E2D940F02FCB476E417D5BFC8EC -:10825000716CA5D5B6DCE021D023820F48C8FF4F52 -:10826000EA18DFA17FB38CC342F213D413D00FAB53 -:108270002D1E9F86F28DEA06B34F2EC0E7DAD1B0ED -:10828000771E8B16F8E0122E1797D6BFF995144774 -:10829000DBB5C4389A7EF79969591C8885AA1FAE48 -:1082A0004F06E53B654133D22768B4A08F4BCEA97A -:1082B000F2D7B157D3E7B4A8B723BED0FD9D96E05F -:1082C000F2C27E2F8867F05EB03ED6EB09E37FB343 -:1082D00038BDAAF16C17E0289DEFC712932BEA7105 -:1082E0005E4C289B0AFDFEC3EC7A16F077C1FA8B30 -:1082F0000A7ED625059E7E04F071ADD9F114EB36C9 -:10830000CB15462F87C5B89735B87FDD85FEBC0DE8 -:108310003980F7C1AC0F289C5777182C1E3BB4EB63 -:1083200015FB7FBA9132BEBC30F974AEFF04620215 -:10833000F83B36033E2CDD124B3C8342EB00851BA1 -:10834000F0BBF632C17E9674BC7902F879AD368006 -:10835000F8B3C468C2FDA9BDACC579902DBACE8072 -:10836000F89ECADFC438E721589FE767A3AD676F5F -:10837000A00F53E8735CBFFB6D78FE506C1C71322C -:108380007AF10EA4F3BF64B4C7275078D5E9297EEB -:108390000CC16E5CC630FD8A649895FBDF71E42BDE -:1083A00098CF32A35B0FF27EF9DC7A3DD0E582787C -:1083B0005F896570F8BE8F96BFBEE19BEFFB6ECE06 -:1083C000874EE9295D44A1C3D39C2E26034ED2F2E9 -:1083D000543AA39F5359A4FA0528AFA725FDEE549C -:1083E0002EAF17B1BABA1F7D02A39F53054C5E7919 -:1083F000D631F9A17EEF32DFEF6909CE20C04D3CC6 -:108400001F93C09EBF98E0FC02F089F2C3BF737C4B -:10841000F559697F0B5E3720BE924DC13CD8C79E8F -:1084200075E5F1F926479F57DF04B63EDAEFBF60E6 -:108430003CFA9E13F5F6D762BC608790A9943F037F -:108440003F5E9749801FD371F50936ECD767C5F7B2 -:108450000CB80EB285F2698AB7DD2576DC97ADA53A -:10846000143F814FEC3558804F087C127814813FBF -:108470009C8F09397C33C86119E570624209CA6171 -:108480003DD039ED51CFF4C1FEB8DF8867F237DF58 -:10849000EFBD46B68F94DE3313703C5F7E38BD0966 -:1084A000380B3E79AA8F122F9EE27C70007FAF07B7 -:1084B000CE09ECBDA47E4CEE09FBA084EFFB335645 -:1084C0006529E4D8F0494ABDE4198E6FCF58E3C45A -:1084D000BE1402BC85FC8BD8EF47D97ED3F786C18A -:1084E0007A1618828B12A9FCFA01D58BF445F8DDB7 -:1084F0006EF82EC24F319EC9DDBA7566027A81339D -:10850000C1C2E05F1CCC82FEC8A020F2A12584F28B -:108510001BE9DAFB073E81344A23D3E298DC9164FD -:108520003A20D0CC206287FE28BCA784C35B3DDE06 -:108530004968A27AE0EC04497B16F6A89014C27E42 -:108540002D7AEF0BF342DAE5458BD1A3A172E487D4 -:108550001AF73CE8A7F3B623A8F79FD4FBF29A4D8D -:1085600051DAF5BEC71F9242ED8B9F913D7ACA67E3 -:10857000DAFC9D0FCCA178B9C42F3B60C82577FCED -:10858000F59DE1A04FFB750EB06BA93E71B796CE7D -:10859000FBA486ED27A957FA051A38BD50BD4A4BF2 -:1085A0008685F893D00B5612DF00D01F9612A71EB7 -:1085B000CAD36B574C25145ECB4D0DC8B7CEAF9BBD -:1085C0008CFA7215F160FBD22DBAD3E1F26479B363 -:1085D000B2BE62BBB2BED2ABAC5FF811C3B748BC8F -:1085E000677A98AD3CBA7EF118A7B70BFAE8EDDBD5 -:1085F00038DE96FF6CEA4348FF7E1D31503C69D857 -:108600005B9A42A2BC2FCABACBB9C41B268742FAD6 -:10861000471EF10E85FEAEA03F10FA013BB721C602 -:108620009902F6C885B2E8F37880CFA3EE729F5E18 -:10863000FA8DC37E2FE45E7D9D75978DF85EE4F71D -:1086400026EC97EA5951BFFFAD805342F4F65FF72D -:10865000CC2F15E562E83BBB4AFFCA40B95A77D92F -:10866000A290D3A1F6242657B99F80EEAB07F562FE -:10867000AEF7518168391B1BE263BA3E6C3E826ED5 -:108680003E9588310DFD6AF7723BC25100FAF1A7A1 -:10869000A07F01DD4EB4BF16A0535D7AFBC83C6DD0 -:1086A0006E88AED4EBA1F8F879204C2FD89F604E9D -:1086B000C2711DC401E30A7A58745B45BC9BEEDBB2 -:1086C0009FEE284F710F0EC73B0F8E5FAB177A9F3F -:1086D0004921C7894ACE2F6D3F827ADD32A32B0F05 -:1086E00098D39FF7DE867452455CC9401FDD7B0737 -:1086F00066B9FF17F25DCC67A6E7561DD3E3295094 -:1087000029DDCEE0F399D9C1F44A8DD1A9C3719C7A -:10871000C46E4946539DCD9732592DAD8FE9993F8F -:10872000381D0919CDE72FC1F714BE63784996B8F3 -:108730005361DE0618978E1743BCA950368D74D846 -:10874000A11C27B9B46C1E5EDCE709A43E03DED78A -:108750001803325B279D41327CDF032FAC9B797D70 -:10876000D3AC4B8B96C3739319F98F9ECF434EA412 -:108770007C7310F22523ACDB60F29D87759979E953 -:1087800029637ABA2797389AE86B7D482B81714D17 -:10879000A68B1E58AC855824A8C7582EF9C05EB9C0 -:1087A0006831793443909F1A12819F4A6F57C1BE36 -:1087B00050FECDFC57BDB56B7D682709FE98C0E71C -:1087C000D7C4F9631A61704822AE7D4E8AD7F799F3 -:1087D000ABA6923810E36E1C7F47DCA4C3305F0069 -:1087E0003CCAF949DAD3E172C6E6D22AF85FCA5C1C -:1087F000653DCDADAC1BC9490BE8A392CF95FA7589 -:1088000022DA7F83C09FA3E3FC66561F362F813F89 -:1088100079899CBF733DC4C5FD01B5097A827EC4C8 -:1088200064A3910C41BD242F91F9073EA63B4DED69 -:10883000C620F2F3C271CE010F50386F7E4F76DC46 -:1088400049F769B3D9BE510BFADE3C89E9F7DA562C -:108850001FF8875A16591D5BA13DC679CF3FA1FD70 -:108860003D9980BE55077EF94478D1520ADFB56440 -:1088700059F0BDA4F220FA53837711D4A722F0F463 -:108880000A9D3F85F713880CB49F6596D5CFD1F725 -:10889000D35CB10E29ACFD4968A7F394385EC0F3F0 -:1088A00071C3C0FE657FFD3A0AFD4EF06F386594D6 -:1088B00087751D856F98E83CFAB90B1D80B6FD3BA6 -:1088C00078FC25C9E065F1074AB5741EB38D6C1EAE -:1088D000751DA53797D0F6FEFEA104E210B187ED15 -:1088E000F36BA04943ED6EF8AE2C16FD5EC7B8FFE2 -:1088F00089707E305C456FA342F88FED85A24ED51E -:1089000006E730E6D6C07A12A30307117F8C3E6FCC -:1089100024A13FF8BE3CD41FF2A3F1A1E610BDD1C3 -:10892000A515191D4D35F4BD839513110FEBC0EE40 -:10893000A2FB315CEBDB07F43D8A9785BC244B9AA4 -:10894000119E5B37FAF6EB72C0D5E292A13ECC7273 -:108950005713F43746F2619935F7DE2640AB7DA018 -:108960009C217EB92B801E3757100BE85F4D231CCE -:108970000E0B6D9A3397F96767CF357AC1DF3F5B8E -:108980004B585C4CEBCEF901A5AB1F2C607E61A867 -:108990002F08F3BB8838C8316AC7EC8EA20FEC4BA6 -:1089A00064724A7C5FB749AF8837ED4D3461FB1381 -:1089B00089133C89A8A7B97380FE3627727D6C1095 -:1089C00019047C258CEEB722DD97BED51B5F50B60F -:1089D00073BE30DBF90B1DEAF19C3F083EEC023A16 -:1089E000A4DFF925A70EE0F7611983FFD1D295C85E -:1089F0001FE610373EA708A27385FB9B2685E94337 -:108A0000749CD92EA57E3467AEB22EF0558C3BCF28 -:108A1000AD6C9F21F4DB494AFD76C17F5DB1A21C9C -:108A20004C797ACDD7D9185F413F411DDD27165FBC -:108A3000D1B278CB26BD17F4A4BAF6B5076D40477E -:108A400077104E47BBA56518FFD92D2D0FD323FAFC -:108A5000D67825E0FB03E99AFCB8AF418C2B1DD3F7 -:108A600079F741BCE5D84ABA623ACF37F42C6E792F -:108A7000208678C06F2DF0D33C83F95D291A63FC02 -:108A800024C312EB007CDAA229423FED9638B323CF -:108A9000DC2FBA7523C5BB30FFACDDC0428CC77A72 -:108AA000B17F8F24323BE74189F9C93DF38C68EFF0 -:108AB000D9FAB91471099B4C4E80BFD19368473CD9 -:108AC0007A90FB4320AE3794965E89E9333DDFCB45 -:108AD0006413FA2755FCC796E8C0B8802D3E1FFDE9 -:108AE000FB733B0A9F447E638A710C9042FDCF75F5 -:108AF000B7689783FFA0A345BBCC14C2BB93025FAA -:108B000063492CE06B8FBFEF0503FAFB7EA871056C -:108B1000002F6BF4BE02A2C4E7C0D5E4D80A8E2FA2 -:108B2000BA32D7BCE5743EDDEFE899FFEB0E82F474 -:108B3000FAE21E2BFA2BB53308CA934DA504F1A116 -:108B4000BB4542FDED336B35DA019BA46694135DA2 -:108B5000091370FF56990EA05D5BFDA8EE74B8DE98 -:108B6000B5EA49657D35F1A35D5DF35C043E23FF05 -:108B700012FCB1B64DF91DE9AFE48F859CEF17B932 -:108B80001C332B60EA731DFD985D4D7C06BA8E92F6 -:108B9000B7F5DC4FBC80C94DF2B404FA56B7F99C66 -:108BA000CCE89CF1E312DE9F5A0E95707D6A2CE5AD -:108BB0005B607F0AFD88BE8FF5039A0E3955139AC4 -:108BC0005731FF4EE865826F8B7D291D41C8088AA9 -:108BD000F7B9497C5F73492EEC2BED1FE901504238 -:108BE0009F80FD7BC06E1BC5C7A3FBEE0139EBD197 -:108BF00018BD80479BA57AE4D346C2F9B5E446BECA -:108C0000FC3B8F4706B88E24F533A7D2F7461BFDF1 -:108C1000B1000F8A0F7949B6109E34115FD66E49A4 -:108C2000812FD8DE697D2B2ABE08F9E2FB90E91777 -:108C300053E88AA19F0A08F8D0F280C4ECC289A642 -:108C4000FBB5F0FD5B9AC9880F9388570BF3ABB067 -:108C500028F77962AAB23ED91E8107328CEBE4F084 -:108C60009C3248D9EE147C8D28F95A0EB982FB4CFF -:108C7000EE3AF443F00BC46E208340EFA01A22D2E8 -:108C80009B9A1F4C4AEA355E3229294ABCA49BFBB9 -:108C90007F6F2481AAE7A4487CE93AB8414E0DC30E -:108CA0002B81C7AFF0FC0AE9751E972D66FEC090B8 -:108CB0009C67F8328CD76E047CA3EFAF1478924D8A -:108CC000B2014FC6B4C7F8640AD742DECF8D8037F1 -:108CD000452179EED398ECFA5CC00FC716598ED4B3 -:108CE000DB9313EC882743354EC49312E24884FD8E -:108CF00019616C6DD2C2FCF70CEFEB3629F0620DF6 -:108D0000E28544F102E92A422E2ADB557823F6EF68 -:108D100030D79727124F7F188FB2B103A02FFB7265 -:108D200018DE541027E2C99BB99379DCDAADC57E11 -:108D300088521E961B9578A0C62B3AA2267C5C35DD -:108D40009EF58637D98037421E265E1B6FEE49326C -:108D500029F4EA30BCB927A9A477BC51E38BE027FA -:108D6000BB632CE5A097D6554BC88787BED3BF09F8 -:108D7000EA03D7E460FECB6EAB03F5D6BA7AD65ED3 -:108D8000EC77CA901FD3AF81B7E7B8CAA15EB781AD -:108D9000C5294A8EB1FC99FE77B0F6C23BEBDF30B5 -:108DA000837CF7B0EF5F39BF598EA3EDDECDFCFBBE -:108DB000D2E672A8D76D61DF7F067126BABFC34EB7 -:108DC000789BE0F97577E73898F9C9F4D9711C4FA9 -:108DD000774B2FBC81DF35B3EF561C32F621A80745 -:108DE00033BD752C5FE7B847D93A933EBD69929D74 -:108DF000E2EFF2A007F5A6B39A9A61C86F7AB13391 -:108E00004BA5E60C2829DE209F711A295EE7B238AF -:108E1000E44E3AC45B49CC9F21E277904F109E3FCD -:108E2000F0561293F7E2BDE404C2E2CD0F9BD11FCE -:108E30002CE28BBE87880474066BE4F23F6ABC7137 -:108E400062BF7A8C334ECC1671C68076091DB7F09E -:108E5000EB2F2644F3A71C4D627AEA399E1F219E10 -:108E6000577B73348017BB0149D20148F5BF07BD5A -:108E700009FDAF4C6878C808D857560F24D56CDD6B -:108E8000428DF4159A7AAD07844C16B5BF68D7D3D6 -:108E9000FDC4171F1739FF895AE203F944B46CFE69 -:108EA000554D540E4A21BE345BB09DD103904E67A0 -:108EB000F17DBA28F8CD503214F8CD6CBE6F3F303A -:108EC000D6EB98BC6CD6A9E8FF2F48FF3B7AD59B20 -:108ED00095ED2AFE50CDC7ADE2FAF24A1244BDE04C -:108EE000ACE4C5F2DC0EA62FAF361D43BDA2FB617C -:108EF000A627D69000EA1D6AFFE1EA5DCAFA9A56F3 -:108F000065BDAE5D59EFCEF7E038DD3BD60C03FF13 -:108F10005DF5F677D02F5C2DF88457C927A882C459 -:108F2000F8C443D7A3DF4663A47CA218C0D507F3D7 -:108F30004D86126722F00310B25FD3FA5DF0491A32 -:108F4000AD6B5C093694339312CF88F1658CE7BE24 -:108F5000E3B487F6A5C72E54F18942E18FE99F80DB -:108F6000FE2AC1370AB95E4226A9EDC6FB91FE86EC -:108F7000F25ABE8DFB53B8DD23F40CFA3DEA197E9C -:108F80008DC9ABD184EB155EA4C72223951348424B -:108F90000E23B3579A896A7F0B6D57B79B94EDAA3E -:108FA000FD1776CB30BEFFF388BB2FECC72CE23A1F -:108FB00008F2E1E887D50A7BE9C33F4E10FE14B4FE -:108FC0009BBEBDBDE4FB4EF652CFBEC750FD919691 -:108FD000E533260F7800E2E36D3198F75927B17D2C -:108FE0004E9E772C2BDC7F78B491D8B46174DF343B -:108FF000D96084F860938ED91333A69C1AB6248C5A -:109000006F3C6F2C9D0DF0DA2CF97FF411D81747C7 -:10901000648279351D36DCF74BCDF439C5B74B8FFB -:10902000DEE0F0D0C717742CDEF899545F05A95024 -:10903000621E551B7E1FA3A5726C85EC7D2D00F171 -:1090400055C9FB720D6D3BAE772F85FE576B7C7A51 -:10905000E6B7F3639C54F4DFBB1FD2837C4CBF9F05 -:10906000C9C5A0D4C7C1FCB89EBCF078D39264E651 -:109070006FFA30C15507E308B927E20927D74E8CAC -:1090800007D1F02571C6439C53D242CC2E723CC806 -:109090002BD814E6573E19133D2E70878DF1579843 -:1090A0003EF0F734ABF32736E0B7DCFE3BC7E35DB9 -:1090B000E7E258FC6B8B8DC9810EFEDDE3BC3CC73B -:1090C000E363E7129476A378CFCBBF3BD368346ECB -:1090D0000ADB4FFB43867A2FE653F1FC9106C2EC84 -:1090E000A43DD696AD61F1D0676DA51D000F5B3F25 -:1090F000A73E0DE0B787C961884743DC78A4C5FD6A -:1091000020B4D7DA8913E2AEC41ED0CF84F823D8B6 -:109110009DA83F307CE98E61A598D7B3B6CA0E589A -:109120006FF7DA00EE674FBD92F1C7676D2E1CB77F -:109130007BB668E7F56D01BEFFCC7F20FCD9BDC5CD -:10914000C3D4F12F2A38989E1DC3F8983AEEBD502B -:10915000F0311EF75EC0F9D0C20EE61F5F64249B9B -:10916000FBD2F6C51D29CC5E8CF3E429E2DE9ED845 -:109170006F95EF20F0B33BD3DF13AF7D382C5EBB90 -:1091800086C7FBD688F5B529D777C4D66BBCF688D9 -:109190002D4ABC569D17F032C8F7FE2178AEB3B009 -:1091A000F557C835E57AE013CB08E691AF3BB2B48A -:1091B000C948EBEBEE02CF1FFC317D750D87576F71 -:1091C000F3B3B934C4AEF013F721F630BB38CD9DFC -:1091D000A0A8A3061C9687D9B73A5DF17D667DAE3F -:1091E000E2FDEC0DD72BDA733C458A7ABF2D372A86 -:1091F000DE1FD05CA6A80FDC7E93E2FD42D22F1EBC -:10920000E3B18765F09590EBBC3314ED37ECBA45CC -:10921000F1FD67A4FEC1D1F4BDB618260788C7E9E1 -:109220001F3C2C94779CDFBA44F17D93D43ACC4711 -:10923000DF5FE667FEF621EDAB14FD5D889BC0ECB9 -:10924000081E7FACA7FF181FB7CBA80FB54BE46172 -:1092500029321E59DD71EFE6BE2452AFA07F28E708 -:109260005751390F7A945ACF30279B93101FD24908 -:10927000FAD7617415C20313EA61971E95D19F5600 -:1092800048063E341AE1A3235E7BE47E5D22CCCF08 -:1092900073E939B303FC652B8E2C45FC33A42AF10A -:1092A00020C6AEC483D8414A3C303B94FB1E3F42AB -:1092B000B9EF6A385B9D4A3C107014704E9CA4C490 -:1092C0000B01DF11F41FC0B788040F619EB5577200 -:1092D000F84894786F7B0BAEE35A7ADB70153C87C5 -:1092E0001E703699104E2CEF4AE84906EE9F56FB49 -:1092F000CD85FE313199EB3DBC1FE1E7DE2C795085 -:10930000CFE989678DF065F97240DFA927CC5FE26C -:109310009A926C8BEA57C3E7BDF9D5041C853EB31E -:109320001AF4193ACE72E246BE7486EB332B4CF730 -:10933000635CF0C21F197CAB8917F9F5B78D978371 -:109340009E48C2FC8D6A384A1D92CF0C74C0F976D3 -:109350003AE9107CDB8D791314ED8CC314F105A56B -:109360001E4A9C52387F127AA9184FC053F02D31F3 -:109370009E81D4CBA940072A3E4606A9F554A5DF15 -:1093800043F84970B0B038C6F09EF804B313437E7A -:109390002FE6E790B3739A08E8DF16E1D7F0CF879E -:1093A000E7C2AFA1B6EFAF15179DE991028FE44474 -:1093B000C643457C952EF3D38FE8C7A3257B268C27 -:1093C00037E3958136A289E697739C7895F6236BEF -:1093D0008289E1FE32E1BF7E530AE0BC7F409C3FC0 -:1093E0002561FA422D699D303F07FC9F546EC541AF -:1093F000C9FC3EA45DAD97B278A286AE04F07B3581 -:10940000098B17E684DAB12E47D6459ECBB5E4FB2F -:109410000D2916EEEF60F93984F33761BFF5662F39 -:109420008978FE413D85495128AFE5E5646E6716B0 -:109430009002E89FD2D52BC9689F533A94C2E9AEF7 -:10944000270F06DB23E84EB57E11CF97CDC5E87711 -:10945000591ABEDE6F000FA147FC8BAE0DF6E7FE7A -:10946000643BD6D7F439F907273417FB15F98C7507 -:109470007A963F4C5A95FAF3C7C91AAE4F38E56F42 -:1094800002A7DEF781E785F17DF8A6FA90C80B13F5 -:10949000F03B23F86008DEE7147CACC76EEB81F785 -:1094A000B9687C4EC0E36289FF69D827D97C2C1942 -:1094B000E0FC0FB3EB22BC9F79227056D284E655B4 -:1094C0002177623EE8A57619EDA4DA312C4FA87613 -:1094D0000F06CD49578701E382D5ED6FA07ED6D91F -:1094E000481969FFDEE1D4B35E15BC7BB357C47A7B -:1094F00074294A7C13F922749D312951F3017AE0D1 -:10950000A06CE77010794A15F2E0F840985D728817 -:10951000EF7B8CD6159F42C72F7E3F230EE0532151 -:10952000771C4A07383448785E699C8178C0DF9F91 -:10953000C6CFAD8D08D43B2C141EA919263C7F3410 -:10954000F087B20BE299A71AD627C0F9AACF1BE978 -:10955000D0D4EE1828695C886FE4858F7F5C0C712D -:10956000B60598A7BCD0C0E2FF393F8AF5F5A37CC9 -:10957000E2753D3102BDE972EBF17C46D02AA3BD14 -:10958000912493F1805F02CE49B16C1DE279E963C9 -:109590004F4A90CF249E8F6B0A0E5D07F94CB0EFB7 -:1095A00025A1758E2B0F0EAD3785E02CF204893680 -:1095B0009835238C3E8E7078D4DAF49B411E761950 -:1095C000B91DC8ED4162D1221F69E0F1F69303A8ED -:1095D000458AFDF8CC9097551BE38C1F0EFE2EC8D4 -:1095E00027A0C5971667BC15D76F47BDB981EB5744 -:1095F0005D3CCFBB6172590AD853BDE53F4D4D610B -:109600007A7E0D8F838BE7355A1FE62DD540DE71AC -:1096100058DED3B7CD3B16F9E6BDC2C1AA255A0A1A -:10962000875A89B8AEF6DEABFF92A3DABBEB5334B0 -:1096300057CD835B952229F2DC6A21CF8D3E6AD813 -:10964000539A42A2F4D7236F2EDFA8C8271379D2EA -:10965000B597C7623E59F9CF3AF19C20F46337853C -:10966000F2DC7A83F3916406E75AC80F1B1AFE9C5A -:10967000E151A8FF24DC875F0300C1DFD12EA35F87 -:10968000F6D7873593764699EF76BEFEEB6D5AA4F2 -:109690008F1B7CC4D912657CF19E38470270AECC1A -:1096A0008F9C5F5B596011CC1FF257A38DB795E378 -:1096B0008B98775B42A08AE3399EE3E8A95B94FB31 -:1096C000F80CDFC7B69B0259781E6972F47C7AB138 -:1096D000DFC3B4F512C02360761F44BD730EAD0C1A -:1096E0008173003E0DCBA36274D6DBBE87E0AD5123 -:1096F000E41546C25B8FFB2CFA1376C9F9ED32C62E -:10970000FDCF1FE574499C2689D2D7AD5C6E9D279D -:109710002C7E70BE59427B64899B900D94BFDCFA0D -:10972000E46A8CDF543D357433882B787E07E5235B -:10973000B7A6123296964B3629E3B7CBEE8E88D772 -:109740009070F948D54FB4AFABEE577E574DEEFE53 -:109750000BE83FD52AFD6620F777ED4DE1F6C230E4 -:10976000320CF8FBBAA7BED043EA6E6FF8FE39A5FB -:10977000EBFE5AE083162CDF4D711E003EFF718A0E -:10978000FB4DE0DBDDEF31385CAAB9C4F8FEA3493C -:10979000286F0CC09CE9FF1AE6B338ECCF28BB80D9 -:1097A000F89BC1C0F41BA1D7C9F27A398EB68FFCE1 -:1097B000734302EC5FD2B3132781DE6F7B36D60989 -:1097C000F0DA5AEA2C043FC0D64A13E633180D2CBF -:1097D000FEEBFDF5C8FD100EE8DF7A6F19D8A196F3 -:1097E0008E7D3EF0936CD1FC05CFA16C19CBF2DDE0 -:1097F000C438751D95BB613E59B398DCD89AE32CEB -:10980000B484F54BB89E56CB61D6BD77E03D70FE73 -:10981000FD91C3A826D3F5E5A23FEE7AC2F653E444 -:1098200055C1D8E1FA6827953F909C27EAD7B74AF7 -:109830003E1D5DCF9AB6DD18C7A8B9D3973C1FE48B -:10984000CC335A8C0389F925BD9E5606F11E215F43 -:10985000E64B1694FF42DF9E47C41F8B17CDE57879 -:10986000308FEBD9F363197C971047167C778B9177 -:10987000C4819F7A7E796B09CA9FD53A2BE835223D -:10988000EED1BB3E10DD5F54FBB4999DA795827964 -:10989000D0C9E7D4FE20CC6F14F57C52522AE3AF36 -:1098A000B5795CEFEB4F9C1067AB7D6D600BF805F5 -:1098B0000C7D583C96F21DE38822D47B8D60CFACA2 -:1098C0007C35C6C7FCD65E7E6ED6590879217533C5 -:1098D000328A303FE104E51F66388F18C8423AA546 -:1098E0007C45A2B22D7FBB65AA16CE0DA653BD8ABC -:1098F000D6E7A7664DD5527CAFCD0D546968BD69DA -:10990000FB7056BF3E7016EADBB697B17A51A04A9B -:10991000A6F55DDB5DEC7B30F02862BDB47DCE54F6 -:109920000FE813562EAF1D013C475CFBCA404DB8F3 -:10993000BFB22595F1A5CFB9DFF5F31CB27806C00B -:109940007B5000CFA989F77E9A2AF45C96E72BD644 -:1099500029BE23A9D1FB1F9DCAFCC42BF9F9DF71D5 -:10996000B1644B0C8B5779E228FC0F740CC4785B04 -:109970004E6A028717EDA738D48F80A3E84F8CBBBF -:109980000AE42AF05B1DF39B8AF6C9A98C3FD271C9 -:1099900036E1388319FC6B676414C2BED1FDD2F284 -:1099A000FDD232FBB385CD8FF66B2D40FE3E14FC0D -:1099B000DE07AED0F77342F356E3C70F387EAC6CC8 -:1099C0006271C6A0B51FE2D1B858A6EF9162E53A20 -:1099D0007671F8B5A45A997DD5B31F29128ED3C4D8 -:1099E000E19841E19EFFEDD75DFD3DAD3B6CBF9C35 -:1099F000709EFF40FB753BC3D723F2B6453F9F6F78 -:109A0000547D3782E54FD526F4C3EF7E16438CF89C -:109A10009CECECF92EA780E999A07F8AFB1D886752 -:109A20002C3A0B6A38D7E8B9AFA195E711F677B2AF -:109A3000F3CA33A616F3F559F8FA2CC6B07B1A7A96 -:109A4000E8F158306B9639127F7BE0DED3DFE022FD -:109A5000DE9F82AEA3F507F4D1DB7E3CCCF1E3DFE1 -:109A6000B61F629E2A78F6C059353F014FA067FCA9 -:109A70006EB0121FC53CB7A58ABC61155DE77CC7F7 -:109A8000F14AD9776B6EE3F9C076253EAF69CBD149 -:109A9000401C5D7C37097CEDB690DF6D6F2AB7DF27 -:109AA0003248462F7970FB52A3FBEBF0B9DA7EEB1C -:109AB000B6B2FC67B5FFA0DBE6F0C3B93ECF457692 -:109AC0009E7D944ADF8038CC0BA6D0772179A2AC5A -:109AD000C7A531F845FA838278FEB6D850F6A2DDE4 -:109AE00041C847DBD7207F2E8E2F5B9F43EB81ED54 -:109AF00075ACDEB7EC8B1CCABF4F6FAF67F51BCAE6 -:109B0000BEC8857AEA5A561FE77C51C608C2DAA950 -:109B1000E3D342FAC3A7A976A67F946B08E09141EC -:109B20005EEB003929E0D95B596CD0D447D34F3B69 -:109B30007BE899C5294670F93C42D8E701ADC23EA1 -:109B4000EF8E63E793BB419ED2F5FE3DD5FD975462 -:109B5000D053623B17E5D0AEEE8CFD580FFA90E47F -:109B6000A4FA06F83BEC16B200F2EA3AB7BA403F64 -:109B700022AB1C462DC293FB9FE8DABEA6FDBCFAC1 -:109B8000DA33B7F765C3B8601E2339FDD7BDF6D504 -:109B9000DF204E5AF7B9C901EEBD911D3BD6837E39 -:109BA00035B2E3ADAF98BC65E735C4BC47821F91C1 -:109BB0003E1FD16EC0F98FECB86E39BC3FEAFD8E06 -:109BC0007E801F634EFA9A801D74EFFD5D5FC5397C -:109BD0000DF299F45DCE69F4C0E3CF54798A4778E9 -:109BE00024A6D9001E57305FAACB76747300F534D3 -:109BF000E57918AA97639CF512E9E380788138F734 -:109C0000ADF65B9EA8A4EBA3CFC704E90CC2F4E5B4 -:109C10007197A97D1FA6679712ABA25E6E4C53BCCD -:109C20005F61C951B44F4CBD4ED13ED95EA8A84F1B -:109C3000193452F1FE3447A9A27EF388C98AF72B62 -:109C40009D958A7AA1AF55F1FED0C3EDCAF6637631 -:109C5000DC87A1275DE5A0C73BFCEE262887773689 -:109C600097C7DB4984BFB638E06D82E7A3AED497CF -:109C7000F84894732CABDCE8E78F38C752CACEC3E0 -:109C80007769D8390EE19FBD12EB9E9486FE590A82 -:109C9000760AECB1C66022EC57C5E26D983775299B -:109CA00048D09FD5A60FFC7C14C8F98532EABD6D5B -:109CB0003CDFA66D6EBE177C7A27A4C0CB10AFF731 -:109CC0002C64E704C6500D17D70DB14D09F6C9AD88 -:109CD00058772959A9DAA7B58A7A85E536C5FB13DD -:109CE00053372ADA27DBEF52EDD3BD8AFA34C70E99 -:109CF000D53EB5A8F6E91945FB9833812620A37116 -:109D00009D1ED94CE77FE389E672D89751273D0B1A -:109D1000815E8A7DEE2660872507EADF80D247EDE7 -:109D200029F053ED6F4CC5F240A31DFD4C871A0777 -:109D30006179B8D181CF7FDF3802CBB71B9D58FE48 -:109D40004FE3242CFD8D2E2C5B1B5BF1FD171ADBE2 -:109D5000B1A410CC04799194D8730F4326D8F35D45 -:109D60009A402D4452FF3B6D1FF2C5AE3E812EA896 -:109D7000DFE9791DF9E24A30A628BDB54049F7F37D -:109D800067E94E299D96DBD2D873919FD0AA7116B0 -:109D9000827E7D5FDA91BBB59954AFDDE84AB55854 -:109DA00059DD48EBB8D998A775E46EE768427E03A1 -:109DB0002203832647A642BD3B86B56F4B3B82FA02 -:109DC000B58823CF0AC591EF03BA57C7917F73CEE9 -:109DD0006E067FCAD12B03CDB0AEA3DC7FE4248511 -:109DE000BA5B6959AA2DD4815C3CA1D2234459A7FE -:109DF000297D04FA6DD53866637EF04D3A02F9E8A4 -:109E00003324668FF6E881E94C1E754F33A0BD738D -:109E10004CE35C8E794F52F07180D78B3B3E44F817 -:109E2000759B83590087DD3B4EB0BA2DF8B8E40826 -:109E3000ABEBD83A7FBDE383A91E53D4753E9F1682 -:109E4000255EDE96C6CFC7FA9C99207F45FD58A5B2 -:109E5000730DC88963A5CE01309FA32E03D28FC78F -:109E600065F642DE25D13A4B6687F9550AD275B8B8 -:109E70008E597A4667E41639EAB9F3A9E94CCFC29C -:109E80007D037B6E5E2CEAE1C734D1CF8D2FE3F0EA -:109E9000B9D027BA7F65793A93836533CDD85F7798 -:109EA000430CC671BB5D03510FEAAEA750A2F4D1BB -:109EB0007DAEFEE24BD86E10212E8C57CEE77CEAA9 -:109EC000371DEBFF7A9CBEFF7143AC0379B8E57A8E -:109ED000944FB7F09717261A516F593823B30CE4F3 -:109EE000D27C1EF75A64D62663F84B6BD5C39542D5 -:109EF000CB4C859B41FC572555EAADB45E9DB176B0 -:109F00003394ABFADFAB87A39A3583776F06F5718D -:109F10000D25AD12B49702EF34D2792DDE20DB99F6 -:109F2000FD24CE1FAEFE567916020F8FF17C190A62 -:109F30005FB40BABD225855D52C5E1F5651AD7DB61 -:109F4000F249FED7CA78CE65C093CE85EFE4F5E23C -:109F50007757B673BDED0F7A36AEFADE0A31EE0AE8 -:109F6000BEEFC7F4C429811E778B19F1A360EE17E9 -:109F70007796D0F517745834188F177CDCCFEE0F16 -:109F80002B39E3463E37BC33F0F4718278DE0E7431 -:109F9000722D3935D3B311E5C3C82FA9FC01BE78A2 -:109FA000C5FDF1716C4D8A7A2ED3D758CDF9633D3A -:109FB000F2B5038D1BB07EA8D183E5E1C62D9C3F91 -:109FC0003663FBDB8DDB397FF472FEB80B9F773491 -:109FD000CEC5F2B5463796FF30BB32D3812E8C6E9C -:109FE000CCD33CB8C3406488377418104F29053C63 -:109FF000FE4812E4C1182C70FE4E9D0FA3E6B73D3B -:10A00000FBDF16712FC675304E4FFE0BE867D9BDCA -:10A01000E3CF516237033F294DCF9C06FCE3A8DD17 -:10A020006E06BDB5EC615AA7DF1E75DACD3A5A2F20 -:10A030004FCF6275B7DD6CA0F5F10FF3BAC76E8E26 -:10A04000A1F58AF46CF6BD9760B0FAA6F4FED38051 -:10A05000CF9612E900D043B931673CA4CE56584A96 -:10A060000F001D4C4CBD753CD0C19E343BBBEFC2B4 -:10A07000BEF100D4A70C6AD1C2911BA7A970137CB2 -:10A08000579654A985EFC667ACDD04DF4DE87FAF76 -:10A0900036FCBB4983776F82FA54478B16F4C13D77 -:10A0A000692C0E2AFA1175D12EF8ABC8D71AD2E155 -:10A0B000423E5ED0EE423E2EE05236ABF2A7E0A723 -:10A0C000AB6B972C12CC6396D41384879CB8DA2B95 -:10A0D000945A289F9D973EC4BC917E5707F51BB1AB -:10A0E000BE6D6374BEBB283D8A7CF980D329C84D00 -:10A0F000C88BFE40CFEEF5780DD687FEC35BCDB79B -:10A10000627F6E33C8D703694C4E1EE6E5655EFE7E -:10A110009397751A6735C8CFBA741E4F8CA4EBF5A8 -:10A12000E98C6E55E7057A69E774FDC3741E5FE636 -:10A13000F727AC21EC5CD1B5F2B65686DB6F3990CF -:10A140009FD37A08F246D579103570DEA85F643E59 -:10A1500030E58B2CFFB15D9947DA637FF4617C0FAA -:10A160008E3182D1F1F3DED77DDF35D67D5FB475D8 -:10A17000AF242CCF59BD0EE2B6216D89BCE7C8F5DE -:10A1800004A2AF27621DFC9E3E55BE35D58376C224 -:10A190007C2A169B09F86FC2F9C4F1ABF00935DFD0 -:10A1A000F977F1B3ABF09BDFC13CD5FC469C7B5605 -:10A1B00097429F83F352907707F7BE809F7E63B2EA -:10A1C0007B3FD0477759F06F1AB0CF92028867690A -:10A1D00056F741E85FD2B3F8BBC8673DA7F1FC165C -:10A1E000F4A2F7D25722DFE902E140E9F108AD839A -:10A1F000DE33D2E27A0BFA238318FEF496A7799421 -:10A20000CBC5C89228F215BB5BBECA423FD635F01B -:10A21000BD373854C8A303702EE0D2885854793A19 -:10A2200025E2938A20EF3A19F588CE4CBD16CA7FF5 -:10A23000B79DD8999987FDABEDC5CEB4114636EEE2 -:10A24000844950B6EBDDDB6F053B69A401EDA477D3 -:10A25000799EDFF4D35792405E4D977DC90552A495 -:10A260009DD979644199BD20D2DEA4EB1B0FEBBBD5 -:10A2700096DDE932FA13008C6AFBB366C3DF08E4AB -:10A28000478FDA7085C0FD65D7B647890C6CA2E8A8 -:10A2900084E30D284BCE38311D67D8B9FA37A01C9E -:10A2A000F92533CFAF955774E3E5D637D831F1C1EF -:10A2B000CA7B1746BCC5EC555E46DCEBB6CAA3CCE0 -:10A2C000572BF595601E851C8883F2A21440BF971A -:10A2D000AC61F731887B18A81D9BD3D706762FCBAE -:10A2E0009B1A07F9467472153FFE70D1ED48F7319D -:10A2F000A8FFF4D8B12F69304FA04DEB8C1F037627 -:10A30000EC86018E8DB4FE27BFED8157695967F940 -:10A310001B09BFEFAD66C32545BD7363E8BE20C80A -:10A3200087AEF9978C72A786902DB05F3564BF7E9B -:10A330005D981C24AD7FE981FB10CAE72A017028D3 -:10A34000078DD39DF4BB4A6E6F107217AB733B8BB6 -:10A3500078CE4DC3BA8DBFEF59C0DA3345FBC2E9A1 -:10A360004E3A4EE500D1DFDE69584F1375DEDF75DA -:10A37000A2FE007B3F477CFF12ABE78BF1DF67E378 -:10A3800099D9FB373D72DB74E00382BFBBFA2AEF39 -:10A39000F9A1FC7E565FDB55F34A94ED5C1E887B89 -:10A3A0007D2A7E3C39F61DA0E7560973E06AEED09F -:10A3B000A17FFB42426B41F839659187E22A373B26 -:10A3C00041DF5BF3F2C09D32CFCB017DE37E9E8FF8 -:10A3D0005F219B301E71E96EC6E77BD3D7AA36BCDE -:10A3E000A2D8CF88767EEF3206EAE87817B7A56064 -:10A3F0009E3BE9EFC778F8BABE92B8BF11CFB98AD1 -:10A40000BCAFA47EC409F669D2EF62D8BD9667FCE2 -:10A41000C87FAB7EC7FCBD6B76BC81726E896C4712 -:10A420003C7E27C7BD01E0D36566F717566D780DF2 -:10A43000E9B5299BEB0996E0E070787AFA72B91CCD -:10A4400082FFA6BE255785BFB2FD7B86BFDACF2C23 -:10A45000CE49AFFA96F9695D66160775F07D3AAD9B -:10A46000B10FE3F07A1CD67371B93FCF2A43F2B033 -:10A470003F99E51DBD5D0276D0A57A33DE77B460E5 -:10A48000FDA982F0F329A254EBFF9D4047B610BC12 -:10A490009E8BC4EFD66BE077EB7F12BF53B401BD48 -:10A4A00003E2A627D8FD63C3FCA7F5E1F92EFEBEA3 -:10A4B0004CEEC6B7B338913A6FCBDFD7CCF4241E3D -:10A4C0008F5933E3EDD1108F11F4302E96B4827F83 -:10A4D0009DE2B583E3B503F05AE06F282E43BF8BAE -:10A4E000425F21FC25388E80D3079170FDE81A78F1 -:10A4F000FBD17F126FDBA8FE8B71CC9762D07FA25D -:10A5000086F3BF385C05BCE333AE0EE7F88CEF078B -:10A51000CEF11976A5FF81C3BB37F9A4DE1F31EF59 -:10A5200028745AF25DE8F4E7999C4F6903982FAAC2 -:10A53000DEF7E48C887D4FCFB8FABE2BDBBFE77D1A -:10A5400057C34D5DD6F0F8A6FAF9888C5EF9DDBFE9 -:10A55000058EFFBFF9CF17D6EF53B42FDE7044D16D -:10A560007EABE73D457D74C05F0E682EFCE163CF96 -:10A570000551BFFCAE7EF5DEFCE9D35F5CA18178BE -:10A58000DB083FF3E7FF35D3BD2D83C2F95D8DB7FF -:10A59000C94CE13AFC642BBBBFAB3A0FF387D6F34F -:10A5A000397E31FAEF1FDF4EF1E60B62407FA76F75 -:10A5B000DF755A7B7E241E945ED61067581E5AA9FA -:10A5C000D1AA75A2BF8638A3E1CD7D1C6F30FF876D -:10A5D000D2FB5C23D125513A9F3B57C27CA7B9845B -:10A5E000E545D3D2E7A6EDD3B5C407F724579AB40F -:10A5F0003E03C6F994E79A0DFC1E659294A838DFD5 -:10A600002C3B65CC4B9B3D82C5076F31B5E2B9D27F -:10A610007987EFBC783B6D279B3C252CEF5A9C43F8 -:10A62000FBA3E6DBC4FDEECB6074DE2DF138B2A4F3 -:10A63000C37BB222E44106F38F4E9737CA90EF12E4 -:10A640007C8FA0DE2DE88EAEEFB0A1889DB380DFB9 -:10A65000B1A8243ADF403CF77C6F39BC5F73CC8EE5 -:10A6600070A91BB1B100F6B16EBCF489A12064D70A -:10A67000D46DF812FBA9909F6B82F72F9D60AEF00E -:10A68000E19DD44EB187FB2B038B802EAF65FF88F5 -:10A69000799F6CF4213E7DDC7818CB77C7BE5502DC -:10A6A0007A46A0D11FD52FF95DFD03C22F20FC04EF -:10A6B000820F88FBF93A32385F304A7DF15E352DE2 -:10A6C0002B05BFDC1FC95F0F655C5D5F51B67FCF97 -:10A6D000FCF59BE2794D2A938B6AFC56E3B5C06783 -:10A6E000B8FF1B7EBFE016AAEF815C9D4F3CF93599 -:10A6F00094CFCE5DD1AC1B257D77BC5E653A93458A -:10A70000A29C37F9F6FCDC8EEB97CB65B40F447E48 -:10A7100082D887AF3222F4F87F5E432EFEF33F29C2 -:10A720001723E5DA9945DF4DAE11853E909A1981E0 -:10A73000AF199957C75765FBF7BCEEB073308B6400 -:10A740004DE8DC07E40F831ED7ED65E71AAB739A7B -:10A75000F1DE79322218077AE3CABD32E221D13A1A -:10A76000B56961F74E7512DF1F001F578C5E81E7D8 -:10A77000E122EE8B32B5E1F938F5BD51225FB89692 -:10A78000F7A3BE3FAA96E709D7AAF2764A33797EA5 -:10A7900070112962F9154ABD545D763512855FB294 -:10A7A000EB4A23FA01263FF6D2CF3DA343FB707359 -:10A7B0006604BECECCBC3ABE2ADBFFC3F82A9B9F00 -:10A7C000C47351DF165F0D766735CC5BF0E1059001 -:10A7D000C345C75DF0AAC10BBF0F20EEC9EE96D8E6 -:10A7E000BD34DD9F10F41B5DEB9EE591C7DC78AEB8 -:10A7F00073F8DB4E99E511B07C03A1A708BD655441 -:10A80000675066F7E1F3F3503C2FE89BF22F87DFA8 -:10A81000827A8EF0BFFDBBFCD642CEED35DA919E3A -:10A82000857FB038E0423DAE4BE72B817BED3D7B31 -:10A8300062A2EA013B323557BDCFF51F66F70E80A5 -:10A84000FB4CCEDFC5BDAE1532BBF7F9925F46FFBC -:10A850005DC34FDEFFED23F66BDBF575964B51EDD7 -:10A860002251D669D87989A2723BE6ED81BD04FEFA -:10A870003BE1CF53BF7F30BBEC59985F853C1AEF6B -:10A88000D9BCB49DCDA7B77DA9DB10C4F17B6DE722 -:10A89000E3D7ED2DB184DF8BD199D9639F59CE1ABF -:10A8A00043FBFA4DF77F4C70AE42BFF97FDD6E98E7 -:10A8B0002E53D591CAC77CC9CBF453C2F4D405C476 -:10A8C0008FE52212C4D24D583EFD12E2C0721971BA -:10A8D000613927DB1DC8C4FC966032E643BEFC8F9D -:10A8E000C1803717C78E6A86DCB9EF4B4FEB2EB4A9 -:10A8F000E3F8DD2FFD230BF25AAE794F7E9CF38BEC -:10A90000CC28F1E4FF2995317E428AD721BFAFE4FC -:10A91000B72590F12C2E767F720EE24388FFA5B406 -:10A9200008FE07F1D6FC4F342C3F64A584F7BAB675 -:10A930000734485AF9CB73BC704F4F7B1B6BCF5F0A -:10A9400063F54AB49E3F3286B5AFB57AE1DCC342C7 -:10A9500012407A5C0CA71E643807C3F89BB8079DA9 -:10A960006AECB9A0672DEF30B2FC7D12E80F7CBC19 -:10A97000A017FBE6E62CA6EF0FC9657C7B4899D2B1 -:10A980000F61E3ED0DD965F559B4FC719633398B40 -:10A990002E7548827FEB2F8AD12F8FBFCBF2D9C87B -:10A9A000DB307E28BE7B24BBAC2FBCFFBCC4F2CD09 -:10A9B0003D7BF9EF17906072F8BDA273B2CB73A024 -:10A9C000BF415984DF531F1DAEF0FB75AE28F69CC6 -:10A9D000C8671C023615FAC3D9FD54CF4BAC3E32C2 -:10A9E0002BF9E64D26F4E17B40AF7D24DB5D84F35B -:10A9F000D7136282F93F66F0EE44FDB33E0BFC9143 -:10AA00002B1E3768402FF8908A553857F251A31102 -:10AA1000CB53D4CE85F24FD4CE85F2136AE742F9F8 -:10AA200029B573A15C7ED9419186906359CE29598D -:10AA3000B650BC4D3DDFF1598CAFF68CBF578FE35C -:10AA40003764BB11BE3DFBBD8778211EF2BC359833 -:10AA50009E70157CEB9DCF30B888F89FBAFD463EBE -:10AA60008F82362DCAF182F6405C55D87BF3B2D87E -:10AA7000EFA9E5BF7406CF8976597AE0EB94E892A6 -:10AA8000A76B587D5ED660846F43B6B31ED64DE982 -:10AA90007B219405EDEFDF07E77968FF9847D02D1C -:10AAA000051F443D5FB50E351CC4BA9EB7FAB7C248 -:10AAB000F7CFBF940B2BA1FC8630BA013C92A2AD1C -:10AAC0007723CEF76643B018CEA9DCFCB51C356FF2 -:10AAD000B821BB14E16C12F826E0C4F7EBBBD275C9 -:10AAE0004F3C9BE32911F76C00EFB4831CBA1207AB -:10AAF0007A5D258FD7B7B7F57F17D6E7392C930145 -:10AB000076C45F05DD3DC1F74794F97BF52ED8A7E4 -:10AB1000E7F79EED0FF7B0D27DE90FF7B2FE226B9B -:10AB200000B68BEFF2477EF5F02F92F07DFCDDD082 -:10AB300079A4A502F249E61BF71D84252DB47C52A9 -:10AB400001F9248B53A54350DE6ACF990079242262 -:10AB5000DF7DE9A0D243404A531D95A88F9502732B -:10AB6000099307E5C6587E29B4903F898AFAC4D470 -:10AB7000BE8AF727DBFB29DAA70CBA41D12EC69D86 -:10AB8000EA18AA786F48423017EC2FBA0E760FF603 -:10AB90005332E6DDE5BF74ECA61B687DFAD3B3F152 -:10ABA000DEBFE779FBF417CAF1F708BB293CF5547F -:10ABB000913A37E2AE077F019DA9F4FB9ABD4F1C85 -:10ABC00072DAAFA2DF5F43AF17FC757587B104F887 -:10ABD000EB37D5F3D5FBE2CB52EAFDBDE14B0F3DA0 -:10ABE0004876862FFCDE2D35BE107227C73F564EA5 -:10ABF0003FCACE817D5B3EF667E06361E7307B4A0A -:10AC000095BF6D88DEF1EE7AF0BFBF23133C57C7C6 -:10AC1000CFE755C1FFCB213C27CB5A7E0AF74AD15B -:10AC2000E71ED03FE11CA893F67F398BEB4D35FB37 -:10AC30007E9A561C6A270D9F28DE2777489B15F5BC -:10AC40004D39CAFADDA59BC3BFEF8D1F566DBF55A9 -:10AC5000EFC6F39B52D4DF7F15F3A9D81F83F97990 -:10AC6000D320EF843EAA2D7E4F0BF1D569BDC84F8E -:10AC7000C177E6C9A43E5ABB9CCDFA9DBA3F06F304 -:10AC800059BE6DBF1F525862BEE0EF98FCFC30DE2B -:10AC9000AF0DDFF7B86C89DF7B70EF4FFE0671CF29 -:10ACA0003D04F3372F5A19DF2F68FB4CA301F9D766 -:10ACB00087E14B8125A00179D25D1DEB81FCFCBAB7 -:10ACC0009566CCEB1C921BFC83B190A2FA2FEFB9D6 -:10ACD000C748F7ED8F7098314C9E76838D43EBD942 -:10ACE000D9F720BF9FB23FC6A7F90EEBC9A63A1409 -:10ACF000EA1B658CBE1701DE70B902BEF3BA9F92E3 -:10AD00001E3903FC00D60FF5D9BFBCEFDDFB41FFB8 -:10AD10003EC2E81B32E5D476FBFC30BB9D3CCAE862 -:10AD2000D248FF813EB7EA40B31EECB96BD3772B14 -:10AD3000E6CD7C53BA1E99CD7FB7A3773A3E3A85CC -:10AD4000EE4BDD1E76CFC4A58E0178AEB537F95D2A -:10AD5000B75D83F427EA5D1DF224C057F539710110 -:10AD60004F62C953DCE7B46ECCDF67809C5CB75799 -:10AD7000CB923D7A1B678B86D8C3C679FE354335A7 -:10AD8000FB5D4B36FF6E219FF7FE35A174302B37EC -:10AD9000469173542EEB92402E57B2DF5D38BE378A -:10ADA000A50CE07F5C223E3B9EBB6279C63359779F -:10ADB000F0DC84F788A40ED286DF7728ECC8D97B34 -:10ADC000670F003DF20F6D4B8E3B813D64F7C3F181 -:10ADD000E6100FEABDC7ADAE4CF0374CE7F1FEE32D -:10ADE000D66027F0E3E363622588DFD3FE3791B0B6 -:10ADF0007BFB8EEB5C99EC3E0891577CFD77BABFEC -:10AE0000AD42BEA3740AC4AB17100BD89137CB4C1C -:10AE1000AF25AF33BA14FCAE4EF227C03CE764CF87 -:10AE2000F8EF6C3AEF940D3F47BBB2076E5AFEBB8A -:10AE30004FDF50AFEDB15F7749EC9E1207D3F76B50 -:10AE4000475F78600E9C73A376B644E7B3A47D1F7A -:10AE5000DEC7A3B6AB7BEC9BFFA57F34D23E726D01 -:10AE600087F509BFB7DA4EEAD1CB857EF714CB73ED -:10AE70007F63CC435DAB69BDE1A95884E3F9C70D9D -:10AE80001EE0DFE7771AD0DE399F103CB91EEA2FAB -:10AE9000E43B3C385A1E9EEF12F8BD4263FF00E4CB -:10AEA0000EF9BD0EEFDDF8EC3103FECEC7CA27AEBA -:10AEB000DB09F6D36799F6679F03FFDEB336BC0F55 -:10AEC00080A4B2EFA7717A04FAB2D3FD907F6546F1 -:10AED000BD61E58B69C8BFC4FE9D7B2C06CFC19FB9 -:10AEE0003F3C331EFC609D9ADDEC7729659307F8A3 -:10AEF000F0EA9D31A8F711BDFB15587FF9AFA6CD3B -:10AF0000190AE3BF6F23B09EEE8E17D1FF18DADF68 -:10AF1000E872FD52473FC6077AE42CCB9B5D1CBA12 -:10AF2000AFD907FDAF21E23E4496375B244BEC7767 -:10AF30002AB7453F07FE5E36B3D76A84BF2491180F -:10AF400053810EDD84DDFFB86D20DEB77B3E3B41D3 -:10AF5000D0313FEF28F0ED64EDABE82F31B07CBD90 -:10AF60005EEEB73C95CDCE055719BF54F84D6A3704 -:10AF70005C56D607B3DF6D2E6AB20F5D4BCBF51C66 -:10AF8000CE9A5457209B7EBFAAF5DE97DF46B83C89 -:10AF9000FAA33FC2B8874DE8A7216F33F8A9ED9710 -:10AFA0002A6390C71D5A147AEFD91D1F60FEC8D9B5 -:10AFB000976EC0DF2B5B22FBCFC23D595D66FFC79A -:10AFC000B7D3F285C347715FD4F38D88C34B8CAF81 -:10AFD000D4C03A8642FE8AEB6FD948B78CDE4F6FF9 -:10AFE000CD47F8093F6DF7F9E8F69598A7E85FCCEB -:10AFF0004FF42FDED3DA997EFF7F0189AF015A002B -:10B00000800000001F8B080000000000000BAD58FE -:10B01000096C14E7157EFFCCEEEC18AFD7EB031FDD -:10B02000F1C1EC1A8C898D3DF8AAB1A12C36A60489 -:10B03000A17639225CCA3169C25188E3950D154A5F -:10B040009118675B2E11C555AB88B469BBA1224529 -:10B050002D515C07901B61BA0435E0364D17052968 -:10B0600034B5E8D46DA8D5D8D8A569232424F7BD74 -:10B070007F66588F316D137557F6F3FB8FF7BFF767 -:10B08000BDEBFF3D26252A332B007E56A400D401BC -:10B090004CD26719C0982F5199E1A5713F1F1FCB62 -:10B0A000441ED701E800B301DAE8CF6AA432B8B38E -:10B0B000B391B631350A7C5C874C4EE31ACE3F9D86 -:10B0C000F726B86A683184E51C80C7C1FA6467B99D -:10B0D000A01E6003FD8D473FDEF09BBBCC07B0098F -:10B0E0007ADD50027043E8DE278900A3BDDF716B73 -:10B0F0005E5AB4C27FAB0C80E91F0893E5493DA7B7 -:10B10000530017D03AFA4C8A497DF566288BA09CEB -:10B1100031BF5717AA00E629CC754BC6E92228A2F1 -:10B120007538AFC66B91F679D428EAB34F082F5023 -:10B13000D0EEA7A5782588C97DFB048D8F8FB277C7 -:10B140007640908E8B5786D300C6332460E94867DB -:10B15000AB8910E2A1FF13D4532867DC0D6D7D7815 -:10B160006E6D8B10E9E376B8860DD44F00C6F5AB53 -:10B170002DC771C475298DCB96DE011CAF72AE4F01 -:10B18000DAE3E42F2902B7AF364B88F4563C88C780 -:10B19000269A477DA310170957FC6C9011F7260BD0 -:10B1A00077809008E897672CFE19D91B172B516FF1 -:10B1B0009FAC8B684FD305F40BF24DAEF825A22C53 -:10B1C00004B01FFD0BFDEED1FB7A100E79E52E9237 -:10B1D000D368B997A1ACCDB8EE108B009D2B430F6F -:10B1E000A7C75882EBF17998E034047E1751849F09 -:10B1F000D31510E6742544385D053D9CAE865E4E41 -:10B20000D740825378341E85009D74C07F2B15C9AA -:10B21000633B8549A4B51B21D2EB7D108703164EF5 -:10B220000FC74167148F9F168795A0E57179D3F1F9 -:10B23000282CE3F13D1D0F0FC523FA2D056279443B -:10B24000978221125D46818B729683E222BE05426F -:10B250009C6FFD1F71683034975631031E2D33C724 -:10B26000C5B72C3C66118675493FF52B661DB0FDB0 -:10B2700005A86778E1837EB4C76B539BFFA1608903 -:10B280008829ABC2AEC5C8D734779520FFF3D8461E -:10B29000936F6A7E2388FC1BCA97C3AE7C8AEBE659 -:10B2A0001AB70AD0CD36855720AFA5F82AA18A0A49 -:10B2B00047A940F1B3D76FE2AF75EF53FD98475AF6 -:10B2C000915725FB640F6286F889252234202D5E74 -:10B2D000157FCB8DEB5648DAF7291FDBE5B84F41D8 -:10B2E000DCF776B7E602DA7B5832D77B709F5C9D3D -:10B2F000B40BC7F514E4FBFACABB58F0E1E7A3DCD2 -:10B30000D32457EB9EA703E9718EA9A6279B73DB75 -:10B31000B04E8C26DC704C499E7332577B4D413CBD -:10B32000412E05F27B816CCA19ED2B2F27BFF42B20 -:10B33000661D85EC400DE136911BEEA7F5E36966CD -:10B340007CF5530CCE7E383594D0796586F1F10FBB -:10B350005101DC3FA8681768BE23F55E29D5A5DB3F -:10B360008BDE3B64049271CAF0FCCD687734043103 -:10B3700089D79125FE5B5847017D3089FE1CDF8E01 -:10B38000721087DAB01675E3F0E7364FD463912276 -:10B39000B957B85CC9285E84FBBEBBFEA664C6591B -:10B3A000A11967561D1AB838F88D02930DC394BCC5 -:10B3B000EAB878F75F7F40FC3AEE78555A9ECCA702 -:10B3C00097BAC0478BBC8EBA61E75963BF272EFA84 -:10B3D000885FB09DD62D7D6FA884EC5A366444D327 -:10B3E00048CEC0FB05A61E565F087DC23E4B5F6877 -:10B3F00015A93803749E13631EC4AB93452EA71181 -:10B40000FF1A5375D4FFAF32C6473AAD0F79F3D167 -:10B41000AE5D965DED83A70EA521DDF5F2936BA0E1 -:10B4200092D2C1CDEBB7825FCAFF3DA7DDC97ACE0C -:10B430007FA323D0CE0EB03F7189E2A0BDD7B9AEB5 -:10B44000038EFF9DEA4EC7D43A8F7A7DA2A465731E -:10B450007F59FD0AA885A0BC9DD65EB2C34B7A0F6A -:10B4600048310F43FA832ED54FBC953F70E3391E08 -:10B4700097F67A78398BFBDECEA7AF1D41DDB3920C -:10B480007855BDEA0911EE55AFE686C8BE2A09B661 -:10B490008539DE311EC755181B0CE3E9F58C89A0F0 -:10B4A00080E7BC3E50A6620585370F86E0CF7393D8 -:10B4B000FA755AF9D42A9E6991300EEE3C057E4CFD -:10B4C00049E81CFC715446BEF328D00AB843BF506B -:10B4D000CE9D112146721A076BF2C8DF67ADFCF4EE -:10B4E000E409A04CC1294599054A5992B7F1F5588C -:10B4F000FE492DCB74CCA7A98F38F6A737049DFB46 -:10B50000F550A2A29EEAB1B93F23F4A863FD61DF22 -:10B51000CAAB14974B133BD6102E59ABAA1DF3F5AB -:10B5200020F3FB435DA1578DE17EF8D8ECE70DF8E1 -:10B53000E5FD002222D9D764007C0FFDD138EA72E4 -:10B54000F83DC5C078C47529D7A7F81D7F3C8A93FC -:10B550006F08601C50221542E1D43848E2ECBD8FE0 -:10B56000238F83415C4438A74931BC723C80533DF2 -:10B57000CC4DA7F9BAAB22C438EE5D6A1CC7678709 -:10B580009D78E7B639F1CED79CF816EC72E25B14E1 -:10B5900071E23B67BF13CF80EEC4AFE448A363FD05 -:10B5A000BC9E66073FFFC46AC7FA05B1750EBEFCB4 -:10B5B000F426C7FA85BD5F75CC57F5EF76CCDB7105 -:10B5C00035DDEF8BE29D8E75D3FD5E73F559875C9B -:10B5D000DBCF3A7EFF9F7EDE37CDCFDDA81BD5AB1C -:10B5E000777D23C7290DBF986AD6A5567149224495 -:10B5F000FE5EE256C9A7BF53B25AD228DFAD3E1451 -:10B60000B6FA101C3864F2569CA809F532D5D1EA76 -:10B610001BE1161FF2B546E43295E3FA919E96744B -:10B62000858789E2C73861162E5F6A60E072E40B95 -:10B63000F23949DCD6EBDD623A2E6EBA178BF27224 -:10B64000494185E7ADB3E6598359D7D78652C0350E -:10B65000058FA5D63850D346794BCC29586FBD07F6 -:10B66000F05E0E12DDCB0539160DCC749F544F8859 -:10B67000FC9EA4F17BD315A6B9896E9013C5D4BFE7 -:10B680007E92A3FD2880F5EAB6A02AFC9EC58C28F0 -:10B6900019354E8651D3D1AF87435EBABFE3DF8FF2 -:10B6A00060DD7DEE5A58AFE0EAFB0DD45FB3F439AC -:10B6B00013D04E0710FF61E63F54837BDF6DFCA87B -:10B6C00098FA8F474424B00E66F9423FA579FDF001 -:10B6D000920C5EA773D13EACA386A0F0FB83FE2C38 -:10B6E000E3EF818F48D8E229797AC4CDFB0E58EF79 -:10B6F000A32D165EF6FB68B375FE308AD885757A81 -:10B700004BFF158ECB9EBC517065F178E3F7A427F3 -:10B710000BBDD5C7C8A6508DBA6E218DDBEFA50233 -:10B72000F1D3F4C556B122DD98E1BE68D33D79234B -:10B73000FC3D777FFF19B38F3C5CBECEE33669B723 -:10B74000297FF8682AEF2FC3478B9A8926E5DFE621 -:10B75000F2B744AE39E264DBFEDF3BE2EF09FD4FB6 -:10B760008E79237BC25D80F61BE7F3577E05F11BC4 -:10B770003BE7A9A77723FAED8FE4175BBEF1FCFC4A -:10B780001574DE7FB7F36F1CDFA1830970CD4DDA2E -:10B7900079F3E00DCE1B070D4EA7DB69BF336D2A91 -:10B7A000BD05652EF4CF049BA59E0C3C78CECEA0A3 -:10B7B000F93E1B5A9ED34C7D76A8487299B4D4E4C6 -:10B7C000F31B64935FB98AE8B8DB7B84DE99430C92 -:10B7D000420CE361330BFFF009B4BB3B47BB477638 -:10B7E00076EC9EA874613E7454195B19FA333F439A -:10B7F0009BA47186D7BBFC4CAE6729DD3B4604BDDC -:10B8000092612D587CB2702DDDD34766E9B7A9133C -:10B810002F0AE6ADA57BFA8864E6C7F293C25A1DEB -:10B82000ED58ECD7528228E74326C6793CFF82C503 -:10B830004EF17833A475693C9FDAE8DD45EF5D7A17 -:10B840006F8CA798D41F64DCBE0CA2B393B49C6A1F -:10B85000258E2FB768AB78BC94D1FDE08407281FF4 -:10B86000F09C9040E70C7862A790CF41DDE99EF212 -:10B870002BC9BCCF57FFD213A7BAB143FE98FB69BF -:10B880006E30C0E5649760E5C27DD92F786251D2F1 -:10B89000CF4814AF45FD7ADC787FA1F7F4759CC7DB -:10B8A000BC1B7B7EFEC96353FC313768BE87E02931 -:10B8B00000733EF7159A6F1F1CBE4975E4B701ADC2 -:10B8C0008CEC1F16947AAA23EDBE4B12D59FC6A00E -:10B8D000C2F7A1BEDC7EAC07DF641C67D9FF178C02 -:10B8E000D76D586CD2E9FD26682AED6F970D89E473 -:10B8F0006144F0FBDFC3EC1FDB9E78B102E9ED345D -:10B90000B598CEB1CF453D1A498E6DB7AD4752CEF1 -:10B910007F8EEB1DF284237F6FBD74B894F264C8F0 -:10B920006DDEEF10678DECA816D9B675C87FC1C261 -:10B93000C55EBFD5F2A790177E2C887477E4DBE74D -:10B94000DF5192F3E3ACE7EB1F90DF06BDBCDE4DA9 -:10B950003FDFDE3FDDDEF68B831C17B4772BD93952 -:10B96000C5DE8D748E6DEFD8C0FB2F56289FDDCEBF -:10B97000F1A2844472C75FB95BACE0FEF60B576E70 -:10B98000501CB55BEF7D38EB7CC77B66E17B317388 -:10B990004A5DA75A37874FB3A9F7288FBDBFD0E5B7 -:10B9A000DC8F176601CF3B6BBD23FA297F67786F69 -:10B9B0009E4D08BC659ECDC37B1AF503ECBF54FFBA -:10B9C000EDFEBBF79AC0E3726F00F83CE94579C021 -:10B9D0008CB7793FB0FF9F1065D8E7301E3A25ED50 -:10B9E00020C509685DBC3F8873BC2AC573DFAF57AB -:10B9F0005BEF26B3DFD459FDA58EE490FE15E9BCBC -:10BA0000EFD45AE7D6CB789F0952E9D6ADFF9B58C1 -:10BA1000FF5F38FA367F6FFD1B3AD0569240140014 -:10BA200000000000000000001F8B08000000000064 -:10BA3000000BFB51CFC0F0038AEFCA3330C42B3167 -:10BA400030742B33307C03E20E79841CADB02A07AE -:10BA500065FA5F303230BC02E23740FC8E9174FDF3 -:10BA60006AC208F6525E06067520BF02482B0A30ED -:10BA700030B001D91A40BC0BC8BF05C4CF80D84133 -:10BA80008881819D8F81C110888580581328EF0996 -:10BA9000A43FF161375F4B18BFFD8F0550F9A282BB -:10BAA000A8FC3FFCF8F5B709E2971717223D4CDEDA -:10BAB000AB911F1FC6EAB44F33D4C4371950F91FD6 -:10BAC00065181898E51818DCE421FC6B48F2114061 -:10BAD000B14F3210F66D3160DC01D55D66C06EEE9F -:10BAE0001DA0FC13A07C0AD41C0004EB50106803BA -:10BAF00000000000000000001F8B08000000000094 -:10BB0000000BE57D09785445B670DDBEF7F696DE8C -:10BB10004216C2163A2C0A08D86C21084A67C3A0FC -:10BB2000019A454407B5598410C822E27C3CC77984 -:10BB3000345B061DE64D147518079C06C380F35050 -:10BB400003460D1A980682A3CF2DB8208E336F9A24 -:10BB50007D3190002EAD83E3AB73AA2A7D6FA79B46 -:10BB6000E08CFFFBE7FBFF2016756B3F75B63AE7ED -:10BB70005445359808194BC877F043D32512212432 -:10BB80002D9AD29FBF7F974EC82433FD974C48A172 -:10BB90006C23643821136D2468A275268EA11F536F -:10BBA0000979B7460ACAD086D60B6413524AD8CF51 -:10BBB0002485D44BD7137231E7C5AA216E4224AF36 -:10BBC000972C1D4A53B78BCC8474CCDEAF2507214C -:10BBD000CE1C0321FD589BEFE8DF64AF15FB12F983 -:10BBE00094A24EBA7C9AAFABAE7EE719BD74E55D08 -:10BBF000FC0374E5DD4A86EAF23D2A6FD0D5EFB941 -:10BC0000344F97CF0ADCA2ABDF7BCD145DBE6FF55E -:10BC10009DBAFAD7AE9FAD2BEF1F2CD5955FB76DB0 -:10BC2000B12E3FA8F6415DFDEBEB57E8CA87841EB5 -:10BC3000D1950F7BE3315D7E44D353BAFA230F6F66 -:10BC4000D6958F0AFF5E573EFAF44E5DFEC6D65774 -:10BC500075F5C746F6E9F2B9E42D5DFD7CF307BA48 -:10BC60007CA1EB535DFD9B338EE9CAC7BB3FD395E7 -:10BC70000B3CB8B5DF25DDF7099EBFE9DA29C447DB -:10BC8000814D889154626A26D5985A492DA636D29C -:10BC900084E9864CFF9D64046DF074A08A50BC5BFF -:10BCA0001968FDEF149ABE9BD3DBE91F08BD790923 -:10BCB000A1783B91754D269A6D2199E299C94C0264 -:10BCC000168A0A8E08C5B7148A771182A92B42F109 -:10BCD0006D18C5BB8819D34E914EF83D25E2C2348C -:10BCE00035D215BFA74532304D8FF4C2B473C48D21 -:10BCF00069466400A65D22FD30ED1A198AEDBA4549 -:10BD00003C98768FDC80DF7B447230CD8CE4E1F7A9 -:10BD10009E112FA6EEC82D9866458A30ED159982A2 -:10BD2000F57A477C98F689DC89DFFB4666607A4DB8 -:10BD30006436A6D746FC98F68B9462DA3F5282E9C5 -:10BD400080C8626C775DA412D3819107F1FBA0C813 -:10BD5000524C074756607A7D2480A927F208D61BEB -:10BD6000125983E9D0C863F87D58A41AD3E191A78A -:10BD7000F0FB88C87A4CB3239B311D1909629A13D2 -:10BD8000F93DA6A322DB30BD21B213DB8D8ED46238 -:10BD90003A26F22A7EBF31528FE94D806F29807793 -:10BDA000214CBD91FFC2EFB9913730CD8BBC8FDFF5 -:10BDB000F3234D981644FE84DF0B2387311D17397A -:10BDC0008AE9CD9130A64591B3988E8F9CC6F496A2 -:10BDD000C8456C776BA415D3E2C837F87D4224823E -:10BDE000A9E07724476D0E0BFCEB05FF9FE93A793C -:10BDF0001DE54BC46FF88EA6C446F16054B47E6C4A -:10BE00004AB91DF24995E25512C5EF64CA0B811F6C -:10BE10004EAC9482376751FC480D37425ECD31B944 -:10BE20004D347F176955017FFF42C276E0A77B47FB -:10BE30009DEA1EA6F8FA6E5AA807456EF8417EAB39 -:10BE4000C29C7A03BF6D56C2F4FBC4D47D697E1BCD -:10BE5000B4A7B43114D09B8E0FF84DD111FAB94B61 -:10BE60002101079DEA41E86114D60B99687E66318D -:10BE7000F10EA5F5AB46996604E93855437D253E9C -:10BE80009AFE22CB3703D2FF02E2A1F3DFCFD383A6 -:10BE9000C480E98B9914EF297DCDBCAF2FA3A702F5 -:10BEA0000AC42E1DC36174BA8BC90D5B6BA66FD01B -:10BEB000D5B753081B4FD47F96F83E82EF813CD212 -:10BEC000AFD216AD47BF1F867A71BE7F1AEF7BBD1A -:10BED0008132020AFF402763700BC827E2764E8644 -:10BEE0007999DDCE29F6C4F3FAD932D740A58F76F9 -:10BEF0009E419CDFCF2432A396F1978C2983B07F9B -:10BF0000948701AB05FB9739FC45BBCF019EB4DD9F -:10BF1000FB165F0B93A7EEEE08179BEBAAE042DB44 -:10BF20007D897051683BFBD5B74B9C56333813AFB6 -:10BF30001BE7C1BF57984840A2EB68DD620F6ECE89 -:10BF4000021C7623FF2C7171069A4A8141E57A49D9 -:10BF5000322C8190C63D492103AD9FB7C5BE19F46F -:10BF60008096BCC0933E80F366956CA15556ECF963 -:10BF7000F9A1DFD07CDE2695500D832C487A229BD8 -:10BF800050B85D2B496CFC80776F1FDABF9F881F0C -:10BF9000AF04FDCF27ACFF1689D151608B13E17A36 -:10BFA000BAA0A66A344DC3BBCB8A09E5E3A72858DB -:10BFB000BB50FC5E60250AA494831B113E01F578FA -:10BFC00058C817A467259A97DBE7E7435ED03F5D23 -:10BFD000F782A01ACDD3BF0BB7E9F31A78E1BEB749 -:10BFE0005AD4E066C4AB6E0C3E025EDE6E0C7E1C64 -:10BFF0005E0516356048457805810F382537C2A1A2 -:10C00000C4A28664DA4F0985239060C9EE87D30104 -:10C010004E0BB7595CC735E396D526EBF215F55DA7 -:10C020005CC73572F4E21BCF38804E1767185CC7C7 -:10C03000297F6B5EE64D394EB7ECFCB2224C057E93 -:10C0400094D566B96CBA7EF4F98BD55211C36FB72B -:10C0500073DAA0C478B638C3E83A4E49F5EC362610 -:10C060006FCF2E33BB609CE6652E171B3703530141 -:10C07000AF454BAD585FCC2F51BF3FF4FC08A9230F -:10C08000C7CCC0CF6959EFC4F513D293F2B911E907 -:10C09000A441FD12F0C64CFF7E67403CC2BCE8B72D -:10C0A000A2560E98AE87EFDB75E3D176EE931AF9C0 -:10C0B00092986E1572528397F7430748A766DC671C -:10C0C0003FEDD149FB6B516C6B408F9AC0F1A702D9 -:10C0D000EA517E50660E1BFDF4D3B93AB61F89C6ED -:10C0E00039BB6C5B37E06B25E66A2330AB92DAFE36 -:10C0F00005404FE7EA56A6837C59285FFCB12F4ED6 -:10C10000FB5F08BA0DAAAD7A7919E4F3A4FDEAE859 -:10C110008CD8DAD64DF3CD063A94AD7DBFBF929858 -:10C12000DC29DF7E70DC683AFFF2FA0B4698C70420 -:10C13000C9FF2B292DBA7E09D64FFB29DD76C4080D -:10C14000EB3BAD06AEF949D615E0D96E9EB68C93A1 -:10C15000499AF905A82249E975760EA757E2BEFD6E -:10C16000534A9F67DE52C923741EE432AD45CB3378 -:10C1700079E95CE27300BC66D72D44FE7306F80FC4 -:10C18000C861529D0DF8718E188A607DE7C8FB8EDC -:10C19000611AF8ED938C1C3E5495A5FCC084432194 -:10C1A000DCBA00BF32955435C983E1BB12E07C494B -:10C1B000FA0EF94950427E56C2BE07887939AE63FD -:10C1C0000DE34701FA07F2F756EBF9D3FCF5FAFC59 -:10C1D0003C32255DA1FC65DEE32AED91F2372DFFAF -:10C1E000A3F07B566272773EA9AC72D1F96F34D25C -:10C1F0007DA2F39FED224A37BABEB2573666CFA270 -:10C20000F9372526C7CE2EA3D3BF86F6D389ADBF77 -:10C210007469D0E81DD87E7DC7EA864D1F4DB03FBA -:10C22000261F4B85FC256E251BB925557213AFBF04 -:10C230005B9DECB538A01EFDAEE1CF73D6E8D7D735 -:10C24000D1FA63D74BC863886FA5DB2613C033B11F -:10C250001EB15F623DEA36C91B8C4307618EAF8217 -:10C26000AFB572F809BDE38B98FC3731F9EF62F294 -:10C2700002BF554EDF14EFBF9046003DB78E637886 -:10C280001236B2F30CAB678CD6FBE64AF54C9C5EDB -:10C2900068BDEFAE54CF12ED4F31A4B5AF57F6CA1B -:10C2A000732F07287E97BEF08483507C3CA354A74D -:10C2B0007BE8F7455B563B004EA7958003F0E64CC4 -:10C2C000502E8A07AF510649E81B3689EE7BB9C06C -:10C2D000FF31CB27827CFF728BEA7A84EE4BC53626 -:10C2E00053C844F7BBBC6E4131198CF9232CFFB302 -:10C2F0000B801F15F5EA51EDBE966E7D22DD6DC7F0 -:10C300007DE866001D9884BA119A96D79C18077A22 -:10C31000740569457C8E6D07E3C3D18EF2EB5946F7 -:10C3200067FB72716EAC609F4845DDCF2FC0B9B11D -:10C33000822847B5785402B84CF5BC01067B2A9C8C -:10C3400017C8483212F88A800309A6215F5EF9EC0B -:10C35000AF061FA1F368AE79CB2169E04335248491 -:10C36000CBC5DA397F4DB9825C384FF1935CA36D50 -:10C3700017C476EE7A3A81CE34DBC0D2456AC83132 -:10C380009AC273D126D54331932C7AEE99DF3D457D -:10C39000E98E7C62F2F4A5F05EF8DC814337D0FCD4 -:10C3A000C21D6A6A315B864D4A8FEE4705FD0B76EA -:10C3B0001901FFD2170F18DD83D8F7873A45F761C7 -:10C3C000E18EBD4632A83DDCF26BF71AC3B638FBEE -:10C3D000517B641CE8332B9FFDCA08FB7D668F44AC -:10C3E0003A67B56F5FB2E900EA2F0027DC3FBE3F36 -:10C3F0006DFBD56E9F42135F1D8EF55CC0AF13EDD4 -:10C40000931D64F508C4E3E75FA5E397FCC9E481E5 -:10C41000F5973C7FBF03D6714AA964F8BC7175BA21 -:10C42000978E5BA206D25D98B2EF254F3F8078369B -:10C43000FFE003A89751FCE862409911E802EBBBCA -:10C4400077C36DB8BE79C48FF856B251F605810F27 -:10C4500028A468471C7A7881D3C3A9CD9453D2F518 -:10C460009D02FE087AEEFB32E78FF7A11EF9005F0E -:10C470002BD56430FF8599ED5395C120EC72661D74 -:10C480009ED6FC0CF9E8D91EDECEAE810807C13776 -:10C49000919FCA070B3BB3FD61FC17DB51BCCB87F7 -:10C4A000EF50BF49F55A06EBDA717EC9C65FC2C7C5 -:10C4B000A7F3B682FE712A9DC989D8F5FDC920F877 -:10C4C0002395AF1AFCD2D035A3F39A87195D0B3AA6 -:10C4D0000F4E2E82F2CF3F64F403ED40FED07985FB -:10C4E0003A63F9DE6912F2011309C5A3E71A95D37D -:10C4F000B3BE9C7268D4DFE8BC15C9A9C513DA7F46 -:10C5000027843FEA25F31EA7ED34FA74058C87F5DE -:10C510008CD1EF5951BA9DCFE9FFF740FF4951FA4D -:10C52000271BD2AEEA7CB6480DFEEE29A0574A9FE3 -:10C530000137D0ABEA83757FB67DFFA13B295E7FD3 -:10C54000562BE854CF3763E9B464E70304F033961D -:10C550004E3FEB5E49E2D229FD1E974EBB87FF5747 -:10C56000F8A680DBC118B8513EF8DB57DD89E1172A -:10C57000CB072B0CEEB87C90FE7C48B2DBE39DC071 -:10C58000378167A5FF59D613F84D1B3E0A7C6BC354 -:10C5900047816FB1EBD4C32DB67C03F01B8D7EA019 -:10C5A000AE20013BDDE7D6DD329E135BDCAD8E4E67 -:10C5B00074DCD516720FE8D92D2E9E4F66F9D6344D -:10C5C0006315F005F1BDD54266007EB6F85A1DC967 -:10C5D0001AFDF94883EC70D3F2709014C5D3AB29DF -:10C5E000C7C5F1C32451F972845FA16CCB5C3A1CBE -:10C5F000CE55B20774B7B9CB6F7780C9A2A5A1F7A2 -:10C60000A419F4FBBD6FCA68D368B13A06C3BCE88D -:10C61000B95DE942E13B87EFF3691278720C5DD7AF -:10C620009C06A617CF5DAB87C73CDB1223F019AA87 -:10C630007F46F140832FC24F50B2415F5E4AD6E23F -:10C640007E95C6E08F9F9F77BAC81C7F869021FC9D -:10C65000BC6180FE16733E55280F9C3483C2BDE535 -:10C660000D999868FE62834CAA609DDBA520013A73 -:10C670000EA4211E9653FE4034E7C266C0336362A7 -:10C68000FA6D7EE92FD93FA15516BDFCE9E0DFD058 -:10C69000B4F9E54FAE790DF2AF7C9CF929695F3FA3 -:10C6A0007FCFD777037F6FD963226827D9F3C7CCB1 -:10C6B0009F40FE559307ED1C2B4C5ED48FF7D8831B -:10C6C0007DA1BC07B32FADDCFDD5E030CA9B55B8CA -:10C6D0004F05323B475C6CF8DB7F4BA990D255810C -:10C6E0001CDD9384FA75C5AB96201C3A5B767F956A -:10C6F000EDB7FD70EB2937123FE29F9DCCD809F8CA -:10C700009ACCEC6915AF8D7A66391DBFAC6EAF71EE -:10C710000E2DCFFFC3B78381AFB4EC64FAC1793576 -:10C72000FC34F11032497E62B94AF7EB3CE86A5DAD -:10C73000295F920FE5066CF1E0C2E0D042E100EB28 -:10C74000A27029017E98081EF3FE65E171E16E1862 -:10C750007F51C348226769E12279D9777BD02CE1E8 -:10C76000FAD9F73D5F0D06BEFB59ED7294DF1DADA2 -:10C770007B35AC3BEDFFA5754BA1AB5977CDBFEC3D -:10C78000BA19FE0F90993C8AA583F678FECA8F31BC -:10C79000FFBCDD83F3BD4AFA6FFC975DFF3FB8EF46 -:10C7A0003B25F4C775B4EFC7FE65D7DDD1BEBFC961 -:10C7B000F7DDEE027B6FCBEE6F338966FD1DADDBDF -:10C7C000A0FCABF2B72BAF5BE83D4D864AD7703A81 -:10C7D000BF4F48F56D59347DCF7B29158EA3940644 -:10C7E0007CF1CE0D4315766E30819D092ADE260937 -:10C7F0007B5193CE8FDBBD04F58C89DE5FA07E403C -:10C8000094CAA65C5ABF296F8EE711AC31F4B01FF1 -:10C81000F2D36EE479FD79EA5D897825AAC74ECC1A -:10C82000BBF50DD0EF267965D4FF688A7ADF47998A -:10C83000E3D8F71CFD39E28E9873C0ED33F4E5B709 -:10C84000F1FEA693C5AEE1145ED3BB2BAE2005D19D -:10C850001DB9952AACE78EBB2452ADB157DE16D375 -:10C860009F4321DC4EF28FC16F6E1BFC16233C48A8 -:10C87000AEECD942AE027E84C1BB69DA9020D861A9 -:10C8800088E261F09B5EE6413B283F67AABCBD6A37 -:10C890005BD30474AB12FDF9529C1313C199F0736E -:10C8A00027F6D32B0A77D52BE3B953D31FC243EC1A -:10C8B000C7F7DD07B17FFFEC7E64C37EC4F19F2D17 -:10C8C000309B6F03FF85B99F84E7F6496B658C83C6 -:10C8D000310F94108EBE1C15FD3B270CBE6C509C76 -:10C8E0008B878D2C7F9075EB01F82CE0709C472A8C -:10C8F00051EF2497BFFB6E0CF88D1042B4DC4BC88F -:10C90000047A0E9937460A59E9FAE72B24E01C0A03 -:10C91000764D891CD5DA3583FA3CFCDC941EEDA7F4 -:10C92000A3FA89F8C30F9DFE95F2A3A37DE87905CC -:10C9300052058757B4E7C47B1A181C2B1649C15EF1 -:10C94000884721D5A7F1EB7CC2F1FAAF0F0D433E2A -:10C9500097FBCB414E3CBF7A07A0BE5FC1F5FD8B74 -:10C9600001B713EC35171B7A3BC11E73F18D7C8721 -:10C97000962F8AF4203F477EB0CC8C694B81542D92 -:10C98000C3798BB44E44395C6021C07762DBED52D1 -:10C9900084DDA592F919E98F9C0DFBC87EE6D3A62C -:10C9A000CE4E9A7D5B3BE18C32B8FD3EC0CF518DBF -:10C9B0009FE49F852F9C5B01AE072DE171BE38EB94 -:10C9C0007D8BC3AF78DFD746B0134C69C852012EB8 -:10C9D000530A645DDCCD7E859FA786916130AFE20E -:10C9E0007DE31DA3605FDE903D160ADF8A860B465D -:10C9F0007F1C7F5B2C3CA17FB00B1F533DF3009E3F -:10CA0000C77E6121014A0FEF70FF0F2DF202FFA2D6 -:10CA10005D79C13EF6A1C2FC0AFD5566179F5A9C7E -:10CA2000ABA6D17107D6B9868088E9CAEBF757DD86 -:10CA300058DE8DB713F5BA2E62F58E185DE5F1D686 -:10CA40003FC1C8D63F9F787E9C23FDEBED5BEE2F68 -:10CA5000EDA13C90EF0512F291F6784D903E2E1626 -:10CA6000494190BF708EC57CB184F2FF1D032B0F2E -:10CA70004C61F252E07D2C9C2595C1598C9FA532CA -:10CA80007C36AA0C3E02CE02BEB1F315F529BF1AC0 -:10CA9000ABB5AF4CAA1FF23CE827E50D920B4C7FDB -:10CAA000E54AD808745851FFA80AFE823BDCAC5F07 -:10CAB000A2F8066BFDB5FD5505E7B37FE868D41F06 -:10CAC0002FAD65FAB177EE0507E841EF183CEF8D21 -:10CAD000067A7C57C678824470FC74D9B669058A98 -:10CAE000B6DF2C9CE7D445B92A98837EB468AFDAC8 -:10CAF00059834FFDD54E582EBE775DE41E0ADFE9FF -:10CB000078388FC07F98C816DAC5C0DAA6BC245A18 -:10CB1000FEA3CA64868725B57B8D98CFC2FA623C96 -:10CB2000314E2C3D4D2B4ED2E5E7E487BB035C8AAA -:10CB30004DA1259E3878DAA80A3FC9F794135E8A7A -:10CB4000B783FF7F901317C679E3C06D9DDA4E3E21 -:10CB5000748E271F162F777706F82FDEDDBB331074 -:10CB6000C7E2370BD3E3C9878F96317FE0C7949F25 -:10CB700041DA328DCA87EB35F2619A05F123B6DDD1 -:10CB80004FD5AB940F62BFFE97F9CC47201FE2D080 -:10CB900075B5AA970FD31B66A17C983E4D266E8D66 -:10CBA0003DEE672AF77325940FB9E977605EF524A7 -:10CBB000C5C19B8FF8B904E00A298C0372E20F9C6F -:10CBC000EFC7CA8B44FC7C8A51E2FEEA0EF8F9FFFB -:10CBD00025380B7EBE989E5F400F6C8F8704F9F559 -:10CBE000E23B283F97001F193F5F7C17B74BC6F009 -:10CBF000571FF0D7E15AFECADA97FB993CA8A8CF95 -:10CC0000FAD54C5A7E67B5EA31D3FA7746F96DB654 -:10CC100096DFFE81F35B0AE74C579CFD9D3133891B -:10CC2000B8F5FCAA0FF0A96343FE38F045C0FB77C6 -:10CC300064F4239EE072FCED217F1C0EF6F354A3F6 -:10CC400082F87382F3AFF3CB82D30A281DE7CF6556 -:10CC5000FA70D97619E1505EC7F4BCF23ED6A09BBB -:10CC6000E6C70DFD1AFD810B77337F20055471AEA9 -:10CC7000661F17BE13AEEA06E59B24F467CEF32CBD -:10CC8000443B3E59CFECC466FA87C57578D18E5CBB -:10CC9000C6E1B5A06113DA9B1704F576E8B23EB79A -:10CCA0009C81F380E0BF0BB7C5947B1E467F45197E -:10CCB000D89B35E71099EB0FF7CAA1812F426CE79B -:10CCC0007BEC5C15BBFFA25EDBFA4BFEC9F51FA433 -:10CCD000EB1FFEC3AFFF6AD7AD1A39BD0F25C38165 -:10CCE0003E4E18BC48EF81FFA2EBA7E3CC7DB46FAA -:10CCF000676D9C510AA7CB770CFEAA2E50AF5CC281 -:10CD00007AF337EC38904EF3336BC91030D3CF5FE2 -:10CD1000AF978B6D72B8CE8D727666E50E69F64070 -:10CD20008037A9043C9B33D4E4077FEA414B2BF2C4 -:10CD30002F8177371A193E8FE6E31EEBDA5A80E728 -:10CD4000887AC9857411B2B0730585BF85E6F78FFF -:10CD5000FA6A1C8737DA632AEAD9FE54D0FD00BA92 -:10CD60001AD7C0F3DB981EF6232A6FD01FD6B05710 -:10CD7000857625B47E0AF29B013A3F17F8E772D315 -:10CD800035FBB6FB08C3DB2D9287C4D9B77EF44FC1 -:10CD9000DC7DFB81F055C0E34623D7E7F9FE1DB4E7 -:10CDA00034150F433F94E4D90C951B92D18F72BC7C -:10CDB000BA37EEE3AD1C7F63F11AF47BB7C69E343D -:10CDC00019260EF19645168C73C3717B31FD47CB46 -:10CDD0004F62CFCD15A409F5980992FF2F8A26AE90 -:10CDE0006D3A8F3F117E5A4DBD5FA957A847325CFF -:10CDF00006E093F78B784B881F4EC7B825FCD9DF28 -:10CE000023FBE39974BD97D6C81EF0FFDC6E701F3C -:10CE10001A03F4FB884A002F2FBDAD7A99DE99845E -:10CE20007C77D63BC7543085CCA23081FD9EF5532C -:10CE3000C65F8F4167F4DB9FA8DCF282AF9ED48E81 -:10CE400080F8E1699EBD856EBA2FB70D3FB81AFC18 -:10CE50007053F35D870E017C1F9609C0F7E89A7C3A -:10CE60003C9FDC7F9F84787D98C211DADF362DEB02 -:10CE7000D0213AEE5D6BD2D0AF36D37BA010F06CF0 -:10CE8000CE24BB0DFC6BB7F693895F03C7BB48D3B9 -:10CE90006AE0D7332BEFBB0DE65B42E500D8594B78 -:10CEA0001A0E167686FC06C9E3A6FD5704FCC6CE0C -:10CEB000740B9BD65F3082BD631EAD07DB53B1811F -:10CEC000D5ABA8913C16C0C7864791EFCCAB9188F3 -:10CED0000BEA537DCFCCFA0D9A69BF4D1B687B9A44 -:10CEE0009F0FEDA1DF9AE4E9E047AB785B66ED7355 -:10CEF00096BF0E7C691E6D478B4953CD7DD8DF826E -:10CF00000D12C9A0FD95E464FD470EF4F7B6EA8161 -:10CF1000F28FF7FEDA08F3BE9B8ED785F63F470EF9 -:10CF200017427DF213C9B505ED4D2C4EB685D301E0 -:10CF3000F9B00BA32F89E7B91E28E4E107C65E8884 -:10CF40004FF3962EAF8275850369597004AAA8BF66 -:10CF50006004BDEE3885B39FEA6DC7781CDBFEC068 -:10CF6000316358C3A75A8DBDB1FDDCFA5CA4EF7BD9 -:10CF7000890FFDDDFEE54C0E1F596D094AA07FA803 -:10CF80002E9493FB575FFB24ACFFFC732AFA47CF28 -:10CF9000F708A33DF6D4069504E81C576E90916FF0 -:10CFA0009CDACEEC40F24615F3F31F30627EFF862A -:10CFB000A9E3801F9EA2F0073CCCDF586884FC7C6C -:10CFC000CAD74D71F8C73C7729E31731FC61FE7A67 -:10CFD0003DFDB7E3174BC631FE1EC30FCABA57A1BA -:10CFE0009D2F964F54109BE00F4321DF14EA82F8E7 -:10CFF0005BFEB64A409F2B575C77AF07BC9969012F -:10D000004F31A58BD001E06B9782923B40CB7F7470 -:10D01000CFAE1100BF93006FA08BB529E84F9D17CD -:10D020009C857015F184F3D7EBF159C42FDDE1979E -:10D0300089572B074A92885753EFE39F52BCA4E3CA -:10D04000DD532F052D12E48FBCFEC070CCBB000F4A -:10D05000CB977279BAD68E78FBF1BF5D580D78798F -:10D06000F74312CE9F04FC552057CAD74B6EB063CE -:10D07000CE7F88B59F4FDB03BE7CFC6B863F148F51 -:10D08000DD80E7E51B1E7D1DEBD7486EE8FFE34D15 -:10D09000B350FE96046482E53547503FA67200E324 -:10D0A00080F607E474C0F3F2552617ECA3C017818D -:10D0B0007F4754E6B72766CFE0A9B4DD26A31BD788 -:10D0C0001D8B77F28C2CC4AF8AED2AE2474580E1B4 -:10D0D000D391E764C4C3FDAB6F47FC39BF454A80B9 -:10D0E0007FF9C62E807F4156DE867FCF4A1CFF180F -:10D0F0005E9F5AC2F0311FCA01FF5EE2FA29213653 -:10D10000ADDE21F04FE0534778D74E2E25C037AA29 -:10D110001B4F8779DDBFDA82F3CEAFDA357D29D2B6 -:10D120008D8AFEF9FCAA7F4B073A9DA7B0380C0107 -:10D13000C73285C5E9B49BC7E3CB8D5DAE663E3192 -:10D14000F3D81B958B43412E425C49888EF3C7ED83 -:10D15000CF60FCDAB9DF1FC1B8C485AFD17DA7F5B8 -:10D16000CF6FB79310EAD341E42FA57532C685126D -:10D1700025943D55737F44C45B2C7CC18EF02DDD1E -:10D18000690A16D3F6A52F1F1B8CFEF015ADAF0351 -:10D19000FD047E2F31BB7C203C782AC4552A2CEE1E -:10D1A0002356EE8E32317B4DF3AEA419A0FF48DB3F -:10D1B000F6A23FA9B4F676D5A4B14F7A4C2A8E4B8D -:10D1C000EBB17B2E74DFC18F08F39B3C483BBFE57E -:10D1D000ACBF6719DD94D6ABA817956EDB8476BD1E -:10D1E0008A6D1730EE35FF85E71C00878A7A591F54 -:10D1F0000FB54D0E99305E4B3E6262FC4917975455 -:10D200005EC7EE6594D7F2B89F98B898852FEC7EEC -:10D21000394041B3F0C5AD0EA0A3B34D5B1C004F28 -:10D22000DA1FC6134DCA49106FD4519C51EDC3711A -:10D23000E38CCEC23F2882DC6DD2C767926D8C4FE3 -:10D24000D15DCFF6C5B1670A7D65E1735F3C0D71B5 -:10D25000AFCD3B3F7B1AE6BDE8EF979E86B80DB297 -:10D26000C7E202FDA1E2F71F61FCA068B7D4C4CFFA -:10D270003FCF6EC5B8CBF39F9850FF3BBFFB542602 -:10D28000E807E7777C9D0EF1944B7617A2FD61C904 -:10D290004BF99D499CF3AD48012F835711F719BBFA -:10D2A0000FFBEBE4908DCEF3DC6113D2775BBC58BF -:10D2B0006D198BBF73F338B1EDF1E36A457C537997 -:10D2C000DDD44937027FAB6372BC2DDEA9A3F8B071 -:10D2D0000FE97E5E7F15FBB69DC7FFC5ECDB39F815 -:10D2E00007DD9F274CFAF8B02FEAEEFDED535056BC -:10D2F00017FF3E99A0E38EE025E276E798BC411344 -:10D30000D0CDCEFFC4383CD8AF6237C8F92F32C178 -:10D310006E795A6D457B60EB6E930BE2B64A777F70 -:10D320008CF471FEA58318174B78FCEC79D2F6C308 -:10D33000E21DB94DA2A2C6CEE2CA38DC21EECCED88 -:10D34000C0EF3CBE8CE1AD883B4B146FF691A91742 -:10D35000BF77C1E2E2CADC4D4680BF360E4DCA81BE -:10D360007D3AA28BDF13EB8EEDCF057018A98D9B54 -:10D370004C14CFC7F5F1B67D627CF8FC261E47D968 -:10D38000161F4948F7A110EFC3E45D4550FA98C451 -:10D39000A1471137D9144B8FC1AB8B97EC78BEFFE7 -:10D3A000183CF69B98FD49C0A5F9727C7EFC19A734 -:10D3B0006F7A2E396BD2DC4BB9879F4B441C9998FE -:10D3C0006F552D93BBCDDB985E184BCFE5DCDE1E91 -:10D3D0003BCED77C9CF2FABD8381EF34EFDBC5F105 -:10D3E0008DE173F9F623C600E7CF412D7F86FEE27B -:10D3F000F013D9CCFAA3E7D8B8FD556CBF10B7BF6E -:10D40000B38AF77698FFD926A6679CAD958B827173 -:10D41000FA3FC7E54FDBBAED463C57C90E2BF29FEA -:10D4200025F69CC3CE54488D18BFB072398F77F85B -:10D43000A92703E0BCD27E0B81F9AC06F868CE992F -:10D44000AACB4F40CF51337CC3E1FC24E62BCA8DDD -:10D45000A90612D4EEBF12C0FB91137B7DA5807C80 -:10D46000695AA6BFD7D1A4B80EA4D0FE9A0A240F39 -:10D47000E8B3EDF14CDFFF64AFACB38781ED19D6B3 -:10D4800075D163C0FDB41B422E5A85D82D4D197835 -:10D49000907313B7928E21DDE8DF7E64D9B61E70DB -:10D4A000CFCA413C1294DB3D6DF75BB03F27898DBD -:10D4B000B3261FF6C926FC0A3094BBF6825DC2DA99 -:10D4C0008FF483FB3B2E62F5C0FB0AEBF8BDC7B5BA -:10D4D000763FCADB8474E361F75E849DC899A3E854 -:10D4E000EEC5247BF5F994987B90825FE3153A0AA8 -:10D4F000FF71FCDD87E442B67EB057F54D8FCE3725 -:10D50000398D7842503EC186F1CC361B9B9F982FB7 -:10D510009D0FF2030A26369F81E100E8E1745E3137 -:10D52000744CF0DE139DDFD198F9E9F4B83BCC5C84 -:10D530003E2844013E623337110EE78BFA38D300A0 -:10D5400081B803671B5C6939ED274B9A6482B80583 -:10D55000179C827BE37831EDBABBB4F7C5EAE11FD3 -:10D56000A3D05FD468043FBF5982E333E90CB80607 -:10D5700040509A8C008C5FD9443E84FAA2AFEE20D2 -:10D580009E3FCB6A0F62B901F2344D497217741B8A -:10D5900042C8C36B0A0A32FA43BD5919060FE61B8B -:10D5A00015A0A3C9FE0CC310987EC1AAC631846C15 -:10D5B000259503C0A2645EE56D7CA307E01541A735 -:10D5C0001D09781B0137B78A3C6580F0BEC2566BD7 -:10D5D0005BDE6BA67C716BAFB67C00F23500FC1B8A -:10D5E000603C6FE32A88F331FB5699E9B893371A08 -:10D5F00090EEC6466C78FE20E14EC89F09A9B4FAA9 -:10D60000E2DC976EB3F3F07A1DF1F1AD3C1E79B216 -:10D61000DFEF81ABDE23B93C26AEF030B88FDD62A0 -:10D620009EFDA4594B871B2FCABDE8FC9E84BDA755 -:10D63000ED9D45AE5BFAD1F939371858FCACD9FFEE -:10D640001BA8DFF721BF01AA8C25E1FB25E0C37FE2 -:10D650004EC5F98871AA76B37355D56A437005E251 -:10D66000AF5B02F916DDBF70CCFEB5B2FDAB3F82F9 -:10D67000FB57DE7084ED5FFDA6BD466E8F8773CBD2 -:10D6800056E2D901A6A71D6B661428745F524CADF3 -:10D6900055B0AF2A995E50DC1FE1FA425CB8F2F94E -:10D6A0007504D7ADA737FF7C30E8F5CD064F5F1284 -:10D6B0008597A877C8CCE2C4A659FD0D304EC5E3C6 -:10D6C000E12A38FFBE7AFA7DF403F76DBE181A4CD2 -:10D6D000E7DB770C37A7F071B7366F467FE656C0A9 -:10D6E0006337B8EEFD2B404E268607C3EF3678D45D -:10D6F0001D41F818204FBFEFE4F728F2EA252FC8A4 -:10D7000089141395A3347DCFCCCE31C7CC324F9939 -:10D710009DD1D9DC4B01BD386F9A01CF534E9E4647 -:10D72000D7CFE3FFCC8A4EBE88FD147844487512EB -:10D730009C730A9CFE3FEBF1E6B1A45EB47CECF175 -:10D74000A3F7835D4FB4DBB28C78E66AEE4353FCFB -:10D75000D9A56B57F88015ECA1A23EE065BC730219 -:10D760006D7716DAC138B08E5DC72FCA00EFABDD1A -:10D77000D7D8EF4DCBE8787D12D38F2F97DD2B8A4A -:10D78000FDFE77B3F03B327DC41BBDF7F777C08752 -:10D790003273D8318DEE6F79EE2523C06145D2F911 -:10D7A000D1F1FC9E89E6D174F95A1BC8E97D115369 -:10D7B000DC7B04FD2D4CBF7877D90C0FF8E11F16E8 -:10D7C000F704B83C2BE07CB7A04F6931635A9AB894 -:10D7D00031305870B959085FE8FC8A727628203FCA -:10D7E0000B89465E32F93801F49187F36482716ADD -:10D7F0002E5527DF6E057BB903DE05A96C84E16F2A -:10D80000CED0DF039D34E68802EF158CCFA1E2581D -:10D8100082F769F4E5B7C6DC139DEC9DE529E0E5E8 -:10D8200097F0FF415CE7A49C3B3C055A39A154F7B3 -:10D83000837D3EF8AD1C576F7CA00D3E3E84EB2BE4 -:10D84000160A9FEB619DB35631305D191EB1708C85 -:10D85000854BC19FE7317B610C3C6EBE5CDD98124D -:10D86000070EEDD75DDD0FE4A6805F2C1C9AA02E7D -:10D87000EA4DA620E8814D4A18E1D844E118E07E3F -:10D88000ABC274CD3E8BF970FDE156FE3D169EB1E4 -:10D8900070A4FA05EA0FE307D9D10EF636C00BE300 -:10D8A00000AA3F34D1EF6FF651C923C0FB42633168 -:10D8B000CEF02682B022AF489505E8977131FF0A75 -:10D8C00095E70C1FFECCEC57C51136FF716E162F75 -:10D8D00043E17134061E4763F040776E899DE72B64 -:10D8E000F08F5171F083E3C1220B3FDF641237DC0C -:10D8F000FFCFFE64B893F185F8F2716CC4D7D60FF0 -:10D90000D33BD8FB1C12F1B77D77D17E425E15E385 -:10D910003FF3CD2EA48F7CE24D81F72020C810E686 -:10D9200029E6354CF2FDD49206EF378D4FD1BE0F6C -:10D9300021C617FB92CFE1974F027BE11C9A4F94CF -:10D94000CFB5EB16FD5559B89ED593F4443F391821 -:10D95000434744FB13EB4B4921217C3F4432E33DD9 -:10D9600027FA5FC0D8293A9E881FB5DBA7545B58B9 -:10D970009C0461711221DCCF3C5E9EC7DF6922E608 -:10D9800084EFF290EF92A2F37BDA2229F86E029FE5 -:10D99000DFB937CC0188D77850F26F86719AA5B776 -:10D9A0000703BCA83E760DDED38F29BF74B8B11C27 -:10D9B000CA69BD79588FAF6BA1CCEC64F4FC8FEFD2 -:10D9C000A1B4E7E3CC9E46C94D211AFACCB332FA92 -:10D9D000BE95B8BBE37B69C4AF40DA6861F7D06E2F -:10D9E0003EFC18EEDF5BD69BDF007A2B224105DF81 -:10D9F000F971E9F1B0433CED177BFEE5EFBA28ADD4 -:10DA00009900D77D966BFB801C13FAC2FB16DF1FB3 -:10DA100060BDFB2C8C3F1FF58E7817E4C2ECDC61F7 -:10DA20008786D3D460F6E1BB0BF7025E5178E6003F -:10DA30005ED1B6FBA0EB2E88576F5846C0FDFB1891 -:10DA4000BC32337BDA6CCAB6601D796BD46FB4F329 -:10DA50006A8317978B1DE987A4912AF4E9F0DE0207 -:10DA6000C3CF7D165300F4B6BC87597CC41CE27F3B -:10DA7000BA5AC2770074FAFA5C0BB37BCFFDB505D6 -:10DA8000E99C36DE50097E2E0B7FCFA11F7B77A746 -:10DA90006DBC6A4D7BD877733AE2E15CEE3F3C2E79 -:10DAA000B173CB5C4B21BBF7BB5EBDA8C5C7D8F13A -:10DAB00013F61BD36E9FC4EC24FB5437C6838976C0 -:10DAC000E72D4C8E5F34F7DD60B8C27DF079E64E0D -:10DAD00003959468FEA4C532239E5E20FA6B3B97A3 -:10DAE0008BF30431AF6EEC1E3D4FAC5EA11ED09F98 -:10DAF00027D403FFCC79C2F5887A60156DFF848145 -:10DB0000F9DF88E2EB3F59A30775B1327DF080CD94 -:10DB1000DBC54AD327B8DE48359CFE5A7BB5A897AB -:10DB2000BE348F1C1B167DB74D52E80CF1DD0DFF86 -:10DB3000729043CA0C827281F29F7BE2C50BD9EDD1 -:10DB4000793D601C41970F1BDC35D52C8E01FDC043 -:10DB5000BEA5B351CF9BBAB404D396A397AF01FA35 -:10DB6000CCE3701E60E5F69324463792E41F60858F -:10DB7000F87CAF6C073FEBC27A99FBF1D87B575327 -:10DB800027C869F0FD9859C5F3E13E3BDBEF63849C -:10DB9000BD5B9377D0E4ABA3E965923BC1AAD13BCF -:10DBA0002F9302CC938C74F46B8B7B8CC748169BA1 -:10DBB000EF1AE637B8B8260BE39BF7A97A3BD5589E -:10DBC0002BD393C75AD9BECFE6EFDB019EC13B13DF -:10DBD000B31537DA0D67478CEC7D353A0FC4438BAC -:10DBE000BE9F22DE4F515B3F04EBEFB3C4F6A3B000 -:10DBF000FE393EC7C2FD354B7E31ACE732F14EB047 -:10DC0000221EBA15804FDEF0C6C3C0F73AE6F30114 -:10DC100009F87CC56529D413EC68752A9EDB9AB98E -:10DC2000DE7FAE6E7FFA6C9A96EDF8C001E7C3BB5B -:10DC3000F93E9D539AF03D8A452FC9789F9AA26F6D -:10DC4000FA8FB0FD9C6C761F84DD6710F2EF866F53 -:10DC50007B77F7613D763F41E85DF9E64010E6B736 -:10DC60006FB98CF62A2A1F75EF9314D6B17B0BB1CE -:10DC7000FAD812ABCAE338D93E2E71B17112D17302 -:10DC80005EC44A821A7ACE53DC0ACC3F2FE220418E -:10DC90000AF773A737AF9B48F13C90A1E2F98F4A8E -:10DCA0009B46D407A3FEF1467847AB91AFE740DD32 -:10DCB000D469F0EECAEBA472D5205AA720EC4F65C8 -:10DCC000C44D4F6FD9517DACD0A5D70363F5C4A225 -:10DCD000864757C11B2DCDF001C6379B30BEB89D7E -:10DCE000FE68BE39AEDE48C8A3883F37BCF4CCAD71 -:10DCF000F02EC50D670C2E98DF34AB9BD153DD257C -:10DD00007C37A19C84A64379799DEC0AD1560748BB -:10DD1000DD75202F857C1770095DDE6FF6801CB0E5 -:10DD2000C8AE15B04EF36D3688BF18DD323015E43D -:10DD3000DC3EB38AF6C93C4B5FDB1C0D3EEF4B6506 -:10DD4000EF091C48EDADFF6E5E771DC8BB5D3C9EC4 -:10DD5000ADF1E49DB630D69B9A8AFA9A90EF317A6B -:10DD6000ACB0838DEF2BB7D9C1B4FA2F91373C6E8D -:10DD7000A1E5B75EABE27DB88230F3A7B693EF972B -:10DD8000FDABF83945F7BD88EB0DEDE47D14CE3AD7 -:10DD9000FDF4552BD7CFDC6410E89BA1CBEB16E24A -:10DDA0003DDA8624D70AB433307DA6E578E9BA098E -:10DDB000F0FD6D99D94D2ECB4847FBF62CEC19D6CA -:10DDC000D02F9514B86F5F0EB970FE35BA2F5F9ED5 -:10DDD000B07A028877B5D7C5F79705399C425D9927 -:10DDE000FD3DD095BD8FC1CEA33745CFA34DC00F0C -:10DDF000E07D19101B191B8E18E1DC7C8EAAE888C7 -:10DE00005F74D1805F3779C3B24B339FE356662F7F -:10DE10009866F51E023E122079DDA872424AACDEF9 -:10DE20005C880F6F9D4C5C9BE97A769FCE93549AE9 -:10DE30001FB325CB23D1FC4E5038816FBE24072160 -:10DE4000CE6427DC67A3FD2E68AA3666D171037500 -:10DE500032DAFB1770BBF969359099ACC18F5F2638 -:10DE6000B1714FABFEDF423FA73F31A11DFCF4096A -:10DE70006B5C797B7B12E397AF71793624C98DF99E -:10DE800050F3ABAF77A5F30A455C4300EEA5DB2E5C -:10DE9000C8F09ED28D5C2F2B7EBC6915D86B266E88 -:10DEA000685580EFF882AE4210B553B6795490436E -:10DEB000D3B6FB54D8DEE97595189F34A3BEFA009B -:10DEC000E4EF0CD562FEBA24FFDF00AE37AD69DDAA -:10DED0000FE8D2A79A28F8BECFE74CDF4AE3F3E871 -:10DEE00015F1EC732236E71A00BFDBC67FA84901A3 -:10DEF000957EE22A363EED4F4D82FE2A5BF341AE1F -:10DF0000652E65FD6592BDCB9DEE68BF632F3749D9 -:10DF10005A3B42DE4F16211E3DFDE0A29E60670F78 -:10DF2000FCC944FA66719A4885EFDDF9FDB270FFCD -:10DF3000293ABF74C8C4F08698592AF0C96B66782C -:10DF4000E4B2825EF0E3272BAD4017A93EB7511B28 -:10DF50007798B7AE78C09B80A71613DAE3BE1CC2D1 -:10DF6000F4F62F1FB505F9F97400E0AD9053B363D3 -:10DF7000FC2E513A67784FBB08C23C444AA4152E88 -:10DF8000A2CD935006CCAB4712E3633546F74C184D -:10DF9000AFC66A72C178B3CD7D8DC097DAEC9A3C7A -:10DFA0002E6D34D72B779FDE9702FBFAE590E5992B -:10DFB000A02F870CBF413ED4115E3D66F566273128 -:10DFC0007D0EF57B517FD749EB409083AF097DCB28 -:10DFD00033AB27AC57B49B9AC4F4A89DDC3F27E829 -:10DFE00020B58978370D445079776AE0313189C995 -:10DFF0005191EE54DD0146472C9E73A73D64EE0D12 -:10E00000F4BAAB37E6537DC4E681F895FABE1EF04C -:10E01000D3503A9F98A489DBBB91D37F6A532BD20C -:10E02000DDD59E034670F886945A4E3F04F910D011 -:10E030000FE3CFA16EFC1D1EF4FB015FE0FBD34597 -:10E04000CAC03870DC67B1EE544EF7F773BA0638C1 -:10E05000407939CF8BF2451C5E85F240A7366EAC15 -:10E060009DDC5E9A41403F2C5CDA15D3724E670B03 -:10E07000CC8FA29D7441EAA3681F4DF55663BAA0E8 -:10E08000A01ABF676C9885F8B1607DFCF7C5DEE229 -:10E090007AEFB9D306F68E94C1DA15F04F9437595A -:10E0A00055CE0FFD0F023E9CA95BF7E46077D4DEEE -:10E0B0007BA686C9C112AB5EAF5BC6F161F7E7FB19 -:10E0C00052005FBEB4544FBC13E8648BEC5A0EFB95 -:10E0D000585328B9E3E09F16CE00D78A9A2FD0AFC5 -:10E0E0005A4EC2E8573DC3F53137F79F0A3F6BB030 -:10E0F00086F1D7D32AE3EFA7A51409E803F83BF08C -:10E10000D9D3271EC97C10F048B2A35E037C738765 -:10E11000063F166EDF54D595FEF3A6CBECDE4E48D7 -:10E1200021362D7F167822F86DECBC37F17D1578FD -:10E13000383A2A87362571BB686FDA6FF9A317D191 -:10E140002EFA32DFBF1AC037A0E73502DF8618D8B3 -:10E150007B697A3A1EF903F1EF5D8F3D95897687E9 -:10E160001C4AB7F0BE1AD0751CBCD8C3F1F231AB53 -:10E170007F17CC3F96DF9F91FCBF4DE91D6DBFEB34 -:10E18000E42D03666BFA59CFE1F1A5EAEFE98A03C2 -:10E19000AF285C4957D8E712BA330007B241726919 -:10E1A000E3DD533730FBFE7B9C3F88EF222FE03DC1 -:10E1B00036FAAEDC7B494CEE1B4124670499DC2720 -:10E1C000865BBA821C5F60F5DE827696470D04DFBF -:10E1D0005195F210DF536B9E38F9ED70482DBDD08C -:10E1E0005F42DC06F0832E78D88DE7BD15BFB320E3 -:10E1F0009E9D4862F1112B6A54C4B7336A35C6E15B -:10E200009D3951DA13FC2D814F981C4A044F813FF0 -:10E210003B39BF1178D76B2DC3BB1AC56B05BC1337 -:10E220007254E0E7992D370F057A13EDA378E31ABE -:10E2300022F06616FDDE6B4D5886FDA1FBD60A70F6 -:10E24000E8BDB615F957A27D137E34B17F82AF0FBA -:10E25000B319747E03838DCD3F3581DF3F2AD7F418 -:10E260007C98EE87641BA1C77FB85A29E8A9B90337 -:10E270003AB8C7C6DE77AEFACB1CF4DF0B3F8CF0A2 -:10E280008F8AF1536C0C1F12F9515ACCFE4EB618FE -:10E290003F9F1BF93AF39B88DF33B0780B8B63DA2F -:10E2A0000545C02F8E5B83DAFBB9D72AC4AB0CA51A -:10E2B000D861CBC2795D0BAC82E653971A491F7ABD -:10E2C0007EFA72D4DE4607AD3FA1355C7C3D5DDA57 -:10E2D0002E6378DA24B0EB126F29E8136883073CC9 -:10E2E0006F66FD1257AD6E9E03389CC5BE887527BC -:10E2F000925B89F6E31E1BF77BF1F2583A37F2F294 -:10E30000D39C8E3AA6D38013E8F42612580EF1154A -:10E31000F4A08D71696D744A0FDED07F01EF577CD8 -:10E3200017F938745A604BD3D06924CCE894D3A33E -:10E33000B346F5C6D34FA6D8983C72D614E6823CB5 -:10E3400071FA30AC9CFE30BA5E40E91AE83500F450 -:10E35000D919E0C9E8AC97B71AE3197BD530BDFAF3 -:10E36000CB64B6DE05377AF7C27BC80BA85E2FD127 -:10E37000AAD59CAE13C33DE494987C72023FB96960 -:10E380004C381FE4AD1BEC169DF1575BE0A68C1DCD -:10E39000438221BAEFEECB84F189134FDDFD20F0EB -:10E3A00087476D78AF49C89FB424FF3CC0CB44F485 -:10E3B0004CF1D20B76A7C55FDBD8F92F81DF7BEC60 -:10E3C0005203E99382785EA1C5F3B1BE5619E09A73 -:10E3D00092E4CF5093E9F836EF38730FBABE2CAA07 -:10E3E000DFD2FC4F697E2D5DC7D64E61C2F355B6B4 -:10E3F00051FFB83D2EB0F6A6D7C1BFBF25C9FBEF70 -:10E40000308F16B32F00FB7C53B75619E395AED26D -:10E410006F5F017638BA9EA3B70DF8DD2CFA75F65A -:10E420001DBE2A2815F6E291DC5E5CD13004EDC8F1 -:10E430001ABBF12F6D57B01B7734AE83D33DC56F38 -:10E440003CC739725A65E08B82AF6CB475E2F81C38 -:10E450002670AE10F4057C09F45A113F00F6433BD8 -:10E46000FA2382887F90770E8DF29BB5D586B8F11E -:10E470004DDB6DB6B87C9434FCEDE507C53B8A8C6A -:10E48000AF6EB769F48A9AEAA3E94C4F65EF92DD63 -:10E49000CFCFF2EB5678DEEB931ABDD73CCA640CB3 -:10E4A000C07B8AF460E67669E223A506296487B812 -:10E4B000BB6F6811E0D137064CD7FDBBAF280BEC22 -:10E4C00025870D9E1504E310103E393D09BEB35358 -:10E4D000CFED9CB9C76C5EF0EFB74866E49F2D475F -:10E4E000AC01909F2D7603DAC71B779B902E2EF5FB -:10E4F000B1723B465067EF10FE9A4B6FCF4901BE99 -:10E50000FF24F75B3E79C735687F14765945A13003 -:10E51000EF04662976EF326F6957B49B0A3B6DBAF8 -:10E520007996C4828458FF8A99AD2B5DF14B60FFC8 -:10E53000DED4417CC35F6D46A1EF1E06F8563C1445 -:10E5400036C27955E8BB421EF76CEEB517E21C7A6D -:10E550001631B3D8A6668301D6B789A25172567B0D -:10E56000BC12F8B3A97D1CC1099B865F4E5ECDE24B -:10E5700008DAF2BCDD6F791CC1D8E3475FC4F7F25B -:10E58000CCFE8F74ED0AD3ACF1DEE19EBEF4416C9B -:10E590009F08EFA71BD8FB3BB1DF4D76CEB795CADE -:10E5A0006E78FFE9AF3F4E72C7B1C74CFFCB6CFC32 -:10E5B0003D11B1F6B3E8F8FFEE29A0FB26D9DBFC4C -:10E5C0009499E037EBC84F193BEF43AABF473CF99A -:10E5D000141B4727C66BDF9E9DBFDAEA19897F8728 -:10E5E0008DF53B54D36F8E9DE93DD32582F1EDE44B -:10E5F0005B82725AE009857B373B2DCF7EE7D830AE -:10E600002BFA715A65E003970EF7E98EFEF304E7E3 -:10E610004D311F42FC7DE3C5694C877776E2AC6FD4 -:10E62000849DC9E7E92AF3374877F4C5F3FF748B73 -:10E6300049D2C6E567D9251D3D097BF33ECB48BCD1 -:10E64000BF0876F978F08BF5C366818F348DC1C52C -:10E6500013079F84DF4FC0B92AD79BAB30BB18DEAE -:10E66000434BF532FE995A44D07F3652F2223C6E2B -:10E67000B6337D69138F7FBBF4368B57CDCE75E3F0 -:10E68000EF71A272A2D03E02E3A95E3468E2A9044F -:10E690009E543D47E5B1CE6EC8E84A9C9B93391F16 -:10E6A00076C17B129A7AEE87800744E540F755667B -:10E6B0005D3E73898B281A3991ECCDD0E5BBFB5CAC -:10E6C00056382F752F72EBDA09BC13F17CF8930AD8 -:10E6D000EB76A1DDA9139FCF48C98F78037C0DECA1 -:10E6E000C1F7F27DA2EB9D037834B6287C498B37C5 -:10E6F00062BD1DADEBE83237F2C2E3CBE87C295FA7 -:10E7000098B3366B7906C2DD45E01C71729919BF6A -:10E71000DFCBDB273F3E0BEFC926AF72A33D36D9D7 -:10E720005BF93ADCE349AE74E3BD81B9D59204E705 -:10E7300074CA67B0DDC6652E4CC57EBB68B9648BF4 -:10E74000BE239E487EADB2DB74FADE15E4D72AFB09 -:10E7500088F6F2CB60F6BC097EFDB206D90D78B121 -:10E76000B2B813C6F7AEAB65F7D9F637B0B8BA751D -:10E77000D3991C11E39E7FC989F2E2BCF87D29DEA2 -:10E780006FD2A7A0BFFF9B74E0B39B6CFEC7EC1ACF -:10E790007EB9AE618485BFAFAC933FF4C705F71B6C -:10E7A000D0C726819E34648DD21BE9FE29684FE6CE -:10E7B0008587597A039EFA3F8077482F1DFE3C13C8 -:10E7C000F64FF8EB843F4F8C23FC7D92E47F463B71 -:10E7D0007E7B7F9EDE0F253BCC18879B23B3385C66 -:10E7E0008D9C25B08F2B411FA478B6F28815E1B11E -:10E7F000F25B466F749E2FC0388DF66CC41F214F9C -:10E80000E93C07BF4BA2F3AC30B4666ADF21D5CC3C -:10E81000B3FECAF38C8953E5F392ED0ACEB785585F -:10E820003D30AF7AA3E7B01FE4EC792BDAED5ABCA8 -:10E830003758E03DD916728305DE99DD6EF337C295 -:10E84000FECB3D5A1DA067EF6F18D61FE69BC8AFE1 -:10E85000DA6CCB7B03E645D7F716F20957F8D2F30B -:10E86000EEE8FAAEE08F7D0FDA7D8FF51FFE3EEB0E -:10E87000AF80DF8FC10CDDA84F499CEFC6E295D475 -:10E88000B0F76B880FA2F4837199814C125C49E157 -:10E89000543588E117994BF8EFC7D1E3C1269BEFB8 -:10E8A00034AC57D0DD15E0D30CF37EDCE63B0FF53E -:10E8B000611E70CF83F299562EAF5E341AA27A543D -:10E8C0004A0AE357ADC904E36762FDDD76FB94AF06 -:10E8D000A05D7A3FBFE41AF8BDF09C38AE08BF10C7 -:10E8E000C63D887BA665E09785F8AD3AB559FF7BB4 -:10E8F00074F470D86EF359A1DF401E7B2F0EF06ABE -:10E9000025B9223C1C0E84873FD941E1615729BEBD -:10E910000050726665009C5BCC2C1E60E772068717 -:10E920009677181C761D37201E3F410620DD0D35D9 -:10E930005CBC1BFAA7FCA31BF433A6B55682F36F8D -:10E94000E712B701F86CB7568F6CB832DEF6743048 -:10E95000BCEDE560FB703FECC3B0B7995DE60A78AB -:10E960007B0D8CF73DE07EBD63C4D5F3178A57C39A -:10E970001C1ABCBADAB82889DF8F8CED8F9E87D03D -:10E980004FB0779709F951F94E761FB47CCF293CE7 -:10E990007797BF6A42A42C78D5C2EE35D4B1F2F392 -:10E9A000B9F1FDF9631CEC9C55567B9F472F77030B -:10E9B000F8FD97DE8BAE3E72D43F9A3281DD13585C -:10E9C0006911F1A0CC4FEAE07896D2C3E705B9927D -:10E9D0005248F0BE80C3C6E206DBDF0760749BC608 -:10E9E000DBB95C6E09E01D7B3F200DDE8B667E6E21 -:10E9F000C417D960F580DC4F298AA9672B423F6A8A -:10EA00005ACC7D82390EEE4735920CE023B596F84C -:10EA1000F7805A1D42AFB3E2B94EE1F36AB41BD995 -:10EA20003B2E7633AE7B71324929C6BC82F23CB6AE -:10EA30001F91267B0DBA7B26294556DD3B0A69BE10 -:10EA40004EBA7CE7195D75F5BBF87BE9CABB950C3E -:10EA5000D095F7A81CAACBF75C7A83AE7E16453812 -:10EA60006DBEF79A5B74F5FB564FD1E5AF5D7FA79E -:10EA7000AE7EFFE06C5DF975DB4A75E5836A17EBE6 -:10EA8000F2D7D73FA8AB2F27D0B35F72B0F38E2C4D -:10EA9000F46CFB703FDE2BB29B2593E63C57CDF721 -:10EAA00023D7519401FEC755F6711970DE6C4CCE18 -:10EAB0007686E3F42BD27FF41CF6BC436F3FCBE3A6 -:10EAC000F6B3F3FB281781DF57B19FE201FE7E26E4 -:10EAD000FFF30E6E0F98E586FAFCDD0AC583EB980E -:10EAE000EE30A35D2CB6FF6A873BEEF94936785CC1 -:10EAF000C552627809BCEC085E2FF3F9FFB3F03A17 -:10EB00001413F723CE6FB1EDCE390C5CBFF637018D -:10EB10007F6B3BA79156D987E7B4CFCF0708F05357 -:10EB2000827A4B223D408C2F49BE4FA09F587EEAEF -:10EB30005B3A8F9D330D5EBC8F95E8FC76CE117BE2 -:10EB40007E2B9C81FB916CD4C1E9D3363AF7EACE97 -:10EB50006FAB92B3F1FCB64AF5665CCDF9ED5307A5 -:10EB600032270A77373BC78AFD347ADCEC1EA75E72 -:10EB70007F69AF6F53F947D7B90EF43809F4B2146F -:10EB8000A67FEF64F7FDC5B857A16F13E755E8DB23 -:10EB900026E259A3C8B85F4627AC7F5EF87E8BFC9F -:10EBA0000FE9D74EE7F7907FEFAB1E8CEF7F7F82A8 -:10EBB0004CE0DD954B4523F19E74227CFC90DB5F9D -:10EBC000DE7532F87664BF787F59C915EF57BC3FC0 -:10EBD0009EC5514E89795F778493D1CB2427C7078F -:10EBE00013B3439C7BD98EF1F0E76EF9087F2FD2E7 -:10EBF000B9BA61C303F87BC03C4B206E2660B3A357 -:10EC00007D6FCAF811C397DB3578C47FDF58FE2BC0 -:10EC1000EF38C07E336547EFB4802D31FE4CE2EB18 -:10EC2000234AF81A8C977EED0CFE3E9A29BBFAA671 -:10EC300031FBA23ECE2CD6EE33656939E29BC897F4 -:10EC40004508C695B5E515769FB82CA2601C5A17E5 -:10EC5000279783DC2E94105E5709CFD8EF029EEFE2 -:10EC60008F3FC3EEC55BE2EB1B3F71EAFD16B1F7C8 -:10EC70005212DDB798CDF7E952D128BC5F3FC5E805 -:10EC8000EE7B35762A01A7A6CBA792802FEC81FBDD -:10EC90002E71FAFF9193F1B33DDE13296096CE35C4 -:10ECA000B7E603FEE7723B789C78FC0AA0BBB19103 -:10ECB000A21F241E7FA993DBED78BC7B81D3CDFD01 -:10ECC00092FA78FC8EEE134D36C6976FD3A2F0FB06 -:10ECD00008E8F5FE8D2AC6EDCDA7730880FD6D937B -:10ECE0008AF6B70F2E9B08F8414E6D509F8138B3BE -:10ECF000928DBD373E4EF325E34DE8B799BF89BDF0 -:10ED00003342C65B82E07F2DD9F4403ABC1BFE192A -:10ED1000A5DB4554699ABFF1098C7BF9E0F823180B -:10ED20005F7D06E8997E2FF9F667D301FEBB8CD58F -:10ED3000D70DA1E9A2ED92EE7E44698D459717F1BA -:10ED40007B62FF8814BD37E1A6726433DF2F21AFE9 -:10ED50008745FD5D9B9DCCDE8171F0E513D8FDA854 -:10ED6000FD27D9F9FD401F16DF171A7F7BF110BA76 -:10ED70008EF169EC7D96D8784002CE31783F85C718 -:10ED8000EB8EFF4469BBC7C2CABDB642CDFD80D77A -:10ED90009755E2BE8CFF35B39B8CCF6271ED09E3D2 -:10EDA0000433DAC5F9F703B9D92E3E307A7FE76824 -:10EDB0003CBCF9430C5DEF3FC9E201E7BDCDDEC7C6 -:10EDC000EA886F7EC8E7FDC1F101773D4FE1F1416F -:10EDD00011E3E21F5CBE7935BE3FE39308C4659E34 -:10EDE000BA1CFF9E58B253E84DFEB6FB34B03F53F9 -:10EDF0008B16B4E5812C6FF3DDA7BB6F73F5FCE6D2 -:10EE0000CAFC64A593F91162F97B2CDEFF9FE2EF47 -:10EE100053C61FC884FBF734FD1DDEC3DFC1F86392 -:10EE20002C9DC7F27331AFD8F996450CBAB8E16999 -:10EE3000C0074668F9B911F93C55EFD9BB30D94A3A -:10EE400070A5847A80E4A270186E0BA6E4D221FE2D -:10EE500007B1ADBCC8008000000000001F8B080097 -:10EE600000000000000BDD7D797C54D5F5F87DF3C2 -:10EE7000DE2C496692C96412929084093B15718018 -:10EE8000B008A82F04421482032AA2069D84256C90 -:10EE90002191AAC54A9B810444441AEA8614ED4094 -:10EEA00041F95AF41B116B6C834E04115C6345C528 -:10EEB0007E15C3229B2811AC1FEAC6F79C73EFCDC9 -:10EEC000CC9B4C58FCFAFBE7173FEDE5BEBB9FFD22 -:10EED0009CBB4CAD737D82BF2F632929EC369F9D6F -:10EEE000B1B3F87755383D611F69760E62ECD138C1 -:10EEF000BFCD990AF5DECC1CC912191BF856BDE22C -:10EF000087FA271536B93E46BB1FE34C8C41BB2D13 -:10EF1000665EBE05EBF50D97A739F37F8C83FEB6D1 -:10EF2000DA20857A8CD99C877A3396C74C2C496530 -:10EF3000AC58F1A7E17815B69695A5503A6FF7B79A -:10EF40001628620F5BFCE95A1E63814C8B77636E57 -:10EF5000FB713D4EA804EDD2168C6407073266B5EE -:10EF6000B140DC00C6148D05CC03701CFF2213B425 -:10EF7000D72633B65C61AC19E686F559EF74134BAE -:10EF800063ECD736467F81910C27C30207E28335B5 -:10EF900030CE8F4CEF8970F889E9BD705E9F30BD2F -:10EFA00037A672DC5AB14ECDC4FCCFC58047A953F9 -:10EFB000E1E3305F4F9F83B1E923993F121E321D79 -:10EFC000E7D4A85EFE2337E5B440F9E7FB6FCE61D6 -:10EFD00090EE787848524B8CFA32FD437595771451 -:10EFE00034BDBFDA4F6912633ACEE781EA99DE5148 -:10EFF000DD1973421EE735DDE2EB991CD1CF65CEFA -:10F0000064C253E2E55B9ABBBA193BB442752A1E4F -:10F010004899A908DB1F0C26156DEDCBDBB90DED6A -:10F02000F83C55A633D60DD66DD7BE6B11B03BCB91 -:10F0300070BD8CFAED689DA5024F16E6B5617BCBDD -:10F04000816B6CAC2BF4A7E84ECC4B7AB81C4640D5 -:10F050007AB8173F5D0E74A7F86F71523B3D459625 -:10F060009FCDC5F18B282FC767592EC6323A861718 -:10F0700053743FF67394E9A598365802973861BDEA -:10F080000DF16C662C7A2E17F8EB21D6C598DD7938 -:10F09000F812311ECC6F63823E1BFB3969F3CDC57C -:10F0A000F4CACEAD352AD24D9C53D46F61887728EF -:10F0B000BF1DCB597A0BBB16E07D254C763964FF1A -:10F0C00071F400F3009C125B0F310F8C9F88F88B5A -:10F0D00001376B32E7ABBF3356149BEF142A5F281E -:10F0E000E6B901F8C5E40EF3CB53D0EEB9BEC8774C -:10F0F0007EC177FA350CCA37FCD1A52C87F2AEBA9F -:10F10000C784F4E16E667A10E121E02EFBDFEBB4F8 -:10F11000101C900F9573F0E1AA8BE4C30D7F1C6760 -:10F120008AC379FE96797B78B0DCB3D806F927E6F6 -:10F130003BBDCB21DF6D05101AD4CF5E10BF5E85BD -:10F14000FA6B9D7C9D5D1E628BE3A076EEDA560D18 -:10F15000E5C3B885CD9A0DEAE7D6B668289F5EFA72 -:10F16000ED9A1CA4AB639F5FA33AB0FFAF65FF00AD -:10F1700020E0F7E14E8E4336B4B40BE267B393C39D -:10F1800057AEE38FF1FEA7089F55AD0556A896B37D -:10F190008069282F8F29FE3FA774C37EE32707FBD2 -:10F1A000227A39BDBD74F8789F32C8BF24F95D1941 -:10F1B00099C9D2191BB1C14CF01CB1E1E15B11DE60 -:10F1C00023368CD114A8F2841652345C6795AE05B0 -:10F1D00020FFA6D34CE31FFB7C761705E7FBB19518 -:10F1E000F58801DF9D62FD9B9D5C7EFDC3129B6ED9 -:10F1F0005F6D933B9C9F863345CAD757857C4DEC0A -:10F2000006F09877F72992AF7F717AA8DF27B4FAD2 -:10F210009D99342FE60DC0A7D99BDE23792FC79186 -:10F22000F5E66C5EB714EB65DDE1ECAF7AB05D4BF3 -:10F230001CD2CFB7711C5FDFDE1D1F5CA410FDF771 -:10F24000F75D1A830F59C86A4A270CD878AADB4C95 -:10F250004301AFADADF928F7A0CBC5C89785C91E4E -:10F26000035ED6B53AE3915FCEA70F0E087C5E2809 -:10F270001D6E4FE67C03F25F473C05066BC11AF832 -:10F28000BECEEE3F8AF23FCF1E4CC9872AB5E7D7E4 -:10F290009B2710BEA0374FFE2CBD29F4A5D49F6D2F -:10F2A000E5029F35427FC6D09B3FC6D29B6E16BCFF -:10F2B000BF1FAC879D307937B2F6E32E14FD9E8CCC -:10F2C000D7D564187F84C27C386EE289034C89905C -:10F2D00043F3045F6F1174F0948BDD3621C63A66F8 -:10F2E00009FA3495B45A5AB09F4685E8BFFD7AB9F9 -:10F2F0003C01B998928C7CD605E4A6D25E6EC6C05D -:10F300004726CEB3F35BFA76249261C91B1200FD47 -:10F31000E7C2474E32E143EF82A984FF80B3EA6D32 -:10F32000BEBEEDE1DF3399CF7F9843EF81F54F0B00 -:10F330003EEB082F8392393E0A93B93DB3C521EACB -:10F34000C519EBDD96CCE13C35D9C89711F81B9473 -:10F350001C037F520E9F8CF70DC575FFFDE89604C8 -:10F36000A4238927297FA2F115E6B345B41E807333 -:10F370003EB68FD63FB27DB41E0AB70FD07CD721E0 -:10F380001D21BF211D79B89E58D7373C3F49E7253D -:10F39000627D67E3F5625C4FF43C9D274CCAB9E699 -:10F3A00099DCEA5690FF937527A5FF386A52705E84 -:10F3B000CE564DC17939857E8CD683202E04DDF062 -:10F3C0007EB6A3DC80F1977E39351DF1BC34DF9F1A -:10F3D0005E05F5AF71E8FE64E223BD14E131C5A11D -:10F3E0009761FA631CC7F3A0647D1AE693851D1527 -:10F3F0003DCFB9627D00CF39D84FE22816407D78E5 -:10F40000D5197B10442C8000E60DFA2151778E44EB -:10F410003D96B89679914E53125A9BAC906F7D9859 -:10F4200079D743BE67C063B2A27EBB435F8CE9D28B -:10F430002F55B23B97E6B3E062EA87DBA1ACB66B2F -:10F4400090F437F05B24BDFE5ECCE3F7C99C2FC17E -:10F450000EB92799E3F977984A3B44F2514776452C -:10F46000041FD652BB0BE7C3FB71FD17C1877F4852 -:10F47000267F42AFA3799E870F1F0DF3E12358FF2C -:10F480007C7CF8A4E0C3ED22ED880F5F13707B3322 -:10F49000B943FFE3C9587CE816F420E91DF910F5DB -:10F4A0007DA39827C8CFBFC6A2F70BE0CBADB1F8BC -:10F4B000329A1FDBFABB40FAEFC8FE1BE23AB7FDF7 -:10F4C000D76CE77897FC0CFCB253F0CBEB825F76FD -:10F4D000717EE17A399ABFDAF44D2B97138CD525DA -:10F4E00020FDC879EE97FC13AFBF17C967D24F91C3 -:10F4F000F093F5FF23E8FBA848135B0F30940B0053 -:10F50000B77F45EA8DA704BF048632E217F0B746FD -:10F51000A25DF9D209B0232167777179306275F362 -:10F52000766475A6D5254C74740CA72B5D1E01CF8F -:10F53000D87082F1BF8885B746C49BBDBD3D1F8D85 -:10F54000AFBD623D761787C7CF9D87841FCEE3325C -:10F550009A87C7B43C42CF2B2E45D21973417AD536 -:10F56000A85695D1BC4209E042B5C9539605EDF3C2 -:10F57000DAB7B785DBDB5C30CFAB7468DF37DC1E16 -:10F58000C62779D7ED0E90676427EB26D44F4B73CF -:10F59000393D44D3FD06B41FFA46E0AB2E93F0B5D7 -:10F5A000D2E64FC3F96DD03C26B4EB362C732A015A -:10F5B000C263553CD28FCDAE135FC7904359AE8B1B -:10F5C000B3073C2E2E87725D1720877A0BFC801CB8 -:10F5D000EA85F5EDE791434304BC86BACE6D0F0C86 -:10F5E00013FD5E29EAC790434370BC6839B4D5C6A1 -:10F5F000E110834F8763FD34A73E02F1047C7A85D6 -:10F600002B42AF41BBAB30BF52B45F5167EA4DF6FE -:10F61000338BF7C6F233C6B9EC063BE50AE13FB0DF -:10F62000C6EFFFF6DBC18C5562119FE738314FF210 -:10F630002736D41D4843FCC39F21AEF2E062EFBBE6 -:10F64000DD116FEFA80CEDD0077FDF62417837C482 -:10F6500027F6639785C7ADFC0E083205F0F29D8949 -:10F660005289C7798D8B0632F023F20FFE90837694 -:10F67000E5C9FDDF517CE484BDAC04C7DFB18DC7B3 -:10F68000494EBF353505ED7339FE7CC417CC6BB4DC -:10F69000DAB73E04EB3DB5CBE2457DAB32CFA323D9 -:10F6A000603E95BBCC2C48728AD9B0BE994F9799D1 -:10F6B000772D6D561331AF05447C43394BFE8C27B3 -:10F6C00009E9D6BC4B65C887CCCDCB03CCB6E82CBA -:10F6D000F89B49434DCC13110F49D6E39927223E9D -:10F6E0009152E432E4537D9986FA9D2677359467EA -:10F6F000F87F6528EF3C7380219F5D35CC50BF0BB0 -:10F70000F83B91F9DCC03586FADD964D34E47BD4C4 -:10F71000DD6CA8DF6B7599A1BC4F70B6A1BC7CF7FE -:10F72000F316F4AB2FD934DFF0FDD2FADF1ADA0189 -:10F73000409ABB039D4C631CFE97352C36D49FD654 -:10F74000327B1CD26DFFD07263BB3AF3210ECF0027 -:10F7500043781E617E0BD299C65A777606B8CF0BD6 -:10F760002ADE10549BD590DB0DF9E18B378A762980 -:10F77000FD605EAB793BD9CFACA0313F47DD4CFC9F -:10F78000138DE74AD635C9938774A0B2A012C6FB81 -:10F790009C4DC6F60CE35DD06E8E584F345D1C61F7 -:10F7A000558F8C40FA08E8CDDDD3C2EB36B3FAC1F1 -:10F7B00021FC2EE8C429E844AE5FCE5FAEDB09FF32 -:10F7C0006139287C0BD2D98C0685AD51DAAF6F66D2 -:10F7D000E3AAA59D63AC93B1A005FDEDE8F9875CB4 -:10F7E0000E37C5AD72580EC6AD583BFEB0933C3EC9 -:10F7F000B5560D5A81AED540EF28FE30AE3F1A8E79 -:10F8000017CB2F1E01076BBA915FE23CF1D1F436A2 -:10F8100038C4DAC335A1B7918F241C255C1DDECC1A -:10F820009874E581FF387C75F64BC2F704C2372126 -:10F830000CDF9336FF4994C3A7F77EA312DDF95B73 -:10F8400006A21EEB482F391C234FA31C83FA3958FC -:10F85000BF3201E46212F473E0879EC86FB29E6FFC -:10F8600041997714C84545F1FFE08A888B34EBAAAB -:10F87000230FF035A741F5A21E3EA9D9972997D1AC -:10F88000323DCE3454D2126F1C8F126F4AE3F6FF12 -:10F8900028002F68E3B760FCB5C86BC3798227479F -:10F8A000714E05DC9BB309A467E353283EA2338A5B -:10F8B000FF9D62DE1AE8AFC6F1B74BCE130F494C7D -:10F8C00021FFC29F118FF6436BCBE967B17BADD9A6 -:10F8D00089E34CF0FB693D43708260573327C029B0 -:10F8E000225E04EDD2B1FD84C7FF9880F6F04B870D -:10F8F0004EA9A45F3E71933D2CED83F6F67580F41E -:10F9000097B4D7C13FEA92C2ED985CECAFCD3F12FD -:10F9100076B5F4733AEA07EC8EDE68CF74942AAFBA -:10F92000AAA44F5B9578EFFA18FA342F4589A94FAE -:10F93000417FE6A5A446C4E3EE3CBD13E51DC07BB4 -:10F94000087E7738C0AE512EC8AE198EF51F4D48CF -:10F9500024BA6EDDAD067B418353364F920BE03601 -:10F9600052E85945031DE20AB7ABB2B9FA6A03B1CE -:10F97000BC4F128BE1A7C87424D64B89882FC619B7 -:10F98000FDD1A503F8BC8A53B83D739FB09F4AC50B -:10F99000BA2B310E97128EC3554EE671E687A3E25D -:10F9A00097A5290EAABFC43EB214D7B3345721BBC2 -:10F9B00069A9A218F6919253F2A9FC16D17F29F4F5 -:10F9C0008DE33DD595CFCB1DE5BF678BFAD929BC1B -:10F9D0005FE0A43E886F8BAAC684E78C143E7F69E3 -:10F9E0003F49BE192BF8A650C8CBAB7B80BC24E6A0 -:10F9F000D2C78D86F251A29CA96BF758A17C6C2FBF -:10FA000033433A1B857209E5BCD37CA0A57758CE59 -:10FA100017F6AEDA81E2614C3A7C8F902745CCD75D -:10FA200019E9E06A8FF1FBD83D85C7905FC7328D39 -:10FA3000FAA1EFB91CAE09AE30BDFF3EA54D1E794F -:10FA4000CE025F87E2FD0F1663FCE16DD5BB9EB56C -:10FA50005FEFFD026F2B849F82FB48E87FB844DA9A -:10FA6000BE3E87CF6B76DFFD044F0DE0097C1BB2F5 -:10FA7000B4D424E1381F301A2773A6DE84F9413E3E -:10FA80000FC338F1D25C66F7227DF637511CC4ED06 -:10FA9000778EB240DEBD963C1566D658C031202C1C -:10FAA000179E4EC925F8AF60354D49503F69EDD7D7 -:10FAB000AC2BF90FCE514E9443D358CCB8E646B197 -:10FAC0009E098F77D5D00F4BB2297A30C63A368A45 -:10FAD00075805CD880F2E12ADBFE814AD7B05C41B8 -:10FAE0005796FEEF9029B85169DFDE662F781AD756 -:10FAF0003F6826EB20CEC9E731DDE6ABA77A7B3C39 -:10FB0000B43F512EE5F33413D3806E6E126473D379 -:10FB1000DAA6FF903DF0C3D9B3AAB4B319F5CF70FC -:10FB2000BFA07CAE2388FB07E58DB9018A0FCD54B9 -:10FB3000685FA3B2F13D1FE6CBF3F29C24D7121409 -:10FB4000E5706F32D11997631A3B2CE945158B820A -:10FB5000FE270BBD20FD79D0032B1200FEE56BD7ED -:10FB600035654095FF01858F78DBABFAF7DE03FD45 -:10FB7000DE00CA69C1004C35564271F474EAE77A76 -:10FB8000D14FE03BA61CB685C7BDA17137AD67AFAD -:10FB900099056C404CE6917C68F36F93687F15F48F -:10FBA000298D3BC956371AF5DC494B6B3F2FFAD7E5 -:10FBB000DB3ECA0E003D7DFABBD30E0678F84C6BD7 -:10FBC00075E0F7A30BDF77E800BF4F17AA4588CF92 -:10FBD0005B85DE90F03E22F07EB9DBB70FE17D5B06 -:10FBE000F58F83FD91719205A924EF670561861158 -:10FBF000F6C39C4D0968D1B4E52BEA530C79A907EB -:10FC00002AACAC2A565CB0B39BFBF3B336AFB374EB -:10FC1000F6E0F8FE561CFF28C85BC4CBD1AD8E20A1 -:10FC2000FAB3723E659BFB5BD0BEF8ACD1CA42E82A -:10FC3000AF68CD6666E77244017AF00BBC47CF73BC -:10FC4000E7CB09D4DFF487B9DC2985B116005CFD68 -:10FC50008DB348BE44AF63FAA79EC24E00EFE9F7EA -:10FC60008126F7F0FA0B016FFE05F77E8DF65AF448 -:10FC70003A4B034679337599312FE560B9C037B0F7 -:10FC8000DF32B47BA7D719EB9537DE4FFD97A39CE6 -:10FC900092DF61FDC96E61870E6643502ED5D8BBD9 -:10FCA00026F9CFA1774E548381DA93B1E3D5364A52 -:10FCB0008F56334AF7A5707A9DDBF8DE5D4837F33F -:10FCC0001A9EB3603FB5C1D1CE6150C5DA081C851C -:10FCD000F625EE1743D329B85F0CF3ACC18964E075 -:10FCE0007EB2AF9B1BDA9B9D51FBC7627D2502FE56 -:10FCF000CCEE22FA2AC1F5F4C3EFDA3791EB39B52D -:10FD00006BA00DC7EDEB16F27608AC4BBDF075C9D4 -:10FD1000F5C8F5C9F20A15E82C467B49DFFB84DCFF -:10FD20009AB661C2D24C0045CDB623E41733619731 -:10FD30006B023F9A7D39D9E51A03BB9BAF53D8E5D7 -:10FD40006C0FF2ADA4B3683A2A473820133B793BD5 -:10FD50009BB0D7DBE8A7F1018287C433F0473ADFD5 -:10FD6000C70BA5E33E1ED0D1A1283A32E4A7D7198C -:10FD7000F35F995B7290BF815E0E45C2F7ABA8F34B -:10FD800023321DEEEE4AFC36CDA3173AA17C3AF39E -:10FD90002D75D2FAEB082E47B5BA9DF720DF6DE03E -:10FDA00074FF99C07B83DB57EA267DA5F7437D3539 -:10FDB000727186EA867AA52B1427F2D3D4DAFE85EF -:10FDC000C88703984EFD4DE9C0DEAA7173F89755B8 -:10FDD0009999059465198C8172AD6CAB1AE4712BFD -:10FDE000DD5E0C789829F05071DF73960C486756E9 -:10FDF00095733B20C8F905E04A76C0EC154DE457F1 -:10FE0000835F1193DFA41EA8A8379657B215848785 -:10FE1000CA287BE0F792CFBCCC8BF4E8BFCB615310 -:10FE200092CEBF5ED63E6E42719553BB7A907D787E -:10FE3000CAE3E984F5FC89FC0C8DA2F987E07780A0 -:10FE400013E9A3D6450941B47FF79F01BF0E6D3278 -:10FE5000A77F8805E0D2F2AF6CDA6795F429D75313 -:10FE6000695B41F459C98C7E63293828180F2DDD50 -:10FE70009812C4FD71E8BF5F03DA151BCD64370427 -:10FE8000D8FC740674E65B62267958D6904C7E6B7B -:10FE9000592DDF4729DB9C1C54B93FBE07E31012E4 -:10FEA0000FFB6B0B2C1984A75C2FEA35D66036D07C -:10FEB000B7C44FB4DF377B59D3CE744FC7718108B5 -:10FEC000FC1CEA003F8722F1B3250A3F6C610A97C8 -:10FED00033B7BFD603F78D4E55C579D5187E84D478 -:10FEE000432C0B08707038BE569429CE3469DE342A -:10FEF000C4E7E91583085FD1782AFA692AE183FD0E -:10FF0000CBC130EE3AA51BBB6D227CBF4DE1FC316D -:10FF1000A5E6EA22D4D76FBAB99C7917E4936E614B -:10FF2000EC3D904F3AC8A7F7416E61FE83EA74CA70 -:10FF30007F54EDA1F4E3EADE941E12F6BCE41B202C -:10FF4000000BDA51EF09FDF89E5BFA4177A4A3E9B3 -:10FF500050F4D3FB834C406BA98159D78CCE66EC0F -:10FF60005ADDA8EF265F6FD4672D6667613ADA7DA8 -:10FF7000F729B4BF50E61B6EA8CF348F6502FAAFE5 -:10FF8000BD0786BF933DE7B14C047EBF695C8AA183 -:10FF9000FEA4659D0DF9636E0FB71B8BBA19BEDF0A -:10FFA0005C7289215F7A06803010A9D94578B8C380 -:10FFB000C6847FEDE2714F71BEE49BAA219D7E0352 -:10FFC000F3FDE62D339547E343E275DA6A13F3C395 -:10FFD000D4A6AE86B541BF87EA004FD0EE8BBD0EEA -:10FFE0008674BC74F3C07786427EFF6633C52FF7F4 -:10FFF000D7A6AC44FB68FFE6D4448C8BFA97AAC220 -:020000021000EC -:100000008E705A5884BC2AA85D44E74E4A83562F06 -:10001000D90B3B024FC8BC4741BE679C5FF6A84165 -:100020008C5301FEB87FFFB495E2F247C16E738234 -:100030005E38AAB05A4C51B12441F9BF9B5383C8D2 -:10004000CF453FA97A3AD2D3D37162DF45A1FE8E64 -:10005000BFD763FD72A22F4F7D88F8D64AFEC0D469 -:1000600016BE3EA60CE88CF83F9ACCF4649844C5C2 -:10007000FC8FF66980A7593D9BFB85A05D496E28E2 -:10008000F5466877628399CEA160BF4EC857FCD50C -:10009000BA8ECB11BDD3844B23E119EC87EB9E6262 -:1000A000F265A7027D1D9F11EC47F26C612AF155A4 -:1000B00034DC0F59FC04DF00F28112968F613EE3BD -:1000C000FB6920D43250CE4C357BD3503F1D5A6152 -:1000D00026BB13F447228E0F9C4C747C48F314E229 -:1000E000BA0F2DCB6528AFE4B8652B54F23B90FED8 -:1000F000A8FE2AD50F3602937A2AB04CF1B34EED02 -:10010000E9E6D7B70FE984EB89B66F65FA15F0AA6F -:100110003FC25E98BD4DF5A1FFC1F25AB4EB2F8DE1 -:100120005C472DDF5F48E7FDDF21E4FADCAEAFEF8F -:10013000B39B50AE774B42BFE2D81E95E8EC58D740 -:10014000BAC1E9DDF0B8C8AB837F03F92F8A038712 -:1001500035C83F61F55F930AFDCC31ADC841FFE87A -:1001600064E3C195C3A1DDF167CC5E1C76F6D3B321 -:10017000BA50DC5DD8D7EDE55628539CF3C9500042 -:100180009E733CF5A4B73D9B61105A7F90FB49429A -:100190008F3B1F52D096620707399663DC622AB004 -:1001A00047A4DD7DD0CCED8292542EA7A47E5F23A0 -:1001B000F2534D9CAED9CB0AF96DF067D003522EA5 -:1001C000CF49ED4AF5DBF432AB27793503CFB1C027 -:1001D000FAE66EB20683B9D4C6897C3E8BA3873D0E -:1001E00095EA213936DBF2CC23C843E5AC99E67DAC -:1001F000DC1C9CD19C8BEDD7D5BAA8BDD94BF15353 -:10020000A14F6CC040288FCA05DF55D429C110F119 -:100210000DD78BD345FF0CF54C84FC6AAF578CFA95 -:1002200064BAD0A3D35954FCB5CEA8DF7C09DCA9AD -:100230009D0DE3A2BE0CCF0BEC6380D90C7F70E761 -:10024000789AB7E20DC69847396B0DA938EFCD3CC7 -:100250000E1F3DAFE8755CE83C6778278C4ACE8B73 -:1002600018376ADE12DE14C08DC08384FB8C0087D1 -:10027000E78C4685F0F5B9B0CBE08FE2C612EFE52A -:10028000CC371ECFD7953F04F232374C076D7AFF3B -:10029000B920ED377CC1EA12ED40F773573F37E9DB -:1002A000726CB7F63DF22F4A5CA11EA664C65202DC -:1002B0007B96175D11639F21CA3EF8A5E083B3D7F3 -:1002C000068B76008FE91B543DAE9FA11EB597F6B5 -:1002D000C1CC40C08271C99922DE77BE795662BD19 -:1002E000011732DFD8F6CCFF75DE7B5285FFD4CE06 -:1002F0001EEA11D38F6AB383CEA37F3F3187B251F9 -:10030000FFB6666BA47FBED1BC1FE5BB511FF720B3 -:10031000BFA023F93A43E8E1E9A897213DBCFAF9E7 -:1003200044F4DB3F7FE879DADFB43C333D11EDE2A2 -:10033000C3ABA7AE0C004B1DDE3C95F470F91AA9B7 -:1003400087FD9648FD5EB0BAF4CFBF43FADC144790 -:10035000F1F9193BFCC2EE0679877270359777EC9C -:10036000212E0FCB515FF5257DD50BEBDD35C3DF9E -:100370000BE93CE23BE9B1BBA6FA87507BE60CA156 -:10038000DF05923384FA4AEA53A9673593DF9486EE -:100390007A407DEB83BB61FD5F6E51C9BDAB50D729 -:1003A000E53831EEDF81DCFEF9F036B5C13BF7020E -:1003B000E05D86F026FB87C3FBC0320EE7832B3857 -:1003C000DC976EEE9688FEED8165DDC8EE39B0B93A -:1003D00007C17BDA728037D9BD1EA3DDB30CE08D77 -:1003E000763EC21BC62DDBE111F0F672782F137A30 -:1003F00067054FA7B5836BE056942777FDC5EA459F -:100400007D7E342E948AFEC8D1E75486E70EDAEC5E -:100410002261BF4838FF9BD53D8176543B7B669572 -:100420009561BC72D60B8E2083FC7125BF1322E030 -:1004300044DDEB89385E78FC363B66705AA41D7348 -:1004400081F899C77C742E7F5EE3EB7BD18E577465 -:10045000EED7CFB3D943C8B7E0EF9C8894E78A07BB -:10046000651AC649BC361BD24116F3F8C8AE91FBDB -:100470003F7E86FB3FDFF6F8FAD6F9C4CFAD3D23C9 -:10048000F7492AE343668C2FB53EA710BE2BEEC872 -:100490004FCC67B8BF5445F3B82E8DEB6345D729D1 -:1004A0006E6805BA8987F126A579F8778F93C71109 -:1004B000D7C2B88EF07CA3BF8F47D2437D6E8F1D0D -:1004C00087AD15E354A826F23BE65AB8FF21CF7753 -:1004D0004C15E553D3B8DF3E2B8D9F9F3889F17DB6 -:1004E000E8F7E4AA04715E7914C533DBE227126EE3 -:1004F0004EEDAB3679857C25E207FBB00DCC739AC7 -:1005000055C47341C562FB5B44FB5BEADEA6FD3567 -:10051000F05C1E47BD3B6581D58BF66B609B95E813 -:10052000EEDE78BE1FC2DC491AF2D1CD42CEDE52D9 -:1005300077BF0FF731A7D425E898C2380126E2A784 -:1005400079B89F9A69A1F86989ADE51974B36F4BC1 -:100550003F78A70D96B6C8C4ED96452E46E7632EA4 -:1005600003B31DE3B17874E46CCAB9E8C7181F9EE1 -:100570008B71DA618C13D65082AB210FF0A5FC9AF7 -:10058000B4D1631FCA62EC9FCC7329E27B2EC206F2 -:10059000E9A13489E200D762BCD885A946743651F6 -:1005A0006301134F9761684DC68FC78B75DF309419 -:1005B000859260BDA1DDCC10BFBE31640AF5023C5E -:1005C0005CAB859A90AE4D368F19FD015F9132007C -:1005D000FDE4B98B2F6CBECFA4F968BE734DFC50FF -:1005E0005FEBDD4A703DC0E9166072A4CF5B35B6A3 -:1005F000431DC0F187F457E9F204A8DEED9CBE6507 -:10060000DC5CE2A93F741F09DF5BC4FCA09F658925 -:10061000D8DE123B7EF4529AF483B9BD3947F0EB31 -:100620001C496F9B8D7CFA31F20BD457D0AE05B8C4 -:10063000DD22D28EE8FD43D1FF8769DCEFDE7191C8 -:10064000E355585988D6BDCD4A7894E35E2BD23D08 -:10065000693CFE26E721E999893894092407D2D11B -:10066000A1BA1AB29B6646C5815964BC4A8D956F82 -:10067000933FA6B3985A5AA7E17C942BE3BC48D782 -:10068000B758EA7B54D9DBD793FBB125ACD9CCEF73 -:1006900013897896D057A3557B6FF4774A94782FB7 -:1006A000DABF27F31D015312C65BCC84DA12A00710 -:1006B00094CF9FC4F1FDF72949778D47BBB024D172 -:1006C000A2617A1B6B76E4E686ED92A5F930D94CEF -:1006D000A4B2C0581DF235284F78FE7E3D8BA24350 -:1006E00022BFE44DDCB7B8FE07C03FE5978ED54189 -:1006F0005E9C7C4D94B37BA9FDC925828E03F78F48 -:10070000C5FA271F96E575BCFC3E59FE10CF3F2069 -:10071000FB17F95551E58BA2CA1FE379CBA30F8DC7 -:100720000DA03D2BF6634A8629244F0A059D952C82 -:100730000E117C4B4CAFF274240BE17D89F3D51B79 -:10074000D0C957887A4B751C72A0DEBE3C432F443B -:10075000BB6340AA3FB913A4B32728010BCAC93D04 -:10076000C19E42AEC73C675D28E8F6B274DE9F8446 -:1007700037F493D929F5E2FB7919E735C8D04FB79B -:100780009FD3CFF2F6F3E9FB73FA3919D58FB48B07 -:10079000EECDD4C7209CD821B7E1FCDC9CDF7B9355 -:1007A000D0AE62787E0E403F67717DCE40E87FCE4E -:1007B000B32FE5CC88F0BBE79D31311DECA7CA33E0 -:1007C0008CD22F9A3EB678603EF3B636590AA15EB7 -:1007D00025A40511F39A2BCF8FB2166D62845E1F8C -:1007E000D7C924CE25AEA2F9CE79F618ED5BCE316D -:1007F000D51F5E83F19E613CFE16BDBE3CD16E1FCF -:10080000EE23C7B0DB2776E27AF8AE2C7D02AE731A -:1008100020CA0C480B6A62EFC3FF49F45712CFE5B8 -:10082000DBD4C10E9BE732DC47F5D7E0BDAE196BD8 -:100830007307601CF786D491B710DC3A8C8BB6F244 -:10084000B868238F8B96B89AEF00E1CD1EE9B4F516 -:100850007E1BF871631F957C062C0B6D8BAC32FFF1 -:10086000E6D8515914E7A2FCDD8FEEB83F00FDEC4D -:100870008AE7E70CA60CB9341EE5424B6E82C90923 -:10088000F2E25677E923388F2943AE28C4EFF956B0 -:1008900047CF521E5727BAB8D5EDBB1DE905EB630C -:1008A0005CC36FE1712EFF1B2AC5B9FCFD12FCB1C0 -:1008B000F6A92B3B71BA79A49393D25D8066B43BC1 -:1008C000E43CE4F860A8DCD10CFD1D5A9CD11FEF7C -:1008D000CF35B8F31F26B888F11BDCFEC59897E327 -:1008E000C372FBE1F70B9D47B5C0C7C3026FBE11D2 -:1008F0002AD323FCC589A3120CF9EBC7A5303D32DE -:10090000DE7A7D67437E72493743FD9BA75D62288F -:100910002FB636E7555D84FD5BE970C4A31DF6690B -:10092000E3BF3FBC05EDBA0DAA5781F5CCDAB6F1AD -:10093000C3E150EB141E2FA5A0A787E25EC7F15CB0 -:100940001AF29EA66B91FB355FB2663ACF17B11FC4 -:1009500060D87799E3DC41E7097FA9FD9AAD9DC492 -:100960007EC0003C8A8CFAE8038AB3CDB3F3F57CF1 -:10097000F9D27E0BDD0340FD01F43D061BAAC8E75A -:10098000018A431734ECA7FB56933A71B93C2FEB1D -:10099000760D2C32560929CAFD42904F49401FCD91 -:1009A0004DECD2AD780E37D741E7262ACE4C642CD9 -:1009B00005E928D0F776A837675911E5E79D89A79B -:1009C0007EDF559B0BE9BCF58B0AED1714779EB2C1 -:1009D00018ED51ACFF6B18AFF8BFC714217CE66D62 -:1009E000E5E72B8AD57FE6613F73EB8AA87DB1CA24 -:1009F0007629601F8C2DE07AB618753BE4D5C18E40 -:100A0000E5A85F554BA8E79F509E581C244F92CEF7 -:100A1000DC4CE3579EB151FB4F84BC30B7F0798D6D -:100A20003EE3A3EF12EF073A7535DC0F34A76ED023 -:100A3000CAEC589F51FD6BCEFC8A52B9CE377AFF73 -:100A4000C58D72CC9CFA4D219E277DC3AD38C9DC83 -:100A50008892B7A7AB8624B118F2A86D9C33FC7CB2 -:100A6000B2F50C3FAF7C20433F837C3D7E618B869B -:100A7000FB37CC6E7322BCC60FEDEF9911C147EA6C -:100A8000AB3759102FE687DEB3A07EB7425A10511C -:100A90005E21CFE347C9E39FDAE4F1224AA57E61F4 -:100AA000E937913D7AABBCCF2AF8E40B212F64FBE8 -:100AB00066A471C4E30B56F29FBECFF027A7433F55 -:100AC000CDF96CF216928FCD39B86FF24BCD1FF085 -:100AD0006C53C8BE6FA1F3FAE3877A4CB81F9096A7 -:100AE0002ED7C1F9F57CEB50D3F93ADE55D902EC9B -:100AF000F7DDABAE6AD6A1BFA67B060E44B92FC701 -:100B0000ED956EE1FD3A5B7F407FAEF2E5040FF2BA -:100B100075313A4779613B16BE338CFF55BE6C5D2B -:100B20008FE7682A13C19F85F10B5E890B211D3762 -:100B3000BD12A7A17E782ACBDF0BE153F04AAF515B -:100B4000E8BFE98D568DE2079DF4DEE9833A9EEF1A -:100B5000F9E453349D49BEF42FE3FC522AE8B44C27 -:100B6000F09F5FF0D1E9AA4EC487A717C2A4719F76 -:100B700073A172E956B4073C0E3AFF23F9B218FD8F -:100B80001EF85E7C4932F97F117C477C38F78C93E4 -:100B9000FAAB38E3117CEEA2BCE4B732C12F566148 -:100BA000474C13F43D3CD37F633ACCBFB806F81DE5 -:100BB000C6F12FCEC8433E0AD38BC5897405F49283 -:100BC0003E23826F6A9A6E62687F58DD3EA2976903 -:100BD0009046DA1FD3DBEC0F67611ACC7B7C6DAEDD -:100BE000E1FE4989C0FF85D2FDD582BECAECA11EB7 -:100BF00068AF9AABE2BC789FEE949BEFCFCCBF8FEF -:100C0000C36FBED95780F6C3FCC7142F6086EC0AA9 -:100C1000944783F7565922E38D379DE9C73C0087F7 -:100C2000EBCE74A7F48654FF6C8443E99949025EC5 -:100C3000FD7ED63EE0209DC797CC41AB771DEEB33D -:100C4000C5F955C4EFD16CE67C3022BE84F1308CFE -:100C50008BC9FD41196FB2E27E6A849EFCB756973C -:100C600083FE4EBBB853BE711F6D6ED33F079BA072 -:100C7000FC78AE4EF1A729267F2DD2F3EC89C1670F -:100C8000CD909FF3C0F38918EF96F0ACD7423D505A -:100C90004FD6031C310E56BF422D0A727B2681EFC0 -:100CA0007F71BA96741C4DDFB3CF74257A3A5D65B7 -:100CB00025BD731AE89545E81DA96FA47C977A476E -:100CC000D27385C6E556853D89CE5584F5CD041F82 -:100CD000C671596FC5DB8345EA9BF52B8721FD9FC4 -:100CE000747BF1AC4F34FDBF589D4EE76CA41E8958 -:100CF000D637529E4BF92EF5D5DA0CFF8B88F7913B -:100D00007FFDFEF97FC1A76B34AEB7AED11C443F67 -:100D1000172E37F70BB9B9DF2037E77520F71BD34C -:100D20002F4EEE3F2DF805EC57B20B51AE47F6F7BC -:100D30007DC6C87711DF7BD2793CE0979A7747F27E -:100D40007E4F1BFF5E98BC6F12EB3D9FBC3F22E4C1 -:100D50007DB47CC70B6D28DF4F6EEB43FBD3FB18D4 -:100D6000E803D47B8D099E8D42FE937E884F0A9EB8 -:100D70004BFEDF9535F54807F2FFE8FF45FE4B7A5D -:100D800094FC22F943F24334FF487E187B3FF87FFE -:100D900088A777F9FDA90A2DB099F60F3D09FD91B5 -:100DA0002FDBECB6AD0AF1593BBD20F826CC274627 -:100DB0003D21F942F289E48F0AC10FD3A3F861BB48 -:100DC0005AFFE03068579DE1CFC81814E68BB95B35 -:100DD000A2F542877485114336DD5DC590AE2A20A9 -:100DE0008DA42B6B07FC90937171FC60CFB8307AA7 -:100DF000EA9FF1FF9C9EFA67C4A6A70119BFA03D18 -:100E000071BAEAA33CBCCF743A0FE46C6E98DEC6AC -:100E1000BEC9B8BDD08DDBFDE037D2BC7759B22951 -:100E20009E33F62C3FD72AE952E259DA01D3453CEA -:100E3000615EA66F52466AD85FB8503C5BDDCD1646 -:100E4000F443A6431AA9FF3BB2776FC9B848BD9FC8 -:100E5000716176E2DC0C7EDFFD17B4137F83F088CE -:100E6000C62B73BA0C7108D07FD791FD16D2E888D3 -:100E70004C877EC56A0E67995F12D2A4BE4D417D34 -:100E80000BF4B200C7FBB9F4525CC0443C70D738D5 -:100E90007D04E0FD0F22CFDE1A877C3869A82CDFA5 -:100EA000BD42D750EE301947A7B8C8BBAAC807DE65 -:100EB000786B14AC7FEC832C1C6787F2D12392DA19 -:100EC000E2280A0BD77FF4B1D7DF5A4178E6E75E14 -:100ED00098BF45E3FB4C229F077947447E68547EC8 -:100EE0002DAF9FA8B5307E4E31C8F955C5AD374EF0 -:100EF0003FBE087B04305988E709C66F559C180728 -:100F0000B979C449DA8F0DAFFF9FE3303E3BAF5153 -:100F100011F90FDFC2F5DEBC95E7B73DF6AF15015D -:100F20004DF497467132FA33D72B3A9E7F983B5453 -:100F30000976CD6D0FE76D1946FF06FF34637B869A -:100F4000E7EF2EA63DE299DA77A5F621EB458C7FF7 -:100F5000E388D8F712DE96FC25E209D43FC0F2BA46 -:100F6000FAD8F7243E10F59B71DF84E0757205D244 -:100F70004FB345C2F3AB1508CFD18CE73F7BECAB49 -:100F80007181BE7CFA7AD4FACF35FFA60CA3BD805E -:100F90007F1E63FBD0B9E0F77ABBF6827E661AE962 -:100FA0002949F3ED380DFD2481FF8F76F13C5FDC9C -:100FB0000AB4FFC3F4F11FA28F6619CF6F47FFDF9A -:100FC0008D1B6527FB47D4FF6105CA379FA9AD3E3E -:100FD000E707495FD0BE377F9F8DDAFFE7B1EF5754 -:100FE000207C003F544E79ED1CFC501F951F11C50D -:100FF0003F82FE897F51CE037C7AC49033E9999C6D -:101000003EBE14E7AA9B47723BB159DC9B1A9AC9B2 -:10101000ED424F2687636F51BF393E020E1178862D -:10102000BF10FA2111EB2638DDE496EBCE2A1ED74D -:101030001DDABB78F980CCF4070259E17C747F7922 -:101040009959C5185F0DF79FF936C2F52601B7A16A -:10105000999DDF0E7079A8205F561081005D6C5558 -:10106000022AFA09481731D6CD32DBF15520AABD44 -:101070006E3E477B4BFBF67A547B66CEBB98F602FE -:101080006FE3A2F05A1485D75151F912990F1AE45F -:101090009F948B650DAB96A4B9312EA9D09DCF300E -:1010A0003DFFAA18E9798E53D2EF2504D7303DF7DA -:1010B0007D1BE5FFC47A290F2F7D4007BC4D407989 -:1010C000382C9CBF0EE505E5FB15EB4991FAE2B221 -:1010D00007507EDEB84CD6F752FD9B6B657FFDA9AD -:1010E0005CE291050614135EF384BE080C7C1BCBF6 -:1010F0006737F2F673D6E4BD1DE87E0E7EA88B82BC -:10110000CBDAA87C20AAFE43E7D12FB551ED1746D4 -:1011100095AF88CAAF8ECA2F33B62F9DA6101F96E3 -:10112000023D2022CEC797F764B6D9A96DFA54B113 -:1011300093DD66E0ABB1353CBF644D7EF1B2BE11CC -:10114000F9CC82E248BE90F77BAD6E467C61EE4002 -:101150005EFE3AB30379D93B5ADFF2F2CFF09F1922 -:10116000B4BF63B00BB6ABC67C932AE73DE1ED3B61 -:10117000EC11FBA0CC578CFE41C7FB2DE38B474500 -:10118000DA2581E262A44BB94E59BFF0C7B32A8E6B -:10119000F7A7CCE2E20DB89F3352EC43BA780A7A53 -:1011A0004D45BD5929E23185783E16EBC5877ACC8D -:1011B0008FB443587D4F5C67D33DFCDE40A006F002 -:1011C00083F135E6B5603CA5292969C193507FFBC1 -:1011D0003DEA02D4A3FB16A4D0B9A43399DC5FD8AE -:1011E0009ED4256D3AE49B126EB3E0FDE4A67B47E6 -:1011F00053FAAAAA2F6D055E7B694D49B1BD0F96C2 -:1012000027117C5EC89C5CBC08E8BC012FED407BCC -:10121000BFCB9986F71AD87233E3EFE5789F20BAEF -:1012200079C0DA1FFDE7D24597D0BE55D9C3130A5E -:10123000E9DEC21233ED67C01F9D3FF12F1F4DE75E -:101240009EA6D58A343086D2577EFA4B4D22EEDFE9 -:101250003FAED07D892BBEA97F13DFE5295FD6CDB8 -:101260008BA87919EC7A3C8F7460752FBA2771308E -:10127000AE8ACE7D427D86F5CB7FF0BC333E0FEB50 -:10128000AB4E3C5A7118BEA33D7CF83E75BD82F34F -:101290004A74C4E379E9C33F7ADE41BB16CA9D8B29 -:1012A000E1FBE125B3D2D0CE3AAC78121558FF0756 -:1012B0006B6617A767E0FD7AABC0E76C4729ACBF48 -:1012C000D4D4462FA43F6624F3FC0799B38B37C2CE -:1012D000FC0F3FD68BCE7D8DEBAC7F980970CAC8D2 -:1012E000D23FC2F4A0B877FCCA4F7CBFF01F27CA18 -:1012F000D2305EB75FF0CFCB67CAD2CA22EC9D195D -:101300005F6A84F7572C9E3B709EAFC4672B743E78 -:101310009BD5A760BC7B9AF03F807E173C1FC3EE35 -:1013200069CC54A9DFA6FB5347205EC3747C37C940 -:101330004FF21B207F6ACD9DA4D70E5917B083288A -:10134000B7C4F94586AF0D21FF6D8E0BC6E562FC73 -:10135000532FD4C98FA9EF39D111C177A2FEA701AC -:101360007E3EF753A88FFEDBA781FF7144EE43C892 -:10137000FAE5898E001A13471C0E0DF1B04FAB3EF3 -:101380008CE7FA663C6E26B93FE3F1D485AD286F51 -:10139000805E303E16BDAE2B3B9B793CA2233E0CBB -:1013A0002C35F2215B7A4E3EB4FF69C939F9B05C45 -:1013B000F829858F9BE99C7AF9208786FB8F231F6C -:1013C0007F6D23DD5BBD3D6E00DE4F287FDC4AF87C -:1013D0006A7138024EDC1F4D7468C9906676E6F873 -:1013E0001DDE99F34D81CA34DB004AE95E82DCD709 -:1013F0003BB6E0C147F018E571169C3404E0770A6B -:101400001106703925EF6545EDF355EC7EDE92CF80 -:10141000CEB1CF779EFD3DBCF18C7C78A1FB7CFDED -:101420003B8B73AE6DFB7CE69EB88F582EF6F90AA7 -:10143000D6F2F35BE50BF83B1C05293CDE7BA83AB2 -:10144000808FDFE27A034EBC9FFB10D72FE54C095B -:10145000DAE09F63D6DE4EEF933E2DE44A29BEA329 -:10146000D517F9C59B837EFA8CC7E308AEE54FCC50 -:10147000FAF03168D7B2A8D81DE9178FE96C9670D9 -:1014800065784F57F67364D1EF7290EE0BFE0CFE49 -:101490002DDEF74B66CFDE948B78CAC8C1FD485964 -:1014A000AF7CF13D3D793DF08FC10F2EBD4FE5F78B -:1014B000A65FB092BE031E4F6711F799A7D5EEB68F -:1014C00058FA86EF7F1D803C5EA98FB80766417889 -:1014D000C97B49F8973E58D8DB1E921FF4BE70892D -:1014E00049A1FB4B20B9E8DECF9D9DF97EE1ECCE12 -:1014F000DC8E2DCDF1D2FD978A9556EFE25CDE4F62 -:10150000DBBD6A3CE7646A9E41FB8F7FB3525CA4FB -:10151000B2364E8F4BE4E722B6F4A573D19A05F7A5 -:101520004D3C5C4EDC29E8AFD233610CD20B94EF1A -:10153000D5F01C9683CBC38A64F1FE1BB437C13847 -:1015400027F15FDD78BF19FD22C657C477E8C7933E -:1015500018EE7797892DC3B80BD6EFD30FE19832E9 -:101560006932CEEF1995F81816BF7228DA77CFA82E -:1015700003D1AF2DBD6F7BE16ACC3FD71F6F2CB07D -:10158000D267DF277D3147E0BF459C072B833CBEF8 -:10159000AFB6B233D7F77E95C77B560A38493A9033 -:1015A000E515F7F1F350154BAC64BF542CFA88FAEB -:1015B000AD7034A7A1DCAD78C14CF7985789799705 -:1015C0002DCA1EB117E8AACC9C44EF48CF0D145B7E -:1015D000303FB74EA17CB85D6A0ED2E917B52F2611 -:1015E00022FD1C8C0BF5403DD47A7B9C17CFE1C9C2 -:1015F00078DB17B53DD6635C669AB3D981F791A6BF -:10160000DDD1CD85727B9F3364C1F27DF5B926CCE7 -:10161000EB4EE708CCEBDA6594FF429C3BA13FA47C -:101620001785E379EEE6ED96AE30DEDF047D7CF9DA -:10163000CCFB3D514F55E434F7447D0274D0B333B5 -:10164000C2F96985F4F0BCCDFC9CBAA48379480743 -:10165000C077B3051DCCDBFAE26F901FE621FE07D1 -:10166000B4A723A0D31DF47DCBBA42C6DBEF403A2A -:1016700091FA0BF2B56617C6DF441EC6C1FC8B0893 -:10168000CF542A1FC5CB037DF939B7163AB757296E -:10169000EE2BB6C9A70EF0BC47E0B16C9195E4ED16 -:1016A0001E81E796FB5E48443C7EF9CCF69DB84F20 -:1016B00052B105B4B427065F08B854221C12691D44 -:1016C000645754E2BA13C37068A37FC18F958CAF7F -:1016D00053AEBB52137090E5A2FD07826EE6320155 -:1016E000B7ADBD38FF097E437EA67776C4FAFC2EDF -:1016F000E37BE2DF89F51D147A612ED005DECF622F -:10170000783D51CA0928FAF2B97514F791F892F3A5 -:10171000B66779A4BCD3935D613CB69862BFA77CE1 -:101720005AC06FFF924E390D00B72FC0BFA273038E -:1017300040AF5AC478926EE478057F9D700DAE1765 -:10174000FA0F61FF72DC7D81040DFBD9C7387F2061 -:101750007DA2FC947C595033E59AFE78EE37F0A5D3 -:10176000A35B5F5C2F1FDF9EC5CF2DEB6827407BFF -:10177000BD41A1B8F37EE1CFEF5FF2626259049CF4 -:10178000E2B338BD4B3AC33F8C47C9F9EE72F1382A -:101790006EF4BCA51C92F32EB8F7C66BF0BB9CBFD1 -:1017A000A457499F128E924EE5FDB7687A255A9349 -:1017B000FA5335C87BD28F63B2BEB6F8EDEDBF47A2 -:1017C000E7A51D74509CDF6E4D653C5E5F9BBE239C -:1017D000F2BE0FFCD923F54E843E59A145E813A96A -:1017E000FF2BDD3ABDAF322F8B9F2B39CEEA2DF97F -:1017F000D0EFDCA3CD85899EB0DD79C5372115DF1B -:101800003599BB959F3F93F09E7B6207D17D85B84C -:1018100097547ADFFBC54390BEFFCB4CFB31A54B01 -:1018200046D3FDE3591BA70E46FAC1FB0C28CF8F08 -:101830006D1834903FCBE54C9B84F71A363C38E961 -:1018400066F83EAD41F5925C877E905F4BEF1CC819 -:10185000905E0EC6B5140F437BFD6ED589F6FAF087 -:101860008D831662FDE18E2EC9B81E7D430AE57593 -:101870002D89F482B473E5B9BC1A33A787C9599C82 -:101880008FAE6D4B399D15D4D4F4C4FDF3D675716C -:10189000F49E518945DCE3DCD689FC894A0B5E293C -:1018A000A47BA16487CDB4305B063FEF6CCB80EFA7 -:1018B000BBCDCD77A2FED87DA7A33F9DAB577F18A8 -:1018C0005CC6ED67BE5F98627C3F48CEE346317EE2 -:1018D000747FB2FD2E71DEF8A098FFB1DAFF9A8412 -:1018E000FAEFD8A61E2E5CF7916D71740EFF48D4E6 -:1018F000BB8C177B4F0BE836EA1ED4627E6F20CB81 -:1019000068BF493A3FEF3DA54FDC51FB01E73E5F21 -:1019100074A29AD17DEA4BC1A7C0F6A3127E7C1EA9 -:10192000CFF5CDA8B33AF13ECB21A47B3ACFA3F2B9 -:101930007BB736CE07879EEB1F44BF71C627FC7E60 -:10194000D18E55F7D2B982E96057E251AA363BF9F8 -:10195000A15593900D4E79FD4B33A0DDA94DFC1C94 -:1019600044BB770B763FBF33F2DD828BB58F2FD42C -:101970002E96718587B38CF7C0245CA57FF40AE0AE -:101980007FE880309CBEAA9E4976F1896A3FA527F0 -:1019900095FD2B8723DD3A92E8BCFE3F1A1E54F1D9 -:1019A0009D958AADFD7F40FF76983DC989FCFA552B -:1019B000F502DAEF3C515D4569F8FDDC20A5576C76 -:1019C0006DA2765F350C6CC47BAE2FDB9384BC8F2D -:1019D000DED7E178ECE8FEAE5CD7F1BB393EE5BC82 -:1019E0008F6F9A9A88EB6AFA534AE3E588C7842492 -:1019F00027DA77E5E29CC7E1D5DC7E3E6A4B7A7256 -:101A00001C9E0F597B5D1ABE8333BDE9FA49F87DF0 -:101A1000C636C58976BF77DB8444F4433FD75A1274 -:101A2000F15ED3E7ABE57DA820BDD33AAC88D1BE4B -:101A3000D3B090C63CB97C8B19E9E4F2131ADD3BB4 -:101A4000FD02F7A330EEF1433CC53D98D8679AFEFE -:101A5000128F97B4F9B1C28F1B2ED6DD8ABFB39116 -:101A60001AFE5E30947F3FB2F6F9F1D8DFB10D6611 -:101A700027CEFBAB0DFC7D86D9E07FE1D594A39BFF -:101A8000B87F33BB5E217FF8D826D0CFB0AE8ADBDB -:101A9000CD3ABFAF69A4BF0228C7738D92FE66EB33 -:101AA00041A2EBE8F73392593DDDEBFAA5E8F1707E -:101AB00096F13C661B1D76847F0127E45BA4438975 -:101AC000E7D9ABF9BEB9ABBE7F3ED293C47BF4BBC2 -:101AD00072351646F71202A6787AFF7782DD6356D2 -:101AE00060FDD7B95B46A1F89C98CDF5B85A60D295 -:101AF000F11E1AABE1F7F3DBC98F2C6E0FD56433FF -:101B0000EABF73363F2F2CEF63C91416924DEFEFE7 -:101B100025B8FEED812AF6C76BC76B30FF09C35DA0 -:101B20007776F3028A1E5F3E5E03BA9D30D0F5429F -:101B300057C8A765DFC7F397B9069921BF68D1FDDC -:101B4000E347E1EFB264EBF1D911E3C87EE1BB23D7 -:101B50001BE6B133C5EFC4B4D2C2EF479D545AFB64 -:101B60002DC80DD77F4F61FBFEA184F32D6646EF94 -:101B7000C074C6F90FEA38BD255BCFE0E31ABF9702 -:101B800031B684CEC705F8FD16F8F3D9D2F0FE11B0 -:101B9000A7A73279DF6599F1BE0BF3F2FB57F21E6E -:101BA00092BC67D4277C7F6AEDC5DC9F3A6986F5D5 -:101BB00026B5BFCFA634BE4EEF61D504584B1CE10D -:101BC000C1787FA52281BFD337FF852F772059CDDC -:101BD00092F60A2ADBC1E1FBFB2C9DEFFBDF29E833 -:101BE000F04835EBDE1D58F9DAE6E6440F4CF6C452 -:101BF000F8504FE46F8FD59F8FF03FB2B6266BBE83 -:101C00001BEF7D5ABDE3A0FED120BF573957D89BAB -:101C10006C43AAE073357415D4DB95DB87DE6F184F -:101C20009BCDF5F289DC500EBEA713C8E5FE0DD49E -:101C3000A3F36B458BC7A462BD13CFDDDB7D3AE018 -:101C4000CD8AEFB7B9286578FFE96A3BBE854CEFCE -:101C5000BA3195F66983FC9D31A897887ADD3335D2 -:101C60009DC7D1F9BD39892709FF76788129A03D23 -:101C70006AB23133CEBF0F5BEB447D21F123DF31FC -:101C80009DFF028F9FCC575A6A5330FF8C42E7DF8B -:101C90008ED8F8BD9EF67A6EA305413D73ED54C310 -:101CA000FB3CF2BDD05F3A0E343F5BC897FEAC7F81 -:101CB000E47BACE5A2ED68B5C483EF49CE4FB5D166 -:101CC000BB1DF31FEF46FA041C6116598FAD4D2161 -:101CD000FA589AAB129C6735307A77A7B82193CE21 -:101CE0002B8E6B70519A78269DBE1F7BF2CD3C2EB9 -:101CF0007F381E8A9FEA44EF47173FD56B24FFD1F8 -:101D00008176EFFFF07793ED36BA473B7F37D74BBD -:101D1000F36F50293EC9C4FD709F988ECFBE8CE2F0 -:101D2000393E16FB1D589F7C0756379FF31D5809F7 -:101D30005FABC04FF4BBB037EC1E988E7EAA7C1709 -:101D400056BE63D72CEE6D45BF0F7B6F6221BD0F72 -:101D50003B59E77A24FA7D582D10E745FBD69C6560 -:101D6000E7EF35F8A3DF8B6DD170DD9346F0F762B6 -:101D70006F981CF12E02FCCF3CE26B92D3E611ED82 -:101D8000DE0732237D5B7DC6FA5B24FEFBB03EE7B7 -:101D90007C8F37CB42EFBC69F85E35E42789F77852 -:101DA000D18E43FBFC94CEDF95B3C6F37537B3BC3D -:101DB00074E4FBFFDFDFA13EDFFBD3D1EF4D47BF74 -:101DC000333D70D71F0DF941CD6B0CF587EC5D6F7E -:101DD00028BFBCE56943F9F0A35B0CF92B5AFF6EF1 -:101DE000A87FD599570DF97CF6A6A17E81ED7D439C -:101DF0007EB4F37F0CF5C7A41F34945FEDF9C25095 -:101E00003EB6F769E37A34FF59D487C5DEEF0DEDAE -:101E1000C633CF1FF01DE71BDD267AAF43C911F68D -:101E2000B5A0BB1FB384DEEECE72507E8D564784C4 -:101E300088EE1A14E2F7683DA67DE1D3311EC75E35 -:101E4000E4F7BF92C0EED322C64BD66DE01086F306 -:101E500029454E433ED5976EA8DF69B2C7509EE133 -:101E6000EF6D28EF3CD36BC867570D35D4EFB24008 -:101E700037E473034586FADD96F90CF91E75930D68 -:101E8000F57BADF61BCAFB04671ACA2FD95465C887 -:101E90005F5ABFC050FFB28680A1BC7F6899A17C09 -:101EA000E0AE3A437E50F36A43FD217B8386F2CB5A -:101EB0005B3619CA871FAD37E4AF686D30D4BFEA0F -:101EC0004CC890CF67BB0DF50B6CEF19F2A39D1FAB -:101ED0001BEA8F49DF6F28BFDA73CC502EED96B125 -:101EE000BDBF367E17764CB1F73F86F68191E27D15 -:101EF000E82D0ABD0F7D5B4E57F9AE684B1CBE8BBB -:101F000018F051DCC78507FB504EE1BD6B173F173A -:101F10005342F12337D939A48A3C784E07EC8044E8 -:101F2000F4AE7273D14E4E08DB63596723CEC99D60 -:101F3000CF1EABC86144E76B73FC6539A9E87F3CF1 -:101F40005748EF7BB3C0529C877CE7EE9DA8778D06 -:101F5000657AB5ED288B7CFF78775C5DD68073F869 -:101F6000EF57DB4E307C57B9AD5F11AF50607DF35A -:101F700023FA5F09FE82D69DB1BA6AE01BB091FEDA -:101F800058EDA4FC43D5E9947FA4DA43E9EAEADEFC -:101F900094AEA9F652F9DAEAA1947FA25AA77CB0CE -:101FA000BA88D2F5D53EFABEA17A32E59F04BF18B1 -:101FB000D34DE02763FA34F8BB58BE19FC5FCC3F21 -:101FC0005B1DA0B4BE7A197DDF525D47F9ADD5AB7C -:101FD00029FFB7EA20A50DD59B28FD7B753D9537D8 -:101FE000563750FEE5EA10E543D5BB28FF6A753346 -:101FF000E57754EFA5FCCEEA164A77551FA5F48D78 -:10200000EA562A7FABFA0CE56B4DFCF740D6E41894 -:10201000F721645EBEC720EDBFF168BF23710C35A8 -:102020007F65B0DFA3ECE8687C1C1771DDF0FB096D -:102030003DD7D744F84F4F8AF1E47B0CD1EF2830DD -:10204000619FCA774FE57B0D33C4BCCA053F0C4284 -:10205000FAEC4DF4F9D6C5F80BD21F1C90EAFF1B21 -:10206000D167B62940FEB09DDF27BE21D5FF52CEF5 -:1020700020DC2F9CBE93C6737A69DFB0D81A4ABDA4 -:10208000318FDEFBA6B85C47E3558A73DF1D96BF30 -:102090007C2C0BEDE9A29F547A67EB1DB3837EDFA6 -:1020A000F02D0197B7724C86F4E354FF9B38CF6F45 -:1020B0001D55B79A60FEDF5E79FB93BFCE0DFBC95D -:1020C000D7A2AB09FECD04E631D3B942A6BF968BA9 -:1020D0007613185698BF910528BDD5EDDF83FDDC3A -:1020E000040637E6FDC3AC39B1D6153DAFCF72B8A3 -:1020F0003FFC598EC9905AD3FCFB104EDF3A749ABC -:10210000D73B978FE989EB92F32A12EF8E8C67AD5C -:102110004FE0FCBEDDF6F561A55B18FED21FA77B84 -:10212000FD28C76E57C4BB76EDDE11A0F2923B15B9 -:10213000B2CFA6803F83FB43F2DD805355667A0F12 -:102140001EDF19C0FDB353559FDB919CA11EC3FD3B -:102150008D1A3CA003E53577F3FBF425F82EC60075 -:102160007CB7C0C6FB5DA810DD0D4FCBE5F79FC166 -:10217000DE23FFC9DD4AF7F4804EBE273AB95CA5DD -:102180007BE7EF98823D15DA4F9E6E51607EE56EDB -:10219000AFE17703A2E9609EB82F20BF037D99BB12 -:1021A000C0385FBD34A437C5DF5FBEDC83F0AA3121 -:1021B000F1FB43813754F17B4E5C44ABC32FA53810 -:1021C00023D3BC5E8C17158BFB264D2A5B10EBBD11 -:1021D000F05E5D38BEDE49E7EFE7D544EDB374E964 -:1021E000C2E9AA4B174E6FC5AFEEA67784E6EDE2C3 -:1021F000EF1DB2BC96BEB1DEE7AF5CF0469FEE11BC -:10220000EBA86CD8CFCF57B096BE91E7C975D1AFC8 -:10221000A423D5E2F0AFB347CE8FD30FD0754F8450 -:10222000C3B7C940D7DD88AE0FE3BEE278AB27E97C -:1022300046057F25807D85EFFBF8FFECA4F341F296 -:102240009CD034E6A3B41CC800E9D8175845EFB9B0 -:10225000CE66F5F47DDED0A9F47BA495AC75543A36 -:10226000C0ED86658B5EC3E7F0AEAB5B351AE3ABC2 -:102270001383A5AF613A61837218FD54E08B215D31 -:10228000301EA2542DC12399376FCE5F825B66E367 -:10229000558E0FF626C707D08DAEBADAAF13F8E029 -:1022A0002A6CFF6DB24EEB50138B0C7C50B298E948 -:1022B0008A3B7CDEBD8D2F86CEF90CB7D498D64AEA -:1022C000FBE6952F5B5D88E7D98CEBED703C43EA2C -:1022D0006B46743E87C57BB1DE7141D7C7B319D158 -:1022E000F57185D13D756947B21C7FFA806E61BD7D -:1022F0007BDC141C9CD88DF4F2249CEFCEF4EB3CD8 -:1023000018079BE3B6D1FBA7C793833951EF7CD065 -:102310007B44328EB5D2CCE34AD1F35286EEE4BF91 -:102320006B616101DC9FC0DF751E8CFC8CEFE628C1 -:10233000F40E740BF2BD79A4CF13ABFF5AD1EFAEFC -:102340001FB9BF1B80F5E0FDC676E338C538F17CC8 -:102350001CA93FDA7E473A8D19C6FB4D975CC2CF68 -:102360003B0E9DE6BFC8944CF226C3E6BF0BE94E78 -:10237000C675A41FB82BF74877F2D77FA8C942FBD0 -:102380009CDE2140FBFB4A2E97DE317BE8DDDD77CA -:10239000F273297E2FE5EDB54379FCEB5A19EF1A5C -:1023A0001115EF8A8AB7B011B1E35F8C79CD386E21 -:1023B0001FF689840FC5595E1DA1197E3FEA55E1BC -:1023C0007F9E2A72E7219DEFEFA2D23A1353F8BB0A -:1023D00021AD0E95E86C7BC06BC7DFA3582EE2A43D -:1023E0002BA2DEBD5E9E37DF89E702AC0EFE9EE5C6 -:1023F0000323E367469E477FAD073FB77463CFFC77 -:1024000077915EFADA8323493DEB9A07E7AF88F5C7 -:102410005CE204789BD0EEF48978A7FC5D9351A42C -:102420009F259E2F543F3FAD0517C7E37ADD8CF8FB -:10243000CEB1DA46F253ADD74378343AB5E7C4CDDE -:10244000843FCDD71BC7691A1CCFEC50FFDB260B8E -:10245000C5A15E3695FD19CFADB77E6C6578CEA16E -:10246000DED1594323B7FEC75F8DA2D431BC90BFE4 -:102470003FC912F09DCCFE4EF697FF462489FB61C2 -:10248000F50ADBC51F6BD513F09DB77A133B7D159D -:10249000CC6B8B7DC0839711A9F9545CE77BDDFD84 -:1024A000AFE03C06B32ACA3F60F1CD5C07E33EE0F3 -:1024B000B2117DCCEAEE7B95CF932D1907F3BBB219 -:1024C00040A1DFAD5B227E97CDE18D37BCB7EB3B02 -:1024D000D393F4C5DB423ED7A6EBCD78B1A343B886 -:1024E00039B556C33B592C8BE273128E91F8720E9C -:1024F00036E0CB6F8EC4D750C0D7A591F8D2958B5C -:10250000C1D7935D18CD57D26560A467D5A83CAEFE -:10251000C76AA896338FCEB7B6A34FCFE67AC86FF7 -:10252000D72E217849FA94F41A834E6FDF8EF23851 -:10253000DBE4C4FDDD7BC7C5937E93742BE9D5D264 -:10254000959FAF02BAF57585748ADD371A654834F0 -:10255000DD62DC2B923E4B3AA463E68CE4D7F1605B -:102560003F24B9D0DE39BAA13E823E4BAABED6B8CE -:10257000FC387B55FCE0709CEE7F012DB720EB0012 -:10258000800000001F8B080000000000000BED7DA4 -:102590000D7854D5B5E83E33672633934972924C93 -:1025A00092811038934C424826302480FC552721D4 -:1025B000D0F0EBF05783243A58B4412193026DA335 -:1025C000D77B33908001EC2DA2F5A1F2EC808A68D4 -:1025D000B506A51ADB889320DC685107B52DB6DA5D -:1025E00006DBCF9FB64A10AF175B5AEE5A6BEF93DC -:1025F000CC994C10ED7D7DDFD7F7A27C3BFBEC7DC9 -:10260000F6CFDAEB7FAD7DB268A6C4DEB130FAB9A1 -:1026100000FFFCF0EF9D62F81D7F5CF85456DED59C -:10262000DA8DE2F915434BE8C7DE2D1EEC675AB68A -:10263000A9981918DBDAE264CCCC58BBE4F5E5C004 -:102640007872D3A90DF87C8B0C1D1D8C853CE6F0AF -:1026500043388FEC2FF6A70C8E975554E550B318DE -:102660004BB9EC4FC93740BF4FB30D2A93E03DF54E -:10267000BA276C93E0BD93C90CDF4BCD8C363C0080 -:10268000EDFD6F8E65FB60984FD704C62876C6B601 -:10269000B5C03EDCB89A708E612A967D39062796C1 -:1026A000AA939701277FCE447B98EA7B5CF98C4DF7 -:1026B000C6BA4FF4EFA3FEDBCC3B2D369CC7655169 -:1026C000F64983EBBCC2C89A3A60BED92A6C0AD6D6 -:1026D000CBCEB7AA8B53B02E51FDCE96DDFEDFBB1D -:1026E000713D612A33178459A08C315B71480D41CB -:1026F0003FCB6616C0F7E3E179BF4BA675587AEE7B -:10270000612AF4CB747BA500F4732C80F13438C3B8 -:10271000BF45008AB472E8B78FF9D824848F2D1C86 -:1027200092868EB728ABAA574E1DFEFC16C5E10156 -:102730001378A09DA7E56FC64087076B4E03CB6655 -:102740006C23F65519ABCE875F70DE66F3DE2498F6 -:10275000F75A359DF6FD89A32A8D79869FEF7E383D -:102760009F501140BDC542E5BE168585004F1E0431 -:102770007CC1FAFE1695CA032DC5543EDAE2A5F6D1 -:10278000C75AA652FD472D3EAA77B4D450FDC916AC -:102790003FD50FB5D452FDE99600959D2D0D54FE01 -:1027A000A4A589DABB5A9AA97E45129C1BEEA738CC -:1027B000E45C02E7D17EB3D9A7027CEEC67304B80D -:1027C0001FF1E5677AE1BCADC5069604DDACC777BD -:1027D00031DC8FD569F085E11CB63A77B1AF43693A -:1027E0009A92D22EA5C1FE1FB7B74B13A05DBE9320 -:1027F000A9F0FC7E29D4C0BC8CFD6B78865F9EC698 -:1028000098DBF9CDAA0CA8B7862B775A006F8BD42A -:10281000C5B59B62EA6A4AF98D0795C1FA18CF5E81 -:10282000D906EDED6AF54E87C4D7C14632B62B3CCA -:10283000C7BF09F02892CF4208F77E97398CF8B8C5 -:102840001ACF4BC6F52BB4FEF9ACD56980F58F5184 -:10285000CDE54837D03FC21C97DEFF6E55A5E7F1A6 -:10286000EF5DAC9F61D225F563C68B8C87EDD245B9 -:10287000C6B1484B2D5158FB0E93E01F5976E21F0D -:10288000ED2676AD1FE0DE6EE5E5699744F3F5BA17 -:10289000AAAE724179958B9F6BBB35A454E1FC6560 -:1028A000062FF20BD6EC7A3D1FE6FBF64B32DBAE81 -:1028B0000EE2E7E3829E0BC7A4F8701EF62F967017 -:1028C00021CCF3D5318FB76540BDF001AFD708FDFE -:1028D0007730AF0DF12474BB813D04F51F4E2AC83B -:1028E000580CDD4B27FF382300F8922CD61166AC2C -:1028F00006F16DD3961BC6F441F9E909CEA7BAC417 -:102900003C7B4DD1263ACFC97686FB666C6732F2A6 -:102910009D4D4E38A4CB18338CE0A5D9A45C8DFD19 -:10292000CC5BCC2C04EB31FFF5328B1FC66B3D9793 -:1029300054837C84B16832F231B335A0A4C3F39DD3 -:102940002103F18556D51E9660DC1DF6F25E15F961 -:10295000A762F016221C3D0682639BFD6B6123F289 -:10296000676953032B80F52A4F5A5CF03CEC312801 -:1029700048E761DF921AAC8702B2B750150C02DB50 -:102980000319E1ED382EEBFFD9046CAF635E84C30D -:1029900096EC3FF72443BD75B9E235F2DEAA3C85DB -:1029A000B111F81B4CD96AEADB9C8CEB58C1FBC314 -:1029B0006FDEC54087A949FCFCBED73D57C92F2310 -:1029C000B912EAE37C49BA0084289BBC162FB48F65 -:1029D000B797D7F8A09453CA2D2AECB34D29B7ACBA -:1029E000A2FD333B83793219E74FAD8AA1262CDA59 -:1029F000BFEE2131F5827B0A9112B5B7D9777523E5 -:102A00003CE4EB1973A9B83E984FE37B000F4BC130 -:102A1000CC5E15F6D17E4306ED4396BC5467D7CB0A -:102A2000B4EE91AA2DC2C6039F372FEC65C03F4676 -:102A30005A6E5A80F5110DF2EFFB62F8744E405F4A -:102A4000CFAAD5D73319D42D31F30ABC89875B3C83 -:102A50003C46286D2770FD2302323D8C5FFF3DCA46 -:102A60005DE9950CD769A77566DBAFAB040801CAB1 -:102A7000F93721FEFDBDEB1CAF2CB1B860FEF10EA5 -:102A80000382934D60FD9B71DC1D02DFDB5DFC3C2E -:102A900007E9CAA8D1A50FE9724CB3818562E48E1B -:102AA0002B6463A198F90ADA3374F5C29D2375FD8E -:102AB000C7EECED7B58F0B97E8DA4B0F94EBEA65EC -:102AC0001DD375FD277456E9EA1323F374FD2B7AA1 -:102AD00097E8EA93A357EBFA5F76F23A5DFBB4BE50 -:102AE0001B75ED33DE5FAFAB7FA5FF165D7F20E387 -:102AF000868E047272BA8BF38536A72FEA4B20CFED -:102B000007F42E45EE1F380FE09D494EC0EC98F9B2 -:102B100052BC3640A6C13A63A3947793459DE47AAC -:102B2000ABBA19F139D54CF82CA33C87FAFA9BCDF6 -:102B3000E124C4C3CBBD2AF217AF8BEB336F17F977 -:102B4000BE8AE756996A21B920DB793FD93E87F4DE -:102B500094D1BB812F55A0D6C806DA93913FB78494 -:102B6000FC6EF7E0BAADCA4E86F45B995AC3FAEC34 -:102B700083EFCB8A8F0552703E95E6B32821EA6732 -:102B800055E1FD987D1D3618981DF97837C809184C -:102B9000BF23255746FAEBF86B4935952933E620D4 -:102BA000BE4F54D8034F40FF0E89F532D0933A0CF4 -:102BB000EC2CE86CEC497BF99D20AE8135FA8DC890 -:102BC000EFA6B0262A471B980DCBBD52DF0606FDA7 -:102BD0003C4D27AA72A0DF0977600DEEFBBBA04336 -:102BE000E0BEBE3B9EEB595BB2E7A9A897B5BB3AE6 -:102BF0007AF3713D592057901064BF17F50A6DBFE5 -:102C0000778AF394F3DBFB50FEAD4FB7A8A82FC92A -:102C1000969DFEDF03BCEE37F53DD20AF5364959E5 -:102C2000DB817CF166BBF72186FA23879B9A62A839 -:102C3000D80CE3766CF2C9E9D0DEB18D79DB903E39 -:102C40001C959BD3E179E1A855860CA407F7A6CD86 -:102C5000586E413D16E61BE7D96BC884F6D24995FC -:102C6000B50C65AF02F3650E8F4FC6D4DD0CF7C30C -:102C7000DCF2BB8857A8755F80A55766C079C3BCD6 -:102C8000563C6F894A8283F59C3D6CC5BA9BC3C58F -:102C9000EA93C2C95077B87D92CF83EFEDA6F3B522 -:102CA00046F47AEC1A77E04E84A76381FE5C65CB2C -:102CB0005DB4BE1D064E17EDE9EA7194CFED2E7797 -:102CC00046AB3AB84E8DAFDC2FE4A7F65CE32B0A97 -:102CD000DA145983FA0DE0F96E4301EA673B19F201 -:102CE00027EBAD3B19E2B55509A90CF5F07F0B11A7 -:102CF0009E6BFAED064133D5F9B51694D7671DE5FD -:102D0000A4CF5A9BF7D379C5C3CDDA6760BE8BC019 -:102D100035B5E85E92EFC080D542804F4FB6BD61B9 -:102D20006F02BD7FAAB01BB6011947495EF92DC8D5 -:102D3000AF4DC2CE004C30A07C3BAB30925FACC3F9 -:102D400045F50DE9BCAE8DB321AB3CE762FAB77532 -:102D5000B7850562F6B10DE641B86C39BFB806E13A -:102D6000CA64220EB6E3AF9EBDDB1196C2AE992AAD -:102D7000E03D1BE706B88E3633B20BBC8E053548F6 -:102D800077FE73F9247CFFE4CAA07EDE103336D1CF -:102D9000BA4D9A5C325C98406B55CD9A1C26D596FC -:102DA000CB2DF8BFFB82847C3F468EF182E4BA26AD -:102DB000B70B77EADBC7EED6D7C78587BCFF06CA55 -:102DC000FDE5FC77900BFAF67B85FC5E8EF21B4AE4 -:102DD000B6CC4472CF022BBAC0E5EEA01C04BE9064 -:102DE000D711A944363A6A638C3C64B40F9D7C5C6D -:102DF000E3E67CCCDF2B9BF01CFDE7C0F8A818CAEB -:102E00009747277178F79853C29BE1BDDBC12E0A23 -:102E10001471FB3900A4F65DD9FBCB3AB4B37A8DBB -:102E20005EC0D881738A3FD715F91C7F7A5DFEBFDB -:102E3000BA487FE8AB40BB1AE70BC4CCD7634B1D45 -:102E4000CFC06E79B92860CC877E1FD73826217F06 -:102E5000481AC54C489F383F2B1AB4DFAF12F4B460 -:102E6000C3FB5AD31158C76D2793501D67B38DC745 -:102E70007B5BA0BE3E4F267EA65CB6F60768275752 -:102E8000FD1ADAE19DDB543587F4F45E13D9EB5576 -:102E9000028FAB84FD75B4D044E3E68A75E78812EF -:102EA000DEB071FB3B62437DB6F400F062FD792633 -:102EB000F3761FE9BB651DF1ED3E86745C22F005DB -:102EC000EAF64AA84F14F50E26652A708E136AFB9F -:102ED0007AD094F0BC78D4867878D0CAF5B7470514 -:102EE0003E6433C91B81F5671FB07BC3D02FC5C8B3 -:102EF0000E46611FDE17E47762CF7D7C97BEEE61E0 -:102F0000317517AE435FBF5D6D92102EB7D7818EBE -:102F10000E5BAEC84F71BC5BCA10E645885FB38DCF -:102F2000F689684FADAFB433846BD2A9B1FF2B8A59 -:102F3000FCE38491A15C5092D53BAAE17DE56799C1 -:102F4000DE4DEAE0F93FDA82AC1BF8DE052F6B03B9 -:102F50009EFCDD2A5B03EABF8FC179A21CF911D860 -:102F6000D9D8DE01E78AF527C1CEC6F210D8D9F844 -:102F7000FC69B0B3B1DE097636963F013B1B9F7703 -:102F8000819D8DF5AB8A2ABF8AF8526FF7CF9610D4 -:102F9000AE3E595580AEA44138931F48627DD2059C -:102FA00020903A85F525015CCF8DE17490841E2632 -:102FB000E0C32CE0B5205E7EFE383E6D9C8029D1BA -:102FC0003853611CB2132C0AFA45F2E18D3478FEB5 -:102FD000E1CDBFDA8FF262A11458910FFDD74D7E7B -:102FE000C7CCF5E77E33F6DF6305FC073E344AD0F5 -:102FF00041A80AE08972F725A3B7157A5D3EEBD4A4 -:10300000862CB0BF6FDA377931DAEF97DF74AA62B6 -:1030100034D40FEE0B2F964119BFFCE1534FE5025C -:103020000FCE796015AFDF79EAEC28684F0BED58C9 -:103030005C3D0DFD525C3EED91586DAC7ED72CF0A1 -:103040003BD8BC8BE41CF077867068CDF6937C3C53 -:10305000EDE84F5D05FD8359FDD9D75D847F079B62 -:10306000EF2639D49AFA07D23F5A07E48597E485C8 -:1030700036AF262F3E16B8A7C98BF5565E1DE8174A -:1030800028A0E7770ABF0E0B17523DD3CAEBFF5EAD -:10309000A5BE8A760FC087ECDC23A925DF9B897645 -:1030A000658DEC4D82FA9DF6722BCA9B07F3B9DD54 -:1030B00002E386D08E0FCDB6841FC24375A8448F1D -:1030C00019DAF80E372A5D2C43ACE385E9B608DA45 -:1030D000F9ADD5967DA84FEEB2E7D378AD53CD21AB -:1030E000F4AF68F5CDD3A75B509F484FCD70615DBD -:1030F000E34FDB01EFB1841F238E5B25B65B65B127 -:10310000478CC8CF2DA63FC5EAC9761625FCF11A13 -:10311000C020413E50C0F1AA82796BF1B9596A0AC8 -:103120002132EEC1B5E33E52849F92E5F2756BFB0E -:10313000F0E5F27D69FB483187C43E484FDA6537D8 -:103140004450DFDB05FBC2F176E7AB049FF87D312D -:1031500074BDC2B8B3A68A752B330FE13A661B7CE7 -:103160006DF8DED1CFEA1C805E6C0E6B92F17901B6 -:1031700058B4E89705946EBB7011BD23DE2F7BF920 -:10318000EF24DA0FBBC94CE7F24C215FCFBDE6B0AC -:103190008B91811B1EB1246578FC7D6308FEFA18B3 -:1031A000D2536B868FE3AFD29FBA09F137BD3F7B15 -:1031B00033ED2B92F03CE2F138FE7C7E0BFF841C59 -:1031C00030227C3FEF3CB573D4F0205E7E4D28501A -:1031D000B4F375D23E7DC59C0E343D8A819D9332F9 -:1031E000147E5B613CB568B06E76FA493F3639BCF7 -:1031F000C5E8BF6DFD9BB12191FF36AD80D3C1A65F -:10320000541BE9CDADA95C6FEE4E9DA7B377AAC163 -:10321000FE91003F8C99AC03E9C8987635F9BF8CD4 -:1032200039A821E1BAE2F4D1B4055C1F55401F4D25 -:1032300030AF56CAA88F26D05307F4D18C795C1FC3 -:103240004D35933EBA27C55CBB3701BF792F9FEB45 -:103250007BDDB88F04F61ED879E487D4EC3CB3123A -:10326000207B4DDBE77BF99CAEB4FE494A1343BF9C -:1032700098D1EC5551DF34DAB8FE9804DB2C8E91EE -:10328000DFDAFCEFE49B088E3D45FCFC0C16AE9F9C -:103290005CFEAAD49408EE6A81A63F24C6BBBF0395 -:1032A0006F882F94DBCD3ED40FCAEDCE2AD40F8683 -:1032B0007B0F4CCDD0FB19837CC5FBB72946923FD1 -:1032C000B2D78978D661EA7BEA55B4E38EDA49DE73 -:1032D00074A48CAA8AD59FC15E0D15C32007FF0276 -:1032E0009468186AA782FD34BD00C6ED599F3D89D8 -:1032F0008F0B7A5ED950BD32DE1F3040EFA9FB5DE7 -:10330000FCBDF0087C4F5A3F3507F12A9EDEB532EE -:10331000CFF952DE6A5857DE885E2AB5E7FF9B195F -:10332000C9BF16DF7FF1C03970B93C0E264B33920E -:103330003C5E8CEBFE70E36BD95E584AA37C86E45E -:10334000F2C74D53D36E5339BF3D8072E69B32F1C5 -:10335000DB516BBAD33362CEF9DE96CE3CD98D7198 -:1033600083685EB59BEC015FA2F5FEABA03F16192A -:1033700043FCD924F0407544E78E05B8AB7683173B -:103380005DD2207C757CA0524EAF5660FEBC16E626 -:10339000B543DDC514F267E55D3012BEE51D594148 -:1033A000783CC6D12F853C31F3202B8E898B7CD283 -:1033B000544DF499973360C751FCE013476431D200 -:1033C000F72777F115E53DA06F07194BFEE61B3691 -:1033D000DAC2680A8EB95531603DEF07121BE5C2AB -:1033E000751C71DD86FE9A6792C95F63DCED267FEE -:1033F000CB0FA4C0F505B08E0FC3EAB7D1CEA51F81 -:10340000E8B7EE3BB67DDB498E45E7921CFB968123 -:103410003D94C09FD456C0FDE35B04BEE7395FC94D -:103420005B5D81E5713AEF4BA5A783C8B7619CDB73 -:10343000D27652BC2B54C58AD1FE6B37015E25A0D3 -:10344000D73305226EA6F163013F2B5A2BB00FA391 -:1034500024F4BC038F3EFA6836CA6D864ADE00DD6E -:1034600069E32417775063B2D7C7D0EF20293ECE47 -:103470006795903384F19DBF1A13E27544E3D3AE90 -:10348000AD4EEC5FEDF63A910EBA5D539CD701FC60 -:10349000EC76334B8AE1C31A9EBC903285F4106DF2 -:1034A0009CF529F917B5B7CDC08FD58BC86933FA0C -:1034B000BD519FE999665161BD5BEDE551D4B7B649 -:1034C000DA1DE5E43FB703DF88F127D9EDC7080F20 -:1034D000ED5EEE67B323FF457F92D87FB7EB18ED23 -:1034E0005FEBB7A780D3BDDD1BE1F147B066B09FAE -:1034F00055F687D0CEB03A18D995560BA7A76438A1 -:103500000E4B0C1FD1E6FD7E01B7D7B68E2A8F5623 -:10351000D2FA64F408B0ADCE7227C9438433EAA36B -:103520002306F451F29BBC2EF881364E6B37DFA791 -:10353000BFD9E9ABCE443BD4FF22F285ADF6EB2CEC -:1035400021940B29932E3ADEDBE2DC868ED73C4BAE -:103550008CF73AD28331A55CC1F14CC82712E0DF69 -:103560001FC4BABEAC5F0C20AA90DDC6B87E051899 -:10357000EF4CA44768A545F8B786BEC7F9A44BD859 -:103580002FC0273FC5F5AF1BF5CEB14AEAC5ED9672 -:103590008CB972B10CE7F5319CA0511AB4E3E3F594 -:1035A000994A633FC9354D1E69F2E95ED467CC8301 -:1035B000F4A4F95F721BFC24B725879FF006F41B67 -:1035C00015E9C68871DF04709BEEE6709352A7AAD6 -:1035D000482FD5E7FB72F1BDC329EFE7B2183F9A38 -:1035E000C60F5FF86CBF15DB3F69A8BAA8DEA2C59D -:1035F00085878B07A7DEF2876FC6EA2DC3C5873F95 -:103600002F2EDC936A26FFDBFD929E2F4D72733EB8 -:1036100038C1ADC50F0363DD59D8CFEF25BD51F8D3 -:1036200053DE2E0A94B8D1FFD56E662138CFC39FE2 -:103630004D71227E5C2A7C35FFF948A14F8DB4EF95 -:1036400097904E47368425F47FE7367448BE8BF456 -:10365000330ABF92D6DF24C6BF42EE37A2BCBA42BD -:10366000D071EE399915C7E8817F2BE0FA9449E8CB -:10367000EFA93D8F5871BC1E83BFBD08E543AA4129 -:103680007D2886DE4D6BCA2D5531F069C5B84E8256 -:10369000F3AB730FE85D641F69F2D6A4C90987AC68 -:1036A0009313C1648EB79ABE139CCEED21490A2CA8 -:1036B00047B89E9EFE8745C8B24E4B1D668C7F7FE5 -:1036C0005E5C6340AF31845769760CD28B57567E6F -:1036D000DA07EF4F7CB892E861320B507919E37A40 -:1036E0001FE8515FC7F92A70C931E7CBD0F590FDCB -:1036F000F9FBB812FDDE59E89F8B92FFF4BBE7257A -:10370000E2E3F1F0D93F009F81F89DCE0F9A2BE4C0 -:103710005AAE6857D10FEAC27894DE4F59D1ABAF99 -:103720004F8EEAEB979D8CF37B867C3F7767F3782F -:103730003F0EBA07E80AF9C16A11A71C150A572AF1 -:10374000B0DE3CD641F1C0DC860C1D5C2F378A3CD4 -:1037500009E69398B64EF8C995177E80EFDFE7D655 -:10376000F49F10E9593788F66F54AFFE761BDACE16 -:103770003B4DE40FB5C0E408AF6FCC5D321BCF7595 -:10378000883FB549EF47CD8D6D0738DCB0C7A46BD6 -:10379000F7FB26921DB054F86907F68BEBC8E2FBE5 -:1037A000CD2D1F3AFFE7CF0BFF3286CEAF8D7B2F9B -:1037B000F01BE4A3EC3C9CEB14841B438F03CB93E2 -:1037C0002312C6A54736311FEAC3B91B992F917F33 -:1037D000FF6501AF7838B3D01504BF59E2D948BBB3 -:1037E00091ECF4911B0DA4078E047E807C60D15A6D -:1037F0002017A8E7AE55498FBCB2C1C0500EB0F338 -:103800002DBAF761B9E4EFD4CEFD5E1C0FF5C87593 -:103810002C6CC0FD3495103DD1BAF207F101E0F5F2 -:103820000E879785E3F75493CEAF99877ECC18B86F -:103830006878901BF7BCD1CDE32E1A5D803C7BD914 -:103840004D78C2E55C21CA3958D287D34EEEEF805D -:10385000F55DBE99D17EFBD36D619EFF30102F3098 -:103860005E180BFCC932AB18FD2A3B149B01F31404 -:103870000EA7F7DDC7D219FB2DA8BFD533197BDE04 -:10388000D65F2A41FD8F0FFECBAE763894C3D6FEAD -:103890001FA2B3D77EFBE6253531F5D47FBF9BEA67 -:1038A0006C2A5365808F0D67807DDA9479078C30A0 -:1038B000BFCD632727A48D0DD029EDA76DBA7A3B24 -:1038C000E679B4151A484F62B1EDB08FDA4245D0AF -:1038D000B78FF2D8580D8FDBC78E2F3B2E32FE3CB0 -:1038E000187FD21718DFC2D79F8D8F40BE64E3FACE -:1038F000D14F8DE3E3F9A2B328767E319ECC427B93 -:1039000031BE02F3D9253E9F827924D94C9F3730AE -:10391000309F02F395FD03F6533BF43C4C173B8F6D -:10392000ABBFD879B4197CB4DED0783BD93F0C9AC0 -:103930000D53D0CEE0F35965F6825CCEE1DA366500 -:1039400010AEA0EFD1B8D07DD305016713C25931B5 -:10395000139C87835B8FC2F398B629B6F026D7FFF6 -:1039600085F372F2F38A9D0FF5C64B9EEF6A98CFEE -:1039700071E9F3217C917E06E00B67B239FBD2E15D -:103980000BAB0A5D0A7C7B605C430C5C07F385EE45 -:103990005150FFB79AFC162FF0DFEB0B791EA2C730 -:1039A000B1C442F903594B2C9897B7C563AFC1FC1A -:1039B000BD2DEE6516538C9CDEE2A9A376E84F7907 -:1039C0004E9E880DDD13AC8C45C9FEDF36B3DAB9E7 -:1039D0000AF1A789E74D6979449A3C64223E49FB84 -:1039E0008217D3BE72A8BF07FA6F6B9A44796269D7 -:1039F000E97FA6FCA81D0D5E2FB6DF67E571C6BB8B -:103A0000459C091195FC68E3A73F80F1D6F2C2F509 -:103A100012C517D75E3CBE587E265A8579566C155E -:103A2000CFA372D6C971F2504FB73B10AE3CDF291D -:103A30002C71F8EAC6BBAF308BC79FDDFB18DA7775 -:103A40004FC158463D7D1930EF289E1E65B34FA9E2 -:103A500044BD7CBD81D6918BA17C1071E5650B9C2A -:103A6000ABE0F9A8EB65AF04CF733CB752FE116829 -:103A7000F5A46F783CC7ABB03E649FABF5FB88DF25 -:103A800057FCBA417091BCD1CEABFC8C3719EDA874 -:103A9000F2C225941F463F1ABD1BE3F69389F6AF89 -:103AA000C16705396673C7EC8BE9FA093BED7FB650 -:103AB000BE0D9109E5627CFCEBDFFCB4CE24E6B5DB -:103AC00098E9BD3AB217B5B8DA48A41D3CF7D18CD5 -:103AD000C725E2DF9FC2DF674E1E674BB281E9094F -:103AE000F427DD6823FF655212D4E17C2433B38CC4 -:103AF00080E7F70ABFDF2689C9581F9C2FC270BE16 -:103B000056C9BFD3EBC292DB4BA6743FE517629850 -:103B100036D6EEECC1BC0D685FBFC695837EBB3464 -:103B2000208828DACD222EA5F949520BFA56A2FC9C -:103B30007EFDA1BF2CB1A07C46C7D274D0BE0B3F86 -:103B4000DD159A39489749E7463235C67E49929B3A -:103B5000287F23E9DC689D3F2522EC2EADEE73C85B -:103B6000D538DF7FA15D00F85CC994367CAF128048 -:103B7000A2C6FA47CF3975E30C8E3F4A376F04EC83 -:103B8000E7D838C0F0E32733B53876FCFC61C62FA0 -:103B90008A1B5F4938FEE0B899BA71B7C89C5F8448 -:103BA0001CB670227F5E5651D57924E5E1F2CB1C1C -:103BB00045DCCE057E2C53DC49E0CD6DCE26CA37E0 -:103BC00033DA787CD424E22547521A785EC4287D03 -:103BD000BE591553646CDF923AA75782F62ABB5E32 -:103BE0004FBFE2FC3B46E43B57C87A3DDDC79A082D -:103BF0003F2F67FAE7A6517A3E7010E903FDFE29D0 -:103C000093A294979665A73C83E1FC076FB530CAF1 -:103C1000973225FB9B50C695ED4FCBDCE2847A1A98 -:103C2000C7AF19FBDD4BD11FF496C0E32D40F70859 -:103C3000C7BAF5397B8D31E3D69923852847EA0C3D -:103C40003C3F9F7E60FEB7B246923F357E5ECAF033 -:103C50008DF147D537497E77CC3EDE12743130DFA7 -:103C600086DCBDA8C70ECC9714994CF30DE4F988F7 -:103C7000F9B2BFDC7C6F0B7AD6E6ABFFB67E7FF580 -:103C8000E628EDAFDEC0445E3F9FEF6DDC9FEB4B5F -:103C9000CC27F2B506E6FB8E7E7FF54951DA5FFD53 -:103CA000803D29E6CBFE72F325999B281E7387C4BD -:103CB000CF754351D99DE88F3FBB60BD8AF8A6D927 -:103CC000678BF005C0B345229FE9CA5166D21BB489 -:103CD000710FB44C653E33F7DB60593C53A2FCFED8 -:103CE0007153251FC6C3F600DDFB8AD02FA5507B7C -:103CF000B8C549E5BE1695CA07C11EF4917FCACB67 -:103D0000EB45DCCEBF6384B26235EA0B95369EDFAD -:103D10003C730668A283F61618603D56CC23FC1A45 -:103D20009BB81D6A45BB393C1CD5D9613C27DBC417 -:103D300017A22D504F9A6654316F3BC9C5FC89FCC0 -:103D40002E3F28E2FED8DBB47CF8AF483CDE0EFA0A -:103D50004825ECFF5A016A665C20A15E75E577D2C2 -:103D6000491FA95BD697A2C03AAE9126FEDC0DF0A2 -:103D7000F8ADD047AE1DCDE938DE9E74A0649984BD -:103D8000F97AC670187E5D9AB294ECD1A5CB19CBA6 -:103D900080F7AFC4F740AEBC2AF49957FA9218DA0C -:103DA0006BA16A1E67BEE656BD1D798735A2A01EAF -:103DB00077C74407C3F3A8DBA86FBF4DC40B96C6F3 -:103DC000D99557C6E5D180964978823C814D83F3D9 -:103DD0002A4A71507EABC8A3B9BA48E57C6E948379 -:103DE00092A833E6BAD330FE98644E7CEF461BEFC0 -:103DF000A8E03BCCE12338687967CCF8D8447A5FF7 -:103E0000CCA7BD77AFF4D8888BF935416F7BB7AFBE -:103E100098CB67D4AF0FC6ADF3EC82FCEF55B3443B -:103E200078DB2FA35F415BFFFF297CBD097D1AB0C2 -:103E3000EF57677D3289E22D6C14ED7B91863F222E -:103E40009F6AE9405D66724C3E1D73F67BF0BCDFF5 -:103E5000F84AB2773BE19FD01F226F1A2E247FF1E0 -:103E6000F106D6E1F4E5717F5CB542F94062BCE150 -:103E7000E01C9FEFA0F96DE82726DFB0752FCF7704 -:103E80001CE9A8FA00EF45E1F3777478A5BFFFD4E9 -:103E9000DAFD8884F6C57D789F4B1E9C0FFDB4210A -:103EA000D25FF5F7B2E2D7A5DDB7D1D6D36A66C542 -:103EB000648F1A803FC07C0BED7DB2A4A2DFBD5F92 -:103EC00046FC2A19CBFD449813CCEFB9703DCF982E -:103ED0006BE0F91B6354AEF7B9FB47C7C685D2C682 -:103EE000F278DAC2E4D736AA20FF4C0F6F5E8AF967 -:103EF0004B0BD35EDBE882BAE5E1565ECF7DED1376 -:103F000017E86CB687DB78BDF4B54FF2A16E7F7809 -:103F1000CB52CC675A38831150521FDE4AF2326DB1 -:103F2000AC664F4747E17C0B254E1F5FB634261920 -:103F300012C6EF9D63353F2933E13CFEAEFF388961 -:103F4000FCC8AFF95F7DFA7823C3A66CBC27247E3A -:103F50001CA9A4CFCCC3DF019EF3E54837BE6FB0E8 -:103F60004408AE63316FA69850E0AE0B17C98F8836 -:103F7000C72309D0B519F565556175A01FB736B3CC -:103F800080B52006CF994FE039CFE3D1D6A3CD3FFE -:103F9000645D70A47246ECBAF6D038DABA4E4F4C73 -:103FA0000AE17D322D7EAAADEBB4D47F3F3A23BE29 -:103FB000F9C3CEE5786EA753FA474B503FF1F0FBBB -:103FC000748EA7B3FAEF97BC3175133FC7CB1FFEB2 -:103FD000C152948F1B25DFE563317FCE6CA77B6BCD -:103FE000ED42CFDB91150831AEDF53BE63288FDF82 -:103FF00007A89E24F962E3FB3502BFFE632CD71F9E -:104000006727ED6C3A01F8183C24B14DD03F78FE9B -:10401000AC19EDF1855DA7CC6877371E3A6546BBD4 -:10402000BA11EB304EE31E33F1AB78781F1F6BD41F -:10403000C5D1357BE2685ED11607ACA771B5E4C582 -:1040400014D9F5CFA6CFC6FAFA55B84BE0EF330F27 -:10405000CE4674A9F7776FC1F25AD67714E3052BD1 -:10406000027A3D7F65835E2FAF6FD2EBD3D7EE84AC -:10407000D301F9756D73AEEE3D861A32AC678538A3 -:10408000CF15CEDBA3C6F1588FB987231159937F83 -:104090006725DF01947ABFC5C22E89E8B8B1D64240 -:1040A000FED7A3793C7F3EB8D6487941414407AC5E -:1040B0003749C29FE523FEA8C9EFD99D678EE5E287 -:1040C000FB6B4D040716F245D1AF5F2BF0E9DADA4E -:1040D0009A0F10CF6AD51BB91C1FB3DF44FE9500A1 -:1040E000D7C755E1FFAEEBBCA33A03F5CF8D12F96C -:1040F000375636E8F5F57AFC05F5B766291C7121C7 -:104100009CF4EDD736EBEBDBC70A3956CA4A914E21 -:10411000BE375692896E44FD4F79BF78250213DD74 -:1041200022F97721DEAD3547C6A35CBB450A505D59 -:104130006B87E78D5CEE70796F008A22BE6BE27E42 -:1041400085D03A89F071E510F91FA31F1887D68F23 -:104150000A7ED26AF56F247BE93949417DA45AF67B -:10416000C9199E417B361E1F8F093C7F85F57970EA -:104170005D450874807FD1D2B430FAC38A9E5F4512 -:10418000F98D451592D740F46C60CDE558CAC41F2F -:1041900050DFB4425964ECA8257E3DC1ACF0FC412F -:1041A000278BE503BE479884797CB8749C77FEA87A -:1041B000DECFF01C17EDBEFD0CF23B7781AFFC0E9D -:1041C00058DF0E2B9F7FC7B312E9AF8D9E63C417D4 -:1041D00073004D70DE46A7E08F9DC01FB5FDC3790B -:1041E000E720BFC20B210B3C34EF082D3EA0E5D7E2 -:1041F00046AA0C1780EFE488798F97A9B4EFEC1BDF -:104200003B24DC771E0B6D423FD18FC7327AAE95CF -:104210009A1F7FF960BCBA06CF739DB3CF4CFAB733 -:10422000885727E8B764ECE404FD7C4CE747986DB9 -:104230003C9F8A71E5F5CF155C34AFC26831E8E880 -:10424000D5A4D874743DBF584FE70BBD7AFABE723F -:104250006A81AE7DB1AF54D7BEB4A642575FEE9F20 -:10426000A1EB7F55ED2CBDBDEF9CA7EB6F5597E8FB -:10427000EAC9C557EBFAA778AFD3F31B4707E50F99 -:10428000982DA1BE808AF7E6199B9A31C8AF4B538F -:10429000A13394B60AAB1DCBF68949113CB7F69110 -:1042A0003C9E9AF4E2B79C11847ADA63964A287F9E -:1042B0002885AB305E6411765EC9AD4CC7CF1795CB -:1042C000723CD74A5371401907E7E339A0E6F27C04 -:1042D000E968099E8F051D8888C74F5B48EF9810D5 -:1042E000A7FFBE5256692B467FEBADBEB9E497EAF5 -:1042F000640ADE97DD67E6F94CA1A779FEACA7B3A7 -:10430000CFE08BA1B7BB8B397D7EDF5F45F9498D4F -:104310005D20CD10BF77BF6346BF5D6357772ACA64 -:104320008DF1FE77CCA85F0F3E17F244EEB761FC2B -:10433000F2898EC47968738ACD34FE31C16FEBBFC8 -:10434000C5F92D20DC02B48F34FE597F90EFAF7E8B -:10435000B999E85BE3A3C03F75F1B078BEBC726663 -:10436000780BD22EF0519DFD72EDB2391FA03DC4E5 -:104370005884F418E0A3FAF6515B89BEAF8DB36F91 -:1043800026150FF053CF05A097937E43C27D2D2DA8 -:1043900095695F2703B308DEDF07B8A1DDF8FD21CB -:1043A00070E2F0FB3CF83C2EFC89DA39C5F7AB2D06 -:1043B000E5FAE8E3C3F0CB3DE21CF749D17264664D -:1043C00041BF8DF074A5C5B21CF30C8EE57DBA1506 -:1043D000E309F53F96D09665BFEE7E311BF30ECC18 -:1043E000078F66633E44B0E368360338AD35A99B5A -:1043F000502F063CF06E827369EC8CD0FAD775545E -:1044000074E3F3759D92175961F0D09939B44FD682 -:10441000B715F5F87DC3ACEBBA62AEA7AC2B56A9C5 -:104420000C06604E94B38792C88EAD3F087C08D7C7 -:10443000F5AC44F730F66DB3D426D24FEA4BF9F71A -:10444000185ED866661847590BEFE33E8EE51D33BC -:104450005B106F0E4A6413063B4E2C477F7C70A3A3 -:104460008961DC565BDF8779D1DFE0FEDF5C6D625E -:10447000786FB075358FC7BEB9D148E318AF3751E3 -:104480007DC51A9E277C64F5EFB6E6C2B86FAE957F -:1044900028BF7ED6F5FF790CEB2BD6703D281E7F0A -:1044A00007F0350E3F5704F47837044F1BBE1C9EAF -:1044B0006E1BC4D3F12867E1DC67E720FEDCCCE8A3 -:1044C000DE62EDF923A61C586FFE56C58BA1DD32C6 -:1044D00063784B36F28523BC7DE2DABD12E72F2AE2 -:1044E000DD67CF6D3733CA532CE67C680F9E5716B5 -:1044F0006EAD5FC2BC362647F3717D2E91C7F5A421 -:1045000089D51E443F92CCF94BD933CEBDB17EA4A0 -:10451000F9021F35BE570AF6FE41F243778CC47B81 -:10452000E68F9BB87F6CB418AFB0A07FCE6228BB7B -:1045300004BEEC17EBD0EADF10F8CF3AF6911C5D21 -:1045400068E1709FD71CA9C37DDC20071E43FEB71E -:1045500060F42FD6A25C6BCF7FC913203F5709C9E7 -:10456000B5A0388F23D3DEDBB301F3EDC6D9E81C49 -:1045700017F7DC13C5736D74CB9467682D9C941387 -:10458000B8881F21784ED5DDDB6BEC3A33C79780B6 -:10459000AEAF13EB2D13F7F35817F71F003F96A795 -:1045A000960FF6D3F6AFF93DAC850FD2396DF826EC -:1045B0009BC8EFEDDF417058B9F68484F752AE32F4 -:1045C000F94C7680F32FD2D872B4835F6A61744F4E -:1045D000ED38DE570356F24A8B42F5A8B8B7F65AC3 -:1045E0008B4AE55566FFAB089FE52F341522BC8E3C -:1045F000E4DDEDC7EF309C3E2EF459A6F07B8C0233 -:10460000F7CE76199905DACF1E92C2E43411EBBFCA -:10461000E6DC4816007EF22B713F6E5DF3EBC4E7DB -:10462000BC0D67E6A09D3171EDA9AD580F36FFE7CF -:104630001CD41B7E037202F12BD82931278C5377AF -:104640002E83DE5FD779C28CF6FCE386FE3908FF45 -:10465000D06189EE55059BCE10FFDC23FC2B69E36E -:10466000781C31D835D140E7E92BE1F68938FFEEE7 -:10467000923FA722FFB234ABAFCEC073EC35D23934 -:104680006EAFEA4F55129CCB491817F3477E25F2BF -:10469000F186F0597388FCB2B5026FE3DB93C7195A -:1046A000343BDC24F2949804EBA913F8558FDF8394 -:1046B000C9403D5F8AD8806EEBBB66917FA3BEE99F -:1046C000E2DF77190EDF2EB56C64DCBFA1D5D1FE19 -:1046D0008ACDD742FB4B7F0F3DC4EF71E5B9730222 -:1046E00017D1EF827D23297ED2D8CE285EB2EE5C30 -:1046F00009951F3D7B1BDD7BB2D8FAEF46B9C08A16 -:104700000CA4D7AF0BE9F59B4F4B381D7C5AC2E97F -:10471000B8601CD8271636609F801D5284FA0ED8C8 -:1047200021A93D4C679FC43F27FBC422FC86A02ED5 -:10473000059E4CB0EEBF9454958ECB42BADA49F840 -:10474000CD00BF11AFE2F739651C5F9746CF2B7ADA -:104750003E30A3BE1BEC4C4CCFE6D2CA2938EEB695 -:1047600061F2EFCE8B7DAEDBCD085EC1DD1904A713 -:104770000FD96E7F15E0E587B00EBC977EDAEF4F5C -:104780004E87F74F07FCC9189FD3E8BF71B78DDE7E -:10479000DBE65E9289DFD1982FF0FEA3CE59168416 -:1047A000F335BB39DD69F3FD26B22213E967B2A9FF -:1047B000DF8CFEC9515DA75251AF9BFCECD24CA4DB -:1047C000BFE1D639A384F3E575CD2397D3BD1FF898 -:1047D0003102DDDF24E4587073C48CF0BFA9991155 -:1047E000FE763FFDEB46A4DF8FBA921594931F3EF1 -:1047F000971C427E7FFA7052D80043AD15DF3FFA16 -:10480000D0D4B788F4C7678D94AF103CFCC7BB9178 -:104810001E834F27D13D9A9BBA6E3B83726E6DD734 -:10482000DC0F642C1FFBC7D2C3BAE6D1CB63F38B7A -:10483000FFD8726024F2CF8F64CE276EEA7C8AF4B0 -:10484000D99BCE9F1D8FF9831F3EF79729C8CF8232 -:10485000CF9F9D827C2CF8D3B353B03DF84C72535C -:1048600022FD646D29F79F68F2D1F586ACF3B3643D -:104870000B79E06ADB5983DF29987C6219C501B4A2 -:10488000F6C985063FF69FFCF3EACCEB63DE6B8B43 -:10489000CA942F31E94475F2EA18BC4C2E35697E72 -:1048A000BA4BF38F883C04CD3FB22D2AF37B750DB4 -:1048B000C630E6F1AE8CF2F87BBCDF8431FFFC320F -:1048C0003CEF35595EFC3E0FDE4BC7B8C8E99B0B89 -:1048D000C3742F3D6439EA8ED18356440D9124F47C -:1048E00083742545501F5A11954F25C5F8457EA361 -:1048F0003CB905D5F81501BD1F23DE0F023F297213 -:104900004CFCA47E63C4A4C9A98530FF2FB6300532 -:10491000E33643FC23B55F253F4CBC9F448DDE65E9 -:10492000C1F75437FF9E8EA667E2791D4A40EF1506 -:10493000829E353A6A8B1AE81CDAA2551637941E05 -:10494000414787406C86302FA86BE94368A7B79D25 -:10495000BF2A19E1D5F6C61286DF8B38AD54590A45 -:10496000F1BDF35FB52CF70CE2C710FE318EF3C733 -:10497000017D601839F7A1E05BFF2879F7C13F8915 -:10498000BC03BBBA1FF937D8D52BB9DF83DBD5F110 -:104990007242E3BFDAB8AA38E7A1FCF703D25FC0DE -:1049A000FE25FEAB96A8D46F54D7E24CB28BDF58ED -:1049B00096A9DA878E5F207B0D199EA1E36BFA5AC8 -:1049C00030E43B6A413BC6C7F34F83CB24FA6E54B5 -:1049D000D02F919E1DAC3385B15D5B4F74198F0B49 -:1049E0002EF74AF41D104DFFD3F4C381F649D0EEE3 -:1049F0001AD41735BD30EAE77ED1653E13B55F6541 -:104A00000EE4944CC6FD59E9F9E4697C5CE0034787 -:104A1000D1FF79D5D724FA4E97A62F6AF819AF4F50 -:104A20007EDC5570D1EFCFED1178A9D1D7E838BA37 -:104A3000D0E4D47C81EF8D28A733514E7F66EEB34E -:104A40000FAF77839C2E2DA1F718BD3FE9E7B23F4A -:104A500091DD7D588C3B433BB7E80B95B8DE3C16A7 -:104A6000A5BCA8E1E467AEF0D30CD73EFF12E9F88D -:104A700086927F2C1D5F57F2CF41C703FA9F39F111 -:104A80003EFF52527913E2AFCDD844F7A3D8CF4CB2 -:104A9000E4B78EEFA76AF6A4CC74787C34CF6C4070 -:104AA000BB27D8C0EDFEF674F555B24F5EE4F7EEC5 -:104AB0006F12F94A379E53A86CC70F8361FBB75C2E -:104AC000E4B7B9F1C009930FDE5FB9519A88FEA02F -:104AD000950DFAFDB467F9E6C6FAC1DB4774505C80 -:104AE00021F450818AE3D7E366D11FD23E328CB1E4 -:104AF000C746F4E34CC0E731F72D609E75E2F90C30 -:104B0000E1DF61717AC04FBBDF247F0FC685907EE5 -:104B1000CD5D12E585047BB9BFA3B18BF385F71B8F -:104B200024E227EF8BFC8C60B395FCDB9A1EF181AD -:104B3000E8B7E66689F4BD217A854F1F7759F7E01B -:104B4000CF892FC6EB111987F838186F41BFCCD128 -:104B5000BC2912D6D7815D88DF250DAAEA95B97CDC -:104B60007D2C4CFCC5A7F3A37CDCFB3BB223573E5A -:104B70002BB14CD23BE2E22FEDF3E2E22FC78EE6FF -:104B8000E23842CF50E03FF41FC6EB198D9D274C11 -:104B900068177C5E9CE59912BD5F708CCCFDAC63A0 -:104BA000BA2405FD4963049C2EDB662338CD797B4E -:104BB0007526D2B9763E1F2DE6E7F5D19B9F54E2CC -:104BC0007B53DE9615E4B73F7D73E3EBB9BCAE5A79 -:104BD000547C6F6332DA211FBDBD3E19E1F85328C2 -:104BE000F1FB48CF9C9413FA0F0B4B39BF01F976B8 -:104BF000BC84FCBFC26F2C837C4B19F4BFC4BF378D -:104C00004BBCD78EDF2D42FC7B96C7B7DB4704E653 -:104C100051FD9E7C9E472C737C7DAA2B5D417DAF10 -:104C200014368B71D81FD9581BC657DAB3022F110F -:104C30007DDC6320FC85F7F977270EAA24EFF08A44 -:104C40001DC63FC683ACB1505EA383FC37DA7761E3 -:104C500046801D2ABEA3B00CE3AEA5220E32DEC6EE -:104C6000641C7F8729B07D1CC65DBA65EF267C4732 -:104C7000F666E27790E2E3315A7C588BCB6871E2BA -:104C8000E1E23212CE339EE359EC774EB4F80BFBDF -:104C90001ACFDF6C9DDA44F75F7B31469238EE32F3 -:104CA0007A5C82784AE938ADBF3E9EB6BDF849C20B -:104CB000B72F1A47BBA164B8F9556E77C6CD3F2907 -:104CC000FDE36CB25FFEFA5FA924CFBACE92DC3965 -:104CD000DD9F24EE71F6713F759789ECF5D360077F -:104CE00065C5C8B3F6717CDC9EAE59848F87A2D5AA -:104CF000C9D8FF09F17CDB1BCB96A23E1D8ACA3CBA -:104D00001F9B71BBE650549ECCF5832170BAAC2436 -:104D1000417CCA624B9C07F49EF017BC27F63DEB22 -:104D20004D6EAF0437F2F88122E82D5863267E726B -:104D30002C2F5BD2FCC83989E20BCFF6139FAD5FF5 -:104D4000C3E3BB971C5FE8EC36B1FC047EDB9A3909 -:104D5000C46F2ED55FCBD00A9E32C89F2B4BC5F7B0 -:104D600086CAB8FFF6C5127E5F27A36962257EEF6B -:104D7000EEBD61CF3B70B0F4D2E27CCF7B2EAD9F15 -:104D8000A138513C7068BFA997D86FCE25F6BBA15A -:104D9000F8D2D6D77589E3EDBFC4F16E1997A8DFB5 -:104DA000FFA3F1CFF8F8667C3C343ECE99F4E2F5EF -:104DB000216CBB4DBABD3F82D04D7DBA5602529593 -:104DC000D31FB4205F5B308DC703B6555BC27BA594 -:104DD000C1B8A806AF87CBB8DEA578CE84F0BB8873 -:104DE000A37DD1EA4CA0E3D3D318D90DA7ADE27BC4 -:104DF00048B23262319D9F42DFC369B7268E2FAD24 -:104E000014E30DC7475E29AB7CBC7432DD1F4AF842 -:104E10009D8AEA526E67289D8CFC354C56472CA122 -:104E200079D5112867D25EE0CF53238CF2FBA0DD49 -:104E3000B584F467D585EBDB25E25E19F38A5CE87F -:104E4000A7CB00798B71913B303E427E7D85FA691C -:104E5000F34DF2F0F97699988471ACD0389E57C131 -:104E6000D42788EF68718DE3A6C8EF574914D7E8B7 -:104E7000C5F5BF6C8878F6B9F8B9207C3D87148AEF -:104E8000B7BC32EDE162BA172FE21C1B14DEE50855 -:104E9000DA19B08E0DCF5510FEAEEC99F6CB3AD4A0 -:104EA00007DD32C179881E2EECAB93C23ED4ECAB49 -:104EB0003EB41363EC8DB784DE9080AEDE2A4D40A5 -:104EC000A7BB246EFF865EE6F66F85D95B109B4F0D -:104ED000F5BE80FFAA08F7C36A76ED785FD8900D1B -:104EE00070A8B8D9184902395DB1B5CC8CFCBA624A -:104EF0006B9E8DFC4AAB0F1A3478273AF78FC53A70 -:104F0000B7F5F6535CE2A9F87BE61E33B5EF15F86A -:104F10003309CF16CA0D85722B8ADFB4998A319175 -:104F20005FBC1EF47E5CDFAA76BE5E2D0E521F5162 -:104F300067E13CA78EF66FC5B2BCC1358BFC866BB2 -:104F4000CF6C45B9193C7FF6D815E40730AB89EE34 -:104F50000B3C5B6624383C858A08C26BAE4C79BB3F -:104F60001573653AEF8C7A2BD9E1192666C4EFAE3A -:104F7000662CE672ACBCC6310BEB6C593AC9E1F257 -:104F80005E35FD7ACFA09D9F31776316C2E9F3E2CB -:104F9000439ABFE02AB32FD333F98BC787D61D7F3F -:104FA00083F2CCAEE9D3C787B478CF70F1212D3E20 -:104FB0001BACF944174F0ECAFD73D0AF52F1DC2978 -:104FC0008A0F073B25C5E91A8C1B050F9D31137C01 -:104FD00045BC08FA9BF1BD0A38F61119F8BD011E4F -:104FE0003F7A1AF371CDF83D3D85F26E7F82F9B8B4 -:104FF00045F83D3D9E8F7B18F371CD78FF83E7E345 -:10500000F688FCDE60D7198A374DF30CC9A7A27861 -:10501000C42D927FA6479F4F45F5F87885D1C6ED00 -:10502000D060AF89BE771E3C6E213E5BD9B56A0C5D -:10503000EA63DA77C81B315E10E35FFAC8E7B5E2CE -:10504000FD9E8FFC5E2BC6092ABA3F30ABC4772287 -:10505000B998C2D42847CD68EF231C28CFAFABD274 -:105060008A70FD5CBF7EE7FFF7EB7F11BFFEE13288 -:10507000EED7D7F847B9DF40F7CACB7B7DD6EB63D5 -:10508000F8C3363FF70F6F73E713FDDDE5CF4F5FD2 -:105090001DEBC7AFE1F65BC65CB735F6B9713CFFF7 -:1050A0001E448694F87EC1768F61383D707B62FD28 -:1050B0002E713C605B0DE7239ABF7F687CC0FBA22A -:1050C0003BC6CFFFD1CB16FA7B0ADDCF26913CFF42 -:1050D000F4B9A47DA87797D7AC1E9302F5F2934953 -:1050E000CCC5E5912EAEB0B2C6E0B3A6268A23F8B1 -:1050F00072E97BA1F1F1821A03F1F78178418D7C8D -:105100008AEA423FBFE6CC7B29F8E9EBA7A4703BD3 -:10511000DA174FAD93BCDD6C68FC0006CE655361B9 -:105120001735DC4EF0D65AC82EF8BCB842DDA113B4 -:105130005BD04F3091ED6CC7EF4F4E741B14104590 -:1051400009E20A3CBFB35CE811F1FE01C40F94FB15 -:10515000F17EC1E7C5F93D2FE4FE5CD4F9B306C783 -:10516000D1DE8B3F77479974513FA32CE4565B4DBA -:10517000F9363CB7D0020343FEDF56536571C78C46 -:10518000F79A87E7CDECC2388523364EC1E311F19B -:10519000F1098D3F55747F3607CFFDAE2EEE3F0AE5 -:1051A0003AB93FB3E27025DD33195C27DFDF5DCE0E -:1051B000817B86E98CEF8B59B89F8BFC0AE50B3E0F -:1051C000E9C1BF37C0FCE9F4F70B82C7DDAD76E477 -:1051D000230BE4C9924AFEED017F37FAA396BEDAAB -:1051E000300FF3812B964F3C81E7B2BCCE44794718 -:1051F0004B5FADA5EF8A6BF2AA62F9DECDF8F768D6 -:1052000096174B5EAB8AED3555D83EFFB1087AF65E -:10521000D8425C1DD04BF438F4CE27FFF6C7483790 -:10522000158B85DFBB8ECBD5E55D8B4DFCE3567AC8 -:10523000397724EF53B29BCF7655903F3B13E3ADC4 -:105240009E413953F11CC89F9441F9F3F7CA1D4799 -:1052500019CFF39F00F207D793B198C705E3CFFFAB -:10526000350F3FFFE1E4C970FC13E507FF7B3BA16D -:105270005CC939287755B4A72F1B94BF4A27D4732C -:1052800086C7BF7902AFD387D1BF660BFC1C365FE0 -:10529000A3F31FE3F7AE2CFB27F17B0BFB46F37F59 -:1052A0006BF6D07D02CE5AB947F08DBF3B5F1985B2 -:1052B00062C27CE58CC4F9CAD77448F41D1691AF5C -:1052C0007CD4CC2A0F3A304F4FDC4B08FB49BF3916 -:1052D0007AEFAFB63EE2C07B09928262675DC70992 -:1052E00092CFEB409F213DA8EB8FDC2FD5C1F34B34 -:1052F000D775EAEF3F68E5112197AB613FE44716A8 -:10530000797C730E71BA0EFACC61D5857EA16FCB14 -:10531000B17EA1A01ACDD2F203C35C2E25CCE36BE3 -:1053200064FD94EFD7D82079511E7C693F918FE7B7 -:10533000F75DAA9FA8AD4CF885849FF99152CE0FD6 -:105340006A039284FAA8C5E05F4BF9BD8725255111 -:105350009EE8BD02DFE70B3FED7E33C783FDD3251B -:10536000CAABC57B3178BEFB0FF3FCF9FDE53C7F92 -:105370005EF3CB6A79F1E306FDB2741F46CBA7D783 -:10538000F2E3B5FBA18B77DB22A85FEC3075389197 -:105390000EB5BCA2F9A88B601C467C673C7E9D5B69 -:1053A000CB2AE79751BF61F59BFD6509F49B33421A -:1053B0007E3E56A6CF238AD1CB9F289BACD3CBA9C8 -:1053C0001EAF97FF4FF965E70CEF17365CA2FFEDB4 -:1053D0005B97D8AFA12C817DDD6A4DFCBDD0D4F1A7 -:1053E00082FFC6FDBD1136E47E0F976FED92FACBBA -:1053F0001914E732519C4BE32FED297CFCB7055F74 -:10540000D1CA7382DF0CF75D49E378DE6FA3E47BDA -:105410000BCFB1F480DE4F56D6A1F7934DE8CCD038 -:10542000D5274646EAFA57F4E6EBDA27474B74ED00 -:10543000979D2CD7D5A7F54DD7F59FF17E95AEFE5C -:10544000957EBD9FEC8A734BE2EE1D71FCAE048C21 -:10545000887D6F96E5EBBA7EB90DFA7DE535E9F703 -:1054600035A659BF2F6D5C5748BFBF8276FDFE320F -:10547000D07FEFF9F2FEFB4D1E55F8EF0BE8BB7F36 -:10548000BB6ADCF49D6BEDFE9FD6EFBF0137C3FC1A -:10549000BB80700000000000000000000000000061 -:1054A0001F8B080000000000000B53E16760F851FB -:1054B0000FC15BF918182EF021F8F4C01CCC0C0CAD -:1054C0009C40ACC8C8C02001C4FC40CC06C49E0CA3 -:1054D0000C0CFF81F81B10BF05E22740EC0CC40741 -:1054E00058B09BE3C6CAC0E001C4DC40B3789889D9 -:1054F000B7DF8917C17ECCC3C0700E889FF1D0374B -:105500000C061B5E27403FBB7E43ED3A2932F0FE7E -:1055100006612131609A1447F0A78AA3CA0B8B2138 -:10552000D8C9D294D9950FD40F00F19321F08003FC -:1055300000000000000000001F8B080000000000B9 -:10554000000BED7D0B7C94C5B5F87CBBDFBE92DD16 -:10555000CD26E44900370960501E4B80C84BDDF072 -:105560003252C40411828A2CAF10027914A9A5FF0B -:10557000DABB0B2804AADE5851A37F6A17041B2D3F -:10558000DA80D11B6DE02EA208D56A684551AB0DBB -:10559000888808498C8F6AB57ACF3933DF66E7CBC4 -:1055A0002E89B6FE6FFFBF7BC3AF1DE79B993367A4 -:1055B000CE3973E6CC9999B3268385192E60EC1BFE -:1055C000FCBB9C319B893136A62B6D573A86AB3993 -:1055D0005DE5B7F9BDCC6B66ACCE6FA5748B3F9D16 -:1055E0007907C3779FA1306867EC5EBF8BF2BFF08D -:1055F00017525AEB2FA27A77FA4B287FBBDF47E985 -:10560000667F197DAFF157537E837F0DA59BD445EF -:10561000692C05FA66458559C98C553D9393B71990 -:10562000725B668D4F504743FE15233366017C9FA6 -:105630004AFD31D5BD69E0E8AE7A1A9E9BD449FD9A -:10564000104EED128E17B3325B8C7A5938CE3B97E1 -:105650000878F6D69A9CE4A8F50623BCDB4B00DE5E -:1056600050287085AC39D1E15D8CF03697A8BC5ECE -:1056700072B0263B3A3C0FD6ABB941C04B0F5863D2 -:10568000D41B83F536DC20F0EBE7ABC98ADEEF787C -:10569000ACC75CEADF5AAD8CFEBEC9C6FFB7BB4ED5 -:1056A0005D2CF246CC263136AEAB9D3E652CC070EB -:1056B0009C2AF315121FDC995F7F93CFD84D0813F6 -:1056C000DA0726B19011FA0F24B1E0FA2CA9FE4CAA -:1056D000AADFDAF7EB6F52A5FA014394FA26D6A0B7 -:1056E00060F9CF518E80EFF7F97329DD28E4E7BE2A -:1056F000A106C6B05DBA393808DADDE3F790BCDC44 -:10570000ED1F4BE5770939FC7721674121670FA22F -:105710009C41BA15E5CC8CFDF95A4B014EFBDE7865 -:10572000B6D94DF2B598F05419C1DFB077C8F6CDAF -:1057300000FFBE1B569DDE06F46F6B1EE63142BDB8 -:105740007B866AF2C5BC2CB9ABDE3DB34F38170D72 -:10575000257A97219CBB3D827F2A0C2CA2DEDD336B -:10576000C2F52AB0DE5D9E30BC5064BF774D09D7CC -:105770005B457C56584983BD3B5F763085E6230800 -:105780000AD1D784F48579F9EC80EB9456689F921E -:105790009C97C6A0DDFD381FCD38EFDC4417AD3D2A -:1057A000D2D907DF332CAC1AE10365F71B015FD3B5 -:1057B0006C7722D2E5F66B8B98328CB1BEA23C3569 -:1057C00050A464015CFB9C2205BF9B6643397C7737 -:1057D00089F2E435BCFC762C7774952762397C4FCE -:1057E000AA8672C8DBE7F2F23BFCC089C15DF536E0 -:1057F000019F7DC4EF74FE1DD88AF4318DE6A98621 -:10580000F713282440BF83988EE9C27FD3A07B334F -:1058100016DABBF0B50DAEA7BC86DFA6C17194D772 -:10582000F0B15DD82F6321A47D97F465DE5C311F54 -:1058300058773A277AB3A5F24CD593A0029D325FF0 -:1058400032B200B02013C413E1E9DB153103E1D912 -:10585000E3FC4BEEDDFC330D95E9A0A547053D3497 -:105860003A6CEC2FD3C13240A6C3C601321D2C17AF -:105870009C9F0E3B989BE81C8B1E5ABF9B87C8FDC4 -:10588000C65D24F7BBF922B9DFB88BFF39FDD664BA -:10589000C9FD5AB3E57E6BB2E57EAD39FF58BF4C0A -:1058A000F5C064407DA5FD5D28E9B7AB99EF2CB646 -:1058B000473D87F349D373A6641FF3D9BBF809EBBF -:1058C0001463F99170064B7A15E07C8AF5008EF727 -:1058D000FC705C3A3883F470BE16F8B0483DDD0DBC -:1058E0000E1BA81F8749E1ED428688FE99EA6345B1 -:1058F0008EC8761E5DFF39FAFE9D8A1887E1BCFDD1 -:10590000BB7574CDD6E39326F06186F3D183B97469 -:1059100070B2F470DC029F90725E386EFD382E1407 -:10592000FD071469FD027A0CEB6AD70EF8D13A959F -:105930006709EE04FD10DAF7E5295C07CE355EEB6A -:10594000B640FDFD232DA1CBA1FC5CB0206881F207 -:10595000C94F1E75A21D53F1A451C572C33E1BADA4 -:105960002F6D3B142AAFB2B4DC3901CA3B9E34B26E -:10597000EDD45DA601C7774AE81416E2F9521BCFB1 -:10598000566CDB7F23B62F6BB2301BC0AB787AD955 -:10599000CC09905F76C8C4B04AC5CEB5E6BE905F6C -:1059A0001E541A300FF8D23A15C8B3057742FD7568 -:1059B000FBBE6C43FCCF359A06213E67609D70C3E9 -:1059C0003AF192A3257536D0A73CB87B1AB62FDFE3 -:1059D000A57840C301FE3B0F6620FE8F281E0BB04A -:1059E00070457D3C7347CC97538D461AEFAA6D4A9C -:1059F0009001BC65AC761AD2B302898378782C41C9 -:105A00009BD235DFCEF8EBA83F2D5FF108F407ED10 -:105A10002B1F573C38E44A03F3E13C6E7BDA56F225 -:105A2000901DC7BBD63CD881E3DC68C67ACB820B1D -:105A30009FB2B911CF6DE66988EFD66DE6D2A14865 -:105A400047B6A06828E2F77F65FCEA8C5E1CEFAAE7 -:105A50009196ED46C083D943036739BAEBD933B089 -:105A60005EB923D6CF72067A9FD6EFA0B97858D701 -:105A7000F72F0D89A43F56D41B99DBDAD58F261F4B -:105A80008123423EF63A88DE1A3F57B9F814D0F81F -:105A9000B92A51F057EDC89F35AC3B3E77225FC81D -:105AA0009E7651FA0B583731DD02EB3CD2EF5EB0F7 -:105AB0009FDC64977BE8FB03602761BA15EC244CFC -:105AC0001F043BC92DEC24ACB71DEC244C77809D02 -:105AD00084DF1F067B1CD37AB0C7F1FBA3608F6302 -:105AE000BACB1FA0EF8FFB6B286DF0D752BA07F926 -:105AF0000669A33F48F59EF2D753DAE46FA0EFCFD3 -:105B0000F89B28BD5DD0D1399115E03AEAF43217FF -:105B1000923D6986B7C004F9A4229E4FBD21506012 -:105B2000867CAA0FF24097BE2B430516C8F7ADE658 -:105B3000E5036E6193AC901F10E0E5D9B77B27D9E0 -:105B4000209F5DCBCB076F0D4C8A83FCE0202FBFDD -:105B5000685768523CE42F6AE0E5C39BD9643BE494 -:105B60008787783EEF25EF6407E4F35A783EFFCF4E -:105B700081C94EC8E7B7F2F6E3CF068DEE28EBEF0A -:105B80001E937B31AA9C03CADB5E3503F266F74D98 -:105B9000A8128F2AA728DF68F252F9FB4ABB578563 -:105BA00075BED1ECA5F22F94CF29FF94C947E5F13A -:105BB00006A580F2661F95F737C451BEC914A0F23E -:105BC00011863E3C6F0E507981A15F01C27FC614E1 -:105BD000A4F26B0C8378DE1CA4F25FA8C30BA64072 -:105BE000FDC70DBEBDA8EFD62BBE32B40F99DA901B -:105BF0008EFA4AB32B77E2E0D0CECC30D33CD8F348 -:105C000087FC87681EE05F32E64B1F46BB14E01C32 -:105C10002438268063EC194EDECB632538792F9724 -:105C200069705E2138B6DEC1D9F3F278199F97CB3F -:105C30003538C7088EA377E3CA7B65A28CCF2B2BA0 -:105C40003538C7094E62EFF0693C2AD3A7F168984E -:105C50003E67707D589FD23B7C46BF26D367F46B6E -:105C600061FA7C4CF864F40E4EE36B327D1A5F0BE4 -:105C7000D3E72B82D3BF77E31AFDBA4C9FD1AF870E -:105C8000E96332209CACDEC179EA6D993E4FBD1DBF -:105C9000A68FD380F419D4BB71E5BF23D327FF9D12 -:105CA000307DD2089F21BD83F3D43B327D9E7A277D -:105CB0004C1F37E133AC77E3CAFF8B4C9FFCBF84AA -:105CC000E93384E08CEC1D3E4DEFC9F4697A2F4C2A -:105CD0009F3C8233A677F88C3D25D367ECA9307DB5 -:105CE00026109C71BD83D3744AA64FD3A9307DA6DC -:105CF000109D2FEDDDB8C6BE2FD367ECFB61FA5CBB -:105D000045700A7CF5840F03388ED8709E3927D3EE -:105D1000E7997361FACC213853014E4ECF70C6B764 -:105D2000C9F419DF16A6CF02827365EFE03CD326D3 -:105D3000D3E799B6307DCA88CE57F56E5CE3DB6554 -:105D4000FA8C6FE7F4A9B278263BD0BE4B649EED87 -:105D5000D0E492930D079C9037D99907C1BEA484D3 -:105D600076207C582BC92E543D9A9DE2616887CEDF -:105D700070BA3DE8F7316AF6086BA1FD827D57A243 -:105D8000E40FFAD230E916C4D701565BA45D923015 -:105D9000364EB28712BD4952BE4F615FA97E4A514D -:105DA000B6549E567291549EE1CB93F29965E3A549 -:105DB000FAFDAB2749F90BD64C97EA67056649F916 -:105DC0009C9AEBA4FA836A1749E517D6954BE543ED -:105DD00082ABA4FCC5F5FF47AA3FAC619D543EA22F -:105DE00069B3543E32F40B293FEAD00352FD312D02 -:105DF000DBA5F24B8E3D2A958F6BDD23E5279C7E3C -:105E0000466707CAFBFFF5058CDB831966B20743BB -:105E10000E33E5CDFB6C64FFEFC73CF0D3DC7706B7 -:105E2000E5CDCF2E7627E37E1A01C07A5FD0B7EC9E -:105E300042F4F7DC3CDE77A10BBEDF6CF68D7045DB -:105E4000F1477854DF3E03F98B5A14968EA9DB8014 -:105E5000699C51ECD72D5CBE3666E53F148890D323 -:105E60009AFE30FF207FD86026FB5593EF8DFD4BC7 -:105E7000D31746F4B3A1BFB964FB50FE7DB11DFB3F -:105E80002B7A11E75995B96330E2A5EFC7923D56D9 -:105E9000EAC73AA08CFA790DFB89F07B590694E9A0 -:105EA000FAB1966C17DF453FC7705CB1FAD9983DDF -:105EB0005E1ECF8072EAE75D5D3F1B0794EBFA89B7 -:105EC000E3E381EFA29FF7CE3B9E9C89F2782E58A8 -:105ED00049FD74E8E866B960A5AE1F3BF583DF179E -:105EE000933F17760169C0674B4729C9C17FDA58CC -:105EF00000E4C29C59FE6BCCB3B76C6C10F6E38621 -:105F00007EA11ECBE5FEA3A70D49349ECFE280FF04 -:105F100011766AD77E3640FBE2A5024516048C60F6 -:105F20007F5B296473C9AEE20137B9216D3A30F065 -:105F30006EEC678BC33308F26D4D93CD8BA3C8D342 -:105F4000D25AD3A9D648BF88B6BF99C472ABA1FFB5 -:105F50005D369794D7D2958A8B097F04E54FC0BEF2 -:105F600085C17EE0CFB02F6040AA774D7C9FF60EB2 -:105F7000EC6F30DF0AFB1B2C676C2DB53B21FCB4AA -:105F8000276E578248EFCF7EF24313E9F1007B354D -:105F90003D15FD6EFC6FC19A78F4F187F15B18E84E -:105FA00023E5415D661AD2695F48FBDF8EA72DC1EC -:105FB000ED48D79A4CA0A9A897CDD8EBB0C9CD4849 -:105FC000A26CA6612C63B3AB8BA7A6D12C52FAAFFF -:105FD000023C67358E34410BD6666ABDD163EF82D1 -:105FE000CBBCA613481F2BFC4338D714423EA2FF5C -:105FF0006B8BE4FC5CA676E581DF838DD9826FA292 -:106000005FB7D7847C2D4AE5F8CCC5340F8BB9BF78 -:10601000A3C4C5DB6AF8542D36B110ED4F03290C2B -:10602000FDD18164AA779DB6CFD4E15762B27A8B55 -:1060300080AE250B8D44573DBE6FEE8BF71A86431D -:106040005A73B7095D9B3DE13FCF2797B332DE9F7F -:1060500046574D5E4E09FE9E40FE43FA3EF21FF04B -:106060003E29F8DF25C79CFF5516DF4CE47FC7FDAE -:106070004646FC127C9F23F8BEB456E6FB1CF49304 -:1060800043FD39ABB382EBB17E5D1F89BF307099A0 -:106090000EB5774D05B5DA0DFFB7851C5C57B3FB20 -:1060A0007964EFF565BAF1093EDC28F8305F478F77 -:1060B00039826FF305DF96B1C06D19E43F0A9AD0BB -:1060C0002F36AF4C61A82FAA7EAAF1AD55E29B4FA7 -:1060D000E39B0EDF1B05DF6EFC09E79B1EEF56C13D -:1060E000B7D6BA8F4D2CBB3BDE7A3C17ACD18D2B8B -:1060F000A0E75BAD38777099D1DE29F616F439192F -:1061000051FF9AC22BFB9C8CD00BD716154BF9B9BB -:1061100025F3A4FAF37C0BA5F2EBCB964BE5F3AB9E -:106120007F28E517ACF989547F6160AD54BEB8662D -:106130009354BEB4F62E29BFACEE7EA9FEF2E03633 -:10614000A97C45FD23527945C36E295FD5F4B4542B -:10615000DFB06FC8D5285F2F1D3532F4977DEA79FF -:106160009FFC759F7A4C1EAC538932370EE5D94D92 -:10617000F27CCA9F4BE969BF87E4FD8C7F2CA56D3B -:106180004D07ECE87FAC8A03BD9F0876B8F1CDB52A -:1061900035FD70BD81F6E3196B36B6AE0D40FE00DD -:1061A0001E46C1BC99516766A1510CA4BB6F589E95 -:1061B0003B8C11E5AD3D94D7A92CD4A77BF98CD6A7 -:1061C000E8DFDB958EC119E8277CC3C27646F8EB81 -:1061D000BA9F57B04CB42B62959F35B0B2C8F3ACA0 -:1061E00093467E4EE2344E3A698474A599CFFF956A -:1061F0007B32263127E64383ABA3F85DC2FD350031 -:106200003269C8E71C69DE2FABBBB86B9E33EC2745 -:106210009BE476797094F47D45FD04A95DAEE27B44 -:10622000D708F5CEEE37D27ACD4207065C330CF1B3 -:10623000F39EC4EFAC2985ECAE16BFB7CFC9818CF5 -:10624000FDD15F48E9ABFE224A5FF397507ACCEF6D -:10625000A3F44D7F19A57FF65753FA8E7F0DA5AD98 -:10626000FE00A527FC35949EF4D7527ACA5F47E911 -:10627000697F90D233FE7A4ACFFA1B286DF33751EB -:10628000AAE9CF9EE4EFB4585FCFA0FC459133F369 -:10629000AD6C5DCDC42E398B532DEB50CE34FACE80 -:1062A000A8B308794895E42111D76192B31ECAEBCF -:1062B0004C420E63B58F5E8EF2D6F77B9037C6D612 -:1062C000911CCC1472F75DE58DA1373E05E529538D -:1062D000274FB21C6A72A4E9815CA568B83AA64B44 -:1062E000AE661AB99DA4C9D5CFD14E8C626FDDA020 -:1062F0002A62FDE3F611F36518D07E5B25FCFECC27 -:106300009D4EF94ED1F77A00D782F5D4602EAE2398 -:106310009DB97F1B8CFEF1CE6316867EF858E3D3C1 -:10632000CB4B6CBA7B69FF501A84456D54F7725B96 -:106330001CA7ABCDC00A591E9ECFE61FF3013FE359 -:10634000FEF3E23CDCD7C27795915D15F41447F17A -:10635000B73394F1B49EE9ABD53FF5C097F9786EA9 -:106360003E53CCF3B803467EAE1D7AC8734DC4F9D4 -:106370000CECB7D3D1EFDC31C8EC22FB21D457A60B -:1063800063B0AF44C703833E1B8CE71B9B400E7179 -:106390007E750E1C9CC0CE231F3DE9F99EE8B928EE -:1063A000D8B797F434333C37027A6EC7FB2FBDA5BC -:1063B000674F7AB227FD786233A7B353D8A7B1E805 -:1063C000DC3E09E65D1439BE475565396603F97947 -:1063D00087467FDC9746D0FF52BB9BEA3FB7EFADC5 -:1063E00001ADD04F67E385098C9FE7905DD7F1A49D -:1063F000B0DBDD99321F5BFB125C0DCE734FBE3EEE -:1064000000F7C9B76106E6D993F145BF5253BAE028 -:10641000F5F61C3ED6B8767FCBF9D99EAACDCF969D -:1064200001284F9F093D10737C3DC9298E0FE05C08 -:10643000A5F0F16D3016FD0EF54C787CA3537A353E -:10644000BEAA04335346007E0EB3992530B643F5F9 -:106450001D54691FE7690DA09F625FBC673DB0A432 -:10646000CA79E6E5901BDBC9FE8C15F536976C3FC3 -:1064700025BA64FB29C315693F751E7AC8E903FC78 -:1064800056A51B5C2747E13AE715EB1C5F5735FC27 -:106490002A1AB25C76098E9CEFAC550A1B489EDC2A -:1064A00009B3A39C9769E9AA74B3EB24AC5767EAD4 -:1064B0007312B0DF337EAB8BAFAF2E17EF37DD1526 -:1064C000B9BEAE5C1347F535FC62C1FD67E3C75842 -:1064D000237BD78AEB2294E5C4AE1F939FEA2766FD -:1064E0003A976E367D86F6BB2D57B3DF55CA6B7073 -:1064F000AB1A8C01CB08FCBE4BEA0FDAB9B5336698 -:106500006C175B6E54764AE327F0DF8A07EFB46FAF -:10651000B5129F7D003101E0B5ABF61A94AB132A9A -:106520009FCF55424E2BACAD669F9BC8DD82F2BC1F -:10653000682CD326CCDCB7404F7FF0A289EE69B13E -:10654000AF007A7ED7558125ACC8894ECF458D2BBB -:1065500066E0BAFD8141DB0FD7E6E3B8CF314321D6 -:10656000EAA573EC8FCE5111F3758889FB63580D42 -:10657000DFE704E01F8E6F69ADBCEF595627E74B8C -:10658000D9AC54D4B7A55B4C2C08B82FC77D933633 -:106590006ED0BF1926EED758C6AA37E03EFD5E136F -:1065A000F7F72C72313513F0AAF88F5FE6A3DFC737 -:1065B00063E27687769EBC3C89E35D3E3B68F642AB -:1065C000FD771B47CD018D0BED831BC8FE29669E11 -:1065D0009DAC3BDD17D7C8F8F584BF1E5FCD0EEA32 -:1065E00076AE2DF048AE57BCC1287AEE329322F633 -:1065F0007F7C7ECC36C9FE9C7926D9EFA3C9814920 -:10660000C8C109D577B5690CE73BF251513BCCBE07 -:10661000887AE6AE7AB3CF57CF82F58C546F9E2935 -:1066200005EB754CA3FD3103791ADA55CFD605EF8A -:10663000460E4FAE57F11F8F3D15007929FFED3DF6 -:106640004E06EBE6076A6DAA07BEAFDC799BD30B5B -:10665000E96935E0447E7E10341646A3C796303D86 -:10666000BC7605FD69423E594D80FC149FED34B95E -:10667000C8CF5F6F0959404E2B1B97CF60C3297F4E -:106680009CE7377E64C47C93CCAFF25FDF93EAE68D -:10669000F76CB83F8985C8CEADDCF1DE345C2FAA3B -:1066A0005807C999BE1DF6FF7912CDEB85E684EE39 -:1066B000E58027F913AAC42CAB6AFCF9474627E604 -:1066C00065F92813F62AD209F7F9B7991CC9A7E288 -:1066D000217B09BB04E7B9460F16E476EBFA47EED7 -:1066E0001B7E1CF039BBE345A73234523F7039EBB7 -:1066F0006C58FC2BAB21B61E6903398CB48F00306B -:10670000B57337097BBB99A72B4D2127DE6759B994 -:10671000CDE40109642B1F3332BC07C0DEB004D1C5 -:106720002FBAE2B1E75F1B0F745FB1DB943C830FBC -:10673000C7AEA476F1A50AFEB726AF8B0FE54F3C96 -:106740006F760FE3DF6F49EAE2C78ADDFBCD6C5855 -:1067500077FA4D6ED86F6EB547E14BC3F169B8CE8D -:10676000AE7FE4AF66F4277EB04F616959DDDB97F9 -:106770006D7B9ED63BA413F151F029CCB76EFC0A79 -:10678000CD7C6634D573A11E8CC5AF6542EF823CCB -:106790003FFE0CDEFF79D3E2C1F1973D7E9313C734 -:1067A000F1BE5ACDE5FA97B7A5E2FC2E3305525D4E -:1067B00094F2EF650FFE88E46DD9911FA592BDC0DC -:1067C000BC1906D2C5810C1CDFD2ADD7D2F84A99CC -:1067D0008FE4AEEC97C622BC8FF8A9CA0A77479916 -:1067E00017716685F0797F3B183230BEF7717F896B -:1067F000FAEC8F46BA17C5D80FE9DED88FC45861B6 -:10680000E5A3FCA756CEA7E3424FE24496E475C742 -:10681000C616E4CF99FEDE343CE7003A0404BD948A -:106820006F00AEF1C8D434CE1FE656F3453BD0EF2F -:1068300093F13BD66F31796DC3A576421FF2FE57B7 -:106840008BFE01EF385CAFDE4F8D6EEF8D11E38371 -:10685000BF1616215F11F39BCFF71D9BF8FCD6E600 -:106860007BB0B810CB3F7995CF1F6C87EB03E01559 -:106870004AA3F2FDB315D207B0AF8E36AF7798C4F6 -:10688000BC96CBC152A4F51EF0569584483901F848 -:1068900049447FDA07976E817611F65715F647F56A -:1068A000CC5DDF23D68765420F98CC30FF2FEE9A60 -:1068B000FF6C2B9FF73DD9932B4DC1871FC0F9FA71 -:1068C00086C51370E37C3515E1B83FDC75E0B5EBA8 -:1068D00040AE3F6CD0E6A9AC3FF5F3B46CCF1816D0 -:1068E0006D9E7E6887FD55B4790ADFA3CE537B2B5E -:1068F000C9F1F7AD3F35BA0D35CB7A13F5E033EE7C -:10690000D8F4D3EBC1DF9BDC4447BD1E84BF57598D -:106910007E77B9D3E44D93B3F2DF545C80FA262C32 -:106920008F9ABC85E5519337FD3865BAE9CBFF2ACC -:10693000F4CDF5D6C26BD02EB67630DAAF14CC36A5 -:1069400006719F6CFD84D17C9F74433CE5E71A5B24 -:106950009F409BEFAD8AB9C3701DBF9E054CFCDC08 -:10696000BCD64476EA57DF7C3311C6739DA0EBF5A5 -:1069700040E6AB800F25AA128A033CE7A92C909031 -:1069800084FE62859D88C0E3FA32398F7F97A576B1 -:10699000C1E9A9FEB7B5ABBF6B7AC4CFCFAEFE8459 -:1069A00029ED2FC0708E90A3E2667E4E51355A09B4 -:1069B00066D3FC6B558B22F6098F99B99D7164CA19 -:1069C0003563907E05738725907CD70EA17D6095F9 -:1069D000D05B9D017702EAF3CEE61CDAF7751E5A0A -:1069E000ECF045D15F07849C3D2FCE59DAED4AADDE -:1069F00011E4BD9D7590DD12B0DBA2FADDEACC0694 -:106A000061EF08BEC19F11FA2F1172380F9A26E468 -:106A100045F06DF6551FA8CEEE7CC0BF1311FB8666 -:106A20007F94BE28D748DF03B6D6694551FC338F23 -:106A30000A7D7DD9B35F98719D9BD25CA0221DA772 -:106A4000D88D92BF63BB365F87B2A188D765CF2E42 -:106A5000BF630CC871D521A3C706E3AB6AFEC8ECBF -:106A60008BB27FD3D313E1A3FDD86AE6F6F151537D -:106A7000D152A4EBD16BF979EE9FCC9E8A6878CE87 -:106A8000B6723CE7B1A24F472BFF7AF42D98EB0882 -:106A90004D027A74DAF9FDE4EEF2C7E77DA74B09FF -:106AA000AE55500E8D3C9FCCEFFF4E63BE3B262A69 -:106AB00034DF2F8FD45F054DC58FE17D96CA66C543 -:106AC0006580F24AB5D58C725CD5B45B45BBFC07DA -:106AD0006EFECE82A9D5C36647F8B75ACDDC9F7447 -:106AE000E06FD7CD47FA7E3CDBC2102FEFD08F9CF2 -:106AF000B8DE7FDC3C8AE641AC71FDC1EFB9660AC5 -:106B0000FAE3CD5C9FE9E5615A72BC94BF7632EB43 -:106B100087E7BC97595A6FF244E1DF3A0B9FA7BD54 -:106B2000D66FD6FF61FA6D22E8372ED7A648FD361C -:106B3000DDC2E53E42BFA545D36FABD6BAD3502EDA -:106B400056EDCD4943BEAE3ABC34259A7E7B41EC2E -:106B50006B0F8B7BD2EDFD40BF8D88D06FFD40BFAA -:106B600045F1838FB66876670FFACDFADF33FF5EA3 -:106B700040FD1665BC5708B9D3F45B61F35AD26F78 -:106B800085FD8CD27DA4CB2CC28E8BA9DF16DE7343 -:106B90002DE54D9EF828F2837445FD7658E839ECD2 -:106BA00007F5DCCF2CDF4ECFCDB3727C7BD473FFE7 -:106BB0004D74D6F4DCAAFE0AD92FDDE590EBB95569 -:106BC000595CCFADDACBF5DCAA415CCFE9F5DBA4AB -:106BD0006EFA8DB7AFCC85F6B44FCCBAEF06BCCF0A -:106BE0005762F258A1FE0CB7F6BEA07A4CA4BEFBC9 -:106BF000992586BEF380BEB3F7ACEF5E417DA792C8 -:106C00001E1B88F3482F1FD307C64BF7D58E7E7106 -:106C1000EA37BFC5F9F20723DD077ADDC0F743FB8A -:106C2000BE38350AE7DDCB880FCC979D42FEDAFCF3 -:106C300063499F4E1ECAE77BC5A1385A272A1B15F8 -:106C40003EDE5B94A01BD781BF7D4EFBE4F97BF950 -:106C50003E79AE85D383FDD8C8DF4500091646C806 -:106C600043C9E7E5E4E72B519915EDD70587A67FE2 -:106C70008076EB82CF6BC8DE5D80DFF17EC5EED61D -:106C80000D99D0EFFCE50AED3798B80FA1DD97B864 -:106C9000BE793FDD5FD1DF83D0F4F9FC6AF9FB02F6 -:106CA0009D5D7F408C13EC59A20B7BC518D53F77B7 -:106CB000404F0F0F1F7FC56A6E1F87E901F4712BCC -:106CC000DDE9011C9DB130B56BFCF39F8471257724 -:106CD0008D4BA3877E7CDAFE6481981BB1C6ABD155 -:106CE000AFDB78357AEAC6FDBC45D84517B36138C5 -:106CF000CF5E37F8EE188372F17B183FE03367DE22 -:106D0000A0B4483DFCA2D0E757F98E4F497523BD8A -:106D1000F8FBBBEBCA763F9F0AE3B8DA9B9587572F -:106D200011AEFD9BD9877E8403B60ED26B9A5C5D53 -:106D300068E572FE7701E7685FD7145A3F9A141727 -:106D4000CD97904E6F897B6155404F9C8F554D621A -:106D5000BD0179C3F9364D5B7F90FEF09F573573C7 -:106D6000FA57552B44FF99ACE320D2B73259F1843E -:106D700000D4B4A6DDB7E13DAA176CF01DE76D990C -:106D8000E2D9CEC961CF488D2A976A34B964D54318 -:106D9000C8AFA0AD830BB05E12BE17793D05ED13F1 -:106DA000BDBD7199A5E528E271D98F4D6C1BEB6EC5 -:106DB0007F68FCCE857FDF44BBCFD383FC0E12F609 -:106DC000E50B486F3BD2B5C38C725F15E2EB86567C -:106DD0005EA5BAA7107D347A37C1BA309AD31BDFCB -:106DE0007DE9E979B5964779C6FACD8A09DB5F096D -:106DF0007CE80345930D5F1CD4E417DF89E9E98241 -:106E0000FBFF8C88F98E7A29F2DCB1B2E908D165F2 -:106E1000FA6A30AB22E88EFAEA7CF4E9361F9AF679 -:106E200047BD07F56DE7C38556793EECB375BC38B1 -:106E300002FD5B7B15D207AC3951DADF5F61E5FB00 -:106E4000A603361FC96DC76113DDF7D6EB8DB1827E -:106E5000FEB89F887C0737190782E7BB2E1B7B573C -:106E6000C3239BCB4FA4BE7EC1E6233EC5823F4DCC -:106E7000C08F652F85F1C5FEF03CC52DF7A75F2FAC -:106E8000343F4F4FE3BA46ACF7DF755CE1F349D6C8 -:106E90006266DC9FBFDB1C71CE3447F8F9353F5882 -:106EA00044BD999631B1EBA1BF2504E37E61D74380 -:106EB000E4D73DF7E8F19928B72B7E676456E07375 -:106EC000DB2E070BF17B14665C57CB1B8D51CF4536 -:106ED000185B4FF8ADF8AD83F44AF91E4B7006B459 -:106EE0002F7FEADDE1E89F6A5BC7F54BE051211F88 -:106EF00081D6E1785E5EAEF2F3623DBC1F0B79395C -:106F0000FB747C09EA47A59EBFEB2C6F986BB244DB -:106F1000ECCB2BF1C08DD7A37BC8814714F28377CC -:106F2000C76F2DAFF708D77BE54DA620BE0F2DAF5D -:106F3000DF46FBD9AAFA8FCC68C74DFEED636447E4 -:106F4000543519653F61BD3164213FA6F138A67AF9 -:106F50007F5D656305CDC7CA06E10FD3F98B56FC8B -:106F600076EF530120CD8A277EED443D73A665A7B9 -:106F700093FC70F5DCCFA6DAD5E87EB89EFC6F0DE9 -:106F80009BA2FADFCEE07FC0FCDB6A95FD6FACBE52 -:106F90004FAFCEC1573CF6E983782E7476CF870F7A -:106FA00022DE2BBFFEF8C19FA27DB2CFE6C2F5AEB6 -:106FB000EAD1A3E457D7DA3D25E655DB23BF7EF8B7 -:106FC00001987F6D6F58E8FE55DBDEF707B8619CCE -:106FD0006DBBBF4845FFE5EABD5369DFB2FAC9C9D9 -:106FE00069E7BB47827219ECC579889E0F071A8D35 -:106FF0000CDF419E3B66213B23EC476DA8E07E6998 -:10700000B7F09FEE8A7EEEA4F9FD2A1BAFB9FA52C3 -:107010005CF71A4D1E377D177EC09EFCA6AF023F5F -:1070200047F4826FBB845F5CC7B773F81FC09F3F94 -:1070300059657FF3A78D4B7FF5009635F689E937C3 -:107040000DF5825EDAB9D636ABF71D2BCE873DBF84 -:1070500021FF34F20B6C6ED6F6D8A703D0DF70DABE -:10706000D47123DDBFD86BA17B42E57B5FA7F9D14B -:10707000F6E4113A2F62E25CA98D85FFF83980D8D9 -:10708000CB54ED70707FABA03BFA63DD4EFA2EFC63 -:10709000AE5C6E357F6C2C3F6C1F9BB8072ECED933 -:1070A0002A76BC65663ABFB63216F9745C3A17D4D4 -:1070B000C6AD87E7423A5C12799E10CBCF2DF468BB -:1070C000984FFC1CA16D9B385F089F1B30D62F0F7B -:1070D000EFBFF3F3EEAAA0F23A8B321FB5F304A789 -:1070E0004D371F83BD3B47E819DFEF460FC5C6F795 -:1070F000AD1A5DCE7E155D1F0FB129E2FD812FD740 -:1071000016B1EE2C10EB4925D08BBF27E3F89E1566 -:10711000FBBBB38F1A83B80FDED07080F4AA7E5EFB -:1071200057B2E8F143C6DBB83EA96CDA3F1CF5CF95 -:10713000D9679F26B9ABDC75DC1C003807EB9F30A4 -:10714000B70EED9273D4D7C1087D7DF6F1FDC3F97A -:107150003907DF47EAE15F21E05735CBF0AB767DB9 -:1071600024C15F116830BBEC3DF77346F5CEC5F125 -:107170009E6931515C94330DC6C268F14A86622023 -:10718000A9942E3A6D70F0F771C62433D991AB1DD6 -:10719000638F2524636A76E33E7AFD5A7E1F72FD73 -:1071A000CF3CE9C897F58973E81CA856474757B202 -:1071B000AB00F7D7AE2945A351ACF47A20D16B9040 -:1071C000F05EED284CC3F7DCB70A7B84A91E7ABFBA -:1071D00067744E2BC471185D06972DEA3ACAE1997F -:1071E000EC45142FC2E492DFD37DEFF11FDCFDE408 -:1071F000F80F817EFF68FC07467130FEDFC77F080D -:10720000603FFF02F11F42E4B7D1E23F247FCFF19C -:107210001FD63239FE83E06738FE83E0E7FFC67F82 -:10722000F8FF2BFE8331EEEF53303E8316FF21250E -:10723000CE3C3532FEC38571095323E33F8C8B4B23 -:107240009F1A19FFE10771595323E33FCC8FBB68A5 -:107250006A64FC87AAB8515323E33FAC8D9B4879FD -:107260002DFEC3DD7153A7CAF11F664E9D02F9B60C -:1072700038DFDF71BD8A15FFE13D9C2C637A8EFFFC -:107280000070CC716362C77FD0C38915FF01E02411 -:10729000109C18F11FBAE11323FE03C049273831AF -:1072A000E23F74C32746FC078093457062C47FD0D9 -:1072B000C38915FF01E05C1497123BFE831E4EACA0 -:1072C000F80F006714E11323FE43377C62C47F008C -:1072D0003813094E8CF80FDDF08911FF01E04CA541 -:1072E00071C588FFA087132BFE03C09949F8C48895 -:1072F000FFA087132BFE03C0994BF8C488FFD00D65 -:107300009F18F11F008E8FF08911FFA11B3E31E203 -:107310003F009CE5042746FC073D9C58F11F00CE2A -:107320002A821323FE831E4EACF80F00E7A7042722 -:1073300046FC876EF8C488FF00706E253831E23F46 -:1073400074C32746FC07807307C18911FF410F27CB -:1073500056FC0780732FC18911FF410F2756FC0788 -:1073600080F32B821323FE43377C62C47F0038F501 -:10737000248731E23F74C3E7BBC67FB085062A3954 -:1073800014FF81E24486E33F247FEBF80FCD88EFC2 -:10739000FFC67FF89F19FFE166BBEFEB38F2837EF3 -:1073A000B7F80FB6F86F17FFE1667B517C3CEE2F04 -:1073B000BF65FC87D4F86F17FF01FA498F1F13BB15 -:1073C0009F58F11F7274FDF414FF01FA1974DEF175 -:1073D000C488FFE0D1D1EDFB8AFFF045DCF9E33F43 -:1073E000FCCBC559806D0A9EFF149328B27F99B8D3 -:1073F0000BD7C6FF93E32E90B1F0AF1477417BBF5C -:10740000DF60C2F5EA4DC1F7D7845CBC25E22F1CD2 -:107410008B197F217815F94597CBF117A60B3ECE36 -:10742000F3C9F2309DF1F386E953B278BCCC325DFA -:10743000FC855CF9FC7A86EFC81400C7AEF2C8E39D -:107440003822E46166C947CF217BAE1E1B3DFEC2D8 -:107450002CC18F621D5DA60BBE158BF47A7C920247 -:10746000F23CA3EC888A749DE96E55C9AFFD038D8B -:107470007F6E897FB3055C3DBEB304FF665DC9F9CD -:10748000A7C7FB55E49F13D2B251C43F3DDE7A3CFF -:10749000F5FC6791FC8E889B51C0E4B80B93AD72EC -:1074A000DC85A92E39EEC215E972DC852BDD72DC94 -:1074B000851FE4CA7117AEF2C87117AE1E2BC75DE7 -:1074C00028F6AED5C57DD8A48BFB70972EEEC3FDF4 -:1074D000BAB80FDB74711F1ED1C57DD8AD8BFBF020 -:1074E000B42EEEC37E29BFB8E6B0547F69ED1129F2 -:1074F000BFACEE0DA9FEF2E071A97C45FD07527903 -:1075000045C34752BEAAE90BA97E6FE33EBC2ADE03 -:1075100003BF26DE031F13EF81DF8C11F7E1AF3FBE -:10752000FFE2B6C8F7F85FFEFC9BDBF03DBE41BC56 -:10753000838D15F7215C1E23EE4357FB6F1FF72148 -:1075400025F99FFF0E3FC7CECF3727C44FCAB1A73B -:107550007CF777F8D716C9EF99E796C8EF9973ECDF -:107560005C9FCFF3C9EF9AAF2F93DF3597D97CD9C2 -:1075700088873EEEC384786F8E1DF5A5789F1FC265 -:10758000F7A9B0363E8BEF53217D0EE33E407A10D3 -:10759000E33E407A08E33E40FA7B8CFB00E94B185F -:1075A000F701D29731EE838A712302226E448D88CF -:1075B0001B512BE246D489B811411137A25EC48D0C -:1075C000681071239A44DC8810C139E13F44E949CD -:1075D0007F0BA5A7FCC7283DED6FA5F48CFF34A554 -:1075E00067FD1D94B6F93FA7B4B7712334B9FC33D6 -:1075F000DA0D66EC9FCBB126A733EC033744CA699A -:1076000091FDA20D28A7B1E245CC459AA6C48E17DC -:10761000112E8F112FA2AB7DEC781169A3BFBF781B -:1076200011FF16CFE5F51F8D1731BF5A8E67B06079 -:10763000CDF9E34594D98A56A35C6AF2F86FF1FC60 -:10764000BCAAA77811DBEC8A58AF812E6877015D60 -:1076500068BDEEE1BDFD738E8773713FD1997BD11B -:1076600079E31CE8E52236BD795C83EBBEE738118F -:107670003DD155ABFF66398F5FF06FF1E78F5FD07B -:107680002D4E444FF105067D467AB2B771227A5AE3 -:10769000177AA2E7ACEF394E444F7AB5277DFAC787 -:1076A000E99CCE13E2CF1F8F231C17CEDA72901AFB -:1076B000BBBC34B555F10EBC60B68BFC27EDBBC42A -:1076C000BD312F73BB52F93B75B437DBF7240C6720 -:1076D000F47EDDC5BCC09F78F15DD9B57F3F9EA724 -:1076E000DFEA64DEC4248A07EF36E6E03E6CA415C8 -:1076F000FD29158D1FBDFC3B806B6B36D27DB276AC -:10770000C0A185EC3E6F22F22D9EDD4EFB743CE362 -:10771000FAA64FE47B66DDEF37609588F39BA946B8 -:107720003BED9B3AB7F27B9E4676F17D1347D37DC6 -:107730006A167413FFC84E5D21F0ECC414EBFBAC69 -:10774000643F2E3BFC447E88F1F3CA48BF419F4210 -:10775000D94F5367730EC777952CE06D41FB7B893A -:1077600080975224FB6F3E5C547808CFE997F84A23 -:10777000E91E425A89ECCF61E2DD386EC7C2F7E5F7 -:10778000009FD226853DA0747F475ED67CD706DC5D -:10779000E72C0FEAED6F968B7256CEE23CB8EF5DA8 -:1077A000512F973B1CE23E879DD97B45B7D60BEF07 -:1077B0009B987C5EBA7942587F9783EEC32E3BBC80 -:1077C000D88CCCB2A4CB74B3B965BAC5E7CAF4D12E -:1077D000D3CFE191E9A3A75FC258D9FFA5D14FBB91 -:1077E0006FA832715F34C8EF91767B87DFB48DF07C -:1077F000D4D34F4FAF510E714FA28B5E45D654522A -:10780000F98467861A22F9D6CF874C7B48C1FFEEF0 -:107810009F1C5C4BAD3C0E15F5563A07CD9425BC2C -:107820005D3CCE078C2BCB3C341F70478FFEDD7840 -:10783000F66721F7EFB26F20BDA9F8B9E38BA0740A -:107840002BCADB08FEFB0BE4AFD27E3781795CB834 -:107850008F6AF05BDD4B543C1764EE2503F13CD09E -:1078600045E99DE2DD6FFB5046FBFE86D027A978F7 -:107870008E76675EC74CF43F542D6545B87EFDC8D3 -:10788000C9DF5D6C12E90827F7CF6C2E3230EF6844 -:10789000FC1D1E635041BFABCB7BF872B4479B4DC0 -:1078A0006E7A47ECEA78F97A2A1F45EFA3330CB5D4 -:1078B00023111FA84FEF6BDB9BDF752E8ED0C36D9E -:1078C0004D770FC1FBC5F71BA2BFEB2D7568EFDB32 -:1078D000F8FD8E115D71064A1D63281EC19DD9D029 -:1078E0004F657127F15193CB0982FECF954E27FC4E -:1078F0009E6C56DCE8AF9B66BCE107C300BF7147D6 -:1079000055AEBFC4BDEED1A2FED3CC938EF88EBBD4 -:107910009429387FC6BDC13C0124717529DDA7FBC0 -:107920009D73DA21E4D7946690279C0F67ED1EBC07 -:107930002A3FA645BE2F9738C57700EF175E728C99 -:10794000913EBBE498AABF1F63C4FDFEB856F9FB85 -:1079500004DDFE739D26774E968A72B7E52B23E1F0 -:10796000D5DEC13CEB006EFB92BE746EDBFE0923DC -:107970003BB1FD2B6361B4FB25773BB8DFEB7E3376 -:1079800023FD7D7FA99DDE393C5B5A7E01DA179F7E -:10799000FDC47741343F65849D96C0DF9F7B13D83B -:1079A0005894C35B154EEFDA8CA228EB9626779A93 -:1079B0001C6AF297511AE78B765F33D9C9EDA34958 -:1079C000A5B98A19E5679FC290AE6DEB00AFF3AC25 -:1079D000DB01B62E13F1A96AFA98EE61599B95A8BE -:1079E000BFCBF384C3C9EF03AE0BACC5FB1737C3E2 -:1079F00024423D9561AECD8A063FC0B6905DFA80C7 -:107A0000C3CDDF0D58451C21B53603EF23B4354DEA -:107A1000BE7203E0F900CC07E4EFFD260FE11DA8DC -:107A2000608CEE930A7F5DBF996CDBE608FB77AF55 -:107A3000A3E030CAED6107B71BFBF83C0AE2EDF9A1 -:107A4000FB5F9D08BFFD730BF1AFAFB037B5762775 -:107A50001D9C3E254EEF016CCFCA9249F9787C4EB1 -:107A6000F7923EE837077A47B1AFB4753DC9C7E82A -:107A70007C22C96E089272F27ADD2EE9BE7780E62A -:107A80008D360F584861F85E5FD36F4AB31272802B -:107A9000DC8FB6DA4378FF2CA90CC69D8CF13CAC88 -:107AA0001C5E8B7A56F66B813CE6A371CFE8BD3F36 -:107AB0003A5211BEA6F7347D796B22D747B7DEA5BF -:107AC000523CD0AD6AAB0DFDA9595EF7240C4D9325 -:107AD000A4BAE95E4AFF323E0FE3737E9918B603FB -:107AE00060928FFCDAB820DA7BA60C94A714A497D6 -:107AF000EF4307A4C30F753C8BE682C7C6FAF0FBC1 -:107B000053424F08BB669A58EFC6BD67E0EF284363 -:107B100097B3C8F7457A3D0172FF27FCFD9EFBDF56 -:107B200053294E68583F944EA3F58919871E403952 -:107B30009BF022E3C751423FB8E01FD2E792977C07 -:107B4000EB118DEFAA17F4FC66216B388F3FCD3611 -:107B5000EA10CCB7C875D629D67BA1476E2A1EB8C5 -:107B60001EE797264717DCE231FA22E8A86F1FF6D6 -:107B7000532AD6F077770EEA91978C783FACBD0008 -:107B8000F80D747912E70BD03BF193E095C8F72D0F -:107B9000CD57D850BE6F0D4D72CD803689D622623A -:107BA0005E22F3923F270FA8837122D69350C07EA6 -:107BB0005D2DCA72A6E03DAE42C9DFA3FD2E1E0CAC -:107BC00094F812E603C871E43D564D3EF5F2A8C99B -:107BD000EF7ADC60E1F91D7ACC21352A0DC4200B47 -:107BE000DBEA423DABD997EBC3F65C22ED33560B93 -:107BF000BB68BD7D9A95D4C0FE645ACF57E3FA04A2 -:107C0000E35F9DC2681E68E3D0CB63D5E706168CA0 -:107C1000D81F54A91D748FAFEA73330BF6C171FBE3 -:107C200026E1B835BA8C1474D1D321DB29F69B82B6 -:107C30001EB1F1CC77E1FDD944AB976D243C27D13F -:107C40003DE786509E15D7DBDB7478F602BF39D14D -:107C5000F053ED31F013F1DB2630DFEF5A415EF3E4 -:107C60006FAACBE0EB057B353D827FFA7933B6A96D -:107C7000FA803962BE687E5DFD3C19D1CCAE41BA56 -:107C80008F0BA90CCF5F7B9A2F9F88F156C5737A13 -:107C9000B5CFE9188CF2B943F5553BC9BE683560DC -:107CA000DCDFF6A719CD67CFFE934E8A6FD4D2BB27 -:107CB000FBE99A1DA5D94FFA7A9AFDA4E95DED7EFC -:107CC000F876A7CF8FFD2B4D209F30FEF52EBE2FCF -:107CD000DAEBF0ADC3EFF130063C4A62B9A12CFEFD -:107CE000FE5596FF58F21EAF93E706A013FD4E1601 -:107CF000E8FF414A773CB4FEA73813F9790BCC660C -:107D0000D443FDF219EFAC92D1FDC97EC3990FD7D0 -:107D1000A77E79FCDE5F50ACDBDB84BED5D2BD8EA6 -:107D2000A2FB117F93CA0296BCEF8E37A28AF7B1ED -:107D3000B73BBDF7A1FC590BBD348E4C17F3A0FD2A -:107D400099A93628F86E3269A55BE1F7B059D73B9F -:107D500026809739C35D80729289FB68ACDF1C3D39 -:107D60008ED6134E9364677A58384ED513D82FD8D1 -:107D70009907CD80779F195ADC2BEDDCC6A3209D97 -:107D8000DA1C7308E9B64F156E8F27727AE9F7038C -:107D90004878C44F15F9DBCC4CB525B1AEDFE134E2 -:107DA00058C98E8F679E06D44B2F3BB3C5B9A8A781 -:107DB00006F3FFAE7658138776C9F19D13677954A1 -:107DC000A8E2BCB47338EE99409E0F23BE6D133BFE -:107DD00007DF4AC4E818C0E5C66B94E2E268F46FB6 -:107DE0003249F4B7E13E3B520F3ACCB48F6C53E2C8 -:107DF0003C38CFDA962B1C4FC52AE206A9F2FE5F6B -:107E0000E8234DBF763AB308FF7816A07D00B37A19 -:107E1000AC748F5DE08F7115C9AFB3373EB81DCF1D -:107E2000A3747114F57116272FB6D3BD8B2D7B6DFE -:107E3000B42FED2CE2E7F39DCD16D2BFB1E6691A5F -:107E40002A83F3C40B04BA7520DDD24CD589A8F778 -:107E5000D2E6F3F9AFA7473B0E14F73B7F3005A3FB -:107E6000BD57D7D2F4F4BEC56897A567A453AA7DC1 -:107E7000AFB3AB51EF611B1314294EDF10E851EC87 -:107E8000738C09F0FD9CEF8FAF7959D7BDF6BA38E6 -:107E90004EBF4EDFF8848751AE40E0E8F704B4737C -:107EA0004DB19FD7E22769FD6CF15B8B31E467DD53 -:107EB000A2E9365C075298F7CA793829B798D84EA4 -:107EC0006A972BDD77BDD73FB218DF276726F07B97 -:107ED000B49F6C994AEF9953D93ADB60A0436991FA -:107EE000C183FE80738BDE741A407E1665B6E4A3F0 -:107EF0009C26987C990963C87545FB8D6525E660CD -:107F000008E8955C070A81E818B892E8B8D010D55F -:107F10003F9C9DC0F79D6F89F5243D7D40F19251B6 -:107F200091F97E44574D8E60FE642C19DD150F13B8 -:107F3000F87951429479D06E624DF85E42D347C9C8 -:107F400042CC347DA8C97132CE0FB4E38A403F4998 -:107F5000E77D5035B5EBF70C95E617BE403BD6797B -:107F6000E924D237306F6B48CE73B9FEB4A13E8B93 -:107F7000F05BB5EF7DBD3FBE637AFB671F3BF05DF5 -:107F8000CB5FD40E07EAAFD3B7FCC98171C0DEBEA8 -:107F900085EF936FD4D9FF5709F90826144D41BADC -:107FA0002EF0FF3D3FD25E636BB8FF7979507EBF04 -:107FB0008AF7BF23FD80150DFAFB00011EA74CFCBC -:107FC0003EA79E0FEB041F96EFDA66CE7463FFBEEA -:107FD00039D8FF69B1BF39DDE8A0F7141A3E8B76B6 -:107FE0008D34A3CDFF97668B78A7D762E27AD93B11 -:107FF00003DFE7F804DDF4781EDC174FF096DEC3EC -:10800000DFAF2E84BED6805EF435F3384AFA712C89 -:108010007DDB3D0DFDE84B3729B48FC3FAB7C03A7D -:10802000E15BB391DEF1E8C7B93020FB73F4F11ADC -:10803000B5FDC032C1FF25F86BBC3951E23836F3CB -:10804000F774CB74F645E7A19C781CFF9A0461672E -:10805000E7B34B306EE79E43D909D1E26168E95935 -:1080600071DE8FF7FA313DED67944E4970F3785D1C -:10807000CD476E46B9AA6CDA4DF111F705DFEB3347 -:108080001EAA14347F6144A12A10F6D87C618FEDBA -:10809000615C6EC08EDE8CF27FF9E73A3B5A8CF35E -:1080A000064DEE0F2591DCDC80E31A8EDFD54FA262 -:1080B0008DEBEE04F9FD576FC7A58D471B9F565EEC -:1080C00021DE9FEBDB69723E45C8DD921DC51BFAC0 -:1080D0000229D6EF7D7F8088234771B63439D2CB11 -:1080E000C932C1B7B03C34DF41E3D2F806F29E2E6C -:1080F000DE25A5A33FA327B9D0F3BFCDD43A00E72F -:10810000AB9EFF6D31CE7DB627F0738D256EEF34BB -:10811000F4AF8079B8C115613F9C566B0FFE14E730 -:10812000D10E2EC791EB22194B2F9A689D5DE570F9 -:10813000A725DA05DFC6E1FB454B00EB69FD9CF2A4 -:10814000D7CC1A48E78DB5B3060EA4771B946AE521 -:10815000A5F77FEC44FBB43D97917FA1CD21E37B54 -:1081600004179B319872FAAF545BBE7E0B75D08EAC -:10817000168ADF7AEA2BE19FF8CA52186D9C6713C2 -:10818000B81DA8DD3FB951CCA31B9BF97BBB455B58 -:108190008BCDE4075823DFD77849714DCB84A6BE39 -:1081A000869166E4B39E1F4B3D57D03BF06E7C61D9 -:1081B000B7135F97EADFB5897B4C0B847CCC74B92D -:1081C000859DE6A377C44BEA8C64DF2F7357D3FEFB -:1081D00066851AFD3DD61897E1BCE3D18F6361A394 -:1081E000427A4F8FFFB21D6B37F465387E3EBEEE8C -:1081F000E308F5233D23C6C95A2FE7EF32C5BAFD80 -:108200005FB8D1C6A4008000000000001F8B0800EA -:1082100000000000000BB57C0D7854D5B5E83E7326 -:10822000CEFC24334926FF21413C21111212E29059 -:1082300084000171F24BC4080301826075405184CF -:1082400090207A5BEFABB79990682DFA7AA358CB60 -:108250006DEDFD062BAD0A4880A08126E9041403CC -:10826000040D820A96D68014B1053280B5587D8FF0 -:10827000B7D6DAFB64664E92426F5F87D69D7DCE9D -:108280003EFBACBDFED7DA6B9F65ECD94B720E633B -:108290000FB7CB8CE53356FBACEC65A98C2D63CACC -:1082A000E9BE0C46BF6BA9F85F67E59204C6EEC550 -:1082B0003F5568DB57553278AE5CAE9985CFF56F88 -:1082C00090995982EB1EEF53C971D036498E4618EA -:1082D000C71E379EEEB33066817FD746D33C8C25D0 -:1082E000E0FCFCD723B1A75260FEB38AFFBD08783B -:1082F000EE2CC0E181799678F873F47EF8FF32C7EE -:108300008C2F2478DFFDEDF229730E5E5D6D32C097 -:10831000F8A52F496C1D8CBFFF69DD78B12EFD3AA1 -:108320001EDAF0A3B9E91981710F7B9F0BE9C3DA5B -:108330005456C0D87D023EF6EA7F05EE73F84DAE86 -:1083400008C632ED117167B3A05BC0265D4B63AC0C -:10835000CE1A99C3A2A03533C2233B64F46E02B88F -:10836000D644C08201CE355BA3BD1EC4E3EA68C615 -:1083700046C0B8F68D26B70DE6C4DFED8C9DAB6F19 -:108380009E9B9E0EEBAF7F7A6EBAC2D82CBB9DB17E -:1083900089408FB6E7685CB7E29A6487FE2A4BDFB4 -:1083A0008FEF5683F03899D363995C696286C07CFD -:1083B000FA7659B3F1CBBEA0751621FC56F86312BC -:1083C000C02FFF3DF8D5C4685B006EFDBC7FAADFFF -:1083D0001002F74A85395B6C81F568E326DA0DB443 -:1083E0001EFDF37A7A30E6A5717ABAAC443A04D12C -:1083F00017E15400AF3D1D56EF5A89F888E0F67436 -:108400008411DC1793D6CD3D93C7D8617C00E0AED4 -:108410001DF132F55F515C6E7B3C5EF48F728DC74F -:108420006762199B323CDE6046C6607C2ECE0FE34D -:10843000768539F3988CD75DB1C807D31BFAAA2C7F -:1084400040AA3AFBA40A05DE33FDB9BEAA30E83FD4 -:10845000629FCCFB9BFA8E5A1C8C35B02915A5F077 -:10846000FC63700FE7BB5E9B6F762D66C05735804F -:10847000534B0CB4C7C6BC8DF256D35B5921454251 -:10848000CB984FCA057E7046FAAC39D4678530AEBA -:1084900033CAFD1FB8BE55579B2EC938EE98C2E5AA -:1084A000A53B8EF0A000EC61F05C53B853B503BE61 -:1084B0009A622C8EC654BAEE098BC1BE535583AE58 -:1084C0006BF4C0E7108E2603734643DB75604C5493 -:1084D0005FF6F078EBAA57AB14A0FFBEFA0C6AF572 -:1084E000F78B4CF674073C5F6460EE16DBE0FBAF85 -:1084F00022BF109DD414A4736DB789E41C7F12F0C1 -:10850000FD2AA1876A81405100CFAA63CC171E893A -:10851000E3CABF50B06D95D8E910BE6281BE3C3C45 -:10852000DC37DAD6E27C4A309F703C152BA9554ADD -:10853000D07B4B6D99217D39D19081EB6172B8630D -:1085400013E0574E31ACDE01EB976F8616F0A1D8E1 -:108550001DF212689B4BA6CB4BA16D34B2852DD872 -:108560001AD8F2603C750879D2DA4B76D76F90EE64 -:1085700017DEEF2DB0929E1A6927F916EB6D941C49 -:108580003ED4439E2EE6D804D79A6417E37CDCC21F -:10859000908F7F2FE671980D3B55E0D7F7EC0F12C7 -:1085A000FF3AA20C8FA642FFA3E615150AF0AF23EF -:1085B000C570251578F478F34ADECF325C190DFDCD -:1085C0004F9A6B787F2A4C99CCD8C9E655159E6C8A -:1085D0009C97EB31B6C59985EF510C12C9A9B2D75A -:1085E000E46D843F9B22393F3519812F6370BC4A6B -:1085F000E39F6A28DE6C05FE578A9DEA6A1BC73531 -:10860000F2C3FFB4D5F0285B0DAB118FD822BECFDB -:1086100088756B7460ADCEAC39A8175A9C5973231A -:1086200010AFEECF11AF793DBDD3510FB77EF049FA -:10863000813B9BD30BE7C9EB612C12D673E1AD9B59 -:1086400036CA52803E97EC45E7515F4BA0A61F8784 -:108650007549AA9DDD0372D7E864AA09D695C85E5C -:10866000B2A3FD30207D4005B532AE5F3AA35C5F1A -:10867000E2736CA48FEC4CB5DDF515BE5FD3CFACC7 -:108680003766483DACD757A69CC765067C1093D289 -:10869000767C29EAF3DF9A1DB7A8088F933D0E7008 -:1086A0006C333085C5107B642870DFCAC21DEB5067 -:1086B000DE1D2CC903F2856823E0E01707F6D028F9 -:1086C00064485B073C5FCAA09D8470DD4AEB9291D1 -:1086D0009F2630978C7AAB8079ADD8F677BC95849D -:1086E000F87A3E8CDDE782D6F22A737A83F4467EEE -:1086F000B444F89F1563A436DCD83217F934FC1261 -:10870000B3A31FD0FF0B9382F38360DC89D71DFBDB -:108710000D0CE1FCB5D16B8F82BE3F53515F66817A -:10872000F9FA059DB5799F37A999D1D0AF8A9108FB -:108730002FBF2EE2F6D8FF85C9FB722AE2C7B2DA54 -:108740001B2457E3A3F9B8BAB8E2B1D1F07C4B4788 -:1087500038C3F74FEA0C3720FE376FC90D433ED8B8 -:1087600086B881F5C798ED8FE07C315700DE54BAAA -:10877000EE24BC2AEA8428C06BE14C9BBA0EF0FEC2 -:10878000EBB09699C8F7FEAD06F632BC629BC931D4 -:1087900007FBDB2EAB76D4B3BF4E6D09A7F56C3566 -:1087A000D07AB685FBC7AD01B8D7652815089F629A -:1087B000650AEA5FC550AC3E02D7A74573FDA8E93C -:1087C000E39A6895FACF4BF0FE5C1C57447253262F -:1087D000DB48DEFAFDCC6B86F7C4CFEB95911EE14A -:1087E00073809590DF159FCC703E17121A5A9BD15B -:1087F000AB929E75DA9600DDA70B3D3BFD644D25DF -:108800008BC48EE3D854986F9FCDC8705DB7B13ECE -:10881000D902FDDBAE32870FF9E7AA427E981DFE32 -:1088200005FB7B65629E5F494C898271455FAA0AA0 -:10883000F257110BF5DBCA36947F81F6ADC4A2BBAB -:108840008EFE5C24B64AE03ACCB3285AF861A3D82D -:10885000A86BA4CF60D6046147555C7FF67FE1BA70 -:10886000FA2B4C0E5CFF769BF3E3A9A8077B8D6C7B -:10887000131B5E8E7E550F1A7D0C08C7D570E68DD2 -:10888000253EB421FDC76D68F684C17AC7A5F3F90A -:1088900091DF506F8CFD455C2CEAED8868AE4FB4DB -:1088A00056E32FE4237B14E723FBAD01F9FB5E7451 -:1088B0002A8DD3E409F90BE7D963F42E760D6117FD -:1088C000812FBF877CB9DDC62A90CF9F1961598857 -:1088D000F2A4BD67B7E07B7DFB54C39A2E23AEFBA9 -:1088E0002FA0FF01EED2E4ABA660FBDD15C7E12DA2 -:1088F00093BF25BFFA62BB44FE7C423BD7D7C17C05 -:10890000316268BE7801F17A3DBED0C7011A5FECD2 -:10891000B81E5F74FF637CF18B68E1DF0ECB17DF5D -:1089200046E2FA1FEB2849647FC78F69137C30DC6D -:10893000FD2956AED7F4D7DB053E779B9AEFCC41A5 -:10894000B9BFCBE040B906AAA7CC05FBB23B9C3F20 -:10895000C794D569D8DFAE703DB2BDDD4C7A64BB3B -:10896000CDED267B9D6461E82730C5DDF77DD47FA2 -:10897000C916755D10DF3E2EF4408BD137E573F4D8 -:108980007F0F70FA4EBE2B5736C1B8110F70B9CE9B -:108990003F67DA28C33CD53145BE6818DF17CDEDF7 -:1089A00062DD1918057C597BC644FAEDADCE23E58E -:1089B0004E1BF9374EE4AF497B8E941767E378CEB0 -:1089C00047DDA2D5FA53704D3164768E25017E5D68 -:1089D000C24E4C615C0FB9903F72027DE634523C4E -:1089E000A6F1413563596827E6F639CA908DAA2A5F -:1089F00042E95BED9B4971DFFCE3CEB20858D77CBE -:108A000097EEBEA07FB58EFEE007FF01E564D5E6D8 -:108A1000DE4E1BF2ADCAED698B697516F77B56A762 -:108A2000A1FFAFC911FD004F2DBFCF78795D901D1B -:108A30005763F83A9F752874DFD367F2DE0297FE1A -:108A400037E3CFB5087BF3AD90E3DCC7DE588CFC91 -:108A50009BB7DCB90FF1BF284EA6EBFFC97C96345B -:108A6000A48F4321FFABC5A8967C2E05C631C595C2 -:108A70006183FB7BE2C3F3F0FDD531EE6B4827A6A3 -:108A8000F8BBF1B94985B9792857B6094DB1687F66 -:108A900034B801AE8A4DB6001C1A5CE785FEA98E7B -:108AA00059720DF180CFA15E693B75D682CF6B7490 -:108AB0006FE9B8C4E91D447FA47780FED27DD8D782 -:108AC000F06011ADD6FFE7E9EF1B89F41896FE18A8 -:108AD000F747FE8FE83F2A6608FA833F958ED73521 -:108AE0007FAAC5047E7576A0AFD1BDDA5E44E31CD3 -:108AF000265819FA4F9D1057A21CBAA3D1B9613B51 -:108B0000EDFC5DFDBF3F3B0A5C4036292686CB93DA -:108B1000C93F06FD8D093E89FCBE0920F0F7909FF4 -:108B20003592F49D43E0879D95A4B319DC05BF966B -:108B300082FE9F2F16E56082B9D287FCBEC33A3D04 -:108B400005FDB75CEBB434E4A737331E3B8426E75E -:108B5000CDE4E53B5F51037E8EA6D7F68969B5F774 -:108B600097C770FADF0E6A16FD3D740D83E1D0F4ED -:108B7000379205E1907CD5866B56D2C7ED7D80AFEC -:108B8000DB110EC06B97C45A517F17199C7125E8F1 -:108B90008FC5FB14EED77D3D4A05BEA96C7FF73823 -:108BA000C25B69B1F930DFC21CC6F37D41F912BD69 -:108BB0009FABF9259ADFAFF92D5A7C89FE0DDECFE8 -:108BC000C7EB00BFDD0C00A2FDF159BC0DF0FEE7C4 -:108BD0002FAB994E21AF0AACA352AC6336EB25B84C -:108BE000D8B7D7AE4D03FACC12F8A8EC86B8300748 -:108BF000EF337617E0E12E85C78B7739203E0CE204 -:108C0000A3D99343FBF89B9E1098E77AE3F5FA7F8C -:108C1000AAC817FCB371A6D676831D3A0D0C70B0A6 -:108C20009EC73485A3658F82F1803BD380FC582793 -:108C3000EC1A84C943DB2321AF8586BE1C07E0B74D -:108C40006BCF3764FFF6EEF9E623F4E7A67CA1309C -:108C5000333C5FF8457E14EA07E60A9DB7EE8FAD18 -:108C600056C6AF13FFD48AB5EFAFC78C18C267A141 -:108C7000F637E79F5F8FF37D7946E1BC2DDE5F6EAF -:108C800072A7DB6DD8F2787FBFC4FD1DEDFE7E2399 -:108C9000C00DD737C568717FAF42F919F89983E8DD -:108CA0007C17C6FBB901BADE75AEE20B2567307DD5 -:108CB000F0F7FF23DED7E2FCB744FCC0F69D30A9F5 -:108CC00000D78CD64714F4A36724C9CC19F4DE3B33 -:108CD000542B7306C5FB6FC4E8FC907DAFAD9F05B8 -:108CE00076A4AE477684A1BCB66F3F9483FD5ED96F -:108CF000611D828FF4F89DD1FE8882FC9F10CBE528 -:108D0000E67AEF2F1C077C722BD29D911F77B14022 -:108D10002239D2D377EF9E9FC7F6650F8FEFE1E838 -:108D2000AFA7C36FCE1747215EAE470F3DDF76C2B8 -:108D30003A3DB03E1FACD303FED6DE7A3BF5DFAE44 -:108D40004FA2BEC6AF751DBF8C457F4DE3D3B25851 -:108D5000CE375376AF8F65B600BD347C5D1474ABEF -:108D6000668EF9B3E0CF5D922382F48487F52615F1 -:108D700004EC55F5B172F233347B552D671B51FF6E -:108D80006AF60AD3C2A8CFF4F6697E7A9111D5AA01 -:108D9000DE2EC1028DC8BFD50B43AF57F4342B1163 -:108DA000D433109D2449E043F8D51A3C1F3217C133 -:108DB000ABA7A7069F1E2ECD9FAE1674837596E1B6 -:108DC000D2E7AA45B48E417655ACF746EDA93936BF -:108DD00034CEBA72AEF4FD9C21F87538BED5DFD71B -:108DE000F44039BE20975A0FFA1109B10944AFF285 -:108DF000AB26E6047BC14686B1CF82F3EFAF649227 -:108E0000BD7B54D8DFE1F8A6F6AA81B96303FC6301 -:108E10006C7BCE8AFCB35B69B662DEF136DB9CC646 -:108E200028C053E91F8BE7A15F57D76760989A2A3C -:108E30006BBFB40FE3F6BAE3CC81FAB0B8BDAB04B4 -:108E4000F9ED6DA557A638FA4BC69E0BF20FDBDA8B -:108E50001BADE83FB5C5C914A7EF8FE6FCA8DD6FD1 -:108E600089E5FCD776E6F22CE710F73F13F74B4F76 -:108E7000E51AD148F6C74750BEA1FC6903ADBF54FF -:108E8000B25755A2FF718791FC7A885BFEF07DCCCA -:108E900037B599B763AABEACED878FD881102DFF87 -:108EA000E7B30633E60FE6488E97615CB9EAEFC296 -:108EB0007EF9BC54DA8799F47F65F25FFD774B94B5 -:108EC000F7280776C17EF93DA95ECC3FEC9178DFAB -:108ED000D3C1F3FECCEE899D05EFF9A03276C23AFC -:108EE000E229AD7F4BEE3A261838289E7A6C17DFC0 -:108EF0003F7AAC4CA2FDA3327B0AF304F155F9D3BF -:108F000040CF3CE0C7F6C462E4DFAA0A997983F84F -:108F10007ABECBCABC41E3F7877178FC92D98BF952 -:108F2000124D5E670AFEAE5E181B327E0EE37EE2D5 -:108F300042D66C44F9AE13F0D415013CF0FC4C1150 -:108F4000A7DEED4E09796F256641606856DC68B290 -:108F50008FB3BFEC23B33A473E796C31BC87657061 -:108F6000F9D0E4AC4CAE69223E48921C181FCF9752 -:108F7000C0AB9451DF85CAD1ECC9A1FD394EBD7E8D -:108F8000089577BD1ED7E47C7E876CC4387A7E91C5 -:108F9000E46043E803BD3FADD703930C8E7730AE5A -:108FA0009E7BD549FC35480F9CACF887F4C05B200C -:108FB0005B93415E7FA4E9839BD84DA80FCAE42D43 -:108FC000EB913FFAC1AE9987E00FCD2E68F176396B -:108FD000C827F2033BCFF725CAAE829CC606E2ED56 -:108FE00001FD007E8363087FE657B16921FB4903D9 -:108FF000FA22C86F3016FCF37E4319F88BA65C8406 -:109000006F24F3E4919EA2FC1EB43ECAB3255DA278 -:109010003C4A1DC4F114CFB35F125CA8D7A49800DA -:10902000DFEBFD092D4F3B42E409F4FC3090B79B88 -:1090300067F4229F69FC506EE772513E4FA6FCB95F -:109040009E3FB4F75D8F2F7C12F085F477F842C80D -:10905000D38DF2C5218D1FD259FA8DF083C6071A20 -:109060005FE8EDC5415DDE65387B71F23AF6E29D61 -:109070000C23E965BD9DD0ECC28138AE7FC7C7F235 -:109080007D8A9999F36DE8578C407D80FE9EB037BC -:109090000379A30D9C0FDEE95BAA486837500FA443 -:1090A00006E15DE44D35BEAB7D9A51FEB052E89FBE -:1090B0008B1D3C9F56572A7B2DF06749FB73EB793C -:1090C000DF48F9B622A54BB1C0BCB31D9203F335FE -:1090D0004E917F9B75D5E455293F3FF47E7A95E00C -:1090E0001B8C7370FC6CA7E4851074901EAABACA1E -:1090F000EDBE5E1F5589FDF22ADD7EB9294ED0F501 -:109100006676F3BFD2EEC7C72570B919868EDAF33B -:109110001A1D35FA4DC0B1283FFBBE36A911DC3F00 -:1091200046FACDB8AAD03CA3E242FD962FCFE7FE87 -:1091300027C574627C5DFB25937BFCF0F05FCF2F2D -:10914000BD59F3C3855FAEBD7726C8780A3A863A23 -:10915000FBA1BDE7BAF6423CAFA7D3E4B8D0784252 -:10916000A387A64707E15BE8D9E1E8753D3DABE998 -:10917000B37FB59ED5E6D7EC80F65EBDFE1D2E3ED4 -:10918000D3F4E9531B0D9417B94DC4C1B7893CEB17 -:109190008342CE970B7DDBFF178B01FDAC6D9DDC11 -:1091A0001F7198ED87D06F08E4F3385D9F8C601EC7 -:1091B000DC2F674AAF85F62F8B81A4B87F99CCF757 -:1091C0002FB7283E17E96987C21A405EFE2AF216B9 -:1091D0004FEEF52C463DFDE4E93106DA47577CBDFC -:1091E00018174FCA55683F28DAAC52BEF76287D9C4 -:1091F0008ECFF5EFFE5E9711E7F90B7360A8F67658 -:109200008779603F06F54299DC23635EBEDF0FBEBF -:10921000388C9FB6D05782F1CE6DACB711E3EA42DD -:10922000A4E310F47B55675FF479FB920EEE27956B -:1092300044F0BA9FE980467CEFF43613F985D7CB2A -:10924000DB177DC9C85F1A94AF6FE37A0606119FDA -:10925000DC68DEBE107D3DE0E39FE8F40E1B267F58 -:10926000BFCDC4F773FC478C0CFD5E762E6EC8BC78 -:10927000CBF5F2F8BB3BC39D6A24EEBB71FF7C7754 -:1092800067B253CD197E7C4E9FBF18F395DBB6CCE9 -:1092900055284E14F9CF41FB223AFCED9058931516 -:1092A000F369ED8E528C3F86DBE728F63B69DE1BC7 -:1092B000C51B63CD9CCEA27EE9762163DBCE863BC7 -:1092C00091BFB79D4D76223CBB057F6AFCBEFBCCAF -:1092D000E570DACF343955DC07F6475B1C2F13BF36 -:1092E000723E6F1931C68BFBADDB853C6C0BF71FF3 -:1092F000CC8A0BDECFE0FB179DF59EAA33E9B4DFE5 -:109300002D61BE51DB27F680BC505D4E0C237E32B2 -:10931000B21686EF6D74B29F633B7D9A1A85F8BED4 -:109320001CA7ED47AA519467F8F64A816BFC60BC14 -:10933000EFA877513D496BFDC22A05607CB3DE4D35 -:109340006D5BFD726AF7D4AFA6FB6B0F453E8E7660 -:10935000BFCEB9A04A09D21B9FC5F3FC526ED6E915 -:1093600012E473F60D6318EF4C7FA24F463D71FB7C -:1093700055584748DD887219F14CF9CBB4403F5538 -:109380005A12867C79FB55E8078D97E2A3391D9A1E -:1093900094A65B0A485A881FC2E29D17E3E0FA0FC1 -:1093A000ED2E7F5C3CF241F5BE0B8CFA97F1FA0E84 -:1093B000E96EF9028CCBF31551DE380FF3C6B934E0 -:1093C000ED62C4DFC42E13ED7B6BF9DB5C31AFF3D0 -:1093D000ABD03C729EC8DBBEC9FA289F9C6F81C08F -:1093E000CA807071FA39A5F94912E6FBE24D0EAC5C -:1093F000579898E6CAC37C6B573CA3FC695757C281 -:109400004815F0E054785ED7A9E575D9DFCFEB7643 -:109410007F1AE9217D057E0AEAA7EEA3910E1FEDD2 -:10942000FF59C8FFDB810F627D4338AF1760F3E659 -:10943000511EFD760B5F07D89FF878CAFBF9F61D21 -:1094400086E77E7B99F17DC4DE93B43F5D62C84CB4 -:10945000EC0338F74963A3B07DF1D3C86C6A8F463B -:109460009E47FC741AAC2ABEF7C37A56857567CE40 -:10947000F76DB49F31FD7D9B82EDE1FA3EAA477BFB -:10948000BFFE1CB547EAFDD41EADBF4AED3B701DC3 -:10949000F9E7103C8F6DEEE2087A6EC7A20813C29E -:1094A000DB19C9B668EFC17A335FB8AF1593F9EF2E -:1094B000C57FBECE7213D83BB37BBC3481B113F1F0 -:1094C0009FCF54A07F68C6A87FFF0BDCFFDD4F2E27 -:1094D000ACB3005CF38EDA5A7BA0FFE94F2EAEB33B -:1094E000A19E3D140ECA0EF546FF41907496873634 -:1094F0003D9971053B19FAB1A2EFE99F590A245F22 -:1095000050D297C580B5A6FCC43FD302785C607585 -:10951000FF1BF64D9E976696DE847DE6C17A2EBFD0 -:1095200064A4F89E8D94E2B07E6599DD7D2C3EC8E2 -:109530007E3BA53FD2FE51815362D1714457DACFB1 -:1095400062F653B1C1F2B6CC5E760CE971473CDFEE -:10955000BF9A384D7206D749E8C74D3CA396229D65 -:109560000ACE9537613BBB229AFAAE85939A509EFC -:109570004B6DC33D5F42CF2F8837127F162B524869 -:109580007D887E5C1E3013FAC7FE03E1941798783D -:10959000CCDD8875A36549A9B9B2D0798CFAD11B05 -:1095A000711F6D62E587A5B1283F36C981E6A180AC -:1095B000F535C5C661FD231644E1BA9E2BC1FA9D5F -:1095C00089AAE440B41539BB5AF1F9224784A308AB -:1095D000FDF1636A299A9CA3CA84C3F9306E46BA26 -:1095E000ECB0C044477D774CBD00FDA28C28CAE397 -:1095F0001629ABAF1CA67E84A341C5756CFC792DE2 -:10960000CD63267BBE6356C97F20FF14BBA228E72B -:10961000576A3B3537B82E0CD64D7017D9656F9801 -:1096200084FCFD83523BF4778C9218CACF515FE6DD -:109630009FE97E77B81A0680EE30D94B71BE1D26A1 -:10964000C9BE96FAAE121CEF196354314F541EF77F -:1096500045C8FC334AA5296710FEECA80978AD621D -:10966000E4A590FB3D8BAC64272ADFCF267FA8675B -:10967000510AD98BCAF7A71563DB63E07E7AE5FB55 -:10968000951574DFC0E3DFCAC5DF718A3EC5BB959F -:109690008B5751BF4B4AFC777CDF95ECA85CCCA381 -:1096A000CD4CFF7AAE12ECFFADCE24F9CF1579BCCC -:1096B0002243E6FA6900FFA307F83E4465B6145258 -:1096C00037372BFF54483DA86BDA1721FDB9A59712 -:1096D00042EA43E7557E1DD25F304FAA0A1E5F7AE9 -:1096E000209FEC6BBEA85FD2F24B458285DEA9CFEE -:1096F000A82A05B93C00ED03A01F8A7A45DE55E192 -:10970000717506FC433D586AD3E577994AFBD91534 -:10971000DD7CDFBA3CCE783AD83E54C84F707F41EA -:10972000B7FEDC0346B293B9D132E5AB34F82A4632 -:10973000863EAFF95F1502CE1D0677530CE5C79C38 -:10974000BDE87F68F06BEFD7E0AE90EF29A5EDBFE5 -:10975000EBC0AF87170025FF4D0FC78178118780B9 -:10976000BF41FE5937AF4B835FDC50765BF3CF2BA5 -:10977000414F4507EB299B1487F576C3E9296DDE38 -:10978000E1FC306DDE6576173DEFDCFAD9D1423968 -:10979000A89F7A2A3626B8FFDA67EB43EEC79FAA5E -:1097A0008A0EEE6FFAAC0AEF4F57D4461BF0E34136 -:1097B00026393CC89F3DAA82FBCF25C79C4DD89631 -:1097C0009D746399299B71C6D384EDD4F3DE1E3357 -:1097D000ACEB8E0C59C5B85DF33FF4F09A13781CCE -:1097E00072F0AA6AC5FDD31D1ED58AFEFB8E2754D2 -:1097F0002BFA1F3B9CAC02E331679A6135FAF3CE3A -:109800002C5E677855E8E16FE2F9F35A7B5A717F75 -:10981000837A11EBC2D127A8FDDA4F75E007D1AFEB -:10982000CA1EEC571D54BC367CDFC127BCB6E07D98 -:10983000C21BF5ABFE8C363A1EF96C4E887C9658EE -:10984000EEAE0A96EF32FB9290FB9FC6A904FF8C06 -:10985000A48743C6DDA13E12D2077F3103FD9146A6 -:1098600013A33A598F81D7C9EAF1F8A8C0A3C366F8 -:1098700047378619E354AA6BD38F739470FCE9AF12 -:10988000A727F0B86823C80CB6F72470F8F475B1B0 -:10989000FA3EC47C0B713E983909F9DC61355C01F4 -:1098A0005797391392EEA47AD93CC3A369D0AF4E2F -:1098B000C8E2FDA9869D581F7B774236EFDF6AC854 -:1098C00033821FF02B36FE4EAC07AF0D13759D0F84 -:1098D00024D27E9816DF2886532F2EC638738F9198 -:1098E00061FEFE1913D8BDDCC0BEB9D5CCE352ABC6 -:1098F00089D76D3F957AF429D41B6A987B7A02F94F -:1099000051C52AE2EFBCDD42759D8FED2E4B44FA26 -:10991000DF93C0F35C593BA726A17EF917BC7F56A5 -:10992000C2C4E1DF8F75BE38CFF91D59E47F67DD12 -:109930000CE89502F887F098AE87419840E72598A3 -:109940003309F36C8DD1269AE79E04CE7F37DA0E69 -:10995000AAFB8D32ACDE0EEDFD82FE0FE07B095FCF -:10996000FE51737063CEEE1F35773CEF237D653972 -:10997000D78F7EACFF3B11B4AFC246FA69FFE5E377 -:109980007BB21CE89F7E12CEF1B7D03BBAB14FC577 -:10999000FA0DEF4D582F9191E8AE453C2C327B6F7C -:1099A00021FEB1AD8EC0F96FB41E78F07B2180042A -:1099B000FA544FE1F4D1DE0B38B5A03DF8589C03C2 -:1099C000D1E080F7FF00F9408367000E5D5DB89637 -:1099D00067AEFBA381F20C7512E83DE8EF3CC91CB1 -:1099E0001E98E7A2E6AF8BBC266E45E17BA61C5E07 -:1099F0005A628336BF6D258F737B95903CD7A4E365 -:109A00008A7EBF83ECD654ED795D9E71AA886BA7E0 -:109A1000EAE2DA1713849D4966C9C1798035226E5E -:109A2000B8DC333A0AFD4CD45132E0D5A4CA6C728A -:109A30004C40CE5B21EE674171BFC667E38FD9EF23 -:109A400047B8C71F63F7915DD7E61DC82F70BC5C90 -:109A50003ECEF132A12FE3A7D3A06FEC3632AF1A7E -:109A6000584F2107955DC6FFE078BBC98B75CB05C4 -:109A7000077E99E7834BE624035383F010A68633D1 -:109A800035482F5A336242FAB2866F61CFF3C4FC75 -:109A9000118EE49079F6C49477A37DCFB32D27FB84 -:109AA0001E357974C83CAC4709B1F3B028DABF9CC5 -:109AB0000840FD0CF05A704C09B1E793E23CB862E3 -:109AC00036F9A4A2B3FFCD32CA41E199D0EB0786A3 -:109AD000A3CB70F863393F45FFEE1FC55FB4331465 -:109AE0007FB115A1F88B7785E22F7161289E46B86A -:109AF00043F192B27C5CC8FD9B56E786F46F7EBC56 -:109B000030647C2A18A4E07EDAD33343C6DFD23C2B -:109B100037A43F76C3A290F199DEA521F7B35E5D2D -:109B20007143F41EDFB226649C9EDEB7B6FDAF9093 -:109B300079357A7BE0DFBF82DEE6C4507AA70AFD82 -:109B40001AEDE4F565FD46DBD312E8234C13A15E64 -:109B50008B6E7FF76BCC43788A55AA9FF3CC64B4A5 -:109B60000FFD82EC92500FA5C0148634AA5FA7FAAD -:109B7000BB1F1B0C21FBE28989DCBE2726F27CCDB2 -:109B8000CF4DFCDC520AF88F64870C2C102F031E7B -:109B900022315EA678FAC7CF60BCDC14DD97A14203 -:109BA0007C6CC6FE4D017DB9C8AC36F6013E26C8B8 -:109BB0005C1F829E4C4B84F93F919E30723FC26382 -:109BC000443F22C5C23C91B9643F287F1CCDE224AA -:109BD000ACC78F0AE869F51A106BDF8A2C3A07F5D3 -:109BE0001E4282FEAF2586ECE8DD9A7E5A9E49FA37 -:109BF000E9B22DD40FBBFC401A5D3F71AF99F6FB63 -:109C00004F883A446DFDE784DEFA53BD85DAF3F5FB -:109C1000F6103DB67CE3FA08F41F4F64707F51BB29 -:109C20005E82789B88AD2CEC9AC58EF9AC7BC038EF -:109C30004701BE5775F7452E62E43716E3BA6B3716 -:109C40005EB9F74DE8D719FC09DC3E7878BDCCC782 -:109C50008CFCCFEA6F5888FF343791C7E973C5FC95 -:109C60000BA0B1039E1600FEA3B17D775A39F227EF -:109C70005CA7F369B3BB19D59FCC71A7D23EE35162 -:109C8000E6F8701780F89D4495E09CC75CB45FFFD0 -:109C9000D1BDAB2270DCC07CDA3CC028E86F7C1CF4 -:109CA000ED312660DC7F1BAF6F80F759F0BAEB9E79 -:109CB0009427D10E69EFFB88B92F7C88FBDDCC415E -:109CC000F36AF3331613A29F762C5FF9692CBC6FED -:109CD000CD0103E513D6749829EEEA5FF1D7AD2FD5 -:109CE000C2FDFB52FA6E42BBFCC98A6FC6203FDC44 -:109CF000BD01F410ACB130CAFD7062509C72E281BB -:109D00002B11781FECEBA617D1386E36537DEF2759 -:109D10002B368F09F6471F4D2CAAC5E7D8E41B3B0D -:109D20006F58F27A6622D563097E7A58F0D39AD7B3 -:109D3000C6921FB52662809F787F13AFEFD0D6F111 -:109D4000A1E0C715AF7F5D107CCE7407F0913A8615 -:109D5000EF6BA920533B7B2EE7E0FD57147713C22E -:109D6000D779F57424F677BEF737829FCDBB31786B -:109D700051063D0581FD65EDDCE5C2F6D83CA43B0E -:109D8000C85933CEBFE837AF5DF81DE2A763F3A62D -:109D9000EFE3981B3C7FC9847D71083C807DA1F86E -:109DA000A09F85F3731D428F2AB8839E86E7991C76 -:109DB0002AF1B3931DC27D97C62E03C3BA9548DC22 -:109DC000B409CAB345CA06CD08392D49A09F855E9E -:109DD0007925F1E49D4DE4E787FA3DF96FAF08F18D -:109DE000775CF08FFC9D97DC8D9807BAAEDFE3338C -:109DF0002C3145DDB8FF0381B0532A105B38F06B7E -:109E00004B14FB22420F77A21C61FD3FCE85F97AED -:109E10005F383F670CA602F5F80F604DF8B0294592 -:109E2000B4D2C50C0BE8C5BD897F78E669D093969E -:109E300074BE5EEC37E2DFDD9CDF06FCABB7C7919A -:109E40009E62DFC2DB100F225FA1A7533EC8078BC3 -:109E50000D9233F1BC6FFFDF22314FBB35467D1FC2 -:109E6000E9E03F20D33E4D98D2678A1E222E7B1315 -:109E7000F59E89FB4D546FDEC6F38116D5C9300EB1 -:109E800008B3DB27049FB36B17FA6ED5FE4F4699D4 -:109E9000800E170C3D91D9307FCDAE1D91E8C6DF05 -:109EA0006B747F8A7CB7F2C40705763ACFB671141B -:109EB0009D03F08DA6BA83F10AF328B983E1A8DBEC -:109EC000904BC6B8760325E3D9F8F6BC87501FD56A -:109ED000F9F83A716E2CFCCB6C63D4BFD8D61883DA -:109EE000F3D5FDB62319E567733C8F135FBF3A8E38 -:109EF0003FAF3005C77F99182DF8D96BC03863B3D1 -:109F0000884F2E5E35D038EDFDE3DB8A643BF043AD -:109F1000B6AF792FC543ED6615E91AF60AE37868FE -:109F20000F2339AFEB9CC1309FDF1FCD1C12DCDF4C -:109F30001AEEFF039D33EB30AB981F0DB337B31808 -:109F4000987FABD80FCD048EC2F34ADA75ED7D61F0 -:109F5000ED3FC55802F981F2B4614A33BBCD168C8E -:109F6000E708C2733CF2533CBEC767C0FC88FF16CB -:109F7000C65E26B80270327AAF066726F9735B4D6B -:109F8000FEB3787E05E0B223FD33198793B58F5574 -:109F900031BE0FB33B691D6176D5E19106C355977C -:109FA000C3BC68BF7FBC960DC82BCA6F5D78A06F1D -:109FB0000119D83A9A09F9B63F5B3A2DB80F8A646D -:109FC00072E0F9711B629E6D1A49718347C638169B -:109FD000DA88185CA7CACF3B636A2897E301F7C504 -:109FE000AD167E7F603CF0B70DFB363ECE1165B7F7 -:109FF000CE94484E28AF572BE4FD31C977F67690C2 -:10A00000D3BFF8F6E6A8004BCDBB7B884F571ADAD2 -:10A010005F1C0FF7375ADCF94980CFB74E1AE81C9E -:10A02000E99F5E0BF35662FCB87B63827308F9D03C -:10A03000CFFFC3E36B9F4F41FAEF9654CC9BF61BC7 -:10A04000FDA310DEDAF6CF4D548FD0768AEA938ED8 -:10A0500024B99DF89EC96D0DB46F3C8535D3BE7192 -:10A0600096387FDD92C4F5C7E563635E6E08C2FF74 -:10A070008349DC0F637EF7CD2837ED423E3BD12F7D -:10A08000817697F08F7675DD9DA606E5FD1AD8DE00 -:10A0900014C4F75AF636B5DAF57E2F3FCF98F5910E -:10A0A000E53E6710FFB993B89FE716EFF327B9179E -:10A0B00024A1DC769D3645AA785EA56514DA911652 -:10A0C000F09FEC43E065406E757254A7F84D38BEC2 -:10A0D000EE1C3F770A746EC2FAFFCD1FB58D5B028E -:10A0E000D77701AEB1DED373C24C758FBB8CAE1483 -:10A0F0001CDFF0E15739A8B72A1069F0BFAF3A5614 -:10A10000DE8C7803BE2F0E47F9DACE488F69F299BC -:10A110008DF209CF6723DFE7633F93F4F056532FA7 -:10A120003FF7B98B9FFB04BE273900BEB7A39F90B2 -:10A130006D0739A0E7C7927C6FED35D0F9540FE871 -:10A14000F15BA85F5C85FDADBDA576926FCCC3E7E2 -:10A15000A29CFAF6D23C2D108320E924E60AF61FD1 -:10A16000DB1323898F35FD783091EBFF960C350A90 -:10A17000EBFFADB21C2217417690F7859DECDD50C8 -:10A18000FCEC0BD3D0DE09BB20FC27769CEBF94717 -:10A1900085AD5AF34EE1EC2DB0CE3587E5817A6E70 -:10A1A000F4577D824FF60AFF15ED849AC7EB67F0EE -:10A1B000FAC40DBCCEB5C0B9BA04CB38265734EFBB -:10A1C000C3B6D0D55282678EA72DECDDC7CF1EF364 -:10A1D000F3E3AD7BEFC8C27DEAFE136686FB24ADD8 -:10A1E0007FF3FFE175C0C3773B01FF43D825580ECD -:10A1F000F11F58EA149634F87EBFA4E98FF9952828 -:10A200006F175BE5401FEC612D3038F67F9D54F5EC -:10A21000AC07004B1BE17C1D59A230D94D6DFF915D -:10A22000BF25A02DD8758CFB4DAD266716F24FEBE0 -:10A23000E8D0F3FA5AFB62123FE79C6F6643E625CB -:10A240000F09BB37C6C39E413EAA6D95ED5EA0FBCC -:10A250008556D96902FFE6ACD39D806765CE31CFC4 -:10A2600082A968E745DCA87D4F6519FA2760A71E1B -:10A270007C61501EDF807CF450BBC47E066B5EFEAA -:10A28000D2D0FB0A35629E87DB36EE4F013AAE78BC -:10A2900025745C8DA813ABD1F92F8792447C98C6A6 -:10A2A000D2D02F01FE21BD605458B719F8F5C16412 -:10A2B0007707C61B9BC5770C407F921C7608BEDCD7 -:10A2C0002AEA04FC5B25DAD7CB7CD52B1BE0F942CC -:10A2D000C52BA39D62D0E23EC164A7BB1CF10BEB72 -:10A2E0003E86FB35CB851E5CAEF9655EBE9F01E602 -:10A2F00096FCB229CCDB1889EB7E5572F854FC8EA3 -:10A30000C8A03A5C5A779D5877CD8623FB318C5B89 -:10A31000D5123AAE4EACBB4EB76E6D5FFBCF49BAAD -:10A3200073C837B86FF16723F7133E10F368F7CDA2 -:10A3300023B83EAC05F0906E355ED9EBE57E9D0D01 -:10A34000BFC373BF80F77E41EF3AE633A5C0B8556F -:10A350002FF075B26743EB3F1F6C7DC484F1959E6F -:10A360002F966F31923F0A8833A1BFA8E78B156201 -:10A37000DD2B74EBAE754B3AB8B89F3C18AE960522 -:10A3800048D7555B8C0CEB11F5702D6B59528E7CB8 -:10A3900036985F395D5688F90270AEA6737C370A2D -:10A3A000E7A811822FC7B17144978AD81BA28BDE10 -:10A3B0008FDDBE7F9C15E5FB72F7688ADF35BAEB4F -:10A3C0009F2F177EF08C0D8CDA0B6D25D6F118A718 -:10A3D000F4181C924AF156E478C0475E87CC2AA153 -:10A3E000DFDF9EB6DE0378CF3D9C5F85F17CDE61CA -:10A3F000039D77DBD99D4FFBC07907D263D3281F1C -:10A40000EDA0EFCDC03C643FFB7B72D7E3B980FE8B -:10A410009ED27C9C57827168E773851D68E8C9B538 -:10A42000069FEF2E18C1E3F5A7923EFB31FAE13308 -:10A43000B61BE97CC30CA3FF3DAC9FDAD9ADD0BEFF -:10A4400075CDE1A56BC390AEAF49B46FBDBF774D7D -:10A45000DC62E4AB76A31DF7A1FBDBFF6D2FDEF71B -:10A460006C91E87B12751D65595BA19FBB31CF11C3 -:10A470007CDE2B375A25F8D8082BC5C3336E3292B1 -:10A480005D3C9F6CFD25FA372B9C1B498ECFEFD985 -:10A4900069A2FAB9AD1243D3BF3F69DF1B888FF3BE -:10A4A0006F1E31A1935DD27AC4D4F777ECFD052FEE -:10A4B00004FE1407379B304E59B551EBF799904E77 -:10A4C0002EE1FFD4BE728AFA2BDA24D2332B5E92AD -:10A4D000E93CFBBE8EB74CC8C7B55B2496981A748E -:10A4E0007F8314F21D84A58CF3C152A1675632EF0D -:10A4F00053C9306E6533AF23604F87D6E5AEDC328B -:10A5000087BEDBB4AC79687DF3B0E0EB87301EBC6E -:10A5100015BF83143AEE61EDBB5C3A7E7E5CE3E7E7 -:10A520004C9689FCFC55911A950DD7BF3AB2E2E6DC -:10A53000A1CEB1F7083BACD9C1CB3E03D911FDB8D0 -:10A540008B6D5708DEBA9ECB26B483E5ED9708EFF6 -:10A5500095ED5D54C7711773D7209EEE6AB7DA5137 -:10A560008E2BFBB85E9AD96EF67A25BCDFD284F4C6 -:10A57000ECEFE4758B9E3D12F92F9ABE7A48E0EF1E -:10A580002181BF874041A7E4A21FCBE3DE8733369A -:10A59000EE8F81FBB5E27ACD817D91E8EFCD6497B6 -:10A5A000EE457AC07B18BE87BD148AE73B1987E366 -:10A5B000CE2DBCDE596FAFFA4764CDA6FC23C49DF7 -:10A5C000084FCD96503CD7EAE2ED7523B87DDEA466 -:10A5D000C373A59F59B3110E5576786974AF82EF96 -:10A5E000EDCE9128BFDAADA6450DB5FFA8B5EF09B0 -:10A5F000BF59EBCF16E7AB5BECCDB6E038D894CCC7 -:10A60000EDFF8A29B207E934103FA4EFCB510D8149 -:10A61000F801E286DF8C88E771041674BC3B526651 -:10A62000717181F8E18749EB2B73A15FB785CBF995 -:10A63000C5C9301F7EDF4B61E45FD66D31D339C0B1 -:10A640003AA03BC509EDFC1C83AB5D2A437A83FF2E -:10A65000FDEE888978AE8619E360DD73DA389FCF26 -:10A6600029BD447C72209DAFF7B2A2260EE58F6B08 -:10A670007E389EC35283CF3F805CE2F8DA765E0F6D -:10A68000D4BAF7EB51A9A8D73AFE3A6A09B45746AB -:10A69000F0F56B7E9E1FFCBCD1DCCF3986FEE783D4 -:10A6A0009ADCD8F93EDA83C2CE30A989F8BBD6D875 -:10A6B000F2760CFA4D5BF9BE3DDB6DC46F9CB18642 -:10A6C0000F5E6F8A81755F7C5DA27A347CFE09E043 -:10A6D000B38B4B5B4EA31FFDD5560BF98F0F828FAB -:10A6E000383D77B03C6A72AB7D77AA81AD257F7229 -:10A6F0002D6BA27695E0E38B6D8D26CA9B79839EA8 -:10A700001F3DD8EF58A5E33B537228BF357C104E50 -:10A71000FE5FFF01D98EFB2780A7FF4E0EC687F094 -:10A720002F5AF786113DFB8FD8C85EFC49F0D979C6 -:10A7300091376E982CD3FA0D53789BD5F9D668A42F -:10A740001FE21BEBDE3777BE358E9FA7F612DE5772 -:10A75000BE8A49F120385BAC94DBD3FA0D1F2CA2E2 -:10A76000EFF0D4ED19806B8C292E00D770FC2F49A7 -:10A770003C1E3448A1F160DD6ED9155CEF05EBB9E4 -:10A780000FF54F929003A6F813D02F1999AC92FDB4 -:10A790006A68E7F43474F016DEBF80E73B8CF4FEA1 -:10A7A00041F78B3D3578FFAB542BDF4FBEEAA9C490 -:10A7B000FE7747CB544FF9DD0F568C0DD69B0CE13D -:10A7C000047AD619FD0914371E31107C75472E27DF -:10A7D000A4DB501F6D2CB567A3DEE1FA6EFF68EBBA -:10A7E00072E4630FBE373130CF6BC2DE325C6F1262 -:10A7F0007A152FF079C57AD7B2B9223EE67C942D2E -:10A80000FC3D882B26264F1C1C57DCA83F09F6E090 -:10A81000E86209EB89140FC6B53B8F737DD0D0F188 -:10A82000D0A7C8E7759F98A9BEEABB9D0F8DA53A32 -:10A830005BB7FB56F42BBEEA7CF856CAF3496B09AA -:10A840002E0FC29784FECB8709580FBAAAE3C30420 -:10A85000B2AFBB26AEF744A09F927B275E07BF81B5 -:10A86000F80FFC17E2BF9D3DF99ABF62C579571DED -:10A87000505C889F5507F20F55A21F71B8381FD53D -:10A88000B874389FFC953CF4576C01FF455B4F65ED -:10A8900032AF77E9EF0AA33C81C44673FE61E92138 -:10A8A000FC53D3FA0ED9F59A3639A46E507BCE9D5F -:10A8B000ACF07D7E8D7F5A2427F1C776DED6B4EDCD -:10A8C000A4F5AD34B610BD1BB618F9FDADBCD5EA84 -:10A8D000AA3D2CC683F8388497800E334D5EFA6EFD -:10A8E000C5C154EEBFEBE9F15932CF631C3CE1BE68 -:10A8F00019F9E560917BAC7D08FBE061C53C3E95B4 -:10A9000004BE5BF97925FDB853C93C8E8F8C0D3D93 -:10A910003F3A605F9239FFCC340DFD3DBD9F69F237 -:10A92000C4D83306E08BA39546FB3AE1B78F08FA0B -:10A930005E42D55D46F20F8E32FB3B5867384BD3F3 -:10A94000AF93B95DD5F2DDAE0D2ADFD7197CAE919C -:10A95000F4E47C6D3EFD7969E1D7CCD7F935EB3570 -:10A96000FD37868D41FDD722CEB9ADC90CF306E780 -:10A97000A3F4ED7EB18F81E775B06DC8FC98F23617 -:10A9800007BB4EBC41756627C2D8689E97A3FCF5ED -:10A99000AA61F2D70D03F2382F84BF347A5C10DF3E -:10A9A00055D1D3E30D81776D9F2D5CECB39D56DCC3 -:10A9B0006F24535DD67913FF8E9A9FE2AB864CEEDF -:10A9C0001F5D2893685F1CE01C650ED2EB1746F0F4 -:10A9D000B8EABB0B24CA9B76E1788C9F5A24AAABB9 -:10A9E0005EE5EB35211F8D695DF224C9AB871D63E0 -:10A9F00041DFA9986DE17671806EDABA07EC568C6A -:10AA000087EBE1386A713CDAC159C2EEE9CF218D9A -:10AA100065BDE51857563B2507EEDBEBE93D77E1D1 -:10AA20008477E2FF013A9F4B761F21FDD67B7901A7 -:10AA3000E63F0F667E3E0AED65ED307CFB3BC1B71D -:10AA4000DAF7591C63D546FC3EC98F12DD9F207E84 -:10AA5000FB0DDF468E63F87CDF7FAF91902E8CE894 -:10AA6000319C9C9C12F39D4A16DF258CE3FB24CB82 -:10AA7000B18FF26AF48EA4FC42F68DED4B35EC7E7C -:10AA80003707F5D6C5AE0339A6203A9E5F03F28E8E -:10AA9000F6A3635F826A0BE63303F1972469FCA691 -:10AAA00008BB18CA77E791EFB2B1FD30321DF5EE61 -:10AAB000F6A391B7E07CBB783BC09FED328D8378E5 -:10AAC00067CCFC8860F89E24F82EB4F07918EB1B54 -:10AAD00053353EF87EE3707C6B4CE1F584217CAB12 -:10AAE000ADB705BF8783FE7DA799BE8783F9E6E8EA -:10AAF00020B9484DE1F230497CFF660AF3D0F700F7 -:10AB00002789EFE04C51984F89C17D2E9FCCF76586 -:10AB1000F9798602C1BF93145F17D6394C11FB3205 -:10AB200085AC97C64D677E6A9DCC4EE7148A9983A3 -:10AB3000DAC916DF9D9876C96E69A1FA3F5F821265 -:10AB40007DD622CE430C41B7C0FA15FAEE0DF1A521 -:10AB50008CE76186FE6E4A650A9773FA3807D2F76A -:10AB600002A3FC147EDF0C5F325561155877749B8D -:10AB7000C22CE100EFF6B70D24BF9D7DAA17EB4074 -:10AB80001DB1E2B92F18D5BB4E7272F944D382754C -:10AB900012DA7AF5782884F9303F364981C892F084 -:10ABA000E8A3F7DDCEF8398D22A6D207566EC78FFF -:10ABB00027935EF7539C54027112EA7583C543F8DC -:10ABC00028C3E4CA44BEBF1109F314364BEC38EE77 -:10ABD00057A4F1F56AF3170223E0B9BD32B15E4C18 -:10ABE000811E8FE1FB1E9154385C6AE7DF094AA0A1 -:10ABF000EF04DD285EFB13F8772123EFF75FFC7E7F -:10AC00007E60FFC781DF0D8A0C7C8FD281E74C30DC -:10AC10007FE753CE07FBCD77A72CAD4E9918A897A9 -:10AC2000636EA6A25FA1AF9743F49D0B3ADFACD54C -:10AC30007BBCEA9DABE2B9B98571163A4F9B6B19A3 -:10AC40009587762B23D15D9D42751F5B6EA14914BC -:10AC5000EF44574480CFADCC3919F11CA8D7E3DFBE -:10AC60004F1A38CF94C0E8FC9FD5CCEB199F01B99F -:10AC7000C0EF178154A958D7C29E28A1FAC7A7A22E -:10AC80002D0E3C87604678AD01781B2DA2EE47570C -:10AC900077D96833D0F7381B59389DE79E15E6FE03 -:10ACA0001EAEFFB188623A2F9DB56D5A12F983B07E -:10ACB000DE69DA7A0D83EB10B1FE0F9FD3D7FF69FF -:10ACC000EBC2E3EBF85EBBC097B64EBB76DEC7A91E -:10ACD000849CF7D1D6FF4C385FA71177E2D3E859AF -:10ACE00015F5837E7D1A3FFC3FDDFB356D605C0012 -:10ACF00000000000000000001F8B080000000000A2 -:10AD0000000B7B2ACBC0F0A31E818565181826F1A5 -:10AD1000A18AD112CFE066607804C42C3C0C0C856B -:10AD2000407B23807424101F01E2A340ACC2CBC03F -:10AD3000100BC471403C07C89F0BC4A5409C05750F -:10AD4000632B0B03433B107702713710EB3033302A -:10AD5000E832136F7FBE0803C31309045F51126802 -:10AD6000A734FDFC3FD8F00A7DFADA276DC0C0B0E9 -:10AD7000D502C15703B2B759A0AAD96E81DF8C1D85 -:10AD800068F23BD1F8BBF0E83FAB87CAB7D540E5E6 -:10AD90004B693130782285899D067EB7A0E30AA0F1 -:10ADA000DE4A200600FB72DB43680300000000005F -:10ADB00000000000000000001F8B080000000000E1 -:10ADC000000BE57D0B7854D5B5F03E731EF3C8CC6F -:10ADD000641242483084092FA30D3821210D14DB61 -:10ADE0008140448A1AD42A54D4098F24E435011F9F -:10ADF000176BDB0C04232060B058A2463B4150F097 -:10AE0000061D6890200107B034F4A206AFF5D1F614 -:10AE10007A8352400824E20BBDB6FE7BADBD4FE6FF -:10AE20009C9319A07FFBFFB7FFFDE3D71EF639FB0C -:10AE3000B1F67AEDB5D65E7B8F6C3213692821DFCF -:10AE4000C2DF0F089926114206469EF6D7889BC49A -:10AE500013529F4DCB4984A48D2041221032B986D4 -:10AE6000967309597B27099A3308D97FC484DF5721 -:10AE7000FA5899B60B99AEA1DF47B2F74F64D27674 -:10AE8000F4FD1317446C179841829B693981D0DE19 -:10AE900086133A840F9F933D0DD6D1B47ED39D2661 -:10AEA000627613F2381D868C27C441BC56429BAE95 -:10AEB0001CC1FA7B6C86E93951808FE19479B4BC6E -:10AEC0006A4A49DE2A5A5A2D33B81A67973C17A0A6 -:10AED000FDBB4CC3711EB4DE13765AEFD1F74AC9DD -:10AEE0002ADA6EC31C93509245EB352BB3825991ED -:10AEF000F9ABCF3944E2ED0266533E3CBDFC195636 -:10AF0000E0F98B89261C674D0DC307ADA798520841 -:10AF100069ED3C60F1D1FED654B61E2DA4DF1F1999 -:10AF200061F2500C92473A0F58AFA4E307724D9E5E -:10AF300091B4769A14165CF6C878E309057C1CADCA -:10AF4000E7D96171DBFBD7A7FD4E8279AFA67817F1 -:10AF50003322EDC6029CB4DD1A4AB2101DF797B237 -:10AF6000E7308CFBCB1B12850089D4BB1E80847A12 -:10AF7000734C244CEB11A9D742E838AB26BE6519B7 -:10AF800049EBAF2A32C124C81A8FFADD6325D0DF1E -:10AF9000D4518747005DAFA7DF611E598FCD8279FD -:10AFA0003F3A452180FF5F0AB41E457163B1F24309 -:10AFB00080CF51435CF09E3EBDD1F0DA2658100E92 -:10AFC000B27A0321790440C0BF55DEE08A61C05FD8 -:10AFD000B9C403E5340F6D6FEFDFBE4B30235D1A4C -:10AFE000E5402AE02F16FD46707CAECA5C6C057AFF -:10AFF00010D29052349A90F580271854F2B9673ADB -:10B0000022F557080C3FEB64E215E8FCE27295E08C -:10B01000528A6753966B36CCD7EE53C875B4BC5280 -:10B0200008A48A4097D10AD9EC46BEB08EA4E53573 -:10B0300057257A80FFEA85508A04DF6FA0DF699781 -:10B04000078AC6CE06FE6CF228C8CF947F0E03BED8 -:10B05000D7F812C92A377EEFC4F6F6112E33628272 -:10B06000C243F13280F212E035FBA6FAEB87037D92 -:10B07000C6995C40A155C224F73C909F048B0BC637 -:10B0800097C7DD8CF49307260A4443EF9F03BD293D -:10B090009ED6BA8B7E0ECFA7723F4C1849EBAFCE2F -:10B0A0007EB911E8F4F4FD16A4DFD3E33A17815C0E -:10B0B0003D7121E73D1FCAA5E2D94CFB7926FB442F -:10B0C00006A1033E36EDC304C0DF90110DF7102733 -:10B0D0007DCEE8AD2563287CA4A1687E06F2897048 -:10B0E0000BC5EB90250A715B182DBF25F09D7843A9 -:10B0F00059AC6CA7F319C2E9DCDAF996A518FA9BEA -:10B1000043C2A39CF8DE929C18D13343724938990C -:10B11000F6FFC4824328E74F5F9DEC61729E82FC7C -:10B1200092CEFB4983FA54BFA45848208E3E8774C0 -:10B13000F4DE0C700DC93C3107E0DCFFFA2101E8B8 -:10B14000F6CC986437E8A3045F27E9A2741F92F550 -:10B15000CE8350CF610FA6146561FDBF603B03FC39 -:10B160002D6EEF26C0DB36A1E630D027906DF23091 -:10B170007A333DB8FADEE420E89121B63FCD14875A -:10B18000211F10924CE1731194937A216C190EEDEA -:10B190001E60ED8692A000781E921958243AA1BE36 -:10B1A0004F2872F41FB7153422C807E574E0D7EDB5 -:10B1B0000A292F8A2207AF7279AE17C82CE46722BA -:10B1C000FD15F8666802E31BB5FC0CC043C7DDFE45 -:10B1D0005AE20FB3283CBF5A322C5BA4F0AC857600 -:10B1E00051E4660D97035B07090814AFFB7FF73B3B -:10B1F0002BE06DBB899441FD4999214B17A72BD0BA -:10B20000630161FD37656DB4A0BE103291EF16E4A5 -:10B210002B5EEB1890BF65828FB64F7131BDECF09D -:10B220002841D0CB8E948060A2F0B8B3886B6306BF -:10B23000EB2E40F13717FE018C2EB1FAABD7240468 -:10B2400057D1EF73B3A8A001DE28AE4C74DCF984AB -:10B25000CD73AEA77E11D08F902213E073958BD162 -:10B26000A709C6A153694A63FDACB98F0497011FB2 -:10B27000B958FB11D084D26D44EECBFF22D07ED3DF -:10B28000783B907B68179712B498683B778D89203C -:10B290007C52F8B000741F9DEC06789A523CFF3E39 -:10B2A00003E09F257936D2CF23000EDA4F538DC9A4 -:10B2B0008BFA225769063DBDCACBF4BC8AAF0C3E5F -:10B2C0006E9A272CD0B9930CAA27114FDEB0D50562 -:10B2D000E52C064F462E9B571FFCA395E032DA382B -:10B2E000CD1226504FC54309EFAF84CFC39E125CE9 -:10B2F0002101DCB90C6EBA2E233C69594A33C8418E -:10B300005A0AEBCF4DF1A3E21DE0B2A970E5D2FAE3 -:10B31000A0873D4A33B0828DC35792C5E0D97FE400 -:10B32000AD0E81F5877265E3F0DAF8FC09C09BCCBD -:10B33000F53AEDAF450E0B22AD1F1C47DC1BD9685B -:10B340006E292FF2FDB11A8A075AB0F371C87A3309 -:10B35000CA037D15F896F2C1BC065ACE8CC8C7C880 -:10B3600015669DBCD8F9BC49039323CA366168971A -:10B370004158D904653A8F924CBD9C118FA64CE17F -:10B380007000BF53FDB374BCC2F8E72A66C710A2B1 -:10B39000A9077C3ECEFDEC6AFCAEE0BA9EFE5345AA -:10B3A00007DF909AE4C922E8938E276F36015FDDAC -:10B3B0004B4C623CF2B3D0A7BFE8783B1687AD3068 -:10B3C000495B475122E02DBD2671B20278ECF06155 -:10B3D000D9D651E3C5272C4D6309194C34E3648059 -:10B3E0007E7555B450BC921A2504FA7A9C164EFA12 -:10B3F0003DFDB5869940AF87171D4A05F94D36B416 -:10B400001F631A86723AE4355A0BC73FF133A8BF5F -:10B4100092EB131B403C169FAFC173889DEA59AA5B -:10B42000A7D3298295B1117DB1EAAA77B27D76CEF4 -:10B430003F89F80CC3D3A85734F5AFE2F503C245F2 -:10B44000EB9DC07A2A3CC6EFE70413EA2907D89996 -:10B4500014BF8F12D76C5C973D265C17E3F8FB9006 -:10B46000E7C064A4678878840CD0B77F356BF9E0B7 -:10B4700027F012F4AD14423951D26D681F52398E43 -:10B480008375AF49AA2983F7A1341B01BD7060EA17 -:10B490002101F099D6E61B0A72A8DAB9933DA114EE -:10B4A00078FFC861DF95289F31EC46D54E34CEE752 -:10B4B0008A6B97A13E18EAEBED80F5DE5E2979AE46 -:10B4C00003FEF251B8ECA827DDE4BB147E4F6029DF -:10B4D000E859B78F9607D167257F96B1EF2B6BCBD5 -:10B4E000728E4B917E578EA0F628D58BEB3BD75BA7 -:10B4F0006E003BA3C6E406BE5DE379CBE2B54379BB -:10B50000F200C0736B916AF78505182FED6D2FDA85 -:10B5100079E35C8A0B94D6687338D5A5592F9AA61F -:10B52000BE3316E020B75222A6C6A6239D2FF2599D -:10B53000ACF504603169D691FD993B707D799D5CD5 -:10B54000857451D715751DC11EA97E99C7E5E811EF -:10B5500077C822A0BEA2B24BE9338FEB113BD79B39 -:10B56000540F333DC7D793358B92713D51F527D892 -:10B57000D6A024E6717DBB26FBB9841B284C76D06F -:10B58000B3A09752C864587F47829E01FD240504EA -:10B5900018AF699C8BACC2754CAF4F47D6303DF8A5 -:10B5A000480A417EA2EB5033AC774D69A114E8A75D -:10B5B000A9E680E0D3AC9FEA7AE7A8E924A007E7F0 -:10B5C000E6B2756E6E161BEF0F80A0710C5ED0ABED -:10B5D000C675EF171377A0B28CE3F69611FF828938 -:10B5E000D9818FCE780BF1B866FE63F8240D1BB0BD -:10B5F000BF140BA3C1CACC03F87EB5CF340DECEE5B -:10B60000F552E78A1114FEF5D3E62A01FA7DB587D3 -:10B61000F95DAB26CE7D0ED635B3496170D594A1C8 -:10B62000BD1AC7E1DA007DA39FA8A05F74DF9D1B50 -:10B63000570CA3FDA4503F467043A5A0C54CBFDBEB -:10B6400081A6A0BF7D6106BF874C2651E0FF0FC1D8 -:10B65000C6FC505F67C748A4A7C905F0C6797A2D14 -:10B66000E027BAA91FE67603BC6EEB6884D7E45ADC -:10B67000EA8EB4FF3DF717EE82851FECFBD9EF4C45 -:10B6800003F95A7727F3CB8CF0DF3729D861C271E1 -:10B6900008BA758E18789D031A0CF48F27887039B4 -:10B6A00032195CC70546AF473B275F8F7E52117D3D -:10B6B0004F3B7AAC739815E4DB68EF3D1DF74136DC -:10B6C000DA3B8675E652E521067D3FDA1C9A8EFC50 -:10B6D000B6CD847A8A10A6E70462727F3B1C1611ED -:10B6E0000617B21ED5DFCBE5F0ECF9B4FEF29D767D -:10B6F00002F852F9218DF7B9AA86F24194797708B8 -:10B70000622CBA333B83D3BD13C61B7869FA5369E5 -:10B71000B682DD160AD60F2E07FFA386F9BBA1F06D -:10B7200001D43F69536E433F654B73F2ECF9C05748 -:10B73000995E0FA0438507EC93687EE27493E5A2BF -:10B74000FE7B2C3DDC58B91CFDDEC6CEE8F39F68BD -:10B7500062FE7688EA494F56ECF1F34CCC8E4E30BF -:10B7600071BE9B7A2845BB9EA9EBAABACE0E914822 -:10B7700040D4AC87B772FC19D74D22355846313EBC -:10B7800047FFB1713E8B436C9868C2F88ACAE7B430 -:10B790005E0AE095CE03ED39CA8741B0E71E250D5C -:10B7A000283701DA7E33E90FF79DC47459F39BC043 -:10B7B000E7D7371EF7AFEFE2FA6A5DF6FD56E88A83 -:10B7C0008E9702FCE177323D59E560766CC14E39C7 -:10B7D000FC030A4755B3807696699F15E13CB7890B -:10B7E0009669D7618782F5CFBA2C58F69B3BD77EF6 -:10B7F0008F967B778A04EDC84C9B09F8F504E757D0 -:10B80000924BCB600F5B59B1AA79FF5DD05F599B1A -:10B81000995869FF55BB4B6FFC1E2D9776C804AA3B -:10B82000546D5EAA0CA6E585412104E59EC974A16C -:10B8300002BC242A41F0DB7B9C9DC93FA2F33E5D04 -:10B840006B216E0A4A9DA333F9568A8FF2E0F642C5 -:10B850006857DE228046A4F3D87C2815E6B555F05B -:10B86000807F5FB1254E670F9EA053F901FDBE9802 -:10B87000CE13E4B2943414C23A57B5799DE2D6C4DB -:10B880001F4ED7BA701CB55CB5958E43DB55BF28EB -:10B8900078608AD526E2033D746EB775D6B3769884 -:10B8A000DF52659403E6F5B002F54A83C52F5BDDF0 -:10B8B000005FB35248BF9737352B10DFF29BC9DDCD -:10B8C000E0E7566C19A087AB5144795D9C60D908BC -:10B8D000FA9CD8BD29378FEE4FE7D3B554C78E8A6F -:10B8E00094CB411F221F0695999AFA43C504E4D7C9 -:10B8F0008A2DA2DECEE6EB7FE028A37F60AF03E3D4 -:10B900007E2AFD16737F59A5DFE2044E4FA9372F1B -:10B910001A3C6B811E149E06C0177DAEE6F03927D7 -:10B9200092491077717A894B88C2D7C667834C8A4F -:10B930008175FF75D9CC49522ABA0F8B20F2E45A8F -:10B940003E7BD2145AFEBDA968B309F587C70D72B4 -:10B95000A4FAD9CF98985CD6A72A88BF86A979CFB0 -:10B96000B2F804C175AF616AC9736017D0F6DB4CD9 -:10B970002887B4FDE8D8ED5D85F9BAF6AEC232B5D8 -:10B98000FD4E6C6FB978FB86C209FAF10BCBD5F688 -:10B990007B117EFBC5E1775D37513FFE7595D8DEA3 -:10B9A0006F66F4EA4DB0A05DB3DCEAF14ACC8E0AD2 -:10B9B000C37B2971D446A827AAFC403ABD607FDB2F -:10B9C0005B12C6AE225ABE98FC3AC0E1A0D2A2E5F4 -:10B9D0008BF87C9B8E1F13BC89BA32EDC975E23B94 -:10B9E000BC0C83382D088F3258417D3169B005E198 -:10B9F000BD7F9F15CBF74F60F0DE3FD88E72866B10 -:10BA00000BA5E3FD8AEF1AADDD0A2B138492DE103D -:10BA10007D1F027E23EFDD26786F13490DEA673321 -:10BA2000417DF47046DEB3010D7E560CA1F4A5E510 -:10BA3000B360FF0C8CE0F5E1212529C59A71EA87F6 -:10BA400028B33666B1F7F3EC305E510FE0C1AFF4C6 -:10BA50008E02BBD2388E7958BE6E1C4B7A198EF38B -:10BA6000B5611C737A99611CCBAC8DFC3D1FE71B43 -:10BA70009857AC711E1E36413F9FF4721CC72C1A9A -:10BA8000E6935E6E18C7C6E643DFF371ACE2C5E627 -:10BA9000337CA27E3E432B719C2451D1C5ADCC4357 -:10BAA0002B0DE3D8711C780FE39034E6DF28E6DE37 -:10BAB00012A4FFAB5602F6B462F63D0FFD923F5A58 -:10BAC00009EA13371D7710E89544DC2FF80F53224D -:10BAD000CEE70B1BA5BF5D4BE7806A17A0BDB38007 -:10BAE000834882F5E89F57731E9DDF32337D293CE2 -:10BAF000DB0A528AC1CF5EEFF040FCF45C5B81321E -:10BB00002F8A5DB0A0413ED1A5E35FAEF72693CC6E -:10BB10001AF0B3B81DA0964F50FD45A8DEFA90EA82 -:10BB20002F789E94A99EA6EF8F53FD46142DBC4BF3 -:10BB3000B1DD0989E1F144135B47BE587754C6383B -:10BB40005F80BC9D49E7711B9FC6828638E62B70DB -:10BB500038FC9C1EBDBBCDC18D480FEF1560F79022 -:10BB6000C6011457BCDE30C0171597442C5E01F691 -:10BB7000D18F576CFF0D547B47281EB298CE775655 -:10BB8000EB3AF90A5A3E2777DDE5B16BFA99257F42 -:10BB900008F3B6D0FFA09FD93E5AD68C7F4799BEF6 -:10BBA0007C279122654AB7A9E2304E0F3EAE3B2872 -:10BBB00003BD6E4B66F0DC09CFB1F0D985F4BACB8A -:10BBC000C5DAAAF0F81F944918D7A3AE81CCB81DE6 -:10BBD00088F57CEABA6280EF2ED9E22DA2F4BCEBA4 -:10BBE0000111F16884B76B5F9CD744FDAAAEC64FC4 -:10BBF00065F02F2F05FFDD4BF4DF49808DA7E2555F -:10BC0000E583DB674D1A705C536FB6EFFA01C735F9 -:10BC1000FC7247D94C5DF9CE9AD9BAFA772F29D65A -:10BC20007D2F0E2CD47D9FB76291AEBCA0E1015D4B -:10BC3000FDD2C6A5BAEF0B832B75DF2BB6ACD3951F -:10BC4000AB424FE8EAFBDB9A75DF4DFBAEBA09E485 -:10BC5000B1EEF72201FBEC73FB89B5605F7D6E9757 -:10BC6000D0AFAA065EA37278AA3605F9FB74AD1BA5 -:10BC70009FE7DA72707FCC6FA3F24CD7FA0D75870D -:10BC800097AE98087A84D6A73AFCA9BA379706A83F -:10BC9000EFBE1182D494EFC546858407801F93D8E8 -:10BCA000C7D7BDA2E67BD725BE37D2052BA7FF7726 -:10BCB000B12BFAFB1EA17714D87781F7CDB87F138B -:10BCC000CB7EA07F579028FE83FAEC86F88646EF5D -:10BCD000BC2A32BBFA1A71F2AB227D562A4CDE2BFB -:10BCE00077A44E867841A5121E5513C5CEEE1B2FA4 -:10BCF00044811904FD30795918BC2222BF48BFE1A4 -:10BD00003AB9BFC1E4DB07FAB97BBFC8F607C2077F -:10BD1000D3619FE61AD1FB2ABC276D03717D7CA7F6 -:10BD2000D63BE0F80842DEAB9D86CF3FD4160D80AF -:10BD3000F8D19F6A6761F9835A1F3EBB6ACBF0F95D -:10BD4000616D0D7E3F5EBB04CB276A03F83C55BB9B -:10BD5000029FA76B1BF07B776D2396CFD506F1A9C9 -:10BD6000CA816A8F92246EFF717B9DAE1C583ECFB4 -:10BD7000E720D27F77A25C7B5240AECFDBBF1805B5 -:10BD800076EEF9F7CC18448F852723BFC5A69F17F9 -:10BD9000D7FB9220A57F4EFFEF561BA38FD544A65D -:10BDA000817FB672A44220AE6E7BF53B682FD3F73D -:10BDB00012417D19F468F711FBFA87390FBA349DE7 -:10BDC000D4FA279EFCAFBCB959401F465FDB41B196 -:10BDD00086D1ED590FD04D833F6697EDE4FADC80B4 -:10BDE0004789CB9D119F6707AAF8EC4C87784B9544 -:10BDF000586492E8BBF3AD669CD7F9F638B68FED80 -:10BE00004ABAAC785EC516AB4BAB1FAA42092EBD31 -:10BE1000BE487569F5C5F98E679D20F78B534CAE0A -:10BE2000E339C01F5ECE1F8CEFD4FEAB42192EBB90 -:10BE3000AE1F7DF97C83308DED2BBAE36F8DE21F51 -:10BE4000A8CFC5298AEB38D50BA7B70C8F8771A966 -:10BE50001FE78271BA6B5D2E366E8A4BCB97954B7E -:10BE60006C585F852F56BFFF68F860C7EF230B8BB8 -:10BE700035419C2656FD98F4903E53C03F20EDF28C -:10BE800017B0EED832D57547C2B2DAAF3F2406CC30 -:10BE9000D7C0FB16DD78B49D5BF5A1A15D6CBA4BF4 -:10BEA000E4844A4FAA27AFE3F921949991CE3EDA70 -:10BEB000633CEDAF47B2AF80386F86E4467DE787DD -:10BEC00081283F5559BA149F1BD1DD8971CF7C550C -:10BED000EEDDB7FF91B2DCC7FF26633C837C437B7A -:10BEE000A7DF65FE753E2972829331B7B56206E819 -:10BEF000C98F4DAA3DD09007F33E4B4CB89F7F961B -:10BF0000BCE5CCD1D86565128F4FAE60EB7380FE77 -:10BF100007F3A3769A6EBD2E6DD4974BC8CDC9207A -:10BF20000F25EB65D8B1250B61BDD7EC9BCC925C9E -:10BF300038EF5252530F76CA2A99EDA3CE7511E904 -:10BF40000A0A57D5AEA7F3C09EF54B4CDFABFEF304 -:10BF5000C2440677795250F1D2EF1FB5E6DCF63DC8 -:10BF600002ED83F5A0D7020EE289168F99B7420F32 -:10BF7000DFA5E037C24BC8321D1C6ABF2A1CE2167F -:10BF8000216A9EC6CF2481C775987CAC91F4F6EBEC -:10BF9000631C0F6A7983A1DC64A8AFF289CCF92411 -:10BFA00043F23D06FAA7CAD25B88761AA1FC911526 -:10BFB000A9A744EA6DB8583D33D413B15E93342E2B -:10BFC000763D6BA4BFE668FD55EDDAF67280F2535C -:10BFD000F94B8F3B21E8FBB1D4900CF1AFCACD0FE8 -:10BFE00039014FA7A48013E8FD71508C1A177CB754 -:10BFF0000F5F5EBB007E04B236C5FB0B8FDC08FA18 -:10C00000FA8BCD32E6C5F8B798C366CAC7D5AD0B73 -:10C010006740FC9E968FB1F2C39FC0BEA1BF4D4F3B -:10C02000CFF2E71F4F863811C524B3B74918ED8EFC -:10C03000EA4D7F2E043DEE27BDC887C67630FE85CB -:10C040004494FB6225BEFF77355FC1CFE5CCDFFAB4 -:10C05000C8279097E037F04F59DF7AD2A5401CA14E -:10C06000437224A15FFE5DF25DD0032A3E4890D961 -:10C0700013755B378C3946E1E9DEF46F4E41E777A3 -:10C08000333E3C1F9AF7AB57DCB1F5CC39EE0F4588 -:10C09000DA05B19DBB8DD93FA49D3D2BE5B013ECD6 -:10C0A000CDCA66D9433994546E7BF6B927C14F7B0C -:10C0B000DF8C7E5AC5B6DFBC3381962BB6CB4933B5 -:10C0C000D874EC4272842E7EFABF2563237428FF55 -:10C0D000F56F14F768F6FEA789117A546CDFAF90FC -:10C0E000D1FDF15710DAAF74D9A3D02574AC10ECA0 -:10C0F00095BAAD5F2AE0777DBC4F208332FAB72F27 -:10C100006BFE0DAE878027A423A7531FDDFAD12B2A -:10C110007CE32BB958CF057A3216BD5EE07AB96A56 -:10C1200097832440FCF30FE6E00CA0E38BF7386123 -:10C130001E27A51AC6D74F3F940CFB7F657220D9E6 -:10C14000854FF6BEEC99FB90DF4A859A64B68FE97D -:10C150004DE5F1F25498DF82A61FE1FC4A880FF901 -:10C16000AEEC69B108E2C39F4B64DAF628727183C2 -:10C17000CCF69F4E6E3443921F3909763ED8D76F66 -:10C18000891867256411EE83DDA7C671C9622C7F0B -:10C19000CEF7A546C826D53FB4E8F875D3C39D4071 -:10C1A0009FD343BC83004E8A8700C79700FBFDE204 -:10C1B000D1A983187D58BE01B6A3FABF00DE43FDA6 -:10C1C0004E19F70935EDB8BE64E3DFCBC7A770DBC6 -:10C1D000603D3B99CCF62B8DF35BC2E747FF3A8974 -:10C1E00086BF34F2CDE47DD34A26DFAABC07674E72 -:10C1F00083EF9FBDCDE407DAC1FA41E10A0FC2EF38 -:10C20000FB6F15501F9849389A5C6F92B95CEBBF71 -:10C21000FBA99C425C80C22D413E43844F68FF894C -:10C22000887FF44B4AD6D3761AFBCC0FE3613D25C9 -:10C23000F25EB37E94723D304DD6CB3F691A785989 -:10C24000F662A54C02605A56BE6F46BFBB729B5C3D -:10C2500004F33ED372F09D1F53BE3E1352E554AF1C -:10C260003F8D725AB663B300FC6994D3336574B5DD -:10C270008E26A7F47D54392DEBFABFA23F55BCF9A9 -:10C280000D78A37A7068822936FE8C7AD021BBA300 -:10C29000EA41FAF736C9EBCF772ABFA97C462DB41D -:10C2A000A1A0BFFBF851E5B73E7E54F9CD384F3D14 -:10C2B000DE8CDF2780A146E12ADA2DA35F52D9CE9A -:10C2C000F66F68BB4357E4227EBCB87C9186435727 -:10C2D0002469CB41433964A8EF35948B0CF57D86F6 -:10C2E000728DAE7E65DB418525198575F5CC4B9E3B -:10C2F000241F45B1EFD575C6DFFA8912007E48EBE1 -:10C300005540CFC9CBA86906F1B3BD22FA5B3DEE1B -:10C310005E67227DFF9095F9B13D2E5E4E60E5DEB1 -:10C32000814A3DE839F57DAF95C5397B8A7A9D090B -:10C330001AFFFE58BBE884FDE0AE20CB47ED0F4F5F -:10C340001DCA4D1789F59DC505A78AF6F425E0BFDE -:10C3500035881E700DE72FBDDD09FB6E3DEDC36F07 -:10C360009A45DF2F382C82F94C7A6CCE31001709B0 -:10C3700078A5D43C9E3F41FF4E91C02F2742DE441A -:10C380003BB3AFE7AF36D8C3F67B15CC2F5BAF8995 -:10C390006B69F8BF9CF753D6A4FF5E4E5623FF95FA -:10C3A0001BE4C1C7FD81A3AA3C64936CB6BF4D9842 -:10C3B0001FCBF5EE5431EBA65914EF3D1D22E6CD0F -:10C3C0009E6F17493DCCB345C07D4E1218887255FB -:10C3D0004D7A51DFA978E906B95162EBA3EE9DFFD2 -:10C3E00091F720F0C7CB7F1CF3147D76BFFCFEA82D -:10C3F0003D50DEF56EFA1F49FFFA05FBBEC27DC453 -:10C400009E7D668C73F5ECFB6DFA83507EC58C7156 -:10C41000AE9E6566DC4709EC730447C2F721CC1F6A -:10C42000A8DBFBE5189627B91CE9F48DCCFC91F349 -:10C43000EDFFF501E48F9C6FA7B302BB605F1CCAE0 -:10C440008DFF152BFADF3D7BBFCCF3D9FF71F3A92C -:10C4500056880FF9CF4166ED007E4D60F160FF9E7A -:10C46000F1CF427E7355EB7E05E2EC05AFFE650C25 -:10C47000E8C99E1DCCDE3927773D03FB6166E59355 -:10C480006532C5F339109EC1843CAB8C2D086445E0 -:10C49000C30BC3430FC503CC8BE2A50CF47B2C7CF0 -:10C4A000A42BFFACF8F8E42EA6C7BE8B79F611BC1E -:10C4B000085EF6DE11B408387FF67EDF976340CF62 -:10C4C0009C092D457BE452F3BE5661FB2CFF73E6BD -:10C4D0002D842F67DE73FE69E9CDF8FF43585F07AF -:10C4E000F69783FE7CBEEB7E2CBFE8F020BC97293C -:10C4F000FF3FFD9F46F71D94EECE4BD3FDA97FDA9B -:10C50000795F8AEE8739DD1D2ED85FEED9FB178C57 -:10C510009BAAF3BFD4BC5FF97F74DEAABD3EDD5495 -:10C52000736426AD7F8484D71751385F4B9BFAF62E -:10C530004CFAF5B731EC91D30A8B7FFC96B03CC135 -:10C54000408AC0F23CB85F5440D8BA5E90598A76AF -:10C550004641E623681F10A9E64836C5C7F4F4052E -:10C560001E960F3616CFA15C977AAD07E38106FFC2 -:10C57000F0A040BC900F5D70F5F51DE0AF4C499305 -:10C58000C3E631F83C06CF43CE69ECBD5DEF17CD75 -:10C5900000BF46E3E75DEFD67F2FE4FD4D238B8F91 -:10C5A000CCA4E34F4B135D416837A94182F9CCA07D -:10C5B000C2DDA0D90F2A34F47708FC5A4DBCEC6FC9 -:10C5C000C55F9A99F991BFA5E36703FED2648C0712 -:10C5D0005E127F84E57F5D979A8DE75188E441FC88 -:10C5E0004D1F5CC5F1C9FC6689B797ECF59D20B776 -:10C5F00012A17E2FB3CBD05F56FDDE587826DC8F9C -:10C6000096F8902ADEA53419F35535FD213E547A6B -:10C61000FCAD7450E9F7F7D2E39C811E699FB92401 -:10C6200090CF026EFF4FF9AC53C4729A47C2FD28F7 -:10C630006EFF4FB2274860FF5F2B1D15412E4B2D1B -:10C640006DD3214E6FF108C8D757769BD0BFB1E4A8 -:10C650000A88F7CC4609CB474DAE716068DFF8BD5C -:10C660005D671E20101FF62A68789322169FFFE64A -:10C67000DB6F27AAE735F03B213750FCCE6F2261F4 -:10C680001B9DE7028904E21321BE2B900F75F15D1B -:10C690007D19FEBE9F1CE9E752F563E9917FF473B3 -:10C6A00017D55B1F52E6D80D4FDC57A12CA1F18F97 -:10C6B000BFDBCEF0E53F4282C3502F78C522CDBE0E -:10C6C000D92366A63F76FD69470EC4C526F564C525 -:10C6D000337D3A02FD023FF70BCE13773CE41F9CFB -:10C6E0006F1F1E8FFB821DA2C317252EB395FBCF94 -:10C6F000FF0AF914F4D9B38934C0398C1ED28BF1F6 -:10C70000D8C0264BD4FDDDFBCD6ABC89D38DFE8914 -:10C71000EA792337E68B04E2B574EB9EF1B134A6D7 -:10C720003F1DE0EF43CD7EC9DF8B5FF0D701BF5BDC -:10C73000AD5D85D1CE83ADE0F8BBF1C05718C7BC65 -:10C74000BABDD904FC7BF526936EBF3160E67ED777 -:10C75000583216E0BAF180D5910B74E9103D903F44 -:10C76000E86FFF44F145D9B732E213FA87B8F83ED3 -:10C77000338BF3EF9143F300AF7BCE5A303F67B773 -:10C78000D250110DCE2BAD4CCF2D20A17BC664FC19 -:10C79000F3E177528F3D3C19FCCC4D84C7318CFCC2 -:10C7A00047908FCF6F21783E14FC52D00BE75BD8B7 -:10C7B00039608A9235E04F5379FF81362E7365DBFD -:10C7C000F67F053BA0BA5D7041EA6CB5D4A540BCCC -:10C7D000D5DF9620C2BA9BED56F32A5DA36FD5C86C -:10C7E000C53E33CB373E3861CF1D30EEA7DD0A01A1 -:10C7F0007BC4FB5AAF13D6ED4FDB73E2A3E5CDABA1 -:10C80000CF5FD792E95324E88720DE8DFC90D56274 -:10C81000D395BF27FA06837CDD68EEBAD713857EF1 -:10C820003E0BE3B3CBD66FC1FFCFF4DBDBAA7EF3C5 -:10C8300089451A39CAB4F4D36F83A2E9B7C5827B9C -:10C8400010E07DF1DEE18380AE8B0FCB03A3E9B76F -:10C850006DB56C3FEF259E0FDBD34AF5DB351AFD36 -:10C86000D66AC1BC3863BB448B89AF8B97D06FC18C -:10C87000FF1EF9DB06FA2DCA7C475A98DE50F5DB1D -:10C8800098F663A8DFC6B49A7479A369964BE93722 -:10C8900061E0AD600F77C89EB828FCB38DDBDF2F59 -:10C8A000F13C3C1807F4DC1D16B6BF79B97A2ECBE3 -:10C8B000CAE87D493DF7DF846755CF2DDEA99E7319 -:10C8C00034F221D3738B77533D27003F323DB77845 -:10C8D0002FBBC7C1A8DF32FBE93782F5ABC3ACBDC4 -:10C8E000BF2D63C31CDADF58AFECB1D0FA6323FA73 -:10C8F0006E9C56DFDD6161F72EF4D3771D97A7EFAD -:10C9000076727D47F5D830D0AF46FEF0B4EBF38EAB -:10C91000F78C3FD9F26B9097D745DC373CCACFA54F -:10C92000BD31FE642EF0578B85E9DF3ACE7FE76A92 -:10C9300003D87FC16B6C7E5576968F5CDDCAECC3E5 -:10C94000EA1621E8A6FF2C9CF09502F02FDC2B9034 -:10C9500041B43CD3CCEA93E7D57D2F32235BC30FA0 -:10C96000F3F32B306E3F5F221688CB57D80B3F86F0 -:10C97000787C453E8BE357F0F70B0F77D5433C7B34 -:10C98000E11302EE7B129E0FA0E63796B62FC57814 -:10C99000AD312F40D5E70B83FAF715867CC6663E8E -:10C9A000CF996217E285BC2946CD4B6836E2A38356 -:10C9B000E3639388EB661F3E287EDC19FDF1412975 -:10C9C0003A233B3932FF85AFD379E546E6A5E2C38A -:10C9D000383F35EE5CC1DBC59AAF8ABF7EF355F1B7 -:10C9E0006998F7B3A037402164931CC88BA17C8061 -:10C9F0007A23F03B11CFEF174D1A3948AB87B77246 -:10CA00007D9ED330A9209500BE480DF04D49E3A28C -:10CA100043A974DEE3DE738F85E5F17B13CC3ED84A -:10CA20001FDD6AED45BDA6F2D5D79CAFDEE178DC0F -:10CA300033B806CFA9FADB0417D815FEB015F1E715 -:10CA4000A7F883F32B7E7E7ED14FF90BE4E9E01348 -:10CA50005F307CED15DC101F2F54D71FC03FAD9FFA -:10CA6000D3CEF0EF0F0A88FF5CD28BFB23D58D82EB -:10CA7000274CEB57B72DC2BC0755DFD23FBB961EE4 -:10CA80001A7E94A2F12356D2AC7F15BCDE8DE686C9 -:10CA900077803F6F7C5E26CD1AFECCA4FF7D1B8580 -:10CAA0004E2A3E2FC59717389EB6011EED80AF5E09 -:10CAB000663F85BFC27334EA77BF14D0E1B1E0C9E5 -:10CAC0000B17C5D338154FC0A7A0A7DA8B452897F9 -:10CAD000B409644046FF79C2FEA4566E17EE3DC607 -:10CAE000FA7F5AC07B4B8C7CABCEBB1FDFC6E057B6 -:10CAF0003897067ED1E5F2EDD706BE7DC3DA7B24FA -:10CB000007F876AFC0E207ED09BAFDC5C156B6FE1B -:10CB10006FB552FE867DADC3B267A3BBBF7CC7F1C4 -:10CB2000F50BEC7EEDB9A4AB602290F7B8C5827925 -:10CB30006408C73066576AF5EA362B19786B6EECD5 -:10CB4000FE5379FFB1EC1AB53C1AC6837CAF363A76 -:10CB50005E66643CA35E57FDFC4BCD6BD4DF39AF02 -:10CB6000BE3C4CD289FB4E1992EF51B3260FEE36E4 -:10CB70009E67442140FB4A532FCB72917A24C5858E -:10CB8000E79FEE71A97CC6F2DD8B781EFB5471E243 -:10CB9000BBB07E7EEA65FB7CB926F2FB89A09F27AD -:10CBA000CB788EEFD32332C66B3F9DC2F2386F7ABB -:10CBB000FDA004719A9B4039517CDC344E407F05C6 -:10CBC0008E61C1BED92E6ADF7847E17C72E01C57C6 -:10CBD000F6A68602387F3C764BB00E9E9E82DEA47F -:10CBE00037008F93440278ECF40E2880FB93EEF923 -:10CBF00033C1FB43E83A8BEDC7769081506F827763 -:10CC000020BA03E35BD717407C74E641BB1DEE6797 -:10CC1000C96C32519F2182BF09245807FBEDE38F75 -:10CC20007B6F0178CBA8BD0071E7B2F6E63A279496 -:10CC30009B048F9BF6EF0FF80A9D741EDB1A3F29A9 -:10CC4000FC0EC823AD07DDF89B583DFF26B87808D9 -:10CC5000DEAFC33C9B924D021EFCDA16148885F5AC -:10CC60001BB4D07EB735D1F6B9B04ED0F6D0EFA612 -:10CC70004FDEBE05E4FD88C8DAB7B07DEA12DACE31 -:10CC80000D7CBB6911F6B7B0492029B4BFB216B606 -:10CC90000E941D913DF0BD75FF13B88ECDA0E3A598 -:10CCA0006680DE0F4F8132C9115C18EFAC1C8574B1 -:10CCB000EBE1724E268E64FA43E065EE37A876D338 -:10CCC0003B5696EF5BE259AA0CA0FDBC913F3003A6 -:10CCD000D202FC6D9FE0FEF3718A671FEDF228CF50 -:10CCE000DB3898FF91D2A559873EB5B2FBADE6B7C8 -:10CCF0004DC27C8605A408F3196E1CCFECB537AF86 -:10CD0000B506E18A8337E5DE34787FF05A33DABF3F -:10CD1000E7B6C9C847E78674617CFA64938CE786F6 -:10CD2000EB9AD8FD5C275BD83A2E3ECDF6F54B1D2D -:10CD30000A960F36DD5208EBDBC94DECBC63C1D35C -:10CD400053152897360B1E767F11D38FAAFF56E214 -:10CD500062F908AAFEABE2F3EE97B768D07755EA1E -:10CD60007A63D07755B0AFEC84A7FEBD9FD8991EEB -:10CD700004BB1FE81EFE0AF9B7FA884CC0EE173E46 -:10CD8000EA2EC47CACBD02C6F3C7B70B5ED8D72F62 -:10CD90007BCF1C447B35587CF74F408FBF6F26827A -:10CDA0001BF2DA29DEA97EC837F7FEE917F4FDC7C2 -:10CDB000472D900943F9A418F1ACE67FE66E667939 -:10CDC0002CB947D727C3794B326500EADBD24691AD -:10CDD000F8347AE363C17BCB8F995EC6FB2954FAA2 -:10CDE000E52A0D25B08E0DB731BDE4DE2C438E084B -:10CDF00039CCE324D49EC6F3B70B77AF4B5668BD4E -:10CE00007A9EFFB170EFBA6491BEAF83F58BD65FA7 -:10CE1000A8B0FE17EE135CCD9AFED5F66A7F6A3F86 -:10CE2000CA6E7D3FC3F7F2F265F6A3C2A18E1FCB97 -:10CE30001ECFFFF70BEBE1BE98FC37454C3ACEFF17 -:10CE400068C670ED7E87FA54E3AF796F9B8857838D -:10CE5000B7FC3FD98857C317ADE3A87C53BADDD0E0 -:10CE600026040194D671C794AA5C2CBB409EAB7972 -:10CE70009CB67A0ADBB76ACD3EBA1CE47B46AE802C -:10CE80007C40023E654012DA416ED85F28CD65EDE8 -:10CE90004B697B90BBD627981C527DE0067D51DD07 -:10CEA000B4AE10EB6F12DCD07F6B7331AEF765F967 -:10CEB00022C1EF9B8EA1FD51D6762C09E495CAE7DD -:10CEC0007A587FAB279AF13E2F55EE54397E53E6C0 -:10CED000F735595CA321AFFF41002A8AFC8A470835 -:10CEE000F3535B6494337F3E93CB37B78928CF07E6 -:10CEF000AFBD1DE5F0DC6621861C1728702EF96495 -:10CF0000907DEF93E3AD029763A61F4EDA995C170D -:10CF1000C07790E39D02F707993D689463552E2FE3 -:10CF200025BF155B0CF21C436E3BA5AE5B61DC7B41 -:10CF3000AEB522DC05DFDFFDCE3DA87F64CCFB284B -:10CF4000F8FE03C9A0EF4A2496AFA4E2B14A62F901 -:10CF50006CFDE058BF5449BD2C78F4703C657544B5 -:10CF6000F487087CCEEEE10A6C9291CF8D72F8F7CF -:10CF7000CACF3F4A9E0F73FE51E111F7B2F6903FC0 -:10CF800016A678FA6DCBB398A77AF6856337029E1A -:10CF90002BF650BEA5F33DD7E2E0F7BD04719D2905 -:10CFA0006F15310F9C48E1BC5B1C5AB96479481578 -:10CFB0002F39903FCA77B07CD2F2973F1A837922FB -:10CFC000CB7A31BF2AF002B737035D6380AFCB2540 -:10CFD000960F6594F35B6DCCFEECDE1D370BE621FE -:10CFE0006C61E7F4CB43B7CBC0876ABD1FDA64B589 -:10CFF0001EEE5F0628DFC2FE3AC0A73D77AEE641CF -:10D00000756F65725FDE26A3BF54BEA519E3D8FE17 -:10D010002D9F609E7BC14BDB307EE06F13F5798FD7 -:10D020005B44DCC7A24FDCAF32E61F56B756E17E49 -:10D030005B7588E7F719F2DF2A5EDAFB7280A2A639 -:10D04000E2D7CF3B410F9CEEDCEC047CD2FE306F8C -:10D05000F0FB9F49BABCA8D8F9BD5E7D3E6168650A -:10D06000D47CC2D3F00FCAE00FD838BFAA79985B3E -:10D0700006F03CED705E5194F87DDFB99D6D9F3FE9 -:10D080000379EEDD3BCE3C037057FEF5D367209F5E -:10D0900089ECB3E2BAE47FE1F79827ACB6FB858D63 -:10D0A000FBF95B9FC7FCEA73EF9BD1CF39B7F764FD -:10D0B0003AE4AF9DDBFE5532C4E3EEDD3B15E3956C -:10D0C000F7EE2C1844A2E877F5097C19BC8CFC6EAD -:10D0D000231D0EB61EC4BCABB3EF99519FF5E58579 -:10D0E00086AA589EAD9BE783B644CFA357F318ABEF -:10D0F0005B6FB9E95AD0CFADCC9EEBCB6BBC541E65 -:10D10000E8DB949ED75C06DD5A789EAF816E67E1BE -:10D110001F943E2103DD3E6F5DF0AB27E15BEB80AA -:10D120009879A0E1CBC0979AA7FF739B778F0DCE1C -:10D13000FDED880BA4307A05670860EF7D9E0EE751 -:10D140001A4EC9BD98EFD1BBD7EC827CC6F2BDEFB9 -:10D15000A27C9CDB7914E3AA84E7C99F237D7F2C02 -:10D16000AF59E0F3DBE460F9A31CEF905FEA76E2ED -:10D170007B9E47CAF856CD2F8D9557DA6B1BC6E2BA -:10D18000D0FCDC4015F593F8BD597DF9A6423ED0A0 -:10D19000E9982E4F579DB7B13F17D79B91FCE8E810 -:10D1A00079BB6ABE60844E6C1D51F39FCF35F3BCD2 -:10D1B00069FA3E6D2CE4C1B1F5DA1F14DE2551E4A5 -:10D1C00051CD8F3E6333E445072F2F2FFA52F0FEE7 -:10D1D000EFE2E3031B8B57AB78E9FE26BA3E56E23B -:10D1E00098DD49FD53390EF705987F7A37F74F558B -:10D1F0007CA9F0D68798DDD0BD85F9074679AE8E3B -:10D20000715F52121FA7BA6DFF18D03BDD0776730E -:10D210007E63FC5CDD728CE5DD52FD1CD4EA677E2A -:10D22000BF84B1BF74DE9FBF3D7A7FFE964FA2F6EA -:10D23000775AF2DE0EF09FEE6476D2E990382DDA5E -:10D24000FD36963859973F50EF60F765884E1BDAE8 -:10D2500047F73AF2DF8B4F82A782793D754B791EF3 -:10D26000D0CF3C78AF689D633A01781E02FC68E23B -:10D270000CB2CB47C04E93538A72457704DE3E7A98 -:10D28000249948504B7F299C06FAFC83EC9332F496 -:10D29000F79F86F8C87F4AA47E1085EB3F0382671C -:10D2A000A93BB65DAD967D3F1575F18C6A73EF07AE -:10D2B000609F9357ADB81F2EEEB306303EF60CBB01 -:10D2C00057E3E0CE2F9FC37B797E6526DC2E14408A -:10D2D0001F94F238C5C99D5F3EF35F604742633AD1 -:10D2E0007EE933B43ED8CF2D7168EFF7EC881F0389 -:10D2F0007180D2571FBC11F44529E83EB0335F1A44 -:10D3000014ACA3FD9D18C8CA27B60DC17301153B07 -:10D310001C984F7870E7AE6AD0F7E75E8A23A0EFDB -:10D32000CFCA5D7F85B27F4F3C6976A3DDE7D6AE7D -:10D33000AB0B89E4D6DA731550D6E5B710CC6FC1C4 -:10D34000F81BE5E78AB6783CFFA1A9C7E539309814 -:10D35000DF133518E48EDA8D6E7DDE33FB3E3F8EB3 -:10D36000E92FBFB9F77E761F02ABEF577A4B58B95A -:10D37000613093DB4EACBF48E557FEBD7FBFACBE0E -:10D380003F8EC50322FDB0F6D56676BF8691BE3FBF -:10D390008D13F879DCBF5C19EDFE8928F0B37BB9F9 -:10D3A000041280FB57C9762BE669552AE15190AFEC -:10D3B000FEB2C2F63F2A9DE15190AFBE87EBBF4A55 -:10D3C0001B2DD3F783391C501FCAC4D2F522DEEBC4 -:10D3D000B4CB8AF7E155BDEAF0A29FF0F297279E01 -:10D3E000CA857CB538CC93AE7AF55F90FE55E6F0F1 -:10D3F0005DC0FFBDDBCD783F69F7F6C3E9603774E8 -:10D40000CBE1F4C48BECEB5485CCBA7D6A751EA7D6 -:10D410006B974C8073BCEA39C3F218FAE2F5389680 -:10D42000D7D11CE7FD15D373FAFB654ED7CED2DDFD -:10D430009B586E89AEC75A402F68E27862E45C61FF -:10D440000BF47B9674D50FA624A9127A717FBC7C4D -:10D450004B461AF8BB07AC57E2BED501D98DFE206A -:10D460003CB5FAF854AD2747C2F3F499391285A3B5 -:10D47000A7F99392C104F203ADB3A2E9A7BD7171FC -:10D48000C84FE51673D4F39BBFE3FCB60DE46D1CE7 -:10D490001BCF931519F7801C54008E897637CEA7C1 -:10D4A0009CFA01EC9EA8D939DA73DB0BA506AC47D0 -:10D4B000E50BF1B190AC5772EDFDF5CAC225B93953 -:10D4C000520E2AACAFFBF84D8CD0890492D04E920C -:10D4D000380DC9FA545DBEBF241759005F0A29727E -:10D4E000492290BA01E5D44642F8B4533384AD439F -:10D4F0003504E2E3A7F8FEAC59723F8AF7CD748891 -:10D50000A8CF2F85B777E39C08B759AA211EB43757 -:10D5100066B8C01E13023EF22DE587BADA6939EC0F -:10D520005C38F142BE1BA6BE51F89CAE435F817DC4 -:10D5300040F98CDD63F57D12ACA3E3C131638CFF50 -:10D540004D66F7D91BC7FB86D38104F6EBEE3B870C -:10D55000BF5EF5FE3CF0D7E3FF9A0FFB317617096B -:10D5600083BD146727E1B831704F9E745A2BBF4EAC -:10D57000C2CAC3283B835E734DD47F37F235F1486E -:10D580009FF5E94511DB7F6668FFD9C5DAABF8F096 -:10D590005B367A8EE744F062E373084CF65CE8028F -:10D5A0007C8C717AEA808E4AEF070F023EC6D899CA -:10D5B0003F98D448B4FE5A8E9DE9ABE5FCFE69FA6B -:10D5C0005764D7F4475C168C8FAEE478EFABAFC6E8 -:10D5D0004DFAD5B74A80D77EF5ADB1EADBA2D77751 -:10D5E000C482272E3A3C0931FA0F44AF5FFDEABBF3 -:10D5F0006F84DDF092E90D08CEF373CB3976F0AF8E -:10D60000E23F482E665CC1F6030C74B301FF517E05 -:10D61000B08DD0BC87FFCBD2D06F5814FA9330F2C4 -:10D620005D31878796EDA914BE1F7370A76C62FBEE -:10D630009573EE6571A21F5B587EE9317E1FD09C09 -:10D6400046E657CF59C2F61149193BE7E3A2FFC19D -:10D650007877422794DE773608C17006DC5B63B0CA -:10D660005FFBEEC759A840FD6243DC45E527F53C6A -:10D67000D23C6E5F6770FE5C407A1D20F7C673EF88 -:10D68000AF71BDA6EAFDC03A9209E7F64593CD0316 -:10D69000FBA3223F674A9CEC3E3FE21DC2EE97533C -:10D6A000F3B832DDF1B0BE91107FCFF759165FEFBE -:10D6B0001EA43DA7255DB0E1FD2075B22705F4A0AD -:10D6C0007C81DA75D455532E0C236ECD39326ACF56 -:10D6D000A170CB2E765FA2E42A22A56007F2FB019F -:10D6E00048D2F43EBBEB4D8A87C5EBDC786E758182 -:10D6F0009DD999BF7014DD631F07F665BE87DD7382 -:10D70000ABA76360279B5F1DCC2FA33FDC758AC747 -:10D710008376E7746A31601CC783BFEF209ADDEF20 -:10D72000BA411EFF4D66BF57D00F0F8C7EE7931294 -:10D73000F15EF6F9CE551F009FAEE6F711AEA8CD0B -:10D74000C4E7AADA14B43BEB6B3DF854F162F13450 -:10D75000E0BD6F9611AC3F8BCBC7EC0A6ACB403E65 -:10D7600085E4AA0943D9925643C0DEB5F6E1A70184 -:10D77000F1A3F4957D5836BBD8EF46C88D3310CF52 -:10D78000B43D29A5DF173B7C4F829C58DD57EBEE5B -:10D790009133A78C35DC3768C09BCA1FDB18FED6D7 -:10D7A000088C3F8CF85B2377BA615F79CDF57DF704 -:10D7B000CE20FEA879CFF0F73BB6CF16137FAE444C -:10D7C000B45FE7E7D5DF55475F3DC2F7171FAECD22 -:10D7D000477CADE4F7483E54EBC5A708F8A3F33304 -:10D7E000670508DC8FCE7E1B823EED455EB87F1656 -:10D7F0007817F027DA193ECD2935B8BF66B1337CEA -:10D8000089F600E245B6337C8976C66F0A2F4B80D5 -:10D81000BF1C6C8FEF29FE0E007F59D226E8F0A5C1 -:10D82000244DBE3CFC3D41F147E148E2F265C44372 -:10D8300092C2EEA754E52A961DF7389D3FACDB1B3C -:10D840006A093E07C6F0178739D8BA9964AAD92F52 -:10D85000033E12095F4F02242D8FB0D443F84B09C9 -:10D860001037940506076918A2BB57527449867B86 -:10D87000D9DC1B800FD61F964D902F2F2E99AE3BD3 -:10D880000F2ACEF226B8119F3EBCA7F9915A37D283 -:10D890006F1DD011EE01E5FED7439C9E0FF37B2850 -:10D8A0005772F958C3E5E5512E2775FCDEE4D5D350 -:10D8B000589E5552B689DF571626DA3CA6044F8883 -:10D8C00028142EB4A9DDF8C47B16C97BE6E048DA3B -:10D8D0002E2E8B78814F12DE7B20C8EE6B2C4A05F2 -:10D8E0003B2841BD7F71A23B61361E840D4BCCEFBE -:10D8F000A0AA10FD984E53B47BAAEA3C072C100F47 -:10D900008D054F9CC79BF1101D2FAED181F6FB00FA -:10D910005FD1EC05B46C6F8CC3F85F1CFF7D163BC8 -:10D9200085BB5443EF58F7506F745C1FEFA0F4743D -:10D93000018CF4F958E370FC5D96C7E522FC1D9755 -:10D94000C7F97AAADE73AEB6FB9AEB4767EED53A13 -:10D95000BF75BDECC576AE897AF95FCFF56DE2147F -:10D960003D9FABFAF6789FBEF50D0378922F4C41A0 -:10D970003D96747374BD5B272B786F79DD6826E75D -:10D980008162859D6BE9AF07304E7DDE376A23E803 -:10D990005195AF9611A67702C4E6C17588DF6FA3D3 -:10D9A000DAC12BE01E40AE5FE1298E60BF3F903CA4 -:10D9B00087DDE7BB9ADF63B596F215C17B4F3DF873 -:10D9C0009CEE60FB13CB2C63F13EB53ABB09F584AA -:10D9D000F4BE39082687B47FBC0BE20592ECE9F46B -:10D9E00042BCCF2185E0DEDC3A7B2EDEFB2E24E438 -:10D9F000BA80FE5F38E60FBD583E1D9D28DE97E9D0 -:10DA00004A2A221F66E16E009E5F915D3713881BD4 -:10DA10006E48AAB102DEC63B585CBFB1380FF14870 -:10DA2000F17B936360A49F41B3A6F7DD8305DD6EB0 -:10DA300088710EE60E07B397485A808CD0C879A338 -:10DA4000FA3B27EE00C9D4C8FBB2918504F687FAE9 -:10DA5000CB790C3DB699E9B1E542743DA6DA99AAB5 -:10DA60001E930DFA417DD60F9DA63BA7A524798074 -:10DA700077E1193079C0BE7BB9FE8E04C4430DE056 -:10DA800081A44CEFF35F7F300CECC7BCA8FC66D4DC -:10DA90005FF3FBD6736F32D0E994EC1E341BF8E9C8 -:10DAA00070F4F57CD263573D0A7C30FF77A2A0DD8D -:10DAB0004F29BDB002D7D3920BF9F82C6B9C867C12 -:10DAC0004F200AAEF1C34E36DDE704B84E36F23CC5 -:10DAD00080263908F919271BEFC3FB4A20CF5BD4F6 -:10DAE000ECEF935C37DA97EA3D632783F738B5FBB1 -:10DAF000BB25BFB07AC16E8DC55F254DD1FD7A586B -:10DB000043217E4A01CC047B98DA37BD61B07F3671 -:10DB10009A3D011229071EB346CD4F5CEC98FA38A6 -:10DB2000E07DB1C3FB34C839B1B37B4163F3391B2A -:10DB3000F7046C02C37ED3933C4F53F239B5F7BB65 -:10DB4000F5DDC7C9E324C412E3BB4DFD7D8318DFB7 -:10DB50009D2C9F83B8A27F57FD84B8889FD006F381 -:10DB6000A86A3C53FF3EE289FB091CEE533283FB5B -:10DB7000D47366F63B3706BE38C5F347160A0CAFBA -:10DB80002A7F9FEAB3777C780F8D91FF848D576D44 -:10DB9000184FFBFDB443C6385C25E51FE01B61E36D -:10DBA00078CC5F171E1BFF28E4257D7644C4EFE583 -:10DBB000172CF8BDFB679E0D7320CEF3BA8CF7755A -:10DBC0007FD631359EC579F471E8054EB6CE9FE615 -:10DBD000725F726115F2671F7F342C5040AE4A2E7F -:10DBE000AC457BA6648B80F7449240EFA14912E7D5 -:10DBF000C309D0FE6CE132C0F7C406DCDF28DD6C5F -:10DC0000F6AC12FAD3F9B4C3ADBB57BDB46B35F65D -:10DC10004BA83D95A4D9EF3EC5F3804B2FB0FB0137 -:10DC2000892B405280EFB9DE89F0AFFEDED76E6BF4 -:10DC3000F438FBD7DC9E29B93041E73744E6F77D5D -:10DC4000269F7C3D2FEDCA6770F5CD67C3F868F35A -:10DC500089CC6322B6EF4E883E7E06C7F389DA325E -:10DC600038B941CA1456AFA4E13E05F449495342BC -:10DC7000A2A099576963852E0FA3B4A95899ABE95F -:10DC8000374207DB6F278D88D02163AD7CDD323BC7 -:10DC9000ACF7450E278CB77161DE4FDCD01FD33F48 -:10DCA0001FCB0DE935A85FEE71463BD790E174EBD1 -:10DCB000E24AA58D9C3ED44ECED5D047A58BB1FD72 -:10DCC00089E6D2BC9F403CF909762B486CBD63A025 -:10DCD0005B4674BC4DE8C35B26E6035D1A6FDFD17B -:10DCE000E5FDF4C31BA7AF8A17F53DB58F72005F42 -:10DCF0001320E03410FA61F4BF14BE22E372FA4F2D -:10DD00008A3E0F5FDF3C969000B51FE65F721E0FE4 -:10DD10009280E522F350E94FAED6D1DFB776E475B5 -:10DD200020872ABDE71F7802F9773E9547D8973FAD -:10DD3000D9709F6E7D88C01783EE2302242BEFFFDE -:10DD40001CDD3F9603E990F71558C7D691531B1F6A -:10DD500049D7E279B163D202A00BD934F0B2D68FA1 -:10DD6000C0644F871BD72519E361BB1D3EBF93BE1F -:10DD70002FE37EF5F284C251D1D67DEA174E84F8A6 -:10DD8000735DEDB489106F93B9DD08BFAC05F6265D -:10DD90005C811EED7EAD064ED7876A6B307E4D2CC2 -:10DDA00001E2D29EF725CC2EFA9AB0788BDA4E910A -:10DDB0007D2E887F2A0229427B4EF2ADC8C8853865 -:10DDC0004652764083BFB54E66D7AD4E39E0827C71 -:10DDD0005233ED1FE2319634E9BC7E9F9295B385B4 -:10DDE000F132CC474E0A118C6766D1F71A7C2B4969 -:10DDF00014CE8BF89B92C589FB451261769A3A7FC7 -:10DE0000FA06D7B387F9BAB40CE2B849608799D05B -:10DE10001F5ACFE394BFAC2DE27890701D3327B02A -:10DE2000FA4A3C83DB0A716B11D6D530961D70C35C -:10DE30008E885793E1EF8F261037FE4EDF0012AE2B -:10DE4000C77B4C2675DD0FEFBD71BE2DC0075FA4EB -:10DE5000767E20401CBAC87725ACBF8D6220DB4D92 -:10DE6000EBFF4AECCD867AF0FB5EEF25B2E750C8B7 -:10DE70005BF669F6A5D8BD9C6E6D5CCF581EBA44A2 -:10DE800032ECD77C73A5F67B739C7717C091F49125 -:10DE900080FB30755676AF4F9DE3B67858BF8F72D2 -:10DEA0007A21FD817F3A981D735E72C727627C33A9 -:10DEB00033E735DDF81E5D59E2FEDB26CA8F92E6B8 -:10DEC0005ED61192D704FC32B281BED7D22F4A5C03 -:10DED0002DD18ED7DF46DD8751E1A3E312C09F78B5 -:10DEE000A190ADAF063ED82330F8030EEE6F9180BF -:10DEF00008F49CADDE172C2D6765F5F722808A1497 -:10DF00008EF7D5FD05B29C95F93EA57F2EDB8734B3 -:10DF1000C233BBFDE14E88EBCF6E4F9D07FB53B381 -:10DF2000EDA3FE0CCF3D72EF8138B003EF13F0FC90 -:10DF3000C78F7FFF9A1C479F3BDFDE88E78DCF723C -:10DF4000B9BB8BF4E23DEC3EE2E2FBE4417C3F17DF -:10DF50007E600ECB2119FCF439E1E08F6EA0A53B69 -:10DF60005F0BDE0066DB5D1DBDBF0135E00BB90A4E -:10DF7000710F406DD7E639C4CAAC5D040F166E8FC1 -:10DF80005A705E91795B100FEFF7E58D07901E7D5B -:10DF900078E2F72AA978E99B77FC6DD321CE1B4B59 -:10DFA0009FCDB667FE996D7E30B88C78FA0C3E51E5 -:10DFB0003BF233A7D71A4FF5DB474EAF0D9E959630 -:10DFC000DE746918CA8B13CAD5A26F6832C5C3D96B -:10DFD00021BE2B07023E3A075C961EFDC0CAF40024 -:10DFE000C94DC7F9A8F7BE1F7CE0A403ECCEFA9D8B -:10DFF000EFA6C3B34AEC5A733BC63745F487CEB796 -:10E000005E79D1F3611F40DC89AE7F23E3553E6426 -:10E01000F3BB9B9FAFB9BB350ECFD7DCBD44D4DD7E -:10E02000DB7CF712967747A4CE31B7EAECF5E53101 -:10E03000FB813880B19F794B26938F06C03EAB6B36 -:10E0400012C6059E61FC356F8A57847CE4092B0457 -:10E050008CB78C3FEE6EEBA2E579C104FCBDA379D1 -:10E060000F2CCE817B08AA3B597C6F90B828FB67A8 -:10E07000103F39C0D671282F02F9B67BDD764DBC32 -:10E08000BF5BAEC9867BF70277DABDC03FC5B77A02 -:10E09000DFC7FB1C781C425D57773516631E6BF19A -:10E0A0001C773ED0BD3864C5DF1F2CB610C946F5BD -:10E0B00058B1442CF01CA410C90A4F1BB1C0336FD7 -:10E0C00019BB27BBA47126DA07CEFC2205EEBF2DB3 -:10E0D0006E7FFE73685F2A85F7B3732D0C3FC5ED25 -:10E0E00087BF02FE59E02DC2BCC3EF6C5174FEDF46 -:10E0F000E890BE7C4D9BBE9C1DD697733AF4E5AD6F -:10E1000070C799C68E38B0D78CEB44C519764EEFE0 -:10E110001501D62688079B519E0A2ADAF3603FFA3A -:10E12000CC8B0E137CDFF317E6F7F66EB5E27D6F4E -:10E13000FBFF602336C82B7CC9BA11BE9FB185F2A4 -:10E14000200E47EBB3DFD92A0A8D02FFEDE5AB5570 -:10E150003F3D3806E6F5F25F599E4CEF5633FE7EA2 -:10E16000CA99DDCFBF08FB6267B65E8176D62B42C7 -:10E17000C004FD065632FA1BF9B4628BDE2FBE3F97 -:10E180009EE99B1E81E1FBCA46FDBCAF0AEACB3F7C -:10E190008F67FED45CA2799F01FBF7EEFA14585703 -:10E1A0009F8D7EDFF0435C2E5E784151F956E4F797 -:10E1B000B311B7E6FCD29EC8FEDDBD57405E05E058 -:10E1C0006258E47D85615CB5FFA278B60F9FC4F705 -:10E1D000677A5F17113FA70DBF5BD867D7D5D6A465 -:10E1E0004ED1AC43258DFB938BC13F6ADA9F3C57E0 -:10E1F000B3BE546E3D987C07E62549F8BB4C95B3F9 -:10E200009F5B3B2109DE8B218017BE43DCAB3BF4D7 -:10E210001B27D4A3F6EE585183F7D2C6FB52A7684A -:10E22000E4F46FE54B559E2AB97DB22BBFB310F2D3 -:10E23000C42B1AD9EF3755847E740BFCFE22696219 -:10E24000E74CF324522452F9A9DCFEA31FC2EF715C -:10E25000F99F1EE701786817B7C2FB8A964FF03C1A -:10E26000C12AC3EF08A8CF7D9CBEB47ED844EBAFD3 -:10E27000BACD5E06FA89F6FB1A940F646EC4FB4DA4 -:10E280009CA7589C96BE7F0F7E12E5D4E4C01B77F6 -:10E29000D0A66748E89D1B3260DE7A3EA37C2B80C7 -:10E2A000DDD5BB59C0DFB5A59656DECD60527B9754 -:10E2B00062DE2DFD7E77B4F3CE0B83FA7E8CF4FF05 -:10E2C00003E75FFA97A9E52363BD013302782EB116 -:10E2D0007209D5771A3BBFF27803DEE7681C078323 -:10E2E000709A7C03582FDD28DF56F5FE21C192C7B6 -:10E2F000F36687B332DE5B08FC4A19A5E26A32C5D1 -:10E300000DF8BE994C83E72B4278AD28323D8171E0 -:10E31000A06D71A827BA5D5DCF3D05FCD5321AE32B -:10E320004F83F979CF6E7718EF79ECE1F1C96E1769 -:10E330002B97B75B310FE6CC5905F5E8D2D04127D2 -:10E34000D0A3FB45AB097E97F4CCF60193214FB2E5 -:10E350003BC4EEFF3D1D1A80BFFF1A6BDD32EA039E -:10E36000759D3C06FF84F534DEFB35ACB76439CBD4 -:10E37000231D34A0263BDAEF49A8ED92949A6CF065 -:10E3800053FE17A753B28F00800000001F8B0800B8 -:10E3900000000000000BDD7D0B7854D5B5F03E7316 -:10E3A000CEBC92996466324926218F09841020E000 -:10E3B00024860814EB24040C187542D1A2B63880C8 -:10E3C0004080BC44DB46A55F2624424251428D0872 -:10E3D000087140B1F48A6DB0A8C106EF80F86AB543 -:10E3E00037DADE5EB5FDB92370295A1E23F452DBFD -:10E3F000DBD67FADB5F799993349AABDF7B6FFF7DC -:10E40000FDE9478FFBECC7597BADB5D75A7BADB55E -:10E41000F744BE6EF1EC2D60F01728509C8C5DF235 -:10E42000BB3C9BA0BC4482573318333A7C465B3AD2 -:10E4300063D672C6BCF0CFF186BC5786FA53B2E7FA -:10E440009BB6718CDDC57C0686CF72BF818D853E03 -:10E450009DD0388BB1650A0B290E782EF4BE2F4D56 -:10E46000A53263D07FD92E29D801FDEFDA6C64CCB8 -:10E47000C4E8EF33F8B7A217CAC5B1F22A16343090 -:10E4800019FE63575C3B187F95123A2AA530B6DA1D -:10E49000C442C930EEEAA7B4FDD6B010C1D370E0D3 -:10E4A0003363FCF8303FC600B4FF64EABCBC6EDBEB -:10E4B00034C69C0628C3BC236FEB838887FF907DFE -:10E4C00034AF35CC4FE3DCDE5AC54EA531D67C5F88 -:10E4D0006BD65DF0BCD87A7FD65D57433DC201DF75 -:10E4E000B730DE9FC1BCF601CED654B3502EC0B7B4 -:10E4F0001CE69B5406E541293405CB26164829E342 -:10E50000EF53CBF87CBD71F0D5B31EFA5EFD2EED56 -:10E510007BF68B34C267031BA27AF6545C3DE0A302 -:10E5200041E0A1E100BC8FC3C3CC0352C07A159671 -:10E53000821D19005FD359C63641A9E9D06746CD7F -:10E54000F8AC8731C04366126366A0D7A3125BD4D0 -:10E550005F42FD26D64D8136F8771D96DBA9DD0991 -:10E5600081BF476F5991E587765BEC50CE16089EC8 -:10E570000EDFD0E1C7A91C32C17792AE8E96A9BE3C -:10E58000623D2FD7D98A6BB6E730B64DEFCFB201D7 -:10E590001297C9BED77480BF271DFE5B90DF96E936 -:10E5A000BC790ACE97798B7C00076BE57878ACACA8 -:10E5B00065624B490CAE187C9CBEDBA4FE900EF845 -:10E5C0002C7058F2EC7323DF46F47E4BAC5DB34DF8 -:10E5D000A279A41E0BBF3606E9FEBCC4F642BB1DE1 -:10E5E000D287AF8D817E3BE6B95907945D4027B94C -:10E5F0000CDFB34E09F0527EA8EEEE5791CEE549FE -:10E600009EF1F0683C5429375A68FE77FA009ECC98 -:10E61000E4963D3AA8CFBCB3B80CF91BE67DE702FF -:10E62000787FAFCD4DDFCBB270BABBD6070AD69696 -:10E63000E0F77D77BF0ADF8B4C49F2E0F7330157F3 -:10E6400056073DBBCCD88EB54BD8EED1143E7EBA22 -:10E650004EBEB30ECB65BCEC582779F712F36DA50F -:10E6600079671A590DC289EF8325B464BC07A93EA6 -:10E67000C8E93BBBA514C7CB1CC79F4E432807C79F -:10E68000794BA5F760968E6520BCF0DF00CFBD0703 -:10E690002B331DD0FFAD732645970A4F176343D820 -:10E6A0004E0959183E0B8B797B93685F3A3B1317E1 -:10E6B00083334FDBEEA2DE9B7A35E025F08ECC90E3 -:10E6C0001EBFB37853EDD0EE4B063E8F443AF62191 -:10E6D0007D603ECD9F02E46971745B74C580E33553 -:10E6E0007FAAB0E0D5B1F7E7DA4C2C58142B37D419 -:10E6F0001F9B8BED1AD9D006E4ABC6FE64168CE3E3 -:10E70000F72F258DFC5D95BF9B3FD5B1401AB16FAA -:10E710008ECF8AF8896C588EF01F91D83E86F50608 -:10E720001688FB7EF3A70E6D390A67068D136BC73B -:10E73000B4ED067E4FEDD8F4700A7EE7822D9CE2A0 -:10E7400010F3C37ED9326B41BA5C0CEA027A58C727 -:10E7500017DCBCFE226335FD96587B75BC0B8B0C19 -:10E760002C44788FD0B8889700C8B69D839F18DC5A -:10E77000506E183C4A7851F9211E3F8138B991D129 -:10E780003114D2C19AFE856D5557891948714C5D77 -:10E79000BF6BBABCB3A05ED669D6737279747D9331 -:10E7A000587954270B79D0D0553D2BBECCDBC7FA16 -:10E7B00037D654C3FA2F2FE1FD4FD89ADE58AFC495 -:10E7C000E411CC230FF1122D9B12CA16284F892B6E -:10E7D000DB12EA9D09F5AE84720E6F7FCE1ACA93E2 -:10E7E0003D8C7D645B5BA3807C3997155A2C417905 -:10E7F00073C7BD35D520E71ACB87BC32CACF41C914 -:10E8000023B118FE9A3CCC1B04FC593C61C3B212E4 -:10E81000C4C3D06BB8FE1B06249B047C6EE93F1872 -:10E82000A232F673C7F5EB97A85F43FF87D46FD486 -:10E83000F18B75B48E37159FA4768000DB69A0D369 -:10E840005799C45201A5058AFF8FA8BF1AFB7FC341 -:10E85000F52E8B18F8FCB81CBC90E57D85E4E01122 -:10E86000C986EB2ECA7738AE25C6EF6AFB5F4D1915 -:10E87000FC571C26F9DE4FDA1568FF7F1A7F338DAF -:10E8800001A97E854D66A05C0D4E447DBC93F927A1 -:10E89000A21EFA7AE3F8A33A6877421FDECD005F42 -:10E8A000C5F64D350AB43B610DE74A2043266DEDB0 -:10E8B000E5E5F4F06EC46760EBA384DF13B9E15CB7 -:10E8C0001D94A7DA43BC3C3EBC1BCBB76E7D86973C -:10E8D000A7847365E83F3670A0A61ACAFB6C23AF05 -:10E8E000D77C3B97E32A7C97C779B3EDE9C8765C80 -:10E8F0004FECD603C6401E2E5EFDF1B3FB000F8B1E -:10E90000EF4F2639B5EFDC57E6FB68FE019F520159 -:10E91000F290B33ED763248F15B203B250773962B9 -:10E92000F4B0E60DB949CE4F6A3988FA3E737109E1 -:10E93000C9F94F53BDEDF669B1E72719F00438DA8C -:10E94000ED362E97659D97DA3F6025BB678B99CF93 -:10E9500007D60DD1D722E8512EE6536ED7D133CF4B -:10E960003687C6FB40F2EE30C9F8640133D27355E6 -:10E9700012D91977EC01B90072B957C0DDBB7562C5 -:10E980003000E3DF21311FCA8D5EBB370BE5C30BBF -:10E990007F91EFC4F9F69642199E3F16F2BEB7CEAC -:10E9A0009B658FD38BBD7B78BD2A777A0B787F559B -:10E9B000DF6476F0EF646E99B817E791AC302F966C -:10E9C000972F2ADADB4E7A7B01CD9B79BD5912CC89 -:10E9D000F7F4AAB13AB42355FAA4157A6FC2F9DC58 -:10E9E0008EE35B627452BFDF8EF346BD2F83DE87FA -:10E9F000F93EE0F0D3FCC10E984A76A0B003DA717C -:10EA0000BED362F8654A781ABEFFFF084FF760FD73 -:10EA1000FF144F23C88B00B66B6C0579A18B93173D -:10EA2000027FDBA4903E93CB0B0FEA397CBF00E45E -:10EA3000E3ED36FF468447FDFEE2071AC9EE53E1D7 -:10EA40004AFED68B355F65C3D759A25D76E203D304 -:10EA500066067AEC84A19FE4E289F9CCD38EF24376 -:10EA6000C7EA118FAA5D5971FF9AB718D8B397ED0D -:10EA700032D1B95BF266E1BCBA81AE26D4C37586E9 -:10EA8000E0BE82985EECB50777AC40BADE52E20990 -:10EA9000B8493FD27A0BB42653BB5E7B9829583FC6 -:10EAA000C36D034890CE448FC86D86E05E09E9CD02 -:10EAB000F9A577D5A4604022BA07A8FF6D9C7F7A9C -:10EAC000EB18D9F7BDB7B9886FCC2C68467846E308 -:10EAD000838C0E467CC414EFD43A6B0C0F3F13EBBF -:10EAE0003AB93CFCFCBFA11DB9D94C7624EA4CDCF8 -:10EAF00077B19E4C8217E8F902F187BA5F7A242B2E -:10EB0000B889F6679E0AA4C746AB7709C1FFED64D2 -:10EB100037C2BFCBCCBA4C65B8FD609D24EF043C36 -:10EB2000ACE73186F6D99DC23EFBF7FA4B56B403EB -:10EB30005EB573FB0A19C504F26F29E3F54BD725BF -:10EB40007F88FB99A5EBE49011F62BAC6B8E371CFC -:10EB5000B7CF208E82F1FC425EB2ED112BF28D1FF9 -:10EB6000FBA5E0F87FB4BA2D5886FE5391ECD0BFD8 -:10EB700038D6FF3DB16E17CB1C7ED696EC46FC26F0 -:10EB8000CAF5F754F87A1EF3C67F4FFD4EE2B8B0CF -:10EB90008F7B1FF105780FA5A23DFF6D99E89A08BC -:10EBA000AFD31079C80CF58BDB64FB7AC0A7BFD557 -:10EBB0004AF355E1BD3333722DEDAF12C63F93DCFE -:10EBC00054A1E0FCC5FE83ADD3EEBF1833C4CAC068 -:10EBD00017CB5984F631C3DE8B7D6BE2BE8FB1BF9C -:10EBE00018E3DBA9EB85B9A504F8055FB92505E9AC -:10EBF000E69738DDA2F44E805BC5A7EC18199F4E4E -:10EC0000433817E595BFD5487848ECAFEABDC7CC87 -:10EC1000B03E80AFB64B12F1E3F6FB92498F311351 -:10EC2000A763F3EA2437F2E74E43E4695A372F1912 -:10EC300019D2F5A239F202C9A342EE37B8F83379F6 -:10EC40000FB6BB90CEF9FAC2613DAD270E0CD83B92 -:10EC50003F93F752BDC4C7BDD09EECC6F5D88C9883 -:10EC600084EF3707FEAB8D01FE4EE9F83EB87940E0 -:10EC7000BBDFBD00FFEACB6272E122E3DF090C706B -:10EC80003900335D45DFB923896D82719B7492171A -:10EC9000EDA3A6D593821D9C5F4CB85E1A04484D27 -:10ECA0003AD8F795C5D67793EE6411EE9B1A4C9B34 -:10ECB00087E414AA3F8EFB2D86FB25E8B71A3B1587 -:10ECC0000CE7E7A6CDBFFD33C2DD74484BF78618CD -:10ECD0007F489F49D83F8E5F0A627C40F635CA87DD -:10ECE0006A161C2F713F0C96936B8682E887691613 -:10ECF000FE89F463E1B9C81FD6F27EB6149ECD67D3 -:10ED0000B97D317370CF2BB8CFB5D70CE5E2349B0A -:10ED10005BD75E7DFAEA187D5538670C6E9571FFFA -:10ED2000A6DA2571FBC7890BA6C43FD7533FDC8FFA -:10ED3000E2F7C2F80AD785C2F5D936A1CF40EF91E4 -:10ED4000DC5DDE3381F41EEA25945FEA7E16E51968 -:10ED5000CA8F271D558B1C30CF92B4AAAF38A6F1AD -:10ED6000EF901D8F9BA019C3F199A857D476B8AF27 -:10ED70006DB18CDE2EEAE7D991CAE583225179C5BF -:10ED80004FF57B36117C0AF1CBDADD05246F557F18 -:10ED90004C83F043AD10FE9B15C27FB372BB91B99B -:10EDA000E3FD55416DB941ACF74616E67EACFD502A -:10EDB0001FEFB7A966212BD6A3FF069FFDDAFECD74 -:10EDC0002C385B41FA0E7C668C7FCF7AF97CEF148D -:10EDD00074DF61E67E9B99EBF6C8DC19C5E79B5AA8 -:10EDE000E62D7810F5C49B7AF22FFC87A0938A1742 -:10EDF000A3A3EAEB88EF24DC8F61BB078D8497D354 -:10EE0000A08F0F0ABFC602DC67B6F9B30A0B113D2B -:10EE1000B6BC05D6E1F8DDF492B91EF965B343A797 -:10EE2000E1A72A879ECAE4EF41BCB727935D0D682E -:10EE30009E8A7C543156D5936C2AFA993ED483BD70 -:10EE400005E5A65B2D7E1C2F8C7601947708F9B51D -:10EE5000C361A0F1D472741F27F805BE43E3A1DF9C -:10EE6000C517C707C168FBADC25EE47261DBAA24A7 -:10EE7000924731BED531E2DB129F01FD452F0939A2 -:10EE8000F2122094F651FD662E47142E9F5E3A3BF7 -:10EE900089E4DE1B1FAF26B972695112334AD4DEF2 -:10EEA0002B61FDF3C6E07A28DF25FCA82F49DC0E94 -:10EEB0000C1CB1D2380D06FF0EF42B343C37DE03A8 -:10EEC00014632F1882DF7F1AEB5F3693DFAA218548 -:10EED000C3D9F0D21892933FD6079FF901F9218C3C -:10EEE000649F3524B953A9FE27690CEBBB92FD83BF -:10EEF00048CF6C23B71B1B0CA1223BE0F16490DBD5 -:10EF0000BF2751D0E0F88356B26B00CC2CFCFEA991 -:10EF1000EE4CCF26770C2FA71E9A4CFCBF4DCFE9A5 -:10EF20001638CCFD9A27F5BEB959503EF97CA90791 -:10EF3000768EECA2CF1032008CCD5BB8BDB64CE71C -:10EF4000EE6B45D9F472B247B3DF7C78652DD637C6 -:10EF5000AF5E7713CAC1D1D633CAF3787FED0516F9 -:10EF6000C9A3FD66FDD8FE107CF7C2E0440FA94797 -:10EF7000E60262039FD878DBD37AC037F2D7113D1F -:10EF8000F1EF171D1FE78BFB3FD42FF89D6690BF55 -:10EF9000513F32C9DFB8B23C5299D3B3F9A54C61A5 -:10EFA0009F69EBEF48F55F40B9D6F4DDDF9F682538 -:10EFB000FC4648FEB11EEE1F3FADF72E463EB5574C -:10EFC000870C4BE3F6B78634BE8E9619855E6721B3 -:10EFD00043FCBA53EB2BAAB47CAE3EF5697C1F69A7 -:10EFE0001DE2727C78BD4EAC9BAF18516F71D70D8E -:10EFF000ECA7CF727F8621CD4DF533CF860CCBA009 -:10F000009CBF2E6458219EB82E00DF2113CCFBF448 -:10F010000E2B5FCF80061C67C57446F6C80A19EC34 -:10F02000D0327CEF1E08035DCE3C6FE7FCF527C0B5 -:10F030000AE07B0913ED8C60B782DC7AB1530AA138 -:10F040005DBF64BB71AFB900D7B157B6223D774BF6 -:10F0500024B796745616ED80F2EA435388FE29D3FE -:10F06000395FAE0EDA49FFCD147270993168203BDA -:10F07000FA19EEA783F1C91E6E804E5965C3F1805F -:10F08000F25BC30F416D9C6166BF90A7FBE3E20B8F -:10F0900063E3E47A7F427FB0E3B4FC1150F50E974E -:10F0A00073CC9D89724E95C34687AF348DE452610F -:10F0B00026D217E8C9E5E44189F0DAC85AB8DE106B -:10F0C000F23EFA5DA12FCEC801AE978C5BE93937CD -:10F0D000AD80E8B61AF50DF9CDF9FE6E343E989B79 -:10F0E000A6137271643EB85EF041C35916BA16BEDB -:10F0F000D7B08E851AA7F2A7752AE941AE0F4D2227 -:10F100009E61E2F18ECFD38B897A7098DE4BD077F7 -:10F110009906A1DF049DE3FDD9A8EF67AE0BCAE80D -:10F12000D7CCB379AFCD4C8FD92FCDEF994CEEAB77 -:10F13000B0EC63632DE89FA97CC685FE5DD88FE3A4 -:10F14000BA4A06BCEC81F7BB55FBD6C5E7EB32707B -:10F15000FED52B3E566A41BA0CD17E3592CE6CC894 -:10F160008F2A3E775BA15F19F6E3EB2DDADFC43A15 -:10F1700093E2FA57BD6426B97AE5B0356824BBC37B -:10F180009F6F87F1327E65243BF4C24B56D29F17A6 -:10F1900084FE73AAFB7EB681E8D38A744D476EAABB -:10F1A0001A83FE5326CD1F832250B5C31AEDA3F94F -:10F1B000B3457DC1D0AD9CAF8CB45FBC620F7F13F3 -:10F1C000CB000F43FBBA05E98CFEF643B34B1F801F -:10F1D000F7CD3E8B8763DF5F8AFC6A94EFBD15FD38 -:10F1E0002A73E57591FB601E8DB9169B11BA54E721 -:10F1F000FFFA97B741F9A3437A66443AEF9BBD887B -:10F200008D1D5DFEAE0AEA4F86E3D6CB9AFDDA721B -:10F2100063BFB6DCCC9493E13879FC589AD5796613 -:10F2200032C90ECF67C0DF4663CBD93D00AFF1C70F -:10F2300046D2470D69FE5D69E837D5455E433C1B04 -:10F24000F3CF4D453F4555FE9F28AE73E5DBCC839C -:10F25000705F315792FEBEB2C3EC0EC4C9AF66C137 -:10F26000FFBD79B554DFBBD3E896787DEDB40AB421 -:10F2700007E9DBF867D201FE9BB7CFFB88F64D6844 -:10F28000B543B917ED4BECF79C146C47FB713BD7BA -:10F290007BE7C17E34A1FE14EBA9591E9C6B82FF53 -:10F2A000EC75D44C44F9A2FC59F121FD37E25071C0 -:10F2B000F6EEE1E8FAE47E9C1BD08F338EFC3887B3 -:10F2C000516E349AC2864A18E7BA3FFF8EE4F2CAFA -:10F2D000D6A564D7C7EC5C23C99195F7F9E9FD2B56 -:10F2E0003BAEA7799D8179237ECEECE6FBB99539BB -:10F2F0009620C2779D9DDBBF2BA19F240DC74B227B -:10F300001E7EB3EB7A17D2FB378C7F2FD0CFED84E4 -:10F31000DFD8865248FEB85B52D0CE6BDE7EFD470A -:10F3200028B756EE963DA8C7D9112BF93D56EE9E4B -:10F330003371B905C7B99C568978EB9B6393E9BDD6 -:10F34000EC0B72FFC9D075F05EE9BBC68DEBE4F83B -:10F350006E2387CF6E7A1AE1BFEECF32F1BDA26382 -:10F360007EB4577B0DDE89B8DEDCBBF6CD45BCFE36 -:10F37000A62E5B47ED9F95980DF1606FCDC0F72BE2 -:10F3800025C587EBAB7EFBAADA787BA4334D267CC0 -:10F3900057E6AFCB085B88DF6F453DD7B85B4F764C -:10F3A000DDF1051FFCF236678CDF57CA3DB7CE8C06 -:10F3B000B3379A77DD28F8013436E069A5C0933178 -:10F3C0007F5D117EF7F3F87FE5FA96221E8FF9EB49 -:10F3D000EB20BABE77F1F5F007D0F7B45FCF7168D4 -:10F3E000ECFBD1F641AABFD9E461DE7D168A1B7A17 -:10F3F000719F9BE754A83ECFC9ED6CE50F6BF7BF3B -:10F400000DF0F7A7F98D4E789FCFBCA5485777C46C -:10F410005605E6244E89EC1FB6CBC8ED4985FBDDC9 -:10F42000B6A5B3A737C5C1998DE3A5D3FAB43961A1 -:10F43000DC0BEFFFE935C45F53DEB9A93C9EF63B18 -:10F440008A4F590679DCD2E2F131E48BE6C13A7693 -:10F4500057494C1E367BB8BC4E9CD77227DF6734A9 -:10F460003B23344E753A5F67AABF77676B12F9F595 -:10F47000763A8366BEBF0D3094E73795CB3CDE22EB -:10F48000EC129FF09399BCAF308CC7308FEC190F02 -:10F49000E521EFA9CE3428BF5D3EC72343D9E27DE5 -:10F4A000B26B2CCEDBA317F5E3C85FF8D6AC4AB23B -:10F4B0004F6EF2CAF45D569F42FBF521EFCF9D7768 -:10F4C000C1776F66DEB4D3F08D1A50D648C721FCE1 -:10F4D00036DA018ABFDC19E75FBDD1332FED74BC8A -:10F4E000BEF472FD8FFBF17E113718090F25699567 -:10F4F0003311BFD77D99D3E1E367F9FEE36333F7B7 -:10F5000063ABED3EB6723D53EB94841DD89F87727A -:10F510003E5AFE5AB1260EEC34F4E7E13AFBADA4B4 -:10F520001D6775978EE2B3ABBA18C5633FFEFE8BBD -:10F5300079286F3FDAF762DED238F812FBA9CF5B89 -:10F540009D5ABF94EA87748AB8F4528F91FBFB46A8 -:10F55000F143AAEDD976BE1FBB08D21DF94EED7757 -:10F56000B13EC98B76E545662279B67450F835BD53 -:10F57000DE4227EE1FD4FE09E36F41FE01B8A4016D -:10F5800089F6E7C9251192AFAB4CBED7C6B8312F6B -:10F59000C54BF499877494905FBD069CB722F679A9 -:10F5A00046C5D788F45CDEA3A56396D326E2944EC5 -:10F5B000A2BBA1C9A2A07EC8E810F2FA1B3ADABF2A -:10F5C00018B25D16944BD715257562DCDD9994321F -:10F5D00015FDE6B9D9C5D43E50C5F93A90C1C86FFA -:10F5E00095C55A2492B736EEE7CE99CE6C98E7F1DE -:10F5F000A293DB832EE6D92E933DD82F91BF5FCC0B -:10F600005F95EBC82F28E73E964CC42FD2A044F656 -:10F610009DACEB5F8CE38EC63FBD09FCD3FB0FE6D0 -:10F620009F3EF57BC3F8C74F71BAA52ED3C8FC2304 -:10F63000FCAA5FB8FD6871C26F98543FB384F3AD04 -:10F6400015E3D59A2C21792AC98773F1FED45D6020 -:10F6500067E27E448D2B8EE958E2E676FA5018F781 -:10F66000E5C9D79848CF7D47375480F67C629C1116 -:10F67000286B47798F3286FC8AAD55BED36971FA03 -:10F68000FE08DF3734DDE7A5F7B307B97E6F2E3408 -:10F6900090DDD93C200590CE4D3E43D0544071952D -:10F6A00025A4B71F32BB799CC4DD4E71926FBB7924 -:10F6B0001C25EA470DF73D80FC566F21BF4362BC15 -:10F6C000E585BFC8FCFBE3197DBFB794C7777AE730 -:10F6D000B9C9AF911847635DDAF5ABC6512E5A012F -:10F6E00031F0BDA59BCD44876C99E399A59AB87E6E -:10F6F000192E07C85F9B315D1046C43BA2EB1A244C -:10F700000396B345BD1A9FB196F80AD0C2BD3DED30 -:10F71000B93793D2FF967C86D6EFFCD57C8680B134 -:10F7200016F3194C683D8B7A041BF4AD5AF69ADD3A -:10F7300018BF89D52B60379A0624F1BDE76F98531F -:10F74000087890D4EFAFDFE4B550BC58F3BD78F83B -:10F750009484F1F530BEC52DDA070ECC9BA3505C26 -:10F7600052D47FD68DF91B5BF4DAF108A5A23F16BF -:10F77000D4EF1DCF9CFB9DCD3931BD0F7680297D07 -:10F780005A4CFF6FFCA0B6E72AF856B2EDB201F56D -:10F79000AAAAC79B9D3CBF2171BD3AD2F97A05FB4D -:10F7A000D5914E7283DBB5B5223E09F6EC5C5C5A0E -:10F7B000CDEB7C0CE393602F64A4631EC3FBE7CE08 -:10F7C0001C45FA2DF898ECF9E64F15EE7701BB03CE -:10F7D000ED7393E07336A0277DABF2C16A217F7A87 -:10F7E000EDA0EF915F8F48D302C4172D79B7000DBC -:10F7F000EE4FF7BA697CB1EF4A8477463AF7933413 -:10F800001757ED28C2F19F9218EAFB4DC52733D058 -:10F810002E691EFC3063795CBF55038F121E56EDB6 -:10F82000D78F38FF19E9DCBE6C3AFC3CF9073F0E74 -:10F830004AB496EB9560F74C28D7D7EBD04263E5F6 -:10F84000C125B791BF7F91818D87F9E50B7DD4BC30 -:10F85000FF2B8199B83F837F12BCDAE95B417A6F55 -:10F86000E7229305E30ECDC54BEF263CD892BC882A -:10F87000874DC55559F89DA6BAB9368A13807D853E -:10F88000F54DF7DD4E7E1315AE4D03FA1AB4BB2AC3 -:10F89000C0CEFA11C09DEB985FE381F537463E5824 -:10F8A0007A8F05E3C223CBDF7FC9E0F4EC947C813F -:10F8B0009BCBC94FC8E2FD7EF903DC9EAB4B37689A -:10F8C000FCC275E9DCCE9C15189A8DBCF7B2124EBD -:10F8D00046BBB799793FC1FD25F359DCFB884E5CE7 -:10F8E0008E38DBDCE43F3239C3DFB90AEB6729B479 -:10F8F0007F604AF811FCEE856EA7671313FC8BE559 -:10F90000FB4A822847FF39DDBF18F9AC42D88F1770 -:10F910000E5F5F8A7E36D53EEADE630E621CB0DB88 -:10F92000EAFE6E0DCAC13F283CEE6D8A0CCD467AC8 -:10F93000FCD141E3769B83DD48FFC0563DD51FB621 -:10F94000FA5721DF9CADAB29A2BC1B4BA008E3BC3E -:10F950007A670F433B01B60BE44F30397D0CE3A1CE -:10F96000B3034B1409E57C82DD315BE48F92F084B4 -:10F97000F755428C8D072E3863A225D0F9595ACC01 -:10F980000E79E34F0B157CA9DA273A138F67552FB1 -:10F990004A6232F2FD86C86B3AF45F3B87C87E6DDF -:10F9A000EC97E83B8DC5CF513ED81A917714CDFF27 -:10F9B00051C2940FB53E3D59E8F14ECEEF6C88F63A -:10F9C000CBEC00A7276361CA938AED23DAA99D3A9D -:10F9D0009E41F8DD1B85DF053418D53F94AEDA076C -:10F9E000EBC553CDEBE2DFDD260D7965C46BA9A431 -:10F9F000F117ABCFA7D2B97D987A2C3217D76FE425 -:10FA0000B09AA7C9F330774C9BE441D369589EE67E -:10FA1000C02773916FC0D0A6F5DA34F0C5F234BFB9 -:10FA20002FF60DFFEB799A1EC9BB179E3F4AB7739D -:10FA3000BF959AA7E9E1F853E36C89F99917B242A7 -:10FA40000ACFB70AF7ED43FE1C30521E57EDC0EB4C -:10FA5000EFA17EAC35B17E8C4326DA196DB6AF0CC2 -:10FA600022DF5F3C7FA6EF418679BA2F78285F239B -:10FA7000C17E48DC27ECC52659A3DB7BEF46E9C9EC -:10FA8000EDBD68F97FDDDEE3F67C601FCF0F50E54A -:10FA900079B3D89F5DACBF94827AE644149E843CCF -:10FAA00086A7441EC3E0C8790C8AC807027B3D4084 -:10FAB0007C7290C775DE783A99E4C7259BB217ED42 -:10FAC000A5F3D6C83711598AB0933A8F18DD282F7D -:10FAD00040DE91FC0E1CD4F3380DC66D308EF3F26F -:10FAE0004411C711F1A29792C96E694871A7627F4C -:10FAF000354EF363A16F1A92787CA62BD97F397D9E -:10FB000084B8CD1E617FED81A16C38DE7B4611C7C4 -:10FB1000060181FB9D877279DC41C46D2E8AB8CDC8 -:10FB2000A9625DC8C0FD10E4A77277292C0BEADD3D -:10FB3000EF99836EEECF32E940EF2F53E3362F7308 -:10FB40003FD532119F39B5602EE5072DC7FC7719D7 -:10FB5000FD18DCCF1CCDC767361DCE670D888B9D89 -:10FB600028620280F56BE0B5A493D09E707742992D -:10FB70008C656F4F0D7C7769A78EF623CBBAB4FEE8 -:10FB8000F22B9BEEAE41FDBDB193C71F035D12E9A1 -:10FB9000EF65CCEB427B43E587828C34A273A053A4 -:10FBA000E7C5EFCCC8E0FE04407D90E6279E9D7A35 -:10FBB000E1671770B4335D089F3A893F37DA949A4A -:10FBC00011F5B218AF53DF62AA443B3657477EDEC9 -:10FBD0002B06EF22F2933A8A886E9DD696AE1A5E75 -:10FBE0004F6BE58A39E2A3FA6B156EE831B703E58E -:10FBF00064668688DF24CC77798FB69C187F581589 -:10FC0000D4969731FF842C3C87B05FFB3E3383CB87 -:10FC1000A92B9B0A849FDF437EFE4EBDFBDD029431 -:10FC200053DD0AC9C9F61C8E2F5D2E7F8EB5572F66 -:10FC300022FBC00E7605C1CBE11F7BAD53427DD9BF -:10FC400069E77CF93F853B11DECA8C226E27A071E3 -:10FC500087EBA85B0A727C71B8BFA8BF626986F0A7 -:10FC60001708F9132DFFEFEF37393F76CB62BDD977 -:10FC700048FE2C15F1C65392E7E910BEB7805D002F -:10FC8000702FEB96CBD03E99FD150BCDA3E9657394 -:10FC9000D008F58DEBC279B88E9AAAC2452D23E023 -:10FCA00015A15554B905ED963A617F80EBB64B1B13 -:10FCB000871A1E57F47E2B231DF721A70EBE8EF444 -:10FCC0003E6826BD04FF75D488FE8EC305642F4DA3 -:10FCD0004DF5B765A03E4F0AF57DAF00ED136E1FE1 -:10FCE000350E1AF7A0FDB7B4537B6E866DD6C6B934 -:10FCF000589783FC19AC57FB1ECFA768FA0D8B7B76 -:10FD0000713DBFCDE09F8876DD755FE6F1F5F3AB21 -:10FD1000740CE9BB4CF6AC403972DEACB5BBCF5BC2 -:10FD200039BDFAA274F614219DFB46A5B3A708E9D4 -:10FD3000BC4CC7FCF1E334229DAFC6EC734EE7F335 -:10FD4000CF5F5384743E77F09A22A4F3367D8F17E9 -:10FD5000D7CD930EFF5EC4CFE9393EB29BD4BCC968 -:10FD60002FCA8F8732B4FA305AFE3BF93F46D3830D -:10FD7000A1281C5A3DE834B873501E2E3519FFAA2D -:10FD80003EC4BF11FD692623F9235EFED3E58751EA -:10FD9000BF050665B23FD4F15E56FCE3D05FF0F2DA -:10FDA0007B2E4F401A7DFC066157B94C2C807E0F8C -:10FDB000D5DE57EDC64479FC0B319FD319DE1AB45A -:10FDC000B355FF6CBD18D314BCCCEDD3A724F2BF40 -:10FDD0009ADCFD3C7FFEC8121BFA67CF06B93FB61E -:10FDE000E9F952F2D7AE0ABE12C2FC273628D97002 -:10FDF000DFB0EAA90F53309E0DFBD0531971F19576 -:10FE000039621F7A36782A05E3DEF0FD6AFC7EB29D -:10FE1000336240FE6D82FD1934614D4A84CE0D354A -:10FE20003919E9FBF201ED7E4D8D4FEEF41948DEF4 -:10FE3000ED1C9482B83FCB30F80B72503FB11CDB05 -:10FE400099E4D87AF924C36BCB9C161F17F65ECEC3 -:10FE500088CB570AEF48253E0CEB9997EC801D564E -:10FE6000219778BCE63F77D9833C7F89B7FFCF6085 -:10FE70000195557DBD429CC35B21CEE1A1FC0E25C1 -:10FE8000C8EFF87234DEAC9E3703791E1A29FE1DC6 -:10FE900097B714DFBF8945447EDE6746CDB8D17C75 -:10FEA0009D965237C0BDE66B163A67D80C7CDD5A7A -:10FEB00016E3C3063115950F9B845FB7B9FE24ED99 -:10FEC000039AF17C05DA551ECE870DB03FC2FCCDFA -:10FED000C475CBFAB5F98CA3ADE329995ABD122D9F -:10FEE000FF83FC98D333B5EB579DBFEA078FCE73E2 -:10FEF00050E2EB2B615E89FBCA44FFB5BA2FFCA22E -:10FF000072EDE64CAD5C8B96FFC172ED8ECCD1E408 -:10FF10009A363EF037CBB5C4384121F77F639C0059 -:10FF2000E3B6FFD338C147EE9E0C1DCFC3D7C44FF5 -:10FF3000BBA4969B4CE330AEC8E3CB8D5623C56182 -:10FF400013E3AACDEEB9228E38F4CB19A8370FE906 -:10FF500019EAF37ACB4A8A5736CB070C78A4705843 -:10FF60003C51394A76FBDF1A575F9F198DAB1760FA -:10FF70005CFD15CBE5347F1C3DAB4AC0C02F193D5D -:10FF8000DF68B3A053B2C88B302901668FEB3F5AAC -:10FF9000BFDE4C6E27BF22F2635C069EC7BEC50A59 -:10FFA000FB3098BF4BC7F377EE4FF76D43F968729C -:10FFB00073FC3E71F8AB0CCF1D3DA1EF27391268E1 -:10FFC000B478501EAA7E17757C45F80FBE28DFFF57 -:10FFD0002081EF7FF077E6FB447C0CA872E76F8D01 -:10FFE000876D07DC68D607A3B8D75B18CF2918CE72 -:10FFF000C7A38D331A3FFF34D3F75A26C947EF54AE -:020000022000DC -:10000000CACBFD82F226B93C720AFD3BEC90D18D41 -:10001000FB0D933897C13667893C4A4F451DE51360 -:10002000F3730DEAF98FD1ECC20FA3729ADB851F2F -:100030008E2AA7FF7B76E1030EDF299CE7E94A6F52 -:1000400011EACD8D56801FF77BDF378E78CE423D8B -:100050000F00FCC4CF9B3CCBE3E0897CF58704FD1B -:10006000F287BFB37E194D9EEA5D2A1C7F67795ADD -:10007000FFC714F47B8E3E4E80E0A8A81AF28AB81F -:1000800015C3B8913A8FE6219E7F9621F2AAD4F744 -:10009000116117DEE9F266BAA0FFB9F74D26960A9C -:1000A0002610F218DA633E0BC5039AFA799E48D3FC -:1000B0003A46715FF51C65D3401D43BBAF3FCD5F32 -:1000C0008079601B3FB004E454F4932F6068EF5DC7 -:1000D000789F971BD2FCE3294F6C5D581377A8F8E3 -:1000E000ECF206F46700BCE41F708AFC4C15BE3AC3 -:1000F000179767EAF32681EFE8BC9C1C4ED62F07C2 -:10010000D14E4C760F911FA9E91037DE2A642FF9E2 -:10011000EBD91A079D9F683A54594AE7CDFBCDA504 -:1001200068E756FCAAD686FE8973D73A29CF204FB6 -:100130000EAF423BEB9FD3FDB3105E6B79701EDABE -:10014000A9F960A7A2DD7BEEE0BC527F9CBF7B1BC0 -:10015000FABB61DC6D56AD3F9B99789E78FD5E9E43 -:10016000077CD8EA9F8BF8DD66E6F006B68ABC67A6 -:10017000E1E74E5CFFEABA8F9E73BCC344716955D8 -:100180002E6CD3333FEA3D559E94883C39C007CF4F -:10019000D31BACE3F91EA26C716AF3154F67CC292F -:1001A00041784AD0D13B0DEF518848E8775F2EE285 -:1001B000F0D78B7C0A357FCAA8F8BE8EEDD9BA9AE3 -:1001C00058FC7D2CF617F177912793FC29B79FC730 -:1001D000DA0CC43756585FE41F01BE41FACC8A0CD2 -:1001E000CDC6F34485BDA15988CF973FD5113E9424 -:1001F000BAB7287E928A648371C66D0E774F403FEE -:100200008AED17D7225DDC3DB62A445D7F9AAF9117 -:10021000E0505A8A715F59F5AF7A9E07782499FCAD -:1002200003BD790D940778E103E388E746D467803E -:10023000ADA7BCBFB1033F273FBEF59034623E6718 -:1002400097CBC2CF0D078628BF8CCD72123E942368 -:10025000BFA2B8AFD2AD9007A353EFD5E139A84004 -:100260003B23FFE5F85E9B0EE9922FF24B2EBEFC7E -:100270005F53FDB44F51FDF6419E0FA40F6FC07D3B -:1002800097D21EFE32AC60D678C8AE6B2AC1F1227E -:100290004D3CAF3D99219FE40F8C5BFF2528E7770C -:1002A000D99884F2E7A535F9E42F85798E1F619EF0 -:1002B00077BB78FE8E722459877A4BD9CA28FF50B3 -:1002C000B1675411DC8F4219C65923F8468D470295 -:1002D000B82ED44777BAFCBB11CFD17332AD49FCED -:1002E0009C8C3877696DFDE0593C7FD267E0E70C64 -:1002F0008FBD3C7901F9EDBA1509E970C5BE24DF5F -:1003000006EFF78B756B558698CD128FFF63946F50 -:1003100039F608CF4B53F49C4F946EE71EF40B7ED6 -:100320009AEAA7BCD26B3B4332C5B36CA71FA97135 -:10033000C7ED6BB6733DD2B49FEFA713F7319FA7FC -:100340003F8EBAB47649B4FC0FB24BDE4AD01B7F65 -:10035000F3FE8469F77589F649E23E6E98DD9D30BB -:10036000DE68768A9AD75115FB0EF1C32B56D50E4F -:100370000A68F25EAA2CE2DC9B493BFE53224F47FF -:10038000CD83C9E870B7635E79E4DB8CFC6C6A3EB0 -:100390004EA08AEF1B023A139D8773B11ECAC31980 -:1003A000C3429244F67F98CE7566623E0EF47BDFC0 -:1003B0003596E0DECD3C5D32C943B784709B318F0A -:1003C00083F236833B56E0776EB1D077CC98C77115 -:1003D0003586E2BD3B507ECEAEE771886CD0B7C8A3 -:1003E000B7D9859C0FCD8B783E879AAFA1E657A8E9 -:1003F00078A812F8CD9EB0A200F707DD92FFFBEAC5 -:1004000079DAF873D2D1F3D1ABC6D27993E8F9B9DE -:100410004226EABFD839E9447CAAF91D5536BF2DDA -:100420002B7DF87959953FE2E84670ED3CC2EDF539 -:10043000AA7A03C17F71D57CF2235E5CA563B86E96 -:10044000AA068D9CDF12BEB7337A0F46D04CF75DFB -:1004500008BA7F9EBD0AF42C463FEDB1B69AAB4F69 -:10046000036E8FB7F9E879D12CF5CB57D179C6C592 -:1004700028992E67EDACC57B0A2E5A237978CFC117 -:10048000E5EC076FA4727AE4049653761EBA11EF76 -:100490003DB8383ED287F71E14EEACE4F5C883D9D8 -:1004A0008C5D9555716380E6CDFD4EB363E7B3CBAC -:1004B000113F8D2CBC6188FC3B3C7F1FF3FD900EEF -:1004C0002E8B81EC1997C8B364D522EF12233050DC -:1004D000EEC82AA578B585B90F0D617D0E3F2704BA -:1004E000F5C4BF1DE3B95FD824E8CA72543F52383F -:1004F00080F2A9A3C04EFDA372F49031C8FD59FC4F -:10050000FBEF3C3F85E24B6AFE2863B6DC8553284F -:10051000DF445356EF37608A2D17ED850EBDB04B83 -:1005200045392DD55F97156717BD33E75B25B80EA5 -:10053000CEBFF04021CAA5EB0D60B78F20877E9D0E -:10054000CDE5D045BDA54B023BEDE729FEDB719C17 -:10055000F79217CFB5C3BC16A5551AEC086FE0FB90 -:1005600032CAC574416FFB420E9FBDDA272D8771D9 -:100570003BCCB07EA17FBA5FF1529EBD7FA1740BD0 -:10058000C0DD2171790B9D52695F52EC4EC5FCE5CF -:1005900006715E5216EB7E46FF5619EDE977DB06D3 -:1005A000662A8531F87E2EE2CB3F2F6077D68DB05C -:1005B000DF6DCDE2727B81EC9E827CB4411A78AB18 -:1005C000360BDFBBE9FD9C94D672CC3BBE3EB9A591 -:1005D0001CF5CFB0F7A9F0BE24AE6CE4ED1A4C9137 -:1005E0003C3C9FEC4DF6AFCBC2B8D0920F296EF9D0 -:1005F000CDEC774E60DEC13BFA9ED929A85F0AC4D4 -:10060000B97EE1377C6D82EA3734F1F264EE378CE3 -:10061000E6734DE1F964B50BF939C55A91AF30D79E -:10062000C6CFF5CC2D2FF074008837B18882726F59 -:10063000EE7BBE14DCB7B385FE72DF94D1ED19E614 -:10064000D2BBE3D7EB3C775C19FEDD50AC2DDFE885 -:10065000D1966F9EFEE709F1E53DC9DE1D38EF1F1B -:100660004B3CFF313083D9689E4E298076C7E41712 -:10067000B3C5F94E9EA7F74F625FF4E27446F519D1 -:10068000FB4D7B31FF5DF533CBA27EB28B99F21D22 -:10069000FCBE00D4571149E4FB392996C25EB8DB91 -:1006A000C6F1076D0D30CE0B4BDCB43E322C3AF662 -:1006B000655C43E526B2432AC69892906F8E09BEC8 -:1006C00053CFEBAA7C58A1301FE62FC0A717E2F347 -:1006D0001DBDED28FA97031F31C6E955A950FEA1AB -:1006E000F81663ED547E4CF0F7310153E0DB0AADB0 -:1006F000E757AD06A2A7FC13790FEA098CCDA0DF5E -:10070000F8D2E649049FBA7E6055173A33C8A52D42 -:10071000C655740844B1B02754FE460B08DB8DC1A2 -:10072000FF2C203E27791399C6EF4FF879019727C0 -:1007300091AD0E711E8CC7CB724DD171BD386E5606 -:10074000F43BFCBC51862843554807F3FE4D560147 -:1007500097CB83AFFF81F4B2C5E3C7EF18524C7457 -:100760004E465D37B6CEDFBE553B03E759F40D9AD2 -:10077000E77CAB0DE7590C6CBDC8414F6F1A8DC7B4 -:10078000D78F9CE471E33AF94ACDE1994A1CDF40E6 -:10079000FF46DE3F59DBDF05FD1D71FD53A07FC91C -:1007A000F0FE4F594D21DD541CA7C21D26791EA213 -:1007B000C9CC17F3923378BFF9221FB43005DAA3FE -:1007C000BE29D6E66BB0E91E13BFAF439B9F71BD38 -:1007D000B42E0BD7D53C53E36018C67B5DD0ED7AC1 -:1007E0009DFF77783FDDEB8B8B8EE37AAB31051580 -:1007F000DC0FDDC0421B9098172BFD4FD8C7913CF2 -:10080000F80BAE8B26D93FC101E5F3FA9EC2BB0BB4 -:1008100068BD7C96356D38BC2A5FA8F0227F209F8A -:1008200045F92301EE289D6EEAA744B6DD60F7E0A6 -:1008300053B583186BE1F9C6EEDCD8BC8089E69A23 -:100840005A0AD10E79BD3D4072E37AFB2394D7F466 -:10085000E7317E6736C0B5E8AA4FE85E13E65A3244 -:1008600001ED7B80373D3BFDFF1DBCAABD372CDF72 -:10087000F6238326DF76B475A57EB799F1FB69660A -:100880000FEEA1FCD9E685160F9E8368C6FCCF72D9 -:100890008A2F911D87E784E99E13C924ECAE2F9A15 -:1008A00097CBD7616FA39BECB7A81C1779E5BDA5C3 -:1008B0001CEEDEBBDDEA3D27DCBE5BC2F83D29EA6B -:1008C0003D27CB6D54AFE69FF7EEE17EBCDEE72718 -:1008D000D07929B0DFC85E60A93A0E5F81F67E1537 -:1008E000FC933262F9D2DBF4DCDEDCA9F354209E07 -:1008F00077621CE8AFC47FBF9AADF59BA8E544BF03 -:10090000DE930EFFEDC817CB4BBC7912F0CF32034C -:10091000F7DB017FEDC2B31535ACE529BC3F701E96 -:100920006BF9856E1CF1979FF86BF227FC5EC1187E -:100930007F2DE1FC1520A1A4F25794AF8A13F3ABED -:10094000FCABB17DAFBDFF574D68A70E1A892E6A6B -:100950009E5CE23A8E83E7B49EC3E394658267EDC2 -:1009600048F07C113E8FE7AF4CC6F979347ECF5406 -:1009700058C05A16E3F73DC9FE76843FCAF71BF804 -:100980007E6418DCB285F8E3D6DB649E3F9ECCF52E -:1009900015C62BB2E0FB75E2FBB776733EBAD56A9B -:1009A00020BEAB1B6CA47C2256CDE30E1EF81FDFCD -:1009B000077A09BF8B44BF85CE523DB2ECC25A6D57 -:1009C0007C6291458D7FF8F4B81E6F5DA83F19AF2A -:1009D000EF17B1CD9F60DEDB228C63A8FDE0BB8FFB -:1009E0006747E31813308E715CECD32F027F23FF2F -:1009F000BF9ABE72D7DDC0B7131E2F29437FCE9C8E -:100A00008C554F6D85F2F7764EA2F2AB1977DCFB71 -:100A10000ED6F71551B91A2F71C1FD4623EF5F5C51 -:100A200071DBFC02F8EE71B31817D715EEFB92FCE0 -:100A3000BD75D0CE35756C19E623560BF970F16E85 -:100A40009E0F7FC355569EE2B9D24D7EA3EA245134 -:100A5000FF753EEE5BA5FF568679A9D563238BE92A -:100A60003EC6B21F4FC2F271E993C523C54D26178A -:100A70004BA189809F6A076F5F5BF6FD6CDCC757EF -:100A800057F1F2644F65F738ACD75D5A3CD2B9D014 -:100A90009F8AF5143DF724D6E98BDE0FE99C93CFAE -:100AA0002479708ABEE91FF27B892C920DFD8F3E5E -:100AB0006F81827ED2D95E9EB758656ACFC2FDEF44 -:100AC0004D7E4339E69FDA4CA5C7D1CE489D5E39AD -:100AD0000DE93BDBC4F4A89780CFFF85F8FC9A4F63 -:100AE000F25290B92C5A3E57F9A84EE5EF6A2D1FE5 -:100AF000C3FAFCD7ECF4CF97AFA3F1317CFFDFB1A1 -:100B0000FFA22F69F54A74BC84F59638FE6872001E -:100B1000FFE2E55C0C8E7E5A57399815360ED75D8C -:100B20008FBAEE220887413744E73EF225CF243AB8 -:100B3000F0388AFE57E1CB05D9C6CA86C3857F8ABD -:100B40006A9771086CB60CFC2EAF877E5EE688C192 -:100B500005DF676350EF6FE0F0EC965AB8DC107673 -:100B6000B1BA3F6E52E73BA09D6F45123FEFEC429A -:100B7000FF05F673964EFA6B70370BBDB9D0E47B68 -:100B8000C80873B8C5BE8CF8E1AB2CF03CDA27C6B8 -:100B900054BF634C3AEEBB0247C205E4CFA5BC018B -:100BA000A077DA9838FB44852B111F4DA3C8C344A6 -:100BB000B813F110A3CF10D957EAF9A9E8BC12E68F -:100BC000D361E5EB3532CDA8DE5F528CEBE26D6987 -:100BD0009227DE9E7E3B416F27C2A5DA11AA5E55A1 -:100BE000E1417F11FF7EA41DCF90DD38662CD99D99 -:100BF0002ADF640AB80C3A69C438EA8D6374AA7FA4 -:100C00004E43C7C4734E2ABED4BCA0443CA9793D10 -:100C1000C3E23509F1C8D1DA49603F8F710CC79F33 -:100C20001AEF7144FD5C029FA512C93F87F073CD96 -:100C3000F6F0F309B5ADFC9C7C6D0D4C0070FFB671 -:100C4000F01FA8787EC8EEBF8DF347781AEED3BFA9 -:100C50003BEF698A73A8F7C825E267F928F8198D70 -:100C6000CF47833F2DD5B712BF7B5E1AAAC0CA2DCE -:100C7000E9E2FE41E62FC07560B71554A21F02E4F9 -:100C8000EA679FE1660EAB80AEE50E7F33F2F9575F -:100C9000996F0ED2D751E3D773FF3A23FFED5AB1C4 -:100CA000DF9A23F4EDA55D32C507AABD131F9B850E -:100CB00076E21B7A16A4F5EE25FDB946C07F099FA2 -:100CC000D8DEC2F5EECA377F54012B864DD8AE8BE5 -:100CD000DDAF00FF26069334F72B4CDEEFD094A750 -:100CE000F4676BDA5F353056535F1A9AA4A9BFFADE -:100CF0008D324D79DAD04C4DFB6BDEABD2946784EC -:100D0000E76BDA7FE9EC024DF9DAC8ED9AF6A7C491 -:100D1000BE9805BC43C51978BF389FEF759F2ED587 -:100D2000F4FB6DCADC37900FEFDACCF3972B01336D -:100D30009A7B267AB85DD102FFE374F52988AF1556 -:100D4000606F63DEF2CAED5ABBA37E70EB0694A51A -:100D5000897915AB594B155E49979857516D5BA230 -:100D600043BEFBA731C2EEB8865D23EE85F9AB74B6 -:100D70002D62E3FF5B7435BAB47435BBB5744D2E88 -:100D8000D6D2D5EAD1D23575BA96AE76AF96AE69DF -:100D9000355ABAA6FBB474CD5CA4A56B965F4BD74D -:100DA00031F55ABAE6B668E99ADFAAA55F4160B59F -:100DB000965E09F456E5E5B8AEB59A7651BAFBEA07 -:100DC000291F667CCFFD9A7155BA07E07F9CEE2DF6 -:100DD00094AFFEB7D29DB120F95F13E97E3681DE74 -:100DE000A0AF3E42B90076C6397C2E9A20EC79DF5E -:100DF000C876862A7FE2F57AFCBE7534B9344C8F0A -:100E0000897DECA87A2C611FFB3E66F1907DB49938 -:100E1000FC3CB709FEBC8CAF66A01FF507A49FDFA2 -:100E20000740A6035CEF23DCF09DF79326939FE138 -:100E30000E16D2D3BDBF98890883DE8989C932DEF8 -:100E4000E7E3A6E732A1BF970B3F8437D99F92C350 -:100E5000FD0FF919F8DD9C217EFFF25B695FE89ECA -:100E60008293E887079D721AFDF0F0BC60E6FC7083 -:100E700046950F5EE676C6E16DE96C89F4323A7C00 -:100E8000703FBBF4AB12C51996FE9E3FC7E770BB1F -:100E900037F1D9D1AAE28DEF876EC87193FECD618B -:100EA000FDC27E637ECB381A87FBCD9FE4F78F3E71 -:100EB0002B3165BA838E49111D334D1CAE67F5CCBD -:100EC00084F87B86F9DD8897EF28209A789EFE24A7 -:100ED000E487A5BF7F672CFAB164D97513DE2F3D77 -:100EE0001DBF0770CCF95A8B847EDD4C578B847EF6 -:100EF000A361EF0FDD2FE1F9C26899F176F88778E9 -:100F000050FD73C53A1EA78EDCCDF7174F7D9D911E -:100F1000DFA9A3355019C0F8940C0607E6B1E8F92B -:100F200079E41B72B8DF2D8B0DD1BDA6EC356117AE -:100F30008AFBE04B44DEFB0511E759B1C7C4304FD3 -:100F4000A2E4E05107C67556002D87509F297EBA4E -:100F50005FA364C7AB0E7ECFB8DE8EE7D8543D3AB0 -:100F60003ABD1576262E7F1CE8D832921E5F93CBB1 -:100F7000E3B31D6D35B3302EA3C2F3609B7716F239 -:100F800087AC7818C693F0DE9DF8FC338313EAE350 -:100F9000D6AF62A9D194F5161F5D66B1A1AD85F8F3 -:100FA0004C2FEE07DA98B3D616FFBB01AB7374E291 -:100FB0001EF200433B9B8B7A7C2A67503EFC91F1EA -:100FC0007DA8D105E3C4CBB57BF358BC5FB9ABCDED -:100FD00047F06E90FC7E1CC458C842E614CC5BC03F -:100FE000B397F07EC7F56F601E8DC1BAD613728FAE -:100FF0008E37A34BB9122F971EC801B9941C934B7F -:10100000DF6D3B4B78EA685B44DF037C318C9F05E6 -:10101000B2B87DDAD1B684DEEBC0CE427E7A65C747 -:1010200084A36EA83F01FFF09E1CA393C3C5CAF31F -:10103000483F2D167C803EAB5CE09F13AD7AE2B357 -:101040007B722D415C84F7BC3DFE28DEF369005EB7 -:1010500092FF06B8A3DF11783208B904FCE4C3F5A7 -:1010600066C856C8FFEBB02D203AFD77C753F16B29 -:101070003033BA87C6906B21BFCD1785F37B390912 -:101080007ABE3C8FE4E83D022FAFECE0794727EED3 -:101090006564BFDE731FF7BFDDD3C828FF9BB5C2F1 -:1010A0005F458C6F54799D8E3781C0CB9E3610344E -:1010B000458C3DDC66C293572C19FD64E36274ECE9 -:1010C000F12A7674C76FAD76D6E1F3E1E9A77B50DC -:1010D000AC6C99F5BB217CA28F1BBF6F6B6141B4D7 -:1010E0003329160BDFB7D74319BE9F22EA53FCBC46 -:1010F0009C2AEA5317F172AEF739A91A014B88837B -:10110000E45A1CF30A51EEDDC5F8B95B71EE7EB707 -:1011100090BB632C8EBA6AACFF1AA37C7CB5FE71BF -:10112000519F6539D9350EE5F2426DFF1D020F99C9 -:1011300096933DB3295EA2AD57E31BE9964B6F50E2 -:10114000FF126DFDA3A2BFD572696836D6176ABFBC -:10115000FF90A84FB67079C87CFCFE54B5FE3BA248 -:10116000DE8CF5F87D8FB6BE5B7CBF430A127DE84E -:101170008E585C3FE9DC5FDAD7C6AEC5F5D3D3162F -:10118000A175F470DBA7442709992C3DB6AE6CAD70 -:101190006CC4F3E092906729EEB0D73B82BC53EB6E -:1011A0001D367EDE5D7619888F8C16212FC43A8C11 -:1011B000CA0BA9C5C3998BFBB13F8F9F61815D416C -:1011C000FB220FFE909F73EED5317F9CDCCA6E48E8 -:1011D00062FEB8F6AEBB1C9A72C6D7B235ED9D0B57 -:1011E000C76AEA2DE59334F5CC9B4BEB65ADE0ABDC -:1011F000A492324DBD7A0E9FF5E46AEC677DE14C16 -:101200004DBB4BC56EFAFD9033F3D4DF19F1985006 -:101210002EACB58ECD44BDF34CDB7434B2D9B3B033 -:101220009EF0E8D4013BCF2F3E807159B4D7DBBC90 -:10123000F47E1FD483E5C29E84F5E686F67BDA6CE5 -:10124000547EA2CD45CFDD6D6E7A3EDE564CF53B29 -:10125000DA3C547E0CC6C7E7A3300EBE7FA4AD8631 -:10126000CA5BDB7C54DED2B688CA0FB5F9E9F99DBA -:10127000B67A7ADFDDD642E58D6DADF47CB02D40D7 -:10128000CF8EB62EAABF46D0FB8038C778A0929FDB -:101290004B4EA4E3AC5C49732F9835963F302B1727 -:1012A000F307FAC39AFBDD71DE349E99CF3F71BC20 -:1012B0003A1C0FBE3B890DB527F3754C71C7F1037E -:1012C0009EF5C9C0EF635A381D0A0622549F55CFB8 -:1012D000695127E065CE00CBA9E0C750B1DD0569B3 -:1012E000A82A99C76129BF8CB9609E15E27E1C624D -:1012F000BBA00EE152A673BDA9D2353A6F3B87134E -:10130000E73F12BC5F13F397CBFBF9FD17353D2187 -:1013100064FB246F0BDD7F615AE40BE1EF57387DEE -:101320007E3A8F3FE9D3B9B0B90139F3E997991BF8 -:101330009E390DDA7D4FF65D659AFD85FCE9C3CCDB -:101340007D358C5BA2DD9F2415AED5F433E5DCAF93 -:10135000A93738D76BEA97AE29D8E0427C8E611462 -:101360009F316E6E6718525CDEBB95E0DA24F07E2A -:101370004172D379DEC041353ECFEDF3EF09BDC2F6 -:101380004C9B693D4CB0F362516A40877AE1DC8F37 -:1013900052491E3DFD842E88FED7892CA8C3F53FF7 -:1013A00019CC3DAC9F8237E8CA74A58A8CE552E619 -:1013B00096B17C358BD0FE04ECF3F5B9DC3E7FC2F0 -:1013C0008CF1C15CFFF778DE5288F46691A06791DA -:1013D000BA1FD9AE24FA65BB72890FB5E7993A8571 -:1013E0009DDE6EAFC8C4B8E88551F2CAACAE993381 -:1013F000F177B4AC59D3E9A9BE7FC8AD1BF19CEE1F -:10140000E3025F2ADF4F0426177CFF38CEE37CF926 -:10141000BB19B8DD6B2A8C10FF5F90BCAE2588D756 -:101420003765CE878359342F45E0553958E95A023C -:10143000F853DE1EE709B0D8779E6EF3CE54945869 -:10144000B948E445EE6FAB9B591DF7FE75014F316E -:101450001BAA41FD545CA2F304696497467E990B74 -:101460007BBC78CE5C29631E146F1359CF7AD4D518 -:10147000CA5F64CA73518ECD606ED817582C21860E -:101480007941AF47E7C934BFAFF43B5B752ADD173D -:10149000981D957BA813F1F79486907F7ED7ABE7D4 -:1014A000F33AA6AD2FB6F0FC9D15C586A05BC2B081 -:1014B0007A0FDD8BA7F4490C4D7FE52FB3090FECB4 -:1014C0008564E2BFE4ED53E94AED9B14FF0F91BE42 -:1014D000E743EE1774E3042F42BBC6C986BD688F8D -:1014E0004D40BCE0840A8B09AFCBC57CF7B72D21FA -:1014F0003CFD5ACCA33337011EE6F1E2BD912B7AB5 -:1015000055FF87769E0F9557DD8CF7EC750CC9C299 -:1015100056D2E273937E682AFE36DDF930C0251379 -:101520009CBF46FACBDB2BE8F7954081D0FC1A9F95 -:1015300080FD7E01C9A31AD2DBD374949F9AC85749 -:10154000A7841C6BC9E5797F56D79767E2EFBCC5C6 -:10155000CAB3883F9FD1B162CA2FD1F1FDA59ABF0E -:101560000186831BF775A579BAE83D1AF3515FDB55 -:101570007594F727EF49A2F389B25DA13CE34E4B86 -:10158000B56D358E635328AE32579E358476B3D110 -:10159000AEBB1AEDEEE37BEF1FC2FC12395761E8D8 -:1015A0002FEAB429DCEEC8D1513E9662AF36611CF9 -:1015B000A6C872BA12F17974CF37C9BF217F43E44C -:1015C00088087F925E90AC93B5D0F8811C45DCE72B -:1015D000E1AD2DCD10210437EE7F6A3E423FCA7146 -:1015E000DB2533DA2B6ECB0AF2A715E615D07CF497 -:1015F000186F83F213EB2ED9516EBDB96783A30028 -:10160000EDE7A0423648F19F3BB2E9DCF91E039DAD -:101610008B57F19A1F503471BBDC566DD99810BFAF -:10162000D3279C4BCACA2B107A6E110BC5CD47EF3E -:10163000E2FB35E6B4D07EA7304F629FE962E53128 -:10164000A2BC5F1FC8F6007E8EED59918FF3BA726F -:10165000D84F79BEA3D9FB1FE7BAD5DF4332EBE8F9 -:101660007ED59019F37E9F6A63E968DF99820AE567 -:101670005DEF13F2ACD0C2F9DF90CFF93CF159D84D -:10168000C3D79D722029988C74B3F59705804F2697 -:10169000BF328FB941FF15DABCE43F2C6C35A4632F -:1016A000FEC0DC1F5A884F2E5992C84FA8B4267925 -:1016B000F07DC7DE8A62771CDCC1365B3AE6E5EC7A -:1016C0006D33A5A39C0A8E225FC7D97594AFECD663 -:1016D000F17CBAF9791CAEF979FCBE9779A2FCA429 -:1016E000125880703E09F4C43CE9A39BB93DBCB6D6 -:1016F000DD4470AC7D731CD955A3E1EDE936573A52 -:10170000DE0FBF77B32E1BFD4795DD859BF09E84D2 -:10171000B5567E4FAC9C3AE9314C45673FD533B462 -:10172000DF3B52667A96C5C97739755631F2952CEA -:1017300007B2D12F7267DEFC9B315F12E8B713CB83 -:101740002BFB4A79D91AC8C6FCCAE6BE69BC9C1EE6 -:10175000D889F995DFEA9BC1CBB9816CFC1DA9B68C -:10176000BE6B79797C60279637F655F232FA9E4047 -:10177000766EE99B7333CAD90E83A71E05F20F005C -:10178000FE1280BF5F3CB70ABCA8F5CFE17BC0F377 -:1017900021F14CAC7F41F41B18A5FE25513F38CAFE -:1017A000F82F8B7EA151FA1F13FD8E8FD2FF35D1FA -:1017B000EF8D51EA7F22EADF1A65FC9F897E43A301 -:1017C000F47F57F4FBC528FD7F29FABD374AFD0792 -:1017D000A2FED709E39F10EDC3E2FD58EBE60F42EE -:1017E000C07763418EA05C2AB66E76E03ADFDB55A7 -:1017F0004EFCDF51C1E33B2ABF8FC5DF6F827A5DAC -:101800003EBF4F4A97CFE33CCF88F1810FB720DF2F -:10181000AD7D5BA63C9B0E9DE76C10E5E8261DD9CF -:10182000036BDFE4FBF3B5DD4A30FEFCC53309F0A2 -:101830006F10F0750A789FCCE3F139A3CB955E1B4E -:10184000EF47B269CB9896857217E437E5ED1677C6 -:1018500057751597638C4C471688D2680AE17D0D41 -:101860008A55E8055B794F31C26751E89CBA6257E7 -:1018700042FBB1BFAB9CEC3B15BE4E8B42F775C92A -:1018800056AE07E6FE70960DEDAC4EE61FF2627F97 -:101890009742F6FBD1AE321BCA3D83F52E1BAEDF5D -:1018A00076379F5775537112CA6BF9211DC9EFE343 -:1018B00036BEDEFB5C3AF25B805EA1F32C20AF3DCE -:1018C000A82326B0503B9D8F78F88525DCAFC7ACA8 -:1018D000A515745E448D434B4A9CFD7F59E0275FFC -:1018E000E81105F50B3C9F2C17E71C02DCFF046494 -:1018F000738D893BAF79394FE6E740D438A25C4B12 -:10190000F716E5AD5334FEF79C7BB5654382DE5098 -:1019100012F4CAB82E9093717AA72060D3944FE640 -:1019200009BF8E8779D07E9DFBC3CD240F2FA17E6A -:101930009346977B51F92BE4F193E21E9E2703FC1B -:101940001CF1D1CD653F417AAFEDD6D1BDD35F5407 -:101950008E3E93C7B87FDA0F7A07ED198565E37E6F -:10196000E9F3F0305EEF73D0BD0A9F838FF18F965D -:101970003B50DE8EF72BA47786E98DCFC1D7B3928B -:10198000E73D3FD2D19EC4ED6A1B9F77678693DF08 -:101990004724CE1FCAC25E7B50F8C195D4B96EFCF5 -:1019A00089904E7B0B9537489ECC1BA0FD46C96F96 -:1019B000C3F21B8E24AE777293880FF7A32D43F7E3 -:1019C0001C16F8D03FD21F34A8F71486F0FF0E6221 -:1019D0007E8E7A0FA28BEC33710F63EFCDD5D85E7C -:1019E000B14D469373DA138F6DD1830D7AD0C0A2B7 -:1019F000EDF13CD533C775E29EC4DD5BD05E3D980A -:101A0000C434F7401E443F3A8D17DC82F73EC2F7DC -:101A10006E90610F767DFEF7B658B262F054B90F42 -:101A20006C69A73C59BE2FB1337E4FF779773805E3 -:101A3000970BEC4FAECAC77DF99ED3199ADF5D13A1 -:101A4000ED5345FBA6C148D30137B59F960FEBA0D8 -:101A50007120925242EB2B5211DF3E45ECF7E3DA54 -:101A60007F89C61FA57DB10ACF81776F2DE1ED2B50 -:101A700071FC0BEE7006E5BC24C093367CFCEBFFDA -:101A80001A3C9344FBF3A177A9FD0516CE9852406A -:101A9000FD6EC27E17DF7AB742CC3B03ED64908ABD -:101AA00037E37B34B7F8EFB1B490FDDC6FEAB1A156 -:101AB000BD66D6F7F850EE16E2BD4ED363CF05F9FA -:101AC00085DCAE4A78DF6F6269B5C88FAD3ADABFA0 -:101AD000F49B86CA4AD09E7ED102320FF5C23A0FDD -:101AE000CAC181F05A4F09B4EBCB9945FB8A838672 -:101AF000967E3ADFBBC442E74FFB6C3D365C3F66E7 -:101B00007B8F0DE308F27DDC7E52965AFC4F213F1D -:101B100085D6162F8F5BBF556E3DC1DFFDAA65339D -:101B2000EE03BAF59E9E0968675B15CA3F57960E8D -:101B3000CEA7F3823FD03192EF30AF2A287736EA32 -:101B4000E8BEFA87DD4BEF413C30C5E7AB827E79DA -:101B5000E98A84E72F1E547C268C5F1885DDD6E742 -:101B6000E1BFF7AA7E7787B02F77E4F37BABBA9714 -:101B70001C287E0DFAF5B5AEEDC7EF99279A18E649 -:101B800099F5E59CE9C6F3A28FBB60C70B78B0342A -:101B9000E8E8F75A1EAF8536A9E8CF3068FC15CFC4 -:101BA0004AFDD43ED0A8A37D82A5C4A0F16FA43580 -:101BB000E8BCE8773CE0F66F427EBBFA6DE506FCD8 -:101BC0009E6BBC6243FDF490EB17261DC09952AE8C -:101BD0001DD7364B3B8EA35A5BEFACD5D6672CD4C2 -:101BE000D6BBBE6648F0D768CB29C8478847900166 -:101BF00016D04349BC8A2559AED0EF8575FB77F5E1 -:101C00004C8036C6E440E96B006FD2A424DAEF6F53 -:101C10007C3509171FC81F467267E3144679AFC7A2 -:101C200072BFE9427D9A889FBE1C03CDD75208F847 -:101C30002CC0FDFA59FA5D2F0B8B6B5780F8F13EE3 -:101C400093CFF7EFCC5581FE394672F059D57F7CA2 -:101C50000B3F4FD5D7CAFDD20F2DE2798134830ACD -:101C60005CDFBC7D0AFECED854F4DB77DD8DF98EC7 -:101C70008978CDC4FC3239C61F1BD4F32B787AB2D5 -:101C8000828B655C7797DCFCFECD9705DF1C14F733 -:101C90002D44DB23FE3218DFCAC2786FE6ABFE07A5 -:101CA0007E1E609B1A8F1165BCC610CB078F3B6EE2 -:101CB000C0F5B46DA1A30CD7D3466197A5E618BCB7 -:101CC0001301DE47DE3004A4ABA0ACB0E37AD0E76A -:101CD000071DFCBB86379302789EEA1157399DCFCA -:101CE000FA389FFBF39EABF4FCBC96D6A342E7DF29 -:101CF0001E717ACC65DCDEC0BBAE19A51681697198 -:101D0000B4B68CF6A98F783D665CAF8FE478CC983A -:101D10009F6CCE526CB88E1D2E85EED17AC4E4B77E -:101D2000A1DDE2000588BF1F67C8ED9947E7920073 -:101D300087BA0A1E1260228F0FF3E8D204BEFA5C43 -:101D400077D9F0FCBAB3F0D0B7D0AF9E86E3A5F058 -:101D50007E8827BBC0D3A57C37CF4B16E3A7DDF524 -:101D60001CB5C7BFCE8AB8F13C9CBF0CF358907E1F -:101D7000074D7C5F1D273A3EF392DF7EC34F38DE6E -:101D8000DA73F9FD4186358CF661CF55FAF71F45B8 -:101D9000FC6425D13E3BDB955D85FC91FDC6CE05FF -:101DA000780E61C34FB8FE342CE7F1A66C8599BE5E -:101DB0008CF34EF7DB108F89EB30EB784F1D32DB65 -:101DC000FF054658D4C60080000000001F8B0800A5 -:101DD00000000000000BD57D0B7C94C5D5F73C7B43 -:101DE000CB26D9249B0B212124ECE646201736E193 -:101DF0002222EA7209A222DDC81D233E210102240B -:101E00001040FB46CB6B161214156BA8A86851370F -:101E10000A142B6AA88058D177B968A95A4DABBE6D -:101E2000A55A692254416E31B4EF4B5B3FFBCDFFA5 -:101E3000CC4CB2CF9228EDFBF6F7FBBEF86B87795E -:101E4000E676E69C3367CE9C7366765702BBCDE799 -:101E5000602C61A28DB9EC8CFEFECEFF976A61EB1F -:101E6000CD098C254DE1DFF342BEA7248DCF2D6235 -:101E70002C79BAB17E0A0BC9BB79BD239D77B058C6 -:101E8000C6065419EB3D197DAC9899900BF96EFE7E -:101E9000EE7C93D67EDFE0118CF9532D9E6D2EC61D -:101EA000D2C3C663EC9B08E4356672FD3D8BB1F18D -:101EB000AE78C6FAE17B9DCB57C8D82E9B738223A0 -:101EC00089B1CE15CCF30C6F3FFE950D73DFE1F9B0 -:101ED000FF4A77382378ADB423CD6D05FC3BDBA7F3 -:101EE0000F46FD2D16FDE9685EBEE5687FE6D71852 -:101EF0008B886675AD1C4F3613D391FE1D7FD7625C -:101F00001C2B8D33DEC527359231DE45C094F2CFD0 -:101F1000A7AD0307E63B3DE8CFDD66E7FDB65A9C7B -:101F2000F9169E1FF9F4630F59D3310F0EE3189A77 -:101F3000B6978D66ECF9C37CDC013CE77FF2A189A2 -:101F4000165E1ED55DEE47F92E9349E4FD81872686 -:101F50008E656CE0E1D6350E2763654FEF78C8CE0D -:101F6000F116F92B51EEE379BF0578A919D4CEE724 -:101F700077306309CDBFF177112C82D72B347B36B4 -:101F800023CF3E8964DB787EC79EB1B35DBC5E63C0 -:101F9000CC28975EC0D8349746F32F43DAEFD27936 -:101FA000996D1EDDE3B8F4FB8D126F8C798EB670DF -:101FB000FA163E6B63F7F3C23CC00D7AB544069E39 -:101FC000017D9B1FE34CC7589553D0BC6AEFFD19A8 -:101FD0000778FA6A4C59A58BB7AF8A99980C78D2D2 -:101FE0002E32A62772BA35D899CE719596F4338DD4 -:101FF00071F806261D1EC71CE09BB6354EA4755110 -:102000004C0FE1CBB48B16A60F477F5EEA0F7FF62D -:102010006470A1F86B4AD0D91A0E8F9FE37A1BB86F -:10202000D319D5A11581F1277ADBD5FAC8049FB25F -:10203000D9AD05E03A81071BC7A9B584A70E4B307F -:10204000A297FA77C87A66BB23681EC653E75B4738 -:10205000A95F87E54CBBBDA79E3D60217CB01A16E9 -:10206000C8D1084FFE08E4E31228CFBC5E575232B5 -:10207000F89F1172D32CEC70041F97B897AF9F5440 -:1020800016A4F4498E1E47162AA5C77F1ECDF089D7 -:10209000818F9F616C72285FABD434C844F065D7E0 -:1020A0009BFA9DE0F8C93F14497058D6B340241FED -:1020B0002C1BF4E074CBDEC0021637EAD9FA9D4837 -:1020C000443B97E403A789D178AD43B1AE36BFE571 -:1020D000D8C0E288BE24773647B16AE04B8DC7D8B6 -:1020E0001AE28780E48B2D0D4EA2A32A1F5873306D -:1020F0008C8E09063AAA7A691707103D7BFA0D50B3 -:102100007F69F5BB891FD22E66483E717D47FF99D6 -:102110007DF49F42EDFBEE7F208DFF64F0C3F8A9B4 -:102120001C153FEEDC1DEFE369A4B5D9E7E905CF47 -:1021300069B71BE5E4B07D46B9ABF01269F52695A9 -:1021400071FC47DE61F2B4F0FEAE386AAC37D9FDFF -:10215000513CD6634FFD60D234D4AF15F5AF3A6928 -:10216000ACEF1BB727ACBE80EFDA8BC67AE1F4097F -:102170008797C3D56F46085C13EC1186F6B32B2EF8 -:1021800081ABDFAC10B8AE4B31D6D7D7F40ED78DBC -:102190007911DF0A97AAF7BDD197572F7C1ED32656 -:1021A00047F48177517FD6ECCBEBF796EA6FAF77A8 -:1021B0005B7DF8387EB95FF1B5C5D77122FEC19756 -:1021C0004062BDC91BC9F75127EB6458475D725D7A -:1021D000253027AD67BEF035ACAB0FF0CF54C686C7 -:1021E000B87D5F437E4DB07BCB1FE15527CAFD8A8A -:1021F0004DE13D5E89CE7D8537175ECA7F8CAD256A -:10220000B85ED3749DD13E6BF76CE3EB3B3F8DD949 -:1022100053B91EC052029937C73016ED56F29A8B49 -:102220001A0EE75089BB1706B4AE8CA7751E48007E -:102230003CFFE8B8FDDDDE0477BF9EFAE1F57AEAFF -:102240000B3CD96CAD2B006767ADC383FDE1431434 -:10225000F176CFCE8C089A39BECE5B1DEB352E675A -:102260008E46CF7BAB1FC7C307B1BA0BFDCF9E75A0 -:10227000FD3DC86B07135D2B397CE72BDA4701AFB7 -:10228000DE683DDBCDE1A8B1EB8392F914CFA6EB7C -:1022900083E3805F5F22E195FFA3D0D72BFC029EF2 -:1022A000899AC07F629C5E8871269ADA9EF2E19BD1 -:1022B000A56D14DA31673F82EFAC8DCBBB5ED6BF24 -:1022C000C2C378D9CF01ABE7EB4E3EBF031BE33C63 -:1022D0008D1CDEAAC459F396F3A205265F72D06C5A -:1022E00080FB2A8C57E3A818940AB8AD126E7B3F86 -:1022F00089776FF6B7C1DD88F1B0AFFDBB16D8E6C0 -:1023000016B444FE157F7CE07E9E8F305DF810F29F -:10231000A3B3D0E4E17B04DBC2F50B3BDF57DE97D0 -:10232000F87E92AB3FF604FABE1EDF53A244FB9444 -:10233000474D8146DEDE37FE55A2D3B3CB1C1E339C -:102340001FAB82B96CE0DB4AE6B501FE3F8EFBDBDA -:10235000EBED7C7E73DCFA74CCE3B64453C68704A1 -:10236000879E5FC6F98D8D15F8FF2E7E606C838980 -:102370008D62EC66A91F2C90789CC6BC568C33836A -:10238000E9568CFB9B73362FF4D2DF4007E5F0CE85 -:10239000627EFA3E870528BD8505A9FEADAC9DF29B -:1023A000BF8E2E4AAFE7F0953D363807EB3104EF8C -:1023B0004B24BFDC9624F8E58BFEC0FBA67E97C5B8 -:1023C000BF659AC0DF10B7BECA4DEBD595E4014C8E -:1023D000CE09037D3121EB67623FC17F1667CEB71F -:1023E000AD9FB6AED822368CE4812395E3E13A491D -:1023F000CAEBBC4BA760BE902058AFDF93EBB5D4BF -:10240000EC60499C2E6D2E732082C33279DC8A14D5 -:10241000CCF7176BD8AF8673FAFD629C9935524D95 -:102420002FB59B2AFB9B3A70D229E827EFB260D2E6 -:1024300008DEAEF4A27E388EE367AA796713D7B8B8 -:10244000D9E481D6CFDA43E4DAF549BB2C8CEB2F03 -:1024500037641BBF4F29E0F910B93B95597ACA3947 -:10246000FD0F003F903BACD90CFE7DCC1D93047D4D -:10247000850D6543C5F9805323643E5DF66F6CE7B7 -:1024800079BBB7DDFA53E0A395F1E7E691DE611180 -:10249000F359F69E99F4CACF1A18388F9DE0FAA125 -:1024A0003797B1CFB97E81FCC986144ABFE4FA00E0 -:1024B000D2330D79547EAEC143F9AFDCBE9F804E5E -:1024C000F3D77F65C1BE746FA4C2B7806395E4BBC8 -:1024D0007BD3473DF6578ED77BDFE50B83C353DDB8 -:1024E000DA3C0960AF4AFF6C2DF4E755CF691ED482 -:1024F0005BBADF6B737078161CD6EF019917BDDBE2 -:102500003E1562A216FA2BD71BEEB3FAF660BC9109 -:102510001F9D48D67905EFFE8EB71279FD2F1A461A -:10252000135CA71ABC04D7E986C9944665FA5E43D2 -:102530007D2FFBCA86FA37EDECB0A4F1FAA55ECD8B -:102540008BF5788D9705021C9ECD5621DF3773F9E8 -:102550008EF539AEF0E6276F6790BFFA9B683F2390 -:10256000A1B234917F9F3ABAC2827AB3BEE632CD2D -:10257000DDC387DFBD0E053E6A255DCEBEA1119E7F -:10258000CEEECDFFDE55BCBF378E989999C3D57579 -:10259000D14470751D8D0A406955F556EE31933E54 -:1025A000B932DD1600FE56EEC9EF0F7DEA34A71BE7 -:1025B000CBED19EFF40BFFE6D243E4E8E984D6FF54 -:1025C000FA1872EA5321A7B8BEF9F913906303070A -:1025D0007840F77356AE9703D1AC2E1AFBD8329BD6 -:1025E0005C5F5CCE207F3A4A9C8347BD98361EEBE9 -:1025F00005E3B96C3D7228F7C5C7327FE0EA196F71 -:1026000047EB828F9FE0F9B30193DFCAF799B3AC30 -:10261000F5DCCF2147B73A3C381FDCAB7178B08F7F -:102620006E1B40F93CCD12554FFC1CA0F59AA7B982 -:102630002CF55CFED4FCECF101E0A7D7380E46F394 -:10264000F2D73646937C7ACDEA39568FFE9E14FD3A -:10265000FDE487777EB60FE983B5257702C999092E -:1026600084EFAA1F2D1E8AF67C9F66A9BCBFE75F78 -:10267000D182917C7D166E3AB03695C3376C4B870C -:1026800069004F8BB76A8D48F3D36F3862E6E5F681 -:102690004C17C1317CA7DB9C86653520F0F1B5B4C1 -:1026A0007F1BF7F5824D5F8DC7F152EDEF43B5D635 -:1026B0002F5B701ECE385AA213FE9AA99F3DFBA72E -:1026C0007D700BC33CB8E600B82B6C1EDA4F02FEDF -:1026D00016D0F9AC9EE7B91F6BDAE77F1CF43DAB6F -:1026E000277BB0BFEC35F963C7A0FE310BCDF39566 -:1026F000ADBF8EB5F27CDC6E2B8BE4E5B5C59D934A -:1027000050BF36DD45E7F0F4A7AE9B0CFC2CDBBDDB -:10271000A785FAA9B17B34ACB33D17DE4AC379E88B -:102720007AE6C901DFED16F907267A3DE0B7EA96A9 -:102730003F8B7C9B8FF23EB3DF6D41FD4AA1E73CAE -:1027400026F731D65E44F28E58D9D543AF0778319B -:10275000CA37BBFDA9758E9EFD8FEF5BF999BC3C16 -:10276000D526DB3BA765F8FE817DCB26F721D5DF9B -:102770006336E68FE4FDA4F3EF1AF6559BD86FB7E6 -:1027800071F9027E51FB2D1FF7AA4CD1DE0B39994E -:10279000C637D7623E9FB4C72202B4A75FE6F84AA5 -:1027A0004F5A1E25E499D23F662736BEDECEF1FA97 -:1027B000A758FD3ACC6F81DCAF99C59382F91D8F84 -:1027C000F54EC6F835F6CE0CCC81EF8753905F6698 -:1027D000E6FA535688FE64BFBCFD3022CE7B33DA66 -:1027E0005F6EFDB151BDCBDFB15DA349FEBE2EE5ED -:1027F000EFAA3F9B5831CFAF7A2482E409ED69BD3F -:10280000E0E575BEDE752E5FFE0376039E5EFDA7D6 -:1028100076339D3F0E9B6ADEE2FB290D9D89FFEB1F -:102820006C8C1B41792FC87CCD9F4CBD9E0F55CA27 -:10283000E954877979BF36DA1BAEFDDA69A3FE1D4C -:102840000997355F731FF335C78AF9EEC77C39EDF9 -:10285000567D5542F272FF65CE333DC2BB06F40D84 -:102860009F0787FB5E7C0F87BB9BBF3B2F0FEE3B19 -:1028700034E637619D7D650B609DEDE76062DDEEBE -:102880005F5C10C07ADE6B13797FAC8DF4CFFD31C5 -:10289000CC0FF9B1BF2C39E077430E32A19FF6631C -:1028A000A23C52B69F934CED074470FEE779764BFD -:1028B00094ECBFEE9D4294AF49F37008B87E1B586C -:1028C0009F49FAAD99EC8647A5BCDE141FBCC5CC68 -:1028D000BF6FFA2A97619CA32C98B61CF5AAA3484F -:1028E0000E6D8AF7A626703CEEFDC64CFBC2A662B2 -:1028F0009E77909C26FBCEA6326F6A3CCFCF957414 -:10290000D9D412D8F628FA2BCBF3F8F93803CCAC8B -:102910008EEAB9453F1F5B45BBDF49BAF0754CEB0A -:10292000FC83CCF941E0599F1A6D815D84633C556D -:10293000E3F03F5195C3485E4ABBD76C4983B93D2C -:102940007CE0B58F825E2BFEE62CD81609793CA37D -:102950003A92EC5247ABD7C6B8F87833747330026A -:10296000FADFF45283DDE9834C2F8DCB0F16F29CF6 -:1029700010AC041EDFE8B433C8E5BEE859DB3A2EDC -:10298000F144083F54DB84FC3829F5A15763F4F780 -:10299000C0EFCBF75D9F782244DFAB5A509A4B765D -:1029A000DFAACB3BDF35824EC368BDFA4DE08FD640 -:1029B00048A2FFE49BED44EF2E87E919D8256F93D9 -:1029C000F2AA110761FEBD714F44602DFFB63C2293 -:1029D0003813F28AD3FFB9EDA0EBEB9144FF1A9BB9 -:1029E000E0A79A9FE7137FEDB579DDEBD0FF1B11D0 -:1029F00044F79A58571C95BF9DC824FF91DE501389 -:102A000015CC8DE7F85C1FAD9F02DE38DF913DB835 -:102A1000C626BE1F937C758CF70138FC7531C48FB8 -:102A20004CE6F51F24D2798AEBA3C4BFFA43F9948C -:102A3000D76DDED405581F2BA309BE63D29E76AC9A -:102A4000269EF8BBFCA1A5EF324ECF63BEEDF7E5A5 -:102A5000F27AC7F65B3DD8977E5F6F0EDA385DCFAE -:102A6000AD3E3E6A33CFB7AFFD24430FB1A395AF60 -:102A7000AD9D8276E54B564FC57ED917BECB6B22F6 -:102A8000B8CCEDA1535296D79CC5F1EFC9D26D5980 -:102A90007C9ECB0BDA1742EE9DB3B53D85F3C1C7E3 -:102AA000717A24BE9F7FF58BED240F2D9DB9D0CF79 -:102AB0009759381F802FE5FEB95CF2E54B597A1C17 -:102AC000EA73FC913E1E5DD026E4DEEACB93F35F11 -:102AD000EEDFB657E3E32C8DDABF8C5273A008FD0E -:102AE0009CD682B15A16F0C7F538DEDF196730166A -:102AF00074D0E5B969E90EE3BCF007BBCA52FC83A8 -:102B0000B75BDA6A26BB0ADFDF6D807F292CBD0642 -:102B10007F82902BBC9F67681D3A7E3FEF071CFFAA -:102B20004B9E1B52027D7269FCBE1F5E45F5783BD1 -:102B3000C5E7E64BF36A3E97C223E67746F2F919FA -:102B400026E5E06C5BF7391C7AD0B917FA1BF8E67A -:102B5000DC734328FFA5D6A94571B8CE4979C43C9A -:102B6000ADA3CA7080F0B68E823EFBA8FCBE34B125 -:102B70007514E48F9247CCDE5A44E7EABCD6229C17 -:102B800027953C63BED65CFA1E68CD45FBBD266129 -:102B9000A7A03FCCFBF9B416C2835DACC725CFE735 -:102BA000135ED438E1F40B9FEFD42CE11FE0F0DE8C -:102BB000E6E3F5076FB619CA87048CF999B2FEA04F -:102BC00030BA0C30771E8880BC7F96D17A0D1FF703 -:102BD000D62C614FFFE94FBBE96096E745E652F41A -:102BE00077097DDB0A7CFFAE1BDFB7A77179BA14CA -:102BF00073CCEC99FFDE623D0D72FF9C49D8A9F7BA -:102C0000C6F37C01F41C814F9557780CE7A3B5BF40 -:102C10005B98067FCAFAAC6E3F477FF05B23E425E2 -:102C200097178D56818F2F1BAA879FB0E03C5A972C -:102C30005A65E999CFC2CDC576AC97455B8AEDF36D -:102C400043CE3B8D3B861F7171BA9CD96121B34144 -:102C5000A325F043E8D18D3BCCAD7E46E5762FAF82 -:102C60007FC671F03DD45BB825BE047AAF6ABF68F9 -:102C7000F31DA95521F8CEDF61C47F61AB310F7B15 -:102C80007468FE47D00547FEE3ED8A83C6FCF02357 -:102C9000C6FC171FDE3E136CFCCA68C1EF27033168 -:102CA00001F8A9AA3F997404FBDAC9BDAFC4823EFA -:102CB0004B3FAD7A0BE796459B8D7CC6E9A641AFAD -:102CC000F76FD7883F1607C2D79D5CEF97ACC73523 -:102CD000CAAE9917CA27E1F43CCD5A677A393FD575 -:102CE000D4AF1C0E7F48F514CEB81C9E2B5B37DA90 -:102CF000E037081FAFAF75CF1C5E17EC5515A34525 -:102D0000D998FAF1EC388CBE1B7E3D09EBADE2019F -:102D10008DF6FF8A97071F86FCEED835E7064A67CF -:102D20004E263C28FBD9A2FD5A3086E79DA35DFBC9 -:102D3000DA79BB05018DF687F94D113D7288FFAF39 -:102D40006A43181C9B42CA39FC8BF61DF88BC6FBE4 -:102D5000AFDE626CB798E30B727FC9D6BF47847E43 -:102D600057E7BE31FB5BCC98F70205BFFF1A8679A7 -:102D7000091724171D525F39810C97F71109BE36C8 -:102D8000EC2F633689765C605560BEB50E9B0BF305 -:102D9000ADB5B3603487E3488CCDEBE4DF2F6C8EA8 -:102DA00021FBD4C208AE179650CA224BD0CE43FBAB -:102DB000F4E7EF9B495FA9C5D8E8E7698DCE3FB539 -:102DC000303622FFACC82F66419A07F8C51B3ABFC0 -:102DD0008031CF9AC5B9A9C6123C007C2C61EDE2C6 -:102DE000DCC3E9E80DF1C7D5F0791E4D803E646C77 -:102DF000BF9CB552FDE5FBFE1E11FA3DC44E4AE7ED -:102E00003975AE34DB9817FAB1F9EE28DAEFB9204C -:102E10008E027FAED3BC8FDBCD48C5BCFC1B85FECC -:102E200033B745EC175C3FCD057E366D1CE2819EC5 -:102E30003297EBD991D023164751BD4DF18CEC2B35 -:102E40009BE6E40A3DFB9B978318A7F3118DEC23C7 -:102E50009B8A45BF9B1E1C42E590871A8D13417AC1 -:102E6000CBA632559E4E7AD2C7002D157AAEFCDE27 -:102E7000CF45DF0798BDB9D0D7D9C39174DE577A53 -:102E8000EDB3097A6C76BF9EF92A3D98555F9EFE98 -:102E9000B74DEE779D1B85FFF784E67BCB14A29799 -:102EA0000ECA16FBC3A8F1DEEDB21EF901AA4C65ED -:102EB000F75FCBE1A97AD4E46A74F7E09D79BDB9F4 -:102EC00098FF898D9125E0B351E385BDE758B19016 -:102ED000DBD1239837C0D3BC6CB17FE4659B0C6910 -:102EE0004A14E73FDECF8952611F8E19E1233B1B55 -:102EF000D7D9487E87CF638484AFCAE67BFBEA5E7E -:102F0000E0E9E6838942CF38B1427B46C0C5E9CAD1 -:102F1000F3A37E1449F6B913725F51F8E77C33923C -:102F2000F66929AF364A3ED908FA633F5B2CCE4199 -:102F30003D7C62E483B99AC02B7B50E8A79BE245B5 -:102F40005EF1013FEFB0BF824F4A19E1BDAF738F11 -:102F50009AE7A61651CEE93D05F40E3FF7287A33DD -:102F60004B6024CE8D7DD17BFEE8F8519A89FCD64A -:102F70007EF8ADB1D7115EEEB304D67238065A04AE -:102F8000FED32D82BFB854F64795507DAF8DE72B09 -:102F90001E5EC4BCBC7E451A237B10AFCFE2509F9F -:102FA00077833816EC1568571127FAADE8CFE89CFF -:102FB000407F5C5E6523CDA47EBDA604D13EB68471 -:102FC000DAFB4DA2BDD7C2D34159429FEF5C171126 -:102FD0007806F2F9DEF45CF0C194F1463EF88F6CAD -:102FE000B1DFAB74688E4B1A953C2958DFF39B8692 -:102FF000D07ED118E9ABDD03BABD20F4FF8A7B6E29 -:10300000BD6924E07B31D103F0BE9CBA8BFC0DF38B -:103010009BE6DCF111CE0D3B22E9FB7539FA5DD957 -:1030200023A107BAE6EDE11FE6CF38644BE1EDF5E9 -:10303000D6B2B33FE7E954FFAEF7A00F4C9D6EA6A2 -:10304000FA5399B08FB22631CE4DFEAF2C29BCBFBA -:103050009BC66A1433D011E9CC58C1E1AF90F4BBE0 -:1030600047F26F63249BFD3307E04ACFCDE4DF6F67 -:103070008286D98BFFEAB0AA3F4EDB02BD66D00440 -:10308000B1BE547DF4837EDF96EB69A3C48BCA7313 -:10309000BC52FDAAF5111D59B148ADC1C13CEDCCE2 -:1030A0001DFF08F86A4A269BB41978BFD38C5805CF -:1030B0000E6F6705ADFB985C17F854672C48F1114B -:1030C0008121C4D71DE33A3BEEE5F98E96C11EB2CD -:1030D000F9C873F4029CAF5C2817724CC99763CE91 -:1030E000F618E25779AEAE94ACF1C7FA098F5EC11B -:1030F000EB573A6C1DD80F163C322D167126959B56 -:10310000CC229E6383F15CCDCFBF2F812EE1E7E41B -:10311000F0F33078067C54B541233E1CD4E8B1A5C9 -:10312000921CD39C985F9523980DF95EE589F4A0D5 -:10313000FC4C8337F14436FC119329655F73BC8FD7 -:10314000823D965110C7C11C7D3FF054D15C41E7D0 -:10315000C5E8029DE4D3DFB25D84E729B02742DEF3 -:1031600058DA53B10E6BD5F70467AE83F839920184 -:103170000F1D56672EE0EA581769C2BE3965ADE0EB -:103180006BBECEEC16DEFE3E0B8BC27ABF5FB62F57 -:103190005F63F1B5F0FC403BB3C42480AF8A89AFD4 -:1031A0004B06EB1B818793FFCE4663FFAFDCB091EC -:1031B000E0517CC12C6D1313A1DF6D7397DCCF7AC6 -:1031C000F8A864F0F80FD0AE9B1FA66BC4073C3D77 -:1031D0009045FC70F351944F191FCC5E59003F5637 -:1031E0000DF3C28F90C23CB00774B14ED227BAB86B -:1031F0003E0179A6E489921B9C0FBC88EB51F455E3 -:10320000F2637B030789E37547839DD29F36389924 -:1032100085CB809D0D29947FB1C145696B431E7D8F -:10322000FF598387F2BB1B46537E6F8397F2FB1ACD -:103230002653FAF3061F7DE7782139A4E48A9247E2 -:103240008A9F945C0AE7A3791CBDD794507B927B3C -:103250004ADE611EA6921E79A4E89BA9F9FC296E9C -:10326000C8B1F6399017A5E6332FBC023B49B5C368 -:1032700013E1025E84DCEB72D849CE67D8D83E9C5D -:10328000D71B57783BEE0DD9576FA9D69825844F99 -:103290006FAD8B6496103EBEAD3EDE902FAFFFE06B -:1032A000CDFEBC7F2D5E77E470388EDDFDF993BFD7 -:1032B000E5DF9FBEFBCB1CD09BC3B1ED318CBB3A8D -:1032C000AA1B8E04E49BACA43F0C8A12E720FC816D -:1032D0002EF399589F4FDFFD575ADF1DF5112E33FE -:1032E000AF37BF3E82F0F531E8C4F1FA7B49A78AD7 -:1032F00075C75F7805EB7CB58DE4DCFC26B92ED76D -:10330000737C86E86B9FA532D2CB342F63F0C37CED -:10331000F6EFB620DFF3D9679A3DA041F7E187A425 -:1033200072FE5D5FFF0B8ABFD2EA8F903EAC232E08 -:103330000B7602BFD5108FA5D5CB38ADF681863878 -:10334000AAE8115E1BE403781A749B9F7790615D75 -:10335000B366CD892DA04A7EAF5AAF91BED1AD2FB5 -:10336000E498898E75D9164ADFC31AA7FDA299F68B -:1033700027C5AF5C5E78035817CDC5B68521727836 -:10338000BEFC5E9967A2547DAFCBB6513FEF41388A -:10339000F07EEFCFCBB42D2039E7B2410EA8FAF37F -:1033A000F34AEEC91C817EC625B190F5E8CDB15037 -:1033B000FB3A047AE17C6417F6FF9A3EF601A59782 -:1033C0009CC43FAF24F8E9BCB5E4C5E75F847F6CDB -:1033D000C9271144A725C3A43DA220306A1AE933A6 -:1033E0005E87C6E7B94CD27FE2F39FC6B6F3F2E53B -:1033F000BB85FD92A71D4897ADAE26BBD6320F5FA9 -:103400001F0990AB463FF2E1173F896DA773853FD7 -:103410000DF1857C5B486329F0171D9F04BBF87292 -:10342000D6790FE2BAC2DB2DD7BE8E15F67DE12725 -:1034300057FECBD2D7FF9C4C70ECB9900CB9B6FCC0 -:10344000F575C97A2FF35E1EE6BF567E7365075B7E -:10345000CE367C05BF5B78BD9539D2AF7D05BB828A -:10346000EC141646710C2BED020F5D819C38D6CB07 -:1034700078DDE36EE6829D9F43BB2CAE380F87F369 -:103480007C1F717CAFE488FDF9ACF4A39EDF692654 -:10349000BDF0FCCE18E2FF653B1F7EEB2A9E5FB6B7 -:1034A00055C3B0AC96B5119E96ED36337BE8F90660 -:1034B000769BC4BEE15CFA7C4C1DF86971ABE6DD1D -:1034C0005600BFBC2BAE5FA8BE28F9696944EB2843 -:1034D000A28384FF7EA91FA97A8BF73F6C03BD7876 -:1034E000BD73A4B7BC140D5D9BFF75BE07384F6F4D -:1034F000194E7EDDC5ADBB96D1BEBF33DA89297EBC -:103500006935DAA30239623D057284BE715ADA7FE9 -:103510004FBF6826F90338B10EBFD4849D57B5DB81 -:103520002EDB6D9778BB2947AC47557F716B476C95 -:1035300036AFFFC5BE0F286D95F35AEC682BC27EDF -:10354000F9C5EEE8C9014A7F3CE9353EDED9D671BE -:10355000495AC8BA7A3D47C40D9FDD629E0C7CB1C2 -:10356000808A336AA5F99CDE99A6D1B916F8E6F8E7 -:1035700039BDFBE55813AD5BBF6827E968B20B7B2B -:10358000AADBE292F60BBB137AC65CAED5C57179A5 -:1035900057BB5BC403847F57F569BDA582DF3B6DD4 -:1035A00082FFA5FF5EFA97102742FEF8185B00FB2A -:1035B000EBBC61AE59B7409EBD6315F418E87A0CB8 -:1035C000E7AA79EF2792BD62A5D5D51FF93FBD6B5C -:1035D00025FBF9BCE1729DA7B48F847DB2C32DF6A3 -:1035E000F59AF57C85F0290FE0F4F7F3F9D5044C52 -:1035F000144F793C2793E07AA2DAE4B5919F23989F -:103600000B3BE5311BF39BA127FF2C92F4BB9A4C9B -:1036100061777F02FCCED39A84606E22EC5D928E3D -:103620003537F3F2107AD63C13CC85DE72C626EC21 -:10363000782877222D11F51A25DFA01FF4DBE1761B -:103640009E23FD724F0C839E6F7A2546D8137E12FF -:10365000497E07D5EF05C9578DD2CFE5DF26E003B8 -:103660005CD09B17DB9A73A157AA7117C736D37822 -:1036700067E4788BA39A85FF40C685A13E8D6F6570 -:103680005E9CC73B9F8B20FDF4CBD4B6BD18FFCB0F -:10369000E786901FBCC31D58B88FCAB9DEC6E9B013 -:1036A000E4A71141C07BEAB918F2739EB20A3DE863 -:1036B000544C32E94147621E9D87FEBAB64668B057 -:1036C000A79CD2982D05E5DBFA91BF6A49433DF9E5 -:1036D0000996F0E50E7F344F27C3AF7C6ADB10B24A -:1036E000B39CFAA599FC8BFCFB7A7CD759F3BCBB45 -:1036F000B0EE7644939DEDCB9FFE6D48A8FF41A5AB -:103700004BB61AED498AFEAA3C2957ACAFA45C819E -:10371000C7945CB1CFD446B73E9A49F314EB95D326 -:1037200081CE5B7C7D24C33E7DACF5D564CD013C70 -:1037300007737F0CBCEF10E79A2F775AC92FB2E4BA -:1037400095182FD96FEEBDC284FD628959E8BF4B31 -:1037500038BB8954D88796C4E6927D88E39BCE8F88 -:103760009DDBCC721C31EEA9EDE9C2FE1E94F9BDC1 -:103770008501F0F9940476DBCDA4DF6C29025E2F7D -:103780006C8D36812FF8385EF8ED97DCF50381CF2C -:10379000B885A48F33C4418F82BF5CC8CBDA7BAFBE -:1037A0008A433C0C7BDFCC20FA2E583CFD210FC312 -:1037B000F1B52857CACBBD4FDAE03FABE1EB05F1DD -:1037C000414BA5DF74E94F35D2E796DE73D563240C -:1037D00007DFB3B21C0EC799D6876343E95126FBB6 -:1037E000E969EFA1FA4B797DD1FE9D588267BBD57F -:1037F0000378C2E978D9ED7F6ABEACF6DDFCD1CAA8 -:10380000F7F5A24BE77D81B57DFF13C8919D911E11 -:103810003F7D6D25BFF3696BEB42CCFBF40B91242C -:103820005F4EC78BF5FE0597877E1BE0B8F121B28E -:103830006FFC661A83E85E1430F6ABC69D992BE4E4 -:103840006F6DA2270EFE8C5A4E07F4C7E9F23D6A4F -:10385000FFBE95DA87CF63A46CD7BD3E5F88267E16 -:10386000393D40D0E3F48B83695FE988177CCEE172 -:10387000CDC039E574BC487153067CB0449E434FBB -:103880008F6BA573F7696D17A51D56D16E49BDF4F1 -:10389000DB72BE4B01DF8027E1B7B26F68831E0188 -:1038A000FBF4A8124A83110997DA99C19FD8875E61 -:1038B000CC15F62CA83590EBE4DF20FDA4D50679D5 -:1038C000AC4B3DAE66E7A5FE32F283EED4C8EFF313 -:1038D000A05CA7803A49D9C7393F2EF56B5EC41B5F -:1038E0002D6D5AB118FCBEB46EE32DE077358FA56F -:1038F000163619E7AB0ECD4CF07444F275033C84D8 -:103900008E97D983DFCD0A5E809C4C7A2629D75BBF -:1039100072C57E857C33EFAFA649DB40E3B8D5792D -:1039200052CC4FE189A3C5063B193FE78BF23EE637 -:10393000AFE00C9FBF82A73557D8273ADCAE87C6C9 -:1039400082DEBF3293FDF4C2D7C3E312BE452FC35C -:1039500089ADDB5ECCE17F9DEFD5E8C70FF986F539 -:103960000C7B348733778BD1FF91B7D5981FBAD3AF -:10397000982FD86DCC17ED37E63D878DF96D725CC9 -:1039800085279C7311D786732E529C735DB9E29C78 -:103990008B3CCEB94871CEC5779C7391C7391779E6 -:1039A0009C7391C7391729CEB9F87E4ECAEF1A69B0 -:1039B00077041D28BEEAD548E507A7F5727E4E328A -:1039C000C94FE5CF3CBFB880F2DDF69C323BD973DE -:1039D000549CCE2D71FAD15CF21BB6DD930ABA5914 -:1039E000DAC98EBBFCE7C28E5B5312E9807DA17DF4 -:1039F000DD17F7407D2A8AD33FCDA5B8A6CEED22AC -:103A00005E294872A37D8DEBFD6B05FDC8CEA1E25A -:103A10006E2AB0DF25F44DC7703F0ADB60F49B844B -:103A2000FB51C2FD27E17CA0FC264F5B3B5321EFFD -:103A30008F3F67DF00F88F4BFB189BED24FD4BE9B0 -:103A4000D5DDFAD783DA33D8B7BFC94DA0F65D47C5 -:103A5000B8BEDDCB7EABD2CA8B25A43776E73768FC -:103A6000268A1B4989A57D6895842943EBECB81704 -:103A7000F22EC644FBF8058789CE05173E34931E07 -:103A80003118FA79C87C8604A20CFC95BF2321CC9E -:103A9000FF37C0507FD8BECC30FFDF50A35F6AFA3B -:103AA0009A03385F4FDB30DC50AFCA7755181E25BC -:103AB000DC522F6D5CBD3903F267554C17C1BF6AEC -:103AC0004F24C5D5567178BDF0CB21C351506DF749 -:103AD0004E05FEAA5BADF1D8E72BE5FEC3EA8DFBF0 -:103AE00071B585F99D093D7C57ED64DE78DEFE6C8D -:103AF00071F37613A7DB59D39647C7BAE0576AC963 -:103B00007072BEBA5D6B4DBE92F7F7378B5E309820 -:103B1000F35B8635F8C372C8CB5D596C0DAF777C0B -:103B2000C3CBB1A4774B3ECBB03AA340EF966633FC -:103B30009D0B60973227F4F0434B736254B6A36732 -:103B40009E3DF4FF9AE6C7E9E2C13DC52EC7C1819B -:103B5000ABA0C7B58AF9568FD3FCA427CBF9AC9498 -:103B6000FB0ACB16FDDC2EF327E47941CDEFCC9098 -:103B700003452EF8311BF6659821C74D3BB7E3FE90 -:103B8000C0DD51FA758347225E32E7B763F9B84B5F -:103B90003E12F1BA7FDC3421F64AE89F2F583D539C -:103BA00078FEDEE6676D38172FB1046C3877563F24 -:103BB000D762F3F2F4BA1D2DF47DE18E0A3A6F2F2D -:103BC0006275748E3CA9E26F253EAAC76B5B9C1C94 -:103BD000EE17070BB9511D25E2364ACD63DF445C71 -:103BE000FA851D5A31E63BDDB7CB5601FBB3AC1766 -:103BF000BE3EBADE9D56DA0FF6A456E1F7EC6B3DF9 -:103C0000CC08E6D17A9876D145E9F48B43E91CFBE0 -:103C100011F315929C28083BCFBE2BE290BBF68B8C -:103C200075506D0B264DC33A79C34AEBA496CBAFC2 -:103C3000D1253827333686A7BEB16603BF2E9F181D -:103C40006DE0E7D92CC1E0479E894B9B21F9E953F0 -:103C5000B20CF5674DCF0FE3FF929E729223630C77 -:103C60007126B5ABFD2E8DE259C61BBFF37435F13D -:103C7000D90D86F6B5ECE69E7A38076FFD35E199E9 -:103C8000B1361BCE5BD5261157335BEF90DFDBE9F6 -:103C90003B9F88611D0ECAF2FC56EC8B56B2CB2BB3 -:103CA000BBF46CFC3BABB77D91135A8E8BF850D8AC -:103CB000170CF1851C003A7F3241875A69EFA9CD74 -:103CC00013F69E5A7F9B0DF1B71CFF96348E9265BA -:103CD000CD1AD9F3787D7B5A82C8AFC6F7DDC6FB13 -:103CE00006E8EF22CA8F982BB05EC2CB97F17943DA -:103CF000CF58063B0DEC4CAA7FD9AFE2CF459B8D48 -:103D000076A365B0E784D0F1ABC12EE2D3253B7634 -:103D1000BD3580E3659A2FBE18EBA7A6B5CC5A51E6 -:103D200070299F29F97EA1DA447EEEAE770F119FAC -:103D300075555B889FBF0B1FCBBCC29E19CE7F0BF6 -:103D4000F97CE0975DB85BF30434510F781900BE3D -:103D50000CC34B5A2FF85278EAC65B58F922FC6321 -:103D600004E206B440D0DD1B5E241E55FF6178627C -:103D7000A38D7858A8BBDE87BC5978C4CC02973194 -:103D8000EF45981FC6E7F3C3F8375F147612E5379F -:103D90009879D142F96E3EF189F8E9E9538CEBB29A -:103DA0009B6F7C629DCCB8984CEDFEB7F9E7BBF8F1 -:103DB00046C11D1E9FACEEF7FCF76069271CC94683 -:103DC000D2FABFCCB861B5DF2B3C0FBA7B34C51338 -:103DD000753932497FE8DE6F9CC6F29531991447F8 -:103DE000AC4BFB9C92BBBAACA7C6A9E0E5AEE1E048 -:103DF000E381C9B0BBDED39495D11EA297E8EBACAA -:103E00006437CD5893486945A43319FB45C51AB3A7 -:103E10000FFBE067F7F54F1E0D3BFC3A6BD214DE4B -:103E2000F567778EC86085C897527A7C63C4EC507A -:103E30007BB64A5D79623FA8BDFB28ED5F674DEF19 -:103E4000C6CEC63A5BB7271621354BD77D30CAC9D7 -:103E5000558F168B3E280F71845ACB7627F0E66C6F -:103E600029823D7A1868D7AF474F58B2AEB43FECBD -:103E70005F35DF1C7A0AFBBBBEC69A0C3DF3D487C4 -:103E80007CFFD368FF22FDE024E28F93E0B78AA68F -:103E9000FB6D2735E685FF66B1F94091D3B09FEE03 -:103EA0009F09385E8DD287E5919F36B03D05E37B53 -:103EB000FC142FA9AFC989EBCD5EA2D2E59B85FE8C -:103EC000B65DD96BA55D177A3BF2D0DBE11482DEDB -:103ED0008E3CF476A4D0DBF1BD4CDAEB07357616D8 -:103EE000E3DCE91FCFF2EA687F75E4412F5FA54567 -:103EF00079206F56699EFEB083B1ADA9625F0DA3B4 -:103F0000AF4AAFEEE4BA5508BF5F7BD1CE42E3C7FC -:103F1000C6B178437E823DD550BFD4E936945F97D1 -:103F200032C4507EBDABD890BF31EF4A43FD9B3CBD -:103F3000E30CF9EF8DBEDE50BFCC5B66C84F9B3CF7 -:103F4000C7507F86AFC2503E6BF66243F91C7D8539 -:103F5000217F4BF59D86FAB7D6AD31947B99D382FC -:103F6000FD6D3FCE531CEF6FE03CC5D355BFCA710A -:103F700084D275EC04535D6FF6F8EF4BFEDD3CC464 -:103F8000BB02FC992EEF81A4CBFB1C4D792EE2CF16 -:103F900034DCDBA7F36C5B2AF826BC5E78F9D8E842 -:103FA00083175C9C867FD83173BA85CB87B1571C49 -:103FB0001C9EC5F309431E986EE17265EC55075FC0 -:103FC000CEE4F90143DE14E5C30E5E40F903431E5F -:103FD00012F9698C548BCC21E3A7FBF93CC65E9B9C -:103FE000B9C123EC21BDC65BAA147840DC22F08065 -:103FF00034C8F913E941CE9F480F73FEACCA66EC92 -:104000002DCE9F488FF07325BEBFCDCF9548DFE5FD -:10401000E74AA4EFF17325D2367EAE44FA9B86D9E7 -:10402000947ED8A053BBFF6CA8A6F468431D7DFF07 -:10403000B8A19ED2DF37F8E97B204FD90F826467A1 -:1040400051FEA465F0E3C10EB7CF7A26D4CFAAFC07 -:1040500081CAFFD758C7DAA3B14EDB2DF19FDB7BB6 -:10406000FC7A7DCB590BFB3C44DF6A89F63E9F47C7 -:104070007692814E92D7F2FB786D5A7A094FFFE221 -:10408000D27781DE334A2AD7C5B9710FA4CE0A7E12 -:10409000F9C8D4FBBDE0A63C617F5839C4BB97F892 -:1040A00044FAB1951FB93B3E25C4CF6D0A898BA157 -:1040B000BF90F816E56F56F134D7D8457C9EF227AD -:1040C000ABB819D55FE94546F2EEEAF516D24F6274 -:1040D0002C2C88FE557CCCD5F6D662C40B5C5DE3F7 -:1040E000A038B4FEFCBBAD84EA79CD3CDDFA675E56 -:1040F000BFA8C77FDD5FC2CFCB09FED28B3AD95DA7 -:10410000AF96FE7BB4B78B723FDA23760A7A064FFE -:10411000C9AEF624E29C4A7AFCE9A81F2DEA07D131 -:104120005FF67FF1F1627BD64F7A426B31E2A9D222 -:104130009739289E6ACBB820DDDF5AEED63F039D23 -:104140007C11CE4FA369FD64A5C34E5026F5DE6FEA -:10415000A1C31768A7F0A3F0ACE8A2F01B12774444 -:1041600078ED8B4EE1F409A78BA247E9C51E3C030D -:104170004F97D2A1874EB0C7FEBF4287119656BA5D -:10418000FF175163F700AEEFA2CB6D9D6C12EE13DB -:104190000FCED49B80E78A8BAEB790AF64E32661E5 -:1041A0006B52E59EEF289F85F27E7D97DFD147F920 -:1041B0003B912A1EC1EB28E6749920E5C7AA5281DB -:1041C000DFC96E33E17742C122D2479943E8752EA9 -:1041D000FE1FE4C9A4AF7D4DE86F5292513F54FEDB -:1041E000E01B647F93C3FCC03748BDF18630BD70CF -:1041F000D410A9F7B9995B9CFBC43DF789729F4E17 -:104200009374CEE287F9B1A023D32D105A8771CFD2 -:10421000BD08F7C0FD94BF9E0528BD910569DFBAB2 -:10422000890B38E4BFC718C5331E8A9E5ABE9CF757 -:104230003761F8846C7C0FB9D777DD907E74AFEF6F -:104240000FCE907B7D0727BA486F3868CF223D0696 -:10425000EBC01A6247FB2597FB086538C4F705A435 -:104260006FF27D219B33F92FF8BE80FC0D796B181E -:10427000DA4D7219E34D54FB1B9DE3996578DF72AB -:10428000F7C6A25707C2BEF24EFCE089B03BBF138F -:104290007FC544CCF79DF8FE269146D8282D7C2575 -:1042A000BB373D4BF161CF78939825F152FC2A7CC6 -:1042B00086E351E1F79FC0E78ADEF0D9041CC0AE67 -:1042C00067FF20362513FE2FB1FE6B5F29EC0FF838 -:1042D0004F0134C425DB055EC2ED3B5F34B081C0C5 -:1042E0002FDB1A47DFEF903C7475FD18AA7F4DFD58 -:1042F000689ADF5551FADA217C9C3325C15CAE39CE -:10430000B02FB634D2FDDBB32F9A3DD0BF6BCCAE0D -:104310000D1EACF577C47D39F6F5A10CF8DBD8D6C7 -:10432000DEE3766BEC0A6F7EC2A737D3DB24F63F61 -:10433000718F58EDBF032344BCABBACFDAD77E3CB4 -:104340002A4AC8958111420E2A3AF176944FE3FD2C -:104350008CE27223EDA128D2BF4724781F073ED5F7 -:10436000391AF14DD8A7AE09E6C7213F19E7499E92 -:104370007F5BDE4F7B7B685D5226C7F7219BFE2C5F -:10438000DA31F3D766ACEBC61C8DEEB9771DC94A9E -:1043900002BEB7A97557C48A42DF1B50FA71F7787D -:1043A0004966F28BAF847F3409E7263BD98BAE6137 -:1043B000B9E4379D28C72FFD6525BD83A0EE7D4458 -:1043C000A4988CEFE7B8A20CEFC144E72518F231AE -:1043D0009E0186FA71A3330DE5F1DEA186F2C4C910 -:1043E00025867C3FDF1843FDFEB3C71BDF75D36F07 -:1043F00030D44FABBED99057F22B4D7C62E9757328 -:104400000DED07D5CF37D477FB9718DFB7F17BDBFE -:10441000F29221F7C45FD6FA9586F21FC78A7B0D08 -:10442000931D0BE9BD8A9CE6BB8CE34B3AA5C509FD -:104430003A319790AF7EFE1FF8A634C5286F273813 -:104440008DE76DAE0F6AD8DFD3EA2C86EF9FFD0FA4 -:10445000E91C8E972EBE3505511FFA10CF5FA30FB2 -:104460007D08768D8949564F80097B7AE8BC604F7C -:104470000FC503ECE9A179D8D38DEF4219E90E7B82 -:104480007A68F9F02346BA8F6C33D2FD8AA346BA14 -:104490002B7E0CA7CF95ED467E08A7CF5527C3F8F6 -:1044A00043D26336FFEFEFE29E34D16B9243634F0A -:1044B000B8FF79FA240FE5F4C9EFA1CFFF49D35330 -:1044C00087F6C3FDF40B1936D0AB53BCD7B742CA3D -:1044D0004F154FC8CFBBE23EDD5D66F2EF1F3335AF -:1044E000D37B49079DBA1BED6F2BA8D3E03F4861F2 -:1044F000BE5D0B397CF3FE2382FC09F306897B9DAC -:10450000ACA09DE2EC959C9B9726E258860C95E723 -:104510000B8F886729182AF4C2188F93E25E2B0A42 -:10452000C43D027E2CC8985708FE793712EF1676E4 -:104530006D12F6FB76ABB85FEAE77C04BF18F44473 -:10454000E871E9528F6AFC9DDD0EF8076F66867D83 -:104550007148C06E88BBCCDFE134E40B5B530CF5D3 -:1045600087ED7319CA8B837986F2E1473C86FCC8D4 -:10457000B6D186FA571CF51AF257B64F36D4BFEAB1 -:10458000A4CF904F639D8F03BF8334711EAD1A2A51 -:10459000E278F81A227FD2BC7BE3C5FD41794E5503 -:1045A0007AB08AC7D525DF85EBD3836C3AC5F73659 -:1045B000A6320FDD03B0CBF30933EAD9BA8CA75585 -:1045C000FA28F31BE369551C6DB73E2EF56FA50F56 -:1045D00087C4D17A43E368E7C97BBEE1FB5E9DA453 -:1045E0007B38FC836C62BE8D77DAE8DE82822B1C1E -:1045F0009EBFC9F8CE6DF6DEEF8FDC3D54F8DB7F51 -:1046000099E5FB3EF8F529888FACDEC6F3B4FB399B -:104610007F35FEBBCDB3D6F5DDE3CD1B26E6536E6D -:1046200032DD565640714BB37F1632FE0FE5B8AB04 -:104630000AB45EE7372F4EC415B1389B0BFCDBF78D -:1046400078029F2936D644F75C64DCF9AD1B5A1F0B -:104650008489BCDCD66C15EF9705ACE08729E3B9FB -:10466000FE540CBBD5370F3BB89EF154BD85EC1002 -:104670008F0CBD69863FBBE71EC1207EBE007F4018 -:1046800057C1B9C45E20E266F70E15EBBFD4FC75C6 -:1046900077FC37D9D31993F25B9C5B7AE137E2431D -:1046A000358F7F751C78389ED4B990C97D275BC241 -:1046B000A5F0D77D8E97F853F1F8AE1556DF330E7F -:1046C0008AEB9F8C782645BF8105822F4F0E15F40B -:1046D000463DC8A3BEEA959A0BE260AFED62AE38E4 -:1046E000E7B7D823FF557851F8EFEB7E4F5FF2E143 -:1046F00012B9D0C77D9FBEF893FEFE817B3F21F2A9 -:1047000041C497487A04B24DE4CFBD37C6B88EFB9A -:10471000E70BFCEE57FB859F9F278D7282C1BEDCA5 -:10472000B8CE2CE584D857A16FE0FB827556D237FE -:1047300058BD8847AE96B298315FF29811F0C75ACB -:10474000E93DAB6BBC8CF491F90E5BA085D7AFF063 -:1047500087EFAB5E6A4FFE1A17DE2DF1DC03FB7BA1 -:10476000E57A63BD450EF1AED782B073E922792EAA -:104770005D14762E8DCC97FBB28779486F92FE67D9 -:104780000567375F05B2282E18E754B3B09750BCC1 -:1047900052B71D1FFE85907734393EA3F2B06F37B4 -:1047A000597A8D23EBC6671F7EF233F093BBB0FEC0 -:1047B000BBE8FE4FD7EE48E14753FE0B59FF8CFF95 -:1047C0000295A33E7A3B5BDC56043F52B7BF23CC35 -:1047D0006FD2E530C58E467F3BC5FB0B2A0E60C904 -:1047E0005F0345CE103FA7DE6E32C45D84A7FA9A00 -:1047F0003D1417D062D14BF2F93C4E5B3C76BC17AE -:10480000799FE36032EE6B4F91F69A7078BBF5D0EA -:10481000B19AF013FA851EDA3559233D94CB4586BB -:1048200075A4FCD9652C988454F90FF4F5A309CF2D -:10483000CA7F50111C4D70CE685C64C5937DED8FAE -:10484000AF2E8D72F5F815DAD3453C4A5FFE8569C7 -:10485000173DD4DFF48B63A89FB27CB7B8C7D5F4FB -:10486000E00AF0D1D01DCC8A79B687C563ABF4409D -:10487000BEB07F1FCB57725BC6B9ACD1849EAD3141 -:1048800015F742725BE52F34CB7CA9C8AF5A27F2EB -:10489000EDF21DA3EDD2DE807922C57C702EDE29DB -:1048A000ED11980752CC03DF21A790879C421E721E -:1048B0000A79C829A49053F83E9FF9328ACDC20FD5 -:1048C000323164DDC00F3231440F821F24340F3F78 -:1048D00048687DF84142CBE107092D871F24340F3A -:1048E0003F48687DF84142F36CF4F53D79C8356F77 -:1048F00099213F8DEBE31343D62DFC20A1FDC30F7F -:1049000062E84F5F61687F0BAB37B4871F24B4FE4A -:104910006DF59AC14F729BBC975EB93981F8638E71 -:10492000DBF7C37C4EDF3F447F738715E734F3FE2C -:10493000C5747EAA8DF2083A374F1674373141E7B5 -:10494000CE3944E7D536912F1571B1BDF91B2666D6 -:104950000B7F0352F81B90C2DF8014FE06BC870D4C -:104960007F0352F81BF01DFE06A4F0372085BF011F -:1049700029FC0D48E16F400A7F03DAC1DF8014FE95 -:10498000067C87BF0129FC0DF87E0C7E8FEC1EB8DB -:10499000A0B7671BCE779C0F0DE73BA7210FBD3D4E -:1049A000B43EF4F6D072E8EDA1E5D0DB43F3D0DB02 -:1049B00043EB436F0FCDB70D75D1BA84FE1EDA0EEF -:1049C000FA7B68BEB0D9FF266C4C376D3977186911 -:1049D0007B8CF694C645C1FBCF1F9F01BF517BA4C2 -:1049E0009611CF97BC553B356322D7CF74195F56CC -:1049F000C43AE97D675DBE5BA30719C5C316FE25F2 -:104A000045C805756F087F9CEEC5BB199D03CAE4B8 -:104A10007EAADA7B98D34C724BD6EFC9F75E2F7C17 -:104A20007C558FE465081CFC80588C3888E2D58E54 -:104A300012C4716F3769220E72AD88430DE72B7374 -:104A400081904BDB4DBB0E4621AEA542A3F7E2732E -:104A50002DEC08DEF12E6CAE2B81BE703A3F5ECE9F -:104A6000AB6E0CE26214DCCA0EC8E504DDAB1ADBE7 -:104A7000C96C5505784F8CD91640BEDB849E807674 -:104A8000383FE6FB35EF3321FCFDE77CB1BFE9FEA3 -:104A90001563AAF8F7FC9D7563705F6B4A9468F71D -:104AA00093A763098F539BB467702F6EEC4EE6C5D6 -:104AB000FDCB6FA43CCDDFE9B455D1B84EBAE7A524 -:104AC000FAADD89241F7D22A58FBC414B2E56BF480 -:104AD0008EB9C21B9FDF61CC8F8BF82356D247C59E -:104AE0007D9128795F44DD13715B7CC1A1237BEE4E -:104AF0008B5C3D22BE14F15A6CBF7877EFA611157E -:104B0000EBFAF1FEF5807877EFEA3FD5BD49F9ADD4 -:104B1000E2DD3D628351340EED6B83FD1ABDF7304B -:104B2000D5DF624A72E1FEE81A6B32EAEF641EA832 -:104B30003F8399B807A9E02B606D26BC3BCEB798A0 -:104B40004389217CC425C074D0BDD863A5F720CA91 -:104B50002C4E2BE446F83E7E693C5D989E10160F65 -:104B6000D1B8FA68863913F61E932708B9B5279A83 -:104B7000F405A5EF54C838A80B4D6FD27BD615BBF2 -:104B8000847EA0733900F9A7E2236AB3021926E8EC -:104B90000B035A8A12CC62FF2FC07D24FFCB334710 -:104BA000BB708FF14D8AD7AF5837324EDCD711FE2C -:104BB000872A89A72A19FFC20A9CC9D03BD53BA6E0 -:104BC000A5E6B17174DFAD59E873CAFE52F1ABE1ED -:104BD0006F81CE154FCAF740D657D03DA0F038149C -:104BE000A51FAAF74E16375929BE6571981EB854ED -:104BF000EA814BC3F4C01B0AC2F440F53E9DAC539E -:104C0000F1AB4333484FA913EFF195AF117A0BDBAA -:104C100025DEB12F5F33C184772BCAF7783D5A2F39 -:104C2000FCF1BED45FA660D044C4F90CA074E6C504 -:104C3000144A675DCC233980BB18A07FFBAB8CF492 -:104C4000E90FA4BE3203717EB81FE78F90F17C8C10 -:104C5000F4A562E62C85DC18EAD50EC17C3DC5AA18 -:104C6000AF431CE1941646F7616E825EC30B664348 -:104C7000CF190E3E7797D2BD80C91ADDAFB869C48F -:104C80000AC9D79CCF19F8DC2FF9D647F9EEFD40B9 -:104C9000F2B7EEEFB0D0BBAC7ECD8677D974799EFB -:104CA00055FC1BCEE7F3E4EF4D3087B03375DBA145 -:104CB000002C3DAE72CD4CE88BF360BB1B2009C9C4 -:104CC00051145320CA9B0AAE99D984C3CDFFD03E5C -:104CD00051AE7E8781EB5990A7B7DE5E6C9B1F2299 -:104CE00057CA8AC63F5BD8AF87EEF3BBEF8D15F48A -:104CF00087FEBFF2BE9CFEDF767FB192E319EB63C5 -:104D00005E5CFB1D7819776B01F34E1C8DF798D50F -:104D10003C5910F16A7365FED7058BFE737D01E186 -:104D200087F2819D5366FA69BD0879750BE4951980 -:104D3000724A7FAA00F73BECED93408FE8824E79F0 -:104D40001F5EEE4761F6885F17083A84DB252A0B61 -:104D5000841C671657C62D744FD545763D05FF67F1 -:104D600056E3BD4195FE52ED230DFF9A78FBAF92BD -:104D7000F59F437E3C6A12F7B707989B99B40F8959 -:104D8000DFC990EB87C9F70C7AE8CFA506E87F9FCB -:104D9000E60CA5BFBE5E13F7A6FBB0E3B0BCCEC762 -:104DA000B7C18ED7207E9FE3E95CC1474FDF652303 -:104DB000FDBBDCD6F626DE695278FCA4FE4756F130 -:104DC0003B2FC11CBC3F35B72E92DE7B2D2BF2B59D -:104DD000812ED1051EA2C7B38829E5F5DB9DBE0F44 -:104DE000309FDA0D079EC2FDF1E5FBDD74AFB162C5 -:104DF0005FF13D78D7A2AC483F8AF20A87D386FD9F -:104E00007B59533CED67F3FACBFB85AC93FC540A1A -:104E1000FF9D05C28EB5BD48F47F5E9E432028CB22 -:104E20000CF5645C71D83A51F6C1703B43F87B02D3 -:104E30007DAD1F654F80FDC016625F54F6096BDEC5 -:104E40006773B07F96DB8CF7E154EA2E94E75C79C8 -:104E50000E5CD0BD7F154CEA0F7D79A346BF5B5336 -:104E6000E570CDBA92E7AB8E581129C8A624B8C414 -:104E70003B12F7897724E6F3F50A79532EE386AAE5 -:104E8000368FA6F55615E06962DFEBF2968D87D274 -:104E90005F05FF04BD744FBCCAE9B52584ACFBCAED -:104EA00066CD70CF5CE5E30B853DAE1C4F98974017 -:104EB0005EB86D78CBA59CAB1588437317BA0C7E92 -:104EC000575E8FE218A664B2B7C43B3E1C6EB7189B -:104ED000AF24A4FFF9CDC6FBF2BCBE7897A2308602 -:104EE000FAAB70F279C3FEE174129C1C0F84A7CE5A -:104EF00007797F2E1A87E851190C5871DE2E47FC6E -:104F000004CFCF7506AC18677E9378B742DF20C612 -:104F1000D1D7C7DB0AA12F599CB674E04FBE6BCF27 -:104F2000E1233958C5F182FB3FEA1E60387E2A240E -:104F3000BC55CDF1463DAC79A315F498D3C7FDF926 -:104F40009B24DDE7378DA3FBCF55162FC5D7EB127A -:104F5000BF7F5C11793FFC0373363D6675F3FCD56A -:104F600085827F6F92789D9219CCA1F76956447A19 -:104F700000E71C6733CDAF1BBF8F707C687807C517 -:104F800047F8E57CE1471C59D526233D7BE011F825 -:104F9000ADDA5441EB6DA145B73943E1D87C200728 -:104FA000F77AE6F0F58D77779853A7FB369F3F3277 -:104FB0002B83E6C9E1045E633CAE49786F86F30952 -:104FC000F1B1E217753F588DB7A050DC135C50D893 -:104FD000BB7DBD675D7A49BF69E4F485DDBBAF7514 -:104FE00069C345233EAEAD4ABC0316BE4ED5FA5446 -:104FF000EB52AD53B57E9FB2FA82295A8F9CE1FBEA -:105000006DDDCF7AC1D3B312DEB992AE1CAF874348 -:10501000EF156D2814F2A83CD3B8DED11FFABD4BB2 -:10502000958F0FE6E01EA0AAAFC62D97BFD305BE91 -:1050300007BFDD25E98EFA2BA9BEF17E4465B7BC1A -:10504000D8B92E19F2629746FAEECA070FA5FF1BD0 -:10505000F4D817841E7BBA66DBB254D80D2C818C31 -:10506000D0F799AA82423E2CE0FA0FE4C542B94F2C -:105070005F97A3DF573832A4DEC32FE4EA42BE04B1 -:10508000215F7EFFC26B1F8D71F5EC9F0AFEF9EB6D -:105090007F6DAD7084E24BF0F9FD795D74EFABD2BA -:1050A000617321CEB6B2A982E42D4BE1E7092D242C -:1050B0004E2A8C0F2A9A347A37ABB27E54C0FCBF8A -:1050C00028972B3794D1DB3C8A4EEAFD0DB59F2AF9 -:1050D000F8774AF8E74A3E7E49AEBFB9D56EDB4263 -:1050E0005AF76E5B25F85F96CFA9327EEFA653B7CD -:1050F0009FB9E09E14798F85CE251BACC2BEB73315 -:1051000086F4D5D32B5F796F26AFF7E5A32D19D0A1 -:105110004F141C8BA41D6F81B4C72D947A2BA7D379 -:105120001B85217276D1D3824E952FFEEA53BC0F98 -:10513000559E29E5D983E27EF9FCD65D44B739EB6B -:10514000375ADDBCDE7B856E839CAEAC2B76C23ECF -:105150003D777D8B1572E0BD4281B7707E2F9771D0 -:10516000A90AAFD877B410FF85AA0FF9B78B8F7350 -:10517000FB8AC858C465A871FE5BF271655D7C024C -:10518000C6ABACABF821CE3D4ADE87AFBBE3916244 -:105190003DCCE7FD615D1E1FE7A17BB6E5F2F7A5FB -:1051A000C2EB9F9374FBB155BC239816DDFA1CC566 -:1051B000152C8FF2403E6467B707302EF81970DB6C -:1051C0004CE2DDC1EC9AF6AF0007578B293E05296A -:1051D000DE3B829A9CCCF3CF98C47D20C496204DB0 -:1051E0002A12FC00D314CA59523BBD7F16129F6984 -:1051F000E0571BDBBA1EEFAFD89218FDDE8BE24FF3 -:10520000D58FE24FC5BF7DCDCF517479F33BEE967C -:1052100076883C4F06EE51CC7B6830BDCFFF5DF306 -:10522000B4C977F0BAE71B217EB7E092F9668B73B9 -:105230004BDFF3DD549ADCCB7CC3E7A9D6898ABD6A -:10524000EEF62B340BBFC2718DEF5FBCDDF1159113 -:1052500014F7A5E6A5ECDE971B2FEF294A9076847C -:10526000F618E891E5F2F7205850E4F1BD2CE4BBC4 -:10527000DAF7D5BB614A3E9FA893FB226B7F10EB08 -:1052800099D567D13B19C79A8FC7E0FD8EE3E30438 -:105290007CAADDED5671EF95C5D85C783F919FAF44 -:1052A000E8771F1634F5A773E4ADF55924176EF5AA -:1052B000C70BBB83D4EF174A39187D7BC53D57A078 -:1052C000FE66B753E3E32C70783EDF4CEDF33DD040 -:1052D00007A33795D93249EF15E700E507BA5D63B3 -:1052E0003EBACF043989F5653A908D7D67D16671F4 -:1052F0000E986262EBE12F1CD4E89B940A39F1B856 -:105300007837926D31BEAB7430C7776311F016F603 -:105310001ED9EDD6566F7FC871AE6FC0CEB4C0E156 -:1053200023BDFD6D29278F6DEAA0F7C9155E2FB942 -:10533000A76213F7523B634C647FBBDCFB2A55D258 -:105340009FA4F846F9A39EC0FF5D093C99685F2BB6 -:105350003597D3BB3EF76C9A4069D5C6D247FD85D9 -:10536000B80FEB4B1E43705BC93E56553B41DC1FEB -:105370007D26221EE79B0CAB3F23542FAD6AB997C5 -:10538000EEA99C6C89A47B2A139D6513E393E8BD69 -:105390005DBAF7A5EAFD40AECB25B5130CF74C1668 -:1053A000F03E1107FBE7D6688A2B55F747EE8ED201 -:1053B000BF5FD44FDC23B9D225EE8FA4527D57AF07 -:1053C000F670957EDE20EE2384DC8B993A87B7AFAA -:1053D000A97D3916FD2C7DE483511C33B03FAD050A -:1053E000DDBAEFC56C16F7621A715E821E99E09BFA -:1053F0003907F8FFA599F0DFD778D5F85192907367 -:10540000C4AD8138D25BF520B3C19FAC3B19E9C56F -:1054100027CDAC1E7A80D25FD4F747255E4EC635C5 -:1054200067803F166F7F2C03FBCBA918912FDF3EBF -:10543000EB6DC82B7D6B84D0CF2D8CF4E14ABFD0AF -:10544000AF5975827A1733721EFCB145D1E21D1E29 -:10545000797F46C1A5DE5B3D6511EFC5E05E0CF8C6 -:10546000FD134B7001E8FB09D75F718EFD819463DA -:105470009F349BE97747FC7CA1400FF9A4F9E5181C -:10548000DCCF55FA5AA9F9F75EBC47B3728FB8A7BB -:105490008A77CDE9CD4A69075926ED202B5FB54EB5 -:1054A000C2EF8E70FD8BBED45882B6DEE8B744EAF8 -:1054B00057DDF9DDBBE8DC56B353E80F35AD1DA46D -:1054C0003F287D44DD8B5BBAB383F409D56ED96E7A -:1054D0008197DADDE27B05E2D6E5EF856AD9384FC0 -:1054E0006B94FFB460FEAC3596D07C05E53F2D5043 -:1054F000F6914ED207EFCFFB0D9DC36B9B64BF3C73 -:105500006F0D19EF4D30693FF13DCB81F662DF57EA -:10551000E5B5BBE3A97DB0366A3DF679EF32870584 -:105520006963AD83F6FD2D75A63CCB080017E581B8 -:105530001EB75FC66FF55BFA9F91B01FA4B2CE4352 -:1055400078F7F5A0533F0A7E55BF67A9EEBD9C7F53 -:10555000FD8BE1E8FF9A41ED17F0C683754DED2C08 -:10556000F827DA8BE43C0ADA8783AFFB1D14F2F9E3 -:10557000492B5B4FEF075B7C0C76FBA0F42BFAFF0B -:105580006212BF2FA1059F0DD5AF9286093DDC1792 -:1055900021FC8B5EB77E0A707C4FB31616E34CED90 -:1055A00032E7A07FF53B2A4A4F1D2FE573BA3C5FD7 -:1055B000D906A438C0C79AD74BF710D7161CACC46D -:1055C000BEFC40A79D7E5F55C5E18DEF8C22BD35A9 -:1055D0007DC064DACF34978595F3FA070B4C41DC34 -:1055E000DB7A80D9455C803D4CAF3545523CB2B644 -:1055F000FF177F813C4F337F7508BF5392F66F1AB8 -:10560000BD7F39AFEBF327F11B33E52C504CEFE0B6 -:10561000C5EBA66190C35D933B744EB2079CAD761B -:105620008FD8275828FCFBEFFC4B6C82A907AEF300 -:105630009D9FD3BB82E73BED64AF1DBF5FBEB71735 -:1056400006CFF91417C545F37AA4679E7798E89DAD -:10565000B1F1FB0FD1BB79E3D5BB7A76E3BB7ACC52 -:10566000951E0F7B32D950B95290DC28E8764D9CBC -:10567000F19C98334C9CB7728609F9A1F0D7653F2D -:10568000F78EAEF5ACC3E5CA7FAF7E6FAA3A827ED5 -:105690006FAA6B7FD6B7BE9FF001F407AE176CC838 -:1056A000F4160EEBD7B37FCE907851FBB059F63F8E -:1056B00043E26786C324F011F67B1B8A3F14FD1575 -:1056C000BCEADE91A21BBBABED4DDC0BE2F42A7C05 -:1056D00088119DAE203AFDE5DD75B8E63FC0ECEDE2 -:1056E000D0DDFF123A05F10ECE65D3A92D9C4EC137 -:1056F000C8C1D0131E11BFBF151ED7C8F218ADF315 -:1057000079E628B203EAF25D70BEBEDFC4FA56EB5A -:105710007AD0E4F642EC8FC7F8D11B70B59B5AE9FA -:10572000FBF7878978C281AC2D55C6DF8C845ED6A5 -:1057300028DF3FEEFE1DC3C50E7A6FE47C40BD7FBF -:105740001C787C211F77D38C02B2EB9F6772BD5708 -:1057500077BF932DDE3FEE7E27DBEC273BC99C28ED -:10576000B2F374BF939D23DEBB7E4D63B97887D6B9 -:105770005F66A7F8F8F077B2F93EF31CFC194F54B6 -:1057800047911F4ABD8F3CDEA9D7818EE1EF233FB1 -:10579000AAF9E62C407F850EEAAF7D4ED48BDB055F -:1057A0009A83B0E31CAB8FA177A1155F2AFBF5208C -:1057B0007FC7E3C093BAD7F907C95F0AEFEA5E9BD8 -:1057C000C2BFE233BF95D1FD4FD001EFCAAAF7D9CE -:1057D000B5D5526EA8FB846F785C481F8CD7D70371 -:1057E000EEC6155C6E905DBCFD0ECCF7C93B63BC8C -:1057F00080EB98C9F8FBBD2A7D7898C9F03BA1F3EE -:10580000E47E354FC5FDD71BE3FEC3DFD14C8CF3DF -:105810003D328CB73FAB7D300A1FDFFD3FE65EE3D4 -:10582000489E92EB7F44B4FE24EAABFB0F4A3F7CD8 -:10583000B7F88B74FABD91AF0FD1EF2ACE75FA028B -:10584000A817992DFC017F486DA7FB1A7F98F3D705 -:1058500074B227AF16EF7F5E2E9C97DEA715FCB0C3 -:105860006A8188374C6375C4BF293DF7342301C76B -:10587000FF6FF7697BEEBB4E1E7E82E22E7CF47BCF -:1058800015E1F4181B71F065173FA9FC76D897B3A2 -:10589000E83E69DCC1556E9E3FF6D239914F3B78A8 -:1058A000C1CD69D3FED27991CF3F7801F7513F7BCB -:1058B000A953E4AF62E4CF3AF1D257B370FFB4BF5B -:1058C0005BFF23E835F362DD9BD85E3F5A73F3023A -:1058D00037DDA72C4BCF13F7293F41F98CE4F9EBC7 -:1058E000E2B49EFB94268FEF8FE0DBF35F09FE7638 -:1058F0007358C127FF6CAAEE932A79DB975C54EBAF -:10590000EE5F751F56AD63B6DDB3DE0A26F4FFD336 -:10591000F7549987CFEBFF021C7874630080000076 -:10592000000000001F8B080000000000000BB57C89 -:105930000B7854D5B5F03E73E6994C9249C80B02EA -:10594000E104420C18D299BCC05BEA1D2089015ABF -:105950001B6CB52018068D90D76442A82DB5D80CC5 -:105960000611A8DE0B5754B06827400035E8A001A7 -:105970002718EA00922252BF98FB37F2FD5FE10B35 -:105980003E90979310B557EF55B96BADBD4FE641BB -:1059900022DAFE7FF8DAEDDAEFBDD77BAD7D86B196 -:1059A000B196F3D18CFEAEC98C1D3FFC9EA249641A -:1059B0006C4681D16A90A034772BC6020EBB01DE03 -:1059C0007595F935B1BC9F36B45FA2D766C17E75B7 -:1059D00066EA973908FD72B1DF9F476BB1BE416F30 -:1059E000356430F6B48EB94D098CC5688EC8B84E92 -:1059F000CC2063CDD07FAC8131631E63297AC6B0E1 -:105A00001DFA312394BB06F97AE3121A56309867CF -:105A10005C85D9DA9C81BBF53056C858DA28FF6816 -:105A2000DC5FDA4A3DD5C7687A940633638126FF86 -:105A3000DC0F33192B8E8ACD653F8052CFB2711F98 -:105A40004C13656D85F54AE4AFBAD2006EEC906CEC -:105A5000B0342B36946F671319ABD7029088FF339D -:105A6000795A711D6D77F51EE8D7939C66DD08E0C5 -:105A7000D8D4832C331FC6BBCA72D804C68E5A1C16 -:105A800039D62468679B241C1F9DC3C7FFAC2C7AA2 -:105A9000870CE3FB0FDF54E880BA3B0CCA01666554 -:105AA0002CDF3B7A81F61680E39442C902B075EC94 -:105AB00002ED688053940312B41BDDA31714DF8238 -:105AC000E7335A3ECC66EC174C627180970CAD639D -:105AD000BA15CEEB2CFB44CF34D83EA02F9F0AF74B -:105AE0006A854960FDA4A3704FB0CF8139319E1DF6 -:105AF000703E96A314627BBA6E20D602F7D1FF9552 -:105B0000B6CC63A671B13F87FA6BF8F7AF8C3DD77F -:105B10002953BD0AABE5375689EED795697E0CEF60 -:105B2000AF3ED568A4B2F36A29C379B4E59977C0CA -:105B30003C763D5B529E73FDF801AB86F695B10E47 -:105B4000103A86C8CBCE14F8BF28A6C26E369DB1D7 -:105B5000965F41C5BFF0763809D34FD208F896ADAD -:105B6000C5DAB0FE76EC1F6C6776230B8E775AA7EA -:105B70006E5D9B29D6433C2F639E49708434D620AA -:105B800031B8BF54E627FCBC644BA073D11FE0E9D9 -:105B9000D94453CB46A45719E8328F4A6681322D37 -:105BA0001AD683F6B4374C1EA4AB5D264EB7991AAD -:105BB0005EEED2F0FEFA28E6463A1D073083F26D1B -:105BC0009BE377B6249AC74FF3C8FB6D488FA39920 -:105BD00097D64F616EDA8FDA6F2CEB3621CCB40397 -:105BE00059844F5933EC7D26D9666E463A0B34D929 -:105BF000D947DA607D203A765528FEEA71BC3974BF -:105C0000DC2C1AA78E77AED2B08F46E1E1FD443F7F -:105C1000CE4C8DDD9383E3D89B521ED677EBCB63BE -:105C200082E37A9B8CEC23B8D7FFD3C4A83CDD6415 -:105C3000A1F5FF6F532A957F6B52A8FE6C533695E2 -:105C40007D4D56AA7FBF693A95772D8A2940FA770C -:105C5000F966B28F8C42CEC0FF9C5E9DA32F04EEEE -:105C60009D393C1DBD26E8A83763F8F66E6C077CAD -:105C7000F6DECAF1D97F3FF3ECC820BA5C6B49B8B5 -:105C80001EFF30C284E7EB8F610BBC704F6F17486B -:105C9000347FFF680EEFB7EA683EBB866DC5F16FD3 -:105CA00017E8F9FC133455D86E4FE0F3F666010C93 -:105CB000FB59307DE6CBC897F664A8CF0BC2BD5325 -:105CC00078BB7D0CAF57F7ABB6FFCE66E17428F01A -:105CD000DEAF83F57388DE697EB5FFD7459C0F2361 -:105CE000FB7B3235659E61EE23C1C6FB135FC07D31 -:105CF000B8910F3242F8A25E21BE50E950A5BF977D -:105D00006CFC9E330D82CE4127D0FDA16E40F99AE6 -:105D1000027C20D1BDD8199C679724F825921FA03A -:105D20004439AEF283CA072ABDA7019F4909C1734E -:105D3000FC28825ED5F2B495E3A53B39E601C26B3F -:105D4000A7CE02A210FA03221310BEB3C00EE34A7C -:105D50001E35370C27BFE2FED97B50E5C108F7702E -:105D6000DDF9F5BCFCBEE727F986721BE9761879E8 -:105D7000F5B53581F6A3D26D92CDFE5F483FFD9219 -:105D8000492BC54169E2741379FEB70BF83954FA0F -:105D900079C9C6B8BEC4734EBC5EDEA9E7193AE73E -:105DA0007246722F338AD747E2573D5788DC8BB152 -:105DB0001506EF93316E0F8C057B606346907E0372 -:105DC000495F2E43FDB5CDAAD0FEFEA09109FFAAE2 -:105DD0003E19AA97E425F373C2F40CB3001E070E14 -:105DE0001B88BFFD1A56F50A8C6B2555113CF76DC3 -:105DF000362E0F06174CD2AC827D05FE6E76A3DEE2 -:105E00000A8C19382BC1F8C0563040C87EB0FF58F4 -:105E10004A66EC7ED029A897AE809C63598CC9DB7A -:105E20003E3F2BC1BE976D9319DA350110DB328CE2 -:105E3000733D19E331F2718CC1B83A31AE79EBA7F9 -:105E400077217D9D07FA44FBE62353FD040676CFB8 -:105E5000EC6D3ABAC765317A0FD61FDBFAC48945B3 -:105E6000009F6F9714B4374A6533B5D73C2F7B70CA -:105E70009D3A73E94509EC9C407BCB535150EFDCD4 -:105E8000AB63261857DA2E59FD30FF726F0CDE0C0B -:105E90005BB645F77E5F76506EDE26F458D52EC988 -:105EA0000314C3AAB687B7D7EC0A87EB983608C3A2 -:105EB000FCB36C318964FF4D6636B4FFD896045448 -:105EC0005643723B92AE506D237EEC8D5C1E33F6D2 -:105ED00059F21D4097F2E1CFD3DF377378BE80CF00 -:105EE00001FCC9E7FCFED57BAB1732FF93D1ACC0F8 -:105EF0000BE7AC3F6CB2B8E160F51D329D23E08D3D -:105F0000A37B7645F5DD4E7C7A48B6A01DB6C12749 -:105F1000BBB1DDD969DAA98173D61F9018DA9F4E1B -:105F20009FC1C3EFE9EA326C5FEE3359146C3F64F2 -:105F300060328C0F00DE4C88C7717D847FC42BDA01 -:105F4000A7F0F763A928887F19F19518C457F3566D -:105F5000BE9FF37B397E4AE5D55AC2578BC4524265 -:105F6000F0FC67CD8B43F8C27EB3B7FDB50BF1BC37 -:105F70000CF6675010EF32E1F93CE007E7D51FFE61 -:105F800028BDCF1CC4B70CF8FEAD3A1EFA2FBF01D6 -:105F9000BEAB987B1DDA73DF17CF69C8FF4964F782 -:105FA0009EFF03DABD31608F23E908FB38A9B6F7FD -:105FB00078222C589170D9B902EA27A5BEC232C105 -:105FC0004E90E21D8F225F9F9DF39747101D3D73FA -:105FD0005FB4215D34EBFA5A9F860A777CB4157959 -:105FE000B03F63FEF6D7609DE2842FD3F723BFFC5A -:105FF000C96041727A42F023FE1901FF4EC6EF1BC1 -:10600000F0780ECFEFEC34F80D708FACBDC43E6469 -:106010000F4C407DECD5A39C2AD10F54AC407B1C87 -:10602000E6C375242023E4EBDACE3F9F96609CA460 -:1060300024B2C5081BCD7E19E769D35D193A37CC68 -:106040002359FE42FDDA6C13E8FC13537EA4A0FC36 -:10605000695EC81C5113BF4DCE3392F3CF0A7F65E2 -:1060600044FB6F0479AFDA7DCC3D361EF90BEF822D -:10607000F30F973BCBA733F127F842C0556BDCB148 -:1060800046E8BCFC666B2A9EFF63A4B358A4BF53CA -:10609000DA51B0AFBA5689F0568FF483FE15EA375D -:1060A000A8EFF70A39F27C77F1A8442C252B702A47 -:1060B000ABEE94AD7E68AFF6717ABA8E6E84FCA8B2 -:1060C00069E3F2E33A3A6A0338C44EAB47BA526125 -:1060D000C0F7C9A0FC987A0DF6FBF23426F4955B64 -:1060E000D05B4E5C1FD0CB2053E22C39217A4BE29F -:1060F000F6962A576EDA0AA23E64DDC91E23D386BD -:10610000AC7BF35E4B183CD59B1AD6FF073E25AC03 -:10611000DDE6CF0E6BCF3F610D830BBBA787F59FED -:1061200076DA1E06DFD25716D6FF8717CAC3E0C13C -:106130001C38CF3076C7901E4A95C2FACF514C61B9 -:10614000F3CFCB8E0F8307CDE27E841DA8DAA75F45 -:10615000D8B81D1459AAF7FB136BF83AAA5FFCD301 -:10616000E9E1EBCDB787AFF75DF1B21BEC7E2DD83F -:10617000F57B413F62F902D8FF5AB0EBDBC0FE4726 -:10618000F825B0FFB1F482FD8FF5AF80FD8F703B35 -:10619000D8FF081F047F05615F531995879ACAA924 -:1061A000FE46F7D725D63D21D63D29D6FD47EF49F6 -:1061B0002D9D6593345F009FCE4CB8A847396C6F16 -:1061C000EC2BC538C0C05B32DB810CE2F09C684A26 -:1061D000447D348AA1DDC2CA07DEC63845FD818907 -:1061E000968D0AEAA1FF7C07DB03EDB282F2FCA8E0 -:1061F000EF83589CE7CA17C087F938EE8358F48FAD -:10620000EBBE64046F847605E039FB4130903D03BA -:10621000720DFB67AAB047CFA02C6FDBAF477CD4D1 -:10622000EEDD4FED6F7975E1ED7B5BC2DA2DD81FA6 -:10623000CA5AAD87FCFB4B3E753E3FF5AFCB94ECA5 -:1062400068175FDAFB9FC9CBB05FDBBBC9F77DCBBB -:106250007D7F72F0C51C94EB4ED0C37E73701E67B9 -:10626000874EC07CDF7599FB4B135011B4496C12FB -:106270001457D826B60AE45DADAFB50EE5506DF6FD -:10628000221DCB207924E20D206DD15E42E71EEE67 -:10629000EF8AF7D3D8FB60DE37BCC76FB723FE3A6F -:1062A0008FC5E2BAFDED72983F73771EB75BEFCEF4 -:1062B000D313DEAEB41F8B55A07D83F718BF6FAD2F -:1062C0009FCE7D54C0FD50D23DFB643A77F5171A3E -:1062D000BA7F75BEFBF3649A678E6F520C9EABC794 -:1062E000CBD773E529B4CE9CCCA595B8FF93A90B69 -:1062F0000B65B2F34030A35C9D32AF15E303B55E8E -:10630000D93E9CBFB546CCDBA5E374F856E6AB5D41 -:1063100063803E4E968DB291CC17FD7E93C7EDF112 -:1063200052BD2313F5428F5989413A7EB86C620CF5 -:10633000E2F52896585FB653EF80B2A69DAFD763BB -:10634000E98E457AEB69CF97D16E51E75B89EB1601 -:1063500086D0F510DEDC84A72A4F8B19E709E28F7F -:10636000D7BBF2B81D7ED2F3EE5D68A7F464475B3D -:10637000112F5D7A46FE6D2DE015F5414F675A0BE2 -:10638000DE83BA9E4BE0A33F5B43780DF874A2DF37 -:10639000A25616D64FC7F1B52B7C3F16CFB97F5BFF -:1063A000847AE959B0ABA1BA4ED7908CE7FF787BDD -:1063B000F8FEAAC43DD7E9FCC9C921F45AD731C4B3 -:1063C0002F66A2EF0E953F14C2A78AC79E6C6EB7C8 -:1063D000F5A41A3CE82FD6ED6F25BABE3EBED39D7C -:1063E00081767EDAAF8D1437BC913FABDA01217E26 -:1063F0000F433F4E5736B1503321A8EFAFD9EC2FA2 -:10640000E615A23F544EFE5E0F1B5886CADF897602 -:10641000701CCADDBF3D85EB0EB683BD07EB3A8D20 -:10642000BEB91F829D35680546817D0F6ED7798480 -:106430007F6246FB7499B04F3F561C4532E857E7E0 -:106440001A0D9DAF2E278ADBB5424E7EB23FE3A7E1 -:1064500048AF7527648B11ED50F05B086EE3764111 -:10646000BD37E3DF67A0BDDDA6233B40B53B9CC243 -:10647000EE382FECD9F36B06F464AF1E96D813B048 -:106480008F2ADFE6AE346877E6CC257BD529B75175 -:10649000FC71F9D670BBA0DA130ED7EE0D879D11F3 -:1064A0007683EAB7F5E40DD90F93D1FF289167A45D -:1064B000201F7C2CF0A9FA232BA75A5390DF3768B2 -:1064C00095B96A3C00EFC975F8D56ADCAFA72ECA4A -:1064D0004A7EC1AA43749FFD9F71BFA33F9571FB84 -:1064E00088F17BEDF771FA76E924EE6700B9D27C8A -:1064F00046C9B3069AFADD83B12497182B437E6808 -:106500005CC8FD483BC65CA1DC9727E24511FAF266 -:10651000566D9F1C1F221F3ECB9B40FB2FD633077F -:10652000EAA9953156D25BE38DDCDE2E59EDB5211B -:106530001D8C07FFD81012CF1E6F1E90B0DFAE87E4 -:1065400078FC5CF5EFE76B2DBAF810BD0792276C6D -:106550007E90247CFC8DE6B7C0FCE6E0FC70DF7129 -:1065600078DF9F1658491FA7CF67AC9BF8B181F819 -:10657000513DCF15A0B362A0338C9920DEEAB61F3F -:10658000A138B09375933F521ACBF7518AFB41382B -:106590008A97967C2E37CAF3F9BD350B58955B6FF9 -:1065A000E5DBE3F3A1DC9BEF48CAA77A0BD1E54A10 -:1065B000412B60A7A4F40D23771BFFC2FDAA4F81D6 -:1065C0000F90CFEF699094CC303B88D3B78B57B105 -:1065D000CBCCDB3B03EFC16DEFCE4E463F8AF3D50C -:1065E0009255262533844E5D48E7702F5596EA1F55 -:1065F000A3DDED5895AC60BCDF85743F01AF91D34E -:106600007522FC43FFE23A3AF786C3F0B71DE9ABC7 -:106610009E19ACA8475CBEC876AB16E33AF9F9C040 -:10662000073707F9205DD0658B43F2A0DC6FF94A8C -:10663000CBE3588B258A5BDD09954897F487FDAA43 -:10664000667A70FE3B01447F886D4924BEA1469066 -:10665000233F17E7BD53EB3F827C7C5CE7CDC078DE -:10666000CA7127CFEB2C646070807C59CCBAA9EC3E -:106670008DAE3FE0A7C9DDE3D06F7ECF61A0384E7D -:10668000CBDA1D31284F73D95ACBF96C54EE6CEF2D -:10669000B5FC91ED0A2024765EC50BC5853611FE4A -:1066A00055BCEECDB7CF47FC8F34BEF6AF076E4773 -:1066B00097A2F681567D0A279BEEECA220FE5CCCC9 -:1066C0009B8DFB55F135843FD8F358B887056CA0F6 -:1066D00008FD1A156F46F8371CDED4FB4CD70DFCAD -:1066E0000CAF0CF412C997487CAAF75BCF1A743C24 -:1066F000CED5F0CE42E87FF75A8D82F6E175F8BD2F -:10670000011EFC26DEE48F91C8DF1C092F2A3E54AF -:10671000FC9C8EE7E34EDF23539CEEFF355EDECA22 -:10672000773CFA6DFC18C97F23F1DB9255117C1977 -:10673000C17F2ABE1CAB6289CF543CD6298CFCD6C3 -:10674000BACE18AB8705F167867F883FCC53503CA3 -:10675000A65D62CF48DF850FFB28AF11891FA00D12 -:106760003BCAF59D11FCA7E26D24F9A3CAAF33CC57 -:106770007FDC22517E80F3E7AF0C1ECC2FAAF901FB -:10678000350F704CC8BFC8F20CD81D9877D998DD6A -:106790009384F65AAF5E9D87E71FCFACE91EB70220 -:1067A000C69F99C9CB5EB4D342607B148FC39D1939 -:1067B0006D70E3BD9D9126CF423D7E46FAF5ED1CFE -:1067C0004ED12B082F4C996501B857A7C6ED1E1660 -:1067D00072D843E59985D38AA99FC4DEC4FB5024AF -:1067E000564EEB48524219ECE7CC0393F29A59F01B -:1067F000FCAFE4737BD62BE4F9501CFB3712C5B118 -:1068000097800AB060BC7DD6D36513A0FEEC8313DD -:106810006D94FF6B0C5F1FF56806C50737D37CB717 -:106820007E31A05B9A13DCD790FE2BBECAEB2B27E0 -:10683000913F512570684F98CCFD58CFC438D4474C -:10684000AA7E1A3CF1AA39347E7911F417D387C095 -:10685000931F4F0FD56F4776FF3E0BE7A9D2BB734F -:10686000AD507FA1E50FE9680754ED7E348BECD283 -:10687000DD1BB2D0BFA8DAF1FB2C3BC1D10EF26F09 -:10688000B4FCDC97F7DDB27363881DFC6021F70B65 -:10689000161B8F94A07D3AF7E64F1EC178F8A40727 -:1068A000258A8BDDC3BA1F41BD5991CDF9886D3161 -:1068B000925C87F928EFD83AF927BB509E9FCCFE0F -:1068C000405709FD4C055ABA8F0AE6792C05E36159 -:1068D000EB258A8705FB8FA33CE6D2B5923E3511A6 -:1068E000F561BC4D56705C3CEDE3DEF5B62EACAF09 -:1068F00058CDEBE71A3CED3D38CFD37A6BAB821322 -:10690000954F280FC90B9B0AB8DFB5E43189EC71AC -:10691000759D494F25B7849ED35420F4F98C6EE2BF -:10692000FF9F0ABCFC78F5BB6FA62A984F72C4156E -:1069300040FB3B4F9ECF44F9559C703107E97C9258 -:10694000DEF14C359E7B8781E28705B969720AF4D6 -:10695000CFFBE5CC27B05CB27AE933D51807DD6A06 -:10696000243F4ADD5FA3A468D0DF3CD6F28B7BF1E5 -:10697000DE2E3C69243BBAB1E5A614360C9FAAE58D -:106980001EC0BF92C5D8F34D462A5F6CB230058E4B -:10699000B8AF2995E0979B142AD9024E5F8DC25F4C -:1069A0001D69BE7CF0F715905705EB613EB0376D61 -:1069B00026FB143CE7A429CE1D1BC4B926C1789B35 -:1069C0003B6336DE43C186155D688A2617F0FCE21C -:1069D000DB3DEBD3C98E5E7DEEB96A685F5A509E8F -:1069E0005F00F76DDC7E95FCFC631D8F56505C7F6D -:1069F00087819F4F9CFBC2935929CF60DCF52D1DE9 -:106A0000F9DFAEEDE79EDB00E57D8FADD087D2FBF1 -:106A1000773DAF4DECE7467C35D23D7C7FBEFA7DBD -:106A20003AF1CF0EE0AB9C7F9CAF5CABD7D0FD3D85 -:106A30005A507E37DEFB059D3B1DF9E9C2E41F116C -:106A40009DBB0F4B74FFAA1C57C72F10E7ADD5781D -:106A50001F237B50C8F1CFC1F3C3FB3DD2F17116A8 -:106A6000DAC39FFB167EEBB90F3661061DE35A466B -:106A70002A23DB8BF48E8956385F9186DBC191ED3A -:106A80000F17A871719E6FC73F8C0BD709FDE98462 -:106A90008DC525A0FE93FC51B998E7B8EDA216FD6F -:106AA0002FF0EBDE0FB72FD9FB217A7CA4FDDEA8F7 -:106AB000ACC779B441B93BEDB486F943F4F62D7D0A -:106AC00051CC1FB2EE90DF01757ACCB3748C26B92D -:106AD0008078C3BC4CA063F20E842FEA391E0307F2 -:106AE000C1BFE27115261705CF79B1E3722ECAD95D -:106AF000C8F3D61FBA4CF451E77BF4AA44E79F735E -:106B0000519B7BE3F31FD97D3917F17751D7578418 -:106B10007E5440DF978B78A87F9DCBF3EF7B0F6A85 -:106B20007DF57A3D8FEF4916F2074BE42BE4C7075A -:106B30004E703FBEBE6327C9D3C14E1E4F7169BAA6 -:106B40004B5330FED070AE0BE5D9602AF7AF607EB4 -:106B50003BDEDB8C89420F6A07D2E7835C3B2AF27B -:106B6000B5AA5F7701F9578FF378EBE83D526E34A1 -:106B700043BBE212F233D457ACCA5887747EC19338 -:106B8000849120F676EEFFD453FCED8D688B4C7625 -:106B90002BD486E06FE81C1E993F9C61AA9F1ECDF6 -:106BA000EC21FD5C7AE5A7E41F9FE47932D714CE8F -:106BB0004FEC10E727E7DA23FAD490F95E52E58725 -:106BC000B01FE7BEF13FC497A76CF65328CFA25180 -:106BD00016E27CA9711E4912FD8A82794073A7F0E2 -:106BE000C7CB646A77F964361AC7A4C650BEBE8C98 -:106BF0006DD2A2BD3B977967F077327DFFF643688F -:106C00009FF7869C8FEFB1C07EA6FC71699423B379 -:106C100011ED238D24EED55B303F549F15727B6BB5 -:106C2000862C911E1B181D4D76CA9C05CEC5B85FDB -:106C3000B55F9996EB339887EC2CE619C8C57C268E -:106C4000F30FE4629E53ED77D71BD10DA41799B7CC -:106C5000E0AE9075C61472BDF929E69F419EB84416 -:106C6000FEB344FEEA29F4A31A0FF33C61AF26E316 -:106C70003D7CAFE5867B46BC5E06BCDA51FF3898AA -:106C8000DD8EFC3335C983FCE3DA27317CB756DF70 -:106C900061D881719D7A5D5F32D2F306DF5FF5487E -:106CA000CFAE03EFEA95A9389EC781C05ED7E0FD5D -:106CB000BA84FE72FA6E7A0FE36ECE135C8B3AB52D -:106CC000EF925F5FDBBE9FFCF73AE627FFBDAE2D7C -:106CD0009C5E0653799C3D923FC6142A617C3167C5 -:106CE0002BE78BBB64D680728E89B8E99CD414B232 -:106CF0004782E3849D285F7E04ED97FE09925582CA -:106D0000A9FAA3DC6BD12E7267717BA6FF4F2F16F9 -:106D10002C23B9E229F819BE8B11F6EE9CF59BB530 -:106D200072C87EE674F238617F14AB3A48F8768C0C -:106D3000453CA4E7958F2DE4EF6472E99D8F86C7EB -:106D40003523CFF1AC88E39CC4384F4E70DFF3D2CB -:106D5000D2B81C631EA29F2E0D5F5F7DF7A28E5FCF -:106D600021E869C81F92787C6A24B98279944A9193 -:106D700047A91479944A9147A91479944A9147A94B -:106D80001479944A9147A91479944A9147A914799E -:106D900014AC3F895BA5F7703B9F417AE8421E1B0C -:106DA00013847B1322E031E1FD7B13A470788C44C3 -:106DB000FD8B0B773EE3CEC138A645C8252506EDF1 -:106DC000AF0B261E5FEA8871CC2D84FACA39CDBB81 -:106DD000F97B443BBD67294E58B818F96B30D1C0D8 -:106DE000500EB90B1DF3111F274ECCCEDC4CF2D147 -:106DF00064C53C77EFDD37C7515CEE2D99C9B0E42F -:106E0000CCECFCB50500CF344B44B720277E50AE08 -:106E1000FA9330CFEC4E9ECF2891EB2A71FEC6D16B -:106E2000A67C8A6BE53B161586C40F4AC72CCF4457 -:106E30003BA84BA7BC87F154F75F740CFD2835FEC7 -:106E4000A6F6EBCD9B598DFB9A933D716D1ECA1B27 -:106E5000602E946F763D6BC37DD935D15233C92BEB -:106E6000458BFC5F2DF03D4BE1F6B05FAF6813D072 -:106E70006F8F9A99E85678BEAA52E4AB2A45BE0AAB -:106E8000F1730AE36650BE03F55876433D9691EFE1 -:106E9000B9761794AF24BA6503E9A1EFC1E6225F82 -:106EA0007139938EF4FC8288C367178A7769F9E594 -:106EB0000FF2715E9AA756C4DF2EEBC2F378EAB8E0 -:106EC000E07846E51D3FE0F299C5E9F97BD7B1CC02 -:106ED0008DEF69EF786D34C593021E8D5B17073017 -:106EE000F038CA2FF61AF76F592AE7973B5E4DA183 -:106EF0007ECD220EEA4CE8CE4A40BD2BF84A850FE3 -:106F00007EC3DFF938F30086F275899FCF79477722 -:106F1000563CC001C9A4C1F8B873076FEF117CE7F4 -:106F20009C20E613E761466F3AE2A3FFF06BE9F7B6 -:106F300002BCD1EC5FC6E5BD3F8BE434F367E17B77 -:106F4000A1CB92F72CBEB7FDF5C17F5984EF6B2F13 -:106F5000EBBCCF21FCDB8333382CED3F6B096D4F4D -:106F6000F2A6E37BDC5F1FFCE1227C9F7B3969FF9B -:106F700073F1D61058F7CA596CD73F3C635131F4BE -:106F80009F67F09C6842BA7999D39769DF81F3785B -:106F90003FB51DDC5E9FB5EFC09557501F1F88A100 -:106FA0007CBDAF3083EEBBB963CF63486F81FD3AE0 -:106FB000E2838D6D7F7DEEB7D4CF40619479066F0B -:106FC00001865CDC457FBB1BF7352FDAFB19C29BC2 -:106FD0008B6EA37DCE1BC5F9F9A9A2B98B903F0397 -:106FE00007F6FD0AF96F5E1C18B2B89F174D849F13 -:106FF0009A572717631C2010D35D81F3D7BF60B069 -:10700000229DD6BC9A320BE302C70B797CBA7ACAAE -:10701000A674D4AF9A43CFEFFE2DC6295F30517EC0 -:10702000C695C0EDBB1AB9A56805E16FE76E7C3760 -:107030001278DE4479D26A9803D7ABDE3D89E2EA62 -:10704000AF7FFD4105E2A144DEBE1BEB3FDB65D215 -:10705000E03DF4E8ED713F423EECD1919F592DE0C7 -:10706000EADE517C3FD17DA584BFC44DE9A85F6BAA -:1070700046FDE676DCF73C79D373E8E7B03D06CA17 -:10708000155C7C1EEE0DC65D6CD5D12BD5C0F331E1 -:107090005AA497CBD2A68A6770FE56DEEFB2691368 -:1070A000DDA7BBF52686EB413F86F2EAB2B439ACE8 -:1070B000FE62EB9E5CF4432FBD308FFC5195CE55A4 -:1070C0007EA9D96508D387240992C57B0952B36E7E -:1070D00066063D5B2DC04B07B7059E61C1F197DA8F -:1070E000747E3DDC51B581ADC5F7C12A3FD4A4DD26 -:1070F0005686E7ABD1B464A1BD529DDF57817C7148 -:10710000D1C48CA9F88E4EE8AB9AF635F3D1EE1DBA -:10711000693FB1E25DDFE7820F3FF7993CA1F9C11A -:10712000C8F26F4D4C3915F26EF89E0603D9EEEA9F -:107130007C6FEBBD75E89FD52770F97116FAB781A2 -:107140001C331771B9B76455787FA988BF4BACD78A -:10715000F765A1DE53E7FFA650956B7D5928AF2256 -:10716000C7CD9385BC7951227953D32E9D93E19E4F -:107170006A8C6E0FBEDFA94167929F537B4DE2E39D -:10718000528BC4BDC3D8A78B3268DD9A3693DD0419 -:10719000E36AA3FA62D11EAA8BE98B453B277048AC -:1071A000663B04BA1293057E26089485C41DABBDC8 -:1071B0003ABB2977183CA3DD84EF73F0BF61FDB6BD -:1071C00022CE2755BE685A8F59FA8A904EABB687A1 -:1071D0008FC3735942F82FE0DB991CEA8FDBC4BEE2 -:1071E000FBA573C427FD5FBF9F8E78AFD1B0B59864 -:1071F00047BC24F1EF1E00A6EF1E2E897C64CDDF74 -:10720000CD51482F973EAF23BE0D487D24D7CE1CCD -:107210005C407229A0EB23B9D6535441F22110DF10 -:10722000578172EACCC17ADE3EBAAF4281F64E8413 -:10723000B17D1C237D7FB9E801921FF364FEBE81FE -:10724000EDD459781C687D6F13F9153A25D4EFBE3B -:1072500052A4E66DF4C173CB41BE0930655F3BF2C9 -:10726000619599E239603FB5BD8276DEC2642BC676 -:10727000C5AB701CA7037D68FE2F31E1CB65889FED -:1072800045718E3B8B308F9DD347FE035035D9E936 -:10729000F57F32901FD9AF1BD88D722A37CEB1B08F -:1072A00008F651A7EF5E87A1A72BBABE2ECCFBCD67 -:1072B00095B93C627B385D057276F2EF2444FEB0EE -:1072C000BA88CB5FD05BAC05E942E2F83DE67BF5DE -:1072D00014CA9540F74492C7917C73D1F7442CCAE5 -:1072E00087D3A0C7DD217EFEE9A57B284FBF00DF45 -:1072F000654079EFDA707A18FCEA67E4EFB1C742CB -:10730000EA910EB784C3917484F4E80F933B6EA2A4 -:107310009B3D82AF6A6775D7E33D0CC177002C8730 -:10732000C04723E088FEAC9CDB097BF0BF61DEBA7E -:1073300071FE5EF2CFF7F177B1CDA0BF083E104DE0 -:107340007963CD3ED04F895C3FA15EA88DEDA6B894 -:1073500054E08081F2230F777C4CEF19810E29FED7 -:1073600052DBF15A32FAED3EF41392480F26D33B2A -:1073700095031DC9E86FA8F5751A6F96788F4F763B -:10738000BA5AEF94FD59B8FF5AA93B17DB7D851611 -:10739000D11F60196146E7A89338BFB30E99E4790D -:1073A00024DEF60A7A05B9904BEF2C0EF1B8802A4C -:1073B00007AA853C398AF5399CEF2D6A5E49C2F7E8 -:1073C00072D1C3CA879B8A547BB881E236BB8A14C8 -:1073D0007EAF623CCDCBE34AD45EFFFAE5DC0939EF -:1073E000384E11E342E4D0C4A05C41FE4F25FE7F3D -:1073F00058970CE7AA794EB236A39C5ABCA614BA89 -:10740000B3E5DA15A5142F13EF3F23F7154947F617 -:10741000228EDF1A4D7C4962C87C97C05D4FCD2318 -:107420003943EFE8EF4F7CBC14E313BF58BC99E835 -:107430007948DF84F2399E673B97E3C836D734D763 -:10744000D3F1F286967529C3EC23729FD58E96D21E -:1074500064E5FA7A75BF974CEAFE66E99242EF61FD -:10746000C19AD22428971BFFD17BE0E7BDD461F0FD -:10747000A35EAD5EBC625DDC3074739D3ED81EA21F -:10748000BF26207E3D94D71869FF91659DE4EFC526 -:10749000381103BE6A25FE027E09D10B6542BF0E7C -:1074A000C51BAA968E47BF9339968E473D037C55E0 -:1074B000611DC6AFC42F4B34F476C34D65E47E3EE8 -:1074C0002BE271D2B222CE2FA76CF66F50BE8EF493 -:1074D000BD85619AF4ADDF5BA46906DF417E4B4B4D -:1074E0008E51300F54323B9AF73B6CB260DCA6FFF2 -:1074F000F09714D7ED7FC4BC80E70BCC6C34B47725 -:10750000A54EDD11AA473CD3385F461770BBC59521 -:10751000ADFBF6B8504ECC505C88EC869C68CA93A4 -:10752000047C9F92DEEAEF2CB4603E23D00DDE2176 -:10753000F093EBEBFF4A46FD1AE8FC88DE8305BEBC -:10754000FA98DE896D10EFF48EFAC43BAB6E258697 -:10755000BE8B2BFBA014FB6D1465303EC0E35A6A52 -:10756000A9FAFF21FEEF946985C3FABF090E73687B -:107570005C4049192E8E121A17C8D4F2B80096181A -:1075800017C8CCE4710184312E8025C605B01EE3F6 -:107590000208635C00618C0B208C71012C312E8001 -:1075A000F59F89EF1FFA4130F178A599E4FA4A7CFA -:1075B000DF0EF7B7F230CF3BAD6C95297F8BDF3F05 -:1075C000A07EBBEEDD4CBB7837E3DD4C793CD701C8 -:1075D000D98A2872E9068E631CC7B55FB2AE41B97D -:1075E000D2B480D6DFD059F8DE62AC6FD559350AF7 -:1075F000D111C7638B44EFF46B3A5B29EE549C7254 -:10760000584FF56D12C338E95D06EEE73A65A8CD2F -:10761000A33C28D9C14E4337F91FB57B25A532F4C9 -:107620009DC6F4AB2407D47CF232DEC49C5E935238 -:1076300039CC3B90A177E7E2DDF432CC33E37B71C8 -:10764000F92B7AD7EF04877414D2E156FEFED902E3 -:10765000FF88DF23DE35D574EE5F87EFA122F3CDFF -:1076600043DFD345E49DEBA789BCB28D7F5F51F624 -:1076700064E5BE03B0DEE02603D91BEE42C703D3A8 -:107680009230EF6FA7F8C8F1C326F28B3EDC7C5333 -:10769000587C84E53B1E9C46F9F9B114AF68D44987 -:1076A000A48F67974D4CC17B9C7D42477AA737AF2B -:1076B0007C35F66B9CAA503CAAC4C01EA079C47B42 -:1076C00029151F25CD924703F05266A577F64BE0AA -:1076D0009A305ED9AF33AFC7774D4B187FE7A0D252 -:1076E0004DE36689E8060304789F15E23E9774FE31 -:1076F000F94B7CC7709F81DBAD691A9EBF4EDBC81A -:10770000DF33DCCF1C7AD4B3CB91BA64D28F7FEA5B -:10771000837A47F4D8746E972B2938FFD2933A7A3C -:107720006F5B92F2932C07E9E9627AC720F917C9D7 -:10773000D76E1E997F22DF311CD771B902F748FE40 -:107740005017D225C5651C549E6CAAA2F277E27B25 -:1077500088EBDFFF0F9C453F312D25C68A726EC432 -:10776000EFDDA2BEFD7BAF17C4FBB5344D4FBE822B -:10777000F7F177B315EF437D2778CA56BE1FF16442 -:107780008F656E0B7D0F061210EEB5140F22615C33 -:10779000DB6BC7EF8E060E4B167A977C9D7CDCFC6C -:1077A00008BE1371654A1649C1F8F7A69264D877E6 -:1077B000E9840CDAB7CBC7E3A37443C9183FE7F8F1 -:1077C0004ACF731C9B5618AC9F27F82600FD399DA5 -:1077D000FCD083F4F61DE2A6BBB0BF9B99E87B6AA0 -:1077E000FA83FDCCBB791CC54F55BA196C4BD981B6 -:1077F00074F39E90FB8B17BFAB43FDDF9BEFE8C19B -:107800007D54545E7D2499CE377CFC4A7DA71E1999 -:10781000BF0A959FFF3FDEA79F6A6AA0F29DA6550B -:10782000547637B9A93D44FE5F1A41FE47C63FAFC3 -:10783000227F47C63F99518923FD09FCCDE3CD1135 -:10784000F1CEB251F7AE87FB9BBD456FC52A35FE21 -:1078500089EF87579A491EFCF7B461E39EEABD9908 -:10786000294E3AC84C7978FFB3B2276A35D0AE9D1D -:10787000CEF1A7C61D913FF07CC81F58227F68B586 -:1078800041FE78560F2C5CC0F5BC9BF4BC89F0BA65 -:107890006E0DC80F80EF639630F97125427E80C36C -:1078A00071377D57D56960182754DF51CE82E28B3E -:1078B000BC61E48997CB937151DEE7E97BFFFA283D -:1078C0007A9F7B5CBC873BBE81BF87AB64E5B4EE2F -:1078D00030722516F171DFA881B37F80FEF7FDDEDF -:1078E0004CF6CABAD1CB8AFE19B9724D7CD7F234A4 -:1078F000FEAE80F6DB7E57E03109F3A18DF7301B39 -:10790000E259FD5D811491CFFE1EBF2B306D7AE1EF -:1079100077FF5D815BA78F5F1CFABB02B7FA323835 -:10792000ACFEAE001BBF7884DF15983D3DE9FADF61 -:1079300015B86D3AF71747FA5D01B027CB705C9226 -:10794000CD3E07CB34B1CFC8EF694F8AFC5D97C6F7 -:10795000B118CBD258B796EA359E02FA0E5EE3FD17 -:1079600025F981F98E9FE3794B9FB04DC90638CD3B -:10797000E02539D99B67BF13EBAFD9EC77E13A919A -:107980007173C42DFAF7B09FBBB13DF2DD958ACF7C -:1079900015D3B9DC6814E58CE6E1BF276F9CCEF304 -:1079A000F237DA37ECB706D71BDAFFA6A505B81F02 -:1079B000D86F2DD6C37EEBB064E684B0EF53AFA78B -:1079C0003337D155E3744E5F20CFE67DC8ED412AB1 -:1079D000B3B49E78B41FC73CE489C7FD8E691930E3 -:1079E000E177107F740F9850BFFF71F58009EBFFAE -:1079F00068E7EF9523E77F793AF703B2660CD0F892 -:107A0000F168E3937D3E108FF65356D587EB28DF60 -:107A1000B27732E997F142BF8C7F6882AF0FE86D91 -:107A2000FCB638CA67B3E2446AAF31723EAD79A89A -:107A3000F2E00185BEDB9AF76188BD33D903FB0E06 -:107A4000B3BFB483FCDD25C0784F7B750423CDA282 -:107A50007DE564FCDDE5182137D04E5B0C72C15921 -:107A6000F5E69794F7C7F1381FE66891FE7CBA41B6 -:107A7000F17D9A05FDD0E50BD674915FB875A85ECF -:107A8000F899FBD7A1DF0CF65B587D4DE5912ED41C -:107A900037B57BC3EB9D0D57C97F05FB2DACFE9E13 -:107AA0005F9ED3F3DF2F08AF07FCEE45BA54F17B9E -:107AB0005CE79D8C7EDE71679495BFDFF7D2EF9512 -:107AC000EC10DF3FEFFC8F599C6E04BE61BC377435 -:107AD000FCC8F4D14CFDDDB35836F2C38D4A552EA7 -:107AE0000DFDFE899EB929BE373786E48E4BF855C9 -:107AF000F59516D2F369F546925F25729415E1A1CA -:107B0000DF3F2993859CF212FFF7DC1E4F713C3A50 -:107B100000C2095329EF93DCCCE1812403C9871209 -:107B20004D79DD1E28DFD4847FC7FE2CCA0719F9E2 -:107B3000977F87E9D27BF977E25AA510FDDC66C909 -:107B4000BE0DBF7B6C96441CB1DA4CF9827E8C2F43 -:107B5000C279B6C47BB62D8375B6DC9943F6713F06 -:107B6000E3F2D4BD80E7ADB6C4972F5E81ED0BA7DD -:107B700050FBC16F263E5E80F653759415EDA72D20 -:107B8000366E5F6F999F4DEDAF4BCA1A3CB7FB2124 -:107B900046EB6C99CFCFBDE5F171E2FB0B8F09F994 -:107BA000794B8B7D34E6A366591C17105F63443E06 -:107BB0006E4B06D443F99454BEF07E9C672ADFEFE7 -:107BC000EF6C0AC98FE30BA73CBE5B2135E2C7BC53 -:107BD000906B6E0CF9C1FF0BB81F749470470000D6 -:107BE0000000000000000000050207000000000087 -:00000001FF diff --git a/firmware/bnx2x-e1h-5.2.7.0.fw.ihex b/firmware/bnx2x-e1h-5.2.7.0.fw.ihex deleted file mode 100644 index 280bbcf..0000000 --- a/firmware/bnx2x-e1h-5.2.7.0.fw.ihex +++ /dev/null @@ -1,12847 +0,0 @@ -:1000000000003BE8000000600000068800003C5053 -:1000100000001968000042E0000000AC00005C50E5 -:1000200000008DE400005D00000000EC0000EAE844 -:100030000000E3000000EBD8000000940001CEE0D7 -:10004000000058E80001CF78000000C400022868D2 -:100050000000F9700002293000000004000322A80B -:10006000020400480000000F020400540000004594 -:1000700002040058000000840204005C0000000636 -:100080000204007000000004020400780000000078 -:100090000204007C121700000204008022170000F6 -:1000A00002040084321700000604008800000005E6 -:1000B0000204009C12150000020400A0221500009A -:1000C000020400A432150000060400A80000000489 -:1000D000020400B802100000020400BC001000007E -:1000E000020400C010100000020400C42010000030 -:1000F000020400C830100000020400CC40100000D0 -:10010000060400D000000003020400DC0010000020 -:10011000020400E012140000020400E422140000B3 -:10012000020400E832140000020400EC4214000053 -:10013000060400F000000003010401240000000098 -:1001400001040128000000000104012C000000004F -:100150000104013000000000020401D00000890603 -:1001600002040004000000FF02040008000000FF79 -:100170000204000C000000FF02040010000000FF59 -:1001800002040014000000FF02040018000000FF39 -:100190000204001C000000FF02040020000000FF19 -:1001A000020400240000003E0204002800000000B9 -:1001B0000204002C0000003F020400300000003F59 -:1001C000020400340000003F020400380000003F39 -:1001D0000204003C0000003F020400400000003F19 -:1001E000020400440000003F020404CC00000001AF -:1001F00002042008000002110204200C000002008A -:10020000020420100000020402042014000002195D -:100210000204201C0000FFFF020420200000FFFF5A -:10022000020420240000FFFF020420280000FFFF3A -:1002300002042038000000200204203C00000000DE -:100240000204204000000034020420440000003575 -:10025000060420480000001C020420B80000000131 -:10026000060420BC0000005F0204223807FFFFFFE5 -:100270000204223C0000003F0204224007FFFFFF6F -:10028000020422440000000F010422480000000084 -:100290000104224C00000000010422500000000074 -:1002A0000104225400000000010422580000000054 -:1002B0000104225C00000000010422600000000034 -:1002C0000104226400000000010422680000000014 -:1002D0000104226C000000000104227000000000F4 -:1002E00001042274000000000104227800000000D4 -:1002F0000104227C000000000C042000000003E840 -:100300000A042000000000010B0420000000000A85 -:1003100002050044000000200205004800000032F1 -:10032000020500900215002002050094021500202D -:1003300002050098000000300205009C0810000033 -:10034000020500A000000033020500A400000030F8 -:10035000020500A800000031020500AC0000000208 -:10036000020500B000000005020500B40000000610 -:10037000020500B800000002020500BC00000002F7 -:10038000020500C000000000020500C400000005D6 -:10039000020500C800000002020500CC00000002B7 -:1003A000020500D000000002020500D40000000198 -:1003B00002050114000000010205011C00000001FB -:1003C00002050120000000020205020400000001F5 -:1003D0000205020C0000004002050210000000406F -:1003E0000205021C0000002002050220000000138C -:1003F0000205022400000020060502400000000A59 -:1004000004050280002000000205005000000007E3 -:100410000205005400000007020500580000000813 -:100420000205005C000000080205006000000001F9 -:100430000605006400000003020500D80000000665 -:100440000205000400000001020500080000000190 -:100450000205000C00000001020500100000000170 -:100460000205001400000001020500180000000150 -:100470000205001C00000001020500200000000130 -:100480000205002400000001020500280000000110 -:100490000205002C000000010205003000000001F0 -:1004A00002050034000000010205003800000001D0 -:1004B0000205003C000000010205004000000001B0 -:1004C000020500E00000000D020500E80000000742 -:1004D000020500F000000007020500F80000000718 -:1004E000020500E40000002D020500EC00000027DA -:1004F000020500F400000027020500FC00000027B0 -:10050000020500E00000001D020500E800000017E1 -:10051000020500F000000017020500F800000017B7 -:10052000020500E40000003D020500EC0000003779 -:10053000020500F400000037020500FC000000374F -:10054000020500E00000004D020500E80000004741 -:10055000020500F000000047020500F80000004717 -:10056000020500E40000006D020500EC00000067D9 -:10057000020500F400000067020500FC00000067AF -:10058000020500E00000005D020500E800000057E1 -:10059000020500F000000057020500F800000057B7 -:1005A000020500E40000007D020500EC0000007779 -:1005B000020500F400000077020500FC000000774F -:1005C0000406100002000020020600DC000000010A -:1005D000010600D80000000004060200000302200B -:1005E000020600DC00000000010600B80000000068 -:1005F000010600C800000000010600BC0000000069 -:10060000010600CC000000000718040000A900004B -:10061000081807C800070223071C00002C2100004F -:10062000071C800038930B09071D0000292B192E89 -:10063000081D685052F60225011800000000000055 -:10064000011800040000000001180008000000006C -:100650000118000C0000000001180010000000004C -:100660000118001400000000021800200000000122 -:1006700002180024000000020218002800000003F5 -:100680000218002C000000000218003000000004D6 -:1006900002180034000000010218003800000000B9 -:1006A0000218003C00000001021800400000000495 -:1006B0000218004400000000021800480000000179 -:1006C0000218004C00000003021800500000000057 -:1006D0000218005400000001021800580000000435 -:1006E0000218005C00000000021800600000000119 -:1006F00002180064000000030218006800000000F7 -:100700000218006C000000010218007000000004D4 -:1007100002180074000000000218007800000004B5 -:100720000218007C00000003061800800000000290 -:10073000021800A400003FFF021800A8000003FFF9 -:100740000218022400000000021802340000000019 -:100750000218024C00000000021802E4000000FF32 -:100760000618100000000400021B8BC000000001EE -:10077000021B800000000034021B804000000018B3 -:10078000021B80800000000C021B80C000000020C3 -:100790000C1B83000007A1200A1B83000000013806 -:1007A0000B1B830000001388021B83C0000001F4B0 -:1007B000021B1480000000010A1B148000000000CE -:1007C000061A1000000003B3041A1ECC0001022711 -:1007D000061AA020000000C8061AA00000000002AF -:1007E000021A1ED000000000061A1ED800000006E3 -:1007F000061A36E800000004061A36E0000000027F -:10080000061A500000000002061A500800000004FA -:10081000061A501800000004061A502800000004B0 -:10082000061A503800000004061A50480000000460 -:10083000061A505800000004061A50680000000410 -:10084000061A507800000002041A404000020228F4 -:10085000061A400000000002061A400800000002CC -:10086000041A62C00020022A061AD1000000000209 -:10087000061A200000000124061AB000000000281B -:10088000061AB1400000000C061A330000000014E4 -:10089000061A33A000000068061A81080000000252 -:1008A000061AD1C800000002061AD1D800000020A4 -:1008B000061A249000000124061AB0A000000028A7 -:1008C000061AB1700000000C061A33500000001424 -:1008D000061A354000000068061A81100000000268 -:1008E000061AD1D000000002061AD25800000020DB -:1008F000021A292000000000061A30000000000241 -:10090000041A30080005024A061A301C00000009CB -:10091000061A320000000008061A5000000000020B -:10092000061A508000000012061A40000000000263 -:10093000061AD0C000000002021A2924000000009C -:10094000061A304000000002041A30480005024F29 -:10095000061A305C00000009061A32200000000868 -:10096000061A501000000002061A50C800000012BB -:10097000061A400800000002061AD0C80000000253 -:10098000021A292800000000061A30800000000228 -:10099000041A308800050254061A309C0000000931 -:1009A000061A324000000008061A5020000000021B -:1009B000061A511000000012041A401000020259D9 -:1009C000061AD0D000000002021A292C00000000F4 -:1009D000061A30C000000002041A30C80005025B8D -:1009E000061A30DC00000009061A32600000000818 -:1009F000061A503000000002061A5158000000127A -:100A0000041A401800020260061AD0D80000000242 -:100A1000021A293000000000061A3100000000020E -:100A2000041A310800050262061A311C0000000990 -:100A3000061A328000000008061A5040000000022A -:100A4000061A51A000000012041A4020000202679A -:100A5000061AD0E000000002021A2934000000004B -:100A6000061A314000000002041A314800050269EC -:100A7000061A315C00000009061A32A000000008C6 -:100A8000061A505000000002061A51E80000001239 -:100A9000041A40280002026E061AD0E80000000284 -:100AA000021A293800000000061A318000000002F6 -:100AB000041A318800050270061A319C00000009F2 -:100AC000061A32C000000008061A5060000000023A -:100AD000061A523000000012041A4030000202755B -:100AE000061AD0F000000002021A293C00000000A3 -:100AF000061A31C000000002041A31C8000502774E -:100B0000061A31DC00000009061A32E00000000875 -:100B1000061A507000000002061A527800000012F7 -:100B2000041A40380002027C061AD0F800000002C5 -:100B30000200A294071D29110200A29800000000E3 -:100B40000200A29C009C04240200A2A0000000005D -:100B50000200A2A4000002090200A270000000002E -:100B60000200A274000000000200A2700000000059 -:100B70000200A274000000000200A2700000000049 -:100B80000200A274000000000200A2700000000039 -:100B90000200A27400000000020100B40000000185 -:100BA000020100B800000001020100DC00000001A9 -:100BB0000201010000000001020101040000000127 -:100BC0000201007C003000000201008400000028C7 -:100BD0000201008C0000000002010130000000044E -:100BE0000201025C00000001020103280000000075 -:100BF0000201607000000007020160800000000137 -:100C00000201055400000030020100C40000000190 -:100C1000020100CC00000001020100F80000000108 -:100C2000020100F00000000102010080003000001D -:100C3000020100880000002802010090000000006E -:100C40000201013400000004020102DC0000000186 -:100C50000201032C00000000020160740000000784 -:100C60000201608400000001020105640000003000 -:100C7000020100C800000001020100D000000001D4 -:100C8000020100FC00000001020100F4000000016C -:100C9000020C100000000020020C200800000211CD -:100CA000020C200C00000200020C201000000204C4 -:100CB000020C201C0000FFFF020C20200000FFFFA0 -:100CC000020C20240000FFFF020C20280000FFFF80 -:100CD000060C203800000002020C20400000003406 -:100CE000020C204400000035020C204800000020C7 -:100CF000020C204C00000021020C205000000022B9 -:100D0000020C205400000023020C20580000002494 -:100D1000020C205C00000025020C20600000002670 -:100D2000020C206400000027020C2068000000284C -:100D3000020C206C00000029020C20700000002A28 -:100D4000020C20740000002B060C207800000056D6 -:100D5000020C21D000000001020C21D4000000018F -:100D6000020C21D800000001020C21DC000000016F -:100D7000020C21E000000001020C21E4000000014F -:100D8000020C21E800000001020C21EC000000012F -:100D9000020C21F000000001020C21F4000000010F -:100DA000060C21F800000010020C223807FFFFFF9C -:100DB000020C223C0000003F020C224007FFFFFF14 -:100DC000020C22440000000F010C22480000000029 -:100DD000010C224C00000000010C22500000000019 -:100DE000010C225400000000010C225800000000F9 -:100DF000010C225C00000000010C226000000000D9 -:100E0000010C226400000000010C226800000000B8 -:100E1000010C226C00000000010C22700000000098 -:100E2000010C227400000000010C22780000000078 -:100E3000010C227C000000000C0C2000000003E8E4 -:100E40000A0C2000000000010B0C20000000000A2A -:100E5000020C400800000411020C400C00000400C9 -:100E6000020C401000000404020C40140000042195 -:100E7000020C401C0000FFFF020C40200000FFFF9E -:100E8000020C40240000FFFF020C40280000FFFF7E -:100E9000020C403800000046020C403C00000005F7 -:100EA000060C404000000002020C40480000000A0E -:100EB000020C404C000000F0060C40500000001FE7 -:100EC000020C40CC00000001060C40D00000003AAB -:100ED000020C41B800000001060C41BC00000003F8 -:100EE000020C41C800000001020C41CC00000001CE -:100EF000060C41D00000001A020C423807FFFFFF29 -:100F0000020C423C0000003F020C424007FFFFFF82 -:100F1000020C42440000000F010C42480000000097 -:100F2000010C424C00000000010C42500000000087 -:100F3000010C425400000000010C42580000000067 -:100F4000010C425C00000000010C42600000000047 -:100F5000010C426400000000010C42680000000027 -:100F6000010C426C00000000010C42700000000007 -:100F7000010C427400000000010C427800000000E7 -:100F8000010C427C00000000010C428000000000C7 -:100F90000C0C4000000003E80A0C400000000001B7 -:100FA0000B0C40000000000A020D0044000000325B -:100FB000020D008C02150020020D00900215002089 -:100FC000020D009408100000020D0098000000338C -:100FD000020D009C00000002020D00A000000000B5 -:100FE000020D00A400000005020D00A8000000058D -:100FF000060D00AC00000002020D00B4000000026B -:10100000020D00B800000003020D00BC0000000249 -:10101000020D00C000000001020D00C80000000227 -:10102000020D00CC00000002020D010800000001CA -:10103000020D015C00000001020D016400000001CE -:10104000020D016800000002020D02040000000110 -:10105000020D020C00000020020D021000000040F2 -:10106000020D021400000040020D022000000003E7 -:10107000020D022400000018060D0280000000127C -:10108000040D03000024027E020D004C000000014C -:10109000020D005000000002020D00540000000884 -:1010A000020D005800000008060D005C000000045E -:1010B000020D00C400000004020D00040000000145 -:1010C000020D000800000001020D000C00000001EC -:1010D000020D001000000001020D001400000001CC -:1010E000020D001800000001020D001C00000001AC -:1010F000020D002000000001020D0024000000018C -:10110000020D002800000001020D002C000000016B -:10111000020D003000000001020D0034000000014B -:10112000020D003800000001020D003C000000012B -:10113000020D011400000009020D011C0000000A4C -:10114000020D012400000007020D012C0000000721 -:10115000020D01340000000C020D013C0000000BE8 -:10116000020D014400000007020D011800000029D3 -:10117000020D01200000002A020D012800000027B6 -:10118000020D013000000027020D01380000002C84 -:10119000020D01400000002B020D01480000002755 -:1011A000020D011400000019020D011C0000001ABC -:1011B000020D012400000017020D012C0000001791 -:1011C000020D01340000001C020D013C0000001B58 -:1011D000020D014400000017020D01180000003943 -:1011E000020D01200000003A020D01280000003726 -:1011F000020D013000000037020D01380000003CF4 -:10120000020D01400000003B020D014800000037C4 -:10121000020D011400000049020D011C0000004AEB -:10122000020D012400000047020D012C00000047C0 -:10123000020D01340000004C020D013C0000004B87 -:10124000020D014400000047020D01180000006972 -:10125000020D01200000006A020D01280000006755 -:10126000020D013000000067020D01380000006C23 -:10127000020D01400000006B020D014800000067F4 -:10128000020D011400000059020D011C0000005A5B -:10129000020D012400000057020D012C0000005730 -:1012A000020D01340000005C020D013C0000005BF7 -:1012B000020D014400000057020D011800000079E2 -:1012C000020D01200000007A020D012800000077C5 -:1012D000020D013000000077020D01380000007C93 -:1012E000020D01400000007B020D01480000007764 -:1012F000020E004C00000032020E00940215002085 -:10130000020E009802150020020E009C0000003022 -:10131000020E00A008100000020E00A4000000331E -:10132000020E00A800000030020E00AC00000031E8 -:10133000020E00B000000002020E00B40000000423 -:10134000020E00B800000000020E00BC0000000207 -:10135000020E00C000000002020E00C400000000E7 -:10136000020E00C800000002020E00CC00000007C0 -:10137000020E00D000000002020E00D400000002A5 -:10138000020E00D800000001020E00E4000000017F -:10139000020E014400000001020E014C0000000199 -:1013A000020E015000000002020E020400000001C3 -:1013B000020E020C00000040020E0210000000406D -:1013C000020E021C00000004020E02200000002099 -:1013D000020E02240000000E020E02280000001B74 -:1013E000060E030000000012040E0280001B02A281 -:1013F000020E00540000000C020E0058000000090C -:10140000020E005C0000000F020E006000000010E1 -:10141000020E00640000000B060E006800000003CE -:10142000020E00DC00000003020E000400000001B8 -:10143000020E000800000001020E000C0000000176 -:10144000020E001000000001020E00140000000156 -:10145000020E001800000001020E001C0000000136 -:10146000020E002000000001020E00240000000116 -:10147000020E002800000001020E002C00000001F6 -:10148000020E003000000001020E003400000001D6 -:10149000020E003800000001020E003C00000001B6 -:1014A000020E004000000001020E00440000000196 -:1014B000020E01100000000F020E01180000000EC5 -:1014C000020E012000000000020E012800000000B2 -:1014D000020E01140000002F020E011C0000002E5D -:1014E000020E012400000000020E012C000000008A -:1014F000020E01100000001F020E01180000001E65 -:10150000020E012000000000020E01280000000071 -:10151000020E01140000003F020E011C0000003EFC -:10152000020E012400000000020E012C0000000049 -:10153000020E01100000004F020E01180000004EC4 -:10154000020E012000000000020E01280000000031 -:10155000020E01140000006F020E011C0000006E5C -:10156000020E012400000000020E012C0000000009 -:10157000020E01100000005F020E01180000005E64 -:10158000020E012000000000020E012800000000F1 -:10159000020E01140000007F020E011C0000007EFC -:1015A000020E012400000000020E012C00000000C9 -:1015B0000730040000E80000083007D8000502BD2D -:1015C000073400002EAA000007348000312D0BAB39 -:1015D00007350000358217F707358000396D25582B -:1015E00007360000142D33B40836321039BE02BF5E -:1015F0000130000000000000013000040000000085 -:1016000001300008000000000130000C0000000064 -:101610000130001000000000013000140000000044 -:10162000023000200000000102300024000000020F -:1016300002300028000000030230002C00000000EF -:1016400002300030000000040230003400000001CD -:1016500002300038000000000230003C00000001B1 -:10166000023000400000000402300044000000008E -:1016700002300048000000010230004C000000036E -:101680000230005000000000023000540000000151 -:1016900002300058000000040230005C000000002E -:1016A000023000600000000102300064000000030E -:1016B00002300068000000000230006C00000001F1 -:1016C00002300070000000040230007400000000CE -:1016D00002300078000000040230007C00000003AB -:1016E0000630008000000002023000A400003FFF2E -:1016F000023000A8000003FF0230022400000000B6 -:1017000002300234000000000230024C00000000F1 -:10171000023002E40000FFFF063020000000080055 -:1017200002338BC000000001023380000000001A69 -:10173000023380400000004E023380800000001021 -:10174000023380C0000000200C3383000007A1207A -:101750000A338300000001380B3383000000138834 -:10176000023383C0000001F40C3383801DCD65007B -:101770000A3383800004C4B40B338380004C4B4095 -:101780000A331480000000000233148000000001BE -:10179000063220000000010206328020000000C84E -:1017A000063280000000000206323DA8000000045E -:1017B00006323D800000000904323DA4000102C150 -:1017C00006323D00000000200632500000000400F8 -:1017D0000632400000000004063240D00000000243 -:1017E00006326B680000000204326B70000202C215 -:1017F00006326B1000000002043274C0000202C402 -:101800000632DA40000000020632E0000000080064 -:10181000023308000100000004330C00001002C66F -:10182000023308000000000004330C40001002D610 -:1018300006322450000000B406322AD00000000214 -:1018400006321000000001A002323DB80000000086 -:101850000632500000000020063251000000002037 -:101860000632520000000020063253000000002023 -:10187000063254000000002006325500000000200F -:1018800006325600000000200632570000000020FB -:1018900006325800000000200632590000000020E7 -:1018A00006325A000000002006325B0000000020D3 -:1018B00006325C000000002006325D0000000020BF -:1018C00006325E000000002006325F0000000020AB -:1018D00006326B780000005206326E080000000CE1 -:1018E0000632DA880000000206322720000000B429 -:1018F00006322AD80000000206321680000001A03D -:1019000002323DBC00000000063250800000002082 -:101910000632518000000020063252800000002074 -:101920000632538000000020063254800000002060 -:10193000063255800000002006325680000000204C -:101940000632578000000020063258800000002038 -:10195000063259800000002006325A800000002024 -:1019600006325B800000002006325C800000002010 -:1019700006325D800000002006325E8000000020FC -:1019800006325F800000002006326CC0000000526A -:1019900006326E380000000C0632DA9000000002B9 -:1019A00002322A300000000006324010000000021F -:1019B0000632D0000000000602322A340000000087 -:1019C00006324020000000020632D0180000000657 -:1019D00002322A38000000000632403000000002C7 -:1019E0000632D0300000000602322A3C000000001F -:1019F00006324040000000020632D04800000006D7 -:101A000002322A400000000006324050000000026E -:101A10000632D0600000000602322A4400000000B6 -:101A200006324060000000020632D0780000000656 -:101A300002322A4800000000063240700000000216 -:101A40000632D0900000000602322A4C000000004E -:101A500006324080000000020632D0A800000006D6 -:101A6000072004000093000008200780001002E611 -:101A7000072400002ADE0000072480002E050AB893 -:101A80000824E4A061D202E8012000000000000068 -:101A900001200004000000000120000800000000F8 -:101AA0000120000C000000000120001000000000D8 -:101AB00001200014000000000220002000000001AE -:101AC0000220002400000002022000280000000381 -:101AD0000220002C00000000022000300000000462 -:101AE0000220003400000001022000380000000045 -:101AF0000220003C00000001022000400000000421 -:101B00000220004400000000022000480000000104 -:101B10000220004C000000030220005000000000E2 -:101B200002200054000000010220005800000004C0 -:101B30000220005C000000000220006000000001A4 -:101B40000220006400000003022000680000000082 -:101B50000220006C00000001022000700000000460 -:101B60000220007400000000022000780000000441 -:101B70000220007C0000000306200080000000021C -:101B8000022000A400003FFF022000A8000003FF85 -:101B900002200224000000000220023400000000A5 -:101BA0000220024C00000000022002E40000FFFFBF -:101BB000062020000000080002238BC00000000166 -:101BC0000223800000000010022380400000001269 -:101BD0000223808000000030022380C00000000E3D -:101BE000022383C0000001F40223148000000001DE -:101BF0000A231480000000000622100000000042AA -:101C000006227020000000C80622700000000002BA -:101C1000022211E80000000006223000000000C08F -:101C2000062240700000008006225280000000045E -:101C30000622670000000100062290000000040058 -:101C400004226B08002002EA02230800013FFFFF84 -:101C500004230C000010030A022308000000000007 -:101C600004230C400010031A06228100000000A08B -:101C7000062286000000004006228C000000003C86 -:101C80000622B0000000020006228800000000804A -:101C900006228DE00000003C0622404000000006C5 -:101CA00006228380000000A006228700000000407A -:101CB00006228CF00000003C0622B8000000020062 -:101CC00006228A000000008006228ED00000003C20 -:101CD000062240580000000606228000000000088E -:101CE000022211480000000006223300000000021A -:101CF000062260400000003006228020000000081C -:101D00000222114C000000000622330800000002ED -:101D1000062261000000003006228040000000081A -:101D200002221150000000000622331000000002C1 -:101D3000062261C00000003006228060000000081A -:101D40000222115400000000062233180000000295 -:101D50000622628000000030062280800000000819 -:101D60000222115800000000062233200000000269 -:101D70000622634000000030062280A00000000818 -:101D80000222115C0000000006223328000000023D -:101D90000622640000000030062280C00000000817 -:101DA0000222116000000000062233300000000211 -:101DB000062264C000000030062280E00000000817 -:101DC00002221164000000000622333800000002E5 -:101DD0000622658000000030021610000000002876 -:101DE00002170008000000020217002C0000000388 -:101DF0000217003C00000004021700440000000825 -:101E000002170048000000020217004C000000907A -:101E1000021700500000009002170054008000904C -:101E20000217005808140000021700600000008A22 -:101E300002170064000000800217006800000081A3 -:101E40000217006C000000800217007000000006FE -:101E500002170078000007D00217007C0000076C12 -:101E600002170038007C1004021700040000000F65 -:101E70000616402400000002021640700000001CFC -:101E80000216420800000001021642100000000184 -:101E90000216422000000001021642280000000144 -:101EA0000216423000000001021642380000000114 -:101EB00002164260000000020C16401C0003D09085 -:101EC0000A16401C0000009C0B16401C000009C4B0 -:101ED0000216403000000008021640340000000CDA -:101EE0000216403800000010021640440000002096 -:101EF0000216400000000001021640D80000000158 -:101F000002164008000000010216400C000000010B -:101F100002164010000000010216424000000000BE -:101F2000021642480000000006164270000000023F -:101F30000216425000000000021642580000000045 -:101F40000616428000000002021660080000042409 -:101F50000216600C00000410021660100000041449 -:101F60000216601C0000FFFF021660200000FFFF49 -:101F7000021660240000FFFF021660280000FFFF29 -:101F800002166038000000200216603C00000020AD -:101F90000216604000000034021660440000003564 -:101FA00002166048000000230216604C0000002466 -:101FB0000216605000000025021660540000002642 -:101FC00002166058000000270216605C000000291D -:101FD000021660600000002A021660640000002BF8 -:101FE000021660680000002C0216606C0000002DD4 -:101FF0000616607000000052021661B80000000171 -:10200000061661BC0000001F0216623807FFFFFFC2 -:102010000216623C0000003F0216624007FFFFFF0D -:10202000021662440000000F011662480000000022 -:102030000116624C00000000011662500000000012 -:1020400001166254000000000116625800000000F2 -:102050000116625C000000000116626000000000D2 -:1020600001166264000000000116626800000000B2 -:102070000116626C00000000011662700000000092 -:102080000116627400000000011662780000000072 -:102090000116627C000000000C166000000003E8DE -:1020A0000A166000000000010B1660000000000A24 -:1020B0000216804000000006021680440000000561 -:1020C000021680480000000A0216804C000000053D -:1020D0000216805400000002021680CC00000004AA -:1020E000021680D000000004021680D40000000414 -:1020F000021680D800000004021680DC00000004F4 -:10210000021680E000000004021680E400000004D3 -:10211000021680E800000004021688040000000493 -:10212000021680300000007C021680340000003D62 -:10213000021680380000003F0216803C0000009C20 -:10214000021680F000000007061680F4000000056B -:102150000216880C0101010102168108000000002E -:102160000216810C00000004021681100000000419 -:1021700002168114000000020216881008012004D3 -:1021800002168118000000050216811C00000005DF -:1021900002168120000000050216812400000005BF -:1021A0000216882C20081001021681280000000861 -:1021B0000216812C00000006021681300000000784 -:1021C000021681340000000002168830010101204F -:1021D000061681380000000402168834010101014E -:1021E00002168148000000000216814C0000000425 -:1021F0000216815000000004021681540000000203 -:1022000002168838080120040216815800000005D3 -:102210000216815C000000050216816000000005C6 -:1022200002168164000000050216883C2008100197 -:1022300002168168000000080216816C000000068A -:102240000216817000000007021681740000000170 -:102250000216884001010120021681780000000169 -:102260000216817C0000000102168180000000013E -:102270000216818400000001021688440101010158 -:1022800002168188000000010216818C0000000403 -:1022900002168190000000040216819400000002E2 -:1022A00002168848080120040216819800000005E3 -:1022B0000216819C00000005021681A000000005A6 -:1022C000021681A4000000050216881420081001DF -:1022D000021681A800000008021681AC000000066A -:1022E000021681B000000007021681B40000000150 -:1022F0000216881801010120021681B800000001B1 -:10230000021681BC00000001021681C0000000011D -:10231000021681C4000000010216881C010101019F -:10232000021681C800000001021681CC00000004E2 -:10233000021681D000000004021681D400000002C1 -:102340000216882008012004021681D8000000052A -:10235000021681DC00000005021681E00000000585 -:10236000021681E4000000050216882420081001EE -:10237000021681E800000008021681EC0000000649 -:10238000021681F0000000070216E40C00000000B5 -:1023900002168828010101200616E410000000043E -:1023A0000216E000010101010216E4200000000015 -:1023B0000216E424000000040216E42800000004D1 -:1023C0000216E42C000000020216E00408012004BA -:1023D0000216E430000000050216E4340000000597 -:1023E0000216E438000000050216E43C0000000577 -:1023F0000216E008200810010216E4400000000860 -:102400000216E444000000060216E448000000073B -:102410000216E44C000000000216E00C010101204D -:102420000616E450000000040216E010010101014C -:102430000216E460000000000216E46400000004DC -:102440000216E468000000040216E46C00000002BA -:102450000216E014080120040216E47000000005D2 -:102460000216E474000000050216E478000000057E -:102470000216E47C000000050216E0182008100196 -:102480000216E480000000080216E4840000000642 -:102490000216E488000000070216E48C0000000128 -:1024A0000216E01C010101200216E4900000000168 -:1024B0000216E494000000010216E49800000001F6 -:1024C0000216E49C000000010216E0200101010157 -:1024D0000216E4A0000000010216E4A400000004BB -:1024E0000216E4A8000000040216E4AC000000029A -:1024F0000216E024080120040216E4B000000005E2 -:102500000216E4B4000000050216E4B8000000055D -:102510000216E4BC000000050216E02820081001A5 -:102520000216E4C0000000080216E4C40000000621 -:102530000216E4C8000000070216E4CC0000000107 -:102540000216E02C010101200216E4D00000000177 -:102550000216E4D4000000010216E4D800000001D5 -:102560000216E4DC000000010216E0300101010166 -:102570000216E4E0000000010216E4E4000000049A -:102580000216E4E8000000040216E4EC0000000279 -:102590000216E034080120040216E4F000000005F1 -:1025A0000216E4F4000000050216E4F8000000053D -:1025B0000216E4FC000000050216E03820081001B5 -:1025C0000216E500000000080216E50400000006FF -:1025D0000216E508000000070216E03C0101012098 -:1025E00002168240003F003F0216824400000000B5 -:1025F0000216E524003F003F0216E5280000000017 -:1026000002168248000000000216824C003F003F84 -:102610000216E52C000000000216E530003F003FE6 -:1026200002168250010001000216825401000100CE -:102630000216E534010001000216E5380100010030 -:1026400006168258000000020216E53C0000000059 -:102650000216E540000000000216826000C000C0C3 -:102660000216826400C000C00216E54400C000C02B -:102670000216E54800C000C0021682681E001E0057 -:102680000216826C1E001E000216E54C1E001E0083 -:102690000216E5501E001E00021682704000400027 -:1026A00002168274400040000216E55440004000CB -:1026B0000216E55840004000021682788000800033 -:1026C0000216827C800080000216E55C800080009B -:1026D0000216E56080008000021682802000200043 -:1026E00002168284200020000216E56420002000EB -:1026F0000216E5682000200006168288000000020D -:102700000216E56C000000000216E57000000000F3 -:102710000216829000000000021682940000000061 -:102720000216E574000000000216E57800000000C3 -:1027300002168298000000000216829C0000000031 -:102740000216E57C000000000216E5800000000093 -:10275000021682A000000000021682A40000000100 -:10276000061682A80000000A021681F400000C0878 -:10277000021681F800000040021681FC00000100F2 -:1027800002168200000000200216820400000017DA -:1027900002168208000000800216820C000002006F -:1027A00002168210000000000216821801FF01FFCD -:1027B0000216821401FF01FF0216E51001FF01FF5E -:1027C0000216E50C01FF01FF0216823C0000001317 -:1027D000021680900000013F021680600000014058 -:1027E00002168064000001400616806800000002A6 -:1027F00002168070000000C00616807400000007FA -:102800000216809C00000048021680A000000048CC -:10281000061680A400000002021680AC00000048EA -:10282000061680B000000007021682380000800003 -:1028300002168234000025E40216809400007FFF17 -:1028400002168220000F000F0216821C000F000FDC -:102850000216E518000F000F0216E514000F000F16 -:10286000021682280000000002168224FFFFFFFFEC -:102870000216E520000000000216E51CFFFFFFFF26 -:102880000216E6BC000000000216E6C000000002CE -:102890000216E6C4000000010216E6C800000003AC -:1028A0000216E6CC000000040216E6D00000000686 -:1028B0000216E6D4000000050216E6D80000000764 -:1028C000021680EC000000FF02140000000000016E -:1028D0000214000C0000000102140040000000017E -:1028E0000214004400007FFF0214000C00000000EE -:1028F00002140000000000000214006C0000000040 -:102900000214000400000001021400300000000165 -:1029100002140004000000000214005C000000002B -:10292000021400080000000102140034000000013D -:102930000214000800000000021400600000000003 -:102940000202005800000032020200A0031500201D -:10295000020200A403150020020200A801000030BA -:10296000020200AC08100000020200B000000033B8 -:10297000020200B400000030020200B80000003182 -:10298000020200BC00000003020200C000000006BA -:10299000020200C400000003020200C8000000039D -:1029A000020200CC00000002020200D00000000081 -:1029B000020200D400000002020200DC000000005D -:1029C000020200E000000006020200E40000000431 -:1029D000020200E800000002020200EC0000000217 -:1029E000020200F000000001020200FC00000006EC -:1029F0000202012000000000020201340000000277 -:102A0000020201B0000000010202020C00000001FD -:102A1000020202140000000102020218000000027B -:102A200002020404000000010202040C0000004045 -:102A300002020410000000400202041C0000000416 -:102A40000202042000000020020204240000000210 -:102A50000202042800000020060205000000001207 -:102A600004020480001F032A020200600000000F1D -:102A70000202006400000007020200680000000B70 -:102A80000202006C0000000E020200700000000E46 -:102A90000602007400000003020200F400000004BB -:102AA0000202000400000001020200080000000110 -:102AB0000202000C000000010202001000000001F0 -:102AC00002020014000000010202001800000001D0 -:102AD0000202001C000000010202002000000001B0 -:102AE0000202002400000001020200280000000190 -:102AF0000202002C00000001020200300000000170 -:102B0000020200340000000102020038000000014F -:102B10000202003C0000000102020040000000012F -:102B2000020200440000000102020048000000010F -:102B30000202004C000000010202005000000001EF -:102B400002020108000000C8020201180000000291 -:102B5000020201C400000000020201CC00000000DB -:102B6000020201D400000002020201DC00000002A7 -:102B7000020201E4000000FF020201EC000000FF7D -:102B800002020100000000000202010C000000C867 -:102B90000202011C00000002020201C80000000045 -:102BA000020201D000000000020201D80000000271 -:102BB000020201E000000002020201E8000000FF42 -:102BC000020201F0000000FF020201040000000008 -:102BD00002020108000000C8020201180000000201 -:102BE000020201C400000000020201CC000000004B -:102BF000020201D400000002020201DC0000000217 -:102C0000020201E4000000FF020201EC000000FFEC -:102C100002020100000000000202010C000000C8D6 -:102C20000202011C00000002020201C800000000B4 -:102C3000020201D000000000020201D800000002E0 -:102C4000020201E000000002020201E8000000FFB1 -:102C5000020201F0000000FF020201040000000077 -:102C600002020108000000C8020201180000000270 -:102C7000020201C400000000020201CC00000000BA -:102C8000020201D400000002020201DC0000000286 -:102C9000020201E4000000FF020201EC000000FF5C -:102CA00002020100000000000202010C000000C846 -:102CB0000202011C00000002020201C80000000024 -:102CC000020201D000000000020201D80000000250 -:102CD000020201E000000002020201E8000000FF21 -:102CE000020201F0000000FF0202010400000000E7 -:102CF00002020108000000C80202011800000002E0 -:102D0000020201C400000000020201CC0000000029 -:102D1000020201D400000002020201DC00000002F5 -:102D2000020201E4000000FF020201EC000000FFCB -:102D300002020100000000000202010C000000C8B5 -:102D40000202011C00000002020201C80000000093 -:102D5000020201D000000000020201D800000002BF -:102D6000020201E000000002020201E8000000FF90 -:102D7000020201F0000000FF020201040000000056 -:102D80000728040000C00000082807A8000B03491A -:102D9000072C000032FC0000072C800035790CC0A5 -:102DA000072D00003AC11A1F072D800039EF28D0E7 -:102DB000072E00001C3E374C082E3710391E034BDF -:102DC00001280000000000000128000400000000AD -:102DD00001280008000000000128000C000000008D -:102DE000012800100000000001280014000000006D -:102DF0000228002000000001022800240000000238 -:102E000002280028000000030228002C0000000017 -:102E100002280030000000040228003400000001F5 -:102E200002280038000000000228003C00000001D9 -:102E300002280040000000040228004400000000B6 -:102E400002280048000000010228004C0000000396 -:102E50000228005000000000022800540000000179 -:102E600002280058000000040228005C0000000056 -:102E70000228006000000001022800640000000336 -:102E800002280068000000000228006C0000000119 -:102E900002280070000000040228007400000000F6 -:102EA00002280078000000040228007C00000003D3 -:102EB0000628008000000002022800A400003FFF56 -:102EC000022800A8000003FF0228022400000000DE -:102ED00002280234000000000228024C000000001A -:102EE000022802E40000FFFF06282000000008007E -:102EF000022B8BC000000001022B800000000000AC -:102F0000022B804000000018022B80800000000C83 -:102F1000022B80C0000000660C2B83000007A1205C -:102F20000A2B8300000001380B2B8300000013885C -:102F3000022B83C0000001F40C2B8340000001F43D -:102F40000A2B8340000000000B2B8340000000058B -:102F50000A2B83800004C4B40C2B83801DCD650034 -:102F60000A2B1480000000000B2B8380004C4B4088 -:102F7000022B148000000001062A29C8000000046A -:102F8000042A29D80002034D062A208000000048A8 -:102F9000062A9020000000C8062A900000000002C7 -:102FA000062A21A800000086062A20000000002032 -:102FB000022A23C800000000042A23D00002034F85 -:102FC000042A249800040351022A2C500000000017 -:102FD000022A2C1000000000042A2C0800020355CD -:102FE000042A300000020357062A300800000100BE -:102FF000062A404000000010042A40000010035937 -:10300000062A6AC000000002062A6B0000000004C5 -:10301000042A840800020369022B08000000000053 -:10302000042B0C000010036B022B080001000000B1 -:10303000042B0C400008037B022B08000200000058 -:10304000042B0C6000080383062AC000000000D88F -:10305000062A24A800000014062A254800000022A1 -:10306000042A25D00002038B062A266800000022CD -:10307000042A26F00002038D062A27880000002279 -:10308000042A28100002038F062A28A80000002224 -:10309000042A293000020391062AA000000000281B -:1030A000062AA1400000000C042A29E00002039334 -:1030B000062A502000000002062A503000000002BC -:1030C000062A500000000002062A501000000002EC -:1030D000022A520800000001042A6AC8000203956F -:1030E000062A6B1000000042062A6D200000000432 -:1030F000062ABCD000000002062AC360000000D8E7 -:10310000062A24F800000014062A25D80000002210 -:10311000042A266000020397062A26F800000022EF -:10312000042A278000020399062A2818000000229A -:10313000042A28A00002039B062A29380000002246 -:10314000042A29C00002039D062AA0A0000000282E -:10315000062AA1700000000C042A29E80002039F3F -:10316000062A502800000002062A503800000002FB -:10317000062A500800000002062A5018000000022B -:10318000022A520C00000001042A6AD0000203A1A6 -:10319000062A6C1800000042062A6D300000000468 -:1031A000062ABCD800000002022AC6C000000000A7 -:1031B000042A29F0001003A3062A50480000000E3C -:1031C000062AB00000000006022AC6C40000000063 -:1031D000042A2A30001003B3062A50800000000E93 -:1031E000062AB01800000006022AC6C80000000027 -:1031F000042A2A70001003C3062A50B80000000EEB -:10320000062AB03000000006022AC6CC00000000EA -:10321000042A2AB0001003D3062A50F00000000E42 -:10322000062AB04800000006022AC6D000000000AE -:10323000042A2AF0001003E3062A51280000000E99 -:10324000062AB06000000006022AC6D40000000072 -:10325000042A2B30001003F3062A51600000000EF0 -:10326000062AB07800000006022AC6D80000000036 -:10327000042A2B7000100403062A51980000000E47 -:10328000062AB09000000006022AC6DC00000000FA -:10329000042A2BB000100413062A51D00000000E9F -:1032A000062AB0A800000006021010080000000165 -:1032B0000210105000000001021010000003D000A6 -:1032C000021010040000003D091018000200042341 -:1032D0000910110000280623061011A00000001894 -:1032E00006102400000000E00210201C0000000076 -:1032F0000210202000000001021020C00000000287 -:10330000021020040000000102102008000000014B -:1033100009103C000005064B091038000005065056 -:10332000091038200005065506104C000000010069 -:1033300002104028000000100210404400003FFF2F -:103340000210405800280000021040840084924A75 -:1033500002104058000000000210800000001080A1 -:10336000021080AC00000000021080380000001045 -:103370000210810000000000061081200000000201 -:1033800002108008000002B502108010000000004A -:10339000061082000000004A021081080001FFFFB1 -:1033A00006108140000000020210800000001A8018 -:1033B0000610900000000024061091200000004A32 -:1033C000061093700000004A061095C00000004AE5 -:1033D0000210800400001080021080B00000000184 -:1033E0000210803C00000010021081040000000068 -:1033F00006108128000000020210800C000002B5B7 -:103400000210801400000000061084000000004A32 -:103410000210810C0001FFFF06108148000000022D -:103420000210800400001A80061090900000002412 -:10343000061092480000004A061094980000004AC6 -:10344000061096E80000004A02108000000010807C -:10345000021080AC00000002021080380000001052 -:103460000210810000000000061081200000000210 -:1034700002108008000002B5021080100000000059 -:10348000061082000000004A021081080001FFFFC0 -:1034900006108140000000020210800000001A8027 -:1034A0000610900000000024061091200000004A41 -:1034B000061093700000004A061095C00000004AF4 -:1034C0000210800400001080021080B00000000391 -:1034D0000210803C00000010021081040000000077 -:1034E00006108128000000020210800C000002B5C6 -:1034F0000210801400000000061084000000004A42 -:103500000210810C0001FFFF06108148000000023C -:103510000210800400001A80061090900000002421 -:10352000061092480000004A061094980000004AD5 -:10353000061096E80000004A02108000000010808B -:10354000021080AC0000000402108038000000105F -:10355000021081000000000006108120000000021F -:1035600002108008000002B5021080100000000068 -:10357000061082000000004A021081080001FFFFCF -:1035800006108140000000020210800000001A8036 -:103590000610900000000024061091200000004A50 -:1035A000061093700000004A061095C00000004A03 -:1035B0000210800400001080021080B0000000059E -:1035C0000210803C00000010021081040000000086 -:1035D00006108128000000020210800C000002B5D5 -:1035E0000210801400000000061084000000004A51 -:1035F0000210810C0001FFFF06108148000000024C -:103600000210800400001A80061090900000002430 -:10361000061092480000004A061094980000004AE4 -:10362000061096E80000004A02108000000010809A -:10363000021080AC0000000602108038000000106C -:10364000021081000000000006108120000000022E -:1036500002108008000002B5021080100000000077 -:10366000061082000000004A021081080001FFFFDE -:1036700006108140000000020210800000001A8045 -:103680000610900000000024061091200000004A5F -:10369000061093700000004A061095C00000004A12 -:1036A0000210800400001080021080B000000007AB -:1036B0000210803C00000010021081040000000095 -:1036C00006108128000000020210800C000002B5E4 -:1036D0000210801400000000061084000000004A60 -:1036E0000210810C0001FFFF06108148000000025B -:1036F0000210800400001A80061090900000002440 -:10370000061092480000004A061094980000004AF3 -:10371000061096E80000004A021205B00000000101 -:103720000212049000E383400212051400003C10D2 -:103730000212066C00000001021206700000000078 -:1037400002120494FFFFFFFF02120498FFFFFFFF25 -:103750000212049CFFFFFFFF021204A0FFFFFFFF05 -:10376000021204A4FFFFFFFF021204A8FFFFFFFFE5 -:10377000021204ACFFFFFFFF021204B0FFFFFFFFC5 -:10378000021204BCFFFFFFFF021204C0FFFFFFFF95 -:10379000021204C4FFFFFFFF021204C8FFFFFFFF75 -:1037A000021204CCFFFFFFFF021204D0FFFFFFFF55 -:1037B000021204D8FFFFFFFF021204DCFFFFFFFF2D -:1037C000021204E0FFFFFFFF021204E4FFFFFFFF0D -:1037D000021204E8FFFFFFFF021204ECFFFFFFFFED -:1037E000021204F0FFFFFFFF021204F4FFFFFFFFCD -:1037F000021204F8FFFFFFFF021204FCFFFFFFFFAD -:1038000002120500FFFFFFFF02120504FFFFFFFF8A -:1038100002120508FFFFFFFF0212050CFFFFFFFF6A -:1038200002120510FFFFFFFF021204D4FF802000E8 -:10383000021204B4F0005000021204B8F0001000AC -:1038400002120390000000080212039C000000080E -:10385000021203A000000008021203A400000002EC -:10386000021203BC00000004021203C000000005A5 -:10387000021203C400000004021203D00000000082 -:103880000212036C00000001021203680000003FF6 -:10389000021201BC00000040021201C00000180822 -:1038A000021201C400000803021201C8000008034C -:1038B000021201CC00000040021201D000000003FF -:1038C000021201D400000803021201D8000008030C -:1038D000021201DC00000803021201E000010003F3 -:1038E000021201E400000803021201E800000803CC -:1038F000021201EC00000003021201F000000003BC -:10390000021201F400000003021201F8000000039B -:10391000021201FC0000000302120200000000037A -:103920000212020400000003021202080000000359 -:103930000212020C00000003021202100000000339 -:103940000212021400000003021202180000000319 -:103950000212021C000000030212022000000003F9 -:1039600002120224000000030212022800002403B5 -:103970000212022C0000002F021202300000000987 -:103980000212023400000019021202380000018401 -:103990000212023C000001830212024000000306F2 -:1039A0000212024400000019021202480000000640 -:1039B0000212024C0000030602120250000003062D -:1039C00002120254000003060212025800000C8684 -:1039D0000212025C000003060212026000000306ED -:1039E00002120264000000060212026800000006D3 -:1039F0000212026C000000060212027000000006B3 -:103A00000212027400000006021202780000000692 -:103A10000212027C00000006021202800000000672 -:103A20000212028400000006021202880000000652 -:103A30000212028C00000006021202900000000632 -:103A40000212029400000006021202980000000612 -:103A50000212029C00000006021202A000000306EF -:103A6000021202A400000013021202A800000006C5 -:103A7000021202B000001004021202B4000010048E -:103A80000212032400106440021203280010644054 -:103A9000021205B400000001021201B00000000192 -:103AA0000600A000000000160200A0EC5554000023 -:103AB0000200A0F0555555550200A0F400005555E0 -:103AC0000200A0F8F00000000200A0FC5554000025 -:103AD0000200A100555555550200A104000055559E -:103AE0000200A108F00000000200A18C5554000063 -:103AF0000200A190555555550200A194000055555E -:103B00000200A198F00000000200A19C000000004B -:103B10000200A1A0000100000200A1A400005014B6 -:103B20000200A1A8000000000200A45C00000C003C -:103B30000200A61C000000030200A06CFF5C000055 -:103B40000200A070FFF55FFF0200A0740000FFFFFD -:103B50000200A078F00003E00200A07C000000005A -:103B60000200A0800000A0000600A0840000000564 -:103B70000200A0980FE000000600A09C00000007D3 -:103B80000200A0B8000004000600A0BC0000000372 -:103B90000200A0C8000010000600A0CC0000000336 -:103BA0000200A0D8000040000600A0DC00000003D6 -:103BB0000200A0E8000100000600A22C00000004A2 -:103BC0000200A10CFF5C00000200A110FFF55FFFE6 -:103BD0000200A1140000FFFF0200A118F00003E0A2 -:103BE0000200A11C000000000200A1200000A000B3 -:103BF0000600A124000000050200A1380FE000002B -:103C00000600A13C000000070200A15800000800C7 -:103C10000600A15C000000030200A1680000200073 -:103C20000600A16C000000030200A17800008000E3 -:103C30000600A17C000000030200A1880002000031 -:103C40000600A23C0000000400000000000000008C -:103C50000000003100000000000000000000000033 -:103C60000000000000000000000000000000000054 -:103C700000000000000000000000000000310032E1 -:103C80000000000000000000000000000000000034 -:103C90000000000000000000000000000000000024 -:103CA000000000000000000000320056000000008C -:103CB0000000000000000000000000000000000004 -:103CC00000000000000000000000000000000000F4 -:103CD000000000000056008C000000000000000002 -:103CE000008C009000900094009400980098009C34 -:103CF000009C00A000A000A400A400A800A800ACA4 -:103D000000AC00B100B100B300B300B5000000008A -:103D100000000000000000000000000000000000A3 -:103D200000000000000000000000000000B50102DB -:103D30000102010A010A01120112011B011B0124E7 -:103D40000124012D012D01360136013F013F0148BB -:103D5000014801510151015A00000000000000001B -:103D60000000000000000000000000000000000053 -:103D70000000000000000000000000000000000043 -:103D80000000000000000000000000000000000033 -:103D90000000000000000000000000000000000023 -:103DA0000000000000000000000000000000000013 -:103DB0000000000000000000000000000000000003 -:103DC00000000000000000000000000000000000F3 -:103DD00000000000000000000000000000000000E3 -:103DE00000000000000000000000000000000000D3 -:103DF00000000000000000000000000000000000C3 -:103E00000000000000000000015A015F00000000F7 -:103E100000000000015F0160016001610161016259 -:103E2000016201630163016401640165016501666A -:103E300001660167000000000000000000000000B3 -:103E40000000000000000000000000000000000072 -:103E50000000000000000000000000000000000062 -:103E60000167016C016C0179017901860000000095 -:103E70000000000000000000000000000000000042 -:103E80000000000000000000000000000000000032 -:103E90000000000000000000000000000000000022 -:103EA0000000000000000000000000000000000012 -:103EB00000000000000000000186018700000000F3 -:103EC00000000000000000000000000000000000F2 -:103ED00000000000000000000000000000000000E2 -:103EE00000000000018701BE00000000000000008B -:103EF00000000000000000000000000000000000C2 -:103F000000000000000000000000000000000000B1 -:103F100001BE01E9000000000000000000000000F8 -:103F20000000000000000000000000000000000091 -:103F300000000000000000000000000001E9021A7B -:103F40000000000000000000021A022102210228E5 -:103F50000228022F022F02360236023D023D0244A1 -:103F60000244024B024B02520252028A000000003D -:103F700000000000028A028E028E029202920296D5 -:103F80000296029A029A029E029E02A202A202A631 -:103F900002A602AA02AA02FA02FA031103110328D6 -:103FA0000328032B032B032E032E03310331033489 -:103FB000033403370337033A033A033D033D034019 -:103FC00003400381038103880388038F038F0393D6 -:103FD000039303970397039B039B039F039F03A3F1 -:103FE00003A303A703A703AB03AB03AF03AF03B064 -:103FF00000000000000000000000000000000000C1 -:1040000000000000000000000000000000000000B0 -:10401000000000000000000003B003C20000000028 -:104020000000000000000000000000000000000090 -:104030000000000000000000000000000000000080 -:104040000000000003C203D703D703DA03DA03DD5D -:104050000000000000000000000000000000000060 -:104060000000000000000000000000000000000050 -:1040700003DD040A00000000000000000000000052 -:104080000000000000000000000000000000000030 -:10409000000000000000000000000000040A050D00 -:1040A0000000000000000000000000000000000010 -:1040B0000000000000000000000000000000000000 -:1040C0000000000000000000050D0514051405188F -:1040D0000518051C000000000000000000000000A2 -:1040E00000000000000000000000000000000000D0 -:1040F00000000000051C055C00000000000000003E -:10410000055C05650565056E056E05770577058017 -:1041100005800589058905920592059B059B05A4E7 -:1041200005A405FD05FD0613061306290629062D1F -:10413000062D063106310635063506390639063DA7 -:10414000063D064106410645064506490649065014 -:10415000000000000000000000000000000000005F -:10416000000000000000000000000000000000004F -:10417000000000000000000006500656000000008D -:10418000000000000000000000000000000000002F -:10419000000000000000000000000000000000001F -:1041A0000000000006560659000000000000000054 -:1041B00000000000000000000000000000000000FF -:1041C00000000000000000000000000000000000EF -:1041D0000659065F0000000000000000000000001B -:1041E00000000000000000000000000000000000CF -:1041F00000000000000000000000000000000000BF -:104200000000000000000000065F066E066E067DDE -:10421000067D068C068C069B069B06AA06AA06B996 -:1042200006B906C806C806D706D70748000000002A -:10423000000000000000000000000000000000007E -:10424000000000000000000000000000000000006E -:10425000000000000748075B075B076C076C077DE1 -:10426000000000000000000000000000000000004E -:10427000000000000000000000000000000000003E -:10428000000000000000000000000000000000002E -:10429000000000000000000000000000000000001E -:1042A000000000000000000000000000000000000E -:1042B00000000000000000000000000000000000FE -:1042C00000000000000000000000000000000000EE -:1042D00000000000000000000000000000000000DE -:1042E00000010000000204C00003098000040E4029 -:1042F00000051300000617C000071C8000082140BD -:1043000000092600000A2AC0000B2F80000C344050 -:10431000000D3900000E3DC0000F428000104740E4 -:1043200000114C00001250C00013558000145A4078 -:1043300000155F00001663C00017688000186D400C -:1043400000197200001A76C0001B7B80001C8040A0 -:10435000001D8500001E89C0001F8E800020934034 -:10436000000020000000400000006000000080000D -:104370000000A0000000C0000000E00000010000FC -:1043800000012000000140000001600000018000E9 -:104390000001A0000001C0000001E00000020000D8 -:1043A00000022000000240000002600000028000C5 -:1043B0000002A0000002C0000002E00000030000B4 -:1043C00000032000000340000003600000038000A1 -:1043D0000003A0000003C0000003E0000004000090 -:1043E000000420000004400000046000000480007D -:1043F0000004A0000004C0000004E000000500006C -:104400000005200000054000000560000005800058 -:104410000005A0000005C0000005E0000006000047 -:104420000006200000064000000660000006800034 -:104430000006A0000006C0000006E0000007000023 -:104440000007200000074000000760000007800010 -:104450000007A0000007C0000007E00000080000FF -:1044600000082000000840000008600000088000EC -:104470000008A0000008C0000008E00000090000DB -:1044800000092000000940000009600000098000C8 -:104490000009A0000009C0000009E000000A0000B7 -:1044A000000A2000000A4000000A6000000A8000A4 -:1044B000000AA000000AC000000AE000000B000093 -:1044C000000B2000000B4000000B6000000B800080 -:1044D000000BA000000BC000000BE000000C00006F -:1044E000000C2000000C4000000C6000000C80005C -:1044F000000CA000000CC000000CE000000D00004B -:10450000000D2000000D4000000D6000000D800037 -:10451000000DA000000DC000000DE000000E000026 -:10452000000E2000000E4000000E6000000E800013 -:10453000000EA000000EC000000EE000000F000002 -:10454000000F2000000F4000000F6000000F8000EF -:10455000000FA000000FC000000FE00000100000DE -:1045600000102000001040000010600000108000CB -:104570000010A0000010C0000010E00000110000BA -:1045800000112000001140000011600000118000A7 -:104590000011A0000011C0000011E0000012000096 -:1045A0000012200000124000001260000012800083 -:1045B0000012A0000012C0000012E0000013000072 -:1045C000001320000013400000136000001380005F -:1045D0000013A0000013C0000013E000001400004E -:1045E000001420000014400000146000001480003B -:1045F0000014A0000014C0000014E000001500002A -:104600000015200000154000001560000015800016 -:104610000015A0000015C0000015E0000016000005 -:1046200000162000001640000016600000168000F2 -:104630000016A0000016C0000016E00000170000E1 -:1046400000172000001740000017600000178000CE -:104650000017A0000017C0000017E00000180000BD -:1046600000182000001840000018600000188000AA -:104670000018A0000018C0000018E0000019000099 -:104680000019200000194000001960000019800086 -:104690000019A0000019C0000019E000001A000075 -:1046A000001A2000001A4000001A6000001A800062 -:1046B000001AA000001AC000001AE000001B000051 -:1046C000001B2000001B4000001B6000001B80003E -:1046D000001BA000001BC000001BE000001C00002D -:1046E000001C2000001C4000001C6000001C80001A -:1046F000001CA000001CC000001CE000001D000009 -:10470000001D2000001D4000001D6000001D8000F5 -:10471000001DA000001DC000001DE000001E0000E4 -:10472000001E2000001E4000001E6000001E8000D1 -:10473000001EA000001EC000001EE000001F0000C0 -:10474000001F2000001F4000001F6000001F8000AD -:10475000001FA000001FC000001FE000002000009C -:104760000020200000204000002060000020800089 -:104770000020A0000020C0000020E0000021000078 -:104780000021200000214000002160000021800065 -:104790000021A0000021C0000021E0000022000054 -:1047A0000022200000224000002260000022800041 -:1047B0000022A0000022C0000022E0000023000030 -:1047C000002320000023400000236000002380001D -:1047D0000023A0000023C0000023E000002400000C -:1047E00000242000002440000024600000248000F9 -:1047F0000024A0000024C0000024E00000250000E8 -:1048000000252000002540000025600000258000D4 -:104810000025A0000025C0000025E00000260000C3 -:1048200000262000002640000026600000268000B0 -:104830000026A0000026C0000026E000002700009F -:10484000002720000027400000276000002780008C -:104850000027A0000027C0000027E000002800007B -:104860000028200000284000002860000028800068 -:104870000028A0000028C0000028E0000029000057 -:104880000029200000294000002960000029800044 -:104890000029A0000029C0000029E000002A000033 -:1048A000002A2000002A4000002A6000002A800020 -:1048B000002AA000002AC000002AE000002B00000F -:1048C000002B2000002B4000002B6000002B8000FC -:1048D000002BA000002BC000002BE000002C0000EB -:1048E000002C2000002C4000002C6000002C8000D8 -:1048F000002CA000002CC000002CE000002D0000C7 -:10490000002D2000002D4000002D6000002D8000B3 -:10491000002DA000002DC000002DE000002E0000A2 -:10492000002E2000002E4000002E6000002E80008F -:10493000002EA000002EC000002EE000002F00007E -:10494000002F2000002F4000002F6000002F80006B -:10495000002FA000002FC000002FE000003000005A -:104960000030200000304000003060000030800047 -:104970000030A0000030C0000030E0000031000036 -:104980000031200000314000003160000031800023 -:104990000031A0000031C0000031E0000032000012 -:1049A00000322000003240000032600000328000FF -:1049B0000032A0000032C0000032E00000330000EE -:1049C00000332000003340000033600000338000DB -:1049D0000033A0000033C0000033E00000340000CA -:1049E00000342000003440000034600000348000B7 -:1049F0000034A0000034C0000034E00000350000A6 -:104A00000035200000354000003560000035800092 -:104A10000035A0000035C0000035E0000036000081 -:104A2000003620000036400000366000003680006E -:104A30000036A0000036C0000036E000003700005D -:104A4000003720000037400000376000003780004A -:104A50000037A0000037C0000037E0000038000039 -:104A60000038200000384000003860000038800026 -:104A70000038A0000038C0000038E0000039000015 -:104A80000039200000394000003960000039800002 -:104A90000039A0000039C0000039E000003A0000F1 -:104AA000003A2000003A4000003A6000003A8000DE -:104AB000003AA000003AC000003AE000003B0000CD -:104AC000003B2000003B4000003B6000003B8000BA -:104AD000003BA000003BC000003BE000003C0000A9 -:104AE000003C2000003C4000003C6000003C800096 -:104AF000003CA000003CC000003CE000003D000085 -:104B0000003D2000003D4000003D6000003D800071 -:104B1000003DA000003DC000003DE000003E000060 -:104B2000003E2000003E4000003E6000003E80004D -:104B3000003EA000003EC000003EE000003F00003C -:104B4000003F2000003F4000003F6000003F800029 -:104B5000003FA000003FC000003FE000003FE00138 -:104B600000000000000001FF0000020000007FF8CC -:104B700000007FF800000CDF0000150000000001BD -:104B80000000000100000001FFFFFFFFFFFFFFFF2B -:104B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 -:104BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 -:104BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 -:104BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 -:104BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 -:104BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 -:104BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 -:104C0000FFFFFFFFFFFFFFFFFFFFFFFF00000000B0 -:104C1000FFFFFFFF00000000FFFFFFFFFFFFFFFFA0 -:104C200000000000FFFFFFFF00000000FFFFFFFF8C -:104C3000FFFFFFFF00000000FFFFFFFF000000007C -:104C4000FFFFFFFF0000000300BEBC20FFFFFFFFCF -:104C500000000000FFFFFFFF00000000FFFFFFFF5C -:104C60000000000300BEBC20FFFFFFFF00000000AB -:104C7000FFFFFFFF00000000FFFFFFFF0000000339 -:104C800000BEBC20FFFFFFFF00000000FFFFFFFF92 -:104C900000000000FFFFFFFF0000000300BEBC207B -:104CA000FFFFFFFF00000000FFFFFFFF000000000C -:104CB000FFFFFFFF0000000300BEBC20FFFFFFFF5F -:104CC00000000000FFFFFFFF00000000FFFFFFFFEC -:104CD0000000000300BEBC2000002000000040C017 -:104CE00000006180000082400000A3000000C3C0FB -:104CF0000000E4800001054000012600000146C0DC -:104D000000016780000188400001A9000001C9C0BE -:104D10000001EA8000020B4000022C0000024CC09F -:104D200000026D8000028E400002AF000002CFC082 -:104D30000002F0800003114000033200000352C063 -:104D400000037380000394400003B5000003D5C046 -:104D50000003F6800004174000043800000458C027 -:104D60000004798000049A40000080000001038064 -:104D70000001870000020A8000028E0000031180FB -:104D8000000395000004188000049C0000051F80AB -:104D90000005A300000626800006AA0000072D805B -:104DA0000007B100000834800008B80000093B800B -:104DB0000009BF00000A4280000AC600000B4980BB -:104DC000000BCD00000C5080000CD400000D57806B -:104DD000000DDB0000007FF800007FF80000193EA6 -:104DE0000000350000001900001000000000000065 -:104DF00000000000FFFFFFFF400000004000000037 -:104E000040000000400000004000000040000000A2 -:104E10004000000040000000400000004000000092 -:104E20004000000040000000400000004000000082 -:104E30004000000040000000400000004000000072 -:104E40004000000040000000400000004000000062 -:104E50004000000040000000400000004000000052 -:104E60004000000040000000400000004000000042 -:104E7000400000004000000000007FF800007FF8C4 -:104E8000000005C700001500FFFFFFFFFFFFFFFF49 -:104E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 -:104EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 -:104EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 -:104EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 -:104ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 -:104EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 -:104EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 -:104F0000FFFFFFFFFFFFFFFF400000004000000029 -:104F10004000000040000000400000004000000091 -:104F20004000000040000000400000004000000081 -:104F30004000000040000000400000004000000071 -:104F40004000000040000000400000004000000061 -:104F50004000000040000000400000004000000051 -:104F60004000000040000000400000004000000041 -:104F70004000000040000000400000004000000031 -:104F800040000000400000000000100000002080F1 -:104F900000003100000041800000520000006280EB -:104FA0000000730000008380000094000000A480D3 -:104FB0000000B5000000C5800000D6000000E680BB -:104FC0000000F700000107800001180000012880A0 -:104FD000000139000001498000015A0000016A8087 -:104FE00000017B0000018B8000019C000001AC806F -:104FF0000001BD000001CD800001DE000001EE8057 -:105000000001FF0000007FF800007FF80000112E73 -:105010000000350010000000000028AD0000000076 -:105020000001000100070205CCCCCCC5FFFFFFFF4B -:10503000FFFFFFFF7058103C000000000000000060 -:1050400000000001CCCC0201CCCCCCCCCCCC0201F9 -:10505000CCCCCCCCCCCC0201CCCCCCCCCCCC0201BA -:10506000CCCCCCCCCCCC0201CCCCCCCCCCCC0201AA -:10507000CCCCCCCCCCCC0201CCCCCCCCCCCC02019A -:10508000CCCCCCCC00000000FFFFFFFF40000000B4 -:105090004000000040000000400000004000000010 -:1050A0004000000040000000400000004000000000 -:1050B00040000000400000004000000040000000F0 -:1050C00040000000400000004000000040000000E0 -:1050D00040000000400000004000000040000000D0 -:1050E00040000000400000004000000040000000C0 -:1050F00040000000400000004000000040000000B0 -:10510000400000004000000040000000002625A0F4 -:1051100000000000002625A000000000002625A0B9 -:1051200000000000002625A000000000000E023252 -:10513000011600D60010000000000000002625A087 -:1051400000000000002625A000000000002625A089 -:1051500000000000002625A00000000000720236BA -:10516000012300F300100000000000000000FFFF1A -:10517000000000000000FFFF000000000000FFFF33 -:10518000000000000000FFFF000000000000FFFF23 -:10519000000000000000FFFF000000000000FFFF13 -:1051A000000000000000FFFF000000000000FFFF03 -:1051B000000000000000FFFF000000000000FFFFF3 -:1051C000000000000000FFFF000000000000FFFFE3 -:1051D000000000000000FFFF000000000000FFFFD3 -:1051E000000000000000FFFF000000000000FFFFC3 -:1051F000000000000000FFFF000000000000FFFFB3 -:10520000000000000000FFFF000000000000FFFFA2 -:10521000000000000000FFFF000000000000FFFF92 -:10522000000000000000FFFF000000000000FFFF82 -:10523000000000000000FFFF000000000000FFFF72 -:10524000000000000000FFFF000000000000FFFF62 -:10525000000000000000FFFF000000000000FFFF52 -:10526000000000000000FFFF000000000000FFFF42 -:10527000000000000000FFFF000000000000FFFF32 -:10528000000000000000FFFF000000000000FFFF22 -:10529000000000000000FFFF000000000000FFFF12 -:1052A000000000000000FFFF000000000000FFFF02 -:1052B000000000000000FFFF000000000000FFFFF2 -:1052C000000000000000FFFF000000000000FFFFE2 -:1052D000000000000000FFFF000000000000FFFFD2 -:1052E000000000000000FFFF000000000000FFFFC2 -:1052F000000000000000FFFF000000000000FFFFB2 -:10530000000000000000FFFF000000000000FFFFA1 -:10531000000000000000FFFF000000000000FFFF91 -:10532000000000000000FFFF000000000000FFFF81 -:10533000000000000000FFFF000000000000FFFF71 -:10534000000000000000FFFF000000000000FFFF61 -:10535000000000000000FFFF000000000000FFFF51 -:10536000000000000000FFFF00000000FFFFFFF34F -:10537000318FFFFF0C30C30CC30C30C3CF3CF300A4 -:10538000F3CF3CF30000CF3CCDCDCDCDFFFFFFF1FF -:1053900030EFFFFF0C30C30CC30C30C3CF3CF30025 -:1053A000F3CF3CF30001CF3CCDCDCDCDFFFFFFF6D9 -:1053B000305FFFFF0C30C30CC30C30C3CF3CF30095 -:1053C000F3CF3CF30002CF3CCDCDCDCDFFFFF406B3 -:1053D0001CBFFFFF0C30C305C30C30C3CF3000141B -:1053E000F3CF3CF30004CF3CCDCDCDCDFFFFFFF29A -:1053F000304FFFFF0C30C30CC30C30C3CF3CF30065 -:10540000F3CF3CF30008CF3CCDCDCDCDFFFFFFFA6D -:10541000302FFFFF0C30C30CC30C30C3CF3CF30064 -:10542000F3CF3CF30010CF3CCDCDCDCDFFFFFFF748 -:1054300031EFFFFF0C30C30CC30C30C3CF3CF30083 -:10544000F3CF3CF30020CF3CCDCDCDCDFFFFFFF51A -:10545000302FFFFF0C30C30CC30C30C3CF3CF30024 -:10546000F3CF3CF30040CF3CCDCDCDCDFFFFFFF3DC -:10547000318FFFFF0C30C30CC30C30C3CF3CF300A3 -:10548000F3CF3CF30000CF3CCDCDCDCDFFFFFFF1FE -:10549000310FFFFF0C30C30CC30C30C3CF3CF30003 -:1054A000F3CF3CF30001CF3CCDCDCDCDFFFFFFF6D8 -:1054B000305FFFFF0C30C30CC30C30C3CF3CF30094 -:1054C000F3CF3CF30002CF3CCDCDCDCDFFFFF406B2 -:1054D0001CBFFFFF0C30C305C30C30C3CF3000141A -:1054E000F3CF3CF30004CF3CCDCDCDCDFFFFFFF299 -:1054F000304FFFFF0C30C30CC30C30C3CF3CF30064 -:10550000F3CF3CF30008CF3CCDCDCDCDFFFFFFFA6C -:10551000302FFFFF0C30C30CC30C30C3CF3CF30063 -:10552000F3CF3CF30010CF3CCDCDCDCDFFFFFFF747 -:1055300030EFFFFF0C30C30CC30C30C3CF3CF30083 -:10554000F3CF3CF30020CF3CCDCDCDCDFFFFFFF519 -:10555000304FFFFF0C30C30CC30C30C3CF3CF30003 -:10556000F3CF3CF30040CF3CCDCDCDCDFFFFFFF3DB -:1055700031EFFFFF0C30C30CC30C30C3CF3CF30042 -:10558000F3CF3CF30000CF3CCDCDCDCDFFFFFFF1FD -:10559000310FFFFF0C30C30CC30C30C3CF3CF30002 -:1055A000F3CF3CF30001CF3CCDCDCDCDFFFFFFF6D7 -:1055B000305FFFFF0C30C30CC30C30C3CF3CF30093 -:1055C000F3CF3CF30002CF3CCDCDCDCDFFFFF406B1 -:1055D0001CBFFFFF0C30C305C30C30C3CF30001419 -:1055E000F3CF3CF30004CF3CCDCDCDCDFFFFFFF298 -:1055F000304FFFFF0C30C30CC30C30C3CF3CF30063 -:10560000F3CF3CF30008CF3CCDCDCDCDFFFFFFFA6B -:10561000302FFFFF0C30C30CC30C30C3CF3CF30062 -:10562000F3CF3CF30010CF3CCDCDCDCDFFFFFF97A6 -:10563000056FFFFF0C30C30CC30C30C3CF3CC00060 -:10564000F3CF3CF30020CF3CCDCDCDCDFFFFFFF518 -:10565000310FFFFF0C30C30CC30C30C3CF3CF30041 -:10566000F3CF3CF30040CF3CCDCDCDCDFFFFFFF3DA -:10567000320FFFFF0C30C30CC30C30C3CF3CF30020 -:10568000F3CF3CF30000CF3CCDCDCDCDFFFFFFF1FC -:10569000310FFFFF0C30C30CC30C30C3CF3CF30001 -:1056A000F3CF3CF30001CF3CCDCDCDCDFFFFFFF6D6 -:1056B000305FFFFF0C30C30CC30C30C3CF3CF30092 -:1056C000F3CF3CF30002CF3CCDCDCDCDFFFFF406B0 -:1056D0001CBFFFFF0C30C305C30C30C3CF30001418 -:1056E000F3CF3CF30004CF3CCDCDCDCDFFFFFFF297 -:1056F000304FFFFF0C30C30CC30C30C3CF3CF30062 -:10570000F3CF3CF30008CF3CCDCDCDCDFFFFFF8ADA -:10571000042FFFFF0C30C30CC30C30C3CF3CC000C0 -:10572000F3CF3CF30010CF3CCDCDCDCDFFFFFF97A5 -:1057300005CFFFFF0C30C30CC30C30C3CF3CC000FF -:10574000F3CF3CF30020CF3CCDCDCDCDFFFFFFF517 -:10575000310FFFFF0C30C30CC30C30C3CF3CF30040 -:10576000F3CF3CF30040CF3CCDCDCDCDFFFFFFF3D9 -:10577000316FFFFF0C30C30CC30C30C3CF3CF300C0 -:10578000F3CF3CF30000CF3CCDCDCDCDFFFFFFF1FB -:10579000302FFFFF0C30C30CC30C30C3CF3CF300E1 -:1057A000F3CF3CF30001CF3CCDCDCDCDFFFFFFF6D5 -:1057B000305FFFFF0C30C30CC30C30C3CF3CF30091 -:1057C000F3CF3CF30002CF3CCDCDCDCDFFFFFFF6B4 -:1057D00030BFFFFF0C30C30CC30C30C3CF3CF314FD -:1057E000F3CF3CF30004CF3CCDCDCDCDFFFFFFF296 -:1057F000304FFFFF0C30C30CC30C30C3CF3CF30061 -:10580000F3CF3CF30008CF3CCDCDCDCDFFFFFFFA69 -:10581000302FFFFF0C30C30CC30C30C3CF3CF30060 -:10582000F3CF3CF30010CF3CCDCDCDCDFFFFFFF744 -:1058300031CFFFFF0C30C30CC30C30C3CF3CF3009F -:10584000F3CF3CF30020CF3CCDCDCDCDFFFFFFF01B -:10585000307FFFFF0C30C30CC30C30C3CF3CF300D0 -:10586000F3CF3CF30040CF3CCDCDCDCDFFFFFFFFCC -:1058700030CFFFFF0C30C30CC30C30C3CF3CF3CC94 -:10588000F3CF3CF30000CF3CCDCDCDCDFFFFFFFFEC -:1058900030CFFFFF0C30C30CC30C30C3CF3CF3CC74 -:1058A000F3CF3CF30001CF3CCDCDCDCDFFFFFFFFCB -:1058B00030CFFFFF0C30C30CC30C30C3CF3CF3CC54 -:1058C000F3CF3CF30002CF3CCDCDCDCDFFFFFFFFAA -:1058D00030CFFFFF0C30C30CC30C30C3CF3CF3CC34 -:1058E000F3CF3CF30004CF3CCDCDCDCDFFFFFFFF88 -:1058F00030CFFFFF0C30C30CC30C30C3CF3CF3CC14 -:10590000F3CF3CF30008CF3CCDCDCDCDFFFFFFFF63 -:1059100030CFFFFF0C30C30CC30C30C3CF3CF3CCF3 -:10592000F3CF3CF30010CF3CCDCDCDCDFFFFFFFF3B -:1059300030CFFFFF0C30C30CC30C30C3CF3CF3CCD3 -:10594000F3CF3CF30020CF3CCDCDCDCDFFFFFFFF0B -:1059500030CFFFFF0C30C30CC30C30C3CF3CF3CCB3 -:10596000F3CF3CF30040CF3CCDCDCDCDFFFFFFFFCB -:1059700030CFFFFF0C30C30CC30C30C3CF3CF3CC93 -:10598000F3CF3CF30000CF3CCDCDCDCDFFFFFFFFEB -:1059900030CFFFFF0C30C30CC30C30C3CF3CF3CC73 -:1059A000F3CF3CF30001CF3CCDCDCDCDFFFFFFFFCA -:1059B00030CFFFFF0C30C30CC30C30C3CF3CF3CC53 -:1059C000F3CF3CF30002CF3CCDCDCDCDFFFFFFFFA9 -:1059D00030CFFFFF0C30C30CC30C30C3CF3CF3CC33 -:1059E000F3CF3CF30004CF3CCDCDCDCDFFFFFFFF87 -:1059F00030CFFFFF0C30C30CC30C30C3CF3CF3CC13 -:105A0000F3CF3CF30008CF3CCDCDCDCDFFFFFFFF62 -:105A100030CFFFFF0C30C30CC30C30C3CF3CF3CCF2 -:105A2000F3CF3CF30010CF3CCDCDCDCDFFFFFFFF3A -:105A300030CFFFFF0C30C30CC30C30C3CF3CF3CCD2 -:105A4000F3CF3CF30020CF3CCDCDCDCDFFFFFFFF0A -:105A500030CFFFFF0C30C30CC30C30C3CF3CF3CCB2 -:105A6000F3CF3CF30040CF3CCDCDCDCDFFFFFFFFCA -:105A700030CFFFFF0C30C30CC30C30C3CF3CF3CC92 -:105A8000F3CF3CF30000CF3CCDCDCDCDFFFFFFFFEA -:105A900030CFFFFF0C30C30CC30C30C3CF3CF3CC72 -:105AA000F3CF3CF30001CF3CCDCDCDCDFFFFFFFFC9 -:105AB00030CFFFFF0C30C30CC30C30C3CF3CF3CC52 -:105AC000F3CF3CF30002CF3CCDCDCDCDFFFFFFFFA8 -:105AD00030CFFFFF0C30C30CC30C30C3CF3CF3CC32 -:105AE000F3CF3CF30004CF3CCDCDCDCDFFFFFFFF86 -:105AF00030CFFFFF0C30C30CC30C30C3CF3CF3CC12 -:105B0000F3CF3CF30008CF3CCDCDCDCDFFFFFFFF61 -:105B100030CFFFFF0C30C30CC30C30C3CF3CF3CCF1 -:105B2000F3CF3CF30010CF3CCDCDCDCDFFFFFFFF39 -:105B300030CFFFFF0C30C30CC30C30C3CF3CF3CCD1 -:105B4000F3CF3CF30020CF3CCDCDCDCDFFFFFFFF09 -:105B500030CFFFFF0C30C30CC30C30C3CF3CF3CCB1 -:105B6000F3CF3CF30040CF3CCDCDCDCD000C0000B9 -:105B7000000700C000028130000B815800020210B3 -:105B800000010230000F024000010330000C000051 -:105B9000000800C000028140000B81680002022062 -:105BA0000001024000070250000202C0000F000086 -:105BB000000800F000028170000B81980002025082 -:105BC00000010270000B8280000803380010000002 -:105BD0000008010000028180000B81A80002026021 -:105BE00000018280000E829800080380000B0000F4 -:105BF000000100B0000280C0000580E80002014002 -:105C000000010160000E017000038250CCCCCCCCAE -:105C1000CCCCCCCCCCCCCCCCCCCCCCCC00002000D4 -:105C2000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCB4 -:105C300000002000CCCCCCCCCCCCCCCCCCCCCCCCB4 -:105C4000CCCCCCCC04002000000000000000000000 -:105C50001F8B080000000000000BFB51CFC0F003B9 -:105C60008A59051918AC84117C7A607E4ECAF43BBF -:105C7000F232303803B12B103700F1616E06862303 -:105C8000DCC4EBBF2C8F6087CA32303402F11E694E -:105C900006063B3984B8B90203C30A203F0B2AF633 -:105CA0001E4897CA53E6EEC182B55531C5349411EA -:105CB0006C1D2CF2C858174DBE5D1995AF4740FFBB -:105CC00040E32C1D54FE742D08FD4D1B4267A3C9F3 -:105CD000CF80CAFB40FD95A383DD5C5F22FD9DCA9A -:105CE00082CA8F47E3B731A2F2CD3850F94950F557 -:105CF00000CDA28F7AC80300000000000000000061 -:105D00001F8B080000000000000BED7D0D7854D5BE -:105D1000B5E83A73CEFC25672693908409093009CB -:105D200021441B700C3F0D16EB097F8636D70E14ED -:105D3000696C150744881048A4D6874FFD3291003E -:105D4000E17F504B43413CFC29BD97B691A2A596FB -:105D5000D2019F165BDFF782CF7AB5B5BD23A5F8D8 -:105D6000539498774BEDBBDEFAF65A7B9FCC3927DC -:105D7000332448BDED7BEFC6AF3DEC73F6CFFADBC5 -:105D80006BAFB5F6DA7B9C0E37148E04F818FF6EF5 -:105D900000F81715000A524FA70762D9D700E4E6AA -:105DA0006BB16415C0D07C2D0113D8FB802BE49619 -:105DB00052ED8CE789DC9941ACD75EA00581F5D125 -:105DC0009E3B0FA2D857B411A01040F100FD19F569 -:105DD0009D81391EA8A2577FF9D8F82E03AC0994EB -:105DE000E5603B7BFF003AC04473D90160F4C9DA37 -:105DF000790D78CBD98B7C80AC090EFDC652067725 -:105E0000B99EC0727688C1CDCA274A5FF08C62788D -:105E10006CB8DE117653EBBB012601ACC4BE42EC7C -:105E2000FDD884F8AE84B13C433ED4E662E5EC7222 -:105E3000A0FABEB1B1848BDA696A116B1700DE2E4D -:105E400050B9B81EC601E468AE145CBC1EE19F2DBB -:105E5000EA79CAADDFB361D307B21F4B4988F8585E -:105E6000FF35EC7BA5E97BE5CCB7B0DF6C30B563E3 -:105E7000786CC37F14017C0E7CF9E7B0F3CFC26766 -:105E8000910E303D0F60727FFAA5E81623FE027076 -:105E9000BE78A1EF8FF8E0117CB8717AB2C1C1F081 -:105EA00056A73800F19E297FE4296374DC7C4A26DA -:105EB0003A6C6E60FFC7BE6FAE73E8B152C2B3BE3C -:105EC00088B51F29F0CC9BF8B2842C5AD7CACAEEE9 -:105ED000FE747687131ACA891A8E513F6EF66E08C1 -:105EE000932B77490FC9CDC81A464FA4CB031CEF9B -:105EF00018FBEFE3B2143DDD063DA758E9E916F4BF -:105F0000CCBBC74A47770DA3A31FBF5BE9A8E33FFC -:105F100018BD1619742C80D144C7581ED177B0749F -:105F2000CCB5D13160D031966C5050FE908E0CDEE5 -:105F3000AD9A03B259B9F735B72E23DD625A77907F -:105F4000D5574563B586CBD16601D77AA4DF18FA59 -:105F5000E4700419BFAABA343E6F121296B3AB7440 -:105F600092772F23CB905294575552183D37563283 -:105F7000790D119C92A3A63F5CEC8FDA6F64F0A8B8 -:105F80002678367ABA3C122B6F63F0C624AC76388A -:105F9000807269E0ED0E392CF45682593679E7703B -:105FA0001AF06DD3F87C36C141EFA1BBAB436270F0 -:105FB0005E9CE1800DD2C0FD6EEDEBC7DABFBDDFA8 -:105FC00001E14B06BCE50CBF8B2FCAE10D8C3E1BDB -:105FD000435D1D28E75BA7737CFBF3F90AC7EBE978 -:105FE000F1944F308D17EEF104D2EAB72B1C0772F3 -:105FF000AD78D504BC81AA2B1F07020B4622FF33C4 -:10600000F1E3AF067F88C16FA293B73C2061FFDE4A -:10601000B10F7B80E6FD610FC2611FA71FBCB67187 -:10602000EDE32895314DA1924D1F057400937EA19B -:106030003A217C727D921DB6EA196FA54DBF84ACE2 -:106040006545E81BC5A66F3EB0EBEB0983D4335A18 -:1060500023C11B12708198CFA3C47C9E762819F4AB -:1060600030FA95EF32F4F5033FAF64F27040E8EB9D -:10607000039D407AF64017D3D734AFB9BE1EC7414F -:1060800083AA6FBEEC40FCF7F6E91B2B7DCAE2DA6F -:1060900054D43BE5F1B003FB29DBC4F54D59478BE4 -:1060A00003F9344EE82D38CAE9E061FF99F5759996 -:1060B0001867D42E2B1DCB90BEAC5DD511DBFB1A1F -:1060C000BEEE958189AE6CBCADF80F46AF6112A3F0 -:1060D000E367D8BF474305D171CA20D73D4147BBCD -:1060E000BE2EC3B147313A3ECAF435C36F6480D384 -:1060F000B1BDC3010ED48FBB1CA41FC794461C584E -:10610000CFD0DB0234A814F8EF13EB9D01E7A8070A -:106110007A6A51B99743CF0937EB27771384132154 -:10612000D4D325B538CEE371AEA7CBE3E0889AECA3 -:10613000A15C01CFE3D37B5F1CC3EAF5C69530A217 -:10614000B91F420E4F698AAEC67A3B52C8E93F601A -:106150002D931CDAF93852C8A59D3E6374ABFC96AA -:106160003F6AE3C7266B79A44DAEEB0D7E18723DF6 -:10617000487EB81588B9F3B0AC937DE761342A60E6 -:1061800065F907CF6928D76A277F97DBE1D04B995C -:10619000DCFADA7959E950F45A36EE6D6880B1F2DA -:1061A000E818E86897CAD33548327A8F0E244066DB -:1061B000EF474E87B06C9A2F869D69F06F94A0DFF1 -:1061C00028616FE43CD8EB45397F3CC0E88E7C7F8A -:1061D0004011ED7BBC91B129BADBF5C3571AAC7401 -:1061E000BF39926DA1D7ACD0104B79FCA96197E46F -:1061F00093A13F0C3932E8D68F0F312BDF7CD3AD22 -:10620000DFEDFAA74DB2E99F41F2C975122AD18E8E -:1062100019E3C80AEF2DED5FEF61C921EC218F7EF4 -:10622000968DB70024C861FD2F87E408A4F7513587 -:1062300044DF5738928558BE003DDB878F4AF53FD3 -:106240004281A3520E53DA8CBCAB1848C33C90C8B1 -:1062500026BB18229E422201D14562FFBB95E44530 -:106260007120BD8A03FC3DC472142C07C1F80B5980 -:10627000ECC4A2552FFC5962F353124F19F9C8C64A -:10628000774294E4C103712A6741173D55E8A6A7F8 -:106290001F7AE819808084CF3C08D313AED69F4A7A -:1062A000901E7D2040F4F4FE0E3ECE4EE1B346F04B -:1062B0006D1844BE2F4D443E24C023A7E4D02BE6E6 -:1062C00037B3D7482F7B2A99FC96A27FC0D6D52A10 -:1062D0009AFFDC9F99DE134379CE51615884BDDF6C -:1062E000D81A20FDBCB9D543CF0EA16F4AAE796153 -:1062F000C71DEC9F8F8CAD79732F7B9E68DBAEA1A1 -:106300005DD33196EB97A1D3BBEB46A19D58AF70FF -:10631000BBB09DDBAD39825A1DA393FA6A567FCB81 -:10632000DD9EB0797D31F4D096EB9307F7B1EF7A2B -:106330004B167DD7A70B7BEC23C67FC30F42FA8594 -:1063400005DFEA136487B2F7311FABEFF990213F05 -:106350009E7D0FF6B4A6D33F1D6559A4FF3A4EAEFD -:1063600087105BE7435A4C23BB760A33594BC9BEAF -:1063700075C4AA70F6457F2531FAE6C40292A622BA -:106380007D40C2761E740891BE4A3C68B657FBFA3F -:106390001F1E0B2E64FDC5AE77850F90F88063DE5F -:1063A000D8CC72BFBEEDDEAF6A69EC27BF4322FED8 -:1063B0009EBCBEB008FD5D17048AB227E03C72C1E6 -:1063C000015C9FAE5F3C329AA65D6A3E19F651FAB7 -:1063D00067A6766E195ABA4CFD963B1CA42FC1E1F4 -:1063E000A1676E09979750A5909B18687A1A3BF39E -:1063F000F3027E8F128380B0A73F4D7ABD2D713896 -:10640000D74BD0D095061E1DE19988F3A02986FEB2 -:10641000404E1B9757A6B534AC1F52F8D3A87FA3A4 -:10642000A8FFA4C0E332F44DE1A3386FF307A9EF4E -:1064300070DC34F884C5F89733EED651688C062C9E -:1064400074B7F3B36F7C8797EA5DBC7E7B10FDE782 -:106450004C70865A58DDA1EC592F9E55E25949BA25 -:10646000BDDF7897DBDF144788F0B4F70BFBB9FD8D -:106470009423D6A913935D34CF873F00229E62D523 -:106480001BC3991F89FA4D3FC8167809F5062F3F9F -:10649000B61FC89EEABDE721B23B4B50AFCA18E712 -:1064A00088D23C2E8510950DFDB616F51D7B5E84B9 -:1064B000C82D8E02D42B5D27515FD64FB87B6ABAA8 -:1064C00078D11DC6FCB88CF5E8F3ECB9C013B9134C -:1064D000FB57C3A735B66243EE5C29969DD37F5E1A -:1064E00031F10CCE31CF873EB9E0F3A91DE5BD8A6D -:1064F000CF9BD9AC5C579E1E4EBDED6291B0FB8622 -:10650000917FA3C0B039A6F9A83FC8E6156BF7B8CC -:10651000E8CF78BF5DE017FB04F3A08E3D03615D1B -:106520004375394F6F7122DF6E96A26B10EFB9F58C -:1065300091E791F5EAC16E2D2B44EF3B1C6C9CBAA0 -:10654000501C3907AAD61DC3E763F72CD4908FBD22 -:106550004C67C969FC66E399A539AC7E92DDEF1BF7 -:10656000E47CBC3A1C9F8A765865C3891388EE0286 -:106570004F7427C23524F2945680F0864E6B7926EC -:106580007E8D14FC5AE6E0F8E73E20F8A66841E468 -:10659000C75D10D98BED039AB0BB07094726F947B1 -:1065A0003B13E93812E59DE9CDF63093F7D2D47C60 -:1065B000C811F3A15DCC87DE095CFEDB03D58174D5 -:1065C000EB8521EF86FC1BFAD05E2FF109E4FC2A53 -:1065D000F6AC8000F9311721FADF900E0C7BB26B1C -:1065E00072A777913F67CCABFAF0E9E943183EEA2E -:1065F000845035D2DF18F7BC90BB051EEDE7241F91 -:10660000E56D4A1EC36BCC3D101EC5EACD2ACF9561 -:10661000CCF2FE6A5FFDC8699A5FF7746B4A68E066 -:1066200076FF43E077B31479CD2C87AC9F5F615937 -:106630000D75A384F5D13924EC7BB96D21D90F4CAC -:106640003E0348E7792D2DCFE37873AB226BB0BEC4 -:10665000D1FFAC90CD6E97A26F61BF7639AD83B894 -:106660000297B17E8C94A217B09FFA5037C19B3B22 -:106670003D4272C6E0FEE05382FB2F48D74C70BF0C -:10668000858D516F86F7905E63F0C9328363F403A2 -:1066900009258FE87E5A41BA333A3BE582149D07BB -:1066A0003BCFB7897936D07C6FC77F4C46BB383A31 -:1066B00004C7CF13762E244F00F7AFAC71CA19F27E -:1066C00079403B2BB72E09181F1A724A0EDFC83EBD -:1066D0000DAD0309ED62C38ECD13F3D180674B9FDF -:1066E0009D1CA4F933444D06232ACED74964B73DF7 -:1066F000529B0CA29FB7B63544DF033593D6DF110A -:10670000C2E1A304C786D6B0B0AF6BE819AFEB3DCA -:1067100085FB025B820EB27F37B5561A71598237FC -:10672000CFB093EBCE909DDC1BCC127EA315BE7830 -:10673000DD19CBBE87D10E82A6385619F623ECEBB5 -:1067400010D73703B5574BAC74EF6BAF0DAE7DD69A -:10675000046BFB5A2DD981F1C400C68F100FA1F72D -:10676000FC02C6408D83FC6483DE9E2A6B1C2E5E79 -:10677000977E1FA76F5DB08D07E559A932068B6222 -:106780008D04DF4A015FA67ED6887895517666D063 -:10679000934DB25827C57E5440C0FA88C6E8A1A6DA -:1067A000E83144C8DD967AEE874180C7E70C3FC7E1 -:1067B00009FC7B6A3C8E379549DFC7F83836F88D7F -:1067C000F62ED13E131C2E7B7F67593F934CFDD88C -:1067D000E0CC049F7D7F0CDEB6F693597FD9DA9D1D -:1067E0001F1C1FFAB503133FA99C672B0FB3D52FAE -:1067F000B37DBFDAF6BDDA56BECE567FAAADFC0534 -:106800005BFD39B6F2576DF517DABE2FB57D5F69BE -:106810002BFF576BFDAABB3E197DFF3FA39331AF02 -:10682000FAD345B7ECEFDAE75519244624D8736F4D -:10683000EE4B8BF1D3BFC892728EFB243C8E058940 -:106840007111933DFE7B357A06D7B1BD1F6959A8FA -:10685000F7F7C75FF6A33E32DE9F97DEF05F156263 -:106860007AC19558C1E33E719A3759A09C49562286 -:1068700097248A9779D44544724F397B6FD26F6ED3 -:1068800088109F5D25D6F710E7F3B01C7D7AD65FA0 -:106890006C9B8BECC15811E8A3315E94CFFBA7FA37 -:1068A000652978AB15AE9F8291782DCEE1610D5DA3 -:1068B00027F069A753705AECDA1730DEF008F7CBEF -:1068C000F7CFB0FAD5B728DC0FB94DB96CBFE0D51A -:1068D000F172AAFFFD0FAAE13656653F02C1CAB1A7 -:1068E000073D3AC63746605C8E6F1A505C6E38883A -:1068F0003F117F2BC17FB376C3D55314670B350689 -:106900004EA2CE9BA354D0788F4B3D57E1788EECAE -:10691000F3D7F2FDBCBF7C4CF17741AFE0C649C96B -:1069200018A3176C758547139DC34467B702EDEE36 -:106930006A14134EDFD5ECB578AFF8F2D06D12FCC7 -:1069400040FD3B0AF7B575E0FE6482CA3E48523905 -:1069500047D8B9639452EE17083F9379F612FA5F5D -:10696000C12F32BF3CCDFA315BAA1DA314A4E29320 -:106970005288C721A54D2FFC59C278572584F8FEAF -:10698000948807AE97A58F311E1E18DCFE4EF06B63 -:1069900056BE821285D92679FE5A1F3F39BD46055B -:1069A00039FEC1ADAE16F46BF6CFB2CA81515F5657 -:1069B0002E3B5EB17DDCA84F4F0E729551044F7F88 -:1069C00039B83580FB07528CD12D7BF074CB91B553 -:1069D000AF2A13114FA0F22149BB5529489515D074 -:1069E000E69BBFBF2A4716E0F7D854A86C5153FD69 -:1069F000B0F78B32BC5F92EE7DA961B79EE5EB7874 -:106A0000B1B0AF86B6C7C92E2D6ACACB32DB59C525 -:106A1000625DD8D3B4D08BF86E6F48AF078DE74670 -:106A2000E1F765AAA74A5D11D42B3056810369ECC2 -:106A3000F26751BE4DFA54ADB2DA5BD317C56AB1F5 -:106A4000BDBFCE01B86FC2D679B2EF8A842E7B78F3 -:106A50004A4CC2BC97F872083FC4F0F22F2AF3A642 -:106A6000B3931ED6B6D3FB1DF5876791DFC2EC3A10 -:106A700099E2E25DEBB13CA4C6011BD2EC173C21CC -:106A8000F0DB5CCFE964FF5EE18268BA79F8AC22A2 -:106A9000F61994980485A9FD92274E147DA192C100 -:106AA0005B1C7684BDA1149CA57D765382E855516C -:106AB000AD0430DF80297E8BBDB9A3BD7AC71D68C8 -:106AC000B7B3F768B7EFBC3E300CD78D3DB515B303 -:106AD0001A517FDFE980D1A1141C633AADF43CD197 -:106AE000373FADE3B27E6BC97FAA67E44A43872B89 -:106AF000A547A71837939CD8D755BB1C5CCEFA7016 -:106B0000937CE5F8FD00E7E144921F8AD30CAD6762 -:106B10007E5C556A1E197E8A5DCE02750B49CEB623 -:106B2000D7977911CFDEBA6AC9C5EA6DC19A69FCF7 -:106B30007163BC4CF05438A3DE00CDC385523ABA21 -:106B40001546D3C7CF35A7883F2B5109DB67AA3736 -:106B5000C229E441CCAB4231AF82535AE6D0BCD813 -:106B6000A5C0438C5E0FD755B78D26FA3948EEA6DF -:106B70006B5CCF164EE0FB993E46AF67D9BAF7483B -:106B8000038413ECFD23135C96FD9942411FBB3C2B -:106B90003E32807E01B3FFC5E45F71AA7CFFB61C64 -:106BA000CAD19E7AB8EED2ED074BDF608343D39112 -:106BB000BF35D503C44DDA2E779D9A773DCA63CD94 -:106BC00020F3276CFA029EBB6BFD68C607DF2EA67A -:106BD0002F201D7D5C167F7C207AD8E93F0EE99935 -:106BE000FDE9D1D3FE7D8853C40107498F27EBCB44 -:106BF000B6968732D7B7E363B4DB28E6DBE7A14775 -:106C0000C6F9AF4180E24B53214CCFE910A167B7E1 -:106C100012FD9293D59F092D5436E2508D0ADF97CD -:106C2000802A3EAEB1BFAD4C03B293C78C077D2F17 -:106C3000EAE72973C4A6AFA29DF3A0D1C6E048E35A -:106C400057013C447817DBD663234E31B4295E5F8D -:106C5000CDFA2DAE77501CA3B8E6B0D7BC2EFBC53D -:106C6000FC31FADBC9BEE3FABCB36970FC32EA3D21 -:106C7000A12429AFEB899A87DA70B951F2DE0EA60A -:106C80006B6FA7EB968FBABC9134F0EC5C7494F206 -:106C9000B776D65C3A8E3290DC8C91D3DBB39F779B -:106CA0007B896E3B733DB7F0E49C5596FC0390D511 -:106CB00052F3B83B3F82DCC8A5F489669D2F5B9CEC -:106CC000221FC4073E94FF4CF4309E9F361D9E9CAD -:106CD000DAB23492A67D859BDB136B722186F92292 -:106CE0004FBEAEE898DFC00496E471D22D211DEDB1 -:106CF00097355EAE979FAC05FA3E29577C7F2C44B2 -:106D0000F954C59D1073B1F5ACF8B5458FE4B27A6E -:106D10009B16310FB234F57E53F86407EE133FF340 -:106D20008A2380F6D1246FC2136678D5887570E700 -:106D3000A29394771CDBA58447937E97409A44DE08 -:106D4000BC25AE79DCA910BC3BC30F7B716F6E47CD -:106D50002849FD7C63F2494F88E1B7A9A4DB837819 -:106D60006EAE7998D6CBC38BCABE5C4164B5E6974C -:106D7000CC94A7746B98BFBB88EF5BE426BB3D98AF -:106D80009FE46F50E046069F5FE5F86E5A033AAE07 -:106D900053D5228F4482D9E41717D9F2B80A6D79F6 -:106DA0002681F0CC77709F9FF6FF1109B9E991B168 -:106DB000184F6C7688F4538DE6A94FE0E70B6B54BF -:106DC0007FA67CCC8B790B3BDA9500AE7F015BBF55 -:106DD000763C02103DA149D40F8DB3E351BE4E065F -:106DE000265266316B2AE00E30B887B021DBAD70D9 -:106DF0001B74B58FE3B395DF36E4B91846A31E3292 -:106E0000E2CE06FC76B9CD9FA41F7999E1BBF315BC -:106E100095D6EB9D352F7FAD19D7F94A37E5717DB2 -:106E2000E1E2C1A6EFB3E72F3E385A8ECF2F16ED21 -:106E30009FD08C74107912463CAF107B26FB55E82E -:106E40003563BCAA3DEDCE7C7A45F9159B4FBEDE7D -:106E50008871E7A22620FBB748E1F2E96B77E86D7D -:106E60000CFEFCEBE2240FC50D09025A6DE892629C -:106E7000267B5E15F69CAF292AE13EFE8D0D712F13 -:106E8000E68BF844FCD737214E76D20CF90D4F52E1 -:106E90004DF1CFC87F37E69F9D3F158B78DE497156 -:106EA000BB1246B08B9B5A1C6487D7F07CEF8ACE0E -:106EB0002E89FB7F3C9F9E87D4D933D2C8F30977B4 -:106EC000713BDDC8FFF63759F917E8CB9F8FD2BE6B -:106ED0006B69A7ED7BA4EE2D2E87567E96B9043FF5 -:106EE0002B44FEA0CD4FDBDC24F6E9548F7E29BB7A -:106EF000F6159187F32AE23FA6FFF79B33E8DF9B65 -:106F0000DC7C9F5F767477901F779D83FC383B1CF9 -:106F10005B9AB8DEDBEF7258ECF82B1DFF36A1FF51 -:106F20006547F26F327E531FFE7F9BF1EFFF1B8F91 -:106F3000BFE16F4CFF1D7F63FC0FFE07E33FAF52C5 -:106F4000B2F8697B5D1EEAEF87EEBEBC0D8BFE9644 -:106F50001DE9FDED332E87258FD8C84B9CD6A02D7B -:106F600070A1BE0CF3731EF6FE66C82F75A01EDC62 -:106F700021F2B1991ED564CC779A6C9CD3E0FAAF1C -:106F80004EE8BF3AA1FF0E67D0ABD5355CBF33FBEF -:106F9000420F95E292119F5581EBF72985F28B0FF5 -:106FA000035B6650AF85DC69F3B10B05DC767D5A77 -:106FB00028F469F54BB6F7428FDAD7F9D2BEF82933 -:106FC00050FCF4BFBB447EA94DAF1A74D851C3ED39 -:106FD000E5FC39E9EDC14D363EAA135A280FC1CE62 -:106FE0008F332EEE5F1BFC58E0D17EED2AC8CCEF2C -:106FF000A4E0F70D82DFBF7405E869E48D64E277F1 -:107000008D9B8FF359DFD9601B6213A9253EC8827F -:107010004F326CEAA6F82F7C03CCFEE5968F981DC4 -:1070200082EBBFAA52FCECB3F9E03092ED3F32F6AE -:10703000E9D89FB39BC751E57C97CDDFB2DBC11E7A -:10704000CA8FDBA9F1F3563B6BF6EE5C81EBD32BD9 -:107050007C9F79676EE74B78F40DE2E31584C3B04B -:107060001B41C467D1A4E0F928F6FD27ABDDBFF3CF -:10707000A3AE04DA5F815229CC3C2BE8083D9C9FEB -:10708000F63C9ECDDE57DD3E8BBF0B370ECE6E5FDE -:107090002DF8CDFCC502B7697EAFF6CD1CCFF3A2AB -:1070A000A607709F47D2663A309E9EA91F8CF49E19 -:1070B00033ED3B352ADA70EC4F42FFB132E53F0247 -:1070C00094F0F8BC81FF60CF0D34DDC5F7BF055DDE -:1070D000F3AFEBFAABF891469CD7A8A72A094877FB -:1070E0003EC81EB7BBD1A94D46FC060BFF6E143837 -:1070F000F6FCE72AB92E5DFC2029F4AB1A79EAC523 -:107100009B59D50973251EDF67669B795F6D53BE5A -:1071100052972EDEF533314F7E894139D2EB09C8C3 -:107120009328AF04102F633EDAC7BF568C7BED1552 -:107130008EFF8A98D7D78A790D10A6FD984CE3D692 -:107140000ABD613C3FE9B8498177AD4BC4350618AB -:1071500077B6C073F615E27B5E8C3B7B90F82E1001 -:10716000E32DB8C2713F14E32E18E4B8770BFADEB2 -:107170007D8574563C92E86770746E13E3B55DE1EB -:10718000B801316EDB20C7DD26E8BBED0AE95C22E1 -:10719000C6DD66A373A6F9BBF70AC7ABF4F0F9B373 -:1071A0005FCC5FBB5E33C6578B1C116CBF3368ED81 -:1071B000E78B6E3EBEF184C4C7E4BF168B7DDDC98C -:1071C0002BEE5DA8A519D7A86F5F8F338DF335110E -:1071D000AF319EC6387EB11F3AF93A364E1AFA18C8 -:1071E000F5AF75713D98A9FFA5029EA597898751B6 -:1071F000BF16FB9F98B9FFFB041CF7D9E01FA87FBF -:10720000A3FEEC01E0EF1070745C26FC46FD050364 -:10721000F4FF2D01C7B72E137EA3FEDD03D0E709CF -:1072200001C7139709BF51BF6D80FE9F16703C7D4B -:1072300099F01BF5B70D409FE7041CCF5D26FC4677 -:10724000FDFD7DF3DD3AFF54E33C50182A31DF7831 -:10725000046485E97E8370F204FA01EA2A7EBF01A4 -:1072600074D9CF4199CE4FB1297EE2BE8A18D6DFBC -:107270007D178FFBEDBE16C88FD85D20F295455C5B -:107280004B15F6E0EE6B791C647790E7EF832D5E8B -:10729000B49BF93BB4EF5BC2F399D5AA3899983403 -:1072A0005CA13011439857C3CF5319F69E71AE6A53 -:1072B000B58853EDD680E254BBAB7879E774D01D26 -:1072C000A5A6F3569509CA4345C316E3B1A9F362CF -:1072D0001AACAA36E563AC4A50BE8122F246184188 -:1072E000C09297613BA765DCA37073589B816AAE1F -:1072F0007402DFCF2B8D58FD87263CBCC5EAFF56B4 -:10730000E8C900D64BA3670E7914CE3F91B7395721 -:10731000E06FD0AD5AF073CBEC0FBAA7313C5F9C55 -:10732000E2C44C1678F194A0E31459E7FBE7E0348B -:10733000EBED3E39CFE00FAA9D2D27BD8C3E37BF28 -:10734000046164A36F97B6264471B58F48FE28AEDA -:10735000C6C6BD79575C41F99BD5199A86F1C0B96B -:107360002F8556AB987FDD09610DC9FBD1D7A99F49 -:10737000BC7608EB9C556D01B2736DF139E3BCAF7F -:1073800088CF61B8DAEC5FCE127857B707D6E0D66F -:107390005DF574B7C57E9D25FCCC2F696EEB394930 -:1073A00071EE7196CDCFECF458E3756A676406C64A -:1073B000BFE5B9A7353CF73C26220586B2CFB745D5 -:1073C000B629189F9CB5AB85E7F567B80F23E7B1E1 -:1073D000393EB3FD3E46C8F32F775DDA5E37E20CE7 -:1073E00046DCE114E619BBD14F0F0ABE70B932E496 -:1073F000236FAE6491934E0FD7239D1E1EC7FF4F80 -:1074000039F9EBCAC96F3CD6F843277E63F3B12242 -:107410009C7E9FBED1E3FACFF9FA29F0C1EF4DCFA0 -:107420000768CAB1E4131B795576BA19F7C618650F -:107430000FA43F8F57E215EBACDDAF7F235A8B785B -:1074400019711A80FB6DFB9B53C2978A4BC8C6BD4E -:10745000038E3764C4A7D22BF48F020AF56FC3835F -:10746000E67D61EA3E1D7B7F6BC4791E032F677941 -:1074700044C37B56D818B4DF8779EB87AB707D0C9B -:1074800058F0D6BC7CBDD950C9E56D43A5A2679321 -:10749000BC45ADF71695EFF5A4B32B8C2798EFAB51 -:1074A00028EB0FAFAB3C1A33C3E312F0D8FB999330 -:1074B000119E464BFCEB72E1715F05D08D72AB30D3 -:1074C0002926F9FDBAA53F47A54EE7FA33F58367AC -:1074D00064082F1B5F328DEF29B19E5770E5675905 -:1074E000E45D51F36CF78AD8E4AB2F2E34B8F1EC9D -:1074F000E718DBC5F9147B7BAF1287701ABA7B43A0 -:10750000F67C0C9DF8603F5FE30CD8E0B6F5BF0950 -:10751000DFA5C9F730EE195A27D6B5F58A4EF656CB -:107520008C8189F99E6B845C2A019DEE67FAA657CF -:107530004A8B3F84D3AFB74A797AF83D2556BABB18 -:10754000F2F3AC7C50D29FE7586FCCFBC07ECD7C71 -:10755000BF56FF797E2C7CA9F5BCEF5E2DE937F292 -:10756000C70CA5035EDB3D1683E4AFF2E11080217A -:10757000A632D3AB18AF657384F279EDF54F1BF4E7 -:107580007B632FC16FE8E9EC5D465EED27C3439254 -:1075900040EC935BDB679C8742CFC942AE9F1F00E4 -:1075A000FF4CFCCD2A77D8E6CBE0F8EBC5798FEB22 -:1075B0009EA2894BB0ACF33ED37810E0F85EEEBCEF -:1075C000FFA4700EA98B02EA3357300A51B6CE17CA -:1075D00005E3B44FAE4A3D31F4C7D89C0A219F77EA -:1075E0000E09F1F3E3A67A53593B67A923E6C43C9D -:1075F00010089FC0FAB12074617D8CC7ECAD4AD5EC -:10760000532588A0BCAB054A04DF1BFDE54CB1F651 -:10761000C7CC04D97C1ECBC817205787E1EF9CCC80 -:10762000FC53D6DEC5ECD03DE9F44916B743B39F11 -:10763000F3D279435F44D551248B26E894175CD468 -:107640000861F4E72A3ABB21CA3AFD26C23111BFCC -:10765000C7E9DE85A25D71DAB7CF77F373EC454DEC -:10766000716981699CCA2C2EDF53E778689DF87A8E -:107670002DBFDFA23BB8305E8BE3D5F07D2F5FBE20 -:1076800002C3183D7CAFB9B9FF392109E67B23DE7F -:107690006E85EA45A301DE6DF5D0F37C6B809E819B -:1076A0008FFE279DE75B33715208F3472FFA1A4785 -:1076B000E2BAF17E6B90BE6F7E301CC27C22F9E490 -:1076C000EB749F444ADE6332D430BA4D486AC83FF7 -:1076D00013FE7BBDA67DFE3EBC18BE0BD8381B2515 -:1076E000C7ED381E9617929C7A649729FFC325FC34 -:1076F00046E71A883C5585F797E8D2DD55A6F75E30 -:1077000066B7E1FA3A31407C4FD1536F13F4BE169D -:10771000FDDDA297045DE7D45C72DF64536BA27B4E -:10772000FAE85459CD70EE6DB673EA0D591837C2A8 -:10773000439F6CBC69732A8722BD1E755ACF931B69 -:107740004F39303E5C8E7563450E9A87E27E959583 -:10775000578586E69AFA9F2DE4523EF923A26F766A -:1077600015CF0F617FF545A6FCFF926823BFC7AF19 -:10777000859F9331F62147DE9A6CC32D8991ABAC7E -:10778000E767668AFB504AD73828FFB57432E9505C -:10779000286D03CAB3DA2787AB51BE1F835772F136 -:1077A000007B09836F389BAAA5316B3FFB16D7BFBF -:1077B000807100E37E95D5EDBCBF11A1F0A910C684 -:1077C0004FAA1C642F8F84B007FB1FA93A00CF1764 -:1077D0008D02533FAC3CBCC5DAAF1DDE529FC38166 -:1077E000F10E039E1170C4A3E553FFA0B3F625CCA0 -:1077F000CD2B4E039F7D9C5146BDB1D5D509483355 -:107800002EF4B4E1BE50BFF107E8B7354BD8E13EE6 -:10781000F0A33EDF2571FC632FCAE103C8D7BB0F7D -:1078200052BCA6646527ADEB9D59DCBE5BCBEC0179 -:10783000D589760A7B8ECE2C877280112E87D68FC3 -:10784000B4F2F76456EDD62C8C87654DDD8A7298BC -:10785000A584BE82FCC83AE504DCC7CCD2E234FF82 -:10786000A09CDB191BABCA7270BE65B5B8D2FA6BAF -:10787000ED594E826F5796A4605E28932DC24B69D6 -:107880000A7D6B262B7617688FE3387F2E88D2D33C -:10789000781F5CD81042F99CB6A48AE25FBD9D12A5 -:1078A000C5BFDE927417A66A2F9BDB32EE46468F69 -:1078B000D9B9D127B0DD1239B1D6C9E0597E6B4BA9 -:1078C00005D2A71EF3FD0A70B818F7074BCE841532 -:1078D0003C1756A2249C4CBE3D8193AFF167AC1679 -:1078E000E5DD832761183FFDE5DA3BE837F9C43968 -:1078F00024197A629817E89F0270C6C437F4E9CC5D -:1079000065DCD3359733D17FA0E722D6F6CC685C0F -:10791000E5C39A4476814EF47305C2E3104E39787C -:10792000AAB0DCB4CEB9057EEE690BC5FD489AF06D -:107930006FC260F66FDD022FD4E1674CED9D416BA5 -:10794000590EFC75F130EC6EE9A7FF7E0EF9B8FA1E -:107950006927C53DA73DED4CDCC0CACBF748B4CE86 -:10796000388E73BDFEFE7E89E67DC2E7223DF05E65 -:10797000C043E56677F796CFB172CFD332EC25B22C -:1079800034D07D52E78CF5F4282F2F160ED2F23D1D -:1079900027E6637F8D47DD80EBC4F21F2DB9E973C5 -:1079A000ACBC84C93156597EA0CD358C95EFD2A59B -:1079B0002E2C5F980A2467B13C978E792D17FCDD39 -:1079C0008537ABB48E41680CEE6F7717CE65F2B891 -:1079D000547F6A26B65B7A48C2482AC3E3C00B4587 -:1079E0000CAEE5DF91687D5C76309BDFBD22E877E9 -:1079F0008EA17203FBBE92E189FA7009C46722BFAF -:107A0000961FD8E632AF73EFB65652EA87515EFE44 -:107A10001D360E6BB7E27B5218515C81F90EB85ED1 -:107A2000FEC8DBB04F45FCDA5C153EC46B9D0BEB2A -:107A30002DD1173CE30D217C7B5C33D9F7A5BBF638 -:107A4000B8165721DDE0765C57971DFC0CBFB3C01C -:107A500080AB53267F6165AE672FDD6BAADAEE47F8 -:107A6000E9830B2C702D157A83F97D2EF379B76796 -:107A7000B273494E971D942DE318FC8F9D067E1E10 -:107A8000ED273E3A8F66F0CF58AF0CFEAD342EFA9C -:107A9000537A26A583670BF283C11367FE0D3E1F41 -:107AA0006E0DD2F3D1D610F1693BD2710CCF4BC120 -:107AB000F76CDED6E23D687E0D2F0403C8ABD76AB3 -:107AC000310F332FC2CB85B746A5D025EC74E3B96F -:107AD000DD195D8046CE94EC6FCF50983FB6DD1532 -:107AE000BD1B43D60165EF8CE96CCD6BCA8E4CCAC9 -:107AF00036EDFBAD15F7275D931D22FCD716B9882F -:107B0000DEDB6F9BB44FC49F689DDC7EDBE22730D9 -:107B10003ECEDA7F3E1BFD0BB1FF97A97DE1FC1A3B -:107B20004BFBC2F98D46FB99D4DE73E9F6DBE75FC8 -:107B3000671D7FFE52A3FD4D04BF7A69F80B6F9F4E -:107B4000621DFFF6266ADFECE6FCEDC9F550BE7556 -:107B5000BB379C407D4C17A94DC07CF28ABD58CFE5 -:107B6000587798E6D7307F5B3D945BBD01CC72348B -:107B7000753EC28179596639CAA9C9B2CCAB5C2DB0 -:107B8000CF521E5237CC52BF205266F93EB4E16A42 -:107B90009B5CAA747E91CA08141AE60C4ED7301763 -:107BA000E9A3DA61DC0EBEF7B897CAF75EC7F1BB8E -:107BB00077984AF3186146BFFC5E57F41AF3BDADDF -:107BC0000C2F093773EE54A3F7211EA9F72107BE26 -:107BD000CF12F94E596E207DB7AE74D2BE98899EF1 -:107BE0001DC3993CB0727BB68BD35DF061DDF0C5EF -:107BF00041B3BDBE76B8AB01FD0D7C7F878AE345FE -:107C0000D6E278CDAE9E0AB43BECE3B8CB6A2CE367 -:107C1000784634D238DBB2793CD518C73DA2D1368C -:107C20008EA761AF782FC67904E52CD338EBCAAEA6 -:107C3000B3E23362298DB3DB36CEBA114B6DE36408 -:107C4000717CD87B318E7EA971DCA3A658F119D93D -:107C500044E3FC931D9F914DB671541A07DFE3383E -:107C6000CCF00DE17D592E77CF62E2FF4FBD64E786 -:107C7000B8DCD127C9CEF9B597EC1C564BC37A5066 -:107C8000C9FDDB7BB2F3F8BD5F598CFFAA99CF31F8 -:107C900091771023BFF84E0122E80C22A6DF560888 -:107CA000195C7468F688367C1E9D165C80FEE8A31D -:107CB0003E8AE3BD7F749AEB8E34FAE8CEB8F35C6B -:107CC000D224CF7D7A55C46383D97C1FD2289F13D9 -:107CD000F19F33182762CFB79C40FED059112F4A2D -:107CE000C1DB46EDCE897DBD73BBF83A7571DB69AA -:107CF00027BF37155EA96270CF1368DC19B7DE9312 -:107D0000D92CF8D1F323373F07045A31DD8FD73907 -:107D1000C4122FFCCDF17F7881E7DD4131DEF7FB26 -:107D2000D58EA79EC76AAF4A0B86AF64F8361CD9BA -:107D3000E62C66E5F79DC9F961D5D44F8393CEDF74 -:107D40001B7EC82D51A7C57EFE5AA3B57C9BCD9E38 -:107D50007E23BBCCD89FE5E3867427F26B1EEEB181 -:107D60003216DE864F4ABE0B10BFE607785B039ED5 -:107D7000E6FB9D90A0F52E594071CE5801C569A231 -:107D8000C6BA65836FBED3A345183FE7DF27131D2F -:107D9000EDF0268F676B0EE6E7243BFF9713CFF1DC -:107DA0000C04FFEDABACDF21E6B4DC4760C8C15783 -:107DB0001A6AF79D35C9C72DD159FBCE5AE834DB75 -:107DC00052BEADE5164BFDDB572DB07C5F10BBCB33 -:107DD000F2FD8E8EBB2DE53BE3F759EA2FE96CB33C -:107DE0007CBF4B5F6FF9BEECE0364B7979D70E4B19 -:107DF000FDE6A37B2CDF1DC7AFFA12F981BF94E922 -:107E0000BCF31FD5735BD07EFB6340A1FD9CB7C55F -:107E1000FEDDBBE23EA015287B9371FE8CF7A0DF50 -:107E2000D09CC5E633B325C6A9056B3BA6A01E01B1 -:107E3000BA5AA35A2D5E1B63CEEE64713E51EE74A6 -:107E40004162086EAFA4E2B03D72EABB9264DFC744 -:107E500067FE2E772A69BF2B49256DBF17A49E0A9E -:107E6000B41F63AFBBD39E034FCD4B28864BDC2F93 -:107E700079DE018D66FF6D9ECAE3432F644F9DA797 -:107E800016D071699AEF4D878BA6A2DFD0E44A54D1 -:107E9000A4DBB7E91BAF4BA27B03E7A97CBEDCA543 -:107EA000175BE269CB0E8EB2CCFBD7B2A237ABAC7C -:107EB000DEF91332E959483C37E2CB63717C6D1E21 -:107EC000BE87A305B43EBEDAAAED3BCBFC80D75AF1 -:107ED000EBE8F9ABD6C8BEB3CC257CA3B581CABF4D -:107EE0006D8DD233D9DA48CF33AD2DF4FD6CEB2A4A -:107EF0002A9F6B8DD1F3EDD60E7ABEDB1AA7EFE782 -:107F00005B3BA9FC7EAB4E4F631E18F62E44843DAE -:107F1000D9F78309BCDC2B70900B8D386698EE95F1 -:107F2000EA552F56A01DDDFB9A9BF26E33D1C92E68 -:107F30007799F9A7D17ABF58B7C6998DA7378BF330 -:107F4000C7EB803ACC91583FDA4571B4AC9F7E863E -:107F5000EC71F65E017ECF7278769AFB3ED1FF46D9 -:107F60007E0DC427A3FEB96FFFDBA48555C89F32E1 -:107F70007EEFD773720BE7DBBEF097C70E4C3FB2B4 -:107F8000F98AFAD351FAE96F46607CEABD02839E12 -:107F9000DD2330B8A5A8911D2887BD47DC8457EFA5 -:107FA000B16C9E8F8241B541E4BF2E3BE8D5CDFA3E -:107FB000617957AE6ED51745BA595FF49EDAE7C7B7 -:107FC00079BF3228EB67C7A37C68423EB8DC19FD55 -:107FD0002FEF2AD5554B3FD6726F5CAAA37B202189 -:107FE0009433F712F7A7AE0CBA689C770F8EA2FCF9 -:107FF00003E627EA6779BC53E7E30675B35C36AD61 -:10800000CAD6CF0E49C197A9DFBF367C0047E077BB -:108010009ECCE771077A82F2AF2EBAE7ED98F32291 -:10802000AE3B6EF6BF8F295F48A1B2D16F73971C2C -:1080300073E3795E3864198FB50B193EBAF9FE9C6B -:10804000FE7CB7E683FF166589D66D7EBE3C8AE767 -:10805000CB597F1714B543BA2675BEBC59C8E57213 -:108060004FD21565AFDE3B32EA92F920EFB69E0A99 -:1080700028A3318F20EE4267A4B1EBAAE9A81FDF45 -:108080003BB2BA10E369CBE4DE7BD39D9BFD50E5A8 -:108090007136D09D3D49133E467C0680F5EB49C1C3 -:1080A0008F927ECE54B6EB6BE3E9F0F1B8FB8A43D6 -:1080B000A7677E8EC1BFE2E8072E84E3A81A75F891 -:1080C0004CF84BE27CFDD2836FBA10BFB79DB18AEA -:1080D000FB2FA1A7FAC3A9062DFBA131E8C679BCE5 -:1080E00090FFF602CAD3577ECDA6E63BBF7002FED4 -:1080F0009E83B15F619C7B5804113FD26BE1916517 -:10810000141F7EE7992F0A7B2E3E09E5E33D70D4CC -:10811000217EEFC1CBFEF126FA95FBB81F031DDCD3 -:108120008E31CE05327BD662D72CE9B49617C39C2C -:1081300042D41B8B1F75822EE1FD9FA67B9818DE13 -:10814000F93E6EEF2E8196B568CF296EEE1F2C0C8E -:108150008052CCF4E9F21F3E3609EDFECFF8F8BEAE -:10816000A311C7B82B8FDB7B4BF37517EE27FCEE03 -:10817000C8F8799F43E973EB6B715D869CF4FB7FD4 -:10818000777458E11B087E3BBCC6B9F77EF1140139 -:10819000877C504A9B9F36D927E44EE891877C56CE -:1081A0003B7F9DAD5CEF1371561964E4F37B014F87 -:1081B000CC9143DFE99C6DECB03BBC3A84F76A4557 -:1081C00022285FCC2E1807A67ABF57A3F4FEBCF472 -:1081D000D2623A67AE24C6513E9E07284FD125E4AD -:1081E00041CEF28F836B304EDA424EFD6AAF7F2F65 -:1081F00096D7FAF839A8669CA7ACBFCDFE99A730F0 -:10820000AEEF8178422BC5FD6F6BFCDB1BB296B3E2 -:10821000713EA13EC117C88F3050BC28BBD25ACF87 -:1082200017B69697F6D129219BCF7DF83D6A027F3C -:10823000AF026A94F366BB798587C30F78AF2AAB28 -:108240007F8FB0E757402846798B412E07F7CCE265 -:108250007913F7F842E118FB2E291A9D8F58874DA4 -:108260004DEB58F38712E826BDDEACF4B8502E9BD8 -:108270003F54E8FD6E35FA20D2D5051AD9B91E460D -:1082800034DCBF56D43A8BDD0B25E27E405BFEC268 -:10829000265FC0E2EF197AC129F422D317EB7C05DF -:1082A000A8077B66F27DF5A48BEFEFF07AAE54BDA4 -:1082B0004D0847A67ADE54BD6DE9EA2DFFE1779FB0 -:1082C00089B1F9BEF4FBDFF4E366DA3B4ABC10F394 -:1082D0001F9A0EACF1A31CBFADC4FC88F73B7AFA21 -:1082E000BCF79F097D87F94E785E7E85E0D3BBFFA2 -:1082F000B8F126A4FBC5034E3A6FDF7CD09D7033E6 -:1083000026AE38721797A783EE3779791DFDFE48A0 -:10831000F351EB7C5BFAE4370B43B4B9172B16F738 -:10832000B393FDBC62FFEF67A23DD20C3DA427ECE6 -:10833000ED70FC0FF368FD5A80E7FEEDDF8D7CAB3E -:108340006621F7CD4736525E55F391599447D56C67 -:108350009BE78DC20F39EAB3FE6E83410FD0B95D42 -:10836000BCFA3BDF1AF72683E7FCFE5FF8254BFCDF -:1083700088EB89DEAE3B1E7F369459BFBF2FFCFAD7 -:10838000543B9DDFFF7D94DBF1708C3F9B9C093F4C -:10839000FA4D4D7B9C61A641A0E9BBFB9EF836CA15 -:1083A000F7EB6E8A372CFBEEF3AF5EC7CACB9E723B -:1083B000E6D7733454CC0336F88267DC315FD7E0FC -:1083C000C3D21F3CEF0A8DE5EF1FC84BF163D953B1 -:1083D000275C30B63FFDA6759D70F1F3E736BE749D -:1083E000BD3913EDEED5DFF9930BE7D73BC7251861 -:1083F0005ADABF7DE39EE7C9AE433A111F059FFAE3 -:10840000F8D68F5F899B9E9D40F502B88E0DC4AF54 -:108410006FA3CC14905C7FEF59DC2FF8953B8C74E4 -:1084200068FCDED7FD88CF5B4A0B97EFC7D614E216 -:108430003E7AA3335618A0277FDFB8FB1B24774B67 -:108440004E7FA390E7416945FCF78C62451407DC39 -:108450007533E1B918A2247F8D8FC99487FE470533 -:10846000EA9E4A333F6EF0733DF6D65E375D7EF787 -:10847000162A5CF4175F96757EDE96E7257EC3D8D4 -:10848000F7C0FB1B59F98F1ECEAF02BFC3B8D7CAC6 -:108490006391DBFDEBBA914FEF0ED78662BC92D1B0 -:1084A0002126E826A11E924FCF18CAF90421659211 -:1084B00068C7F4E4347C8FF5BB9D9A779CA59D58E2 -:1084C000D7F8F8F788F119DC59689FBD55C8EC9DBD -:1084D00034F82DF31BF39FD91F263933CD733EEFAC -:1084E000F7AFE7F3DC98F7FAEC3AFCFEAFAFF079C0 -:1084F00084ED709D67702586D2F7137325D20B6EBD -:1085000048A49BDFFB9D627E5BBF33AF9CEC5B436B -:108510004E18FC0AAE5B2979E1FBBC8C0F64BF2DC1 -:108520007E94B537DBE7382ED573A5DE9BD6FB25C9 -:10853000421F5CE7B7FD8ECBAE8241DDFBD3E4D4B6 -:108540009FF836CE5F365F71FD69FAAE93F244FE56 -:1085500070E8B957BFCAE4FC0F5DC6BCB5EA53FB6F -:10856000BC6D3C3C11D2CDDB3FA861483B6FD9FBD1 -:10857000B4F3564D923CFF47E953837E0BFDD63C46 -:1085800027433F66A2A35D3FFEC517227ADAF52393 -:10859000FB7B0526F5974343FE0CB95BFA4FCBE90D -:1085A0007742FAE4D390BF3EF934E4CF8EAF957EA4 -:1085B000F6EF9F4143C58817B3A7F32188F9309E92 -:1085C000FA1399E2A917184C6B199F2F1C2AA5734F -:1085D000C46BBCDC3FBF10E8F1E755D13D3854EE29 -:1085E0002970AD457D61BCEFF1F2F8F785488FDF6A -:1085F0009C07F2E631D98FFB5D491DEAD2F9234C85 -:1086000023131C49C8F49DC78B2FA0FD87E3658DFC -:10861000D0916F336475C42AF4F3E3FCBCFCA2B6BA -:10862000AFF8711FFEC2B1515B517FDDF9A20CE2C0 -:10863000F71315CC37B943F0FF6D886D9FC2F0BCBE -:10864000E318F72B166D4A2F2F4B45FDC5EA3D2E3B -:10865000D44BCC2F38638E872F15BF4BD6B8CBF6B3 -:10866000FED81749AE96DAE42A2AFCC6EF1A7275CC -:108670002D5C2BFC3687399F6D865CB515ED920B12 -:10868000A7781CB2F7984CFCE83D24F1FC278C0736 -:108690004F4679E87199F3D8CEA3FCA5B9DFA0EFD6 -:1086A000FBD3BF99743FABD2F4CCAFC7ED64CFF32B -:1086B000CFBC5EF1632CFFF09F47FC1AFAD79F7680 -:1086C000FCCFB49F7DE1B89BE0B870FC6723EEC798 -:1086D000F2B36EBAAFE6C2436E9EFF79DC47F7D6BF -:1086E0005E18CEF38556FFE44FE3E8BE3EBCC99D5D -:1086F000F1ED353FF7C77A8FFDDB6F317FB8F79823 -:108700003B8478341FCFA6FDADE667BD14A7B9F052 -:10871000933F4D32E7335D293E2BC47D88177CD0D3 -:108720008079CA1772F9BE41F38F27EFC37344CB28 -:108730008F9C70E17ECCB49FFEFB38D43B170E7348 -:108740007BE27D677237EEB3FECE7FFB3A27C677BA -:1087500071BD1E06D09AA3DF88F7E1F4A70BA7C36B -:10876000054607C48BD1A511F565267AFCEFBF5BE2 -:108770007A7C301FC76F3AF6599A3729BA481A7F60 -:10878000EFD3F16813C39FBF3FFEA771681FFDA120 -:10879000AB8DD6F981F02ECAF97F0D6F293118BC47 -:1087A0006BFE6EF1E6F27FDC1FE2797FB679D05F77 -:1087B000CE7F782F95BFE70B13BC839CFF0D7FB74F -:1087C000F87F42BE1F667CF70FCCF7FF92C3F78598 -:1087D000FFFEF01E88EF2F0ABEFB02988770E1278C -:1087E000FF4EF17503FF81F0DEFE7F29DE863DB48A -:1087F000C1118E9795621E76A23BC4E05C53392767 -:108800008E612959E45DDBE17A2187FB17B2C4E36D -:1088100036309CC78F40F81B7DBF03A9F2F3558A01 -:10882000BA96DF47A684E97EBD0D572F0C536E071D -:1088300054BF16C572C914FA7D5BBBDFD52E8126E5 -:1088400031FB4FB9FA0BA7D0FE77563A12EE71F40E -:108850007C139FEB44DCCB197059FC0DD5E62778CF -:1088600043D6EF6ED19F07AAE3F8FBDD1E5509E85A -:108870006C7CB5364EF8606E67DCB46F88BF8F9D38 -:1088800030F9637BF107024DF6E4E5D2EF4F39DCB6 -:10889000FF94A5EA6ECC8B85AB1CFC7E73E0E78A67 -:1088A00037948475BA8F59F897297AAEED463A2AEB -:1088B000C0FC438E1FF99520FC494574A1543A34FD -:1088C000AFB59EF09706E40FE7C78826C19F9516BF -:1088D0007E18F44FC3170B3F0CFA5E2E5FECFCB012 -:1088E000D3FDE7393C3E67E793251FA480FB2509AC -:1088F0006620FFECD03E8A8BBCF78F6FDE84F59745 -:10890000FD5806FCDDC4F70FF92081F357D15DE86F -:10891000672D3D22535CF8FF002820961900800047 -:10892000000000001F8B080000000000000BED7D20 -:108930007B7C54D5B5F03E73CE4C6692C964F29AF6 -:10894000CCE4C524811834E0244040419D104010FF -:10895000EE754011B451470810CC13A4BDB4D51F17 -:1089600003C1343C6C43E5A5453A202AAD5803A623 -:108970005E50D4411E62AB6DB4DC5BB46883A280F0 -:10898000F24869F5C3FB79CBB7D6DA7B67CE994C51 -:1089900040FBF577BF7FBEFC73B2CFD967EFB5D789 -:1089A0007BADBDCE9E4B97E0EF26C62E892B632D67 -:1089B0008C653256F77C3263198CDDBF2B213CA5C8 -:1089C00000AE2F7E3C940D61ECDCB29E4339703FCB -:1089D000F44BC5F714760F750FBD0DEEDFAFB17B0D -:1089E00003A5D171E435CD69626C046367F624CDCB -:1089F0000CDB1953B6EFBB87C6ED98614E50A2FD54 -:108A00006C4E33CD0BFDFCF83CF40B253C48E93BA8 -:108A10001E634BF978BF50387CBBCD611BC2B77D5C -:108A20008B250870346DFF8BC50F70543DFF9CA3E0 -:108A30001BE66BDAADB24809A3BF4B0C9FAB918428 -:108A4000A1743D8E57C6FC76A582B146FCD70BD7E4 -:108A5000CE8629CC01D78E557F511DF8BEF9A36E65 -:108A60006BF4FDBAE75F793104A8A97BE119871798 -:108A7000AE9F753DE560A534DE7D9614C634BB66B9 -:108A8000E88FE35E4CEB3B0ECCCB980BEEF35BAC8C -:108A9000A963059FAFF35F4E32848FC138126E58C1 -:108AA000DF67F88F87B151CEE48C4FAF81FF47B2BB -:108AB000919754B86E4F67ECBABE788AE22BC4E93E -:108AC000F9DC179B43809F33BB3EDF8CF0D7FFFD63 -:108AD000AF9B7F08F863AFDA9C4FC1BA9B7EF91F4A -:108AE0000EA4AF7C6F9A53A1F7CEE5B19007FA9D23 -:108AF0007B2F211C825BE75E3999EF85F59EDBF9C0 -:108B000095CB0BFD17BD323E0BD7BFE8D75559CCDF -:108B1000DE3F1CE79630164ED0C315263A7A77C34F -:108B2000A059D0DC2BAE31F4D8DFB93F1FE13C7B3C -:108B300034C1978078827B8BCB913E40A7A1BCFD4E -:108B400020E0B771C78FFEA20E8D87E7508EC98DCA -:108B500074FD7802C2C9582487B911BF3DAD4E7B60 -:108B6000DFFEBDF43A02F4BCF61BD06DC70A3E6FBF -:108B700007D0CDD1976E67F11FA04F13D22D294A90 -:108B8000B72F58F0E79E226877A6135DE3E12BF23A -:108B90000DF055ABF0F16F70FA7FE044F9D995D440 -:108BA0004BAF2948AFE7BEC86740EF53E69E7BD87E -:108BB00070C67A5E49706E85FBF7BFF24792937379 -:108BC000BF7EC78274843FBB02EB3AC77AFFBA709C -:108BD0009D8D8A58E7B6E44882238AF7C6F0D48987 -:108BE0005E07DD3F4EF7C39C7F117F39489FF0BE83 -:108BF000DB9538F4E87016D23A583893D6DDB0EDEC -:108C00004F16E41B4927A48F320AE9757C02DE97D0 -:108C10007492EB8E1DCF897818A9A3DB362E877D41 -:108C2000E9DA636145F1E805F0E27B082FB4CF6D26 -:108C300049D094147E3F17D671CECC6676201C6145 -:108C4000E58FF1E8CBD8325ACFB3B17229D6772568 -:108C5000B9BC12DCFF285E9E703A697C899F335F45 -:108C6000C7D7CF8750CE01FEDDF6E041E41FC6AC8A -:108C7000E11330CEBD4C61294551BC4978CF688C99 -:108C8000F4EE995FAAE110ACBFB5633FE9D958F99A -:108C90008675F93BE2CCF747315FE3EE7D43510F38 -:108CA0009D797D0FF15FE38EE396108C7368FB0B6B -:108CB00096EED228BFA3FE0EEBF4F7995FED1B4AA8 -:108CC000FA16C78FA36F4E88F19BF61AC76FDAF1B9 -:108CD00017C3F875A10E8BD37EE5793ED3FC3370B4 -:108CE000BD9F759919EABFCF3AD489E138F3BE29FF -:108CF000EC97C453EB3B16B263C3DF4D0C27009EC9 -:108D000016BD33F14F291978B57801B5AC7329E751 -:108D1000ABCE87FC394897CE77EE52D19EBC88788F -:108D2000BC2A3A6EC591E6AA6490DB8A6381E1C8E9 -:108D300056B1FA60E45193016E98270BF5F372185F -:108D4000C70BE330CDE70EC0B8AA63C244844775B1 -:108D50009A9CB6B876958F67B6075810E03283DDD7 -:108D6000F6EAF8C93DCD3194A5E0F23C26D40B0BD0 -:108D700081BD503FBB2DAC4403F89829D1F7148C2A -:108D8000BB70B0BFEC20B417CE71FB42F0DC731B9C -:108D90007FEFACD31E325D8BEDFC30CA51D24595CE -:108DA0007941F59D51DE9ACB40252409BECAE94898 -:108DB000223B93A4793754433BA956F30146D92764 -:108DC000F6605E6A26BE67A1F73CA98AF629AEDB8B -:108DD000C11C286F727CD94F8ECBB4C8505C3FB396 -:108DE000328D815DC9651C6E55ACA7887529C8DFB9 -:108DF0002D531D5BB1BD29B996EC7F3EEBD9E7073A -:108E0000BA3DE9987018F518FC6BC27E79CD46FB27 -:108E10003E60B1B15D10D262E4D76B0A00FF15B5B8 -:108E200019EF6754552E18E063EC9ED4CE891AE8EA -:108E3000EF8C19953B7300A79357BECBDBCF5496AD -:108E400079A0FD1F6B1A2669A047327E5F59960FE5 -:108E5000ED0B69DF9F44CFEB0049D783EA5F3374A2 -:108E600052A8342AB79900668A4AF27C23E2E16C60 -:108E7000E04C2B3E6D98FEA5051EE15F00F190379A -:108E80008AE321D77E6C2783FE034CDD4B912F7F35 -:108E9000FECAFF4AC57E5EE6A4F53AD972E7A75638 -:108EA0005C3C1B7569D8E5F499C63E957CA846E5FF -:108EB00020C515BC3515F8AA7556C98609A86BEBEF -:108EC0007DC45F30B393ECA1ECEFCC20FAD408FA68 -:108ED000209C56E0B339BC0BAB65ED420F8D73E2BD -:108EE0003C4AA85EBD74CDB7876796E49B64968CB8 -:108EF000F7B57A2FC1D595E99F83F8FA2A334857F9 -:108F000079DF3D6BA63708F8BD3135300FD7E199D1 -:108F10007B311FE19F92CA68BCAA79763FDAD50BF4 -:108F20007B41FDC5912B79DDBA84F9B441FD3F9FAA -:108F30009616FC2E8E5FF89A77D76118EFDA1A8BA7 -:108F4000CF06535CBB78B84F4B677C41E87708BAD3 -:108F5000B991962877DF636194BBF3098ADF0FED3F -:108F6000F30F38492FE7D64C398CF6EC7C52414749 -:108F700004EFFFD04BF2081E8082F290B7372562D3 -:108F800073103F7F19C3CF5F1AF9D738EFF94BDE63 -:108F9000DDDD349E538C070E113CCF13743AAF7253 -:108FA000BFFCFC122FC101EEE33EB4B7DF74BEB5C7 -:108FB000A9C24F12F479C8E65F87F400FC6FD0E3D2 -:108FC000FF67FDD37133F6033AD235968E73ADCD7C -:108FD000F9A817EE0F744C008DCD4ECEFD5E053214 -:108FE000F7D4D4E036EC5F3FB3EB9099A0692E46FE -:108FF000B9ED4B6785F4B96BEF7D4BCDD06E423A3E -:1090000079FBD2F3DAC56544371D7D3B70FC6BF705 -:10901000FEC584F04BBA6E50B81D887DFFE55445FF -:10902000CC5BBFD40CF8BCB0DB42FE6F6CBF83A935 -:109030005EEA27DB43AD153E0DE434CBC482F1C6B6 -:109040003DD8675CAB2F210EFCBDE339F97880FF7A -:1090500037F4F8FF6DFFF8FF9DC0FFEFBE25FE8FD0 -:10906000209DFBC3BFF4BBEB847EA863ABC9DFFCD0 -:10907000C43FCD3510E69FA0DA491EE63FA5921CFD -:1090800042FF291E57549FCCBFAE791FAE77FE1307 -:109090000AF16D4D90EBF9CFE74E3984FA7D4EBB66 -:1090A000D17F9A3B33644138E76D34DE9F1F8E8950 -:1090B00007994EAF035F9C89F2EF00AE77DC642F17 -:1090C00055211F55F34A53D05F7AD5ECFD3DF9E3A6 -:1090D0006FAA6C6B1CFCE7A715903D96EDBC664033 -:1090E00092CECEB31A9B09F5A51C77DCBCD22CF42A -:1090F0006B16267B2F1B870D586CB4EB05A144E63D -:10910000D58D5BD49666680F6ACF36F4BF6A63A1CB -:10911000E1F9E0F0D586E7D76C2F37B487745C6F40 -:10912000E87FEDEEB1867659E41643FF6187A71913 -:10913000DA23BAEE32F41F797496E1F975DDF71B84 -:109140009E8F3EB5D0D0BEA1E707463FC6C4484F6C -:10915000B24485F4E68125A72A4E20C30D57C621C7 -:109160003EAB46F1BE0716584C4E075E8B4D4EE0A7 -:109170008FD7E74C213FE0C00297DF4BD70A3FC6AD -:109180003F4C1D333C18C7CF1DEF3C5D7142376F1C -:1091900095D56CD073E39DC6F6B034113F0CE07CDE -:1091A000332ACD285F6AF39488059AD9F30766E1DC -:1091B0007C2067A3D3B89CD1F58A72E668AEC0362E -:1091C000C859655A1C3963C2DE560A7E82ABDF522B -:1091D0008E8C954C76D98F37BD743FA441BC32D666 -:1091E000EACB3D88EB32F9329009C7CD0C1CE0E3A5 -:1091F00009FBCC4A4CDFC63E4B39779BBC21B26B96 -:10920000698CF24B8FCD294E613AFCDE956612FADD -:10921000A09DC791CEEDC33489C742FDFD8923B41B -:1092200092E87D65DE942C943B773F7AD1E22E1A4A -:10923000BC0DF4B1C553405779BF75A66962380EAD -:109240007D1BD2789C21FDAEC151BFAB01F17BD615 -:10925000FDEEFA4180AFC6EA1EF2BBDCA6F605873A -:10926000705DBF5179DE0C3C2BD40B73841F3D67BE -:10927000D24F171C02FD34E7ED41A49FE43C9B96BE -:109280004406EBFD86DC7EE2AAED029ECD4BFC831C -:109290006B06115CA41FA49F9E1F6A9880F1CE00EC -:1092A000D64C71E37A13AB8D37CE0A314E16921C31 -:1092B000E175DA494ECECE3DE6D0601D89C9C115B3 -:1092C000C86FB3AEEDAAE0FE98DF370DF8273F7206 -:1092D000F77AEC9FEFD65858E93B7F5675B0AD0052 -:1092E000D6B73CCDE4B353BB47C1FE090F32960E4F -:1092F000FD97FF5D257896BF7E1DC3782DC1DECC1E -:10930000D0AF95EBDA9FF638E147ED4C223BC8D061 -:109310002505FC7D57D0FE0B774D17FA1D5FAC3548 -:10932000D37C5FC01A9D30FE179D6A189DF7436974 -:10933000891113B4D5B664B2DFF9E88342FFB99D51 -:10934000C9616F41142FDAC6312C02F62E2197AF76 -:109350007F799A3D6C2FA075AFC1754B38E5BAF394 -:10936000FA89432369DCCE327F8981CE1E88C9BA4F -:10937000706E0D9C7F18475D6BA638714EAA9DE0FC -:109380000C2F090DAE31F75D5FAB7BDAAD77023C98 -:109390002D4754A6C238DEEE76C2C75CC047D8DB84 -:1093A00017DF67BD055F9A54823B82FCA86E9C4024 -:1093B000EB62E8D7C37B0D3F57D8E305C897C18957 -:1093C00044E76C137BAAA0EF3ADE48E3F9DBC369FC -:1093D0004EBA5ADCC55C4EDC03076F83F1DE423DBA -:1093E0006565F1FC80DFA7717F9AAEB1FA09EC6088 -:1093F00008E1B8B051217A9E54C21633A0ACEEF603 -:1094000066F207A47E52FD2AF91F524F49B8408FD9 -:10941000BD9FA6B38F6ACA834371DCFEFDB59DFB79 -:109420002CE8AF3919F96B528FF6E7AFA19F86FC94 -:1094300027FDB45331EB84F57D2ED6F779BCF5F5D5 -:10944000D1BF77354B3FE72F6997F133332DF1F5D6 -:10945000D355E99C0E4D4E0BA3FC14C6CBE83FCC74 -:109460003785B7621E4A0BDBA6EAF0939D2EFD3CC2 -:10947000EE6FF4A7F7AE149714AE2A25FD7BA1CBAF -:109480009B9206D78C8F95E678E3A88B9F1D8674F8 -:109490009A6FAB4C4A07389DE9467C3DB6A28FFDDA -:1094A0004A4FE7F8A36B1FFCD9017F26839FF86220 -:1094B000B197F0E749BF8C9F78F6B60F2BD02E9D61 -:1094C00013786AEC8D7BB99ECE06638579AD06E68E -:1094D0007FF244096F5F5268D783F2759BED81413B -:1094E000387ED3EE494FEAEDF7D7693C9FC6EC6969 -:1094F000946F95E3B984DE8738FBC64FBCA4FFBFE9 -:1095000044FA46E3EDEE0A8CB75A7E7D550AFA67B7 -:10951000E35EBCD389D70B190309AF675F4CF02317 -:109520009C67D3401FDBB13DF210E6213E5F7238ED -:109530004D4F97B3BF7AA7C20CE39CDDF54E8586ED -:10954000F90C91AFE9B54797FE501180F743635985 -:1095500049B35DC727566E2FD6DA78BE23D3656927 -:1095600065D7423C92994AEFAF73997E8CF755EBE1 -:109570001FF24FA09CC5E477D69ABD2D76E03388C4 -:10958000E57CB84FB070B0DF3307F33B53DD949701 -:109590006951B81E0DCDE1716846212B2980F1CCAF -:1095A0002655C5F77A3CCCB715BA241C688FA0DACB -:1095B0004BECEAF023F8C313D3089FA3CF38158CE4 -:1095C00027643E48ABE2E3F54CB784B7EAF240EEDD -:1095D000991AD9C524AD83A19EBE2F338DE097F98A -:1095E000A0AA6933039508D7C3268A6740F12AA841 -:1095F0000F73C43A0A3CBB5648DF4673215B324CBA -:10960000FEB055C0FF0301CF0EAFC98FF957476EAB -:10961000E4A819FCBB9CE58C7DA4F323932C42DECB -:10962000DE5649DE92BFBEC93A13FCA3A4449E573E -:1096300075045A17605E1CEF7FA71CE9C2DF27FA8A -:10964000A898A662A11400397994715C49BFCE250F -:1096500056DF4060E85D4B9C747D7A899BE0FAE9B7 -:10966000122F5D7FB2A484EEF727A757BA3EB2044B -:10967000E6D5F153C648C00AAC37436524CF8F8C7A -:10968000A8489915C71F90D7C7971C768D1B241023 -:1096900008F4C8AE776E59594074462182D5BDBDD5 -:1096A000C23F86B187CDFE050C586B4DFAD7E3302B -:1096B0006FB54A31519EEAA7E96FAC08E5E2D54B98 -:1096C000744FDAFF1EC37CA76778BB82F2EEA96FE6 -:1096D000273E18DED5C582E2BE1FDA9E23FCFEC3FC -:1096E000368EE7D58C4D4478ED0A0BE0F59C8DFB6A -:1096F000839FDAB87E3C2DAE43D2839B518EFFE62A -:109700003C5AFC3080672B7D3F1FF73B92F67F452C -:10971000F96075A8C58AF2E1D97B9CF6415453B72C -:109720008581497EEDD13F537E4DB5040A78FBD744 -:109730002BB19DE9086C41978D85FE3CE9801BE4C7 -:1097400006F9E17AC24608E578954DB443C7080F9B -:10975000ABCCBCFDDAA37FA275AF3207E6235EB0C7 -:10976000BD1CC65B95DAE13641DBBEF4BD15876FE3 -:10977000C0B6ECFFDE8A10BCFF52BAD437010FEA44 -:109780008FDEB613DA43746D8DB799955FE5FA1ADB -:10979000F67F752807F8B571AFD281A079F6AE5182 -:1097A000709D9EDD6B08DFF407F281CBA03CA935EC -:1097B00064C1F79F5E72D8B91CE8ACA5B5B910EFCB -:1097C00057B9837E7FBCFC44A6F47FA1BF3ECF1671 -:1097D00036F774EBFC710FE372C396837E88E35F08 -:1097E0000CCDAC3C9D01E3AC55822B55D433CF99C5 -:1097F0009DA8475817D74367C4582C9C4DFE4DBDB4 -:109800008D37CDCB822B07A39EB85BF361FC5C57F1 -:10981000D05E89F6BD6E4F816F298BF24B5D6A87F2 -:10982000AB1CF927D5D86E117997ACD4E6D4D452B5 -:10983000DC8F58938FFB058DACFD9E1F20BC6FA95C -:109840000CFDF4D3FBAE4B190DED0668A3DFD0D0B1 -:10985000F98E05F9F3D10CAE3F1B3B817F609CD59F -:10986000205F7E7064B668CE44D44F4FFB9BAF46FA -:1098700017EFEB47FF6B920DE8FB4CA1DF89F47605 -:109880006798575AC1697CC6E21CCCCAB06D27FEE6 -:10989000AA2B33713962F6DFF835B1FF09EDE38F9A -:1098A0004EBA459FDFF5E0BE0CE0B969933D644ACE -:1098B000217BF3BFD1DE366E3485507F99AC5D16C7 -:1098C000A4AF1BF776893E4EC2DB22A9CF63F4F525 -:1098D000A24969B7607BD1C385CED065F297B51731 -:1098E000935858E71F3D9AC1E5B8560BD13E4AED53 -:1098F00045073DFFE7CD6763E161979BCF4ECFE51D -:109900007CF5D1F988AEFBCB7FB37E20D06DD14EF4 -:10991000B32941C7778B768AFD6A9B3F0BC7C9B4D1 -:10992000308177F0F701BF5A416F3BA4819C3FD251 -:109930002BE703568E1B83748B3E67A30C7AC08F74 -:10994000F1E62389520F5C15BF7F624CFF42D9F6C6 -:10995000AD1C97DB179ECCC468DB0AFDB5FF4EE853 -:109960006D237C6B4C31E3A5C9F947D17892AF8E5A -:10997000A757FE2634109EA7B65762FD46CF1CE6B9 -:1099800045BB8CFCEAD3E9FDE3E95CAE6B2F16190D -:10999000E81DC57BB1E1FEC9256EC3BEDFBCEA454B -:1099A000B43F791CF53C8EC3421457D56ECA616131 -:1099B0009D3FF5FFE1F847E118DD0F1C37FE0FC3AF -:1099C000516090CF281C030DF7FF5138B6DE517C53 -:1099D0004B017459A784AC8568171E3251DE444D83 -:1099E0001DE75D8AFB0F0F69E4E7A14B82F51F8538 -:1099F0001A3BAC95A3FCB4FB31CE67CB78FE08EEE6 -:109A0000B799CBC90E911F5CB437E13EF4D30A6B12 -:109A1000FDF3F1CA724B697F43EE0B32910793FB62 -:109A200019839CAC5203E76D74E67D64A70A03D5E5 -:109A300075E8CCA9C9C313D13EAE338543385FE87E -:109A4000A77CBE4C53B8C38ABAD731D089F62ED37F -:109A5000C1F51F5B594AF66FABA9F0EA0500C7C311 -:109A60004A65E29B88E7D442CAFFE2FD85707FAB7E -:109A7000B05B6AAACF89766AABB05B2D42BFCBFBE5 -:109A8000496981FBD09F3895B1E816EB75A887FC32 -:109A90006DE9606F4E662C5AE9F6A0BDF1165AC109 -:109AA000BE9C5CFB00D99BAD4BBDD9CED4687BD0AE -:109AB0007F83B5263DF1C04AF45796DB17DE8FFE53 -:109AC0000E3CFF8D15F4EC336942EF88E785BD7AD3 -:109AD0000AF412E83175696F3B847AA9B057EF3CFC -:109AE000407A67DB6695DA6FC37CE8FFC03A422AAA -:109AF000AE7790467EBD0D604984B66D7021ED1342 -:109B0000C1BA5922FAD783F97399CFB70C32513EB3 -:109B10001FFB231E6D1EDEDF3295F9705FCB926C4A -:109B2000A73844EE0FA8629F2A51D46928CEA91401 -:109B3000DF5957972FC478CC3AD0B80F6B89A9E773 -:109B40005063EB3BEC11F2BF4E6788BC7E3A735F0B -:109B50002A8ADE07BD5D8E57D79DCB2B11DE85C9C6 -:109B6000CCA9625E2518A17DCE58BB66053BEAD51F -:109B7000C987D5CEFCF1EA090E65723FD67E51A3A6 -:109B8000F866AD02FE0DDAD164CE67D23F323B25D6 -:109B9000DF1AEDAEF497CCA97C2D8B268DCDC2F8C3 -:109BA0005DB5FBADE8E7EC7396535E4065BE5B2B9D -:109BB00075FECEF2C824CABF694E3FF9E145224E78 -:109BC000549D3EA6F7735A9740607915634F56141B -:109BD0008F457978DC16B116217DD79928DEDB5FB9 -:109BE0007E7F48C1FCDB624672FA64856B2CE6D14D -:109BF000B7688194BB515E8EC07C5E4E37BE9FDBE2 -:109C0000A260BEF80B6B2005F5C123C8F73ABC3C37 -:109C10002FF0F1F70CAE7F1E3673B968057822007D -:109C20008776F11ACA6FADC9E4790F4BF538CAFFD0 -:109C300058001F98DF4B60CD2127AD97E7EB12DC72 -:109C400026435DA0767128BDFFF70C9321AE6E838D -:109C5000757A75FACBC64294AF431C3F15C77F791E -:109C60003B93C72356F087BCE49FC4EC73F7F58F92 -:109C7000C85F91F4E9F55314F04F2E138F3541BCB2 -:109C8000ACD7F74D5A0FE9DF268887F1FE39A79543 -:109C9000FC4359F76017FAACD51D6C1F8D7C9EE80C -:109CA000188A79008D7510525663DD03EA43B7D6E2 -:109CB000D3CBFF20F32D36C756ECB75CD44124F943 -:109CC0008CF293C8DA237E94CF129DDC30C477885F -:109CD000C64DF01AEF331664186768EED83A89500B -:109CE0006F3D14D5F369EC31DCBF967E6F8EA847CB -:109CF0003A9BF421E5D1C0EFAD4CA77D801E8A5B75 -:109D000064BEE7DBFAC9453806E61116FFB5E20482 -:109D1000CAD9D40905783F49E37C02AEB896508E83 -:109D2000E1D584F9A9B0FE3B85FDCB50DBA96EE4FB -:109D30003511CFFECD39D3437114E093EA6D127D16 -:109D4000DD142F0A3F4DEDD58F7F5EE137FA9D215F -:109D5000BD9FB76ADD9F572CE7F10AB55F7B3442A0 -:109D6000FAF3619B6CBF4C6DB073118C97D88B0963 -:109D70005EE44378DF8FF2C6EE28263F5B2D64D980 -:109D8000888F710E2BE94DF5C584ADE807435CFC67 -:109D900052BA6EBFF86CF2D17CF487E38C17328C28 -:109DA00097FFEDC683F93BB11E473E1FE7D8185118 -:109DB000F97B5E7C8FE5767D1882F1D7FD3A81AD27 -:109DC00004143E6E36CABBBC6E15F28CFA465F0FA9 -:109DD00069A9AEF123534BB94E7027B2888E9FA468 -:109DE0009C6B1707B3884E4E8A32F9BEAAA6F92992 -:109DF0008FA45D2CA5E77F4799A6799C579827AD3E -:109E00009F798691FEE87F9E0AA15F98D8BFD2A86D -:109E1000AE46EA85FEE43C769F2C562FCAABD48B27 -:109E200059997CFC7D99C6FCEBFD1B3B0E210B7DFB -:109E3000660F1EC8A4FAA8630E34E1F5A6C850E464 -:109E4000E34FFADE6FC4C5BD95CEF3FEC5DB17BC8C -:109E50008EECDA9519FC02FDA0DF648AFD4937D843 -:109E60004315ED1DD88B52CAE77E9181F9DCA077AE -:109E7000C37886F27407E573535C81521CBF755A30 -:109E800005E51C24DCAB96F03A35A967ED5A90F055 -:109E900065D542FCEA0C820D67EC42A679B2A62099 -:109EA0003EB91C1D5D7781E4C0A6F989AF6C4E9365 -:109EB00017FD021BC485A877973A4D7CFFC66DA598 -:109EC000FC7FAB021122E88D85A98597DD1FB75C69 -:109ED0007491BD0548DC7ABDFDCF9F2743D807E3C9 -:109EE0003C9A93FB0D6C3FB7C388848F75FA58FA80 -:109EF00003B1EFC58E2FF129F16B45BC96923D8CD5 -:109F0000EB6FD85CC6FDCC2CA96F338F1647E06E83 -:109F100083D2ED40BF06F4A8CD857A7A488FC3E49A -:109F200025FDEBE27E5048F035B3EBF95AE6A9E5A2 -:109F3000BA24FC0BDF9C63D5EFBFC4C21B6B67ED7B -:109F4000A5C6BA059BD758B720BF0B50B500F18DF9 -:109F5000798CDF8A72B2D459EE443F67B9E6FDA32B -:109F60009FEA2DCCE46F83FF6E985F5E1F01F94777 -:109F700038CA5C26435D8DBC26E33E4A9CF7A6BAF0 -:109F8000B89E7A64DF9DA487351FDF678AA51F63AB -:109F9000EDC42FC9C5CC49F95301AFE30AE3F6C7B5 -:109FA000473FDE67233F591B650D635D67EC7CAA65 -:109FB00039E05750EF9631F293D53C3EBF3A885185 -:109FC0001DB863781A2BD1E1B1D53D8D9E2FCC748D -:109FD00032A4B79A6C0AC4E31789A7812E93816FC4 -:109FE000DC926F3CEF17A31CE8F826108F6F06BABF -:109FF000B8BE4238F4F46D751766C5A34F542F727E -:10A00000BEBA125FCC4AE27E4EA785EBCD06C411E4 -:10A01000C44BF5999656CC7F9FB1F2E7CC5FC2FD59 -:10A02000322BE7B95949F961F4873A357F12FA655D -:10A03000B37AF76DFDF4BD47BDCD9F721DDAC777CA -:10A04000B8DF7CB2D2DEA6C03827CDFE14C4F7C973 -:10A0500077546529ED83F3FA39598774D2EC5D752D -:10A06000353C9FFD33D5BF941E1BFDC133CC3FEC67 -:10A070006DF48F77ABB4DF52F0D3FBD421D0BF06A1 -:10A080001C45E4A75955F610DAE1CEF79B3F447D15 -:10A09000347B73827719D6B16C1CF625B63F5D9D73 -:10A0A000EC4DA03C5BA1E2C1FCD79A0227ED9B2CB2 -:10A0B00066229EBB7D7215E8D05FE2D4327F0D6BC5 -:10A0C000FE94C9E7A155E3609D5767769AEC00932B -:10A0D000B221B4CA0AF47B7869C08DF163876BC67C -:10A0E0002A8C1F5D2E7FD74D102F9E70DD3919DB16 -:10A0F0009D8FCBF1EE5AE507BDFCB22958A0C0F305 -:10A10000A4AC072653FD6A911CBF959ECFFAF95562 -:10A110005F1E85F1CB366C9C8C39B78A6AF17EE87C -:10A1200009826FCE18D9DE9A543510DE4F62863C14 -:10A130009A391A8F529EAEB3D7BF7A7A32C69FB37E -:10A14000C736576930FEB20D3B569582888C6CAF8E -:10A1500074FAA1FDA30DAF4F4E027EEB64FE3A8C64 -:10A1600077576D3830D97A038C9F6E1C3F4315F9B1 -:10A17000D8D0E15598C7EB858FBDB7CA3F30DA7F9D -:10A18000983B61752837CAFFFF2AF81FF8FD572E44 -:10A19000DC07B4761FC2145DFEE21E0BAF7B15F523 -:10A1A00029B9DD4379DD8D689774F33A65D976F383 -:10A1B00076E7B2F8F6FE2F6E2E779D89F19F7F2805 -:10A1C000F439C0EDC7FA9594A3CCBF238E3C1D741F -:10A1D000D949FE0E82BF674D8BCAD5AD20DBA3B037 -:10A1E000FEC7CAE194E3C4BE7F4CE82716BA350D1A -:10A1F000F9788AE0F3229FC2EB7876278507A1BF22 -:10A20000C722DA6DB09EED229FB1DDC6EE9D0A53E6 -:10A21000BB12597027FA9FE9D02EA5F7FD3BEDD16F -:10A22000F1DEE2A2CCC61705B6E178E3B33C652DBA -:10A2300005D17100EEE5D67203DCDAA8347C1ECAC3 -:10A240005E50AAC367295F07F009E10BA679F626DD -:10A250009097CEAEAB0B57C21256B9BC86B8AFA220 -:10A260006B1A7D97F29F6EEEFF302F7F3FB38AD738 -:10A2700085F4EC49A23C05B37615239DE47B1705D4 -:10A280003EAA7E346503F6ABEF3233AAFFDF59797D -:10A29000597FA01EF37A3AFFB15E8B503C578F79FD -:10A2A000BD6138DE5B16B463388E57E4AF312F974B -:10A2B000D9129FFED21ED65F4C65A1617DF56674F2 -:10A2C000FC0C7A7EA57545C733C69D7DC7B3887DD6 -:10A2D0000081774DE0DD121FCE0159824F01DF264C -:10A2E0001D7FCD11FC06DA93FC80732F0EDEBAB20F -:10A2F000403F2FFFEE06F4F3B337A1BEEC4AA4B8FB -:10A30000A542F34FC6FE155D69B4BF20F943F2853F -:10A31000A46B675A33E56B7A1E53C80EC6C2552C20 -:10A32000E1DAA8101C59D541F53E1D7C521E60FC97 -:10A330004E31FEF051243F4F707900B9B91BE5173B -:10A34000F72B711DBEEEA1D386F485FF2768FF466B -:10A35000101D39FE7F6D13F51C1C6F7DF19F730579 -:10A360007AE6D3F38AAED7699DF5FDC8ED5B6E073B -:10A37000C1997534E2F042BF4705FF77767CEC184F -:10A380008D72B15B658A97AF1BF55685D4C76CEEAD -:10A390005B6341FF65F5B6415F7A910EBDFA3362AA -:10A3A000B546FBBFE29E3B65393CCB48E0F29AA143 -:10A3B00082B5298FC2313D8BFB59A382F1FDD27743 -:10A3C000DDC9F45CE2FBB1C555EC6358DFCF5C7CC2 -:10A3D000FF7354774841BA48B98ED5538BB2B83C15 -:10A3E0002EC8FA7FA4A76C57D05336A9A7F8FD83CF -:10A3F000101C613F97AB7BA802FE738DC9EFC2387A -:10A40000ECC43B3FA0EF38E689BA952158B7827675 -:10A41000F36880ECCA697CC8EB571EC218704EBB4B -:10A42000B17E856DE3DF89C6F255948F42C27F17F6 -:10A4300070087B706B42F7AF7891B1519E651BE05D -:10A440006C3415E99EDBB9DD9274007A2F6769518F -:10A4500039FEE8C5AC2DA86F87B9795E31A3C85F16 -:10A4600086EB9772097655F089E9DE6976AE37A6F4 -:10A47000C5E1DF27847CCED9C8F9A6F3BFAA26237D -:10A48000DE3BDF4D4B5DA6D3134F093B28C7957AC2 -:10A4900048BE279F3F29F8637B9683DA4FB99245E0 -:10A4A0009EC714F7BBB9A774F695F8A78DF30FAC48 -:10A4B00037A4E7EF616EC5605F7BEDAAC0738305CB -:10A4C000F00BF8DB6E0E6563DD4E459789C6ABD9A0 -:10A4D0009D4CF580351D1C8F35EDFB4C753AFCC449 -:10A4E0008EF71F59DC1FD862E27544074DC06F8894 -:10A4F000773B87EFDC8B1ED29F8745BF2BDB8D6FB1 -:10A50000A667B658781D29D097EAF91A5ECAD962AB -:10A51000D4D34B05FE832DF81D5BC606E6C35A2B2C -:10A52000C0534401B867B885DEB1F82DF8DD6ACFB5 -:10A53000638CF6F30755FBCBBCD06E0AD8CB15184D -:10A54000AFB89DEBE18AB5E0C7A0DC59A55D787393 -:10A55000877EBE6359C9221EE1FC5CB391E36F1094 -:10A56000F83FCFE215C6F915F9F11C9E8FD6778C0E -:10A57000C6FC937CFFB4A0FF95E0AB40F88647E1B2 -:10A58000C3F1919F983DB00CC76DFCC3AE1CFDB8E4 -:10A590005F66717D9BA1CE1A6B433DBF06EC0E49F1 -:10A5A00067703F7E9750B337D5B992913C9B30EEA0 -:10A5B00091F3D6883C24C85DC554585A71EF3C923B -:10A5C000AEEF3DA75FBFE6E6FEDC3F8BBE9D96206B -:10A5D000ADA76727C0EB8DE2A5B3E3BE6536B41324 -:10A5E00047990FED8484775075B703EB4E9A84FD3D -:10A5F00080F59A307EC9F89997B520DEBAC65A30F0 -:10A600007E8AE56B49A712C6E547C66925B84100B1 -:10A61000ED3CF750A17F18C5BB1FBDF4CAB32B2971 -:10A62000BEE27469AAE674AC740767B833A3720813 -:10A63000FABC02F555CDDA5E7DD4C1EF77E557035C -:10A640003EAF754B3937D22523D061C37D0DC9D7B5 -:10A6500067F70C09AFE474A6F93B3B92C38A82DF2B -:10A66000A1362FC5B85BEA0984475F8729E1E9A5D0 -:10A6700023033A0E89DE1F54CDC76B0279473EAAE9 -:10A68000579B158F427A80F2AC59A807A09DD5C17F -:10A69000FBB1BDFC5C0489A7FA193028C49D7E7704 -:10A6A00029AD43E22BAB3A62AA875B13AD55FE138B -:10A6B0003A7FEDB0D86F40BC4CA37883EBEB7A3592 -:10A6C000908B712BCB4AA0EF38C10E917E39686315 -:10A6D0009A0DC67B03AE6897C6AB0BE83B9AF14573 -:10A6E0000AC931680099F789A03F7DEB4D4924FFE5 -:10A6F000ECEB0706E23A3393381FC23856318E9599 -:10A70000ECA0B007BFCF07BF4E89EAE5838A42E3DA -:10A710001CBCE19AAD545B28F812C743FFE9A03294 -:10A720003597EC6567A6282EE2F0F76FCFBAF3F104 -:10A73000B93E5EC4F82E1A6F96ADBE19786AE4C4AD -:10A740008E88C989D2317CCABF01FCE321DEB4C145 -:10A75000FAEF137C7DB020A43A10AE41B06EB8750C -:10A76000283158DA6C8FCEE312F91B97A8DF457FAA -:10A7700001AF260FD7FF3FF6707BF181B8BA1CF10D -:10A78000F33D1745FF3FDBB99E5E5919FFBBED87CF -:10A79000845D9171E7AD62BF03E2CE87DC3CEE14CD -:10A7A000F5A77C7F04FC7BC26FD58FAA69DFEF8B96 -:10A7B000AEE929FC3C04AE0FE688FACF7B1F9AFE77 -:10A7C00013E4B31358670E78F844F0CB09A7DF8180 -:10A7D00075520D89F1EB889F14F034083C9C5CC2E3 -:10A7E000CF2F9883FB72C07FEBDCDCCF9BD77EDB67 -:10A7F00004A4FBBCB50AEDCBC9FD7F49E7DA4DAA3D -:10A8000021BF3E07F7E5D2FF9178AAAC9F786AB8DE -:10A81000219E92F3C6C6551F2D711BF60166B51712 -:10A8200089F32378FFD9CC4770CF6ECB31EC23B2BC -:10A83000B6CC6FF4DD3FC651A1B8F0590CF73F5AC2 -:10A840006265213D1CA70652FDC443EEE0CB6E03BA -:10A850001C492C64C8878E71D2F744369E87057FC9 -:10A860009CC73170DD62277F7D22FAB3BDF930D0FD -:10A8700023CE14D44B95FBDD23A2F18394B3FA319C -:10A88000F1E38875C20F5AE7E27172CA511957276E -:10A890007A513F4ABF3CF6BD777BF9D7E8575E292E -:10A8A0000F017C1CD2C749B1E39E72FFA3F177511F -:10A8B0003FFC52FC3F127F578C09529E8FB52B54A0 -:10A8C000D332729C311EFA1AEDFA08BC2619E2A1A5 -:10A8D0009A6A633FE6E1F69F79920C7E7C7FF8D41A -:10A8E000FBF14A11EA413E5EA3E08B82CFDEA57AFE -:10A8F000D2311EEE178DC8F62778E0BA5AD493AF3E -:10A90000B6F1EFF9B7FCF77EF76CF48FDE36D3FEC5 -:10A910003FDBCDF9A6F289452D783E80BD4371EA33 -:10A92000BF5FFD97C58ABF06E43A5DE8BB7A1F5F4B -:10A930004FBD2F621968C7FA620E476EC73E45D3F6 -:10A94000F15D6E2DEF97E7311BF2E205A23DC0E30A -:10A950009471CCBE4919D8DFAFA15F90DDA190FD05 -:10A96000CC6E66E457670F5768FC7F19BE45995D4A -:10A970001A5D6F9B696AA913DE6B7325F9D0FE2CF3 -:10A98000C90E5EE541F88E4522682E471EEBD23097 -:10A99000DE5A93ED2F413CC8757A556736FAF14976 -:10A9A000C7387CEDBD79266E7F185B25FCD2ADDC07 -:10A9B0003F53D961C6FD73B2F3AE65256407E57AEE -:10A9C0005C69C28EB85870979DFAB791DF62E57ED8 -:10A9D000806B5931F9F392AED1B8737039C69D4589 -:10A9E000AB23DA2C78EFA54DA6B8E7554C10788745 -:10A9F0007554EAD77125BD25FB99FBC93B4ABE4F6B -:10AA00009A183F9E074B48CF2B9FC8B88BE473B969 -:10AA10008561BE5AE27F4D76E0768427BB638B82E8 -:10AA2000B8F948D4297C94C8F3F11FAD7C5641FF96 -:10AA3000F281F9CCA9B2FEE1AE5FACFA6BF4F2BCE4 -:10AA4000DC427491F14A141E9E8769F070FB7428F1 -:10AA50003B5083F46EDCBD86E2EAF9DB8E5B2EBBF5 -:10AA60000FF10DF1A6D4727FBD7EA695EA992A9FBB -:10AA7000D088EE75CB2DB46F58BF63277D9FC61E5F -:10AA8000643E94FFFA8E9D4A0DCC5BB763A73247B4 -:10AA900087C79CFA30D56F5F952CF72322E44FC708 -:10AAA000F237E611D07F3964E3F27FA6D21EC2FDF1 -:10AAB0008933E6603DF63BE349F2E13EA6C4FB1B69 -:10AAC0003B6FA6F30292772544F0DA66DAEAB642E3 -:10AAD000BFB6AB2D3EE4A735D9C1154897342DD06C -:10AAE00089EFA76624FB707FC39BC0CAC97E7F43E2 -:10AAF0003C8C8CE18B910F72797959E817F8A37A25 -:10AB0000AA273DDC2FC7ED25D45787CC7C1DBB1869 -:10AB100087D7E4F16F443AB1C369346F767D44C19D -:10AB2000FA8BD879A37CE5DFECC9FC3670765850F7 -:10AB3000CFD7097D53F9C436E5631DDCCF79548244 -:10AB40002F7BC71605F367F09CF40DF46758EF945C -:10AB5000BD83C7AB75F07C8E4EBFC875C4D1339D25 -:10AB6000089FFD58D701AE67227CBF40C01B4BCF6A -:10AB700088C74BF34F007781EE5B4225182F1F2AC1 -:10AB80004CA4F1A4DCC7CA69C4C3FDCAEC4DDB14F4 -:10AB9000939DF655C8BF94F0C97E23B2C71EF0102E -:10ABA0001EBA080F0D9B345ACF784B60E0029D3CD3 -:10ABB000BC2BC67B7DC68774AECEDA7F7F87F8B1AB -:10ABC00001E26C8A33DADFB14C473B13FA858AFB2A -:10ABD0006093B98BC2D68B73A72677723DDCD0B950 -:10ABE000539B6D8FF269C167AFD379550D1D090C69 -:10ABF000E32BE0BFA3084F2C9F4AFC483DDB1F3DE1 -:10AC0000411FF1F829641179BE6001C63F524F9B84 -:10AC100084FC333BBFFF855857947F829F790C7A21 -:10AC2000D6467251F059F9EB58EFD9E053E8BC8E93 -:10AC30008C2A8E4F3D5CFA7830564F623E31C0E32D -:10AC4000FBFC69BAEFBA7AF5BD78FF22D29BDB8DA7 -:10AC500008BFCF0AD17E4BF863E937309BFB6571A3 -:10AC6000F84CC91ED1D79E493B5FB0799786DFE586 -:10AC700048FE998C74D7F18F33DB42E33AB33582C7 -:10AC8000677D25DF8F5C6FE6766CFD522BD567BE46 -:10AC90007127AF174BBECB12C1EB41D3AC7A7C7E90 -:10ACA000309BC3D1665A46DFA9815CA66613FF3884 -:10ACB00018D78F5C1FAE7D81EBB3FA909DE2DFFA6F -:10ACC000E0ED35540F9061F3611D2D0B1EB04C4F1C -:10ACD000EECB57DE5DFB2C08FFE40E2E7F920EA01C -:10ACE0004F89BFA43C48BC46F11936C893A487A934 -:10ACF000D79F0816707F89C75BA5E23BC25AABFF9E -:10AD000090D98B710CCFCB968AEF09655E7696A0B1 -:10AD1000CB667BC087EBEC9397FD86F142DDE2DFEB -:10AD2000527C76BFFB4DBA4AB985B8D620DF3709C9 -:10AD3000BA176773FB3E219BF34DDDF00E92CBBA41 -:10AD400013CD24CFF6895CAFD98FC5F88FEC11A154 -:10AD50008757D37BE3933A26E0BEF2F89F2B4E8CC5 -:10AD6000F7FB83731E7E8F8571DFA6FD8EFB10BF00 -:10AD70005F43D4A1FB5E67463697AF33DB01E1C486 -:10AD8000EFCD96CBF9E3571A8F458E28741E88C0F5 -:10AD9000E5991D55D77D82FB40DB537CF8DDFDE74F -:10ADA0003B6EFBFE2700F7996D37F9D04FC8680955 -:10ADB00010FFF464DA7C5B799E7622E6B19676EC3D -:10ADC00077E0F73DA79FBDB61CF576A380F3B317D8 -:10ADD000D4C5889765CF3C7F233EAF0B2BE9E8BFF6 -:10ADE0009ED9FEF3BF67C338B5DB9AF0A431D6F223 -:10ADF000EC6B141798C25BF8FDED29E4E79E7E72B8 -:10AE0000CD8D88EF968E167AFED9935BA8FDFA3326 -:10AE1000CFBFFA5FD0AF3EE0A0EF9E3F7B611FD176 -:10AE2000A53EA8517D7A7F7CBD7EE73EAE2FD1CE78 -:10AE3000A31CCCE47A4CF2B5E4DFD3CFDC7B9DDEFF -:10AE40006EC8FB6D229FD396C8EDC8E7426EEBC675 -:10AE5000DADBF0FAF973363A9FB3D1D25D8C717EAA -:10AE60007D29E78B07053EEA3B16981BEDF43E8DE6 -:10AE7000F39F20EF781D02FC897560D06BDB25AA5B -:10AE800067FA15F5877EA330DF33A3FA38FFBEB328 -:10AE9000B4D95C47703ECB9FC3AAF5CF2B16C58FA4 -:10AEA0002FD767DB0DE7AA65774ECDF5921E48F0E8 -:10AEB0000DD2F9BFD9B5C19664B87FCBA2A00FBFA0 -:10AEC0008F7FE9D4BB13F03B86674A9461447F557A -:10AED000E1762E64A7791A701F09E28FED424E20A9 -:10AEE0007CCDB81ED6335E6319F889EF78C68E988C -:10AEF000492F3C45E3839F43FE9BF7B5194FA1DFE4 -:10AF0000B3DE1CF48CC071DA847DDCC6E187F79D6A -:10AF1000F6721ACF793DF7D717E27BE7974EC94013 -:10AF2000FF1EC6ED32EBE231E0C87CB48F38DE7034 -:10AF3000C4D3C4D04CB2535E0BAD4F9EFB09EB1F84 -:10AF40007AF790A87CC6E69B503F617EF85076E584 -:10AF5000BEECCCE8D5D54FBEC69C03CFD19EE5F85C -:10AF6000E9FA4DCF117D7DC6396EE75F3E4E7CDB41 -:10AF7000887C8BF3074F18ECBCAC7759BFE738F1EE -:10AF80006DCD6EAE8F1B77575A30DEFA7C899F7D70 -:10AF90000C8E6EA3E0BFF54AF75CFA4E6C8F8DBE47 -:10AFA000FF3B27F9B3FDF8A7A87F0A777B289F709E -:10AFB0006E0FE7D3832613E5010E6EBD664B8BD271 -:10AFC000D7AE82BF4D72D2D8CC84BFBDE85DF4CF7E -:10AFD0001A6A793D7A630C1F156CFEA815F92515C0 -:10AFE000BC63ACB3017F66027D3F59CF46A09C662F -:10AFF0008FF3EFC9A17D421E9F67D7823E81F62D58 -:10B0000019F37D78E455EA38F08B91FF326EF061E8 -:10B01000DE6C7D5E472BFACFA1F18CCE575D6F6E53 -:10B020001F8B71F0FAF15E276012F0B68DFC6B5643 -:10B030006211F6AC86FCF246F7777C94D78E95FFCA -:10B040003D4BC9BF6BF426FAF0BCDBC9BB9585DC70 -:10B050009FB13384BF11F08BEDC9E1D16184E7ACBE -:10B06000C09FC4E33973179DBB7BEED709748EE193 -:10B07000E4719C5F53C77590FE7863CFCD64AF25B4 -:10B080005F26BF9840763B4D732A98E760ECB60484 -:10B090008467B680A75DD4EBA60A3B52B49AFB71D5 -:10B0A00029395C9E52724CE26A117C2ECF6509519F -:10B0B000DEE1ACA03FB189EE5CA7869A08C953FDDA -:10B0C0000E3E5E4682BFEC011DFF4AFF4AEECBE218 -:10B0D0003EEDD438FC3D42C051B07921D17D76ADF2 -:10B0E00038F76135F72B18F005E20DE8487C704B16 -:10B0F000C63CA2DBECD5CA5D44C75005E53FA57F41 -:10B10000163BFE75627DDB6D81E158EFD79399ECBC -:10B11000C33A82EDA97E13ED2394A5521E24339DDC -:10B12000FB8B99C25F8CCA7D60B809E639E54AE6B7 -:10B13000F40EFF5EC3FCF6F81CAFF4FF0C7E5EDF7E -:10B14000389F8F37A53D3414E31EB9CF2CF1115E23 -:10B150009A3853AF4F6F12F8080F6633516F403C67 -:10B1600061A73CBC13E6C17CC2D6D14FF27C023F42 -:10B17000FFB92487FB3DE3D303C3D14FCB2C0A2C6B -:10B18000E2F693AF33161F87B2651C704F19C6B134 -:10B190008DB7DB7D28776B5F5666115F87AC7828AB -:10B1A00010F03D97437098A8BE8D0535A247637394 -:10B1B000201C9FEFA7929C3582DF8771C064E4F367 -:10B1C0000CE2FB30E77B6EFF64BE01F5A4DEDF9688 -:10B1D000FA40EA19B46FC8CF522E1A6FEC2E46FA15 -:10B1E0007E53BD72CECCE5FC1CE001E548CA4DF2B1 -:10B1F0004B5C5E562EF556E2F39520F77A7AC7C679 -:10B20000670827C62B52BF2FC90E3C90837907537E -:10B21000A495BE4115FAB8F1A515C5F1BE2392FA61 -:10B22000D82ACECDB48693C2FAFD12ACC1482EA75F -:10B230006B08ED51D2E2F8F998D61C695FFBD4AFE8 -:10B24000B5223CB1F56B2EB45D283F5B93E87B36AD -:10B25000999F8A1D77B1E037491719A7E0BE07F615 -:10B26000DF9AC3F9659DE8F76C8E22E4226CE07FDB -:10B27000AF29781CEB0FFAB363F2BD7F56BE4CCEFC -:10B2800023ED692CFDE5BE0DAE676A69FFFDDAF7B7 -:10B29000893830861F77093969CE61B4EE7673E458 -:10B2A0000B92AB05C98CEA7E36327F3AEE07BE7A46 -:10B2B0001597077F4F318E3F342FE8C81D11CD0BF6 -:10B2C000E37D8C4FEA34164A009AD46D3787F5DF58 -:10B2D000D33C95CBC73F9F6C0DA9C0E7FEBCE0BE39 -:10B2E0009C11743E087D3717FA818DF6B1C0911E0E -:10B2F00081FAA589753B10CF8D6A5731E631AB5D78 -:10B30000C14348FF8F4C5DF9BCFE83EFB31D137939 -:10B31000DF6322EFDB6989E4FD5B46F41CBB0B8C29 -:10B32000D75F5DE832A5611CF8C1EE3F3CF732BC47 -:10B330007DF7CB67EFFE21626B65D23D3F836BB536 -:10B34000550D68BAFCDCB1E4F87AF6CF82BEBDF5E3 -:10B35000514B13E2E6FD9FCFE5FD9A62F6B59FCF14 -:10B36000E5FA34FA7D14DFD7FEA09FF3AFAA72B9D5 -:10B370005EEF14755BB1CF278A79B69B59F146848D -:10B38000674B32D503308D9F5B56FB68810FF7F119 -:10B390003B0BF939F93DEB14B203C7CC5CFFC0DFBE -:10B3A000EDD68AA81D453705FDC45A67286202FDFF -:10B3B00051BB283982E765C27D6D0CCA5AC849F570 -:10B3C000C3B3847D9CDDFCC65798F7A8D598750C4F -:10B3D000BC77D25EE340F330F7BB0FE051342CABC7 -:10B3E000BA5DD4998A73D8FC53D44B4997F3EB8C4C -:10B3F000DF97BC901B30E7C2FAAB5338BEAB1FE0FF -:10B40000E7F1CAFEBB85DD8BE5B7EDC8AB00EF8782 -:10B410000AB72FB1F364E78DED40FEAB76079CC809 -:10B42000C7D50F9C35E8B5734AF7D33F43BE5C9050 -:10B430002CCE4763F9FA3AA521B95C6EEA70DF0CAD -:10B4400054E3F9B2AEE2C505C8FF3DF97FC4BCDBE9 -:10B45000DE04AA73AEC3FD33DD7E777FFB67FDEFAD -:10B460009B792DC8E78D1715E293597BDF388A7ACF -:10B47000BD51EB26FE9965B5137D1A2F6AF49CB574 -:10B4800099CFE8BF975BE4F65F83EB0BFD684C2A2E -:10B49000EDBF65C17DC273099DB7B150D49767E711 -:10B4A00005CB11CF1B921CF7627C78C1CACF576ABB -:10B4B000B2F03A7226BE43967CC272938D7CB0F78E -:10B4C000CDAF10AE1A6B90CEA99C3313E26915E98B -:10B4D0001619E12CD5D37FCCB73A27D7857A03E06C -:10B4E000FFC0C2EB88FAF23FA7C3F342BF7C90CD06 -:10B4F000E5E8837C56BB0BAF57C315DEFBA050B409 -:10B50000CB793B769C7A21471F0CE5F62BB430298A -:10B51000EEF920F708797C21D77F07E255DE7F52CC -:10B52000C0919DE7BF13F108FAF16EE2AB14164922 -:10B5300085F1AA5FE3BF57C096F7501D6BEFBA8A3B -:10B5400005BCAEF8702D8D8E5B83E3413F3FF9F172 -:10B55000AFDAE83B383605F435EAE785790CF533A0 -:10B56000CC5B8FF3C3B89154EA9740EB606DA0B702 -:10B57000817FCF8FF0125D5656029F0E17E7EF7B4B -:10B58000A37C25F929968FBE9FABF4B7BFFF7D84BE -:10B590002B767F9FB181446FE2B76FF13DD9E8749C -:10B5A0008E1790FB965CB2BF91217AB9937896FA88 -:10B5B000F28344235F240A3AAE12FD7AF12CCEB313 -:10B5C000CA28E27650C60B3F13EB72C45CA55D8BB4 -:10B5D000DD1F7008FA3B7279FD14D06503C229EDB6 -:10B5E000611F7A6FE2F4867E9B488F25F4DC930E10 -:10B5F000F6EC0EF093F03C4B78CF85EFF5C95B8C01 -:10B60000E376B8696132433FE1E95C51F73DBC87BD -:10B61000EFDF95F4903E9AC540EF2857A61FE60845 -:10B620003CA00F9FC7FA118043C17AA43452035E35 -:10B630001C0FF0BD3337338AEFD8F98EE123F00BBE -:10B640005FCE15DFD995B132A4D73DEFFC35F96E49 -:10B650002F9E77CEBFEFFDC41E7C0DC739F3FD379B -:10B66000290E38668914B7DBE33CB744366F50A225 -:10B67000CFEFFD851AC2DFB7E8EC3AB36E06F0E50E -:10B68000AC2ED58753CE7AF08BB747A27FDD65A667 -:10B690007D28F02F56E3799FC7445D216B36E6097C -:10B6A000FE24E82EBF3396FA49FA09F3998FEBA5E9 -:10B6B000447EBEFA470BE6D177C6352C7008CF57CB -:10B6C0003FBD7012F9CFF35890CEF79EDD663C5F18 -:10B6D00037F65CDED8F37831A18FF88A3D97F7F31F -:10B6E000EFC5AF9BE9CDBB57C5F737B43CCECF9F75 -:10B6F000F753AFFE37C1AFB2BEA049D617BC72F93F -:10B70000FA82A698FA82A83F22EB0BBEE6F505AFB7 -:10B7100018EB0B3E1F1B1F8EAF7BFD9DA47EC675D5 -:10B72000D0FDCF0B2FBFCE263C6727EE77E476BA4D -:10B73000DF5F7D43A6C4533FF51DA9791C4F4D170C -:10B740003D067B9C99E78DF1C772E979534C9D4486 -:10B75000F439AF8F90F903A02BD5E3493F30F6FBC6 -:10B760007A99DF97F2F3B1C2AC1ECAB7AD11FAD421 -:10B770003714FDE68FD11F43F9BDD9FB6A37803AF4 -:10B78000FB87D7156B8551F98A5D0FF0E567FAEFF6 -:10B79000D807E789F3207CCC47DF390AB9B8E7FB43 -:10B7A000E353707FF6CF0F5619BE5FEBFDBEDD226F -:10B7B000FD40BBC19EB3187B3F7BF79BE4E7D558A8 -:10B7C00003F41DDD27AF7C9FECFC5C1670A19C9CF4 -:10B7D0007FE5AAFCE0FF859D97F0DC16BACFCCFD93 -:10B7E000FB0CF24FA609786EDBCBFD4C93D56FA610 -:10B7F00079FCCCEB745108CFE105658BE7E8DDD02F -:10B800000B7F299DBF3146C0AFE0FB80DF1BC49595 -:10B81000CD0ABA116E792E00709D1BAF2DD7F9BCE1 -:10B8200078BD4909684CF7BDE804D69C8BFD4DD620 -:10B830006E559C5746E7CC2744F145ED64D15E7EBA -:10B84000FB857BE6E07D3B3FAFD822E0B83F4F7CF5 -:10B85000076D65565C77823D729AF60FC535349652 -:10B86000FBEDA1425E979C88E721C0BC76FBD91016 -:10B870002ED6C99CF49DBFCD792182F18BEE77261F -:10B880001AF346E87E678245785EABBFE731BF4377 -:10B890009126E06B117AD283E71516D1B90CA42753 -:10B8A0007F9A3C97CE27CFB42FA27DEDC71C13699A -:10B8B000DFD38588C77AFB89BA7315E07966C078CB -:10B8C0009E42D64C63DB1334B6ADEC18D587299174 -:10B8D00080FB527AF4DC48B3D037B72772B86E4F8A -:10B8E000E471DE237926833F1290BF0F93C6CF5DAC -:10B8F00038E7B25AB14E03FC9347F2B87FF22150B9 -:10B900001AE249FEFB316537F907AD1B8EBF8BA2EA -:10B91000FA96019D5A93BD4B35F4FBEE14BF23A656 -:10B920007550FDC3967B527D58AFD36A735662BE85 -:10B930003494C7F3444DE2BB0FA048DD0E786FCBC3 -:10B94000B41CEA9751D54379D69E158CFCAA3E7C4F -:10B95000FA35F03FE0FB496CE3791035BE2EFC0E62 -:10B96000D8E357A96E593EDF86CF014E45F005DE7C -:10B97000BFA922FA3B4F457BCBF6E379962CA8F87A -:10B9800078DAD24BFC3E5DF8F34D7B2B6F1D0170D6 -:10B9900015750D23361EB857ECD3642488FD667EDA -:10B9A0009E6F6CFF81D81FDA4987BDDFA9C7472684 -:10B9B00088CFF1BDB149B4EE23224FC5847E18195A -:10B9C000237FA3A3F240CFCB44BB49D417E2191481 -:10B9D000FE0A9E06A17E195C3E7C4CFE71B9BD9E9E -:10B9E00045FF709CAAE8B8A4A7C6451F47E5109676 -:10B9F000586EF5B5D443BF8353F9BEFC482DB20F42 -:10BA0000E57DB4B896892B9BD54EF85DB934F2BA72 -:10BA1000B90053320115DB15CE152D38CE0D4A84F1 -:10BA2000AEF933D7B4209B5D9D5F24F241C1F1286C -:10BA30009FADE3F9F7D22DA37C3E273C9A3193E7E3 -:10BA400071A7CFB4521DF6748D9FEFC4B460C11DB1 -:10BA500020677754F3FC31B6AB75F919B95F7204FE -:10BA6000E29B9D71FC83ABF3B95D93EF3789BA21FB -:10BA7000F9BC389FE7CBECF9134EE771F8685FF833 -:10BA80007C9EF0D34A5849CCEFD1FC350FFDAFCAAC -:10BA9000DFF6A7278CCF859E98EE7FD44CFEBDD0D5 -:10BAA00017522F07443D54973897E5BDB11CEFEF6F -:10BAB00056CE277D713B6B267D7E070B9911BFBD4E -:10BAC000FA7FA2CE3F8279A6078CFED28C99B17EF6 -:10BAD00015E75739EF9D41E3F369D2EF9D68F47B99 -:10BAE000ABFFEDEB54B28B594F375C1A10AD7B6A4C -:10BAF0008AA97B6A14754F4DBB171CCCD4D53D3534 -:10BB0000EDE5754F8DBBAF54F7D443FB4F47CCE108 -:10BB10007DB82F73643E8804C0B95FD4C91CC03A95 -:10BB200099F2285F264FE3F959605FDA67C97526F5 -:10BB3000F9909FDA4CE594CF6D7324FBF4F9D3951B -:10BB40004B81EF74795C59E774A49FB8B83C9FFBB4 -:10BB5000C1EB159E4F0FDD69A53830B32860D8BF03 -:10BB6000C854D951CC4B9E167ED07A912FC1FDBFBF -:10BB700061700D2BDCBFE97D1FBF9FC23C668C3E10 -:10BB8000CA4CF7D1FE4166CA10DA0798B9B76C1BE8 -:10BB9000E91BBBCD87DF07C8F16706B768587FD4BC -:10BBA000B4778B56638FF2DDF87CC1AF492C09F96D -:10BBB000B5372FB82B81F2829FD80393F2E1FD7A3B -:10BBC0004B642833F233DDEFCFAECD13FC621E1B86 -:10BBD000B8730EC073FE6D0BCF8F3DC8485E5FD843 -:10BBE000934A794D6D1A23FBB2BC92F1DF8BD9A237 -:10BBF000903F7732959F43B47C2A233B782E6D0289 -:10BC0000D16F3E0B1FC273866A37990DE709DDBFFE -:10BC1000CDD8AE671D646FEA77F4E167D25B523F1F -:10BC20003630AF8A7AA8B1D3F83E1B68D48F65C28C -:10BC30001E0C9B3EAE05EB3C8699B8DE620FFA7295 -:10BC4000A651DC5DCDED287B9ACEAF3A9F7C4AE5CC -:10BC500072CEF5F188A8D634D8A511C2BFBA51E387 -:10BC6000BFB320FDA511E277170E98F6AAF41B3F8B -:10BC7000029EE1E23DE9A7497D2DE952390A7F3371 -:10BC800002E2F07CE1EF14B242A42B8C4FF2A060F0 -:10BC9000A0C48F4CA6DF6F182DE603BAF3F3EB4C6C -:10BCA000D630F251ABD24C7ADACA84BE5682A4970F -:10BCB000FF3D1452910FAE63CDB7E1EF818EB176A7 -:10BCC00025915F6A0FFE44CF272D2C92BF5331F090 -:10BCD0000B3D3F93FADBB8FC22ED4AE43DEE6F4C9E -:10BCE00066E007C2BCFEF7B91F7440E1F122F88399 -:10BCF00007305EFCAD6912F1C3245806F61BEF3421 -:10BD0000D2F966B7B13DC9DB870F54FDEF5980C446 -:10BD10006908CFE412633FBFD46FCCA8DF0AD8D73D -:10BD2000BCAE7EC5A1EF62DE2069312B413F063CEF -:10BD3000475FBCDF2BDD85F68298A0CFFECAAEFC44 -:10BD4000117DF757CE8B3CF1F5AC7BEE0EA52FDFC6 -:10BD50009C3BB85875EBF84BF2F34BA21E43794D60 -:10BD6000ECE30EE7F9C2A89DE77C53215AD723DF05 -:10BD700041FF3F483D207E77E486DDB608FEAE4EAB -:10BD80009918E77AE49FF2A85D8F98EC5E4B21F258 -:10BD900089AF4D55FBFAF3AE342FF1CB30939FF8BA -:10BDA0006504F3A5239D46593B5A34847FCFC89C34 -:10BDB000A0DDC01F7FCC47FBA7007F503EAB8F7D2F -:10BDC000343E8FE11F49C7C3C28FBE9979298E982F -:10BDD00028FCE84801E79F2AFBED1ABEFF4621CF69 -:10BDE000378CC38D47FA6ED56817ABAC463E88E5F5 -:10BDF0002F98D1A49F3796DFFAE39B01C837D22E44 -:10BE0000A65F996FBEEA9F6FBEBA1CDFC4F28BD4E7 -:10BE10002B3B6DCE2A3BE6B76A15D2C7C3DE1ED8D0 -:10BE200082EDAB1A0AA85E6667AA6F3F3D6FE6CF48 -:10BE30008777F955ACA7295A249E1704AAB0DDB418 -:10BE400098EF678C38C2EB6D063EC89F972D6BDE6E -:10BE50008FDF093685F8FB2F9D6EA5EFA5C2ADE2F9 -:10BE6000FDCAF62A6C37B5F1F74FE2BED4B55827B4 -:10BE7000176EC1FB835717F87858CAFDDA9B049FE9 -:10BE8000EE5476EDA7F7DAF97BF30E5913E977084C -:10BE900085DF7AA358E74D9BF83A333EBE857E97FF -:10BEA000744E4F88FCA74F4DF5F4BB37FDC59F95E9 -:10BEB0004A7B2E5E6F467D8287795981AF0BF9BE32 -:10BEC000E5569862C400EE0FCAFD3EAC3FD0D71BCA -:10BED0008C18C0EDBEECE74AE3DFB5B1C793295F2C -:10BEE0002CF723231B98827A19D728FC80B8FB9360 -:10BEF000371735D3BEE4CD03E4BE64B786E7B29707 -:10BF00005DFAEB847879963162DE53A29E42DEAF11 -:10BF10000D17D0EF8CED4426A1EFF29FFA3DB5C589 -:10BF200039E34C7C07B7B380B76F19B0E5276D10C4 -:10BF3000BCCF33356B782E1BCB57E83BC07FED620F -:10BF40009114475FF86FD658C4C2BFE323F8E7B631 -:10BF500058B6F2EF31B95E9A2ED5CE984124A7B7E4 -:10BF60000B3ACD1820ECD330360CF5CD7441B73BED -:10BF7000ACE0B7925E6B37C7C8FF7706A0FC3FD630 -:10BF8000AFFF6C7C1EA31F6AC5BC7385DF3C1F7F9F -:10BF9000CF54C5F3E2B9FF7CEA31EE37DFCF3A2860 -:10BFA0001F79FE71EE2F36C0F2905FFAFCDED77675 -:10BFB00063BBA123F6776643347E9FDF712DE5795D -:10BFC000DDF38F3554607EAF76E3DB943FAE95FAB8 -:10BFD000226CD417E060707DB1E16ACAEB98ACFCCA -:10BFE00077368781BEC0BA9461586F0AE30F15E7B0 -:10BFF00000ACC057C4F7FF03486F4CA47A541A4FE3 -:10C00000A57DE0B7FDDE287DA4DD88D51765325F0C -:10C0100033308DF259527F94093F854D8C8D1FD757 -:10C02000921C0E13AD8D92BE220E927E07BC4F7EE7 -:10C030004797C91E3699F47E4698E4B2DC0AF68228 -:10C0400044C96765E23C81183A6FC2755D268E323D -:10C050003E8FE10319C754083EB893F9293E7A513F -:10C06000F0C1BBEFF1DF839B6E5F447CF8DEFBDC4D -:10C07000EF9471D4B78F9F22FF50FCD44B771BF8FD -:10C080009349F8BB169306ADC3FDF44E1BFFFD6B41 -:10C0900085D3D975E7917C7D7EF15DFC1D17DDEFC1 -:10C0A00043B44C4AB0E23E628B99C717D3267F5007 -:10C0B000314BA73F86A45746105FAD4AD7F7FE84A1 -:10C0C000F1C69BE23CD6BD9944F70B5DFCFE854D65 -:10C0D000D7F84270FB73B338DF4A699E8B25541240 -:10C0E0008EB9E2775FE6A9E157BB713F5609BF58A9 -:10C0F000AFD0EFB4FC0EE5B2CE14B1F0BC5E17E5E4 -:10C10000E9E5F8FDE72943145F5B5EE7F6B14749CF -:10C11000F4F13C6FC8F0FB3FBFF3F27C943F2FF08B -:10C120003ECE23ED5F6C7DC2B10537D377AE7F6322 -:10C13000FE14DC175534FE7BCFB1F3623DC2725D55 -:10C140009EFA982DFEFEC129A16F4B105730EF4388 -:10C1500039FED338FF2911179E12FB63A71C7CBF41 -:10C16000EC6F03781EBCC4CBDF4B14D753623FED9A -:10C17000549A319E94FDECE27A628935B05C47575F -:10C18000EF868466CC4B641689FA93458CC74F7B47 -:10C19000520DE72E64792B4BBCB8CF5124CE2DD84D -:10C1A000C3ED32EE63E33EF313D941133EFF3FFD8F -:10C1B0002524DF00800000001F8B08000000000025 -:10C1C000000BD57D09785445D668DDBEBD857487E2 -:10C1D000CE06618B9D7D0F9D0DC3269D8428B86082 -:10C1E0002780A06C0D0804C8C6E27CCCE8BC3406ED -:10C1F00011F95CE2382AFE2E7F83E0EF366384A0DB -:10C200005103D32A8330EAD820286A465B46013599 -:10C21000242D2E836F783FAFCEA9AA74DFDBDD6CAF -:10C22000BFFABD47FCACD4ADBA75EB9C3A7BD5A93F -:10C23000345A897D7B3E21C4EAD34F2D20A44F225E -:10C2400033DB4DB4D4D1923EEF8B6265B65522A458 -:10C250008C90C1D69A6C6B227DBEC2A7277250BD4E -:10C2600086D6D3A0EEC8B6D27E7DD3453BAFDFC322 -:10C27000EAF49F860C226401FC66A5A5D1E4910B2B -:10C28000E9EF1B743DBE6C6C276753099164E22291 -:10C2900071B4924DAC0E333C1D673996478B28DA4A -:10C2A0004EC769D29B364823B1BBC348C79BC3C79F -:10C2B00023C3CD5A187F361B8ACCE9DAFF93144387 -:10C2C000C85C23593F8CB6CFEB1AACA7332075312D -:10C2D000AE4C0BC04D265A8ED1EF4AAE68F96C3485 -:10C2E0001D1BFE4D082D09D19263627E08878B10BD -:10C2F000807B8417E1DA58E14FFE8F5242FCBB0C81 -:10C30000962DF43B0D5D6F1D91285C0D02BE0E2530 -:10C310007C651C9F8418DD5F1809B99E4864201D48 -:10C32000A7D3E42C037C36187D384F3AA2DE41D7E0 -:10C33000C575E7B858847F307D9FCEE7A5163BF9D9 -:10C34000A72E80CF9516067FB55C5FA54F20E4D45D -:10C35000CDC462A08F56EE5FD86AA4F59577110B15 -:10C36000FBBA5D4346D1F139BE22CD2FD1A1215672 -:10C3700023AFC367670E20D6EC407D88334E51A7AC -:10C38000E31298C7723EEEB0BAA18AF74734A72AE3 -:10C39000FA5FB62657D19EE22A56D4D3368C51F492 -:10C3A000CF68AB54D4B3365DADE85F44D206120A11 -:10C3B00067D33E99B8296A73DCB58AF6BCA76F5279 -:10C3C000BC7F9C343F348EF6EB888A2924948E5AA5 -:10C3D000A362B640495C766F3EC5CFCD1C8E82F617 -:10C3E000058A71BE89B9721FACEBCDDEC5D7124A82 -:10C3F00057233B9729C65D2ED7B3756BD31DF5D157 -:10C40000F79AE90FE0B398F8F70EA3F4D1E8966C29 -:10C410001EDABC64136B17EF2DEDDC8CEF2D752B42 -:10C420009F2F7F5A59775592EC66CA9FBFB59A13D2 -:10C43000901E8692A16783F82A4007B413FDDEA9F7 -:10C44000C764B72105F093F5F038C48F8EB8ADA15D -:10C45000EB758A109B07FA3F6FB6B9687DC9FE85F8 -:10C46000381F4392920EA2AC4A3A88CE56D281D956 -:10C47000A65CF781E5CA7557E337D69E7B4EFCC6AE -:10C480004F52D285C06B39FDF939F1FA24E0333AC5 -:10C4900080CF923DF65613E2894C338E02FCB1F9FF -:10C4A0001A884306394712A89CA1CF6D6C0872D236 -:10C4B00062726928FDECB04ADA63C6C038455ACFCB -:10C4C000EB00CF7AC945E0BD28E24E0279D15AEEA1 -:10C4D00049F6D075293636C3CA912F4D8E97414EF5 -:10C4E000D6EB3D85D02EC6FBD2E4C4E73DD23B8BD4 -:10C4F000098597683D85280F8D04BF2FF0386A00A5 -:10C50000A3E3E5C48172F8254ECF5F7C5487785C45 -:10C510004C9AF7DAE9F7BEF998E177297161BF45DE -:10C520006D4A3C84E04F85374A3656F86E13877B58 -:10C5300019216E4D5A283EA52EC9632E0434740964 -:10C54000B9ED3C5BC2C80EF03986F4FF43F92DF01B -:10C550004B3B48C1F209BE671914F89EC0A7905B17 -:10C56000E23B06D22C27011FA8E418C956AE1301DE -:10C5700021310AFFC37FAF52196A8CE31F1B04E30A -:10C58000C0E409B99C7F872C7026019E8CA40DD72E -:10C590006FA364DB20D3EFC897A5B4128ACF128BA8 -:10C5A0005D86F52A23DE59F0BCDCD8DEAAA5435D02 -:10C5B00046CE58909E063FD570363E008724E072E6 -:10C5C00049444BEBE3797DAA4BF23D9A02F0BCF56E -:10C5D000137C773C2FA74249D78F82F9CF4FE8CB06 -:10C5E000E324EB08F85EEDAB59894037EBA566A272 -:10C5F0009ADF91D7E838B2C61F0FFDAA8953CBF452 -:10C60000AE1BF5CD5B920FE77D03B1DF01A5D06FC7 -:10C610008DA4FDCA59B4DED841F5560C94511E992B -:10C6200096A453854FA23D0A750D8504E87B39D445 -:10C63000C5BAA704DAB12E87D6D7521886C49D5F33 -:10C64000BF3F9C62E1FAD19FC9DA997CABE3F8AABB -:10C65000137ACBAD9C5F37FC328490BFEA294E8AB7 -:10C66000818F8C2ECD40425253385F169242189FD4 -:10C67000F255660A1D7F501CE5432998EF587FD17B -:10C680001EC2772AF849335DDCD114DFE652BD9330 -:10C690008ADC85C1F05E003E841DB10CFA02BC2923 -:10C6A00056AC370CE8FEC00ECDA5DE64D0FF629D0F -:10C6B0009AF4C409F618694FC4EF8AE757A7683897 -:10C6C000BE283D5E009E22AF433ADA43621D2ED45F -:10C6D0001E1A1BCFE62FF0E708C5F734053E09C543 -:10C6E000678102DFD3C2E29BE3E36499F72958270D -:10C6F000D97C6810E0797692E346E83FE288EF98CB -:10C70000A409CCAB5AEE79EA51D0639DB20D78B949 -:10C71000713C93738DAFC8C8FABD5D06B744C7A915 -:10C72000EB7C13EDB39E162A487591F1D40FAF0A36 -:10C73000DFA1F860EB28E059A1827FEE81EFCC7396 -:10C74000AC08E72DE7C1C32DE1F0F0CD6FC83C4741 -:10C750003EC0973FD0971FF86E315FF7DFC7386E46 -:10C760004DA1DF2F7D7F780CE0A75AEEDA3B14F065 -:10C77000B05AB219E8772718882B8AAEF39035554E -:10C78000E49F74ADCA7DCD360BC547D270934DA6DC -:10C79000F8C8BA4576B8E9B8FF58BD2A6E212DBF52 -:10C7A0006EA19FCEA0CF258D03E98D6CFFF4777429 -:10C7B000BC2CF36CDB465A9B63A0F3A1DF49F94D17 -:10C7C000B4278DCA89BFE88911F84D97DA7C703299 -:10C7D0001DD71F2BDBC00E4E90C944A02F81E784CC -:10C7E000680687785EF1F856C9670A3C9FD0EA2F41 -:10C7F0005949CB19B0EE6501382754F94BC0EE11F9 -:10C80000784E4863FD89D69F5C1BC41F65800FDA94 -:10C81000DE0D761DC56763A27E3DE8C15E23AB13C6 -:10C820007B36DABFAB8D8C3FBAA392DDA01FBB294C -:10C83000AC5E1CCF6326A620B918651F7839859B8E -:10C840001C90C9365A7C6FB10F8C457C58D838DCA7 -:10C85000DEEA256412E069F5E4CAC171B44C6C6586 -:10C86000F851D3C9AB29CCEEAF3F4D19AF24F0BC82 -:10C870005EEBD15B4CF05CAF787E94E2CD6508D482 -:10C88000179C48BF92A09CB1AD87FE0B374413574D -:10C89000907DD5C1E711092F8DB15AA2A5F86894F2 -:10C8A00088E35CFD5EFB6F19F1AB9EFFE7BC3DB119 -:10C8B0002A3C7C47003EDA5E75E7B50F83FDD9E878 -:10C8C000D511037DB4FA958AC124CC78FD783E3D1C -:10C8D00096B8E383EA5A1FE2A3F1F415F8BCEACE56 -:10C8E0001E3DD03D8C63A5CF5747D907DBCE81E7EE -:10C8F000323E8FC6D3B1C4151FFC9CC993C0F80942 -:10C90000D8FE2C2090D2ADAB53766FA3AF3EBB4F79 -:10C9100033694B98F9EA5319FCB9895AE4973C0FEB -:10C92000B16F0EF37DD16F501C95D72686E79A82A2 -:10C93000D0F97554FAE6C2FC2F9F48ECE1BE779A15 -:10C94000D38B9877479C6F31A7FBCC1A7350DDA22D -:10C950005CC7442E173AAEF625C3F8BD93991F1F46 -:10C960008A2736CF51DA6609F05191E42C02395208 -:10C970003F8356289D0C9EEDD138F3037C1769DD6B -:10C9800003F8A6FE57C9B9F0ADC77631DE570739AF -:10C990005F12BB49A2FC349FEBADF95B975F4B651F -:10C9A00067BF1FF3D526EAC7D04F7C459ADF3443D3 -:10C9B000BD4D423F658193903554EE2CDE56B21E3C -:10C9C000D4C5FC2442AE8863CF6F83729D2EA06FC6 -:10C9D000F1FF7612AC1FC5F76FBE5B69BFD691BB86 -:10C9E000BF05FBE7AB834C3E508D867EF8E23F2AC5 -:10C9F000C7ABDB7ACD7198679DCA0ECA02438FDA46 -:10CA00002185A9DC4F1B4546811E58B9ED3B7D8C25 -:10CA100035321F7C4DF93D3D03E4A505CB8A547B9F -:10CA2000592AC4190EB0793A529DA353219E72809F -:10CA3000CDEB54FD29A6271E4B40FD6400614E7FBF -:10CA400035CC32BA5BE93CEEA4E2248AE2C76060EE -:10CA5000F690B0036579951C43DB477FB93A0ED653 -:10CA600037E1B9AB26C17889CF45DB019E8D15F63C -:10CA700022881B6CAC31D95AE99046FA3EE80FF790 -:10CA8000B3A3DF180A5642FBFD95C380ECBA5EF7EC -:10CA9000405C6583E6DBBDC368FF0D57105B2B0967 -:10CAA0007CA7A9ABE645984FF234A66736A6D88B8B -:10CAB0002C41E3126ED73572DCF5EDCABA6F2C5DEE -:10CAC000DF47F7A1594DE14B1D08722397B075263A -:10CAD00067289E289DC0B783EDD71EAAAF4856A0F1 -:10CAE0009EDB2E7974149E868E1735A00FEB6FF7A0 -:10CAF0000C9A057AE919AD6D4BD0FC12FE32A4D226 -:10CB00001A13D047B3240BDA0BC23EBF91887FF9CA -:10CB100048373339DDDCC8EDF259D10CBF0B882D15 -:10CB200019DEBBC948623494A56655B597A1BE5AB3 -:10CB3000AE8B053B096009B7DEA28C145F6A7CCA24 -:10CB4000EC92E8BAF74AFE4C18E46B88F9B03893D7 -:10CB50007B4B4AE838EB5399BC68CCE476623AB137 -:10CB60009B29DC8DBBB3366FA44D8601741D8B51A0 -:10CB70002E19CB8BD14E3682FFB3F4B5288F141308 -:10CB8000C00BB1D88B34102FA81D5EBC116CD32301 -:10CB900054BE5006EBD5F992918FA9DC91A8EEFB1B -:10CBA000CF2D936BB494EE1A87523B8CD6DF4D9DFC -:10CBB000C1EAA9BEC51A5AFF614B33ABE7FA8E41F1 -:10CBC000FDEC965B6BB4942F1A8B7D8B655A1FFA24 -:10CBD000E45DAC1D1C424A58594FB6D5B8E8F85F21 -:10CBE000C772FD6EF3CD05FA697C354BB33108DEB3 -:10CBF000F83426B7BE8E62FDBE4E21F36A01DFD93E -:10CC0000BE4C98A7E8F7AF546117B76129E014EF5D -:10CC100091A4F0E3FF99BFB7B48ADB25D16403E0A8 -:10CC20008D2E932B86E27F4F57D616E8FF406A1C65 -:10CC3000C7171DA734308EC0A3184F7C7719E85D45 -:10CC400090C73A166715EDAFA532F949BFB30EBFCD -:10CC500093CFF0DF583BBC08D68DAE9796AF979632 -:10CC6000F9AB9BB13F8C1B5B88F2BF444BFBEF39A8 -:10CC700043FBA704E6ADA68F7D9C3E96B652418845 -:10CC8000765A1AD2D18468661F9252251C43399E67 -:10CC9000E3D362199CFDEB3158C2EFB4723C0EA78E -:10CCA000782FB878B83FE6F3F9B9E10E5A2FBB0CEC -:10CCB000ED9D395B82E121E47EC5385FAF55BD57FC -:10CCC0004E1910E6119786EFDD19458CF89C6CE93A -:10CCD0007F2FA590D9A560AF3670BB9AB8AEC0E0E3 -:10CCE000423D971A0D1BBC7A2BB4B74B7637D067F1 -:10CCF0003A850FF05B7B6D2987CFC2E1B330F8DC5A -:10CD00000A3A2587FCC9D3CCA1F4DB8FF7FEF1F2F8 -:10CD10008BF9780ABE0E371EF047A4F530A5FDCC7E -:10CD2000EB21E6A9C2673F9E55F313F8047EC6F7D0 -:10CD3000F295F4D84FCFA9621D557C9D7289DFAB67 -:10CD400060EF35FC96AE23D82756253D3774A4688E -:10CD500016E407DEEB84B52C0BC4E946A6717F6FA1 -:10CD600038190EF2DB55C9E2A9AEED065BAB15E34F -:10CD70007B2569E1E37BF85CEDEFF5C5EA89847614 -:10CD80009132DED09768F3DAC14E3D496CDBE8B8EA -:10CD900063557607ECDB6C3705DE0BE81365DDC504 -:10CDA000F920347EE44F86F9951A2A77586D845C11 -:10CDB000F7E453289F4B0756AE4AA1F5DA279F6642 -:10CDC000F56195DF418866DA93CFA03C2FCDABFCAF -:10CDD0002E15EA69CFB2F609F61D32EE383C5B3308 -:10CDE0007148C07E989E6665F6479586001D19E4D9 -:10CDF0001536D093029F91CA5283A6399CFD3AB74B -:10CE00009F9FD9BE4639D7CFE5C29FF76915FE7CF3 -:10CE10005F8CD1250F847D2EAA4F29BC4BD39C0B50 -:10CE200001FF4DD13D73C114BE3DFA533DD843922D -:10CE30009DDA1B101FB15AC86C3A4FA967A303EDC6 -:10CE4000C06536A316F1C9E35514B6B3749CD77602 -:10CE50003F73EB30F61907CC6334E7FFA6DD3FFDE7 -:10CE6000F809E8D1AF4D3608078EEE7A6415D85729 -:10CE7000A3BBDEFE89E95B13EE5789798F86B82361 -:10CE80007D5EDE69C0F98FEECA5904FDC7BEDF952D -:10CE900006F431BEDBD30AE2A06FD7CBC39CC1FB43 -:10CEA00057E4B87436EFE2ED8B7E7C7CA927605F97 -:10CEB000527CDC919608F838B318E28BBD8907D70D -:10CEC000FBD04E1BCEE299FC7D6A9767039F9F22A1 -:10CED000036CB0BFD06766E3A8E39C476A287CF484 -:10CEE000F9783F9D4190DD3CE1B4910A9040BD82CC -:10CEF000C42AEA55C6218AFED5961445FB55493900 -:10CF00008AF6C9D62245FD9AECD18AFED7D92A14D1 -:10CF1000F5EBCB272BFAD7D86B14F5224FBBA27FAA -:10CF2000C9BE4E65FB212BAE4349B7A30AEC799BE2 -:10CF3000D7D90AE5E53D6D5503AD2424BE5BEA7300 -:10CF4000B7C2F3B1679ACB3C2434CE4B9639715FAC -:10CF5000C000EB2207ED135478911F7B35366B70C0 -:10CF60003C77F620E7ABB04E6F4914ED14D9571853 -:10CF7000FDF1B05ED5F3EE9163605DFC04E35F1DEF -:10CF80007ADFBD6341CFCF91D1EEEDD012B41F3B1C -:10CF90006616B821067844F2BDF409C8A939D1282B -:10CFA0004FC6530B17E186BD5009D6C9A980BB8275 -:10CFB0002C55ADD30A45BDDAF25B45FFAB92D62ABC -:10CFC000DA275BEF52ADD3FD8AFA75B64754EBB45E -:10CFD00059B54ECF28DAC77FE16B05369AD0E39278 -:10CFE000CD74FE638EB455C1BA8CED76CD017E2929 -:10CFF000F5385B5184EC697E134A0FF5AB20AEF532 -:10D00000464B12967B5AAC1897DADB928DE5BE162A -:10D010001B3EFF5B4B3996EFB4D8B1FC7BCB242C85 -:10D02000BD2D0E2CDB5BDAB1FFF6964E2C290647A0 -:10D0300080BE4888E7FA87D6C1DFEFD5F81A61E7E6 -:10D04000D59FF6BF514EF60EF0F542FD76D76994A6 -:10D050008B9FA413946FF119ACFC29DDBE2ABD8C03 -:10D06000C914E44F9D6903E881768DBD08EC6B6DB2 -:10D07000BAE60FDA1184DCB1D6916489657523AD07 -:10D08000E362836346347FB00F27E44FA03270938E -:10D0900045530BF5BE28D67E364D53EB42FDC0F608 -:10D0A0009DA705F69DB5E961F69DFF74C26A867875 -:10D0B000CBC133596680EB208F2FD949916E3E2D1D -:10D0C0002BB4453AD08B47547684283F335598018A -:10D0D0009E768D6D3AD829AEAB75641B9517B51247 -:10D0E000F347FBEDC074666FF75D67407FE790C65E -:10D0F000BE08E89CCAE927005F195BE36A41AFF408 -:10D1000099FDC98087B4ADB1AC9EE87F42B205D528 -:10D11000750CCEE15B2DB5AEFCB070A6C07CD470B2 -:10D1200066A6F3FD068F7D04E85F513F54636F00F0 -:10D130003D71A8C29E01F339E83020FFB81C667724 -:10D14000060839ADBD6C7A50DCC59DAEC3F7A6E9C3 -:10D15000199F919B64F7B6307EDAEE7466EFE3BAFE -:10D16000813F776334DAE18734A46E7B183C7EC05C -:10D17000F1F3CD80F0F1970FD3991EAC9C6AC6F104 -:10D18000FA5647E1BE6F9F230BEDA0BE668A25CA03 -:10D190001F7D279A4FEEC47683D812C3FDCD595C0C -:10D1A0004EFDA96BD50F8769FF4F5747DB50865B54 -:10D1B00072513FDDC43BCF8937A2DD32A7764425CB -:10D1C000E8A5597C9F6CAE593B08B7CBB4B17A0B3C -:10D1D0001DE76653D17A50FF8B136AF4B1B45E3702 -:10D1E0007CC57A2897A5DFAF8FA3657DFE8BEBC149 -:10D1F0007C6CA0AC5586FE92EFDD163AAF796B647D -:10D200002BF39FB85EB32FBFA87319820E018F4016 -:10D21000A714BFE8171EE1F816EF1DE1F85A9CCEDF -:10D22000EDB602527056B9FFB30CF8A167CEBB99A8 -:10D2300011E2F4CA766EB77DA067DF5DFEB4CE1D45 -:10D240001C4F12DFFD289DD9D787F4C42E811D778E -:10D250009319E9A370E677B79751F80BBB2C1ADC4A -:10D26000BF1772DC4B307E5FF68513E5DCE53DBE13 -:10D27000A70E13A4F34EE093F3E9A9A9AEB5A81F36 -:10D28000467F4FF50FC8C533CE4F0FA31CACE372DA -:10D29000B019E5D79E963558DFDBE2C2725FCB0648 -:10D2A0002E07DBB0FD9D964D5C0EBAB91C7C1A9F13 -:10D2B00077B5CCC472778B93CB41B6BF5ACBE969B3 -:10D2C0007692F33EC093D8C79C6674EA005F7F7D78 -:10D2D000C44064D89FE832209D520E78E2D10438D1 -:10D2E0003763B06CB4869E9F51CBDBFEF557EDF7EC -:10D2F000AE4EB23F0AFCDD7F5E06ECB3CB22D3CF4D -:10D30000416235833CD9917E432DC8E78356AB19E2 -:10D31000ECD68EADBC6EB79A75B4BE337D06CA9797 -:10D32000834EABD940EB2F6D9DC1DA5D567314ADC2 -:10D33000BF9C3E93D5DD0437B7BBD2E7A09CAD20A0 -:10D34000D21EE0872A63CA442AAEA97EACD8037CE9 -:10D350007055D2FC89C00779E956A4C3C9D6B57BFC -:10D36000A07E4DF6666DBC15A2A145EBE0BDCA845A -:10D370001A2DBC3771F88A75F0DE95E9F76B83DFFB -:10D380009B94FFE23AA85F6BDBAC057B300FE45661 -:10D3900062601C5117ED42BE8AF35D23BB1C28C797 -:10D3A0000B3B1D28C7055E2AA7D5DC0171BAA64E26 -:10D3B000C922C13CA649FD9BF612B5211ACF506E79 -:10D3C000A172F6EDF4BAB8B514CE26A88FC1FA1F33 -:10D3D000D68697BBDE70FAE543CEA7A0376BE83858 -:10D3E0001F52FE81F368360E5F53D77CF37CD4570F -:10D3F0004E33E8D7515C5F8EE1E5325E36F1F233B1 -:10D4000093FD63F8CEE791F9FA4BA00FCAB78BD919 -:10D410003C42F85AD9CEF9FA38C72329F52743BD3B -:10D4200081B4619CF07CE7BC9606FB6F29705EA21C -:10D430001DCF61A8CF4BD4132F1BAF5D75DE82F8D3 -:10D44000F4B80FDA19F41CE511F73F0630B93713B9 -:10D450008435381D1914EEECB0706B3312CF09B758 -:10D46000B29DC3BD94B8F17C9B1A0EE24C44DE5AC7 -:10D470006E3A84EB190A8F2F3C3C217030FF5D9C83 -:10D48000671171796A07256494811C341388DF045D -:10D49000CB89C3E790136A79F473C9B973C89B1C2D -:10D4A000C09B5ADE88735AEA52D873B4EE82737AFC -:10D4B000AEDD5118A73F697596C2387D95FE1F35C0 -:10D4C000E09F25F890CE7E3FCC7939E041D2B3FD84 -:10D4D0007AFA4626ACDB098DEBCF601755656C41B7 -:10D4E000B9D30BCA81F2E3585A07BBE7F1A18EF119 -:10D4F000F01EC966F413E95CE7C40CA68F424BA288 -:10D5000038DFD8B7F9A7648C639D87DE23E1A15A81 -:10D510001EE77381BC2F8F4693A747221E89DA7FAF -:10D520003D1583D08EE819A1D742F973FB893D23BD -:10D5300032717CB5BFD833A4DCC8BE7BE524283B60 -:10D54000F5CE4DF3C14F1A6D403FE93D7E2E704A36 -:10D55000343B47F51EEC13D37E538E9E4900FDA548 -:10D56000F6377BF6CFAEB41686FA9D14CE890067E7 -:10D57000FDE79A3BE0D9C5FAA1F56B7E24DA78BACB -:10D58000AE6BCE106DC985F8A5440671517CC4F60A -:10D590002694655F78E30AADE07F0AFB81FBA7E78D -:10D5A000398F54EE67F6C28433245B5B0A71A6019F -:10D5B000B87F2395BFCDFC565E8A7D91716C0A645D -:10D5C000AEC6E4D6A72ACE23256969395BF68D82DB -:10D5D0007A2FF1E23E89DA9F7D8BC7A1A85FFB20FD -:10D5E000D0ED7A7E4E89AE483CD06FF5EF3E9A7B07 -:10D5F0002BCA8128B487FAFDDA9D1A3C67D0A1B501 -:10D600000F1C0F7EED9A0CDB5A5AFFCC9BF8E06B97 -:10D61000B46CB2FC887813FC5BBFE63BC4A7A8F7E8 -:10D62000F0B86F9B8EEA1F5AD6FFB78C7AA89E90EF -:10D630000DB86EE40DFDCA20BD48DABFEDC7FF4846 -:10D640002AF76A0081A8172BA7DA69BF1AEE7F10A4 -:10D65000F226AB73BF8BB852A7DAE9B83589BCBFE5 -:10D66000EB21561F21DA1F66FD33C478FFAAC5FAE5 -:10D670001051E7E3E588FA7BAC9E22BEE767F5022E -:10D680005137B3F1CDACFFEE6D3BA6823D22E4FDF8 -:10D690009E0CAE1F8B48113F9FB30FE57FE47329AB -:10D6A000CA76AE1FE63D23BBF423617D2647BF0B40 -:10D6B000FCDD2EE119BAFADB7418EFFE26AEBD7060 -:10D6C0005590BF22CEB138AACC76B0FF1A5ECADA26 -:10D6D00022F3733D607F10BE1F5D2D9B707FE2D4EF -:10D6E000DD4CEE47B2DF16AF794DB19E21EDB2C4ED -:10D6F000FC71D8B8A3DF3B79CFE0CDE85FA47B71A4 -:10D70000FFFC588624F6E949795CE0DC58421AB1FE -:10D7100083BF9AF03295CFB0C65F78511E2F7E99A5 -:10D72000C57F1B1E7913F5DE02D98AF1DCEBF29D71 -:10D730003D809F5EB317E38A8BD7ECC679FD9F1CB3 -:10D740006E3758FCF9C1F8FC3E14FFA7CF83FFD316 -:10D75000BF26FED571E765A63D08EFB28B3CDFD64C -:10D760006B66FBA236BE4E4735D6511C5F719910D1 -:10D770003F5FE4CD8C95E1F0B177103BB7F44E19E3 -:10D78000F845A79ACD04D67DF6AA7F143AC3C47D86 -:10D79000D5FEC0CDF0CDC400BEAC9921F84DCF2C44 -:10D7A0003B277E95EDBF307E076B7D7A1BECA31E79 -:10D7B0002138CE28EF517DF0F99889994C0F0FEC64 -:10D7C00064FB46EA735F1333CDCC6EE2FB330DB5D9 -:10D7D000EF8C83FD19C10F13A2493BC4DB295DDB2C -:10D7E000385DDB80AE05FD06F669E87B61F82B400D -:10D7F000BF4471AEEF9A4C6E5F06F07A7DE6B9E9F0 -:10D8000056D9FE0BE3B583DAC3B8AFB9330AE329BF -:10D810006A3CAFE47815F86ECD64FC1F09CFAD808B -:10D82000E7C49F1FCFAD9956453C42E03B927E52E4 -:10D83000AF8F9877183E2DBB143ED5677339A5F589 -:10D84000E17953F5BA6F0CE5A77BCFC34FF7FE9A8A -:10D85000FCA4C69BBAACE7FB9DEAE7CF678AF3015D -:10D86000BF0C1EFF7F8BA7CF697E5DD13E6FCD7E43 -:10D8700045FB7CD701457D9CCF5B05642EE2E357D9 -:10D880009CF0BF09F54B8DB3478AAF4FD9B1440324 -:10D89000FB6FE55E16DF6FC8764A5974DDDED3B8DC -:10D8A0005BCD14AF9777B7CBB81FE62EC27DC055BE -:10D8B0007C8EDF8DFBD7A7B752BAF98E1830FEE900 -:10D8C000793D476B2D08A5838AD332B107D98915D5 -:10D8D000C6582DD85315D4520E4737FA2C467778B0 -:10D8E0001E88F2FB4C23D125503E9F3953C2F34F83 -:10D8F00033093B574D4B8F93B64FD1128F81D66B67 -:10D900004C5A8F01F7FD58DEC374364D62D01217A2 -:10D91000B4938478F483A7C1433A5FD92EE379B6F0 -:10D92000E9E56CBFF02653BB0EF4E98DFB6E3F7941 -:10D930002B6D27EB5C65ECDCB6C863FB587331FBE1 -:10D9400080FA2CC6E77D12DF5796743638E7AA7E38 -:10D95000EFE34C06EF1479AD0CE75FFC0708DADD66 -:10D9600082EF287CFB0CC52C4F630CC049749EAC25 -:10D9700018B09FEFAF82FEF587AC8897A6F2B58509 -:10D98000B08E4D13A5CF0D8501FFA669CDF768A711 -:10D9900057CBCFB742FF53475868FCF21E970CFE97 -:10D9A0004A207EE99B0B7C793E3F48CCBBBBC583BC -:10D9B000F4F469CB3E2CDFBBE2ED32B0337C2DDEDC -:10D9C000B0F1CB4B8D17883881881B0839F0D96DA1 -:10D9D0005583812E6D595C2E18A561201788969568 -:10D9E000425E8ECA0A91AF63B2CEAD5795EDBFB01D -:10D9F0007CBD503AAF4F627A514DDF6ABA16F44C93 -:10DA00005F2B93E8776FA2F61EE8D559C455504FA7 -:10DA1000E5ECCC256DBAB1D2A5D3F532D317C92424 -:10DA20004CBECAC5CB732BC22F57C9E81F88F30A57 -:10DA3000621D1AB242ECA115E759B715BFE6BA85C7 -:10DA4000EAB52FE65E9A5E230A7BE0EE50B8DBCEA5 -:10DA50000377DBAF0A778A55E4D1CC953581BC11C9 -:10DA6000384F0C765C9F9BE545D6A5B4C5E0E1CC6C -:10DA7000727F0CD88D4B77C94887446BD70EA1F4C1 -:10DA8000BA84D36B0FF17C00F4B864DC12CCA7AB82 -:10DA90007B2CFCB9E246DE7F99A9430F702EDBAAEE -:10DAA000ECD7C8CF15D73FAF8C8B368EBBEA388CFE -:10DAB000DBA83ACFF35216CF4B2C26C5ECDC85D22F -:10DAC0003E5597BD2D4411AFEC3DD382F180DD5919 -:10DAD000FE075CC383FCFFD0F5DB97756E7B4ED9E8 -:10DAE000FE2BD3AD6CDE8AF955174BB76B73EDFF88 -:10DAF00080790B793C1B6413FDEEECD70C6E17ECB0 -:10DB00008F9659597C5372B7C27E5BDF4F04E3474F -:10DB10000B789C33527EBA386F30FA90BB959D37A4 -:10DB2000B0CB902F3A6A9FA30AB62B4ADE69467B98 -:10DB300024E2BE95C8B3E2E7872E54AE89B8DEA8CA -:10DB400013CD6867D9BC16B487C69C6E7F13F4E307 -:10DB5000CF15EF16FA706C3CC35BA9CF81765EAF30 -:10DB6000CE53F621D809AF4485B51362B3D9FA4D27 -:10DB700075CDD7B1BCC390FDC0D86CBA1E53B9FCEB -:10DB8000D718ED3AC053B5DCF3E00CA01FAF8CF111 -:10DB9000BDD5BF7FFFCF8F5ACFEFF73759BE43BBFD -:10DBA0002192FDDFA461F917C555563CE707FE1425 -:10DBB000C4F744BC4FDD7F426E651ACCAF5A1EE7F6 -:10DBC000B5C37C36B1F9445A9FA635DF2AE28B9162 -:10DBD000BEDFB4ABCCB220880F6ECE9684DF613945 -:10DBE000660CACEF85D2C178FF4C85FDF3FFBA5FC0 -:10DBF0003145A6A625D59F05929BD9AF84D9B1B34F -:10DC00008917CBB9C48FA593B0F3F70B880DCB9BC5 -:10DC1000793EF3811CE74C58973E9D7F109E9F7C78 -:10DC2000E9DFF9403727AF18DB06DB5EBF941DD76D -:10DC30005764C5EFF7EDFC77329C83399F5C589DA4 -:10DC4000645F9E1D66FFF9EF15F24C966FF518EABA -:10DC5000891A7E1B0399C8F6D1484A0AD243402E3E -:10DC60000EDE2CE422ECCF167CAE61E749964AEE3C -:10DC70000CDAB5D3A741D62A5894E296A1DEC1DAD0 -:10DC80000B1A62DD12AD178C8E62ED2B62DD104730 -:10DC90009F437CC88FF3A82884723E61726F21B1C4 -:10DCA000B37C07E24F053B6C5197919DF727BE74FB -:10DCB00090EF8511FC9FB7B299DF3C3295C9F39183 -:10DCC00095CA38C53D5C0EF4E6549EC8A6E5A96C1D -:10DCD000FBBD80979171DE8D0F9462DC9E80FF709A -:10DCE0007CF46F71BF51BC97985BF900F47B416283 -:10DCF000E7D35DBB0C783E82BE31C81174AEFF40E5 -:10DD00004ED523D0CFCDED928878257E45FE6C8010 -:10DD10009F5C38BF91E07361BC9C3E28C7EF62FDF9 -:10DD2000C5ECDA69EB4C18E37781DD9B98EB7C1648 -:10DD3000E7AF27C404F37FDCE0DE82F6697332C408 -:10DD40002B973C61D080DDF01155B79087F2498B5D -:10DD500011CB7F503F18CACFA81F0CE5E7D40F8620 -:10DD6000F29FD40F8672D1E922AA2C283FE5D8DF92 -:10DD700064F41D3E4FAB4BE05B7C7F971EBFDF9B87 -:10DD8000E344FCF6AFF72BC40D9B3A2FC4FA87C6C9 -:10DD90009D83DE22CB198617B15FA86EDFCED7B583 -:10DDA000B0438BFABDB0D317B338A8DF816C3DCE3A -:10DDB000B360E7179887DA6BE9C7AF5DA2204FD150 -:10DDC000B0FA81EC3AC46F6F8EFD04C04DF9FB30A0 -:10DDD00094859DEFFF01F27FE8F878EEA04FF23FC7 -:10DDE000847E800A0E351E045C2FC47A37C2FB2F56 -:10DDF000EC4C0548A8BC218C6F808EA470F0AEC599 -:10DE0000F95E6FF097425ECBF567E5B0E78C7B7308 -:10DE10002A10CFEB04BD093CF1F5BA54BEEEDFFF8A -:10DE2000E6744AC43D1E203BADA087CEC480BD57DA -:10DE3000C3F7F73B3BD2DF03F85CFB64926145FA22 -:10DE400055F0DDB01C4627A22CD8A577C03ABDB04E -:10DE5000EB58FACD265C97F445B47F744E8622FECB -:10DE60005830FAA7FF782001FB5BE0533792CDD5FD -:10DE700070FE6496F1F5BF0248732C9F57C3F99367 -:10DE80007949D25E28E75B53AE847327E27CFCC2FB -:10DE9000EC8ABDC04AD7DA6AD04EAB00E112A40FBB -:10DEA000AA8CD1B029D85FAFB6C42BEA57250D5341 -:10DEB000F49F6C4D53B45F939DA76817DFBDD65692 -:10DEC000A2E83732CE9F0AFE198503F9816C93F1DF -:10DED0009C5EC1CE4357E7D1FA94A7A6DBC02C794C -:10DEE00081B74FD95EE586F5E8A3F8D45303EA4439 -:10DEF000F95D0F3D0083A9ECFFFA5D4FEEB55B2F96 -:10DF0000C2FE8F60F70B39BBBCCB580672F642FDE0 -:10DF100000F5FA8CCE51FA0591E8A69F2F242BA389 -:10DF20009BFD32D916866E08B99DD3212BA71C64A0 -:10DF3000F963172BCFBE0479161FE08FFE52159799 -:10DF40001BA9B7BDB70AE2F4EFCA04F3F1785EDFAC -:10DF500062F85D0ED03BB979F31D4312F0B90BECBA -:10DF60005CC82FB5D3F157E470FBA9FEF53B86944E -:10DF700006DAC9EACF15FDC96DD27A457D5D8AB250 -:10DF80007E77C5FAE0F723C9C5C59BE6EB9D98FFF0 -:10DF900029D9DD61E483984FF51B5178AEEF3A380B -:10DFA000AF421F35961ED0C23EEC7511F4A8903FCB -:10DFB00037CAA4395CFB6D392CCE7FED1B51780E2E -:10DFC000E662C7FD88E212CF19BECCF4E84703BD74 -:10DFD000DAE075BF93CFFB64D9FDBFFF11F6475F51 -:10DFE0002178EEF3642C93FF851DC7351AD0830387 -:10DFF00018BD145A7C1AD02B7D75D12E38D7DFB4BA -:10E00000D4CCF25F52FD1F18E9D2DF97F3CE1F8DFB -:10E0100074DD3E8624C820BDDA074E11AD6F7AE666 -:10E02000ED69EBE8FBD7BC11E5D15C023C9BF8BE87 -:10E03000C4C84AC6E773816EB87E81187BD31DA41D -:10E040005FDF805C00F8A1FE5ECE7B87FE0876F87D -:10E050007EC6E770C24EEDDFCF0AF2EFC9638C2FA8 -:10E060008DF4879D5352F1F79E36BDE99C7CDE8E80 -:10E07000E76E2E94BF77E4F03CE1C8FC7CF01ABA5E -:10E080003E4DAFB07B2D4E7565605E6C247DDEB479 -:10E0900049463EECD75F5DF22437EA29651EBAC0D7 -:10E0A0002BB1DB903FC5FD512BC7FFAB16F4E6CA81 -:10E0B0005D5A764824D27736C8C41AF49D17761B69 -:10E0C000EA30CF8DCFBF4FE8EB5D3FC455E4B3726C -:10E0D0006D18BD47F5B42E01F4748D847EE5E15DC5 -:10E0E000832B014F8725E2B162DE163BA73C950DDD -:10E0F00007CF4D786F4952369E4F16FEA5F02BA7DD -:10E10000EF9A9E0176E5071D0B0ED39523C772D2B9 -:10E11000908F661017DAC187631D23202E31859FEB -:10E120000F381CEBEF01B97C787CB404FBFD74FC68 -:10E130007530BE80EBB0CE3182DD3F21CE25E75E6B -:10E14000D27D71D5F26D15D7C0FEF66C6201BFF2BB -:10E150007A99D9B9E42F8C3F85DC6B92BC7130CFB2 -:10E160000339B5A773289E06AFB997C75539DEB4F2 -:10E17000EC1CE285DAB9FDFEECD312BB17C5C6EC88 -:10E18000FFC671DF3C3803F2E4A8DF2DD1F92CE89B -:10E190007C1DEFFF51FBD9FDFECEFF309E1AEA2F0A -:10E1A00039E27283E2E46ABFA9DF4E17F6DE367603 -:10E1B0004EFECDF10FF72EA7F5D5DBA2118F5F3DF7 -:10E1C0006170811CFF6A8B01FD9FAFE2FCDDABA09B -:10E1D000BEBDC0E6C2AFD914F7A32DD1583F04FD90 -:10E1E00043FEA6C37B3D8E3F6EF0C0798FA54FE600 -:10E1F0006C017FEAF808EB73CF433CF0B944BC678D -:10E200008038D9FBD7717E04FEB252D343FE2F3340 -:10E21000DA114B770C413926D6EFC4E3519847FF0A -:10E22000D5BEA903215ED6A37911F378886C7281DB -:10E230003C5EBE250AEDC035166729C05FF55FD785 -:10E24000CD2881EFBF9F48009EBEAE1D18AF0CAC1D -:10E250006F78FD7EAA2B8DC9817E7DCBCEDDCE83EE -:10E2600073B76978EE760C8CDF40C4FD8BECDC6D07 -:10E27000B12CD931EFE09EF079E4D7E432FBB15E06 -:10E28000C44FE2893109F8D04910DEBE7BB2B680B6 -:10E29000BFB330378E7FD7CFF32505BD7537BE8628 -:10E2A000F113033BEF17157E1F7B462ECB2B5E6CC5 -:10E2B000FC5E11BF695CF39322AED2984F50EF160B -:10E2C000B75A4B56D07215C7F3EA54C74D00DFB2A8 -:10E2D000F6FB5F7A07F1F2D86F3E86EFEE3361DC32 -:10E2E00086BCC3F0A7F667161BBFE5FCB4596107EF -:10E2F0001F7BE4433C6F726C675E21ACDB02D97B11 -:10E300000CEEE5EA357B3FBD9596DBF71DC47551F4 -:10E31000CF3764DF5E6272A51EE08887F32E8EE63B -:10E320005CDC1766FC7E746301E24FC473FBBE0ABB -:10E33000EF6F89798AF1C5FCC4F8A2DFFFE2EB75C3 -:10E3400052EF2D04FD9C06FB166581F69331DEC26B -:10E3500058133C67792D27E3683D886E7EA9FD9DA3 -:10E360009B789CE78866ED2D7A4A7F3DED0FE89C0F -:10E37000C172F422F775C47CC5B9529147FB9FB9AD -:10E380003C9E3D828C88907FFB646E59D8FC5B7C00 -:10E390001E29FFB63FDFF607966F2BF26B4BAB34AF -:10E3A000CDC179B6421E96E6D1E7F9B0EFAFD4EF12 -:10E3B000A52395FD23C9C7F1796C1D4BE3C3E7BBCA -:10E3C0001EE2EBDC4A3CEC1E42AE17C772BC8BFB74 -:10E3D000BF849DD2C8E5B6C8F31CDBC5CE6D8EE503 -:10E3E000793B540A609E6BC83D6F4979A857C53D7B -:10E3F0007D121D6B765CB87C612FCEE30AE2C7D23A -:10E400004E2C5A2829FAB19C481C585E499AB19C56 -:10E4100044DAB0BC9AB463792DF16249723DFCBC18 -:10E42000E76D2CCF74F2120DE8D7D219E1EDE21F9F -:10E43000CF8B0717DE2378B178B892B0FBFE42F09D -:10E44000313C1BE95B8D0F75BEE678E2C38B4B2632 -:10E4500000E1A6811F6CC5F3AD55C48EF5EA0BC46F -:10E4600043B9CFA965F9BD2A7C5485A78BB31C1F7E -:10E470001B40779605D6A9348FC901B15ED4114BE4 -:10E4800002F9AF5E47F1BC34BAF23B2B1511C3F26F -:10E49000EE988E79DC2595ABD268BDE0B907597D41 -:10E4A0006CE50EC8F31E99F7F074CCFB1E5959A207 -:10E4B000B3C17D729BA64FA4ED4E7E6EDAC9CF4BE1 -:10E4C000136791E29E2CE7DA5BF0DE31E708930DEB -:10E4D000E01479E1721ADB5F4D9EE4794347FBED6E -:10E4E000B23807E595C139734F8C15EC84B5D578F2 -:10E4F0007FD49D7AD65FDC6723E013F7DC6CDF9E68 -:10E50000B74A4A3DFF3CE8F8E97989309F0CCC8F47 -:10E5100073EE94783E5CE5E099546EF4787504F2FD -:10E520000BC4F72CA9CE1C980F81A478CA17C3B8C6 -:10E530001EEED99E9707EB549AC7F30713524A0071 -:10E540008F0B521DA5D05FE44597C2BA24462E67B3 -:10E55000E7D98BA1BFFAB9C8CBAECE7396437B5334 -:10E56000F419CC37EB2D7A7FBD2F25344FBDD54E16 -:10E57000DC7A942BCAFCF4BE457ABCCFA9D4E16CFA -:10E580008523CA97CFF68FC27CE13C67158EABF727 -:10E590002517D1F7FE3895E5BFABF3BD77EDDEAFBC -:10E5A000C86F177CD69FDF7E8AE5B707F8EB9155D9 -:10E5B0002428BF5DF08DE0BB3190DF1E03F59C4544 -:10E5C000D06FFCFBDD98DF3EA1DBC7F3DB3F54E6F9 -:10E5D000B7DBFF7549F9EDC7F9BD6FC78DECBE24F8 -:10E5E000719FD4CA9D6CFF77A5C4EE935AF9277624 -:10E5F0009F94F00BEB387C0DFBB7AD877DBEBAC79F -:10E6000016E27D5484DF876AA53FC17EA1B89F547E -:10E610009D07D304FE20DACD1EB4BBD4F9304D8F54 -:10E6200055A13FD8A4B2A36FC9E3F11DAECF08B77F -:10E63000FF96F077010E13FA677AB43B573EBECAD5 -:10E6400066813AE72BB2EF7912DC9F3C168FB4203B -:10E65000F86CE90609ED5781BF914F19EC789FF1ED -:10E660005383D16EA5F636CF6376337F9BD20A9C57 -:10E67000877F21D69F0A76F20BBBB26D54C29257A8 -:10E6800023DE43FDBCEA1EEA2715F7509F82FF8177 -:10E690009D7642E386714691ECFBC6D17AD909ADED -:10E6A000CD6D0DDCCB7CBEFB8705FE0D7CBD2EF653 -:10E6B0003E62F5BDCF22FF417D2FF19DFC5EE2F170 -:10E6C00011EE2536C85D32DA0FDF6B15F7135FCE1A -:10E6D000E12CB71237DCF73BA647AB58FF725F1B44 -:10E6E000017B28EA90561147305895F597F3787CCE -:10E6F00080DF2F128A6F533F3E0D88CFF487119F22 -:10E70000AAFB9E059EFAEF7B1E6E42BA1FB37F875F -:10E710000CF2E062EFFDFEB5EFF93EDFBDDEEAFB95 -:10E72000BAD5F77347BAEF5BAC7B9167A5A2BF7A06 -:10E73000DD4BF6FD4E791F355F6F17FDF939D7FBBD -:10E7400007D57AFF1B2E40A37CF8F7981377035B5D -:10E750004E896672ADDFAF1FA7433FEB3D6B7C95E3 -:10E7600019F89FEB2907D753E4B676DC8777707AE0 -:10E77000B179D93982E223ECFE8A521F3B4F30EA4D -:10E7800044F8FCA0EBCB25C5FE6EE8FDC52CCF7888 -:10E79000EC19764E4FBDEF2FF2866AEC51CAFB1B87 -:10E7A00022E41189380EB5E3891EEC780DBBCF2E1B -:10E7B000CC7DC79BE4B4E03C2227C677A619BDC92F -:10E7C00040CFF129CECBF21303F9461320AF4842D4 -:10E7D0007F90E7E124DC0071C73E48B21D4AC8675C -:10E7E00077C7DE80F70624108B6F1473777176F984 -:10E7F000CE6C18E7A864595F42DFFDFB986F924129 -:10E800003F19605FBB18F77D73A15D7D4FBF4F63FC -:10E8100045FBC2F53B09FD876F60B0D141FCBA41B1 -:10E82000C7F31A557FC780FB53E2EF181CA543D4EA -:10E8300051B93DA793E5512F4FEAE17E18BBC7754B -:10E84000E17013DEFF44EC2536E6870BFF6A987C07 -:10E85000317AF37CE78B96277DA5F073C9F3F11726 -:10E86000B49F18809B8D7FF4AE68D43747EF1A8130 -:10E8700071BEC0F8BDE8F7CF69569E339EB7E62358 -:10E8800005FDCD777DAE68F725F875C328FCBE97EA -:10E89000865C398BE2EFE44EC328E033BA6EF3F2C4 -:10E8A00083FC7BDF3D5913991D703E38BFC17974DD -:10E8B000F373A202CE4F5B8E60DDD7E2539DE7710A -:10E8C00029FC5251EADF20784F8E5F1A600B1767E0 -:10E8D000399ECFECF66E9E07D9CDF320BB79DE6270 -:10E8E00037CF53ECE6798A227FB45B2276384F31FA -:10E8F0005B723C315FC2FCD1DB00CEA665FE42C834 -:10E90000B76B1AE99B2BC9983FDA925F16367FB432 -:10E9100010F2DE5F797EF60D60D79F18E0C27B496A -:10E920005ECC9F7903D8F527F48C3F5E7FBEF2065C -:10E93000C81B7B7CA8F32E18E74B49F6203DBF226D -:10E94000E17E2AB1FBF4B5E7C82F6DCB67FB0BF76F -:10E95000E7B37D0C513E97CFE4D9EBBCAC96EFCE3C -:10E96000C4BC9F4D06CCFBA1DFB16B82F6FFD5F98D -:10E9700059C57F3178406E8838CCD67CB6CF0A79BD -:10E980005B30BF84FB0C2C6FCBE74D863C2F38EF00 -:10E9900003F7669043C4CEF2C0D8FD7D621DB6E693 -:10E9A000F3736770A17E69204FAC61FFD14F418E38 -:10E9B0005C97EF7C1AF99FE72F35C4BC8EE7265E83 -:10E9C000CDB7E27B74BE083F9507EB24C473481CA7 -:10E9D000AE3DBF2C34FF3D12FC2717791FCA4F09EB -:10E9E000E44F05E54DBD0AF310708B7904C6393745 -:10E9F0005D8B785220DE756726F049B78ED97BE2B1 -:10EA0000BEDA62599A574BEB6F71BC88FE9FF2F5E4 -:10EA10005C9DEAD80FF358D6CCE26EA2BD4F6AFBDC -:10EA2000CDC7B06EFB4D28EFD4DF17EFABE16DD84B -:10EA3000BD1FF142E19D0B7006C1FB617E507CF071 -:10EA4000E4AE0F1F02945F2A9C179BCF6C18C0EE98 -:10EA5000450C8D4BD3850DB2A70CE2FDE1CAFBC678 -:10EA60000CF0F711E8F73AB81FD2C1FD904E1DFF28 -:10EA7000FB352ABFB4C3CBCEF57424E9F1DC0EE13B -:10EA80007F6F41E8E1D507D8399FD52904DB617E46 -:10EA9000C00F926F2FEA85FE7BA324AAEF285D7C2E -:10EAA00063719202A06BE72AD413F265261BD0F59E -:10EAB000F6BF5DCDFD2BA677CAB89E298371008E67 -:10EAC000FC81A87F4AF97747199BD1BE1D4D5C3C5C -:10EAD000DEC2E31277ED55F865FF17386EB02750A8 -:10EAE00068000000000000001F8B0800000000000C -:10EAF000000BFB51CFC0F0038AAF9B3330E4593198 -:10EB000030CCB1666060B56160683047C8BD114700 -:10EB1000B0A9897FCB53A67F932403C31620DE06BA -:10EB2000C43B2449D7CFAD8D6037AB3230F000F90C -:10EB300021409A558381E1B51603032F903F03C806 -:10EB4000DF03C42780580528F612480BAB31307C10 -:10EB500001D27C40796D20FB8A1A76F3F9B5F1DB9E -:10EB60007F5C0395FF138DFF401DBFFE2C4D02E11E -:10EB70004B401E1BE6B3273F3E8228D03B10F830A7 -:10EB80005ABA7E6CC2C0F0CB9481C10E9AF60F20A7 -:10EB9000C90700C59E9840E34D8F81E1961903C3D4 -:10EBA0005E1CF9E20450FE36503EC61CBFFD0ACC86 -:10EBB000A87C615E4C35DF9810ECC942A872C7840E -:10EBC00031D5F38A323000002621667DD80300005B -:10EBD00000000000000000001F8B08000000000083 -:10EBE000000BE57D0D7C54D599F7B973EFDC99499D -:10EBF0006E269310C24002CE2411A2243040C09849 -:10EC00004CE0E68B041270F87829565A27E8226DFA -:10EC10004111DDAEEF2E2DC347435454D8A26BAD46 -:10EC2000BFDD812AEDEE6BFB0B162D9B049D8480CE -:10EC300068F88868B5AE6D376AD7061B6C88C1D294 -:10EC4000DF4BCB7B9EE79C93997B33930475B7FB9B -:10EC5000BEAFFCFCDDDC7BCF3D1FCF799EE7FC9F88 -:10EC60008F73C66AB111D775845C85FF1610327F29 -:10EC70002221646EF42A9E57D8492879262169F604 -:10EC8000435D33320859A8C9BE1A0F2113EC0D9DFC -:10EC9000A488903262F3D8BC84B44B3FEB9A41EF26 -:10ECA0004FA4587D3602FFDD4BC83C4236DBE99F5E -:10ECB000B4FC894BF44ABF3FF1474B98488454CB8E -:10ECC000F54482EFED122FAF6B4B3209A922ECBF56 -:10ECD000F99748152D46AADC77D593198454BA685C -:10ECE000293B7B7795952784962F25AC7EDD6E7C1E -:10ECF0005F4A765F949D70D72F070A697D5754E36A -:10ED00007B77CD6F8913CAC53C8771C01F940653AA -:10ED1000494AC687C9F4EF9BC84D57657A55C61155 -:10ED20007273942EE62B212142C613D2C2BF5748DC -:10ED30006006DC13F23CB69F2EE858DB43DC74DC43 -:10ED400019C5C457430738A1566F07BA9456A91E70 -:10ED50001BBD6FAF9E37B14723E4BB179AB3480181 -:10ED6000FD3CBC01E998C1E9D87EE1C577EFA6DF9B -:10ED7000FB6B89CF46EF5BADBE898182E1FDF1D7A8 -:10ED8000A63B08AD676FA02319EB21E4CF57337979 -:10ED90003DB984B40572528371BE13D7C7B6BA08A1 -:10EDA000B145EFF7E8A4B6591B5EEE4598CCB950D3 -:10EDB000FD1AEC6729A7E57725B2BA19DB5D8DF35B -:10EDC000D4CAFBDFA97724F714C0FB48B2858E2391 -:10EDD00074D1429EA555B4F55524417FB7EB9608F2 -:10EDE0003C6FEB53C3400FE26ECE5A5638BCFFADBA -:10EDF00017D7CEC671053718DAFDFB3E3A5E0DC651 -:10EE0000F77CF2425ACF409FC525D379DDCB9FB71F -:10EE1000069B935DF05D6F3ACEE7635BE9DFD3124B -:10EE2000D3E3B1F95FCF096A50CE6EA447DFC0C902 -:10EE30005C3A6F6DFB141F8C6B347AFE3D6F47DCC0 -:10EE4000A7FB22952E5AAFBFDF27811CA5F71132F1 -:10EE5000CE0B72D176CC09F35B4F502EFC810AC7E2 -:10EE6000F56C1C3ED903EF4FC9C01F7E5704C73154 -:10EE7000D41FE8DF34E8A71BAF4FF2F69E8079C4B9 -:10EE8000F16D774CA5FD1D2856B09E03FAF672056C -:10EE9000EBBB1291811F37307ECAF004B75981FE57 -:10EEA00077125FC803F5121CF73FF2F13FCDEB1369 -:10EEB000EDB4F5A5972BD0BFD5C40762522D6F696D -:10EEC00087EFFDEB59FFA73CB04902FA5DB7A507F4 -:10EED000AF61DECF3DF03D2D90BDA95F02BA4DBEC2 -:10EEE0003F82D77DDB7ED90EFD4BDD491CA00BF6A2 -:10EEF0005659D2E0BBBD0B2739E0BD3340059FEA30 -:10EF000003BFCF756F271DCFBE2A05FBB9AF8FD2C8 -:10EF10009F9673865C3E906B67C8C3AF3E1F946F2D -:10EF2000E5E338CADB7D998FC719D279B94D055011 -:10EF3000CE190AE135CCC7493C1B91EF360BBEB365 -:10EF4000066F8479CB18246E42E5F9E8A78B274237 -:10EF5000BBA27E73F9834FB5CC817E8F1F24EF59FE -:10EF600067C035D200ED4D837138E1BEBB41423DF3 -:10EF7000154639F2F75908C98FEAA90CB2ECD55BEE -:10EF8000F0AE1AE548E881D23ED522A5C6CA591589 -:10EF9000CAC13E2E07557D11E4132A67C72C944E33 -:10EFA000A10B54CE287FB5062C38DFCFF4ABA88751 -:10EFB000497E246B59CA70396ABBB86E36F45BC897 -:10EFC000D370FDF1FF867CEDA3E308C6D16BA23DB3 -:10EFD000216FE6F7A3CA9B2B84F2D646E52D04F4F5 -:10EFE0000C581C79207F4D1694137755733B9397DB -:10EFF0000D286F1977B2FE4C58134639184DEEF6AE -:10F00000795CE50AD4BF9AC9695BDFFBDB6C301F12 -:10F010006B08D71357DAE1DEFF00936BB39C99E5D9 -:10F0200030D5DF8DF2E9DDD94FE0EAD9518F7C4D43 -:10F030005B71A0FC2590C33690C3A2FF7FE4B012A1 -:10F04000D6712A7769DAAC4E171DF7A27EC2F0900E -:10F05000B6B713D6F1EA6C1B5BC727BF7DDB3DF467 -:10F06000FEA43519E97F723C7D5804F732CA5DBBB6 -:10F070007757F666FA7E518684EF09598FF25D2341 -:10F08000F0123CA2F253DE239179E950EE833D95D4 -:10F09000F4FB577B890F5EBD9A2D637DC7FA0893F9 -:10F0A000632E9F357CBCC7F8FB81CB240CF2B900E2 -:10F0B00020097DFEE9F9FE2976FAEAF7962B8524E8 -:10F0C00087AEC79C6F05CEA8E6F2FF6A86AC83DEEA -:10F0D00038B625254CBC585F04F8EDD5076C61990E -:10F0E000B6379097FB5C8400FEEB9FBA99BEEF7435 -:10F0F0007D92122B9FBD7C1E3EE2F3DBC7F144CB19 -:10F10000F4C03289E2A257F37251BE06F23E994230 -:10F1100028A9EFC9FDC3877025A4590DA40CAF47DA -:10F120007CDFE50E7E59A2F3D31BFEC009F37DE11F -:10F13000F02733E04ADCE310778D86CF4A040EEBEC -:10F140006DDE01388454513E9917E59309BDCDC752 -:10F15000806E257D0C8F91DA8D0C67BA185D28FEC4 -:10F16000CA82EF5EE2FD6A3D4F719A86E50CF5B406 -:10F170005A7BD60458FDF87D898BCDEB907EE174E7 -:10F180007F529208C3896CFE4AF8F77EA5F9BB80CE -:10F19000B7FD2765DF36FA9DFF724F1589A3870EED -:10F1A0004869C8AF65FD467E6DBD705006BAD0FE99 -:10F1B000CAD0DFD2DE6699E971C66725621DE97D96 -:10F1C000DEA0DF45FBADBDCF239E1FE855505F2578 -:10F1D000A26B071FC74B5C9FB4F179A20C85FD3F62 -:10F1E00046FBFFD008DF570233C6F45BC8DF82CB93 -:10F1F0004906BC5ED69F6EC2FFC6FECE57587BF353 -:10F20000815E2431BDB648E9BCFECF462FB35E1106 -:10F21000F5B6021D0B86F78B00538B7ECBFFFDE905 -:10F22000DA067F30FBE504C819E93924833C56CB64 -:10F230001AEA93D22A89E1723ECE7AF89636552B95 -:10F24000E4CA23A19DB7D82F856B006FF87E807626 -:10F25000E24091CD037A688267AFD213C36F8BF916 -:10F26000F7A2DF47B7EA38DEF6B96F6741B9A3D72F -:10F270006FCB867958E4793B7933A5FF092E772D3A -:10F280005B6BB15CE965F2C82C98973C2667F3F993 -:10F29000583AB9DEE9E0747B99AF9B6F6D0DE2F5EA -:10F2A000CDADEBF17A6EEB26BCBE7AF9790DE6AF07 -:10F2B0002B3F17D7AF5AA5598967579598D6859789 -:10F2C0003C14EFD0F2757D6B77CFA2E33E75D98207 -:10F2D000FAF9547EEE8878A585CFAF28F78AFB0728 -:10F2E0009540B7FA5EDA5DEFF0F2A5BDC6764B89C0 -:10F2F000D40CF8AFD4F7BA42A87DB4A468BF168B7B -:10F30000635A2F641642BDADD2AF56CCF124EE47FE -:10F31000A9BF1BC7B924F28EE249495CEEB4D25DA5 -:10F320003F07ED54A68F4A7DEF55E9B4BD9A82FDA3 -:10F33000F5C817838A05F8A2BEE0109F5F17CEC7F5 -:10F3400012B19E15C9B561E84FDF00F6B3AB401EA0 -:10F350000FFD7BC822235F2EF1D810CF266C7F5083 -:10F360002111902F2582F3748AD6037C719ACA31B9 -:10F370007BDECDEE69BDF0BEDD6BD37C404FB7F0D8 -:10F3800047AC37F0477DDE9C53BE22584F64C4978C -:10F390005D972B94347A7F1AD6574F943F4B397F21 -:10F3A0009E8679073E0ECBB8FE09BC2CEA3B7A3923 -:10F3B000E79122DADEE9B035EEF7812AA33CDEE2FE -:10F3C0004E36DC57658F33DC9FEE9BFD6600DAA37B -:10F3D000FD073C47421B0CFD3F0AFA0BDA7349B8A4 -:10F3E000FE9FB852D5770F940B1BFB65EE47D7E510 -:10F3F0009CC757D27A4F1D96914FABDCC67E555EA7 -:10F400007AF314E8A73AAA5F806E2FE98A0EE33EEA -:10F410007D3825BC8DF2E54B05AF27036EA0FF6953 -:10F420004B683B9584CD6F4586B19E537DEF3F3C45 -:10F4300013F0AE5D463D57F1C78E9D00AFCE16DD91 -:10F44000D709746E2512D2A9ECC20119EA5B1536F0 -:10F450007EBF728D913E1B578E33E97FA37FA9D269 -:10F46000C3FC44F37D17B1BE12F0FFD0FB0ACDE818 -:10F47000179A0FCA20A6DE32935FA8C4C3FC4225A8 -:10F48000E01712E5BC6498DEA7F7D8BEDFB4AE9BE8 -:10F49000E53BA1FC5BC87AF0A790FEE5A3E096ED02 -:10F4A000DCBF62D4B744D927C5E28A166B7332E257 -:10F4B00086594C7F91FEF4B8FE2AB31E21E43EE447 -:10F4C0002B4147E20A918C79307E5EC6ACFF385DF5 -:10F4D0009AE8745CC57520C4F18B27AEBC9BBFCF86 -:10F4E000E6F2BEB097EA4D58AF7DB20BF4C6A9CB99 -:10F4F0004403793C4BF99DB5DC7335966FEB7A9BF1 -:10F50000912F69795C064F5DF6A1FC062632F96DF4 -:10F51000F7D628694C7FC69577B31CF492D0134573 -:10F52000745E4FE5E53EBE927ED77558E8018B8E3E -:10F53000727598E1DED37D9B915F0728BF02D98762 -:10F54000CBFD392D76DDFFAF9277B39C0FC9FF302D -:10F5500079677AEBD4A005C7537949C17AEAAE102E -:10F560005CC7CDF27F9ADB6F2FE96F6A3E580F0BB5 -:10F570003E40FB987C66796776486B2FC1F6CB2EB0 -:10F58000BC2FD3917F61F22EE45CC8ED35CBFB7FBD -:10F59000919C9B9F7FD3C2717F02398DCA7F08CB1C -:10F5A000ED4821F9E0676B91927CDBBD20EFCCEF59 -:10F5B000632E3F4E16FE587BE837745C0D9459520B -:10F5C00029A937929E29C00F13267AF0FDDD969E59 -:10F5D0004CB8FF3DE9CF9C4EAF250A3902EBAFA4F2 -:10F5E00013F200ED92E4719135B309794C0EDA65AE -:10F5F0005A5EEA8DFC51A27426F7130FE0C16952DE -:10F6000030199EDB289D345A9E28E710271212419C -:10F610007A2DE542B7D4AE45D00F5F6CEDEB117497 -:10F62000C7F5638DEBC3E9B45E1291AE4E8F8EF3D6 -:10F63000A0359CE5D3609CE1EFDF0D7EABEFA9BE6A -:10F6400067E3D0DDF219C709EA07E96961F40C59EB -:10F65000927CCFC6C15B8BAEBDFEB792E8B514E815 -:10F660003873381DA53E4A3FA083F2E7AB6027966A -:10F67000BA197FC9BF5775F0D310D91EBE3E4E3F91 -:10F6800036F27E3C26EB37516443E4CA66A44F2B26 -:10F69000CCBF06F4CB20DF8CE1AF85B28AE393EBDD -:10F6A000C8265C5F48C4027A64B4F9B02A44916108 -:10F6B0001EBBAFA2DE6DE4FDB3D1E7DAECC4F325E7 -:10F6C000D7F9FA23749EC8EFD93CB52E32F2E5166D -:10F6D000DEFFFB78BF403DA17D04F5537AC9BF53DF -:10F6E00037C55B27760BFA737A99CBB7DECAC62F7C -:10F6F000CAEF92993C85AE7DDE564DC84D3C6F8277 -:10F70000DFA5BE1389E66F53388E7CCF932D7CBC6A -:10F7100021692CF2B090F3A55C49E70DC6576DA4A2 -:10F72000E30E3EAE35BCDEDB25FD7F023F4C93028F -:10F730007F075752D58DF2073C0EE5A613FD5BFC03 -:10F74000FD569053526B7C4F9F6FC7EF5677637C8B -:10F750004A3C3F26E93B65F6BE11BFD38DEF291F1A -:10F7600036C173CA2F449E0DCF3DD81FCA27C44E41 -:10F77000EF1BF7DFF165A02BFDFE51AC9F9C337CA6 -:10F780006F050591CEAED26C767D0AF88EDBA73B75 -:10F7900056EB4857956CE2F6335BCFE6F3F5CCFEBB -:10F7A00047B60E0EB854F46B290E3D1CA1D7745702 -:10F7B0004407BFF338D21D027B6CD54AD9A0E75766 -:10F7C0009BD6972FDF695C7FD76CC832DC7FF5FE54 -:10F7D0005CC37D70CB74437D6B77CE31DCDFB9BB0E -:10F7E000D470BF6E5FA5E1FBF54FD719DE7FFD99A1 -:10F7F0001586FB0DCFDD1637BE29D6BB072DEF6D65 -:10F8000008D071ED805731785189C62F2D0C8F1992 -:10F81000BFA3ECE751E6413982AE08339F2AA6F830 -:10F8200067CF90FC6C36ACB71D216F064005DDAB91 -:10F830006888FF437A775E66140F547AD6D5C75B23 -:10F840007F457F145EAE9CF454C2BCE98AB19CC271 -:10F85000E3B59AAF1FFD30E678ADE25988EBBBB94E -:10F86000BFEFCA2919A09768DD1E8CD36A635B4F6E -:10F87000471D1FD584631A1F6FAF1CC6999B785C08 -:10F88000F38BFA65E8DE58C715EDA711F78838F94C -:10F8900012569494789F417B6C09F40FD6E7228628 -:10F8A00077ECF41F5B6719FDEB78F9C0FD2E2BE0B8 -:10F8B000E34095B19F751C47513954404F94E49BE8 -:10F8C000DE433F674039235EEAE4FCA8293C5E3E04 -:10F8D0008FCCC379E072BB4CC86D35F3731057FC05 -:10F8E00038FAE2CBB4D01C6CDF907FF05A7E6E12F7 -:10F8F0007CB7A489786C149F3C38779BAB0270BEB0 -:10F900006EF5D5D2D2953EEE6FD265C4B3D7E5B3CE -:10F91000FBFA2AE67F5A1CEC463F60FD9DE16D70C4 -:10F920009DB43EA2603F4C747DCA134E436CC0E947 -:10F930009BC5E99525E8CAE928F4F8A40DC679AC79 -:10F940002F32D26B29A7A799CE4B391D979AE87809 -:10F9500014FEA074999B808E4B381EB5CFE5F6DD62 -:10F96000607A5CBBF129EE1F13FCA398D635A13F4A -:10F9700086D637CEBF8F811E079CE7E23885AF7BE6 -:10F9800089E4A83CAF614F39F8C933AC86F8C54269 -:10F990003ED6923C16EF28C99011F797B8DF88EB56 -:10F9A00067067A57CF8BF2E7D15E667F34BACFC94C -:10F9B000304F75790CE7EFE4F411FEBF56EE1735C2 -:10F9C000F7EBC4945036E0A3939742D99B8BC0FFCA -:10F9D00023219FB4CDBA379BE50BB07EFA797BAF7C -:10F9E0005C0CA1FD76B277E4F8A2C0F966BE29F1FD -:10F9F0008531CE5802FE62DA5E6D3F5D83E8D01736 -:10FA000046FE59F61402AE8E28D09F7AF75A05FDAD -:10FA100065EE0605FCCBB5EEFD95400F3F09EF7096 -:10FA2000825FCD23F92240C70226BFEBE9BF58F918 -:10FA300015FDADE90B2A20EF351EA35DE3E7FC566B -:10FA4000ED363DCFAB417EF39BF86DBBE0B3EBC928 -:10FA5000F5B17CE6E7F3A25ECCE1F21A9FCF44FC5D -:10FA6000E2DFB99FF5573C4EF72E8FEBBDB3D58340 -:10FA7000D757B6E6E3F3E35B7D78FFF6D662BCFFCB -:10FA800039F879E9FD1BDC8FFBFAD600DE9FDDBA81 -:10FA90001AEFBBB89F56F0F12E1E4FA996DBD0BFD0 -:10FAA00058E70BDA5D31FC54C7FB8DAC0F38A4204E -:10FAB000BEFFD536E58802FC756E484E08EA8BE538 -:10FAC000F5DE030F51BAD8BE4D82802B6D1DFFAA03 -:10FAD0004CA5FC5F57EBB5AE83F642CDCA1CE0C720 -:10FAE000C8BF2AB9F0BC7E96F58E38ED8B7612B57C -:10FAF0006FD66F2B6A8D76B05FF8D1FB832118E744 -:10FB000084FE6004FAE777AB9E787EE1F689EBDC51 -:10FB1000C04F8D17836EE0A7C689276466AF337F19 -:10FB2000B8CAF95494F7BB8DF17C95F7BB8D3E872D -:10FB3000FEB6F58F4D0E44B952A559766989C7674F -:10FB4000F637ED94E2DBAD4956866B9D3CBE4A75B7 -:10FB5000A60272062C0AFD9F40D906E44BD398DF1B -:10FB600022D917E47AD9B88EA7150702A097B40C4A -:10FB7000E2AB01F5A6F5B8816FE4E285E7619D256A -:10FB800005317A1BEC1EB3FD1F7B2FE3D2154A49CA -:10FB900087ABB91CA3AFC659A86916EBDFA3DCCFAE -:10FBA00021E8AB71FA96784EFE02F4EAA33EE68FA6 -:10FBB000793483C565078AD7222E2BE176818DECB7 -:10FBC000C1F249A419AF3B38BD078ACF11907B59C8 -:10FBD000A1B83903FA630F87E8F74E937E573423B1 -:10FBE000BD254A933580AF7B1583BD2115333D6F0D -:10FBF000077B1DEC188E5FA2765E905C05E28F118C -:10FC00004FEDB41AED3171ED552CC80F2EAB299F75 -:10FC1000EEFF7AFA9DF842E927ECC4219C77EC6B61 -:10FC200004E231229F50947FC5E46F52B3591CC641 -:10FC30005CEF2D5646F705568E8F059EF09BDB71C7 -:10FC400084809E2AB5A71CD2F07A12B5477A678FB6 -:10FC5000E2B7DE86ED9F555CCC9EE0F940D42C9750 -:10FC60000CF6895D77837D38EC7BB7C520A7C3FB95 -:10FC7000CDE8F345F777093548E1BA54E8E1628603 -:10FC8000279779289EA47F2ED3189F9E2997C2DBA1 -:10FC9000914F7583BD555B5C731EF512B547D479E2 -:10FCA0001CA7D3FE3741BDB49ED7278AEF86F489BF -:10FCB000E5EACCE1F504AA18EE21A17F5914EB3F47 -:10FCC000085076C99F0DF5B2EF69D1F6ABF1FAC1D4 -:10FCD000F556A0F8DEA59A13EE75E949C07B05310B -:10FCE000F800E89A6733D2D9A4FFAA86E93DA3BEFB -:10FCF0005D48F9F7086DA756DE540F2EEF9ABD6BDD -:10FD00000FBF8ADD117688276EBDA7E08F9B01FDAE -:10FD100019F10AF1B13C8ECA90A71EE99E2191B05B -:10FD200017FA6FECC7C26C931D96611EC71E9CC765 -:10FD30000E85AE2374BE3AE83CEE41FB38BE3D254D -:10FD4000ECBC05DE41B4A784BD47B8BDE7A2FF62A5 -:10FD5000F158192F5F7EBF4701FC5B6E37F9998719 -:10FD6000F28F09DA530B88B1BF65DCEE2B33D97DF6 -:10FD700042DE5F14FA52D8B55C1FDE22ECA9B291C4 -:10FD8000E3CB9DA67CBA2ADAF1E66B900302BD8232 -:10FD9000781319A29381BFDABD539B2394AEB7F8B1 -:10FDA0001C2CDE42FBA9087D8E7462387B292F7FD4 -:10FDB0008B4745FEF76B2C7E513F8ADFC25FCCE25A -:10FDC0000667ED125B0F42E44D12931F5EE961FA84 -:10FDD0005A33F145B627500571204D917C61329C14 -:10FDE0005FABB83D07DF6FA1A4A8CAA336F9EC78D2 -:10FDF000F9E5DDE05A2565B40F4F7913CFAFEEEB8F -:10FE0000AF84E919EBFC1213CE3EDBFF3EE6750D25 -:10FE1000144818F769F77E8AF68188EF44E977027B -:10FE2000F351FCC59FA0BD3294B7C5EB5B2AEA2B0A -:10FE30003E86F19AEFB88E25433CE60CC471E9F793 -:10FE400067947E0DEC9045025F518A46043DBDD11A -:10FE50007C9308B7ABCEDADF4806BDF912C7F54789 -:10FE6000FD726D3C3FE70299F999C5F54695AD3BAA -:10FE7000F35486E7C4BD98DF217E924F15313BFCD9 -:10FE80006F0DF36EAE1FCAAF46FF60A460247BB453 -:10FE9000DE44E7292A5FF738DE180DD78A719AE920 -:10FEA000601EA7F93BA7CAFC65775AF5E9EADC684A -:10FEB0003B62BD33975F96202FA7BCD8E89F5C704C -:10FEC000D9989773A73558A2527A562AD2CE540F92 -:10FED000EA3594A78E2B1AE29881FE8E9D30ADC72D -:10FEE00007997FB48CC8611B5B17EA216E27E44633 -:10FEF000F0BFB91FA3B55F36D883F678F9E5FE2ABF -:10FF0000E0BF5BFCEDA8579750BD3A2E8E5E5D2892 -:10FF1000F7ED1C07F2EB63FB3BCEFEB2BB0AEF35FD -:10FF200009F361F5B25C651CF0812BBEBF6A3EE748 -:10FF300093E1F13CA1575D0AE006B3BF6D3E97BB6C -:10FF4000F9267E08AA4338E8A6ABB9A3CF53227E90 -:10FF500018E81FB82F9E1F555C13E55DDD4D4CF46E -:10FF60006D33FA9FCDF5087F1091DBB2419E85FD80 -:10FF70006B2ED7A4B2B8C7F1C2BB486C5E95D00750 -:10FF80006A71B3067EF1AEE291D70B733E5C39F431 -:10FF90003786AE9576633CF609457F10F8318A9333 -:10FFA0001A98BD5ADC80F6EAD202BE2FA8F02EB411 -:10FFB0004F855DDD78F321CCE712F95AC23E35F763 -:10FFC000BB6BE2F398CF335ABF851D7FCA26B33887 -:10FFD00004B5DB3D68B753DC17E7BB576C8C5E3F5D -:10FFE00055F4FD20AF3BADBABB01E28C8536DFB3E3 -:10FFF00071E6A1D7C6E4BB2B41BCF55710F8988B2E -:020000021000EC -:10000000E3403A98D71B61C78A7D4A13DC4C6EEBFC -:10001000B81D5B5AD080F298E6A6762BD0CDC7ECFF -:1000200056D267B453976ADD5930FFE6F54E1EE4A9 -:1000300076ED18EDD65D0EC6474117B1BBE97B875B -:1000400042A1295DFF1E972B8E013D76A511B407B5 -:10005000CEA4A9E10371FC0D6F737EAB963718F83F -:10006000AD8CE312B5AA47037FC09941E6C74B3474 -:100070006F0F99707A4E3E29B739E1DA5F0EF4A01E -:10008000F7BA0DAFFD989FFD70E1BA9C78F51D6839 -:1000900052E2AE4BBFE3F3B65CE46BD7327FE4DDF4 -:1000A000052AFA8527D4BE7702F9B49EF3E9121B1C -:1000B0008EBBAB50C179E9BAD9DB0C71CDAE423BF6 -:1000C000E6A3B417FEEC9790AF5D562C19F24B04E3 -:1000D000FF9601AE86FAEDCCDF79B79BE9E12E8D74 -:1000E000E3179E37B291CFE999C31F3863F34656A1 -:1000F00008BEAFE77E72137EA26A246E1C47E4211D -:100100007F5CCFFCC2778BF11E39B413E4AE8EF363 -:100110004DFBA5756E94CF232C3FAFB1B001FD45CB -:10012000ED13DF52E17EA3FB4315EECDB842CCEBDD -:10013000DDC53F65F9917C5E37823F9EF2FB4B99AE -:10014000D3AD1E7ABF3C72B315FC9DC23F3B2C0E53 -:10015000C5E329356CF8A4C6CDF0F589CC6492943A -:1001600001F492C312D02DE22049907FE6B6861D9D -:10017000F4BE4EE99902B825D984173F7EE1503686 -:10018000C8F7F119BF55A0DDEB8ADF6B84714C2AEB -:100190003E84FEFEAC23873AD3693D4BF3894FF78B -:1001A0000CEF4F355F9FEECE60F94277FBC221D84E -:1001B0007776E10ADB4F51F1C21B95B0AC0D8FCBC6 -:1001C000E804708888EB286E1E17E1F10972E5AA31 -:1001D000143B6F754AD00EFAB7B1F80D27F4773992 -:1001E000A75BCE61B901F8BBEA85395F013E2137D3 -:1001F000DB5CD7D3062FB87EEE9CAAB1F777B17A35 -:10020000E70769F9BA8243D9EB0A87EB9721F92905 -:10021000F8C3D620EDCF99453FCB06DCF606D5BB1B -:100220001E6897EB2DB3BD645E57CD7931E67167DB -:100230002ACB6A6D7361BEBFEFF6C6F019D5036BAA -:10024000A1FF1B9FB4631E57DA91D75519F41BC544 -:10025000EF3552948F36723EAAD398FE6B2C24E170 -:10026000ED12F0DF87F5A52077AFB27CC30947DE3A -:1002700063F9A3A6F5A18BAF1BC2EFDC35F17D942A -:100280009F8F0F73790959A4587F9256DCBF12E6ED -:10029000C52C27E27E7E7F4FDCF5E15D1BF79B0CD2 -:1002A000B2F71AD5DF10D736BFF7737BAA0CAE3181 -:1002B000F5DC6763B8575CAF210FE1896F53F96FC5 -:1002C000DFDDE1BE03F59486B87DE39143F910B319 -:1002D000C93C7CA88AEB0BB4CB643ECE09C4837ABC -:1002E0006AA96667F103139F5B8BF747003E8B7526 -:1002F0001A0C722533AA47E4583F441C3B8C84F403 -:1003000037F362F2BEE8FA4E40AF54BA99FFD5CC4B -:100310002769C554EFE024502E8C89FB9AF9B64E1C -:100320000BBA219E4DE5E73C8B7FD2F50AFC137298 -:10033000BD0FE793F3A785FE83F52FD967E44F6BD5 -:10034000BE6AC02BE67EFCA3CD88FFC5FA9CE6EE14 -:10035000C1FE2DD59AB3A1FD09EE1EB4B7A87ECF7C -:1003600086ABE033A1AF87F8AFF0A6C5A0DF81AFC1 -:1003700021447EA6784E12E8C13A37C329C4E44F1F -:10038000EF728F6C6F749AD6BF332E665FD515935C -:1003900024572AC83BF33B753D92BE3F39C62FF721 -:1003A0004FD6608B2DC6BFEE2CF8D2629713F40C9B -:1003B000CBDF2AA1EACB9A1BF5670ABFA988F70908 -:1003C0003FE9307F66413BE6775945DE058FFF0DFB -:1003D000CBFB4910771457E1CFB46D6F567C3C5E70 -:1003E0008278AC9EFBE106678FE20F65FE078ACF3D -:1003F0007E6E1B3F3A3E3BC8EDCC5E501EF4BADE2B -:10040000E6C2AB06F928B4AB5D8EF8B8ED656EB701 -:100410005D8B7C9E94E13BD6CE4726FE12CFA3781F -:1004200098C9C184E2439DB178B8AC89D286CE9395 -:10043000DA44A690D4C47CB77448EFFDD4C05F43BF -:10044000F878145C2CF8EB92ACFF19E898A85C1DC6 -:10045000EF47A2F78D85B6D5906F45CB9109A9ECF2 -:100460003A8D5E3B671CCAB6D0E7AF01FE8AE9470A -:10047000D7F78EE0387EA5B27D365D97D6E5003E93 -:1004800038ABE8A9F6F163E71FB33CD9E7EA9E6D04 -:1004900054FE8E66DB717D3EEA6638E4752819C32A -:1004A0004F9BD5E075F6B9A8EA7592CE959CE0739E -:1004B000509A5563DB27767B72CFFD81185CB91BA0 -:1004C0005E4D84381FE39B07D51ECCC7B99DD66E01 -:1004D000A3ED1CD3E4CCB5F47EB69DF1E3B1903529 -:1004E0006EFEF36C3BC3CF9BD5C06CE82769DE84FE -:1004F00072D620C901907FE21B9B7F6E474BFCBCEC -:10050000D2CA68FDF3B1FEC3B47EC00D3EEE7F27B4 -:10051000AECCB8FE763EEE0821B5202F8FA619EDA1 -:100520004DBF9DAD7BF3A3F52F8EAD1FF3B3E6E278 -:10053000F32538CFCFB1E7F9762617E5B92CAF4DC3 -:10054000D051D4BB325ADF4AACEF08FB2ECFCEE3FA -:1005500006BCDF02E79BF39F163AD87C44E3A6046F -:10056000F56689C6FCF513FAC3C7E0BE9CF07D9919 -:10057000D2DBB87FEFA8D58BF900ED8E694F6FCA3B -:10058000803C0923AEB7719E51EC3F946371BACEA3 -:10059000714C49760EE2E10E923BA29D237087904A -:1005A000EB05C27F7AE500EE176BE1DF8B76CB4D72 -:1005B000B82EBA5FB11BF72B4EE8EDC6FD89152E9C -:1005C0007E5E44DA37D1BEDEE5B897E1F9C99FE235 -:1005D0007EE505D907E5787E4245F45F7903DB3F88 -:1005E000EA62EBD402815F4D76C64B995D32E0C87A -:1005F00044B8FE84147C26C2FC9A067CEF8F7C6D86 -:10060000C3214A57BD97B81CF4BE24C2E24C151C46 -:10061000D75728E12C581F6AB2993FAAE54FDD59F8 -:10062000B03E1CFF3413D78BEB94FD38DE498A179C -:10063000F1FC4213FEAFB01FDA0679138B14898CDC -:1006400023C3FB05FBD5C08E2871B3BCA0126AC5BD -:10065000819DF1326D1FFC65157FA2F3678987EFDD -:100660008D38A5562927AC1CC7FBD9CCBF341A9EA0 -:10067000AE30D903625E2B943D556097B4809D41A6 -:100680001FB5283B9474DAAF5D8304229BC4CFBFAF -:10069000CBC9B630FB60B2650DD08D58997DB0CB1B -:1006A000F5D776B40FE87BB00F2AB87D5061F7A27A -:1006B0007D301A8ECFB1333BA1FDE254B49F228E20 -:1006C0001F66817E16F9E402DF0BFECB54CA4F8011 -:1006D0003C2FE07C28F0BE4DE0FD2B9B089C275072 -:1006E000A118F1BE8DF35905C7FB2D10F7027E3D11 -:1006F0009F79CA0BF11881F7AFB898BF9BE37DB122 -:10070000CFB203E43306EF779C1FC0BC8597B39943 -:10071000DE17787FC89EFC8C78BF4CE80F8EE76BA5 -:10072000386E10EFFBB9DE33E37CF3FB6BC5F98465 -:10073000E3F8283E36F26FFBEE1C8CAF94B8EC6801 -:10074000072CE80D0EDE4BAF995736FD662FCA51C8 -:10075000B20F3EB3713B6CD43C5013EEA776C34E40 -:10076000D87F539EC7F28ED2B25D55B09FBDC223D3 -:10077000A1FF69985C98ED806C17DA69954A83C887 -:100780008F1B11EF57682EC4DB8A523326BC6F963D -:10079000AFDA3CDB887C9DED30E617940BBDA9DC1D -:1007A0001B42BDA9DC1B01392AB7737F8FE36FDCC5 -:1007B000B1E73AECE2EB81D0D3425E3B1CD39460CC -:1007C0000CFE1AE26B25578BDD5FDCC1F9F2078A5C -:1007D00007FDAD1D76661F98F1D850798EF72B383E -:1007E000DEAFB033BCDF311CEF173B62F09BD3CEE2 -:1007F000F0FE58F30A841D5B63B263DFB71BEDD8CC -:10080000447CFD215FD7A3F4F4325CAB7811D70AA6 -:100810007A2A1CD7DA004FCEC4751571AD90E3610A -:1008200074B5E61A706D39C7791DCA9871EDADB10E -:1008300074315F2B46C1B5BB1C14D76A580E716D5D -:1008400085C0B5495E03AE251AC3631DDFCBC771F2 -:1008500074A4313C6BC66389F107D76F265C21BE57 -:100860006F4921D9E89F1BC225D3E2E2924438C4E4 -:100870003CAE16C025DA5F029778709C663E3F9AC0 -:10088000A2A39D1FC529BFFDC6212A87BB2E123CEE -:100890005141E0157FE48FC71A8A102F1087273A3D -:1008A0004E8157043E11EB638BC2F249057E49E449 -:1008B0001F15D76BC52F2732FF17E21E336E117835 -:1008C000C55C7F8795E199963FBDF59F8A6316EEDB -:1008D000A7DC47E5A45CD9867AC9AC075BC05B4D51 -:1008E000CBBFEC22E110D4FFA773727A1C7D6CC6DB -:1008F00033669C32567CB328EF22E61B8E863B3A49 -:100900009430EE936F51EEB3833E32E31A333D736E -:10091000B24903C40304DE49C4C750EE2E6714076E -:10092000252A47F538E2A384F5D82F5E2B2E3AEF1F -:10093000181117313D50E1667A20115ED9E57369CF -:10094000B179AC627D69CFCEF925EE37EF55F1DC98 -:1009500084F6F353519F26C24B6D26B9EB003DA29E -:1009600045D7AF8474E91D407917B86A347D21EE0C -:1009700013E129B1AE9401E81F9F386E392589D95A -:100980007D0FE6303BDAFC3E9A8762C45524A31003 -:10099000F9F81EBE1F3311CEA22B9893F9AF42D89F -:1009A000CE2A6E87A2CF701ECF43A05D0DE4913C8E -:1009B00058270276263767E64A2837CBE0399DD795 -:1009C000F22A16373A5728613CFD4CB90DE7F5D4A9 -:1009D000C72C4FB13D85F95FCFCC72F80ED02E7C7D -:1009E0000CF5D275F99CA3BB0870C0AC24EE2F485F -:1009F00067E35C921CD98071F339D32D21EF7079B4 -:100A00007F3089F7235DC3F85B1DC7A3103FCC9AE5 -:100A10003D7C9FC1D3495EAC1FF2E7B368B99D9698 -:100A2000EE8773E8238785C55BCD74FD98D31D08D9 -:100A3000638BA1437D9E5D7750FE77DCC8E256470D -:100A4000AB6C98A7E380103BADF7A1FC9C9478FCBD -:100A500021C6657EBE9F8FFBDCE47E5CDFCEF2BCF0 -:100A6000DF8D8A14027AA3A22E82631527ED7F8878 -:100A700016FD4A521AF6EBEC0BAF23DF9E4EE374E1 -:100A8000D025B4D7CE78983C855C5A18F66BD2EF57 -:100A9000ADAB46C807E92EAFC9677134422488AFB1 -:100AA000C11F39C3E9BDA256C671AF70EDBE17E4D0 -:100AB000F15CED1BC9702EE5D2410B01B95BE12A57 -:100AC000B90B9EB7A7303E063A038E5A51F5A56F73 -:100AD000C0F3FA7AE37C9C4CCAC171942A6C3E60E4 -:100AE000FEB2660F6F97AE7E41353386FEFE9FFDE8 -:100AF0008D14B3AE887C167B82FCBE44E39662F50F -:100B0000AE1CF5474E28DEBF07F6CD048AD879180B -:100B1000751E1282F86F9D8F44BC9CBF30CFA633E8 -:100B20008FED17E2F29556BCBF2907FC97830A8B1D -:100B30004B9BD691523A57D9E9E04F67F37366AEB3 -:100B40008C765E6931C3F9A51CE7D7E90D18EFABC8 -:100B50007FA473770EBC97B3ABCB3D3C6E1A433F7B -:100B60007284F9E79699F83CC5E4FF2FF599F206EF -:100B700079BEDFD1FC675CC03F0FA673FE992DA143 -:100B80001CBD2E791E01B910745A9224E233C4633D -:100B90008DE18F217EE0F36BA67B227A9AE964E6F1 -:100BA0000B33BDCFA498E89580FE89E85D5A5CFEC2 -:100BB00017A5EF05ABCD0A7CDB6EFD6D36B78F88D0 -:100BC0001CA34FCC74BBA07952404F9C1B3C87B8F0 -:100BD000EDF464CF57F07C2C2AC778BE279787E8BE -:100BE0003C507970C6CAF3DB53409E299F59A19EA1 -:100BF0007A5DD21D207F8777DD8BE306397546E568 -:100C0000C84CFF61F247FF57447F7387CB91399FF0 -:100C1000ECB3CADFB7409F53BA2D4CF2E055E8D38E -:100C20007AE2FA4AECFE5611676FF73606605F7A91 -:100C30005DAF05CF016A197C5E590BFB5D6B255CCE -:100C4000D634D28DFDD59A58BEC4D4A71E2090CFDD -:100C5000FEC864E2037DA535B1FC09FA1EF3270442 -:100C60007E17E73AD2F73ACB17319EBF94E233E6CC -:100C7000FF2CEFAB403BA2939F8724EC0491F74AF3 -:100C80004CFB5E1AE1C9C4E8FE90A64B616647249E -:100C9000D80723AE667BC17C3DDEF1CFDF003F622B -:100CA000599E8A7EC4B2C1881DEA7BB8A0A316F300 -:100CB000DC6A2517C4E38E7FDABC03CE415A5EF0AE -:100CC0007E5C5CD27AE1091F8CA3D5BAC7970EFA75 -:100CD000613B5BB71CD30A26AF1D01F7046BCB6BDE -:100CE000BD3312E799DC93CCD7F7F6AF1D7810E24D -:100CF000DE7DAA0FEC97C53CCE5FA7EC59BD96CE22 -:100D000067E722C9B78D3EEFBC61EFA60E88639CF2 -:100D100057D1DFD775E96036D819AF7DCF8EF6E8A9 -:100D2000F14F0F3E8D79267DEA3C18EF50FFAFD78B -:100D3000D8FB8F5F3C097A6679FEF22268C7A190E2 -:100D40003DC04FD70D36BF0BE725D4F5AA7341FF41 -:100D50002CAFDD6FFF2BA053ED4FEDD783FD31E8B6 -:100D6000A986F9BC2E2958994CF55E5681F73B1996 -:100D7000D08E8FF874A46B3701BA8AFC04610F948B -:100D800071BE6959E44D2131743D3798930274CE98 -:100D9000A9E5790C8BE400D8CBE75CD7A7A07FB29C -:100DA00096E52F98E9B51C707A2AF4CF3B795D9CC3 -:100DB000F53BA7F60F5B83E00FBE81D9E7E6F77737 -:100DC000707A3B7EB7EE008CD7F17DBB0BE0B5238C -:100DD000417EE6D464AEE7DD63F397083C43E96AFD -:100DE000B7C6F80129DE5F9F1C1377BDD6F6BF9A00 -:100DF000CCF4C02539B819E85FCAFD2565DC5F92DF -:100E0000A85F25A3F831281F219D96831F6326BB69 -:100E10004EA3D7CEC5DEC9063F06D1DDA067CF41C0 -:100E20007C0EF098B26C3BF4A3EB02F36724E2DF94 -:100E3000E579076FEB88D1775D563D1BECDCCE1B67 -:100E4000DECE82F9FFCFE2DF213EABFD69139CAB22 -:100E5000F550C1F2F1A0FF62F8F869988F6BE56375 -:100E600033FD5A16E5A6102DCACF828F87F3A584CD -:100E7000F6A8E0EF44F301E5C01E157C9EA8DCB99E -:100E800045D3E2F27FB49E8B23CAC16ACE57770066 -:100E90005F8D07BDACBB400F2FCC7A17EDD657B88E -:100EA0003E1EE29394EEDBEEA17A27F4AC1DE3E85C -:100EB000472FA978FEFAD167D6FF00D68DCEC10A9A -:100EC000D787B88E97BB56D07EDD00F64301CE4F54 -:100ED000A712E337BC902CE2E6C67CDF9FB87E9376 -:100EE0005ECED659AD9CD27B265F276EF43E93042E -:100EF000EBF94CBE9F62469B1A775DE61082146444 -:100F0000BC6E01E85F70D8584E1BDA9FDE6C81F82A -:100F1000E08DCF99DEF37DD5E6FCC87F4F36ED7FBF -:100F200032ADB7F64B23E769FC0BB77B9FE3F9BF04 -:100F30003FE1E70936F3F3049F877DAEF47A18F6B4 -:100F4000B9D2E72FC23E577A7F84EF7325D9633B2E -:100F5000375E9CF7A4723A344D0C1BF6698AFDDFAC -:100F60002D709E12E001B7CACEA17351B405792A43 -:100F70001C2F5A92FD7615F6737D44304FE5AFCFA6 -:100F800077233FECE6EBAC19C788F31ECDFD52A3E7 -:100F90007454C04F7574727075A0804F18F0CDDC1A -:100FA00009FB1F8AC1D3A91AB32B1BB9DD16BA449A -:100FB000C2CF4AD1F2A72F91830F313F5B4806DCA5 -:100FC000017F51165EDC4B10C72D2EDA85F617E037 -:100FD00040C06578FE580EF8BD5E443CB77870DEC0 -:100FE0005D0CB7E8C370DC10DD64A413C3E745AF44 -:100FF000A35F71716F7C7E8BE637ADEECC8BD9979A -:10100000503F18ACE7F8C8157B6E826AE22B733D3F -:101010006945CC7FBF249FFB7B783C44CCE78E4D59 -:10102000DDE82FEF2AB279C0BF60C689669CAF1693 -:10103000B17D64CACD6C3FEBE24B2C5E880C9319FA -:101040003D9F4DE579BE2DAEA00FFC98753E13EE89 -:10105000E5E74B95E51BF1BC19EFABBDAA09EF879E -:10106000D87AB89DCDE7998F09DA51CFEE63FE812A -:1010700056B787F11F09A3DDB3C06D99F59007E25C -:10108000566C7F66C920417F4949AF07FD4F0BFA77 -:101090004864EA0C3C87B809CF1932D16F01B87A9D -:1010A000D3A11E4FE7784AFF050AD909E7CB64DAD6 -:1010B0001B749003D5BD09F7E3407EC338C647F6DD -:1010C00058FAAA49A77680082CE07E35F1BB1513A3 -:1010D000EC87900F62E66FC4F898CAF94EC4BBCA99 -:1010E00079FDE57D2CDFCDCC0769F68BEFC239CFDA -:1010F00015831A9E036D9EF7E171B0FE0F1E8338B3 -:10110000CFA524DF7698673B9B67318FAADC26C387 -:10111000FE0EA2B0F912F130B37FB5D4B46FCEDCBD -:101120002F715EC256CDB48F8CE3F80ADEBB26C7A2 -:1011300021C3B9B5155CCF0CADDBF65C1ED762E7F9 -:101140009CB6F6CD1E31AED5EA62E7FE11D7F2515C -:10115000F4DE76B68EF0F3054A8B4912E09CD23E5F -:10116000C2F8EB114B38D91B5B3E6CD857EEEC5BE9 -:10117000B518CF6974B9AAC0CF564A58FC52EF25AA -:1011800018CFD4C9213918332E112F51B95F4C957E -:10119000D8B8049DCCFDBB7DD0680F7D2564DC0FE5 -:1011A00071DB03C6FD1BB76ECA32BCAF599F6B78AB -:1011B0005FED996EB8FF92DB787ED0FF081ACF0FF3 -:1011C0005AB1BAD2507E59C0787ED02DB5C6F383BD -:1011D000EAF4DB4CF2AB1BF8FBA8D4FD5D18BF258D -:1011E000F997B923F979CB468B2387D879426807D9 -:1011F000C689B398F7BB7DA409BC609483CE5039EF -:101200003B6FA7D7B3AFDC03F12A9F82062E3F576F -:10121000A89AB072D56E166FA9CA886FCF0B3D68B9 -:101220008E4F8873014BFBBA910FCA4CE70096B8FA -:1012300017C63DE7F33F34D3B91809CEBF18B67EC1 -:101240008F757C3CCE34EAF878BB25A4FB98D39B01 -:10125000787C631DD7507E179C4748E9D10D8F26B7 -:10126000B2F71A95B79D69F978FE4586BD424919CE -:101270001FF577127DCE98F2D1DAB91F9FE82BC601 -:10128000749E6986DDC3F84267F868A7A487E1FC0D -:101290003C731C55CD177154E339188E9D442FA013 -:1012A000240A55108CEB8772ECE11D12E493B37D98 -:1012B000A68D375870FD69BCA8EF81FC94A61B145D -:1012C000DCE7582D6B585ECD66EB931F72EF217FE4 -:1012D000E2357DB5E1FC0EF77617C889FA347B9FBD -:1012E000683C6D13D5D5F1EC859B52181E3AAB04C2 -:1012F00066A6207FE86E168F08E37968222F3751A3 -:101300003E2E058E2EE44322F0019BBFEF403C258C -:101310008EFC56A53039F31748612BE497AE246153 -:10132000EB0876659BDB12D79F5198C2F359AE5CF0 -:10133000C573EE5471EE5E163B77AFDD749E65218A -:101340006FF7788A9DF181F7A021DEEDE7F2B0D842 -:10135000B38EC4E25971FE8FDAFF3EFA99CE8C72D9 -:10136000FE8E886FEDE6FB9A2B2F5902F1FA3F9023 -:10137000A2209D9ED5AC71C7F700EF6FDB141F9EB6 -:10138000B7DAF8B8859D17EF6E9C84FBBE53FE8AD2 -:10139000307F17EBFF622EA77E777807498138F5FB -:1013A0003B4FC2EF87A8C536F0E591333734E0797B -:1013B000B1BBFB295EF446C797C2D71BFFBE8EDACE -:1013C0005CC0432765F4F7D4F4B27CF3A5C5FBF900 -:1013D000392D3DB88FD1FCFB2525B5411DD6E5A59E -:1013E000F5911D887F7C9E72FC3D13E2DB86BFAFCA -:1013F000326CBFA586B8AB6D90F17DDB8F7CEDF8CC -:10140000FB206E811BF5FAEACCE8B96165173B76E3 -:101410004208C67C6E98F9DC216197A9265C29EC0C -:10142000B13A123EA648C3FDCC89ECB1BD29DC1E01 -:10143000BB81DA6374FE6FB7B13C5BFF16A9188CF1 -:1014400046C7166922E8AFA7F83CBD5916C4F35B3E -:101450001A13ECBFFBDF5CCEDE2C8BE03EA7366FB1 -:10146000D0ED1BA17C610ADB27A85E61E77EA87630 -:1014700096D73574E5F93082AFE7396D782D75323E -:101480007B7BC1D5E7B2465A3F4BFC4102E3A1FA50 -:10149000256EBED80BD03EEC178CB0F32BD4A6F73C -:1014A000ABE2C9B390C3CD6AE067A03F764A9BC266 -:1014B0000ED403633FD772A6FCF9F5CD554D3F918D -:1014C00042EB7DCDFA0F1E908F1D41E3EF4E89EB6D -:1014D0006B5AD08EF477772483BD7931297836859D -:1014E000FBBB617F615BFFF376D4A726BA9BEBB9A8 -:1014F000CFC9E653F5B0F7E417BA67798C9FA4CE4D -:1015000029F1F5437F07EA9F6DD5FF0DAE0F56C455 -:101510008F43662A15BF06FA556B811EB8B6F51FB4 -:1015200040FF714A92FE1EDC9729FAFBF0FD3F59FD -:10153000F50F989EAE727D981FDDEF90689E21702A -:10154000F1617E2CBD3E1F9D33EC814136CF7A5038 -:10155000BBC67976D2EB1A585BE8F73D65F1E3ED4F -:101560004F717EA27286F982623F8CDF4DF478EB78 -:1015700097284FE75F7562BE7B2800FBBACE4CB25E -:101580009003317A4E9C63D0D8CFECC281FBA50387 -:10159000CC2E2478FFA3AF790F407C77E5142EC7BB -:1015A0007C3FC61DF71BF7498B766F4E95C6249F6F -:1015B0000FF3728DA94C3E1F4FBD46F9CC60F50864 -:1015C000395515765DEB62F57E98CAF82C294D12D7 -:1015D000F9E9F94E26873D29D7363F4FACC8FDFCC7 -:1015E000FC21E441F519F3F51EE1F220F415ED6755 -:1015F00019CC17ED6730E9DAFA9959F205F0B1D84C -:101600009720274B067F78C0C9F8E90EDEDFB38A42 -:10161000BECCC9E477B97364F95DE564F2BBDA69FD -:1016200094DF5B9D4C7EBFEC64F27B9BF373C8EF51 -:1016300047203F90E7C8FDF8E49451EF505C7C17D9 -:10164000D4BF5891F83E6FF21B29C6FE58DC1B240C -:101650003A5B2C9F89C50D14BFEAB8AFE34D637D9B -:10166000EFF0758BEAB1CD50EF3BBCFD1DFFC6E836 -:1016700007747C3E8E5C0A3ACAB60637EC8B4DB4D2 -:10168000CE059C6C9D2BB7B17D17E4246DBFD03087 -:101690009E6D40B7A1F184A865177F3CA1B8E3E92E -:1016A00036D617339EDD50AF18CF82ABA74694478E -:1016B000BF904757448675DBAFC45F17CE38D9BAA1 -:1016C0003990AC3F09F432F397B886397F25DA1F99 -:1016D0007356A90843FF4A14A6078916E99163C601 -:1016E0005792DF20C61DB4C4FAD97AE3EBC9E79C50 -:1016F0004372F71CF2DF3EB69F87F2F58FA19DDBA8 -:10170000C7B956E1FEAF4F98DE7CEB4F5BAC69B4D6 -:101710009DD5197BBF03D75F3B59DE4BC3C51C2743 -:101720004C434F19DB17D938919DA7D62819CF55AF -:10173000FBB59077AEFFAE41BEDFCA913FBB7C7C6C -:101740005EBD40E9D3CDF5528F23F7DAF4D2DC2F1A -:10175000A0FD955308E2E3C6FD2A9EBF25E4E67688 -:10176000985B760E820E79145FA5F7167A3F0846CD -:1017700037ED47309B10F76C2C1752F19C04BD17C6 -:10178000C651ADE9E7E14AF5D04770A57AE8775C44 -:101790000FF57D1E3D7402C644BF6FA23CD40D7C84 -:1017A000A88479DE2FB747F8584BF28FC5FDBDA945 -:1017B000B6DE035A08F206F3D93ED544ED46C0DE44 -:1017C00080C49504BF6725AEE58FAFB58311B083A4 -:1017D000E23AF0A3BECCED9436685F83F62CF8FBBA -:1017E0003FAF1119E3F0E6FA1A27F3753F85F3F3DB -:1017F000C475685FE9578CFEB54A7778F7EC22F834 -:10180000BDB33BD83EAC2B77905585804F8204CE3C -:10181000E154E915F23745BFBDA953193EE5FD5422 -:1018200089A42C2C88EA91CA7E12595084F806F3B8 -:1018300066A11E0FAF275808EB7D9A02F1BED712A2 -:10184000FC4ED3E372303F35C6DF584E8C7885CEE0 -:10185000FF0DA9E371FE6F4C65EBD074B8D2F92F80 -:1018600080EFFA9C4CFF3D2E0766C2F360060B41E9 -:10187000D3F2BE54C62FB352E77E7E3ED941D8EF95 -:10188000F202FFC6C6AB9FE5FAE1E8F8A00EED5400 -:10189000FD6859E724FAC986E6063CFF78C175FD64 -:1018A0009F9C85FCDB2C15E3818D8F18D7911F72CF -:1018B000FCF3D2B5EB19C41154FF2D81767710A635 -:1018C000FF426EF6FBA30D13731E65F0911A9899F3 -:1018D000D1736DAB5CCBF0DCAEAF3FE79D0DE76045 -:1018E000A95C3F2F74B7AB6B615E21DF348E3E0F76 -:1018F0000EF58F6A6FC33A15FFFC97CD1C2752393E -:101900006E4865F2BB16E6E785F1FA1DA97F41FC3A -:101910002FF4505061FA86DA4D21B09B565DDE748B -:101920001C96A9D5646F35C437285FFE2DF4F3CB20 -:10193000F643C7D94F12862641BB941FFF8E8F678F -:101940000BE7C76F717EFCF6E719D7D753191F272E -:10195000C29F02870BFC4DF5FC23A94CCF7B9C5FFB -:10196000CCBAF10FA90C77079DD7B86EDCFA05B495 -:101970004FF1C641685F4F2523E2DBE7F8F87F9C13 -:101980003A846F7F0CDF2DB5EB3F81EB10DE2838FA -:10199000F91BC8938BE28D7699E30D25D69FEDA7B1 -:1019A000F88BE7D5DD6999179513B53F3E0EA94F22 -:1019B0001DC2214751AFEC6638A47EA8DFBEDE30E1 -:1019C000C8E1242EEFEF307DDCA0F6DC09FA594D9A -:1019D00067F3A8A4337CF92A9FD7F7A494B8FECD67 -:1019E000AE687B5DC85F5B587B72F22CF67B204251 -:1019F000AF58256C47F887EBD3D977A29D45FC2AD1 -:101A000070AAB99D5FA40ED95FBFC071DD2FF60724 -:101A1000EBEF40BBFE285D23B17405FD62991743CF -:101A20004F8EEB12E1B818FAFD078EA789B5334443 -:101A3000BF607C3D7BAB4B167CF2BBD411F8A39FFF -:101A4000F3C7C5287F5CE4FC31908AF884CDC3EDF0 -:101A5000E38CFBCEFF90CAE8B39BD349CC97B9FF88 -:101A60000FF2F743F4F09C7C2616D7FAF3D356AD69 -:101A700006BF6593ECB3D0FBFF032FADAD0C008028 -:101A8000000000001F8B080000000000000BE57D37 -:101A90000B6014D5B9F0999DD9D94DB29B4C924D9C -:101AA000B281246C20D858032E21C42841264F022D -:101AB000448C88888ABA014C42802422B6B6D5CBA1 -:101AC0006242785A637D142DB60B420B16DB88A94F -:101AD000A518700382F80EB68AD6DB1AC4F25084B9 -:101AE00005B55D5A5AEFF9BE73263BB3D905D4B696 -:101AF000B7F7FFE3ED3D9C33E7F9BDBFEF7C334B18 -:101B00000891482A215790FEBF1C13AD17F38A7C19 -:101B1000D42779F208991420AACF46C817F0373E87 -:101B200054C629022129842C946BE29431744079A3 -:101B30008BAB6604213DA57DF36B22F4BF2789F5AD -:101B4000BF21635D798A8BF6F7D27658DF49FF2D86 -:101B5000127263438FE8D18DBBE1A3C373D408F342 -:101B60007C37C944085DAF75A67B9FAB804EE334DC -:101B7000B9379281FD1E4C94B1DF84A13E2981F6D4 -:101B80007BFD1451D6D37E374E13541F3D57253F4E -:101B90005702DF578E2261FF32A8C338B96F4EA4B7 -:101BA000735CC69F57B988DA49E7A95288BA3542AB -:101BB000BFB17C9F136223CF73139F672261F384AD -:101BC0003FBF95EF6B4269E4F157F2F967389FAE7A -:101BD0004822B09F7566805FBE592D56E8B81551F2 -:101BE000F0902A95AA80AF180A3A733E21B7D0B177 -:101BF000263AC1AD80735A3E2C7A2AE1B98782C356 -:101C0000990F94E01D0478ADB0A913605E7BAC5AC7 -:101C100005E538499D08E54FCCEA242809F113521F -:101C200048C8144E3F53AC36BF184FFF51643EDED8 -:101C300067656D5F0C85FF3F53397C092102F10B0D -:101C40005F5C02759F08F35FE1DAF78E40FB5FA1EE -:101C50008D3B2A858DCB500EC7F1BA88FB42F86CBC -:101C600037FFD065330D3CA7566EB779AC0087536C -:101C7000B19E5AD867AB73BDCD45E1FDB2A7D3EA9B -:101C8000A6ED1F271084E3E93875369CBB753B69C8 -:101C9000E8A4ED629CD0D2A9835F8362C2F5E62AF4 -:101CA0000C6F6F48EA5C986F8A556D84725A16C53E -:101CB000139DF7D6E4BE457AB8DFC1F1343F898D74 -:101CC000BF4566FDC2F739973F2F96046F1CECC9DC -:101CD000B6EF4331027F4E827F51FE293EAA4C9FD0 -:101CE000E1A0385B2EBA4DB42EE70A11F9D41BE2FD -:101CF000532FF2A98BF2A99DD2871C993E82BC7FFB -:101D00004514BA1CC3F7590ECF238C1FC1E9B6DCAA -:101D1000D123123ABE98F35B78BFBA2491F1B19BFC -:101D200054459AE787A17DFF10F7ADB07DE79B6B27 -:101D30001E85FA4C657F45226D2EB9CF319D380046 -:101D40001E2662C946385941AE491C4E749B04EAAE -:101D50000BADAC2EC5CE2709B4CC72FA568D04F863 -:101D6000B599DD2E5AFFE0E80722A174B6F1A1D3A0 -:101D700002A1F2627B8090E46C98478619E1CFF46F -:101D80008530703EFACC2569EB51D05C7994A81669 -:101D90004ABF571605A69278C378F2059DCF16E87C -:101DA000F50A803F2BF1C65D8A64FCBB9C549C15F0 -:101DB000E74BA3EBC279E4CF880FCEA33A3DD564BD -:101DC00024218981BE1F3563BBCD3D01CF456CC049 -:101DD0006FA1732E44FED3F625DBFA9EB89FF6EF73 -:101DE000FE3CD67D2F9C3B50798CED8778EDC0D79B -:101DF00062B51BE43B2116DC9F89FE077C362E482A -:101E0000F79BCBF70B8B14E8F64F069EE761B1E624 -:101E100015C0C7AD56A2C6E7A37C7815F86198999E -:101E200076A0706C57049F97F66B7F68CEF26C902B -:101E3000D7AB25F77002744EB60994CEC7D275EFB2 -:101E4000A272472E223685D665273B7FFB7D8E7595 -:101E500071023C97C84CFA7C6CC07F46A0708877B2 -:101E6000D6552BF41C321F2F50C0C178C1A59099B4 -:101E7000F940B7BD2241F9E0447868FCA37E8308AD -:101E800087ADA86A08D057B944BC56DA5F70B279FA -:101E9000AF2401910C033C504540CB52E2C6F27E88 -:101EA000D1730CCE6395295EE9FEAD26AB6F890038 -:101EB000F8AB79B50AE15EAE1CCE0DC9B368720805 -:101EC00020775883ABF8F5E55EC5A2C87CF58F1086 -:101ED000DFFC03F98630BD3C6D28933B7BEC7D3302 -:101EE000F57CBF5C61F26939976B44627CB65056F1 -:101EF000CD89E7E0F3D55C1E8E4862F2B39544E6E7 -:101F0000E36712D9BCD3EEF5B50FA2F09B9224B8CB -:101F1000410F576CA99506BB42FD06717D989CAA9E -:101F20003A60DDD6EDEEA33E07681F19F57BFBBBDB -:101F30006406CC5FCBE5E7DFF8BC6712D93E86F0DC -:101F4000FA41C13E23125CB213FBE1929D08E7F413 -:101F500030B88871A3027EBA0E19CCD7310BB84EB7 -:101F6000CF50261F872719D719CAE51F95FB1727BA -:101F7000A2DCF76540BF97CD6C7FE1EBBA43EBBACB -:101F800071DDF96CDD4920E781FF5DFB5E10757640 -:101F9000D7A4808780DD033C6C2A0CC97BD9E51768 -:101FA0005B687B7114393F8E9F9FAE330EF6455AA6 -:101FB000181EFDA9EA9550A776C17858BF67A88278 -:101FC000F2F2F54126B29EF2656DFAD0EF83D8D4D5 -:101FD000E6F95522A3879EEC76E72C8A2F3940DC60 -:101FE00016A4F306947BC55CBEB46EF71078EE1DA4 -:101FF0004465A66EBC1C986525363CCA3FBED0FA27 -:10200000533E6A0F0C4DF044C08B56AE5ACC44116F -:10201000712DC0710BF9B8F07EB68777C5C1FC2B66 -:10202000A1FF370899CAF1430F8CFB9BC479A735F0 -:10203000B03EAE8FF6DB9E3BDBB01F7C4EF9A83D79 -:10204000F78938B097BA33A91E0039F5928872B271 -:10205000DDCEF0D89E5E47F4F66899D32F1E8679C0 -:10206000CECE26D329FE8A9D1E72913DB4EFE2DCCE -:102070003AAFE0C0F66763E83CDF4EBC08F12EE7FC -:102080007948A50DE0D249EAE8F965C52FBA695942 -:102090001620FEF105D09FCA7981CDE7B2EBE7218A -:1020A0009D308FECA6F400E3027EDCCFF6A3E7863A -:1020B000A32DCF6490DF1A5F52BBEE5EC07FB97272 -:1020C0004D79229DBF714B76BE48E7AF74F6C8B319 -:1020D000F2506EB7029DFC2A456D4BFC5FB4E7667B -:1020E000109F19F03E218BE981294D826F3D854F6C -:1020F0007B989DF018E7C7B12179B716F9AB48B3C3 -:1021000013D4C713CF6D07AF83E7E7B0837F06CF44 -:1021100023D8C19B12991DBC19D6A376F09389CC04 -:102120000EFE39AEFF15E1768D42343BB40BE673FB -:102130002472B9FA7B668F86EFFF1E7EFEE5F4AC53 -:10214000BD4097924F6274CEF8F40ACEA7938E5298 -:102150007EC91B48FFDD94FEBD94FE4E53BB49CCA7 -:102160008E4E4FFE0BE4CB928719DFB73A7721DF13 -:102170003DCFF9B39BAFDF9D2B56033E5F26A222D6 -:102180000A03E76BCFF43841AE87F39F7AD648CF86 -:10219000654EDFEA7CE09B7DB3DDB0AD707E946977 -:1021A000593722B4EFC3C0876374F2890852E5053A -:1021B000F021CCE319017646A204FCD74AD8BADE56 -:1021C0007D22EA89687C44E9E624E0AF1F2E006C9A -:1021D000DDFE29DD04804E289F9DFA3AF4B28AD3B1 -:1021E00007F543FE0AF3E4F27A6D14FF4248EAD79A -:1021F0000F4212F0F74CA687B2135D4847B5C421D1 -:10220000837E51C5CC2C902F745E7312EDFF66C295 -:10221000B9E7B525F5F39F0DFA93BBD8BCAF809114 -:102220003D66E0BC1392A8FD11619E0CBEBF1BA3CE -:10223000F80B399A7D92D76F9FA4C37A39C037744F -:10224000FD1D29EA60A86B7C53CCED961705A35EB3 -:10225000BEA4DFDF677A2E8DDB2F644EFFBC390012 -:102260001F0D9E9A1D50CBE583364F2EE7BF614967 -:102270000A1BDFC0C63BA04EDB2BB9FF44E172292D -:10228000C2DBCA9E9FCF2F7A4061718B3ABE2F2945 -:1022900051D1F41BC2B52A9ADFA584F43FAEE7669C -:1022A000FD4770F8D07615DBABD93EC62A0CEFE1BE -:1022B000F18368F8D1E0EFE4E723B96C7EE2ED87C3 -:1022C000DB64985FA39768707B3381C16D9206B71A -:1022D000363E4F983C5825755A9508E7BC91D3ABCC -:1022E000568FCB35CA8768F1943121F8D4221C0A65 -:1022F000D8BEA3C5572EE7FDAF4CEA875F038EB368 -:10230000B1FD3EC0E5356D9F87ED196CBE3B42EDDA -:102310004DD8EE64FDA3F9FD7770FD3537A97FDC5C -:102320009D38CEC1C685C713B4B299EF6F7E68DC05 -:10233000DD382E878D7386F0BE18DBAB58FBD78D4A -:10234000BF39F9BADF0DC16515F2BDCACEFFB7843A -:10235000FEF6EF637B315B379AFCF85B029B6F05FF -:102360009FEF4AF08BE91C8941922B39C06B8A752B -:102370004FA05DD282AA1FF447E967B20BE47485CF -:1023800068F30A541E4B2E2BFAC9311251C1AFED1E -:10239000F9FC5BCEBE3CACFB41AF2F8B29B182DF99 -:1023A000B93C5B72833E2C794062FEF57113CAFB27 -:1023B0004A713ECEB34BD1ECDCDB0D7EB44B715594 -:1023C000C7C03EAC227131FFBFFA2AFA7C3C97D7D6 -:1023D000BBACC926986F6C268B178C77D5A1BF4EE6 -:1023E000CE323F5AA5FF31F9ADA25E96F93829A346 -:1023F0008508581AFD6D99AC3E258E44BD8076D473 -:10240000D880D1FF965D9547607E99E8C6D175BBAF -:1024100093EC0EB4A772C8F02F28FF58720562A182 -:10242000FE4585E4F1031E26BAEA94527A1E4B86D5 -:10243000C70A7238C7EC1F0CF184B60CD9ED05360B -:102440007CA8DC9A0DFE5607F5CF110E6AD2352313 -:102450004278B214AB04E890E204F9ABBFB4B132F5 -:102460002599D1F1F1240BE2B382D7B5E7E1782FBA -:102470004C8E65728458BD1FE6829C104802A5C32D -:1024800005A42F0BE8312D9DE98F26535F2AD44FE9 -:102490009240AA8396AD1D525524FFE727DC2F5B9F -:1024A000618A6C2FFDC43CF17D80830471834B31C4 -:1024B0002EE0B10C0BC50F347B558B2344B35BEF7F -:1024C000176B8EC13C82E23F03FD07DABF5E76EEFA -:1024D0000C26A7B552DB472D87CBE0642B9E6FE718 -:1024E000DD6564960BF1F439C7D3BECB002AD973EE -:1024F00014C0D34BD98FE4405CCA9AFD9003F8B363 -:102500008A30FBB4C205B29890476D9EB3493AFB3E -:1025100066624E2DDA4DC5592D684F2D8BE2977EA0 -:1025200047C38F4627368F39790CC4BF165A61BC12 -:10253000A4D4C442B93338154B6AF75AE0F9B20C47 -:10254000563F1F1EDEE37229DAFE27805E80784D3B -:1025500046FF3952607EFADC2BE787CEA1DB5F7A3B -:1025600072CAC0FD5993993ED2F625E570BACC35B2 -:10257000D25D4D32933397246BFEE205D3DDDB173A -:102580004277E1E79D98BDA8EA6212DABF765EED78 -:10259000FCF4BCA3E13C15123BFF46C5A3C21414D6 -:1025A000CE05008701E7B246D6FBAE64D397E5A31C -:1025B0004792865DF879BEC4BCD393BF049CF68C69 -:1025C000539D204FDA52287D523CB509ACD4FADB3A -:1025D000397D3EC3CB2F2327867F89F39538851716 -:1025E000401F8EF71C2C8365CA8B4781DA017EACB5 -:1025F000073C94E63D20CDA2F5F6BB67A3FCDC3397 -:10260000AE05F7BDCC6EDCAF56A6707C1467A9C8CA -:102610007F6D9CFF2A08F323B57ECFF37385F347C4 -:10262000F87CE17CFDA84DBD0BF69592CCF61FF22F -:10263000FF7A45BDFF57CAF5D738EB1D86F8C73876 -:10264000EEFF2DFB6CA8CD4B0F7A9AEAB57F8AFF7F -:1026500077863E013F29A3D4AAF7FFDAAC65D8BE3E -:102660002C53ADBAD401FA5874DF4B107EE80F7AC0 -:102670000551D918C11F5C9629FBC7D3E71685FC05 -:1026800014F65746F525C45F2C8A4A2E1A31D02FEE -:10269000DC652D23103739AD9067C11F3BDF7936DC -:1026A000271BFD4209FC423E3FFA854A0BE9C378ED -:1026B0004F1901BB06DA5D2340EEA8C463073D4213 -:1026C000FD429D7C3A6DBD03F93D7C3D2AB79E06D7 -:1026D0007CB5298C8FC3FD413999D9C19A9C0DA72E -:1026E000870A27A39B18BA7533931BDB9323C8FB78 -:1026F0002F2F9FE694830B703D59B2075CB5EB8298 -:1027000001095C9E6F27337EAAB13DDD06CFB5F986 -:10271000C3F1434FAE423C1DEC1916BFA1F61AB5EA -:10272000A3CCD45E5B2984D65FC6E11D0D1FCB40D0 -:102730005F47E0A303C9262E7FC2E3447718EF5F0B -:10274000142F7114B2B83E89007F91DB49CB29BFA9 -:10275000C0FDCD32B3DBA9009D6616BFE3017F3E0D -:1027600053C6FB0822B538AFB10F3CE772889F45CE -:10277000D8DF9F939310AED60C93C13E23E41E8303 -:10278000FD18EDDC84EFCBCCCF25003C73F5F00CCD -:102790003B77B982E706B31EE68D37B9899FF245CC -:1027A0007C1671A3C08A37611C56E37385F3B92682 -:1027B0000F6C0A1B77B56318B3CF445B40A4E75F87 -:1027C000E5A0F6349DA755DD857A551B9FC0CF6FD8 -:1027D0001BC7E28D36BB5F5122C0E17ECEE7D1CE72 -:1027E000D9A14A89E5747FF72BCCFE96C6996A7CFD -:1027F000188F62F15A85C34E2C29B082DD3E091C28 -:10280000F814D8CF56451FB712F97EE2EC743FE7B3 -:1028100090932BC2F61393DB570EFB97B2552551BD -:10282000B7FF0A876607F4227F479BEF3E2EE763D8 -:1028300072DCA40EEC0D9BDB0FF75A316A5D218828 -:10284000C5D85C3799AD6B8F550B475B7474D891C5 -:102850002947BC8FF82F0793FF7649AD81717645E4 -:1028600022704F66E7F672B479A3EDE37CEBDDC42A -:10287000CF3B603D5764BB62A883C90D69DCD61AA3 -:1028800090D36484448647D013290EC6A7F1729F63 -:102890000BFC754A8F9E48F3890E99C3FB5FC41FDA -:1028A0009ADD5DD2B56F28DD6FAB4D720B20BF8A0C -:1028B0008EF6BA74F0A17A7D9643173F106D1E9480 -:1028C0006FA28BDDBB575998BFBD679CF19EAC8151 -:1028D000C3EF7D5E46930BE31D9A3DF6AF39E79754 -:1028E000C55F05E04E07970E800B01FEFA415B6B5A -:1028F000047949E1D3FE55E0B39AC3E5694ED7D1D7 -:10290000E033CA61FA97D241387CCEC7D7213EF373 -:10291000914311E0D86A97D3671BF8BF03ED904845 -:10292000FDEA74E78DC6871A7DDCC4F14205A42157 -:102930002E203BBCBDCCAFBCD3A8E7C4F96E2E9F04 -:10294000C9590AB744DE3FD146FC71F1A1F9E572DD -:10295000633CE179078F0BC4901880CF69F754016D -:10296000F2142CA699A394A1B04487007A2215E60C -:102970001949C8035C7E86EBC11495F9C983498B5C -:10298000C0F44A06EECFC1F711AE07D3A95F03F139 -:10299000183822F8D38369DD0A360851F11E5CF03D -:1029A0009AD05F76129F00F367903E2C87402A02F0 -:1029B0009D3F9BF40A39147F0F54D48D02F9FD0E0C -:1029C0009CE392D039CE678F6AA5667FACFE37C193 -:1029D000FB93B07DFE1F82F792321DBCE51423DD10 -:1029E0007C597837707887C7F38A219E970DF13C20 -:1029F000FF6EE053F92CB33F7AFE2E637CAF2D9B24 -:102A0000C5F32AC4EA35780FEA92D1FD9072FB56DD -:102A1000419E936677A2CE1B168AFB594FFD4082DA -:102A2000380A918E229CF06EC885F22C3B05E53168 -:102A3000B323C6F3FDCBD973AC70EF1DF29FFC221C -:102A4000B33798BD24733A287696A2FFD276F6DC87 -:102A500076C785FA493BA53D787FADF947AD8159E9 -:102A6000E82F858FF34BFEF7E0FCFE80EC827C9331 -:102A70006E7E2FD67D6AAF214E1BEE076976D57824 -:102A8000BEFFB28067DFA570BFA5CC222CBEC9E017 -:102A900020F375DA9CA7F11EFCF9B326F4B74E7348 -:102AA0007FAB18FC2C3BF377EAEC03CF794DCA459A -:102AB0008638BCE63FC138C8AB2B53FC22D8739A8A -:102AC000FF04ED2EFB40FFA9CA127805F637E51585 -:102AD00011F342A2C137DC6F0AD73F335398FEF996 -:102AE000560A8F1784C1538BF785DF4BB76BFC27D2 -:102AF00079053DFF87AF2FEF9A88FB278A2E1E3B73 -:102B000034144F14542FB92B3F143F8C10376C01E1 -:102B10003AD4E2869A1ED3E8D842FB5AF19E397223 -:102B20003CB13B7BEF30E617BE900CFC59A1B0B82E -:102B300091B63FEA17DE93A2C3477180E96DCB7F60 -:102B4000B5F42DA1F02549C4CDFC83169795D62B5D -:102B50001592BC12F9CC86795AC50E01F94EF2C70E -:102B600060BDF2B8DB1743EB965D2F89A203D69BBD -:102B700045628410FD68791D6D810F5601FE4E1F60 -:102B800097DCE7F2BB2B218866F0936243F844F9A7 -:102B90009664A83F22791E4D413B6150689C08F91C -:102BA00060430DF967CF48EA63D06FBA55FD11F65F -:102BB000FFCFC3FB2F53305EBCF72BE13DB40ED3E8 -:102BC0000760B39174DD7A36DA7839ACE342FAEF14 -:102BD0008F4B2F22781FB309700671964F880FE232 -:102BE0002CCF995F14411FB5F379AE201D2E7918B3 -:102BF000DB2FF4DBBCD1B90EE8E2AD946C9CEF396D -:102C00009B67F528DABE6F83340AE236ADAE67AC57 -:102C1000903FBB6B637B469F8EFFF66DF60C89E49D -:102C20001F6A25FD4B3015E1B9E259A98A2627B65E -:102C30008B501F609F6DE852609DCD1BAD3322C548 -:102C400035E454C6EF576C60766D55AEC90DE2ADF4 -:102C50009878A524B88F7113B79F36C48DD8DA5BE6 -:102C60000ABA285BC47B0D5ADF1D4FEB716354F425 -:102C70000F2E1EB115C75FFC49A99BE5517A6DF96E -:102C8000B4BE2AB774CC4A5A1F12EB39067C45F5FC -:102C90004C8784FAB4330EF200E2464C4D59496B2E -:102CA0007102A98964E7FE3D85D9799BCD1A5C251F -:102CB000CC83DCB55146FEDA972EE2FD1385DB7C32 -:102CC000A8FF393D8E504A24E5AAB71CE058413A86 -:102CD0005BC19F2A775DF3423CF90AF02BD8AA002A -:102CE000FFAF8A6287BFC5F7874284D2CFDE0D6D02 -:102CF00037920879D4FD79D671AA2515EE57F8BD1B -:102D00002E714E45FA898EEF7B99BFD9E96F8DA55B -:102D100070BC624BC720FDFCEF42D0356520BE2160 -:102D2000FF995C0AF9B71ECCA76D3D6A42F8BD9CBD -:102D300027F8040A9FBDB922B5D9E8AE72ACBEE14E -:102D4000B4BE9AD371F596FD6D8380E5531DB8EE40 -:102D5000CBB94F58597EEB85C7AF47533E6884FBCC -:102D6000648A8F094AACCF45F1350FA6A0F5718A68 -:102D7000D5E7A7EBF5D87BCB12E812CFA508EEF587 -:102D8000402FB94401F9812E8889214AA175101973 -:102D9000484F0E82F95CAB0AF3D6435C6C6586AB98 -:102DA00013F20D778CB062BE59783EF10EA1E58525 -:102DB00044884B250A28AFF7E6BE89F7747B332C8D -:102DC00004E815137EE9F3B624C6A7710546FBB3E4 -:102DD0002A359BFB9FC46B290CED2B2EC7AAC6502E -:102DE000427A31918DDF9723F880DEF6B9B87CA066 -:102DF000E7DD080691D4214D1F111DAF2F0D9FE077 -:102E0000D2EC62413BA769E0399E137CCB87C23983 -:102E10002EA6E7A0757BAE80EBDB9595B7132C8BC8 -:102E2000EAE11E337CFFF7A632FF50A664970BF24F -:102E3000AD73F9447D7E8C5C74FB145B3CE631A180 -:102E40005D99962BE079261E65F7B903F2B315E27A -:102E5000910DF8A156476A68BEB8CF9EFD36E4FFD3 -:102E60004E2E12FC31B01F9EDF4CFFAF07F48B9C3F -:102E700053CBF2AF73D7E179261599DD709733C93B -:102E8000E6EB28A5F5978E4918CF9E9C3301F3AB4E -:102E9000C3D75FA9107F1585EF4B7912C23BE6A21D -:102EA00027709ED7F34C286F26433E36E42FEBF372 -:102EB000AA511F1AF3B9278BFFAD9640B39BF12B94 -:102EC00091BC8340BE4F711AE1673F6ABC2FAE2EA2 -:102ED000B018EA93F3E4303DEC457A793193D1C5EB -:102EE0008B170BBEF5D9213A9B7434C90774067F42 -:102EF00062A1018E8673C6056415E0B7EFE29F3DBF -:102F000008F72471AE65B7E33D3887BF4627711CCB -:102F1000EFF68C5F7F1BF49406FF703AB870FC5F8D -:102F2000535302F82FD0EEEFC3F01F866F8C416A27 -:102F3000E7183610EFB87EF6407C6B7430E0DCF7B3 -:102F4000752D1F4AF1FAB29D3E003CAF937DF70A02 -:102F5000213C9D17AF392548372B950E1BC8FD988E -:102F60008B0ED9C03FD0E88288DD057A7BFF9F8534 -:102F7000EFD2D5027326DD820FE27A6FC0A3CB4376 -:102F8000EBBC98DA9FD7F5622AD855352C8FA3551C -:102F9000CD67EF5D15307D1A2E1FFE902AE2B81E18 -:102FA000F38B19E7CA53ADB67908DC8FB542BE1D65 -:102FB0003D9FBCBA16DE6820F2B45A949764B5C03F -:102FC000F2108A7F8BF27D8ED3B75488B01E5A32AE -:102FD000B84F17937BC5C9D89FCCD0F2926ADEC791 -:102FE000FD4F63F50BDDD76BFFA47DFD9ED20A8BF1 -:102FF0007731BBF96A1E97D7ECEE2936967738A55C -:1030000058447CBCBE41F0617E24EDE7A574D2C873 -:10301000C9F66A6E079E2E7AA67D940BEC41D560A8 -:10302000770AC53D68F7251419FDC14435D680FFE0 -:10303000E4AA24433DA56690A17FDA8CA1C6B8829C -:10304000E79B86E7831BF20DF5CC962B0CFD87DC06 -:10305000556AA8677B2719FA0F5B3ED5501FDE71B2 -:10306000A3A1FF37D6CC323CBFD8D768787EC9A69B -:103070008586FA88CEEF1AFA5FBAED5EC3F351FE89 -:103080009586E7A3F7FDC0501FD3FB98A1FF65EF1E -:10309000AC373CBFBCEF49C3F3B147B71AEAE30210 -:1030A000DB0DFDC7077719EA25E41543FF32EB6F07 -:1030B0000DF50AE53D43FF09CE4386E7135D1F1B6F -:1030C0009E6B743039F75343FB55EEBF85BDA75354 -:1030D000C3E21C100F18068F3AB08C259DEC5E875A -:1030E000F462F960A1A73C0DE8F3C7DE7648486AB0 -:1030F000F506FE0857D3AF170D4B60F6934AF4F26E -:1031000053CB4FA57E8B378692427C90D2ED684A96 -:103110007741014B2548256B32C47B62B04C0A26AF -:10312000637B7230114B477030B6A704D3B14C0D9E -:103130000EC3322D988DA533780996E9C18BB11C49 -:10314000141C8DE30607476199111C8BED99C1CBC7 -:10315000B1CC0A9661FB90600996AEE0642CB38313 -:1031600013B11C1ABC16FB0D0B5E83654EF0266C6A -:103170001F1EBC01CB8B82B3B1FC46B016CBDCE08A -:103180003C2C2F0ECEC5F29BC13B70DC25C1DBB1C0 -:10319000CC0B7E0FDB4704BF83E5C8602B969706F8 -:1031A0009760E90EAEC27EA3822BB0CC0F3E88EDB5 -:1031B000A3830F605910FC11B68F093E8A6561F038 -:1031C000092C2F0BAEC3B228F8732C2F0F6EC6F24A -:1031D0008AE033386E6CF0692C8B83CF61FBB8E0EA -:1031E0006FB0BC32B81BDBC7077BB05483AF607BCA -:1031F00049F0252C4B83BFC5F6B2E07E2CCB83EF84 -:10320000617B45F05D2C2B8387B09C103C88655515 -:10321000F0632C27068F613929F8298E9B1C3C8589 -:103220006575F06FD87E55F00C96FDF22E6ABEB231 -:10323000C784FE2CF753A3FB0B5E949766FE5E1CBF -:10324000E45663FE7F8BE0C378A1A3EF05A89B8BB8 -:103250002C182FBC9904F03D813F903E3BC8D39E73 -:10326000CB8F6440BCE9F5147FA63EDFC1CCE30000 -:1032700015E27109FCD5298E5D29A04F6FA6CD906E -:103280006744D42F300F720ACF83BC59A20E16DDCB -:10329000EA7E98E172ECE7B7D0FACC6AA2E6D3FEF8 -:1032A000ED975B30AEDF9E4FFD205ADE97CDF26585 -:1032B000BBD298BE7C2A8DF9A5CFA531FFEAC942C1 -:1032C00096C733F3F6E18C9FCA93CFE33731387C4E -:1032D0006324CFB3B505B2303FF602C79D48E57908 -:1032E000B5BCFF836935CFA7D1766F29C96DB1858C -:1032F000FAD1F65D51DAF7803C086FDF6562F8F0CD -:10330000BE2D723FA12661EA39FC84D717F77EF300 -:1033100085E1A1FA1B51FC504296B0FBC35DC7AAE0 -:10332000AFA7FAF0EA22D14D2507F9EFC5DBC67D3C -:10333000389CAD0BF999DE5211E317338BF7EF4947 -:10334000A6F5998B1231EFBE7F5FA5667C3EC5F96D -:10335000F6375FA047BFB9E537E33E34C4453D6863 -:1033600077DDC16994A8E6BFF669CF915E59DCF7B5 -:103370000E58DC05F2CF8CF3F6AA66DFB9F263884B -:103380006A21AA81EE19BC56C1FEC1F7275613ACBB -:103390001BCFFB50B8A2DEF7C6CBBE56019C7757B9 -:1033A00002D05D5C5E809C2BBE0CF0943051A1CFAE -:1033B00006764C3478A63819FD2514AB4E2FC54F30 -:1033C000DBDF45BCE7DA9D58A800FD7FDF9693065A -:1033D000FCE174327A6DEB7917E35B090501E2B524 -:1033E000B1FB739705E2F8562C972E7663D9B6B8E1 -:1033F00008CB95193FB042BC444C91201398C4644B -:10340000CEC17890B6BE397196B5C44DE75B63A95D -:103410008610920871066A2224D2FA12EA539C4D51 -:103420006374FDBAF3431BF0C3D93417D64513BBFD -:10343000378E2BF0AB909710E7564A2557A81DFF03 -:103440001CD8BE1EFC91D749DFEA6B018E2A7B1F78 -:10345000A395BF6FDA5A329CC3551B1786F7303CD1 -:103460008BB21BEFADC558DA3F2F3A5EF39C2C2F81 -:1034700001E84BA2F4F529DF3751E34C309F86DF9A -:10348000D35200F3A95A85C87997851ADC155539A6 -:10349000D73D0A51A4BFEAE5A92D6F5B183DDB506B -:1034A000BE621DF2B9B8BCDA9BA6163BE9FC8BAE36 -:1034B000E472202309E5006D9F7E056DDF66627E64 -:1034C0008A3749467EA14048803C5F6275254C3D65 -:1034D000471EC4B2C58A2A99E17EC09500F05AC63B -:1034E000F3F5E00D65BD1CF857F50BC90B1F9E2BBE -:1034F000BCFF3613E7ABD8183C97C8E1A18D9BEF12 -:10350000E4F238BBA6D689F1115706C8555A9FED8B -:103510001C83E7CF00BEA2F5DBB0AEF4D7EBB1BFA2 -:1035200093F5C7449A0B90C3745C138E93FAE769C2 -:10353000C1BAAD7FDD85B88EA3BFBE08EB19ACFF65 -:1035400085AEA395FDE77F93C9C9CF24352189C2F4 -:10355000A7E6AED935E5546F5F7BD75C2C3F58DCCE -:10356000AB825C3D4CE5491B856B4DC93007F83992 -:10357000D75E35CCE6D2D16B3D8F6BEE5A6EAE0284 -:103580007D57BA42ACD980FCB4C49037B7CA69E65B -:10359000FE0DDB471DE5F1BB29C9D5AFD9FFCD36FF -:1035A0009D3D3A8BB865A0F7D9CBCD21BA263AFE1E -:1035B0005458DB3693E7FB37C039568AFCBE82F39A -:1035C0006B22E1FEBC2BB5E61C7A872CB7104F04AA -:1035D000793C103E84FC95F2C167B61C8CCB524BF3 -:1035E000CD1A695E0D4ED1D6AB8F12FFD5E0A4C1C6 -:1035F0005B6B3FB47AB4C2EC6A9F018EB3EF1B835E -:10360000F1CA7A1EAF278956CE9FAC5F1D5D672B2E -:103610008C935417D03BD423C9176DDD3AFAAFBB56 -:10362000F323C197C361A599E9F130F81E5E333CDD -:103630001EF45038FE2E14CECD1682EF530436DA27 -:10364000591CC93103E76FE0EB13C74CDC4F035F34 -:10365000EF859D717E13ED5FBAD1BE1EFCE093A590 -:10366000DE476A403EAD37633EDBBD3B57BDFD23C1 -:1036700078EF639D19EF4CE6C63D5C08F7B1A7B83B -:103680009EA30AA007BE9FE021DA9F2AC0FCF58412 -:10369000CD7F52BBFFD89880F03C5ABEA17D2C2D27 -:1036A000FB762CA886B8CB919D57ED05BF796E2C83 -:1036B00091D231BEAFC8C87F5EF38746FB400AD5C2 -:1036C000C581F57AA8EBE247737DE60FF5743E6F8E -:1036D00093B1AE8797490F2F57B9115EAE0A03BC5D -:1036E00084E7ED7E5107AFF298E10ED0EBEF3A5D43 -:1036F000088F8698A5A9009F861D2BB09CB729C668 -:10370000FBA16EDD059D89867AF3B674AF5EAF9C32 -:10371000DEF7443CD0E142A7E8FD90EAB9E38BD55F -:1037200056B0634E2CAEC252C3FF82CE6CAFCD30CA -:103730008FB17EBA43A862F2D99530ED1CFCBAD0A5 -:1037400029E33A1F6D62FEE6478BAD5E58E7F862EB -:10375000C5CBD6757A991DC5E035FFAE38EF87A386 -:1037600043FB8B36EF3F7B7FD4C22787AC04DFD986 -:10377000F9E21C7A3BAA5C923E93517F749BFF0C4A -:103780007463A5FFFB02E3A812D6B5799B3B452FD6 -:10379000E41313B2C5B01E1DE73AACE3B7E87AC133 -:1037A000F89D8971100B43F9CCEE413C700F42E754 -:1037B0003B29D996431C41BB0769868568DF05D63E -:1037C0003ED9439B3EE91A76CEF7CC299EB2412FD3 -:1037D00037583B6450B60D9D1797033F7DD2D59A5D -:1037E0000AF2639E78FA5B91DEF7BA3E9DDFCFFB6B -:1037F000CC01A3BFE8D3F6992D19F88CD8FACF4D98 -:10380000EBC7A3BCDF53CBE76DDAB2BF722CDD7F11 -:10381000D3B65332EC232DDD539B9E123ABFC0EF3B -:10382000811A371D94E17C47CDDE8BBE772EFB7E5F -:10383000C03E6D4E43DEA197F4027FCE2A221AC30A -:103840005EFF1E9537C75E3113B83F2467692FFAB4 -:103850003C8B3F9D436AE2015EB3BAE6A1FC39F6B8 -:10386000ECE4BD2CFFA8A310E8E31362C2F7DC3F31 -:10387000216FC68FD6C16F75BA963FC9BE6FA3E5DB -:10388000B7D00DA6637E7A437B2FBC376621929713 -:10389000CB25817DAFC627A03C6B60ED5E625D826B -:1038A000E758CEE49197FE07F5DB3A8CF2A97E8DBE -:1038B000B15E47A6A6427E77DD4366C8202273F537 -:1038C000F28FC2EF8E7466D7D7939676B0E71E97C5 -:1038D000595EF72C854883A91E5AF0EBC70B6B691C -:1038E000FDC17476BFF311F733E0BDC774FABCF1C4 -:1038F0002E9FACE60D3CDFA1AED1D3C7129C8FE961 -:10390000AD46CD6E252E88E30F867F0D8D7EFEC1E0 -:103910005D22DE3B0D86769D7C9EBDDC78BEF39DF0 -:103920003FFCBC84FC00CFDBB8E91AF4DBB4F368DD -:10393000F8D2CE63DE14F93DDF27D30583DDB49DD5 -:10394000C34FF3BB9F0FABBF10567F299DD9F72103 -:103950003F9DD1B799F337A5FBE781EE1758039543 -:103960008C4EFA64FD7DA81CEAF7C2B9FA5938BF3B -:10397000D07E2FA58F89DE2F2634DFEB91E65BF01A -:10398000EBA79E057FB4F1970FC7C365D031A9237C -:1039900015DEB398BF71693CC0E9A8E48D07BA3958 -:1039A000E613AB22C14B1AC4E506516D02C57B93E9 -:1039B00046FFC54BA6807EFFF346B3027E61F32629 -:1039C0008B1FBEBFD4D43517EF6B68FD20AB2FC360 -:1039D000F72A9BB7993FD0E3B5F1670FA7627E073F -:1039E000F10E66F7E9FEC1F0E9A0A60D7FAA043F3B -:1039F000B99904909EC3C7C1FAC12494D7B572C2C5 -:103A0000C0E75ADCB4993591E6AE55A7206EDADCF2 -:103A100035F108F07D33913ED0D35303D034F557C0 -:103A20003E4FE779779791CB40BE68F020BE149463 -:103A3000CFAD9B7F38F220DDCFF10DAFC40B7A7F85 -:103A400095DFB79FEE9CFD7EF239F4C3094AA7FAD1 -:103A5000F73134B9EBDA46379046ABDDAC9C6FF604 -:103A6000C78FA5709DBFCE8CEF87CE7FEA899F3E22 -:103A7000067944EF5AF0FE63DE537BDEBE82D6E762 -:103A80003D6D7654B363D8E03E58C34B33FD1FDC25 -:103A90004F6878687C668F0CEFCF403BF8071A3E82 -:103AA000E63DDD23931103E157D6D923F7D922E070 -:103AB000A5F36025BE67B4F92F32E0FDD84E81A48E -:103AC000650F1CDFB06E0FDA310027C423C7533FE8 -:103AD000DE06E0CB3F657B01F653406E9F0F5F072C -:103AE00040AFA6205DFF623BDD47C3EF2D6E8043F4 -:103AF000C32FEE8887F31C915A187D3FBE3415F210 -:103B0000DC1ACCDE54054BD6DEF0E33B91EEEAF74F -:103B1000DF99CAF20ED5749EDF910EE7BC6DED758C -:103B200078CE3AE241FA6B785CAC813C98CF255272 -:103B3000F57404FEB89BF3C791F514B9F49C4740A3 -:103B40005E3A42FE8EF65EF39DFD7110760FF939F6 -:103B5000BF879C3A48CB5B67F2B79F6E372C43B95F -:103B6000FA51A69A06F793140E9A1C45F92AEEAF5D -:103B700048637862F218C751FA2B8376E8DF6BC688 -:103B80007B61DD382E3FD9FA8BF8FA74DFB1608F94 -:103B90001C498DFC3ED0A67EFEA7FA5647673A3EEA -:103BA000677CBF6105E3738DEF7DD754C1F3CF7E92 -:103BB000C7F808C6813EA2FBF2A7E1F39E6902CADC -:103BC000050BF147E2EF0D66CEDFC6E7D462477B17 -:103BD0004EA313BA7F09BE4716A217BA4E12E201CE -:103BE000ED95BA87E8789D9DDD0CEB623F39D49E58 -:103BF0001DE2E37A2E0FBE3DC8280FC8DA940B8A67 -:103C00000BCC37FB7EFA18F02FE557AF0BF8D78CAB -:103C1000EFDD7CBC65F7DB37523AFFB853E35BA3BB -:103C20003C0DE7DB86AD77627C309C6F3FCE682130 -:103C300011F93683BF3717CEB7197DFF5679AAC160 -:103C4000EF2761F0A3F2F127DB5DD1E1182E1FC74A -:103C50000E72213CC3E523FDFB1D291C48871AFD7C -:103C60006974D7F8F30543400EF5D3A7467FFDF4FA -:103C7000A9D15FF8798DF01B20DF20D949673F98E3 -:103C8000EF255E3BC577608788DF4B3AE90AC4437E -:103C9000FC67690CB915ECF0930AAF27B27A20459E -:103CA0006E0739A1B5076258BCF2644D203E5167DA -:103CB0005F1FEC16E321BEDBE78BFC7D37CC48A40D -:103CC000EBF745F9FE9B168F38191B3F12D78BCDAA -:103CD000F201BE2A445BD65D9037DA21E2777CE6BA -:103CE0002CB93E1EF2434E760FBB7A066DBFED2512 -:103CF000FE193FAF2AA55338CFE6783F4ABC8F1450 -:103D0000D3F3CDEE66F6F39CD591E944BB37AFB360 -:103D10002D92411E51BB35441F049EB3EF2C34AC91 -:103D20000D6BEF9E8CF4D418464F1EEE1F1D1BC466 -:103D3000F3FB479151DC3F31E9F3412AC4BCABE1CD -:103D4000BB9C27F789986F7DBA5B24ED70CE2D82DE -:103D50008F007F7B53902E9BA8FCD0C77F8F03DD05 -:103D60009DE33DBAE3BFFA43E1F76897F9CFBE3769 -:103D7000F247B43CFEECBB173D07F55F1FC87A8FD6 -:103D80000CEC5FB6F3CC2D20FF4FEEB4108CABECF7 -:103D90007C31EB7B50DF6EC1BCA393F75A54B4A7C0 -:103DA00077DA318FEE64268BA7B6EEF8CB48CCDB02 -:103DB000266D8837C760E6779CEEFEDB1FF1FDDAE3 -:103DC0006E7A2AD0B73BE3D01E6FDE1EE30327F5E1 -:103DD000E48EBF14EAEF2FBEEE799A6416BF3F69F6 -:103DE000273320EE753291C5AD9B9FBBFC892574AE -:103DF000FD055D3D32BCB753F6FCDF4782BC39B9E7 -:103E000095D91127CC7D3F266E42860CBEE73E3306 -:103E1000C5D709B0ED28AF3C3778E755DEBC487010 -:103E200061703849E100E7A270690039190D1E85FB -:103E3000FFB1F038750BAC3FBFFB32BC7F08C1450A -:103E40005059BBDD6715F0FCAC7DE75F46823CFE58 -:103E5000B87309EAF7F39DFBBAFFE7CE2DF82FE41C -:103E6000DC8BFE63CFCDE8FFAFA09FC60CE483815F -:103E700074FEEB6F61FD177637EEF702F9FF21381C -:103E80007FCA7FE2F9BF22DEB70A98BF723EBC3F0D -:103E9000F31F7BEEF3E1FD258E77BB0279122777C6 -:103EA000FC3D8BE8CE7FBE73BFF97F94DE353BA827 -:103EB000D7D4A214D0FDBD4B3AAECBA6E51BEAA7E2 -:103EC0000E705B2D51EE694C19CCAFB0082CEF9BF6 -:103ED0005C2768F1A55E43DE534603DA1B53D4FB2F -:103EE000D8F799A4965EC83BED2D9DED5E893DF215 -:103EF000F17B02BDD3C6F1BAD1DF7A5D20AA40EDD5 -:103F0000DB29A593F781BD77B52AA23D484BB403C1 -:103F1000DFCAAA64ED45463FE38630FFE0FA19C6E2 -:103F2000E7D7F1F9A693854A0185D7F40C49F151F9 -:103F300010DD50D26286F3DC70B3403A74F1CDEB01 -:103F4000C2E6FB2304D07476E497855F413FFC16FC -:103F5000223C4889766F771EF81106EFDE69A35878 -:103F60007EB1E466F09BBEC08D7153EE879AF978FE -:103F7000B36D792FF0AD9918FD4FCD8F8C0667C2C8 -:103F8000FD529C676808EE665544BF54371FC24314 -:103F9000C3C797C58386BFAF8B0F398318EE75B53E -:103FA00072AEB5761EDC435821DF9DCE7BF56AF6F6 -:103FB000FE88354F4038D61499F1FDAD3F996A0A15 -:103FC000C170AE1E7D59D377D9B46E80CF5C0EC759 -:103FD0003AD282762739FBC517C58578FB8776EB01 -:103FE0005C9590ABA85F52572CF863E9F9EB25E29A -:103FF0004DC88738A8403ED0C7417DC63AFC5D9980 -:104000001A9AE77CFDA3C9877F76F93E95471F5032 -:10401000A41F8412F366D8EF5D68FEE3ADDD0C8E5D -:10402000CDF305DF50A423BF597FFFBB3983C5679C -:10403000DFBF7B34CAB992FB472430BFB600F379A7 -:104040009AB9BD7FDAEB4A8078CEE9EE610910AF0C -:1040500039BDAF2C3E521ECF7EEE57FE76B115CB4A -:1040600093E542879880EF9D4C413D5C1E4340EEB6 -:10407000848F5B91A1C5655AD8BD246179F875FC20 -:104080001CF5746842920E6FABAF3A268D1C880700 -:10409000F8FB4077AFF275E10B7E2CC0757F4C5F6B -:1040A00065A4EF13FE88CB85EA5D6764881F4CED3D -:1040B000CEC6EF4B4E2D37BE07F86006F7CF4793BD -:1040C000D1B0AFEA5D13E32F07BCEC13DD3114BEB2 -:1040D000CDDDA7644F84FBB97078C2FC10473E6405 -:1040E00076D7013C0FDD1783EFFFBFC6EF8BF2F8E9 -:1040F0007721E1D341103FDBC0E17A2683C5D1AF00 -:10410000AD2E31A7D075F3BA945190573688F73F4A -:1041100093E1C2E783F938ADDFA0F9ACDF4159691B -:104120008A74FE21598C7EEA89FB5B45C27F1EDEC4 -:104130004AEEB7FBE1BDB8D3E5027F6F269CAE091E -:10414000F2C7E92AC107FA17FC58AC570BA8FF5F62 -:10415000D3F2EEA6327DA9D17D389CF767980C7911 -:104160000EA738DCDFE6F4A1C159836FF87EB5FEF7 -:10417000545E8DD7C75BAEDE36EA17609F34750B91 -:104180008A894ED524F5C9C087CDDB1E30C3FDC258 -:104190000DFCF759885433527FBF7B2683FDCECB6D -:1041A000EEFCB1683F7EBA9AD9C7EA9C53F160072A -:1041B000BD6672BF3116F8F175D1F05DF3F0F2BD56 -:1041C000C54A63B9593F6F36EEF3DAF92566080F31 -:1041D000DD34BFC79CA6A3A73319EC7B415AFBA0D3 -:1041E000F92ECC5FA4EBE13EBCDFB710C8C7C8EB2B -:1041F000EC2D8DA3CF6F6A496474D8D0D923639D09 -:104200007D67585B4F5B279C9FA655C719EAB3CBC8 -:10421000FA32002ED516FF2277043A7D2853BB8749 -:10422000FA927A42A5743BF2FF073D71AA32D27727 -:1042300050676732FAD5E987B448FA61E112571A34 -:10424000C07FE18E6169C01C0B5FAA488DA41FDE90 -:104250005ACCEE0F0FF0BCCB93D3A87EB854A71F57 -:10426000A6C5207D848FBB2AF302F58386AF7FB37A -:104270009C790BF44304BEF6641AF5C3F4EE5AD4E9 -:104280000FD3A789C4A58BC75D9F793EFD50927A55 -:1042900003D6CDEEB80874F316F74B00AE50C23A11 -:1042A000A027EECF64723F5C5F4493E7395902BFA9 -:1042B000DF3E8F3CFF5F82B326CF175EC7DEE31F72 -:1042C000488704E5F5C21B04FCFD92853B983C5FE2 -:1042D00078338F4B86C9D71A90AF057AF9CAC6379B -:1042E00079983E68DE96FDC399F4F98D1D66B79501 -:1042F000F6BF31246F0BF5F2F6FE4C49837396122C -:1043000001BF3366C61197515EE5809C3A34EAC519 -:10431000BC6780EE5F63EF99FD89EBF15747BD58AD -:1043200000F1F4C37CDE67B9FC3AB1983496533897 -:1043300094CD61F6F0822D22C2A1A98BD9794D9B33 -:10434000047C9FB732FF0CDE1BCEDBC1EE0DE17BA0 -:10435000BE253A3CCE7BADAF7D303C5F27E0BD67EC -:104360009D7B1E7BEF6F0D8B135BE97F902FB1223E -:10437000367E3DC13C1D15E3CD0B38DCAA2D81BD39 -:1043800030BEFA67827B1DCA35637C7A41CEA46356 -:10439000E01FCCDB14D6EE5E81F7190B20EEACF3F8 -:1043A00047DEE2E7BB4DF4E73D0379816F88117F7B -:1043B000EFECAD7038347C4D38ECA77028F8EA701B -:1043C00068EE7E00F36FBEEEF90F64F2787B3E2953 -:1043D000007EF9934945FEF7BE2CE27BC5731E189B -:1043E0009EA6CF53FA1387C36B264F7B3AF46B62BA -:1043F000EF1FD7AF7D7A0FBC1A3EB3938C82B07D8E -:10440000FD1AA39EECD7CB5D2ED4BB335B9E16E08A -:104410007BFEB789047F076C76BEC503F7AFFB63ED -:104420000228CF343A4CC892D877DCB8BD776850B0 -:10443000A01CFD8A6D82827C02DFD3803AC5037C9A -:104440004F63F7E57FA9E470C7F84CF33686A7669B -:104450008A17E0B34A6AEF821EB989EA1DBC2FEBC6 -:10446000EE3143FF06DA2F19E58E1BFD5D4D3FC18E -:10447000FD5D49AA0E6F3B0E32FADD28B84904BC37 -:10448000E5D2FFCE85B768F8D2EC870BC59B068FC7 -:10449000842C23FEF6C7F4568FC67B2AF63B40A435 -:1044A0003B11EF553EEC188678CCE472369CBEC1C9 -:1044B000DE77E9E24BD7C0C6F1C3F531982787EB29 -:1044C0000E65F6905EBE84FBD1CDA417ED9AB47450 -:1044D000CF5319BABCB0E93C7FA5FF5E37D4AF3EDD -:1044E000734CF47EC4598AF73F5A7E2DFC7214E651 -:1044F00083F1FAEECCC20333E9793F5D2EE2FBC9CA -:10450000D79B5C6F17031FAF3413A0CB4F5F35AB46 -:10451000CC0E8D43395CFBDA213384466A21BF809F -:10452000F6ABBD87C9DB4330196DFB3DD5632A7CF3 -:10453000B784748E81BCFD69EE9E0AC8DBBEAE6096 -:10454000FF52B8A7BBB64C79FB6D80EF0A91007C97 -:104550003F585E86FECA1DB70B48D7EF2CC6DFC298 -:1045600022D74DCB7EFB6DBAEECDCB53F09E6DA620 -:10457000BAA702E86DF6D5761BDCD34DCE15894778 -:1045800007C79B49EF5290DF335B6EBF0EF6DB40EF -:10459000F502C45D1BBAF757A4417DAD80BFA3D619 -:1045A000ECF5C8F00A54EF9A5332C43FEA683F4032 -:1045B0004FF35AD6AF798380EFF7D451F900E7ABC8 -:1045C000DB20107891A497DA7F5636AF0F3ECCD41B -:1045D000BB968EA7F57A180FF36E48C4DFBB6B7ECF -:1045E00095BD1F5457B4642FC8A73A3A8E3E26BDD6 -:1045F0001B6EC7F9E6AE1508A4063714657FBF0821 -:10460000E67BD58CDF0539D0F3A80CFBBE85AE97D1 -:104610004EE79F2DF655609EF5F70405F3A0ABBF5E -:104620008B783BC9F980647C87F199C0EBDC2ED490 -:10463000F4E3C6ACA12CCFFAAE25ED70AE3E6F4AC6 -:1046400036B844CDDB4EC960E77DB8183E3C43F137 -:10465000C6F3E0767B0FC97D3A39B52B6B188E9F78 -:10466000B3AD04F9FC365283F7E29E254C2F1F5C54 -:104670001AE313C01E312BA837772FFDC62370FE17 -:10468000134F99F1BEF444661FC6678FAC35E377CC -:10469000435AD78A28478E6C617121F1F1EB2AD3F6 -:1046A000017E540E00DDED5E5B26833C3CE2137020 -:1046B0007CD9E377A6B2B8AF517ED4B91A515E3C2B -:1046C0001EC3E443FD9AC8F7AB51E5C5A24A26DFF5 -:1046D000C3E4C1828C768CFB85CB89666263F65D10 -:1046E0003EC9877AAF3F1DE9B7E9553301FBAE49B3 -:1046F000526E5903743333066E92295FF8F7807C4B -:10470000FBD427B8BCF4F94DB7FE660CC0EF30C03F -:104710001BF8627532DEAFD6F96A11AE5A3E62FD01 -:104720001A233D6B794F3778C4D07B3EF47F373501 -:10473000C41155D7EFC03D942EE97AB76E137CF0C3 -:10474000FDA303F71CDC7B6701D615A0C3A6BBB88D -:104750005E5D6D47BA3DF09D534B812E6FB95BC0D6 -:10476000FD13AFA71DF44AD31AC10571CDFABBD909 -:10477000F87A3A1EE8E5C0A38C7E281DBB80CE9B4C -:10478000D63EB017FB6F105C30FF8175B5A8871B54 -:10479000BC22C1E71B0EA2BD4CF501E60DEDF68A69 -:1047A000A940E74D6D1605F0AAD18B467F07F9F7B2 -:1047B000A789D53DF25AF87D8A2C5744BA1367640D -:1047C000237D356F3123BD347B193D1D7C4A443A2E -:1047D000DCBDF4FA4AA09F131B8528F447E9AB20FF -:1047E000445FE2E3661C5FBF99C51776AF65747DD1 -:1047F000A48BD9A7658F0F47BFA6FE353361F1079C -:1048000062D3DB1FE7A3C370BA1BA097381D46A372 -:104810003B8FB9733AE41FD4FE82EEDF15825759FD -:10482000FB77300E50D67E039E57E31F78AF05F21C -:1048300036E6742C61F98C12CBEFF9D2FB0ADBC798 -:104840008321FD980FFA11F24FFC741F2F6E79022D -:10485000ED804F9E3C88F98DF39EA3F8A7FD4F6C29 -:10486000B1133FDAD93E94338D5D22E69712C95FCA -:1048700078ADEEFD2D2D2F63DE2FED08F7C6AD16BA -:104880005F351DDFF8ECA191784F7E2FB353BD4FFC -:10489000B2EFCC106FDFC86B213F5362F921E1FA10 -:1048A000D73684C5718EFF260EBFC7246CEAC17B44 -:1048B000A6C6CEEBCD165DDC521C6266BF03F19B33 -:1048C00038F69E19C53FDC2FC2FEF4BF27A1E5854F -:1048D0001CDFCCF8A7719B19EDA3C64DEB30DED7DA -:1048E000BCE914E6CF96FDF2A9788043F336D1985F -:1048F0003FB549F45B30CF4B3C6861DFE530E431D4 -:104900003575B1F73B9A3A799E5058FECCBC5FEEB4 -:1049100078D64B4133EF999FC5033F7DD4BB311E01 -:10492000E049E7C3FCA3AB8BA2E4279D2F2FA9731B -:1049300005CF4BBA0A7FA7233C2FE923F807D5E31D -:10494000F94338DEB5BCAE4D4C6E51EC17467A0FCC -:1049500049B35FE63DF5F98F218FF6F8D68F7F0CCE -:10496000FB9FFF8F4F7F0C791D64678C02F644F329 -:10497000936F61FEA136AE7A08B3A74E6CFE19E6BE -:104980006F9E78D78276E1891D47B2C05E38F1F418 -:104990009954C8CB5CB4A302E3138B7E5586EF8792 -:1049A00046F337813E7D17903F1A8E8FDD5DA2DF83 -:1049B00046F7F9C93B16E4FFFE3CB3CE052C7FCF8A -:1049C000C5F3CBB644CED3D5F2A19ABAAEBD7A1C0C -:1049D000C8BB2EA6D7FBF3A3CE9757F63B8AD74B7F -:1049E0002F007F5B78FE60E75511F3CA3E817F5050 -:1049F0003C350E31E6957DDE75DB4F1E83675D919C -:104A0000DFD3D6F8FA7C70D3F2802F1BA2DE3904F4 -:104A1000F868EBCF318F0FF056ED02FDFF7916C429 -:104A2000378F9A0318370CECB02890EFD5B8E30015 -:104A3000F2CB895FEDC73C5BC2F3714F90FE3F96AE -:104A400037C96317CD1BEC2C1F8DC31FF2D55CF14A -:104A5000D8CEF3D2181D6BF96AD1F2D47E3E84D938 -:104A6000415A7EF20257AFACD842F802FC084580AA -:104A7000AF8386FC3FEDDCE1F3290087CBF4F997A7 -:104A8000D1F201B99D3E005F4C2E9F58C7F331FB18 -:104A9000F32CA949970FF9414C1F36FB840391F081 -:104AA000ABE55FFE340CBFDAF9A2F185C69FE7DF04 -:104AB000F75783CB9A212CFF5F83CFF1B391E57435 -:104AC0000FE777EAB7F887E8FC965BB9DFA2E59DC8 -:104AD00069FB6DEF647AF9F826663786F3775394AD -:104AE000DFD37A6308F3EF9AB6F58C0439747CD778 -:104AF0006F38DD31BA6EDA7250F672B9EDD3CBEDA4 -:104B000028BF5FF62EDF37F57723CED7BCE554C438 -:104B1000F93E92D4EB61FF1FF5323BE4A34E31E244 -:104B2000EF20ECE67AA9FFDC7619FD2E313E16E582 -:104B3000D1227BD13BF05DB7457619F31D5A97F032 -:104B4000FC887BDCF83B1EADF649F8FB0F4B013EC1 -:104B50003A3FD4AC78F07727CCCE9A02F0AFC2DFE0 -:104B6000EB941D26E2D3E35FF2E2FBBD5386FE45E4 -:104B700002BDD3BBD8F8DE48AFA4EC49A6F3F59646 -:104B80000B6EB07707D29971FE6B54D1103F8358EA -:104B9000359CEBB49B7D0FCD6EF22BB40BB1C7F4FB -:104BA0003AD1D173B1DFABFE1F05EC5EF50080009A -:104BB000000000001F8B080000000000000BB57D06 -:104BC0000B7C54C5B9F89C3D67379B6437D990047A -:104BD000121EE1ECE64D4258C2534539092426F233 -:104BE00070414554D4253CC23389F8B8D4D2B24080 -:104BF0008C88B40D824A7BD12E34A87F4B5B40BC9D -:104C0000050DFE170816ADB551D16AFFDA06880802 -:104C10001A6005CBCDF542B9F37D33933DE764438C -:104C2000D0DB7FFCB5C39C7366E69BEF3DDF7C3336 -:104C30009B48E89F8790752BED598A959004E295E3 -:104C4000884C88D3AB04DAF208FE5DA1FF4B24B494 -:104C50006EE775371647B34613E2608FE87BD701DE -:104C60008B44485C1EC9534612E222715E99D637C6 -:104C700026686F4A0984AC77FA27D3CEC915F81B8A -:104C8000DFBD245EA51DC6B3D3FFAE507812C7D2D8 -:104C9000BA3D327E9266AC27135D1DE1D108E90B67 -:104CA000CFE99F4A48B94C21A3702495598231120B -:104CB000BE9F9CDD37026F522AF186E0FD148737D4 -:104CC00040BF7738187C025E0ACF718047A5FF216C -:104CD0003C856D010B41B88EEBE1A07F92CF89F04E -:104CE0001D37C1775C0FDF30D59972B2805614A2A0 -:104CF0005CA1F875D85B09C7F3793D9E0909106579 -:104D000034E053E095BEA7FDB8A54DCA1509F0EAF9 -:104D10009248268E676A37D075329ED769BF7BE18D -:104D20001FD711D27F89DA62A3F3F4D92517A0A186 -:104D30001F85B51590A0B4DA0019CF3A443D64231D -:104D400085F4BB3DEFD9DA68B974E77BF8DE02750C -:104D50005A26C7AB13070C27E4FEE0305F5A3E7CAF -:104D6000373BCDE2C57AAB924A48C3347F9A653867 -:104D7000803FACB16520212F92BA21127D6FAF2FF9 -:104D8000683D7223F015FDEB0FEF0B5AB54278CF5B -:104D9000EB8484089DC78B715D75CD9E46EB9EAEFE -:104DA0007A00EA4D80FCEB61BC82D67ADAFEB0EA8A -:104DB000BB5B1D45C8B4E72C444A21647CA723286B -:104DC000011FB4F521241D9AD5C5015DBAF119C59D -:104DD0002F498D7CD7233FF2EF289C153BE9FCA798 -:104DE000F967FB268E20648CC4F04A5C6D23A63BD9 -:104DF000018EAA256A6AA4DDB4E7CECB1E0ADF12B3 -:104E0000CA53D03EB1C2754B1E852F710BC5960A91 -:104E1000DFFB1F00B8B357F82DC01EE349DB831238 -:104E2000A527F93405E111E334EC97917F1B1EB3FC -:104E3000045723FFAA926FA89E7E6D26FA8519FD5E -:104E4000F61E43FAD5341F63F4DBBBF500D0BFA6D2 -:104E50005972C5A8301FEF2ECA44E4F1E0049F3216 -:104E600088D23526DC0074B59212DFE47CC4EB6393 -:104E7000309F6E78E5F0F586D7174F6D7BB2887E50 -:104E80001AE8B078B349045FE2BB1DAA0DBF2BF24C -:104E9000F89F023CD46E6A6B88A570BD76EAFD046B -:104EA0003F8537BBE37CA888C29B3D0EC5B86BDC51 -:104EB000173BB61DB0D17FBE087C4C5FE410FF6A83 -:104EC00097E36AF860FCDD858F3DC7103F16A8D3D5 -:104ED000E7BB6D6401D0B574AFA40581BF63C8FDA5 -:104EE0003E5A6E5729A351B8F6A9322F2546C70E50 -:104EF0008FA2D2F6A5B75BB4202D137919997F3D07 -:104F0000FF5E61FCC5F121E829F88890C6F8699434 -:104F10008E79B9FEDD46BE792ADE43DF8F6F3FFE14 -:104F200020B144DA6D5F497C73AD91EF28FFFCCC72 -:104F3000D0AEECE1387F61E47BE04BE013337D6879 -:104F4000BB109397A7E2611EFBDACFCB80EF6BA576 -:104F5000ABF979EB4ABF6FA2B567F9F195C83EC0CE -:104F6000ABF9F9518E5FAA1902ED79A0B5259248E7 -:104F700051DD2FDD7F14E05B6A6F4BB89DD2B7A681 -:104F8000E4820DF0B03AFEEC0DFE28FDF40447EB90 -:104F9000A55C878FCEEF60670CE2BB5B3BA0271D53 -:104FA000E7DD95337D1329833E119750C4952DDAA3 -:104FB000B3895CEF4ECC5A349929AD2EBB275D895D -:104FC000216810146A47CAE00985AF62EC2E05EC2F -:104FD0006719D1D94B37F6BB8D0C037A580D766D16 -:104FE00052D62DA7C1BEB42A6D6B1229EA5BD32419 -:104FF000B43F375F6A6C01DB75739AD560E72A5559 -:10500000637D126176528C334DA374E7EF2FE0FF7E -:1050100007717E53558A5ADAFFD4ACB860804EF9D6 -:10502000D6B177F926EAECC57B97E5FB7D85DDF106 -:1050300033D92DF0E343BCFE3E96E26718CC73767D -:105040003D43D3D5F161C6A3192F133F9D3F99145A -:1050500075C7CBB5CEBF0BAF84FC04E6374993C907 -:105060003A7704AF66FCD0BF29F0DD7B25F43B091D -:10507000FC820EC542EB95D74944F805657D7574F1 -:10508000E7F099F16AC69FF03726F176EF00BE2867 -:105090003F4D92B738801F2A7FD43A3199EAB1CA7E -:1050A000418CBE2444914BF17213419C015EB721A7 -:1050B000DFB9ACE86750BBCEF8E3D3F2D3121D7F63 -:1050C00072277D47E12C57A5201511C0CB71135EC7 -:1050D0008E9BF8E2B87EDE66787F0FFFB82E0ABF9F -:1050E000288D7920F713DCD43F01FF2183A857A82E -:1050F0003D1AFDC9C844A61FA2DBC9F19DBEAE7E04 -:10510000183E1A916F24E2EF7AEEA2FD84346B0A06 -:105110004503996077A19C4C20DA9A763BA04246E1 -:1051200038055C97D37CB7BB69FB1252B9A65D8F7B -:10513000E74F853D67F89EC0F13781040EC80950DE -:105140002ADFE8E72DFABB57CC6730190CFED08771 -:10515000AACAF432EF4FCC2F399984240A6058B28E -:1051600007B749003F09D8FA44C6B372FA9ECE9AEF -:105170005EED46BD5E47005FE0B6003D4BF9FB5279 -:10518000BB2304F010BBB5A38B2EE0C390592EF0C7 -:10519000FB285EC895F8087C0FBB25E5645E04BE5D -:1051A0003347EC0199F2F5C474FF0F000F1DD23B99 -:1051B00045802FEA97E5803E37BFBFF0714B0DBCAD -:1051C000A7DFCDC7EFF8BC1683D34DF926BC3F2629 -:1051D000B8CD1D4D9FAF62FAD74E3D519D9C96C6EE -:1051E00031399F447C0AF8970763999CB5C42E44D3 -:1051F00079282775F543697F7F8CBBF908C8592545 -:1052000009E077652E231FF6C6A7B790F07DE0F77B -:105210004ECAB39AFCE800D2E7606C6E16D8B3832E -:10522000B14C2F0BFFE165B7EF5937BECF08825E57 -:105230003EAE8D7A17EC4455C9888F46D2D262F7BC -:10524000D9809EF380BF285EC7027FD1B607A1EB4D -:1052500074E4AF20B49FB3D6C45FF664ECDF47D5E7 -:1052600018C055AA59BFD5FBD55D78E376B2377F14 -:1052700091B428248FE2752EE7D383B13101F0E396 -:105280004A9FA0724CF13787F89F6F94000EABC114 -:105290007F9F1B6B457F6FEECF6351DE69E32D75FA -:1052A00074C8F9F4F93ADA0FC95307EAED3A69D448 -:1052B000B507FADB55E4C7B92EF6AC9DF691DE07CB -:1052C000FAA5DA8DE2936CB69ED7F3A579FC1EFBA6 -:1052D00035B53B28919960570F5AD5815E9DFD7871 -:1052E000D36DC1F99FB7676FB1787AC6D37C7BB2B3 -:1052F000A68C88D44FC6C6CE8CE62788FE045EBB3B -:10530000D617E49BC6967191F5C563ABBF6E3D326F -:1053100048BFBEF8BA55737CFFF5C5A9AD5FE3FA87 -:10532000E2690BF50F016F8A2F7F9ACE2FFADACD43 -:10533000FC976096F635C8E1D3DC8FA41C943F6DD2 -:1053400068F7EFFA2E9F404E50168BB193406C31A8 -:10535000D5030A09588BE17BFF2A0BA5B73293A02E -:105360005DA27A08FD4F331E4E6795FE03F856C8BE -:1053700067691CE57F2A8F4F58D4A646F0B3DF96A5 -:10538000A9CF4A475F3E07FDBFDB962FC4F2DCF191 -:105390004B39A0174A39BE150FB3EBB5F14CAE6AC5 -:1053A000E3991CFD31CDAF78E8F3564D768EA4FD20 -:1053B0002DDE2B7B63102DE10CE0B7DBA6C8A9F036 -:1053C000FC84DD8AEBC7834E46FF1344AA00FC949D -:1053D000BE17E3DB43CB47D34A723D3A3FF1D1B42A -:1053E00089582715D4E1A37CB9CCCEE4E10471330C -:1053F000B8D74ADEEDF4D1F9B5EE44E0CF8356627A -:10540000F047D23D0AC29BEE6178ACEAA4C2398271 -:10541000F15D1D1DBF4A516DE0FF5775DAF039C0CF -:10542000817C196BECC7E361FEB8C7C3F8A9AA5326 -:10543000C220C1C158733F0A7BCEF9DB4C87A7DC81 -:105440001372603E8FA669B91EF45F5505F0533A9A -:10545000B2E563D087BDEBFF8004FABFF692141A61 -:105460004CE7DFB1C78AEBBA0EBE2E38B3E750DF88 -:105470002A5A2EDDF54102AC1FC7727A9D515A138C -:1054800000BE25AF527FBA10D9B9EF3DD87ECEE825 -:10549000756C18BBDE2E5E7F3973A00FBFA3008E24 -:1054A0008EF86513EC8120C07770953C13E846EDCB -:1054B000A6F0CB24D093657B642DB6A8BBBF36D5B0 -:1054C00063E5FE3AA3E3432E364E4FF25DDA194F01 -:1054D000823AF92E555405E02FED4CC0E7674E6D2A -:1054E000DB3895F27D20CD8AEB436A855AD05F94F4 -:1054F000085FF0D13A9D4F0B9FCFE13DB7DD7E03B2 -:10550000FDE79B607FE83713DBFC294CD8E9EA6EA6 -:1055100074C4FF2A7319FD44B31F29EC5945F3865F -:10552000FA0104F01EBCED06E0C3530A013EECE6AE -:1055300067DB6FEEC19FDC807CF4DA9E5FE13AAA04 -:10554000C8A362BD76CF8572E0E31A129A01FDD638 -:10555000EC915D21FAF561B2A700EC8AB0FB022F55 -:10556000A14B87EC5EB00BB1B26B35CCD37E8743D9 -:10557000A578BAE15C610ADA3FBBB502F462696CF6 -:10558000B6638E8E9F0FA6C815C0078753328DCF86 -:10559000ED1B0BC0FEEDB3307DD472F26E471B7E67 -:1055A000775B0AFA71C2EE9BFC561127ABCC96834F -:1055B000D1FC61226FD9144BDF4FCAB51219FCF729 -:1055C000B645E80F74B3FB97FCB83E30DB7F8177BC -:1055D0008A6994976E7E6B04CF06FFF5690F8F97EB -:1055E000A96428F8A3A14B1B17039CE79AE35DABC2 -:1055F000311EC1FC9D73ED8B364E81E7EFC8185FFD -:1056000039774946793AF8C6E2C16D3A39A61604A7 -:10561000E97471F8D7675FA7F4B9F8799C3780FC13 -:10562000B7B320DA7A59ACA3E8C8FD2D69087F7FAB -:10563000CB5814375CB7DE1459B7FEDA83EBD6705B -:10564000399893B42DC76CC01767A80B0FF00628C4 -:10565000F1B753BCDEA4B5C92E1D3CFF97CB7791A3 -:1056600047DB057A25404A0750A7852C88D34A6E28 -:10567000007F741A716DA3F3D97FAA54B2D2FAB81D -:10568000ED6EAF44EBBBC12105BE7D550E6EA77814 -:10569000D84DF5F16EDAEFC2D6469B9B8E1BD843F0 -:1056A000811A43EB9490808753D64046928E4F16D2 -:1056B00065B2714F59FDBF847E4E7D1243607D7887 -:1056C000EAF3B8A876B83893E9CDD7B99D7364AA40 -:1056D000D83ED4F1DA9BFD295CA14ED770C0FBA265 -:1056E00097BE9667D3716EE4FEDAE44DADF510D740 -:1056F00099BA25AC80FEF1055D656082A7BFE4B56F -:10570000825DBA7D87CF0AEEF98C3D7556783F737E -:105710006FE361A8DF1DDA89755BA6FF23C0EB4D3F -:105720006BC387805DB21A89027241BE617E589850 -:10573000CB9DA7D37B3011B9BAC4027CDE35FE8A7B -:1057400056055CA2A9F56C7CDA5F1BF657179E0024 -:10575000F62D6339EB2F831C5895A846FA1D7FA9B7 -:1057600055D2C71B4A7FB804F9E8F947970C4E0693 -:10577000BCFF358664BBB96CA4C0F38141587F126D -:10578000A52D7FBADE3F23A118C637C4CE4AC14F2C -:105790009A9DF1912B0EFC85479EA98B03FD90E20B -:1057A000536D7E1D9D4A374E1EF216F0696C0CC675 -:1057B000ED2E0E677EFDC50D8E6080C5BB8700DFB8 -:1057C0000A7B5505F436C4A384BC33BEA75D04012F -:1057D0000E511269B58BE8EB24940670757A187D2A -:1057E0009B6CEA2C18AF292EC605E355D9B36DA0E2 -:1057F0009FBAE29F1044A47AE206EE6FEE3F753046 -:1058000019E87A71F8AA0C5817842CFF8EFAA83779 -:10581000BE5AE2D1923211CE4006ACABC4F7FB4E79 -:10582000C615823D7C5DF861DED98361BEA25D5103 -:1058300026F30BA83CE0FC851CA4B4126D6B21A2DE -:105840004ADBADC3477E268BE38972B7550D3039ED -:10585000A27E08C8953364CF0479DD9789F5141FBB -:105860007178E9FBDABDD95E594539CFCF4C8DC887 -:10587000FF8D5CFE535AC32877D7BA3E706532BE9F -:105880000D293BB9FC10D443203F4C4F870630FE16 -:10589000080C00BA805EE0F449976859CDE92CE61F -:1058A0009DC2E57E2A976BC003BCAFE4F314EF6F93 -:1058B000E6F82A930B13DBA2C47DBAF86E793A019D -:1058C0007FB16CF9002C2B39BC0BED1B309EBA302C -:1058D0006503C65153B4462C174E6CC4E7695B662A -:1058E000237F2CDC2C19E2A2A27C81FB5F674E593E -:1058F000D07E114B5C7FE03FF1FED7E067B0B8F09F -:105900001D80E7D37B363E53A446E2C2A79B983D59 -:105910005C1067F4EFEEE6F3DAFFCDC164E0978B3D -:10592000B18D53EF0639D92EBB56011D9BCA2435C4 -:105930000AFFE9F10C78AD6DFA4739CCA386B4358E -:10594000809E3ECDFD32B559427DAAEEA5653F2A27 -:105950002C4D4CBF9EB232FD7E4A4A96403E40BF1F -:10596000839E3DF5F9BA8C47818F2427FA37A037FB -:1059700077E9F863F18EAD0DFDE93F6FBAE41A0ED9 -:105980007C15528843AF9F059F087D6B867B05A7DA -:10599000ABE0C31B22766805E00DE2A740B29A0D8A -:1059A000E7317EBA81D3AF09F80DE479ADE0B7E114 -:1059B00016D4A726391EF32FD2DFFB9EFA4506C662 -:1059C00025C652B9A5727D1AE43A0A5FFC9CD36FD2 -:1059D00089C7BF29338ABE3F2DF97F999C1969BFBA -:1059E000EFE42D43AA74FD3CC8F171D1EA1FEC8AA3 -:1059F00082AF085E497FA0F3024A19C003D922B9D9 -:105A0000C0EF13EF53B6B07D8097B91C89E7A22E83 -:105A1000F03D1EF09D89F87E3993D97D1B98E4B442 -:105A200020B3FBC4724B7FB0E30BE3B45B300EB327 -:105A3000C14220AE44A452E4F794A6A74F5E1E09CB -:105A400065AC07F755A85F0DFBA50B9F50711DB8FE -:105A5000FA8558E4B350A607E7B5BAC98AFC76DAE6 -:105A6000DA98817CF9F9A2C1B02F13F884D9A19EEC -:105A7000F029F8E727DC5E0BBEF3AC677CD7A4689F -:105A800071C077C28E0AFE3CBDFDE6629037D13E02 -:105A9000C237AEE1826F66D3E79EB56D32D087D252 -:105AA000ED8F8087CCF561D45F3DD14DECB709FA1D -:105AB00009BD9E906531E0FB330E7F0AF75FBAD3D4 -:105AC0007195811E3746F8FF5333FF5BD5883CFD47 -:105AD000A11739B83ECBC5E20C9FCD4903FD22F694 -:105AE0006BC43EAA18FF2CE7879EF65B0EABFE3315 -:105AF00099BAF9C07EA08A7A9DEDAF94717F7BD967 -:105B0000F698600CA5DF3E7805FAA23D2E087EA22D -:105B10006897AB104D2926E4BF33DD385E2EA80A06 -:105B20005A4F596E235974DC8BD71D6849A0DF4F3B -:105B300009B74D1E46A7B6CFD676FBAD10F725DACE -:105B400022F02730560F7CDEC1FA25AE9D0638AD17 -:105B50005916C33EA898774F76AB277A5C9FC5F756 -:105B6000C7F87BB39C1FE3F83AC4CBDEE53490085A -:105B7000727A1309AC82FD117289B8C01E77C9E927 -:105B80002582F6657096514E453D8A9C0ECED2CB4D -:105B900069671B93532E8F894D562D9A7F32348B14 -:105BA000AD7B139BCA4AC09E24FA08C63FE8345115 -:105BB000AE1752B906790D807CF6037C32FEF2688E -:105BC0008DF7C17B4F13F3AB2F26B1F92EBC513BA0 -:105BD00020839C53BF5EA29F3672B9EE19EFA14499 -:105BE00089D9A744D027378D6B9B00F656857D81D8 -:105BF0007E303F46DFF1E3483044E9AE5E224C4F51 -:105C00007CFE8BFB1E05FDB0C1E1CD5623F627ECD3 -:105C1000F197001E7A9267CA971AC4A396FD9783DC -:105C2000AD037BD81F1FBF5C46FEA37C7E4B960E48 -:105C3000FFE37D6119F09A1CEF4FB32611724FD329 -:105C4000D0E9F641747E6EEADFD2FA4C5A5F0F71EA -:105C5000B73E6D84D79F72A47FFF38DD3D5985EF35 -:105C6000D753B80399DA5D59A9B86F7D0FC073D3C4 -:105C700080B00CFEE7B5EEEFD7427C8ECEE7F81D84 -:105C8000435E984D9F56DDE56B80B7228E3C86C7FC -:105C9000916B9B87637C59174F5E94759578726FF3 -:105CA000E32670B9A7FC8DEBB884B16119F4A2D0DA -:105CB0002BCBB3FA707E6E23B0AE10F2057A09FCDE -:105CC0005A916700714527EE5704F17BA8271647C4 -:105CD000F4CDFA464B4534FE7E3CCB11558F92E60F -:105CE000FFFE8F4747D3F9C22BA6571FCFD2E9D566 -:105CF000A6C6E37D999F4AAD3CF51B1EE46BF98D6A -:105D0000ABBD7FCE02BE7B57C678CA7531B6800464 -:105D1000EB7E8DA8AEBEBC3F10BB6629E42CA2F57D -:105D20006F25A2419CF25B19CB8D3FF655B8216ED1 -:105D3000F2B1C5BB9A60BE02E267EC6012B4D37FD9 -:105D4000EEE5F1CF92130E0DF200CE4976D49FE727 -:105D50008EC505C07E9E735A306EDEB23F06E5E208 -:105D600042561C8F67040D710FB19F73E19D39C9B5 -:105D7000A0F79FE1FB9BCFC4B2B8EA3377E5603C64 -:105D800052C46D1585E2BE0F84A9285EFB807F3C5E -:105D900000E3A9228EDBD73E5B6249456C1CC5CE71 -:105DA000E6D757F14B101FDFDA4B3EC4EB59361ED6 -:105DB00007F0EF01FEAD5DD1668375ABF07B855DCD -:105DC0001EDCE139007911832B58986C6B87C50272 -:105DD000F3DC4AD929C9DD9DBF041F6DED9E7770A4 -:105DE000204B17A79DF618CB3BE8AAF376BFE479C2 -:105DF00007E3DB8FBF02FE1C95F75D867665A97110 -:105E0000FE287A6BC6F21F62FB9EF87F8685F8A398 -:105E1000D99113427F2B7503C04E91BF3F12AF46FD -:105E200089CBCCF8AC2A15F0628EA745C6FF318E1F -:105E3000FF59168F1F65900CD85FEB6D3FD30CF7A1 -:105E40004756FFA068764AD0D93C5EF7F66C1DD65F -:105E5000F59D8DF8773958BFC5BA7E53B299BF33D7 -:105E60004362FBF5E432417B2DF884E2FD3F812F54 -:105E700046FFE9C48838DCE709CBA00F2E7C9C35AF -:105E800010F7DB7B58770A7808F16747CBEBA0E384 -:105E9000F9A2D121299BD1618695ED4748776563A9 -:105EA0001C60466C8C14A3F34F2E77D95BCDB02FBA -:105EB0007B3076CC488C5F5AD581D1F067DEAFBDA0 -:105EC0009C45905F012FDE28FC24F695059E1B4A19 -:105ED000B41285C5C7C83630811AD3A3291504F773 -:105EE000D7C6481AE223339BF94D5B79BEDC857730 -:105EF00064D40BA34BD4206C91527BE1CE1E85F968 -:105F000057AF5874F957824F1A7E43EDB2217EC8BD -:105F1000E44AAC9F93B83EA65EA3B64BF79DBA0287 -:105F20007440C41E0CACB71BEA190FB988A2B31792 -:105F3000495A9AA13ED0E78A8375D3C00AD5D04E7C -:105F4000F09DC8FFC3BF1498B70BE34F7D383C6387 -:105F5000243FF20DE837880F97707AD2F98EC7F98F -:105F600056B45DD0F38D986F6FF33ABE92C243156D -:105F700058FB4A0A2FD50B73D6BB57A521DE5D040B -:105F8000D6132757DAF1F93CDE3E69D3EC86743A32 -:105F90004452BD8A71D924ADEECD74C8B7ACA37597 -:105FA000FA37B7519260BD4EF50CB67B6EA50B4B20 -:105FB000416F177D2F817D2F2579B04FD3931DF32E -:105FC000673B0CEBE1ABD8317FF6A8EE76CC62F7FD -:105FD000BE05FBFF4B9B6515F862CDE43E1AF0D37E -:105FE000C69D9217E26E879A591EDEC619CC9E880E -:105FF00071CFBE9A8876E3ACC4E49CB424A11CD4CF -:106000002671DAD427E17EEC39BEAE5E91E5AFCBE6 -:10601000D6E9CF8DCDA362715FD66497E89F4BA27E -:10602000ED700F4E02FF69F85A2513F5C072809F7C -:10603000CC6F1B119B097CEBFF609C047AE09B0CEE -:10604000A0A7795F4FECFF897DC13FA6F95765EBAB -:10605000F456F7FD3EE33E959C60C73CDEB132CB83 -:10606000E3D5D95F02745D037E22E5BB35C7E2103C -:106070003F6B2E33F9A370FE04C669718E467E1203 -:106080007696C259F42EE90E67AD258CF1421D9C1F -:10609000CF5C1D4E539E2B87AB0BFF7C7F4A762A2D -:1060A00008FF3912E70538F7DABC1FFBC10E9F8DD8 -:1060B000C3F89EA04F0D97B173941E1285F3DCDEDA -:1060C00011B11607F847FE17805EF2A07002F8E7DC -:1060D000879A47E4C37C7ADAA73D9255FA7236CAAA -:1060E00099FF37D06EBCABEDC26FD5C8FCAFB2BF65 -:1060F000BB0BDA7D07FCBCA6E7A3DEF053AB38D6BA -:106100004A2C408E7E98C4F5B499EFA4E603FF05AF -:10611000794754DE30EF339041826B28DE1A8632A5 -:10612000FE2373898A76D9C4272BB27C6F03FC4285 -:106130004EAF829F7701EEDA2C5F2B7C0F700C281C -:1061400046BDF47E36B36FAFD82CD89EE5AF241190 -:10615000CCC731EF9F9FCEAAFA04DB0BFF2BCF2FCA -:10616000B90ABF931C1CBF3A7F85902F96723C2DB5 -:10617000857D5DC857DB63ED30E44598F0F0789697 -:10618000AF83E181F2D948C6676BC855F11186EF3C -:106190006BB3FC17002F4E2BE51740CAD8D9698086 -:1061A000E7C3AAF635ECFBEF5EC5F071EE4F0C1FAE -:1061B000FBDA2DC8D74F93212897C596F3F741FFF7 -:1061C00054BF5C867EC685774AB06EEEB740B58018 -:1061D0005E1E10F6CA96ABF3AD9483EB27BF022583 -:1061E000A5C383408711EFB078CE55F8D60EDF7F78 -:1061F00007BC27E57C07FD43F92A15FA177C75AD26 -:10620000F956942FC8803EDDFBA3EB28DC5F38B045 -:106210002F06F555CD6E09F579CD1B5FE07ABDE609 -:10622000B51864CA89AFC5E2FBF37BD8FBB325D1AF -:10623000F3013272FAA0DD59BAF3019FD14E07F093 -:10624000F9CFB4F3AE2C39B2BF9A3C859D435813B5 -:106250002BF24DD93E6B02E7B3E4413E0DEC507298 -:1062600019C17CC10407CB43EC7EDE80C96D2A6F67 -:10627000E772A912E0D97CFE408E63F985A964FD1E -:10628000D780A7E40AE3FB544705EEBBA69ACE29C4 -:10629000087C97E570FFD946D2408FEC34E55588ED -:1062A000F2FD1CEE07D627E17A50E170B5386DC8D3 -:1062B000B7CB9C769CF7B224923C19EB0ADA7F7339 -:1062C0003F5DFEA76621AAFE1C45451C5175FE5187 -:1062D000AAAF8FA1DE6F667FC3F7E97E8FE1FD80F5 -:1062E00005430CEF07D5151BEA83975F6FF8DE4D6A -:1062F00011A0AF67AEBDC5F07D76E374433D77F383 -:10630000DD86EFF3835586F7052F2D32BC1FBA7358 -:1063100099A13E6CEFA386EFE51EFCF26773589CD3 -:106320004D167EB973A41FF84A76DAA518DDFA6F08 -:1063300019A7474942451AEC5BD63BCBD3607DDABF -:106340009244EDF155E26EDF77DDD628E8CFFDAF60 -:10635000521E773B7B906A11CA7F3587281F0C43FA -:10636000FFAB3187FB5FB355F83E6C437BA278717E -:106370001E3312EC184F33F7BF2C478DBADE922D27 -:106380005ED764A9677C09BEEC0D5F9B395EFFB7E1 -:10639000F8FAC8943724D67BE6767FCEB1707FDCDE -:1063A000BF3B47BFAE2361D987EBBA6FCE0608E883 -:1063B00051827E4D6DBC0BE312663F408CFFC734AB -:1063C000DFEBD08F599FFA96CF67DF59E80243EE93 -:1063D00079BDF7E71CF37AAF6C26D223C966C0D328 -:1063E000FE2E3A6B86F55E7DD2685CEFD55BB5B468 -:1063F0006B59EFEDCF2188EFCD40D7541D3D6D5E39 -:10640000D5857ADEE8BF74F7CFA9FDA3F3DC087E5B -:106410009D047E5932F3D7774B386F31EEF7F0CFCA -:10642000DBF5F6A927FF3C8678D72A32D2EF4BB0AE -:106430004FD41F7F3056FE5EFEF885EF620FDFB748 -:106440007A318FFDFD29325945F178A1624C3F1216 -:10645000451F8BF2288FDFECCE2548B7DEE21FEF19 -:10646000AF5C70D5F31CEF57B23CCDE9C047BA71B1 -:10647000D373195F8CC8E5FB92312C8E71E63F9C7B -:1064800078EEE0CC2D1F261027E4B78D1819803C3C -:1064900066E27D08F26F020E27C609A7578E1AB969 -:1064A000CAA9E3ABB10CCF137EFFA70488FF4CDF72 -:1064B00095991A70F4CC4F23F8FC88D2968379D939 -:1064C000AF9FEEABD272FABEEC5416A734E6AD998C -:1064D000E346D397D718E47869A74482C9BABAD2F9 -:1064E0008AF9814B3B157C7E39C71857EA115FD773 -:1064F000884FF37381CFF72B4F67403CFD6C6C7472 -:10650000FFE37E8EEF2EFE319D83E9E97C4739EF74 -:10651000FF42C575FD40CF4DB7A9D9D712E7127814 -:106520006ABDF4453CE88937E07C4D94FEC7E7B28C -:106530007DA537B4CFE1F80329B1872700DF97F0B5 -:10654000787A94BCFFDB7261BDD459F12FC9FB9FEF -:1065500095CBE9C3F3EAF372D5A879FFBD9D5F9AA5 -:10656000668B6EEFC646F0F721C8EB83CF595D000E -:106570005735F84E10BFDB6AC5F8DD07976208ECA7 -:10658000A77CB1C5FA2BC8575BF05CE6739B687DAE -:1065900041650CEEFF546FB5B2FDB9CAD82084AA8C -:1065A000166C7DB8EF1C3ADE57546E9764D3F7CF64 -:1065B0003D8DF9331FB4AFC3FCEDD320CFF4F98286 -:1065C000CB8FCF00FCEFB335160CA7E5921D92E1FF -:1065D0001CC6A2A658435DE4030AFA1129723E4381 -:1065E000A5F6A421D7781E6B4464DFAC2197D96B44 -:1065F000CCB3AF99C2CE631D3AC9D6FB87B358BEA0 -:1066000060A8F2CEC9C3E93C2A53AD182F31E71771 -:1066100012824427F379FE6FE5270A9EBBAD1CEA80 -:10662000443FF0CD95754807DACE51A63B8F50F91F -:10663000731677A974B3BCF91EF30E4DF986E27C8C -:1066400050B73CC3C8F9A0E3D1F8E657B946B93E04 -:106650007492E515CE7F4766F3EA456F1EE5F3F8C1 -:10666000A07DC8BDBFA5F8F8A08269F10F2EDDFCA2 -:1066700018C4BDBEF04904F23CBFB814FD5CDA3F5B -:10668000BAECABBFEBDC0ED0E7B68A855D7510CBFC -:106690003B7C0F18CEF55CBBBEB9BA3EA9CE65E710 -:1066A00032CDFADDCCF7FFBFF4FBF4CAC3190127E2 -:1066B000962F40D9B18BE947B39C9BF5B980CB0CA1 -:1066C000EFD24ED990873C16F4C028BD3EB7E17B8F -:1066D000EAEEE37C02A395E01A09FD80CF81EF4743 -:1066E0003A82C92574887AD7B6F8ABC56FE8FAF94B -:1066F000347C5FE3F6774099FCC7FEA560EF47BCAA -:10670000B313F308CFF5904FFEA1DB94BF2619F722 -:106710000BBECD2DF910D6FFEB54560AF91C498556 -:1067200090E73B7C9BCBF6E57E0AFB96356F5D449C -:10673000F97CDAE64F83F840A0BFCDBB3D4A7E88A6 -:1067400092F7DDCE25EC80F83CD03D2FCFB0DF07AF -:106750007122CC5B381E8771A2E7D3B4B83CFADD56 -:106760002B695A7C1EE8F334CD91A7B34FF57C9E7C -:106770008A25BA5F5C9627F8DF87767C5E29D5BFCD -:1067800051F8D09BC7F2F94B9EB92B03E2719F1FC2 -:10679000BB3B03F463CBD363AE9AD7F633904FAAD7 -:1067A0003F9F04BD9F1DD94FFD09971B11EF9E67A9 -:1067B000F3E5E8F3B192F392D87EED75BB5B3D94BF -:1067C0004FDAD7CBA8BFDB1D2C8FED8443A9682AF5 -:1067D00064ED520CEDD8F90519F89ECAB1E250BE2D -:1067E000D5EBA332E0E9D49EE759C6E964235E3BCA -:1067F000B4B71DBFC50E76549634178BFF337EB8E1 -:106800008E8E00FCF038D76397D3FCE301EF366E31 -:106810006FAFE3F6567198ECEBC0ABEF8FEF4DD353 -:1068200026423F77A7696540D7BDB64001C8CDDE97 -:10683000B8E8796993F2983F129BC7F98538D07F01 -:10684000C5F164DCA79F9AC7F6E97D50DE3420BC11 -:1068500006F2C93F74BBBAF6B97D789EDE7707BCF5 -:1068600027696DE456C893A3C0C23987D74F1D2747 -:10687000A0BF12C2ED04F269124CF9AEA2FC2A8F3D -:10688000F91FAFF17DCFEE72C7F8CCCFE16CA2F269 -:1068900002E74185BCC0FE3AE44BAC53FD5CEE58C8 -:1068A000BE47D3537D24D867F168AA05F803F24C9C -:1068B000413F99F3839AF3981E053994AE22870FCE -:1068C0007F47396C7A6AB22516E07C94605E075582 -:1068D0007EABEDB4FEFC329717CE8765AE27B80EBF -:1068E0001AB43C6E1BAC93025C9E066F22AB63E94C -:1068F000D76E9EC727F2A2DDF56D0A9E177894E544 -:10690000E99DFEFC16D909FD7F2DFA37E6058A3C84 -:10691000BE468E5F318F251EFF93C01FE6BCEA9EE8 -:10692000F3BFBECC873C87E784BCF33C9C713C0F33 -:10693000675CD3D3188F1BD774B322D14F9E5742B5 -:1069400012ACF79EAFD314B037BFCB637939BDE536 -:10695000C1BDCCF9B191D3B9A77CCA17F87751F270 -:10696000295FC84BD5E593FD80E5533E9EA7E2F72E -:10697000CFF33C9AE7EB58BC6ED14BEF49FABC39E8 -:10698000F19DC8BB1BF810CBBB7B5E698B05FEB9C4 -:1069900018CBE875F10771C15518946F1B1EFD1CCB -:1069A00082398F9CE58F0F0E874B301F8810BC07F4 -:1069B0006148BE6AA0CBD6B02B0EE4A5377BF0268B -:1069C000A7E7B5F2E18BF90C9F51ECE63B80AFEF06 -:1069D00060375BF398DDFC20EFFBD84D6E2F85FD13 -:1069E00014EF8F717A56E751BBA9F36B7576F358A4 -:1069F0005E14BB99428298A7413A2C5E7D5EA8281E -:106A0000FDBCDFB73DDA17D07E1C8FA724741C278E -:106A1000924E0F4DE7722DEE9778B10FB97F5A94D1 -:106A2000794CE1FD596685F13E8A8466296A1EDA51 -:106A3000876EA64FA85EFC4F94B3C1546F4ADDF534 -:106A400066147AFC13BE1FF08E760898E4FAA4A6AA -:106A500078709FAE420F4B7E2AD04393A114F82F3B -:106A6000BE625C470AFCC7E533F9ED9BADC5E6D3D2 -:106A7000F22F5CCE7AA24B7A3EF36386F052E4A901 -:106A8000EF36F9A313F2195E6ECE37C61575F44BC7 -:106A9000CF8F423FA187DFF6F806023CAF9DDA1D9B -:106AA0000F7C24E824F48F995E11395B25F6C9B375 -:106AB000F3A3D81FD1DE6C8722ED0308F756E0A3BD -:106AC000912CDF07CF11F0F308023EC1E71A9FE7D0 -:106AD0005F3DDA7080D70CA7ABC3225D0DCEA470EA -:106AE0008A04F29FA4B9B07CFD944502B85C6105AC -:106AF000F3DD5DDC3E9AED2055171CAFAC9F17B956 -:106B0000DE6838C3F2101B4AFC6910FFCFC9D626D5 -:106B1000025CD5795A1994D7656BE5507EE8667E9C -:106B20004B7ABE560175912F6086D397DF957770AB -:106B30002BE033612209803D84FB64609F2581E75F -:106B4000312468AE52B063095B08E60924C7870F99 -:106B5000C4C0FEDFD3C40BE79F7202AA05D65F99BB -:106B60000F69ABA16C38C3EFC52921787EB22B8F9A -:106B7000AEDE837974206F7A7EADE278AECA677A32 -:106B80008EFA21F7E733B866E7EBFC1021473DF9B1 -:106B9000153A395C80EDAE5D0E6BF3BF9B1C3EC8B1 -:106BA000E5F0A16B91C31F46E4F051F8BE37395CA4 -:106BB000C7E5EFC55EE4F0FFF07E7F97DFA31E5DC3 -:106BC000174D0E459EB0E0779043B0F741DE1FD5DC -:106BD0009F3FCB4FFD5E72B9399A5C9AE5B1ABBF6E -:106BE0006BE4FF9EFCBF0143FC7CDED1FDBF1D3C7E -:106BF0005F5CC833959797B9BCFC9ACBCB0E80F7F6 -:106C000043B78AE398E5ABCBDE84999E80FC3C7D5C -:106C10009ED6E108BE5E857ECC7939E34CF1FCCF8F -:106C2000F2193FBCC3CB84F071027A81E2ED8D7C16 -:106C30009DDD7891CB4B602CCB3BA5925A0A7EE52B -:106C4000BE0EEA470238F90CDE719B5B0F81DF480C -:106C500094C678B8E7AA273C7986A8625F202A9E66 -:106C6000E8F87F86F1CD746B06BA39BAFBF3667A21 -:106C70003573B90D737C7C5F3804FE008E61088724 -:106C80006A59A7B3F39F733D41E16D0778C74F0C75 -:106C9000CB04E10AC5C3FE89D0A764206D3FB27B57 -:106CA000FB8E48FB0EA0D7788DB62F8CB44F825048 -:106CB0007E26E831AACFD04FD6F0BC62839BF18309 -:106CC00099EF9B6CEC7C4417BD1AFB23BDE6AAFE32 -:106CD0006FA1FF26859D1B695AEB92D8794096EFEC -:106CE0007B225343BE8DA287C890EFA68794214C88 -:106CF0000F59875C831E720CE9D243F1F07D38F79F -:106D0000EA7A6800FF7EE090ABEBA10CFE9D67483D -:106D10008FFEC0009897590FAD53191EA2C8E960A5 -:106D200080EFDB5C4D8592CAA97B486AC4AED17600 -:106D300099509FCBDBAF6F64F9160112E78DB6CE89 -:106D4000F00E715C6BFE9997C3F99DF2A837FEB8FF -:106D5000CD06F816794E625C73FEB4A0634DF3AABB -:106D6000116428E4695DCA00BFF2DCB16F313E7284 -:106D700024AB4A83F15BF68F31E46589F197F178B2 -:106D80005A995CB813E2B3E78FD830EE2913F5D9DE -:106D900071149EDA235612443DC5EE1B10FB61D6DA -:106DA000230DAD108FB712DDBD50B89E5113816F0A -:106DB000AD47D8FD4C2485BD0F10FB2A76BFA371CB -:106DC0009F3F4933EEF32757F431EDFB1BF7F9FBF7 -:106DD000CD34EEF3A7FB8DFBFC0316149BF6FD8D63 -:106DE000FBFC8397979AF6FD8DFBFC996BA79BF6AE -:106DF000FD8DFBFCB99B8DFBFCF941E33E7FF55B10 -:106E0000AFD8605D5DF0D232D3FEBF71BF9F22A4C8 -:106E1000354B775FCCB0BDAB0DDFCF6D63F7900D19 -:106E20000FAD33B66B64F71504E87F80CF2F88DF92 -:106E3000067CA690F09B0320BF25287943F4B385F8 -:106E40007B778D86B298C7C5AB371BEF395818349E -:106E5000D6BF7ABBE208E481D58210D17E6A5F9208 -:106E6000824177CF745FFC92B1BD88F32EE6F3398F -:106E7000CF9D82F35B643CB76CE693EAB76E63F731 -:106E80008605B456B8F741E041F08B8BF38B804B0D -:106E9000E063B1BC04E55CE041DC9F55639A7FB7D9 -:106EA000F9EEDD8AEDCCF336CF63FB90AEFBB0702C -:106EB0003F8074931307CB13A2F3827D72399067DE -:106EC0009213231E7AC2DFB5CA8DCAF1109366945D -:106ED0009B5835CECC77486F333EE3F38CF264C6D3 -:106EE000A7D3DB3F2A7F89FB4F713EB01FB25722E9 -:106EF000BF90BAE37541F386860151F8897A7E988E -:106F0000E761C6EF7B26FC1E56FD47413F5DF8F862 -:106F10001B19E9EA6F1B01F6EC2AF9671FF3EFAFC3 -:106F200075BFFD187C2FDA9BF7DBCF419EA4EEBC2A -:106F30008AD44537CD942779E8BF601F89B6F1DB45 -:106F4000200E5BE1B5B3FBC0CCF96BFE736047026A -:106F5000A51AC138E079E25D43FB5BE3FC8F825EFA -:106F6000E2221786A0BFEBC7FB85C687DB2EFC1687 -:106F7000BA575A5D304EB47B484DE70F2FC3B8DF88 -:106F8000F79E47E1B7D3759252C0FC6E5B817E9D40 -:106F9000D475BF2A5BEFF4D48FC823EBA9940ECA33 -:106FA0006857C3529C37DA3D65E905467BAF3BE73E -:106FB000995EA0B3A3350F5F7813F41EC5F7407830 -:106FC000EE7452FF46BA26FF4685EF9F8D4F40BEB6 -:106FD0000EBF250773DD707F959AD8A7B0FB7D4B58 -:106FE00022AFB00EEE534A86E7F98957CBBF28355A -:106FF000DD7365BE97A8A198C155CCE7E9E7F75DB9 -:1070000095F3BA389726E271B53359BCF969531C28 -:10701000B3BCC0C9DA679596039D1ADC12FA4F0D0E -:107020009264D84FBA38A4A41CE6ABF1FECB21364B -:107030009F8AE7EB10AE14D33ADE52C0BEB7149469 -:1070400062092B7AA0B74D96A3E2735201835FF8D1 -:1070500051DFE39E99A33123BBDF3363BE1FB13CF5 -:10706000AFAE05D48379DFF7D5DEEE99395A1E75B8 -:10707000FF17F01BDF27C2F7730B8CF72086E2FCAB -:107080001BA7403CE24FB217CE9B98E7FD4001F3AF -:10709000FBD7F3750BEC2BC17AA40F2FBB7FCFF07E -:1070A00014CCF23D807855285E29BC211BBB0F34DF -:1070B000FC21C171FA2FD00E407D944FC5F3150D00 -:1070C0006EE280FB82C2C32D181749F1BB26C2BDF8 -:1070D000BE295BA43E804EA117AC0A093829BF34F3 -:1070E00016B891CEEBC99A0370BF49E296AF8907F3 -:1070F000D713AE892ED0477349D438E7937C3ED35B -:107100009EF328B02E4BB447BFCFE1493E0FAA1FD4 -:10711000D6C13CC6DB8F8D903C11FD024B5BFCBFA2 -:10712000768BE15CB3284F644E68047E1DB580F415 -:1071300010F7647C7A83EA7B06FA1F7554C5FD8AD2 -:107140006AA1A7E75A08DC3B7A17679FBBB6B0FC79 -:107150007572E9CA1559F8DD04FB27B07F50BDC42C -:107160001984FD84EA6637DEC7471648B8CF51DB7D -:10717000FC9E0FEAD52347BA50BFC54B12DCCB08A3 -:10718000269FE933859C14FC22F349D1FE6772FBEC -:1071900020D6F7D41EAC8FA778AFDEB2F5009C8F57 -:1071A000F87FD4F003DD3E96FD1FFF90F67B073598 -:1071B00052CB8BA154C82C8CABA7613FB7F37E0296 -:1071C000DF12E9A43D32EE1DCD6FE17C3EB6928028 -:1071D0009D3293B5940D6D7D3411F75B457ECE0CD9 -:1071E0007B6319D8B973B670119C9F3AB7FF2F8390 -:1071F000601FFEB31F5D70C2BEFCDF95B0139E9F83 -:107200005AF18113EEC5FB6C05BB3FEA3E6E3F04AD -:10721000BEFFC4F5825AE86B01BADCBFF2F268FD2A -:107220003D3864792AEAFD854119533A845C2D7E04 -:10723000291E3C9BAEFAD29DC986BAB0074B634863 -:107240005DB438A1A590F1D1C21D5B6D035418DF68 -:10725000FF118C7F0A1289295D4EED71A2DF28E0B3 -:10726000A9DA31DC067EC6DF9B634808D62F4AAB1D -:10727000959DBFD4264B941FFC9CEE6638DF7C2383 -:107280001EFB9BF734D33FB3E958CB295EFDCDEC11 -:107290007E4BF33CE67DA696F7A3F89EF704B5E88F -:1072A0002AFB7E05A59B7FF9E3984F6D9EE7EC8056 -:1072B000F93E4B0DF55F35A7EF9CB5C6F7D5CD4F21 -:1072C000623F7389BA1EF206E7359ADF577E017E68 -:1072D0004CB5293FBB53E8A7D1640CE8A783F6CC93 -:1072E000C468E73045D9B1D285CCF9E54A3B96A7C9 -:1072F00056122C5B0A18DF2E697EEF11E09F9ABDB3 -:10730000BBF0FEA143C15129D7D34F263557E27EAA -:10731000E124BE8F7C6FF7FB34E30A69FB890ED34F -:10732000F9673EEF599C0EE23CF42C986F113C57E4 -:10733000BED1CFE7FC914C07FA43853CFF660C9D1C -:10734000977CEDF312F311F313EF97CA94DFA2B415 -:10735000177CDE52C0E216739BA635F4A7A858B37B -:10736000FF0B5C2F13D37D7A13EC4FB6F27C33C343 -:107370007D79F4EF28C8AFE0B76AE2C5FB43CD7C66 -:1073800025E84C1CD600BFEF18FDF82E7E6AFE09DA -:10739000E245D01B6EC6D3DFC744F9CAE037533E7F -:1073A00032D4E7351AEB67AD6D1920EFD5A6DF476C -:1073B000386BCA2F11A5A7D083F23757D5CAE11C65 -:1073C000CD3CE26B6079B8EC1CDE29A5F1CD1F82C3 -:1073D0001C363139F83BA7FFB6425F6521DA2FAD85 -:1073E00008EF415C9D2EC345BFB3D74B2E90AF39FC -:1073F000F5C3F13E9D62A2617FF7F6E0872D296417 -:1074000074A8AAB3121B359E55740CD073557B64B7 -:1074100071CF95634A5FB8B785D163E913BB6CE957 -:10742000B45C5057CDFC8320931B718FB4E03FA117 -:10743000FF17AD3F80EB70BAFE30C8572D9C8B28EC -:107440000239363DAFBB19E9506BF213AA057F7ABA -:107450008917F8D3FF88D30EE7AA7A9B37E91E5F16 -:10746000C1F8CBF923D9E83F9E57D57EF09D3F81E7 -:10747000DD5B2F29FE31F09CE20BED5478553CDEAC -:10748000E37BAC53262ADE37E21F03E7DFDBFE3A5D -:1074900008F76305BF8AF9D6DAD723BFD612E3BA55 -:1074A00072365DC040DC74F6F664CCDBA2FD17EDED -:1074B000057F63BB15FD8900599606F74CF81E63DE -:1074C000F7D056ED4DC2756D553DDB6FA9DA91844D -:1074D000E766E9BA12EFF716F438563FC1968EF414 -:1074E00072E33D5964AF91CF059DBAAF0B4D745A0D -:1074F0007BE0CD34B5FB3A5147A7F61EE864B89F50 -:10750000714B21D78F9C4E6405D73F0F1CCE867DD3 -:10751000A6F375B15E39CA7AA3EBFEDEB9D7637EF6 -:107520009988C755F417BF27E0ED0B74BDB07E14E2 -:10753000D2CD4CAF8A7FCE41BA90BF3A09C469EF31 -:10754000CD24F74FA7CFEF9798BCDCBBA6B202ECD7 -:10755000F9AB85CCBFFA33D55B5A2E5D0753BDA579 -:1075600051BDF501D56750FF70651AD6FFB252C5FF -:10757000F293957958B673BF5FC81165041BF8592B -:10758000AF73F979BD50AC971E4A03D7A2E29F1F93 -:107590008CB240E83370DF8CB24184DCAA19EDE193 -:1075A000CCDB8DF6AECDEA2A87F3BC8127D87D6887 -:1075B00055BE1B0CDF1345B5C13DB8246F44E439FB -:1075C000CA9B6A83F3E8774D4E367C3F63ED0043F8 -:1075D000FD834295F995159986E777CF2A30D467D0 -:1075E000F3FB5C893A16E5E6219E374AC8584617F0 -:1075F0009E8FF24DDD987EFF46E1FDE61D2BBE37E6 -:10760000D343D075EE6699F8697F733653FD4541D3 -:107610006C6FA474A2EDBEFAD809674748C38E11F7 -:10762000EF8EA5F5633B58FEEAB1FAE49F82FF7442 -:107630006C476A02C451FD0D32F7335C78CF99E88C -:107640007742FD2ACC53991D8CC17308B35B02CFDE -:107650008B3AFCC400BA78203747E5604842FAB15B -:1076600038C0CB3118C73F45FD3A571FB83F8CD4BF -:10767000430907A712E9FB7FB4A60641AE2BFE29FA -:107680006B69C04F2FC7F27D1A09FBFBF2BDEC6D91 -:10769000EB90BFD49D2194DF185C2FCC6963F3235A -:1076A00052F100A0FFA924A2255120962EFBCBDF8A -:1076B000144AA78539AD45704FCC2C7728F54EDAA2 -:1076C000AEA3C9CAEEA5A7FDBA687DE9AF63B6321D -:1076D0007DA2F5837B2222F80C16C1BCF3FBFB6272 -:1076E0008652FA7D393F58847A6D452ACA9519EF3A -:1076F000ED363FE23700722045F46444CED8FE1BDD -:10770000556EE9A06FE658BD7DC15EB5AFB7B27BDF -:10771000E1142D611A9E33DD8D7CDCAEA8E530EFDF -:10772000F6B56EBC4F478C5BB55ED6D87DB8942F4E -:10773000E1FB0DB21FEEBF11762BB056F2C33D39FF -:1077400066BE79F0813198F76EF67F457996CAAAC0 -:107750005FE7472CDA2FE3EF5890916DCAED86FB77 -:107760001DD9EF7D10FF58433EEA12CF1FFEE6B051 -:10777000A05F9308EB8ED34765E4B3D39EC6D1696F -:1077800099905E7270F4BFD1FA57530227E15CED15 -:107790008383FD2301AF8B2DEB3360FD74AEF9C401 -:1077A0004FE1FED82F7F63F5C2B08B5E5E3818E3E1 -:1077B000F4DCFFEEAEB7C4FDA45A3ADC17B458DDD2 -:1077C00089765CDD211136FF20C229ECBA6B9384E7 -:1077D000F7049D18E55C07EBE539A6735D27F8BD56 -:1077E00015E543993E11F6FE315E9F63617C4DDEE7 -:1077F00090D8BD52FCF71E843D10FA5AE8FD19439B -:107800003D2C9EC1F535213B516FCD87DB94E83C83 -:1078100097BC14C3E2CB2A5DE08FC67B4BF16FE3CC -:1078200050A62F16D97EF30CC852356945F8BFB45F -:1078300006E7B7BAA1FDD6FA3ED8DEEAC5782BB77F -:107840002F70AD3DE8A56A2E7F4B1B25BC1F8970AC -:107850003B398FF74F5EB246EC86278A7D31D9954A -:1078600079DCAECE23A6786DA3D1DEF9E2D9E2773A -:10787000111D17EC67042EEA3F53DCCDF707DF9CA0 -:107880008A704BDE601438AA493804F7442DDDC1F4 -:10789000E2D766B8CCF3B85638E77BA74D4C1AA9A7 -:1078A0001BD704B7C037067C757410789F1F60F82B -:1078B0009CDFCCF6033EE7FE1AFDC338B399FED534 -:1078C000C43715F2F3AA3751FDE98EF083E08385C2 -:1078D000BB82B85FF115694C70503958B279D78CBA -:1078E000EB54583FBF87EB90597D42D99624BA2E6E -:1078F00008BCFD4CC5A0DEE3F5FF2A3C117E6F36C7 -:10790000B6A37899D7C4EEC5D67DC7F3D00388AFA8 -:107910000581800DE2990B787CB037386B1576EED7 -:10792000BD7778191EFFD57087861AFDD8887F9499 -:107930001D75BDD5E517F5628F3FB58606813D0EF5 -:107940000F52D01E7DA378FF529202F6391BD70D3D -:107950003DE9DBF9DC2ECF033B4DCB939B5FC17B35 -:107960008F3EDFF40AEE8FDA7E332F01FCE5939B26 -:10797000E7FC14CE059CDC3107ED72F52F845DF633 -:10798000DBF4F67EC2E6D9BFFC11F0E94BB118D7A3 -:107990009FDFE2E7FE38D57FA0173733FD4736314A -:1079A000FD580DF6AB10ED572E7CF7C87C7F2EF0FE -:1079B000BBEE39DAB547E6F8C7607BE20AF1FB7B3C -:1079C0004360BF847D1576F7DD74FFD9A16017E4AD -:1079D000773EFC019DFF99DD32C67496CA5B33E0A9 -:1079E000F7507AD2E3DF1FDF962E7CBBAF01DF5565 -:1079F000806FF48718BE8FAF65783EB19EE1BD61A0 -:107A0000476602AC838FAFCD443FE8F88E6CC4F775 -:107A1000DC7514DFE807AB463F682DC537F8FF80FB -:107A20006F3A6E558BCAF1ED65F85ECBEDD07A56A4 -:107A3000CEED86D7C07DA0571EF9558C17EFA18ECD -:107A40000DA5C23AE5D42E9940DE42979FC4FD1998 -:107A500081E77F90C6E7C1AFEAE6DF6C882110DFDF -:107A60005CF8AA13CF0D7D2995F403027434FE212E -:107A700001C68B8CDFE5D7788A46E9FC9A6BA44F68 -:107A80000DF1615E7F4DF31F3E06BF1EAE1D827578 -:107A90007F8DB82F62AFF1BE0849059D86E747ED9F -:107AA00076E08381E6FB34FCF8FB3017B3BFBE6F92 -:107AB00019CA733847BFBF521B17B2423C2ABC4B8E -:107AC000427A2F7DA824A184C0BE541DC231BE8835 -:107AD000AD2B244DC338630CE59B38B8AF0C2ED1C9 -:107AE00085E7AA8BC51DB7D0719D1178CDCFA78230 -:107AF0002202FBEE881EB7AD2B627EC052D982EB0C -:107B0000902536B61E11F921B7F2F7B716B175C92F -:107B10001D452CFFE21C2413D17ECF6D88E7F9CEE2 -:107B20001331FE29EE0B5004DE5CCA59C3EF27F077 -:107B3000F8C2DFA00D85736E0C8FFFC24FB6D0F672 -:107B4000F7F0F6F734FE09F7E5E84AE639B0BFF793 -:107B50002E8FF1E2FD8C701F1CE5BBC7E3D83E0AF7 -:107B600049495440AEEEE67AF69EC6277D608FEE18 -:107B70006D8CD7A0A4E304088FB78E847DD8FE3621 -:107B80008CB7CEB2B7FD06DCEBFBD34E3C6CA753F3 -:107B90005B6561FECBAA3E04F36B8651371EE2B7EC -:107BA000F4D59E2BC957E31F633C7909C475AF27F1 -:107BB0008CB1C6225E0D758A5FAC3714DD70E7A606 -:107BC0007184BC4FD4A140EF25801BE087D9891870 -:107BD0001FB815E2CB7DA05490CFA62B246061E5A1 -:107BE0005A07DE87C1E2CD53F9BCEF184B428974C6 -:107BF000BEA1B78821DE7D67C812CAA574B8550931 -:107C00001D00BEB6D8552BAC0F7C155231AC9B97DE -:107C1000ACBE36787F5E547EE7A681B46E61FBFF12 -:107C2000E11F48787FC93D54C8813FEF53488B5CC2 -:107C3000CCE807FC57DB87DDC71D7E80F1B788B332 -:107C40000B3A0DA7DDEBF17B0F878FF6B33601DA28 -:107C5000DBA2C797B673B9107EE7622EAF8B05BF64 -:107C6000ED30CAE961212FE0E752BCDDC3CB9EF8BD -:107C7000FD20E7F7839CDF77168975F8B58DB7345B -:107C80008684F4BFD724C6BD9597A122E63F0B3862 -:107C9000043F131E9FB250CD017CD4DEB806FDA672 -:107CA00005A67831D1C7B1E468F52EFD63B902A508 -:107CB0002D3C17E0916E8AF5025FDF63DB99CDEE14 -:107CC0005F317E27F6716791562BBF8F8CC5B9B88F -:107CD000BD2A931D784E7F96C4EE5F3A57E20C584A -:107CE000A8BFF829BFFFE47C1D3BFF3AEB07EC7C03 -:107CF000E7BD898F4C05FF7056824D81F253FE3BE4 -:107D00004FF79356A7DB1DF14F1A4A647E1FE8BF59 -:107D1000DD09FB196B40AFB0FAB3DA388C2AF1FAFF -:107D20008ABFC0FBDB2F513EC0FA8FEED4E8B8E724 -:107D30000EF3F7015A87FD92C7043FAFC6FECE3D52 -:107D40002DDE37B0FA13E2FD93ACFE13D13FAF6FD7 -:107D500030BD5F657AFF7356BF50F4E49D70CE71FD -:107D600016DFC79975BD847AA518F88DD277D6EA43 -:107D700010E27996E5202B4B4908CE5DF4F6DDE064 -:107D800061BEE2A254B8D7A2DD09F63B77B886F50A -:107D90008143FDFF04BBB6689A14B081BE3C1ACC87 -:107DA000E1FA3D6ABE7631E7DF415ED69FC037ED2E -:107DB000276658EA77EF6707C035CAD08FEBFBF428 -:107DC000B3BC3B3CE9DFA79FCF4CFD08FFE8E16275 -:107DD0006D24F44726DE6088FB2DFEB13711FC2BA5 -:107DE000F22EFB7DA5C5AB77668CA0FD2FFEEDBE08 -:107DF0008CF9BAF5784DA74C34AA8F6A3B252CBF75 -:107E00003AF0890DEE1FA8D973C0565E08BF0B73F8 -:107E1000C0364107D71291874ADA94E93AFB7EDDF2 -:107E2000300BD71BECF76516FFF634EE772EB6EC69 -:107E30003CF90B88035DCFE272E6F9B979BBBFC1AB -:107E4000FE7314FF7DFC30A68FE68FD46E1A06FBFE -:107E50007B80335A4E58137D1F7F2DEF6F561CD3F6 -:107E60007373463BEDD066D451FF1A381F367F8BB3 -:107E7000BB18E2BCE38796560CBB6ABC34CCE2A5C7 -:107E8000CD2C5E3AAB4FEB4354899335BF7BF95908 -:107E9000FB8D844C7A9674DDF30B71483C2E8D7209 -:107EA00077E0CE890331FE85F5F9C35E7F3640DB8E -:107EB0001FE1F7FEDF3B66681CE8873677BCC545E7 -:107EC000E5B9BC70F61A80E3DE313796C3F3921839 -:107ED00067CE6C167747BE282FF4DD07F386EF21B7 -:107EE000DEE1B7B1F897FF6D19E35FFEA2787FB4CA -:107EF000FDED591C0F6B8631FFE58885C2591C8149 -:107F0000438C4F1D96875A697FEDABD387C339BC2D -:107F10006D8525AB112F7CFC6D85FE5AA88BF1E990 -:107F2000748BE0F9B5C2B184C3B11ADAD27E7CE3B6 -:107F300028BFE9D68DD327C61BEAB74F4E269A3EF7 -:107F40000E7BFB00437DE6AC4CC3F777CF2D30BCF6 -:107F50009F12D33AB2EE3BF8C1B54E671CF8639F4F -:107F600035FFE3A37BC0BF6B92F1776A16EEDFFEAD -:107F700011FC6ED3793AE1640C86AA180FFBF20863 -:107F8000FB1D4EEAD729FA7D9D33A4F519D807D5F4 -:107F9000ED1744DD4F15FB058B5D2D98C7F7BFDD51 -:107FA000D7D9368CAF878B21B519ECD2871887AB20 -:107FB00071B0799DD9770C7FD702F20AAE503EBFDF -:107FC000191AC2BD7A9DABF0F7C226F0DF139E00EE -:107FD00097B0C3BA60E0030A9C6BAFA525D897722F -:107FE000AAA712299FB41E2043F7405EAFDB897910 -:107FF000174B3B6FC338F791B840E103F4BBC56B37 -:108000002BB15ED3198FFDFE596E2DC7FCEDDF4BF2 -:10801000B89F3065C0BDAB017EF8FE413ADE94DF0B -:10802000DD5C0178AAD9C3F233A6C8EF8F847E96AF -:10803000345662FB29323922517F21B1F31EEC778D -:108040000AD87A5A97473BD781FD956DA19C7F0747 -:10805000BD6273A25EA9ED8CC5769326303BFD36DA -:10806000D71BD636065759E7347C2FE8DF3ACC6366 -:1080700038776F4D6D52E03E4F6B9B84DFDFD259F6 -:1080800080A598E7DB79BFC2DFA1B2A67E530EF9C7 -:10809000996FA7482E743F4C7AF742DD98441245F9 -:1080A0002F758DD3C9F29D633A59FE73EB70ED24A1 -:1080B000C8D7D4156D0AECEF1087DD05F89A3A762B -:1080C000B83A5F274FF2C1BB6C4017EBA6F76C6064 -:1080D0009763683941F77EA9C8EF37E9E58E6116E5 -:1080E000EE3FAEC2F90A3B438EEC457EBC4F9C8FFF -:1080F000E5F2F209FFBE0B4FC0EB40C75763703D7E -:10810000757AB8FF0AC0DB5AC27EAF8628AD19B0B7 -:10811000AFF2AF829FD2D92EA1BFDFC67EFF77AC70 -:108120006A81FD02C52BEC0B935B318FFF017C0252 -:1081300054430080000000001F8B08000000000076 -:10814000000BC57D0B7854D5B5F03E73CEBC92992B -:10815000C9E43D210F4E208420012643124208C964 -:10816000242408486080AA840699208F8804424409 -:108170001BAFF6CF842410042D8AB7372AD2019181 -:10818000A2D53620B6698B382168E3B5D7467BDBAC -:10819000E2ADB5F151048B3580D72FB62A77ADB556 -:1081A000CFC9CC9924886DEFFDA37C27EBEC7DF63D -:1081B00063ADB5D76BAFBDC37ABB184B60EC163B54 -:1081C000E33F8DF18C253176719A8E31F8F5572287 -:1081D0006BECCC866749499F3B8EB1EE7BA64F176F -:1081E00065C6AEE04F0954711AA81EB30F7CCE725B -:1081F00019DB7C3252BE4F60AC3216DE013CF0829D -:10820000D17F309DDE33210E9FC68302946FB60D61 -:10821000647A2C8CCD79D11C6053A1DD17CD1283EB -:108220007E3A72BDF1CE787C3FB15CB031E63E6102 -:108230009418D41B3BCD9DE0CC83364719AF3A9EB2 -:10824000F027633E3EBEF2593A96CFD81D26FED99E -:10825000DC25822F2A8A316FFB7CC660AC3583CB4C -:10826000189BCED8EAC14882BD7BF8FBCBF5897359 -:10827000198CFBF2BD306898C7EA7B8529C7615E1F -:108280004CB63A27001E2A93576E6330CE4A5147A8 -:10829000F3AD9C1CED6F81AA1B07A3E9FB4A91F586 -:1082A0000A318CD50DA653FB9B0663E9FDE64133ED -:1082B0003D570F4EA6F7C64191B9015E33283037BE -:1082C000C037CCB1FA7430BE492E6F05E2A3B2E5D7 -:1082D000FA79D88F775B52AE17F0B1E8DE7EC90429 -:1082E000E3621683FD49E86F51418E639D2538EFA7 -:1082F00096EE2A1822B41BE731B8E1FD1A78CE09B0 -:10830000295F0BA8EDB42026EC731360DC8B5AD3E5 -:1083100075F7B160F90227CC07F1CD9AE9B948ADFC -:108320003F0AFE6728F5575B021374D09EBEDEEC51 -:10833000DC06E3BA1427CF45BC34ECE4F86BD07B01 -:10834000E65861DC0D8F084EA00CBB35DF6A623049 -:10835000CFFC33F5066F76B0FFAAC1A94C063C2CC2 -:108360001BCCA067C914EF72C443CDE04D0A9DA693 -:10837000D293C9053A1CCF56A4AB8C032AE074569D -:10838000C6F749FD8CC46F41FF9FFC524FE5796EE3 -:10839000DF2D381EBDDFE83C00E33967F68A48DF91 -:1083A00073A9CCBE1786784ECF7C76A0D7AD1D22A0 -:1083B000F341FB6BE0E985E7B968E68E76213E6123 -:1083C0009E59BCED2BF0EFBFA53D696C3CD0B7E1E9 -:1083D000776F4BE318BB2DB36F6A00DAAD2E0DC477 -:1083E000DF0CED5E38A477FAA0DF8DDD6FE4EBA043 -:1083F000FCC37477221381AE63BC0DC8CF1B96FA01 -:108400007FA807F8F6FB9FB3CD9483F8EC94021392 -:1084100024F8BE13F0E8837175EE16E7F9895E2C37 -:1084200072C994205FAB7C1CCEDF1B06C7137E2E67 -:10843000D71BA71C47FE057EC5F7750A9FDF8E7CFC -:108440000F4F7DFF7C852F39DFABFC5C274165F842 -:10845000AECE12E5F7C17C2A7F04FC0728DF747CCE -:1084600089A714F92E4B704E80C746659D548A0724 -:108470001F2844FEFF38CED902EF7FD2E400640506 -:10848000F9BF627009D58B1AFC26F5A7F2BF51E13E -:10849000773DF27F08DFC3778CC177F7E5789F449B -:1084A0003C95FDE06FCFFD17BC5A2005321F8BC3F2 -:1084B000A795F827B80E4CF627D3691DC8EB42F8EC -:1084C000483C556590015FFA87DFA1756084E79CA1 -:1084D00090F24DC8D7D988997E69A935F8FE6927E9 -:1084E000977FD7CAFF1D0AFFCF33B2551E6C4FEAE4 -:1084F0004B0B6DEF7C4ED90B388F534E81B7F74F36 -:108500001A37E0C984F885F1BB915E8B0A64DD7D82 -:10851000E9D88FBA7E399F7CD5F87FE4BC3679FFE5 -:108520001B45DE87CB7706EDA17CFFF885497E945D -:10853000FF6F33D00700FB4E44CA4F2AF29FF4432B -:108540004494FF6AF27F5DEEADBF413C8D20FF7F1A -:10855000FB8FC87F95AFD4F5A2AE0F753D84AF1FDA -:10856000753DDCB0CB19F52DA41320E6495C3F9294 -:10857000EF199C479D1C9983EB525D479B8E0BB472 -:10858000CE86E90565DD04D789564F8CB64EEA9450 -:1085900075B1565917EA7AE8113BF716C277753963 -:1085A0005E634EC8BAD8782C5C2F8CCA570CF96A17 -:1085B0006D5C3D43BEAA8367285F1947590F969C9F -:1085C000AFA70FFE7A8DFC3436C740EDFD2FF2D3F6 -:1085D000D89C91ED0919DFFFB3EC89CBF5BFCB95A2 -:1085E000613C977341CEA607F9ED865719B717C6B8 -:1085F0005B9DC83FBD117C9EBD86547F0BD6BBC220 -:10860000EA118FAAFE5F8B748F0DF269B5CB5B8E7A -:108610007456E9DF1BE1CBDE927DED7436C6F519A9 -:10862000DCD948EF3E8DFEAF1B85CEF373BE9EDCDA -:108630009B91736D745E91F34FB713D78E4457E6D9 -:10864000E6F640902EC66564BF0540A109A3D35548 -:10865000DFC1F1AEC26D0149D5B7B1A86F815FD658 -:10866000E5FC03F2A7720EFC3A06C11797BB8B809C -:10867000EEDF5160D6B31CD7E14D056A79A0C32D5A -:10868000A1DC81DF0BA9073733117E39ECEB3E53B8 -:108690000EF56FD83B54EEC3F28AA228A53DE6162C -:1086A00058B07EDBD1936776D33CF6F0F5EBED97CF -:1086B0003C5342E05C80AD21704118BC8FD7B74974 -:1086C000FDCC4EEDF8F97A85F60517E71F4F883D8A -:1086D00002949C1B8DF6E471C17E1FD07F45D1C7EB -:1086E00006A45770FEAF2C77A780BC3C2128F07FF2 -:1086F0009CC1F9AE38CEE11F1C7DBDC32729ED0119 -:108700009E372A68D6770A6E11DADD5820F8C7A599 -:108710000FC7F30F86F8561D07A860EDF7CC10F7CA -:10872000F5BEC7F54DDF8FA3EF03C6AFD1FFCD4533 -:10873000CCEDB70CAFF773558E7E0EB0DA3EE0721B -:1087400019CCCF9F3DBC7E8F52BF4FA753F075B65B -:1087500003F9A7CFA0E2F34F0457300EFFC7D13F74 -:108760002DF771BE65EEB0F95F6DFC3FCAD1DA0B33 -:10877000F8236BBF0F5C0D7FCF0FC39FC23FB55A6D -:108780007E8A923CA72F433B5171821DEDE24D1E24 -:10879000F36EB4FF83FC3140FCD1676643FCACE56B -:1087A000FF8BCBCBB3C9FE51EA5FEE40F9E6D10DAA -:1087B000D5E7EB41E52FF83E0BF8094D64FCFE834D -:1087C000A3973A7CD9441F2A2758BACA7AE80C835F -:1087D0008BC2D68FC2FFB47E51CE037E268C20671B -:1087E0000C2E8EDF8F04B61CE5645F19B713FBC631 -:1087F000F167A64B20BCD95C1C8F09CAB32F220499 -:108800000F29413AC34F00FD909079139EAAE2D4FC -:1088100079C7562DCC80EF6378B9EC8A7AC4971269 -:1088200084C3DB1BE78AAD42BC04DB8F7E13E552B9 -:108830009582B74C57CC9B0A5F09B82EEB884180D4 -:108840002F8E0B3E11FD04E48B11E6FD97E17CE5D4 -:108850000BFBDEADBFCAF79F0C5F97EEB0EF993E02 -:10886000F7EB7CAFD06D61185DE785D1B53C0CAE00 -:108870005661BF46FEA9727175D7836D09308FDBD3 -:108880008F08A86642F839BD0AD7E7ED76957FC70D -:10889000BD89FC1AE4E7F184E7A59DAA3CCC78C425 -:1088A0000D745B82F2B030082F437941F0842AF7CF -:1088B000B4507D91F908CACF9BDBD5FA13A9FE8A83 -:1088C00056B5BD2C82553A32DFA42AECBF2A57D1C7 -:1088D00017BEEBDEC4F20D27F8F755C726BFE9CB6C -:1088E000B8CA7AD81386977D61B02FACFEC35FA15A -:1088F0005F5AC3BEBF37AC7C7718DC1106B76BBFBD -:10890000AF5923D03AAC017E40427CD5BABC4D5918 -:108910009743F480190816B2DB34EBEA86160EDFB3 -:1089200071ACA0AADD1202BB0A69DDA8EB42CFF848 -:108930008F318ED1BAD08F222F6B5CA3F06556B8E1 -:10894000BEE5E57FC45F93D00E661ABBA047D4C2D4 -:10895000DDA23AEE796F6ECDC6972A7C7D15FA07B7 -:1089600037FC9B765EE0AF2A704555794A885DE218 -:108970002BAF7287CC53AD3FF78B2B22F6B7D35575 -:108980005E7508DAAF2E0B4CA8877AD531FC097AD0 -:108990004D44BDB95989C7CC7D41F4A05EAB8E086A -:1089A0004C68C80E9927EBCCC47976DF23127D7C06 -:1089B0002D401F8CAF317030C135EB8E8A6A3C0C74 -:1089C000F57BEE111B518FBEDD189B80E33FEBE280 -:1089D000FE424FD4D884B5007747AE32C850AF7B43 -:1089E00047053D4F89EEED03B0D6BE7F6C599565C6 -:1089F000129647117E9E702DAE6A06BE3EEC92E93D -:108A00007B6F8C3DA10BEDE7FBF4EC4919C7E3DC70 -:108A10004F7C73BF3107FDE79AE6C909684FAEFE88 -:108A2000D7257393A0DEEA36BD53A07A6C2A8EDB7D -:108A30007B5F8501CBD7B42A4FDFF5F47CF1CB27E0 -:108A40005A6C507FE071C17910EACFFEA4F3D5A92A -:108A500000AF6F1FEF44D29C1CD4313BF4F36EC7C0 -:108A600044BF08FCF89EB9FEE545BC3EC3FAEB3FA7 -:108A7000975F5B948BF545FB36A87F16DEA33D7CA4 -:108A800076A77850C071D9AC11024CE9EC17F26BA3 -:108A900068D742B97D1BBC3FDB765B02DA596705BC -:108AA000D926C0FC7B8ED55439805FD67718157ACD -:108AB000D624D5C0FC6B7443FC42FA635D34877BDB -:108AC0005C35554F227E1F9968433CCF9AEE3EEDB0 -:108AD000023C9972DD2FE1F33D33D7532F7E29AE4F -:108AE000427BFCE717562760BCEE57CAFA3939B803 -:108AF0003A617588BDB3EE2389E8FEA241DE8AE3C0 -:108B00007C312255407F19E81EBB04D6EF1AC5FF01 -:108B100000FE6D7C6E04BBE76997487CDFBD2BBE11 -:108B200048D6F0713DC94FF21B00EE3FB6F1111F60 -:108B3000C8D7F78D8DEC3D5C7CF742C14C78F69838 -:108B4000297EA57FC6EC37A763FCD33D17F9993979 -:108B50003A33975A43D69D52FF0F3E2BD5FF03D48D -:108B600047FFED0FBEDF5B9965B81DBFDE66F5A15F -:108B700031F181D52A211DDE969ACEDE0DDFAD7B47 -:108B80005C4F727FDDE3F1F70EA0BC017EC1F858A7 -:108B9000F8BCA64CD713BE465D87BE6F6BD721FBD2 -:108BA00036C9EBD1D6E15F8FDD5B75C832FA3A5C2E -:108BB000AFF829731FD77B701DADCFB34A0CF447B4 -:108BC000D9E32F3D89FCBE7E8BD9658481AF7FDCE4 -:108BD00048F4EAB75A7D7628F7DAAC52343C4DD3E4 -:108BE000397DAF9BCED7CD1C914926173D5B314EC9 -:108BF0007A09C6130BF0F9C6BDDF9D01FD7CC8FCE8 -:108C000037CD00FC5D4282015E2E1D17297EC824EF -:108C1000B75409F2B19671B950F7CA738652F8B5D4 -:108C2000B67EFD42F4EB6EF3EBDFED577CB62BCA5C -:108C300034519E6EE6AF40AF6ACB37B3DD17C5A99E -:108C4000C4C6065C8F759D61E5F5D77F80F197CD31 -:108C50004C7AB75F8DD7C238E4E9D6B8B39100B883 -:108C6000980B30C42ED5EB33194C71BD05D615CCFD -:108C700077CE3E81C6BDBE51F41BA1FE9C581EF7A7 -:108C80007DBF09E83F91E6EDB303BCFE61AE67D658 -:108C900033C16F825FAFDFB745C2F5D081F205E324 -:108CA000D402F3207FBF6776A6A1BFBEEE7133E189 -:108CB00077FDFEDB7EFB087CD7DF5C1917EA1FE738 -:108CC0002B7C01ED33534CB09D0F9ABF9D86FC3F2A -:108CD000E77BE0E7C27CD747B31F56A523BD92D2FE -:108CE000644BB0DEFA6DF764F27AE027C3BC6B76B2 -:108CF0008A340FF6BC91F41EAC7507C965059F6BED -:108D00005A5F3118B2514EEFEE13A1FEBB008B1625 -:108D1000C2974FC1A301F1B50ABF4DE2DF38F2158A -:108D2000BB5B2639E2C5F955EB84554B49AE0F18AC -:108D3000685D4FE7F1CDAAE9DC9EAD4973DE427173 -:108D4000E4078C4E9453F823AAE300BFAA4ED7B78A -:108D50000EE3B9ECC7468A8F6C6E35BBCD36F23B5D -:108D6000DCC7707C12930C808F8D3297176B143E8A -:108D7000DC2C2FB91EF906CACF48B8BF62E572B124 -:108D80002E1AF0CEED54B70EFAF9187F1BCFDB4D3B -:108D90009A1AD2BFA0BC8776645BB0DD5E1D6BC73C -:108DA000380BD69F3415F1187BD3721CDFB322AD7C -:108DB0006798FC030568E73D2B4E47FFB66667CF13 -:108DC000DC0E848FE6D8B1C99A1FFE9AF4C6ED0A6C -:108DD000FDFBD1DE473D02F051787E7B3AD7FB5E4A -:108DE00091C77DBEADE049E503B5BC6EA79EC7DF68 -:108DF000DB8C64C7D435FF8EDAADB3F625A0FCADAD -:108E00007B5E9F8F72DAA78C7B75736AD119E0AB9A -:108E1000D5FA28BB00AF36FA2A0D086FDC23101CE8 -:108E2000FC2E3E0DF9F4CFAD3FB121FFBC670E4CD7 -:108E3000407D34B0C5EC3C881350E26E7F6E9D706F -:108E400010E3336BEC7D5601CAD76C1D1F83F2FB18 -:108E50006D7BC080E56F77A6EB1076DBED4508BB38 -:108E6000A56904FF1944198F2B31F29F37099CCE55 -:108E70001B9FE9318C83FE9E54E6FBD1B3BFCE44E9 -:108E80007D5597D697897A05F8203319F1FCB440BF -:108E9000FA78D333A2DB3C35C8079B900F60DD6DB9 -:108EA00050F860D3F19F7C0BD7C326A4BF6B381F4B -:108EB000019F9EA6F7C70ECC65FCFBD3C827AA1E50 -:108EC00003B8558FF1348302433F081F9ECED7135A -:108ED0009497F3725F36C953D66F40BB737397DEB6 -:108EE000D71FB2FF331A9D7B143AAE6E3692DCED7B -:108EF00051E6DDBFF3791BD2F1A3677B5EC6FD921D -:108F0000BA63A0ADE511D6858297CD88071BCD83C6 -:108F1000EC8BCD386F5B100F43FCAFACC7CD8CCF63 -:108F2000539DF76649C1835AAE7C7F5AE19B8D4CB5 -:108F3000C1DBF1897CFD29EB0DD733CA55757EDE87 -:108F400018FEBDCAA7E715BDF08632CF8DC017CE7B -:108F50006CE21FB741951350F4D1D10314FF51E9CE -:108F6000A58EFB6F417DE28E8E09D2B15FC76A3B51 -:108F700047889BBCABE0EF9DB6C4B42EC0DB9FC15D -:108F8000CF427B0AF9550AE94FE51BB5BF393F5877 -:108F9000B200E70BED07B07DB5DFB77D9112B6F3F8 -:108FA00036E3EB03F913E5A7BA2EE7B4AC5C9063A4 -:108FB000C37A1F59C767E37CB95CFBDB743B3DDDBB -:108FC000682FC0F7EE2E81E2CFEF287EFD3B6D3F8C -:108FD000B1AD0EC1D367CAB8553EC31F8C4BA9E3D0 -:108FE000ED8DE1F1DCF071AB72481DF79C1D372F60 -:108FF000C0F7EAF8557E55F953C5A3CAA7ECDE7849 -:10900000B26BC2F995784DD5ABA246DE937EBC3EDD -:10901000E5A2C16B19FE3E1C56EDA1F7304E83F25E -:10902000E329D14FF2A3D5713A2344CFC38F2554FE -:10903000EF346FB9DE5E8AFBAFCF084E347942F46D -:10904000CB6E2944BFA876C12DB9E3B8BC8F739FFE -:10905000473A6E3CD737D72607EDD0D99F04C428AE -:109060008C4B1D4F7785EAD38D174E13FFD7B1BEBA -:10907000EDE847D5ECFC75E50CE4F3A7F4B43F53F9 -:10908000D3566140BBFEB6276FCD473E7AB77D3CD5 -:10909000C9F5F387F2A6135F317BC24DC0FF6B0E9B -:1090A000EDBD6905BC5FD3253A49BE433BB86E6B45 -:1090B000EE9CCE906FDE33F75716A2FD7EB7684761 -:1090C000FB7DD69379F762FD59D6B1D1380FF7A160 -:1090D0005882DD5214E907D5EE7D5B91932D7ACE4F -:1090E00017F372F97A2A197A727E9BD3D29289FB8E -:1090F000E90307403EE3BEB241EE0C607F2F2492AD -:109100007FB119DC2107D0FD9CC0EDB25A03332595 -:10911000B9E8BD2909DEBFA2EFBB13F5C82B775A0A -:10912000739A7100E2E7F9ABB93DCDF70F6379FFB0 -:109130002ADED4715CAFF41FDE9EFA7D2FFA11286F -:109140004F95F19F6F7DEA26D483E78F4C88C179D4 -:109150007FF082B91DEDA90FF45C2E0EF9DB7EFDC8 -:10916000FBA1761AD8751A18EC380D0CFCFBBED68C -:109170002EDCC6ED8B5CAD1DA7F27BF5960951A1E7 -:109180007904E1F63BCB08DFB79911C5469037EA81 -:10919000F34213200A1835156D7AF8BE3CF28BE7BE -:1091A000FAD0DEDF63B41B619EEF23FFE3BED4F38E -:1091B000A21FF761D036C7F5F0FED11C3FFA91EB44 -:1091C000DEF2CEC5F64F3FB883F20CD6827D9928E9 -:1091D00084D8CD0F3F7813B2FF25A7777B127C7719 -:1091E000E908CF8B80624B98BDFC7292FC8FDBCB81 -:1091F000D76A27ABF186ED88E7C9F0BB933911CF69 -:109200002A7E55BFE945E083025748BCAFA996ECDA -:10921000E40B4D5E7A7E2CBCF3C02CE45F6B94F3C0 -:10922000207CF6F3AEBD6232D2F978CEE7E8F716CD -:109230005AA2ECB86EFFD2D4489B8F179AEAE9A9DC -:10924000D2598DB7CD3EDE4DDFFDA56BFA8959F0C1 -:10925000DD494B1497FFC3F67B383DC3F340EED88E -:10926000322311DFABF3FAF06E4E5775DC1F1EB9D7 -:10927000D586F3EA7E2CF6C44CA46764941DEDBD3C -:10928000F54AFEC7D90E6E4F9F33451D5E88792380 -:10929000FB96253090B36BBBBF7113BE5FF7826046 -:1092A000473FC0F9C2121BFA6B7F92FA6D767CC2FF -:1092B00077011C8FE417511E15CE63B41F5518900B -:1092C000989C4E5BBDC42F332F487ECC1BF933EEE8 -:1092D00053613CE4F3088A873065FF69ED4F791CE0 -:1092E00065C8BF55FCBB59CABCDFCD8DE1FCADBC28 -:1092F0009F53C0DF7FB0EFB945D8DEF9437A3B8E8C -:10930000FB2F87F4D4FE06F0CB7430DE7347B8BF72 -:10931000B3A153203FF9FC11D0D730AFBA2D7AB7A3 -:10932000216A381FCE81F27E4B900F37B8FDC4DF23 -:109330004CE14713FC7765DC707E8C669DDB111F6A -:10934000FF285F9E095BF743FC381A1F28F8C27597 -:109350008CFCA8D27B4307DF578FE9CC2945BE524E -:10936000E9AFCA095F19CB42BDDA6260599887E359 -:10937000D34538717D2FB1C87A01F0B02CAEBF1C37 -:10938000C569451E9793E21C9D5B87FAA5C5487287 -:10939000205C8E5CCCE5765223F234FCB3E6713B64 -:1093A00042CFEAC90F519FA07752517F2F898CF984 -:1093B0006F19AA7C79FCDB2B2418FF925931778E28 -:1093C000778253F67CCB0A09F877C9F498E7C7018E -:1093D0006CCADBC6CBA7C5E4E9016E6E6E5D510EAB -:1093E000F0843CF7E7B9F1C17ED476E1FD157CFF4E -:1093F000CC64AF2E2F1EE5BA85E4F4C7C2C0D4C634 -:10940000F460FDD705F6F6CF8520DCAF676968DF2D -:1094100059B1ADF8D19F8BF2DC917979C3DFAF669A -:10942000AC8DF2E77CBF3823703FCC63027A2D56B7 -:10943000F86AB5C912207FBE5D7F6188DEC847CE5D -:109440002809E9BA48E1A3C552A01BBF9FC45AED41 -:10945000674D6442EDBB123BBAFC8685C7CEAAEDD0 -:1094600001BF7CAC87F9025F0BC09E8DB0640440E5 -:109470007235C82FE1C42F3EC3765B7CACDF4C74E1 -:10948000A8B6A3DC13985777059E7591B6A918372F -:10949000A98B4CF323DF373CFFD16964AFDB54FB6E -:1094A000C55B40FCBED5CEE7C3BC85C48F772AFC24 -:1094B000F84113ABCF80A5B7B8AFCF26C3A02F2CF0 -:1094C0000A64E27ABF9CE6CD453A7CB0AF25A5019F -:1094D000F8E7A36346E742A87FCEFF1CC5E1362A22 -:1094E000F6283B14AFAC7B315002F57AD3271D44EC -:1094F000FD529CC7F5F585F440DA3D2837D2B9FF17 -:1095000003F528CF6DDEB6EBE3B1DE85A33B32D6A3 -:1095100002FD8C12F35963E8C96C30EFF9D0760183 -:10952000C07A8045DACFF5537B58CF86FA5EBED538 -:10953000C1E3EDCC837245A5974A8761F48121A0F0 -:10954000BDAA33313D8E7F12DB67C7F5AAD2E9038E -:1095500013E011E36726C023ACEF0A0C3AE4223E85 -:1095600079BCA541E86F8D45F85981F2E686EBC1DB -:10957000270D88F2DA7DB792FC51E58E0CFF8D2421 -:1095800077BE76DC68DF9C11E5CEFA3C45EEE4B0B0 -:109590009C2BDC4024FAAE57BEAD10AB6509C71D4D -:1095A0006F72623CADE1F1F1A46F58F67FB2D07AF0 -:1095B0006C5F2CD7ABE922E1FDB62E81F21B2BBBF1 -:1095C00092990C450BBB62E9691B4CA2F7E70FBFF0 -:1095D0009ACBE512A74BE5F713CB28AFE8FB13E9CD -:1095E000A98EA341E1BB0A31BB3380768405C60155 -:1095F00070C32B5C6F35DC28525C93A1884E4062AF -:10960000F21F8FA59DE23F1E3664DF0B57284E2BBD -:1096100047215D3CBD2243FE016FC3C7F16C6A4622 -:109620003C1B1D3A268F607F18153A99E50826875E -:10963000F81D926FD2778A301EFB0DBDD30FE52D3A -:1096400066DB415C4FCCE7EE437F61B9F25D9F99E9 -:10965000F34764568CE6FB1DB6B9BDC86FCBDD5C25 -:10966000EF589D6334FD1BC58D7A6432E6E5F6A2A2 -:10967000CA0FC497D0EF628F40FAF5C6E5501ED2EC -:10968000AEBEE822C9717D91D6CE347AB4F5BEAFB4 -:10969000D27F129B144AFF20DE2D6EB4D32FB9ADBA -:1096A000C4C7A0DDFFAD08E09B7AF50CE76B8CE04A -:1096B000F3BA8498C2B8A85BF463BC6407E201DE25 -:1096C000471568F119EDD6E22F769E161FF11EEDB3 -:1096D000FC13978FD3942779AFD39427D7BA3470DC -:1096E0006A7DA1A6FED8C6320D9CEE5BA0A93FBE46 -:1096F0007DA9069EB06785A6FEC48ED59AF249FE66 -:109700000D9AF2C9471A34F094CE7FD1D49FD6B5C2 -:109710004D539E13B84F533EBDF7210D9CD7F7A86C -:10972000A6FE8C330735E533FB9FD694CF3A774CB2 -:1097300003CF1EF899A67EC9E0290D5CCA5ED5D478 -:109740009F63FAB506AEB0FF5E53FF7AC77B9AF20D -:10975000F9F29F35E537645DD6F26B04977F95CEBD -:10976000BF69BE1353BC9FA23E60E20509F9B6650E -:10977000A5C062319EDEBBCC847260308C0F3FCEC0 -:10978000B52B7E0D4B43795621160570DD5EEA122E -:1097900068FD87EB3BE9CF1E37C6F3D84F0427C6D9 -:1097A000D9A2406D4921FD47BB4DE04806E1D8797B -:1097B000760D1CEF7168EA272E9735E549DE2C4DB2 -:1097C0007972AD5303A7D61768EA8F6D746BE07496 -:1097D000DF3C4DFDF1ED1E0D3C61CF724DFD891D4D -:1097E0005E4DF9247FADA67CF2917A0D3CA5B35174 -:1097F000537F5A974F539E1368D7944FEFDDA38141 -:10980000F3FA3A34F5679CF16BCA67F61FD194CF2F -:109810003AD7A981670F7469EA970C063470297BDF -:1098200045537F8EE9750D5C617F5353FF7AC73BCB -:109830009AF2F9F2794DB96ADFDC907551FB5EB1AD -:10984000772A9D9F69BEF795B919F287EF98E06C6A -:1098500091417EE5F3F80BC8F57EB388F69187E277 -:1098600046319820087C1905420CF90A5D856A8A00 -:109870003FC551DC9754938CF93E60270010A34BF1 -:109880004F477B3A3268B7A55C997EED76DB1A6864 -:1098900013F97C6FBEB72A3F0FFD95A373D16EBF3E -:1098A0008DF9B6E33840EF45F5C3FA78CDAC8D6756 -:1098B000A8CFF926C04B487FAF98F7A4B8AEE2F71F -:1098C000CF375DA0FA43ED2A710E01E6D710D2FE24 -:1098D00003E0574860D7ED698275030EE3434D7688 -:1098E000821F6E7210FCDD26999E1D4D59F47CB4CA -:1098F000C949E5FB9A0A08DEDFE426D8DF348F9EEB -:10990000079B3CF4FE50D372820F831F8DCF23E060 -:1099100057E3F369F08FB1FC19F09711FE61938F53 -:109920009E9D4DEDF4FE58D31E828F377510FCE3DB -:10993000263F3DBB9A8ED0F3674D9D547EA2A98BE6 -:10994000E0934D0182034DBD049F6AEA23F874D36E -:1099500019825F6EEAA7676FD3397AFE7BD30095D1 -:10996000FFB26990E0568CD7023E1ECCE77E908A0B -:10997000171566AC9CF841B50F17A19D8FCC51A06F -:10998000FF8BC6CE0FB3B7C3E9F1A11217D69781EB -:10999000B988F1C33199075B42FCACC795FE7644A8 -:1099A000309F19F8BD59C7FDDAE6184679D64CB193 -:1099B0005FD72B7CC9E2B8DDBA4E19D77A653DE492 -:1099C000217F66117FFEF2EBF815AADF9832C5FB06 -:1099D0002CF167AACE47FEB3C59F89F673C9146FF1 -:1099E000677E3CEE37AE7D99FAB33B69DFB1D218A2 -:1099F00088BF19E323AF8814CF1BADBFCD4AFEF853 -:109A0000A8E527CFA7A0BD3DEF4BD18B787A4D6F4E -:109A10005D8EF1829E7C1E7FEEC9D7699E2F4DF12F -:109A20009EC2F17C6AADBF4507E3FFB478CBE13B52 -:109A3000D283FEF4627449C10F5AC2643DE52732F5 -:109A4000F74BE9D0D48D6060217C33F3D1736EB6CF -:109A5000F7556CA70A0C7184BD85C6B491E6153E16 -:109A6000AEDF2AF4FA6DBE4EF3BC3CC5FB1B3E2EA6 -:109A7000378DEBB599D767E2BCD471E54E9595BCAF -:109A8000E481FD38BE4F5FB87856181FC4BFEAB7EF -:109A90006F2F55F24AB6083C2EA7DA6B4A5E8AEA67 -:109AA0007754DF29F8D15E5F09FE0EEE2FBDA5D8F1 -:109AB0009F6F99B97EBE54AFCF42BBBE5A8870E249 -:109AC0003EDCA5FA3F5950DD427D86FB242D98737C -:109AD00000E52D770B94CF5D0DEDE8A09D6A0C0499 -:109AE000E277F70AC47F13A7A6D3B8ABC1FC233F24 -:109AF0002B6E200DF74B815F2EE37C37CC147D0657 -:109B0000B0875FD3F93305DA975E6B10609CEBE3A7 -:109B1000804FC68DCE0F9B94F307EA7BE0B32FB046 -:109B2000BDBFFC744616C5F14FCE94116F2D3A7E21 -:109B30001EC9F7EFA293E7BB70512DCE9A42714A2E -:109B400026399D1867AA54CEAF748BACF1E8087221 -:109B500074EC0CCE4FAF39F4F3FCD4AE76BF267163 -:109B600006A763E20C4EDFCA53AFA4E2F9AB4DBDCA -:109B70007AB247586E7FB6C73AC27C1A77DD951124 -:109B8000C2DF9BBBDEE1F91AAC3F3B343FBD40E98D -:109B90005FE527D160F51EB0848E6F88BFD3662045 -:109BA0001F45037F8F27FE3E8BF6F622A31C7533DD -:109BB0003CFB014501787ABF67A77C2335EF680D30 -:109BC000F3D0733DB003F2B3C7F7A001F1BF8175C5 -:109BD000D2FB4D05B7A621BC990D943BD09F686F71 -:109BE0007EC901A35CB6E7C10A8CCF2EF5D7BC8431 -:109BF000CF258784B3E8BFC2FA983603E327427DB6 -:109C0000DB18E86FC533A56DC9F07E91C8E9C15E68 -:109C1000E5F400BE718B31C3E709EB61067EFF6995 -:109C2000B49BE621DAE669D643F536E616E282F918 -:109C3000F343EBA3E0F63F26A33F240DD0FEFBE663 -:109C400093C618A4F306C6F57730FEA1EA6D467CEC -:109C50007E3B8B7062BD0F15BEFE3095115F7F2875 -:109C60008083E70ADA932CCDEB708D0FEADF0F7556 -:109C7000FE7CDB78D2CF8B10EF2F3B96C91837BB19 -:109C80003DCEE414B13CDA9FC6F75187E43CBB12E9 -:109C9000198C7B3DA0E771A8F07109052F7F86F62E -:109CA00083D1C07CB8BF01EB9BE5E3BA1E63A0750E -:109CB000D582A8C5F85999471EA9FD56A5DDDE2F06 -:109CC000B81FEC83F9E079C961FDD8957E22783F11 -:109CD000AA1EC1FE488E24304D7F9B31C905D78115 -:109CE000D54DE36FD64593DCF978AC7713D24B8D25 -:109CF000FFA8FE616FFA0719E4C77FDE9282763A09 -:109D0000F02FCF4B2CE6F2E935BDEC43F8B5D27419 -:109D10008AFFAB727771018F972D56E3634561F12E -:109D2000B1B0B80C2B1A395EC698538FFD4E626FD6 -:109D3000A9F8A178CCA92289E8EE03BA63BCF9940A -:109D4000E2A7964672FFFCF73362899F62E66710CE -:109D5000BFD9625980F6A3AC22F15B0FCBB1C484AA -:109D6000C889FB9438EB6EB08758487CFDBEDC0692 -:109D700013E61BECB0F0738CF79745D486E6BBFF77 -:109D80006EB69EF0797B71E92BC83FD9167F19A971 -:109D90006DB724E37C04657E93ED807F1D36ED5125 -:109DA000E2A54E138F4F9593DE56E97EAD7AFB699F -:109DB000C9BF2D02E71FC7681D5A3BCC244FC54EB3 -:109DC000770053AF27152F3D4CF4943C59D84F776B -:109DD0007E04B340FD4FBB0DE4E79FD4ADFE1EE60D -:109DE000C50FBC6964B8FFD9694D96506F747E7118 -:109DF0005D393DADB3E6321EEF8CD481A0C8B1B35E -:109E0000277E844453CE9F750AAC9751DCCD1DA9A3 -:109E1000035FAC53C72E97C0B88E595C7BA711EB7C -:109E200079449CE77B45DE9F225EF2593DC1F71BDA -:109E30003CB507A0DFFB634CC42FF714794EF071DB -:109E4000B2B68530BEE23902C3F3BC6D066E9F59CF -:109E50009D117C6F8A713BDF339849FDFF429197DA -:109E6000AD0E771F1E1C19156F766960283E427C67 -:109E70009742713D158FA1F4B2E76BE8E5D587D223 -:109E8000AB00E83525945E6EE1EBD0CB8F4966F1EF -:109E9000C3F9D457263F589ECBF51BA6CA85F36954 -:109EA000A971B605F35CBA6DA20EE9D61D919C8D21 -:109EB000F139954F55BE1D815FB7F4A0DC4891EC98 -:109EC000B86F6CAC8CA07D18957F55BEB514F2FCB4 -:109ED0002DE0DF5585F05C69F154A06C09E75F8CDB -:109EE0009385F269F5A8FCCCECA1EB7811D815515B -:109EF00031680F9D3BD419C2A7D5F517252E57AE53 -:109F00009444E407E37A8B8A04F66E28BDE1DFBB54 -:109F100059CAFCC81E92C80F53F17AADF8D77FA377 -:109F2000390BEDBBED786E11F0D52E38DD8918EFC9 -:109F3000AA7FE70E7CDFA69C1BF6651BB8DDA5ACEF -:109F40001BB5BD49C5655105B82F30E342E43AA8B9 -:109F5000F769824E46E4B4C9AB7F44EBF04C24C3AE -:109F6000EF6CB17DB54FD0BA9AC870DFF0D3DBBCCF -:109F700063711F7F27D0E95D4AB2F627EA688FAB8D -:109F80003F11D71520D7C19F5E077FCF94723FC185 -:109F900087668E53F2ACDD4AFD7EAABFD3B0C714EC -:109FA00081FDA49BEC0743F8BF4489BB5716A8E783 -:109FB000755A64B4D72A0BB85DB3B7E9C8ECF72774 -:109FC000E0783A67BF0FE3895DE8675EE0EB882CD5 -:109FD0009F8CA921A62FE70878AE815DC73A311E74 -:109FE0008FEF9BA704DB7715F07567423B06E867A8 -:109FF000DAE69343E5A849277847CA83393C53E218 -:10A00000DF6D63546E3AF5089DF38FCD700A980F9B -:10A010006DDAB687E13E8D39C0DFC765B885352179 -:10A02000EDC62D847187F005F0972F0AE48FE920A3 -:10A0300030662ED22182E292E1FD2E8A2FEB956CC2 -:10A04000A3F34938BF3185DF54BE51E74927564253 -:10A05000CEEB978FE376725BA3E100E5A116441384 -:10A060007E3F892B8B6223D89FEA733FF081CF8894 -:10A070007EB3899E07C1EFF64D44BFD941F061F030 -:10A08000BBF17904FC6E7C3E0D7E37963F037E3734 -:10A09000C23F04BF1BE14EF0BB113E067E37C2C774 -:10A0A000C1EF46F8C7E077E3B30BFC6E7CFE0CFC17 -:10A0B0006E2C3F017E37C22546E00F9C4F96CFB1F4 -:10A0C00014E8DA7EB7C18D7984FB15BAF6B8C7C536 -:10A0D0003A81FEE62C1DC5C4CDBF7C88E17CCC0E48 -:10A0E0001D9D0BDBEE7888DD8AFE6CBE95ECA9B673 -:10A0F00067B99D6296F632943BFB055F2D73C2FBF8 -:10A10000AE926ADCDFCB706C298B01785757C53E65 -:10A1100013AC8F4C79C9F2E61058B6BA361CB507A5 -:10A12000E1B1D90724F058D89E8279FBF048108E0F -:10A1300003F3871FED5A50DD0C2C1418C7C8DE1826 -:10A14000483750DECE1AA417C6230A783CF106D64B -:10A15000E2C0FDCCB132784502D50FB0B86BAFBFCD -:10A16000BF40A6F7E1DF5DAD9E2EF79AEA31F12AF6 -:10A17000ED61B97095764CC232531F8C7D975E911C -:10A1800053F1169253ED18DF01BCB79BF9F3BF678B -:10A190002A7ECECCB25533E1B96A26A76BBBD9670C -:10A1A0002FC3FEA7E8289F8135A6FF7A1CF477D736 -:10A1B000BF4B0CF34155FE7C5EE1830963AD742E09 -:10A1C0009FDD63A2FDFCEBC73EDB1A03F084279CF6 -:10A1D0004ECC7BD8C59C11C827BEDD3ACA7BFC415A -:10A1E000EEF89825507D72DEF33128D763677279D7 -:10A1F000E357F2859ADBD68DC578D4A7AF7379780B -:10A200005AE9E780BEAF9EE89967213B04284FF6E4 -:10A2100046B303880D3A5397C49F06BD7D05D633D8 -:10A2200080618079D9862F6698D0DF6B1934CEE3B0 -:10A2300079B37D648718CC5E7B34BCDFE3D3915C5B -:10A2400068912D94E7B6CBE2EAC573CE3EBB8EF2A1 -:10A25000617765EB088FAD969BFC68E74B42732DE9 -:10A26000EA31BFFD98291DDEFBB37594DFE8772F37 -:10A270009D87B0CF2B51FE15FD60B93786CE77EFA5 -:10A280006203AF4EC3F26A6E87B525FCF55424C64F -:10A29000BF6FB43BF9760B93313F8C52C574E877AE -:10A2A000F76F8BC4715431C59FF591FF6A3372FA11 -:10A2B0007DA77BBE7D1CD91921FB5A468CD5394D13 -:10A2C0004E289F6A71CD43FF52B2BA4C98F7D76AB5 -:10A2D00077996A68FE3C5F8DF232A0DD16BB8EFC7A -:10A2E0005C2CBF359BD4E1E98C7C25155FC6793F9A -:10A2F000D48DF890D632962EE3F8245FE8BEA1699B -:10A300007C51AF0CF3685F1743F3900427C16CAD29 -:10A3100044E31E2347D0B9E6BD86CA5EB417C7988A -:10A320006EA7FDADA45A49B3FF94E8D5C2F1CBB5F1 -:10A33000702C9382FB57D0AF7DA61A7FD3E22D1CE1 -:10A340001F49F6D6D771FC495E3A04396CFC8FD8A8 -:10A350001F8E2E65384E0B8D33C1B2BA14EDA67820 -:10A36000E66946FEFB47C739D5BED4940EFD4F8D36 -:10A37000D39179348D0D6CC3767729FCDE9ECEE9BE -:10A38000195C5722CD0BD6E53C5C97631B75E0B09A -:10A3900005DB4FF781E3A6D93F88D1C013F68CD1F6 -:10A3A000D49FD8314E533EC97F9DA67CF2119706AB -:10A3B0009ED259A8A93FADAB4C03E7041668EA4FFB -:10A3C000EF5DAA81F3FA5668EACF38B35A533EB329 -:10A3D0007F83A67CD6B9060D3C7BE05F34F555FB48 -:10A3E0003E5C3F96CDFCFBEC7AA3638CE67E9B70D3 -:10A3F000BF21DCEE377DD9226F437EB619889F25B9 -:10A40000D4E7B8DF7C37F78F4CC54E19E54B81C2D6 -:10A410008F9F15BB1723DD4A6D26D20B9285D793EC -:10A420002C73C95E49EB30D0BD3B929D0D9547A280 -:10A430007C6EF2CDCE98101CB7D9BE87EEAF28B592 -:10A44000CD63988FA47E2FD9DDCC6BC5FE64EACF97 -:10A4500064F7513DB30CDF87CCE3A44EC72C28C76B -:10A46000C18F43FF6034BF4DF5D7543F6D34FF4C6F -:10A47000F5CBD2742C029F0784FE3BD07FCFAE7FFA -:10A48000BD2C9191FFB605E77D3F9EDB46BF6D2A4F -:10A49000B7B3DA1216C818CF694FEFEC1D87E389FE -:10A4A000D751BC14EC66E7D2107BF1B199DC0E9564 -:10A4B000C6B5F7A3FE6B8836C9682F49A603B3DF7C -:10A4C000077CEDD7F73F85F18956C1BEB113E5E2B0 -:10A4D000DD16CA03D9ABE04DB6EAA66F83763B9B87 -:10A4E000DD129ECFEFDCC99CADB83EE24AB745C352 -:10A4F000FB0929353A0C034DCC68DE86CFFB67F2A9 -:10A500007D9F49D90774B1503E39B77439C6BD44EF -:10A510003BF4779538B468EB60381F96219D45BEB3 -:10A5200042EBFE0A0CBD34C644FB9266A4B7404F12 -:10A53000C28379D0E237239CC1F162760BFE488159 -:10A54000DBAD9847571AD341F455ED59B473B1FDBB -:10A550007B8ABC8F213EE3166AE92A990E113E766A -:10A5600029FB12EDD1F22F513FB7A767C4E07E96C9 -:10A570003A4E55AE1C56EC7BF5BD2A571C986B9392 -:10A5800017B46F80CF3B30FE6696F6D0B94CF3BD62 -:10A590007B18F2B5194FB193BDEF933DA43F3C9AA0 -:10A5A0003CB4F271CB4DA8AF2FC7B9C89E3537FE6A -:10A5B00098C6178E37733FCF471B0DAFB6CC4749B0 -:10A5C000BF830096F13CCFA9044B6D68DC537DBA84 -:10A5D0000BB8DDA257F386C093407D7659CD4B7200 -:10A5E00047F2F14573B82773058DEF8E7857E2D5A2 -:10A5F000EC6D33F89BDE10BAEF943C26C443DBE7E6 -:10A600004BE6D1BC255A0C6CD717D907289EACF85D -:10A610004B6EC53EA9445F0C9E69067E8EC019B77D -:10A6200090EE3353E3209766F2FC45A78F893C8E6A -:10A630003794B7AEBB328DC62A1B54BD4BA62CD760 -:10A6400053F07F37E6AB8C6F97B479EE8A1E57F5DF -:10A65000F4843DDAF2891D5A78927FD8F7FF897A1F -:10A66000FE46FE3BE8016DF9A38ABEBE11F535EE4C -:10A67000677D83E78B98604457B89E0DEA3D900351 -:10A68000A99D8152149B295B254D9EC998307D78E8 -:10A690004F914C78F0F44A7AD4B36A9C265C0E0B46 -:10A6A000F75CD882EBA534325246F989710CAF9130 -:10A6B000FBE55EF053EE979CBFAB46BFAA57A43CA8 -:10A6C0002A954EE174AD2D14147DEA110BC93FEEAD -:10A6D0009F8EFE3AF6E70DE94F8DB79C2FF69A3123 -:10A6E000BEA1C65D2ECD935E12E4601C458D0BAC01 -:10A6F00052D6CF2EE71BF53D308E9E33468A8154CD -:10A7000088BFEC6DC23CA95489E4977DC6C6EFA111 -:10A71000FF5DF67B28C778A22C27925DDEABA738B9 -:10A720004099C2C7658ABFA5C65BD20B399FA72ACD -:10A730004FF82282FBF58108B45F271F01D9ABA532 -:10A7400067242FE771B6299DE1E56ECA5FBA4EE135 -:10A7500017CC3B2B4DC0742F0E773221D60E749C34 -:10A76000B6BCFF14BA0ED9AFBC14817C78D4CCED42 -:10A77000B5A7157E48608213F3F3138E589C7EA80C -:10A780006715D9D13E9887F3B4A4C9339B7A420B9D -:10A7900067B310381DC7A18577CBF5B8F5CC7657D0 -:10A7A000834D0E539E59A8E46567B24CE4AF0AD1BD -:10A7B0009283FE5343A985215E8DEF4CFCB73E94F6 -:10A7C00017AFF37BABEC91F283E5F0BDFDD5586795 -:10A7D000B31CA4FFD3E047A37EF8EE15276BD50783 -:10A7E000E35ACF003D33687FD94EE59D4057848FB3 -:10A7F000815F9D41FBCB59F4FEC7E05723DC057E0A -:10A80000353E7F067E35BE3F017E35C2B71797DEE7 -:10A8100084FCF216D443BE88C8396E1A8F716E8BD1 -:10A8200048E76EC2F97147FD7B969B4156153BC6C2 -:10A830002E8C477ED82AD2F9E49B0AC72EC4F3DBBC -:10A84000A171B5D0386330AED62FA8713523D0E7CB -:10A85000F20C59C95F50E26B5E1E5FFBEA76DC6A60 -:10A860003B14BF1CD6CE501CD3E47B3F0B8F6C092E -:10A870002C0ADE7F74F77F1D463D9398E4ADC579C1 -:10A88000D7E5BD6BE076373F4F95A2ACA37D669EC2 -:10A890004F9AA2E40185C72F8BE7BC73473CA0EC1D -:10A8A0009E9FCD5E89FE7FF1EDEF4C4F03F854E1A2 -:10A8B000532B31FFB7F8FBEF3C970C78CA9AB58160 -:10A8C000C37BDFB99CE2C43C8C875762FEAF2D96F8 -:10A8D000EBB77DCAB9A421BDA7AC97CD8D4F901E13 -:10A8E000073B83213E5A123CA45F3F8E1BB0D540EC -:10A8F000FDCDF10309ABAFA20F36371EA6EFF70966 -:10A90000CE737E1CF74C13CF3B55F4CD2585775580 -:10A910007DD360E6A03A1ED0B0F47EAF120762EE9F -:10A9200064FA2ED6CCE11E5B21E9A507CAE45FC913 -:10A930007CDF92FCE31EDB75DFC1BCBA967912EDB9 -:10A9400027EEB5B8CCA8B79E53E418B4EFA3FC9596 -:10A950000A13EDF3B0B8E5B4AE63D47EE2AA291FC2 -:10A96000214619CFE9C28800C6075ACA4D07518E41 -:10A970003E641947EDB514187C189751E16D853088 -:10A980001EC067B42D261D6155CEA9716386BB6AB2 -:10A99000D06E9932ED3235CFC1A4BF106A5F5B58DB -:10A9A0001FF18F53278B681FBA67C9448FE9CCB951 -:10A9B0001CDF1B847A1F3223CE43173A0FB95C3B4E -:10A9C0000FB942330FA1C11440BBB0A502E601F597 -:10A9D0004F5BF369BCE17453E7F3FD42CECFE1F383 -:10A9E00064CA7E927A7EA0CC5E741CC755A173B7F0 -:10A9F000E2B85EFAAC3A0E2F929CCBEA257C3F3E41 -:10AA000098CFD3FA75F2258ADF13F8FED7ED069AB0 -:10AA1000DF2BB3F9781E35F8D3E96087E44FC27DA8 -:10AA2000DFD1F8F84F0ABD837CEC66B8BE5A62DC11 -:10AA30009C8FED03B666E4E3E881846D34AFC08893 -:10AA4000F409E7E7707A0DE05D09E447FB44C4FFD1 -:10AA500057D157A56BF83E98CA2FEE597695DE0E62 -:10AA60009A67204DB34F082DC823ED8F6F87F6E40A -:10AA700090FD3483C34376B63ECE9985F1E6962F9A -:10AA8000C511CF4DCAB3F87A6FB64590FDDD62E3CC -:10AA9000F677B76D81C66F2A073F0AF791C558D67A -:10AAA00089EB4A8C5A41713431112D2F620BAD5D07 -:10AAB0001BB590DBB576D755CF4F49FDA2E65EB505 -:10AAC00061766DCC026ED7DA0C64D7EEB31A961F9E -:10AAD0001841EE0C16723BBD1BE73182DF08FE22E7 -:10AAE000C533557FD160F792DFA7CE7350E177B5BC -:10AAF000BED15ECF30BE261A9C32DAB1A272BE152C -:10AB0000F39AB342EC02B5FFCBCAFECEDBC5FC3CE8 -:10AB1000849ADF5EFC2BA17E24BCE7CC52ED92919F -:10AB2000F9EE1FE01B92132E8BC18D7687CBE2A02E -:10AB30003CF0D1BEC32DEC73314139E3FC325F24CC -:10AB40007D243929AFBF53DFFFDCAFD01F7CC94262 -:10AB50007AA7D39A52166A9783D14AF9C9E0FFFAC5 -:10AB6000B2A0B1A37F8315A90BFABDE087DD302B1E -:10AB7000645FF254C359DA070AB757C3E30A43EBD9 -:10AB8000DD76389D8FC79F84EB5768284844BE0AFE -:10AB90005FEFEA33D531FDBA3530AED4A41C7AAAC2 -:10ABA000EF1F67E2BC91EE4F5B3D4407AEA7274124 -:10ABB000675122E9E7D538EE8FB6BE91E094F19C5B -:10ABC000ED45D2D397EA0BA27620BF67C5907C4DA6 -:10ABD00051CE8FA9E349B9AD3B3AC682797C039344 -:10ABE00030FFCDDFE4B9AE5C4F7E867BA4F13E3012 -:10ABF0004B89C305C6B2D0FB81E4B8BEF91301EF9F -:10AC0000B245E794697DD949FFA972A0548A2EB74D -:10AC1000039FA73631A745C6AB93ED14174BBD2252 -:10AC200012BFA5F6F0FB9DC7C60D0878FFD0503FB8 -:10AC30004A9E93BABFF2497D39ADCFD444C6FA28B3 -:10AC40007EE9A17D884FE2024B707D7FF2301F517B -:10AC5000EA13DA72D0B914B75EB735C22F43D363A3 -:10AC6000EF85F1E178BE27B094741C474FFA0E8C43 -:10AC7000FBFC2492E23E624706C56D6E4BF2DE4558 -:10AC800078F5CB77E9C62B93857A75DF8AA0FB042C -:10AC9000F6097DF3299FE24E1D7B7284B8D4BFCEA6 -:10ACA000E2EBFCBBB3F83A4B75E4737A3B72AF5BF3 -:10ACB000137BEDEBE914CA6D18C7AE283FEDD3A99D -:10ACC0007961BBF523F3152BE27EEA903C56F067E1 -:10ACD000422F08F8451414BBEFC8D34F3F9DC0F86E -:10ACE00011C3717C3F3274DF3822C34F85114E3758 -:10ACF000C91FC1EEE672D65EEFF0017FEFF8421C8D -:10AD0000B1FFD715FA35A7DEE5C0FAE5B2939EDDAF -:10AD1000A9F9676A007F168B811943E4B0CA27E15D -:10AD20007ABEC13AEEAA7EBC01E4B17C953883417B -:10AD3000C9FFDA7E6AA609EF0FDD6E71F5A1FDB5D8 -:10AD4000DD12E7A238BC05E446485CCA627999F88E -:10AD5000D0E2E4F13A0BCA5F8C4BE1FCB371FC2FFB -:10AD6000D3FCD57ACF2A72C8E20CD07EA9D9B98794 -:10AD7000EA99240F9D9F33C531CA6730D9F9BDA325 -:10AD800011193A661A411E1F9EC5FDC0EDD9AEBE0F -:10AD9000321A9F84C7AAD87687CB41FA10F10CDF0C -:10ADA000F758F3A342F1F39E220F5ABAF9FC3C8DF7 -:10ADB00049F6723C6753ECF9AF5979D8CE6A13DE85 -:10ADC00073275A73AFDACE8561ED3C92501E4BED7E -:10ADD000BC87ED8856971DDBD12BF7A786E3F933A7 -:10ADE00085DE7F6F3C0D3048793C8417224C404310 -:10ADF00097F0A705E362B1237DC7E562BAE2BF80A1 -:10AE00005CD417C1BCEAB2DF7D99AF31EEB7C4CCD8 -:10AE1000E779429780B3F1DEAAF0FC8B703B46D510 -:10AE20003FAA3E8276446CE751B4632606D7911A56 -:10AE3000CF49AEF5F0F512E7217E01BB46C6F522FB -:10AE40002A797EE1F3B9A188E35FB015C8A82FCABB -:10AE50003FEF4FC6EF4E5ACF25733B56BBCF7CFA20 -:10AE6000B3C3662CFFA4B6ECAAF68ABAAF3CDA7E6E -:10AE7000B2ED5F3EDC126AAF8CB6BFFC55FBCAA7D1 -:10AE80006C068ADFED17B4E7E32B8AB8FC7317A9C9 -:10AE90007119EF8C228C430A1E273FF0CCE3339FBD -:10AEA000157B0B914E69ED06E603BA9EFC2CDFE1A3 -:10AEB0000D69E75AF1ACC6E1C728F6D418CB610199 -:10AEC000D7E9985ABF8071F4E4DA4EC17D957AB122 -:10AED000455C8FABF5F54AFB25D28088FAAAC4CE33 -:10AEE000F562F2A0C4B242E48EAD88AF5FBD62BF2E -:10AEF000DB4E3D65C6F64EE93CED99A81F6C3AF96C -:10AF0000C990F5AEBFCD652A0B995F0BEE0F8D4052 -:10AF1000C74D45AA1E0C90FE56F5AD5ED513719235 -:10AF2000464F6C8EE47CACDA3B9B0BB93FB4399254 -:10AF3000FBE5AF3ABCEB11FF1F177EB868BC8CE78E -:10AF4000643B0DB89FFE55FB2443F68DCE5FA3FAFC -:10AF500033C8FF4EC9FEF37EF83EE7FBA564EFE57C -:10AF6000E18D23226ECD72FB0FECA93B8BE2F9D56C -:10AF7000FCA1F46661F70B8E361F2FDE6B9A87F10A -:10AF8000BF3E8ACFDEFFB930E27988AE22D52E1AD5 -:10AF9000DA0FD4C4599315FD96AC94CB18674DC7FE -:10AFA000FD2D6D1C747AAF16CEEBD3C233CE84C5A3 -:10AFB000557DEEDFE0793FCC1FC046F7C13A4339FB -:10AFC000B146D9F74CF1F94BF19C782AEBA4FDC5B9 -:10AFD000E4DA180D5E8B4525EF02AF3956C7093FFD -:10AFE000C952E579FCFED921FAFB9826BFBF7CCD7A -:10AFF0005D782526DBC3CFF999A073C4D7FAF94B46 -:10B000002B90AEC3E2B5F5DA386D726839E061DDD8 -:10B010003EED79418F3B87FC8165DFD09E1B54F369 -:10B02000D271BEC9AEE1FD7F75BFF02F6678FF6AB1 -:10B03000BB8F82FC21F9AADC279C8A45D88E14108C -:10B04000709F7B4C3DA37B8593B732F748FB057F10 -:10B0500054F0158E67E62B21FCCD51DE8DB1F07CCE -:10B06000D5315B75640F8E01B9407F6F6023C800D6 -:10B07000809337CA644F2EAED531D40FECF326CD72 -:10B08000F7305C8AA7AA747FD4C2F37153EB985F40 -:10B0900087F3A9BF8ED6138D6B5C901F005F9A7BE0 -:10B0A00005161768CFEBA6869DD355F92039ECBD60 -:10B0B000AFC8AE5917A0E7FE58447CC2F5DF04D4F0 -:10B0C0007F30A48F669E398CF975C5DB18BFD726F3 -:10B0D0003A82DF6B13DC8F10AF00BF9E32CDC942C6 -:10B0E0007B65973D4287790F27A3FB1F63D18C5D5A -:10B0F0002C62BEF222BCEF7060B200F017275AF744 -:10B10000B7CF8672F3C00F30986CD9BDEB9679A992 -:10B1100041D8F6C0F70866054CC67B8130E714D7E6 -:10B120005D847DC111BCEF3A22DB42C1C908A6BDD6 -:10B130007FA7B550DE8D7923AD1374CA39E99072BB -:10B1400098C786D9EAB97F37E5DFB1793C0F20B4DB -:10B150007DCCCF1EB5FD05D07EEED768DFC4C79F7E -:10B1600080AF40CF24E0F8310E8EED237D3168149E -:10B17000DABFD29EC47C0770FF06FAB308BC3F3B1F -:10B18000E6A524306D1EC2507F76E86FCAFFC17CF1 -:10B19000960FA787FE6AF458F1F5E8D1AA73D37821 -:10B1A0007D532DE407E13D56785F9D59E9CFACDC36 -:10B1B000DB85786DCD0FE215EC406A17AA375F5139 -:10B1C000F08C7986097603E17934BC9DB2F3BCA892 -:10B1D0009DF6087F73FAFF077A3938BD42FB437B3F -:10B1E000F29AFB5B01FDC55D7B7F885F5C3F43F8A6 -:10B1F000059A6C4BB876FCC2A87CD782DF53D0AEE0 -:10B200002E04AFC1FCA347ECE81798F51E13E663C4 -:10B210007E6B7634C9EBECB8A526CA47885F4AF93D -:10B22000C56DD916CA876FCBF886491FA2A7DBB2B6 -:10B23000ABA91CEA53DE54762002C3146C0AEBA3BC -:10B2400038C0CEA27207FA85BE7A9E87A5E625A9E8 -:10B25000FA9029FB9F342FF8306AF6F18153507F22 -:10B26000677D2EE59D4545FF95F2AD76D53A9D5813 -:10B27000FE9899EF637E57D9C74246A578DAD4C2C3 -:10B2800027703FD735A141A0FDCB8D57DFBF745D3F -:10B29000EC2BC3BC2D56C3F3B21CD552983ED4AE92 -:10B2A000DB5D88579E3FE517387E35ED3D3B3B9E85 -:10B2B000F0B633E320C3BF3BF41CB4256AD7970E26 -:10B2C000F398C2D7A36470D33D63AC4147E348C64B -:10B2D000D4005071AE290B1D35F03E65AD44F7F931 -:10B2E0002666DF4BF94C60E593BD919DFDCB328422 -:10B2F00087CD738D761EE1F30A1FB77ACFB14A2F3F -:10B30000D7456724FA57AE094B29DF8C7ED4F52E3A -:10B3100086CD07EC61739C8EEE838BC8089917D39A -:10B32000D453FCB77F2EFC18E82A5A47E1FB62FF92 -:10B330008F9F1B3232A7C940DFA9E76CF87EDB186C -:10B340005C3B48F734C6F3BEC3BFCFE7DF3307DF4C -:10B350007F334630139EB3113644501CD368041813 -:10B36000CFE128F78D3DAAC4DB9A052625B942FB1B -:10B370000B50DEBC68BA2103FD8653A665763ADF22 -:10B38000A6F851FA680FE52DB2AC188D3F7A4A390C -:10B39000A7D6705B7A22C6EFA2A0AC0FFD6AC9697E -:10B3A000427AAB7113DBF8FE6FA21E3F3B5BBFCA54 -:10B3B000847A1B9DE042C62EBF70653FDE33ACAE83 -:10B3C0004FE320BFAF630896EA292FC43898A679C7 -:10B3D0001F50FC301576C749E5141F2A9609CFA5E2 -:10B3E000CCDE8ADF95027234F70328F77F0C6F3FBB -:10B3F00045F33E00FE75E8BEC0E8ED476AEE193041 -:10B4000082BF3372FB9961EDDB476C3FD86EACA60F -:10B41000DD3689CB0D5F5C847FA4F81EE6FF17C77D -:10B420008F9EB79655ACE4DB9B40A2E13E94C23FB1 -:10B430003B1CF594C72646F07D533D8811E4A71EBA -:10B440006B2DCFBF48D1E6B1A9F78BB4E1BD215038 -:10B450005E66D1DAEBA56CA0679A807EAAD65E2FD5 -:10B4600046498AFB532CDC8EAFA77D527D8A562E2F -:10B47000F4E07A81F9E8ACB97D94F7166FA1BC8647 -:10B48000D1E20B6F3531CAC7D2477AEA51E7959EB0 -:10B490004C1ADB56007014E7B3C527A7AEC2B8D16B -:10B4A0005B0A3FB7811CA073A40D8907C49076ABDB -:10B4B0000D8109A857AA75FC1C00FD40FF6FC58FC0 -:10B4C000A1386B78BFEAFD312ABCB25E989D11327B -:10B4D000BFB794F531D4DF1DC907D0AE1DEACF1830 -:10B4E000C8A3FE86F28A94FE12FEBEFEFEA0AC6FDA -:10B4F000B5BF957769E7B7D2D047F35BA9DC5BAA04 -:10B50000F6F7079C5FFADFD19F920F36D4DFB7B40E -:10B51000F35B69ECA3F9AD1CF22F95FE12FEBEFEA3 -:10B52000D47C07A3B1BE16F969B4BC0735DFA1D03E -:10B5300091AAC97700CF6661A9C4D88302E78BEFCF -:10B5400014CFFA1EF2C5E5850D4EB253147F8FCE8F -:10B550000789743E88F4E8E2146E87A8ED1F692A13 -:10B5600060EE893C1E84CFAC2281CE1F4C2A10DCB9 -:10B57000B8CFB60FE407DE83B71FD63996FB9B1C06 -:10B58000F43CD824D3F310F8976E8A7F39090E144F -:10B59000737FF1C1247BD51AB43F4A2378FE75D15D -:10B5A0002CB06C83FE1BAC975366CC73BC89E5E072 -:10B5B00039B4CC0E8ECFB8F204BAF73E22E7745FEE -:10B5C00013C03B0A4419F3CA77C823C7737E5ECC05 -:10B5D000E3443B94BC491F9E9724A502FE24CC7FE4 -:10B5E00095422A262EA4F3368BBF154DF64DF5371E -:10B5F000FAAD7618C72D42CE6F32001F7F54EC9BF8 -:10B6000055690B481E84FBA771A8A972319F50F49D -:10B61000FBE1D765D665E4DF2EBB91B118F87E312A -:10B620007E077AEA578A7DF45ABF91A1FFE72BE79C -:10B63000FBD7B7DCABF54B1F3407EC68173E98130C -:10B64000C7901ED55BB5E53B0C7CBD2D0BF35317A6 -:10B6500087E5FDA8F720EEC05F6732D655ACDCFF6A -:10B66000A2E4FDDC85721EE338293194E4AD9ED35B -:10B67000341AD988FB926A7BBF53E4168B73131E6E -:10B68000D43C39263E9383DFABFDA9DF3D2A3C93B2 -:10B6900074B5B829D88167FBB3B8BE477BFD3F8A34 -:10B6A000B5F94997178EFB4E391B896F07248C53C8 -:10B6B000A8E3FFDFE2D71DC57CBEBF9AF3492E3F4A -:10B6C0006797C242CFD7A9F95FCB866089EE15563E -:10B6D000F3FF9863201BE9FD9FB3239DF711FF291A -:10B6E000F648E04DDD95C8AFDFDED0381CEE54CD16 -:10B6F000F955A5BDD1F03CDABD13F413921FD9D290 -:10B70000EC74D079BA78BECF3626AEEC3C9EDFC260 -:10B71000F27735FCA53DA7D5D2FD94807ECB63782A -:10B72000BE4D1FEC17E3C06D166CD7CFE34A81A75F -:10B7300028FE9B521B105AB383E781C2E562CA46BA -:10B74000ED79B3F0FB142B2DFD922063BC7F80CEEE -:10B7500031CE2FE1F4A23B3BB05E3CB727C5641D60 -:10B76000CF17192B73FB3263202D74BF636A899244 -:10B77000671AF9C65619446F46C943AB306FAA32EF -:10B78000EA8DADE9288A4BF6AEC23CA9CAE4373E41 -:10B790004907793BA9E4610E4F7EE39371004F2E78 -:10B7A000F9570ECF6284A42925DF5D85FBAA534B90 -:10B7B00094FB95581F9DDB4E4CE27CF4F73E45A36D -:10B7C0006EC47539A3448D5B323AA7ED39F18B33E2 -:10B7D00028A73C6A9CD7ADDDDF64CAFD8937A8EC99 -:10B7E0001567237B6901FE0EF8BC41B97747670AEC -:10B7F000105E2706EF3579F8EBDCBB133C27CFEF63 -:10B80000116A69645EEDFD886E85FF79DE903A1EEF -:10B81000B5FF61E3C2FB016342C7B58FDA51C7F5DB -:10B82000718ED1274C0BEED7AAE3FA5818D88F4166 -:10B830008F033D7D3548D78FAD0369F8774E60990A -:10B8400079098E1FD82F3843603DA7E3CA921F9114 -:10B850003D559CE45E5982F97B067E7F41BB624781 -:10B86000EE8AF7FAD0AF077EA3BC4D5F2A3FC750E0 -:10B870009EABFD7B6CEB4BB85DFA27E55961DC5361 -:10B88000FF7A2EDEA72EB066A8BFF9F3CB06F4FB35 -:10B890002B4FF0BFD7BAE9F83B06F4DF37210CEDA8 -:10B8A0006CDA6718F1EFC17D888709F8FAD5F82BB3 -:10B8B0002FA566B6C5C17836ADE1F76437FC34BA5A -:10B8C00002E1861A9A255B5174B4023F5BE9E96E86 -:10B8D000C3E72AD6FF12EE4B5479B57EC4376BB559 -:10B8E00076FFCA7AADBDBE6A0F5007F4DAAAC6E485 -:10B8F000B0FBFCF83D81550A3DAB1CBBFBF0FE8163 -:10B900002A16764FA08FC791BEC967004F6D7CA4E1 -:10B9100012FFAE14CE63A34871DE9752B74B78FE88 -:10B920006D733DBF9FACA2EBA281CAA11EEE2B2579 -:10B930008CE1F7E1A9F253D5EFDF7CE1801EE3054E -:10B94000E1F705AE5A3E8FEE055F2E6FE0FA7DEC13 -:10B950006F2B62E07DF83D80D55D5CBF57370A7E76 -:10B96000BC77F79BB55A7F6025EB6B437F6665BD5F -:10B97000F6FDAA462D7CA444D1BF93D9645C1FCFA9 -:10B98000960812AD1705BE90FADBD702C83F499E54 -:10B990004EE4B78D86C054D473E5495E82D5727883 -:10B9A000BF89EB21AEFF75B09248FEEA79DCC25741 -:10B9B000C7EF67FBE6307B20C45E1087C3EFA9F2B8 -:10B9C000D3ECD94A7ED80B02FD7DF072C92DC58417 -:10B9D000F8C9E17CF8BE223F5F63FDD938AE4C6404 -:10B9E0003AA04BE632FEF79F335FACA1BCCACCE96C -:10B9F000825347EB58C71AF15E3190172817D0FED3 -:10BA0000C4FB3232C5CEE524A7A719ECFCDE1D0726 -:10BA10000B5DFFEEA79880F9823874DAC74DE9A56F -:10BA20007B371675ECBE88722E63BCDBF5208C6FFD -:10BA30009772AFF6AE9F0A64CF6ECA7E99E4612218 -:10BA4000B005F6BBC9A1C8C52EED7D188928A7F0A1 -:10BA500000CBC26CEA3749DD7F50F37A036574BFCF -:10BA600054A2D2EF971532FF7B7B1B3A059C772AB5 -:10BA7000F335631CEAD7280BE3834F759FE0C6E0DC -:10BA80003EF97AA4679DA39FEE8751F7C947A8B7EF -:10BA9000A5247E78BDD1E4EFFFF5F37F007E0B583F -:10BAA000CA008000000000001F8B0800000000009A -:10BAB000000BED5A7B7054559AFF4EF7ED4E7712FE -:10BAC0004227813C0C819BD72C90109B8420E8EE70 -:10BAD00078BB3BC984D7D8E1310642A49909BB5150 -:10BAE00092741474A3656D1A616207DD2AA1D045B2 -:10BAF000CB3F1A4A5CA756778366B1D186ED80A109 -:10BB000050519B151D184B2AB0AC23C50089382E07 -:10BB1000CEB0C37EDF39F7D27D3B378A535356ED23 -:10BB2000EC26953A39F73CEE39DFFBFB7D171430F4 -:10BB3000C15C80071C002003D499AF650C5760FFDF -:10BB400040492E607B9D7EEE1CDB9A6D26906DC079 -:10BB50007FAEE39FC5910AF2F4787FD1F46C5D7FEC -:10BB600089B34037FFAE7925BAF146A55C37BEAC44 -:10BB7000A15AD75FE1BD4337FFEE268FAE9F92B744 -:10BB80005037DF2E2FD5F5D3A6AFD2CD9FE0FCA93D -:10BB90006E1C26F5E7792700586D81611FD221C8F8 -:10BBA00000E665E1BED6F4209B08509E8193B14D1E -:10BBB000ADB6A7531B9C9D126519D8DE925149FD65 -:10BBC00094B71FCC8BE236B6892FDB5CD8FE130B03 -:10BBD000B9B3710F2493AF1FE938F351504209F400 -:10BBE000FC3B8F09A026DECE517C77BAB0AD7849F8 -:10BBF0002E408EE04F6CA67716AE4FC57FE7E0DF94 -:10BC00003E5B684F11C0ADB827CC8FEF03F5AEF99E -:10BC10000AAD7B54590093B01F064719CEDB6D0562 -:10BC200085FA817D56BEAE223C6C52D2E3EB86147F -:10BC3000C6DFFBB4D7BD80F6EF8C3007E0BCCE9DED -:10BC400067AD7205F50733146C2BBD67AD909EF898 -:10BC5000FC8C959E774A23A90E6CFFA5DFDC103281 -:10BC6000909307152BDFFF4821B6788E9607CDA15C -:10BC7000143A3B288B5D286F4D20E4AD65EF48D426 -:10BC80008CEF6FE960CE003E6A92EF5B0C4857F094 -:10BC900059CE0E23C96DF87BBD18CF999FB11B6E8D -:10BCA000E5EB017200D608D6C1AA79510BD1ABB928 -:10BCB0004DCCD7F8B96679FD795689FB76253D9F3D -:10BCC000D23B6ACEA0F5D2D9614D1EF0DE3F53269D -:10BCD0004CFA2C0D3BE55071BD04E0A4D76478AF5D -:10BCE000CD1E0960328EFB3C9CDE4F23DDCC8CE800 -:10BCF000984C2741BF6FA3CF2BC4EB043E25CF0B3D -:10BD00007A049F5E61D0D49F3E76FC5DE2239E67FD -:10BD1000378B558119C0EF4DE572DA6C5BBBFE5C69 -:10BD200035D1FFAB5E46F4FF570629B8FF27836F76 -:10BD3000E7C824E77B877286713F7FFF500EA09C87 -:10BD4000B55BE44DD2242E07CE4DC897CE70949F9C -:10BD5000BFA3BF7A909E778499D38E47F50F8CD678 -:10BD6000F37BC270AF239DDE6B7CAE6D8A899FEB47 -:10BD70007945E6E7F7FBF09D93687D4A28C488EF94 -:10BD8000C3562E17FB193C85FDDD7DB6A690C13E3E -:10BD90007F4FF4C6F56FF55941423969C7F5748F85 -:10BDA000238547AC36929BBD782F46F738BE228D4F -:10BDB000F6DF680199C5CF77B130769AEE7FAAD5C4 -:10BDC00002017CBEB9D5CCE97D6AA399EF635EF729 -:10BDD0009FBD05D85F89F29782473DDC7AE548012F -:10BDE000EE7BAA0DFB785FCF3A0BD7BF95F7333EBA -:10BDF0003F597E35797D4E95CF953EBDBC25CBEB29 -:10BE000018396DFB6E721A8ECB69E57533E77B5D71 -:10BE10002EC9CFC3E0DC43FA73EDB02517CF5BDC4E -:10BE2000EB703E86FD59E6D0CF73C82E1C16E3B3E7 -:10BE3000DB7731615FE45574AF82A015B63292238F -:10BE4000C1AF77895F93E96A232C8DF4558A1593E6 -:10BE50001DC2572BC4E7572DD0B4B7829E0BFB32BF -:10BE6000EBF5BC5D5B13E4F611551E35BB576E0553 -:10BE7000DFDE749ADF7F4B23EEF30AAEA7E753D5DC -:10BE8000FDCA4A46EA1BB1BDA0083BF8917A0EAD47 -:10BE9000FF0F1EB11FB4A396211D97D804DD17769E -:10BEA0004757D33DE64EF17D42F66FF1D48FDB016B -:10BEB000ED44B0F89D0A1F9D0F9C269AEF57E97E2E -:10BEC00078FEAF9FDF80F7B5CF48E57C6D3CF46C22 -:10BED0008CF8DC592A01F1DD5E3627D767207F5ABE -:10BEE000EBBF5A04BEEC78BF33325AAF18E8F57690 -:10BEF000F5BCB3ACE2FE104122E5737B2CCDAB8ADE -:10BF0000CFD3EE0FF018BFA7BDEC05CEA70DF7C33A -:10BF10006C333FF136BE4F73FB71B616F7B9DBA237 -:10BF200058D291CE1F4F6C5A7FAE0CE09D1E3491BB -:10BF30007891633D36F0FD05C0FB3D0EDE8FF5E4E4 -:10BF4000F1FEBFF7C8BC9D31D5FB0705F759F15687 -:10BF50005719D1EB70E1335E37BEE7F2310BA7031F -:10BF6000809BD369832A7B572266B0E1F89501163E -:10BF700002163FFF3D570BC087F6E457F43E5CD8EE -:10BF8000D1FD21B773CEB6D17A399DE4EA4C2FF5B5 -:10BF9000FDDDBFADA7B8E134FA09922F7F98411EAD -:10BFA000EEB3FA6A365FDF113E6E95490E4C23F50B -:10BFB00044FFC041062497FEAE516E3F9FC77B29C8 -:10BFC00078EE1FBA32F9FDFD91D926C1CF39224E44 -:10BFD00051F93F38F3771964BF6CDDF20777101F12 -:10BFE0008F9A391FB7BA47321C067C3989FB428ABF -:10BFF000383FB5C9E34DD6409913D735A9729B3C5C -:10C000007EBB4BC82552D8427102FD30A4DB6A5575 -:10C01000BE5AF02A13315E581D66D154D4DB96887F -:10C02000E7BC446D1783B33A7B007056D367F3F8CF -:10C03000F276B36D27ED5716EFAFF4E1A609714E16 -:10C04000735B1A39D184F707F83D520A4B737DDFD1 -:10C0500010DFF987315E437E75622024A3DC775CB4 -:10C060002DE7EDA5FD8FCBA427B6D49167C82FC0CF -:10C070000F4C8E3DC8DF8E803EBE2953F5A0CC23E9 -:10C08000E8B6D4C5A4CFA673BB554EF7AECDF7AD79 -:10C0900070E1F3DF147E9C7188D4DB1AAD04E3E712 -:10C0A0009D80FED846FA84EF2D47FEBC6A70EE995B -:10C0B0001EF72A8A9FA6C2535CBE01E59BE42AF9BB -:10C0C0009EEB5CE25C9A3EAF3C74DE4AF1AE3F6CA4 -:10C0D000ACCF351ED73A3A4F1F4083919F2B57FD67 -:10C0E00073C74EC6E9E5DF99CDE97411767ADD288C -:10C0F0009717F11CBB512E2F7BBD6999B8FEB2CFAB -:10C100009B96951ED7FFCE9D697C5D5FE9D2ECB50D -:10C11000D87F4495FB4B618F8DE87CCF4EA177DAB9 -:10C12000FB4E47576693FED45846AC4E1C9F1239BF -:10C130009341715DCDFE65D9A47FE39DF33EB7B811 -:10C140007747F786F5E7B2853C98519FD6AB7ECC12 -:10C15000FF58D44AF45FDF0D5C7E07F77DD249FAC1 -:10C160007B2992E620BF77F1405A80ECFDE58329D8 -:10C1700021136ED54EF28EF6ECA265F8C73C7EDC3C -:10C180006F7604709EFFE08567481FFDFB501B71B2 -:10C19000DFF591C747C9BFB547169C97A87DF9FB46 -:10C1A000D5878EEE87F87DB5FE851E9B4CF6F39203 -:10C1B00024ECC4FAF06B3C9E5D7FED4AA5B782EE9D -:10C1C000F9FBB964CFFCFF76652ED931FF9B57E6AA -:10C1D000D2B8FFF5B42EA3F8E4798F99D355F38F35 -:10C1E00045272425715E9DAA07455B9E6A2846FA6D -:10C1F000D51C5FEE34CB09F25566F2D2FC9A8F6AF9 -:10C20000B3D725ACDB12931AE8F99CE3B569AD0905 -:10C210007279BBC7A2DA21D46AB43F2B551AAECCCF -:10C220007B3266AEA4BE1450E308769DC7DB204B7C -:10C23000C8E766FA0F55B12F26F17826D0660E951D -:10C24000E17873CCA4D82B691CD725C41900DE452E -:10C25000B388DFF74E766E95B9BF871EEA3F5C164E -:10C26000227F0F01DB5069421CB432668AA6A0DC33 -:10C27000344552A2140FAD8C4967785F8D8F4E3BC9 -:10C280005EFD7931F0F8E85C629C83F1D0397DBCC9 -:10C290000413E8BC5ABCF431C55518CFB66C8C5A9F -:10C2A000C85F619CA49BBFA6E947E7290F5BD3AD9C -:10C2B0007F5E14934C4BF09E4568EE880C7DB11D5B -:10C2C00036D20F2DCE247E0D18E8FB4FDD429F3570 -:10C2D0003DDA1233713E6C89B96DA5D836ABE303F4 -:10C2E0000E130470FF2D91657B186EB6E5DADD69DB -:10C2F00044AF2D2796C263A4EF0EB7AD8CD65DFB7D -:10C30000916D45455C3EC6D80FB7B08FF178C0D867 -:10C31000CF4D51DFFB7DF9BB3CF79F87BFC3BC7A94 -:10C320009A7B32CFAB9B293ED4F2EA643FA1D95F1E -:10C330006DDFBB547A8FB5BFE779FC82F92FB7BFA9 -:10C3400077B9653E6F4AA4319BE7C5279667CBE96D -:10C3500063F72F919CA6AC8AB1FB6BF19A3FA00CBE -:10C36000D9288F51CC5C3FFDCB598851DFCB789CCD -:10C37000ED5F6D09D1B8769ED872C6E7AD70B29008 -:10C380009DC5E33F2D3EBC313E07C78BE2F1A216AF -:10C3900017C6BC8CE741CB150B1F9F31D557EFAEAD -:10C3A000A1FBD9F9F39AF9625FB40343941FDDFD51 -:10C3B0001306DC0EA8F1A2269FC9F1E41791928919 -:10C3C000DF841B3DAFCAA5A65F5393F442F3538F9E -:10C3D000B8047D3AC94F57939FFEDA4A7A305EDC43 -:10C3E0008D7E7A959BAF03BE7ECE4792D728EFBE57 -:10C3F000A8FAFFFB886FD84E89BDE5A2F316426C00 -:10C4000013E58BE3F9CF856A1C33DEF8232E91AF59 -:10C410007C9B1E3FADDEEFFBD2E36D6E71AEFFED98 -:10C420007A7C23FEB31ADF73A6C7F51CC96FAAB9BD -:10C430002BE622BD7B17F54E1E3BEF2E2D9F944021 -:10C44000C79FA142AB89F21E7F9BC0018299F20770 -:10C450003C3F79DB0CB4CFFAABF93C4EBBEF6A261C -:10C460006F83F920FCE883451CB7B9EFA5E31605F7 -:10C47000D7376F64B3090F6A6ED3DF273859E138B5 -:10C480005BE000E3F17230BFFF08E955604F894C73 -:10C49000FBB7D065090F69CB0C6D26FC82709C5BE5 -:10C4A000E9796A9C0EF89E0EF5F91D2ABE034971C2 -:10C4B000C09B83A738DEE31F6040FA6B8DA0FD2090 -:10C4C0007B7254E01D9D1161173EEFB6737BF2B98C -:10C4D00024EEE1EF66A14D2C1E479C8F6CCB213DD5 -:10C4E0001B134F28184FE4C4E3898E173EE2F63041 -:10C4F000397EC81A10EFF1B79B4384C70C15CE657F -:10C50000D4EFC07C3097E24459BEAB409C0B42DC78 -:10C51000AE283A9C64F72DC2EF7F71F43F781ED9A4 -:10C52000BC9F41368F3B9458694E3CEE58135CC813 -:10C53000FDBF1667AC997664A880F653E30C07FE3E -:10C54000127E981C6774868F5B282F18134F24C5A2 -:10C55000119FB9F5B8E03449E0ACD322CC4178D290 -:10C5600034959EB7F5A5F2B8B8FED3D66CD2738DCC -:10C570003F971A05BF2E9DFAD245EBE67E2A39C8B1 -:10C58000DEBE796AE38705A22FDB645AB7318DF2EC -:10C59000904B9F3E9046F47C135B407D7DFDA464F0 -:10C5A000881F2E57ED11FAB7DF73FFF6A88A1B4BD1 -:10C5B000E8DF26C4F197E4751BD475414C3338EE9F -:10C5C000B81FB8FC06F37D0B79FFD962D8C3711F81 -:10C5D00021AFAF45321D14EF95E365BBD14EFC731F -:10C5E0002A6CB157913CFBDEE1FAF1AC89CB2FAE5E -:10C5F0000F30EAEF95B9BF2BC7BFD538BFD28A67D6 -:10C60000A902F132D4B7992ADFF2310FFDCCC64529 -:10C6100068F975A453F994A35F131F2B5341A2FD2E -:10C620009FB0F8B6CEC0254F0C4ACE4DB4467266C8 -:10C6300037E2BD9EB08BAD9ED88FF28AE742E9E625 -:10C64000E7EAAC387292D633D901AB717D675E7A76 -:10C6500094F033085B7E73432E510E18BDA752C869 -:10C660001BE5A30C14761DF9FB873A59D8859F78F2 -:10C6700081F2A0CDF3BA80F2CEDFD5811A07D902BC -:10C68000E770FE0A5C31119FE7E6FB96505ED89199 -:10C69000376C1571C58895E28A55E47FB8BD15B829 -:10C6A0009D09E793BDDC3AFD552E6FCDF43C419FCB -:10C6B0002111DF338FED3FEDD6F64B7EBF2CF2CE4E -:10C6C000A4F7CFC9FC2287E72FFFFD5F19DC9F4548 -:10C6D000AE70BF73792405621CB71B163875C4C2CF -:10C6E000F3F5CB98074D4EF067AFBB041D0E453CEC -:10C6F0005C1E0762B56934FFB4FABCEFC4F2654B47 -:10C70000484E6292B38C9F52E4350331A946C40768 -:10C7100063E8F4D76E033AD952853D4F96CF1C5546 -:10C720003E733CE2DE9E53225FF16F14F50387AA4D -:10C730006FFE2EC6EDCA91C21CA6E1C8B946F585AA -:10C74000FD23DCCEB6DCCB9C0179FCFAC27635CF7A -:10C7500048B6439DE1BD826FC9B86D433DB73B37D5 -:10C760008BDB0265C373E376FA7E8F6A5766091C1A -:10C77000F7AADBC1EF9BD535DB950BF1FB1BD0F3A3 -:10C780008CC780EF06F3466A0DE86E306FB67273A1 -:10C79000F3FEE626E73D7893F39E566EEE1E176E87 -:10C7A00072DE4737F9DE5F18E92DFC1FAD8326D70F -:10C7B0003993EBA2C9F5CE94B7D70568EC71F6E4CE -:10C7C0004894A89BB1AF89A1CA4A992FD8484F165F -:10C7D000CF177581BE5A5B68178BD747357A9DAAEC -:10C7E00013F197A36234908D749EAAC46AB3519FCB -:10C7F0002FCF079E3F5CB68BFA00488EFC46CE3F9B -:10C8000047FE52B4FB41BB719DE94975BFF1EC098C -:10C81000D4BB3E257D71505C6EC0C78D2A7EE70873 -:10C8200003C76D4092F397F2F7CAF9E46F26BE256D -:10C830009E674441D9C5CF25172DE571B45C44E707 -:10C84000DBAED6BFB216FEA088F0BA2CF4BB541FE4 -:10C85000D94675129E0738F83CED7DADB5E27DDB1B -:10C860002DC0A89E1598C1789C0AC31319C99F565C -:10C87000DF3866899E5BCB787DE3AA07EFF79E29B8 -:10C880005AB1BB48F085E85B31E0E07597F7E7FF08 -:10C89000E3741F7F8FA8776C7088298729DFC073A6 -:10C8A0006C3850CDE5B7F9D0FC5FAEA6B8B054E215 -:10C8B000741E138FAB79D649354FD4F2AC61CA17C9 -:10C8C00013F28EF45AD378FE30DDC8DE6C67220F87 -:10C8D0000EBC27F2E06AABB3A42B814F79B5827FFF -:10C8E0006BA3028FD5F2DB4A2564CA413A543F6CF0 -:10C8F0008EA6A0BFAEEE9D6525BB5DDD5B98CAF13F -:10C90000A5D6BD268DDE467C2F56CFD9777484D729 -:10C91000275E4BAA53B6D65AF9F887AAFCB4D602BA -:10C920006F3794499BC90D4FFC4B87D9081F6FC1C6 -:10C93000F89FCEB73628CEABD5435AA2B287DE7366 -:10C940006668A497DAAAB6220FC70FDB477BC97FB8 -:10C95000FAAF5D397227C703AC32C557C9FB5EA871 -:10C960001338E26B149010BD1648219A57BD40E26F -:10C97000FCCE6AB1F37C3CCB02E674EA370A7F5600 -:10C98000D530C9437D589EC9FD71D55139735D4578 -:10C990003CDFCF5AB07132D1E9DBEA441A6E306322 -:10C9A000AAE2213E7ED73A51C7B11356BAF73DC32A -:10C9B000FA3A9156F719AF4EA4D569FD0D5FEAEA30 -:10C9C000CA7E69A49EF095EA0367789DD81F668E9B -:10C9D000BCA278FDC83F306AE5F455EB4638DF4A23 -:10C9E000EB067A44FD681FBE9FDA30DE57C173BC88 -:10C9F00081F7A53682F7A5E7077BA6F336DAE3E4ED -:10CA0000EDA19E79BCAD46B1C9CFA2BAD328AF3B48 -:10CA1000DD5BCB248A53B5BA855697A8CDF7B613FC -:10CA20009D12EA16BC9F5CB730A78A7CD47FD4E203 -:10CA3000DC8DCFFDC76CDCCEBA226BA7515CF6D57E -:10CA400071DF3407AF0364F3BC5293874B8AD39EE4 -:10CA500049F980D769A77A41F5E079ABCCED4EB4BE -:10CA600000F2087F8A5929EF273A283C9E73D9891A -:10CA7000AEDF8AEF87FF1FDFFF2EF8FE485C2FB97D -:10CA8000FDA8F29A945DD41E55ECEB12EC439F572F -:10CA9000E0C47DA5C55CFF76788B335B13F1FC06A3 -:10CAA00091C7652D28B5273EAFA917787E1603AF2D -:10CAB000911D7BA3D6345E1CF846AD615C645C17A7 -:10CAC000E86B107644C3FDC7D6099C6F9726E0FD3E -:10CAD00097DE4339C5BC75707F0AF7E75F1D48D9FB -:10CAE0004DF1775543EBB409D8AF3A990245C21FCF -:10CAF000E9EA0BCD0D26C59E61544F500A4C28B76C -:10CB000063EA060D266EDF6FD40D1AA433BCAFC6E0 -:10CB1000E9F78CFE7A421123FA87829467BCD6C16A -:10CB20009C8330B68E801B17C03CBC45C3095E5742 -:10CB3000767631A72C7F7B7D2147C5193AC399664C -:10CB400092F396B700E8BBADB17586061EEF57C1EC -:10CB500053C15AFA1EABD4E4207F968C17909C9058 -:10CB6000FF4FC60947547F34A2FABB87D5F8BE4AA7 -:10CB70008D4BB475C9FCAF53FDD378B8634D9D8818 -:10CB800027B63454F511FF028B4D407E604B83DB9A -:10CB9000569AB09FB94E7C47B39DEA169312EB1696 -:10CBA000A23E915CAFD0EC54F5E0D7F5C4FF1D1167 -:10CBB0008127F9F304BE597DD07594F43E7E4E7101 -:10CBC000BF1DC8E3188FA39C9920EE0536817B71A9 -:10CBD0009CA16AF19787D2887E5EF45764978E9500 -:10CBE0006E4E277BB258AA6132C7BB6FE0DF844F1D -:10CBF0002DFBA06D2190FF5F31FB38D17DC56A0B05 -:10CC0000FF0E49F357CB3E68AA17E3BB1E4BA5F1B5 -:10CC1000E9CC6997E979839B9E2F7A394A481F2C82 -:10CC2000A1D3A1DEC48E9D93485F664CF595D4E1F7 -:10CC300079AB1B551C7CB5F0AF2B228D16481FEB32 -:10CC4000EF0E177EC5F3E82B916A8E6F6753FDB523 -:10CC500022EE2FAA0FA01F9AF0A7F34375750E4E70 -:10CC6000CF5BD10FD179B21A459D3099FF6695FF00 -:10CC7000E3F995F1EC28F911D33CA1372C2FEE7F85 -:10CC800065CAAF6F8BFB614718FBB9DF807BABF6E2 -:10CC900029739C38EC21557EC7FD7E23FCFDE0E026 -:10CCA0000FD4FD99E0E06A9EA3E1E15A5EF49E4A4A -:10CCB00067AD7D5F6D93F1320D27CB5500BABF0193 -:10CCC00027CB251C2D8BCC7605C7EDF2D533DCC0E8 -:10CCD000CDA259A6EBE5384FC5ED34FC2CE79E7E7E -:10CCE000467146210436917D19B2826BEF24FA6EAB -:10CCF0008FC126D2EF50238F73869EFB55EF2FE80E -:10CD00007BC301E620F7D3D17F9CFBE90E8C6B78C7 -:10CD10003C14B92070AA7EF1BD694798294638E8CD -:10CD20006F55FF5CAB00B71B1DEA777DF50342AF83 -:10CD3000E338D14352224EE4976393B5EF0543C2E3 -:10CD40003F197ED7D70923FC7BC0CE36E68CE2F3B1 -:10CD500064DC28192F7A4AFD0E705CDC48F96EDF1E -:10CD6000FBEDAB9B30E933025355FCF99447D88572 -:10CD7000261F63B4BFCDE46DE7DFFD1E640EA3EF95 -:10CD8000478FA972BF48C56F5FB40A7978F17616EC -:10CD9000A2786E11089CF6C5836B397EFB62157311 -:10CDA0009AE89E2A5EBB50A5C78C385EBB83F0DA3A -:10CDB0001FA33B219C7691CA7F80107F4FE3CED486 -:10CDC00028C51B4F58FAF3481FB5EF8D1EAD13FE53 -:10CDD0002E3505BA8CF4335CE77AB48ECF1B37BF9F -:10CDE0003C596710EF14D58A7D4FD7E9BF2F4A8889 -:10CDF000D3CFD0BA84389DF793E3F43F155EFBB7E9 -:10CE0000E3E3C555C6F1DA98797B6E12B77BD68815 -:10CE10001E9B55FC2499BE4ABD6687A73838EE781C -:10CE2000E3FC20EAB92AEE35A4FAB920937F79070A -:10CE3000AF7F5978FD4BB333C10962FF89F5C2EF6B -:10CE400068ED4C75FFA0C518A7A951E7FD305FC973 -:10CE5000A8C779E52FE971B359FD7ADCECD6709655 -:10CE6000AE3F3B7A8B6E7EF5D162DD784D6CA66E5F -:10CE7000FCB69355BAFEFCE1DB75F3EFF8DCADEBE5 -:10CE8000FFD5881E37BBF3AA1E37D3E4DB8512918A -:10CE9000B8CE63FB996E5E419BFE5E855DFA7B4D6D -:10CEA000EBD6DF4BDBB728A0BF5F49507FBF2CC25A -:10CEB000F52BFE785C7F6FADACE2FA25765AB7BDF4 -:10CEC000A1D44E714C6EBE90576DDEFF0085A782D7 -:10CED000721032000000000000000000000000009E -:10CEE0001F8B080000000000000BE3146060F85185 -:10CEF0000FC1D3F9191836F323F8F4C0C7981918DD -:10CF00008E83302303C33E20DE0AC46B80F83D03CA -:10CF100003C352203D07882703711710BF048AD529 -:10CF2000B1623787858D81810D884F02CD3AC54C1E -:10CF3000BCFD8A7C08F6215E0686B5407C9497BECF -:10CF40006130D8F00C41FAD9F50C6AD76ED181F76F -:10CF50003708B38A3330304A20F8FD12A8F26CE269 -:10CF60000876960C65769501F50300295128158001 -:10CF700003000000000000001F8B080000000000FC -:10CF8000000BED7D09785445B670DDEE7B7B49BA28 -:10CF90003B9D9095257480202A4BCB1201113B219B -:10CFA00089010306440928D26C2184249D01661E50 -:10CFB0003EFDFF6E0842C4D1898A1AFC195F83E0E6 -:10CFC00004079DE0A0139DC0348B8833E804C70597 -:10CFD00097795F401E204212A338E8F3C9AB73AAC9 -:10CFE0006EBAEB763769B7FFF97FFF840F8ABA55BF -:10CFF000F7D4A9B3D5A953754F149D9124DD40C82A -:10D0000025F8A1E5AB0A2124255876489DC3E58182 -:10D01000C1F6B55E1771190979C06BC272BD379D33 -:10D02000B8AEA0CF47EB8AFC1642EEF7DAF1F9E38F -:10D03000DE122C1FF59662F988D78DFD1EF29663DD -:10D04000F92B6F0D96F77A8BB0BDCEBB0AEB372A62 -:10D050000BD2605C425CA6AC64423C2F0F1CB981D1 -:10D06000D6D6678E4F9047D3FA5FF5449F45DF1BB6 -:10D070002D17F987D206B9A4286B74B09F8AE78D63 -:10D080004A5E5F80F3F8581DEB67AA792D3B72BFAB -:10D090002C3286E2395646FC89A564727672C47ECB -:10D0A0008301DE2343D93C89DDF9DAA0C8F0AE065E -:10D0B000780F0DE5F825DB270F8A0CCF09FD7EE5FB -:10D0C000E4F0D23B0F0F8CDC6F0CF4AB7372787D05 -:10D0D0007DA60191C71D0FFD62E013C589105F8B0E -:10D0E000D19F9DF5FDF9455CF42FC5A763AF79EBA2 -:10D0F0000609F9370DE8B4D6BEFCCC163A4E7BCB08 -:10D1000030A7DE41C8672E6782DD1213DF6E81799A -:10D11000C4C0B752182706BECD8D916F0BA05F0C0F -:10D120007C5B02FD62E05B658C7CFBD94F846FF712 -:10D13000021EDF836F1B62D4B75FC5C8B78D31F2A3 -:10D140006D538CFAF6648C7C7B2A946FEA73B5DCA1 -:10D150004124B48B372A253BA09F27B3CD3620EB43 -:10D1600027C1BF3DDF53EFF6C7C8BF5763E4DF11E8 -:10D17000A04F0CFC3B1A23FFDE89917F1FC4A877C8 -:10D180006DB8CE58E4AFDA8610FCB93400FEB5D8DD -:10D190004F5DCDEB7AC03B89908C7039504BCA51B2 -:10D1A000940799B8DBD9BA55F0CDA51C425698E83A -:10D1B0007FE9FBBE3C12D0D3F17D36E2AF9584FE11 -:10D1C0009F039E84E47F732955E8EFD345EC4F74A9 -:10D1D000D0FE30C815E5FF66EF102CEBB91C6D2EA4 -:10D1E000D2A13CF8920D285F4F789DD8DEE01D8BD0 -:10D1F000E5635C2E3772397A00E4EE0A90C3522E52 -:10D20000574CEE0829719453BA76EC89271B1C28D9 -:10D21000576609F09499BCDDBBE7CAAD1B28FCCD6D -:10D2200035BA2BB785C8D91345AA7C51C94C0EF61F -:10D230007BA2FC846DC150A4B70DE03414EBD47E06 -:10D24000BED07E0DEEEE7EBDA0DF63C55CBE641277 -:10D25000081DF7B1D2EE7EE912A5CBBD12296DB241 -:10D2600084F3658AC4F4942A0AF243E6F4DD9F77D6 -:10D2700096B4D1F76DF6916984964F827EA2FE39FD -:10D28000B054DFAFA77476537A641A494D13E04B5C -:10D290005A2585E22B8F7524821C3D34CE45242BE4 -:10D2A00021FDA19D8EDF67741BC9A265E2F83622BD -:10D2B0000D837EB49DD653787BC650DA4EE13C0494 -:10D2C000EDD6607B2A6F4F73F0F7AF63ED0F7B09EC -:10D2D0008EAFF6BB8FF2D94DF15B47F1C5E7C5C400 -:10D2E000057494293BFD21F39F2DE971DE95BC5413 -:10D2F000F1BF2FFB54C6FCA1417CCD832F66CC0F20 -:10D30000C1EFBEC173B0AEE263BEA212EBFD57F532 -:10D31000A69E18D707124EE7D49903847687EC446B -:10D320003FCD71444F7C945F0E2A9E91F8F3051512 -:10D33000E71F54FF5C8C1EDAF6BB3574589721D278 -:10D34000C1D05BA4C3BADE221D0C7D2E4F8729926B -:10D3500003E147A3873AEE862BC571E3AE12C7DD22 -:10D360007095386EDCD53FCCB8EBFB89E31A33C53A -:10D3700071D7678AE31AFB7FBF7189ECA40F99B953 -:10D38000200EF8679E60DF2E10F7C3A0DF60E7F481 -:10D39000C9413B27DB4B88DB12E42791E9CB39A15C -:10D3A00070EE14EC2A85F37F381CD7E5E1D8357090 -:10D3B000E66AE16CE37048A89D0E8343EED0CEE3AD -:10D3C000B7FCBD802E647CBABE92126BE87B4ECD5A -:10D3D000F8B76BC7DF0D760CE6A1BBECF80E0D5D60 -:10D3E000E768F1D9C3E110DDE5E841EC1A38B3B5DF -:10D3F000700E713801E9B2704AB5F3785DE5AB247F -:10D40000AC5F941EC382EF75E4759E423FE845C54C -:10D41000B19DB64B7FB2066EA0FD8F6C91FC465A53 -:10D420000FEC8DC7F5E3FCB6E958DF778D11D7898E -:10D43000F3CEC97E23B527935E78DB06F6A5EA0511 -:10D44000BD0C75DDDE8F6D6D142F8FB1F5C1EBE86E -:10D45000F3CE17F4642B4A63A10EE87E8ACB2659DB -:10D46000C5EA656656ADDAB2EF4E805BDE6C2466C7 -:10D470000AA7EAA525D3AEA3F5258715025DAAB6AE -:10D48000AF36F4A6F5A57EA909EA1D79A41CF469B6 -:10D49000CDDEFF6C87F5E8FC6E251BC63F4BD70938 -:10D4A00007B5C747ACADA933291E15FE5D85F05EF3 -:10D4B000C54EC9492D1CC577FBA10CC07787E43444 -:10D4C000527A2F6B8C270ED5DED1BFA776EB71FE7B -:10D4D000CBE9FC0985B784D417023DAB803830BE58 -:10D4E000D3E8374B417D3BEB3D8CE3A9F5AA1D7496 -:10D4F0003CFA7EF5739213A65AAD236EC0B3FD2598 -:10D5000073E9531698E76AC3602BCC6FBD01FA2DFF -:10D51000F1CF7FD1EC003CB7180A01DFCD5B0C6581 -:10D5200043817E645EC950C0EF2F227E0D7A17CCF6 -:10D5300077F935C6AD7AE0A72530688635DCCE9E12 -:10D54000A5EB952364FDAC20CCEE13D96F983E2C4F -:10D55000F8FC257D22CAC1B2463D7184DA0D2E1F2A -:10D56000BEA384F9317BACFEED59413E2EB77379F1 -:10D57000E57C5C9EC8F92A77E6CC18168ECF83C06E -:10D580001723F38FA07C98AE9B0EF47F1C48BFC777 -:10D59000A8FFE440FFC889CF9FA07E12949BA99F5B -:10D5A00004E593D44F82D24FFD24E8B795FA495051 -:10D5B0006EA37E123C7F9AFAE7503652FF1C9E3FC4 -:10D5C00043FD7228777A7DF8FC396F1D964DDE7A1F -:10D5D0002C9FF73660B9DBEBC77E2F7A1BB16CF658 -:10D5E00036E1F397BDCD58B6780358EE053ED332F9 -:10D5F000E06DC572BFF7189607BD6DF8DE21EF1913 -:10D600002C7FC9E96E9B4072652A2F3617B1039BA8 -:10D61000928A5DB9E0AF2495B07AEA1DBE5C03AD95 -:10D62000A7BA699DD2B1776520D748EBBD6B587B0F -:10D63000E63D24CF44EB993ED63EE097AE3C33AD79 -:10D640000FA867ED8337FBF2E2687DB09FB55FB549 -:10D650003390174FEB5735B1F6E12D649285D6879D -:10D6600007587DE411D7242BAD8F6C65F59C0F7D99 -:10D67000936CB49ED3C6DE1F7F2E302981D6C77728 -:10D68000B2F6895F937C3BAD4F2412D6F32CB9F9E7 -:10D6900089B49E6767F5C2BEF3654784F57DAFD256 -:10D6A000B6104CDACF7539B932F513F61ADA56805E -:10D6B000C95DAFBB21571E47E9A79045D0BE49576A -:10D6C000C4EA06B212DA7FAB9B8EF5FD8A03DBF764 -:10D6D000E8E6B0BAC181ED7FD52DC4FA41C585ED2C -:10D6E000C77595AC6E7061FB67BA9FE37887143796 -:10D6F000B62BFAFFCDEA0637B63F2CAFCFCDA7FD4C -:10D700002BF56E8F8ECA75ADE42E2703415E9BD23A -:10D71000C11EAEE37EEB2C9D03E57E5D8601F56CBC -:10D72000EF7FE53C857A063FC9502F7B1AFC5E0AE5 -:10D730006715C251281C7DCF70267E33568033F189 -:10D740009B7215CE6A84638E0DCEDE6FC68BF87C1D -:10D7500053A1C2D9A0A3F6BED61ADBBC265E9A207E -:10D76000E273A95285F308E293181B3E01E55A01C2 -:10D770004E4059A2C2D98C705262C3C7651827C0E7 -:10D78000711996AA70B6239C8CD8E0040CD789F83E -:10D790001896A9709E43FAF48B6D5E2EE3F5223E37 -:10D7A000C62A15CE1F109FACD8E0ECB78AF4D96F0B -:10D7B000EDA64F00E164C736AF3C9B489F3C5B370A -:10D7C0007D5E433857C60667BF4DA4CF7E5B377D6D -:10D7D000DE4438C3629B575E82489FBC846EFA7CED -:10D7E0008070AE890D9F8329227D0EA674D3E72415 -:10D7F000C219131B3EF9A9227DF253BBE9731EE146 -:10D800008C8B0DCEC154913E0753BBE9F305C2B9D1 -:10D810003EB679E5A789F4C94FEBA6CF258493EBF3 -:10D820006E447C0885638D0EE7503F913E87FA7504 -:10D83000D3C7A407380514CEC09EE114668AF42924 -:10D84000CCECA64FA21EF462726C700E658AF4399D -:10D8500094D94D9FDE88CFD4D8E655D85FA44F61C8 -:10D860007F461F8FB173921DFCC644E2DC4A5F996C -:10D8700094FCB383B0EE2816E204B047A4C036800F -:10D880004FD756F44B65A7EA073909F8B9C536876B -:10D8900013E2017AD5DF21ADB81FB1EC4C14E24D93 -:10D8A0002FE9F38603BE56EA1586FA3D0963E304C1 -:10D8B0007F2BD19524D47B15F516FAA7940C10DA9A -:10D8C000D34AAF12DA33DC23857A9FF2F142FF7E2E -:10D8D000357942BDFFAA2942FF2CDF0CA13EB06E74 -:10D8E0008ED03FBB7E81D07E454385D07EA57FB95B -:10D8F00050BFBAF15F85FEC39AD608ED239A370868 -:10D90000EDD7041E16EAA30E3F21F41FD3BA5568C3 -:10D91000BFF6D83342FBB8B6E785FA75675E16FAEC -:10D920005FDFB95FA8DF70F1CF42FF5CF237A13E45 -:10D93000C9F481D0BFC0FE91D07E63FA271A3F564A -:10D940008C5FD4E612E6CF6618D09F0D580D58377D -:10D95000EC35B3FD0DD493210E518C75C3FE858E2D -:10D960006488070000EA4FE4F62EBF02E255BF18B4 -:10D97000EFBE02E2B8BF30B847D823F841EDB2FBA2 -:10D980001E3DC6135B25920EA54307659C9EC713DB -:10D990008C4C7ED767E53CE50BD183BA7ED4BFA023 -:10D9A000F5F57A8AC798A0FEACEF57963E3F649C87 -:10D9B00075FD0CA55B87B2E70B2D305EC97D309EEF -:10D9C000C7D03918F0D28E631C305618C794598EC0 -:10D9D000E36C84715282E31833CB35E3984AB7F293 -:10D9E000E77C9CC7406FA28DB37EC078713E9915CD -:10D9F00038CE16CD38EB332B34E3C4B1F9D0E77C05 -:10DA00009CA72E378E71E004713EFD2B719CE7B40C -:10DA1000F3E95FA919C782E3C0731887F4A5BB981F -:10DA200034CA67636719CAC19FCC182733F4A9F8B1 -:10DA30000DD4C90766920DE338E8B8B41F199244B3 -:10DA4000859A907FD127217FBE88A3FC0F89A705E7 -:10DA5000F7E33EDCD72FE628123FC588EE93AAB93C -:10DA60006C2EDA393D73858396CD07063D02E36C53 -:10DA7000B43AB369BDBD7992616104795A5CAF9CD7 -:10DA80006A0B91F3EEFD591E195243C75F116747A8 -:10DA90007CD4BA5A26E9C4E727E8BE8BD0FDC987F3 -:10DAA000749F42E87EE52385ED33FF9DEECFA0DE37 -:10DAB00046F767D04EC86A7CEF048F339FF8A5E421 -:10DAC000077A7F71D7CF145C277CE4ADF4548826A5 -:10DAD000B09F79ABE2291382F8CDF7F512EAD41C96 -:10DAE000F7D1A5E3BE16E3079D2F19FD5B81AE7547 -:10DAF0007D284D79BF0184BCBB77EA21C986D53E1C -:10DB0000BAB184CCAC995E90865A24F55B4EF19CF8 -:10DB1000B1FB1A85BE41DA95B63B9D96205CE25278 -:10DB20004E007D4CF40FC0B9A588D643C6BFB5449E -:10DB3000ACCF2272B04EF97D523F80B0F83F1FD774 -:10DB4000E15280AF25748E1994D5B3A01C09CD2C59 -:10DB50005E536A67EFAAF878162A2480FB6B5F0A87 -:10DB6000C4B1892F19FBCD51F7C91AFC4A1593ABE3 -:10DB700084D2B574BE1EE9AAC5F7FDBDF12EDD70D5 -:10DB80005AD63DA24068B627FC67BBC57652CEC6C2 -:10DB900053E9AACACB29CEDF13C07F5A9E06FE5393 -:10DBA000BC4F72FE07E598F1DF63744F03FE776E9A -:10DBB000D213E417E7FB6D9CEF8BEB45BEDF06E766 -:10DBC00071B4FF6D2BB358BCA9A197C05F3A719196 -:10DBD0000EF50F1550B31A86FFDFB91CCCA9DBF583 -:10DBE0000AB0F7F672CDFC381FEEE47C98ABA1C703 -:10DBF0006D9C6F7339DF9610DFBD1918BFF02B10C5 -:10DC0000D79B5D2E11B0179EBB55BEB5097C73AB7B -:10DC10007CD3E07B27E7DB9D7731BE69F16EE37C47 -:10DC20006B6BF84C2103C2F1D6E2396F95665E3E0C -:10DC30002DDFEAB95CDA0DE04F4D77E5AE3819D249 -:10DC4000FF96A2C92B4E86D8855B4BA60BF559A52E -:10DC5000B385FEB3DDF385F6DBCB970AED736B7E00 -:10DC600026D4E7ADBA4BE83FDFB75A685F58779FD5 -:10DC7000D0BEB8FE21A1BEA46193D07FA97F8BD076 -:10DC8000BEAC7187D05ED5B44BA87B9A5F12FAEB1D -:10DC9000F65E7933C8D791B7F504E27D179CA731BA -:10DCA000CE78C1A938A1CF49AF03E5F8947708969B -:10DCB00067BC4E94F3B3DEB15856834C8E033B7B66 -:10DCC000C002F1534F1CB5FB89741D97C7ADA99BCA -:10DCD00000EB0D6D1F4FC8BFCA37ACF1F5A55A0058 -:10DCE000716F4AFFE20603098C2254BA7B77CB732B -:10DCF000A73EA4BDAD87F60699047A85B717B74548 -:10DD00007EDE21750ECE80B8EC7B46B23D24DE1857 -:10DD10007EDE42FA805F11ADFD9C8E94879EF76C8B -:10DD200095D939CF117DDE5699E2556960FA5FF9D0 -:10DD30007C461EB1413D30B8C67299F19A283269CD -:10DD4000C0E78182DE2F69B83AA8E704C661F6749D -:10DD5000A97F94F07C59E375C27B6F48EE2D80C794 -:10DD6000B97D7A5CAF49E040E62DC3003FD7561934 -:10DD7000D6D1E614F4BB5ABDAE15271542DEF41613 -:10DD800061F996B704CB77BCA5581EF3BAB17CDF16 -:10DD90005B8EE587DE1A2CFFDDBB0ACB36AF0FCBDF -:10DDA00013DE3A2C4F7AEBB13CE56DC0F28CD78F85 -:10DDB000E5596F2396E7BC4D58B67B9BB154ED6790 -:10DDC0004FF27786AFAF67410E8DE1727670EDBC92 -:10DDD00035757D837276582E433953E95BDC60E4F8 -:10DDE000F2902AC8C35F611D4E0179E9A1BD41E1EE -:10DDF0007218EDFDC8ED206FBD7F047923640DCA54 -:10DE00008105E4EE7BC81B8153841490A73E1A79E8 -:10DE100012E550952355CFDF904ACE817CA97265DB -:10DE200091993FA4CAD5FDE02746F0B77A2B125F3F -:10DE3000FF987F4402B93A20D9727E5E417C2EACB5 -:10DE400077F1B16B29B856E827FB87C03AD235E4A1 -:10DE5000ABC110DFEF3A4685202BFAFCB4F2129DDD -:10DE6000EE2EDC3F94F929F37B85B79BE3185DCD5B -:10DE70003A524446C2F972CE3137E567DC9FAE1E96 -:10DE800009FB66FA5C264900C7EF9C1EE1BC800CCA -:10DE90002248E79EE8ABF63FF5C47FE6C0B9BF0570 -:10DEA000F49CCE3DEE80BE86E9EF53CE5B42CE972A -:10DEB0003C46673AC4C13BB30D76E63F4C12E94895 -:10DEC00026E1F9814AC703D95F0C86F399FBA81CA8 -:10DED000827E750D1A9C402E231F3DD9FB9EE8B90A -:10DEE00000E61B133D0D04CEB9283DB7C27DC758CF -:10DEF000E9D9939DECC93E9ED8C0E87C84FBA7D1AC -:10DF0000E8AC9E8769F1B84591391FB81C933B3442 -:10DF1000F42F15E8DFD7EAC0FE07F77E9009E7780F -:10DF20005DBBAF48204343DF2F60E73DDDEFE70BEC -:10DF30007A20FDE9EF99B03F3EF8C2BB58AE254CC0 -:10DF40000F375A4AE62A6382F062BD47106D5E1EA3 -:10DF50004512E7D5837E76A4AAFAD99A09F2B49B32 -:10DF6000DB81B0F9F5209FEAFC0EC0FC289CA920BB -:10DF7000D3741EF972C95DC2FC46A7E0BC7B9A9FB0 -:10DF800027C140A411143FABC14012A83C2AEEB5F2 -:10DF90000AEEEB9C6D3E8853EC8D77D65296786CEA -:10DFA00067DF0838E03D319EB1ACD15C23FA4F8980 -:10DFB00035A2FF945113EA3F751D7ECAE6A6F82DDF -:10DFC0004FD7D79CEC05EB9C8BAF736C5D55F1ABD9 -:10DFD0006ACAAAB10870C47A57BD54C4EEE13812B7 -:10DFE000664638EF53CBE5E9061CE76CE3C004183E -:10DFF000F7ACD754C3D6577B0D1B37BD26747DAD08 -:10E000005C155F73725410BF68707F68FCA8449001 -:10E010008F4CB02ED2B681D1FB47E5A7FCB901CF1A -:10E02000D55B942FC07F370F51FD7719EB2A5C4FDA -:10E0300093DE671C01CF770AE3D1F71CEAD938BC1D -:10E04000175D6E64724AE5A71ECEBB08DF1F98906D -:10E05000CF6E0A3181C2EB902D7520577E85E9B3D2 -:10E0600087CB6995A9CDE07620B95B41AE178C5579 -:10E07000E5DC31EB036AA73FFE8B82F7CCC8D714EF -:10E080007A4EF0AAC322526283A0EA82DDCB8A6173 -:10E09000DDFEF8C59BF83EBD3E07E67D9EE88AC0E2 -:10E0A0002E9D276FDA4685E8EB6985C5B1481DDBF3 -:10E0B000E7F8E81F98DFE27A71DFB3A441AC9791EB -:10E0C00019A9606FCB362AC44F715F0AFB2675DE33 -:10E0D000D4FEBEABD811B925A4661DECD31F53588E -:10E0E000BC67819DC87DA8BDAEFAC3AF7320EED3D7 -:10E0F000AE307F573D0F5F9AC4F6831533FD061788 -:10E10000EDFFD1EE51B7518B4BDFF7AF43FF673ACD -:10E11000716E27E1745F5827E2D713FE5A7C553F92 -:10E1200028EC5C9EE391DC2845BC2FF535B773AA3B -:10E130007E2419EC42DC274D5357E540E172E0574D -:10E14000DC56430AE33BF051923B0DEE907E866035 -:10E15000BF24C398E8FD8CD04F8FFDD258BFCE426C -:10E16000DC1F132A4F4383FDCC41787DD9B862BFB1 -:10E17000AA3F3CFBA28FCA4BC5EF1EB511BA6E7EFB -:10E180002CD7A73AE9F3CAEDF7DA5CB43C23FB6C71 -:10E19000C0CF8FFDFA88F77D6F31A8F470592488BD -:10E1A000A771F924753E8C537CB15DB1E33942A36C -:10E1B0003160A4F259BD7B6931198EF5E3ACBEFE26 -:10E1C000533DD49B457E55FCE6D15407BB27C4E2A2 -:10E1D0004924807E6EF5B6FF2884F5C2433A51CEBD -:10E1E000B4EFC1F8179350AFE71B12C2DBF16270B6 -:10E1F0002ABCCF7E3CBBEFFF546F8372F269D02301 -:10E200008F464ECAB9DF0AF482FD7EBEC19A8CF6F3 -:10E21000FE5A722DE8BB4A17E267FE6BED8EC78788 -:10E220001FA7789DDBF6179B3434D44E3079EB6A08 -:10E230005AF86F265D747BD24EE531D44FA280F13F -:10E240003D4733F7BB5B5859A9046C701FA7728B0D -:10E25000E2A492482A9FD513B89F40DE33FA213EAC -:10E26000BAECD957DE194FE9BF6C97925CCCA66324 -:10E27000915283FCF1D0BFAB4606F951F1FB570C2C -:10E280008E61ECF93D4941BE2CDBB5CF408685D38C -:10E290007152D33E439B25027F9A8E17C27A5BBB95 -:10E2A000E31F06882B7EBC57226959E1EF976F79EF -:10E2B00005D73DA013F293F3AB9B7F617C0B4C7BA6 -:10E2C0007934F6B3833DEC896FD9B09F4B41F97E29 -:10E2D000EE65B8C7F4BED10974287F6E850DE6736C -:10E2E0005AAE6172FEEB7B5341DFCB155FAA1D4B2B -:10E2F000F6BCFCC99FA3FC2D39FAF354F41F882BFC -:10E300004387B6D99701F35CBCF9569C671971A392 -:10E310001C96FF5A5F02F74C2FC8A46857043DF9BA -:10E320008B81ED5F4E6FA5CCA5F33C0DF8817D7B15 -:10E3300053EFDF8E71F39FE13DB89FF339D3951012 -:10E34000EB174C8C5F5B0C3A351E6A12E477DBFAF4 -:10E3500056E0D3D97EAE3438F7A074F071BA49973D -:10E36000285CFDD18234C627E29073F87BD4DE4F5F -:10E3700082E7D0BF557199870BEF71FBC8C65FC9A3 -:10E38000C7A778C7C1FA753A35B2FFF70F3E3FFA13 -:10E39000D34A42E42C44DF99FE6FBB8FE9BBAAFF4E -:10E3A000FEE945D0FEF95B4C8FE03D582F285E8199 -:10E3B000346CDF375342FB40F7D991F47C9BC2F5B4 -:10E3C0005C6CA73B1C5CFF5539A1F8CB5242A8BC42 -:10E3D000D07192900FB83F2EDB48DF0FF1CB3C306D -:10E3E0002EF633049F87AC1B4BB85D38A4B107648D -:10E3F000734A4C7E74A5E27FFA09D0DFF78C4E9FFA -:10E4000003F4572981F97FB2F3C03B73A89C7FD2F4 -:10E41000A4EAAD6857B57A5BFEFC1812496F3FB1AC -:10E42000D07D5724BDA5CF23EAADA50DE5F9FF9614 -:10E430005D55E9D7AEA11FD8C7971DD1E9A8B58F03 -:10E440001B0C8E88F691FEBC4572C2E550953F5577 -:10E45000EE2A7E5BD51FEC50B77CAAF2D72D9FAA7F -:10E46000FC69E72BD24FDBFE07D06F8AD7EDA64DB4 -:10E47000D3C07F3675128CC3E7CED4E33D4DD3E7CE -:10E4800084DDD3B8231EEBB3F46DBF079FF083AADE -:10E4900059C3609DBF9DF814766E5FAFA01FFBF55A -:10E4A000A54B13E87CE670FADE4EC93D95F2A35405 -:10E4B00096027114CFD932F12524413C59222742CA -:10E4C000F0B8BD5CACC3CFC4D4209C9EFA7F5BBFC8 -:10E4D000FBBB9647295F4F6413F2372871FF411D3C -:10E4E000EB10799ADEC2CE313CA325FF00D4C336AF -:10E4F000B924641FE13132FB7334FF963140BFDC35 -:10E5000059C312989C0FC6FDA287DBB12E9F230131 -:10E51000EC7B57CB40DC17761D5E687547B067070C -:10E52000B89CBDC2CF613A2C52BD9ECA7D07E9445A -:10E53000BFC66731478CCBCD31AA769AF38DFEE802 -:10E54000E9F8A55C0E67D357134686F06DE6D48FC5 -:10E55000655B381FE0E744C8BEE2FBD217E41AE867 -:10E560007BC0DC565812217E53C9E93771FF9706EC -:10E5700058F7F25B7265A063BE452FC4431619B904 -:10E58000BE0E254301AF89FB973E3086CAB1E7B086 -:10E59000DE69A6F3F3B47C6A7047D8DF69E909F055 -:10E5A000C1BFDC6A64FEF2DB4AC962A0EBDBB7B232 -:10E5B000F3DEBF199C5591F04C37337F733629B980 -:10E5C000305AFAE9D1377796359047E9D16561F746 -:10E5D000B5C3E58FE97D975DF2AF96400EF5AC9E31 -:10E5E000CCEE371712F7031324D4F71B42ED576E06 -:10E5F000F3F467E13E4D758B64D7D1F66AB9CD006F -:10E6000072EC69DE2583DF7E9383B8707F2DD70C93 -:10E610009B1912FFA2CB1ED2EBC05773E6027D3FBF -:10E620009B692480976BE8A73658FF3F6B19857A62 -:10E63000106D5EAF7BC9B47C05E0307BA69587C2C8 -:10E64000E478A17EEB24D217CE81271ADB5638233B -:10E65000F02FDFC4E42C66FB66FAFFCCBE4DA0F6BB -:10E660008DC9B5126ADF2CA630FB9616C9BE2D5F88 -:10E67000ED4803B958BE67207EBFB5FCB5C52991EA -:10E68000ECDBAB7CDFFB1ABF07DED197DAB71121D9 -:10E69000F6AD2FB56F11E2E45FC46ADF4CFF33FAC9 -:10E6A000F72AD8B708F3359B44FB56D4B21AED5B72 -:10E6B000515FBD705F8998A87D8BBF9C7D9BFFE8F3 -:10E6C000AD58579CF111E407E80AF6ED356EE760A6 -:10E6D0001CB0733798587C33563BD72F563BF73FC7 -:10E6E0004467D5CE2DEF27A1FF122E87CCCE2DCF9C -:10E6F00062766EF91E66E79667333BA7B56F796160 -:10E70000F68DBD5F3D84BE8FFBC7ACC7EF80FB8439 -:10E71000A58AD344FB173BD4EF276AC684DABB1B18 -:10E720004C32D239CCDE393FC5EF607AB2777F0503 -:10E730007B978D766C10E891563EA60C8A17EEB347 -:10E74000BDFDE5A9DFFE0EF4E5753DDE177A57C77E -:10E75000F6477BBF3C350AF4EE2113B3BF4B4C8C1C -:10E760009FED5E1FDAD3494399BE57DDC3E857BD1D -:10E770005B62F35DA9F73B601DF8EA22EE9FE7EECE -:10E7800061FBE759C6D69478B897F42F0A61DF7D0C -:10E7900090E2F921F2507AB102E380CFC7D9B6C234 -:10E7A000FEB2542626F063E71D9EF231F8AFF32E39 -:10E7B000D6A1DF3B0F9EC33909BF27A1DEA398D3A3 -:10E7C000BCEB953E24FC7EC44423E3C3C415927F76 -:10E7D0004B16DC4710DBE769FCFA757C9ED49F453D -:10E7E000BA90BFEA23C6EFD669E9E164F3AF5AA94C -:10E7F00017E9512345A407E568F1FCD4E0FCE7BE26 -:10E80000D0B6AE0FB42F95703FA5D2433B4F953E87 -:10E81000EA7E651ED7114FCB2E05F8A59DBF4ABFD6 -:10E82000B079ABF4D4CCBF4EB51F579361A06FEF56 -:10E83000EADC0F8C01F9F833A503C5EBB6D9D96929 -:10E84000A1F6F8416E97A6BA8FE7A73A806EECBBA7 -:10E85000C439E5BB5E49A5F3B9D9953512BE1FBED3 -:10E86000F52B831BE20B07CC9D68DF54F9FA84CBB0 -:10E870007B80C379BBB73D1FD79166C98E7A13D011 -:10E88000D82F7E7FCC730FD3AB03D23FD6F5198D33 -:10E890007485658014AAEB10F081FE776A0BE38320 -:10E8A00007F840FF3B8D741E023A57274BCE00F409 -:10E8B0006FDE752FC8CDAB66FA1CF4B75C72B2EF91 -:10E8C000CB882523F5B2F22947924F0C4EE404D7AA -:10E8D000C579D02F29DCEF98686C7D1BF09848F53E -:10E8E000610B09F74354BE0FA17F2E45BAF7D383BE -:10E8F0001C7FCCE5F355A0B705E8DA69007FC613A5 -:10E9000060EB87DAEE911DF9481F95DECD747D1816 -:10E91000CDE8AD8B40CF9BD53AA7A7A74552E0FDE8 -:10E92000C974FFDA4B82D3AD2F0FA9720CDFC36914 -:10E93000E901F1808C10BD07FB147A3E59DD7C148F -:10E94000E932652575AF42E80E76EB72F489A617B9 -:10E95000D5CD3F8C5E7CA2D18BBDE6CEBF8C80F83E -:10E96000D71E09ED03694914F6FBF166E6671C3012 -:10E97000BB517E3B5F53F0FEB9D68E7CCDE51EF6D3 -:10E9800017A1DFFD4D8289809DB39BC9472A1E03D5 -:10E99000981C85DAEF57CD6EE45734F8717C1D8EE4 -:10E9A000E63FA9F51B613CB88FE810C70BF32F7841 -:10E9B000FCA7A779A5F171BFEBBCBACF3349AB81F6 -:10E9C000B0F8FF0A63C8B9D46DFC5CA03B4E16ECEE -:10E9D00067375DA61FC45F0274DEAFEE7C0AE3BF3B -:10E9E000E79F393E0DE477D91FF5C444F9DCBED367 -:10E9F0004A02ECDE8501D6D98ADDFA88E72884D47C -:10EA0000B2EF1C7F6745FB52F1BCD15F4CDFAF78A2 -:10EA1000F1A3E110B76A5FC3EC8CEF192E1FBEB6ED -:10EA2000E170BE5E21B373612DBCEBB8BC9C7B2949 -:10EA3000BE14ECA4D4C8BE5FAD689AA51843F6E92D -:10EA400023CD0A8E4BFBE1BD65DF0E09E3E5E1F85E -:10EA5000AD66F07630FB57D1ACF8E13BD88AC62DD5 -:10EA6000B8BFF5347E6A00BF6ED2EF9E65DFD73641 -:10EA7000EBC5F861A33E60C438A7FEB87138D35B1C -:10EA800049884755A15E5637F13899267EB4EC7710 -:10EA90007B5EF451D22CFBFD6F6C606FCEB66EB70F -:10EAA000617CAE91C5DF648B1C393ED7535CAEE907 -:10EAB0003E1E979B7A9A0C0F8FCB9D85FF503D9CF5 -:10EAC0006FE6FAAAC6351B7BC5747EBEECD90B4F28 -:10EAD000C279D2B9E73F7912F0AFFCE6B327EF86EF -:10EAE0007389BD663BAC7F9E67DEC6F8BBFADEDD90 -:10EAF0005CCEDB77FCE6E927A81EB6BF67C47B5B6C -:10EB0000ED7B4E67C2F78CEDBBBE4C85F8E6CA3D87 -:10EB100005B89F59F9C2A4B4CBDD3F01F9F4C77021 -:10EB20007EA2E5C781DD7A02DF739E3F6644FFA3C4 -:10EB30003BCEDA54C5E2D70E1E5FDD19F9BC4A8D13 -:10EB40000756EFBEE5E6EB611DDCAD381DF89CC74E -:10EB5000077B8AABBE45F93A2206FEEDE4F1F3A647 -:10EB6000A911E3AAE7E13F944F9BCC625CF5C2EEAA -:10EB7000C5FFF604B4EDEE1535AE1A88816EEA795C -:10EB80005899D9B5CD0CFAF1FC6F318E0D7CA33EAE -:10EB900039697FF64226C423CE289D77E23DE53DC4 -:10EBA00046BC6754B1E75DD497F6178EE23913E19E -:10EBB000E751EDA4FB879D1BF0BD8E679B95C56358 -:10EBC00039FD215EEBB0E1731E976572ACC66BA395 -:10EBD000C569DF37B3FB50EAF95CD5B60F0C4413B7 -:10EBE000FF96C602BF8E0BE78AEABCB5F0EC408701 -:10EBF0006B43CF1FA2C5C3B95D0DE3173B7768DF39 -:10EC0000C2CF23BACF1908E93B12CEC7D9B9B9C7C9 -:10EC10002FBD1B89BFEAF9C3DB5AFDF4C776EED0DE -:10EC200033DEDF8D2EAF9AD9FE56A5CFB9AF23DBE9 -:10EC3000E94EAEEF749DE930E3B9315B67E6F175FB -:10EC4000A69AD28D7DF7C6F03DC7F781E79ED1FB2E -:10EC500061BFBCAEE900DA5BAD9E571316FFD28EE2 -:10EC600027C531FFA0BA79DF70B047E7F6BF84F25D -:10EC700057BDF3B8C147E11C6AFCBDA16D6850DE09 -:10EC8000C18EFB43ECF8B9E7F60D67E72291F3B4C8 -:10EC9000D8387C4F8B08DFB3F35301FE325F93C14A -:10ECA0006EE9799CB3B26B16CCF76CAB42E03EFBDD -:10ECB000D9267D913FC2B89FC13A362648A77556DE -:10ECC000F61D9F3EC9807EE64AEBD863F0FDF84A08 -:10ECD000ABC101FBEDDAD5EC5E65EDFF72A6035F1B -:10ECE0006A136FC373A37A0D1DEDC9F65CD887DB79 -:10ECF000F34B46835869ED41A24B27E0BDD25A94AD -:10ED0000E6B0405E2FE6A710D989DF19EA6D854588 -:10ED1000300FBD5D6737475C5F193CC5C2F266289E -:10ED200076F1BBBFEF900783403E8E6F9D07A353E4 -:10ED30009307A3FCC6FFD7F260F8609C9F401E8C2F -:10ED400000C677D43C18C93F721E0C882F8D0EC99F -:10ED500083D1A9C983C1F9F8CF3C18FFCC8301A5A1 -:10ED60009A07E39D0D650590A742CD83716683A741 -:10ED700000F252A87930BEDAB08AD5791E0CCBFDEC -:10ED8000AB0B42F36064DEBF01DBD53C18CEFB1F4A -:10ED90002908CD839177FFE682D03C1833EFDF5E00 -:10EDA000109A07A3ECFEE70A843C186BFF50007929 -:10EDB000305E8F77B7C6A544CF83D11CE788290F73 -:10EDC0000685F31EC2899207430B275A1E0C0AE7D9 -:10EDD00044DC98E87930C2F089920783C2F904E1F3 -:10EDE00044C98311864F943C1814CEE738AF287974 -:10EDF00030B470A2E5C1A070FE0BE144C983A185C7 -:10EE0000132D0F068563884F899E07230C9F287951 -:10EE100030289C048413250F46183E51F260503868 -:10EE2000E908274A1E0C2D9C687930289C2C8413F5 -:10EE3000250F86164EB43C1814CE55F163A2E7C1D7 -:10EE400008C3274A1E0C0A6714E213250F46183E12 -:10EE500051F260503813104E943C185A38D1F26079 -:10EE600050380538AF287930B470A2E5C1A070A63B -:10EE7000213E51F26084E113250F0685330BF189A1 -:10EE80009207230C9F287930281C37E213250F8620 -:10EE9000164EB43C1814CE528413250F86164EB469 -:10EEA0003C1814CE728413250F46183E51F2605060 -:10EEB0003877239C287930C2F0F9AE7930CC814183 -:10EEC000D240CC8381F938BBF360247FEB3C18BF80 -:10EED000027CFF9907E39F79307E8C3C18B75ADD9E -:10EEE0007F8FC77DE377CB8371265E9337A2873C04 -:10EEF00018B75A4BCE823C7FDB3C1817E2BF5D1E31 -:10EF00000C3ACE3F2E374EB43C183ACBB7CB8341A8 -:10EF1000C7912D632E339F287930122C62FE901FEB -:10EF20002B0FC6B1F8249C4FB43C183FB97C137426 -:10EF30009B05FBB4E9288AE427937F62B485C70D5B -:10EF40007FA8FC1330E99C9F52FE09358F41930244 -:10EF5000EBE1FB9CEFEF70B9F880E7A13816350FB5 -:10EF6000857F2AC677978A7928A6703ECE768BF25F -:10EF70003085B0739429F959FE5AD8AF976BF25087 -:10EF80000C11CFE98BDD47F3293832D529CEE328A0 -:10EF9000978769A59F1E04F6DC3C36721E8A199C71 -:10EFA0001FD3357499C2F9369D97B7C3A739549EBC -:10EFB0008BCB8FCA40D7698E3619E3F437A9FC731F -:10EFC00008FC9BC9E16AF19DC1F9376332E39F16E2 -:10EFD000EFB7807F14EFB7CA4721FFB4786BF1D445 -:10EFE000F29F84F23B247F482E11F34F4C3289F973 -:10EFF000270AEC62FE891BD3C5FC13931D62FE89B0 -:10F000009B8688F927A63AC5FC13378F15F34F4C1A -:10F0100077ADD6E4BFB84F93FFE2214DFE8B4D9AFA -:10F02000FC175B34F92F7668F25FECD2E4BF7849C5 -:10F0300093FF629F505F58F79AD07F71FD51A1BE38 -:10F04000A4E13DA1FF52FF71A17D59E3C7427B5569 -:10F05000D3A742DDD3FCA5D0BFA7FC036FF1EFA17E -:10F06000DFE1DF431FE3DF43BFDF43FE8B772C4B42 -:10F07000D785E6BF78DFE2590779098E5B1C3CAF84 -:10F0800040E4FC16DDED51F25F04DFFFF6F92F528C -:10F09000927FF87C043A2BFB1EB0B7254F674DF9E1 -:10F0A000EEF9086E2D11BFEB9E552A7ED7ADB3B297 -:10F0B000EFB567BBC5EFBB6F2F17BFEF1E11E7960C -:10F0C000000F6DFE8BDE1697CE0AF692E72908C078 -:10F0D00077BAD9106F2BC2F220E4BFC886785B29BB -:10F0E000968721FF052DFF0CF92F687904F25FD078 -:10F0F000F20DC87F910DF9337C3C7F461DCF9F51A7 -:10F10000CFF36734F0FC197E9E3FA391E7CF68E20E -:10F11000F9339A79FE8C00C239E13D8CE5496F2BB9 -:10F1200096A7BCC7B03CE36DC3F2ACF70C96E7BC46 -:10F130009D58B67B2F62196BFE0C552E3F04BFE124 -:10F140000A189FC9B32AA7573FF0C8BAD0FC1923A1 -:10F150001ED884721A2D6F460E7CD397123D6F46CF -:10F16000777B94BC19C1F7A3E7CD481BFDE3E5CD40 -:10F17000986BF961F266CCAD11F33ACC5B75F9BCD2 -:10F180001923E24A6E41F9E3F238D7125BDE0C9F95 -:10F1900055E2DFE553BA80DF45E982EB750F790769 -:10F1A0000E5A9F1E02FB89AE21575D36DF83562E15 -:10F1B000A2D39BE57798F323E7CBE889AE6AFFF704 -:10F1C0002B581E87B9966F992FA3877C0B07B3BF67 -:10F1D000403B196BBE8C9ED6879EE839E347CE979D -:10F1E000D1935DEDC99EBE3985D1B9770F7456BFF5 -:10F1F00097AE34B51EC297ED2E546D997F0F9F3B8D -:10F20000D38EF1998E9DFC5E9C8B38ECA9EC7B7DB6 -:10F21000F0373B9E4F184EF03B7E3B7151FEC4F3DE -:10F22000E7D2CE7DFBE05EC05A1B71252681B34735 -:10F230001CFA81B00FBBC604F19AAADD9FBEF1474C -:10F240000AD7DCA2C7FB721D148756F4FB5C89C089 -:10F25000B778F24BDCA7C319DDA55EA1DF756B7E25 -:10F260000F0774490D9E3F15E82DB86FEADACCEE12 -:10F27000B3EAC9D58F4F188DF7C689DF81FC433FAC -:10F280007519C7B38B106700FAEFB4E2FDD525AF4F -:10F290002D34C0A070DE1A1A37E85524C6811ACC66 -:10F2A000B6E1706F2F5DBDBFE773B5821FBE88C327 -:10F2B0004D2911E3449F2C283A0CFEF3227719DEE6 -:10F2C000AB482B15E346847F470FDB32F03365C232 -:10F2D000EF75FAD97DCFB0EFEA9BB7209E4BFD9A30 -:10F2E000FB4B8D625DA5DB392BBF9762219698E8B9 -:10F2F000D676C5E31392BF3DDD8CE922DDCC0E91BD -:10F300006EF14344BA68E966758A74D1D22D61AC56 -:10F31000185F53E9A6DEA7FCA1E89664E3F73C82F8 -:10F32000F42A31A5A2C9473C33E400CAB7561FFAF4 -:10F330005802F01B7E48BF64FF6A7CCB6995C16EA2 -:10F34000A533D0445AC4DE8B077D80FCBDC489FA46 -:10F35000A0FE3E8A78F22197FB8FC8255AAE987E90 -:10F36000F0F802DABA19E46D04FB3D1A18AF4A222C -:10F37000B89F5388D30EFBA826AFC9B94881734DF7 -:10F38000E25C940DE799762C1FE4DF3B770C25B8FF -:10F39000EF6F0A7C9E0AF7061E1CD9390DE20F9EFC -:10F3A000C5A404D6AF59096C7D5DC64B5B028BCFFB -:10F3B0006C28D111D768F87D4A7ABF44C76BB7BBB8 -:10F3C0005EBB01FCD116763F80D83BDFB81DDB4722 -:10F3D000E1F7E119BAFA6B001FDA1FBF2BEE68F9EB -:10F3E000C8B630C40EB7373F7225DC6BDDA48BFC8A -:10F3F0003D73818DFFFE1D7E3F654430DF42816D90 -:10F400000CE6657870001DA77A7A17F25195CBEB60 -:10F4100038FD0F964D41FC5E68911C10AF2BD4DF78 -:10F4200071D3308ADFB8B7657EAF97DD5F1FCDFB44 -:10F43000D79AA9FEA2FDAAFF1BFC9E95974ECA98DB -:10F440000F71744D19DE13FCA3ADF030F02BC7D54E -:10F45000340AE429BF2511CF713D1F12277E9AD5AA -:10F460002ADE07CCE1F7B673DA881F84E2DA63623A -:10F47000FBB836B17E9D66FF39DFC6F5D4465241F2 -:10F48000EE367EAD9760FDE8E824CE3514DF8E457C -:10F49000BD71FC8ECF09FA891D5FEB8B22DD8F5980 -:10F4A0006E63FCDB642068BF379559F0DEF9FEB26D -:10F4B0008AFEE05F7C7197BB7FA43865889F96C009 -:10F4C000BEBB772590B120876B2546EFFA8C92085A -:10F4D000EB962A77AA1CAAF2975116E78E740FF5BD -:10F4E000339B8472965736443280FCEC9530FCD5C1 -:10F4F000BE86E2759975DB47D6F4017C3CCD9FE171 -:10F500007D32538BE48A744FE7619B8DDD6F5CE342 -:10F510005B0DF7467E419508EC5486A13E2B127C8C -:10F520001FD9887EE95D36077BCFC4F320C9F51962 -:10F53000709FA2BD79D2E47514CF27A83EC07AB5DA -:10F54000497122DEBE2A42F09E2C8FD7F59D46B629 -:10F550006C08F17F37DB721B6D145EA38D7D6FD954 -:10F56000CBED94006FE77FFDC306F03B2E1A917F31 -:10F57000BDB9BFA9BE7780D3675C826B2BBC4FE05F -:10F58000979F51E3E374DB9C8B46415C9ED23BC466 -:10F590000E06F9E663F951DC04CF3F922C3A94430E -:10F5A000E27239ECC27D761FEA8DAA07242011C8C9 -:10F5B00053A0DA37A9450A58A9DC8F365902708F53 -:10F5C0002EA99CCE3B19F29A9818BC56F99C18D7D4 -:10F5D000A2F29803CE3DC1ABF3104805F8AADD5363 -:10F5E000EDE5DA44668FD63E24635ED4CD729B1976 -:10F5F000E2A9592E471EA4884C921D78AFA65F3908 -:10F6000071520C49FCC05F2776FB0154C9AFF94623 -:10F610003F2FD2775B176DCCDF1E97E0FE33D06BA8 -:10F62000F8E1CEFDE02E38CDA417BBFFC5ED04F701 -:10F630006B0AF97A37EE3F74EC7BD1C00D24F43BB2 -:10F640002AAD9DD86466EBFCB8EBD9BA37EEBC05A1 -:10F65000D7BD6E3B515688EBD4C8965107E09EC586 -:10F66000C80F997E126E1FECF40FD029E7B04F0F30 -:10F67000F4F9B67641CB6F123075D787EAE01C8675 -:10F68000EA5BC8FB67357664C5F441B5185EE6727F -:10F69000D4FF1EA7DE1D4247EDFBDD714AC9D4FD34 -:10F6A000DC3110ECC8113DDC0BE9C8A5F3A3F3DF96 -:10F6B000C8F525F173FF6498D7C6961BCD20DF6B84 -:10F6C0000379F662FA4EA2A9049997485C18CF19FB -:10F6D000493D32C88F518B4241FD41A58424A4C0CD -:10F6E0003DB42221DE432C493CFF4B00F9D22DA72B -:10F6F000548E43EFE5AAF2A99547557E6BE1A0052C -:10F70000CE0721624E4BBDD484878146B2D90EEB21 -:10F71000BBEA5FD6727FAED69CE9C7EF977C19E84B -:10F720001FADE4FE51ADA5D084E6605F32AEEB2B99 -:10F73000217E42E9B03285D979753E5AB9F45CD45C -:10F74000137FC83EC12377E27D44CF45033E5FA7C8 -:10F75000B807C0FC55FA5CC3E9A3A58794C0F79D20 -:10F760009C2E3DE39B63877BC1892617598FF8E662 -:10F77000E13DEEA6C04813ACBFF76AF08D01CF6B38 -:10F7800013C684E3295BA2E099CCF0BC8EB8FFD805 -:10F7900046E53767455D6D3CEA15792B3D275CAF43 -:10F7A000B47AA4EA8D1AE7BDB6B2FE005EBBED41A5 -:10F7B0006F3CF18C2E4EA504EF5739F7C4A31DD131 -:10F7C000EAD3E77CFE9E7846BF058A7B06CCCFA3B2 -:10F7D000EBCC043919EE20BD8A2992C39BF5A8E72A -:10F7E000A435B67BF8AA7FA5FA55DA7EAA5FA5DA1A -:10F7F00063F51EFCDA04F77C9003A999CA2DC5A70E -:10F80000D6CEF64B9B6DEE4580573CC53D0EF68D32 -:10F81000430259ECFB5F512FA2E941BC46CE9B024B -:10F8200032AE0B3EBA2E644BE178A8E30F4A48642F -:10F830007CA45A0EEB7DDF1CC206AB269837A7EFDF -:10F8400070E28675ABEF48769F714D02B3BFB50984 -:10F850006CDD52CBCDB692BB51BF65E2338EFCEE70 -:10F860007803AA70DF7C6D82EB2EA087A9C885F390 -:10F87000E863274EF04BFBC84D127C379A54E99051 -:10F88000D83D7312FC7E8BC2EB53ECC8057DED03B3 -:10F89000FB6BE8DF1239CFD8A309EAFD5EE67F3AB9 -:10F8A00049771EAF471398FF7908529FF42A56F301 -:10F8B00082A9E7394E09E8D46EBD0D916EBF2031A3 -:10F8C0003F3D91D14BBB4F00C287FEFEBD7B0D4437 -:10F8D000362791E0EF59D599D0BF8F27CE26B05764 -:10F8E000BB1206F0734C671DD47F25779A128706EA -:10F8F000E55D95E30727CC70422A52DBF55DC361D5 -:10F900004F45E57A27D0BF7D42D760CC41493A3395 -:10F9100099FCB8F442BE20950FCD8AC00733ECC3E2 -:10F9200043EDA4D53004FCD17629CE09F72CDA9723 -:10F930004A0C5FC9C4F329C9C23CD3E3997FDDC136 -:10F94000EDD53B09592827AA3DA6F3AB83523B0FBF -:10F950008F11EF7490CE3DF1FEAD706EA5C93FA939 -:10F96000CD4F3969A105EF7F6CDC63C6FD6B57098C -:10F970003BC7EF6A31A27D8EA6B7696DE688711C20 -:10F98000B5A4F47B0BE897A6D424823D4C9B7BD294 -:10F99000067CD7D2A543F25D7308F645AF2B11BFA5 -:10F9A000BB55CBF4F49B1217D1FEE91993B1549FC8 -:10F9B0003758E488F7CD4F73BD52E5F14A3A22DF5C -:10F9C0000F9D06793CEF7EF31D1709DEDF6F88631C -:10F9D000746C886374EC728F4F781AE4CD9781FA57 -:10F9E000B0583D07E5FB7F35CF943ADE46AF29514D -:10F9F000A62AD0B0608A19D68914E29A3C1B947565 -:10FA0000A342E03BA2C7BC3B12F3318E6D12EFF96B -:10FA1000DAD9BDE1CF3716E077DEA9648D7930A55C -:10FA2000475989CE09F183F30BDEB7E9A83C2DE8ED -:10FA3000D39A03F2FBBAE226F63118EAC2FDC99264 -:10FA400052833F40F996DC400D05A5CB7F03F9D4E6 -:10FA500012800080000000001F8B080000000000E2 -:10FA6000000BB57D0B7854D5B5F03E73CE3C929922 -:10FA70002433794E1EC009E19D108724BC1F4E9E81 -:10FA8000448830BC0485EA8028CF2488D6DFB6DEDF -:10FA9000CBC444F4A2B745E9AFF4D6DB7FB0A2A84B -:10FAA000200182069AA41340E4113408A8A8AD519D -:10FAB00029620BC908EAC5D67BFDD75A7B9FCCCCFF -:10FAC0004922D8DE4E3EBFED3E8FBDD75EEFB5F684 -:10FAD000DA872EC977134B64CCB7D8C0B64A8C7D71 -:10FAE00087BF1B43ADD96E602C89B196383BB54EAC -:10FAF000E70CC7D284F07E8563693E63D5D6D85CB7 -:10FB000016876D7F3F8B85F18A58EAD202685BAC1D -:10FB1000AE5A95B12546AFDD0ECF774EBA3CA48ED6 -:10FB2000E12FD8DF3392B12E236B94E2B01F606CCB -:10FB30000C4350F8CFED56EDD097F0FFE1FD448B2C -:10FB40002D20C3B8CCA35CECB0F047BE1B281E4DE3 -:10FB500066CC285E939ADEF846CA652C76721163ED -:10FB600070DFCA5C8FB22CB8318CA99E18C6A2D89F -:10FB700033F6F3D98C19F07D584757F3BBFD7C0061 -:10FB8000C71FFEE54A0C83FB1F29C118570E6317D8 -:10FB90001E3C15E3B6C1F507E5723FF46F4740C65A -:10FBA00087F0926F870BA3197BC4EE1981EBBA63C0 -:10FBB000DD7F8FF1DA42F7D903703195B1157E19E7 -:10FBC000E7E6F0C27FABB65919B384FA95F509118F -:10FBD0007DC018E1B5D2CCD6D4DB7AD26305D2038E -:10FBE000E65DB17D8B295DC5F9BD93ECD0BFA0C0AA -:10FBF000AB80EF0B0D317E5F66089E25DB4799D207 -:10FC0000E1D6474D6616807530A5DDC86C84B50A0F -:10FC100009F0E61578D3C379B8C54AE3DDF57F6509 -:10FC2000BF1996BA18E67A201E9E6F5A51C1727B90 -:10FC3000AEE3AE3FA8652940BCBBFE4D623E953F9A -:10FC4000FF601E3CFFC0235F20DDF4EB5CEC337EE5 -:10FC5000D211B16E376300CF3241EF3B1F8DBCBF75 -:10FC6000ACE9311A6729F39A909E776DD4DFBFE92A -:10FC700033E4BB654C095D073C5C3E9265453CDC6A -:10FC8000618F493C0F20038F8DFD0EDEDF7D6460A8 -:10FC90009C37A7277EB5F6E23AE06F33637F5E6755 -:10FCA000A1F6C23A46ED08BB4AF459DD74F27EE48F -:10FCB000AFAAC65D261CA7C5FFA78409F04861D37B -:10FCC000373232572173DF7B0EF0F92326B3EF0072 -:10FCD0007FBB19E79FF546CF3D48AF1BAF96D37D5D -:10FCE000FDFA1769FC7F249EF86711AE3B17AF2B16 -:10FCF0005FF6B6AE9FE2BA809FD95858977CFDEB6D -:10FD0000D2D6A3AD4FBB5F2903DFF5F2BEC6EF230A -:10FD1000843E58FADCACF569808ADAE6CFFA7710CF -:10FD20003FB1D328BF1A3F2D1374D2F38D46C76E4F -:10FD3000FE68FA775A9F463FE07FA7C1896DC06988 -:10FD400018D7934FF47CA1E7834E63477F945F3DC0 -:10FD50001F744A6C416FEBFA37FB405AD752D55D9E -:10FD60006687FB7731CF7A3BAD67235DBFA06C3CE4 -:10FD7000FC3394ABE7385F77EB3933973776DCE8C1 -:10FD800047BDB936464D71D804FD80CE9DBBCC3EF3 -:10FD90007C4E9BE7FC3AB77B9011F15E4EED9FD70E -:10FDA00079DC830687EEDFFDAB2BB12ABCDF358C17 -:10FDB00095A3DC77C644C2BBCF2E133CFB900EC884 -:10FDC0007F4AFBFF7C803AE9B9F631A847CF7FFB39 -:10FDD0005FB11E78BEEB5B73796FEB3C2DE807EAF1 -:10FDE000E5B413F8EC762167B73755125D963C33CE -:10FDF000CB84FCCC1EE0F8B4C01FEAD7B6A8D86705 -:10FE0000711D8B1B24D2237A7ADCE59AFA39EADB5E -:10FE10003BFD85F47E0FFAB0C789BE77213D86850C -:10FE2000E831D6A1727854F803BEB943F0CD7965B4 -:10FE30008DC9007AE4FC33806F007995C2DCBDE99E -:10FE4000C1FE0ECE877DAD47BF8EBEE05FF65CCDB6 -:10FE5000FA3486EB1F654AEB45EF68EBBF8BB9625E -:10FE600049EF88F5B28E1B495EAB2D7C5E6D9D2BF4 -:10FE70009AEE9C817C51B519E895D973DDA8771766 -:10FE8000F7026F997CD16881F7BA1E905CA86FFB6E -:10FE9000A283A627EE12F85AB96DF10C349A8B6141 -:10FEA0003E3913F5D1176FC624A25C415FFA1E7A62 -:10FEB00035C91F9B711D8CE37B09E07B8374FDF4C6 -:10FEC0005BB6B9D03D28ECB915FE9BDC83C2F59931 -:10FED0008EAE6CDBACD0F364B7DD26B4C7F10EA1F7 -:10FEE000BF845EEE5BBE60E100E7DA1D0EB26F6CB0 -:10FEF0008D83F46375D31653B8DDD5E44B93B7B156 -:10FF00000E3BF15955E313F41CE85FD501FD4A4B54 -:10FF1000C7CF6F55C3F0394ED051AE30A1FEEE4B76 -:10FF20007F82BEF9B2236C9D231CC2AE08FD7B2DDF -:10FF3000FDA0C1AD1F57D3071ADC1ADF6BEBD1F35D -:10FF40007D5FF0E9E9C2989FFB0B3AFAAC427A84F4 -:10FF5000F5115E05F0DBD66CF53F04F0B6491C7E6A -:10FF60005F7314C1DFE92C769F033FAF2A7521B57B -:10FF700027F0C554F4EB3CD3109F9A3FC70A1222D6 -:10FF8000FC247DABF93779C29FDA1BE5CE07130954 -:10FF90003F4F02F2C3949A8E391620D9AD8EEDE50B -:10FFA0000A8C3FE5898E3951D05FE8D8C1FB5B3BB5 -:10FFB0004E595C8CD5B057CA4BA07F3BA013C7BB32 -:10FFC000565B60F62C44F95D0D7E9205ECD1EAD3C8 -:10FFD000430EA1DCAD6EAF2897C0EEAC0683238143 -:10FFE0003DAA74C706ACB9D46713E0B9E7EDDE6586 -:10FFF000C42F57EBC86EAD3EAD70B9399248EB5780 -:020000022000DC -:1000000000F62878AF2E1AFC55C0575DBCC5559B2D -:1000100049D77D51F1D877AB6AD8758D1EF81EC2CD -:100020005167606E07B4AD4787C4757C8FDD6E5D28 -:10003000C72A14E08383EB2CD4EAEF179AEC83D021 -:10004000EE151A98B7377DF9A483FB8DC0E4E94813 -:10005000E7AA23269277FCA11F5829F451151028EE -:100060000EE0A93CCD02D1B1F85CD9E70AB60D1279 -:10007000FB24C25F61A1BEDC37DCD7DB56E17883AD -:10008000C3F984E3A948912A94B0794B6C51117D4E -:1000900039C5300CD7C3E468D756C0AF9C6E58B38F -:1000A0001BD62F0F8016F0A1D85DF2626837164F6D -:1000B0009197405B6BE476B5D6C09687E3E90581FE -:1000C0001FADFDC0E1D98A74BFF456FB182BE9AB14 -:1000D0000C3BC9B9586FADE40A50DCD4CA5C5BE193 -:1000E0005A9DEC619C8FEB19F2F11B621C97D9B001 -:1000F00047057E6D747C40FCEB8A33DC9B09FDC0B8 -:10010000131FF17EBAE14A26F0F781273ACA15900B -:100110000757B6E1CA40E81F7AE2637E7F220C09E6 -:1001200006EAF0139F94FB6C382ED7676CBB3B1B21 -:10013000E7510C12C9A972C0E4AF85FFAD8BE5FC95 -:1001400054073C82FCF786B0B3EB6B8A5EB602FFC5 -:100150002B456E750D8CE3C78069F4DFDF6A7894F8 -:10016000AD068A53B0457CBF29D6ADD18135B8B331 -:1001700067A15EA87767CF8E41BC7A4F225EF3DB22 -:10018000DAA7A03E6E78FBFD31E8AF22BD709CFC83 -:100190003688DD603D975EEBB7450E8B473F7014A8 -:1001A000BEE3003996DCDC9F94543B5B047257EB52 -:1001B00066AA09D695A28BEB1A18D72FCFDB3D7F05 -:1001C000C4F7584680EC4DA1C3FB31CEAF8F5759D1 -:1001D0007B7CAF7A59AFB74CB90FC8E8E7C4A737F3 -:1001E000BEB704F5FBEFCDAEC12AC2E5660F003CF9 -:1001F0003B0D4C61F1C426C394028C3FA35D1B50A0 -:10020000EE5DCCE90339C3308D80845FE298B0B8ED -:1002100055AC07DE2F61D08E45F86EA0F5C9C857E2 -:10022000A3984746FD3586F9ADD87635BFE644BC80 -:100230003D19C5EE40BFCFB28DB9FD61FA63403CB8 -:10024000F7F726251809EE6863FD6CE4D7E82F98C8 -:100250001DFDAAAEFF3429383E08C874BCEE3A6CC6 -:100260006008E70B46BF3D0EFAC1E18AFA2C0B8D00 -:10027000D725E8AD8DFBA4491DEE407D93C0FB2F33 -:100280001472FB1CFCDCE47F3613F16359E30F931B -:100290002F673CF75BBD4945F1F1D0D63747339C1A -:1002A0007F6C4BB401E9F0F2F6BC28E4879D881B13 -:1002B000587FBCD97E0F8E177F05E0CDA4EB6EC2B0 -:1002C000ABA28E8A03BC4E9866533700DE5F88AAC5 -:1002D0009F86FC1FDC6160CFC2143B4DAE59D8DF56 -:1002E0007959B5A3BE7D21B33E9AD6B3C340EBD9AD -:1002F000191D1CB116E0DE304C2947F8142B535061 -:100300000F2B8622F51EB83E349EDB574D2F2F88CB -:10031000E7F2F3A404F3E7E17385243FA5B28DE48B -:10032000AE2BC8FC669827696EBB8CF4889E05AC22 -:10033000847CAF046406FD491E46498D4936A35F9F -:10034000257DEBB62D06BA4F11FA76CA87AB2B780E -:10035000DCE33A3D11C63B6833325CD764D621A357 -:100360003F38F92A7305907FAEF278C60E7FE83FDA -:100370003DAFF3074BC578EEA0BD042F17B2483F41 -:10038000AE7473D9E712CDA32A68A78B2DBAFBE808 -:10039000E7C5621B193795C50BFFA63FEBFF1DE9AB -:1003A00037E05E98EF3E3B9FAF54CEF915AEAFAB52 -:1003B000DCE4423CECB2B9DF9D887AB1DDC8B6B26C -:1003C000BEE5E979883FFDE0730CBB6A65FE7CE21F -:1003D000471BAE67C4E68DBE2858F788417C7CE495 -:1003E0003BD42343FF333101F5F855A15FB456E305 -:1003F00033E4277B1CE727FB0D2139BC333E939E5A -:10040000D3E40AF90CC7D96FF42FF4F46227813FC3 -:10041000EF44FEDC656314473D966A598072A5CDB2 -:10042000F3BCE0637DBBBE666DAB11D7FD15D80391 -:1004300080BB24EDAA29DC9EEF49E27C552A7F4B44 -:10044000FE766793C4D0CF4F6EE2FA3B9C3F527B5F -:10045000E78F5F225EAFC51F5ABCB0FB87F2C79122 -:10046000BF8F3F365C933FBE8D453CDCD75C9CC262 -:10047000BEC7BF6914FCD0D7FDF156AEE7F4D75F15 -:100480001178DD67DA383D17F5C0CD0617CA395047 -:100490003F7D36AC635F347F8F296BB2B0BF4BE1D9 -:1004A0007A65579399F4CA2E9BD74B76DC6961E83D -:1004B0003F30C5DBF133D4876916754318FF2E8DA5 -:1004C000E7FC566F0C8CFF0CFDE2A39CCEE36ECED6 -:1004D000934DF05CEA522EE705174C5B300E2B4D26 -:1004E00028DC817C74027516B4D5E7E029407CD500 -:1004F0003913E9BBD75A4E96617E11FC1E37F2D9EB -:10050000D8FD27CB8A72F079AE4FF78A56EB8FC7AA -:1005100035C5B3EE78D723ECC678C6F59207F92433 -:1005200037D4676E23C56B1A3FD447033F805CCC3A -:1005300067AA3116869C73CEF330984336A73C9257 -:10054000CEF303D3283E9C7BBAFD55D0CC6C9E479E -:10055000775FF0C17C1D1F809D3D1E8FFED2F18014 -:10056000C980F399D664737F684D16F293264FF4D1 -:10057000033CD5FF61D8B31BC2EC7B6C0297A3C7C9 -:100580005D0ADDF77598FC83E1D2BF33FE5EBDB036 -:100590003F9FA33C63FC70DF2B0BD18EE62F771FB0 -:1005A00044FC4F4F92E9FA2F58C09285F47129E428 -:1005B00097D51BD5E2CFA4D0734CF10CB3C1FDFD90 -:1005C00049D1F9387F6982F722D28929C123F8DE1F -:1005D000D80979F9285FB6517509688F34B801AE2A -:1005E000F2ADB6101C1A5C67055F94262CBE88EB32 -:1005F000C7F750BF347E7CDE82EF6B74AF6FFE8234 -:10060000D33B8CFE48EF10FDA53BB0AFE1E12BA141 -:1006100057B4FE3F4A7F2D7F704DFA637E20F6EF80 -:10062000A2BF352129447FF0B3E2B1AFF7B3EA4D61 -:10063000E077E7F4BC5EE828A4E75D265821FA5588 -:100640002D1077A23C7A1DB42FB0C7CEE7EAFAC3CB -:10065000F9FEE022B2C109F184F76A537008FA2169 -:10066000A30212F985A340F01791FF95417ACF2597 -:10067000F0C4CE4BD2F961DC45FF2E1DFDC3400214 -:10068000FA51A3CC1501E4F7DDD629E9E8D7E559FD -:100690002765215FBD3AECBEE368825E4D5BBEE735 -:1006A0003935E4FF68FAEDA018569BBF2081EBA115 -:1006B0001B41DDA21F882E63381C9A3E47F2201C86 -:1006C0005260BEE13B2BE9E5A60EA0C78D0807E00E -:1006D000A155620DA8CF0B0DEEC462F4D392020AAD -:1006E000F7F7BEE98FF9C18AA637DE43782B703F52 -:1006F00004E35097F162773E62604F3F58F357B47E -:10070000B840F367B4F813FD1EBC3F405CB79B01D3 -:1007100040B447018BBF06E67FF2B23ADC2DE456C7 -:100720008175548875CC64ED0417FBF6BBEF260188 -:100730007D66087C541C81B83117EF337633E0E1D5 -:100740006685C79337BB207E0CE3A399E322FBF8B1 -:100750009B921C1AE75ACFEBEDC044DDFECC3FDA8A -:100760001E017BF409B8CEC7D6F1B874C240D9A730 -:10077000A0E11C9769407EAC16F60DC2E85EEDD292 -:100780004BC22F9E60E8C875017E5BF7FF8DECE0E1 -:1007900081FD7F7B07FDBCF19F2BCC0CEF4FF8BC9C -:1007A000200EF5041BA7125F69E356FFA9C1CAF822 -:1007B00075E2FF2AB1F6C3008F7B28C267A1F677E6 -:1007C000179FDC84E37D794EE1BC2DE62F3379075A -:1007D000611EBBCCC4F3018725EEFF68F70F1B0138 -:1007E0006EB8BE2941CB0BB493DDC79F398CCE3791 -:1007F000633E202F44D79B2F947FAEE4F6A40FFED8 -:10080000FE37F2015A1E60ABC01F3B78D6A4025CD3 -:10081000531BEE51D0BF9EEA94993B6CDE9B542B48 -:100820007387E5039E49D0F923075FDC3403EC4965 -:10083000759BEC8A42796DDA753C17FBEDB2CBDA29 -:100840000B1FE9F13BB5E91E05F9DF98A8927C5F23 -:100850006BFE0923804F6E40BA33F2EB3AC748244F -:10086000477AFA1ED8FFEB848E9CBEF1DD17FDF5AA -:1008700074F8DDC522DAEFB9163DF47CDB02EBF447 -:10088000C1FA02B04E1FF85D07D6D9A97F689D93C3 -:10089000FA1ABF5637FF3601FD368D4F4B1338DF3E -:1008A0008CDFB72981D942F4D2F0F5A1B0577BA3F0 -:1008B000347FC3356F065C3A05768718D4C7DA9D56 -:1008C0006342F66BFEE932F23734FB355F5E544A21 -:1008D0006A53D82F4C23A35ED3DBA9B9EA6223EB7A -:1008E000CD3E2D88EC97B76D5462A867203A4992A7 -:1008F000C087F0B33538CE300FC1A9A7A706971E21 -:100900001E6D7D9A7F3D5FD06FCEA04C23C2DFC3AA -:10091000AE8A75E2409887B85EBBFAB58E9FAF5C31 -:1009200028792BB717BEED8B7FF5F7357D508613F1 -:10093000E451EB43BFC298984C742BBB6A626EB013 -:100940001B2C238A7D1A665758C550E29F7B851D54 -:10095000EE8B7FAAAECACC9B1FE22363E31356E45F -:10096000A37DCA462BE62727DB66D5C6019E4AFE35 -:10097000543417FDBCEA0E03C3145669D31707316C -:10098000AEAF7E8FB9502F1635B51623DF1D52DA64 -:10099000658AB3BF64EC89307FB1B1A9D68AFE54B1 -:1009A00063A24C71FC6107E74BEDFE9644AE3F1A23 -:1009B000CF5D9EE1EEE5FE1971BFE4E33CE2A3B238 -:1009C0004741AE310E4D8AA1BC4489649F53817E5C -:1009D000C84D46F2F3218EF923EE035E6A34EFC26E -:1009E000D47E69E323F7D88110F5FFFD698D19F3F3 -:1009F0000BB324D7B3F05C991A6CC57ED9DC4CAA32 -:100A00007B18FB3F32F9B3C15B25CA8B9401BB60F5 -:100A1000BF6C51A61FF313FB25DEF735F37D02668D -:100A2000F725CC8079DEAE4818B581784AEB0FCE39 -:100A3000DBC0042387C557F7ED9549CFDC572AF96A -:100A400071BFA9D49ECE7C617C55F6A889D635BBF2 -:100A500029A508F9784EB9CCFC61FC1D107EE13C5B -:100A60000FC4E161EF1D8EE270051703DC52486E82 -:100A7000A7093E9FC5B89F387F4142C47BF0C62D71 -:100A8000688F6E6D8238157AD344FC7AAB373D623D -:100A90005E0FE37ECD09162C8983F1FB250D24FE24 -:100AA0009B11B48F0EA8A877CE24A25E63C3B89C16 -:100AB0006872572AAFAE237E70F27DB279124893E6 -:100AC0008CFA2F529E668E8BECCF72F7A8378890E7 -:100AD0007FBD5ED7E47E5EB34CFB72F30A2517EB55 -:100AE000453FE8FDECB1D17DE8856FD587E37AD34A -:100AF0000B1F96FF5D7AE135082BC681FCFE345151 -:100B0000E8877EAC1FEA875279FB26E4972EB07700 -:100B1000E65EF845B3175A3C5E06F24AF27E91EF64 -:100B200067945E4D65BEFC503CDEAD2FC09F70F5F6 -:100B3000E2E73C9D984572D4AD5F34FD11E64F1855 -:100B4000C7FCE3FE4429F891A63C842F83E02B6385 -:100B50003C1F588685439897737E41F9966A88F3BF -:100B600029DE67BF25B850CF49F12139D0FB195A8A -:100B70005ED72AF2087ABEE8CEF3CD35521D8CC678 -:100B80001765762E1F657365CABBEBF9449B4FCF83 -:100B90001F015D5EE69AFC21E4EC87F24773A2D860 -:100BA000571DC4065D0F5F68FCA0F187DE8E1CD365 -:100BB000E567FAB2236FA21D19DDB71D797D989103 -:100BC000F4B5DE7E68F6E277495C2F6724F27D8E0D -:100BD00069C3E7D9D0EFB026F13A0DCD0E75E7978E -:100BE00036737E78BD638922A13D41BD9019867F11 -:100BF000916FD5F8AFEA5189F28D15422F7536F312 -:100C0000FC5B7589ECB7C0FF16373DB189F78D9451 -:100C10009F2B545A150B8C3BD325B930AFE316F9F3 -:100C2000BA196E89E7EB5C91FBF42D3AFACE117C90 -:100C3000349305EBD01FD7EBA53957B95FA0D74F39 -:100C400073C4BEFB1CDDBEFB554DDE07B001FF4C7F -:100C50007FC09CF4FDFE80F6BE46478D7E2AEEC521 -:100C6000A11C1DFCC6A4C670FF19E937F5AA42E312 -:100C7000D893045F0A7FE6CB8B79BFA0984F3C5F87 -:100C8000DDF485C93BB26FF8AFE5B7C6A29F3E3A27 -:100C9000E4B76BF34E53184B47C74C674F6689EB6D -:100CA0003FD47E0CD7AD43A383A6477BE059E8D958 -:100CB000BEE8742D3DABE9B37FB69ED5C6D7EC80B8 -:100CC00036AF5EFFF615B769FA74FD1603E54B26DD -:100CD0008BF878B2C8C3CE4FE2F1C1AD493CEEEC1F -:100CE000FACA62407BB9B385FB272EB3FD38FA05FB -:100CF000A17C1FA7E7C331CC87FBEC4C69B7D0BE02 -:100D000067119012F73DD3F8BEE77625E0213DED5F -:100D100052580DC8C9397C0FE679F8806F21EAE98D -:100D2000873F1962A0FD7725D08EFEC9D83C85F695 -:100D30008F1C6695F2C19DCD663BBED7B5EFFFB463 -:100D40001A719CAF980B43B843CDE6EEFD1BD40758 -:100D5000A5729B8CF9FBAE20C8083C3F6941A018E6 -:100D6000E3A0C9ACBD16E57B02D2B117FAFD2A4952 -:100D70008BB37BCFEF1737733FAE3846263F6E8A73 -:100D8000AFBD18F7ADA62892AB169FD5E5F75FD19A -:100D9000C51FA1FCBEAAF0FA435DFEBE91EB99EB24 -:100DA000CDEB4F40DD067CBC5EE373A16F581FF9AD -:100DB000FD9D26BEEF133C6964E807B30B89BDE6D1 -:100DC00063AE95E7DFD712ED5663719F8EFBEBFBA9 -:100DD0005AD2DC6A6EDFCFE776048BD03CEEDC3E85 -:100DE0005BA1FA35911FEDB17FD2C7FE88BBD17EE2 -:100DF00008D5695FFB21C55FAA94F6B95EBC697529 -:100E00000B4CD43FDDC8B49F9BE474E7F96837F21C -:100E1000F9CEF3696E84EB79C1A71ADFEF3B77391E -:100E20009AF6414D6E15F78F830E8BEB59E25BCE30 -:100E3000EFF5A943FCB84FFB1B21173BA383C7B2B7 -:100E400013C3F73DF83E47CBBA47679F33D27EB90D -:100E500084F9486D7FD9077243753DF18CE20F2309 -:100E6000AB67386FAD9BFD1ADB2993D438C4FBE523 -:100E7000446D1F538DA33CC4B757A8CE508FFFDDE0 -:100E8000EB9807EB511AD6593C0AC8FFABEBECD4F0 -:100E90006F5CE7A476FF3A95DA878EC73E8076BF0F -:100EA000DA6DF22861FAE39D64EE77E5657F524CD6 -:100EB000C5DF7F6354873EE5C10E19F5C58D5761C7 -:100EC0001D117527CA65C437E537B342FD4C6971FA -:100ED0000CF66FBC0AFDB0E7AF2439B83DAA53EA5F -:100EE000462793B4105FFC2DC9DD9104D7EF7178CC -:100EF0003EC176B734FFE02546FD73BC7FAB7C096D -:100F00009ECB0F14525E391FF3CA7934EC42C4DF12 -:100F1000E85613ED976BF9DD3C4DFEBE8ECC33E702 -:100F20008BBCEEABAC83F2CD051608B40C0817A74A -:100F30009F5B9AE794301F98647261BDC3E82C4FA1 -:100F40003EE6635B9318C547ADADC9196A0E720FD3 -:100F5000CFFBBAB5BC2FFBFEBCEF918F627DA4B76F -:100F6000AE9A687FFAC8A9585780F60B2DE4FF693E -:100F7000F5C82DD1BCCE80652CA03CD38DA29ED1CE -:100F800062F69A93495F050E9E80F77E7F99F17D08 -:100F9000C7F60F695FBBD8303C05EB7E0F4A43E3D1 -:100FA000B07DEAA3D81C6A4FC55E44FCB418AC2AD5 -:100FB000CE7B669D5A82756D27D6B112AC637B6B72 -:100FC0009D85DA93EBECD49E5AE7A4F675B88EFCB7 -:100FD000731C9E477E71BF65A37D92296FD9146CE7 -:100FE000F316C650BBFBB61813C2DB12CBB66BF3BD -:100FF00060BD5A203AD080C9FED6A7BC8F59FA816D -:10100000DD337B474AA3186B7BCA3B5D990CE34EEB -:10101000EDFF93AFE0FE9BC9CB1EB3005C734FD9CD -:101020001ADAA0FF76F2F2C76CA86F8F4783D2C39B -:10103000F5AE38EE1E047443A590C605978D837EE9 -:1010400082D65F31BD641263B71477643360ADEC50 -:10105000E495D32D80C75BACDE1F63DFE44B9A5E63 -:10106000D20FFBCC87F56041C948713FCB9012B1DC -:10107000FE65A6C3FB467258FD9E5BFA13ED338DE9 -:10108000714BCC41871F8CB4EFC5EC1F2784CBDBA1 -:101090004C47E91B488F89C9BC0E78F424C91D5EF2 -:1010A0005FA17F6EF439B504E934E642591DB633C9 -:1010B000CB1DD4F72C185B87F25C62EBEBFD627AF8 -:1010C000BF3C99D78D142952445D89FEB97C6026B6 -:1010D000F48F8347A3294F30FAB4B716EB4F4B9DDB -:1010E0009979B2A6FAA8EFD882FB6DA32BCE9424EF -:1010F000A0FCD824179A8931ACA32E01EE17DAB1DF -:10110000A00AD7F54431D6FF8C562517A2ADD0DD05 -:10111000DA80EF17BA625C85E88F9F564BD0F49C5B -:1011200052469D2880E7A60E925D1618E854E0A668 -:101130008997A05F382C8EF2BC85CA9A2B27A81FEE -:10114000E3AA51711D5B7E5D45E398C9AEEF9E51E8 -:10115000FC2FC83F459E38CA09023E4AC2EBCA600E -:10116000DD0477A15DF64749C8DFFF5A6287FEEECE -:10117000FE1296CBC37CC3FF42F78F44AB5100E80D -:101180006E93BD04C7DB6D92EC0F51DF538CCFFB28 -:10119000861855CC1F952546458C3FB5441A7F0EC1 -:1011A000E1CF891B85D7CA331C11F7DB6EB3929D43 -:1011B000A8782B87FCA2B6DBD2C95E54BC35A9083F -:1011C000DB3603F7D32BDEAA28A7FB061E07572C16 -:1011D000FC915BF429EEAD585849FD5629E52738B6 -:1011E000DF959CB83CCCAF4D1B945AA244F88103C8 -:1011F00049FEF3447EAFD0307CD32480FFDEA37C55 -:101200009FA2222733E2F91905524978FDA86752B7 -:1012100054447F7689A324BC0E756E456A44FF96BC -:10122000B99911FD92A30564BF410F5494801E38F3 -:101230000AED5260C1025107A5E59F0A054B15B69C -:101240008BBCACC2E3EB61F0877AB0C41669A777B8 -:1012500047733B5FCED6D00649F911BEBF5D966895 -:10126000FC24DC4E94CB15365E97158987BCA346CB -:10127000B2977931921FE3FA92A34BEBD0F49667C1 -:1012800044BEAFF961E5023E6D5EE673B7A33FA2CF -:10129000C1ADCDAFC15F2E2F2AA17CF735D6A18776 -:1012A00097C17A503FE8E1684A16FE1AF81FE4AF8A -:1012B000897324F04BECCD7E6BFE7A05E82B47B8A2 -:1012C000BEB2498958B7D797BED2C6EDCB2FD3C689 -:1012D0009DE9F0D0FBEE1D9F9E9A2087F5333F4E8F -:1012E000880FEFBFF8E9A688FB491FCF7184F7B7D5 -:1012F0007E3A07EF4F51D45A1BF0E53126B97CC82E -:10130000076DAA1203F4283EEDAEC3B6F4432F9640 -:10131000ABB2A9E77C75D84EBCE86F33C3BA6E1A7E -:1013200026AB18BF6B7E881EDEBF26F3BCC3B1ABF5 -:10133000AA15F75977FB542BFAF3BB1F54ADE88776 -:10134000EC76F37319EE2C039D8F7167F37AC5BFAA -:1013500024F3BA834EF1BED6FA8DDE4E841BEBCC5D -:10136000D137A8FA264875E5C7D0BFCAE9E95F1D9D -:1013700053FC369CEFD8837E5BF87EE2F5FA577F0C -:10138000041E43380A99E409D723C596284FB8DCD0 -:1013900096DA1D11FD93C20F99EA4C8D78EF263530 -:1013A00033E239F01B87A15F526B62546FEB33F06D -:1013B0007A5B3D1E57A4F0F8CE65B3A33B83FB6672 -:1013C000726FE7915CC5865ECFB7A5A4707FF03FD2 -:1013D0005218C1352B85C3A7AFAFD5F76BF17C0F82 -:1013E000E293B99CC8E72EABE10AB8BCACE0E927B0 -:1013F000A6535D6DBEE1DE2CE8573CBD753AAFAB40 -:1014000035ECC13ADB194F3FCFEFDF60C837823F81 -:10141000B0CDF7C274AC2BAF8AE2F5095551A23EAC -:10142000B46E7444DCA3183E7E6A21C69FFB8D0C0B -:10143000F3FC8F99C00EE685F6D9AD661EAF5A4D06 -:10144000BC0E7C7DE6A9F5A83F3E8BF2E6A5509E3A -:10145000B148453C5EB45BA83EF4BE7DA529C807F3 -:10146000B35278DE2B7BCF44279D2FFBE7C151FC85 -:101470007D7060FD308E73717736F9E5D903189D64 -:1014800027D1E801E1335D8F82F081CE6330B7135D -:10149000F36FB50E138D332B85F3E3F5B63DEA8973 -:1014A000E30C6B7641BB2085C7CDB7E2BC046FB0BF -:1014B000FF2CDCD0B307FBCF1EC9FB486F59CE0B06 -:1014C000A27F1BFC510CEDC3BC1FCDF1C63282B410 -:1014D0006FF3EEA26CD706BACEF1B8C03FB0B643F8 -:1014E000C5FA0F7F3FACB718E8F42E457CDC66F6F2 -:1014F0000F26BEB2AD89C179AEB7DEB8EFF921E0F3 -:10150000047B327F3CA797363FE0D882747C579C9F -:101510003BD1E001387E8C70687075C3A3AB3FEFA0 -:10152000147E7B278E971BCA5357FFC940798A6A5E -:1015300009F424F4F77CC85C3E95E8437950DCD28A -:10154000C2F9C69F58526C83B6A071158F8FDB9578 -:1015500088BC9866CF268AE7C7BEA744D8A389224D -:10156000FE1DAFCB4F4E6C9C4EE7F826EAE2E25FE1 -:10157000A488BC651A4B0BCF23AC15F1C6E5B68128 -:1015800071E89F2A10E7CA806F932AB371F121BDD9 -:10159000D0B08E459C53D4F870E469FB9D38DFC809 -:1015A000D3EC0EF207B471BBF3131C2F97DFE37873 -:1015B00019D531ECE949D0371E3132BF1A5AE70448 -:1015C0000E2A833087E2A4CB176C645FC61C9D4350 -:1015D000F5DE66A781A961EB8F52A3991AA62FADFC -:1015E000C3E223FAB2A04F5D54A41F902FE6897185 -:1015F000A5458CB73FBEEC08FA05F9B6E5E417C47B -:101600008D1B18311E6B5322FC833CE67163DCE8B2 -:1016100002FAE27ED998D34A841F302EB091CEA12F -:101620008EFB30F2FA847391FD037DD1A52FFCB1BE -:10163000DCA7D12FFCA1F873B823F197501E89BF06 -:10164000244F24FE521644E227D51B898FF4E5234C -:1016500022EEF75B9317D11FF0C08488E733C18077 -:1016600085F7B31E9D16F1FCE08DB323FA4337DFF7 -:1016700016F1FC70FF9288FBD9DB56FE207A8FAC06 -:101680005F1BF1BC9EDE3734FE34627C8DDE3EF89B -:10169000FBDFA437730AFF50D03B51D859879BD743 -:1016A000AD75196D8FE2797C3C3682FACE81E7E91F -:1016B00063D1FEAB5497E79BC6685FFB97B2474286 -:1016C000BD940EA8356451BD3CD5F5FDDC6088D8CD -:1016D00067B73BB93F6477723DFE6B133F2F950EA2 -:1016E000FE26D929030BC5D916AC77648299AC8F35 -:1016F000639C5DE7E818A63A306F07FDC921BDAAD3 -:10170000E9D1DBCC6A6D07E8975132D793A03FFB54 -:1017100039619EF7A5078DDCFFF019D1FF48B7307E -:101720005F6C1ED919CA433B58A284E700E2427A93 -:101730005CFD0E88757065369DC37A134140BF59B4 -:1017400075D17ED3AD9A9E5A3E9CF4D4655BA4FFBE -:10175000767969165D3F7BBB99EA07CE8A3A470DD9 -:101760000FFAF3D6DA396CEDFEF22D9B62D0EF3C26 -:101770002BCEFF6AD7270BFC4D76CAC2FE59D66026 -:101780003E6C1118F138C07BE5918ED8DB18F99BBF -:101790009370DD555BAEDCFE2AF4AB0DC1646E3791 -:1017A0007CF4DEFC77F9B9EEF97F8BFCAE408593D3 -:1017B000C7F91562FC5BA0B1039E6E013A38B07D9B -:1017C000635219F2275CA7F371338F3023CAF32CCD -:1017D0006F26D54D9C62AE337B01C4F94E95E09CDB -:1017E000CB3C46CC5BBD737B650C3ED73D9E360E35 -:1017F000300CFA25EF3A7CC664CC1B4CE6751330EE -:101800009F05AF7B16A53F8C76499BEF1DE6BD7407 -:1018100006E83B9BB9685C6D7C86E9F9303DB57B99 -:10182000F9AA8F1260BEB5470D948F58DB6CA6786D -:10183000AD6BE57FED780AEEDF91DED10FEDF6FBC3 -:101840002BFF3604F9E1D6CD325381DEAADD7BA72A -:10185000336C5FE5ECD22B31781FECEED6A7D05875 -:10186000BE6CA63AE2F757BE3C24DC8FAD74162E50 -:10187000C7F7D8B8EB3BEF58FCD2F014AAF712FC2C -:10188000B442F0D3DA178792BFB536A69B9F787F14 -:101890002BAF1BD1D67146F0E3CA97BE89F8CEC4F0 -:1018A0006EE023D5CCF7C5D4A160EFDB2EE7D2776D -:1018B0001F8CDE7F75C2BC2D573F89C5FE9E37FF4A -:1018C0004AF0B3B9D7072FCAA26F4C687F5A3BEFD3 -:1018D000B9A029211FE90E72B601C7BFED772F5EAF -:1018E000FA00F1D3FCF2D69FE133D779FE739796D5 -:1018F0007714F6C625F001F686E28B2E16CDCF932F -:1019000008FF46C11DF92CFA9E874A7CED66C77117 -:101910001FA7B6D5407526B1B8091496AF8B950DA3 -:101920009A51725B9CA0AF859EF97FCEDB2AEAA814 -:101930003E20D21F2A38B432C20FF2C05FAF7ED031 -:1019400033DE5ACC2FE9FDA1F101C36253DCF7F875 -:101950004587A6F5EA174140ED96C688AD21F835D2 -:10196000E8F4F37E2157F53816E6FF03D1FCFC338B -:10197000980EF47B7F9ACAF5B72D83F1F36952E78D -:10198000300BE8CB16E7A2C71F856B96417CDDD8EC -:10199000AFA53335F9C47FDD7ED7A111A4B7D8B781 -:1019A000301BE243E43DF4742BC0F3ECF961722781 -:1019B000DE0F1CFE6B2CE67D77C4AB6F213D8247AA -:1019C00065DAFF89523A4C8E5EE2BB57510F029F97 -:1019D000CAA9DC1E581A797ED1A2BA19C60F51764F -:1019E000FBA8F0737F8D4E1E4F561E7EBFBF09E8C9 -:1019F00071C9D0169B03E3AFDEBB3B16DDFF0C9332 -:101A0000F703E4C35567DF1E63A7FCCD96FE180FEE -:101A1000D607F87730462ACCA7E4F584A37A332C8E -:101A20002601CFE927503BB2297F19F2597580AFC3 -:101A300013C7C642BEE18D12F53B1B6BE371BCEAD6 -:101A4000DF37A7A13CBD9CC4E3CD97AE66F3F71585 -:101A5000A6E0F341A74310D36FC0F8E46511D77433 -:101A60005E95E9396DFE918D85B21DF82127B0F1A3 -:101A700000C5514D6615E91AF51CE378688A22B94C -:101A8000AF6E99CAD0EE7739984B82FB3BA2837F29 -:101A9000A4F36ECD6615F3AD51F68D2C1EC6DF2175 -:101AA000F659870347E17929EDBA365F54D3D31845 -:101AB00073203F50DE374AD9C826DBC2F11C437879 -:101AC00076A4723EDA111D30609E253898B1670900 -:101AD000AE109C8CE6D5E01CEEC7F3843B4CC1F302 -:101AE000786E06E0B223FD87330E276B1AAA629E3A -:101AF00020CAEEA67544D955974FEA0957752EF3BB -:101B0000A35DFFF943AC5B6E518EABA3437D0BC865 -:101B1000C08E814CC8F9CF1F2FC908EF83621917F7 -:101B20007A7FC8AF363E5E3789E2099F8CF12FB4C9 -:101B300031F1B84E95D6A7608A298FE301F7DBAD66 -:101B4000167EBFFB79E06F1BF66DFC39579CDD3AC2 -:101B50004D2239E1F5B8421FDC2705CEDF08A4FD90 -:101B60002A702057055856BFB19FF87495A1E9A96E -:101B70009170FFEE28AF2B15E67BED43039D6BFDC7 -:101B8000F38B51FE0AC0C7B07D5B92DDBDC8877E76 -:101B9000FC47DE7BE8C974A4FF3E49C53C6C973125 -:101BA00048DF37A96AFACC44F50D8D1F53DDD39B6E -:101BB000A9DE4938CFB8C61ADA8F1ECF36D27E7466 -:101BC000B6380F5EEFE4FAE3F2E921CFD684E17F85 -:101BD000492A972F16F40E40B96912F2D9827E0A6B -:101BE000B47B85BFB4B7F5D62C352C7F58C30EA473 -:101BF00023BE1F6287A8D5AE77F9F9B9CAEC772C56 -:101C000077B8C3F86F9190F745A9224F96EA9D8D5A -:101C1000F0AE6AFDC414ABE23999FAFE6857EAC126 -:101C20009FB2F782976EB9D5C951B51234E1F3D599 -:101C300017F8F957A0731D9E3778F99DC6118BE1EF -:101C4000FA5EC035D695FACE9AA9BE72AFD1938E00 -:101C5000CFD79CF93A17F556090201F07CDDBC6A32 -:101C600000E20DF8BE281AE56B17233DA6C9670EE2 -:101C7000CA27BC9F837C5F80FDE1A4877798DAF94F -:101C8000F9D3BDFCFC29F03DC901F0BD1DFD861C4A -:101C90003BC801BD3F94E47B47BB81CEC9FA408F6E -:101CA0000FA67ED11CECEF682FB1937C635E3F0FD3 -:101CB000E5347080C6A987D8044927314FB83FD989 -:101CC000E88C25BA69FAF1B093093BA1C6E1790322 -:101CD000AB2C47C845983DE47D612F4FFC2AF0F8B6 -:101CE0002FD176B8855D10FE14F3E6939EBF57D8CA -:101CF000AAB5AF4F98B91DD6B9F684DC5D3F8EFE0C -:101D00006B40F0C901E1CFA29D5013783D0E5E1FDC -:101D1000BD99D7D58E71AF29C6B3CFE3CA371EC4DC -:101D20007682A7BE18CF3E4F5AD07E909F81E6E7BD -:101D3000D91B0EDC948DFBDE5D67CD0CF75D1AFEC2 -:101D40001AFCE34B8087FB5B00FFBDD825580EF1E2 -:101D50001F58EC74E6EC79BF4BD2F4C7A90AE4C76C -:101D6000CE0639D40740AA80C1B1FFDBD4938FFBE4 -:101D7000A09F95E67E3E15FDED742FB55D27FF9A79 -:101D80008CB660EF69EE473598DCD9C83F0D032368 -:101D9000BF1FA0B54FA61A890E057D7CBFEB482A50 -:101DA000CF6F0EF1B1C7908FAA1A64BB1FE87EA94E -:101DB00041769BC01F3AEFF626E3D99C0BCC77CB3C -:101DC00044B4F3228ED4BEF77217FA2960A7EEFE50 -:101DD00065EFFB0FAB99F65B6340BE5AD624B1FFAB -:101DE000001C2C7F26F2F9D5DAF76A1AB71CC6EF69 -:101DF00088AD7C4E771FFD15FA0E46A41F7324553F -:101E0000F827592C0BFD13E023D20F46851D310313 -:101E1000DFAE48F7EE437BFCB2F8BE02E85192C752 -:101E20007D4E615744FD417007AF2B1EBECD2F1B69 -:101E3000E0FD098A5F467BC5A0C57D87716E6F197D -:101E40007D87C9E73E8DFB3ECB853E5CAEF9697E62 -:101E5000BE3F026637C24FAB16AB1FCFFCB5B1B861 -:101E6000FE6D12C5CBABB645EEA7548BF5AFDE7C4D -:101E7000F2309ABCCA7ADD7DB1FE6ADDFAB57DF337 -:101E8000CF5323EBBFAE773FE42F46EE37BC2DC6D2 -:101E9000D1EE9BD2B87EAC826520DD56FB65BF9F3C -:101EA000FB7936FC5ED09D625D770AFAD33AE1B9E0 -:101EB000CA6D923F803CFE78649DE95DF58BCB90C6 -:101EC000AE7A3E5929D6BD7CBB91FC55FCFE0FCAAB -:101ED0009D9E3F568AF5AFD4ADBFCA2BE9E0E37EA5 -:101EE000744FF8EA6F413A576E37B2DEE0D3E8B587 -:101EF00052E3EB3EE0D5E0D4E0FEA1F0F64F13F95B -:101F0000AD116C04D1A93CE1BAE8A4F773771D1EAA -:101F100041DF5BBB7C6420C5FB1A1FE8DF2F137E0B -:101F2000F2D4CDDC6FBCD4586C1D89F14C9BC1251B -:101F3000A9149FC58E04BCE437CBAC02FA5D4D59A1 -:101F40009BF0FB8379270AE660FC9F7FC240E7EFA6 -:101F5000F61C29A07DE7FCA38312B228CFEDA2EFE7 -:101F6000E3C038645FBBDAF236E1F984AEB69202C0 -:101F70001C5782E7D00FC81376A2A62DCF1A7EFE7B -:101F80007C4C1A8FEFD73B3FFD39FAE9537719E9BB -:101F90009CC55463F04DACDBDA7344A17DF2D527C8 -:101FA000963C1485F47D51A27DF2C3ED6B1317228C -:101FB0009F3519EDB8EFDDD5F4E30378DFB75DA207 -:101FC000EF5E54379766EF807EDE967C57F8F9B364 -:101FD0003C874AF0B1542BC5CF53FB19C96E5E4CF8 -:101FE000B3FE16FD9F95EE2D24DF17F7EF3151DD7F -:101FF000DE0E89A1293BEC3CF80AE2E3E2AB274D77 -:10200000E88417379C34757C8F3F70C92FB300C5A7 -:10201000CD1B4D18C7546ED1FA1D26A49347F8471F -:1020200055CF7D4CFD95E8CFC37C2B9F91A97EF7C2 -:1020300060F36B26E4E7AAED124BC90CBBBF598ACB -:10204000F85EC312C6F96089D03FAB987F7D1A3C19 -:10205000B76A23AF5B608F46D6016BFCBD42F0F7D9 -:10206000AAEDB3E8FB533DBE5B8871E30DF81CE7B6 -:10207000EF659B23EFAF107CBD42C7D73F4913FAF2 -:1020800067381B8E7CFD75A11A9703D7BF3EB972C6 -:10209000406FE7ECDB84BDD6ECE5E58081EC8DFE9E -:1020A000B9CEC62B046775DB6513FAA7654D5F10C3 -:1020B000FE2B9A5AA97EE466E65D8DF8BAB9C96A24 -:1020C00047B9AEE8E07A685A93D9EF97F07E3DD5EC -:1020D0003977B5F0BA49DF7E89FC1C4D8F69DF770F -:1020E0005C26F0B80C14787A1EFABB3C6EAE127106 -:1020F000F28A615B0EE33E7B95B8BFFAE8C158F403 -:102100000FA7B12F6E47FAC07C0CE763CF44E27D86 -:10211000BAD08BD3B773BDA8B76B5DA9D933298F5C -:1021200009712AC2B57A7B24BEAB74F1F963693CAC -:102130003FF6820EDF154166CD413854D9E5A7A799 -:10214000DB159CF7482ED85BB4936AD6F77E87F1EF -:102150004DE1676BFD99E21C78BD7DA32D3C6E8E31 -:102160004AE7FEC2CAF1B20FE9D51D6F0C3A98AB2F -:102170001A42F106C419CD69493CEEC08292373249 -:10218000649698188A371E716EAAC8837EF5762EDB -:10219000F79DE3603C3C7FAD30F247ABB79BE99CD9 -:1021A0006235D09FE28A267E9EC2D3249522DDC16D -:1021B0005F3F9A86FBB198528575CF6AE47C3FAB4E -:1021C000E40BE297A383F87A2F2B6A4A6FFEBBE6F3 -:1021D000B7E3F93035CC7FAF0239C5E7AB9A783D2C -:1021E00052C3816FFA67A29E6BFEAFFE8BA1FD5AB0 -:1021F000D845CD2F0C825F3890FB45F4BDC9BB8517 -:102200007C2DB3F37DBABB85FD61521DF17995B18B -:10221000FE503CFA593B78BD00DB871F8503FDF873 -:10222000F64B75F1B0EECE9724AA87C3F7F17B94F5 -:102230009D4BEA3F41BFFBEB1D16F237EF06BF6532 -:102240004A5E4FB9D4E45BFB6E560D7B88FCCF87AA -:10225000581DB595829F3B1B6BE9FBA09ABF42EFCF -:102260000FECE98F540ABEAFD4F15F547A24DFD566 -:10227000BC1D4D7E63D751D98EFB3180AFDFA48565 -:10228000E345F8210D07A288AE5D276D6447FE2C5B -:10229000F8EDA2C83FD78C93090F86F1BCCD6E79BB -:1022A0006D20D211F18EF5F72FB7BC36829FFBF669 -:1022B00013FE576D9323BE0F5B591FF9FDD79AB7D5 -:1022C0006FA3EF0855EFEF866B88293104575F72D3 -:1022D00020493C8E3448917164F53ED9135E7706EF -:1022E000EBB903F551BA9007A6049331FF35009D71 -:1022F0000680AFA689D3D5D0CC5B98FF169E273138 -:10230000D2FC3DEE17F956E3FDAF33AD7CFFFAAAE0 -:10231000AF02FBF70F94A9AEF3FEB7570E0DD7A38C -:102320000CE104BA561B83C9146F9E34107CD52768 -:102330002F270FB2A15EDA5282DF0F9D2EF4DFE16C -:1023400081D6E5C8CF3E9C372534CECB69BC7E8F85 -:10235000E17A9DE86DFC928F2BD6FB109B2DE26AF3 -:10236000CE4F39697CBD108F8C4BEF251EB95EBFF7 -:1023700013ECC3A98512D633293E8C87F7BCC7F569 -:10238000424DF3B28F90DFABDF37539DD7FD2DCB9E -:102390008652BDAFD77B03FA1B5FB7ACB881F2831F -:1023A000D24304970FE173A25F732619EB522B9B64 -:1023B000CF2493DDDD3B7A932F06FD97BCE9781D92 -:1023C000FC09E23FF06B88FFF6B415687E8C15C7F8 -:1023D000AD3CAA78103F95470B8E57A07F71A2A8FD -:1023E00000D5B974A280FC987CF4636C21BFA65B15 -:1023F0004FA6733FA6AB358AF20B121BC8F9870DA7 -:102400008AE09FD50DAF93BD5FDD2847D42F6AEFDB -:10241000DD99AED038CB34FEA997DCC41FBB78BBA6 -:10242000BA710FAD6F95B19EE85DB3DDC8EFEFE017 -:10243000ADF67D581F8BF7213E8EE325A0C3349364 -:102440003F03F3D3C732B99FAFA7C7E7E93CFF719A -:10245000ECAC7700F2CBB142EF507B2F76C2C78A4B -:10246000785C2B097C37F07353FAE73E4B97C477BF -:102470004222CFB76AEDA974AE3FA7997AFF2EE04A -:102480006FD2B57309EC31430146C546FB06E1D76F -:10249000A7867DD761CECD46F2174E31FBEB58EFC4 -:1024A0003843D3B3E3B87DD5E7CBE789F73C9B55F9 -:1024B000BE5FA43B3F334F3BDFA43BEF364FF83BBF -:1024C000F374FECED3E9C28F1FC286A01EAC17E7FD -:1024D000EFD60E8FF287E7B3F4ED61B12F82E78775 -:1024E000B0AD19FE2EE57D8EB59E7D85EADDCE462A -:1024F000B1813CAF47F9EFCA3EF2DF35DD723937C3 -:1025000082CF34BA5C12DF83D1D365B7A6AFC4BE25 -:102510005DB4D8B7F31BBDBB519E2B2D174DBCEE40 -:102520003068427D56339CFB4D974A25DA6F073859 -:10253000FB9BC3F4FBA5541E7FDD7F8B4479D756EC -:102540007C1EE3AC7A89EABC2B03ED26E4A7210DBF -:102550008B1F26B9F5B1D32CECBB1A332DDC4E768C -:10256000D34F5B77B71D8BF7717D9C482D3E8F76DF -:102570007186B083FA735143597B593AC033DF2DCA -:10258000B9B01EA02F3ACF5E30EA7544C3F5D2BB76 -:1025900033DDFB4E3ACA79FBE55B308F7A6CF86726 -:1025A000FDD18E56F5C1C71F0B3CEBBF2BE31AAA1A -:1025B000D6E2F7556A9DDE0ED29F866F6347301CC8 -:1025C000A7E3376B25A41323FEEF4B7E3E13E37E78 -:1025D00096CEBF770FB8A77D9755E9BC4EEB98D143 -:1025E0009F41798A9CEBDBF7AAD9F7462EEAB3CE56 -:1025F000D6A3B9A630BA5E5C0B7A00ED4AF3C1648B -:10260000D516CE7706E23749D2F84F11F632920F3F -:102610002F221FE6607B267610EAE35DA76207E3C0 -:10262000787B79DBCDAF4DFC7BF6101F0D9917132E -:102630000EDFC304DFA57A3E0E631D43E68C0CBF9C -:102640005FDB171F5B33888F3B22F8585B6F3D7E43 -:10265000CF07E38016337DCF07F3D78E3039199A31 -:10266000C1F5CF58F1FD9EF1CC47DF391C2BBEE3FD -:10267000335E6101251EF7CD0232DFF7E5E72DC697 -:10268000087E1EAB045AB18E62BCD8E799C0DAE965 -:10269000B9292C48AD9BD9E91C451173513BCE1289 -:1026A000988EEE544E7D3DD525069215C7798B3810 -:1026B000AFD10BDD42EB57E8BB3DC49F329ED7E95B -:1026C000FDBB2FB333B8DCD3C74590BE9718E5B92F -:1026D000F07B6D38C9448595637DD3648559A2012B -:1026E000DE5D870C24CF2D1DAA1FEB535D09E2BDD3 -:1026F000CF19D5E18E757379459383F518DA7AF59C -:10270000789800E3619E6DAC029128E13140F3DDE1 -:10271000C8F8399242A652FD736946A6D0F7418A9D -:10272000A38A218E427D6FB0F8081FD33354BA8F2D -:10273000FB25B130CE848D127B0FF73FB2F87AB50E -:10274000F1270023E0F9C2E919DC9E614AF5BD7862 -:10275000BE8F124B05CD2576FE9DA364FACED1F532 -:10276000E2B52B997FEF32F6CE60E7CF0A42FB4904 -:102770002EFCEE516CE83B9B2EEDDF830844FE7B84 -:102780001077642CF911F2A356AFC7BCFCDF7DD0E3 -:10279000D7EB85D5E7B10B61E7B0B5BA926DFED93D -:1027A0002A9EF35B9068A173BF7996FEF968C7060D -:1027B0003ABD34FEFBD2F6C13498E21FED8909F12F -:1027C000BB95B9C721BE437583FC3B50DDE7AE9294 -:1027D000199D57B49A797DE563201FF81D26902E28 -:1027E00015EB68D883C5548FB9DE6171E17909337F -:1027F000C26D0DC15D6B11DF05B5F07D717D3D686A -:10280000ADCD40DF1DAD65D1740E3D29DABB2E0381 -:10281000E0BA2FA688CE7767EF9CE444BF317CFDF9 -:1028200093B4F51B7AD647C27A1FC9E8A51E515B3F -:10283000A7F6EF76D805FEB475DBB5734A6E25E2D0 -:102840009C92868FC7A2F9BA8DB8F39F45EFAAA8CC -:1028500037F4EBFDFFDC29BC16A06400000000008B -:1028600000000000000000001F8B080000000000B6 -:10287000000BB3D36660F8518FC0C19A0C0C5DD2C7 -:10288000A862B4C41D120C0C9780F80B106702EDFF -:10289000F5926460F006E26D40BC1D88C5A518186D -:1028A0000280381088FB80FC7E204E07E224A81BA3 -:1028B000B30519187281381F880B815848808141EF -:1028C000588078FB8B1519185EAB22F85A6A0C0CED -:1028D000C91AF4F3FF60C381B6F4B5EF16D0BEE5B4 -:1028E0006E08BE0490BDC20D55CD4A37FC66AC42A1 -:1028F000935F8DC65F83477F810D2A7FAB292A7F37 -:10290000AF3903C3072435DB4CF1BB051D2B00FD9C -:10291000A788274C9730A2F22732A1F2F9A17C00B8 -:10292000BE1E313CA80300000000000000000000B3 -:102930001F8B080000000000000BED7D0D7854D5C2 -:1029400099F0B93F7367269999DC24433260126E7F -:102950007ED0A001879860B0586E20E147A30E0892 -:102960002CB440262888166DC49FC6DD500609BFCA -:102970000921E14F70D11D105DEA63FBC5565B75FF -:10298000BB7682D646AB3568D787767765A015BF0C -:10299000BA761BD96D976EBBF57BDFF79CCBCCBDB0 -:1029A0009900FEECB7BBDFF3C5C7E770EE3D3FEF24 -:1029B00079CFFB7FDE73C725BB59701A631FE31FF6 -:1029C0009413731963B5A9B2C5C362D9398CE5767E -:1029D000488CD530B6B25D89CF827F1676B4BC8282 -:1029E000F5E56D6EC35DCA58FF036E7F0DD44F6F62 -:1029F00057C26EE8DAA8F8A8BEACCB15761BF07CFF -:102A0000EB472FE7E3FB8D5298419DB1BB199BCC5F -:102A1000D81A0FFC13EACB2A921DF8FEDD2D52388E -:102A200086AF99E99B04EF6F65FC7DF3038AC6646A -:102A3000A8EFBBAD894D64EC961E98C5430DD9C770 -:102A4000BC3D63058C45F823D6B205DE57A6DE47AC -:102A500058D7470AF46B8E399EEF9BF53E0BE07B0F -:102A60002DF51CD6730CFF3185B14B993F783A1B7D -:102A7000FE1D66E18F15281BF2191B9DC297B364DA -:102A80000CA01FC5D85CC65CAC1CC6A9BDCCC5CA11 -:102A9000607D161EDB381E97354984C7653E46F5B6 -:102AA00077E74AF1074BA91F9B5E0D253C2FC88392 -:102AB00032C8CC4228231E96C806F8E7B65DF61E3B -:102AC000AE7F034E359ADA2702F07E018BBA18C02A -:102AD000F7672C46E56216A7F2CB2C41702C6543B4 -:102AE000252AD4EF52129B18CC130E45A7E3FEFE05 -:102AF000AEFED8BB12BCBFBF5AAA9D0225F3E5D1DA -:102B0000BA2FB43E6B7E9545AEC37118935D113FED -:102B100063E3AD751E66B18A20637A8F8FD3CB6174 -:102B2000D6CFA03EBE41D04BE3FB7208D6DDF33CCE -:102B30000B633D049B3905EAA1AEACF806A8F73C4F -:102B40001EAB47BC1C6B01CC43FF638D6E295A053D -:102B5000A54B7745A00CA98C2980A7FA86F592028F -:102B6000EDE646F938E34D4D665742FD704C52C5CF -:102B700073ECAFEB314987FA78A83F28E17BDDC5DC -:102B8000609C86865C57B20AF1DD334687B2E2B0BC -:102B9000969001BFF5A64ECF195B4474355ED0DA2E -:102BA0005C93F79B7B38CFCFE83DFBD3C7D67BC088 -:102BB000EF25457CDF8E1D2ECB417859D4DEBF48F2 -:102BC00065314F5E0ACF3BD7C10B770ABFBB0E976B -:102BD0006D45BC1DEB53C382946DE3C3B8BD0DF0CE -:102BE000FE4C951C560CE4B3220E7F85EED77DA9D2 -:102BF0007176AE83F697A5E06854A6F6133E4C4670 -:102C0000FC38B706DA57A5DA3F81ED018E3D080F93 -:102C1000F55B73D48BF34418CD33123DBCB04EA793 -:102C20007E83621DD7FCEF30EDD3DC861689CF2B77 -:102C3000E06BB0C36795167C238D7F4CC0658D6FAC -:102C4000CDF7C4BA10958D4AD523F7E2BA8E687CC9 -:102C50005DF38DC77723FE8E78C231A83F79DDDF23 -:102C60008CB91786B862FAF3973FC370BEE50FDFE1 -:102C70008EEB7A2E8BD6F5D487675EBB910D9FF7CE -:102C80002D81879F9E9B3F44756BFEB9A6344602FB -:102C90003AAB34A5840BE8E558FD571EBED7C07A81 -:102CA000BF89F2A4D23C664A504E846168BF99FA4B -:102CB000A78F419E554277E4C7490D520BB67BE280 -:102CC000C687BE741F3CFAA98BC37DC55F72B82F3F -:102CD000BB7EED9308EF6537AEFDF93350BF02853B -:102CE00020F0DDA537ED5FF377F0CF6F2CFCCBE55F -:102CF0007B18C9855836C0916B4A0CF777D9F7DD38 -:102D000036B972EC793FC99542B33486FCB7AC4F03 -:102D100022F9DCDF08721FDFFFCC1D77237F3D2007 -:102D200099D4FE59771CE5C3311763288F971DF797 -:102D3000C6915FD8AA6524AF2396BC36F397DE0B05 -:102D4000E3BDDB60C9734EA7F41ED6F7AEF98BED79 -:102D50005743FF33A62B8C62D392174E3CBF2BF008 -:102D60001BA92F273A58A6265DE10CF4D0DCA6D883 -:102D7000E4767DC349A2AB6550B2343E9D2BF86C1E -:102D800059C32F047FEA24979CF0BC515B589C895F -:102D9000EE4E09789282DEDEC5FDBE0CE1835E4810 -:102DA000375D4A5C4993D3F0E78A4CA07A0C59FA14 -:102DB000962D76382DB9DD12CBB6E92B90BFFF8268 -:102DC00072B3B92DDFF67C6E0EAB9DFAE9E4F01F0D -:102DD000480E27258207F42FED7F242EC5512E5A49 -:102DE000FB7387D89F4805A3F5FCEA80148FC1FECA -:102DF000FEEA8858DF3E29AE4844AFE6690F8E0BE5 -:102E00007396A7F6FF76B1FFA9FDE3F8B1F095D26E -:102E100073B99B9200428B2F5282F2DAE21F0BBFF2 -:102E2000FD7B7E5482FB57D856DA5D87701E508832 -:102E30007F3FAC3F598CFBF6AE0BF00AFD23871F9A -:102E40000B305F0AFE1621073FE8007A81E712C2C5 -:102E5000599906A780DB857568777B83D4877CFAD0 -:102E60004B31AFD5EF475B66CC44FCDCD12331C49A -:102E7000CFED477A97FD39AC7F753C3B8C53FCAA6C -:102E8000B1387009C0B3A2C7BE9FA7B6DC1C40BA58 -:102E9000F9B02FBF00C7B97D6A42433857275ED5C6 -:102EA0000CA0B35966AF96CC40571FF66D0860FB77 -:102EB0000FD59E1BAFC179F629E1F530FEEA23A5B7 -:102EC000334D4EA744BFAB057E4FAA3D33C7007CB0 -:102ED0002DDF282779F05E9F323B9E417E7E5D523A -:102EE000880E56B7B9655CE748F4F261878B2570A8 -:102EF0001E3541F81CA9DD077D2DF4BEFF81C21BE4 -:102F0000D07EBBBDDD45F2E2F63637D1D3EA0629E5 -:102F1000CEA414BFAD10F0AEDEADD0FB93A644F24C -:102F2000C3DAAFDB05BD9D3C7CD52BA8EFCF80FC81 -:102F300041B93B63E30FB54B000F2BB67079747248 -:102F400077EED27B508E087D798718F7B6B862E3AA -:102F50008F95EDD9B6FD8876E5DBEAA78FE4DF58DB -:102F60008774DDA590FEBC65E3635A88E493DDDEDB -:102F7000440E9B5490B22F4FB0A105D748297AB286 -:102F8000E8E7D636B03703C3EDCD962312D9A317A1 -:102F90006D67B6819D3971B89D69C99108DA67E599 -:102FA000293962C98DBB94E8D820C0F16B57F4B2BF -:102FB000FC72921B0F48B54827FA6FD1AE6431A559 -:102FC00016E5DBC5CA0B5AACC547F0F75E07D0550E -:102FD000067A9D817405F3CCECE9CF48CF33248386 -:102FE000C64BD1CD2D01E25B1C14E068F6985D085C -:102FF000E72530B1B79A4AA6E4F15285FA668419FA -:10300000E8E1D45A297EA894B7F3A13C05B8AE8173 -:10301000E7CD5D97C7B7496817C21FEACF366E770D -:10302000433BD39F47CF4D09CAA2F6D297717F2E5B -:103030000101A055F3F6380FD8598412689F7057D4 -:1030400053D75800CA62E827F3FEF41EDB05488E0A -:10305000C769BD383E8E53A1C4D7A09CB1E878990A -:10306000903B20572B55A0AF66961546BDD9DC5630 -:103070007E5EFBE586B05D7EDC5467D703734DBB97 -:10308000FCBF79F625B6F60B22E5B6F77FB6E80A5F -:10309000DBFBC5D1AB6CF52FAFFA82ADFDD2D619F3 -:1030A000763FE9A7B9B49E35822F4782FB75212F61 -:1030B0007FE2B04FADB2E9FA44CDDBB04F6C9D3B3F -:1030C000FC381427E6B0457D6972C5274B84CFDFF5 -:1030D000009B70FFE04F1F131E437CDEA6BF70B73E -:1030E00066A23B4DF4437309ED2567FB138B619E8C -:1030F000B47EFF26494487E7FA314FCF2F01E4160B -:10310000E0E41C40FD9D2C5982FBE6CE35E8FD5DD8 -:1031100072B200EBBF61437BF3717F7DC962E49FB4 -:1031200066953D27E560BFB0C70DF38135C4DA80F1 -:103130003E5ADA7E741CED38C908B22558F7F812E9 -:10314000C8DFACC3F561D2C23BF0616F28FAA104BD -:103150007048EDFDBF97F0FDF799817A98258B7245 -:10316000D17FC4A9D2F9B069066B457C9D68B4E3F0 -:10317000CD2BD6F17349A676CF31F3B7C8472725B3 -:103180009DAF4FC0BB4D32CFE27C16DCEFE6EA1AB2 -:10319000FB74702B722DC2FD23827B432B4B662B5D -:1031A00023C37D0533DDF2A8E1F09C656656A6E7F2 -:1031B000B3805D333DBFDCCD2AD15E3D216585D72F -:1031C000976239F48F5F03BE8A7DC3177EDC184E89 -:1031D0001753E55C9ABF59D8BB85ED52221BED53BE -:1031E000E621FB95F53C647A50AE0911D7D2269DB5 -:1031F000C4F5B38E4633E949AD9719124B6F776E1C -:10320000DFDBDCD4DE923796DCB2F069C9154B7E89 -:103210005978758E3F929CC1F1D43C843F3A494E17 -:10322000A7131DF03101E131AB71FFAC7D033732E3 -:10323000E6A91E79DF2C3905ED18FAFF23ED17E01A -:1032400089EC3A5798119EDE0D0E2D7D0AD63DD0A1 -:10325000C6F5F5BB458CECC3336D570DE4207E3CC1 -:103260009E0AC44F219F8A150687D6A17CF5A9899D -:103270007E84AB50E82F2FE3FAAB90193BAE46FFAC -:10328000BEFDE4126C67ED4FAED89F66D81FF447C1 -:103290009A7D43C56827B951AF413B37C85D94CB90 -:1032A00085EDEFFF07EAC542875E4448583A1C594E -:1032B000553BAE36D2C7FF6823DA97D6B8D4217D06 -:1032C000FF83DA49C46F61FBE6BB95806D7CE963DF -:1032D000C48390DB68769D9BA714ED5539E10EA45D -:1032E000E8C20997D56F243A61E9F394DBEA644FA9 -:1032F00038EBEEB06693CFEFFEB13CA7D5771E7AE0 -:10330000738EE7A46F271F083C7C0A3ADDC4E9945A -:10331000CB058B6FFFB3E8346AED6B2CF78E23A8D7 -:103320005FBBB4F02C03ED84A11F723BC16D1C4246 -:103330003A8B495995F03EDAA192DD68D915FD6BBB -:10334000FF7A4B193C3F512B931F71623DA7FB3D08 -:103350000F707BD4D2DB51A1B7D12E40BC82DD30BF -:10336000E0E6A507C7F1AFBFB95402B83DC650BFEC -:103370001BDBB71964AFE6D4C5F54628E315873CD7 -:10338000E38C945C4AC6F2F396C37E7D2BD7581625 -:1033900021FB3A3A7AAE3FF5FEC732D74FD34A58AF -:1033A000DE6C182FB9550E3F08FD932EBB1EB3CA15 -:1033B000350AD797492F2B413F78A476438AA557E2 -:1033C000758DF665FEC071DCA791F6017640A738D1 -:1033D000E6393AE478877968FCA4DFAE874E0A3D87 -:1033E00064C1FF09F4EAC262A08FBD5266B83F1201 -:1033F000E3459F030060BFA32A3333B573AEFB1FC1 -:1034000044BF84ACD27C3B2A76CEC6FD8EC5947078 -:10341000FA7E58E55F285C7FE6CC6DC86D84766CDB -:103420007DE67679A2DD63F7652D42FF0A50A7623B -:10343000BC2614D3E7CDC678E4D4BC49E863FF18B2 -:10344000F50FCCBB3B72466FF17D227C14849491C6 -:10345000F1F1A62CF37D74F0ED1E70D7507E262579 -:103460000FC55F5A62EE8C7C6CC929A73C72EA39A1 -:10347000C934595BF570B9628DFB49F519C8872CC1 -:103480006554CA6E3FA7CF2E961E47900325328BF8 -:10349000F665F04FAF56389EFA633C4EA19A32E97A -:1034A000AD994A1393004F1B828CE4411EEE35F216 -:1034B0006D038B030A583E0B0FF8509E046596204F -:1034C000BFD5E9079A4DE8070639684C1F55D65F06 -:1034D00008CF83F357D239038B7079ABC37F9C8FAE -:1034E0004CD2176E81D7686C12C539F39AEC72DC36 -:1034F0008D7E20C847BDC1F17CFE4C3A6F70B3B4DD -:10350000E7B08EAB147FF03498F6AC9AD5207F5696 -:10351000EFBF6AD76218BFE6919BDFC672F2C17B2C -:10352000F2BF0465DDE3BB6EC6B2E4B5E8D84CF18A -:1035300054AB044E61721DC0E763863B67E476C6F8 -:103540007A25827635EC6307D24332569E85F4BDE8 -:103550004AE1FCDFBF400B607C46DDC2E5AA3A1FB2 -:103560009047F4CFFDF4E6943F4D7E852AFC24A5D8 -:103570005DA13842522FA378CBA12DB28625C8D9A0 -:1035800018CE63CDDF2BE2D49D22DEEA84AFB76490 -:10359000A818E5E089F51F917DA8E859E1D9305FC9 -:1035A000979F95101C225ED02CF62FB9B6DE931E85 -:1035B0002F52849FD37174CE80817430A084BD0655 -:1035C000F18D86E346B74C67187F99A58719DA1302 -:1035D0009DC2EF517C26C37DCDD6D94CF46BE195CD -:1035E00016C2FE552C9CC0FEEDFD885B58AF793BA2 -:1035F000F2C10FAEE576C88952BBDC0612EA823D05 -:1036000065B38AD6AB489B4DC1495721CDFF5E2992 -:10361000107295D3EB1BB5531EDB0674F09CDBBC1C -:103620004719F509F8C821D77F006C82FBF6A8641A -:1036300097E75679D0C9476D12D985AAC9D73953AA -:10364000F9B011F5E446B01B0B8DE1FCB2F1754603 -:1036500076E346E0BF586926FEA99650465C2CFFEB -:10366000E4B5E74A18C7F8ACFCF3978A38A713FC0F -:10367000037496403BE651C9E89C02EBFBCEBEC604 -:103680001F4F81D7CF1E58917D0D94DF8B6FBCFEED -:103690001A98FFF6C7F764E33E3FFA2AF0D379FCA5 -:1036A000788B9F9AD1863D4F9CCD586BE727637DE1 -:1036B00005F1D35B0AD75FFD0B7EF7C6D5FF9F9F51 -:1036C000CEC74F6F2B409FD3FE74B6387A1EF9D603 -:1036D0005CC434B4B7A08D89741E0DDA4B9F9A4533 -:1036E000F85EE7E272CCEFF272BB23C4DF3BC7FBAC -:1036F0001BF593C70F16947F763E5DE7333FFA3C88 -:10370000F81DE40EC99B13E3EC7CDFE9E274F72BB0 -:10371000D7275EDF3B5FF81CD607763DD977D7A960 -:10372000CC403F60E20B1E1216AF8EDB780459626C -:103730001A3C0FE5F1F7EE3C929771B46386944A18 -:10374000EA6F326EC737D56C3EC2CF25062B168185 -:10375000BF3C07FE85F6C8753EEE57C0382C04E323 -:10376000AFF6468BD551341EF997AF3EBF2F88F286 -:10377000E5758F5982CF5952CDC5F301CBEE18991B -:10378000DF55763ACDCF7A5A6304C7A94B358A57AD -:10379000A2180B407D6BE9A514A764E1D87109EB71 -:1037A000A37486725C094616931DD2E63666417D87 -:1037B0002B1850B120D12DC94DA5BD37144039006B -:1037C0007609BE5763733D1AFA2FA3640C42337710 -:1037D000DB47E4779F28E6F2B6630AA3739A810772 -:1037E000FE6DA98CF64EBB9BCE2DC06E247E8D0A3D -:1037F000B9910C4E0FB5A09F51A48525A86F8AFDE5 -:10380000E2F8D7B83C313D93D3E3233CDED112E25A -:10381000FEAED3EEDBFCF5CBDE3470BC1FBED6753E -:103820003994AF3FF9F3D72F87776F7CEBB51A8CBC -:103830007BBBEB345BDCD1CD8C37D1DE029F29A181 -:10384000A17C8E9D5C829B99F2EBA418E2275AE33F -:103850008FE37A91B7113FC9290A3F5F84BF10C037 -:103860001710F075074F55D13CB1F7FF2393BCA754 -:10387000BFC9428F40BBCD79F7C7518EA4E69B44A8 -:10388000F2290AF209FDC8A8AF67C91A9ACF1F7EAC -:1038900010FBFC11767572EABCF0D096792D88E7A2 -:1038A000B90B3C3AD2993BB6F96EA473E73ACFF81C -:1038B0001EBC144373B6F9814FDC159AE925FB97BA -:1038C0001DA6FD104D2CB8755020187780FECB56E4 -:1038D000B00CFD0DE88FEB047986F6B6D50FC8D88D -:1038E000C4F59EF14DBF94E2FD225E61F5BB292631 -:1038F000D139C14DE5C006E5C3F1B4C127FFE46B82 -:1039000078EE12537485D341A8220D6FF8678F9B10 -:1039100071BAB86C9F5DEFC2FC0B4BF17D4C217A04 -:1039200071F2CBF8B8BDFD06DFF9CFF587EF27C7F9 -:10393000F344C16F567F0B3E8257CA145FB79FCBCB -:10394000DC5467AFCF1D868FF3C3355DB59FDB3485 -:10395000F8ECE3CD0CDADFCF2EB2D73760FCE6937C -:10396000ACDBC1774F8F31BFA37E06BFDE92BBEFCA -:103970007B227F4BE3A86186E3F42FD83B7F1ED0E8 -:1039800041A1CEED8EC2F90B1B726B504E31916787 -:1039900092D9FE2814FA5E697F49C9417FD4E4EDCB -:1039A000934BDE9A9183E7C5758CCED3A3EA3DB1E4 -:1039B0001C23658FF4ABE55988E7CFDF1EB9DB9B8D -:1039C0009E7793B2471E78D5A8C9608FA8F748267E -:1039D0008C336B09D82355E9F648AB8432287B0930 -:1039E000D823647744DF437C8D6497FCD8B2EFFD25 -:1039F00099EDEA3FA85CCF829EF9A7CFA267C6796E -:103A0000CD7F513F077B605A89B13292810E3F5082 -:103A100079BCC3D29F8DC1848267E7A03755173C1C -:103A2000BFB62EF9128AE30E7D6710D70DEB71B980 -:103A30006A3FFD7ACEA81C9E892ACF8319A9DFB7D9 -:103A400046F057BC9A57D82DF6FDEE5FF08E2EA3A8 -:103A5000FF027E0CFA2F495FD9368C0B9E89A91480 -:103A6000AF53E7AFDC3D17E909EC6C4ECFE7B7AFDA -:103A7000AF1D926D7C3CED6C968DEFEB99FD9C6ECD -:103A800086C77E4ED7A8DBCFE96685ECE774730C5A -:103A9000FB39DDF595F6733AA77D3F73B4EBBFA70D -:103AA0007D1F6A64C44F17B0EF819F6E427A1A89F6 -:103AB0009FAECB37EE8F64D8EF6A8DDBA9ABBD919B -:103AC000054877D30C6ED74563EB291F302F0AF2D8 -:103AD000A694E28614F7B2E25A56DCCBCA0BB4E2E3 -:103AE00059CEF89515F7B2E258528CC7AD9A3DD130 -:103AF00015086F73FB4919E588FE1CCC838C609D0B -:103B0000E30D8BCF7179D0D29E392EE78CBF8DD843 -:103B1000EE53F2D5E7A01FD6E37A2DFD007CFEE040 -:103B200067E173905BDB70BC7F417E1F45F2A49B15 -:103B3000F6AF02708D763AEC838671FA05A7F763CB -:103B40003C4E3DEE26BEBD58FF17131D64D8B42869 -:103B5000F8E018CF8AC64A49BF587C63F189D33F41 -:103B60001EC61FFFD5FC7391FE31F0CFF75CE7D185 -:103B700047C01FCF23BEA75572FC3AF9C1A27F20D0 -:103B80008984548DFB1D4D607B8BDED98B6113E1E5 -:103B90009C28FC9A13A335F22F4E3CFFEFFC1CF639 -:103BA000794F789C5823BE9FD85D10DF569AE23338 -:103BB0008B9FDA3DD11FBBD2F240AC7CC7C31EF352 -:103BC000757C1E52FB12E8AF8466B3F00683F8ECF6 -:103BD000187FCEF9D41766143FFDCC7ED95E571CF2 -:103BE000CF875AA4A1A58CFC56A621DFAA429EBC71 -:103BF00098153D89F86C9E1E29E1F43434CE077087 -:103C0000FDA243217FEDB3F253F348F83F878FE8DD -:103C100090AB76787E40BADC42F9160A69F10D5213 -:103C2000067925F01567E131B83ED8CF7F473CE6ED -:103C30005531899623F8B8D963FEC1F5D9EC0F4503 -:103C4000AB4DF131E0CDA3A15CAC06BC950FC7DB59 -:103C500049175FBF93FE426A5246FA0F811CDD206E -:103C6000A59D930ABC58EB19493E5B749A76DE1009 -:103C7000D2D2D7FBFFA85CB6E4E5E59EE864DC079A -:103C8000B71911F2CFA4FD75CA99E176904CE78C73 -:103C900067C0EEC16E172B5FA79DF5E261099B7AA5 -:103CA00056A1F2DAB37478C2BE78369B4AF36C3E02 -:103CB00095F56773A99C7EF6122A679C1D4D65C316 -:103CC0005900064C9CC6B3A554CE3C7B0595B3CE9B -:103CD0008EA772F6D9ABA8DD9CB393A8BCEEEC1707 -:103CE000A8BCFEEC142A9DF68FB15E25F96DC92F94 -:103CF0004BBE3BE5B725FFFEAFC9EF58C345D93FE3 -:103D0000A0FFBEAA9D477E8F242F80AFEFD3D2E5C0 -:103D1000444A3FDFAF7D06BE3E2EF814F8F73D8CD7 -:103D2000C378C08BA3385598C7A9028666609EC623 -:103D30003E6C025BEA2F8D9CC4B841F3028F1E03D8 -:103D4000B8074A35924FDB821A9DBB6D96F4D15C61 -:103D50001E2413487F3B431A8DB7ED8F8A17F31744 -:103D60005E1A5510C079BAFDB28EEDBF959BDC7717 -:103D70000B9EE34F61E14330DE8A3D7B3CE97EF8F8 -:103D80007E340E00BE40EC69C680AF378EFADD523D -:103D90009CCF3795513C064A3353BED837DDE27C81 -:103DA0005A1D0A219EB6FA64D207DDBA47E4A1265D -:103DB000075AD0CFAD93D9369877C3E877B620D8D5 -:103DC000EAB8B21D6550DF5957E6C54D7AFA950F2E -:103DD00042644FC03B0405CA8428CD1CD89F4E6F57 -:103DE000D838DF799B620CAD4362C5FEEEEA91DB09 -:103DF0006DF20F84903E3A264DAEBC05E6EF9D5421 -:103E0000301AE7DF5E73D4860F45B7C753140C38FA -:103E1000A21F5E97A4B8DA06D9D85106EB0B887CAE -:103E20006B00B33292967760C1A184611D1CAE8491 -:103E3000C2D7C30AE0796E5D2296E4EB3531EEEA33 -:103E4000F32543E82F2A75A729DED6E94F2EA2BA1B -:103E5000030E6BFCDF6A565E00E71B9FE09BE649A2 -:103E6000DF5E4479E4551AED5BB76B6801D6636B8E -:103E70005DECF10CF19B0D829FB7559E3F2EA3FA8E -:103E8000EC70747BEDFEA205CFFBA274C2D1EC1ADC -:103E90001A9569FF3EEDFC175AF7E73D5FE708F911 -:103EA0000397BBEDFB1010F2BC79CAB743782E6EB6 -:103EB000C1D329C13ED47CFEFBD03C85CBEBCF7B6C -:103EC000BDFFD3C6FDBDC6E32AC0A7B3CB31CE38F4 -:103ED000667208E3B53E2B1E1D8E537E5200E3D161 -:103EE000D4CB203DA4EA7C0C456509E44339FBC3EF -:103EF00004EE9352AD190AC9D9CCFBAE8437515E9A -:103F00009B933F2DB8E96FB2301DE8FCD06BC5A77D -:103F10000D7532BF2F81F15F8559E7B33C3E6DF5DA -:103F2000572B648A4753203B6D1C15F4309EE328C1 -:103F300018A7CE1B3EFF7753F4689FBF88C7C715ED -:103F400095FB81EF491C1FB15715CAF7EC7A9ECB40 -:103F500037769C91FCEEAA35E85C6507FC8FFE4342 -:103F6000ACD61747BA551CF978672AA787508E5ADE -:103F700071719A8F9F0F509C1BF314296E6EB00ABB -:103F80007CDF2D40B3C651ADB87CE59A49D8CE6FE1 -:103F900030CF73B03E7F1D4B5C02F006DDAD5B2F72 -:103FA0002FCD100FAF5CF38D2761DEDD4F4DFFD5B8 -:103FB0009350DF25875FAD8376F95FAE23BC3AE38C -:103FC000E1DB2A655347F9E0F31DC27D051B9AE842 -:103FD000E2D61E2986CFB37DBE837CBF5B430AE257 -:103FE00005F424E2C5EBCC8B4CC77719C2B17360E2 -:103FF0001EFCDBBB75DE329C17E1C6FCCA15BDF5A5 -:104000001AEA99E012FBF985BFC95EF756D9E1DCDF -:104010002AF6EF42F4EFCC43EC31E72D42BA3D13E0 -:10402000D418CA9B8D6BAFBE91E4FE76858D2BCDE7 -:1040300040BF8E75756A2ED2FFDD46FDDE0AD41BA9 -:104040000D1AE5F574C7BD714CF1DE5E973A37B1D4 -:10405000D9EF86C6CFB16AE4843B931D2FCEC70249 -:10406000E219739C8375CF96C9AEE9EEE1F358E38C -:1040700075D7BDE5413931D2B84F8F318FB8D19E58 -:104080008AE65DD4BD8BFB36BA385D4FD1E252294A -:10409000DAA3FAC24550DF3C4E267B8809FFAFFB0E -:1040A0005A7E9EF8B066D8EE576C9AB292EC869B18 -:1040B000DCBAE02FB00B27A4EE5B1CF09A2FB8E11E -:1040C000B9FA1C8C04F6C07BB9E11B912E1A831F30 -:1040D000911D756B91AC237DADD8D348EBDAACCB99 -:1040E0002C8176AFDA4A466A136B35F13C00133502 -:1040F00091EEE6C01B99EE45240F75029C73C61520 -:104100004EDA063577512BE5B1341A12F961D70131 -:1041100066501EB4144754A90AFBCD7F07EDBE3983 -:10412000C15219FDFDEB54D6A0A5D9E760171F7346 -:10413000A7ADEBC4B83D41B90AE7877970FE451ECB -:10414000BA4FE046FBF8CA947D3C1111996627FFEF -:104150001A8D4A8C6714257E4F79DEDF4FCA382FBF -:104160007B81556F933EB95F0DFEE52F713FE3CC28 -:10417000E8C754C3CF1A97F8BA26F649DC5B39EC86 -:1041800089FC06C7B7E20113357EBF79730B0BC7F5 -:10419000D2E22A9B9FFFF3E368AF5AF197737977D6 -:1041A000024E0BEE4D12CB223DEF89FEC19DEE1764 -:1041B000B364D9DC099F1FDC19F2E57CB5C04F63FD -:1041C00005FFE4D55678516E8EC57C1FDC87762EB0 -:1041D0004F4CF82F3DDF4711CC170CB7F6CBC6700C -:1041E000B9A4887B5340D712DAB1CE7C2005F37E88 -:1041F000260E971B0704FD5FE211F93F93D964EE89 -:1042000087DBCFAFFC4BB9DE67AD7919EFA17E5FDD -:10421000E8FD17855F9910F71A8F8A7B8B2FAF33D4 -:10422000C8CF7B655D259503EBC2F4FCB57575546D -:10423000A6EE57F179F3851DA662500DCFF97D2CBE -:104240006E00BCFE516B064A91CFEBF8FDEEEEA678 -:10425000535BCAC96EE4E7169B8BAA1385E8BF00BF -:10426000ACF95077F9FA3CFC9E97395859C0D51CE7 -:10427000E2FDBFFABCC24917BAB5FF8EFDF6B156D2 -:1042800086F22E60DAF73B3BECF46FF8FEBB8A2E29 -:104290006EDF7BF11FB08F5FB2F6FD6A7635FF3EB1 -:1042A000C3C5C963E4A34A2107C6003F1D007FDEE2 -:1042B000ADF07CF57C9EE76A8638BF992AAFC7C609 -:1042C0008BF62E4E426C208FE7B517F3F304EA8786 -:1042D00079E5F81EC3922FF0F816CB11F9EF63C5FC -:1042E00038ABC5B813ABE9DE2E3FFF677D3A963E8B -:1042F00096A47A2EF0019641D62A2132C7B041F217 -:10430000B78BA521AA1B929E85F532295CC6FDF0CC -:1043100038E9CF72C5FC7605213F22F3785172311E -:10432000D993A097512EC6D5C822942F1BDAB4304A -:1043300060E25C9E1CDE9FC372435FCD009E7FC423 -:104340006232C91FE53996A55F49F61EE9AF0DEB4C -:10435000F30E6653BE4692F2DCF77B4A6D7A6AA290 -:104360006FE1753AECD746914FE782FE2C43FEA9E8 -:10437000954F07E396647A6F951BFDDAA24C7EFF9A -:10438000C31E49C43392A3290E28F6353E55CE7874 -:104390009F719F87DB358F9666B6A7197B90C6DB2A -:1043A000EFD11DE3265BE8FE8CCEE31B592E93F282 -:1043B0006B36B6F17BFA16FE46835D8BF6F0C6BE11 -:1043C000F9B391BF63952AE59BC3FA7D883F97C8EF -:1043D0004BDE383E78309BC7254A514EF723FE6AA4 -:1043E000D3F0175CD984F8EB7895E7F7823EF7B104 -:1043F0000CF98616FE5C3EF6C54CEFADB26394B682 -:1044000028D3BDE1A31ECB4E4F96723AE1F8CBBA4A -:10441000568D646A9F10F82E2963D1F3E1AFDFA3B4 -:10442000DBC6B5CE7D9511E25D922F4171AE891A42 -:10443000B733362CE678DDF0FC35C7A369E710BF4B -:10444000C421A7A4E2C156DCD8D29BED9EE83F7AF6 -:1044500046A5F425FB3E23B9CB5EF01CC47DCB7092 -:104460000E71CA539BE11CA2E7E2BEEF3256F0ED9B -:10447000A12D47E7E13C7F55C7C8BE0A3CC3E7CD45 -:10448000D5595C2EC5EF149812C659AE89E8F56867 -:10449000BFB9DA9989F9336345DCA6B0BD4F41BA9B -:1044A00008C25E164A78AF2919C3EF998CDDCDC8D2 -:1044B0004F540B67AE5A6F08519A961FA5B0A17E54 -:1044C0005A5FBB663C5E4A60FD14F5C318F13ED0EE -:1044D0003EF3572837C744A294870BFD627EB42F62 -:1044E000041E0BBC9C6F9737842509DA0783498A21 -:1044F0004F3AE5FA18C0CF2569F65B40D4D92A2E89 -:10450000A765F80FF57C7EC42EB7C739EE45071CAA -:10451000792FB95E91EF6EC9ED22BEA913D441394E -:10452000935F9ED2AF0EF8508655A7FA07ACFA6794 -:10453000840F0881E8D98207AF52A2DCDDE3D2BF45 -:10454000F214EAE77A8DE79189FB72D902EF3E74A3 -:1045500098A1DDC094574CDCD71D61FE5D9A3353A2 -:10456000E7911F9A5D67DDA7E3F795A18C619C2E0B -:104570005BCC6FDDABCB66C69BE5400FD96692EE98 -:10458000D5E9D677154C96C03C1CDD27531E9DEE11 -:104590008B907CEA59E0D1F13B1F9AB8A7E712F75C -:1045A000C7B3CDD374BF2E7BD8FAF8FD3A0BEEEC2F -:1045B000ACAA37CB0DDB3CEB31BE0D6B1F9DF17E02 -:1045C0005D1DF793B24D1E87481B9FEED7ED985A9D -:1045D00066BB5F47F3A01F27E8CFBA67E784EB5CB1 -:1045E000BF9ACC76DA84B0DD8EB8D0FD3A57C8DEFB -:1045F0007EC705F2B33EF1FD3A818761ED1CF6A05E -:10460000CBB24347C90CF7EF4C834CDF11C9FD28EF -:10461000199921515C82F4BD65E7E5F1A1FEDBD972 -:104620007979565EBFC3CEB3ECB7DCD9767C3BED6F -:104630003E775584FA5CAC9DB70BFF01F4F290D73E -:1046400061E73565A60FA7BCC86783BBAF84718ED1 -:10465000D6FE48C17CB55DB9FCFB476C987FF0D6AF -:104660000CDA171FFFDED1AE29FD2A7EFFE6774B5D -:1046700019D949561CC12D60DE5524AFA7B07BD790 -:1046800043849FA0C043137E80AC8670151F477C77 -:10469000667A316F21BF8951A3C28A30ED3B7E9685 -:1046A00040A64B5B3115F5783D62250D4F333CF646 -:1046B000EF0434EAF98E7DB4EFF3B973F007F9F73C -:1046C00014E618F67DB7FC24346771BEEB2BED744D -:1046D00070428A0C2AD0E5E9AC5261FF0CEAA82F9F -:1046E000BBD7BAC86E7C6849D9D62BD15F0DCA3A00 -:1046F0003F8E1C1A87F651F351D38B76DEF6C874C1 -:10470000EF3878FF50871246F3F0A9256B5EC57A23 -:104710006CB78BECA0A7FAE615AC48E3BBCDBB1792 -:104720002C5C8CEF3B5CA4DF57ECB96FA03488FDA8 -:104730005DB5E9DF9B6AD9789F8E7EDB1BB5DE8C89 -:1047400076CCD559DC2ED9A82529FEB4719EC6D0C9 -:10475000E5DA58523F7A05DA0FD76819EF93DF95FB -:10476000E5E6F7F95CAD12CAF7C268E67B0156BB15 -:10477000B135BFA5738CE06C99A11FE7BA7E9E8C02 -:10478000F587605F7529454F79829E3616DDBBB58A -:1047900002D73790F9DEA155AECD1AC7E93462E7EA -:1047A000735761D3685CB7CB1D19A847E22A94758B -:1047B0008C8BB8DCAD919BD11EBDDA8514CE3677DB -:1047C000FCB06111EE4B58D2259827A84656119D92 -:1047D00005B318EA8386259156C44B21E83F0CEDBA -:1047E0001516FD92CE290AEB34E685BA67494FC209 -:1047F00005EF3D15D1AB10EF2FADE5DF79290CFAB0 -:10480000E85E5061849FC315B6BB199A0C1BC105A5 -:1048100076917F20519CC8C947D6BA9A977239BE03 -:104820007BED6F4765FADE4C455619E1D56BD8D75D -:10483000ED41BD0BE34C35079710BE6BDC2C4EFCF5 -:10484000EB26FADE55EB22B8764D39F91584EB7775 -:10485000BFCFA2FDBE969912C2953FC4CF59AD7984 -:10486000F29B06151E0FE77CE8E43B8B1F9CF0EDE6 -:104870009C3D8FCEE336B3C1F988EFD85999E868EB -:1048800073D11A6F7A5CB455D01FEC03C99798CED8 -:1048900068BF957F65EB311F76E3172395C81F6FBF -:1048A0007BF9BDD5FB966AB48E87E66A146F7CC827 -:1048B000DF4A747F6AA32B7C08C151F585B89FBB82 -:1048C0008B2BC2186FFB3B3C7C4EF30F768FFA525A -:1048D00025E2F38B7FC8E2E34C51AD717E46F45E76 -:1048E000EB25386728ED3F5B8176E8127932E54E9B -:1048F000AF5A42F2CB25E4F8CB4BF2EAD14F09DCB8 -:10490000B09C7179C8E31481B5D5FC3E8343EE2792 -:10491000EAD4DD33689778FCA75EC8BBB1374CAFEB -:10492000C775D60BBD60AA99BFCB982BDA170E4579 -:10493000D0241B16FFC915FA63EC6EC773A117725A -:1049400087C5C1072B6E06F9F3A52C61478E10F7BA -:10495000D9B5641EF1C319E0078A4B979C24FA8FDE -:10496000819C40BBF90D29195A91761E667D67EE30 -:1049700027221E14314B294FF82D110FFAA9F8EEFA -:10498000DC3B221E745CC4837E2EE241FF80F1205A -:10499000FC7E98F772DAB771751FF5631C6767CDF7 -:1049A000028F01E34CD5075F4220BF680EFA44FE38 -:1049B0003DC11BB4F4D0DCF3C7A91208971BE35226 -:1049C0001CCE97C5F7E85E11700D08B85E137059DC -:1049D0007A10E506D2191BABEA99E461506D95F0A7 -:1049E000BC17E5457F90E405CF130FAE918C09C34A -:1049F000E5048C373ADD4EB7E8EFD4281FD1B17308 -:104A0000FC47B3F8BDC397D6CEDACF8269F228B29D -:104A10007015D25D3EEC0FCAA3681397E351BC77C3 -:104A2000912657AD781AEC4898F4CE0D1C4F23C947 -:104A3000970BC99542875CD98D7205EABB51AE04CC -:104A4000D3E54A6B3FAE3B887285A5F45030F2C97E -:104A5000E4CACFBC65B63889255FAE0636263B3141 -:104A60000CFAD4FFE9F5E9DB424E5C48AF5AF91F76 -:104A70000193915EDF837921E8CF8C67740F473112 -:104A800007299F28B7DDC5301F642B76198DFECC12 -:104A900042CA07D931DFA3235D3C2C254288CF7D54 -:104AA000528F97EF8BDE8FF6C2B6093C4EB2E38F82 -:104AB000F778D1CE7EE9F682009EE3F4E65A7920BB -:104AC000FAE25BA17EAA91119DACD8B3C296F7F031 -:104AD000F3AC3CC2476E0CE40FE0E3E1DBB9FED17E -:104AE0000D9E070265C63C10B74FC483D45808E931 -:104AF000639B14F5501CA651263DD51BE6F92BBD32 -:104B0000E097E3F9606FC3CE39A89F37DC2A33CA38 -:104B100017AFECB907E54CC7848506F2A56B74D9CD -:104B20009B688E6FF0C9DEF43C523C4ED0AAF9B9B6 -:104B3000A128CD1C0079B3D734CE777F54157E1FC2 -:104B4000F6779F270FBE3337341AE304BD8D0B432E -:104B5000386FEFA848288FF253C6903DB071D4A6A5 -:104B6000C5187FEA58AEB1743B69D87C41BB7D6DF6 -:104B7000C519D5069E3FD22173FF32579C4F035F64 -:104B80005522DED2D78970AA26CF1FC1F52A7CBD57 -:104B9000F47DD3DC06F00FABF8FAD17FD57DFA684F -:104BA000941F6A03CF1FD9ECD717A3DFE884C31A79 -:104BB000FFDA6CC9E61FE956DE42FD1A7E8E58C444 -:104BC000F3167A5DE7CF5BE810F2D0F21B47C2879D -:104BD000CB714EDDEBB5C7012D78AE14A5138E91C8 -:104BE000F2053EEDFC175AF7E73DDF4879046BB25A -:104BF00025DBFD8A5C2B9FA5714D08E58405CFE67A -:104C00000BE48F7C5AB89A1B79FBCF7BBDFFD3C6D0 -:104C1000ADCFE6FA11F87400EF51764C9C19423989 -:104C2000948AC70C0D94A33D27EE335AF9232E9D89 -:104C3000FF5355F977EEE4EC22FACEB23A9DE78FB6 -:104C4000D05F863C904D8CCD467F4715F11B279F4A -:104C50005E087E67DEC8CD3EE137461DF3893C1114 -:104C6000E6C83B51433CBFC4CA27E992607DC154AA -:104C70003EC888F33AF0365EC8FDF71CFD87AD3BB1 -:104C8000CCEF575AF927C3F248A6CAFB710B86E549 -:104C900091887C949E5C23CEF3C4795E09AA4D8CE6 -:104CA000E70DCB23993A3D84DF949C5622FADDC070 -:104CB000E8FBBB3D5E5EEF9DC3E2F8BDB35EAC2397 -:104CC0003FD532CA6B19965F32750DE14963916524 -:104CD000FC7C879FF75B7870E6975C90DE2E9047B0 -:104CE00012F459DFA388D03C3DFEF04FEA083E990C -:104CF000CEE30BBE743C9C3EFE253E2E277B441E1D -:104D00005E4FAE3D1FEF3EB12F15A29D737FF52282 -:104D10004ED75DF53AC5DDDD0D3C5E39EC3B103517 -:104D2000767FC019CF3B21E4F585D6EF8CEB6D1B68 -:104D3000E1BED9021FCFE37A68C921CA8B3DB30A0D -:104D4000F42CE0EB61CC67A9B9F87C96D7B3783E38 -:104D50004BAF51BFF052D463518DA13CEDC57C16D1 -:104D600078BFA161847C16114FB4E2A323E5B3E4BC -:104D70009E3B8FB7E7B3F4DECAF3597A7BF83CD693 -:104D800078BD0DD564678D34EED3634CD987FB5F56 -:104D90007171E7A7D34A227F86F92B3DA59AFEA021 -:104DA00081F4C2E9B9AB5123FAEE72713F36369AFB -:104DB000FBCD4C8D8716429B2DFEC4228A278BBCCF -:104DC0008C5E717FFEEFB30C9B7DDCD9F8DD10DAD1 -:104DD000F540872FEB9C4F689C7CB5743DD880CC08 -:104DE000ADB798E8530E64F338822B746CA02E8D07 -:104DF0004EB7087D87F891013FB9D2397C45E5026D -:104E00008AEED3DF1A419F6F64F3F92D3A64EAA466 -:104E1000303FFF631528472CFF75583B0F6F374C09 -:104E2000FE38E4480FE6B761C592273758F2C44E02 -:104E30009796FC600E39734E9ECCE176FA39790272 -:104E4000F2033F75E69443BD5EAE2F2C78DC2898C4 -:104E5000418EBCE70ADBE2344EB973213EFABCE571 -:104E6000CE4BD9F9C2FEE0722788B4817C936D9D48 -:104E700023F27B0F67A63E48F2D0A3F2757B228C0B -:104E80007E2700EB28CF3D788E9251AE574B146FA2 -:104E900010E722F9E2FB830FBBC2949FF630F03398 -:104EA000FA79130CA77D76FE7305E779D2C36BBF41 -:104EB000C6FD33C037FA5D172B872C39F161365F99 -:104EC000F739FA32399C167DA5D1337D5FC0A25FD8 -:104ED0006B5C8B8E193268C179E855D03586A32971 -:104EE0004E1D93E21807B1F2C8ACF1DEF0717B649D -:104EF000A4FB5556BBEF587ED7B978B01ED0299F7A -:104F0000AC87EE9BB32E4E7F73D86E754D15E513AF -:104F1000A88CF2092225E8CF1CF6D9FD622B1F6C64 -:104F20005A493884726283B0D3AD3C322B2FEDB036 -:104F30002FD73A67B6E5A76D18E17EF69BE7F073C9 -:104F4000F1DF3FC1EFB6ADF69A8FA35C047C99E226 -:104F50007B4E9487668DFB5D81A7D73DE693BECFE0 -:104F6000707FF2C52C7BDE55A7CF70C405385E2755 -:104F7000EAB17ABA8F17E5F7AA9CE7EA23DD7F75D5 -:104F8000DEDB3B77FF559CBF377BA22F13FC2FF254 -:104F9000FC373D1C3DD8C93EBFF51CF09A3FC1F11E -:104FA0003B057F4F0BF27B3BEF7BA26FE3F3EB18EC -:104FB000F7AB2D3BE730B683FEFE97416A03BD6C2D -:104FC000AAE5F45A54C9E8FBE3D35B797DC752FEE6 -:104FD0005DD3FED7F9BD8F6D51FE3D53E8D7270352 -:104FE0005E768CE7FA707F15EFB71FEF37219F567B -:104FF00070BB2B0FA3F70A8AEB2895D36B7ABC13EF -:10500000E0FD81A532C545F708BE083093E21CDB00 -:105010002AF93CBB2AE427C4F76816DD02F5CED98D -:105020002B27E3FD92ED229EB26FF1CA2730AFEF3E -:105030008340B9A0BB04DD7BED397E1BC5471E5AFA -:105040009227AD8435EE3B9839BFA5CAAF8A7E3131 -:10505000B788278932A161B9D51479ABAD4C7C8F63 -:105060003DA661FCE999419EB7DABDFA99633351D7 -:105070001F57CA9467D63578D47B19AEBB8EE7F537 -:1050800014A90929DD7FF1FA5DDC4EAB39EA31AABA -:1050900086B77F66F028D1DD76C0BB92E6FFC902F5 -:1050A000CE6EF427A0DF5E57CFC04C68B7775C9E0A -:1050B000143352ED46FB39FF752F91C577E8197D02 -:1050C000C7A1D33CE541B9D989E71FD0BEBBC6CA49 -:1050D0004BEDA17B597BE74C9E8379E2DB6EE0C10F -:1050E000D2AEF021F2937B6673BB6CAF04ED605FD0 -:1050F000F6B568D7D33DA6561E278232639CA81703 -:10510000138111AFE2DC8E525F60DECE86BE019C61 -:10511000A7A88E7FDFA2A82673FF17026EEABFCF73 -:1051200015A3F8E748FBF7AF3E8ECFCE2A7E5EC0D0 -:10513000589CE252BB85DFC5D4A891FE9DD0960055 -:10514000C7CF4E1733315EE6ABD348AFCB6183ECAC -:10515000503FD88F188FDB26C516637E486C92C6E9 -:105160001E278C98DE7118BF9B901746FADB24250A -:1051700042F85DE5D8381EDF3E1AD949F7AE0E80F9 -:105180001D4DE16096203DD51DCDA3FB504723D595 -:1051900083D4DF57A1BB2D8D8279F3F4A148C626B5 -:1051A0005DB6692BDA359D53641DF3363BA5FA28AD -:1051B0008E17CBF5501CD935651EED9F6B549E9410 -:1051C000AE8F6EF473BD30342172A31FD6159A7260 -:1051D0002A17E396DB6B5FD987FBF7C8FD1EA2A3F6 -:1051E000476A07EFC679F69FBDEA7894F8929FD791 -:1051F0003D5A7BBA14ED9E5D4DA772117FC5189F75 -:10520000037D585CC1E368A801C93E537BD8CD80BB -:10521000C7E2368D1969FAD8CBF8791EFEF92693C4 -:10522000DCA3BF67064F795A70BC252C7169809E3C -:105230007B309E65C999E23A96280079B87FC53BD4 -:1052400031CC937B646201DDA32C12EF4972C278EA -:105250002562BCFE375E598FED1EAD2E30505E14B8 -:105260000F0CCD4325515C759AE26C21EBFE47D4BF -:10527000D87F2BD1A74CDFA92C0EBFF317B88E8097 -:10528000AF8FF41CB4A7B899731D8189E67D7EC0E9 -:10529000E337A5D657C70553FE18FD213FDECBEFF8 -:1052A000651767FDC35C252DDFB644C40536498309 -:1052B000B3C92E7D80DBE163599CE45C7155EC6ED3 -:1052C0009E6F1BA57C5BE7BCDBFDE7F4AB44F7A856 -:1052D000F39BC4BD12FE3B3625E2776C9C741F0A1B -:1052E000E557755C95AAEF8B9E22FA7F5A33EECA7A -:1052F000F4BD877D422E6C12FE9835FED85C3EBE12 -:10530000557F54E7F4F8F4CB79D757C17AFEAAADAC -:105310006C12C63F778CE0C7AD0C70FACB1E000B49 -:1053200007F440FF6BAF79319FE56999AD4239557C -:105330005F95F024AB041E617CF2C560FC03E16F55 -:105340007B502E7D35504970AD98CAE3069D550FB0 -:10535000D2395048E77A07F913E5BB2F149330EEA2 -:10536000BDBC86E98744BC2506F8A7BBF3324BE5F4 -:10537000F56FCF253F077885DFABC1DCA4C9E2F725 -:1053800027CAF19C68D3DD227F56467C778A7980D4 -:105390006F699E0345629CFBB8FD8FFE05F62F17D3 -:1053A000F394D77DF76BA8C78B744E1729F8FA3C96 -:1053B000045FABCC083E35F12AFAA1DB271518486B -:1053C000370742E1B79BA0BE7C914AF1F8F21A0E72 -:1053D000C78156997E0FC85FA71DA4FB6326E88B83 -:1053E000347C1962DEA29A8484E75A462B5F17B494 -:1053F000F3A25C34C2000FD40DB1AE73F04FD208EB -:10540000FE22CF20E6169DC3C34A1C0FE877651D18 -:10541000EFE70FF56D4139B6BC8EC30DFA9DE0295B -:105420000A6B0751DF1785F878CB013F87A4145C1E -:10543000D9165C7532E55F15D56807D10FCE16F029 -:10544000AD0C7378FA5F3F3520F1F10C1C2F5BC077 -:105450009B2DD64F09BB05423FC0784FB912F57856 -:105460002FE7D414661CE2B3513CCB7ABFAB15F0E6 -:1054700000F8F18B79D86E37F1132C31F6B1CC7F6F -:105480003FC4488B5B54ECD66C75BFD83FD6C59FE4 -:10549000931F472A91D765E1D7ADACB2F763356961 -:1054A000F532BC5FC6E97DFDB5FCBCE3C0046E1FF0 -:1054B000A1DF718EBF91CEA7188F7505F1BD46FA99 -:1054C000AEA4DD3E6E716BC174940FC5030FCF9314 -:1054D000613D45F73259C9217A96CEC93F98EFDB35 -:1054E0006B12747F367B209287F2AEA4356F3A7EC2 -:1054F000FF2D7B204AF5EC815693E79F810B938724 -:10550000F97A69F394A29CE6F974AC55EB43B95669 -:105510009B0E27BC2F79B9672EF6DF7CF72BA39162 -:105520007F0B1CFD3D39DC7F287E195A0570FED3A8 -:105530006BB1BD15DFC94688F3A87C19CB621FC8C3 -:1055400063284B44FE9D252F3A27BC3329EA13F4E8 -:1055500043F9782C916EE73B4B683F5EB48F49E787 -:105560006D779ADA8D146F1A08F0785340D8AB3DF6 -:10557000CCD84FFABD86E77BF8F039E88FBE9AA306 -:10558000D3693FFB5818E9B9B8ED4FEE74797D73D4 -:10559000A054DC834E10DD6B255974BE077C4CDFB4 -:1055A000373DA0B6D2396B5F113FD73C3AE71509BA -:1055B000F159F41CCFD3B6ECE5E93589103EEF7A0A -:1055C000357A19F1E708F6A7656F3AD77349FD8375 -:1055D000240FC6469917CFD7FCAB55CA632D890255 -:1055E0005C55281780A40B01FE9AD87AA41B23CA05 -:1055F000EBC66A51AE82F26AB06FD70D94FFD295B6 -:105600001A776B05D8B5683F0DEEF6DC80F64A2BAD -:10561000582306DA8BA73CF83D95EED6E9F988E7E2 -:105620006722967D999070FCA29F9A642FD6EA9A81 -:105630008E719809EEC4E8F473BA0373DEA9A6EF7D -:1056400089CDBFB87CB291F409C222A7E991FEAA24 -:10565000A3A45F9EF08F273D64E9154B8FD088206F -:105660005F6E117CD465243C12C92BE05D80F3167B -:10567000942340C7FE222ECF410E733967E993BBB6 -:10568000B9DEB7E4678518E71694B7D0AFBBF689E3 -:10569000DC1B50AE0839EB0F1933F17CAE42C85712 -:1056A000A6C6249CEFC014FEBDCA80439E56B4F229 -:1056B00071BA428CE809F4D041A49B034509BA278A -:1056C0007EA0F5A8947ECFD4D27781D624C3FD1FC7 -:1056D00057C7E5E0382157BFE337387D7AB85C3DDE -:1056E000A7F784BCDD6A1E65E2BBB019F3B0FE5EAD -:1056F000E8F39E8A43E4176CBBF514E1D38A8786EE -:10570000443CB4BBEA2D7ABF3DCAEF01EC32A7CFCF -:1057100021F823CB35CA3FAD393AA70CFD8DA6E55C -:105720001ADA75270305D6F9977721DA93ADABC856 -:10573000FEF5897D7C28CC84DFA9919F75DFD26F2F -:105740000F60FF10F84592818DFA3C6EA473FC9EA9 -:1057500002E23B3A489D7D35067D07C2B98EEF05D2 -:10576000F87769FDD1E4C038DA5799AEF4F86A18D1 -:10577000F99DCBC1AFC36177AB61EF0478BFBB4983 -:10578000D6D7B354FFFF15E0F96813FDFC9EC2CED7 -:10579000C5A7B7609C6FE752F19D3307FCF735F65C -:1057A00079149A07630294C79CF17BFB55FE2CFE8B -:1057B000FD859ABE01B4E703551CAE170306C7FB6F -:1057C00020C7634F44263EDA3558ED457DE7B41BCC -:1057D0001FC97E7712CF6BB1EB9B0BD58B1D727FF0 -:1057E00082BBEF3A9277DF94495E31C6E59DC4648F -:1057F000037F57A325C0E9A94AC8EB0E57623FE6CD -:1058000015743CEB63EB8D145D1489313B5BE58CC7 -:10581000BF9F7628A0F0FD1FBEEFDC7E10FBFEA42C -:10582000C0C385F61FC32C684FF7C5378DB903E594 -:10583000782BF79FFB126F51DE51D1EC85E4F71CFA -:10584000397829F9034555A6EDF735B347F05B2BB9 -:10585000723CE78D078C248FF7ADEE203F7BDF6035 -:10586000E67B3105393C2FAD0FE4257EDF64A4F9DA -:10587000F51CCE7FFF14107437E71DFA5E469A9E22 -:105880007D59E859D2B7C52A8B2969790E1304FED0 -:105890009CFA93A971CFA53544E784BF7DE2FCE271 -:1058A000215326BC5B748EE7078857588729E890F8 -:1058B000CE377A58DC837C136BE2791E4EB827F81A -:1058C000E58B5A5F3087FB21E7E613FEFA443F87FA -:1058D0007B67EDFD74CF11E60B217D483FF88FD338 -:1058E000741FEA5917FD9EED8C675D098C69DD799F -:1058F00090FFDEA2FCA297E0FCE7C3FCFBEA093FB5 -:10590000B7C77EADF3DF2BFAAA7BB0FB0B501F7A33 -:105910005661644FC6417101BD9E16F4CA9EE3F5FF -:10592000955E5EBDF360FF321C6FD5733C0FF3CE06 -:10593000E76FBBF10B50BF6DC0457706EE7C7CBDB9 -:105940003606EAB7C7A53EACFF663AA3DFFB8CE597 -:105950006914E7FA4D60B06001E0FB83751E665C78 -:105960008671D2C182F980873BE24FCFC47E773CFB -:105970002585916D673CFBF82BA301AE3BBF215100 -:10598000FED7578E64DBECC2D3B09469F07ECD4174 -:10599000FEBB91B7B19E99888F3B1FEFA5DF3FB447 -:1059A000F0F9C1BA4A66A4FD6ED89DDF789A7ECF21 -:1059B000F0AE6F49F4FB8A77C9FC1ED13F3FEF5D23 -:1059C000F4980FD7B75EBBD48FEBDAAC61BBDBE2E8 -:1059D0002DDFC594A63BE207B599F0FE8E0307B50F -:1059E00095E897B95933EA9FAF1CB9C226774EEFB5 -:1059F00053C83F5893EBA1FBF5CC6786E64D18BE24 -:105A0000CF1FAC6336B8EEB0E2046A5C9B9BD6DE77 -:105A1000A573FFF72B4714DB3C961D103BC6F542E0 -:105A2000EC6FFD143FB7F66F8DF0BBADFD5B63050A -:105A3000E2D5A1C999E0E9C6FD00787AD6E954EE2D -:105A40005C17A272F73A83F6692FE211CA2E01772A -:105A5000602AABC7EFF3074C9E769CD764D6E3DD94 -:105A6000B2BC08AF172C89921F32921D63957B5DE3 -:105A7000D116F4213B77F4CF52C1EED9AB45EFC636 -:105A8000C897DEF1EAAC06A8FF4D4E64630EC99BD1 -:105A9000B0817C67F9E75FCFE17277D3688DF0BDA5 -:105AA00077E9E4C714CBFFC2B8DFD2954FA03D0120 -:105AB000FDB7E710DF86E93B5D23F52F585667EB0E -:105AC0005FB06C95D57F0FF5F79CBFFFDE65D7D82B -:105AD000E75F7687D5FF1182DF777EF80B9AA7DA2A -:105AE000E76F5E4DFDBFEAE6FB3B94EBA17CFA0E4F -:105AF0006F38E122FF99D1F739D4BC4B0FD1F7931E -:105B0000CEC599064DD4B3BEA772AB518EA5E86839 -:105B1000FA37711D7EE0AE743ACAA9CBB2F155AE28 -:105B20009967ABE7CF1E636B3F2A52667B5FB8E88D -:105B300072075DFA74CA83655C9F9A18E70438B5EA -:105B400031FC7B4DF5633CB4BEFB5FF452FDFE6B54 -:105B5000F8FAEE1FE3233E26DD05FB7EBF16BD32BD -:105B6000DD3E86754918F27A468F0EE4D4A63F379B -:105B7000647C9EA5F0DFB1CB72737DB9B974F2631A -:105B8000B1347C6E29067A80FADB399A2DCEB3B90E -:105B90007865A8256D9E4DC5DAA24355FCF92D68A0 -:105BA000C7EB91BFC3F9BEAA0D5D8AF6AB731E7732 -:105BB000599D6D1E4FC92A9A27E998C75DB2CA310F -:105BC0008F67D121F15CCC730AE964A47936975DC3 -:105BD000635F4FC91D34CFAF719EDAB4F594DCE139 -:105BE00098278BAF079E8B797E73DEF5944FB5AF08 -:105BF00067EC6A9AE7DF1DF3B8C7AE76CCE3A3790A -:105C0000F039CEC38AB81FA5B98756D2FEFFC0CBE4 -:105C1000300EA4B9A37F4D9754FEDE4B71616865C9 -:105C200062BBFF03D8CCA6FA008000000000000091 -:105C30001F8B080000000000000BE57D097854452B -:105C4000B670DDBEF7F69274773AFB4208378010E3 -:105C500034C40E840C203A0D41061DC0E00A2ED03B -:105C600061C99E74449C87A34E1AA28888DA286A68 -:105C700050601A04071CD0C0040810B001757006EB -:105C800035BEE7B8CC82CD2241884983A8F866F1B9 -:105C9000AF73AA6EFADE4E079837F3FF6FDEFBE3B1 -:105CA0003753D4ADFD6C75CEA953D52427819051BF -:105CB000841C8CA3E90842BE89715FEDB012F23DED -:105CC000FCFD90D03F2F21C93C4D21642EE17FFE89 -:105CD000C5022924A4D6CCB273364FCD5A08694BDD -:105CE000515A4901FDC70A9BF30A8590CE9622E3DB -:105CF000ECDC707F6A3AD7279F0CE6B0B6DF93F0F2 -:105D000038DE7124A78E8E5F16E7C0F9A8F993F5E7 -:105D1000346F22E4583DC1B45D26338BE9F713F5A7 -:105D2000740283B5F35D88ED4E4AF49F49345D25D6 -:105D3000F8BD025DD7F20F64320087F93087AEE319 -:105D400076BE8CB9BE5842CCE179784CC405ED42A0 -:105D5000BB4CFE75027C75F531A4D1A43191107550 -:105D6000BEFD09F9D3BEC96F0B76CCF6318C24E4A5 -:105D7000CE255BDF826A1F09257DE7D1F54E6B5E7C -:105D80002EF7A1F94E3938C369D5F4334D3E06EBF1 -:105D900036D3FFA09FE96E9AD78C7F57B93E7F0F0D -:105DA00091C2F96C42AE72F4E7F8E0E32A7E19F092 -:105DB000753B5D533A45E13D900E836207E26B8689 -:105DC00083B555E7E379502601988F144C26B950D6 -:105DD000928CF5DC504FE939BF19B2D9554CF139E5 -:105DE000E30111E11839DFE0BE5897218FA68D5FDE -:105DF000C9A4FFA5E73F7381BE9C78D9782A5C557A -:105E00003AB863DAD8674F68E863BAFB86674FE849 -:105E1000E0345597BFA76EBAAEFECC0525BAF21294 -:105E20006F85AE7CF6927B75F9B9BE0774F5CB1A17 -:105E300017EACA2BFC8FEBCAAB362ED7E56B9A5606 -:105E4000EAEA7B5AD6EACA0DFB86DC44281C1B7E94 -:105E500027121385E3D7D6934F5D9304A9E404B8C2 -:105E60009FAA4F43BA3E5DAF605A0BB4370AF8673A -:105E7000B8D94DF1E48909959278421EF68D59B250 -:105E8000640CCD1B69F9684AEDBE714BBC99842C3A -:105E9000712848F762A3910428A90A24A19BAE4364 -:105EA000A2A63C7889F246890486F72C1783D1BFD5 -:105EB0007709A14119741DDE4F4D6483D093CFC380 -:105EC0007C49FA90B4DECB3B0CA4BC49237736382E -:105ED0000C389F64C7B80D0E4A0FD546C6EFD5DB08 -:105EE000D2C7113BE40383EAAC1719AF894E2615DC -:105EF000FA61FC52E1EF13E65FC4DF001DDF0F8E95 -:105F000073AF77D0F13AF68BD3601E247030EB96E6 -:105F1000A130BE6B037C272DB49374CADFF5AE6746 -:105F20004F5C41C827F51331FD7D7DF1B3276442F5 -:105F3000FE583F0DF347EADD9806EBCB313D565F47 -:105F400087E527EA1760FE64BD17D353F54B303D54 -:105F50005DEFC3F28EFA46CC77D6FB3155F980CA95 -:105F6000A399C5C0A7C5C506E0D37916C2FF58FEE0 -:105F70001C5F8348FFDD867CED4C03BE3E67FD66FB -:105F80005006A5B7739F5062CAEE1D4E9174D73B61 -:105F9000FE5C06C05FA99F124F62CF724B0CC38F8D -:105FA000C54026122A7F1EBFC248243A7ECC1B570A -:105FB000AD13B3F1BB04A443370EE7545B94FE0763 -:105FC00012C4D7A5F0A4D63FF9E29F0B67E5027E85 -:105FD000FA239DC41C14EB18DE5E7602DE2E053F0C -:105FE00089F357241C8537FE9415A4F5BF4C56E160 -:105FF000D99645687A8BA3F814D0C1B96613AEEB75 -:106000005C6BAC9F401F8E24A48BDEE1C6E651B5CD -:10601000D1E2D3CA879AA6789F5E5EA4FBB4F2E26F -:10602000DCA197EDC0F7F3D244DF89E1401F2E4E8B -:106030001F8CEED4FE6B9AB27D565D3FFAFC399F01 -:1060400030B109E5BC1277EBD0DEE7392FCD88E31C -:106050009CDE38200EC63D5D6FF6C1381DF50E1F63 -:106060001B37CDA7A5CBEA05B1BE1389E1F9F5D65B -:10607000EF3F7B7E843493E36682A0FF7E40EFF5A2 -:106080007BC58774DE580CF4D12A7F03FB4E4C8EFF -:10609000BAEF489857FBF534895ED3D5F07DB36EDF -:1060A0003CDA4E39A9E2A9FFC5F02E9193EA3AA94C -:1060B0009C1C4A6537D0292566C4B39BF61847FB5C -:1060C000EB92AC4B043A8E295EC1720F0C44E9A9E5 -:1060D000C61C34BA1504771BE859B346AA7CAFDC5A -:1060E000F1074A725FFC56264BA1FC2FB4775A2E5B -:1060F000F3D239A4D84EE878B39AAB26819CFC62DF -:10610000C78FB99EE22B84757F490C13814FBE2443 -:10611000FF6E1FAED1CBA6C41BD9FC96B0FDD94BE8 -:10612000FF83F5513D4DB75F9735EAF3A5E4E614DB -:10613000E087D21532F1D3B957C07EAFAE9BF2FDE6 -:1061400075F14C8F2B23758B414F592A936980EF42 -:10615000590E22F5A172A266E7EAC2129ABF2DDE9D -:106160008074759AEA770A954315094C8FA94CF209 -:106170001B5DB4FC78F3F0DBAF21D0DEBF18E49AEE -:10618000D7469C1B484FB8CF5EA29FDFA5E61F39BC -:106190005F4216E17CD579A8FDAAF310370A2E7F5D -:1061A000147D7676BC10D693697A5FBC5E7F5D0005 -:1061B000798D7EFB70447E51445EA51399D3892965 -:1061C000DEBD203E19E8223401F53442E923375C74 -:1061D000CF18AEF7F0C5EA99A09E88F5165DAC9E83 -:1061E00025DCDF63D1EAD5ECDCB2C34BE9A9F2F5DB -:1061F000E7EC84CAF32F245F8A937EAFDEF0A81DFC -:10620000E0744AF2DA01DF5FF8C589D1E0B5AF1B6F -:106210005E2EAB007604923685FBAB4F4C013DE918 -:106220009B0DB243A4553C1B4D0113A5DFDAE68A52 -:1062300049240FF34759FEB1B322E45BF4F8ACFCF8 -:10624000C573298A0DF1C0F46D1240BDA376FDE738 -:1062500013408E7B4808E930B21D8C7F2101F9BEC6 -:10626000C418D7B39CCE13F5640FE7334FF313670D -:10627000453BA437B4039F7922E8A8BC7B7F091A69 -:106280008BE97C5E8FB7259DBC8A667F407E00F2DD -:1062900040850BF133BDA261D30B7947E9BC3AD6F7 -:1062A000FFD62EE46AE508A3C7734DB37FBE5BE952 -:1062B0005DDE7472BB28DCCE8FED9416A607915676 -:1062C0009656CB013BE89DD56B6527A55452BDE59D -:1062D000E5575E047BED5313DA6B555BDEFA6834E9 -:1062E000CD576D959326B1E5588594307E3CF47F6B -:1062F0000B8685F151F9ABB78CCA50F6FDA18430FD -:106300005EAAB6EE3792A13DE158D4B4DF18B44688 -:10631000C14FD3D109A0B7346CFAD608F6D717FB12 -:1063200004929ADDB37DF9DAB7705F0438213E3903 -:10633000BEBAF1D7036F8129BB0BB09E03E4E5A57C -:10634000F0E6E372BA66A78DC4D37994FFDEE49FCA -:1063500004F87CED3E3BACA75DAA6374BEFAD11491 -:10636000171DBF5CF6A6383065DFCBD7DC8FF4573E -:1063700026D4A538909F5CE90694DDDE7458E7DCEE -:1063800055B7E13A4B891BE9B07CB558ECA7E9D782 -:106390001299B8350A9F1426303E695F47914BD752 -:1063A000D90E7A3FE8DBFF2EFA37A07D7A2F01F96C -:1063B0007F3F5F33DD2931FFB599E1CB9A6050ED26 -:1063C00045B38E7ED73FD606783ADDD7950AF3A43B -:1063D00070F072B809DFD37EC50FAE4F6578228AA0 -:1063E00054C8DBD1FDA008BE43FD36D965C9D3B57D -:1063F000E3F2938D3F9F8F4FE71D03FB5B7B0AD535 -:10640000EFA3AC6F16AC0FF745BACF69E84CC3EFFA -:106410008CFFD73FCEF85DE57FFFD489507EFE43E9 -:10642000C647D00EF6133AAF402A96EFBF5540F953 -:10643000602281687CBE5EE67CAE2FF7507E053F11 -:10644000814A2774FE9210A7A5173A4E02E201ED89 -:1064500095D215B4BD56BF8171B19E31FC5DB3AF0D -:106460009471B9909F40E5416C581E9055C997A50D -:106470004756CBC40B2A67F5A726B4C7ABB7C8C528 -:10648000B0FE339B0F7E7427A5F3334D2ADFEAE578 -:106490006A24DF966FDB20009D46F2ED9972BA8B7D -:1064A00047E35BFA3D2ADF9607FF9FCA55157ED367 -:1064B00013F4F294CAC77EA042F406C748F9F8352F -:1064C000E85BC93DE523FDFB9014F6A44395FE541B -:1064D000BAA31A5C3F90EBDDF4A9D25F377DAAF432 -:1064E00017B95E3DFC22CBFB838D44E9A47817D518 -:1064F000E8283EAB5B05BF09F9DCFB769F0284937D -:106500000BB737E27BBB4F9236EF8FC83745D47756 -:1065100045E48B23EABB23F275BAFAD52D078D0427 -:10652000F11FD0D5332D78891C8F620FAAFB8FA75E -:10653000F9ACD10B7491193282DC931751D50DFC53 -:106540006B7B45F4AF7529217B02FDFEA885D969D7 -:106550005D0E9E8F67F950B27131C83DF57BC84220 -:10656000D03EEF2A0ED9E335F6FFD156D1AED0F2A8 -:10657000A09F4CD4FA11C2F369407C07496FE5CC67 -:106580006FD81563CFC3F162B2FC407FD78BD6AC16 -:106590000560EFF94427251F3267E11D7642E9AC1B -:1065A000AB75C04DD3E8F7B9EF88A06E53F4B8A42B -:1065B000744A37B3391D9F22DEE7C7D0F5CD6E652B -:1065C0007AF89C65D1E9BE92D72FB5CE37827CA5EB -:1065D0007AF431AD5FB4922C43BA2B5F15F1BDF55F -:1065E000C7C81F9511FCE1E6F6C35E953FF2493E30 -:1065F000CA174298FDCBE5F2F562EE4DD3281EBADC -:106600000E89C4A4803D2B92C5B0CECD821FFC055F -:10661000C49B8C7C564B42280F553875001F0DEEDD -:106620005D4E756CFF53E183402F3BFE90F7124D9A -:106630003B767C3A680FE4777E9CF507D2B37ED137 -:10664000BEEF66C07ED6B5CF847EB1AE7DBFCE7ABA -:1066500010F2BB4DE817EB5A6472011F78F7D9FCB2 -:106660005740795F663F34ECFD362F88FBEB23887B -:10667000B75309CC7E39D7FAE7234212A47455A048 -:106680003FEC8B453EF2ECB6A0BDDEB5F7DB42B782 -:10669000F59FB79E5A2371233DDAC8B46D40BFF110 -:1066A000CC7FECD933EAE58574FC9AE6FDC6D9B413 -:1066B000BCE88DBFE681FCECDAC6F4A24E39B886A0 -:1066C0003809F92AA1EC7119FC7CC04C19843C9D55 -:1066D000B8F1066F6E34B83038745138C0BA285CDF -:1066E000CA41EEF7068F984423D2FBBF1E3CCECEA4 -:1066F0006072ED0704FC4261B8082EF6DDE6370B48 -:10670000B87EF67DDFB7792077CE342D447DE55213 -:10671000EB1E92F8AF4A07FFD5750B81CB59F7C432 -:106720007F597C33FA7F2F41C17946F2414F3ADFDE -:10673000F913CCBF6673E27C2F93FFCBFFB7E17DEB -:106740001BC5BBFDD2787FEC7F2CDEDFE178B7394B -:106750004C20CFF6FE15FDACEAFA2FB5EE57FE87BA -:10676000AE5BD5E36F34D41D9E4AEB1F268115C561 -:10677000749E6F665EFFE1545AFAEB5EF4938F12DB -:10678000991DF86B503EC0FE4B13FC1BD0AE6076DB -:10679000531161FB7A514E19EA1B45394FA0DE4077 -:1067A000A4BAC3F9141E3766CD752EC5EAC33E716F -:1067B000D3FC8FD2AF75A2FF30C27E3C2810974029 -:1067C000F5D8A22B6F380476CCF84C3960CAC3F4E4 -:1067D00028A46FDB27B2EF56BDDD3409EC1D8D1DFB -:1067E0007883A22F9FC0FB9B48E61D9E4AC79F98B7 -:1067F000293AFCD06EAC4F82F54CA2CCEDD39C1F55 -:106800004D88E86F1BD531B5FEB5BF177EE624660F -:1068100067FE9A8E9F0FF0CB94D17F7849F801BC28 -:10682000115EF9FEA5A05B494E84DF8D19351C9ED3 -:10683000CCAE96787BC9BAB80DF85622D42E667ABB -:1068400019DAD3AA5DDC1B9C09B7B3253EA40A77ED -:106850002993DAD9FAFE101E2A3EFE5E3CA8F8FB08 -:1068600047F1F17BC0C788303E32CF3B24E0CF22D6 -:106870006E0F8C3FDF26623ED329E1F90BB707C6C6 -:106880005AE325B007AE953E10812FCBCCBB2AE151 -:106890001CC1EC1490AE077718D0DE31170808F74A -:1068A0009C4609F31F181C2340D19E72CDCE330F96 -:1068B00010F027BB8C4CF12E66FEFCBF7CFFFD98D0 -:1068C00042F0ABB0BF32FABFC914BE735691400C50 -:1068D0005DE75C897821C4612E5DD4319D3F589F6E -:1068E00087BFEB52C2FD5CAA7E6F72E49F9DEEA44F -:1068F00072EBD81584EC829439FB25ADDDFC835610 -:10690000062FCF61E2EF8F72C125166BCED9FE2D17 -:1069100089C98F9D7FDC361CFC6763BB72E3983CA2 -:106920002D30005D7AB85D708E287110AF70AE7535 -:10693000401C9E231E126DEE287E9B4DDC9EFE6544 -:106940003D3A9549D77AE213C16E2221F4DF7AD716 -:106950009BA39E07CF4A3270BAE178A37F62219C45 -:106960005BB0F1E7D2A6715ABC754CFA42CAEB890A -:1069700007F83BA6395FF947E10BF63BC077932553 -:1069800038A1388AFC98CFE137E5C077E8EFBCB290 -:1069900075AD01E8F7CAF506DDF9647512B7BB8677 -:1069A000916130AF29072CB602C0CB21D169A1EB90 -:1069B000F3B49E35BAA39C7345C213FA073FFAABF2 -:1069C00049EC5C608FDC341BE0BAE74B33F152FCDE -:1069D000EE32FAAAA2CD332985C9B9B9A4E9BEBC61 -:1069E000EC7F3DF88EEDB206C6819DB99E70BF4624 -:1069F00024FD11A4E3731B891FF653B04B412E9C59 -:106A0000DB4C703FA7207912EC6ACAEF3FD4FA69D9 -:106A100006B76CFD25E801B5AD82C340CB6BA5A0E0 -:106A200011FCB19E967811F6DD7C85B8F07C587229 -:106A30000CBD55C317AF264908DF83A3F7DC05E378 -:106A40007ED56124A08FB8DE0CD961DFFEAA75382F -:106A5000F2416FEBFA553DA91C2F433F4C1E46D225 -:106A600043EEE6185DFE1AD19D01FC35C5149CEF7E -:106A70008C82BF49C98CCE2E5BBEF9FF3F936F1F3E -:106A8000AAF2CD2D166BF8282999D1BD46BEA54690 -:106A9000936FF3042515E03E6FEF8054C0EBBC7795 -:106AA000E4E468F26D4B3D3BFF7B9DF223A45DCD9A -:106AB00054BE5DAD916FCD54BE65F76CF7B7CB9505 -:106AC0006FFEFF1EFEDB02F22DCA7AE339FC54F999 -:106AD00096D77A14E55B5EB381281ABF9339F952D1 -:106AE000F24D48BE15F4E143B233360AFD6CE1FACB -:106AF000F7EB3C6E0FC60139F7A364765E7AB97284 -:106B00002E3D85F1C925E5DC7F139C5539376F3B58 -:106B10009573D9D1E890C9B979BBA89C13801E9907 -:106B20009C9BB79730FF5B847CCBE921DF08D6AF15 -:106B30000DB0F69E96EC17EEA6FD0D73C94E33AD63 -:106B40003F2C2CEF4668E5DD8F922584730F797713 -:106B5000E8F2E4DD762EEFA81CEB0FF235923E9CB6 -:106B6000AD31BAFC9E51ED9B7F05FCF2AE88E78B00 -:106B70001F18D839D07BA3DA0B80BE56F2F97838CB -:106B8000FD75D67BB1FFA237D9FA6A3633FF776D30 -:106B900033D30F6BD78B7E85FE73C2E8EF8C30FF4B -:106BA0008ABD0249A5F9A926DFF35690C1BF900915 -:106BB0003B172393F235F430676415FAF11B2CF67A -:106BC0007584F2F11C8998C15F5F659DF005F8E955 -:106BD000AB4632FF7E15FF4E78DC801A0759DA7219 -:106BE000EFDB7D48CFF881292686C7292F0BFEB51C -:106BF000D910BFA42FAF8A887F7C8AAF73AA1844AC -:106C0000B890F7C5A8710C4F45C2E31087075DBF68 -:106C10000E1E7E212A3C284627E5A784D75FF16E09 -:106C20007031F8F32B560A78EEABC223729D2A7CA2 -:106C300054FF74156FEF69BD17CFFD23D7AFC2AFF7 -:106C4000C7BA557846ACDF97CCCFBDF2C97088A7DC -:106C5000A1F480F2C3FB1B0A073A4EF1D82B52B5C0 -:106C6000F2F8790E87E1BEB145E904E046EA807E9C -:106C70004A1BEF7D3B9DAE7FC427CA30D826AF1993 -:106C80006D72C339EA264B08E59B4A5FED2ABDF3D6 -:106C90007EF664D48D437BBD4570807EE10958103B -:106CA0008E1E4A67165AE5E0CA6F2670383A4CC8FD -:106CB000577CDFA17037D0FA13D47D88C21DF866E7 -:106CC00078EB593CCF2D20213C2FA96D149C01BAA3 -:106CD0008EDA16062F55DED23FAB161F51E8518AC9 -:106CE000468F049CC485E17DB08AD79B62F27D0407 -:106CF000E7305328BDAF25613CE6D0FF008F917887 -:106D000052E17929FAFC9CEB1F5B008E5680578874 -:106D1000E95101BA2FD8C2E51EC9AB8363D18B17E5 -:106D2000187DED1514384FE88613D02B2D1FD1CACE -:106D3000E815E0A600DC5B4B44C89752F82666F7DE -:106D40005C279C5F6AF9B762EF51D6FF6AC149A21E -:106D5000D0AFBAEEDEE8F71FA5DBF608BA7DCF129A -:106D60003A3C1CE876AFC0FC08ADF1BA7347530A51 -:106D70003B77DF64A1F40DE75DEFC8CE754A4F3E67 -:106D8000BFC0E109FABFA2F14B0D8105C059E04631 -:106D900033C69FE13CFA33FD522B5FB75848F2AD42 -:106DA00005BDF76FE4F6406FFA8D9A1F0AE381DCA8 -:106DB0006BA1E3E584C78B94EFAABD7FA97525A6D7 -:106DC000FC63EBEA8EDF246D78FE648A773F98845B -:106DD000FE1F169F743B8F4FA233403D4B532F2D08 -:106DE0007944EFF5489A19F7E1FB785CFCF5A29538 -:106DF00078E93ABE72C948A77497FEDD1890CBE3D4 -:106E0000E83E4293AF0E8FF8F86E2C17F13CEAA6DD -:106E100077136BE09CEE261046F4FB4DF902EEBFB3 -:106E20001F4067A3408F3513978993302D1FF98337 -:106E300078F41BE5AFF71529949F866DF43740EA87 -:106E40002C0A25BD07F01B2B12805F9B2BB108F687 -:106E5000AFFB3E27F9A282FB2CF633EC1049867A71 -:106E6000A35DC9680E8C6A5E5104FED1A907AD56B8 -:106E7000A0F39C5506E2D6D0EF68E26F8073F8511C -:106E8000275CB700FF95537D01FCCEE5AD6B1BEC95 -:106E9000905F253815DABFC7EB9E60A7F3DAD2788A -:106EA00076C255C087B41E74E359C5EA79D60B4E35 -:106EB00008952D6D5D8EF138A5EB05E280FA7E8197 -:106EC0009859BF7E33ED77CB2ADA9EE6CBA03DF40E -:106ED000BBFEEC87B7009F1F1659FBCDECDCBA94C4 -:106EE000B653805ED7DF8BFD55AC12481AEDAF7CF0 -:106EF0003393FFE58765279437EF5F89FBD8243A02 -:106F00005E7A36C8FBC078C893E18203FD9D99770D -:106F1000225F7771BE261DD398DC10789EDB0DAA08 -:106F2000DE742085C507973A171A13693FEF8D4C19 -:106F3000CE8630014FCB593C8F3E41E1ECA670FE2E -:106F400080C7731C1C79DC18D4EC3F9FA50C403A19 -:106F50009CD33216E31CE692628C7398328AE96BFA -:106F6000EF5F6BF10B745EEFCBA14CF87EF05A1320 -:106F7000EABF9D5B643C2FEEEC1B44FF74FB2A9937 -:106F800040BC46C32A11E562FB66B68F8BAB6F9B94 -:106F9000900EF0DB2038416E1E5C5564847DADDDC3 -:106FA0002F60FBA2D5F7A7303B86C943D56E2B7562 -:106FB00054E8F68F48F9A6CABF1A0E87483957A376 -:106FC000EE331172AE06CE9BED90EABF7B8895C979 -:106FD0003FD0FB01EF81EF907E6B0FCB04F47EE19D -:106FE00078C7048CDB827D93968F6A155C70CE5FC8 -:106FF000FE89C98FFAAABF64E64F417E7F6A22826A -:107000000271F014EE542E8C3485FEF82CFDFEC572 -:1070100007668890A17452827056E3450B36B0F82B -:1070200096820F56A494021CC627A29C2D6B14892D -:107030005B232FBE105CB7DCC9E4B16383461E1529 -:10704000187DA5B07F3952991C5436C8103342B60A -:1070500073F944F56917E80D15BB96A71869BDC506 -:107060003C1EA462EFF2142A1A4803EC5BB47E853E -:1070700091F55FB14F70ACD5F4AFB657FB53FB3110 -:10708000EED2F733602FCF5F663FEA3CD4F17BD37B -:10709000C747FEC7851502ED6FE4FB2206298F3C2A -:1070A0003E6980F6BC434D55FF6BE18706E2D2C0D6 -:1070B0006DE41F63884B4317CD23287F53BC4D6E6F -:1070C00061FA50F388A3C69A02CC3B809F6BB99FAC -:1070D000B6763C3BB76ACEFFE011E0EF490502D23D -:1070E00001F1BA8D8949A8072970BE5056C0DA97B8 -:1070F000D1F6C077CD2B191F5279A080BCA85DB501 -:107100007C02D65F2F28D07FF3DA12DCE7CB478AE8 -:1071100004CBD71F45BDA3BCE56812F02BE5CF1506 -:10712000B0EFD68E3139803F54BE53F9F87D99C502 -:107130008710B36328DC03284B51A2F2AF78983054 -:107140003B75B38C7CE719C9F8F2FD2D22F2F3C12F -:107150006BEF98007CD8B941E8858F299F1684F998 -:10716000545CCDE275CA36317BE5E02A261FDA9BF6 -:10717000999E58B45A9E0CF9B27765C2FC5E4C1FBA -:10718000BC5C7EEEA1A76C8CCECFBDF1EF14B9E94B -:10719000A3FBE8FC6E7A8DCE5F09C3ABE8BA07ECBF -:1071A000E8A7BF6E3AAE579543A5128B679AE35B8B -:1071B000C8E27D2516F7F677CF2B621E8FA5D8C2C1 -:1071C0007244047A8F6771D2EB65A4F7487EFC475E -:1071D000F9E89FC5D7DB391DA9F311F7B2F61057AF -:1071E00016A070FCF5E69731AEF5CB578F4E013CFB -:1071F00057EDA1F44BD7DBB9D9460220B7243FEEB7 -:107200003795CD22C68F132950788B4DCB9F2C3EBE -:10721000A9EA751BD24DE53616775AB9E3781EC632 -:107220008B2C0A61DC95F755AE6F7A837940DF9538 -:10723000128B938AE4F7B1A94CFFECD8153B0DD61D -:10724000216CDC8FE7AD954D77C8407FDDF223558B -:1072500056EBE139A697D22F9CB3C3FCA60ED5CE30 -:107260006F21E2A96313E3FFCA16D96F81F96D5C40 -:107270008BFE6CCFC6B3181F5FF4FA16F423785A4E -:10728000447D5CE44611CFB3688AE75691F189B535 -:10729000CD3578EE56DBC4E3FF22E2E2AA5EDFBB27 -:1072A000C34B4153F5AB5FD8411E9C6EDB60077842 -:1072B000D2FE30AEF0BAF3922E3EAAF77860973E37 -:1072C000DEB0E9711E6F38B99DE4F58C373C0DFFD7 -:1072D00080FD2635225E7363228FEF0E141647F170 -:1072E000E777DFFBD9F2F51A8893EFD876660DCCF5 -:1072F000BFFA6F5FAD81F826B2CF82FB94E7D5DF8E -:10730000615CB1DA6E612AA3B7CE4DBFC0B8ECCED6 -:107310004F4D68EF74EE6DCF82F8B6CEADDFA5802D -:107320007F6EFEDEEBD17F397F7B512A8922EFD53C -:1073300014E8D37F1971E191F838D87C10E3B0BE1E -:10734000FCC484F2AD3B7EB4A986C5E52A3C6E74CC -:1073500073F4387C35CEB1B6F9969BAE0579DDCCA9 -:10736000F4BBEEB8C74BC58B7E48F17AF565E06F8C -:10737000338F0B6E9A1C355EF44BF807C5D3CF5391 -:10738000F5F1A25F37CFFDF98B50D69CD86BBC6866 -:10739000E032E0A6C6F957A7BA5E4D053EDA16EB15 -:1073A0004D6378F34F12400FFC3A0BEE479C92432B -:1073B000180712DA6B7240DC63E5DE8F915F3AB733 -:1073C0007F80FE56C2E3EC3B49F71F8B8716F83AE5 -:1073D000D7DB589C29873FC4A12A76FCCEE34D1900 -:1073E0001DAB71A8BDC59F0653F9FD617EEFA08658 -:1073F000DA4D2C4E3D1C972A8C047C1DD5C5F5AA70 -:10740000EB8EECCFC1E56838AE3A7A9CAF1A47D81C -:10741000135F6C5F51E3A63BD7F2786BFA3D7318AC -:10742000C4C9B1FDDCE3173E8E865F35AEFA0F119D -:10743000F855D7D71B5FA8FC79A979FF57E1F26E01 -:107440002AF367ABF0E9F84B7439FD0DE7776AB7BB -:107450007E9DAAB16F6772BB55859B3ADFC54D4CC7 -:10746000AFE8D8C8EC8748FEA6EB71458BB397D23E -:1074700098FE5BDBB23F0FE450C7815D9CEE185D68 -:10748000D76E3ECAE274A9DCF66BE536617EE4C8CD -:10749000FEECBC3F4F6BF4FE3C9BCF46EDEFB4E4FB -:1074A000BA03E67FBA8DE951A79BC489FE28FD5F28 -:1074B000E0FB52F7BA6D468C9712ED31A84FCDB76D -:1074C0008DFC242E095223C6FD342CE471420F3B5F -:1074D000D300CE0DB61B09CCE751808FC6FF203BF1 -:1074E000DC04F43839ADB84054C2F355CB8D4906AD -:1074F000E2D7E25F0A64827C3F92DF2E437F9F45A2 -:10750000F84D3E93C8E2543AAFCFBC8273A1D2BBD0 -:10751000DEADE6DD0F893A3F47AD297404F477F21A -:107520008605FDD6E23E8B17FD666B2CB8CE83DB5D -:10753000BF7D05E0D5F9731361E7089430A85C2896 -:10754000E3FE8BF6EDDFAEF933E899D0988E5FB6A7 -:1075500086D607FD7A732CDA035DDBE2F2509F7C5E -:10756000E3C1292037CA600F033DEFF5547F03EDD7 -:10757000EF6432CB9FDCD217EF13546DB361BCE1E3 -:10758000C1ED3B6B41FE77BE1E0BC7D1E44B39F812 -:1075900037C87BF6C491B50AEA818A76BFAD2092DE -:1075A000A2D5F3AA20AF8B7F2168A7A33F8ED27309 -:1075B000554B1CDE1FD1D4E3FCECCD60F7650219FE -:1075C000C077549FD48DA396DF9AD69FDFEF0DFD31 -:1075D00084BDAFC0EA7B8CA15296F76530BE6DC307 -:1075E000FA252ABDF2F29EFDB2FA33D3FAEBEAA9EC -:1075F000ED6B4DA42E1A1F54A709FC7EEF5F0747C1 -:107600007BCF22CAFCF1FBFD02F11A400FD86AC100 -:1076100038AE6A636010C4B7EF30B2F3916A7B6032 -:1076200010C4B7EFE1F2AF3A86E6E9F70C3E0FA8D7 -:107630000F79620EBE06F8AED969214BC17E7FC3B9 -:10764000E6023CD7ECF8F6E44B0510CF168B7EAB88 -:107650009A37FE0DF15F630ACC00FA0F6D35917514 -:10766000B47EC7D677B2408FE8900359091739F72F -:10767000A96932E9CEB1D5759CAEF70F84FBEBEA70 -:10768000BDC5CA5EE4C5DE34A68F2E4F733D9D8610 -:107690007C6D75A0BC86FE44E8A76580F65E73A588 -:1076A000125D8EAD4A9375F768C5F03DC555D0EFB4 -:1076B0009724B83883A2A44608E1F979E5C6B34314 -:1076C000C11EFEEC6757E1B9D667C6D05090DB9F6C -:1076D0006585866AE5F1A97AB322C9E897C0B46BDB -:1076E000EDD9D20C02F1839669D1E4D396B4589CBB -:1076F00047E543B151EF83EEE6F4B61A6830998D51 -:107700000B7E0875DCCF8C7E23CC23375DC1F2CA9B -:107710004CBF11BE576DDC3540F7EE84E4C37A945C -:10772000BF101E156485B1C0DA53AE542CB02A12B6 -:10773000DE8F96FEB39BDEC4309ED0C909716A1CF1 -:10774000877467423FA87A1F40928BCD002F232970 -:10775000764822A0DA877C1A439A30B5527584EDB8 -:10776000437504E28A4EF1F35B93A43C0DF2C374BB -:107770004844797E29B8FD3ACD8EF3364975C489DF -:107780007AC72407E8D582D74DBEA7F4D050BF7181 -:10779000C00976FEEF8278380C8DA3F3B33BDEFE92 -:1077A0000EF4034A6768677BAF23FE063A9E646463 -:1077B00079328EF8A39DC777703C10EF7E943F56C8 -:1077C00012FE0BD17C2C4A283A6EDCDF46829D6B80 -:1077D000759000E84DB1561288A5A935573AADE528 -:1077E0005F3B61F9FE949C41AE39C6E8CB23E99A30 -:1077F00038A5F3DD7251C4F6E723DA9FBF587B1535 -:107800001E1EF3806C76FF9DC12586AFC13BCE79ED -:107810002108F0C8B33B1B008FC6D09107011E7929 -:10782000566627263512AD1D37209DC9AB4704B6D5 -:107830005FD2BF62ABA63FE230A3FFF4710EF7EE5A -:10784000FAAA5FA5477D8B0470ED51DFD25BFD98EE -:10785000E8F56DBDCD2736FA7CE27BE9DF1BBD7E06 -:10786000ED1B1FBF1750E023931B1231A8F7A00791 -:10787000A483BD157724A58451053B2788C05B0CE4 -:10788000D01FA58798819AEFF07FB91AFCF58F82F7 -:107890007F1240BA2BE1F3A1796B3A9DDF9D7CBA50 -:1078A000E3D7B373CCBBE7333FD29D0FB1FB424765 -:1078B0007FC6EEEDDFDDC8ECEDBB17B0733352CE03 -:1078C000EE0139E87F30DE3DD009C5F73D3EC11FEE -:1078D000C886777022F4D7EEF776EE97A07E4984BB -:1078E0003F46A527F5DED26CAE5F6773FA9C4B422C -:1078F00036E0FBC87BF4CD692C2E8D9A632E58DFC1 -:107900005D7C7DEA3EE05D4E72E05D00D110E38477 -:10791000F31191DF5B257623BBB77A6B824EFE9C19 -:10792000CB51E260BF236FF2EFFC3DA2793728A96B -:10793000DA7B5ED285587C7FA44176A6815C942F49 -:10794000FC9828942F8C17061045730F8DEA77C882 -:10795000ECB283A01F4772149332D00BE3399D25FC -:10796000DDD8AD87BD4FE1326FB982F760EF486770 -:10797000FBCBD28CE2B94017A27DA4D36DED895721 -:10798000EF76B6BE06585F76CF7937189D4ED44352 -:107990006FA41A04FA7B9C66988F68523E56803F0B -:1079A0007F2B13B0FF7BC281E1F35C52821FE25F49 -:1079B000E6D8971E01BA5D56EFC073B425F5399825 -:1079C0002EAD4F433D7471BD1353152E66A7CF25C1 -:1079D00052389B07B2FECC0E37D333E83E04F11782 -:1079E00092A32E007973661D01FDD7D20D1F1FC211 -:1079F000C7D89D7763DE04799ACA8D9310BEB43DD3 -:107A000029033F6A867B19C0C7A25C49140D5D98A3 -:107A1000D286E9F23DE0A6D2C71606BF2705461F6B -:107A200091F07B526E53E0FCF9C91BBADFB541F807 -:107A300051759FC1EF37EC7CAE57F83912509F9DBE -:107A400053B8784603FDF4043F877CAC7E24C2EB38 -:107A50007188EB1A0CF6810B5311E047E9C894EBDF -:107A600025226D6F52D89C4DD66297A180D12EC031 -:107A70004FB432789AD2EAF03CCE6C65F012AD5E2B -:107A8000848B6C65F012AD8CDE8C3C2F01FC866320 -:107A90007BFC4EE1D79C3E02F0305A072F63D2B8F0 -:107AA000CB83DF4A0A3F3A8F24CE5F917048827BB6 -:107AB0000AB961BEEA4DAF7B8EAE1FF6F117287C86 -:107AC000204DEEC57E4CCE607234C950B75F06784B -:107AD0002410BEBF7849662161A18AF097E6250A85 -:107AE000E405360FB25E8F57D12145BCFBA6BC0022 -:107AF00074B0E21DD900E7A4E2821FEBEE938AD3B3 -:107B00005CF10AC2D32DC0FEFC44BD82F85B0E7846 -:107B10001C0CFB23B3C71EE5F87C0CF804F1CBF872 -:107B2000E349CE2F4F733E6970B2FB13CB26B2B838 -:107B3000ACA47C037F0F2D40B4714FF1CE2662A41C -:107B4000F3421D5BC134807AC62726FF15B45D6CF5 -:107B50002E71019DC47FF2801FD74A8AD3412F8A9C -:107B6000E7FA2F19A3C44FC78BB40189D921541444 -:107B7000A25DD36688F60E5683F38019FCA6BDCDB0 -:107B800067FFD41D4897A5576378304974174F9FF6 -:107B90004BF3D6C658F40FC63ADD858F029F37DA0D -:107BA000904EAD74FE651ABCC7F682D717336E309F -:107BB00064503A144169A3F87DA6718005E0FC9CED -:107BC0005C9C0EF2F539BECF521C28DA73A80E2E3B -:107BD00027ED0557EAECD915B20BDB39C6E8E5C04D -:107BE0000A2E7713C6EBE95D95BB1F75CB5D773227 -:107BF000CC27E5C278E4C7A49BA3CBDF06D9E885F0 -:107C000077051A86327EF79618D97D989EF200FD88 -:107C1000DAE7DC83D6813C55E96B1161F2C74B6230 -:107C20009CB81FF1777454FD7809BC37C8E52CA4C3 -:107C3000E24023D24DCADD068CCF5BC6DFCB7A8A09 -:107C4000D217A43E4A5F905E9BC1CE33169987E15E -:107C5000BB6D0D5603CA0BE95393DF0AFAEAFE51D6 -:107C60000EF02348B2B3CD05FE409BD4B48E40BD88 -:107C70000233BC2721C41738800EBEB1CDE977B1DD -:107C8000383C8A4E01E8C891544C8EE5E2E901DEA9 -:107C90007B911D3713F02BBE90546701B8E5663019 -:107CA000BBABB1A410E148E13B2E2339DC4FEAB471 -:107CB0001BBBDFDB826E5FE8E5FECC940CAE476752 -:107CC0007AC9400DBF370A5C0F53BC2447C3F78BFA -:107CD000AE9840E05CA927BFF722CF363079F6880E -:107CE000105D9EA9FAA72ACFE40839A1A68BFB4D07 -:107CF000D4DDEF322639817621F51A288A24EFD592 -:107D00004FDE158F70980D7020693776DBB53FEC2C -:107D10000F7A6561547A8B946373BAF775570AE0EA -:107D2000E994ACA44E077A7AA7B77DDD558A74E84A -:107D3000EBA3C0BEB4FF991FA35FE7C4333605E4CD -:107D400050D985C7717F28BD300AD3F2C61B703F5A -:107D5000179E9D5C08F4D0BEEAFABC4FC1CFE3B3D6 -:107D6000E1BEDDDE583408CF237DB10AC477B437D5 -:107D7000D2F2827039C48B8B9A780102DE77CDFD06 -:107D80006F52A0A05EAABE7B46ED3AFB68F00BAD39 -:107D900016F15E58E9B33617E89FBDD15FE9AAE84E -:107DA000FE00D86BC1EF4A07CC013D7ABF7D742835 -:107DB00040FB9DB38E9D2334185D2703A0373D63A0 -:107DC000C173C88684E8EF82CCCDB87E19C881B96A -:107DD00019AEE7104F56F64E69EFFCC0C63F098753 -:107DE000CC708EF5227F1F4572DBA7EACED9D83939 -:107DF000D649EE6721E65ECA6378B9D24BB99DC514 -:107E00008B1047F472D5CE880DDB194DB08E9AC613 -:107E1000338B3F4578713B83CFFB94CCE67DEA15ED -:107E2000937F5114FA3FC5E3532A04065F950F4E22 -:107E300075EB476E7C0F27924E8575435E1845FBA8 -:107E4000FDEA908CFB4635A52FA4AB75A3303E5EB2 -:107E50007866D4D310377CFEB088E595172C58DEB1 -:107E6000F1B0F305887B0ABD2B13904FE70F5D1F20 -:107E7000C7FC447A3FF63D7D985C38C6E543E9850A -:107E800027907EBBE9C437D708FC577AE12946DF43 -:107E90001B057CB79278ABDF1D3B90D3E768685F2A -:107EA000317911C07B8C0FCF49CA36989CA00F4402 -:107EB000E2F95886A2F37B94059761BF84EA5F4993 -:107EC0009AF3F4533CCEB8EC027BAF9038BC240D4F -:107ED000F881CBA7301DEBDFA1EDB044F7D39FE3D2 -:107EE000FA4FE9856B747646787DD7E1F752BEFF8D -:107EF000970547613EBC9E1746455B4F781D63B0B2 -:107F00007E477CF4F1D3399C4FD6971317956FE5D4 -:107F10004656AFD477BF11E44EE9AAF80441B3AE98 -:107F2000B2C62A5D9C47D9AA12E32C4DBF613C2CF6 -:107F30007E77AC14C643FA4B0B272FB2825E502CCF -:107F4000F7017E5A5751F85305FA63F2E90BD997B6 -:107F500005F2BABDF13E7BB47B13E97D22F0D3C8B4 -:107F6000F143F5EA020D7E54BC44B63FB9B6ACF01D -:107F7000A7E08F5EC95E21E95DFE44E02D3B3ADC5F -:107F80008675C32D07E38D2E0DB7AB7471453DE0AB -:107F9000C6F1ABC245FD4EF5A8ABFA8C80F108BB2B -:107FA000BFD3C8F07F297885C7E5F81F1B7D1DD397 -:107FB000BAD7B1807829A3CEB9E43A1E245EF3453E -:107FC000D6A1E29FBCA2C3FFB497D6221FAAF89EF7 -:107FD000736025D2EF1CCA8F70DEDFEEBBDF1E2D73 -:107FE000BE685A6F781FE825B985FFF7F0FE85EC6B -:107FF000CD82B832EF720BDA23A7D63D91A585F377 -:10800000DC8CB1F7005EC8FAE4CBDA3FBCE39C87B6 -:10801000C0BEF43E23A33F6D6B86BB0CDA97733B67 -:10802000FC91F80983A2E9078FD61F1A027EBA864F -:10803000FA364C65AE5F12D02FB3515F72457BDFCD -:108040006B491F26571EAD6F637E4FB39738B4F749 -:108050008909D39FFE93307F8DDACE28BB1DE03F88 -:10806000350AA418F53EC9BD24BB00FC1E49F95EC3 -:108070000DFC16F761F79196A51D70C0BD6213ED5A -:108080001FFC39E64CE99CFE9C93E5F3854F45883F -:108090006F96939A08FA4373E9770DBC8D496D3A50 -:1080A000FF74241C24B31DCF9B24C2F43975FDF446 -:1080B0000BEE4B8FF17D6905F76B3E5FDF847EFF32 -:1080C00045B176DCFF16F733307BCA2CE17B35A651 -:1080D0007856DF18C7E66D01BFB708FB6A00F336B4 -:1080E00078D147C4A7D104C8C71345807C22092C86 -:1080F000C67752C6067F02DF9D696E3FE0F19BF4B2 -:10810000B62302F8B18BDD8361FF6D14BDF90AADB2 -:10811000FF7331940FF5B268D127092CED07F1D028 -:108120006ECDB9167B2754D1FA0523F3FD164811FD -:10813000E73D7F19AC2D5F9EE67A1DE6D16061EFC9 -:108140000C251D17F03CA7C1C2DE1B6AB0DD1E075F -:10815000FBF86FFA30BD1DE900E8E810D367CE499F -:108160004A5C02F3932A6FEAFCFC66E54DCD3812B7 -:10817000B7F7D653BA9434E72A03259701E8E60AFD -:108180001FFDAE9D67147F5C82159FE58D7A9EA3CF -:10819000CE0FE2F6018EE2850968AF45D2C39E6E2E -:1081A0003FB357047C4E57DF2F961E61F978A2FE2D -:1081B000A1FDF569B73EFA08CBF3734ECF2C768E4E -:1081C000D9501287F171EA3CA6B73ED6067AEAF496 -:1081D000D6F4D970BE35DD3AE87348F7C8A103B1CB -:1081E000A007DE2FE0BD923B7FF7A61C4BD3ED1F0F -:1081F000AEC3FBCC9F73793A8384F05D783771F01E -:1082000073763F7E9F459C3CDF24835D7F77C07FF4 -:10821000DB649ABBE74DFF6450DB661C0ABD056258 -:10822000C0DDE4988067086ABB16E7DB2CCFDA75FF -:10823000AF5F32E37AC2EB35E3FAD5F5D19922FC90 -:10824000BBE1C3DF6B52E121CEA2EBA6F4323DEEDF -:10825000F61BC945F4F2E9D69CCFD9A1099B4F245E -:108260007CCE4311D51F3BFAB84826C5DF1FFAB8AC -:108270000448ABCDA12CA93FF2890CF95AD1DD0FEE -:10828000429FBFECEB1E9C0C70684BBC2CF979C470 -:10829000C2F8FF08D033C4795D48C275A9EFD01F7A -:1082A0007CA0DD067AE7E2ED1FE33BCB3562F0C947 -:1082B0003BD01F2AA2DD74AE79F045EF9F1D013F30 -:1082C00015DDFFFA66AAF72CD93A674A8C4F663655 -:1082D000C7623CFECC05A2EE1DE9990B583C1F91EC -:1082E000DAF26ED5E9EB8FF4DA0FF80B22FB99BDC9 -:1082F000A0881C1F0EE7B48EB1E83F58C3E86BF6A8 -:10830000789708F1CEA3970878DE3AEA84D212A4CF -:10831000F9D9FE7827B0E7EC07FE6300BC7350DBA9 -:10832000C6FC81A9E2BDF90F839FE500DBC7217F71 -:108330002FD089D5A55835E7051D725D3EBCF7E7FE -:10834000BDC7EA02FE2FB9D5F529BE17C1FD15EA52 -:10835000BEBAB3B104E3644BEE564602FE4B9A2C10 -:108360002E4CCD448AA172AC44226648538D44B24F -:10837000401A43CC90162E62EF7697364E45FDC0DC -:108380003EB2D808EFF196B4FEE26B685F2605F6C0 -:108390000B7961F894B4BEF31DE075AEAB18E31928 -:1083A000AFDA68D4D981439BF4F9AB5BF4F9FC8074 -:1083B0003E3FFC903EBF2193201DCD32DF920BF05B -:1083C0003AB0D744F72288FF3361BCCB3181E1C793 -:1083D000BBC982F2B0A8AAB510ECE033AFD90C60EB -:1083E00047EFF9EBAFF03C3CB42596409CD5FEDF5F -:1083F000C7901888577CDDB20ECAAB28EEC07F59F3 -:10840000F5BA652DD8E13BAE54ED787F1EAC67C759 -:10841000DF587C4D6893C90FE7E36776FDE2353896 -:108420004F3BB3A90FEA57C704AF2106C6FF82F935 -:108430003F83FCBDB8207F2FAE6AA3DE2E9E97C976 -:10844000E44C70D13571D1F42635CD494BCC1D4F5C -:10845000E7D6F5B86926F8810637EAE1A2D61BE22D -:10846000D77F7F90F73F9A18C3749A0D7102FE066A -:108470003BECBF2F477F277911E79F575FED6E27B2 -:10848000F277E288A2B9371596DF647E1F88DF0095 -:10849000F8F70F7FAF229AF968F49389BCFFAFCC4D -:1084A0002C9E3989BFDF7FBAFE10EEFBDD7A5FBDFF -:1084B000CB355E932F6DDC9F5202F6D3AAFD29B314 -:1084C00034F0AADE7430E52E8C7B92C0834BAAA7D1 -:1084D000BFF214F82BAA37894D304F2807B87534EE -:1084E000BD65877A541F1E067E90B03E7ABD6BBC78 -:1084F000868FFF5EBA55F9AD9AEB2F3B47B64D809C -:1085000038F5AA46C109D5AA9A6EBB6532C07B155B -:10851000BBE75A28916291F257F5D6DB7E3C14E214 -:1085200066568F70C27C6817B7C2F7AACD67F13E56 -:10853000C3D288DF3D50D3DD994C2FA4F503065AF2 -:108540007FE9EDD672905FB4DF37217F20671DBED3 -:10855000AF623FC5CE1FE8F74F0C546F3935CEFBE5 -:10856000DE5DB4E919D2F4D164F02B35EAE991D299 -:10857000B7007A596883E05C875F1715DE0C2AB76D -:108580006B21C6FBD2F299D1EE5B57F8F5FD44E2C0 -:10859000FD233E5FFA97A3A59FC87A8993BC184F25 -:1085A0005EBD80CA438D9FA0FA840FDF978C1C8725 -:1085B00068E99AE913440179B8C5A2BE7F24980BF3 -:1085C000799CEE0096C77715814E29A1545D49C666 -:1085D0002B00EF9BC9444847835C81F7F44736E59D -:1085E00041FDDD42F09597B03F1BCAF10E4700DF19 -:1085F00099CCE0F74C3B1496EFE27E4EB5BCB2D579 -:1086000082713667BE34A29C5DD87410E3E83B5E8D -:10861000B3180C541E9CD99A380EE2313B9AD83BC1 -:10862000C5A79B12C7192FB26F47CA0D753F3D0AE8 -:10863000FFA4FBEE9F335DDF64C23EF5088B574D10 -:108640004DACCB8FF6FB176ABB24635D3ED831A1DE -:108650007BACCE7508276FB6847EF03427C40995AD -:1086600008AC5F63BF62B12FAD6FA375C11F9D7072 -:1086700048C4DF6B382E3A7FE21880EFC9A31E345E -:10868000A7C08DEF539247585CE56C8904244A6F6C -:10869000B3613FCAC33CCAE5D9AB048C2B9BB34C36 -:1086A000BF1E782757BB8F56103F7BDF42EB47EC4E -:1086B0000FF12E74BF81772DCD2CFEA272BDBE5D51 -:1086C0001509E07CAA377F6F8A06AFAF89BA2E57AB -:1086D00026AC4BB8D98CF3BAEFB93876DE63242ECA -:1086E000D84F43CFD950BE571137F67727DFD73D44 -:1086F0000F94B8E6801C5E30DB352711EEDBB2FD4F -:108700000F4D3EE46F01F79DAAF124D097BDBB4108 -:10871000605FAD6A150243216F265EFB30F61DDEF9 -:108720001F80756BEFD794131F8E57BE4AFF9D7C39 -:10873000C8F05ACDEF3192F59AF2FEA09F317854ED -:108740006F36E9FC3AA3370B5E1BDE77F537A4D012 -:10875000F9D59EA2B282409CEAF7265DFF10CF3386 -:1087600002F77D62A1787BAE5BAEFB87448BF33F63 -:10877000C2E1F8DC6DA5E9C0AF4F83DE9AC1013DCF -:1087800012E516F71F9080998E1333BC3B8FE58559 -:108790008B587ECAEA57A6348EA1769EECC673A18A -:1087A000D962F1DB701FECE57EEE9BFBD271661B9C -:1087B0005C5912F2AD6B10FA43173038BC30AC6E16 -:1087C000485D143D50C5F3F3425300CE65BDBB98E0 -:1087D000FE652B08C9DAFDB5BA2F93477107827879 -:1087E0006F22B45DC07B962B85A3781F71E50D0ABF -:1087F00001FB3E8DE209E4F14A813C2250B8143479 -:108800004FBDF72DC073418C137EEEA2A679AC58F4 -:1088100063C5F5333D2DB66E2D9CE7A4CECC19066D -:10882000744ED73DF366FAFDDEBE0A8E976E65780C -:108830004F5BE4CD86DF818A3B507CEF5BC0874392 -:1088400063F09E6C2A85952D01D325A07FA5918587 -:1088500002D47BCECEFA4F368833A7427E18CB2780 -:108860003C24B8D621F12DC7FE534D6422CC13BE53 -:10887000831E6906BF0296FB197E8BEAF2A1BFD464 -:10888000012C4D320632A19FC3DDF876A35D319FE6 -:10889000EF63F3B78E4D053BEF700735B8A9DC3AAF -:1088A0009CA6EA43012BFE3ED4C01C569FDB85F3F9 -:1088B000F3D97D83A42C7DBD2ED915371CE4E807A0 -:1088C0004C8F3F6F75A17FFA1A63747FD64B7D99E9 -:1088D000DEE2B92010BF661FF04CFB06F54ACF055B -:1088E00049F7BDA3DEAC8B73AE2E3F80F7EE6B482D -:1088F0001BC661D734C5EAE276AF89893EAE4ADF4E -:108900009E0B22F1461DD7A8FF7E21917813A3D597 -:108910004BD17FA7EBD0E55BBEED5E077C272383C1 -:1089200076B0072771BDB6CB6FF0CA5787F1D2E991 -:1089300008EAF69D4E85E5BBF8799C5AAEF6DF391C -:10894000CDC8EF15B17795013EDEC184BCD87A164B -:10895000FDD1D5ADFB27B0DFF76274A18593572316 -:108960003F521ADA0206CADBFFDEF7D453B94328B6 -:10897000891D50F9F8F4532ECAB729A241C7D7B1BF -:1089800005DD7C8EE2E53983C8E5C299A7C68FD1A3 -:10899000E659FD70FB8E29E3A96E5F90CBDAFFB13B -:1089A000EF97EF2D1A18964B741D59C5364DDE1CE6 -:1089B00091B7D2FC504DDE11519E14519E1691CFAD -:1089C00064F53B6C812CD149487BDFB353A45170D3 -:1089D0008E1D98012F0A2C6BF86ACA789AAF296805 -:1089E000C3F899DA56C189C7FA6A7CBC93E959562B -:1089F00067107FCF2EB6A0ED6D9003D52D8243A0DA -:108A0000F46E6DDA8A7135D5D04ED1B46B6276676B -:108A100075D3516CD76BFF3906E4E7A539C7B09E13 -:108A20007A7E7407E9FEBD8E0B202F6B9ADAD93E51 -:108A30001C717ED499EE3A88F230E2FEAB07FAB5AB -:108A400086E95EADFF87A1ADBF836E62E79F5D28BB -:108A5000D1FA7FAA691F01FA12BC710972FF79C1AC -:108A60003F04F6E717897B08EC47F7D45CB1DF4099 -:108A7000EB1D9183ABE1A9864159969B242AA78FD0 -:108A8000D8827D052A4B72D624DE04F03C921CC4A9 -:108A9000171A7EB6268995F70DF68573D7DCAC1FBD -:108AA000B2FC15C1D590BF75CD952C3F34D857A4D5 -:108AB000EDFB7BAFBA09E0BFC1119D6FFB66317959 -:108AC000AECEAF2CDF959605FA6635DB2FE0FAA522 -:108AD00099CAC51995A7B76CA07098F1D358945747 -:108AE0001B3A6EB9B118D7EF2D863837F6C43BDF85 -:108AF000CF502E4BA807A4C31E9610C6872DAB4D92 -:108B000041797F65DD56D8F75367E4A2BC3F9FE902 -:108B1000AACF1A114EBF1DC0D2FA2C76DF235534CE -:108B200060BC41EA8336D4839EE6E749946F10BF68 -:108B3000568E8F61594CFE0DCB62765246DFEBEBC1 -:108B4000613D7772FD74C5E3FE4D160AFFDF0391A8 -:108B500024A17F1BF5DDBBD652B91107F114AE7409 -:108B600090077781FF37379C57F5F715F9346F0D6C -:108B7000DB692BA6BAD2B571402BD6B27255DEACEA -:108B8000C866EDD57D27B581C127F5E921EB601DCC -:108B9000B112C1FB1773A70D5AB710F7EF9B71BE47 -:108BA000C4E54A07FBFB44457F03E8952A7E1ECBBC -:108BB000774DC2F5882C5E5DC5933A7E3D5FF76CBC -:108BC00091EEFF749D0FF673231CA93E90C7820B94 -:108BD000983E500F8ED8E4307C89141C01DFFF17BB -:108BE000C1E95E58F73F0AA728F2E267306ECD026E -:108BF0002A2F0C1A79C1E1F7BC1090530B34EF9770 -:108C0000D0EF6007DED1D7FD6896E61C67C68335D6 -:108C1000A8FFA9F38AFDB79D13EF203DF92C523F21 -:108C20003BF27BF332F4031A9B502E1EB991381796 -:108C300082FCE0E7B2AA7E59F8D3AAC360479DCB75 -:108C400012B19D45C5AB50BCB594C2E971BAADC275 -:108C50007D74EF5416DFA3EE9B2BF8BBBB2B1EB825 -:108C60000AE3FCBA48107F97CD3B92A0FCEB2E9F05 -:108C70003E08CB29BEBD16E0F78A18FCDD8115F948 -:108C800004EFD9AC987E2596EF51FD4AD3CD38CE6E -:108C90008AA98C9E5654B0384CD847006EBDD1433B -:108CA0004A03F36F10C995A78D077897E32FB62075 -:108CB000B8FD63D02B975950AF84BD13CF477CA923 -:108CC000381EC5EBF62CA46F368FD9CFA6FB97E2E2 -:108CD000B84EB4CF1FB3B94A505E3D1CABC0FC5771 -:108CE00059C812F3303047C82328F7F87C88EF05BD -:108CF0008CF398C9F5B5CFCACFD9401F7893CB1B59 -:108D00002018B0976711563EEBA1D8A360DFCC7A4C -:108D100048C4FB8564C9F52EFD79079D6B0AF8C729 -:108D2000F95F63C8067070433B3BF4FF9F3678CF12 -:108D3000C4FD10BBDF4BBCB4BD261EFA63E05FF080 -:108D4000B38B6CFEA43E5689F62EE8C75CBED3F901 -:108D5000BBB4E3A9E344F64BEDBB4F005E14EE0158 -:108D6000B807167A58E4BFD7AA9F6F9231F4A4854A -:108D700096CFA817E3175178BA17D870BDEA7C6769 -:108D8000A686AE65BF0BABEFFF646C6D21F8C355D3 -:108D90007B843CA4B7C7C02FD19D17314E1AED9AE2 -:108DA0001EDFB93D1B690712F23793B65EF73D0D22 -:108DB0004588983FA72B4590006F6E1EBFD08DEF62 -:108DC0008879ABF034F48B0ECF2463B02FC82DF725 -:108DD0000213C221B2BDBAFFBD60215EB0131B05F4 -:108DE00001E9B1F18158DCCF8899E1D15319A30091 -:108DF0007DBE680C611C937737FBFDCF2E4B680757 -:108E0000CAA581CC9FD0F59EB816EA752633BAEE76 -:108E1000DC25737E22EC1D89F7C475582EB07E3B8D -:108E200017C6627C14DCFF34C2BD4CEF9FEBC1BFA0 -:108E3000A2DAF1C777B0F714E0777BB47630DC9B29 -:108E40002D1F16960FF83E0CF0734B2CF713B92B11 -:108E500070BCBB6208C461D41A048CEBADADBC120B -:108E6000EF9110FE8E73359F5AAD81DA83C3C27CB9 -:108E70005E6B383608ECA96AF3327CDF9996BF093D -:108E80007618FCCC6EF7EF7864F7A4EBDA6567FE32 -:108E90008AF7DA9BF5F8AF0ED309DE8FABD4D24D4B -:108EA00076981E50DF0639319EE0BD7C1BCFC74E41 -:108EB0006CF3839FC6C3FD16C907D8BBB5B682261F -:108EC000027E53CF29A66F8C6E5D7B10ECDFF88994 -:108ED0006D6071D1FACCEF16797F6854EB7211ECAA -:108EE0003A554FD1D895436E1EAA4DD97D5BB053EC -:108EF00061BC207C02FE90D8FEF63CDFDFE83E88B5 -:108F0000F278AE6F30EE83B04F811C53ED5C906B06 -:108F100020475EEE376E5A3FBACE3C65DC2DFDD859 -:108F200039CC10D4EBBD9777DEA4D6037BF7E2FEF5 -:108F30003006B7D0CA382627E00740C14FFC5B791E -:108F40002DBEEB0D8297CE77DEEA6C94BBAA9FA66E -:108F50009AFBA94AB95FA794FB75C0AFAA8D7B05A0 -:108F6000BFA5365FCDF9BE067E4F0ADF0B3085E325 -:108F70005EC19F339E046C500E7E1D3BBB5FA76D90 -:108F8000EF21FE2209E9FC7B93EE5DAC156CBD334D -:108F900039DE575A983F67F4436B45E6A462EB8D80 -:108FA0001BE6CA7EB420FC3ED7E71C4F2A5C8CFD32 -:108FB000C6DD03708F11D9FBE6A147D9EF5D9FA0F5 -:108FC000FBF356EEEFB8D98AF78B5D03212E417281 -:108FD00064DD1CE5775B97EEB6E03BFDCBFAB1F3C1 -:108FE00060F5FBB87EECFE2EFA8100EE0B6351CFEC -:108FF000A660CE033A2AECAFEE97240FFC4F4779D8 -:109000007C67EDED5637F417E47EF195FDD8BEB5DB -:10901000B21F7BEF5FCD77DB759C5ED4732CF0C7FE -:1090200068FDD7FEEEFACC7FA2EEAFCF57C4A05CAE -:109030000AD3AD01EF4FC6E6161BC18FB49BCB918F -:10904000126EAFEF86035A90274DDCEF2C3966C0C5 -:10905000EF02ED3E958BF1924946265F76DF19438C -:10906000207EEFD0E9579F788F969F3B65C4F7F03D -:10907000E6707FEB6E78F71DE4E57613FA11AB8DA1 -:109080004C5FACDE3794E92946F74A88EBF66E93DD -:10909000D1AF556DF76F7A05CBD39D14B3701F9484 -:1090A000E9B9BB6259FB18FF2F5F03BB735FAAD3FB -:1090B0004BEB2F4873EF03BC66989438A29EAB0A23 -:1090C000E1FBA2C7FC4C2F3E068207C669B5F1DF63 -:1090D0009173A5CFA5FD1C7F3C15D743E52DEA4F25 -:1090E000C79F32E1B9D9F3DDE332FFE731B918DFC9 -:1090F0008B39B63DDF492D4BD2556C0C807FDBF3AD -:1091000034D3E7661B9435001FB22FD6A9B3479F0F -:109110002A63EF47543E34E562E7D820DFB5FEDD31 -:109120004E12CA427BB4BC7F13C49376B60E71B2A2 -:10913000E3AA343C24A9E5E7CB276406DFD05E1917 -:10914000E9F972FB07BAE8FE9D3B91E0EFB769CF02 -:10915000D322CF217AE6191E3DBB53B9DEA62FBF1D -:1091600025D31D02F956FBCCB7471628305E08E51B -:1091700021F1317FFA09D93503E8367E7C4017A703 -:109180006556185FCD36F1FD9E048C5A3E54CB0BCC -:10919000C791A8E7362685E901367EEE1C59FE7F89 -:1091A00000F2988AEC008000000000001F8B08008D -:1091B00000000000000BC57D0B7854D5B5F03E7360 -:1091C000CEBC92996426992493F7C93BE4014308E5 -:1091D000112DEA24040C98D209A062B538BC41C90B -:1091E00043B0BDB1C566201102A2861A1128E084E1 -:1091F0008762D5367801A346EF8048B1D5FBC747D3 -:109200005BB4F7F78B4A29528188964BEFB5F55F2F -:109210006BED7D92394322D8DBDB3F7CB0D967BF51 -:10922000D65E6BEDB5D65E7BED1DB36A602C81C159 -:10923000CF4C334B64EC1AC67F324F316FD0C69897 -:109240004555A9FC9A5321D37CC867AE0C99168961 -:10925000D40FE909230B59CA21DD620FEECCC29667 -:109260005E86FD2C9A00FF85A68B64D66629C3EF27 -:109270006A4FBF8BB193079C9EF5F09D7DF995CC0D -:109280002A189BCB443D336BB7C431F67C9B14B298 -:1092900040BDB99BCD3BADD05FC56AAF6C87FCC00C -:1092A00076C9B313EACD6DABCCDF02F93BF7977A01 -:1092B00064681A83E3603EE80CCA50FF9AE649EC02 -:1092C000E3718CCD37074D0A7C674F4B6C0FA3FEC3 -:1092D000DBB0FF65D02819E0F90A7FAE1F4A176F8F -:1092E00036C364F9DCBFC27F8261F96CE8B7BB4B5F -:1092F00066305FB617BE170E7D5FA6840E49318CAF -:10930000D57747B4677F330FD643405980F0E832B2 -:10931000B13B7C369A74525D29637FC0FF26336669 -:10932000CAF48D53C763263769861DE65DC5E735E8 -:10933000B04F22BCD6B32613C37E3AE319BB3A6CB6 -:109340005C0B0B45437A520E50F922F3464A6BD41C -:109350002C1AEF4ED66F6239D8EF80C907E3D9FBDC -:1093600080AE2597CEBF06F960FCC87C3055F0C1B1 -:10937000B2532C742D8CB76C250BD58FE6A91DD25A -:10938000450A0BC4005E17010E62451A55C6F1AAC4 -:10939000160EE16569509F477CAA6178463C869726 -:1093A00037F67C650ECF279918B3C60DD11908453D -:1093B00070274D6A1ADB04705EB3322833985F4A17 -:1093C000BA77522EC01B5DCEE7DB78DC6251C760F6 -:1093D000DEC7B2A1DE176995CFE54179A3C2BCDD36 -:1093E000501E0D78E982EFDBAD2C80FD3F9EA75229 -:1093F000BF6E13E75FA3E263636D4897BE9001E918 -:1094000092C01CC88F1A3EB7DBA15D19B693A8DDC8 -:10941000607B0B6B8B0A6B5FF5A29531582F175E43 -:10942000B007CD509529FE4C27F497F87B335B0F9E -:10943000F9B32FDA97607F678D6C7637D477C9AC34 -:10944000A99BF8650DE1FF8748D7F1C84D55A90CD8 -:10945000795F9A96CADC58BE9ABED73B81BF86A177 -:10946000EF607956DFCD9CAFCCEA4E18EF82B3FFA8 -:10947000079807785800F2CB550E77E3FE49637FD3 -:1094800004DF1B7D360FC7BE7F2CF2AB59BEE766EB -:109490000BF0D71479E5C0BD308FFA749BC30C4D27 -:1094A000AA33FFE3B7B742FE93FD4666463AEF990B -:1094B000349B655F0A87962E0D1A3FEA0F5B2F7764 -:1094C000EDD5E7EBBBF5F946A67CD4AFF101A06082 -:1094D0008B6A779D8C26D9E1F90AF8DB6C6E3AD558 -:1094E00005F09A5F327B56C1E706D5BF03D7538399 -:1094F00061E028E2D99CF9E9683FE0A52AF3CBA313 -:10950000A988FFFB9807E1BE60AD9C4BF4D862557B -:109510000361F2AB51F07F67462D95776E35AB1244 -:109520002FAF1D0F726B092D61AA623100FE1B3730 -:109530004FFD441A4DE516A44727F029B57B4E0A86 -:10954000AE82764B362FAE65507E86054D1680E78F -:109550000F623D35CABD532CF0DFCEB89A51285F5B -:1095600094BF2A3EA4FF5AECEAEA217CBD34B83EFF -:109570002D1D27002F373289C5E2BC9DFE97709EB6 -:10958000F5967E5325F473FD5FBF20B9BCB8F9D5BD -:109590009C13E350DE78E712BD617E284716DF7B1F -:1095A00088BE4B332C04DFC9745BD00CDF5FDD62F7 -:1095B000E679A789F227B74B945FDC2D052D595822 -:1095C000FF627C25CAEFED4687995D8AA748BCFCFF -:1095D00071DBEF621880FC47102DB8BE98A329C636 -:1095E00067C7B2A69819A588AF1B3E41F9B578BBED -:1095F000EC09A19C7ED9EEC963989F3C6AA10DDB62 -:109600007F1E5F89F8DB31D921D377D9877288290A -:10961000DEBEEBE1BBB2E32A15D7CB91ED1CEEC564 -:109620004ECB1348E7EBFF2A13FF2B06E6DF674319 -:109630003A7847E1BA53B7ED9982F8FD635D8A81C4 -:10964000EA3F2B3107E2C3D99C88DF174B8A0FD73B -:10965000D992CD4B6B59CC10DED7A832E1BD327315 -:109660006562BF8DF8FE66D477F5DB81CF71FC199A -:10967000EFFFF656D710DF4B33364FBF06FB7FD2D6 -:1096800048FCA5F5D3B8EDDB823F180B019E160B05 -:109690003C993357E6E3F8975B0F8B5737E53B6C04 -:1096A000975F1783EB7D1BAC8F62C6FEAA4AEC2B3B -:1096B000A0034B8B233D33D27AD4F493ADD0C0F5C5 -:1096C000BE8779F7409A64665E09E457769642E56C -:1096D000D95926C287F297E57BDF04F89F53FDD165 -:1096E0005990CF64DEB1A867D40147552CF4664386 -:1096F00006294738CCC13D24E7200F78DA94C09E74 -:10970000581F066786E80FD6AB0BFB39FBDE974781 -:10971000118F0D199F8E46BDDD78F10B930AF4B4BD -:10972000F54A24676D1E1F43FE68ECAD630B4A8645 -:10973000E463A387CBEF4BE44C9691CB33D700F592 -:1097400033359BCBB74E275F9F5B9BA38228F7B631 -:10975000BA8256043ABA3CC050BE4F2F973D08B665 -:1097600066A7F82C9C5E16EFAB4C467EF5C81E141F -:10977000F17DDE8FDBE221FF66F9648F0C799B7748 -:10978000577B36CEDB6314E539019CF71B132BC9DD -:109790005E99EE95695CB6242688AAA2CFFB8E6BF3 -:1097A000018CFB1DE67DE404D0B1069437D2B10FE5 -:1097B000C7067A9D71F827205EB4F97CDB33F591FA -:1097C00013E1768697DB03F089EBB1F2E1F1305AD1 -:1097D000ADBC0EFBB9FE3A4E87D3CF9A83AB61FC8A -:1097E000D356D03361FAE2B49DEB1D5F9624ECC2F0 -:1097F000EE0C94FB8379659401D7FD3D0E8E0F9797 -:10980000A93B03D7DB9F247D3F77B6CB2C0872663C -:1098100069BBC48200E2E9A79ECF40F9FBC99EE77D -:1098200033E685C117D94E4BBFAB8DD7F198D70220 -:10983000E3CD63DA78A1341C6F9EC7FC21CA0FD632 -:109840003ED9DB1F663F90840CABCF367B497E9FB1 -:1098500083D5887CA7B53BB724CA8B76E6396609E1 -:109860004A30D4BC5E3964C6FEBCDE5C17D0BB4156 -:109870006B1FD17FA7E01FA9470AD9A17E74C90039 -:10988000C9DBA516DFD154285A8A7484FA53918E05 -:1098900012F2ABD784F356242ECFCF387C7767C132 -:1098A000BC1676E8E9989EE5E0F375B8B83DD86057 -:1098B00053505F24B6326E077EDF10447DED8A8AF6 -:1098C00019CDC08E31A5B86D28A7AECF8F6A33C42D -:1098D000E2F78C20D64F4F29A476812ACEDF81442F -:1098E000166C95B0CB2689EC40473F53E07BDA04F9 -:1098F000E6580FD9DE2C6E27BA9967B34C7662B75B -:109900008476A286074DBE23DFA0DC3B2D59886FED -:10991000A45E89EC3ED9D03D07FB1D898FB644F08B -:10992000D1967F321FED1A918FFC2AF191DB323CE8 -:109930001F81DCFC46F559C0A700BE9204BE1E166E -:10994000F265E0FB16A21BFC4838DF5AD15FADC5BB -:10995000169247939CF874507E433FDBC0FEC47D53 -:109960004A32DACF90A6B6CE55B9FDDED72F417F69 -:10997000D1575948EF3D60E8CB423B3FA9A8691F4A -:10998000F247D29C92B256B24FD29C28F751D6E001 -:10999000FC1B9A27F9B81D00FD221FD599683FD1FD -:1099A000706FA58FDB0135B43E1A375855D46793D5 -:1099B0007AB356217F34AE04FB08E56F4FD7964546 -:1099C000906F9865F3A09D62B5CC2CC176AC5DBF5D -:1099D000CED649DD641707A6320FCAED734143C0E6 -:1099E0003806E56CFF8E1FA11E5F5AE209A8B8DE9B -:1099F000045FE632D20B9D4E6F721CE0F5E0DF642F -:109A0000DA17758E853CA42F097A76D679939D90C6 -:109A10009FB7C14A78EFECE2E5E7EC8020E83F45EC -:109A2000E6FDB1580BD73397CA030BE23D7102D361 -:109A30007E36633E45CB773C46768CB6DE3BB3380C -:109A40003CF6125F165ABEB7ABE3FAA260BD27CA56 -:109A5000066D531440BB3B1AC7E4792F0EF7A801DB -:109A60000049C1EC7F6FAC9E189EE7F587DA3F3066 -:109A7000A33A8DF4EB6039820D7A57CB7BAD00C7EA -:109A80005AFB50B902F6A4A54712ED27CC980CAAB0 -:109A9000F89C24C60F281BBD808F87AD4C375E38DD -:109AA0007C4A44FF46E8DFA68AFA8152DFE45C8004 -:109AB000B74C6BBFAAC30BF03D6CD4F7472815ED2C -:109AC00031A38DF7EBDCD7376E481BD2FF600FD880 -:109AD000B3C70FD9016BDFAFED180363453B3E37CA -:109AE000A17ED5F479A34B223B2372BD2665F3F505 -:109AF0000A766D5236C90D6EEFD6A2BD2B939D3BF3 -:109B0000059756E34A1F43FB12EC86D46CB21B3E0A -:109B10003D7908BE77CE384D767EE34585EC8F469D -:109B2000B03FD06EB7F4727B96F51849EF6A74BFF8 -:109B300053C89F4E27E87DE4D397A5F1C8A78C357D -:109B400065DC043468C9F6E6211CDA7E2C12DEEBF3 -:109B5000B2B95DDE5858B5251FFBDF2D31D4FBEBC4 -:109B60000B3F4A44FBA4B1F7C3C48561ED96F63CB4 -:109B70004A7858BAD738ECFCAFCB9669FE0D2F1C4B -:109B8000F0E27A3F1D94682D2F5182EBD0AE5CB28B -:109B9000C480961A2B0FCEBD15D73D9B6D627930D0 -:109BA000BF5CD44BB89FD83B33700DEEDBE0AF0405 -:109BB0009FB6FA16D1FADE3ADB62635908E7BCBBFE -:109BC000090F8E282FE2617D6155328ED35037C543 -:109BD00081FE9346B0B3B0BCE1DEEF923F45836BAC -:109BE0007D8FB106EDAF0AB0B7FE15E04E8F9B56E4 -:109BF000E381F5982AEF1BBB02F29B4690BFBFC9D9 -:109C0000E1F46C937C81EFE0BA7F41627BD4A1F2F6 -:109C1000CC1E6ED7DD9CCDED40EDFBCDD9DCDE9CBE -:109C200018E89B84BCF78AD21F8DF66F23F37E86DB -:109C3000FB4EE6B3A97B884E5CEEB85A54F22B5922 -:109C40005CFD0F8CC1F2890AED2798D2FF088E7B4C -:109C5000769DCBB39E09FEC5FCBD2541DA3F64FB72 -:109C6000E7237D2B841D79F6851BC6CE2B19B29375 -:109C7000D6755983AB010FEBECEA4F6A50BEFD4538 -:109C800021F9C62C037D93901EFF1547FDAEB30648 -:109C9000D721FD031B8D54BE2FC5DF807C79AAAE72 -:109CA000261FF7C1CC16C8AF037E32BA3A18DA0BBA -:109CB000B07D203F83C5E5632AE42705E62A12CA62 -:109CC000F908FB6312FA7968DF0083C3F72A21B62B -:109CD000F2800B4E5A6809B47D153F648F1CFB72ED -:109CE00096821F353BC560F12FC5A6D5B3A3988CCE -:109CF0007CBF66E0A801E613EDEA233BB6BE5BA29B -:109D000071EA0B9F33A1DFE4AE6EBE2E1BC53E0091 -:109D1000F09781F6C0DAEC68A1C7DB38BFB33EDA52 -:109D200047B367383D19837AF6F0FDC42AAAA7F530 -:109D3000675ACDFD5EF5C21F037290CA7F922D89CE -:109D40007DED6A9176F0548CBB49EAF3CA88D7B1AD -:109D500092279C6FB4F429212F620F0F4CC1F53B61 -:109D600000FC857E992D52DDDDAFC1FCB68C2FF253 -:109D7000A009E5067692CBF03BB022E0BDBCE7B38C -:109D800029C8376070D37A6DE8A994EB6DA4B769E0 -:109D9000FF9814DDD485E5497714925E8D1AC7EEDD -:109DA0009801DF7F2EF09A6CE37E2EF7EA40D6F220 -:109DB000121CDF77F76B387E6914F929938036F629 -:109DC000384ADBD12FE466AB24ACF7680CEF3FC117 -:109DD00020DF5157427297F2711EC9BB13D29E6C9D -:109DE00027F76799590DC289DF693F069C81FB59A6 -:109DF000F473613F49393C3D9B1C5250406C65FDFA -:109E00003BF6207FF6981D88A7DA9E5F1E477D5996 -:109E10006B61DD32DA2B1176C6CAF49987903FCF99 -:109E20009D39B9E37EF8F6E84D073D7EA28BDE7ED4 -:109E300088DC2FECC42AC923DB7BBFCBD6DB7B833A -:109E4000F97FB8BDC7EDFAC09E68754F983C6F1496 -:109E5000FBB4734BCEC7A09EF97890BF404F570C10 -:109E6000D92BF376477F88EB6AD0EE8FB01B8E3DFF -:109E7000111D40FA9FEFB6929F4E41BB07E0396338 -:109E80001FF80122C765F27925DC3FEC337A56438F -:109E90007F8D779EFEB901D69DD205764F2CDAFBD9 -:109EA0006A2CC9D9D765B607ED32C5EB40BF870626 -:109EB000BFE29CE2F696A05CE4F35F660AE5931DC0 -:109EC00064624B281F13CA47BBE725A1779645411B -:109ED0001EBE37BBFD7F41BAA598B9BCC276F8BD9E -:109EE0004BD85B5D801207E2E538ECBBB384FEC65D -:109EF000FDCF83E9C1F5E4C7B1103D3F7EC5BC137A -:109F0000FD3C1F171A4226EE97203F96DAAEB0644A -:109F1000A8AF1EB70655EEEFB21840FFCF7FF8AEE0 -:109F200037705F31FF15EEC79A7FE7CAE9B8FFF8CF -:109F300078C61413CA9B85CC4F7EE7C58CFBA197CE -:109F4000B220F757338701C7BB0BC4C6561435017F -:109F5000C0FE55F05932486857A86D9027A3D9DB49 -:109F60005103E3CE6B33D0BE647EBBDE9F7E61FDCA -:109F7000DD35A8C7D7B619B8FDD82E911E9FCFBC26 -:109F80006EB43B34BC16E4C473FF689BC18BE35CC6 -:109F90009F6322FE031205697E226D330A3FBC8057 -:109FA000631533843035483C5DEB506A86D3CF5A15 -:109FB0007F6DC6260BFAC306D20DE407BE60F2CE53 -:109FC000263F6A5C3E433F629BBDA9BD8697D39AFC -:109FD000B9601DF051F9B50A37F8981A87F2323D89 -:109FE00087DB0F91F35DD8A1CF479E4F2C0DEAF38D -:109FF000F399BF203907FD46FAEFE9395C5E5D58F9 -:10A000009F25CE013C740ED06654DFCE4279B54E0A -:10A010002179B92A8DE3CB90CED36C67F56CE25FE2 -:10A0200027D817042F873FFB5A97847AB3CDC9F9F5 -:10A03000F27F0A7724BC37E4E413BC6D68E4C1788E -:10A040006DEBA420C71787FB4AFD174B72F47268AB -:10A0500030FF8FDF77727E5C278BF5E6203934CFB7 -:10A06000C1E7F4B1E4792284DF6D601F00DCF3D72F -:10A07000C96568A74C9A69A37934BC62257F6BFDDA -:10A08000CAFE0CB267ABFAF39B86C12B42AB68F2F7 -:10A090000BEACD73C13E01D76DBBFE9C0A342D0B7C -:10A0A0003F779A99E6BD2F2701F7231FEFFB25D2B3 -:10A0B0007B9F95F413FCEF9019E5D70B596437E5B6 -:10A0C000A7F9EFCF41BD1E15DAF16416DA29DC4E8F -:10A0D000AAEF3577A11D38AF2DECDC0BFFD9A03FDF -:10A0E0000763ED71E4DF609DFAEF4BB645B4BBE466 -:10A0F0005C8CEBFB4D26FF28B4EFAEBFCE9B8C7281 -:10A10000F5CC520343FACE973D8B508E9CB1EAEDCD -:10A11000EF33764EAFDD8374F6E4239D778F486787 -:10A120004F3ED279BE81F9C3FBA9473A037D970917 -:10A130003A9F3970553ED2F9D37D57E5239D3719A3 -:10A140003BBCB86E7665FAF7221E4F4CF691FD04C3 -:10A15000F22AFF9BF0E38B11FCF8E2FF1E3F52BB9B -:10A1600091F4E1D19CE1F5A1CBA4A6A13C9C67317F -:10A170007FAD5EC49F61FD6B1633F9255EF9F2F386 -:10A18000879E403BA457263B44EBEF15C59F837E3B -:10A1900085578EBB3D0169E4FEEF16FB18B78505B8 -:10A1A000D0FFA1D9FD9AFD18298FDF17783C9DE3D8 -:10A1B000FD36ED1785BF7689E8D312FC9CDBA9BB81 -:10A1C00025F2C75AD46E2FDABD0D2FCF75A0BFF67A -:10A1D0005490FB671B0E8C25FFEDD2E0ABA154B46D -:10A1E0000B7B2507EE1F96EEFE3006CFBB613FFAD4 -:10A1F000494ED87E74B2D88F9E0A7E1C83E7E23027 -:10A20000FE54D4CBD1AE0113F26F03ECD3A00A6B92 -:10A2100050068E627F0D2EE609A0A8E8D1EFDBB4D0 -:10A22000F3CBAD3E13C9BBADBD5210F76989267F94 -:10A23000561AEA2796E6A0732EB15EFE33C79B98A6 -:10A240003B3EFCDCD8FB971C7EAE4CEDFBB7C4124A -:10A250001FF61B9997EC802D7621971492537FDE81 -:10A26000E6A47D0FFD40FD3F07B328AFE9EB450AAB -:10A270000B2980F745B3BCEF21DD507E8722E477C0 -:10A28000787EF03C9AF571FD02F23C34DCF9B83886 -:10A29000A7C6F3DDF0F60D6C80DAE139AFAE5F6D85 -:10A2A0001FC09AC6AA00F75DB7DB3C68BF34025FE7 -:10A2B00037970DF1E13231158D0F1B849FB771C9AE -:10A2C00047B41F68EC911CE8DF5DE6E17CB80CF652 -:10A2D00049E6D197AE5BD60D7C1806F748EB785C63 -:10A2E000AE7E1D0FE6FF49FECCEB72F5EB579BBF30 -:10A2F000E6171F9C67AFC4D757C4BC22F79791FEDF -:10A300006C6D7F78A572EDA6087CDCF4BF8C8F9114 -:10A31000E4DADCDC91E49AFEBCE01BCBB5C87383C5 -:10A320005CEE07C773033CD7FD9F9E1B7CA276247F -:10A330001A480F7A75E7A968A7E338EDDB65B20F15 -:10A34000A6C8FC1CBADE6E263F6DE4796BA33A45C5 -:10A350009C2FF6FDF66AD49FFB8D0CF5FA12DB629A -:10A360003ACF6C949F3139D461CE19954364BF7F45 -:10A37000D3F3F775B983E7EF5978FEFEAAEDF378CA -:10A380007F185DAB4AC0D02FA1389661E5F62382D5 -:10A390004FA245FC844509306758FB91DAFD34979C -:10A3A000DBCBAF8A381AB789B5637CC6C3F6682F92 -:10A3B000EE4BDC061EE7D392EDDB8E72D2A2723C2E -:10A3C0003FFEC22DCC00F37FDCD84DF224506FF35A -:10A3D000A05CD4FC305AFF56B15FBD52FE3F30C87E -:10A3E000779CFF07F3FF2479F06FDA78DFF49C6C39 -:10A3F00033E046B74E189D87BD81E73B5997F2F38E -:10A4000048FD8CC4D76FE7FADECC25B9E01D4DE7D7 -:10A41000FE572877A2CB073E467F0FDB6F5671DFD2 -:10A42000817E0FD2971B92B91E533C158867B0F7F7 -:10A430002A304EEA03FCEFD523DB87A706E513B7E6 -:10A440000F4F8D289FFE3EFBF04799BED3C867276C -:10A450002ABDF9A83FD7DA017EDCF73DC5E36BB62C -:10A4600059397F6E93385FB2E678CD7F42F30A3C6C -:10A47000CBCFC723F98AE5E9F96A30FF4F96ABB62F -:10A480004138FE97E5EA92FF8A413FE8C8FD04881B -:10A490006E15557D84B7819725B633CC3FDDD8C77F -:10A4A000E3D4D205BCDAF70BC2DE5D94E7CDC07809 -:10A4B000AF4FDFB358582C9842C8636897F96C7453 -:10A4C0003ED0D0CDE3481A56323A0F6E40FF6709AE -:10A4D000FA05EB18DA7FCFA9FEC2BCF1789E610BBA -:10A4E000C8B1E8379FC1D0EE3BFB1ECF37A8FE12A4 -:10A4F0002C6F5CD9AF3B87A8F8EAF335E8D7007832 -:10A50000C94FE042BF4D189D66E7F1F84B2DBD29BC -:10A51000027EF4E313FF77CB41B417A3D53E3A177D -:10A5200068D8CF8DB80AD94BFE7B76571C433E6A5C -:10A53000D85F39F635AA6F1D8BF66EC5EF6B1DE837 -:10A54000A7F8F45A17C51F64C8FD4BD1DE3A92ED47 -:10A550009F84F8B09707A7A2BD9A09F62ADABF9F91 -:10A56000EE9B3A16E1D6E4DF26F47F43BF9BEC7AFC -:10A57000FF36B378B3EE47FFF7CE24DA3FEE4BF168 -:10A580007F1BE7BFC9CAE10D6CB4F2F52AFCDE916E -:10A59000EB5F5BF749B281C649BACD42E7D49A5C1A -:10A5A000D864647E4BCE903C1927E2E9001F3C9EA4 -:10A5B000AFB78EC78188BCCDA58F6B3C9D33791C0E -:10A5C000C2332E4FA1760B2D0312FAE1178AF3F94D -:10A5D0001B449C85166775C6E15B80F8602B6B8613 -:10A5E000CEE5B3B1BD83F3BF889F89BEC8EDE86CEB -:10A5F0008789F8C6DECEF8B912F00DD267E240DFE7 -:10A60000A458984F6E676822E2F3958B06C2875272 -:10A61000F7069DA7C422D9A09F9C0DFDEB0AD09FF1 -:10A62000E278F75AA48BDAE1A842D43DA7FAEEC942 -:10A63000A375DE5488FBCBAADF1879BCE0CBD164CC -:10A640000774662CA378C1B3EF03BF665DAA0FB48D -:10A6500034C056537C6076CF3BE4D7B7EF97868DF6 -:10A66000FB7C38CFC6E36F027D1487C626BA081F6D -:10A67000CACBBF0FA0FDA1AC53C893D166F41AACEE -:10A6800048D7558CFCF0799D0E03D22553C49D9C70 -:10A690007BE5BF47FB69BFA2F9F1833C4EC8D8BF39 -:10A6A00006F75FCAAAFEEB6005B3FAFD4E4303FA54 -:10A6B0003D8D030DE43779399AFCA3993D39ABBF41 -:10A6C00005F9CC76079350FEBC785726F27500E664 -:10A6D0009937CC3C9BF38CB45E9497A30DA8B794A8 -:10A6E0008D8CE21415676215C1FD28E4A19FE582F7 -:10A6F0006FB4F34900D78DFA68519E7F37D23B5A29 -:10A70000C801D61C45FE44BBC2FD1EF6E6F79F5DA0 -:10A7100005F91DC21F7BF895E219E4BF5BA7484805 -:10A72000870BCEB9990EF8FE8B3C6E8FD8953EE61E -:10A73000B085E3FF30C56566BFCCE3D61423E713CD -:10A74000659DAB0BFD835FA4F929FEF4DAB6904C4E -:10A75000E75B8E138FD4A861FB9BCD5C8F34ECE557 -:10A76000FBEAC8FDCCE5F4C7B13CBD5D3E98FF27D0 -:10A77000D925EF0C8EFF77EE53987E7F17699F44A3 -:10A78000EEE72EB1BF23FA1BC94ED1E23CAA86C622 -:10A79000217E78D5AED941015D1C4C958D8FCB2C97 -:10A7A000FAFE9F12F13B5A5C4C62ABBA0AE3CF0748 -:10A7B000EE63E46FD3E276B4389D4015DF47040CB6 -:10A7C00020F7B2F07CA883E27352594892683FD0D8 -:10A7D000CFB07D12C6E940FBFEBC6C827F3BF3B478 -:10A7E000CB24175509E1B7627C473CC21DDCB20897 -:10A7F000C7BBC946E35931BE239EF611B48E537CC4 -:10A800003CAE73D2121E0F9A02FA17F329B99C2F8D -:10A81000ADB34D14E7A9C56D68F11D1A5EAA04BE5B -:10A82000530A1665E17E418B03D914157CCA2A634D -:10A83000FC8790FB4B0D24F7B5F8BACE3C3588FC6D -:10A840007E0EE3406D571EEF11895F2DEEE3FA7423 -:10A850007F72FE788AFB203DAAC56B68FC1246C752 -:10A860008015C6DFFA32B7DFAB969808FE734BA7A8 -:10A87000917FF1DC5203C37554D56BE6FC1731DED2 -:10A88000D6D92616C27E95A015E5A7C60797B35F51 -:10A8900081AE85E8BF3DDCB237E704ACF9232DDD9E -:10A8A000949EB34ADDF2184C07E6A0A41AFD64C6D4 -:10A8B0004CE56A8C6319C8908075CAF6E6CEA27C16 -:10A8C000C2C007989FF6E4AC590AE8897379033B44 -:10A8D00024A8EF2FF87026E5912753189BF0C46F3A -:10A8E000660668DEDC1F3549F8A3CC4EFFB5F909D2 -:10A8F000785FA07F4D1FF97D78DC3FC605223DDCE7 -:10A900003613D9376E118FC9AA457C269ECC40BE1E -:10A9100035792C9D67DB98BABF0FCBD3CC5CDF3386 -:10A92000CECFAD79DC5F4C2A1265679AE65FEA0FFD -:10A93000A0BC6ACD7252FB41B9BADF1CE47E2E3E48 -:10A94000FE5B074AE91C4A8B3365CC913EAB94E22F -:10A950005174F987ADFC5C94298E74B41F5A8DC272 -:10A960004E15F9A834FF77F3C3ECA4B726FF4B09C3 -:10A97000AE8733077F948B72EA0613D8F1C3C8A55C -:10A98000D4422E97CE196DED12D86D6FA4FAE7233D -:10A99000BE8E47CF99E28479CD8EAF343911DEC0B7 -:10A9A0005332CAC904416FE72C0E9FB3DA272D84B6 -:10A9B0007E5BADB09EA17D825FF192BDEE9F25DDF5 -:10A9C0000470B74AC27E676A2CD9ED856A2C9EFB5B -:10A9D0002D6B7E87E2AE652107642107DE6EE9CF2D -:10A9E00055F240E5766F94D1DE7E479C3FBF93C51C -:10A9F000EEA81B66FFBB299FDB873364B514F9C83B -:10AA000075FFC4776A812F64932748F44BB7ABC8AE -:10AA1000EF87EC15EE7EE847CABCAF1CE3965BD32C -:10AA2000EF2BC7B81339CEE3F685E537E5733EAEB5 -:10AA3000C67A88B7E8A672D463FFB0FE62A1BF925F -:10AA4000BFBFBFC17ECC1CAE6596810C05D6A7C723 -:10AA5000EDDF8A74BB30F7433A8FFD41CA5B1F605C -:10AA6000FCC45BC68E49312887B224C1B7DC5E3B8B -:10AA70005AA0F93D79DCFBD162EEF70439C4E32B2F -:10AA80004BF93D9BDA598CD673AD88BB98E2E0F761 -:10AA900096A69467795A616AD3D98082727ACA710C -:10AAA0005F0CD28FCDF297FB4A47B6C398DBA886DE -:10AAB000CB95A96A581EFEDE58A8CF7FDBA3CF7FB7 -:10AAC00067C25F0BC2F31BDDDEE771DE2F493C8EF0 -:10AAD00033703573D03C5D5200EDA5E2E753BA8484 -:10AAE0007F97E20D7F26F673CF4F60549EB8D7B2A2 -:10AAF00013EF1F687E72599417BB9925338EF0416E -:10AB00007A764012718B2E3A0B6207EF7670FC4119 -:10AB10005D13F47370AE4AEB38D16660D7E15A2FFB -:10AB2000B790FDA4AD8B562BF037E0B122D512853E -:10AB3000FCDE6AF46CC6BEE428B38A7AB532C6423B -:10AB40007DCB3F56482FADB29A29F4F5F08351944E -:10AB5000AF50980FE33500C45998BE65F4049B705C -:10AB6000BE500FE7DBEA6424AFE40A13E969E89713 -:10AB7000E87A78A321C868FE950AC5630A98B57576 -:10AB80000723D1F7C7C4BA960D2C44722CC5427264 -:10AB9000EC08F48FFD1E7E5DEE223F5BA17A3B96B2 -:10ABA0009FB714D0FD9CC6C17B478A01812B1476C8 -:10ABB00094B397DF0FD3D6B3265F22D73348C15C57 -:10ABC0005722E320AAF80F4C2311F53E237B5E3B6E -:10ABD0003F4CB768E58A17C7491EACCFEF67258A97 -:10ABE0007C6A4116AD37A8123294A1FDF1CBBF208B -:10ABF000DF6AF261C7DA1F937CB814FF85DFA7FC18 -:10AC000034BB83E3BF200DD7A11C559086FAAED587 -:10AC1000E9517D61F9425846B3E3103F500FF233DA -:10AC20006B3ECC55C2FC83A9052A094BA8E78D07CA -:10AC3000380E5BD5345CAFC38C5BCFC78DFEC78E3F -:10AC4000EB8671A1DE613B8C0BF5765BCD2143CCAD -:10AC500070E34F5071BCCB8D0BE824A44E137806E3 -:10AC6000BE08A05FEAB0DD40FC394DC4EF1E4EE0E7 -:10AC7000E3B1427D7C4D6E148C4FFE587D3CCD0D72 -:10AC8000D2B636D4CB8F596376223FFE52F0C9D16B -:10AC9000E81FE7A25DF5CB39F94750AE4C895DD589 -:10ACA000864C328D7593BCD1E4DE85E40F2B300FDA -:10ACB000F2EF9A02A0FB0FB2DF9A839D1F713E96BE -:10ACC0008BFA0FE4C3B70A122E855FE3470D6EE4DB -:10ACD000435C07837C1801BFC6476C7A3705206E3A -:10ACE00007BB1453CD4E65AC89C789ABE943F30369 -:10ACF000269E6269E2F3581520B86F703E42F168F3 -:10AD0000D78EF2FB10DED9633ECB50B0B27B6E0122 -:10AD1000EEC300DEBAFF9FF046DAE5978B97D6E0E8 -:10AD20008A5CC7DAF8D28CBD142FDD38CB46F1D35C -:10AD30009344DC69E31203C511C1FE8DECFE066687 -:10AD400009A21CBE46D8D15A1CFF8B12F77F060EF3 -:10AD500098D53D61F6F8A571D42AC5690756F278F1 -:10AD6000EB417BBB9EDBDB837A4DDC1BE81CCB65B8 -:10AD700079E7DD2AC553BC24F1FA81B98CDBEB7588 -:10AD8000A27CA143C45BC05C1287E2D93BBB18F133 -:10AD90007FA73D9BCA5364AE7FD8B7B8FEE9CCE22B -:10ADA000F664E7ADF9540EFB825188F7F932D8CF3B -:10ADB000FCFC9EEF0FF2F878917EDA4D05DC2E1B3D -:10ADC000B473443ED22FBB2BD3BF05F965618937DD -:10ADD0004302BE9A6FE27E57E0BB6D7867A6863568 -:10ADE000ED5672F0FE45D3BB861CE2BBC789EF8AE5 -:10ADF00081EF72747C172C18CFE52F0A538DEF0664 -:10AE0000F9AD30325ECEFF148EDBE9ECFE7D03EE51 -:10AE10002B7ACD44072DEE31729D87C173C2C8E1F4 -:10AE200071C932C1B36F3878AE84FFC3F92D89710F -:10AE30003E1F691D24292C602F1B5A071BDDFE10A5 -:10AE4000C23FB81ED6F07DE42570CB36E28B9B6FF7 -:10AE50009539BF46737D8EE74DC9307E9D18FFE65C -:10AE600075BE6A27D6AB93080F75BDF51417C6AA31 -:10AE7000F9B99107FE203CAD42CE69E75BB345FBD3 -:10AE8000998E3A23FAE366D5EACF9966DBF839D68C -:10AE9000CDB38C1F85DB3DB3D986CF308E71369E06 -:10AEA0004369F5818FDE2F183C872AC073A823C21F -:10AEB000CF720EF81AF9FEB584C5DBEE06BE2BF88C -:10AEC000694919FAE326272EDDBD11F24F6E2DA236 -:10AED000FC6B89B7DDF31696EFC8A77CB541223E1F -:10AEE0003D57CFDB1756DC3A2D2B06E5BFE817D7C9 -:10AEF00013EED7A3FC9D7550CF3D3ABB0CE34BAB93 -:10AF000085DFE0DCDD8CCA6F1C63E721BB8B55F26B -:10AF1000FB554789F2EFF17EDF18FBBB328C33AE75 -:10AF2000CE1E9883FCFD46D94B45983F227D36675F -:10AF3000B873AFE24229340AF0521DC7EBD7963DF1 -:10AF400095827E98EA2A9E2FF654AECBC172C3F941 -:10AF500039C3DDFF8D12FB9EC1FB6C625D3FEFFDCF -:10AF600090EEAFF92C9207A7E89BF021F91D984DC0 -:10AF700072A0EBCCE7CD52D0CF3DC9CBE350AB2C88 -:10AF8000AB92517E4DF79BCA319ED861197B04E389 -:10AF90000C6227548E47BA4EB230A22BF0794C2166 -:10AFA000FAB5AFFA2C230699CBA6E7738D8FEA3456 -:10AFB000FEAED6F331AC4F57E1F8CBCBDB91F818AE -:10AFC000C6CFC0F6B3BFA5D73783FD45ACB7C8FE23 -:10AFD000479203F8132E1787E0E8A6759586D17D72 -:10AFE00039B8EE3AB4753706E13019FAE81E4FA6C3 -:10AFF000E429A20BAD133C16D24711706BF0A58368 -:10B000006C636597C2853F8A662F72081C8E441C4C -:10B010009797433B2F8B1B820BC6BF1EE9C0D67090 -:10B0200078B64B4D5C6E88FD81E6CF68D0E6DBA339 -:10B030009F6F4514BFD7EE46BF13B6738D2DFA3AF6 -:10B04000B81B853E9D65F13D688639DCE49C4FFC6C -:10B05000700B683427CCFF6FA9FE3AC447AB147855 -:10B06000B93F8BFCF114FF01F49E5118660768701C -:10B0700045E2A3610479180977241E86E8D3978CEA -:10B08000A9761F6E705E11F369B5F3F53A30DECC28 -:10B09000DFB550C01485FC9B5211C5A16870BD2955 -:10B0A00071BF6440E2F78F347B2212BEC87B7A1AEC -:10B0B0005CE8EFE3700CACC23B820F166A7E3E4E3A -:10B0C000AF24019FC9200D7B1EFE60A141F3B3EAAE -:10B0D000E819797F4DC39B16E715892F2D4EEB920A -:10B0E00073B78873E591EA4960A7A7C65D8A47ED03 -:10B0F000DC2E6ED04FC9FD4003F7DA490EC60DFABB -:10B10000298F2968DF4FF21C52D02EAFAD81090084 -:10B110000DDE147E1F0DDF0F64F8B71492DEEE1FF4 -:10B120008FFE959F4C7D82CEAB3E30703F7D247E5E -:10B13000F68C809F91F87D24F8A3D27C4FE2B8670B -:10B14000A4BE0A2CECCC16E742CC9F85EBC1E9C823 -:10B15000AA44FF11C8D7AFBEC24D2B16015DCB3339 -:10B16000FDBFC076B730DF64A46F5C8DDFC8CF4908 -:10B1700018F9E1978BFDE364A177CF6FE3F11ED55A -:10B18000DE518F4D44BBF198910569DD7B497FDE2F -:10B1900025E03F0F2A3684F59FB193FE5DFCFA7CD3 -:10B1A0008AE328D86C187A4F03FE8E0A46E9DED36C -:10B1B00028DE1BA7CB9776A7E8EA8FE9C9D6958F3B -:10B1C0000D15E9CAC71D2BD3E5C7F75DA3AB7FD526 -:10B1D000F12A5DFEEAFE69BAFADF3A354397BF7697 -:10B1E000E0BBBAFA1F0FFA0F84DD10F0F615C2BCEF -:10B1F0001788795F7F719EAEFD9F62A61C437E5CBF -:10B20000B081C7A557028674EF8B7470FBA209FE4C -:10B21000207D27B3018A076C084A9E10C3F836BD0B -:10B22000FDB1B4A78BF078B9FBF805AEB90634B917 -:10B230004F170AFBE32A76158F67FD7ABAE6B3BC8F -:10B24000BF8BAE66B79EAE56554FD7E8423D5DED1B -:10B250001E3D5D6327E8E9EAF4EAE91A5FA3A76BFC -:10B26000824F4FD7A4D97ABA26FBF5744D5DA2A7B9 -:10B270006B7A939EAE99CD7ABA6505EED4958F44DC -:10B280006F4D9EE6B42FD7D51FA4BB6F09C537E518 -:10B2900075FC50D7BF46F700FC41BA17301187F94B -:10B2A0003FA47BE1283DBD416F8D1A359EEC8D1288 -:10B2B0004C671708BBDE37BCBDA1C99F70FD1EBE21 -:10B2C000AF1D492E5DA2CFC43E77447D16B1CF7D20 -:10B2D0008F81BEA5413690DFEA56C19F87A338DE35 -:10B2E0003FC7A2ABA11ED4990070BD8770C338EFD1 -:10B2F0004515933FE2BBACDB88FDDFCEFA289DC34A -:10B300000628F53307E9EF79CC43E902E63309FF74 -:10B31000C4F45109E8B7E8AF40FD7F61EE5B1FD090 -:10B32000B9D61BF157F40EC547787E92C7D849218C -:10B330000F4EE0390AE4CF5A07F5ABEA0AC3DB49FE -:10B34000E16F9C3749223DCDE4288AEF9A778B4400 -:10B35000E744F3FE93A78B46493C1E24226D6DD62D -:10B36000F0C7F7473B47A904471AEB16F61CF3DB77 -:10B3700072A81F7EEEB1CB44FB58B785C3F7ACC4AF -:10B38000940971741D8EE8EAB670789E35320BE22E -:10B39000F369E65791180F2820A2F83D8C22E48F1C -:10B3A00079FFF95636FAE9A2A25E98557D359ECB13 -:10B3B0000456919FFC7B4CEF27BFBD49223FF9F714 -:10B3C000004E48DD0E8F1BED7C2DFFB080B71AEBD1 -:10B3D000C1F7247793847EA97F587FFB7FC8EBFD5C -:10B3E0009DFD0DF6C3385CF883F4D3FC9E85061EE4 -:10B3F00027317037DF1FEDFE1EE3FEBBE640650020 -:10B40000CF45653094308ECAC8EFC7EF1CC5FD9E8E -:10B41000C9AC8FFC0BECA866D7FA49FE9688FB17DF -:10B4200067C5B9E2A22E0BC3389D927D87E2F01C5E -:10B430007111F0601FEA61C54FEFBF946C792D8EDA -:10B44000FBFD8C4EBC57A9E9FF91F9546127C3EE6F -:10B450003100DF350D677FBC5AC4E3035A5BFA46FF -:10B46000E139A006CFFD2DC7282F2B1E86E797F8C0 -:10B470003E5478FCA3C905E561F24EB141FB303979 -:10B4800064B4F9E89195352D7D74BE6814EF58AD1C -:10B490004D5BEEF087D989874609FBC71260B84F2C -:10B4A000E02A0A53E524CAB5FF627C1F6D76433F4C -:10B4B000E1F2F362020B3F1F686F394EF0AE91FC70 -:10B4C0007EECC49CCB4256A08F59C1BBC0F07DCB53 -:10B4D0000DC7308ECB645FEE09A923E3CDEC562E69 -:10B4E00084CBD3B723E4E94F5A068A719CD6967E63 -:10B4F0000D5F0CCF6B03C9DCBE6E6DF984BE1BC043 -:10B500003E447E7B754BC12115CA3F80BFF8DE8E5D -:10B51000D9C5E162175DA457E7083E405F5C3AF089 -:10B52000CF07CD46E2B315E9363A2758F166DE215A -:10B530002FAC67134C57FE06700F8DC3F16412F2E7 -:10B5400014F8C987F2C194A2D079419C6306D1E96D -:10B55000EFED4FC3AFC9CAE89D2453BA8DEC822BDF -:10B5600085F36FA3F83B4083F6C94517C9FF150261 -:10B570002FDABB4F1FDCC3C8DFB3E25EEE375C518E -:10B58000CFE81E026B869F8A21BED1F44C02BE50CA -:10B59000031F3B5A60C541170FB55898BF00EC1008 -:10B5A0008CDBCF19A2638757716288C1C66A571DA9 -:10B5B000A60F4D38D181E2EFE1895FF4618A67041B -:10B5C00038BEA38905D13EA6B37F18DFB904F23097 -:10B5D0007E8C288FF1F37CAC288F9DCDF3E9DEE7DC -:10B5E000A46A042CE23C2BDD16373517E5F402C6BD -:10B5F000EF818B7720B60B7D916A8BABABC6F2DB0C -:10B6000019DD0BD1CA7F2ACA936D1FB5E7A01E9919 -:10B61000A56FBF45E021C9F651C7243AF7D2976B11 -:10B62000E74A09B6F3C7A87D89BEFC51D1DE6E3B5F -:10B63000DF3709CB73F5E33F28CAA36D5C1E321FC9 -:10B64000E3EF1588F20744B915CB717C0F2F97B53E -:10B65000773944BD75020E8CA923BFEB28EE77DD48 -:10B66000D1622921BAB45C24FA3CD4C2287F6B5140 -:10B670001CC909430DC7779C8BF383A3990DFB4E1F -:10B68000C1AD42AEC5A8FD5EEF30724F2B8F73F097 -:10B69000771864B789F8C96C137243ACC741B921F4 -:10B6A00035793893713FFDE5F81A16DA05B48F3213 -:10B6B000E007F93AED1E03F387C9CB946551CC1F1F -:10B6C00056DFBD204E974FBC3D4557DF352B5B57AE -:10B6D0006E2B2FD295B35971B46E960BFE8A2A2920 -:10B6E000D3956BEF43B0DDA29E58BFC6DC6B74F5FB -:10B6F000CE17AAB1C8E327A782FEA178068F05E579 -:10B70000C3727B7612EA9FA75B2610729E85750531 -:10B71000462B7BC6C9E3DC9FC1F34328FF598B97B7 -:10B72000BEEF817215D25DB0EE54A8DFD5E2A0FC69 -:10B73000E32D6E4AB7B7A894FEB4A590CAB7B47803 -:10B7400028FF18F48FE9A3D00F7E7FA4A586F21BF3 -:10B750005B7C947FB86536E51F6CF153FA40CB12E1 -:10B76000FABEAEA589F26B5B9A29BDBF2540696B15 -:10B770004B3B6F57C4F5CC33E25EED3395FCBE7C9A -:10B78000241D3B8B841F52C4ADD887E2563A8B30C0 -:10B790006EA5BB9FEC702D6E05E74DFD59F9FC239E -:10B7A000FB7BAA88DB6F45AC6F55345FCF743E9C42 -:10B7B000D7E3591D0D7C9FDAC4E990D53340E5C924 -:10B7C0004B382D9E12FCC95C01965641510254EF34 -:10B7D000ACD45715CDCFD529CE91B9619E15E2FDD8 -:10B7E0002662BBA001E1522670FDA9D17570DE4E24 -:10B7F0000E27CE7F3878F70B78E5F26EFE2E4B4D94 -:10B800004708D93ECADB44EFB25866FB420AA42E71 -:10B810009F9FDE8928BA38053667206F2E5EC75491 -:10B8200048D396E9F76D290BCA74FB22F9E2434C21 -:10B830000539602BD1EFAFA27297EBDA59D27EA80F -:10B840002B37B956EBCAE7DD95B5C68DF84CE5E761 -:10B850004BE60DAB5832C0B5B07323C1F59198C714 -:10B860005949A5FBE5817D5ABC05DF5F3C29F40BF6 -:10B87000B36C207BACC0C9B3F9B10103EA874FFFB9 -:10B880003596E4D2138F1B82E84706F164C0F55F5A -:10B890000C661F9697B27ECA63A80CE6C73255C6DF -:10B8A000FC383640FB2BD85FBC5F8471ABB2FF71B4 -:10B8B0002BE4CFA4FB9FE4717321D29FF9829EF900 -:10B8C000DA7E6AB312E95FEE2F22FF8DFE7E5D9B6A -:10B8D000D85FB459B99F6E95B32209EDD6B323C48E -:10B8E00039DADDAF1E5D00F8B6271FA274D02FA78E -:10B8F0001A86BD3FFE4504FF8F026617FCFF05F266 -:10B90000FF99F2B713D10DD5903B40EBE0ACE47555 -:10B91000CF45FCBE2E737E841D17CE4F11F855F611 -:10B9200055BAE7021E9537733C013634CE132DC746 -:10B9300073300E41CBE78B38DDBD2DC9B9D561DF42 -:10B94000D5624EC742D65783FAAAB0C4E00962C78F -:10B950005E87CE8F61CDEDF0E27B084A19F3A098A7 -:10B960001BC53A56A3EE56FE26539C9572F86AA65E -:10B97000C27EC6660B318C4BD3FA65C21F728F90A4 -:10B980009B5F38AA63E99DCB9441F9873A927D6128 -:10B99000F3F6211F7DD169E4F33AAC2F2FB471BFC8 -:10B9A000E1A242535095F05DB50E7AC751D921B14D -:10B9B000B42C846312E1811D8C263E8CDE3C9A05FA -:10B9C00060BD943BFD9662F4DB85D483861CC193F5 -:10B9D00050AFBED8B413EDB302C48B0DF1726B6ED1 -:10B9E000350E9D5B48F85D28E63DBE98D3AB2D3DF6 -:10B9F000021EE6F1E27BA78B3A353F8E7E9E0F96C4 -:10BA0000577D07DF856CED93B95A8BC0E77A63DF0A -:10BA1000E8B9D0F5997E804B2638C717A30DBAB97F -:10BA20008205488FF3F9D53F2EB1AD5924976A4866 -:10BA30008F8F37B0F0F3532D9D58CCE5EFB1221E18 -:10BA4000876A771F257E1CCA1F39BA00F0F1B481BE -:10BA500015D2B9B181EF8FB5781D19FD0078AFA16E -:10BA600058C845D6C6A6A1DE761A28FE54EE8AA28C -:10BA70007BB3B253A1B8F7365BB5E34EECC7A1D0A8 -:10BA800039D11479621FDAD166A7611CDAE14776F1 -:10BA9000FEB00FE386E47485A1DFABCDA1703B243B -:10BAA000CD40F1808AB3DA82E74AF9B6139588CFA0 -:10BAB000435D3FA07722E4EF8B981DE117330A9294 -:10BAC000B5B126EA3F90A688F766BCB56313C59169 -:10BAD000888AFBA19A4F70BF7DC471DE8AFB02D5B4 -:10BAE000B688FC81F715F37DA211CF0F21FFF8CAAC -:10BAF000F34E945FAF77AD89CB427B3AA8902D523D -:10BB0000F8D7D6147A0FA1CB44EF356878CD0C283E -:10BB1000BA73C8F4667DDE1C711E698CB827B75CE9 -:10BB20008C8F2797A1B0F918DD7CFFC65C36DAFF51 -:10BB3000DC572CDEE914F97B447EAF3190E201FC46 -:10BB40001CEE5A9489F3BAF0829FE2CE47B2FF27E7 -:10BB500015AB62BC80D540EF0287AC1887BEBB85B1 -:10BB600079D0CEB30415BA07B047C8B35C1BE7FF62 -:10BB70003B4AF87A8D4C733BF8BA539E890A4623A8 -:10BB8000DD1CDD650158E7C5AF4E652AE8C15C875D -:10BB9000D780FEF7DC669307EDCF29BFB0119F9CDD -:10BBA000B7F1382EA5F90115BFB7EEAC2854C3E0A4 -:10BBB0000EB6383C289F76B6583C181B1F1C41BE59 -:10BBC000E6380D143FAF1A783CE72EB11E7715F317 -:10BBD000F788760A39B34B09CC403877013D316E8E -:10BBE000FFD0066E1F2F5F65213896BF9E43F6D5A6 -:10BBF00048787BA2C5EDC94578361852D05F55B953 -:10BC00002E773DBEDFB1DCCEDF3796638B1EC3AB34 -:10BC100011ECD74686F67C6BCC359EF961F25D8ED1 -:10BC20009D58887C25CB8114F4E7F43C7DE1268C7B -:10BC3000E705FA6DC57CA8F8839B307E77AF3D9011 -:10BC400082F1BDC78A3FE2E50981AD18DFDB577C91 -:10BC50009297A707520C903F5E7C9A97E705B662D1 -:10BC6000BEBFF82CCFE3D91BC8CE53C5E76F0AA0DF -:10BC7000BFC5E4598202F9E7007F092CB16E919E9D -:10BC80001678D1CA9FC3EFB001DB2FD2C8F283A2CE -:10BC90005DCF08E52F8AF2DE11FA7F45B40B8DD017 -:10BCA000FEB068776484F64745BB632394FF4A94EB -:10BCB000BF3142FFFF2EDAF58DD0FE6DD1EEDD11E2 -:10BCC000DAFF56B43B3E42F9FBA2FC3F22FAFF40AA -:10BCD000D4EF17DFB3ED1BDE47FF7D36C811944B61 -:10BCE00085F60D71B8CE77B69713FFB756F0732A65 -:10BCF0008DDFB32546EF0EDF56C2DF3BBBAD84CBF5 -:10BD000071A584F339F0E1C3C877CBDF94299EA8ED -:10BD1000D5E039154439BADE40F6C0F2D7F97E7D58 -:10BD2000F93A25187E1F486BAFC1BF06E103C66D07 -:10BD3000C314D6DB97C5FC9CD1EC767B6AC3E4992F -:10BD4000D1A1CF83BC602877417E53DC78E1BAAAC9 -:10BD5000F6C2723CEB339005A2D45B42F88E886247 -:10BD6000177AC151DE5188F0D9147A3F4193F3CC50 -:10BD7000E6D6F935DA6C0ABD2727DB79F9945F4CF2 -:10BD800074A09DD5C6FC7D5E6CEF56C88E3FD45E18 -:10BD9000E640B967B22F70E0FAFDB894E3BDBAA1EE -:10BDA000300AE5B5FCA081E4F711075FEF3BDC3C0E -:10BDB000CE0AF40ADDAF0279ED411D51C042AB500D -:10BDC0006EEE7DE8E05CEEE763F6B115747F493B0B -:10BDD000579794B07D406D09C74FA6D0230AEA1744 -:10BDE0004877958B7B3701EE8FCA54983B35ECFE34 -:10BDF000706D89CCEF3D69E7A1722DBDAB95B15255 -:10BE0000D19D23A4DDA3CF9B22F48612A15772DA21 -:10BE1000414EEACE4F1CBAFCB74A849FC7C33C6868 -:10BE2000C74EF9C5069287E751BF4923CBBD41F9FB -:10BE30002BE4F12E4400CAD100BFDF7E6843D9AFA6 -:10BE400090DECBD719E83DEB2B95A30AE218F090D2 -:10BE5000E797482FC0845270DF74393CE4197D7134 -:10BE6000F4DEC765F091F768791CCADB3CBF42FD80 -:10BE70005FA2372E83AF6725CF713FD2D11925EC52 -:10BE80006A6000F4DBC54575E1F9BE49F853B43882 -:10BE9000652549E1EFF58B7BB2B2E0E3FB99578D65 -:10BEA000CBC1F78A9AC8BFBF62DF3D6EB4DBD71A39 -:10BEB000FC0ECC1F8B9B3680E32C874D3FE26F2F0F -:10BEC000F641EF72BE7D33FA4DBA8326ED5DCD109B -:10BED000FEB30FE38FB4773BDD64AF897CD5CDD55E -:10BEE00030DF6EC5518C266847C9E44D46B049F72E -:10BEF00099D8607DBCEFF7F41183E8EFC64DD520EB -:10BF000097F64531DDBBA5FBD0CF4EF9E99BF09DFF -:10BF10005218EF4619F6663B9F99B5C976F5103C65 -:10BF2000BB9FFDEEA655E8B013FB1427E3EFCD9FB2 -:10BF300051FB6390B4B05F595F82FBF5AE1389E1AA -:10BF4000FB75AD7EACA8DFD03BD0F08C4AF53B4A08 -:10BF5000801FEA7B06624A08DF0315E1F563841F50 -:10BF600020ACFEA6AFAB5FA8C1F3CCDB3797F0FAED -:10BF7000DBB0FE59B53F91627A22E089BFB4FF9DE4 -:10BF800004FF08FD1789FA67426F53FDB3AC3FB158 -:10BF9000348BDA3D85E39C7BE3ED0A31EF443CC70B -:10BFA00079D7E6FD197E6FC13E707FA734A9F8BD31 -:10BFB000DBD2E140FBCD6AECF0A11CCEC5F7C72671 -:10BFC0000CA5CFA2F2187FE9F7487EEEB6B0F85A7A -:10BFD000E4D76603ED6F7AFA0D0F205FEE489BE819 -:10BFE000C0FDF33E535F5909DAAF076C64BF1A32E4 -:10BFF0003FB5A2DFDC5CC0D7BFD5D9E42981BC3511 -:10C00000BD84DE0F95EF5DDE4DEF98DFC7DFF752A1 -:10C010007E6CF2EF46FE0A2D2F5C18B6BE7797F2C3 -:10C020007B96EB5EB36DC0FDC13AA3A7A300ED7094 -:10C03000BB42719FCA8F0F4E23FBF0E70646F21FEB -:10C04000E65905FDB6CD55E8F7300C94CEEB2B2123 -:10C050007CF87C55502F234191F07ED0FD8ACF8211 -:10C06000E71D6661D7EDF0F0FB61DAB81784FD7962 -:10C07000A184BFB7B623EDC27B8B5DF8FE8389EE4A -:10C0800075DA961942A618BCE7B6F3D462A46774B1 -:10C09000FF3ABCE71C95A238707E3FAD85323A97D7 -:10C0A000EBA6EF817A03ED1BE29719BCE87F8CCAFF -:10C0B00035E9FC1D361827DC1F1233DAFF47A4E7E9 -:10C0C000B837951B11CFEEBB0DF43EEA83EE772D0A -:10C0D000068033A65CDFDE3151DF3EAE5A5FEEAA4A -:10C0E000D59727CED297BB6F3745F875F4F9268DD3 -:10C0F000AF4026D8404F45F1221665BBD082FB9E4B -:10C10000B5AF4531A2CFCA4D1D05B83EA307085FA4 -:10C11000514551E417589B6C22B9BEB694FBF50FFC -:10C12000A79B6EA43CCC0BF96347DA51DA8F5C8293 -:10C1300017DBA9BF62FF3616F61DFDF2A3BD9652AE -:10C140001E57C3DC15E8C763240F9F95BC9E438828 -:10C15000EFB7B8BF624733F7633F388BC741D20CA4 -:10C160002A70BDF3FA31960D7DB82F8BB1B5DF8DF6 -:10C17000F19D91784D14E70D3BF0762FF29D9FBF16 -:10C180001BBD46BB6785DF2BE8D604BD8B366BB481 -:10C1900078EF4FD809B1EEF892B6B0FB1A89C26FAA -:10C1A000F2F0C47956D41FFBC43B2283FDA9342886 -:10C1B0000F79457F54A9E6AFE1ED3769E73C229F4F -:10C1C000E0E4F97D47E26EC4F5B569565C19EEF717 -:10C1D000D70AFB2E36CDE41D05F37AE49829208D8D -:10C1E00081BCC28E18C12ED817C7C735BD1E15C059 -:10C1F0007B818FB8CBE99E61AD80FBB94ACF3BB85C -:10C20000DE07601DED84FE1F7179AC65E2DC340051 -:10C21000F051A8159828876ACB68BFFB88D763457B -:10C22000BDF9489AC78A71DAD664C581716B716E9F -:10C2300085DE897BC4E277A0FD13078AD484E749B1 -:10C24000E91D53E97E1DE0DA50C18F1A98886FC44A -:10C25000F8C27881CF1DEE050E7C97C195BBFF5FBC -:10C26000D04F1F8FFDC5F0768827A7C0D3AC52955D -:10C27000E07689FEE3173C47F5F1A7AD22AC3F41DC -:10C2800047D35416C47D9A36BED6CF60FFCC4BE759 -:10C29000006B7EC5F1B62A9DBF8F65BA8BD17EEE4D -:10C2A000B94AFF5EE4B381E428927729EE942AE448 -:10C2B000A394635B67E0BD8B35BF8AE2E32CE4FCAB -:10C2C0009EA230CB7538EF04BF03F118B95E938F8F -:10C2D00074D421536A74895CBFC90A6B97E32E5DDD -:10C2E000C7C96E5755FEE861D673C47A493E36F029 -:10C2F0007DEC3F725D6F8FFE602CD72361DFE5CB55 -:10C30000E7DBA4FE75248793155A67E911E3E13B47 -:10C310007B98979841C5B8E8DDA54EC1C7A0974A5C -:10C3200091EF1D936CFCBC9DF8ABEAF90DDFFD3578 -:10C33000E42FE0EFF3815AA9C73AFA482FF6F80B39 -:10C34000B0FE36C5FF38FAD3B71D4FA2F72BCDD1BB -:10C35000FCFD5153C47B299ABED85DCAFD486AC40E -:10C36000BB9BDF34ED4E4B2B7678B0BFB77F6B496C -:10C37000F8C7DB3F6947BA57D9604D3F5372F32680 -:10C38000BCFF6C7D93973F0DF980827859467E976C -:10C39000C31977D2FC5BDF33933FAB54F66CC63CDA -:10C3A000FBBD95FC717B0F4C9C8DEBA4D55EA1A2CF -:10C3B000BD7F40ACE37F1569E4BC6493C78FF64052 -:10C3C000E4F7674B35FF9BE77817D0B7749789DEA2 -:10C3D000711A8C8FE8B2F2785461872E10F26CC11A -:10C3E000C1F5198718BEC351F75A29B45F60AF4E23 -:10C3F0004478522F4ACC0FF26F9B389F4D753D27E2 -:10C40000A19C49731DA944799FCEFA56A1DC486FBF -:10C41000D29F97A55E54A8DDBE142FF5873F18075D -:10C420006A62624DC7F9D92A94F329FCBCC5E48835 -:10C43000E271A1EE6ADD3D6AED7DDBB7851C350159 -:10C440004E8D6590DA147E6F3FA2FEEF443D19FDDC -:10C45000F6E8FC771C3D4EFDDA944FC3E34D715F67 -:10C460004A426B193FFF043C05701FCA62E3F8792A -:10C47000A9D7AB86C7DFA682DC359761FC4980E28D -:10C480004492C5BD082DAE0730E044BF9B16F7B1FE -:10C4900093E9ED112DD5F6E7B9CD32ED3B8A5FB5C5 -:10C4A000F2FD413B0B5A25F48731923BB91BF8F959 -:10C4B000B4E617BB0D1713EA257C0F97C6EBA63819 -:10C4C0006ACDAE02FA92DC5917F1CE94F68EB661BF -:10C4D00034E78B6D2D0EA2A3569EE68FA4A3FE9C7F -:10C4E00053AB977A3195F9E3C3FB0D527FA9CDFB8E -:10C4F000891F522F6650F9B616F532FD678FD07F2F -:10C5000032F1CBC8FDA751F9F6D0BBCEE9808A9FA6 -:10C510000EEC77FA54942BA1A99E61F09C7A8F5E61 -:10C520004E8EE9D1CB5D0D2FDB14AFAB0EF0BDED20 -:10C530001E83A78B61FCA9BE5E4DD66F9CFC5D6B14 -:10C54000AD7EC83513EB2FE3F5BF754A5FDF577932 -:10C5500020B23EC177FD457DBD48FA44C20B70252F -:10C56000DC1406D7248BFEF7DACD9E7B095C09B775 -:10C5700084C175835B5FDFBF6A78B86E2C347F2D12 -:10C580005C5ABDEF4CB8B27A91F39859631E01EF33 -:10C59000BCFE2DB3AFACDFDB967C7DBD3B9A23C7E1 -:10C5A000096871DB3A7B24BE99DBEF0E36407126B9 -:10C5B0009ADD11C71C22FE8BDB0DEFE07F93197B08 -:10C5C00060B46FCEE804C4BFF7F64755BC1FC3F58F -:10C5D00015ABE5EF56C2BEA434FC5DEE21B8565350 -:10C5E000BF2F61BC13E9598B07EDCEE25466494673 -:10C5F000E3CB1DCCC6F7C7EA476BF29AC79717097A -:10C60000DC3D9BD2BDDC49EB3C1887F07CD371EF5D -:10C610001DEDBD67F4F8A1FA23F95B343C994CDDBC -:10C62000F47B1D06EA6D1ED40FEF6211B4DB75B307 -:10C63000398476B516877A3C7ACED10495DE3D589A -:10C640008DFDCFBE65EA1ACC4B87E3D5E536BC3706 -:10C65000D5AFDD2F5D83785B66F167261AE87CB580 -:10C6600000F7C3CC172F2E23FB4A878BD3D0E0A92A -:10C670009638FEA3D2FC0FE338D586BE1D3EFCA63D -:10C68000F4F17DB62381BFBB84EFEB0CB3FE353CE8 -:10C6900054897E0E193D5F0EC0FC0E6D8CA57BF893 -:10C6A0000BE26F99836FB22C34F812F1003D0CEE5F -:10C6B000ED04B76D6E6632C26D14705B1204DEBDA0 -:10C6C000B95F07F760BCCC7D92F67E3AE59F0F38E4 -:10C6D000E9BEBBD9F0F9BB33510F971A3C68776EAE -:10C6E00003FB02DF77FB3F02DFDBF18C258EBED33D -:10C6F000BB6F6E71EFCBBDC940EFBCF8AA5E203AAC -:10C70000ED6AB07970DF3E97A9F4EEEA7C710FE62E -:10C710000F95FFFD723FCCEFA5D1FE83388F3BE232 -:10C720000D19EF121CFE627A476BE295C5CF6AE7DE -:10C73000F033847DB050E07126F352DCEE4DCC6FC7 -:10C74000C471DF3E6BF2A25DFAB68847BE8505E88C -:10C75000FBAD2C48E96D2C44F5BF872FCA42FEADD6 -:10C76000E8D1E9CD005FDD630579B81EC3F0FE06B0 -:10C77000D219F8E50E17E7973F2621DE3B13AE8866 -:10C780007FEB248EBF0746FB7FC3D7ABEAF2204C7A -:10C790008E4969E847195C3FD5099CFF1447DED7ED -:10C7A000AD9FBEF3DA7D7FAF2DB902DFFBE23F37ED -:10C7B00078EFA278718CCB77011DFA547ECF11C42B -:10C7C000863D0074AAA994296E6FED67E27E363A21 -:10C7D00031A0DE2FC7CAF43E99762E395DF4373D7D -:10C7E0008DDF57ACAD9CD9160B7899F2657F79082F -:10C7F000D29A34FDFDC5A9AE2E7AD27C5AAEFEFB8C -:10C800008DAC830E886B4BF471E6D323FC9F87704D -:10C810006CE0AB8BA345BC64112B0ABF6FF01DD13C -:10C82000F67CEDE7A673307EC918FF57488FE5DF29 -:10C83000FEC31CDAD729ECCD7130BF867F97C99E25 -:10C84000FCA80566528071D516E60583FF24D8152D -:10C85000983FD5E2A6F434D801987EDA5248E567CD -:10C860005B3C949F35C6671903FDCE6BFF4C417D41 -:10C87000B4568BC716706871856B45FCC40AFBF211 -:10C88000E318BFB08202DE192CF68E2908FE9D3D0A -:10C89000DD473185EF32EE43566C94C8AFB3F08874 -:10C8A0007F0D9279F11BFDD3514C8CFFCD8944DC77 -:10C8B000A7D7A31D0BACBF22CE9B340658C0DBFB11 -:10C8C000E1D178A8FFC7960904DF272D5E82EF4FDC -:10C8D0002D3594D68FF1A5533DF619BDF3F4ED67D0 -:10C8E0003E54F0F7B34DF64AE4BFBFCECB8241C011 -:10C8F000EB662397EF9B41BEE3FAAC2C9DB1FD1E86 -:10C9000086F2D75F80F3BC296EFEE478F83E7DC2E4 -:10C910005C05EBDDF225E8A0AC213EBC1C5F9F79F5 -:10C920004522FC9C79C549F8D0F0542FE875E660A3 -:10C93000F177F0DDB3578EC9147F7AFEA281E03B18 -:10C940007F3C8AE25323DB2F3F909384F6D89F806D -:10C950007E78F0B1FC4031F9E3FFF4ECBFA8E1715F -:10C96000BF7F8AEBBEF03ECAA9FFCBE514D89B2758 -:10C97000B7A21C4B4BA1F77B06E3D5585334EAB161 -:10C980000693585F206730FFA728BE0FAEF8796A7C -:10C9900015AE171C0FE3BDCCE2F760407F1FFC1003 -:10C9A000FA3BB8D54DEFFD7CBAEFB16C1C7F6FF749 -:10C9B000C2F7B742FF6782FCF7609C61DD675F44A6 -:10C9C00079BADB467ECBB512C085FA744F0AE50B07 -:10C9D0002525AA999C19411E8722A90ABE7FB6EC7B -:10C9E000B92D29C85F784F1DE3EA5FDA184D72EA66 -:10C9F00025A3E78366EC6F3BEFEFC987EEFDA80741 -:10CA0000D307EBCBEE45393786C7312EF8C9D22292 -:10CA10006C0FFA9A7EDFF3D3CF4B21F48394761E0A -:10CA20005A8D714C63B67D68488174EC6EA915D33C -:10CA3000E2F469C7D07F70D71895DA8F7B264BC692 -:10CA4000D8F4A294E0FBD7F3B8119D7E2FE9FCAC9B -:10CA50000AB7999A9E2F92BA4F77E1BE38E37819B8 -:10CA6000BFDFC5DFAF3ED03BF39DDB18CE032C0804 -:10CA7000847BAE89E22E5830D085743EE32FF4D00B -:10CA8000BB2ABEC016E4AF33FE44BA5F78D010882C -:10CA9000C1DFE314F880FFBEA1E777BF1583F1146F -:10CAA000B1FB8D0C7F2F76FDD88129141F92AED259 -:10CAB0007E3C7DC70D35889F86FD07BAA89F651609 -:10CAC0000FFA63971CF89CEEBDB0A93C0EF5CC7E26 -:10CAD0009E7FA0DA4BEF9D2FE9FA33CFF7F928EFCD -:10CAE000930359747F623EB7771E13FA8CF58F66F5 -:10CAF000E1EF2169F47A008AB17C73562019DFBD19 -:10CB0000D2F420E8AF8770FDA1DB91DA3B66F27BBF -:10CB1000F257A8BF4C421F69FD3D66E2EFF4A21830 -:10CB2000C1DF8BB3CDC4F5EE1E9037C82F9ADE85DA -:10CB30007177E0BA3589FB32A9A064C7C27C521F65 -:10CB40003373F97D85E347DE67D5EC90D9F1AD7499 -:10CB50006FF5D354FFCF701CEDFE2A533CF4AEE0CA -:10CB6000EF53BD4F8F49E0EF75E01C402FFE02F3FD -:10CB70000D32D85139617694E5CAF4E2DF52BD072F -:10CB8000709C2BAD1F2987270AF857D80D8487156D -:10CB90008F9AC91F3651DC439D78FE7834CA9315AD -:10CBA0007F2E23B9D2CAD8B0F879B985C779FF1BCF -:10CBB000FA1120BDF68B7E99F623470CCB8E827E30 -:10CBC0002510C87F38D01A5B4E792F92FBBA2F0CF4 -:10CBD000C3EE17B514E8F52EC9E92FF5FE87EBBFB4 -:10CBE00074D0EFCD64B6B82B9AF7D0FB3EFAF96B50 -:10CBF000EF6CC1FCFA51BFAFF8CC40FCBBE2B332E2 -:10CC0000929BBD57385FABCB7B12E18C9C0FC0FF72 -:10CC100029D22712FE417E1FB832F8BF2F31FA7D8C -:10CC200043A0AEC8BFDD2BDE31E85D5A42EF691C80 -:10CC3000C4F748506ECEE0F78E7AC5FDE4DE0407F7 -:10CC4000BDF7F19291E703B78AF6E27DC8DE5B5348 -:10CC5000F87B1DE6A65F9762FFAD3C3EAED718A4F9 -:10CC6000DF53FBFF00D94A3097008000000000002E -:10CC70001F8B080000000000000BE57D7B7CD4C505 -:10CC8000D5F7FCF696DD64936C42C88590B0B91078 -:10CC90008206DCDCB806582041B468038802C6B8B6 -:10CCA0002101426E844BFBC4969AC500A2C51A1E90 -:10CCB00011D1A22E14282ADA50115183CF0A4269C9 -:10CCC000BDA5D5FAD86A692278E59210B40FF6E1CD -:10CCD0006DDFF99E99C9EE6F49D4F67DFAC7F379F5 -:10CCE000E347C7F9CDFD9C33E79C3967CE6CFB8FDA -:10CCF00006B9BC4EC68CD6B939A7F3197BCF67F0FD -:10CD00009AA3196BD1FCB71A0B18F35EB0B0DD69AA -:10CD10008C6D89F1272FE7F92DCBAEA2FAEF3136D2 -:10CD2000B32D07DFDD49B13C3DF837E3EDA5769E35 -:10CD3000CFE5799EBEA4B1F9543EDB9D14C3F30B3D -:10CD4000C3A346B36B787E876FF7D6387CCFA67EB9 -:10CD500086185923D54B13FDFCD12CDAFD81F1BF88 -:10CD600024C61E3533AF2D96B1F1AE45C35D858C1B -:10CD7000796E8C30B16814BA93343E9F47AA86B35B -:10CD80007B359E6D7D88B178C6E65B19FDA9F150B3 -:10CD9000D13A86B179E2335BB078B7CDC3E733AF30 -:10CDA000DAD6A58DE6EBA8BE2BD2C9C79BE731FA30 -:10CDB000C3A278859B4ADC9DD9A2EEDFD331AE9B1E -:10CDC000C66555837886A7267F25E3E3BEDC6365C9 -:10CDD000F772B8FC1D7F5302298718638319FBD4AF -:10CDE00026C6AF6F9BFAC069D51FFFB7DA62DFA80E -:10CDF00045A33CD5C7F8F8FB87780AD0FFF243D7A4 -:10CE00003D70DA1AA857B5B8248B1902E3868E1341 -:10CE10003A5E0BF0C6C71B063CF2262DBCC000FCD8 -:10CE2000B5D97CC01F33F5FC6129CFB7CCBFCA751B -:10CE30002FCFCE9C63756B1C0FBD07C27C611ABEE1 -:10CE400087BBB1AE96C3913E03CFDFAE09F8B7689A -:10CE50008CBE7BF79B7DBBF9B73A8BEF893DBC5D00 -:10CE6000DDCB235D7C6476D0C2FF83F21723447947 -:10CE7000943B6D7D01CA1308BF2F999DD154FE6B61 -:10CE800023A3F2707F560C877753A2678E8BCF7BDC -:10CE90004818C7BF1DFD8AEF2725FD9DE4DD02BFB1 -:10CEA000DEC648EA97C9BCE787837CF7D27ADC49BB -:10CEB0008B915F7535ADC78379F079B1068DD67BDF -:10CEC000D2E1BB278B979F6C1F4CF38893F470B211 -:10CED000F42F6F8CE5F54E1E32BAD0E7074D46BFF2 -:10CEE000250AE5021FDA1C6BD636DEEED48B91AE36 -:10CEF000305E5E767FEDEBF85E7657FD2C4A6BD6A2 -:10CF0000DCC878FDCEBBDE4FF5E45C898FB23ADE3B -:10CF10002A088F77BADCF5C0EF232E4F23D6BB3C0F -:10CF2000A77309E37475DED2F1183332F6EE50CFF1 -:10CF30002A7CEF7EE1933DF8CEF194553A8A2FC3D7 -:10CF4000C4E904F4DB399AE87AB9A4DFF45CCF1DB4 -:10CF5000E88FC3B19C65301691D361C13CD89AC1AA -:10CF6000DF8A4E3E6FDF7D50E3E3D486B737506AE9 -:10CF7000F48D463F67347F94964170F460FF9D7551 -:10CF8000F8A3800F8F81E7397E6AF7EAD7853F13D0 -:10CF90009F572DFE87B7AB6D33BA6DD83FCC67C1B5 -:10CFA000FC6B9925503F4DEC43D001EF6727ED57BF -:10CFB000FB07E53FE478A8796264DEBD1C3FB5312C -:10CFC000877E3291EAF1766ABF18AFCCABF55C3957 -:10CFD0001FB1BEB3721F9CE55FCCA09F7D6182FE36 -:10CFE00099A08FF34F2449FA11747BFE89113ECC2E -:10CFF000275EEE9BF39AD7108E763F62AEDD7C5EA5 -:10D00000CCD53666F628CCBE6DCC9C48C6B64ABE9A -:10D01000563BA86D0CF895E25FCCDA367A362F676E -:10D02000D96DA3E78C0AF03F56DA9645DF7D6D593E -:10D03000687FD0C0AA014F359F9AA79277103CAC69 -:10D0400062BFD63C7535C1478DD3023E027E0C7E51 -:10D050001175E5BA5F766962FF478E49005F1B086C -:10D06000FFD9898372C04ACE2FB0DCEEE6FD8ED8A0 -:10D0700066D1F5A3EA8DF4E9BFFF0AFD737A1B16AA -:10D0800082CF21C69E57C2F87CD9CF389CD895E371 -:10D09000BD29DB3DF9641FFE8C029F8C3915DD38FC -:10D0A000094E024F7FB0283CAD4EE6FCBA1630491F -:10D0B0000FC0EB60AE271972E53CF29037313CCFE0 -:10D0C000D306097F9557700FA5BFBBFEB024B99357 -:10D0D000B7FF6F9781E6150AD7B51C7E286F31B36D -:10D0E000DB4B79FBCF9B4F649C3607D6F371B3DBE8 -:10D0F000CD454D5F7EC9B65C2BF6DDD2EDB9D64588 -:10D1000041706FD99B7FC2C9F17A76AF0923B116FE -:10D1100093EF2713E2F0DDD8E665546E75F3FA67F6 -:10D12000ED47DE44BD25DB63F28CCE40FBA5DB4A38 -:10D13000DC5541F0BF7AAF1E1FA3DAF4F96B0EE99C -:10D14000F3E65C46F4F08FB6CBF5EBF3F927F4F990 -:10D150004FDE597D33B6C1F3E3C4BEF9D417E9B34A -:10D1600072B856BF3FE304E4E8A7079F8F02BE6A88 -:10D17000FF54753C99611D7A3AE578D44C7CBDDE4C -:10D180003D1AD1CB325FE8FE957CE38A7DBD96F0F7 -:10D19000859D154C37A1F83DC3DA6E7673FAAA6BFC -:10D1A0007A3B037A4CF52C4EC890DF6D9B2DCC7EDC -:10D1B000E57803F10F66773B19A7BF8A71A26C422D -:10D1C000D374768AF7C736FD7606F66BC58F35D2EF -:10D1D000372A9E1DF12AE8A66BFF82EB29BD79262E -:10D1E000C1A192B92DE0874BDB357F24CF3BC639F7 -:10D1F0000F75F2768B7D9A0BF35EB42E2CC0CFF8B0 -:10D20000BF559B42E6B125A89CCF7FE9A157BED26E -:10D2100078FFD5DBF5ED967178417ED4ECFA7B583A -:10D22000F077AE0811BC26B4EF3062DD8BE5FC95DB -:10D23000FC63DEC90CEB9B209AB0D3F80F971B96CA -:10D24000619EE2DCC2801C9CB045B4E78CAF02EB6F -:10D25000AEB75B9C5877BD95F923F87C4E445ADCF9 -:10D260000EFEFDE2B648D21F968431AF358F52666E -:10D27000CB433B5734DA7DFC9691F4A47ACE7BA85D -:10D280009FC7355F0BFA316A22FF33915FC6FCB44A -:10D290001ED08D3B789D3E7D9EB50E22BDA4CEE472 -:10D2A0007F0570A9619D046FC6F1E95670E470AB0B -:10D2B000E3EB7C2F16FA97BEFD72D646F5971FFA60 -:10D2C0007B58F077AE67322BAFBF3D9CA7347F1FF2 -:10D2D000C1D168616E039FA7F1CE709F97F490D281 -:10D2E00070D0A959EACB5BEE716761DEEB357796BA -:10D2F000037C6CB3CD053EB6708790435B62B8FE8D -:10D300001A477A33B55F087D0A7ACA02C1EFB6C4FC -:10D31000B4F9C1F7B73C9826F4A9BF19092E3DF717 -:10D32000D97C3B35E8D342EFD9B27904B507BF24A5 -:10D330007DEABE48D17EB680EB96C10E9F97E7FF8F -:10D3400088292641CF766759A91DD7D3D202724AC0 -:10D35000E9D33F1BE6B90BF856EB55FA37ABFE762F -:10D36000FAE66E293F7B36F379F2FE4F6BA5C70DC7 -:10D3700041FAF003B982FF8F99E6DE23EBB950AF93 -:10D38000CA30FBDE297CBE555B0DCE96B400DC991D -:10D39000DB9D05389FDE6CCB039D8D99C6E83C7103 -:10D3A0003257F0F38802E6F6F174BBEC777BAE41BE -:10D3B00097268673FAE3FD9C2EF19B81DFC882528B -:10D3C0000BE42197E1C4CF43D7B13757C8CD2A4BDF -:10D3D000E96F26F5339F3E3A28167ACBE915DA4EE7 -:10D3E000312F81E731FF6E73B5D0BAC5FC14DC393B -:10D3F000DD1492BC977C2BA68F4E7C4FD8386A37B1 -:10D400002B7D1AF8D7747442F0DC72DF28C2E34235 -:10D410008967769F4DD209637F45798993CABFE9B1 -:10D42000BCA5D6C9E980CA39BEFDC077E8794BE111 -:10D430009B997C85A59103E37BD1B898311A077538 -:10D44000B28979C3385C20F3082EF7987C77F1F91C -:10D450000C3509F8A798047D71EEEC0DCFA3FA6E98 -:10D460000BCF573CB094B979FD8A64E6D2447D165F -:10D470008DFABC1B234F2133D0AE225AF45B91C0EE -:10D480007C7749BD1FFC2A13693AF5EB36C48AF64E -:10D490005179D4DE6B10EDDD269E0ECB10FBA56717 -:10D4A0007D18ED9F8ABB53B24007B3A6E9E9203F40 -:10D4B0004FD08D4A1FCF734A39E34AC4FE5EB46E23 -:10D4C00024C98D165B69FD73C0D7D311A40F566CA8 -:10D4D000B8ED8642CCEF9941D070D8E737EE1F0304 -:10D4E0007A5BB46EC1F77E8FF3C85E1B7D6FCFF39E -:10D4F0009CCF85BEAD39CB9FE31F16CD3B6A49E477 -:10D50000ED3D6DB3CFBDC8D31BBDFBDF845E70E3C3 -:10D510004D46AA7F236BFBCB1FC117D689716EF0D6 -:10D520005E3025F2FE6E28D218CABB6C8ED4157CF4 -:10D53000FE15127F7F95FBA0C5C6E6FFD28E79A5AA -:10D5400064A5F3EF374053ED470F1C9727F5C4A9A7 -:10D55000DA76E83DC3A68BFDA5EAA31FF43B19F0DC -:10D56000E0F5CC122E2ACFE14AF5AB36867565443C -:10D570002135FB47F07471C1345B1EAF372B9DCD55 -:10D58000C0B9A9E70E23DB49F3EDA9A07D1F99E5FA -:10D59000C4BEF730E627BEE71B4974DF35B5A7EBFD -:10D5A0006E9EEFDA31C2D5427C5D9CDF173B18C915 -:10D5B000F7AEA982AF29FE72D2D11949F42ACFF36E -:10D5C0009592343E6A9ABE752CAF5F69B774411E5E -:10D5D0002C7E706E9493CFB3720B3FCF7339C636E7 -:10D5E000E9CFF3FCBC9D9137F8CA7379E8F91B3495 -:10D5F000033AAADAA4111D0E6B715992888F690E35 -:10D60000ACAFCAEECF84FCAB72D95C283FDBEC7EBA -:10D61000E034D70FCF37CFA4945DE670E7F3BC0AB0 -:10D62000C8E3FB7E6CBEC7053855B456D0793222AC -:10D63000C743FC69B9A4BB591CCC1AF88DA933099E -:10D64000FBB02B577E8F7564D9899E6D0C70E832C4 -:10D650003BB230AFAEF53603E4E6ACBB045DF37D20 -:10D660006635F1F6F7985838F6FBDFD09EAFB36C0D -:10D67000ADA97407CF0FB53253642CE82A97E8FAA6 -:10D68000E7051E33E0F0E98FD838E805959B36D3DF -:10D690007C145D305347F120E879BBD3F270BE565D -:10D6A00074F4F38269D7E605D3C34D1AD1014F5FF5 -:10D6B000C9207A98338BE8619A3F73259F5789B1C7 -:10D6C0008EB961674864AE303EFF5ED643FA442FA0 -:10D6D000D72720CF143F517C83D381DB1A1FC0EFA3 -:10D6E0009E663E15CE93F7365B297DB2D9C14C1CA0 -:10D6F000BEFB9A1329FF4CB393D2B6E66CFAFECB6D -:10D700006617E50F348FA3FCC16637E50F35CFA44C -:10D71000F4C5E652FAAEF812870BF121C557143F53 -:10D7200052F4A4F852281D953BB137A83DF13DC5F0 -:10D73000EFB00E435E801F29FCA66BA5DEC434F05B -:10D74000B1CE05E01725C6B34F3FCFE1DB5B6D7768 -:10D7500085390117C1F77AED5692F3A9167608E7D5 -:10D76000FF9615EEAEBB83E4EAADD51A3305D1EDD5 -:10D770006D8D36660AA2DBDB9B6274F9B2A6B78FA9 -:10D7800025F0FEFF9EE2F1022F27EFFCF8D1FFE427 -:10D79000DF1FBFF3F3E1C0379FC7EE8730EE9AF08B -:10D7A000BE79C422BFCE4C726658B838270D0B170D -:10D7B000E724FC013F8B98D8A78FDFF957DAE75DA4 -:10D7C0004D614E23F40FE08BC3F70389AF454D61E4 -:10D7D00004C78AF5A79E7E1EFB7D8D85F8DDA275A8 -:10D7E000727F6EE4700DD2DB3E4C62A49F696EC600 -:10D7F0009A38FC3EFC91C5CF653FFB50B3FA34DE4E -:10D8000050E387A632FEDDB3F157EF41DFD69A4EE3 -:10D81000907EECB1DAFD46CCCF6B3E1BDC9FD6741C -:10D820009CEAB1CEA1311F47D0566480634481DBAE -:10D83000023E01DA06FE16651F61D8DFAC55730C97 -:10D84000E7EBAA92DFAB366AA47728F83F9167A48A -:10D850007D753AD744789D863D3B981818C929456F -:10D86000B79C6FB87DD81FADB9962541FC7891FC67 -:10D870005E996DA0547D3FCDB725FA9986CDC5FB45 -:10D88000BD373BDDB298F89DD3027EA0EA2FCACE09 -:10D89000DB905E807EA6C6B1A07DF95C9E49CECBB2 -:10D8A00021E49895CB31DEAE6E0079A0F4934FF170 -:10D8B000BFE369FE74FEAA79E6A9675E845DE2FDB6 -:10D8C00030C253CD35D2BE91E31B3397F41AB75D06 -:10D8D000E3EB6C90F82F7EEA4F519DBC7CF901611F -:10D8E0003FE56917D28635D5642F6B70F17D827D57 -:10D8F00070C8FC6167105DBEFACCFB519D74BEF030 -:10D90000261B1291FA93194F1B0E9C9AC1D01FEB44 -:10D91000D9E0B05FD96EB97699CE996A1D2587BFD7 -:10D920008CA7F1B54BF154FFF0FAF8FEEC20CB993F -:10D93000E9C3BEFD4B7606B7CEAEB69C6DBA60E4C9 -:10D94000F35DBE66E627A0F3D0FA9FE445C6817E6C -:10D95000D8583696EC18266600BE575A051C7A7DB4 -:10D96000C3A3D9D7D85F966FE38DB8AAD56B72469B -:10D97000BBF87CBB613FEFA77E4EBE90EBE7F83E65 -:10D9800062FC2CD5BDCF48E785EE7D9144FF0DFBB1 -:10D990001E383E91E71B76691896D5B30E8253C3A5 -:10D9A0000123B306CB33D877060D3CCFDAA7221B71 -:10D9B000414FCBDA34F76E3E9F5EAB337A70D07C4A -:10D9C0006CF9829E6AC3DAC6105CE5FCFF2EF999F9 -:10D9D000AAB7ACFD010BF0C5EB9D27FDE517118C37 -:10D9E000EC66ACE74DCCF3CCF67C17EC7BCBDAF6EF -:10D9F0003790FCDF17E118CED7F1B9B4F3AB7E0650 -:10DA0000E78BFD34385FE81D67A43DF7CC3346E271 -:10DA1000439827F6E1E7D07383E6992CE7999C2F8A -:10DA2000F49B23D88F8581FACBDABAA23279FD4FE5 -:10DA30000EBD4DE97039CE327BC768C8CD4F0E445C -:10DA4000CCF451FAD3192FF1F1CEB54D8DD382F626 -:10DA5000555EBE99FA3DB7DD3813F062BE4152CF34 -:10DA60006FA3F59CD997ACD1F916F0E67AFE99032D -:10DA7000CF461968DF7A453B89478355D869C36229 -:10DA80009C52CFB4B642DF58C8B5BB68CEEFEA0FA0 -:10DA90005C20F91BFA5DD5A7FD9684F3770FD93585 -:10DAA000F89F01F45BEF10382F31E624601F945F7C -:10DAB000E3BCE556F0B1D7CC020F439D0FE15C55B6 -:10DAC000FED620B25BAC343B1390FFE2757E10E4CF -:10DAD000F32ECF97FB3BB1B31076CEAE3421D7EB0C -:10DAE00036F2830A5FCF108E772F5F729DCFC83CCE -:10DAF000F9013FD1FCFC745ADF23D506B785FC2C15 -:10DB0000FE2CD83D4F5A9897FC46BFB4097F40BAC7 -:10DB1000B0EB3F22FD4575B1FEAC41B07F493CD62C -:10DB2000CDE1E541F8ACDBE9CF82FE72D622EC7C98 -:10DB3000287720CD13F55A24DDA01FF4DB95E638B5 -:10DB40004F7AE673910CFABEE1F9486157F8B96D66 -:10DB5000675890DCAC9674C575262FD6EFDD2DE6A0 -:10DB60008779417F5E6669CD827EA9C65D16D54AFA -:10DB7000E39D95E32D0B6F15FE098BB047A23E8DFB -:10DB80006F66E447E979228CF4D4CF933A0E62FCB5 -:10DB9000CF9F18C920C7BBD27C4B0E5139D7DF3875 -:10DBA0003E6A9E0CF363BE9F3D11E963BCFE67664F -:10DBB000A10F7D16194FFAD089C8ADE5E497D915A4 -:10DBC000A6C1AEF299C62C8928DF2DFC1835CD4DA3 -:10DBD000E47FA8E1DB9DE5513A93C5A27C24D95BA3 -:10DBE0003EFB35DFA71A7DDF88EF1ED65AFE03EC19 -:10DBF000BBBD116477FBFCC9FF1ED99FDFA26697EE -:10DC0000DEBEA4E84095DF23F9D23D128EF7E53B56 -:10DC100008FFF5116D5BD3699D62BF723CD0B98B73 -:10DC2000EF8F78D8BB4FB6BD10AFD901677FD64F05 -:10DC300001F7BDE27CF3F93E33F95D6A9E8F749380 -:10DC40001DE7EEB106C88B1AA3D0836B0C1C7C3C7D -:10DC5000D5EEDC9B053DBBE5095B1EE0C1E14DE770 -:10DC6000C89EDD46398E18F7B33D29C2AEEF97F94D -:10DC700083A3C8AE3F2B96DD3E87F49CEDA301D76E -:10DC80008BBB220CA00B3E8E5BE3F0A9F9C10F0504 -:10DC90003CA397905ECEF71FF1CB3AC92FEBEF9ED6 -:10DCA000183D11FBE92D23835E70D1E44A003F0C3F -:10DCB00085D70792AFD41E7CD402BF5D1DDF371E0F -:10DCC000BE6F6AA57FACF6498DF4BADA0D131F2238 -:10DCD0003EF8A6990DE7F338DBF64054303E8E4B04 -:10DCE0007E1668EFA2FAB5BCBE68FF5A14CD678FE6 -:10DCF000D985F984E2F15BB77FD2F8ADDAF7D14785 -:10DD00001B97EBA3AF5CF745D6F1FDF7C14FF6D9F2 -:10DD1000C87EC5F19E0ABDE38CB96D09D67DE66962 -:10DD20001BF199333162BF7FC2F9A17704E6F19DFF -:10DD3000FBC9BEF1BBB90CF260A94FDFAF1AF735D2 -:10DD4000C97FEB07B9A26127ABE778407F1C2FDFC3 -:10DD5000A5F66F99A97DE83A9E44BBC2A0FDF9746F -:10DD600004D1CB9921021F679E194172A52B46D081 -:10DD7000399F6F2ACE2B676244CAA08C703AA89153 -:10DD8000E7D13353DBE8FC7D46DB4F699759B4ABF1 -:10DD900069927E634E7789A01BD024FC61D64D1D0D -:10DDA000D02760AF1E9347A93F2CF64ABB33E81338 -:10DDB0007228A340C82F86F1E2A5FF83F494360BA6 -:10DDC000F8B247EA7175FBAEF4C301BF75FB34F2DC -:10DDD0002319543F7CD671CA5ECEE9B1D6ABB96D7A -:10DDE00098CFBA15CBC88FD4B8F956D0BB5A47AD27 -:10DDF00089CDC479A84B33D27CBA6C7CDF000EC1CC -:10DE0000E305E95D91817198239EF44C52AE630A5B -:10DE100084BC42BE95F757B74EDB44E3A4A973A573 -:10DE2000589F8213078B05F6327EDE17E503AC5F41 -:10DE3000CD3374FD6A3EC30B849DA22BCD797F1137 -:10DE4000F0FD86D18573FAC5CBF9D1B15FA397E117 -:10DE5000E4D66737E6F3CF034DF1F97F29F95B2D5F -:10DE6000ECD27C9E59DBF5FE90EC5DFAFC55FBF4A0 -:10DE7000F99C03FAFCE8767DDEF5AA3E3F448EABC2 -:10DE8000E08473AF738438F722C5B9D71926CEBDA5 -:10DE9000C8E3DC8B14E75E7CC7B917799C7B91C71C -:10DEA000B917799C7B91E2DC8BEF9505827FD7498E -:10DEB000BB23F000BF0C7BC1A6FCECB45FBA17C457 -:10DEC00013FF547ED2EE653994EFB3EBCCB6925D7E -:10DED000876C375C2F993BD473434121FCA71D1BF2 -:10DEE0009280375327D97397BF28ECB97579363BA1 -:10DEF000EC0C9DEB3FD900F5296BA8670EEA779BE8 -:10DF00007BF6101D98FCC4373AD73ADF9A22F047C7 -:10DF1000F60E668FA5F34905E45DECC0780CF5AB11 -:10DF2000B04D7A3F4AA85F25D49F124A07CA8FF2A4 -:10DF3000B8B92709FCFED413D64D98FF2969276389 -:10DF4000F3ADA47F29BDBAC4682738ADBC4FDB0947 -:10DF500039B5AA2096DAF79EE0FA763FF256A595F3 -:10DF600097F2855EADF29B3403F9693C6E9243AB48 -:10DF7000E49C52B59EAEBB4123910692E317ED0699 -:10DF80003A175C7CC7487AC4886D06DD7A46FAC2C7 -:10DF900075F475F5DED8107FE0105DFD6B0EA5877A -:10DFA000F803AFD2FBA96E5AFB0ACED77337E5EB65 -:10DFB000EA55954E0C81A39CB7D44B5BD66C4B05B0 -:10DFC000FF5915D94BF35FF59C8DEE5D5471F9E265 -:10DFD000E6EBAE4686F3C76AABFB46C0AFBACD1CD4 -:10DFE00003BB56A5943FAC492F8FAB4DCCEB880DAE -:10DFF000D05DB583B96378FB73B9AD7B0C1C6FE75B -:10E000000CDBB71639E15FDA91EAE074B55A6B8B35 -:10E010001FCFFB3B15E3D951C0F773AAD9FF933249 -:10E02000F0CBFD196C2DAF776AD3B351A4774B3A7F -:10E030004B353BC281EF1DAD463A17C03E057B9084 -:10E04000A2871DAD83C233ED817506F07F99D6C7D7 -:10E05000F142F7467AED4786AE821ED726D65B3D63 -:10E0600055F3929E2CD7B352CA15B64EF4B35AE666 -:10E070004FCBF3825ADFD991AF8C76C2AFD97C28CF -:10E08000D5083E6ED8B72709FA4582A71DFBA77AA7 -:10E09000C7F0FF2CE2E3D6FCDEC8E047FE68CBF415 -:10E0A000A8F1D03F9F36BB66F1FCDDAD3FB3E05C2D -:10E0B0005063F25970EEAC7E628705FEFF6BF7EE9F -:10E0C000A0EF4BF656D0797B296BA473E4A76621A9 -:10E0D000A7153CAAA769DB1D7CDE998582BF568700 -:10E0E0008BFB2025C6A2637158EF5E2D17EBBDA9EF -:10E0F00074BFA5827F7F57F2E1D0FDD1FBFADC929D -:10E10000C1B02BB5093FE840FB619E7F24ED87B984 -:10E1100097D228BDE9D2D574AEFA3D2B1D457C229D -:10E1200027E43CFBBA51D8CDDAC53EA8B6F8E3E601 -:10E13000629FBC6CA67D526F82ED1BE764C626F021 -:10E14000B4B4C8A8A3D7E5C5113A7A9ECF62757E4C -:10E15000E59BD9105DFEA65919BAFAB7DC747508AB -:10E16000FDE705CA898F4CD0DD5FA95FE3756A645E -:10E17000479BA6FFCED3354467D7EBDAD7B33981B7 -:10E180007A3807EFFA2DC199B10E0BCE5BD5067127 -:10E190005F67BEA74B7EEFA4EF7C21BA7D382CC30E -:10E1A000F59F422E9AC93EAFECD3F3F1FF19FDC99A -:10E1B000458E68396EB451D8173C7ABDA383CE9F83 -:10E1C0004CE0A15EDA7BEAB385BDA7DEDB6169B412 -:10E1D00013FC4DC91C240DAD1AD9F3787D6B72ACBC -:10E1E000C8AFC1F703E6809D8589FE2EA1FC84B1EE -:10E1F00002FB25B4BC81AF1B7A4603EC3564679AF9 -:10E20000F909D999D438B27F45A74BB7E9ED470D45 -:10E21000B0EB04E17359A193E8B566EFFEE3433830 -:10E220007CE696C6E4621FD5B5CD3657E45C496FEF -:10E230008ACF5FAC3690DFBBF7F5A3446FBDD52620 -:10E24000A2EB6F824B835BD83543E970095F9795EA -:10E250008FBFE480E6F269A21EE03304F419029F46 -:10E26000E47EE0A6E0D507BF90F2A5F89F02DC2788 -:10E27000D07CFEB4FEE012024F354E08BCD8383DCB -:10E280003C96789C6F81FF2C396164BE6FB1FEA50E -:10E290005827E6C1D78979CCB924EC26CA9F70F3F8 -:10E2A0002513E5FBE8A694C32B0FFB4EBF4FFBE8FD -:10E2B000A854EC9B7997E2A9DDBF8A9EBE898ED4D3 -:10E2C000FC15DF0EECA3BB486E2C2F8C8CFB98B397 -:10E2D0000AFEFF85C417247F1D582FF50A3EEAD198 -:10E2E000CB9961778EA37B47BDF674D22BFAE4906D -:10E2F000435FBE32323D01E51E69B753FCD823EBC4 -:10E30000A9712A78B97310E87A683CECB11BD6651C -:10E31000A47606E92B9EF5E678D80B53D70EA2B467 -:10E32000C2E688871CA9586B2C857CFCF09E84F87B -:10E3300071B0CFAF37C7CDE25D7F7847412A1B85EB -:10E340007C09A5A73687CD0FB673AB745BA1D0430C -:10E35000EBEF7C8FE4DA39C3EB51F3B1EFD63F1723 -:10E3600085AB37B5EBDF1EE3E02AC9DD319E870AB6 -:10E37000C98FBA638F037073EC180D3BF5CF6143FF -:10E380001B1CD01F6AD69724C02E56F7B7A38F4107 -:10E39000EE7BD69AE3A17F7EF60E978B1AC935D213 -:10E3A0001B3EB5313A2F7DBA3BC207FFFDA71A735A -:10E3B000C3BFB3CCF8CA68874ECEB6DF8C79EC4DBC -:10E3C000F0FCBCB010E3FBF624627C9797EE677A12 -:10E3D000D60E8FEECF8EA2D2E5DB845EB747D97121 -:10E3E000A5BD17FA3CF2D0E7D908A1CF230F7D1EB7 -:10E3F00029F4797C3F26EDF8C35A7A72711EF54EE6 -:10E4000063D98D2477EDD9D0D75769E12ED2333532 -:10E410005702EC63EC9D18216F43F0ABD2493D5C91 -:10E42000E70AA2FB2997AC2CF89ED95416A3CB4F30 -:10E43000B726E9EA9738D274E5D7268ED4955FE7F8 -:10E44000CCD5E5BF933D5E57FF06D7545DFEBBE3D9 -:10E45000AED3D59FED9EADCBCF9DB940577F5E69C2 -:10E4600085AEFC96F9CB74E50B3C2B74F95BABEFF6 -:10E47000D0D5BFAD71ADAEDCCD1C26C8BD769CB38A -:10E4800038DC5FC6398BA7ABDE186E0FC66BD17454 -:10E4900043637F76FAF3521F9A38D6FD19E823C5F5 -:10E4A00020E890A76EA81097A55C49667E4D9C73E6 -:10E4B0003B924037A1F542CB8B228E5C74721C2EAE -:10E4C00039187BAB89F391A2B147F23378FE9931C9 -:10E4D0000B447EE29167D379FEE0C1ADB79A38FF75 -:10E4E00028BAE6C845948F1E5B2EF27319A91C4703 -:10E4F000C6FC6DA197AFA3684AFA2697B093F47B48 -:10E500004F53A58003EE37020E48FD9C3E911EE15D -:10E51000F489F4554E9F5566C68E73FA447A829FED -:10E5200037F1FD37FCBC89F4757EDE44FA263F6F77 -:10E5300022EDE0E74DA4BF6B9E4FE93BCD1E6AF78D -:10E540006E7335A5EF3537D2F73F363751FA41B301 -:10E5500097BE278E5176053FD95F949FA901FE3D56 -:10E56000D8E70E99CF06FB61959F50F9055B1A59C4 -:10E570006704F669A729E6636BC0DF37309F35B1C2 -:10E580008F83F4B0CD89EE8C3134FE5007F97BE4F3 -:10E59000F769DADC14B8FE6E1DED193986E37B5E8F -:10E5A0005EE5FA68CE3FA65C6E34835E7E2FEFA9EF -:10E5B00086F67F59D249DC58F768B49B6C15F7F0A2 -:10E5C000265BC53DBBC9A6CE16F0A3962F9913F7BF -:10E5D000685E89B4107F6AB9C7E4839D52FB82519B -:10E5E0007E521CA37CCB971D742F6FB2C39548F24B -:10E5F00046E6FBFCE7F80BBA2FA3FCD9EA9E4CF1E8 -:10E60000179DD3A1074CB25B9C6121FE77F8AD5FEB -:10E61000897C57CD87613CE527DFF525F31B46074D -:10E62000FCE193AD1D69B0134C5A6D7505DFFF51C8 -:10E630007E6FED8B0E23E489BAE7A3C651F38D34C8 -:10E64000F1FEF202F778263BDA7271AFA1A5DE4E39 -:10E65000FD25F0EF963CAAE73652BBB65CD8812781 -:10E66000D5D95DB06F2B7F7B825C37AF47EB2CFE3B -:10E67000C243F70D26C9FB06E8C72ACABDE86752A0 -:10E680009C3FC984F5375A5CB0873EAAF1F6790100 -:10E69000FF3FEA4704ED5FCC13FD66FE85CF177A96 -:10E6A000BBDB4DF09DABCE6F4E9997F29959A79178 -:10E6B000FDCA28F3BF1DED590EBC978639FE1441E3 -:10E6C000FB3C2305768ED9526FFF1A7A59FD3F43E2 -:10E6D0002F6E81EFA18CEC69A174A3F0A2F03C1025 -:10E6E0001D29BC07DDD7223CF7DDBF92FD84D2D7C0 -:10E6F0004074A5E869B255E01D78C53D1A4547DA72 -:10E70000176D3B681D755692738A8E42E9E04A3A4E -:10E710001274D9F23D2BF577251D05F00F78FCF327 -:10E7200074D46184DCFD47E9E7F61E36239A17DDD1 -:10E730007B8DE732E446C525E771E42BD9D4192057 -:10E740002955FE00CA075F591E4A5FAAFE8B03F4D3 -:10E75000E7F9A2C71C1D449793A40CFCC300F55F06 -:10E7600093F7E25FB3A9FB1E6E7B2EA783E9920F9E -:10E77000AF2A11F43533CD48FE8CE9394B49BF67D8 -:10E7800076A11F3BF93F646F93FEF5EB65BB1997CC -:10E790004BD7619C19717AFDFB7AA977CF0CF1B741 -:10E7A0005F9F732DE9E1D787E8D9EF8D917A741ACD -:10E7B0004B13E7EB4DA4FF16CBFD982CF19DE134F4 -:10E7C000B2220EF712E6314108BC7ADEE2467FD76C -:10E7D000322FE5AF633E4ABFC3FCA407DCC0050689 -:10E7E000F2DF658CEE8F1E8DB8B16C39EF6F7AFE5B -:10E7F000F44C7CAFB3F6A45A0CB81DE8F90CF2A1A6 -:10E80000C1E8F933F4CC73299E11381F1F29769281 -:10E810001E76C49A417A21F69339C85EF96B2E4769 -:10E8200033B99C3BCAE52CD2635CCE667279F72B78 -:10E830002E6791BF3E7B2D43BB194EFDFD1ED5FEBD -:10E840003B8EE9CC34686039F69DD12F0C851DEBE9 -:10E85000B59811C5C0DB6B31638BB1DED762120C8A -:10E86000220DB3503AEAF9CCFEF45645AF81F16679 -:10E87000D078A1F055F00C85A382EF3F01CF416322 -:10E880000BAF84E765E8F7B09F5ADF8E4A4C879F4D -:10E8900051C6D345083E58FFFCA804ACA3CE2AE0DD -:10E8A00032A96922A5939BC633533EF999BC80EFE8 -:10E8B0006758020CCE217636669A46F9EF49DACAD5 -:10E8C0004EF00CC73CCEE6F9B3B846C63ED9DE12D0 -:10E8D00085FB99E79E31BA70AEA9333A37B9602704 -:10E8E0007FCD28E2822E1F4D857F93EDEAFFBE7417 -:10E8F0009D55C1CF4B70FDD9356EDA6F0CDED9F85E -:10E90000805E33344CDC3326F742DEC07ACE98701A -:10E91000C167868609FEA8F0C5DB09B9CBFB19C320 -:10E92000F95AF2FDE174AE2918E62EC27AF879811F -:10E93000E28A7AB323C85EF11B199738D97F35C5AF -:10E94000E5CDC4B99D7F378647EDC4BEFF8D8C4BA6 -:10E95000FCC520CFB5687F6D5A5E22E0318509BFC6 -:10E96000CA7556B3CBCFE774DD58B90F47B3D13270 -:10E97000AE4777FE507692DE3823C9A1C92CEB2131 -:10E98000D8098A4F98C94ED077DF2D51F8457B4F73 -:10E990005C3482AF94446A6C505A203E272CD1C01C -:10E9A0009C417ABBCD19CE9C41FB23223B56978FCD -:10E9B000740DD1D58F1E97AE2B8F715FA52B1F3491 -:10E9C000334F971F5C3A41573F61FE345D3EC97338 -:10E9D000BDAE7E72F51C5D5EF1BD64F189A5342E7D -:10E9E000D4B51FD6B448573FCD5BA32B5778605E94 -:10E9F0007747763CF8A2F8CBD8B85257EFA7512208 -:10EA0000DE64A67DC92CECF7E1AD3FD0CFCBF8BAE0 -:10EA100046F1A34EC16FBDFC1FD05149A29EFF4ECF -:10EA200077E8ED1AC98D265D7EC33F8A67CF553AD8 -:10EA30003C87C283E3DDE5477D2EBFBD3C5FF2EB43 -:10EA40004A13F40BF82F82E70FFF45F07AE1BF0875 -:10EA5000CEC37F115C1FFE8BE072F82F82CBF34F89 -:10EA6000E8F15CD8A1C7F3D8F7F47856F437103E34 -:10EA7000C677EAE920141F133F0DA10B8987F9FC23 -:10EA80009FFEF04047114EFFD31B19D9E7BE092F57 -:10EA90002F84E065D2484F3BF6EBFC4117532DC065 -:10EAA000538F6704CE939F493B49E83D4E2F57074C -:10EAB000280EE107468ABF396968D5C097FD299EAF -:10EAC000636379FDDB731A897E1259E9FE257C3E6A -:10EAD000E5FF11467E9CF261225E97E574529C83AD -:10EAE000E277E5C9E21ED11B63E5F9CD25EE13758A -:10EAF0008C15FA6CA4CB41F78E2B72441C073F7621 -:10EB0000A5968F02FDBC6E1B017AD822FC269D883B -:10EB1000178E0BC40B43DF847E9722F5AB963F58CC -:10EB2000AD58C7886D4C272747FAACBA7BAF57EF73 -:10EB300075E8F2A3DA1275F5AF39E4D495E7FAB3C4 -:10EB400075E5F9275CBA7C61C7385DFDB1EFB97531 -:10EB5000F9F19D3375F5277E5AAACB27B39E87011D -:10EB6000DF619A38EF5B395FA27B604E110F547EF4 -:10EB7000778C8803957600A54FABFBD01E4977A113 -:10EB80007AFA308BD0535B9298388759E5798BE9C4 -:10EB9000F5758FBCCFACF454E6D5DF6756F798FB1C -:10EBA000F47AA9B72BFD38E81EB33BF81E73B98C75 -:10EBB000DF0E957F71E3847D2F74FEC32C62BD2D23 -:10EBC0007758286E44CD2B743ECBF304DDEEB6F6B9 -:10EBD0001FBF933E4EA3FE8B724B878CE3F51E3313 -:10EBE000BB7C6447B9623C57A717E7CA1F595C77DB -:10EBF00039BF79BCF26BC47ACA0C86DB67E7D07D7B -:10EC0000B1F9BF0C1A3F6F9CA0EFF8095ABFEB2B6C -:10EC10008F16F7B958B4C509FA1D783C01CF440BDB -:10EC20005B477146F2DEFF6D9BDAEE1BC18BCA2C8F -:10EC3000AD66325E309F19F4306B1AD7A772611738 -:10EC40007CF1113BD7371E6B32919D67FCB8616533 -:10EC50005C13EB8BE318C6CF1BA00FE82C38A73C46 -:10EC600039DE48E32C1C27D65762BCDC77FF9EFCBC -:10EC7000178C49FECDE83E4C3FF44674A8D6F1AF60 -:10EC8000BA8FAFE836144EEA7CC9A4DCC994F352BB -:10EC9000F053FB41C14FC5433857984B77DA29AE43 -:10ECA0006226EE9129FCBD3C5EF0A34D8047A1A8F1 -:10ECB000077E3450BD12634E34ECE1BDCC19EDF843 -:10ECC0001A7BEFBF304E81E03F507CD540FCE10A1B -:10ECD000BE3040BCD540F4497FFF40DC55107F106A -:10ECE000F77A243E7C9906F2A3DF1DA9DFC72F8C9B -:10ECF00013F0F5C87DCCE5AB3D57CF2718ECF72DC9 -:10ED0000EB8D924F08B90A7D03DF17AF3793BEC171 -:10ED100058E956C4117DB4C54CF75B27BB9D335CE5 -:10ED2000C23F4F7A07F9BDF8D42ABC7A79CAE5FB0D -:10ED30004EE8C153986B03FC19951BF5E54BED3379 -:10ED40003E833C5F1C722E5D2ACFAB4B43CEA54F5A -:10ED50008D93F2D8C55CA427493F7FB5ACD3474714 -:10ED6000BE8C686977A1FDC953BA17A6E0E284BFDB -:10ED7000263F90E7F00BCF869C5E67EAF7BE5E1FEA -:10ED8000FC06B88F7016F7119CD8EFBD146FD57BB9 -:10ED9000C026FC94CA1F24EB9FF55EA472D4476F73 -:10EDA000E7723B46430FE9F31F85F8A17AED86A889 -:10EDB00071E86F9F99FA53F72D6AFEEA1BED08F28E -:10EDC000277B3A8DBAFB2D57CC7FED7374FFE2EEB3 -:10EDD00018CF3BE0E3674C2E2BF0778FFD483CE2E9 -:10EDE000E46749BB4DE87CFBF4CE224DF861BD22BF -:10EDF0006EB677A646F700381F64D837EADEC06CD7 -:10EE0000E68F43AAFC319E8DE309CECA1F53E11F52 -:10EE10004FF39CD7B2D41CCEAB743EBCA624DC19F5 -:10EE2000F0D374A6887B3F03F96BE65ECAA5FE6E3D -:10EE3000BA3491FAB9382E4DE85DEBEE5B013ABA7F -:10EE40006A2F33639D9D21F7DE555A29F98D77BCD2 -:10EE5000E2D3F23ED15A8DE87CA5C6D4FD22E2D39E -:10EE60002A7FB155E64B447ED57A91EF348B776695 -:10EE7000F6487B03D68914EBC1B9789FB447601D6F -:10EE800048B10E7C075F421E7C0979F025E4C197EA -:10EE900090822FE1FB22569A9A6B147EA5E2A07D08 -:10EEA00003BF527190DE03BF52701E7EA5E0FAF0E0 -:10EEB0002B0597C3AF145C0EBF52701E7EA5E0FAFF -:10EEC000F02B05E7D9B8EB0279F031F76C5D7E2EB7 -:10EED000D7BF8B83F62DFC4AC1FDC3AFA4EBCFB3E4 -:10EEE00042D7FE56D6A46B0FBF5270FDDB9B349DFC -:10EEF000DFE976F91E40E5B641441F2F8D2E758D52 -:10EF0000E7FBF5CF117FFB9E19E70063FB32D0EDE5 -:10EF1000CAFA7097C073EB4C8177031378EE5940AF -:10EF2000785E6311F91271FFB83FFF4DB159F86F68 -:10EF300090C27F8314FE1BA4F0DF140F17FE1BA4E6 -:10EF4000F0DFE03BFC3748E1BF410AFF0D52F86FAC -:10EF500090C27F8314FE1BB483FF0629FC37F80E92 -:10EF6000FF0D52F86FF0FD24FC4841EF66404FCF93 -:10EF7000D49DEB381DEACE750E5D1E7A7A707DE861 -:10EF8000E9C1E5D0D383CBA1A707E7A1A707D7871E -:10EF90009E1E9C5F3DCE49FC12FA7A703BE8EBC1A5 -:10EFA000F951ADDE63B01DDDB0FDFCAB483B23B5D0 -:10EFB000C734CE0A56BC70A00C7EB64E9B961AC3C0 -:10EFC00039A5597BB1AC98E73DF21EDF68D66300E6 -:10EFD000BEC9CFCEF1E6F133BA773CEAAB242A576B -:10EFE0007E5DFAE378CF3DC048EF3F26E33D557B99 -:10EFF00017731891AAFA817CFFF542C757F5885F0D -:10F0000006CD831F0C7371CF24778D3D0FF7E5F785 -:10F01000183471DFF42E71DF3794AE764BBEB4C76F -:10F02000B0FF4838EE0F55682EC4316499D8097383 -:10F030001EE0D49807FDE0BEF131725D8D1370FFC4 -:10F0400048CD5BD901399FA0F8B5A21E66A9E2E3BD -:10F050004CFA82591683BF5B845E8076382F5EED52 -:10F06000D5DC3B83E8FBA1F142BE79BC2B2654F1F1 -:10F07000EF57EF6B9C80B8B859E1A2DDCF1F8F220C -:10F0800038DEB84EDB89F8C3A27DCC8D78579F9CC3 -:10F09000F7D5FB1C962A1AD741F174AADF8AEDA98D -:10F0A00014FF57C13A8B115FC10A3406FFA8821BB7 -:10F0B0005FDFAB585F16DF2A66D23F455C4EB88CE7 -:10F0C000CB51F1386131A555905B2A2E6752414CE6 -:10F0D00009EEC5B176E64218F00D0515EB07F3FE13 -:10F0E0003D3EB70BF78A267DD1788CF2BB4A294F7B -:10F0F000643086C621B936C2ABD1FB1A377A77188D -:10F10000E29C88D75D6B8E47FD7DCC0575878B1A99 -:10F110008A3B55F3CB611D069B06BCB3A38382E8F3 -:10F120008873809B80F75C9799DEDF986D7298C139 -:10F130003742E5F895F71643F48490FB252D6BDEF6 -:10F140004B35A6E37E89C1E507DF7A2E82F405A55B -:10F15000EF54C8FB6617D71D1B7C0B2FAFD82FF4BD -:10F1600003CF368DF89FBA6F529FE14B35405F1841 -:10F17000B26374AC51C87FF0C533DE676FC616AD9D -:10F18000587F8CE2222AD617468BB828E187A892AE -:10F1900070AA92F78A588E231E7AE6879CEFB847AA -:10F1A000D0BDC4688A2B6C15FA9CB2B7287D50BDBF -:10F1B0001F53F146FE71E0BDE251F92ECBC60A8A1B -:10F1C000BF0ABDE7532BF5BD65EBCC747F6859884A -:10F1D0003E582BEF0BD586E883E7C687E883F2FC21 -:10F1E000A2EEF356BC71741EE92B8D66F2CB95AD81 -:10F1F00015FA0BDBCF7C8867285B3BDD807743CA41 -:10F200009E73BBB47EE8E42DA9C7CCEAB4115CE7D9 -:10F210005C4AA6F4E64B4994DE7249DCA344EC0B4D -:10F22000E8A0F305467AF4DB526F99877B9588470F -:10F23000F486C9FB938CF4A65CE62801FFB8CAAD3E -:10F240001D85DA37CBEC598F7B9BB376308A3FBA7A -:10F2500001FA0DE2BFA0EFC0EE5E90564271183386 -:10F26000358A67B9A16085A46F4EEF0CF4EE95F472 -:10F270005B4AF93EB920E9DCE3ED3201EE3778353F -:10F280000BDEE1F3C873ACA2E3507A2F8F90F62720 -:10F29000BBB02FF5D99F30593C6AE38DBE0DF75BAB -:10F2A000CB61B31BC204E239CC237344F98817A3A2 -:10F2B0006F5B8743CDFFA35DA2CC6010F14E5CDF96 -:10F2C000025FBD6D75AE6551107FF962E2B419132E -:10F2D0000B03785F1412A7B7F29EE1095F172F5A4C -:10F2E000C9E18C7D521EDDF93D4EA1ECDA09CC5D01 -:10F2F000CCCFAC0B18538FF7F8712F70A1CCAF7E29 -:10F3000071DC9F36DA093E949F3E21F5362FF15588 -:10F31000C1B76E05DF32825F79A64E207ED53903F4 -:10F32000F888C8E991EF1048B9146287583DC1299F -:10F33000D61B628FA8CC11FC9C999CA9B7525CB0DB -:10F3400093EC796AFE1F9AF5719A7D7E9109529E1F -:10F3500034FF6BE21BFE2BC3731BD6B7D520E2E64E -:10F3600087185B99B40BD1FE57FC83C9772402F848 -:10F37000E77A1AF9D1354730FE3D1B3511A73E809B -:10F38000FD8665F73CBC1BF6BB660B439CEBE35963 -:10F39000828E1EFF8185F4F0324BC731BC93A5E00D -:10F3A000F87ED3BF9BC92ECFFCC3F1FED7C2469BCC -:10F3B0000BFCF98B89A5AB30EF881C17E16306DFE6 -:10F3C00066E8FF644AE9F7095F9B5E790C71FBCB45 -:10F3D000DBD3288EB4E250EE06BC27F2C544CF0F33 -:10F3E00027C08F6B775820C71BD6C5905C2B4F90DA -:10F3F000719DAC87FC540AFE0F4C10F6ABEB8A04EF -:10F400001D77CBF30818E66C5D3D798F3B649F2830 -:10F41000BB60A87D21F41D8781F68FB223C06E608A -:10F4200009B22B2ABB8439FBC30590A365167DFC6A -:10F43000A14A5F557637791E5CDC27C77266244087 -:10F440006FDEAC3920C7AAECCE5BC6F37CD509339E -:10F450006E60B259B14EF17EC73DE2FD8E457CBF74 -:10F4600082DF94C9FB5855DBC6D37EABF2F1347F03 -:10F47000E07D79EBE6A3292F807EFC6E8ACBAF720C -:10F48000B82DB141FBBEB255D3C5F5ABFC8109C265 -:10F490000E57C6D574C0EFB6D56916BCA153C6D5F4 -:10F4A0000BDCEF7B7582531757CDEBD1BD8659E945 -:10F4B000ECB8783F89CF3B4D8C9717D4FFA256FD0F -:10F4C000FB04BC3EE9452F4F8824FC5538F8BAD3DD -:10F4D000903A689E1C0E04A79EFB787F4E1A87F018 -:10F4E00051E9F79971EE2EC37D0A9E5FE8F09931DC -:10F4F000CEA275E2BD10CF26318E67638C6514F401 -:10F500002693C39202F8E1B01C47F3233E58C5E1AD -:10F5100082782B1577190A9F0A39DFAAD618BD3EC3 -:10F52000D6BAD90C7C2C18E0BD821E49B78BD64DBB -:10F53000A578F32A939BE2193C12BE1FADB0DD0BF8 -:10F54000BFC0822D0F99D370CE9E20ECCF3D72DFCD -:10F55000CD4AF70FA7778156D85C98E702472BADC5 -:10F56000AF0FBE0F727868787FA694E0CBE9C28BAC -:10F57000FB79555BF4F80CCC47C0B76A4B05EDB787 -:10F5800025268FC5113C8F6DAF0CC73D94057C7F40 -:10F59000E3BD23E6F0507CD3C70FDE924AEBE4F3E1 -:10F5A000A47B502EE70CBCF3C3E984E858D18B8AC6 -:10F5B000CB56E359278AB84CEBC46FDA976ED26BFF -:10F5C0005A387E61EF1E685F5A10D8C5C7B5548996 -:10F5D000F7D742F7A9DA9F6A5FAA7DAAF6EF63E63A -:10F5E000527FA216E0335CDE36FEB21F38CD90F3B8 -:10F5F0005D28F1CAE1FA6A701CD73513055ECBD2DB -:10F60000F5FB1DFDA1DF948962BF974DF30F47DC29 -:10F61000A5AAAFC62D8B15ED40F7A0B7948986BE7D -:10F62000FA2BA9BE3E1EA5B28F5FEC5B1F0F7EB109 -:10F630005F23BD77E57D4753FE0DFAECD3429F3D36 -:10F6400053B7BB21097AA3C9971AFC2E56955FF0D0 -:10F6500087C55CFF01BF5822E5747B9E276762D097 -:10F66000FEAD7AE0E92C8FE02F7EF0970F9E7EE9C9 -:10F67000F7139C01F9A9E6BF68E36FCD15F6607832 -:10F6800089F5DD9BDD4B717695768B13F7972BD73C -:10F690005510BF6589FC5CA105F01D4A0715EB34C8 -:10F6A0007A5FACB2698CCFF83FC8972B37CDA637BD -:10F6B00091149ED47B274A9EAAF97F57CE7FA1A49E -:10F6C000E33913C5FE5B589D665942FB3ECD520996 -:10F6D000FA97E50BAAF4DFFBF0D4E75FCED980FD03 -:10F6E00081B8213A9F6C320B3BDFBE48D257CFAC7A -:10F6F0007CFECD9B79BDCFB7EE48857EA2E6B154A6 -:10F70000DAF3164BBBDC12A9B7723C5504E369E986 -:10F71000E3024F95CFBCF127BCCB55962EF9D97D8E -:10F72000229E7F51DB7EC2DB828D9BCD69BCDE8A4F -:10F730008969BA7B32958DFCA0CBE1B970E30E33B9 -:10F74000F8C08A89026EA1F45E26EFFB2AB842EE69 -:10F7500068417E0B551FFC6F3F1F67F50A5B14EC79 -:10F76000D36A9C47245D5736C6C462BCCAC68A9F0A -:10F77000E0DCA1F87DE8BE3B6513FB6111EF0FFBF8 -:10F78000F2D45417C535C3AFD59F5CDD2CF1F653C9 -:10F79000B378BF3139A2ED09C0217979B80BFC21CA -:10F7A00033B393FCC6A067CCDB6210EF3D66D67521 -:10F7B0005EC03CB84A4DF75390E29D29A8D8F13C71 -:10F7C000BFD320E2AFD28D227D5EC28797FB51CEA0 -:10F7D000E23AE9DDB9BE779342E8D5C2766DC47BE3 -:10F7E000379638E66A7106E853F5A3E853D1EF403F -:10F7F000EBFB85E423DFB4BE5369D21E91ED4A458D -:10F800009C4AF9FD235CB0CF7CD33A2DF2FDC1BEFA -:10F81000F572621D17DBCF7A33C5B965E0F56E2945 -:10F8200089EF67BDA1EB54FB44DD69EFF32FB40A08 -:10F83000FFC2298DCB2FDEEED40A1BDDFF52EB5227 -:10F84000F6EF6F1B87F0F6C458694FE88C841E5999 -:10F85000162EF7BF5FE4F17D76D07725F7D57B6D67 -:10F860008A3F9F6E94729175DE87FDCC9A32E87D57 -:10F870009293ADA722F15ECAA9A9627EAADD6AB3FE -:10F88000883366911627DE3FE4E7AB934DF0FBAC7F -:10F890004BA073E46D4D19C4176EF3C608FB83D4F7 -:10F8A000EF97483E18B1BA6203DEF95EBC2DCDA1D8 -:10F8B000F17116DB5D1F6FA3F657BBA00F466C9965 -:10F8C0006D4927BD579C03949F68B5C64A296E0CA5 -:10F8D0007C12FBCBF04A26E4CED26DE21C30CBC0CA -:10F8E00036C24F38ACA5744612F8C4C31AC599B3D2 -:10F8F000EDFA77ACC6E6979EA7F35FC83B70ABCD39 -:10F900006DEE04F071AE6FC0DEB4D85E4A7A7BBD96 -:10F91000E49327B774D17BF40AAE57C4FF58441C54 -:10F92000704FA481EC70DF360EA84AFA9514DD28DA -:10F93000BFD423F8CF78C0C94872ADC45846EF2968 -:10F940006DD8329DD2AACD255BBDA3107F5C1A3F36 -:10F9500081E66D263B5955FD7411AFBB332C06E78C -:10F960009B54B33735582FADDA7137C5FF7CBAC316 -:10F9700046F13FC58ED9C53171F4DE31C5D7A97ABC -:10F98000A94582EFD4D44FD7C5EF2CE67DE29DCDBB -:10F990002FDB22E87E988ACBA94BF024150D16F1B7 -:10F9A00039E39D222E2789EA3BFBB58BABF4E36656 -:10F9B00011E711146F74E302DEBEAEFED928F453D2 -:10F9C000FBE0DB631C06B2430D47FF7DF146DB44E1 -:10F9D000BC51963C2FCD8A2DBD7901E0FF6B23C130 -:10F9E0007FA0F1AA0F693A3FDE6DBE68D25B3D7E13 -:10F9F00066811FD9E360A4177F6A644DD00394FE2B -:10FA0000A2BE8F9770F934BA3515F4B16CCF43A903 -:10FA1000902F9F458A7CD99E5B7E037EE5D9152673 -:10FA2000F47313237DB8D22BF46B561DABDE23B5D4 -:10FA300095733A9A5E1421DE3DDAA68F3757EFDCD4 -:10FA40007E6612EFF320DE08F4FEBEC9BF18F87D13 -:10FA50009FEBAF38C7A61609FA7CBFD53883EE0DE9 -:10FA6000F18D023DE4FDD66723110FADF4B512E32D -:10FA7000076EBCFFB3F23911178CF7E9E9AD506995 -:10FA80000769907690952F986724C791FE455FEAA5 -:10FA90004C7E4B7FF8AB91FA555FFEC07E3AB7D5EE -:10FAA000ED13FA435D5B17E90F4A1F517187B5FBF0 -:10FAB000BA489F50ED1A0E08B8D41F10DF2BB20DB4 -:10FAC000CA8EE2D632719ED628EF7D31BF7CAD2939 -:10FAD000389F57BE16CC7E82B28FF4903E786FF678 -:10FAE000EFE81C5EBF4EF6CBF3E6A0F1AA414485D9 -:10FAF000E27B861DED9DBAF35DFD81186AEFAF0FC5 -:10FB0000DF0839EF6EB09B90B6D4DB49EE6F6F34EF -:10FB100064E39EBA5B0B77418F6B97F7B706D7BE4E -:10FB20006B83FD2089F51CC57BBBFE14CF0F8B7842 -:10FB3000BF0978DDC5188827EA3EFC493EFA9F3C9C -:10FB4000ACF322DED4306B53CAE1A7682992EBC82C -:10FB5000E9CC075D0F3E22F8F3A366B691DE6D3661 -:10FB60009532D8EFFDD2BFE8FDCA40EFCFB66BFEAD -:10FB70009F05EB5787247D9686093FE3CED19E4DA6 -:10FB800098C77735F3A85CBA77681C8EFEBBA51FB3 -:10FB900052E9A9D3247F4E91E72BCB90443BE85800 -:10FBA000DDB7D3DC6E8AF7BC2BE74825E4F38F7B07 -:10FBB000AC142F30AD279CF4D6942133499EA977FD -:10FBC000DB35A78995F1FA47720C7EC4C5FD9859BB -:10FBD000C5BD006B887E6BB0D1FD64ADFD575F8104 -:10FBE000AF271B2F1C8DC67DD97FD3E8FDD1F2DE58 -:10FBF0008F1F7D8BE13CECCBA578E814CF1EACE7E2 -:10FC000064EFCC2E0F47DD8F1D6D569790172C7823 -:10FC10001DED777C15156B08CCAFBBE7637AD7B1C8 -:10FC2000BBC74A76DB69EDF29DC390F974273AE9C8 -:10FC30009E34AF47FA66B7DD40EFBB4D6B3F4AEFEE -:10FC4000154E53EF195AF5EF1932674A0CECCA6496 -:10FC50004BE5CA417C8BC0DFE468FD79F1B522A198 -:10FC60002FBE56A4F5FBDEBD8A5B5172E565FB9E97 -:10FC7000DB845D4AECD3E5CACF7F299DF489DEF6AB -:10FC80008CAF7DC7E26DE8155C5FB8708DFBEDA2AF -:10FC9000C2805C9D27E1A4E4B38A5B9827E135CF5D -:10FCA0006E10F009F9DD154537A17411C0BB88F756 -:10FCB00052F8643FE83886782C8EC751F733C2DF9C -:10FCC00049C2DF57AFAFC7B30B438CEE2E4FDABF3D -:10FCD000047FF47EF7B7C65F4728FEFCB611D02339 -:10FCE0001E34901EA1EE3B7AE47BEDEADE23CB6668 -:10FCF000C40FCA8DE1642FF4C877DA391F38063E85 -:10FD0000A0F6FFB0999DA320474FF2233AE6D769AA -:10FD100068A3EFA993D269BF0E651D49F27E4E21FB -:10FD2000F43763E07D6AA2FB16CDF7F012DCBF9CCE -:10FD300067A77BEEDDBE90F7A9E53BE6DD4CF287D9 -:10FD4000F9EA1D73BE9F79BB2D0B4479DF3BE6C3F7 -:10FD5000199DA3B6E4B22CE85FEA777F067CC77CE6 -:10FD6000592CD94D1F79C43712F240BD5F3D25C5CE -:10FD7000933869F095EF576FD54A17E07760BCA3C9 -:10FD8000C47C3B17843FB34780DB0F7BCFC9A648B9 -:10FD90007AB75BD1A9B2730FF3763D0C38A9B8DA04 -:10FDA0003F4B7A53F05771857121785074E73533A2 -:10FDB0008AC3053E1067D4F7FB316B247F51719DD8 -:10FDC0002FBB9C487F9CEAC99D847DB882C399EC77 -:10FDD000E89DDFC37A1FBD23D28DF99D94BF6B11BF -:10FDE000BAAF8A261994BF98E206CAA57C2B577130 -:10FDF000024DFA3881D0774EC387964E06DCCE6925 -:10FE00006F8FC1C7D7FF8FB1DFFB27D74E127C2280 -:10FE100033D1336312C9B9693A7DF2F5DC4F52E848 -:10FE200077662E1F1D0AF9774B4AE975E8D79629A0 -:10FE3000FC077F4EEAA4388F3F2FF86B0AD99FD773 -:10FE400088F759BFED3CAF8C6B16F4B06AB1B89728 -:10FE500098CC1A898E1303F1B236CCE37F5B5C73C6 -:10FE600020EE782FFDBEC8CBCD6D19A787F783F79D -:10FE7000B023CF3AF9C9C67BF8E5728AFB8D3EB252 -:10FE80002A8DE7371E3E5A4E71BEC9472EA671DC39 -:10FE9000DC7BF85591BFFAC845C4056F3A7C4CD459 -:10FEA00087FF6008633F397CBCDCCBF171C768CF4A -:10FEB000FDC0D7CD971A8F411CFF7EED9CC56914FC -:10FEC000D73A3B255BC4B5AE03DEE7C52F5A1FAD5D -:10FED00005E25AF74D12EDBA2F887DD07D41D079D9 -:10FEE00018F8C1E07F3E55F1BD8A0F0FC42FD53EF3 -:10FEF000FC57C527ABFDCCF6B8369A418CDE7F3A6D -:10FF00006EF8C949B42E7DDC70B7B9E731F22B5DCC -:10FF1000604EF0895722DF75425EB4148AB846AD50 -:10FF2000A7C389FB18450522DF72A1C3093E8F3C98 -:10FF3000EC5BDD3122DE51C5C5B65CF027619F1454 -:10FF4000217E91D72FEEE929071F2DC27DDE34F4E3 -:10FF50007FFCA81C8FA1BF5D1744DC61B7ADC3E96E -:10FF600090E3A01F3E6E1AF863D16A2BDD3B6AB99D -:10FF7000D0B882FA29B3F78DAB858C6BFDFA71A7E7 -:10FF80006B41E366F68AF84E8CEBD48DEBA7B86034 -:10FF9000DE1FC59F76C7B81271EE57F96294F3FC65 -:10FFA00043F2772A8A9C7E23E4808A934AB0C8F77A -:10FFB000B8E5B985D7A3B8CC5DBD629DE79BFD359B -:10FFC000D84FC5926F175B84DC64867017EE639719 -:10FFD000182F1F4FC6F9E405713E290E2BDD8EFD4B -:10FFE000D86012FC86C5A9DF4BEB58F6735EEF773D -:10FFF000F1C9F4FB6243130FB24C9C8F97CFCC81B5 -:020000023000CC -:10000000DCE07AF719E0FB77AC5513BFC325DACFF4 -:100010009D1941F750BA0F8F28C4FE9913E67C8EC4 -:10002000F17DDB3BE92BDAA773A29D8538F1F41E45 -:10003000FE6F914F703E07FFAE957D45FAB9F2D73E -:10004000DE12F0D7FE17C6A99F79CE22F4B31E7A2E -:10005000A7F9BF2789F7E9B8FE4EFA47CF75F2DD59 -:10006000CD1C6721CA53CD3D51805BF7659378B7AE -:1000700096F544DD14E49F7DAC5DBC671B4AD787D1 -:10008000270B39B03CD34EEF9D35245AAD94B65F63 -:100090009841BF07632ACDC4F9C06DE9DFEEF88B44 -:1000A000C9425EA56DB004FCEF5C7EB8C399CA7B03 -:1000B000D938C6767C3FBCEFFC051163192ECF639F -:1000C000DEC4C78B4DBAFA6ED4EF2B67E29936D5F2 -:1000D0003EE765FBE3EB4C723CE07989B83F112ABF -:1000E0002F1AA6C4F6BD57487237CE46F7AE328DEA -:1000F000D29EC7EB3AC82E28FCB7C9FF61A338BA15 -:100100005D364187990691EE32C8785F69EF53E713 -:10011000981F4FF14C9A3298FAF1533FC6FDB9D06F -:100120002B92581B8DAFF433558FEB61366232F250 -:10013000F7DE8A8C867EE1F9CEE4A9A5930B41D740 -:100140005EF651909C381F11D5148CBF06A3DEEECD -:10015000F9CEE469D44EB5AF6F9ACE3EA278443F53 -:10016000D14F7DA681CEAD0D46F62AFDEE00EB20E7 -:100170007FA66AF72EE7931FD1BB0D6E4ADFE3FC23 -:10018000F223BAEF379FD20F9A3DF4FD647335A581 -:100190009DCD8DF4FDC3E6264A6FBE35B200F4BF97 -:1001A000FCD05AF651907CAC6F337B82EFD7BC3BCE -:1001B000B57F3AFAFE64E1B77937ADFFF2FB55F946 -:1001C0006481CFEEC542CFE474B9CE113BB0BED04E -:1001D0001D29EE25BC344D9C5FBB9344BE71B278A3 -:1001E0002FD46D60DBD0FEA56916CABF9B6EA077C9 -:1001F0001DDCB1A2DF77B30CA4A75D3F636A03E007 -:10020000E48EE7DFF302F977AF12E5EE21E2BB9A65 -:10021000AF2A9F34A5CF8E9025CEC7C2FFCEE99DD1 -:10022000FAEFC36FB1985F687D759F3E141EBF954E -:10023000FB96F605F477EC83B4A07DD1E0A47DA114 -:10024000E850D15FC314B15F33C3249D73D945F027 -:10025000830CC3F938C146FE4137FC177C3DBB64B3 -:10026000BCFB15FB41FA03D47E50FB40D17B32DF4F -:1002700067C2DF21D631C9D8BF9DFEA1C962DD1D8D -:10028000F191A41F77B79B1D9037938CC2EFD0DDFF -:100290003EAF00F7C24BEEB637F6C7BFDE94EDFFB8 -:1002A0006938287E30001CAE58BF45DAEDFFC1F535 -:1002B000137F03DF5E2CEE6586D26BFB64657717D8 -:1002C00074FBCE64F741D04FB76633E19CD26DEB3F -:1002D000FF1EF94BD3C4BE50F4D33085C97768F8FC -:1002E0003A33AEE4776A3D7DEB5CCA88EF65CA7845 -:1002F000E350FCAA7505F1BDD7270F0EC09331AEB0 -:10030000AFF07E86D6D9E99CAAE8F7FCE0AF96402C -:100310007ECD9FEC147E268351BE072BE449DF7708 -:10032000CD487157417286416FE9392CFC717E7E50 -:100330004E823F0B36E8E0B86BCB14B1EEDEF985A8 -:1003400006D809CEFFC5EE85DC3A3FA4E724F49237 -:10035000F3DBC47BE7BCC7591AEE8D20FEC789DFEB -:100360006D117E10E3C35F9E843EB4E46123E92FE8 -:10037000E7716CE6ED963F287EE74EDD1FAC93ED0E -:100380005AB65DBC997EDF8CD327F49F8F6C0DE944 -:10039000D08BA73FFCE009BCBFBEE4390DE6667612 -:1003A0001476779EFF78AF51FCCEAA8C3B9921EF53 -:1003B000F7D7EC16F7FBEB106F02FDE5C08EADF83A -:1003C000FDC9FABD6666E3DF67E09D343ECED2B676 -:1003D000487E90E4FD6ED1C78D5ECBBC1B604FAEF6 -:1003E000DEAEFF5EB34B9FAF0BB9B7A84D91BF67B1 -:1003F0003092E5D2FDC42DC25EACF8F695FAAE9708 -:10040000E0EB5EA9EEEB7E41EF7B1B0F7F99FAA13B -:100410005DE467CB7C17CF9FFB52C05FC1AD41F25B -:10042000FC7349ACA08DAFAFE1B0CD013B40C30B35 -:10043000C24E70BE2D9AE0BC3CBC93FC0AEC45A3B6 -:10044000037AD83D878C6457A86FB7FD0CBF4BDB90 -:10045000F09C46EFD5D61F0AF309F85C5882F2A546 -:10046000876C0E27CA5F0C63B03F9FE778C3BDD887 -:10047000F3299D847FE0157609FE370BBF5FA1F05D -:100480006F7C58F893973C21F1B36D9589F0EAD3CE -:100490005842DA95785278FE95E1A93E3CA1DDF408 -:1004A000877F7F5CE29D21DEE6E8B64AFA5D0C8537 -:1004B0006FCBE18F52A1F72A3C1B399E7FA8DA3B14 -:1004C000E57B785F83E76AE0D9FE8FE3F98F908F51 -:1004D00085A4F77EFC53E8BD9116F2A32BBB86B230 -:1004E0005B0CAE7DF7581C1F7878E2B3A4E796C783 -:1004F0009EA95FC1C88E76ED14D8D1AE7B033FEBC9 -:10050000CB7E77FD53B9A08F167327FD6E8C3746CF -:10051000BC2BDF9D367BFBF37CBCE2D8AF52F7638C -:10052000DFBC1C46EE93B9725FE2CF1AFC2E60BBB3 -:100530008DEC6DF5ED61C2BE7640EF3FEB4E12BF24 -:10054000D35762E9295F01BD9CF78771D479B0B6B2 -:100550005DFEFE8B3CBFD52A3BC3BE90F7A11C6F4E -:1005600050BDBA2922DE36236192137CA86501F3BF -:1005700084677C1DBF67C4EFD5EFE50DA8070EC0EB -:10058000F795FEC7BC7A3B87E23F4BE5EF4BF6EDB4 -:100590000F99AF5EEB8DB21A89EEE8DD86BA47C5DA -:1005A000EF2B7E02BA8B0AD053838C4F3BF6FDDFD4 -:1005B00098F03B4DDDBBC4FD08CE21B7E29EFED9CD -:1005C00036110F5753D035C6EFC4EF74083EB46CE4 -:1005D0009FE673A6F54347CCB741BC6B1F424FFB68 -:1005E000BEFEDDC37B037C64D4DF393C77943029C5 -:1005F000B7BCFDC64FF6C9AF90DFF1F8DF16CFDD0F -:100600009BC3D7F335FEC66B13F5EFB85CE7D4FF99 -:100610004ED377B2F5BFD3D46B97F091FAA0D253F3 -:100620000F4D11723C3455F0BDC1A51F479D8BBFC6 -:100630003B4E3FDE6CB77EBC6F8B977F555CEB37D4 -:10064000C1EFB81CF7841CF73772DC7F164E2A1DE9 -:1006500068BCFF5FD3FF0B8D21EA0800800000001B -:100660001F8B080000000000000BB55B0B7C94D5CD -:1006700095BFDF7CF3CC7308210904C224242160D8 -:10068000880324542B94C9D300D6065C2D688401BA -:1006900052C83B80B5D2D6FE3208222F5BA8D1A229 -:1006A000224E82E1A1613B118289863A286411AD14 -:1006B0001B698BFDFD56DCF828F23213A374E55755 -:1006C0005DF6FCCFFD3E321942B5DDDDE4A737E72C -:1006D000BEBE73CFFB9C7BA929CE317C394588DC1B -:1006E0009873E69E08215CAB7A8A12B385E87B4357 -:1006F000154D0E2184DB7BBC3E5688DA8EE16253B9 -:1007000032C1257D6F1A00B78DB36FA2F18DED7FD9 -:10071000781BE3BD07558785C65F6BFF280AFB5C26 -:10072000FC325C88E158F7519420B8FAB2C2F02646 -:100730001A77103CAB5515FE4CDACFE83363FC62F8 -:10074000AA0E7BCD82DA929656730FB5557B5B79F4 -:10075000FC0D9F69F0F8DEC641E376CCA7B6CAE887 -:100760008DB2537BBE5DDFCFCFF3AB53159717FD33 -:100770007BFF10B70CF35ADE895B4AED15FCCCBC4D -:10078000B6FDF4D00B996E5A57D341FB440CEC5391 -:10079000D361D2608977756A6B510CD14BB4282232 -:1007A0008D9A8B62AB584DF4AC6A6FAE16D45F95E0 -:1007B000718F49105D023EB518DFA71F8388A375AE -:1007C00076FA8BE877D1F779D452DAF755DFB1DBD7 -:1007D0005DD4063A5F8FC2770307697EE6003ED399 -:1007E0005D44BF1CB4662146D0BA83AF4739687CEC -:1007F000A3EF75496FA39FCFFD9A0607A8653AB787 -:10080000AB7CEE8A2F55A6BFBEDFAD2E95F799D5EE -:100810009E1689739DF4C9EFCD7539647FEAE23283 -:10082000E07F2261418E9ACC78BB000726CE69DE3C -:1008300044A854F968DFCC6BE9B654DBB7CB24E6A7 -:10084000FBC0B7D4035DA3483E4E140F9F4C235703 -:10085000E7DDE332F0BC22B33B7505CD3B19E188FF -:10086000B4D37E0F158F8B045F5F438BFEE25D6612 -:1008700037B59507E5F74EDABBA3206F270F4E5526 -:100880003DCAC07E776ADF15C2C3ED00DF3CCCA74E -:10089000726F6304F619E09FEC9FEBB2F3FC13DE7A -:1008A00077EEBA87CE773223DC09BE749945B98FCB -:1008B000E5843E82EF752636820EFAF7E6821FB493 -:1008C0002E906160BEF6B69BB479F7348B41F34C41 -:1008D000CCB78BCF0DC6C7EEFDE097F7D0FCEA672B -:1008E0005461A1EE6AD38A389CFF931D83F12BD704 -:1008F000E85C6DF2C7C505C96B75C7557D8960F9A0 -:10090000EED0F5C3C1FCD4F978324395782558BCB4 -:100910008250AE6E6D66B92675F3D8A6702BECD4F6 -:10092000268677272B74FEC407ACCEB584FF738A66 -:10093000366EA03686608384CDD45AA97DC624FB4A -:10094000A1B6583F86D8A9106C2A1E976348A17D8E -:10095000D4D6C9E0EBAB335D8FBA088FCD334B668D -:10096000CC043EA26F99A06FD65C8AF08868210AF9 -:10097000D5F79EC077FB0F9A04EC478DB5A3F263C1 -:1009800092D37E27290AE1DDBFC3E4F5B0FCB9228A -:100990009469422CBB49EACD270EF734751CCD5F14 -:1009A00063E0F355B7A85E1BCDEBAD271210C93F2E -:1009B0006D4DFE01E4B5FAB86AB7D2B9F37DC9BF8F -:1009C0009A0EB8C5E4B4D0FA5A1F75125CBB57F141 -:1009D0003AE4FE027A597313CBBA3863AB4D11591E -:1009E000D4AEE93363DE99C38A788CE66D0E8B6AE8 -:1009F00002DE3599B3CF2951D4AA5BD627D27ECB5C -:100A0000B79B3EECB1CAB557E8BFBACE6D2CB7154F -:100A1000DEC1FD557B07C335C23800D3FECDF8E3F8 -:100A20006621DA5C91B1676EA0BF2788095754D060 -:100A3000697A3CF4E104F84AF2241A88D82385B88C -:100A40006F92331E7ABFD1E8980D3A043A4D76D0B2 -:100A5000ABEEF0810AE0EDAD0E731AE8A8B5AB5F1E -:100A600061BA06BE20BADF486D82E0F30784A46F46 -:100A7000A05DCA799D49F15AB19E68C8FB5915EF2E -:100A80001A1A0A78FAA3D83E09510CBD58B520C7E6 -:100A9000003B07351684CAAF747D506C46251AADED -:100AA000D4FFEF197BD4614176E23F5D298C7F81D1 -:100AB00059B87DD47F5FA4331A723FD61A9505BC0E -:100AC000C65A93BCA0FB5863DF1A7C7FF328C5F19C -:100AD000106D7D24EBE5C90AE0DA0827E4444958A3 -:100AE0006C043D368F5A6C84BC8FB5FB324A32079A -:100AF000E0028C431F8497BF5714E136E23BCF8D51 -:100B000054FC06DA3F6023FCA02746BB09F8054CDD -:100B1000121662CD20FCC82231FCFF8E9F9DF08B07 -:100B200018C08FF81D8DF59F67137DA84D9A2B4433 -:100B300037DB85156C17747A5E24792F205EA52922 -:100B4000526EAA771C29C2788DE85E8F754551F2E6 -:100B50001C45380FE030D9AAB9925FB95A7B7FAEF5 -:100B6000F42FBAFDECC8751973A9DD9E5B62465B74 -:100B7000A866C6F70C61EF5729569693CF49FF60D8 -:100B80008FEF5DA1D8533306E45BD7AB3AD97555E7 -:100B90007FAA7EBFCB2C52F0395777068D970BA9D1 -:100BA000D78B56DBECA9C17A043D237A94DB2B6EFC -:100BB00013A46FEED571F6D4A9D4AF5E340BC89EE2 -:100BC000A65FB1F47B256508FDF285E865FB60D87A -:100BD0006F9372EE8F54BC6B09FFD4DCC17A97A47B -:100BE000E941A35BE1F3357E6564D853AA7841F30C -:100BF0003BA973758C7638CC2BCFF5C23FDE4960AC -:100C000029FA1B62594F7990ECD7BF68E7BCD3E84B -:100C10003F02FB71CCE44BB6D3D0B11AAB13FB2F20 -:100C20001014E8905D2B15DDDC9E0AAF6DF3F3E642 -:100C30009E3190AF77DD1627E2B0C6754D91B0E3D7 -:100C400059629DFD4C06820AB1F7CAD4EBC7332422 -:100C500038E28CCE1738628A53C06F9DAFDB735D6C -:100C600079B939D75F5FF5A7B6DBBF03FB757FB3F3 -:100C7000395E8A4977C6B401BEE97CAD131EC65BF6 -:100C8000E7D755FE11EEA3410FF5E25CB633CFAACC -:100C900082E30A8D7F56FA1D8A7F3A7D676A7C5807 -:100CA000DE21ED51285F757AFF9036C4F7C98FEECB -:100CB000607E080BDBBF50BE7F135F28C22CC5507F -:100CC0007EAC45809F8906691F1397919C10DEF7C3 -:100CD00008F7E11E6AEF0A7FCBC472A8F1E75EF065 -:100CE00087A6BE2BBCDFCF48FEBFE34F476EC903CC -:100CF000C17A18AA77D7D3B36A87F3DF75BF47964F -:100D000086F42B443F43F44FE7977B7514EBD9559A -:100D10003EAA2D525F357E45D0EF90FA863FE87BA4 -:100D200035ED8AD79FFC2DF44F21C4896F8F85E85C -:100D30009DCE9FEBD91DDD4E9D16FE63763AFFA931 -:100D4000141907787E62F136034E3794C3EE9D9AEC -:100D500028DB039A7D0B6D4F539CA3901FDB94718E -:100D60007204FCF529B3BE8FCDDB4CF89F5ED33DFA -:100D70006625AD3F9D2BDB53880B83605798580445 -:100D8000BB7E7AA4C5033A9D5626E4C13F9C561EFD -:100D9000B85DC2F16607E005F17976824F99E47C8F -:100DA000DDAFE8F6FFF482EF14F03C451C053D1C76 -:100DB0008A28E1EF284A4C31E173FAFEB4296BC569 -:100DC000C0F99B720DBCCEABD96FC283E9DEF7537D -:100DD000C5DB445D8BE05208FFE4BCDF14A750FF85 -:100DE000FB3F1B3719FC75AD1AFC7DF8EBE41B01CA -:100DF0006FE37DBEF7659F6971905FBAEA270B3E8E -:100E000093FD653906E84BB9C64357CC8468F0A713 -:100E1000DF3B2E1A7E47F743FDC70F44B883F876B1 -:100E20008EFC94181F044F783429D88F1DD9BD39F2 -:100E30001DFB949B3D594EEA3FDBF87412E28DF2A4 -:100E4000DD8FA4731CBC7B633AF299F2A6CDE92E28 -:100E500086C3DD9C4F19E5B92FECBF79D7A6A0B8A2 -:100E6000BB2A5F65FC4BAD470AE16F67DFF0E9C362 -:100E7000769A97F633C50EF1BA57743F0CFFB81047 -:100E8000F131F2B7062BDB73DACF05FE374FF8FEF0 -:100E900073D0E313191F99CA68DEE55C23D367A1F9 -:100EA000F06E89A771B141B1378BE0F9631A317FD8 -:100EB000F13AC59C003BB062D864D58175C3188FE8 -:100EC000251B2677A17FE183B27FB6C57BF024F690 -:100ED000F98DD9D9EC607B9352326900FFCBB966AA -:100EE0005EB7688BC2F1BFFE9DB427E21A83CF794B -:100EF00059E3BFF8CAA2802F3FD0F872DB83EF1C02 -:100F00004DA07DEDB1EE2BB01B6F3F7E26D54FFD82 -:100F10000531E73221E76966F75315387793C589BC -:100F200073646725AAF1347FCA8F731F43BBE8C17E -:100F3000C54F55C0DE6EB772DEA6E3B74A711A60C0 -:100F40008F5F6FFCE112D0EDECE3568EDB57358EF0 -:100F50008F1743E8A9DEEE21FE3B28D1D9576FE574 -:100F6000F6857ABB70903CECAF4F60F8B7F50E6E2B -:100F7000C57C295FABB4FCF87AFB4DFD325C3828A8 -:100F80009ECDDE60130EB2534971AE517974CEB46A -:100F900089354D1BB573A5D1FAC99EE47CD0217B60 -:100FA000E3CA2E84BCE63C998FBD797243128CF261 -:100FB000F2073FD85941E373F34AC6E551BF75C7FD -:100FC000675C5778BDE39185A0777993459E4F3B49 -:100FD000F7D9C7D3E39FA2FD3D6F9838DFAFDBF1B0 -:100FE000C1CE8DD42EDDB2D21C2CEFDFF6BCC91AD7 -:100FF0003EDFA457D7A3C33FAE579B93587F9A4871 -:10100000AF32FF79BDAA7B700DD3EF81BC92D9A01E -:10101000FB59932709FA7476C20C9673CF6185E960 -:10102000AFDB717D7DB176DE2A836FCBF4E4013BCB -:101030007E4964337D8F747C928EB8F752FB82BFF9 -:101040007BEE43746E3F9DBB9DE8EB1F7FEDF83454 -:10105000B37B9C93CE37CD20E3DD6BE2D63C835649 -:101060002FE83697444A9A2BA8CB68FE93FC982722 -:101070009AF0A9EE54FC6159F067B79E3322DFA3C2 -:10108000BCF1C3E038827E3E0CF2DBD7C3F79BDABB -:101090005AEC93366077BFF36783F007F9E99B7BDF -:1010A000C2843FE8BB57F313EA33139F7A3B46B23F -:1010B0005D00DF8CA8C7754C68027CCE2CF9D87B0C -:1010C00088E22659C711EAB481739EEBB890053BBC -:1010D0001B7ADEDA972FB07C54B73FF299C2E79FB4 -:1010E00075CE98F5CDE73FB2FB4216F877CED433F4 -:1010F0000DF956AFB9270B7CA87D45DAF37F940E26 -:101100007A7FC5063A08E979AD62653929542F72AC -:10111000DDA0F7B8AC1BD476EC627BDADF29EB37C5 -:101120007586EEA278D43B567CD0057BD69F20F303 -:1011300028DADF05BA4D1FA7F941635FD25CB26BB5 -:101140002F5E950799FF9D85FE8EC73EBE6AD8012A -:1011500091152E10579C873E53FFC2D5C9EB21E74E -:1011600067BD23A6C03EBE99F5B75AAEF7BD1A6E4D -:101170005739EEA1DE20FE5D3D875715AE41F58063 -:1011800070E10A9A576776FC80E3E313AA405C5744 -:101190003751EA937859EA53CDBA23E684A0FD7615 -:1011A000429F186F192FCE7EF56FAC975B66BA3AE7 -:1011B000A197E1B085D82F21DAAB28DA3CE27FADE8 -:1011C000864344A796F717AB3C5ED7AE8A915893F7 -:1011D00010E94DA373148BAD46C4D3B3856F3AEABF -:1011E00036C2D8F3CB5B687CCEABEAD44D82F3A792 -:1011F00045259C57BA5357213E32281A5D7DD97335 -:1012000083FD599EF453D35585FD58DFC8708E5326 -:1012100066CDAF2905BEFABCAC61721EEDC37196F6 -:10122000F0F665CD857EFAFBB2E6450ECCBBEBD57C -:10123000F015EC17852FFBAEA0EF84E5CBFAE8E7BD -:10124000E4472027759764BDA350FDEA09C4E7ABC6 -:101250000E93BC203E3424BF6B801D273A83AF170A -:1012600088AF2EF81FB770B9A03F934678A13F759D -:10127000FB1561449DA8C3D2843A52ADA9270EF252 -:10128000BCB1FD4F66C8735DDB3B66C724AC977588 -:10129000275248B6E3759AFFAA691FFF2EEA7C35EC -:1012A000C7A517AD31BEC3F97BD5C156CED3AB852B -:1012B0009FF3F4EA96C1F2D29FE0E0BA48A87E8498 -:1012C000E53B06E9C5ACED522FEE52C50AD839A16F -:1012D000D5696725C4733C32B04EC6BB2EF5C2C378 -:1012E000885F02298A53A1AD02619E75888B3CE913 -:1012F000329E09FCEE85EC656C57BCD977D0B902FB -:101300005ABC3B6BC336A31A84CFAC4E59970C849E -:1013100089F243CC6FF768F041B84A22F27358AFB4 -:10132000B26057030659470D3D47BD562F3A817AA3 -:1013300052E600DE731213A51D135E969F2E83FCEA -:10134000BECB40E35306D62FC997EB07F2215907CE -:10135000BB9E5DD94DFC2923FEEC253EA37D9EFC62 -:101360007119D99916F2C780FF95FC315A5F7D0635 -:10137000F7BF58EF64F860FD4D0C1FAA7731DC5EB3 -:101380005FCCEDCBF525DC7F02A87E17FF7BBA1181 -:10139000F2D0051D1B35009F8A0981470D9E7F2ACB -:1013A00046190C8F52787E76FED38D1ED48B66DA6A -:1013B00035FD764422FE3A6B9375A8B33659876A99 -:1013C0001DE5BE259FC6CB66ADDD2DF350573AE631 -:1013D00015C42CE0FCB59FF257D8A395F9EE3CF06C -:1013E000E5F8F1FCD46D6C276D5C073D75F70DD108 -:1013F0005C077C83F271FA746EC6D475D904E74633 -:10140000282CBF642F6E2CD1F34ADA27BF53DEA3FA -:1014100014AAD565D87FD548DB54D8DFCF5DEEDB85 -:1014200080874EEFA251CB53110F75991CEFA28EFE -:10143000EBF9BD49209FD2EB7DFABC0E57EEDD588B -:10144000372B63DCBA29B03BA464B0732EB36801B8 -:101450005E2E43B8B296ED96C3083B70B726C779A7 -:101460000E1917FBCD0E630CEA3761B9B11E5AD7BE -:10147000A5F1F9B8C6E7131A9FDF429D8CDAB7A928 -:101480001F6D37F5A39D01FA4A7965BA3D91575210 -:10149000C6F22BFA9200EB75C1D9D02F696F92205A -:1014A000D75B34F94DD0EC4D576E49955CE7E37D41 -:1014B000AAB47ADB05ED1E443FAFBE6E60BDE07698 -:1014C000DE8DC263859D7F49E69D6234C52304CFCE -:1014D0007B299EED906ABD23F363D2F37953651E99 -:1014E000200E58E4BC04470EF464AD566FEDF51AB7 -:1014F0003C26D4A763BAD363E07F35FDD2E143FF36 -:10150000ADB2BDAE994230B5AF28F27C35F3BAD357 -:101510008761BD6233707DBB498E9FD4F4AF264591 -:10152000DB4F3B8FB0FA92C08FC0E197929610BC10 -:1015300029C2BF4CDA7D7F3ADB6BE14F9F07BBA826 -:10154000F8DE174E8A2B0BA62E318E043D7C3B0114 -:101550005717E42C31DE8CF1D6F7EDC1E3237C493B -:101560008A1D70B61C1FD1BA7398330836BDF83E79 -:10157000C6CD869C250504CFB1788FD7436E7E2BD0 -:10158000E5CBB6BFED0CE856D521E3F6BCFD6D17F3 -:101590005F845F6E8B74C2BCEFCB4F667AAFEDD8C1 -:1015A000B305F2D6DB2AEF0336B5FC69E7CF799EA7 -:1015B00005D724B4AF2F5BD077561EFDE362E0352C -:1015C00027DCF705E0878ECE643CE70C977AFDC8F0 -:1015D000D1BC25D0D3DEB6FD3F81FECD89A68016D5 -:1015E000F8BC60E33A44E5810905D0D3DEC8EE8556 -:1015F000D8BFF6798B13725A79203E0FF58143F9E3 -:10160000B21E5E31716B12FCACE1E57DBB7F8EFBDF -:10161000D5E76D7C2F541723E3BC4AB571DA4AE64F -:10162000DFAEDD4F03EF7D36BE9FAD40AD8AE08A71 -:10163000DD695CC77FE5EB8F16820F85EA8EDDE8FA -:10164000FFE2399B017438697645CF801E9E347164 -:10165000BE59A1C115A7864B7CC27B8A987FB15B1E -:1016600093E0672B87FFF476E03D47DDBA13F98EF0 -:10167000D863E1BB8973FB886EB4EE5CB3690AB8CA -:10168000DCBB2FD20879B9A06C5DF814F66F96F325 -:101690002ED8B6323D3DCDE305BE47F304ECD6056A -:1016A00065DBA0FE73CD7BB2908F9E7F7E0EE7A59B -:1016B000BAFCEAFA52F99C65905F644B40F6A85276 -:1016C000FB5BD83D2282FC6D85069E3FF464EF53A0 -:1016D0006260FDF91693DF4C34AAB08875D6980184 -:1016E0007DA84CBCB518E7AB3434A6236EA998DAB4 -:1016F000B3107A71CE26AC0934EF4DCD6F551E5C18 -:101700003317F1EFF5F0B9A2D9A34B09D27F5D6A87 -:10171000B77983EF2543DBF7EA85FDADB401F8DE49 -:1017200015168EE1F5FDDE34FBAA91A7D5C648FB60 -:10173000F13ECD6F213BF6B5E6EF16AD1E3CBF3F47 -:101740003F86BF5F6BEE4987FFD3F70FE46B7EC325 -:10175000D8930E7B15BA6E0EC211D8911714B6230A -:101760009507950F54A253A5D5E355411761D6CFE0 -:1017700069BCA2C87509D334BAD3DA0D05C9FCDD3A -:10178000CA169BCB46EBAAC27AA210175547F6445D -:1017900021DEE97D59154D1ABB62E334FEA4682CA5 -:1017A0000BAA3756F84C2E5BD6107C46FC44F396B9 -:1017B000E36FFAFE3305297C9EF2F670FE9EB0F7C9 -:1017C0004C839C96EF18BC0EE7B207E95F6FFBAE47 -:1017D000B8E0BC3C45C33BA07CC07A12F8FAC324F5 -:1017E000F0BDD220D6E1FEF23CADC1BD26C1C22A79 -:1017F00061BEF7ACFC6B4418E4E5FCA56AD6DB5E81 -:10180000A587EDDADB0573D92EF59A7AD8AEBD7EC1 -:10181000F42EB60FBDC37A16C24EBD5DB05C8E8F7E -:10182000EC59E8A0F1FD3A3C46B0DF7FEF680DDBF4 -:101830008F39AA7C57217699ECB21EB4E1543DE76A -:1018400017264770FE7DBA40ABF70CF087F32E5D8C -:101850006F7A8563FF41E8617904D775288E6A79CC -:1018600011F1DE823827DE6B94639D940373F07D63 -:10187000636CCCE565E0CF1DA3DD450539B8DFEC31 -:10188000E13C82A49AFD4DEDEF2C9C4F064C7DBBB4 -:1018900061A7D247BB6717101ED5E6EEF5D984D2F3 -:1018A00045534F174AE4B355698FC41E2957BD9954 -:1018B000BBE43D8D765F79B7467F41494C23E442D6 -:1018C00091FC7DBDFDC05BB02BBDDDE3D81E87EA7A -:1018D000CDB9F6C7A2601FFE4C7EDC1394EFFF79F2 -:1018E000F11EBE679D8FF720D42E5937581EFABFC0 -:1018F000BA83F33EB125A81F72D830180E9523C8BD -:10190000A37F90DDF130DDB76B7A5595D75D0B3A4B -:101910005C85E711AC06C1AF85C021F345898C1306 -:10192000B6C3FF133DAAC7F84F719EBEDF2460C740 -:10193000D792FF62B82DDC8B7CC5B09FFC53ACF412 -:101940004FF00B5551DD5C9FEA6DB3F07DEF431D09 -:101950009F24E1FC24875C87A9EA78290EF9FB3EE5 -:101960002D5F203F18C7EF63DA3AE29077E8FDD5A4 -:10197000065F3AF0A28888E375BDBF46F5A703FF6E -:101980002AA53B0BE3FBF2EDDA7C8255C082CF51F6 -:10199000AD487D171D2ADBF350BE3DA9C92BD98563 -:1019A0002C7EDFF1B2AC0FE876A042B327AFA13FA7 -:1019B00053EABD5DBF57A2A515D0F721EC43428184 -:1019C0001E17AFE0FACDE3050E096BEB795F595FA7 -:1019D000E2F1DA572E64A564629D362FD80E8D1B76 -:1019E000B02BD0FF04D6FF874C7174AECA9D8A73AA -:1019F0002DEC54E99A229A2E961B571671DD4C78DD -:101A0000386F0BC52B548E2617483A551A8615C6C3 -:101A100006ED779E6C7AC214B6337ED89D1FC53E04 -:101A20005A843AC50F4BE5BB81ABFE2658CF719E59 -:101A30001DD28E436DAE18AE95E3E52B1AD7C70FB6 -:101A40008147289E15EEC6A238C7B5FD3ABEE76DA0 -:101A50003A7E79A611C17498BFA66804B5CBADFFD4 -:101A60002C1DE479CF7758FCF0AB15A52BD7470F89 -:101A70002137D7F8831D41FE2B05FCF5F2FDC6F595 -:101A8000F00F6DAB15FF29D48B04E95533EB17E943 -:101A90004B905FB8B920A4EE50BE782CE26AE15EAC -:101AA0003C167E86F46AA17388FC920CE42803BF7E -:101AB00019F1701B8ACF5F0AE4BBA49B0BA49E6F35 -:101AC00099E90AC06ECE500D1C8787EEF765818CB0 -:101AD00027BAE322EFD7DF7380D9335449B74443A1 -:101AE000FFDBD0B7C4B84807EE830AF3C3E5BCC335 -:101AF000363BEA3781C397B9BE1B783862BEBC3724 -:101B000088102369BC2B615253B01FF975A13C6F3B -:101B100078B68C5BEA324C7FBF3E941979B53EC4EF -:101B200071436638DF97F4B67FCE7E2BD09963C7BA -:101B3000BD466F376587A44F755FFF571CFC6B6F01 -:101B4000E75FF81D5AEF579FF0FBB48DDAFBC0D763 -:101B5000DAB5F75DDD8E48F4078A3F2AC2BC4D5ADC -:101B60003B502790F562BDD5F35FBD1E1094078FE3 -:101B70002E1C3A0F8E714704D7091CF143D55582AC -:101B8000EB04A969B24E801675825493AC130046DB -:101B90009D002DEA04E8479D0030EA0480512700AB -:101BA0008C3A015AD409D0FFC57CF95E2640422CFC -:101BB000EB97116CDFEF6B56BD88CFEF3B2CEFA19D -:101BC000EE6B54F89DD645FA3EFCDC35EF750E6A97 -:101BD000EF757CDBF85EAFAE4D75825575A6BE63C2 -:101BE000A8EBD4B52ACE35B02FF5F3F9FB1B3B7328 -:101BF000DE2D457FB3C96970804F97E250AFAAECE4 -:101C00006CE6FA5341FC6133F3B74511A897DE65E2 -:101C100091796E8D4ABD53F83E94E3E01A4B37E755 -:101C20001F557B157B59F07DEE4D9FB11D586B8B79 -:101C30006A029E353E9BBD6C88F71F7C2FEC1057C7 -:101C4000EF9B97C929A226A288EF9B97E19E995AFC -:101C5000A17E65E4FB634A4C87431EF1AE2A03660E -:101C6000DD2EF53EE43D556567EBFA4471ED3D34FC -:101C70002A03E07FE8FDB3BB3032F64C380C859880 -:101C80008CB8A9F8F1B2FD6DF4BDFEAD168E3B56D1 -:101C9000E6BB97438E8E995C5C273976D8C6F9D11E -:101CA000C7DBC60FAA937CEE725717F2FDFC68AE35 -:101CB0005BAC3229EC97F38BC7C5F3BB81E326F607 -:101CC0003F1DAE925ACC5B35C9C1F5A9428BB89F76 -:101CD000F7D1DE6951CBFA54B856F11A085E2C9C44 -:101CE00066E8CF22221BCB8B296203DE532D12F232 -:101CF0007D832E37ABB6291C1770A1200EF7929268 -:101D0000BE8B3AFFED32DE2F2CB5C8F835D120EF6F -:101D1000B31337C9F72D3F126E33FCED72F28B68A7 -:101D2000C94FFEAE87FADDE1A393647CEE88C7FE5F -:101D30008B4F98F8BD6F61FCF7D3DDECAF0BF81D4E -:101D400083E2BF47BD72C3F5F527F41DC33193B4D9 -:101D50002F4447CE8BBA20975C9F71737BA2BE9CA9 -:101D6000DB1933A59DBEFA2E91786407FEE17DEF65 -:101D7000235F4C8C8F74C2DEE97A7FCDFBC430D9EF -:101D8000EAEF13C7502B82DE276E713978FF44C308 -:101D9000C9A90ED0E3AF114ED0437FA7B86566C97D -:101DA0002EF0C915253CF82EEE51B6125D8B701041 -:101DB00005756E9F4B45DDFAB062E777D1D7D8C97C -:101DC0006D0FE31D4F5DAA62571CA8876F2D8C23F2 -:101DD000BC8B529219EFBA76592F650AC5A19EAEF7 -:101DE000E983CBDD563862A07F8EA617BD345FCA6B -:101DF000C92D5EC8DBB7A8A33E87F91E6173366B99 -:101E0000F91AF83EE786315C4FD5E5A6BF25BE0935 -:101E100072F346A1F433A5A5EF98100774E5BA8FC5 -:101E2000E2FC0BCB3E7B388ECF37741D8BEC28DF6A -:101E30004B86D6B174BBBC5BAB83C37E1AB53AABE1 -:101E400051ABB31AB53AAB51ABB31AB53AAB51ABD0 -:101E5000B31AB53AAB51ABB31AB53AAB91EB772B9A -:101E6000B87DBB7E35B7DDF51E1E0FB2FFEF5DC737 -:101E7000FE87D6413FC2BCD03AA8B03AA2D98F92D1 -:101E80007ECBFA7348DDB378F8920D44BFFC06B3FD -:101E9000135D7A1D14EF97EF8B607B70B170C8FAF9 -:101EA000A74EB708AE97F60BDB14D03F2F639CD13B -:101EB00040E37FD5F8A0D71FA11F381FF4032DF4EE -:101EC000C39836A01FCF984985B3A5BFF7B0BFB759 -:101ED000315FD7AF21FB41F052611F643F2E86D89E -:101EE0000F4A3CEE061ECB3AE5BB26FDFD661E35CD -:101EF0005F4E19C29EF8A43D1913E6DB87EF8CA94B -:101F00000DE3F7C1C7B4F758C736CA777165A28425 -:101F1000BF3B845D89023F960EEF7BFF699ABF74D9 -:101F20007304C72DEB472E9BF6BFB12B9F150AA656 -:101F3000DB6FEAFD951F132E056152FE0ACC2203CA -:101F4000F735C210C67A50A86E51703FBAEA5E31BA -:101F5000197C2EB094EC009EF1DAFDB688D5EAAD7E -:101F6000C6EE8A3D049F8C4B74E25E6B74C2218185 -:101F7000F74F8575C599B08BFE31EE09453978BFAD -:101F8000BC55C1FAF04C79FE3B8AC39B205781C3F4 -:101F9000E373C0EF7916471BEA00CEA284A5C8F30D -:101FA000E7453B72500770768D9270BCA34D71224D -:101FB000944D585AC0EFCFAC5B3FB6E2DD9A22A2F7 -:101FC000E95C9661EE1C7CA7A6F85399378B3EF628 -:101FD000633717C9FC6BC46BC28F7BABBE59917C56 -:101FE0007F26321D3918A7B8F2BB45241F7FFC9EFF -:101FF000EB16AC4FD4F08CC72DA20AAE76DBD09E88 -:10200000D0EEF3BA0CEE52B445511E23F71BBCD9E7 -:1020100068DF34F87E8C7E92E722EC57F4D8E489AE -:102020001904275A7C6C273B5CAE5BB1FFAB335D78 -:10203000C5180FAD9F83B7C8F3099FDB302FF41D80 -:1020400096CECFA54552EECB8AA4FD98BE56DEC7EC -:1020500086F2BDACC8A0D9B7BF8F37E15B8AEFE984 -:10206000F88BAD8BB3810FE17B2FF0247C17625C82 -:1020700044C470BDE3FA72E6E1EF951549F9227B9D -:1020800056F5B1B467DCA61BBDC3103F8EFA857749 -:1020900018F01DD5D867C3BFC378D6D367837F7FB9 -:1020A000F6C13E1BFA9F75C977D2A1FB3716C9F757 -:1020B00013E9D3FB78FD58FA5637C7E97DC31047BB -:1020C000A5977FBC5EDEBB64B07F19ABF997B1BF4B -:1020D0004869EF21791BFB6434DF6F8B82581EAF98 -:1020E000B44A3DADFC45D9A1366AC76F277C83E26F -:1020F000AF095EC27B505C64EC97EF2D09069DF63C -:102100009A1886CC22BEAA11F2BDE528CD6E206EAB -:102110002B25BB50537EF432BF03C07AEC8F3B5B60 -:10212000C85FBB49C2E4AE918F2E9FBFA68BF3C39D -:10213000ED57FBB57CB3753DF2678ADF06F5579620 -:102140001DE982BFA9DA3BB8BF66C5679CC752FCD0 -:1021500036A8FFDE1F7FC0EF6CEADA07F7137F9F18 -:10216000029F75FE1E33F92620DF3B5613E694FFCF -:102170007EC0B712FADE541DC1EF6777FD3A8FE5D6 -:1021800046E737AD6FFA76F2B196E77BF24406F494 -:10219000E19BDA5ED8A7B441F6C9C375BED9916C8C -:1021A00077EAB4FCAAB6CCCE7E3EB1D6CAF6AB5026 -:1021B0000D7302AE354A3B238A55CD4EF958FF4F79 -:1021C000DE3E8CEB797C00C03193F8DD71DC5A097E -:1021D000F78DB0B07D28349454EFA1F6A86105DBEB -:1021E0008104BCB824BE3F03FBA0427F655DB5CE31 -:1021F000EC53E4FDBE2307F9AE7EDFD4B0D1DB7A29 -:1022000010F9B2E27D7219EA8A7746F0FD4100F5D5 -:10221000463A4FC33069471B16A4B31F088892D2B1 -:10222000958843E68771FDB16198E351DC27365408 -:102230004CE438FAD07F4BBFDB37D7EA441CD530AB -:10224000D9B106EF551A7EE1E0F15714B99FE75175 -:10225000499F86B9F2FC0D15319CF7E87C686874DB -:102260008DC4FDD4CC31EEFF00DF4769F7730DC993 -:10227000D44FED134AC9821F619F4912DF19331DE4 -:10228000AC77C7164C7C74B783DD891FF74475B3F0 -:102290002307E5C5FF033C759D8B10370000000048 -:1022A0000000000000000000050207000000000020 -:00000001FF -- cgit v0.10.2 From 1cd4efddc4512ccbd9fe317f688f361605ca0c88 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 3 Mar 2010 01:23:22 -0800 Subject: bridge: depends on INET br_multicast calls ip_send_check(), so it should depend on INET. built-in: br_multicast.c:(.text+0x88cf4): undefined reference to `ip_send_check' or modular: ERROR: "ip_send_check" [net/bridge/bridge.ko] undefined! Signed-off-by: Randy Dunlap Signed-off-by: David S. Miller diff --git a/net/bridge/Kconfig b/net/bridge/Kconfig index 19a6b96..d115d5c 100644 --- a/net/bridge/Kconfig +++ b/net/bridge/Kconfig @@ -35,6 +35,7 @@ config BRIDGE config BRIDGE_IGMP_SNOOPING bool "IGMP snooping" depends on BRIDGE + depends on INET default y ---help--- If you say Y here, then the Ethernet bridge will be able selectively -- cgit v0.10.2 From 6c71dcb28ff9b63b814a0b76a256f5dae08d3e0d Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 2 Dec 2009 14:28:48 -0600 Subject: [SCSI] scsi_dh_emc: fix mode select request setup This patch fixes the request setup code for mode selects. I got the fixes from Hannes Reinecke while trying to hunt down some problems and merged it into one patch. I am sending it because Hannes is busy with other things. The patch fixes: - setting of the length for mode selects. - setting of the data direction for mode select 10. Signed-off-by: Hannes Reinecke Signed-off-by: Mike Christie Signed-off-by: James Bottomley diff --git a/drivers/scsi/device_handler/scsi_dh_emc.c b/drivers/scsi/device_handler/scsi_dh_emc.c index 61966750..63032ec3 100644 --- a/drivers/scsi/device_handler/scsi_dh_emc.c +++ b/drivers/scsi/device_handler/scsi_dh_emc.c @@ -272,7 +272,7 @@ static struct request *get_req(struct scsi_device *sdev, int cmd, int len = 0; rq = blk_get_request(sdev->request_queue, - (cmd == MODE_SELECT) ? WRITE : READ, GFP_NOIO); + (cmd != INQUIRY) ? WRITE : READ, GFP_NOIO); if (!rq) { sdev_printk(KERN_INFO, sdev, "get_req: blk_get_request failed"); return NULL; @@ -286,14 +286,17 @@ static struct request *get_req(struct scsi_device *sdev, int cmd, len = sizeof(short_trespass); rq->cmd_flags |= REQ_RW; rq->cmd[1] = 0x10; + rq->cmd[4] = len; break; case MODE_SELECT_10: len = sizeof(long_trespass); rq->cmd_flags |= REQ_RW; rq->cmd[1] = 0x10; + rq->cmd[8] = len; break; case INQUIRY: len = CLARIION_BUFFER_SIZE; + rq->cmd[4] = len; memset(buffer, 0, len); break; default: @@ -301,7 +304,6 @@ static struct request *get_req(struct scsi_device *sdev, int cmd, break; } - rq->cmd[4] = len; rq->cmd_type = REQ_TYPE_BLOCK_PC; rq->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER; -- cgit v0.10.2 From a32c055feed74246747bf4f45adb765136d3a4d3 Mon Sep 17 00:00:00 2001 From: Wayne Boyer Date: Fri, 19 Feb 2010 13:23:36 -0800 Subject: [SCSI] ipr: add support for new adapter command structures for the next generation chip Change the adapter command structures such that both 32 bit and 64 bit based adapters can work with the driver. Signed-off-by: Wayne Boyer Signed-off-by: James Bottomley diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 032f0d0..359882e 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -131,13 +131,13 @@ static const struct ipr_chip_cfg_t ipr_chip_cfg[] = { }; static const struct ipr_chip_t ipr_chip[] = { - { PCI_VENDOR_ID_MYLEX, PCI_DEVICE_ID_IBM_GEMSTONE, IPR_USE_LSI, &ipr_chip_cfg[0] }, - { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, IPR_USE_LSI, &ipr_chip_cfg[0] }, - { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, IPR_USE_LSI, &ipr_chip_cfg[0] }, - { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, IPR_USE_LSI, &ipr_chip_cfg[0] }, - { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, IPR_USE_MSI, &ipr_chip_cfg[0] }, - { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SNIPE, IPR_USE_LSI, &ipr_chip_cfg[1] }, - { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, IPR_USE_LSI, &ipr_chip_cfg[1] } + { PCI_VENDOR_ID_MYLEX, PCI_DEVICE_ID_IBM_GEMSTONE, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[0] }, + { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[0] }, + { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[0] }, + { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[0] }, + { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, IPR_USE_MSI, IPR_SIS32, &ipr_chip_cfg[0] }, + { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SNIPE, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[1] }, + { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[1] } }; static int ipr_max_bus_speeds [] = { @@ -468,7 +468,10 @@ static void ipr_trc_hook(struct ipr_cmnd *ipr_cmd, trace_entry->time = jiffies; trace_entry->op_code = ipr_cmd->ioarcb.cmd_pkt.cdb[0]; trace_entry->type = type; - trace_entry->ata_op_code = ipr_cmd->ioarcb.add_data.u.regs.command; + if (ipr_cmd->ioa_cfg->sis64) + trace_entry->ata_op_code = ipr_cmd->i.ata_ioadl.regs.command; + else + trace_entry->ata_op_code = ipr_cmd->ioarcb.u.add_data.u.regs.command; trace_entry->cmd_index = ipr_cmd->cmd_index & 0xff; trace_entry->res_handle = ipr_cmd->ioarcb.res_handle; trace_entry->u.add_data = add_data; @@ -488,16 +491,23 @@ static void ipr_reinit_ipr_cmnd(struct ipr_cmnd *ipr_cmd) { struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; struct ipr_ioasa *ioasa = &ipr_cmd->ioasa; - dma_addr_t dma_addr = be32_to_cpu(ioarcb->ioarcb_host_pci_addr); + dma_addr_t dma_addr = ipr_cmd->dma_addr; memset(&ioarcb->cmd_pkt, 0, sizeof(struct ipr_cmd_pkt)); - ioarcb->write_data_transfer_length = 0; + ioarcb->data_transfer_length = 0; ioarcb->read_data_transfer_length = 0; - ioarcb->write_ioadl_len = 0; + ioarcb->ioadl_len = 0; ioarcb->read_ioadl_len = 0; - ioarcb->write_ioadl_addr = - cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioadl)); - ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; + + if (ipr_cmd->ioa_cfg->sis64) + ioarcb->u.sis64_addr_data.data_ioadl_addr = + cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, i.ioadl64)); + else { + ioarcb->write_ioadl_addr = + cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, i.ioadl)); + ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; + } + ioasa->ioasc = 0; ioasa->residual_data_len = 0; ioasa->u.gata.status = 0; @@ -693,6 +703,35 @@ static void ipr_fail_all_ops(struct ipr_ioa_cfg *ioa_cfg) } /** + * ipr_send_command - Send driver initiated requests. + * @ipr_cmd: ipr command struct + * + * This function sends a command to the adapter using the correct write call. + * In the case of sis64, calculate the ioarcb size required. Then or in the + * appropriate bits. + * + * Return value: + * none + **/ +static void ipr_send_command(struct ipr_cmnd *ipr_cmd) +{ + struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; + dma_addr_t send_dma_addr = ipr_cmd->dma_addr; + + if (ioa_cfg->sis64) { + /* The default size is 256 bytes */ + send_dma_addr |= 0x1; + + /* If the number of ioadls * size of ioadl > 128 bytes, + then use a 512 byte ioarcb */ + if (ipr_cmd->dma_use_sg * sizeof(struct ipr_ioadl64_desc) > 128 ) + send_dma_addr |= 0x4; + writeq(send_dma_addr, ioa_cfg->regs.ioarrin_reg); + } else + writel(send_dma_addr, ioa_cfg->regs.ioarrin_reg); +} + +/** * ipr_do_req - Send driver initiated requests. * @ipr_cmd: ipr command struct * @done: done function @@ -724,8 +763,8 @@ static void ipr_do_req(struct ipr_cmnd *ipr_cmd, ipr_trc_hook(ipr_cmd, IPR_TRACE_START, 0); mb(); - writel(be32_to_cpu(ipr_cmd->ioarcb.ioarcb_host_pci_addr), - ioa_cfg->regs.ioarrin_reg); + + ipr_send_command(ipr_cmd); } /** @@ -747,6 +786,51 @@ static void ipr_internal_cmd_done(struct ipr_cmnd *ipr_cmd) } /** + * ipr_init_ioadl - initialize the ioadl for the correct SIS type + * @ipr_cmd: ipr command struct + * @dma_addr: dma address + * @len: transfer length + * @flags: ioadl flag value + * + * This function initializes an ioadl in the case where there is only a single + * descriptor. + * + * Return value: + * nothing + **/ +static void ipr_init_ioadl(struct ipr_cmnd *ipr_cmd, dma_addr_t dma_addr, + u32 len, int flags) +{ + struct ipr_ioadl_desc *ioadl = ipr_cmd->i.ioadl; + struct ipr_ioadl64_desc *ioadl64 = ipr_cmd->i.ioadl64; + + ipr_cmd->dma_use_sg = 1; + + if (ipr_cmd->ioa_cfg->sis64) { + ioadl64->flags = cpu_to_be32(flags); + ioadl64->data_len = cpu_to_be32(len); + ioadl64->address = cpu_to_be64(dma_addr); + + ipr_cmd->ioarcb.ioadl_len = + cpu_to_be32(sizeof(struct ipr_ioadl64_desc)); + ipr_cmd->ioarcb.data_transfer_length = cpu_to_be32(len); + } else { + ioadl->flags_and_data_len = cpu_to_be32(flags | len); + ioadl->address = cpu_to_be32(dma_addr); + + if (flags == IPR_IOADL_FLAGS_READ_LAST) { + ipr_cmd->ioarcb.read_ioadl_len = + cpu_to_be32(sizeof(struct ipr_ioadl_desc)); + ipr_cmd->ioarcb.read_data_transfer_length = cpu_to_be32(len); + } else { + ipr_cmd->ioarcb.ioadl_len = + cpu_to_be32(sizeof(struct ipr_ioadl_desc)); + ipr_cmd->ioarcb.data_transfer_length = cpu_to_be32(len); + } + } +} + +/** * ipr_send_blocking_cmd - Send command and sleep on its completion. * @ipr_cmd: ipr command struct * @timeout_func: function to invoke if command times out @@ -803,11 +887,8 @@ static void ipr_send_hcam(struct ipr_ioa_cfg *ioa_cfg, u8 type, ioarcb->cmd_pkt.cdb[7] = (sizeof(hostrcb->hcam) >> 8) & 0xff; ioarcb->cmd_pkt.cdb[8] = sizeof(hostrcb->hcam) & 0xff; - ioarcb->read_data_transfer_length = cpu_to_be32(sizeof(hostrcb->hcam)); - ioarcb->read_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc)); - ipr_cmd->ioadl[0].flags_and_data_len = - cpu_to_be32(IPR_IOADL_FLAGS_READ_LAST | sizeof(hostrcb->hcam)); - ipr_cmd->ioadl[0].address = cpu_to_be32(hostrcb->hostrcb_dma); + ipr_init_ioadl(ipr_cmd, hostrcb->hostrcb_dma, + sizeof(hostrcb->hcam), IPR_IOADL_FLAGS_READ_LAST); if (type == IPR_HCAM_CDB_OP_CODE_CONFIG_CHANGE) ipr_cmd->done = ipr_process_ccn; @@ -817,8 +898,8 @@ static void ipr_send_hcam(struct ipr_ioa_cfg *ioa_cfg, u8 type, ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_IOA_RES_ADDR); mb(); - writel(be32_to_cpu(ipr_cmd->ioarcb.ioarcb_host_pci_addr), - ioa_cfg->regs.ioarrin_reg); + + ipr_send_command(ipr_cmd); } else { list_add_tail(&hostrcb->queue, &ioa_cfg->hostrcb_free_q); } @@ -2976,6 +3057,37 @@ static int ipr_copy_ucode_buffer(struct ipr_sglist *sglist, } /** + * ipr_build_ucode_ioadl64 - Build a microcode download IOADL + * @ipr_cmd: ipr command struct + * @sglist: scatter/gather list + * + * Builds a microcode download IOA data list (IOADL). + * + **/ +static void ipr_build_ucode_ioadl64(struct ipr_cmnd *ipr_cmd, + struct ipr_sglist *sglist) +{ + struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; + struct ipr_ioadl64_desc *ioadl64 = ipr_cmd->i.ioadl64; + struct scatterlist *scatterlist = sglist->scatterlist; + int i; + + ipr_cmd->dma_use_sg = sglist->num_dma_sg; + ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ; + ioarcb->data_transfer_length = cpu_to_be32(sglist->buffer_len); + + ioarcb->ioadl_len = + cpu_to_be32(sizeof(struct ipr_ioadl64_desc) * ipr_cmd->dma_use_sg); + for (i = 0; i < ipr_cmd->dma_use_sg; i++) { + ioadl64[i].flags = cpu_to_be32(IPR_IOADL_FLAGS_WRITE); + ioadl64[i].data_len = cpu_to_be32(sg_dma_len(&scatterlist[i])); + ioadl64[i].address = cpu_to_be64(sg_dma_address(&scatterlist[i])); + } + + ioadl64[i-1].flags |= cpu_to_be32(IPR_IOADL_FLAGS_LAST); +} + +/** * ipr_build_ucode_ioadl - Build a microcode download IOADL * @ipr_cmd: ipr command struct * @sglist: scatter/gather list @@ -2987,14 +3099,15 @@ static void ipr_build_ucode_ioadl(struct ipr_cmnd *ipr_cmd, struct ipr_sglist *sglist) { struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; - struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl; + struct ipr_ioadl_desc *ioadl = ipr_cmd->i.ioadl; struct scatterlist *scatterlist = sglist->scatterlist; int i; ipr_cmd->dma_use_sg = sglist->num_dma_sg; ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ; - ioarcb->write_data_transfer_length = cpu_to_be32(sglist->buffer_len); - ioarcb->write_ioadl_len = + ioarcb->data_transfer_length = cpu_to_be32(sglist->buffer_len); + + ioarcb->ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg); for (i = 0; i < ipr_cmd->dma_use_sg; i++) { @@ -3828,14 +3941,19 @@ static int ipr_device_reset(struct ipr_ioa_cfg *ioa_cfg, ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg); ioarcb = &ipr_cmd->ioarcb; cmd_pkt = &ioarcb->cmd_pkt; - regs = &ioarcb->add_data.u.regs; + + if (ipr_cmd->ioa_cfg->sis64) { + regs = &ipr_cmd->i.ata_ioadl.regs; + ioarcb->add_cmd_parms_offset = cpu_to_be16(sizeof(*ioarcb)); + } else + regs = &ioarcb->u.add_data.u.regs; ioarcb->res_handle = res->cfgte.res_handle; cmd_pkt->request_type = IPR_RQTYPE_IOACMD; cmd_pkt->cdb[0] = IPR_RESET_DEVICE; if (ipr_is_gata(res)) { cmd_pkt->cdb[2] = IPR_ATA_PHY_RESET; - ioarcb->add_cmd_parms_len = cpu_to_be32(sizeof(regs->flags)); + ioarcb->add_cmd_parms_len = cpu_to_be16(sizeof(regs->flags)); regs->flags |= IPR_ATA_FLAG_STATUS_ON_GOOD_COMPLETION; } @@ -4309,6 +4427,53 @@ static irqreturn_t ipr_isr(int irq, void *devp) } /** + * ipr_build_ioadl64 - Build a scatter/gather list and map the buffer + * @ioa_cfg: ioa config struct + * @ipr_cmd: ipr command struct + * + * Return value: + * 0 on success / -1 on failure + **/ +static int ipr_build_ioadl64(struct ipr_ioa_cfg *ioa_cfg, + struct ipr_cmnd *ipr_cmd) +{ + int i, nseg; + struct scatterlist *sg; + u32 length; + u32 ioadl_flags = 0; + struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd; + struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; + struct ipr_ioadl64_desc *ioadl64 = ipr_cmd->i.ioadl64; + + length = scsi_bufflen(scsi_cmd); + if (!length) + return 0; + + nseg = scsi_dma_map(scsi_cmd); + if (nseg < 0) { + dev_err(&ioa_cfg->pdev->dev, "pci_map_sg failed!\n"); + return -1; + } + + ipr_cmd->dma_use_sg = nseg; + + if (scsi_cmd->sc_data_direction == DMA_TO_DEVICE) { + ioadl_flags = IPR_IOADL_FLAGS_WRITE; + ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ; + } else if (scsi_cmd->sc_data_direction == DMA_FROM_DEVICE) + ioadl_flags = IPR_IOADL_FLAGS_READ; + + scsi_for_each_sg(scsi_cmd, sg, ipr_cmd->dma_use_sg, i) { + ioadl64[i].flags = cpu_to_be32(ioadl_flags); + ioadl64[i].data_len = cpu_to_be32(sg_dma_len(sg)); + ioadl64[i].address = cpu_to_be64(sg_dma_address(sg)); + } + + ioadl64[i-1].flags |= cpu_to_be32(IPR_IOADL_FLAGS_LAST); + return 0; +} + +/** * ipr_build_ioadl - Build a scatter/gather list and map the buffer * @ioa_cfg: ioa config struct * @ipr_cmd: ipr command struct @@ -4325,7 +4490,7 @@ static int ipr_build_ioadl(struct ipr_ioa_cfg *ioa_cfg, u32 ioadl_flags = 0; struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd; struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; - struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl; + struct ipr_ioadl_desc *ioadl = ipr_cmd->i.ioadl; length = scsi_bufflen(scsi_cmd); if (!length) @@ -4342,8 +4507,8 @@ static int ipr_build_ioadl(struct ipr_ioa_cfg *ioa_cfg, if (scsi_cmd->sc_data_direction == DMA_TO_DEVICE) { ioadl_flags = IPR_IOADL_FLAGS_WRITE; ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ; - ioarcb->write_data_transfer_length = cpu_to_be32(length); - ioarcb->write_ioadl_len = + ioarcb->data_transfer_length = cpu_to_be32(length); + ioarcb->ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg); } else if (scsi_cmd->sc_data_direction == DMA_FROM_DEVICE) { ioadl_flags = IPR_IOADL_FLAGS_READ; @@ -4352,11 +4517,10 @@ static int ipr_build_ioadl(struct ipr_ioa_cfg *ioa_cfg, cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg); } - if (ipr_cmd->dma_use_sg <= ARRAY_SIZE(ioarcb->add_data.u.ioadl)) { - ioadl = ioarcb->add_data.u.ioadl; - ioarcb->write_ioadl_addr = - cpu_to_be32(be32_to_cpu(ioarcb->ioarcb_host_pci_addr) + - offsetof(struct ipr_ioarcb, add_data)); + if (ipr_cmd->dma_use_sg <= ARRAY_SIZE(ioarcb->u.add_data.u.ioadl)) { + ioadl = ioarcb->u.add_data.u.ioadl; + ioarcb->write_ioadl_addr = cpu_to_be32((ipr_cmd->dma_addr) + + offsetof(struct ipr_ioarcb, u.add_data)); ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; } @@ -4446,18 +4610,24 @@ static void ipr_reinit_ipr_cmnd_for_erp(struct ipr_cmnd *ipr_cmd) { struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; struct ipr_ioasa *ioasa = &ipr_cmd->ioasa; - dma_addr_t dma_addr = be32_to_cpu(ioarcb->ioarcb_host_pci_addr); + dma_addr_t dma_addr = ipr_cmd->dma_addr; memset(&ioarcb->cmd_pkt, 0, sizeof(struct ipr_cmd_pkt)); - ioarcb->write_data_transfer_length = 0; + ioarcb->data_transfer_length = 0; ioarcb->read_data_transfer_length = 0; - ioarcb->write_ioadl_len = 0; + ioarcb->ioadl_len = 0; ioarcb->read_ioadl_len = 0; ioasa->ioasc = 0; ioasa->residual_data_len = 0; - ioarcb->write_ioadl_addr = - cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioadl)); - ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; + + if (ipr_cmd->ioa_cfg->sis64) + ioarcb->u.sis64_addr_data.data_ioadl_addr = + cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, i.ioadl64)); + else { + ioarcb->write_ioadl_addr = + cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, i.ioadl)); + ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; + } } /** @@ -4489,15 +4659,8 @@ static void ipr_erp_request_sense(struct ipr_cmnd *ipr_cmd) cmd_pkt->flags_hi |= IPR_FLAGS_HI_NO_ULEN_CHK; cmd_pkt->timeout = cpu_to_be16(IPR_REQUEST_SENSE_TIMEOUT / HZ); - ipr_cmd->ioadl[0].flags_and_data_len = - cpu_to_be32(IPR_IOADL_FLAGS_READ_LAST | SCSI_SENSE_BUFFERSIZE); - ipr_cmd->ioadl[0].address = - cpu_to_be32(ipr_cmd->sense_buffer_dma); - - ipr_cmd->ioarcb.read_ioadl_len = - cpu_to_be32(sizeof(struct ipr_ioadl_desc)); - ipr_cmd->ioarcb.read_data_transfer_length = - cpu_to_be32(SCSI_SENSE_BUFFERSIZE); + ipr_init_ioadl(ipr_cmd, ipr_cmd->sense_buffer_dma, + SCSI_SENSE_BUFFERSIZE, IPR_IOADL_FLAGS_READ_LAST); ipr_do_req(ipr_cmd, ipr_erp_done, ipr_timeout, IPR_REQUEST_SENSE_TIMEOUT * 2); @@ -4916,13 +5079,16 @@ static int ipr_queuecommand(struct scsi_cmnd *scsi_cmd, (!ipr_is_gscsi(res) || scsi_cmd->cmnd[0] == IPR_QUERY_RSRC_STATE)) ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD; - if (likely(rc == 0)) - rc = ipr_build_ioadl(ioa_cfg, ipr_cmd); + if (likely(rc == 0)) { + if (ioa_cfg->sis64) + rc = ipr_build_ioadl64(ioa_cfg, ipr_cmd); + else + rc = ipr_build_ioadl(ioa_cfg, ipr_cmd); + } if (likely(rc == 0)) { mb(); - writel(be32_to_cpu(ipr_cmd->ioarcb.ioarcb_host_pci_addr), - ioa_cfg->regs.ioarrin_reg); + ipr_send_command(ipr_cmd); } else { list_move_tail(&ipr_cmd->queue, &ioa_cfg->free_q); return SCSI_MLQUEUE_HOST_BUSY; @@ -5146,6 +5312,52 @@ static void ipr_sata_done(struct ipr_cmnd *ipr_cmd) } /** + * ipr_build_ata_ioadl64 - Build an ATA scatter/gather list + * @ipr_cmd: ipr command struct + * @qc: ATA queued command + * + **/ +static void ipr_build_ata_ioadl64(struct ipr_cmnd *ipr_cmd, + struct ata_queued_cmd *qc) +{ + u32 ioadl_flags = 0; + struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; + struct ipr_ioadl64_desc *ioadl64 = ipr_cmd->i.ioadl64; + struct ipr_ioadl64_desc *last_ioadl64 = NULL; + int len = qc->nbytes; + struct scatterlist *sg; + unsigned int si; + dma_addr_t dma_addr = ipr_cmd->dma_addr; + + if (len == 0) + return; + + if (qc->dma_dir == DMA_TO_DEVICE) { + ioadl_flags = IPR_IOADL_FLAGS_WRITE; + ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ; + } else if (qc->dma_dir == DMA_FROM_DEVICE) + ioadl_flags = IPR_IOADL_FLAGS_READ; + + ioarcb->data_transfer_length = cpu_to_be32(len); + ioarcb->ioadl_len = + cpu_to_be32(sizeof(struct ipr_ioadl64_desc) * ipr_cmd->dma_use_sg); + ioarcb->u.sis64_addr_data.data_ioadl_addr = + cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, i.ata_ioadl)); + + for_each_sg(qc->sg, sg, qc->n_elem, si) { + ioadl64->flags = cpu_to_be32(ioadl_flags); + ioadl64->data_len = cpu_to_be32(sg_dma_len(sg)); + ioadl64->address = cpu_to_be64(sg_dma_address(sg)); + + last_ioadl64 = ioadl64; + ioadl64++; + } + + if (likely(last_ioadl64)) + last_ioadl64->flags |= cpu_to_be32(IPR_IOADL_FLAGS_LAST); +} + +/** * ipr_build_ata_ioadl - Build an ATA scatter/gather list * @ipr_cmd: ipr command struct * @qc: ATA queued command @@ -5156,7 +5368,7 @@ static void ipr_build_ata_ioadl(struct ipr_cmnd *ipr_cmd, { u32 ioadl_flags = 0; struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; - struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl; + struct ipr_ioadl_desc *ioadl = ipr_cmd->i.ioadl; struct ipr_ioadl_desc *last_ioadl = NULL; int len = qc->nbytes; struct scatterlist *sg; @@ -5168,8 +5380,8 @@ static void ipr_build_ata_ioadl(struct ipr_cmnd *ipr_cmd, if (qc->dma_dir == DMA_TO_DEVICE) { ioadl_flags = IPR_IOADL_FLAGS_WRITE; ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ; - ioarcb->write_data_transfer_length = cpu_to_be32(len); - ioarcb->write_ioadl_len = + ioarcb->data_transfer_length = cpu_to_be32(len); + ioarcb->ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg); } else if (qc->dma_dir == DMA_FROM_DEVICE) { ioadl_flags = IPR_IOADL_FLAGS_READ; @@ -5212,10 +5424,15 @@ static unsigned int ipr_qc_issue(struct ata_queued_cmd *qc) ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg); ioarcb = &ipr_cmd->ioarcb; - regs = &ioarcb->add_data.u.regs; - memset(&ioarcb->add_data, 0, sizeof(ioarcb->add_data)); - ioarcb->add_cmd_parms_len = cpu_to_be32(sizeof(ioarcb->add_data.u.regs)); + if (ioa_cfg->sis64) { + regs = &ipr_cmd->i.ata_ioadl.regs; + ioarcb->add_cmd_parms_offset = cpu_to_be16(sizeof(*ioarcb)); + } else + regs = &ioarcb->u.add_data.u.regs; + + memset(regs, 0, sizeof(*regs)); + ioarcb->add_cmd_parms_len = cpu_to_be16(sizeof(*regs)); list_add_tail(&ipr_cmd->queue, &ioa_cfg->pending_q); ipr_cmd->qc = qc; @@ -5226,7 +5443,11 @@ static unsigned int ipr_qc_issue(struct ata_queued_cmd *qc) ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_ULEN_CHK; ipr_cmd->dma_use_sg = qc->n_elem; - ipr_build_ata_ioadl(ipr_cmd, qc); + if (ioa_cfg->sis64) + ipr_build_ata_ioadl64(ipr_cmd, qc); + else + ipr_build_ata_ioadl(ipr_cmd, qc); + regs->flags |= IPR_ATA_FLAG_STATUS_ON_GOOD_COMPLETION; ipr_copy_sata_tf(regs, &qc->tf); memcpy(ioarcb->cmd_pkt.cdb, qc->cdb, IPR_MAX_CDB_LEN); @@ -5257,8 +5478,9 @@ static unsigned int ipr_qc_issue(struct ata_queued_cmd *qc) } mb(); - writel(be32_to_cpu(ioarcb->ioarcb_host_pci_addr), - ioa_cfg->regs.ioarrin_reg); + + ipr_send_command(ipr_cmd); + return 0; } @@ -5459,7 +5681,7 @@ static void ipr_set_sup_dev_dflt(struct ipr_supported_device *supported_dev, * ipr_set_supported_devs - Send Set Supported Devices for a device * @ipr_cmd: ipr command struct * - * This function send a Set Supported Devices to the adapter + * This function sends a Set Supported Devices to the adapter * * Return value: * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN @@ -5468,7 +5690,6 @@ static int ipr_set_supported_devs(struct ipr_cmnd *ipr_cmd) { struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; struct ipr_supported_device *supp_dev = &ioa_cfg->vpd_cbs->supp_dev; - struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl; struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; struct ipr_resource_entry *res = ipr_cmd->u.res; @@ -5489,13 +5710,11 @@ static int ipr_set_supported_devs(struct ipr_cmnd *ipr_cmd) ioarcb->cmd_pkt.cdb[7] = (sizeof(struct ipr_supported_device) >> 8) & 0xff; ioarcb->cmd_pkt.cdb[8] = sizeof(struct ipr_supported_device) & 0xff; - ioadl->flags_and_data_len = cpu_to_be32(IPR_IOADL_FLAGS_WRITE_LAST | - sizeof(struct ipr_supported_device)); - ioadl->address = cpu_to_be32(ioa_cfg->vpd_cbs_dma + - offsetof(struct ipr_misc_cbs, supp_dev)); - ioarcb->write_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc)); - ioarcb->write_data_transfer_length = - cpu_to_be32(sizeof(struct ipr_supported_device)); + ipr_init_ioadl(ipr_cmd, + ioa_cfg->vpd_cbs_dma + + offsetof(struct ipr_misc_cbs, supp_dev), + sizeof(struct ipr_supported_device), + IPR_IOADL_FLAGS_WRITE_LAST); ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_SET_SUP_DEVICE_TIMEOUT); @@ -5695,10 +5914,9 @@ static void ipr_modify_ioafp_mode_page_28(struct ipr_ioa_cfg *ioa_cfg, * none **/ static void ipr_build_mode_select(struct ipr_cmnd *ipr_cmd, - __be32 res_handle, u8 parm, u32 dma_addr, - u8 xfer_len) + __be32 res_handle, u8 parm, + dma_addr_t dma_addr, u8 xfer_len) { - struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl; struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; ioarcb->res_handle = res_handle; @@ -5708,11 +5926,7 @@ static void ipr_build_mode_select(struct ipr_cmnd *ipr_cmd, ioarcb->cmd_pkt.cdb[1] = parm; ioarcb->cmd_pkt.cdb[4] = xfer_len; - ioadl->flags_and_data_len = - cpu_to_be32(IPR_IOADL_FLAGS_WRITE_LAST | xfer_len); - ioadl->address = cpu_to_be32(dma_addr); - ioarcb->write_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc)); - ioarcb->write_data_transfer_length = cpu_to_be32(xfer_len); + ipr_init_ioadl(ipr_cmd, dma_addr, xfer_len, IPR_IOADL_FLAGS_WRITE_LAST); } /** @@ -5762,9 +5976,8 @@ static int ipr_ioafp_mode_select_page28(struct ipr_cmnd *ipr_cmd) **/ static void ipr_build_mode_sense(struct ipr_cmnd *ipr_cmd, __be32 res_handle, - u8 parm, u32 dma_addr, u8 xfer_len) + u8 parm, dma_addr_t dma_addr, u8 xfer_len) { - struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl; struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; ioarcb->res_handle = res_handle; @@ -5773,11 +5986,7 @@ static void ipr_build_mode_sense(struct ipr_cmnd *ipr_cmd, ioarcb->cmd_pkt.cdb[4] = xfer_len; ioarcb->cmd_pkt.request_type = IPR_RQTYPE_SCSICDB; - ioadl->flags_and_data_len = - cpu_to_be32(IPR_IOADL_FLAGS_READ_LAST | xfer_len); - ioadl->address = cpu_to_be32(dma_addr); - ioarcb->read_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc)); - ioarcb->read_data_transfer_length = cpu_to_be32(xfer_len); + ipr_init_ioadl(ipr_cmd, dma_addr, xfer_len, IPR_IOADL_FLAGS_READ_LAST); } /** @@ -6033,7 +6242,6 @@ static int ipr_ioafp_query_ioa_cfg(struct ipr_cmnd *ipr_cmd) { struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; - struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl; struct ipr_inquiry_page3 *ucode_vpd = &ioa_cfg->vpd_cbs->page3_data; struct ipr_inquiry_cap *cap = &ioa_cfg->vpd_cbs->cap; @@ -6050,13 +6258,9 @@ static int ipr_ioafp_query_ioa_cfg(struct ipr_cmnd *ipr_cmd) ioarcb->cmd_pkt.cdb[7] = (sizeof(struct ipr_config_table) >> 8) & 0xff; ioarcb->cmd_pkt.cdb[8] = sizeof(struct ipr_config_table) & 0xff; - ioarcb->read_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc)); - ioarcb->read_data_transfer_length = - cpu_to_be32(sizeof(struct ipr_config_table)); - - ioadl->address = cpu_to_be32(ioa_cfg->cfg_table_dma); - ioadl->flags_and_data_len = - cpu_to_be32(IPR_IOADL_FLAGS_READ_LAST | sizeof(struct ipr_config_table)); + ipr_init_ioadl(ipr_cmd, ioa_cfg->cfg_table_dma, + sizeof(struct ipr_config_table), + IPR_IOADL_FLAGS_READ_LAST); ipr_cmd->job_step = ipr_init_res_table; @@ -6076,10 +6280,9 @@ static int ipr_ioafp_query_ioa_cfg(struct ipr_cmnd *ipr_cmd) * none **/ static void ipr_ioafp_inquiry(struct ipr_cmnd *ipr_cmd, u8 flags, u8 page, - u32 dma_addr, u8 xfer_len) + dma_addr_t dma_addr, u8 xfer_len) { struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; - struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl; ENTER; ioarcb->cmd_pkt.request_type = IPR_RQTYPE_SCSICDB; @@ -6090,12 +6293,7 @@ static void ipr_ioafp_inquiry(struct ipr_cmnd *ipr_cmd, u8 flags, u8 page, ioarcb->cmd_pkt.cdb[2] = page; ioarcb->cmd_pkt.cdb[4] = xfer_len; - ioarcb->read_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc)); - ioarcb->read_data_transfer_length = cpu_to_be32(xfer_len); - - ioadl->address = cpu_to_be32(dma_addr); - ioadl->flags_and_data_len = - cpu_to_be32(IPR_IOADL_FLAGS_READ_LAST | xfer_len); + ipr_init_ioadl(ipr_cmd, dma_addr, xfer_len, IPR_IOADL_FLAGS_READ_LAST); ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT); LEAVE; @@ -6785,7 +6983,10 @@ static int ipr_reset_ucode_download(struct ipr_cmnd *ipr_cmd) ipr_cmd->ioarcb.cmd_pkt.cdb[7] = (sglist->buffer_len & 0x00ff00) >> 8; ipr_cmd->ioarcb.cmd_pkt.cdb[8] = sglist->buffer_len & 0x0000ff; - ipr_build_ucode_ioadl(ipr_cmd, sglist); + if (ioa_cfg->sis64) + ipr_build_ucode_ioadl64(ipr_cmd, sglist); + else + ipr_build_ucode_ioadl(ipr_cmd, sglist); ipr_cmd->job_step = ipr_reset_ucode_download_done; ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, @@ -7209,7 +7410,7 @@ static int __devinit ipr_alloc_cmd_blks(struct ipr_ioa_cfg *ioa_cfg) int i; ioa_cfg->ipr_cmd_pool = pci_pool_create (IPR_NAME, ioa_cfg->pdev, - sizeof(struct ipr_cmnd), 8, 0); + sizeof(struct ipr_cmnd), 16, 0); if (!ioa_cfg->ipr_cmd_pool) return -ENOMEM; @@ -7227,13 +7428,25 @@ static int __devinit ipr_alloc_cmd_blks(struct ipr_ioa_cfg *ioa_cfg) ioa_cfg->ipr_cmnd_list_dma[i] = dma_addr; ioarcb = &ipr_cmd->ioarcb; - ioarcb->ioarcb_host_pci_addr = cpu_to_be32(dma_addr); + ipr_cmd->dma_addr = dma_addr; + if (ioa_cfg->sis64) + ioarcb->a.ioarcb_host_pci_addr64 = cpu_to_be64(dma_addr); + else + ioarcb->a.ioarcb_host_pci_addr = cpu_to_be32(dma_addr); + ioarcb->host_response_handle = cpu_to_be32(i << 2); - ioarcb->write_ioadl_addr = - cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioadl)); - ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; - ioarcb->ioasa_host_pci_addr = - cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioasa)); + if (ioa_cfg->sis64) { + ioarcb->u.sis64_addr_data.data_ioadl_addr = + cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, i.ioadl64)); + ioarcb->u.sis64_addr_data.ioasa_host_pci_addr = + cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, ioasa)); + } else { + ioarcb->write_ioadl_addr = + cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, i.ioadl)); + ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; + ioarcb->ioasa_host_pci_addr = + cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioasa)); + } ioarcb->ioasa_len = cpu_to_be16(sizeof(struct ipr_ioasa)); ipr_cmd->cmd_index = i; ipr_cmd->ioa_cfg = ioa_cfg; @@ -7578,6 +7791,8 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev, goto out_scsi_host_put; } + /* set SIS 32 or SIS 64 */ + ioa_cfg->sis64 = ioa_cfg->ipr_chip->sis_type == IPR_SIS64 ? 1 : 0; ioa_cfg->chip_cfg = ioa_cfg->ipr_chip->cfg; if (ipr_transop_timeout) @@ -7615,7 +7830,16 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev, pci_set_master(pdev); - rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + if (ioa_cfg->sis64) { + rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); + if (rc < 0) { + dev_dbg(&pdev->dev, "Failed to set 64 bit PCI DMA mask\n"); + rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + } + + } else + rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + if (rc < 0) { dev_err(&pdev->dev, "Failed to set PCI DMA mask\n"); goto cleanup_nomem; diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h index 19bbcf3..64e41df 100644 --- a/drivers/scsi/ipr.h +++ b/drivers/scsi/ipr.h @@ -381,7 +381,7 @@ struct ipr_cmd_pkt { #define IPR_RQTYPE_HCAM 0x02 #define IPR_RQTYPE_ATA_PASSTHRU 0x04 - u8 luntar_luntrn; + u8 reserved2; u8 flags_hi; #define IPR_FLAGS_HI_WRITE_NOT_READ 0x80 @@ -403,7 +403,7 @@ struct ipr_cmd_pkt { __be16 timeout; }__attribute__ ((packed, aligned(4))); -struct ipr_ioarcb_ata_regs { +struct ipr_ioarcb_ata_regs { /* 22 bytes */ u8 flags; #define IPR_ATA_FLAG_PACKET_CMD 0x80 #define IPR_ATA_FLAG_XFER_TYPE_DMA 0x40 @@ -442,28 +442,49 @@ struct ipr_ioadl_desc { __be32 address; }__attribute__((packed, aligned (8))); +struct ipr_ioadl64_desc { + __be32 flags; + __be32 data_len; + __be64 address; +}__attribute__((packed, aligned (16))); + +struct ipr_ata64_ioadl { + struct ipr_ioarcb_ata_regs regs; + u16 reserved[5]; + struct ipr_ioadl64_desc ioadl64[IPR_NUM_IOADL_ENTRIES]; +}__attribute__((packed, aligned (16))); + struct ipr_ioarcb_add_data { union { struct ipr_ioarcb_ata_regs regs; struct ipr_ioadl_desc ioadl[5]; __be32 add_cmd_parms[10]; - }u; -}__attribute__ ((packed, aligned(4))); + } u; +}__attribute__ ((packed, aligned (4))); + +struct ipr_ioarcb_sis64_add_addr_ecb { + __be64 ioasa_host_pci_addr; + __be64 data_ioadl_addr; + __be64 reserved; + __be32 ext_control_buf[4]; +}__attribute__((packed, aligned (8))); /* IOA Request Control Block 128 bytes */ struct ipr_ioarcb { - __be32 ioarcb_host_pci_addr; - __be32 reserved; + union { + __be32 ioarcb_host_pci_addr; + __be64 ioarcb_host_pci_addr64; + } a; __be32 res_handle; __be32 host_response_handle; __be32 reserved1; __be32 reserved2; __be32 reserved3; - __be32 write_data_transfer_length; + __be32 data_transfer_length; __be32 read_data_transfer_length; __be32 write_ioadl_addr; - __be32 write_ioadl_len; + __be32 ioadl_len; __be32 read_ioadl_addr; __be32 read_ioadl_len; @@ -473,8 +494,14 @@ struct ipr_ioarcb { struct ipr_cmd_pkt cmd_pkt; - __be32 add_cmd_parms_len; - struct ipr_ioarcb_add_data add_data; + __be16 add_cmd_parms_offset; + __be16 add_cmd_parms_len; + + union { + struct ipr_ioarcb_add_data add_data; + struct ipr_ioarcb_sis64_add_addr_ecb sis64_addr_data; + } u; + }__attribute__((packed, aligned (4))); struct ipr_ioasa_vset { @@ -1029,6 +1056,9 @@ struct ipr_chip_t { u16 intr_type; #define IPR_USE_LSI 0x00 #define IPR_USE_MSI 0x01 + u16 sis_type; +#define IPR_SIS32 0x00 +#define IPR_SIS64 0x01 const struct ipr_chip_cfg_t *cfg; }; @@ -1099,6 +1129,7 @@ struct ipr_ioa_cfg { u8 dual_raid:1; u8 needs_warm_reset:1; u8 msi_received:1; + u8 sis64:1; u8 revid; @@ -1202,13 +1233,17 @@ struct ipr_ioa_cfg { char ipr_cmd_label[8]; #define IPR_CMD_LABEL "ipr_cmd" struct ipr_cmnd *ipr_cmnd_list[IPR_NUM_CMD_BLKS]; - u32 ipr_cmnd_list_dma[IPR_NUM_CMD_BLKS]; + dma_addr_t ipr_cmnd_list_dma[IPR_NUM_CMD_BLKS]; }; struct ipr_cmnd { struct ipr_ioarcb ioarcb; + union { + struct ipr_ioadl_desc ioadl[IPR_NUM_IOADL_ENTRIES]; + struct ipr_ioadl64_desc ioadl64[IPR_NUM_IOADL_ENTRIES]; + struct ipr_ata64_ioadl ata_ioadl; + } i; struct ipr_ioasa ioasa; - struct ipr_ioadl_desc ioadl[IPR_NUM_IOADL_ENTRIES]; struct list_head queue; struct scsi_cmnd *scsi_cmd; struct ata_queued_cmd *qc; @@ -1221,7 +1256,7 @@ struct ipr_cmnd { u8 sense_buffer[SCSI_SENSE_BUFFERSIZE]; dma_addr_t sense_buffer_dma; unsigned short dma_use_sg; - dma_addr_t dma_handle; + dma_addr_t dma_addr; struct ipr_cmnd *sibling; union { enum ipr_shutdown_type shutdown_type; -- cgit v0.10.2 From a74c16390a47dcb6c96b20b572ffc9936073d4b1 Mon Sep 17 00:00:00 2001 From: Wayne Boyer Date: Fri, 19 Feb 2010 13:23:51 -0800 Subject: [SCSI] ipr: define new offsets to registers for the next generation chip This patch adds the entry to the ipr_chip_cfg array that defines the register offsets for the next generation 64 bit IOA PCI interface chip. Signed-off-by: Wayne Boyer Signed-off-by: James Bottomley diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 359882e..e6bab3f 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -128,6 +128,21 @@ static const struct ipr_chip_cfg_t ipr_chip_cfg[] = { .clr_uproc_interrupt_reg = 0x00294 } }, + { /* CRoC */ + .mailbox = 0x00040, + .cache_line_size = 0x20, + { + .set_interrupt_mask_reg = 0x00010, + .clr_interrupt_mask_reg = 0x00018, + .sense_interrupt_mask_reg = 0x00010, + .clr_interrupt_reg = 0x00008, + .sense_interrupt_reg = 0x00000, + .ioarrin_reg = 0x00070, + .sense_uproc_interrupt_reg = 0x00020, + .set_uproc_interrupt_reg = 0x00020, + .clr_uproc_interrupt_reg = 0x00028 + } + }, }; static const struct ipr_chip_t ipr_chip[] = { -- cgit v0.10.2 From 3e7ebdfa58ddaef361f9538219e66a7226fb1e5d Mon Sep 17 00:00:00 2001 From: Wayne Boyer Date: Fri, 19 Feb 2010 13:23:59 -0800 Subject: [SCSI] ipr: update the configuration table code for the next generation chip This patch changes the configuration table structures and related code such that both 32 bit and 64 bit based adapters can work with the driver. This patch also implements the code to generate the virtual bus/id/lun values for devices connected to the new adapters. It also implements support for the new device resource path. Signed-off-by: Wayne Boyer Signed-off-by: James Bottomley diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index e6bab3f..91e330a 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -72,6 +72,7 @@ #include #include #include +#include #include #include #include @@ -93,6 +94,7 @@ static unsigned int ipr_fastfail = 0; static unsigned int ipr_transop_timeout = 0; static unsigned int ipr_enable_cache = 1; static unsigned int ipr_debug = 0; +static unsigned int ipr_max_devs = IPR_DEFAULT_SIS64_DEVS; static unsigned int ipr_dual_ioa_raid = 1; static DEFINE_SPINLOCK(ipr_driver_lock); @@ -177,6 +179,9 @@ module_param_named(debug, ipr_debug, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(debug, "Enable device driver debugging logging. Set to 1 to enable. (default: 0)"); module_param_named(dual_ioa_raid, ipr_dual_ioa_raid, int, 0); MODULE_PARM_DESC(dual_ioa_raid, "Enable dual adapter RAID support. Set to 1 to enable. (default: 1)"); +module_param_named(max_devs, ipr_max_devs, int, 0); +MODULE_PARM_DESC(max_devs, "Specify the maximum number of physical devices. " + "[Default=" __stringify(IPR_DEFAULT_SIS64_DEVS) "]"); MODULE_LICENSE("GPL"); MODULE_VERSION(IPR_DRIVER_VERSION); @@ -921,14 +926,46 @@ static void ipr_send_hcam(struct ipr_ioa_cfg *ioa_cfg, u8 type, } /** + * ipr_update_ata_class - Update the ata class in the resource entry + * @res: resource entry struct + * @proto: cfgte device bus protocol value + * + * Return value: + * none + **/ +static void ipr_update_ata_class(struct ipr_resource_entry *res, unsigned int proto) +{ + switch(proto) { + case IPR_PROTO_SATA: + case IPR_PROTO_SAS_STP: + res->ata_class = ATA_DEV_ATA; + break; + case IPR_PROTO_SATA_ATAPI: + case IPR_PROTO_SAS_STP_ATAPI: + res->ata_class = ATA_DEV_ATAPI; + break; + default: + res->ata_class = ATA_DEV_UNKNOWN; + break; + }; +} + +/** * ipr_init_res_entry - Initialize a resource entry struct. * @res: resource entry struct + * @cfgtew: config table entry wrapper struct * * Return value: * none **/ -static void ipr_init_res_entry(struct ipr_resource_entry *res) +static void ipr_init_res_entry(struct ipr_resource_entry *res, + struct ipr_config_table_entry_wrapper *cfgtew) { + int found = 0; + unsigned int proto; + struct ipr_ioa_cfg *ioa_cfg = res->ioa_cfg; + struct ipr_resource_entry *gscsi_res = NULL; + res->needs_sync_complete = 0; res->in_erp = 0; res->add_to_ml = 0; @@ -936,6 +973,205 @@ static void ipr_init_res_entry(struct ipr_resource_entry *res) res->resetting_device = 0; res->sdev = NULL; res->sata_port = NULL; + + if (ioa_cfg->sis64) { + proto = cfgtew->u.cfgte64->proto; + res->res_flags = cfgtew->u.cfgte64->res_flags; + res->qmodel = IPR_QUEUEING_MODEL64(res); + res->type = cfgtew->u.cfgte64->res_type & 0x0f; + + memcpy(res->res_path, &cfgtew->u.cfgte64->res_path, + sizeof(res->res_path)); + + res->bus = 0; + res->lun = scsilun_to_int(&res->dev_lun); + + if (res->type == IPR_RES_TYPE_GENERIC_SCSI) { + list_for_each_entry(gscsi_res, &ioa_cfg->used_res_q, queue) { + if (gscsi_res->dev_id == cfgtew->u.cfgte64->dev_id) { + found = 1; + res->target = gscsi_res->target; + break; + } + } + if (!found) { + res->target = find_first_zero_bit(ioa_cfg->target_ids, + ioa_cfg->max_devs_supported); + set_bit(res->target, ioa_cfg->target_ids); + } + + memcpy(&res->dev_lun.scsi_lun, &cfgtew->u.cfgte64->lun, + sizeof(res->dev_lun.scsi_lun)); + } else if (res->type == IPR_RES_TYPE_IOAFP) { + res->bus = IPR_IOAFP_VIRTUAL_BUS; + res->target = 0; + } else if (res->type == IPR_RES_TYPE_ARRAY) { + res->bus = IPR_ARRAY_VIRTUAL_BUS; + res->target = find_first_zero_bit(ioa_cfg->array_ids, + ioa_cfg->max_devs_supported); + set_bit(res->target, ioa_cfg->array_ids); + } else if (res->type == IPR_RES_TYPE_VOLUME_SET) { + res->bus = IPR_VSET_VIRTUAL_BUS; + res->target = find_first_zero_bit(ioa_cfg->vset_ids, + ioa_cfg->max_devs_supported); + set_bit(res->target, ioa_cfg->vset_ids); + } else { + res->target = find_first_zero_bit(ioa_cfg->target_ids, + ioa_cfg->max_devs_supported); + set_bit(res->target, ioa_cfg->target_ids); + } + } else { + proto = cfgtew->u.cfgte->proto; + res->qmodel = IPR_QUEUEING_MODEL(res); + res->flags = cfgtew->u.cfgte->flags; + if (res->flags & IPR_IS_IOA_RESOURCE) + res->type = IPR_RES_TYPE_IOAFP; + else + res->type = cfgtew->u.cfgte->rsvd_subtype & 0x0f; + + res->bus = cfgtew->u.cfgte->res_addr.bus; + res->target = cfgtew->u.cfgte->res_addr.target; + res->lun = cfgtew->u.cfgte->res_addr.lun; + } + + ipr_update_ata_class(res, proto); +} + +/** + * ipr_is_same_device - Determine if two devices are the same. + * @res: resource entry struct + * @cfgtew: config table entry wrapper struct + * + * Return value: + * 1 if the devices are the same / 0 otherwise + **/ +static int ipr_is_same_device(struct ipr_resource_entry *res, + struct ipr_config_table_entry_wrapper *cfgtew) +{ + if (res->ioa_cfg->sis64) { + if (!memcmp(&res->dev_id, &cfgtew->u.cfgte64->dev_id, + sizeof(cfgtew->u.cfgte64->dev_id)) && + !memcmp(&res->lun, &cfgtew->u.cfgte64->lun, + sizeof(cfgtew->u.cfgte64->lun))) { + return 1; + } + } else { + if (res->bus == cfgtew->u.cfgte->res_addr.bus && + res->target == cfgtew->u.cfgte->res_addr.target && + res->lun == cfgtew->u.cfgte->res_addr.lun) + return 1; + } + + return 0; +} + +/** + * ipr_format_resource_path - Format the resource path for printing. + * @res_path: resource path + * @buf: buffer + * + * Return value: + * pointer to buffer + **/ +static char *ipr_format_resource_path(u8 *res_path, char *buffer) +{ + int i; + + sprintf(buffer, "%02X", res_path[0]); + for (i=1; res_path[i] != 0xff; i++) + sprintf(buffer, "%s:%02X", buffer, res_path[i]); + + return buffer; +} + +/** + * ipr_update_res_entry - Update the resource entry. + * @res: resource entry struct + * @cfgtew: config table entry wrapper struct + * + * Return value: + * none + **/ +static void ipr_update_res_entry(struct ipr_resource_entry *res, + struct ipr_config_table_entry_wrapper *cfgtew) +{ + char buffer[IPR_MAX_RES_PATH_LENGTH]; + unsigned int proto; + int new_path = 0; + + if (res->ioa_cfg->sis64) { + res->flags = cfgtew->u.cfgte64->flags; + res->res_flags = cfgtew->u.cfgte64->res_flags; + res->type = cfgtew->u.cfgte64->res_type & 0x0f; + + memcpy(&res->std_inq_data, &cfgtew->u.cfgte64->std_inq_data, + sizeof(struct ipr_std_inq_data)); + + res->qmodel = IPR_QUEUEING_MODEL64(res); + proto = cfgtew->u.cfgte64->proto; + res->res_handle = cfgtew->u.cfgte64->res_handle; + res->dev_id = cfgtew->u.cfgte64->dev_id; + + memcpy(&res->dev_lun.scsi_lun, &cfgtew->u.cfgte64->lun, + sizeof(res->dev_lun.scsi_lun)); + + if (memcmp(res->res_path, &cfgtew->u.cfgte64->res_path, + sizeof(res->res_path))) { + memcpy(res->res_path, &cfgtew->u.cfgte64->res_path, + sizeof(res->res_path)); + new_path = 1; + } + + if (res->sdev && new_path) + sdev_printk(KERN_INFO, res->sdev, "Resource path: %s\n", + ipr_format_resource_path(&res->res_path[0], &buffer[0])); + } else { + res->flags = cfgtew->u.cfgte->flags; + if (res->flags & IPR_IS_IOA_RESOURCE) + res->type = IPR_RES_TYPE_IOAFP; + else + res->type = cfgtew->u.cfgte->rsvd_subtype & 0x0f; + + memcpy(&res->std_inq_data, &cfgtew->u.cfgte->std_inq_data, + sizeof(struct ipr_std_inq_data)); + + res->qmodel = IPR_QUEUEING_MODEL(res); + proto = cfgtew->u.cfgte->proto; + res->res_handle = cfgtew->u.cfgte->res_handle; + } + + ipr_update_ata_class(res, proto); +} + +/** + * ipr_clear_res_target - Clear the bit in the bit map representing the target + * for the resource. + * @res: resource entry struct + * @cfgtew: config table entry wrapper struct + * + * Return value: + * none + **/ +static void ipr_clear_res_target(struct ipr_resource_entry *res) +{ + struct ipr_resource_entry *gscsi_res = NULL; + struct ipr_ioa_cfg *ioa_cfg = res->ioa_cfg; + + if (!ioa_cfg->sis64) + return; + + if (res->bus == IPR_ARRAY_VIRTUAL_BUS) + clear_bit(res->target, ioa_cfg->array_ids); + else if (res->bus == IPR_VSET_VIRTUAL_BUS) + clear_bit(res->target, ioa_cfg->vset_ids); + else if (res->bus == 0 && res->type == IPR_RES_TYPE_GENERIC_SCSI) { + list_for_each_entry(gscsi_res, &ioa_cfg->used_res_q, queue) + if (gscsi_res->dev_id == res->dev_id && gscsi_res != res) + return; + clear_bit(res->target, ioa_cfg->target_ids); + + } else if (res->bus == 0) + clear_bit(res->target, ioa_cfg->target_ids); } /** @@ -947,17 +1183,24 @@ static void ipr_init_res_entry(struct ipr_resource_entry *res) * none **/ static void ipr_handle_config_change(struct ipr_ioa_cfg *ioa_cfg, - struct ipr_hostrcb *hostrcb) + struct ipr_hostrcb *hostrcb) { struct ipr_resource_entry *res = NULL; - struct ipr_config_table_entry *cfgte; + struct ipr_config_table_entry_wrapper cfgtew; + __be32 cc_res_handle; + u32 is_ndn = 1; - cfgte = &hostrcb->hcam.u.ccn.cfgte; + if (ioa_cfg->sis64) { + cfgtew.u.cfgte64 = &hostrcb->hcam.u.ccn.u.cfgte64; + cc_res_handle = cfgtew.u.cfgte64->res_handle; + } else { + cfgtew.u.cfgte = &hostrcb->hcam.u.ccn.u.cfgte; + cc_res_handle = cfgtew.u.cfgte->res_handle; + } list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { - if (!memcmp(&res->cfgte.res_addr, &cfgte->res_addr, - sizeof(cfgte->res_addr))) { + if (res->res_handle == cc_res_handle) { is_ndn = 0; break; } @@ -975,20 +1218,22 @@ static void ipr_handle_config_change(struct ipr_ioa_cfg *ioa_cfg, struct ipr_resource_entry, queue); list_del(&res->queue); - ipr_init_res_entry(res); + ipr_init_res_entry(res, &cfgtew); list_add_tail(&res->queue, &ioa_cfg->used_res_q); } - memcpy(&res->cfgte, cfgte, sizeof(struct ipr_config_table_entry)); + ipr_update_res_entry(res, &cfgtew); if (hostrcb->hcam.notify_type == IPR_HOST_RCB_NOTIF_TYPE_REM_ENTRY) { if (res->sdev) { res->del_from_ml = 1; - res->cfgte.res_handle = IPR_INVALID_RES_HANDLE; + res->res_handle = IPR_INVALID_RES_HANDLE; if (ioa_cfg->allow_ml_add_del) schedule_work(&ioa_cfg->work_q); - } else + } else { + ipr_clear_res_target(res); list_move_tail(&res->queue, &ioa_cfg->free_res_q); + } } else if (!res->sdev) { res->add_to_ml = 1; if (ioa_cfg->allow_ml_add_del) @@ -1941,12 +2186,14 @@ static const struct ipr_ses_table_entry * ipr_find_ses_entry(struct ipr_resource_entry *res) { int i, j, matches; + struct ipr_std_inq_vpids *vpids; const struct ipr_ses_table_entry *ste = ipr_ses_table; for (i = 0; i < ARRAY_SIZE(ipr_ses_table); i++, ste++) { for (j = 0, matches = 0; j < IPR_PROD_ID_LEN; j++) { if (ste->compare_product_id_byte[j] == 'X') { - if (res->cfgte.std_inq_data.vpids.product_id[j] == ste->product_id[j]) + vpids = &res->std_inq_data.vpids; + if (vpids->product_id[j] == ste->product_id[j]) matches++; else break; @@ -1981,10 +2228,10 @@ static u32 ipr_get_max_scsi_speed(struct ipr_ioa_cfg *ioa_cfg, u8 bus, u8 bus_wi /* Loop through each config table entry in the config table buffer */ list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { - if (!(IPR_IS_SES_DEVICE(res->cfgte.std_inq_data))) + if (!(IPR_IS_SES_DEVICE(res->std_inq_data))) continue; - if (bus != res->cfgte.res_addr.bus) + if (bus != res->bus) continue; if (!(ste = ipr_find_ses_entry(res))) @@ -2518,9 +2765,9 @@ restart: list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { if (res->add_to_ml) { - bus = res->cfgte.res_addr.bus; - target = res->cfgte.res_addr.target; - lun = res->cfgte.res_addr.lun; + bus = res->bus; + target = res->target; + lun = res->lun; res->add_to_ml = 0; spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); scsi_add_device(ioa_cfg->host, bus, target, lun); @@ -3578,7 +3825,7 @@ static ssize_t ipr_show_adapter_handle(struct device *dev, struct device_attribu spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); res = (struct ipr_resource_entry *)sdev->hostdata; if (res) - len = snprintf(buf, PAGE_SIZE, "%08X\n", res->cfgte.res_handle); + len = snprintf(buf, PAGE_SIZE, "%08X\n", res->res_handle); spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); return len; } @@ -3591,8 +3838,43 @@ static struct device_attribute ipr_adapter_handle_attr = { .show = ipr_show_adapter_handle }; +/** + * ipr_show_resource_path - Show the resource path for this device. + * @dev: device struct + * @buf: buffer + * + * Return value: + * number of bytes printed to buffer + **/ +static ssize_t ipr_show_resource_path(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct scsi_device *sdev = to_scsi_device(dev); + struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)sdev->host->hostdata; + struct ipr_resource_entry *res; + unsigned long lock_flags = 0; + ssize_t len = -ENXIO; + char buffer[IPR_MAX_RES_PATH_LENGTH]; + + spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + res = (struct ipr_resource_entry *)sdev->hostdata; + if (res) + len = snprintf(buf, PAGE_SIZE, "%s\n", + ipr_format_resource_path(&res->res_path[0], &buffer[0])); + spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + return len; +} + +static struct device_attribute ipr_resource_path_attr = { + .attr = { + .name = "resource_path", + .mode = S_IRUSR, + }, + .show = ipr_show_resource_path +}; + static struct device_attribute *ipr_dev_attrs[] = { &ipr_adapter_handle_attr, + &ipr_resource_path_attr, NULL, }; @@ -3645,9 +3927,9 @@ static struct ipr_resource_entry *ipr_find_starget(struct scsi_target *starget) struct ipr_resource_entry *res; list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { - if ((res->cfgte.res_addr.bus == starget->channel) && - (res->cfgte.res_addr.target == starget->id) && - (res->cfgte.res_addr.lun == 0)) { + if ((res->bus == starget->channel) && + (res->target == starget->id) && + (res->lun == 0)) { return res; } } @@ -3717,6 +3999,17 @@ static int ipr_target_alloc(struct scsi_target *starget) static void ipr_target_destroy(struct scsi_target *starget) { struct ipr_sata_port *sata_port = starget->hostdata; + struct Scsi_Host *shost = dev_to_shost(&starget->dev); + struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *) shost->hostdata; + + if (ioa_cfg->sis64) { + if (starget->channel == IPR_ARRAY_VIRTUAL_BUS) + clear_bit(starget->id, ioa_cfg->array_ids); + else if (starget->channel == IPR_VSET_VIRTUAL_BUS) + clear_bit(starget->id, ioa_cfg->vset_ids); + else if (starget->channel == 0) + clear_bit(starget->id, ioa_cfg->target_ids); + } if (sata_port) { starget->hostdata = NULL; @@ -3738,9 +4031,9 @@ static struct ipr_resource_entry *ipr_find_sdev(struct scsi_device *sdev) struct ipr_resource_entry *res; list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { - if ((res->cfgte.res_addr.bus == sdev->channel) && - (res->cfgte.res_addr.target == sdev->id) && - (res->cfgte.res_addr.lun == sdev->lun)) + if ((res->bus == sdev->channel) && + (res->target == sdev->id) && + (res->lun == sdev->lun)) return res; } @@ -3789,6 +4082,7 @@ static int ipr_slave_configure(struct scsi_device *sdev) struct ipr_resource_entry *res; struct ata_port *ap = NULL; unsigned long lock_flags = 0; + char buffer[IPR_MAX_RES_PATH_LENGTH]; spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); res = sdev->hostdata; @@ -3815,6 +4109,9 @@ static int ipr_slave_configure(struct scsi_device *sdev) ata_sas_slave_configure(sdev, ap); } else scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun); + if (ioa_cfg->sis64) + sdev_printk(KERN_INFO, sdev, "Resource path: %s\n", + ipr_format_resource_path(&res->res_path[0], &buffer[0])); return 0; } spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); @@ -3963,7 +4260,7 @@ static int ipr_device_reset(struct ipr_ioa_cfg *ioa_cfg, } else regs = &ioarcb->u.add_data.u.regs; - ioarcb->res_handle = res->cfgte.res_handle; + ioarcb->res_handle = res->res_handle; cmd_pkt->request_type = IPR_RQTYPE_IOACMD; cmd_pkt->cdb[0] = IPR_RESET_DEVICE; if (ipr_is_gata(res)) { @@ -4013,19 +4310,7 @@ static int ipr_sata_reset(struct ata_link *link, unsigned int *classes, res = sata_port->res; if (res) { rc = ipr_device_reset(ioa_cfg, res); - switch(res->cfgte.proto) { - case IPR_PROTO_SATA: - case IPR_PROTO_SAS_STP: - *classes = ATA_DEV_ATA; - break; - case IPR_PROTO_SATA_ATAPI: - case IPR_PROTO_SAS_STP_ATAPI: - *classes = ATA_DEV_ATAPI; - break; - default: - *classes = ATA_DEV_UNKNOWN; - break; - }; + *classes = res->ata_class; } spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); @@ -4070,7 +4355,7 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd) return FAILED; list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) { - if (ipr_cmd->ioarcb.res_handle == res->cfgte.res_handle) { + if (ipr_cmd->ioarcb.res_handle == res->res_handle) { if (ipr_cmd->scsi_cmd) ipr_cmd->done = ipr_scsi_eh_done; if (ipr_cmd->qc) @@ -4092,7 +4377,7 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd) spin_lock_irq(scsi_cmd->device->host->host_lock); list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) { - if (ipr_cmd->ioarcb.res_handle == res->cfgte.res_handle) { + if (ipr_cmd->ioarcb.res_handle == res->res_handle) { rc = -EIO; break; } @@ -4131,13 +4416,13 @@ static void ipr_bus_reset_done(struct ipr_cmnd *ipr_cmd) struct ipr_resource_entry *res; ENTER; - list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { - if (!memcmp(&res->cfgte.res_handle, &ipr_cmd->ioarcb.res_handle, - sizeof(res->cfgte.res_handle))) { - scsi_report_bus_reset(ioa_cfg->host, res->cfgte.res_addr.bus); - break; + if (!ioa_cfg->sis64) + list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { + if (res->res_handle == ipr_cmd->ioarcb.res_handle) { + scsi_report_bus_reset(ioa_cfg->host, res->bus); + break; + } } - } /* * If abort has not completed, indicate the reset has, else call the @@ -4235,7 +4520,7 @@ static int ipr_cancel_op(struct scsi_cmnd * scsi_cmd) return SUCCESS; ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg); - ipr_cmd->ioarcb.res_handle = res->cfgte.res_handle; + ipr_cmd->ioarcb.res_handle = res->res_handle; cmd_pkt = &ipr_cmd->ioarcb.cmd_pkt; cmd_pkt->request_type = IPR_RQTYPE_IOACMD; cmd_pkt->cdb[0] = IPR_CANCEL_ALL_REQUESTS; @@ -5071,9 +5356,9 @@ static int ipr_queuecommand(struct scsi_cmnd *scsi_cmd, memcpy(ioarcb->cmd_pkt.cdb, scsi_cmd->cmnd, scsi_cmd->cmd_len); ipr_cmd->scsi_cmd = scsi_cmd; - ioarcb->res_handle = res->cfgte.res_handle; + ioarcb->res_handle = res->res_handle; ipr_cmd->done = ipr_scsi_done; - ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_GET_PHYS_LOC(res->cfgte.res_addr)); + ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_GET_RES_PHYS_LOC(res)); if (ipr_is_gscsi(res) || ipr_is_vset_device(res)) { if (scsi_cmd->underflow == 0) @@ -5216,20 +5501,9 @@ static void ipr_ata_phy_reset(struct ata_port *ap) goto out_unlock; } - switch(res->cfgte.proto) { - case IPR_PROTO_SATA: - case IPR_PROTO_SAS_STP: - ap->link.device[0].class = ATA_DEV_ATA; - break; - case IPR_PROTO_SATA_ATAPI: - case IPR_PROTO_SAS_STP_ATAPI: - ap->link.device[0].class = ATA_DEV_ATAPI; - break; - default: - ap->link.device[0].class = ATA_DEV_UNKNOWN; + ap->link.device[0].class = res->ata_class; + if (ap->link.device[0].class == ATA_DEV_UNKNOWN) ata_port_disable(ap); - break; - }; out_unlock: spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags); @@ -5315,8 +5589,7 @@ static void ipr_sata_done(struct ipr_cmnd *ipr_cmd) ipr_dump_ioasa(ioa_cfg, ipr_cmd, res); if (be32_to_cpu(ipr_cmd->ioasa.ioasc_specific) & IPR_ATA_DEVICE_WAS_RESET) - scsi_report_device_reset(ioa_cfg->host, res->cfgte.res_addr.bus, - res->cfgte.res_addr.target); + scsi_report_device_reset(ioa_cfg->host, res->bus, res->target); if (IPR_IOASC_SENSE_KEY(ioasc) > RECOVERED_ERROR) qc->err_mask |= __ac_err_mask(ipr_cmd->ioasa.u.gata.status); @@ -5452,7 +5725,7 @@ static unsigned int ipr_qc_issue(struct ata_queued_cmd *qc) list_add_tail(&ipr_cmd->queue, &ioa_cfg->pending_q); ipr_cmd->qc = qc; ipr_cmd->done = ipr_sata_done; - ipr_cmd->ioarcb.res_handle = res->cfgte.res_handle; + ipr_cmd->ioarcb.res_handle = res->res_handle; ioarcb->cmd_pkt.request_type = IPR_RQTYPE_ATA_PASSTHRU; ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_LINK_DESC; ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_ULEN_CHK; @@ -5466,7 +5739,7 @@ static unsigned int ipr_qc_issue(struct ata_queued_cmd *qc) regs->flags |= IPR_ATA_FLAG_STATUS_ON_GOOD_COMPLETION; ipr_copy_sata_tf(regs, &qc->tf); memcpy(ioarcb->cmd_pkt.cdb, qc->cdb, IPR_MAX_CDB_LEN); - ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_GET_PHYS_LOC(res->cfgte.res_addr)); + ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_GET_RES_PHYS_LOC(res)); switch (qc->tf.protocol) { case ATA_PROT_NODATA: @@ -5715,13 +5988,14 @@ static int ipr_set_supported_devs(struct ipr_cmnd *ipr_cmd) continue; ipr_cmd->u.res = res; - ipr_set_sup_dev_dflt(supp_dev, &res->cfgte.std_inq_data.vpids); + ipr_set_sup_dev_dflt(supp_dev, &res->std_inq_data.vpids); ioarcb->res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE); ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ; ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD; ioarcb->cmd_pkt.cdb[0] = IPR_SET_SUPPORTED_DEVICES; + ioarcb->cmd_pkt.cdb[1] = IPR_SET_ALL_SUPPORTED_DEVICES; ioarcb->cmd_pkt.cdb[7] = (sizeof(struct ipr_supported_device) >> 8) & 0xff; ioarcb->cmd_pkt.cdb[8] = sizeof(struct ipr_supported_device) & 0xff; @@ -5734,7 +6008,8 @@ static int ipr_set_supported_devs(struct ipr_cmnd *ipr_cmd) ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_SET_SUP_DEVICE_TIMEOUT); - ipr_cmd->job_step = ipr_set_supported_devs; + if (!ioa_cfg->sis64) + ipr_cmd->job_step = ipr_set_supported_devs; return IPR_RC_JOB_RETURN; } @@ -6182,24 +6457,36 @@ static int ipr_init_res_table(struct ipr_cmnd *ipr_cmd) { struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; struct ipr_resource_entry *res, *temp; - struct ipr_config_table_entry *cfgte; - int found, i; + struct ipr_config_table_entry_wrapper cfgtew; + int entries, found, flag, i; LIST_HEAD(old_res); ENTER; - if (ioa_cfg->cfg_table->hdr.flags & IPR_UCODE_DOWNLOAD_REQ) + if (ioa_cfg->sis64) + flag = ioa_cfg->u.cfg_table64->hdr64.flags; + else + flag = ioa_cfg->u.cfg_table->hdr.flags; + + if (flag & IPR_UCODE_DOWNLOAD_REQ) dev_err(&ioa_cfg->pdev->dev, "Microcode download required\n"); list_for_each_entry_safe(res, temp, &ioa_cfg->used_res_q, queue) list_move_tail(&res->queue, &old_res); - for (i = 0; i < ioa_cfg->cfg_table->hdr.num_entries; i++) { - cfgte = &ioa_cfg->cfg_table->dev[i]; + if (ioa_cfg->sis64) + entries = ioa_cfg->u.cfg_table64->hdr64.num_entries; + else + entries = ioa_cfg->u.cfg_table->hdr.num_entries; + + for (i = 0; i < entries; i++) { + if (ioa_cfg->sis64) + cfgtew.u.cfgte64 = &ioa_cfg->u.cfg_table64->dev[i]; + else + cfgtew.u.cfgte = &ioa_cfg->u.cfg_table->dev[i]; found = 0; list_for_each_entry_safe(res, temp, &old_res, queue) { - if (!memcmp(&res->cfgte.res_addr, - &cfgte->res_addr, sizeof(cfgte->res_addr))) { + if (ipr_is_same_device(res, &cfgtew)) { list_move_tail(&res->queue, &ioa_cfg->used_res_q); found = 1; break; @@ -6216,24 +6503,27 @@ static int ipr_init_res_table(struct ipr_cmnd *ipr_cmd) res = list_entry(ioa_cfg->free_res_q.next, struct ipr_resource_entry, queue); list_move_tail(&res->queue, &ioa_cfg->used_res_q); - ipr_init_res_entry(res); + ipr_init_res_entry(res, &cfgtew); res->add_to_ml = 1; } if (found) - memcpy(&res->cfgte, cfgte, sizeof(struct ipr_config_table_entry)); + ipr_update_res_entry(res, &cfgtew); } list_for_each_entry_safe(res, temp, &old_res, queue) { if (res->sdev) { res->del_from_ml = 1; - res->cfgte.res_handle = IPR_INVALID_RES_HANDLE; + res->res_handle = IPR_INVALID_RES_HANDLE; list_move_tail(&res->queue, &ioa_cfg->used_res_q); - } else { - list_move_tail(&res->queue, &ioa_cfg->free_res_q); } } + list_for_each_entry_safe(res, temp, &old_res, queue) { + ipr_clear_res_target(res); + list_move_tail(&res->queue, &ioa_cfg->free_res_q); + } + if (ioa_cfg->dual_raid && ipr_dual_ioa_raid) ipr_cmd->job_step = ipr_ioafp_mode_sense_page24; else @@ -6270,11 +6560,10 @@ static int ipr_ioafp_query_ioa_cfg(struct ipr_cmnd *ipr_cmd) ioarcb->res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE); ioarcb->cmd_pkt.cdb[0] = IPR_QUERY_IOA_CONFIG; - ioarcb->cmd_pkt.cdb[7] = (sizeof(struct ipr_config_table) >> 8) & 0xff; - ioarcb->cmd_pkt.cdb[8] = sizeof(struct ipr_config_table) & 0xff; + ioarcb->cmd_pkt.cdb[7] = (ioa_cfg->cfg_table_size >> 8) & 0xff; + ioarcb->cmd_pkt.cdb[8] = ioa_cfg->cfg_table_size & 0xff; - ipr_init_ioadl(ipr_cmd, ioa_cfg->cfg_table_dma, - sizeof(struct ipr_config_table), + ipr_init_ioadl(ipr_cmd, ioa_cfg->cfg_table_dma, ioa_cfg->cfg_table_size, IPR_IOADL_FLAGS_READ_LAST); ipr_cmd->job_step = ipr_init_res_table; @@ -6567,7 +6856,7 @@ static void ipr_init_ioa_mem(struct ipr_ioa_cfg *ioa_cfg) ioa_cfg->toggle_bit = 1; /* Zero out config table */ - memset(ioa_cfg->cfg_table, 0, sizeof(struct ipr_config_table)); + memset(ioa_cfg->u.cfg_table, 0, ioa_cfg->cfg_table_size); } /** @@ -7370,8 +7659,8 @@ static void ipr_free_mem(struct ipr_ioa_cfg *ioa_cfg) ipr_free_cmd_blks(ioa_cfg); pci_free_consistent(ioa_cfg->pdev, sizeof(u32) * IPR_NUM_CMD_BLKS, ioa_cfg->host_rrq, ioa_cfg->host_rrq_dma); - pci_free_consistent(ioa_cfg->pdev, sizeof(struct ipr_config_table), - ioa_cfg->cfg_table, + pci_free_consistent(ioa_cfg->pdev, ioa_cfg->cfg_table_size, + ioa_cfg->u.cfg_table, ioa_cfg->cfg_table_dma); for (i = 0; i < IPR_NUM_HCAMS; i++) { @@ -7488,13 +7777,24 @@ static int __devinit ipr_alloc_mem(struct ipr_ioa_cfg *ioa_cfg) ENTER; ioa_cfg->res_entries = kzalloc(sizeof(struct ipr_resource_entry) * - IPR_MAX_PHYSICAL_DEVS, GFP_KERNEL); + ioa_cfg->max_devs_supported, GFP_KERNEL); if (!ioa_cfg->res_entries) goto out; - for (i = 0; i < IPR_MAX_PHYSICAL_DEVS; i++) + if (ioa_cfg->sis64) { + ioa_cfg->target_ids = kzalloc(sizeof(unsigned long) * + BITS_TO_LONGS(ioa_cfg->max_devs_supported), GFP_KERNEL); + ioa_cfg->array_ids = kzalloc(sizeof(unsigned long) * + BITS_TO_LONGS(ioa_cfg->max_devs_supported), GFP_KERNEL); + ioa_cfg->vset_ids = kzalloc(sizeof(unsigned long) * + BITS_TO_LONGS(ioa_cfg->max_devs_supported), GFP_KERNEL); + } + + for (i = 0; i < ioa_cfg->max_devs_supported; i++) { list_add_tail(&ioa_cfg->res_entries[i].queue, &ioa_cfg->free_res_q); + ioa_cfg->res_entries[i].ioa_cfg = ioa_cfg; + } ioa_cfg->vpd_cbs = pci_alloc_consistent(ioa_cfg->pdev, sizeof(struct ipr_misc_cbs), @@ -7513,11 +7813,11 @@ static int __devinit ipr_alloc_mem(struct ipr_ioa_cfg *ioa_cfg) if (!ioa_cfg->host_rrq) goto out_ipr_free_cmd_blocks; - ioa_cfg->cfg_table = pci_alloc_consistent(ioa_cfg->pdev, - sizeof(struct ipr_config_table), - &ioa_cfg->cfg_table_dma); + ioa_cfg->u.cfg_table = pci_alloc_consistent(ioa_cfg->pdev, + ioa_cfg->cfg_table_size, + &ioa_cfg->cfg_table_dma); - if (!ioa_cfg->cfg_table) + if (!ioa_cfg->u.cfg_table) goto out_free_host_rrq; for (i = 0; i < IPR_NUM_HCAMS; i++) { @@ -7551,8 +7851,9 @@ out_free_hostrcb_dma: ioa_cfg->hostrcb[i], ioa_cfg->hostrcb_dma[i]); } - pci_free_consistent(pdev, sizeof(struct ipr_config_table), - ioa_cfg->cfg_table, ioa_cfg->cfg_table_dma); + pci_free_consistent(pdev, ioa_cfg->cfg_table_size, + ioa_cfg->u.cfg_table, + ioa_cfg->cfg_table_dma); out_free_host_rrq: pci_free_consistent(pdev, sizeof(u32) * IPR_NUM_CMD_BLKS, ioa_cfg->host_rrq, ioa_cfg->host_rrq_dma); @@ -7633,9 +7934,19 @@ static void __devinit ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg, ioa_cfg->cache_state = CACHE_DISABLED; ipr_initialize_bus_attr(ioa_cfg); + ioa_cfg->max_devs_supported = ipr_max_devs; - host->max_id = IPR_MAX_NUM_TARGETS_PER_BUS; - host->max_lun = IPR_MAX_NUM_LUNS_PER_TARGET; + if (ioa_cfg->sis64) { + host->max_id = IPR_MAX_SIS64_TARGETS_PER_BUS; + host->max_lun = IPR_MAX_SIS64_LUNS_PER_TARGET; + if (ipr_max_devs > IPR_MAX_SIS64_DEVS) + ioa_cfg->max_devs_supported = IPR_MAX_SIS64_DEVS; + } else { + host->max_id = IPR_MAX_NUM_TARGETS_PER_BUS; + host->max_lun = IPR_MAX_NUM_LUNS_PER_TARGET; + if (ipr_max_devs > IPR_MAX_PHYSICAL_DEVS) + ioa_cfg->max_devs_supported = IPR_MAX_PHYSICAL_DEVS; + } host->max_channel = IPR_MAX_BUS_TO_SCAN; host->unique_id = host->host_no; host->max_cmd_len = IPR_MAX_CDB_LEN; @@ -7896,6 +8207,15 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev, if ((rc = ipr_set_pcix_cmd_reg(ioa_cfg))) goto cleanup_nomem; + if (ioa_cfg->sis64) + ioa_cfg->cfg_table_size = (sizeof(struct ipr_config_table_hdr64) + + ((sizeof(struct ipr_config_table_entry64) + * ioa_cfg->max_devs_supported))); + else + ioa_cfg->cfg_table_size = (sizeof(struct ipr_config_table_hdr) + + ((sizeof(struct ipr_config_table_entry) + * ioa_cfg->max_devs_supported))); + rc = ipr_alloc_mem(ioa_cfg); if (rc < 0) { dev_err(&pdev->dev, diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h index 64e41df..f10c57b 100644 --- a/drivers/scsi/ipr.h +++ b/drivers/scsi/ipr.h @@ -118,6 +118,10 @@ #define IPR_NUM_LOG_HCAMS 2 #define IPR_NUM_CFG_CHG_HCAMS 2 #define IPR_NUM_HCAMS (IPR_NUM_LOG_HCAMS + IPR_NUM_CFG_CHG_HCAMS) + +#define IPR_MAX_SIS64_TARGETS_PER_BUS 1024 +#define IPR_MAX_SIS64_LUNS_PER_TARGET 0xffffffff + #define IPR_MAX_NUM_TARGETS_PER_BUS 256 #define IPR_MAX_NUM_LUNS_PER_TARGET 256 #define IPR_MAX_NUM_VSET_LUNS_PER_TARGET 8 @@ -139,6 +143,8 @@ IPR_NUM_INTERNAL_CMD_BLKS) #define IPR_MAX_PHYSICAL_DEVS 192 +#define IPR_DEFAULT_SIS64_DEVS 1024 +#define IPR_MAX_SIS64_DEVS 4096 #define IPR_MAX_SGLIST 64 #define IPR_IOA_MAX_SECTORS 32767 @@ -173,6 +179,7 @@ #define IPR_HCAM_CDB_OP_CODE_CONFIG_CHANGE 0x01 #define IPR_HCAM_CDB_OP_CODE_LOG_DATA 0x02 #define IPR_SET_SUPPORTED_DEVICES 0xFB +#define IPR_SET_ALL_SUPPORTED_DEVICES 0x80 #define IPR_IOA_SHUTDOWN 0xF7 #define IPR_WR_BUF_DOWNLOAD_AND_SAVE 0x05 @@ -318,27 +325,27 @@ struct ipr_std_inq_data { u8 serial_num[IPR_SERIAL_NUM_LEN]; }__attribute__ ((packed)); +#define IPR_RES_TYPE_AF_DASD 0x00 +#define IPR_RES_TYPE_GENERIC_SCSI 0x01 +#define IPR_RES_TYPE_VOLUME_SET 0x02 +#define IPR_RES_TYPE_REMOTE_AF_DASD 0x03 +#define IPR_RES_TYPE_GENERIC_ATA 0x04 +#define IPR_RES_TYPE_ARRAY 0x05 +#define IPR_RES_TYPE_IOAFP 0xff + struct ipr_config_table_entry { u8 proto; #define IPR_PROTO_SATA 0x02 #define IPR_PROTO_SATA_ATAPI 0x03 #define IPR_PROTO_SAS_STP 0x06 -#define IPR_PROTO_SAS_STP_ATAPI 0x07 +#define IPR_PROTO_SAS_STP_ATAPI 0x07 u8 array_id; u8 flags; -#define IPR_IS_IOA_RESOURCE 0x80 -#define IPR_IS_ARRAY_MEMBER 0x20 -#define IPR_IS_HOT_SPARE 0x10 - +#define IPR_IS_IOA_RESOURCE 0x80 u8 rsvd_subtype; -#define IPR_RES_SUBTYPE(res) (((res)->cfgte.rsvd_subtype) & 0x0f) -#define IPR_SUBTYPE_AF_DASD 0 -#define IPR_SUBTYPE_GENERIC_SCSI 1 -#define IPR_SUBTYPE_VOLUME_SET 2 -#define IPR_SUBTYPE_GENERIC_ATA 4 - -#define IPR_QUEUEING_MODEL(res) ((((res)->cfgte.flags) & 0x70) >> 4) -#define IPR_QUEUE_FROZEN_MODEL 0 + +#define IPR_QUEUEING_MODEL(res) ((((res)->flags) & 0x70) >> 4) +#define IPR_QUEUE_FROZEN_MODEL 0 #define IPR_QUEUE_NACA_MODEL 1 struct ipr_res_addr res_addr; @@ -347,6 +354,28 @@ struct ipr_config_table_entry { struct ipr_std_inq_data std_inq_data; }__attribute__ ((packed, aligned (4))); +struct ipr_config_table_entry64 { + u8 res_type; + u8 proto; + u8 vset_num; + u8 array_id; + __be16 flags; + __be16 res_flags; +#define IPR_QUEUEING_MODEL64(res) ((((res)->res_flags) & 0x7000) >> 12) + __be32 res_handle; + u8 dev_id_type; + u8 reserved[3]; + __be64 dev_id; + __be64 lun; + __be64 lun_wwn[2]; +#define IPR_MAX_RES_PATH_LENGTH 24 + __be64 res_path; + struct ipr_std_inq_data std_inq_data; + u8 reserved2[4]; + __be64 reserved3[2]; // description text + u8 reserved4[8]; +}__attribute__ ((packed, aligned (8))); + struct ipr_config_table_hdr { u8 num_entries; u8 flags; @@ -354,13 +383,35 @@ struct ipr_config_table_hdr { __be16 reserved; }__attribute__((packed, aligned (4))); +struct ipr_config_table_hdr64 { + __be16 num_entries; + __be16 reserved; + u8 flags; + u8 reserved2[11]; +}__attribute__((packed, aligned (4))); + struct ipr_config_table { struct ipr_config_table_hdr hdr; - struct ipr_config_table_entry dev[IPR_MAX_PHYSICAL_DEVS]; + struct ipr_config_table_entry dev[0]; }__attribute__((packed, aligned (4))); +struct ipr_config_table64 { + struct ipr_config_table_hdr64 hdr64; + struct ipr_config_table_entry64 dev[0]; +}__attribute__((packed, aligned (8))); + +struct ipr_config_table_entry_wrapper { + union { + struct ipr_config_table_entry *cfgte; + struct ipr_config_table_entry64 *cfgte64; + } u; +}; + struct ipr_hostrcb_cfg_ch_not { - struct ipr_config_table_entry cfgte; + union { + struct ipr_config_table_entry cfgte; + struct ipr_config_table_entry64 cfgte64; + } u; u8 reserved[936]; }__attribute__((packed, aligned (4))); @@ -987,28 +1038,48 @@ struct ipr_sata_port { }; struct ipr_resource_entry { - struct ipr_config_table_entry cfgte; u8 needs_sync_complete:1; u8 in_erp:1; u8 add_to_ml:1; u8 del_from_ml:1; u8 resetting_device:1; + u32 bus; /* AKA channel */ + u32 target; /* AKA id */ + u32 lun; +#define IPR_ARRAY_VIRTUAL_BUS 0x1 +#define IPR_VSET_VIRTUAL_BUS 0x2 +#define IPR_IOAFP_VIRTUAL_BUS 0x3 + +#define IPR_GET_RES_PHYS_LOC(res) \ + (((res)->bus << 24) | ((res)->target << 8) | (res)->lun) + + u8 ata_class; + + u8 flags; + __be16 res_flags; + + __be32 type; + + u8 qmodel; + struct ipr_std_inq_data std_inq_data; + + __be32 res_handle; + __be64 dev_id; + struct scsi_lun dev_lun; + u8 res_path[8]; + + struct ipr_ioa_cfg *ioa_cfg; struct scsi_device *sdev; struct ipr_sata_port *sata_port; struct list_head queue; -}; +}; /* struct ipr_resource_entry */ struct ipr_resource_hdr { u16 num_entries; u16 reserved; }; -struct ipr_resource_table { - struct ipr_resource_hdr hdr; - struct ipr_resource_entry dev[IPR_MAX_PHYSICAL_DEVS]; -}; - struct ipr_misc_cbs { struct ipr_ioa_vpd ioa_vpd; struct ipr_inquiry_page0 page0_data; @@ -1133,6 +1204,13 @@ struct ipr_ioa_cfg { u8 revid; + /* + * Bitmaps for SIS64 generated target values + */ + unsigned long *target_ids; + unsigned long *array_ids; + unsigned long *vset_ids; + enum ipr_cache_state cache_state; u16 type; /* CCIN of the card */ @@ -1164,8 +1242,13 @@ struct ipr_ioa_cfg { char cfg_table_start[8]; #define IPR_CFG_TBL_START "cfg" - struct ipr_config_table *cfg_table; + union { + struct ipr_config_table *cfg_table; + struct ipr_config_table64 *cfg_table64; + } u; dma_addr_t cfg_table_dma; + u32 cfg_table_size; + u32 max_devs_supported; char resource_table_label[8]; #define IPR_RES_TABLE_LABEL "res_tbl" @@ -1234,7 +1317,7 @@ struct ipr_ioa_cfg { #define IPR_CMD_LABEL "ipr_cmd" struct ipr_cmnd *ipr_cmnd_list[IPR_NUM_CMD_BLKS]; dma_addr_t ipr_cmnd_list_dma[IPR_NUM_CMD_BLKS]; -}; +}; /* struct ipr_ioa_cfg */ struct ipr_cmnd { struct ipr_ioarcb ioarcb; @@ -1412,6 +1495,13 @@ struct ipr_ucode_image_header { #define ipr_info(...) printk(KERN_INFO IPR_NAME ": "__VA_ARGS__) #define ipr_dbg(...) IPR_DBG_CMD(printk(KERN_INFO IPR_NAME ": "__VA_ARGS__)) +#define ipr_res_printk(level, ioa_cfg, bus, target, lun, fmt, ...) \ + printk(level IPR_NAME ": %d:%d:%d:%d: " fmt, (ioa_cfg)->host->host_no, \ + bus, target, lun, ##__VA_ARGS__) + +#define ipr_res_err(ioa_cfg, res, fmt, ...) \ + ipr_res_printk(KERN_ERR, ioa_cfg, (res)->bus, (res)->target, (res)->lun, fmt, ##__VA_ARGS__) + #define ipr_ra_printk(level, ioa_cfg, ra, fmt, ...) \ printk(level IPR_NAME ": %d:%d:%d:%d: " fmt, (ioa_cfg)->host->host_no, \ (ra).bus, (ra).target, (ra).lun, ##__VA_ARGS__) @@ -1419,9 +1509,6 @@ struct ipr_ucode_image_header { #define ipr_ra_err(ioa_cfg, ra, fmt, ...) \ ipr_ra_printk(KERN_ERR, ioa_cfg, ra, fmt, ##__VA_ARGS__) -#define ipr_res_err(ioa_cfg, res, fmt, ...) \ - ipr_ra_err(ioa_cfg, (res)->cfgte.res_addr, fmt, ##__VA_ARGS__) - #define ipr_phys_res_err(ioa_cfg, res, fmt, ...) \ { \ if ((res).bus >= IPR_MAX_NUM_BUSES) { \ @@ -1467,7 +1554,7 @@ ipr_err("----------------------------------------------------------\n") **/ static inline int ipr_is_ioa_resource(struct ipr_resource_entry *res) { - return (res->cfgte.flags & IPR_IS_IOA_RESOURCE) ? 1 : 0; + return res->type == IPR_RES_TYPE_IOAFP; } /** @@ -1479,12 +1566,8 @@ static inline int ipr_is_ioa_resource(struct ipr_resource_entry *res) **/ static inline int ipr_is_af_dasd_device(struct ipr_resource_entry *res) { - if (IPR_IS_DASD_DEVICE(res->cfgte.std_inq_data) && - !ipr_is_ioa_resource(res) && - IPR_RES_SUBTYPE(res) == IPR_SUBTYPE_AF_DASD) - return 1; - else - return 0; + return res->type == IPR_RES_TYPE_AF_DASD || + res->type == IPR_RES_TYPE_REMOTE_AF_DASD; } /** @@ -1496,12 +1579,7 @@ static inline int ipr_is_af_dasd_device(struct ipr_resource_entry *res) **/ static inline int ipr_is_vset_device(struct ipr_resource_entry *res) { - if (IPR_IS_DASD_DEVICE(res->cfgte.std_inq_data) && - !ipr_is_ioa_resource(res) && - IPR_RES_SUBTYPE(res) == IPR_SUBTYPE_VOLUME_SET) - return 1; - else - return 0; + return res->type == IPR_RES_TYPE_VOLUME_SET; } /** @@ -1513,11 +1591,7 @@ static inline int ipr_is_vset_device(struct ipr_resource_entry *res) **/ static inline int ipr_is_gscsi(struct ipr_resource_entry *res) { - if (!ipr_is_ioa_resource(res) && - IPR_RES_SUBTYPE(res) == IPR_SUBTYPE_GENERIC_SCSI) - return 1; - else - return 0; + return res->type == IPR_RES_TYPE_GENERIC_SCSI; } /** @@ -1530,7 +1604,7 @@ static inline int ipr_is_gscsi(struct ipr_resource_entry *res) static inline int ipr_is_scsi_disk(struct ipr_resource_entry *res) { if (ipr_is_af_dasd_device(res) || - (ipr_is_gscsi(res) && IPR_IS_DASD_DEVICE(res->cfgte.std_inq_data))) + (ipr_is_gscsi(res) && IPR_IS_DASD_DEVICE(res->std_inq_data))) return 1; else return 0; @@ -1545,11 +1619,7 @@ static inline int ipr_is_scsi_disk(struct ipr_resource_entry *res) **/ static inline int ipr_is_gata(struct ipr_resource_entry *res) { - if (!ipr_is_ioa_resource(res) && - IPR_RES_SUBTYPE(res) == IPR_SUBTYPE_GENERIC_ATA) - return 1; - else - return 0; + return res->type == IPR_RES_TYPE_GENERIC_ATA; } /** @@ -1561,7 +1631,7 @@ static inline int ipr_is_gata(struct ipr_resource_entry *res) **/ static inline int ipr_is_naca_model(struct ipr_resource_entry *res) { - if (ipr_is_gscsi(res) && IPR_QUEUEING_MODEL(res) == IPR_QUEUE_NACA_MODEL) + if (ipr_is_gscsi(res) && res->qmodel == IPR_QUEUE_NACA_MODEL) return 1; return 0; } -- cgit v0.10.2 From 4565e3706329f65b5e64328b5369c53b6ab2715c Mon Sep 17 00:00:00 2001 From: Wayne Boyer Date: Fri, 19 Feb 2010 13:24:07 -0800 Subject: [SCSI] ipr: add error handling updates for the next generation chip Add support for the new log data notification and overlay IDs. Signed-off-by: Wayne Boyer Signed-off-by: James Bottomley diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 91e330a..b2e60bd 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -1079,7 +1079,7 @@ static char *ipr_format_resource_path(u8 *res_path, char *buffer) sprintf(buffer, "%02X", res_path[0]); for (i=1; res_path[i] != 0xff; i++) - sprintf(buffer, "%s:%02X", buffer, res_path[i]); + sprintf(buffer, "%s-%02X", buffer, res_path[i]); return buffer; } @@ -1385,8 +1385,12 @@ static void ipr_log_ext_vpd(struct ipr_ext_vpd *vpd) static void ipr_log_enhanced_cache_error(struct ipr_ioa_cfg *ioa_cfg, struct ipr_hostrcb *hostrcb) { - struct ipr_hostrcb_type_12_error *error = - &hostrcb->hcam.u.error.u.type_12_error; + struct ipr_hostrcb_type_12_error *error; + + if (ioa_cfg->sis64) + error = &hostrcb->hcam.u.error64.u.type_12_error; + else + error = &hostrcb->hcam.u.error.u.type_12_error; ipr_err("-----Current Configuration-----\n"); ipr_err("Cache Directory Card Information:\n"); @@ -1479,6 +1483,48 @@ static void ipr_log_enhanced_config_error(struct ipr_ioa_cfg *ioa_cfg, } /** + * ipr_log_sis64_config_error - Log a device error. + * @ioa_cfg: ioa config struct + * @hostrcb: hostrcb struct + * + * Return value: + * none + **/ +static void ipr_log_sis64_config_error(struct ipr_ioa_cfg *ioa_cfg, + struct ipr_hostrcb *hostrcb) +{ + int errors_logged, i; + struct ipr_hostrcb64_device_data_entry_enhanced *dev_entry; + struct ipr_hostrcb_type_23_error *error; + char buffer[IPR_MAX_RES_PATH_LENGTH]; + + error = &hostrcb->hcam.u.error64.u.type_23_error; + errors_logged = be32_to_cpu(error->errors_logged); + + ipr_err("Device Errors Detected/Logged: %d/%d\n", + be32_to_cpu(error->errors_detected), errors_logged); + + dev_entry = error->dev; + + for (i = 0; i < errors_logged; i++, dev_entry++) { + ipr_err_separator; + + ipr_err("Device %d : %s", i + 1, + ipr_format_resource_path(&dev_entry->res_path[0], &buffer[0])); + ipr_log_ext_vpd(&dev_entry->vpd); + + ipr_err("-----New Device Information-----\n"); + ipr_log_ext_vpd(&dev_entry->new_vpd); + + ipr_err("Cache Directory Card Information:\n"); + ipr_log_ext_vpd(&dev_entry->ioa_last_with_dev_vpd); + + ipr_err("Adapter Card Information:\n"); + ipr_log_ext_vpd(&dev_entry->cfc_last_with_dev_vpd); + } +} + +/** * ipr_log_config_error - Log a configuration error. * @ioa_cfg: ioa config struct * @hostrcb: hostrcb struct @@ -1672,7 +1718,11 @@ static void ipr_log_enhanced_dual_ioa_error(struct ipr_ioa_cfg *ioa_cfg, { struct ipr_hostrcb_type_17_error *error; - error = &hostrcb->hcam.u.error.u.type_17_error; + if (ioa_cfg->sis64) + error = &hostrcb->hcam.u.error64.u.type_17_error; + else + error = &hostrcb->hcam.u.error.u.type_17_error; + error->failure_reason[sizeof(error->failure_reason) - 1] = '\0'; strim(error->failure_reason); @@ -1779,6 +1829,42 @@ static void ipr_log_fabric_path(struct ipr_hostrcb *hostrcb, fabric->ioa_port, fabric->cascaded_expander, fabric->phy); } +/** + * ipr_log64_fabric_path - Log a fabric path error + * @hostrcb: hostrcb struct + * @fabric: fabric descriptor + * + * Return value: + * none + **/ +static void ipr_log64_fabric_path(struct ipr_hostrcb *hostrcb, + struct ipr_hostrcb64_fabric_desc *fabric) +{ + int i, j; + u8 path_state = fabric->path_state; + u8 active = path_state & IPR_PATH_ACTIVE_MASK; + u8 state = path_state & IPR_PATH_STATE_MASK; + char buffer[IPR_MAX_RES_PATH_LENGTH]; + + for (i = 0; i < ARRAY_SIZE(path_active_desc); i++) { + if (path_active_desc[i].active != active) + continue; + + for (j = 0; j < ARRAY_SIZE(path_state_desc); j++) { + if (path_state_desc[j].state != state) + continue; + + ipr_hcam_err(hostrcb, "%s %s: Resource Path=%s\n", + path_active_desc[i].desc, path_state_desc[j].desc, + ipr_format_resource_path(&fabric->res_path[0], &buffer[0])); + return; + } + } + + ipr_err("Path state=%02X Resource Path=%s\n", path_state, + ipr_format_resource_path(&fabric->res_path[0], &buffer[0])); +} + static const struct { u8 type; char *desc; @@ -1888,6 +1974,49 @@ static void ipr_log_path_elem(struct ipr_hostrcb *hostrcb, } /** + * ipr_log64_path_elem - Log a fabric path element. + * @hostrcb: hostrcb struct + * @cfg: fabric path element struct + * + * Return value: + * none + **/ +static void ipr_log64_path_elem(struct ipr_hostrcb *hostrcb, + struct ipr_hostrcb64_config_element *cfg) +{ + int i, j; + u8 desc_id = cfg->descriptor_id & IPR_DESCRIPTOR_MASK; + u8 type = cfg->type_status & IPR_PATH_CFG_TYPE_MASK; + u8 status = cfg->type_status & IPR_PATH_CFG_STATUS_MASK; + char buffer[IPR_MAX_RES_PATH_LENGTH]; + + if (type == IPR_PATH_CFG_NOT_EXIST || desc_id != IPR_DESCRIPTOR_SIS64) + return; + + for (i = 0; i < ARRAY_SIZE(path_type_desc); i++) { + if (path_type_desc[i].type != type) + continue; + + for (j = 0; j < ARRAY_SIZE(path_status_desc); j++) { + if (path_status_desc[j].status != status) + continue; + + ipr_hcam_err(hostrcb, "%s %s: Resource Path=%s, Link rate=%s, WWN=%08X%08X\n", + path_status_desc[j].desc, path_type_desc[i].desc, + ipr_format_resource_path(&cfg->res_path[0], &buffer[0]), + link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK], + be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1])); + return; + } + } + ipr_hcam_err(hostrcb, "Path element=%02X: Resource Path=%s, Link rate=%s " + "WWN=%08X%08X\n", cfg->type_status, + ipr_format_resource_path(&cfg->res_path[0], &buffer[0]), + link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK], + be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1])); +} + +/** * ipr_log_fabric_error - Log a fabric error. * @ioa_cfg: ioa config struct * @hostrcb: hostrcb struct @@ -1925,6 +2054,96 @@ static void ipr_log_fabric_error(struct ipr_ioa_cfg *ioa_cfg, } /** + * ipr_log_sis64_array_error - Log a sis64 array error. + * @ioa_cfg: ioa config struct + * @hostrcb: hostrcb struct + * + * Return value: + * none + **/ +static void ipr_log_sis64_array_error(struct ipr_ioa_cfg *ioa_cfg, + struct ipr_hostrcb *hostrcb) +{ + int i, num_entries; + struct ipr_hostrcb_type_24_error *error; + struct ipr_hostrcb64_array_data_entry *array_entry; + char buffer[IPR_MAX_RES_PATH_LENGTH]; + const u8 zero_sn[IPR_SERIAL_NUM_LEN] = { [0 ... IPR_SERIAL_NUM_LEN-1] = '0' }; + + error = &hostrcb->hcam.u.error64.u.type_24_error; + + ipr_err_separator; + + ipr_err("RAID %s Array Configuration: %s\n", + error->protection_level, + ipr_format_resource_path(&error->last_res_path[0], &buffer[0])); + + ipr_err_separator; + + array_entry = error->array_member; + num_entries = min_t(u32, be32_to_cpu(error->num_entries), + sizeof(error->array_member)); + + for (i = 0; i < num_entries; i++, array_entry++) { + + if (!memcmp(array_entry->vpd.vpd.sn, zero_sn, IPR_SERIAL_NUM_LEN)) + continue; + + if (error->exposed_mode_adn == i) + ipr_err("Exposed Array Member %d:\n", i); + else + ipr_err("Array Member %d:\n", i); + + ipr_err("Array Member %d:\n", i); + ipr_log_ext_vpd(&array_entry->vpd); + ipr_err("Current Location: %s", + ipr_format_resource_path(&array_entry->res_path[0], &buffer[0])); + ipr_err("Expected Location: %s", + ipr_format_resource_path(&array_entry->expected_res_path[0], &buffer[0])); + + ipr_err_separator; + } +} + +/** + * ipr_log_sis64_fabric_error - Log a sis64 fabric error. + * @ioa_cfg: ioa config struct + * @hostrcb: hostrcb struct + * + * Return value: + * none + **/ +static void ipr_log_sis64_fabric_error(struct ipr_ioa_cfg *ioa_cfg, + struct ipr_hostrcb *hostrcb) +{ + struct ipr_hostrcb_type_30_error *error; + struct ipr_hostrcb64_fabric_desc *fabric; + struct ipr_hostrcb64_config_element *cfg; + int i, add_len; + + error = &hostrcb->hcam.u.error64.u.type_30_error; + + error->failure_reason[sizeof(error->failure_reason) - 1] = '\0'; + ipr_hcam_err(hostrcb, "%s\n", error->failure_reason); + + add_len = be32_to_cpu(hostrcb->hcam.length) - + (offsetof(struct ipr_hostrcb64_error, u) + + offsetof(struct ipr_hostrcb_type_30_error, desc)); + + for (i = 0, fabric = error->desc; i < error->num_entries; i++) { + ipr_log64_fabric_path(hostrcb, fabric); + for_each_fabric_cfg(fabric, cfg) + ipr_log64_path_elem(hostrcb, cfg); + + add_len -= be16_to_cpu(fabric->length); + fabric = (struct ipr_hostrcb64_fabric_desc *) + ((unsigned long)fabric + be16_to_cpu(fabric->length)); + } + + ipr_log_hex_data(ioa_cfg, (u32 *)fabric, add_len); +} + +/** * ipr_log_generic_error - Log an adapter error. * @ioa_cfg: ioa config struct * @hostrcb: hostrcb struct @@ -1983,13 +2202,16 @@ static void ipr_handle_log_data(struct ipr_ioa_cfg *ioa_cfg, if (hostrcb->hcam.notifications_lost == IPR_HOST_RCB_NOTIFICATIONS_LOST) dev_err(&ioa_cfg->pdev->dev, "Error notifications lost\n"); - ioasc = be32_to_cpu(hostrcb->hcam.u.error.failing_dev_ioasc); + if (ioa_cfg->sis64) + ioasc = be32_to_cpu(hostrcb->hcam.u.error64.fd_ioasc); + else + ioasc = be32_to_cpu(hostrcb->hcam.u.error.fd_ioasc); - if (ioasc == IPR_IOASC_BUS_WAS_RESET || - ioasc == IPR_IOASC_BUS_WAS_RESET_BY_OTHER) { + if (!ioa_cfg->sis64 && (ioasc == IPR_IOASC_BUS_WAS_RESET || + ioasc == IPR_IOASC_BUS_WAS_RESET_BY_OTHER)) { /* Tell the midlayer we had a bus reset so it will handle the UA properly */ scsi_report_bus_reset(ioa_cfg->host, - hostrcb->hcam.u.error.failing_dev_res_addr.bus); + hostrcb->hcam.u.error.fd_res_addr.bus); } error_index = ipr_get_error(ioasc); @@ -2037,6 +2259,16 @@ static void ipr_handle_log_data(struct ipr_ioa_cfg *ioa_cfg, case IPR_HOST_RCB_OVERLAY_ID_20: ipr_log_fabric_error(ioa_cfg, hostrcb); break; + case IPR_HOST_RCB_OVERLAY_ID_23: + ipr_log_sis64_config_error(ioa_cfg, hostrcb); + break; + case IPR_HOST_RCB_OVERLAY_ID_24: + case IPR_HOST_RCB_OVERLAY_ID_26: + ipr_log_sis64_array_error(ioa_cfg, hostrcb); + break; + case IPR_HOST_RCB_OVERLAY_ID_30: + ipr_log_sis64_fabric_error(ioa_cfg, hostrcb); + break; case IPR_HOST_RCB_OVERLAY_ID_1: case IPR_HOST_RCB_OVERLAY_ID_DEFAULT: default: @@ -2061,7 +2293,12 @@ static void ipr_process_error(struct ipr_cmnd *ipr_cmd) struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; struct ipr_hostrcb *hostrcb = ipr_cmd->u.hostrcb; u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); - u32 fd_ioasc = be32_to_cpu(hostrcb->hcam.u.error.failing_dev_ioasc); + u32 fd_ioasc; + + if (ioa_cfg->sis64) + fd_ioasc = be32_to_cpu(hostrcb->hcam.u.error64.fd_ioasc); + else + fd_ioasc = be32_to_cpu(hostrcb->hcam.u.error.fd_ioasc); list_del(&hostrcb->queue); list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q); @@ -6996,7 +7233,7 @@ static void ipr_get_unit_check_buffer(struct ipr_ioa_cfg *ioa_cfg) if (!rc) { ipr_handle_log_data(ioa_cfg, hostrcb); - ioasc = be32_to_cpu(hostrcb->hcam.u.error.failing_dev_ioasc); + ioasc = be32_to_cpu(hostrcb->hcam.u.error.fd_ioasc); if (ioasc == IPR_IOASC_NR_IOA_RESET_REQUIRED && ioa_cfg->sdt_state == GET_DUMP) ioa_cfg->sdt_state = WAIT_FOR_DUMP; diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h index f10c57b..e6e9017 100644 --- a/drivers/scsi/ipr.h +++ b/drivers/scsi/ipr.h @@ -754,12 +754,29 @@ struct ipr_hostrcb_device_data_entry_enhanced { struct ipr_ext_vpd cfc_last_with_dev_vpd; }__attribute__((packed, aligned (4))); +struct ipr_hostrcb64_device_data_entry_enhanced { + struct ipr_ext_vpd vpd; + u8 ccin[4]; + u8 res_path[8]; + struct ipr_ext_vpd new_vpd; + u8 new_ccin[4]; + struct ipr_ext_vpd ioa_last_with_dev_vpd; + struct ipr_ext_vpd cfc_last_with_dev_vpd; +}__attribute__((packed, aligned (4))); + struct ipr_hostrcb_array_data_entry { struct ipr_vpd vpd; struct ipr_res_addr expected_dev_res_addr; struct ipr_res_addr dev_res_addr; }__attribute__((packed, aligned (4))); +struct ipr_hostrcb64_array_data_entry { + struct ipr_ext_vpd vpd; + u8 ccin[4]; + u8 expected_res_path[8]; + u8 res_path[8]; +}__attribute__((packed, aligned (4))); + struct ipr_hostrcb_array_data_entry_enhanced { struct ipr_ext_vpd vpd; u8 ccin[4]; @@ -811,6 +828,14 @@ struct ipr_hostrcb_type_13_error { struct ipr_hostrcb_device_data_entry_enhanced dev[3]; }__attribute__((packed, aligned (4))); +struct ipr_hostrcb_type_23_error { + struct ipr_ext_vpd ioa_vpd; + struct ipr_ext_vpd cfc_vpd; + __be32 errors_detected; + __be32 errors_logged; + struct ipr_hostrcb64_device_data_entry_enhanced dev[3]; +}__attribute__((packed, aligned (4))); + struct ipr_hostrcb_type_04_error { struct ipr_vpd ioa_vpd; struct ipr_vpd cfc_vpd; @@ -838,6 +863,22 @@ struct ipr_hostrcb_type_14_error { struct ipr_hostrcb_array_data_entry_enhanced array_member[18]; }__attribute__((packed, aligned (4))); +struct ipr_hostrcb_type_24_error { + struct ipr_ext_vpd ioa_vpd; + struct ipr_ext_vpd cfc_vpd; + u8 reserved[2]; + u8 exposed_mode_adn; +#define IPR_INVALID_ARRAY_DEV_NUM 0xff + u8 array_id; + u8 last_res_path[8]; + u8 protection_level[8]; + struct ipr_ext_vpd array_vpd; + u8 description[16]; + u8 reserved2[3]; + u8 num_entries; + struct ipr_hostrcb64_array_data_entry array_member[32]; +}__attribute__((packed, aligned (4))); + struct ipr_hostrcb_type_07_error { u8 failure_reason[64]; struct ipr_vpd vpd; @@ -875,6 +916,22 @@ struct ipr_hostrcb_config_element { __be32 wwid[2]; }__attribute__((packed, aligned (4))); +struct ipr_hostrcb64_config_element { + __be16 length; + u8 descriptor_id; +#define IPR_DESCRIPTOR_MASK 0xC0 +#define IPR_DESCRIPTOR_SIS64 0x00 + + u8 reserved; + u8 type_status; + + u8 reserved2[2]; + u8 link_rate; + + u8 res_path[8]; + __be32 wwid[2]; +}__attribute__((packed, aligned (8))); + struct ipr_hostrcb_fabric_desc { __be16 length; u8 ioa_port; @@ -896,6 +953,20 @@ struct ipr_hostrcb_fabric_desc { struct ipr_hostrcb_config_element elem[1]; }__attribute__((packed, aligned (4))); +struct ipr_hostrcb64_fabric_desc { + __be16 length; + u8 descriptor_id; + + u8 reserved; + u8 path_state; + + u8 reserved2[2]; + u8 res_path[8]; + u8 reserved3[6]; + __be16 num_entries; + struct ipr_hostrcb64_config_element elem[1]; +}__attribute__((packed, aligned (8))); + #define for_each_fabric_cfg(fabric, cfg) \ for (cfg = (fabric)->elem; \ cfg < ((fabric)->elem + be16_to_cpu((fabric)->num_entries)); \ @@ -908,10 +979,17 @@ struct ipr_hostrcb_type_20_error { struct ipr_hostrcb_fabric_desc desc[1]; }__attribute__((packed, aligned (4))); +struct ipr_hostrcb_type_30_error { + u8 failure_reason[64]; + u8 reserved[3]; + u8 num_entries; + struct ipr_hostrcb64_fabric_desc desc[1]; +}__attribute__((packed, aligned (4))); + struct ipr_hostrcb_error { - __be32 failing_dev_ioasc; - struct ipr_res_addr failing_dev_res_addr; - __be32 failing_dev_res_handle; + __be32 fd_ioasc; + struct ipr_res_addr fd_res_addr; + __be32 fd_res_handle; __be32 prc; union { struct ipr_hostrcb_type_ff_error type_ff_error; @@ -928,6 +1006,26 @@ struct ipr_hostrcb_error { } u; }__attribute__((packed, aligned (4))); +struct ipr_hostrcb64_error { + __be32 fd_ioasc; + __be32 ioa_fw_level; + __be32 fd_res_handle; + __be32 prc; + __be64 fd_dev_id; + __be64 fd_lun; + u8 fd_res_path[8]; + __be64 time_stamp; + u8 reserved[2]; + union { + struct ipr_hostrcb_type_ff_error type_ff_error; + struct ipr_hostrcb_type_12_error type_12_error; + struct ipr_hostrcb_type_17_error type_17_error; + struct ipr_hostrcb_type_23_error type_23_error; + struct ipr_hostrcb_type_24_error type_24_error; + struct ipr_hostrcb_type_30_error type_30_error; + } u; +}__attribute__((packed, aligned (8))); + struct ipr_hostrcb_raw { __be32 data[sizeof(struct ipr_hostrcb_error)/sizeof(__be32)]; }__attribute__((packed, aligned (4))); @@ -965,7 +1063,11 @@ struct ipr_hcam { #define IPR_HOST_RCB_OVERLAY_ID_16 0x16 #define IPR_HOST_RCB_OVERLAY_ID_17 0x17 #define IPR_HOST_RCB_OVERLAY_ID_20 0x20 -#define IPR_HOST_RCB_OVERLAY_ID_DEFAULT 0xFF +#define IPR_HOST_RCB_OVERLAY_ID_23 0x23 +#define IPR_HOST_RCB_OVERLAY_ID_24 0x24 +#define IPR_HOST_RCB_OVERLAY_ID_26 0x26 +#define IPR_HOST_RCB_OVERLAY_ID_30 0x30 +#define IPR_HOST_RCB_OVERLAY_ID_DEFAULT 0xFF u8 reserved1[3]; __be32 ilid; @@ -975,6 +1077,7 @@ struct ipr_hcam { union { struct ipr_hostrcb_error error; + struct ipr_hostrcb64_error error64; struct ipr_hostrcb_cfg_ch_not ccn; struct ipr_hostrcb_raw raw; } u; @@ -985,6 +1088,7 @@ struct ipr_hostrcb { dma_addr_t hostrcb_dma; struct list_head queue; struct ipr_ioa_cfg *ioa_cfg; + char rp_buffer[IPR_MAX_RES_PATH_LENGTH]; }; /* IPR smart dump table structures */ @@ -1521,14 +1625,21 @@ struct ipr_ucode_image_header { } #define ipr_hcam_err(hostrcb, fmt, ...) \ -{ \ - if (ipr_is_device(&(hostrcb)->hcam.u.error.failing_dev_res_addr)) { \ - ipr_ra_err((hostrcb)->ioa_cfg, \ - (hostrcb)->hcam.u.error.failing_dev_res_addr, \ - fmt, ##__VA_ARGS__); \ - } else { \ - dev_err(&(hostrcb)->ioa_cfg->pdev->dev, fmt, ##__VA_ARGS__); \ - } \ +{ \ + if (ipr_is_device(hostrcb)) { \ + if ((hostrcb)->ioa_cfg->sis64) { \ + printk(KERN_ERR IPR_NAME ": %s: " fmt, \ + ipr_format_resource_path(&hostrcb->hcam.u.error64.fd_res_path[0], \ + &hostrcb->rp_buffer[0]), \ + __VA_ARGS__); \ + } else { \ + ipr_ra_err((hostrcb)->ioa_cfg, \ + (hostrcb)->hcam.u.error.fd_res_addr, \ + fmt, __VA_ARGS__); \ + } \ + } else { \ + dev_err(&(hostrcb)->ioa_cfg->pdev->dev, fmt, __VA_ARGS__); \ + } \ } #define ipr_trace ipr_dbg("%s: %s: Line: %d\n",\ @@ -1637,18 +1748,29 @@ static inline int ipr_is_naca_model(struct ipr_resource_entry *res) } /** - * ipr_is_device - Determine if resource address is that of a device - * @res_addr: resource address struct + * ipr_is_device - Determine if the hostrcb structure is related to a device + * @hostrcb: host resource control blocks struct * * Return value: * 1 if AF / 0 if not AF **/ -static inline int ipr_is_device(struct ipr_res_addr *res_addr) +static inline int ipr_is_device(struct ipr_hostrcb *hostrcb) { - if ((res_addr->bus < IPR_MAX_NUM_BUSES) && - (res_addr->target < (IPR_MAX_NUM_TARGETS_PER_BUS - 1))) - return 1; - + struct ipr_res_addr *res_addr; + u8 *res_path; + + if (hostrcb->ioa_cfg->sis64) { + res_path = &hostrcb->hcam.u.error64.fd_res_path[0]; + if ((res_path[0] == 0x00 || res_path[0] == 0x80 || + res_path[0] == 0x81) && res_path[2] != 0xFF) + return 1; + } else { + res_addr = &hostrcb->hcam.u.error.fd_res_addr; + + if ((res_addr->bus < IPR_MAX_NUM_BUSES) && + (res_addr->target < (IPR_MAX_NUM_TARGETS_PER_BUS - 1))) + return 1; + } return 0; } -- cgit v0.10.2 From dcbad00e6b403089b1846e788bc1a0c67b2bfd2d Mon Sep 17 00:00:00 2001 From: Wayne Boyer Date: Fri, 19 Feb 2010 13:24:14 -0800 Subject: [SCSI] ipr: add hardware assisted smart dump functionality This patch adds the hardware assisted smart dump functionality for the next generation IOA PCI interface chip. Signea-off-by: Wayne Boyer Signed-off-by: James Bottomley diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index b2e60bd..dd12486 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -142,7 +142,9 @@ static const struct ipr_chip_cfg_t ipr_chip_cfg[] = { .ioarrin_reg = 0x00070, .sense_uproc_interrupt_reg = 0x00020, .set_uproc_interrupt_reg = 0x00020, - .clr_uproc_interrupt_reg = 0x00028 + .clr_uproc_interrupt_reg = 0x00028, + .dump_addr_reg = 0x00064, + .dump_data_reg = 0x00068 } }, }; @@ -2514,6 +2516,31 @@ static int ipr_wait_iodbg_ack(struct ipr_ioa_cfg *ioa_cfg, int max_delay) } /** + * ipr_get_sis64_dump_data_section - Dump IOA memory + * @ioa_cfg: ioa config struct + * @start_addr: adapter address to dump + * @dest: destination kernel buffer + * @length_in_words: length to dump in 4 byte words + * + * Return value: + * 0 on success + **/ +static int ipr_get_sis64_dump_data_section(struct ipr_ioa_cfg *ioa_cfg, + u32 start_addr, + __be32 *dest, u32 length_in_words) +{ + int i; + + for (i = 0; i < length_in_words; i++) { + writel(start_addr+(i*4), ioa_cfg->regs.dump_addr_reg); + *dest = cpu_to_be32(readl(ioa_cfg->regs.dump_data_reg)); + dest++; + } + + return 0; +} + +/** * ipr_get_ldump_data_section - Dump IOA memory * @ioa_cfg: ioa config struct * @start_addr: adapter address to dump @@ -2530,6 +2557,10 @@ static int ipr_get_ldump_data_section(struct ipr_ioa_cfg *ioa_cfg, volatile u32 temp_pcii_reg; int i, delay = 0; + if (ioa_cfg->sis64) + return ipr_get_sis64_dump_data_section(ioa_cfg, start_addr, + dest, length_in_words); + /* Write IOA interrupt reg starting LDUMP state */ writel((IPR_UPROCI_RESET_ALERT | IPR_UPROCI_IO_DEBUG_ALERT), ioa_cfg->regs.set_uproc_interrupt_reg); @@ -2787,6 +2818,7 @@ static void ipr_get_ioa_dump(struct ipr_ioa_cfg *ioa_cfg, struct ipr_dump *dump) u32 num_entries, start_off, end_off; u32 bytes_to_copy, bytes_copied, rc; struct ipr_sdt *sdt; + int valid = 1; int i; ENTER; @@ -2800,7 +2832,7 @@ static void ipr_get_ioa_dump(struct ipr_ioa_cfg *ioa_cfg, struct ipr_dump *dump) start_addr = readl(ioa_cfg->ioa_mailbox); - if (!ipr_sdt_is_fmt2(start_addr)) { + if (!ioa_cfg->sis64 && !ipr_sdt_is_fmt2(start_addr)) { dev_err(&ioa_cfg->pdev->dev, "Invalid dump table format: %lx\n", start_addr); spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); @@ -2829,7 +2861,6 @@ static void ipr_get_ioa_dump(struct ipr_ioa_cfg *ioa_cfg, struct ipr_dump *dump) /* IOA Dump entry */ ipr_init_dump_entry_hdr(&ioa_dump->hdr); - ioa_dump->format = IPR_SDT_FMT2; ioa_dump->hdr.len = 0; ioa_dump->hdr.data_type = IPR_DUMP_DATA_TYPE_BINARY; ioa_dump->hdr.id = IPR_DUMP_IOA_DUMP_ID; @@ -2844,7 +2875,8 @@ static void ipr_get_ioa_dump(struct ipr_ioa_cfg *ioa_cfg, struct ipr_dump *dump) sizeof(struct ipr_sdt) / sizeof(__be32)); /* Smart Dump table is ready to use and the first entry is valid */ - if (rc || (be32_to_cpu(sdt->hdr.state) != IPR_FMT2_SDT_READY_TO_USE)) { + if (rc || ((be32_to_cpu(sdt->hdr.state) != IPR_FMT3_SDT_READY_TO_USE) && + (be32_to_cpu(sdt->hdr.state) != IPR_FMT2_SDT_READY_TO_USE))) { dev_err(&ioa_cfg->pdev->dev, "Dump of IOA failed. Dump table not valid: %d, %X.\n", rc, be32_to_cpu(sdt->hdr.state)); @@ -2868,12 +2900,19 @@ static void ipr_get_ioa_dump(struct ipr_ioa_cfg *ioa_cfg, struct ipr_dump *dump) } if (sdt->entry[i].flags & IPR_SDT_VALID_ENTRY) { - sdt_word = be32_to_cpu(sdt->entry[i].bar_str_offset); - start_off = sdt_word & IPR_FMT2_MBX_ADDR_MASK; - end_off = be32_to_cpu(sdt->entry[i].end_offset); - - if (ipr_sdt_is_fmt2(sdt_word) && sdt_word) { - bytes_to_copy = end_off - start_off; + sdt_word = be32_to_cpu(sdt->entry[i].start_token); + if (ioa_cfg->sis64) + bytes_to_copy = be32_to_cpu(sdt->entry[i].end_token); + else { + start_off = sdt_word & IPR_FMT2_MBX_ADDR_MASK; + end_off = be32_to_cpu(sdt->entry[i].end_token); + + if (ipr_sdt_is_fmt2(sdt_word) && sdt_word) + bytes_to_copy = end_off - start_off; + else + valid = 0; + } + if (valid) { if (bytes_to_copy > IPR_MAX_IOA_DUMP_SIZE) { sdt->entry[i].flags &= ~IPR_SDT_VALID_ENTRY; continue; @@ -7202,7 +7241,7 @@ static void ipr_get_unit_check_buffer(struct ipr_ioa_cfg *ioa_cfg) mailbox = readl(ioa_cfg->ioa_mailbox); - if (!ipr_sdt_is_fmt2(mailbox)) { + if (!ioa_cfg->sis64 && !ipr_sdt_is_fmt2(mailbox)) { ipr_unit_check_no_data(ioa_cfg); return; } @@ -7211,15 +7250,20 @@ static void ipr_get_unit_check_buffer(struct ipr_ioa_cfg *ioa_cfg) rc = ipr_get_ldump_data_section(ioa_cfg, mailbox, (__be32 *) &sdt, (sizeof(struct ipr_uc_sdt)) / sizeof(__be32)); - if (rc || (be32_to_cpu(sdt.hdr.state) != IPR_FMT2_SDT_READY_TO_USE) || - !(sdt.entry[0].flags & IPR_SDT_VALID_ENTRY)) { + if (rc || !(sdt.entry[0].flags & IPR_SDT_VALID_ENTRY) || + ((be32_to_cpu(sdt.hdr.state) != IPR_FMT3_SDT_READY_TO_USE) && + (be32_to_cpu(sdt.hdr.state) != IPR_FMT2_SDT_READY_TO_USE))) { ipr_unit_check_no_data(ioa_cfg); return; } /* Find length of the first sdt entry (UC buffer) */ - length = (be32_to_cpu(sdt.entry[0].end_offset) - - be32_to_cpu(sdt.entry[0].bar_str_offset)) & IPR_FMT2_MBX_ADDR_MASK; + if (be32_to_cpu(sdt.hdr.state) == IPR_FMT3_SDT_READY_TO_USE) + length = be32_to_cpu(sdt.entry[0].end_token); + else + length = (be32_to_cpu(sdt.entry[0].end_token) - + be32_to_cpu(sdt.entry[0].start_token)) & + IPR_FMT2_MBX_ADDR_MASK; hostrcb = list_entry(ioa_cfg->hostrcb_free_q.next, struct ipr_hostrcb, queue); @@ -7227,7 +7271,7 @@ static void ipr_get_unit_check_buffer(struct ipr_ioa_cfg *ioa_cfg) memset(&hostrcb->hcam, 0, sizeof(hostrcb->hcam)); rc = ipr_get_ldump_data_section(ioa_cfg, - be32_to_cpu(sdt.entry[0].bar_str_offset), + be32_to_cpu(sdt.entry[0].start_token), (__be32 *)&hostrcb->hcam, min(length, (int)sizeof(hostrcb->hcam)) / sizeof(__be32)); @@ -8202,6 +8246,11 @@ static void __devinit ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg, t->sense_uproc_interrupt_reg = base + p->sense_uproc_interrupt_reg; t->set_uproc_interrupt_reg = base + p->set_uproc_interrupt_reg; t->clr_uproc_interrupt_reg = base + p->clr_uproc_interrupt_reg; + + if (ioa_cfg->sis64) { + t->dump_addr_reg = base + p->dump_addr_reg; + t->dump_data_reg = base + p->dump_data_reg; + } } /** diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h index e6e9017..4f2f1d2 100644 --- a/drivers/scsi/ipr.h +++ b/drivers/scsi/ipr.h @@ -228,6 +228,7 @@ #define IPR_SDT_FMT2_BAR5_SEL 0x5 #define IPR_SDT_FMT2_EXP_ROM_SEL 0x8 #define IPR_FMT2_SDT_READY_TO_USE 0xC4D4E3F2 +#define IPR_FMT3_SDT_READY_TO_USE 0xC4D4E3F3 #define IPR_DOORBELL 0x82800000 #define IPR_RUNTIME_RESET 0x40000000 @@ -1093,10 +1094,9 @@ struct ipr_hostrcb { /* IPR smart dump table structures */ struct ipr_sdt_entry { - __be32 bar_str_offset; - __be32 end_offset; - u8 entry_byte; - u8 reserved[3]; + __be32 start_token; + __be32 end_token; + u8 reserved[4]; u8 flags; #define IPR_SDT_ENDIAN 0x80 @@ -1204,6 +1204,9 @@ struct ipr_interrupt_offsets { unsigned long sense_uproc_interrupt_reg; unsigned long set_uproc_interrupt_reg; unsigned long clr_uproc_interrupt_reg; + + unsigned long dump_addr_reg; + unsigned long dump_data_reg; }; struct ipr_interrupts { @@ -1217,6 +1220,9 @@ struct ipr_interrupts { void __iomem *sense_uproc_interrupt_reg; void __iomem *set_uproc_interrupt_reg; void __iomem *clr_uproc_interrupt_reg; + + void __iomem *dump_addr_reg; + void __iomem *dump_data_reg; }; struct ipr_chip_cfg_t { @@ -1536,8 +1542,6 @@ struct ipr_ioa_dump { u32 next_page_index; u32 page_offset; u32 format; -#define IPR_SDT_FMT2 2 -#define IPR_SDT_UNKNOWN 3 }__attribute__((packed, aligned (4))); struct ipr_dump { -- cgit v0.10.2 From f72919ec2bbbe1c42cdda7857a96c0c40e1d78aa Mon Sep 17 00:00:00 2001 From: Wayne Boyer Date: Fri, 19 Feb 2010 13:24:21 -0800 Subject: [SCSI] ipr: implement shutdown changes and remove obsolete write cache parameter This patch adds a reboot notifier that will issue a shutdown prepare command to all adapters. This helps to prevent a problem where the primary adapter can get shut down before the secondary adapter and cause the secondary adapter to fail over and log and error. This patch also removes the "enable_cache" paramater as it is obsolete. Write cache for an adapter is now controlled from the iprconfig utility. Signed-off-by: Wayne Boyer Signed-off-by: James Bottomley diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index dd12486..a64fb50 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -72,6 +72,7 @@ #include #include #include +#include #include #include #include @@ -92,7 +93,6 @@ static unsigned int ipr_max_speed = 1; static int ipr_testmode = 0; static unsigned int ipr_fastfail = 0; static unsigned int ipr_transop_timeout = 0; -static unsigned int ipr_enable_cache = 1; static unsigned int ipr_debug = 0; static unsigned int ipr_max_devs = IPR_DEFAULT_SIS64_DEVS; static unsigned int ipr_dual_ioa_raid = 1; @@ -175,8 +175,6 @@ module_param_named(fastfail, ipr_fastfail, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(fastfail, "Reduce timeouts and retries"); module_param_named(transop_timeout, ipr_transop_timeout, int, 0); MODULE_PARM_DESC(transop_timeout, "Time in seconds to wait for adapter to come operational (default: 300)"); -module_param_named(enable_cache, ipr_enable_cache, int, 0); -MODULE_PARM_DESC(enable_cache, "Enable adapter's non-volatile write cache (default: 1)"); module_param_named(debug, ipr_debug, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(debug, "Enable device driver debugging logging. Set to 1 to enable. (default: 0)"); module_param_named(dual_ioa_raid, ipr_dual_ioa_raid, int, 0); @@ -3097,105 +3095,6 @@ static struct bin_attribute ipr_trace_attr = { }; #endif -static const struct { - enum ipr_cache_state state; - char *name; -} cache_state [] = { - { CACHE_NONE, "none" }, - { CACHE_DISABLED, "disabled" }, - { CACHE_ENABLED, "enabled" } -}; - -/** - * ipr_show_write_caching - Show the write caching attribute - * @dev: device struct - * @buf: buffer - * - * Return value: - * number of bytes printed to buffer - **/ -static ssize_t ipr_show_write_caching(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct Scsi_Host *shost = class_to_shost(dev); - struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)shost->hostdata; - unsigned long lock_flags = 0; - int i, len = 0; - - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); - for (i = 0; i < ARRAY_SIZE(cache_state); i++) { - if (cache_state[i].state == ioa_cfg->cache_state) { - len = snprintf(buf, PAGE_SIZE, "%s\n", cache_state[i].name); - break; - } - } - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); - return len; -} - - -/** - * ipr_store_write_caching - Enable/disable adapter write cache - * @dev: device struct - * @buf: buffer - * @count: buffer size - * - * This function will enable/disable adapter write cache. - * - * Return value: - * count on success / other on failure - **/ -static ssize_t ipr_store_write_caching(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct Scsi_Host *shost = class_to_shost(dev); - struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)shost->hostdata; - unsigned long lock_flags = 0; - enum ipr_cache_state new_state = CACHE_INVALID; - int i; - - if (!capable(CAP_SYS_ADMIN)) - return -EACCES; - if (ioa_cfg->cache_state == CACHE_NONE) - return -EINVAL; - - for (i = 0; i < ARRAY_SIZE(cache_state); i++) { - if (!strncmp(cache_state[i].name, buf, strlen(cache_state[i].name))) { - new_state = cache_state[i].state; - break; - } - } - - if (new_state != CACHE_DISABLED && new_state != CACHE_ENABLED) - return -EINVAL; - - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); - if (ioa_cfg->cache_state == new_state) { - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); - return count; - } - - ioa_cfg->cache_state = new_state; - dev_info(&ioa_cfg->pdev->dev, "%s adapter write cache.\n", - new_state == CACHE_ENABLED ? "Enabling" : "Disabling"); - if (!ioa_cfg->in_reset_reload) - ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NORMAL); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); - wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); - - return count; -} - -static struct device_attribute ipr_ioa_cache_attr = { - .attr = { - .name = "write_cache", - .mode = S_IRUGO | S_IWUSR, - }, - .show = ipr_show_write_caching, - .store = ipr_store_write_caching -}; - /** * ipr_show_fw_version - Show the firmware version * @dev: class device struct @@ -3797,7 +3696,6 @@ static struct device_attribute *ipr_ioa_attrs[] = { &ipr_ioa_state_attr, &ipr_ioa_reset_attr, &ipr_update_fw_attr, - &ipr_ioa_cache_attr, NULL, }; @@ -6293,36 +6191,6 @@ static int ipr_set_supported_devs(struct ipr_cmnd *ipr_cmd) } /** - * ipr_setup_write_cache - Disable write cache if needed - * @ipr_cmd: ipr command struct - * - * This function sets up adapters write cache to desired setting - * - * Return value: - * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN - **/ -static int ipr_setup_write_cache(struct ipr_cmnd *ipr_cmd) -{ - struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; - - ipr_cmd->job_step = ipr_set_supported_devs; - ipr_cmd->u.res = list_entry(ioa_cfg->used_res_q.next, - struct ipr_resource_entry, queue); - - if (ioa_cfg->cache_state != CACHE_DISABLED) - return IPR_RC_JOB_CONTINUE; - - ipr_cmd->ioarcb.res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE); - ipr_cmd->ioarcb.cmd_pkt.request_type = IPR_RQTYPE_IOACMD; - ipr_cmd->ioarcb.cmd_pkt.cdb[0] = IPR_IOA_SHUTDOWN; - ipr_cmd->ioarcb.cmd_pkt.cdb[1] = IPR_SHUTDOWN_PREPARE_FOR_NORMAL; - - ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT); - - return IPR_RC_JOB_RETURN; -} - -/** * ipr_get_mode_page - Locate specified mode page * @mode_pages: mode page buffer * @page_code: page code to find @@ -6522,7 +6390,9 @@ static int ipr_ioafp_mode_select_page28(struct ipr_cmnd *ipr_cmd) ioa_cfg->vpd_cbs_dma + offsetof(struct ipr_misc_cbs, mode_pages), length); - ipr_cmd->job_step = ipr_setup_write_cache; + ipr_cmd->job_step = ipr_set_supported_devs; + ipr_cmd->u.res = list_entry(ioa_cfg->used_res_q.next, + struct ipr_resource_entry, queue); ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT); LEAVE; @@ -6590,10 +6460,13 @@ static int ipr_reset_cmd_failed(struct ipr_cmnd *ipr_cmd) **/ static int ipr_reset_mode_sense_failed(struct ipr_cmnd *ipr_cmd) { + struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); if (ioasc == IPR_IOASC_IR_INVALID_REQ_TYPE_OR_PKT) { - ipr_cmd->job_step = ipr_setup_write_cache; + ipr_cmd->job_step = ipr_set_supported_devs; + ipr_cmd->u.res = list_entry(ioa_cfg->used_res_q.next, + struct ipr_resource_entry, queue); return IPR_RC_JOB_CONTINUE; } @@ -6944,13 +6817,9 @@ static int ipr_ioafp_cap_inquiry(struct ipr_cmnd *ipr_cmd) static int ipr_ioafp_page3_inquiry(struct ipr_cmnd *ipr_cmd) { struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; - struct ipr_inquiry_page0 *page0 = &ioa_cfg->vpd_cbs->page0_data; ENTER; - if (!ipr_inquiry_page_supported(page0, 1)) - ioa_cfg->cache_state = CACHE_NONE; - ipr_cmd->job_step = ipr_ioafp_cap_inquiry; ipr_ioafp_inquiry(ipr_cmd, 1, 3, @@ -8209,10 +8078,6 @@ static void __devinit ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg, init_waitqueue_head(&ioa_cfg->reset_wait_q); init_waitqueue_head(&ioa_cfg->msi_wait_q); ioa_cfg->sdt_state = INACTIVE; - if (ipr_enable_cache) - ioa_cfg->cache_state = CACHE_ENABLED; - else - ioa_cfg->cache_state = CACHE_DISABLED; ipr_initialize_bus_attr(ioa_cfg); ioa_cfg->max_devs_supported = ipr_max_devs; @@ -8842,6 +8707,61 @@ static struct pci_driver ipr_driver = { }; /** + * ipr_halt_done - Shutdown prepare completion + * + * Return value: + * none + **/ +static void ipr_halt_done(struct ipr_cmnd *ipr_cmd) +{ + struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; + + list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q); +} + +/** + * ipr_halt - Issue shutdown prepare to all adapters + * + * Return value: + * NOTIFY_OK on success / NOTIFY_DONE on failure + **/ +static int ipr_halt(struct notifier_block *nb, ulong event, void *buf) +{ + struct ipr_cmnd *ipr_cmd; + struct ipr_ioa_cfg *ioa_cfg; + unsigned long flags = 0; + + if (event != SYS_RESTART && event != SYS_HALT && event != SYS_POWER_OFF) + return NOTIFY_DONE; + + spin_lock(&ipr_driver_lock); + + list_for_each_entry(ioa_cfg, &ipr_ioa_head, queue) { + spin_lock_irqsave(ioa_cfg->host->host_lock, flags); + if (!ioa_cfg->allow_cmds) { + spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags); + continue; + } + + ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg); + ipr_cmd->ioarcb.res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE); + ipr_cmd->ioarcb.cmd_pkt.request_type = IPR_RQTYPE_IOACMD; + ipr_cmd->ioarcb.cmd_pkt.cdb[0] = IPR_IOA_SHUTDOWN; + ipr_cmd->ioarcb.cmd_pkt.cdb[1] = IPR_SHUTDOWN_PREPARE_FOR_NORMAL; + + ipr_do_req(ipr_cmd, ipr_halt_done, ipr_timeout, IPR_DEVICE_RESET_TIMEOUT); + spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags); + } + spin_unlock(&ipr_driver_lock); + + return NOTIFY_OK; +} + +static struct notifier_block ipr_notifier = { + ipr_halt, NULL, 0 +}; + +/** * ipr_init - Module entry point * * Return value: @@ -8852,6 +8772,7 @@ static int __init ipr_init(void) ipr_info("IBM Power RAID SCSI Device Driver version: %s %s\n", IPR_DRIVER_VERSION, IPR_DRIVER_DATE); + register_reboot_notifier(&ipr_notifier); return pci_register_driver(&ipr_driver); } @@ -8865,6 +8786,7 @@ static int __init ipr_init(void) **/ static void __exit ipr_exit(void) { + unregister_reboot_notifier(&ipr_notifier); pci_unregister_driver(&ipr_driver); } diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h index 4f2f1d2..36736b5 100644 --- a/drivers/scsi/ipr.h +++ b/drivers/scsi/ipr.h @@ -136,7 +136,7 @@ /* We need resources for HCAMS, IOA reset, IOA bringdown, and ERP */ #define IPR_NUM_INTERNAL_CMD_BLKS (IPR_NUM_HCAMS + \ - ((IPR_NUM_RESET_RELOAD_RETRIES + 1) * 2) + 3) + ((IPR_NUM_RESET_RELOAD_RETRIES + 1) * 2) + 4) #define IPR_MAX_COMMANDS IPR_NUM_BASE_CMD_BLKS #define IPR_NUM_CMD_BLKS (IPR_NUM_BASE_CMD_BLKS + \ @@ -1284,13 +1284,6 @@ enum ipr_sdt_state { DUMP_OBTAINED }; -enum ipr_cache_state { - CACHE_NONE, - CACHE_DISABLED, - CACHE_ENABLED, - CACHE_INVALID -}; - /* Per-controller data */ struct ipr_ioa_cfg { char eye_catcher[8]; @@ -1321,7 +1314,6 @@ struct ipr_ioa_cfg { unsigned long *array_ids; unsigned long *vset_ids; - enum ipr_cache_state cache_state; u16 type; /* CCIN of the card */ u8 log_level; -- cgit v0.10.2 From 214777ba125e2902c9b84c764be38099c94d0bd2 Mon Sep 17 00:00:00 2001 From: Wayne Boyer Date: Fri, 19 Feb 2010 13:24:26 -0800 Subject: [SCSI] ipr: add support for multiple stages of initialization This patch adds support for using the new IOA initialization feedback register. It also enables 64 bit support in the ipr_ioafp_identify_hrrq and ipr_mask_and_clear_interrupts routines. Signed-off-by: Wayne Boyer Signed-off-by: James Bottomley diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index a64fb50..10b162d 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -106,13 +106,20 @@ static const struct ipr_chip_cfg_t ipr_chip_cfg[] = { { .set_interrupt_mask_reg = 0x0022C, .clr_interrupt_mask_reg = 0x00230, + .clr_interrupt_mask_reg32 = 0x00230, .sense_interrupt_mask_reg = 0x0022C, + .sense_interrupt_mask_reg32 = 0x0022C, .clr_interrupt_reg = 0x00228, + .clr_interrupt_reg32 = 0x00228, .sense_interrupt_reg = 0x00224, + .sense_interrupt_reg32 = 0x00224, .ioarrin_reg = 0x00404, .sense_uproc_interrupt_reg = 0x00214, + .sense_uproc_interrupt_reg32 = 0x00214, .set_uproc_interrupt_reg = 0x00214, - .clr_uproc_interrupt_reg = 0x00218 + .set_uproc_interrupt_reg32 = 0x00214, + .clr_uproc_interrupt_reg = 0x00218, + .clr_uproc_interrupt_reg32 = 0x00218 } }, { /* Snipe and Scamp */ @@ -121,13 +128,20 @@ static const struct ipr_chip_cfg_t ipr_chip_cfg[] = { { .set_interrupt_mask_reg = 0x00288, .clr_interrupt_mask_reg = 0x0028C, + .clr_interrupt_mask_reg32 = 0x0028C, .sense_interrupt_mask_reg = 0x00288, + .sense_interrupt_mask_reg32 = 0x00288, .clr_interrupt_reg = 0x00284, + .clr_interrupt_reg32 = 0x00284, .sense_interrupt_reg = 0x00280, + .sense_interrupt_reg32 = 0x00280, .ioarrin_reg = 0x00504, .sense_uproc_interrupt_reg = 0x00290, + .sense_uproc_interrupt_reg32 = 0x00290, .set_uproc_interrupt_reg = 0x00290, - .clr_uproc_interrupt_reg = 0x00294 + .set_uproc_interrupt_reg32 = 0x00290, + .clr_uproc_interrupt_reg = 0x00294, + .clr_uproc_interrupt_reg32 = 0x00294 } }, { /* CRoC */ @@ -136,13 +150,21 @@ static const struct ipr_chip_cfg_t ipr_chip_cfg[] = { { .set_interrupt_mask_reg = 0x00010, .clr_interrupt_mask_reg = 0x00018, + .clr_interrupt_mask_reg32 = 0x0001C, .sense_interrupt_mask_reg = 0x00010, + .sense_interrupt_mask_reg32 = 0x00014, .clr_interrupt_reg = 0x00008, + .clr_interrupt_reg32 = 0x0000C, .sense_interrupt_reg = 0x00000, + .sense_interrupt_reg32 = 0x00004, .ioarrin_reg = 0x00070, .sense_uproc_interrupt_reg = 0x00020, + .sense_uproc_interrupt_reg32 = 0x00024, .set_uproc_interrupt_reg = 0x00020, + .set_uproc_interrupt_reg32 = 0x00024, .clr_uproc_interrupt_reg = 0x00028, + .clr_uproc_interrupt_reg32 = 0x0002C, + .init_feedback_reg = 0x0005C, .dump_addr_reg = 0x00064, .dump_data_reg = 0x00068 } @@ -592,10 +614,15 @@ static void ipr_mask_and_clear_interrupts(struct ipr_ioa_cfg *ioa_cfg, ioa_cfg->allow_interrupts = 0; /* Set interrupt mask to stop all new interrupts */ - writel(~0, ioa_cfg->regs.set_interrupt_mask_reg); + if (ioa_cfg->sis64) + writeq(~0, ioa_cfg->regs.set_interrupt_mask_reg); + else + writel(~0, ioa_cfg->regs.set_interrupt_mask_reg); /* Clear any pending interrupts */ - writel(clr_ints, ioa_cfg->regs.clr_interrupt_reg); + if (ioa_cfg->sis64) + writel(~0, ioa_cfg->regs.clr_interrupt_reg); + writel(clr_ints, ioa_cfg->regs.clr_interrupt_reg32); int_reg = readl(ioa_cfg->regs.sense_interrupt_reg); } @@ -2561,7 +2588,7 @@ static int ipr_get_ldump_data_section(struct ipr_ioa_cfg *ioa_cfg, /* Write IOA interrupt reg starting LDUMP state */ writel((IPR_UPROCI_RESET_ALERT | IPR_UPROCI_IO_DEBUG_ALERT), - ioa_cfg->regs.set_uproc_interrupt_reg); + ioa_cfg->regs.set_uproc_interrupt_reg32); /* Wait for IO debug acknowledge */ if (ipr_wait_iodbg_ack(ioa_cfg, @@ -2580,7 +2607,7 @@ static int ipr_get_ldump_data_section(struct ipr_ioa_cfg *ioa_cfg, /* Signal address valid - clear IOA Reset alert */ writel(IPR_UPROCI_RESET_ALERT, - ioa_cfg->regs.clr_uproc_interrupt_reg); + ioa_cfg->regs.clr_uproc_interrupt_reg32); for (i = 0; i < length_in_words; i++) { /* Wait for IO debug acknowledge */ @@ -2605,10 +2632,10 @@ static int ipr_get_ldump_data_section(struct ipr_ioa_cfg *ioa_cfg, /* Signal end of block transfer. Set reset alert then clear IO debug ack */ writel(IPR_UPROCI_RESET_ALERT, - ioa_cfg->regs.set_uproc_interrupt_reg); + ioa_cfg->regs.set_uproc_interrupt_reg32); writel(IPR_UPROCI_IO_DEBUG_ALERT, - ioa_cfg->regs.clr_uproc_interrupt_reg); + ioa_cfg->regs.clr_uproc_interrupt_reg32); /* Signal dump data received - Clear IO debug Ack */ writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, @@ -2617,7 +2644,7 @@ static int ipr_get_ldump_data_section(struct ipr_ioa_cfg *ioa_cfg, /* Wait for IOA to signal LDUMP exit - IOA reset alert will be cleared */ while (delay < IPR_LDUMP_MAX_SHORT_ACK_DELAY_IN_USEC) { temp_pcii_reg = - readl(ioa_cfg->regs.sense_uproc_interrupt_reg); + readl(ioa_cfg->regs.sense_uproc_interrupt_reg32); if (!(temp_pcii_reg & IPR_UPROCI_RESET_ALERT)) return 0; @@ -4831,11 +4858,29 @@ static irqreturn_t ipr_isr(int irq, void *devp) return IRQ_NONE; } - int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); - int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg; + int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg32); + int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32) & ~int_mask_reg; - /* If an interrupt on the adapter did not occur, ignore it */ + /* If an interrupt on the adapter did not occur, ignore it. + * Or in the case of SIS 64, check for a stage change interrupt. + */ if (unlikely((int_reg & IPR_PCII_OPER_INTERRUPTS) == 0)) { + if (ioa_cfg->sis64) { + int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); + int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg; + if (int_reg & IPR_PCII_IPL_STAGE_CHANGE) { + + /* clear stage change */ + writel(IPR_PCII_IPL_STAGE_CHANGE, ioa_cfg->regs.clr_interrupt_reg); + int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg; + list_del(&ioa_cfg->reset_cmd->queue); + del_timer(&ioa_cfg->reset_cmd->timer); + ipr_reset_ioa_job(ioa_cfg->reset_cmd); + spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + return IRQ_HANDLED; + } + } + spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); return IRQ_NONE; } @@ -4878,8 +4923,8 @@ static irqreturn_t ipr_isr(int irq, void *devp) if (ipr_cmd != NULL) { /* Clear the PCI interrupt */ do { - writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg); - int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg; + writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg32); + int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32) & ~int_mask_reg; } while (int_reg & IPR_PCII_HRRQ_UPDATED && num_hrrq++ < IPR_MAX_HRRQ_RETRIES); @@ -6887,7 +6932,7 @@ static int ipr_ioafp_std_inquiry(struct ipr_cmnd *ipr_cmd) } /** - * ipr_ioafp_indentify_hrrq - Send Identify Host RRQ. + * ipr_ioafp_identify_hrrq - Send Identify Host RRQ. * @ipr_cmd: ipr command struct * * This function send an Identify Host Request Response Queue @@ -6896,7 +6941,7 @@ static int ipr_ioafp_std_inquiry(struct ipr_cmnd *ipr_cmd) * Return value: * IPR_RC_JOB_RETURN **/ -static int ipr_ioafp_indentify_hrrq(struct ipr_cmnd *ipr_cmd) +static int ipr_ioafp_identify_hrrq(struct ipr_cmnd *ipr_cmd) { struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; @@ -6908,19 +6953,32 @@ static int ipr_ioafp_indentify_hrrq(struct ipr_cmnd *ipr_cmd) ioarcb->res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE); ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD; + if (ioa_cfg->sis64) + ioarcb->cmd_pkt.cdb[1] = 0x1; ioarcb->cmd_pkt.cdb[2] = - ((u32) ioa_cfg->host_rrq_dma >> 24) & 0xff; + ((u64) ioa_cfg->host_rrq_dma >> 24) & 0xff; ioarcb->cmd_pkt.cdb[3] = - ((u32) ioa_cfg->host_rrq_dma >> 16) & 0xff; + ((u64) ioa_cfg->host_rrq_dma >> 16) & 0xff; ioarcb->cmd_pkt.cdb[4] = - ((u32) ioa_cfg->host_rrq_dma >> 8) & 0xff; + ((u64) ioa_cfg->host_rrq_dma >> 8) & 0xff; ioarcb->cmd_pkt.cdb[5] = - ((u32) ioa_cfg->host_rrq_dma) & 0xff; + ((u64) ioa_cfg->host_rrq_dma) & 0xff; ioarcb->cmd_pkt.cdb[7] = ((sizeof(u32) * IPR_NUM_CMD_BLKS) >> 8) & 0xff; ioarcb->cmd_pkt.cdb[8] = (sizeof(u32) * IPR_NUM_CMD_BLKS) & 0xff; + if (ioa_cfg->sis64) { + ioarcb->cmd_pkt.cdb[10] = + ((u64) ioa_cfg->host_rrq_dma >> 56) & 0xff; + ioarcb->cmd_pkt.cdb[11] = + ((u64) ioa_cfg->host_rrq_dma >> 48) & 0xff; + ioarcb->cmd_pkt.cdb[12] = + ((u64) ioa_cfg->host_rrq_dma >> 40) & 0xff; + ioarcb->cmd_pkt.cdb[13] = + ((u64) ioa_cfg->host_rrq_dma >> 32) & 0xff; + } + ipr_cmd->job_step = ipr_ioafp_std_inquiry; ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT); @@ -7005,6 +7063,57 @@ static void ipr_init_ioa_mem(struct ipr_ioa_cfg *ioa_cfg) } /** + * ipr_reset_next_stage - Process IPL stage change based on feedback register. + * @ipr_cmd: ipr command struct + * + * Return value: + * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN + **/ +static int ipr_reset_next_stage(struct ipr_cmnd *ipr_cmd) +{ + unsigned long stage, stage_time; + u32 feedback; + volatile u32 int_reg; + struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; + u64 maskval = 0; + + feedback = readl(ioa_cfg->regs.init_feedback_reg); + stage = feedback & IPR_IPL_INIT_STAGE_MASK; + stage_time = feedback & IPR_IPL_INIT_STAGE_TIME_MASK; + + ipr_dbg("IPL stage = 0x%lx, IPL stage time = %ld\n", stage, stage_time); + + /* sanity check the stage_time value */ + if (stage_time < IPR_IPL_INIT_MIN_STAGE_TIME) + stage_time = IPR_IPL_INIT_MIN_STAGE_TIME; + else if (stage_time > IPR_LONG_OPERATIONAL_TIMEOUT) + stage_time = IPR_LONG_OPERATIONAL_TIMEOUT; + + if (stage == IPR_IPL_INIT_STAGE_UNKNOWN) { + writel(IPR_PCII_IPL_STAGE_CHANGE, ioa_cfg->regs.set_interrupt_mask_reg); + int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); + stage_time = ioa_cfg->transop_timeout; + ipr_cmd->job_step = ipr_ioafp_identify_hrrq; + } else if (stage == IPR_IPL_INIT_STAGE_TRANSOP) { + ipr_cmd->job_step = ipr_ioafp_identify_hrrq; + maskval = IPR_PCII_IPL_STAGE_CHANGE; + maskval = (maskval << 32) | IPR_PCII_IOA_TRANS_TO_OPER; + writeq(maskval, ioa_cfg->regs.set_interrupt_mask_reg); + int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); + return IPR_RC_JOB_CONTINUE; + } + + ipr_cmd->timer.data = (unsigned long) ipr_cmd; + ipr_cmd->timer.expires = jiffies + stage_time * HZ; + ipr_cmd->timer.function = (void (*)(unsigned long))ipr_oper_timeout; + ipr_cmd->done = ipr_reset_ioa_job; + add_timer(&ipr_cmd->timer); + list_add_tail(&ipr_cmd->queue, &ioa_cfg->pending_q); + + return IPR_RC_JOB_RETURN; +} + +/** * ipr_reset_enable_ioa - Enable the IOA following a reset. * @ipr_cmd: ipr command struct * @@ -7020,7 +7129,7 @@ static int ipr_reset_enable_ioa(struct ipr_cmnd *ipr_cmd) volatile u32 int_reg; ENTER; - ipr_cmd->job_step = ipr_ioafp_indentify_hrrq; + ipr_cmd->job_step = ipr_ioafp_identify_hrrq; ipr_init_ioa_mem(ioa_cfg); ioa_cfg->allow_interrupts = 1; @@ -7028,19 +7137,27 @@ static int ipr_reset_enable_ioa(struct ipr_cmnd *ipr_cmd) if (int_reg & IPR_PCII_IOA_TRANS_TO_OPER) { writel((IPR_PCII_ERROR_INTERRUPTS | IPR_PCII_HRRQ_UPDATED), - ioa_cfg->regs.clr_interrupt_mask_reg); + ioa_cfg->regs.clr_interrupt_mask_reg32); int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); return IPR_RC_JOB_CONTINUE; } /* Enable destructive diagnostics on IOA */ - writel(ioa_cfg->doorbell, ioa_cfg->regs.set_uproc_interrupt_reg); + writel(ioa_cfg->doorbell, ioa_cfg->regs.set_uproc_interrupt_reg32); + + writel(IPR_PCII_OPER_INTERRUPTS, ioa_cfg->regs.clr_interrupt_mask_reg32); + if (ioa_cfg->sis64) + writel(IPR_PCII_IPL_STAGE_CHANGE, ioa_cfg->regs.clr_interrupt_mask_reg); - writel(IPR_PCII_OPER_INTERRUPTS, ioa_cfg->regs.clr_interrupt_mask_reg); int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); dev_info(&ioa_cfg->pdev->dev, "Initializing IOA.\n"); + if (ioa_cfg->sis64) { + ipr_cmd->job_step = ipr_reset_next_stage; + return IPR_RC_JOB_CONTINUE; + } + ipr_cmd->timer.data = (unsigned long) ipr_cmd; ipr_cmd->timer.expires = jiffies + (ioa_cfg->transop_timeout * HZ); ipr_cmd->timer.function = (void (*)(unsigned long))ipr_oper_timeout; @@ -7374,7 +7491,7 @@ static int ipr_reset_alert(struct ipr_cmnd *ipr_cmd) if ((rc == PCIBIOS_SUCCESSFUL) && (cmd_reg & PCI_COMMAND_MEMORY)) { ipr_mask_and_clear_interrupts(ioa_cfg, ~0); - writel(IPR_UPROCI_RESET_ALERT, ioa_cfg->regs.set_uproc_interrupt_reg); + writel(IPR_UPROCI_RESET_ALERT, ioa_cfg->regs.set_uproc_interrupt_reg32); ipr_cmd->job_step = ipr_reset_wait_to_start_bist; } else { ipr_cmd->job_step = ioa_cfg->reset; @@ -8104,15 +8221,23 @@ static void __devinit ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg, t->set_interrupt_mask_reg = base + p->set_interrupt_mask_reg; t->clr_interrupt_mask_reg = base + p->clr_interrupt_mask_reg; + t->clr_interrupt_mask_reg32 = base + p->clr_interrupt_mask_reg32; t->sense_interrupt_mask_reg = base + p->sense_interrupt_mask_reg; + t->sense_interrupt_mask_reg32 = base + p->sense_interrupt_mask_reg32; t->clr_interrupt_reg = base + p->clr_interrupt_reg; + t->clr_interrupt_reg32 = base + p->clr_interrupt_reg32; t->sense_interrupt_reg = base + p->sense_interrupt_reg; + t->sense_interrupt_reg32 = base + p->sense_interrupt_reg32; t->ioarrin_reg = base + p->ioarrin_reg; t->sense_uproc_interrupt_reg = base + p->sense_uproc_interrupt_reg; + t->sense_uproc_interrupt_reg32 = base + p->sense_uproc_interrupt_reg32; t->set_uproc_interrupt_reg = base + p->set_uproc_interrupt_reg; + t->set_uproc_interrupt_reg32 = base + p->set_uproc_interrupt_reg32; t->clr_uproc_interrupt_reg = base + p->clr_uproc_interrupt_reg; + t->clr_uproc_interrupt_reg32 = base + p->clr_uproc_interrupt_reg32; if (ioa_cfg->sis64) { + t->init_feedback_reg = base + p->init_feedback_reg; t->dump_addr_reg = base + p->dump_addr_reg; t->dump_data_reg = base + p->dump_data_reg; } @@ -8187,7 +8312,7 @@ static int __devinit ipr_test_msi(struct ipr_ioa_cfg *ioa_cfg, init_waitqueue_head(&ioa_cfg->msi_wait_q); ioa_cfg->msi_received = 0; ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER); - writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.clr_interrupt_mask_reg); + writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.clr_interrupt_mask_reg32); int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); @@ -8198,7 +8323,7 @@ static int __devinit ipr_test_msi(struct ipr_ioa_cfg *ioa_cfg, } else if (ipr_debug) dev_info(&pdev->dev, "IRQ assigned: %d\n", pdev->irq); - writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.sense_interrupt_reg); + writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.sense_interrupt_reg32); int_reg = readl(ioa_cfg->regs.sense_interrupt_reg); wait_event_timeout(ioa_cfg->msi_wait_q, ioa_cfg->msi_received, HZ); ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER); @@ -8378,9 +8503,9 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev, * If HRRQ updated interrupt is not masked, or reset alert is set, * the card is in an unknown state and needs a hard reset */ - mask = readl(ioa_cfg->regs.sense_interrupt_mask_reg); - interrupts = readl(ioa_cfg->regs.sense_interrupt_reg); - uproc = readl(ioa_cfg->regs.sense_uproc_interrupt_reg); + mask = readl(ioa_cfg->regs.sense_interrupt_mask_reg32); + interrupts = readl(ioa_cfg->regs.sense_interrupt_reg32); + uproc = readl(ioa_cfg->regs.sense_uproc_interrupt_reg32); if ((mask & IPR_PCII_HRRQ_UPDATED) == 0 || (uproc & IPR_UPROCI_RESET_ALERT)) ioa_cfg->needs_hard_reset = 1; if (interrupts & IPR_PCII_ERROR_INTERRUPTS) diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h index 36736b5..137217e 100644 --- a/drivers/scsi/ipr.h +++ b/drivers/scsi/ipr.h @@ -232,6 +232,13 @@ #define IPR_DOORBELL 0x82800000 #define IPR_RUNTIME_RESET 0x40000000 +#define IPR_IPL_INIT_MIN_STAGE_TIME 5 +#define IPR_IPL_INIT_STAGE_UNKNOWN 0x0 +#define IPR_IPL_INIT_STAGE_TRANSOP 0xB0000000 +#define IPR_IPL_INIT_STAGE_MASK 0xff000000 +#define IPR_IPL_INIT_STAGE_TIME_MASK 0x0000ffff +#define IPR_PCII_IPL_STAGE_CHANGE (0x80000000 >> 0) + #define IPR_PCII_IOA_TRANS_TO_OPER (0x80000000 >> 0) #define IPR_PCII_IOARCB_XFER_FAILED (0x80000000 >> 3) #define IPR_PCII_IOA_UNIT_CHECKED (0x80000000 >> 4) @@ -1196,14 +1203,23 @@ struct ipr_misc_cbs { struct ipr_interrupt_offsets { unsigned long set_interrupt_mask_reg; unsigned long clr_interrupt_mask_reg; + unsigned long clr_interrupt_mask_reg32; unsigned long sense_interrupt_mask_reg; + unsigned long sense_interrupt_mask_reg32; unsigned long clr_interrupt_reg; + unsigned long clr_interrupt_reg32; unsigned long sense_interrupt_reg; + unsigned long sense_interrupt_reg32; unsigned long ioarrin_reg; unsigned long sense_uproc_interrupt_reg; + unsigned long sense_uproc_interrupt_reg32; unsigned long set_uproc_interrupt_reg; + unsigned long set_uproc_interrupt_reg32; unsigned long clr_uproc_interrupt_reg; + unsigned long clr_uproc_interrupt_reg32; + + unsigned long init_feedback_reg; unsigned long dump_addr_reg; unsigned long dump_data_reg; @@ -1212,14 +1228,23 @@ struct ipr_interrupt_offsets { struct ipr_interrupts { void __iomem *set_interrupt_mask_reg; void __iomem *clr_interrupt_mask_reg; + void __iomem *clr_interrupt_mask_reg32; void __iomem *sense_interrupt_mask_reg; + void __iomem *sense_interrupt_mask_reg32; void __iomem *clr_interrupt_reg; + void __iomem *clr_interrupt_reg32; void __iomem *sense_interrupt_reg; + void __iomem *sense_interrupt_reg32; void __iomem *ioarrin_reg; void __iomem *sense_uproc_interrupt_reg; + void __iomem *sense_uproc_interrupt_reg32; void __iomem *set_uproc_interrupt_reg; + void __iomem *set_uproc_interrupt_reg32; void __iomem *clr_uproc_interrupt_reg; + void __iomem *clr_uproc_interrupt_reg32; + + void __iomem *init_feedback_reg; void __iomem *dump_addr_reg; void __iomem *dump_data_reg; -- cgit v0.10.2 From 5aa3a333eaae1016f5a72f9e0e2dce39c08762f8 Mon Sep 17 00:00:00 2001 From: Wayne Boyer Date: Fri, 19 Feb 2010 13:24:32 -0800 Subject: [SCSI] ipr: add support for new IOASCs This patch adds support for new errors that can be received from adapters using the next generation 64 bit IOA PCI interface chip. Signed-off-by: Wayne Boyer Signed-off-by: James Bottomley diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 10b162d..7dc9fb1 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -222,6 +222,20 @@ struct ipr_error_table_t ipr_error_table[] = { "FFFE: Soft device bus error recovered by the IOA"}, {0x01088100, 0, IPR_DEFAULT_LOG_LEVEL, "4101: Soft device bus fabric error"}, + {0x01100100, 0, IPR_DEFAULT_LOG_LEVEL, + "FFFC: Logical block guard error recovered by the device"}, + {0x01100300, 0, IPR_DEFAULT_LOG_LEVEL, + "FFFC: Logical block reference tag error recovered by the device"}, + {0x01108300, 0, IPR_DEFAULT_LOG_LEVEL, + "4171: Recovered scatter list tag / sequence number error"}, + {0x01109000, 0, IPR_DEFAULT_LOG_LEVEL, + "FF3D: Recovered logical block CRC error on IOA to Host transfer"}, + {0x01109200, 0, IPR_DEFAULT_LOG_LEVEL, + "4171: Recovered logical block sequence number error on IOA to Host transfer"}, + {0x0110A000, 0, IPR_DEFAULT_LOG_LEVEL, + "FFFD: Recovered logical block reference tag error detected by the IOA"}, + {0x0110A100, 0, IPR_DEFAULT_LOG_LEVEL, + "FFFD: Logical block guard error recovered by the IOA"}, {0x01170600, 0, IPR_DEFAULT_LOG_LEVEL, "FFF9: Device sector reassign successful"}, {0x01170900, 0, IPR_DEFAULT_LOG_LEVEL, @@ -278,12 +292,28 @@ struct ipr_error_table_t ipr_error_table[] = { "3120: SCSI bus is not operational"}, {0x04088100, 0, IPR_DEFAULT_LOG_LEVEL, "4100: Hard device bus fabric error"}, + {0x04100100, 0, IPR_DEFAULT_LOG_LEVEL, + "310C: Logical block guard error detected by the device"}, + {0x04100300, 0, IPR_DEFAULT_LOG_LEVEL, + "310C: Logical block reference tag error detected by the device"}, + {0x04108300, 1, IPR_DEFAULT_LOG_LEVEL, + "4170: Scatter list tag / sequence number error"}, + {0x04109000, 1, IPR_DEFAULT_LOG_LEVEL, + "8150: Logical block CRC error on IOA to Host transfer"}, + {0x04109200, 1, IPR_DEFAULT_LOG_LEVEL, + "4170: Logical block sequence number error on IOA to Host transfer"}, + {0x0410A000, 0, IPR_DEFAULT_LOG_LEVEL, + "310D: Logical block reference tag error detected by the IOA"}, + {0x0410A100, 0, IPR_DEFAULT_LOG_LEVEL, + "310D: Logical block guard error detected by the IOA"}, {0x04118000, 0, IPR_DEFAULT_LOG_LEVEL, "9000: IOA reserved area data check"}, {0x04118100, 0, IPR_DEFAULT_LOG_LEVEL, "9001: IOA reserved area invalid data pattern"}, {0x04118200, 0, IPR_DEFAULT_LOG_LEVEL, "9002: IOA reserved area LRC error"}, + {0x04118300, 1, IPR_DEFAULT_LOG_LEVEL, + "Hardware Error, IOA metadata access error"}, {0x04320000, 0, IPR_DEFAULT_LOG_LEVEL, "102E: Out of alternate sectors for disk storage"}, {0x04330000, 1, IPR_DEFAULT_LOG_LEVEL, @@ -348,6 +378,8 @@ struct ipr_error_table_t ipr_error_table[] = { "Illegal request, commands not allowed to this device"}, {0x05258100, 0, 0, "Illegal request, command not allowed to a secondary adapter"}, + {0x05258200, 0, 0, + "Illegal request, command not allowed to a non-optimized resource"}, {0x05260000, 0, 0, "Illegal request, invalid field in parameter list"}, {0x05260100, 0, 0, -- cgit v0.10.2 From d7b4627f5f3390a2f350f16c047b3fc3eccce6d8 Mon Sep 17 00:00:00 2001 From: Wayne Boyer Date: Fri, 19 Feb 2010 13:24:38 -0800 Subject: [SCSI] ipr: adds PCI ID definitions for new adapters This patch adds the PCI ID definitions for new adapters based on the next generation 64 bit IOA PCI interface chip. New entries have been added to the ipr_pci_table[] array for the adapters and to the ipr_chip[] array for the new versions of the chip. Older entries have been removed for cards that did not ship. Signed-off-by: Wayne Boyer Signed-off-by: James Bottomley diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 7dc9fb1..c79cd98 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -178,7 +178,9 @@ static const struct ipr_chip_t ipr_chip[] = { { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[0] }, { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, IPR_USE_MSI, IPR_SIS32, &ipr_chip_cfg[0] }, { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SNIPE, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[1] }, - { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[1] } + { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[1] }, + { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2, IPR_USE_MSI, IPR_SIS64, &ipr_chip_cfg[2] }, + { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2, IPR_USE_MSI, IPR_SIS64, &ipr_chip_cfg[2] } }; static int ipr_max_bus_speeds [] = { @@ -8825,9 +8827,6 @@ static struct pci_device_id ipr_pci_table[] __devinitdata = { PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_574E, 0, 0, IPR_USE_LONG_TRANSOP_TIMEOUT }, { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, - PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575D, 0, 0, - IPR_USE_LONG_TRANSOP_TIMEOUT }, - { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B3, 0, 0, 0 }, { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B7, 0, 0, @@ -8842,9 +8841,22 @@ static struct pci_device_id ipr_pci_table[] __devinitdata = { { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572F, 0, 0, IPR_USE_LONG_TRANSOP_TIMEOUT }, - { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SCAMP_E, - PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_574D, 0, 0, - IPR_USE_LONG_TRANSOP_TIMEOUT }, + { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2, + PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B5, 0, 0, 0 }, + { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2, + PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_574D, 0, 0, 0 }, + { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2, + PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B2, 0, 0, 0 }, + { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2, + PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B4, 0, 0, 0 }, + { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2, + PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B1, 0, 0, 0 }, + { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2, + PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57C6, 0, 0, 0 }, + { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2, + PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575D, 0, 0, 0 }, + { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2, + PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57CE, 0, 0, 0 }, { } }; MODULE_DEVICE_TABLE(pci, ipr_pci_table); diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h index 137217e..4c267b5 100644 --- a/drivers/scsi/ipr.h +++ b/drivers/scsi/ipr.h @@ -37,8 +37,8 @@ /* * Literals */ -#define IPR_DRIVER_VERSION "2.4.3" -#define IPR_DRIVER_DATE "(June 10, 2009)" +#define IPR_DRIVER_VERSION "2.5.0" +#define IPR_DRIVER_DATE "(February 11, 2010)" /* * IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding @@ -55,7 +55,9 @@ #define IPR_NUM_BASE_CMD_BLKS 100 #define PCI_DEVICE_ID_IBM_OBSIDIAN_E 0x0339 -#define PCI_DEVICE_ID_IBM_SCAMP_E 0x034A + +#define PCI_DEVICE_ID_IBM_CROC_FPGA_E2 0x033D +#define PCI_DEVICE_ID_IBM_CROC_ASIC_E2 0x034A #define IPR_SUBS_DEV_ID_2780 0x0264 #define IPR_SUBS_DEV_ID_5702 0x0266 @@ -70,15 +72,24 @@ #define IPR_SUBS_DEV_ID_572A 0x02C1 #define IPR_SUBS_DEV_ID_572B 0x02C2 #define IPR_SUBS_DEV_ID_572F 0x02C3 -#define IPR_SUBS_DEV_ID_574D 0x030B #define IPR_SUBS_DEV_ID_574E 0x030A #define IPR_SUBS_DEV_ID_575B 0x030D #define IPR_SUBS_DEV_ID_575C 0x0338 -#define IPR_SUBS_DEV_ID_575D 0x033E #define IPR_SUBS_DEV_ID_57B3 0x033A #define IPR_SUBS_DEV_ID_57B7 0x0360 #define IPR_SUBS_DEV_ID_57B8 0x02C2 +#define IPR_SUBS_DEV_ID_57B4 0x033B +#define IPR_SUBS_DEV_ID_57B2 0x035F +#define IPR_SUBS_DEV_ID_57C6 0x0357 + +#define IPR_SUBS_DEV_ID_57B5 0x033C +#define IPR_SUBS_DEV_ID_57CE 0x035E +#define IPR_SUBS_DEV_ID_57B1 0x0355 + +#define IPR_SUBS_DEV_ID_574D 0x0356 +#define IPR_SUBS_DEV_ID_575D 0x035D + #define IPR_NAME "ipr" /* -- cgit v0.10.2 From 309ce156aa27f29338438011d292a8d6496623d3 Mon Sep 17 00:00:00 2001 From: Jayamohan Kallickal Date: Sat, 20 Feb 2010 08:02:10 +0530 Subject: [SCSI] libiscsi: Make iscsi_eh_target_reset start with session reset The iscsi_eh_target_reset has been modified to attempt target reset only. If it fails, then iscsi_eh_session_reset will be called. Signed-off-by: Mike Christie Signed-off-by: Jayamohan Kallickal Signed-off-by: James Bottomley diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index 5f7a6fc..5472b7e 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c @@ -596,7 +596,7 @@ static struct scsi_host_template iscsi_iser_sht = { .cmd_per_lun = ISER_DEF_CMD_PER_LUN, .eh_abort_handler = iscsi_eh_abort, .eh_device_reset_handler= iscsi_eh_device_reset, - .eh_target_reset_handler= iscsi_eh_target_reset, + .eh_target_reset_handler = iscsi_eh_recover_target, .target_alloc = iscsi_target_alloc, .use_clustering = DISABLE_CLUSTERING, .proc_name = "iscsi_iser", diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index 7c22616..4d269b4 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c @@ -79,7 +79,7 @@ static struct scsi_host_template beiscsi_sht = { .slave_configure = beiscsi_slave_configure, .target_alloc = iscsi_target_alloc, .eh_device_reset_handler = iscsi_eh_device_reset, - .eh_target_reset_handler = iscsi_eh_target_reset, + .eh_target_reset_handler = iscsi_eh_session_reset, .sg_tablesize = BEISCSI_SGLIST_ELEMENTS, .can_queue = BE2_IO_DEPTH, .this_id = -1, diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c index 1c4d121..cb71dc9 100644 --- a/drivers/scsi/bnx2i/bnx2i_iscsi.c +++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c @@ -1989,7 +1989,7 @@ static struct scsi_host_template bnx2i_host_template = { .queuecommand = iscsi_queuecommand, .eh_abort_handler = iscsi_eh_abort, .eh_device_reset_handler = iscsi_eh_device_reset, - .eh_target_reset_handler = iscsi_eh_target_reset, + .eh_target_reset_handler = iscsi_eh_recover_target, .change_queue_depth = iscsi_change_queue_depth, .can_queue = 1024, .max_sectors = 127, diff --git a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c index 412853c..b7c3058 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c +++ b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c @@ -915,7 +915,7 @@ static struct scsi_host_template cxgb3i_host_template = { .cmd_per_lun = ISCSI_DEF_CMD_PER_LUN, .eh_abort_handler = iscsi_eh_abort, .eh_device_reset_handler = iscsi_eh_device_reset, - .eh_target_reset_handler = iscsi_eh_target_reset, + .eh_target_reset_handler = iscsi_eh_recover_target, .target_alloc = iscsi_target_alloc, .use_clustering = DISABLE_CLUSTERING, .this_id = -1, diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 8a89ba9..249053a 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -874,7 +874,7 @@ static struct scsi_host_template iscsi_sw_tcp_sht = { .cmd_per_lun = ISCSI_DEF_CMD_PER_LUN, .eh_abort_handler = iscsi_eh_abort, .eh_device_reset_handler= iscsi_eh_device_reset, - .eh_target_reset_handler= iscsi_eh_target_reset, + .eh_target_reset_handler = iscsi_eh_recover_target, .use_clustering = DISABLE_CLUSTERING, .slave_alloc = iscsi_sw_tcp_slave_alloc, .slave_configure = iscsi_sw_tcp_slave_configure, diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 703eb6a..685eaec 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -2338,7 +2338,7 @@ EXPORT_SYMBOL_GPL(iscsi_session_recovery_timedout); * This function will wait for a relogin, session termination from * userspace, or a recovery/replacement timeout. */ -static int iscsi_eh_session_reset(struct scsi_cmnd *sc) +int iscsi_eh_session_reset(struct scsi_cmnd *sc) { struct iscsi_cls_session *cls_session; struct iscsi_session *session; @@ -2389,6 +2389,7 @@ failed: mutex_unlock(&session->eh_mutex); return SUCCESS; } +EXPORT_SYMBOL_GPL(iscsi_eh_session_reset); static void iscsi_prep_tgt_reset_pdu(struct scsi_cmnd *sc, struct iscsi_tm *hdr) { @@ -2403,8 +2404,7 @@ static void iscsi_prep_tgt_reset_pdu(struct scsi_cmnd *sc, struct iscsi_tm *hdr) * iscsi_eh_target_reset - reset target * @sc: scsi command * - * This will attempt to send a warm target reset. If that fails - * then we will drop the session and attempt ERL0 recovery. + * This will attempt to send a warm target reset. */ int iscsi_eh_target_reset(struct scsi_cmnd *sc) { @@ -2476,12 +2476,27 @@ done: ISCSI_DBG_EH(session, "tgt %s reset result = %s\n", session->targetname, rc == SUCCESS ? "SUCCESS" : "FAILED"); mutex_unlock(&session->eh_mutex); + return rc; +} +EXPORT_SYMBOL_GPL(iscsi_eh_target_reset); +/** + * iscsi_eh_recover_target - reset target and possibly the session + * @sc: scsi command + * + * This will attempt to send a warm target reset. If that fails, + * we will escalate to ERL0 session recovery. + */ +int iscsi_eh_recover_target(struct scsi_cmnd *sc) +{ + int rc; + + rc = iscsi_eh_target_reset(sc); if (rc == FAILED) rc = iscsi_eh_session_reset(sc); return rc; } -EXPORT_SYMBOL_GPL(iscsi_eh_target_reset); +EXPORT_SYMBOL_GPL(iscsi_eh_recover_target); /* * Pre-allocate a pool of @max items of @item_size. By default, the pool diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index ff92b46..ae5196a 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h @@ -338,7 +338,8 @@ struct iscsi_host { extern int iscsi_change_queue_depth(struct scsi_device *sdev, int depth, int reason); extern int iscsi_eh_abort(struct scsi_cmnd *sc); -extern int iscsi_eh_target_reset(struct scsi_cmnd *sc); +extern int iscsi_eh_recover_target(struct scsi_cmnd *sc); +extern int iscsi_eh_session_reset(struct scsi_cmnd *sc); extern int iscsi_eh_device_reset(struct scsi_cmnd *sc); extern int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)); -- cgit v0.10.2 From 4183122dbc7c489f11971c5afa8e42011bca7fa2 Mon Sep 17 00:00:00 2001 From: Jayamohan Kallickal Date: Sat, 20 Feb 2010 08:02:39 +0530 Subject: [SCSI] be2iscsi: Cleanup of resets for device and target This patch cleans up device and target reset handling for the driver Signed-off-by: Mike Christie Signed-off-by: Jayamohan Kallickal Signed-off-by: James Bottomley diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index 4d269b4..eab31a5 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c @@ -58,6 +58,123 @@ static int beiscsi_slave_configure(struct scsi_device *sdev) return 0; } +static int beiscsi_eh_abort(struct scsi_cmnd *sc) +{ + struct iscsi_cls_session *cls_session; + struct iscsi_task *aborted_task = (struct iscsi_task *)sc->SCp.ptr; + struct beiscsi_io_task *aborted_io_task; + struct iscsi_conn *conn; + struct beiscsi_conn *beiscsi_conn; + struct beiscsi_hba *phba; + struct iscsi_session *session; + struct invalidate_command_table *inv_tbl; + unsigned int cid, tag, num_invalidate; + + cls_session = starget_to_session(scsi_target(sc->device)); + session = cls_session->dd_data; + + spin_lock_bh(&session->lock); + if (!aborted_task || !aborted_task->sc) { + /* we raced */ + spin_unlock_bh(&session->lock); + return SUCCESS; + } + + aborted_io_task = aborted_task->dd_data; + if (!aborted_io_task->scsi_cmnd) { + /* raced or invalid command */ + spin_unlock_bh(&session->lock); + return SUCCESS; + } + spin_unlock_bh(&session->lock); + conn = aborted_task->conn; + beiscsi_conn = conn->dd_data; + phba = beiscsi_conn->phba; + + /* invalidate iocb */ + cid = beiscsi_conn->beiscsi_conn_cid; + inv_tbl = phba->inv_tbl; + memset(inv_tbl, 0x0, sizeof(*inv_tbl)); + inv_tbl->cid = cid; + inv_tbl->icd = aborted_io_task->psgl_handle->sgl_index; + num_invalidate = 1; + tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate, cid); + if (!tag) { + shost_printk(KERN_WARNING, phba->shost, + "mgmt_invalidate_icds could not be" + " submitted\n"); + return FAILED; + } else { + wait_event_interruptible(phba->ctrl.mcc_wait[tag], + phba->ctrl.mcc_numtag[tag]); + free_mcc_tag(&phba->ctrl, tag); + } + + return iscsi_eh_abort(sc); +} + +static int beiscsi_eh_device_reset(struct scsi_cmnd *sc) +{ + struct iscsi_task *abrt_task; + struct beiscsi_io_task *abrt_io_task; + struct iscsi_conn *conn; + struct beiscsi_conn *beiscsi_conn; + struct beiscsi_hba *phba; + struct iscsi_session *session; + struct iscsi_cls_session *cls_session; + struct invalidate_command_table *inv_tbl; + unsigned int cid, tag, i, num_invalidate; + int rc = FAILED; + + /* invalidate iocbs */ + cls_session = starget_to_session(scsi_target(sc->device)); + session = cls_session->dd_data; + spin_lock_bh(&session->lock); + if (!session->leadconn || session->state != ISCSI_STATE_LOGGED_IN) + goto unlock; + + conn = session->leadconn; + beiscsi_conn = conn->dd_data; + phba = beiscsi_conn->phba; + cid = beiscsi_conn->beiscsi_conn_cid; + inv_tbl = phba->inv_tbl; + memset(inv_tbl, 0x0, sizeof(*inv_tbl) * BE2_CMDS_PER_CXN); + num_invalidate = 0; + for (i = 0; i < conn->session->cmds_max; i++) { + abrt_task = conn->session->cmds[i]; + abrt_io_task = abrt_task->dd_data; + if (!abrt_task->sc || abrt_task->state == ISCSI_TASK_FREE) + continue; + + if (abrt_task->sc->device->lun != abrt_task->sc->device->lun) + continue; + + inv_tbl->cid = cid; + inv_tbl->icd = abrt_io_task->psgl_handle->sgl_index; + num_invalidate++; + inv_tbl++; + } + spin_unlock_bh(&session->lock); + inv_tbl = phba->inv_tbl; + + tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate, cid); + if (!tag) { + shost_printk(KERN_WARNING, phba->shost, + "mgmt_invalidate_icds could not be" + " submitted\n"); + return FAILED; + } else { + wait_event_interruptible(phba->ctrl.mcc_wait[tag], + phba->ctrl.mcc_numtag[tag]); + free_mcc_tag(&phba->ctrl, tag); + } + + return iscsi_eh_device_reset(sc); +unlock: + spin_unlock_bh(&session->lock); + return rc; +} + /*------------------- PCI Driver operations and data ----------------- */ static DEFINE_PCI_DEVICE_TABLE(beiscsi_pci_id_table) = { { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) }, @@ -74,11 +191,11 @@ static struct scsi_host_template beiscsi_sht = { .name = "ServerEngines 10Gbe open-iscsi Initiator Driver", .proc_name = DRV_NAME, .queuecommand = iscsi_queuecommand, - .eh_abort_handler = iscsi_eh_abort, .change_queue_depth = iscsi_change_queue_depth, .slave_configure = beiscsi_slave_configure, .target_alloc = iscsi_target_alloc, - .eh_device_reset_handler = iscsi_eh_device_reset, + .eh_abort_handler = beiscsi_eh_abort, + .eh_device_reset_handler = beiscsi_eh_device_reset, .eh_target_reset_handler = iscsi_eh_session_reset, .sg_tablesize = BEISCSI_SGLIST_ELEMENTS, .can_queue = BE2_IO_DEPTH, @@ -3486,9 +3603,9 @@ static int beiscsi_mtask(struct iscsi_task *task) struct hwi_wrb_context *pwrb_context; struct wrb_handle *pwrb_handle; unsigned int doorbell = 0; - unsigned int i, cid; + struct invalidate_command_table *inv_tbl; struct iscsi_task *aborted_task; - unsigned int tag; + unsigned int i, cid, tag, num_invalidate; cid = beiscsi_conn->beiscsi_conn_cid; pwrb = io_task->pwrb_handle->pwrb; @@ -3538,9 +3655,12 @@ static int beiscsi_mtask(struct iscsi_task *task) if (!aborted_io_task->scsi_cmnd) return 0; - tag = mgmt_invalidate_icds(phba, - aborted_io_task->psgl_handle->sgl_index, - cid); + inv_tbl = phba->inv_tbl; + memset(inv_tbl, 0x0, sizeof(*inv_tbl)); + inv_tbl->cid = cid; + inv_tbl->icd = aborted_io_task->psgl_handle->sgl_index; + num_invalidate = 1; + tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate, cid); if (!tag) { shost_printk(KERN_WARNING, phba->shost, "mgmt_invalidate_icds could not be" diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h index c53a80a..d4d31dc 100644 --- a/drivers/scsi/be2iscsi/be_main.h +++ b/drivers/scsi/be2iscsi/be_main.h @@ -257,6 +257,11 @@ struct hba_parameters { unsigned int num_sge; }; +struct invalidate_command_table { + unsigned short icd; + unsigned short cid; +} __packed; + struct beiscsi_hba { struct hba_parameters params; struct hwi_controller *phwi_ctrlr; @@ -329,6 +334,8 @@ struct beiscsi_hba { struct work_struct work_cqs; /* The work being queued */ struct be_ctrl_info ctrl; unsigned int generation; + struct invalidate_command_table inv_tbl[128]; + }; struct beiscsi_session { diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c index 317bcd0..72617b6 100644 --- a/drivers/scsi/be2iscsi/be_mgmt.c +++ b/drivers/scsi/be2iscsi/be_mgmt.c @@ -145,14 +145,15 @@ unsigned char mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute) } unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba, - unsigned int icd, unsigned int cid) + struct invalidate_command_table *inv_tbl, + unsigned int num_invalidate, unsigned int cid) { struct be_dma_mem nonemb_cmd; struct be_ctrl_info *ctrl = &phba->ctrl; struct be_mcc_wrb *wrb; struct be_sge *sge; struct invalidate_commands_params_in *req; - unsigned int tag = 0; + unsigned int i, tag = 0; spin_lock(&ctrl->mbox_lock); tag = alloc_mcc_tag(phba); @@ -183,9 +184,12 @@ unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba, sizeof(*req)); req->ref_handle = 0; req->cleanup_type = CMD_ISCSI_COMMAND_INVALIDATE; - req->icd_count = 0; - req->table[req->icd_count].icd = icd; - req->table[req->icd_count].cid = cid; + for (i = 0; i < num_invalidate; i++) { + req->table[i].icd = inv_tbl->icd; + req->table[i].cid = inv_tbl->cid; + req->icd_count++; + inv_tbl++; + } sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma)); sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF); sge->len = cpu_to_le32(nonemb_cmd.size); diff --git a/drivers/scsi/be2iscsi/be_mgmt.h b/drivers/scsi/be2iscsi/be_mgmt.h index ecead6a..3d316b8 100644 --- a/drivers/scsi/be2iscsi/be_mgmt.h +++ b/drivers/scsi/be2iscsi/be_mgmt.h @@ -94,7 +94,8 @@ unsigned char mgmt_upload_connection(struct beiscsi_hba *phba, unsigned short cid, unsigned int upload_flag); unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba, - unsigned int icd, unsigned int cid); + struct invalidate_command_table *inv_tbl, + unsigned int num_invalidate, unsigned int cid); struct iscsi_invalidate_connection_params_in { struct be_cmd_req_hdr hdr; @@ -116,11 +117,6 @@ union iscsi_invalidate_connection_params { struct iscsi_invalidate_connection_params_out response; } __packed; -struct invalidate_command_table { - unsigned short icd; - unsigned short cid; -} __packed; - struct invalidate_commands_params_in { struct be_cmd_req_hdr hdr; unsigned int ref_handle; -- cgit v0.10.2 From 944b2fbce26ce39555363fd092386807fa5ea08c Mon Sep 17 00:00:00 2001 From: Jayamohan Kallickal Date: Sat, 20 Feb 2010 08:03:24 +0530 Subject: [SCSI] be2iscsi: Fix for a possible udelay while holding lock This patch fixes a situation where we could call udelay while holding spin_lock Signed-off-by: Jayamohan Kallickal Signed-off-by: James Bottomley diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c index 6709857..cda6642 100644 --- a/drivers/scsi/be2iscsi/be_cmds.c +++ b/drivers/scsi/be2iscsi/be_cmds.c @@ -32,18 +32,11 @@ void be_mcc_notify(struct beiscsi_hba *phba) unsigned int alloc_mcc_tag(struct beiscsi_hba *phba) { unsigned int tag = 0; - unsigned int num = 0; -mcc_tag_rdy: if (phba->ctrl.mcc_tag_available) { tag = phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index]; phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index] = 0; phba->ctrl.mcc_numtag[tag] = 0; - } else { - udelay(100); - num++; - if (num < mcc_timeout) - goto mcc_tag_rdy; } if (tag) { phba->ctrl.mcc_tag_available--; -- cgit v0.10.2 From dafab8e079f432268cca5cf378b92d6acfacc393 Mon Sep 17 00:00:00 2001 From: Jayamohan Kallickal Date: Sat, 20 Feb 2010 08:03:56 +0530 Subject: [SCSI] be2iscsi: cleans up abort handling This patch cleans up abort handling when TMF is sent Signed-off-by: Jayamohan Kallickal Signed-off-by: James Bottomley diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index eab31a5..aee3734 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c @@ -1063,14 +1063,18 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn, case HWH_TYPE_IO: case HWH_TYPE_IO_RD: if ((task->hdr->opcode & ISCSI_OPCODE_MASK) == - ISCSI_OP_NOOP_OUT) { + ISCSI_OP_NOOP_OUT) be_complete_nopin_resp(beiscsi_conn, task, psol); - } else + else be_complete_io(beiscsi_conn, task, psol); break; case HWH_TYPE_LOGOUT: - be_complete_logout(beiscsi_conn, task, psol); + if ((task->hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGOUT) + be_complete_logout(beiscsi_conn, task, psol); + else + be_complete_tmf(beiscsi_conn, task, psol); + break; case HWH_TYPE_LOGIN: @@ -1079,10 +1083,6 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn, "- Solicited path \n"); break; - case HWH_TYPE_TMF: - be_complete_tmf(beiscsi_conn, task, psol); - break; - case HWH_TYPE_NOP: be_complete_nopin_resp(beiscsi_conn, task, psol); break; @@ -3593,19 +3593,13 @@ static int beiscsi_iotask(struct iscsi_task *task, struct scatterlist *sg, static int beiscsi_mtask(struct iscsi_task *task) { - struct beiscsi_io_task *aborted_io_task, *io_task = task->dd_data; + struct beiscsi_io_task *io_task = task->dd_data; struct iscsi_conn *conn = task->conn; struct beiscsi_conn *beiscsi_conn = conn->dd_data; struct beiscsi_hba *phba = beiscsi_conn->phba; - struct iscsi_session *session; struct iscsi_wrb *pwrb = NULL; - struct hwi_controller *phwi_ctrlr; - struct hwi_wrb_context *pwrb_context; - struct wrb_handle *pwrb_handle; unsigned int doorbell = 0; - struct invalidate_command_table *inv_tbl; - struct iscsi_task *aborted_task; - unsigned int i, cid, tag, num_invalidate; + unsigned int cid; cid = beiscsi_conn->beiscsi_conn_cid; pwrb = io_task->pwrb_handle->pwrb; @@ -3616,6 +3610,7 @@ static int beiscsi_mtask(struct iscsi_task *task) io_task->pwrb_handle->wrb_index); AMAP_SET_BITS(struct amap_iscsi_wrb, sgl_icd_idx, pwrb, io_task->psgl_handle->sgl_index); + switch (task->hdr->opcode & ISCSI_OPCODE_MASK) { case ISCSI_OP_LOGIN: AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, @@ -3640,36 +3635,6 @@ static int beiscsi_mtask(struct iscsi_task *task) hwi_write_buffer(pwrb, task); break; case ISCSI_OP_SCSI_TMFUNC: - session = conn->session; - i = ((struct iscsi_tm *)task->hdr)->rtt; - phwi_ctrlr = phba->phwi_ctrlr; - pwrb_context = &phwi_ctrlr->wrb_context[cid - - phba->fw_config.iscsi_cid_start]; - pwrb_handle = pwrb_context->pwrb_handle_basestd[be32_to_cpu(i) - >> 16]; - aborted_task = pwrb_handle->pio_handle; - if (!aborted_task) - return 0; - - aborted_io_task = aborted_task->dd_data; - if (!aborted_io_task->scsi_cmnd) - return 0; - - inv_tbl = phba->inv_tbl; - memset(inv_tbl, 0x0, sizeof(*inv_tbl)); - inv_tbl->cid = cid; - inv_tbl->icd = aborted_io_task->psgl_handle->sgl_index; - num_invalidate = 1; - tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate, cid); - if (!tag) { - shost_printk(KERN_WARNING, phba->shost, - "mgmt_invalidate_icds could not be" - " submitted\n"); - } else { - wait_event_interruptible(phba->ctrl.mcc_wait[tag], - phba->ctrl.mcc_numtag[tag]); - free_mcc_tag(&phba->ctrl, tag); - } AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, INI_TMF_CMD); AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); @@ -3678,7 +3643,7 @@ static int beiscsi_mtask(struct iscsi_task *task) case ISCSI_OP_LOGOUT: AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, - HWH_TYPE_LOGOUT); + HWH_TYPE_LOGOUT); hwi_write_buffer(pwrb, task); break; @@ -3704,17 +3669,12 @@ static int beiscsi_mtask(struct iscsi_task *task) static int beiscsi_task_xmit(struct iscsi_task *task) { - struct iscsi_conn *conn = task->conn; struct beiscsi_io_task *io_task = task->dd_data; struct scsi_cmnd *sc = task->sc; - struct beiscsi_conn *beiscsi_conn = conn->dd_data; struct scatterlist *sg; int num_sg; unsigned int writedir = 0, xferlen = 0; - SE_DEBUG(DBG_LVL_4, "\n cid=%d In beiscsi_task_xmit task=%p conn=%p \t" - "beiscsi_conn=%p \n", beiscsi_conn->beiscsi_conn_cid, - task, conn, beiscsi_conn); if (!sc) return beiscsi_mtask(task); -- cgit v0.10.2 From 90a289e87648f80b63178c463aa7daaf5205805c Mon Sep 17 00:00:00 2001 From: Jayamohan Kallickal Date: Sat, 20 Feb 2010 08:04:28 +0530 Subject: [SCSI] be2iscsi: Remove debug code This patch removes some debug lines which are unnecessary and also aligns some lines in code Signed-off-by: Jayamohan Kallickal Signed-off-by: James Bottomley diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c index 29a3aaf..c3928cb 100644 --- a/drivers/scsi/be2iscsi/be_iscsi.c +++ b/drivers/scsi/be2iscsi/be_iscsi.c @@ -482,7 +482,7 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep, tag = mgmt_open_connection(phba, dst_addr, beiscsi_ep); if (!tag) { SE_DEBUG(DBG_LVL_1, - "mgmt_invalidate_connection Failed for cid=%d \n", + "mgmt_open_connection Failed for cid=%d \n", beiscsi_ep->ep_cid); } else { wait_event_interruptible(phba->ctrl.mcc_wait[tag], @@ -701,7 +701,7 @@ void beiscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag) if (!tag) { SE_DEBUG(DBG_LVL_1, "mgmt_invalidate_connection Failed for cid=%d \n", - beiscsi_ep->ep_cid); + beiscsi_ep->ep_cid); } else { wait_event_interruptible(phba->ctrl.mcc_wait[tag], phba->ctrl.mcc_numtag[tag]); diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index aee3734..b5dca45 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c @@ -3779,7 +3779,6 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev, " Failed in beiscsi_hba_alloc \n"); goto disable_pci; } - SE_DEBUG(DBG_LVL_8, " phba = %p \n", phba); switch (pcidev->device) { case BE_DEVICE_ID1: -- cgit v0.10.2 From ed58ea2ab58c7d80a07a829a1cc2c4161c300494 Mon Sep 17 00:00:00 2001 From: Jayamohan Kallickal Date: Sat, 20 Feb 2010 08:05:07 +0530 Subject: [SCSI] be2iscsi: Fixing memory allocation for connection This patch fixes some situations where enough resources were not avaialable when targets exceeded a certain limit Signed-off-by: Jayamohan Kallickal Signed-off-by: James Bottomley diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index b5dca45..5887d7a 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c @@ -359,7 +359,7 @@ static void beiscsi_get_params(struct beiscsi_hba *phba) + BE2_TMFS + BE2_NOPOUT_REQ)); phba->params.cxns_per_ctrl = phba->fw_config.iscsi_cid_count; - phba->params.asyncpdus_per_ctrl = phba->fw_config.iscsi_cid_count;; + phba->params.asyncpdus_per_ctrl = phba->fw_config.iscsi_cid_count * 2; phba->params.icds_per_ctrl = phba->fw_config.iscsi_icd_count;; phba->params.num_sge_per_io = BE2_SGE; phba->params.defpdu_hdr_sz = BE2_DEFPDU_HDR_SZ; @@ -2169,7 +2169,7 @@ static void beiscsi_init_wrb_handle(struct beiscsi_hba *phba) num_cxn_wrb = (mem_descr_wrb->mem_array[idx].size) / ((sizeof(struct iscsi_wrb) * phba->params.wrbs_per_cxn)); - for (index = 0; index < phba->params.cxns_per_ctrl; index += 2) { + for (index = 0; index < phba->params.cxns_per_ctrl * 2; index += 2) { pwrb_context = &phwi_ctrlr->wrb_context[index]; if (num_cxn_wrb) { for (j = 0; j < phba->params.wrbs_per_cxn; j++) { diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h index d4d31dc..87ec212 100644 --- a/drivers/scsi/be2iscsi/be_main.h +++ b/drivers/scsi/be2iscsi/be_main.h @@ -498,8 +498,6 @@ struct hwi_async_entry { struct list_head data_busy_list; }; -#define BE_MIN_ASYNC_ENTRIES 128 - struct hwi_async_pdu_context { struct { struct be_bus_address pa_base; @@ -540,7 +538,7 @@ struct hwi_async_pdu_context { * This is a varying size list! Do not add anything * after this entry!! */ - struct hwi_async_entry async_entry[BE_MIN_ASYNC_ENTRIES]; + struct hwi_async_entry async_entry[BE2_MAX_SESSIONS * 2]; }; #define PDUCQE_CODE_MASK 0x0000003F -- cgit v0.10.2 From c03af1ae1cce97a5530b907ea03625ce6e00214e Mon Sep 17 00:00:00 2001 From: Jayamohan Kallickal Date: Sat, 20 Feb 2010 08:05:43 +0530 Subject: [SCSI] be2iscsi: Alloc only one EQ if intr mode This patch ensures that we alloc only one EQ if we are if we are not in msix mode Signed-off-by: Jayamohan Kallickal Signed-off-by: James Bottomley diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index 5887d7a..fcfb29e 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c @@ -3190,14 +3190,18 @@ static unsigned char hwi_enable_intr(struct beiscsi_hba *phba) reg |= MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK; SE_DEBUG(DBG_LVL_8, "reg =x%08x addr=%p \n", reg, addr); iowrite32(reg, addr); - for (i = 0; i <= phba->num_cpus; i++) { - eq = &phwi_context->be_eq[i].q; + if (!phba->msix_enabled) { + eq = &phwi_context->be_eq[0].q; SE_DEBUG(DBG_LVL_8, "eq->id=%d \n", eq->id); hwi_ring_eq_db(phba, eq->id, 0, 0, 1, 1); + } else { + for (i = 0; i <= phba->num_cpus; i++) { + eq = &phwi_context->be_eq[i].q; + SE_DEBUG(DBG_LVL_8, "eq->id=%d \n", eq->id); + hwi_ring_eq_db(phba, eq->id, 0, 0, 1, 1); + } } - } else - shost_printk(KERN_WARNING, phba->shost, - "In hwi_enable_intr, Not Enabled \n"); + } return true; } -- cgit v0.10.2 From 64355b929dec0cb6271e4ac7834c9cf262961e40 Mon Sep 17 00:00:00 2001 From: Brian King Date: Sun, 21 Feb 2010 10:37:57 -0600 Subject: [SCSI] ibmvscsi: Add suspend/resume support Adds support for resuming from suspend for IBM VSCSI devices. We may have lost an interrupt over the suspend, so we just kick the interrupt handler to process anything that is outstanding. We expect to find a transport event indicating we need to reestablish our CRQ. Signed-off-by: Brian King Signed-off-by: James Bottomley diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index e3a18e0..dc1bcbe 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -71,6 +71,7 @@ #include #include #include +#include #include #include #include @@ -1991,6 +1992,19 @@ static int ibmvscsi_remove(struct vio_dev *vdev) } /** + * ibmvscsi_resume: Resume from suspend + * @dev: device struct + * + * We may have lost an interrupt across suspend/resume, so kick the + * interrupt handler + */ +static int ibmvscsi_resume(struct device *dev) +{ + struct ibmvscsi_host_data *hostdata = dev_get_drvdata(dev); + return ibmvscsi_ops->resume(hostdata); +} + +/** * ibmvscsi_device_table: Used by vio.c to match devices in the device tree we * support. */ @@ -2000,6 +2014,10 @@ static struct vio_device_id ibmvscsi_device_table[] __devinitdata = { }; MODULE_DEVICE_TABLE(vio, ibmvscsi_device_table); +static struct dev_pm_ops ibmvscsi_pm_ops = { + .resume = ibmvscsi_resume +}; + static struct vio_driver ibmvscsi_driver = { .id_table = ibmvscsi_device_table, .probe = ibmvscsi_probe, @@ -2008,6 +2026,7 @@ static struct vio_driver ibmvscsi_driver = { .driver = { .name = "ibmvscsi", .owner = THIS_MODULE, + .pm = &ibmvscsi_pm_ops, } }; diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.h b/drivers/scsi/ibmvscsi/ibmvscsi.h index 7642530..9cb7c6a 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.h +++ b/drivers/scsi/ibmvscsi/ibmvscsi.h @@ -120,6 +120,7 @@ struct ibmvscsi_ops { struct ibmvscsi_host_data *hostdata); int (*send_crq)(struct ibmvscsi_host_data *hostdata, u64 word1, u64 word2); + int (*resume) (struct ibmvscsi_host_data *hostdata); }; extern struct ibmvscsi_ops iseriesvscsi_ops; diff --git a/drivers/scsi/ibmvscsi/iseries_vscsi.c b/drivers/scsi/ibmvscsi/iseries_vscsi.c index 0775fde..f477645 100644 --- a/drivers/scsi/ibmvscsi/iseries_vscsi.c +++ b/drivers/scsi/ibmvscsi/iseries_vscsi.c @@ -158,10 +158,16 @@ static int iseriesvscsi_send_crq(struct ibmvscsi_host_data *hostdata, 0); } +static int iseriesvscsi_resume(struct ibmvscsi_host_data *hostdata) +{ + return 0; +} + struct ibmvscsi_ops iseriesvscsi_ops = { .init_crq_queue = iseriesvscsi_init_crq_queue, .release_crq_queue = iseriesvscsi_release_crq_queue, .reset_crq_queue = iseriesvscsi_reset_crq_queue, .reenable_crq_queue = iseriesvscsi_reenable_crq_queue, .send_crq = iseriesvscsi_send_crq, + .resume = iseriesvscsi_resume, }; diff --git a/drivers/scsi/ibmvscsi/rpa_vscsi.c b/drivers/scsi/ibmvscsi/rpa_vscsi.c index 462a857..63a30cb 100644 --- a/drivers/scsi/ibmvscsi/rpa_vscsi.c +++ b/drivers/scsi/ibmvscsi/rpa_vscsi.c @@ -334,10 +334,23 @@ static int rpavscsi_reenable_crq_queue(struct crq_queue *queue, return rc; } +/** + * rpavscsi_resume: - resume after suspend + * @hostdata: ibmvscsi_host_data of host + * + */ +static int rpavscsi_resume(struct ibmvscsi_host_data *hostdata) +{ + vio_disable_interrupts(to_vio_dev(hostdata->dev)); + tasklet_schedule(&hostdata->srp_task); + return 0; +} + struct ibmvscsi_ops rpavscsi_ops = { .init_crq_queue = rpavscsi_init_crq_queue, .release_crq_queue = rpavscsi_release_crq_queue, .reset_crq_queue = rpavscsi_reset_crq_queue, .reenable_crq_queue = rpavscsi_reenable_crq_queue, .send_crq = rpavscsi_send_crq, + .resume = rpavscsi_resume, }; -- cgit v0.10.2 From b0f4d4cf12d0eaa0bd766686bba843fc105b6a60 Mon Sep 17 00:00:00 2001 From: Brian King Date: Sun, 21 Feb 2010 10:37:58 -0600 Subject: [SCSI] ibmvfc: Add suspend/resume support Adds support for resuming from suspend for IBM VFC devices. We may have lost an interrupt over the suspend, so we just kick the interrupt handler to process anything that is outstanding. We expect to find a transport event indicating we need to reestablish our CRQ. Signed-off-by: Brian King Signed-off-by: James Bottomley diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index 732f6d3..4e577e2 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -4736,6 +4737,27 @@ static int ibmvfc_remove(struct vio_dev *vdev) } /** + * ibmvfc_resume - Resume from suspend + * @dev: device struct + * + * We may have lost an interrupt across suspend/resume, so kick the + * interrupt handler + * + */ +static int ibmvfc_resume(struct device *dev) +{ + unsigned long flags; + struct ibmvfc_host *vhost = dev_get_drvdata(dev); + struct vio_dev *vdev = to_vio_dev(dev); + + spin_lock_irqsave(vhost->host->host_lock, flags); + vio_disable_interrupts(vdev); + tasklet_schedule(&vhost->tasklet); + spin_unlock_irqrestore(vhost->host->host_lock, flags); + return 0; +} + +/** * ibmvfc_get_desired_dma - Calculate DMA resources needed by the driver * @vdev: vio device struct * @@ -4755,6 +4777,10 @@ static struct vio_device_id ibmvfc_device_table[] __devinitdata = { }; MODULE_DEVICE_TABLE(vio, ibmvfc_device_table); +static struct dev_pm_ops ibmvfc_pm_ops = { + .resume = ibmvfc_resume +}; + static struct vio_driver ibmvfc_driver = { .id_table = ibmvfc_device_table, .probe = ibmvfc_probe, @@ -4763,6 +4789,7 @@ static struct vio_driver ibmvfc_driver = { .driver = { .name = IBMVFC_NAME, .owner = THIS_MODULE, + .pm = &ibmvfc_pm_ops, } }; -- cgit v0.10.2 From 667e23d4e968f6826dc5d3e81238a7f1f343fb4f Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Thu, 25 Feb 2010 14:02:51 -0600 Subject: [SCSI] hpsa: allow modifying device queue depth. Signed-off-by: Stephen M. Cameron Signed-off-by: James Bottomley diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 03697ba..745c624 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -134,6 +135,8 @@ static int hpsa_scsi_queue_command(struct scsi_cmnd *cmd, static void hpsa_scan_start(struct Scsi_Host *); static int hpsa_scan_finished(struct Scsi_Host *sh, unsigned long elapsed_time); +static int hpsa_change_queue_depth(struct scsi_device *sdev, + int qdepth, int reason); static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd); static int hpsa_slave_alloc(struct scsi_device *sdev); @@ -182,6 +185,7 @@ static struct scsi_host_template hpsa_driver_template = { .queuecommand = hpsa_scsi_queue_command, .scan_start = hpsa_scan_start, .scan_finished = hpsa_scan_finished, + .change_queue_depth = hpsa_change_queue_depth, .this_id = -1, .sg_tablesize = MAXSGENTRIES, .use_clustering = ENABLE_CLUSTERING, @@ -2077,6 +2081,23 @@ static int hpsa_scan_finished(struct Scsi_Host *sh, return finished; } +static int hpsa_change_queue_depth(struct scsi_device *sdev, + int qdepth, int reason) +{ + struct ctlr_info *h = sdev_to_hba(sdev); + + if (reason != SCSI_QDEPTH_DEFAULT) + return -ENOTSUPP; + + if (qdepth < 1) + qdepth = 1; + else + if (qdepth > h->nr_cmds) + qdepth = h->nr_cmds; + scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth); + return sdev->queue_depth; +} + static void hpsa_unregister_scsi(struct ctlr_info *h) { /* we are being forcibly unloaded, and may not refuse. */ -- cgit v0.10.2 From f0edafc6628f924a424ab4059df74f46f4f4241e Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Thu, 25 Feb 2010 14:02:56 -0600 Subject: [SCSI] hpsa: fix firmwart typo Signed-off-by: Stephen M. Cameron Signed-off-by: James Bottomley diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 745c624..3734f31 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -2982,7 +2982,7 @@ static irqreturn_t do_hpsa_intr(int irq, void *dev_id) return IRQ_HANDLED; } -/* Send a message CDB to the firmwart. */ +/* Send a message CDB to the firmware. */ static __devinit int hpsa_message(struct pci_dev *pdev, unsigned char opcode, unsigned char type) { -- cgit v0.10.2 From 5512672f75611e9239669c6a4dce648b8d60fedd Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Thu, 25 Feb 2010 14:03:01 -0600 Subject: [SCSI] hpsa: fix scsi status mis-shift The SCSI status does not need to be shifted. Signed-off-by: Stephen M. Cameron Signed-off-by: James Bottomley diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 3734f31..604b4c9 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -1006,7 +1006,7 @@ static void complete_scsi_command(struct CommandList *cp, cmd->result = (DID_OK << 16); /* host byte */ cmd->result |= (COMMAND_COMPLETE << 8); /* msg byte */ - cmd->result |= (ei->ScsiStatus << 1); + cmd->result |= ei->ScsiStatus; /* copy the sense data whether we need to or not. */ memcpy(cmd->sense_buffer, ei->SenseInfo, -- cgit v0.10.2 From e9ea04a65ad842452cbee92b5c865af7fed17f63 Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Thu, 25 Feb 2010 14:03:06 -0600 Subject: [SCSI] hpsa: return -ENOMEM, not -1 Signed-off-by: Stephen M. Cameron Signed-off-by: James Bottomley diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 604b4c9..a72a18e 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -1386,7 +1386,7 @@ static int hpsa_send_reset(struct ctlr_info *h, unsigned char *scsi3addr) if (c == NULL) { /* trouble... */ dev_warn(&h->pdev->dev, "cmd_special_alloc returned NULL!\n"); - return -1; + return -ENOMEM; } fill_cmd(c, HPSA_DEVICE_RESET_MSG, h, NULL, 0, 0, scsi3addr, TYPE_MSG); -- cgit v0.10.2 From 31468401ccf64322ca99fe05fbe64f1551240f57 Mon Sep 17 00:00:00 2001 From: Mike Miller Date: Thu, 25 Feb 2010 14:03:12 -0600 Subject: [SCSI] hpsa: remove scan thread The intent of the scan thread was to allow a UNIT ATTENTION/LUN DATA CHANGED condition encountered in the interrupt handler to trigger a rescan of devices, which can't be done in interrupt context. However, we weren't able to get this to work, due to multiple such UNIT ATTENTION conditions arriving during the rescan, during updating of the SCSI mid layer, etc. There's no way to tell the devices, "stand still while I scan you!" Since it doesn't work, there's no point in having the thread, as the rescan triggered via ioctl or sysfs can be done without such a thread. Signed-off-by: Mike Miller Signed-off-by: Stephen M. Cameron Signed-off-by: James Bottomley diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index a72a18e..3d43bb2 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -53,7 +53,7 @@ #include "hpsa.h" /* HPSA_DRIVER_VERSION must be 3 byte values (0-255) separated by '.' */ -#define HPSA_DRIVER_VERSION "2.0.1-3" +#define HPSA_DRIVER_VERSION "2.0.2-1" #define DRIVER_NAME "HP HPSA Driver (v " HPSA_DRIVER_VERSION ")" /* How long to wait (in milliseconds) for board to go into simple mode */ @@ -212,133 +212,6 @@ static inline struct ctlr_info *shost_to_hba(struct Scsi_Host *sh) return (struct ctlr_info *) *priv; } -static struct task_struct *hpsa_scan_thread; -static DEFINE_MUTEX(hpsa_scan_mutex); -static LIST_HEAD(hpsa_scan_q); -static int hpsa_scan_func(void *data); - -/** - * add_to_scan_list() - add controller to rescan queue - * @h: Pointer to the controller. - * - * Adds the controller to the rescan queue if not already on the queue. - * - * returns 1 if added to the queue, 0 if skipped (could be on the - * queue already, or the controller could be initializing or shutting - * down). - **/ -static int add_to_scan_list(struct ctlr_info *h) -{ - struct ctlr_info *test_h; - int found = 0; - int ret = 0; - - if (h->busy_initializing) - return 0; - - /* - * If we don't get the lock, it means the driver is unloading - * and there's no point in scheduling a new scan. - */ - if (!mutex_trylock(&h->busy_shutting_down)) - return 0; - - mutex_lock(&hpsa_scan_mutex); - list_for_each_entry(test_h, &hpsa_scan_q, scan_list) { - if (test_h == h) { - found = 1; - break; - } - } - if (!found && !h->busy_scanning) { - INIT_COMPLETION(h->scan_wait); - list_add_tail(&h->scan_list, &hpsa_scan_q); - ret = 1; - } - mutex_unlock(&hpsa_scan_mutex); - mutex_unlock(&h->busy_shutting_down); - - return ret; -} - -/** - * remove_from_scan_list() - remove controller from rescan queue - * @h: Pointer to the controller. - * - * Removes the controller from the rescan queue if present. Blocks if - * the controller is currently conducting a rescan. The controller - * can be in one of three states: - * 1. Doesn't need a scan - * 2. On the scan list, but not scanning yet (we remove it) - * 3. Busy scanning (and not on the list). In this case we want to wait for - * the scan to complete to make sure the scanning thread for this - * controller is completely idle. - **/ -static void remove_from_scan_list(struct ctlr_info *h) -{ - struct ctlr_info *test_h, *tmp_h; - - mutex_lock(&hpsa_scan_mutex); - list_for_each_entry_safe(test_h, tmp_h, &hpsa_scan_q, scan_list) { - if (test_h == h) { /* state 2. */ - list_del(&h->scan_list); - complete_all(&h->scan_wait); - mutex_unlock(&hpsa_scan_mutex); - return; - } - } - if (h->busy_scanning) { /* state 3. */ - mutex_unlock(&hpsa_scan_mutex); - wait_for_completion(&h->scan_wait); - } else { /* state 1, nothing to do. */ - mutex_unlock(&hpsa_scan_mutex); - } -} - -/* hpsa_scan_func() - kernel thread used to rescan controllers - * @data: Ignored. - * - * A kernel thread used scan for drive topology changes on - * controllers. The thread processes only one controller at a time - * using a queue. Controllers are added to the queue using - * add_to_scan_list() and removed from the queue either after done - * processing or using remove_from_scan_list(). - * - * returns 0. - **/ -static int hpsa_scan_func(__attribute__((unused)) void *data) -{ - struct ctlr_info *h; - int host_no; - - while (1) { - set_current_state(TASK_INTERRUPTIBLE); - schedule(); - if (kthread_should_stop()) - break; - - while (1) { - mutex_lock(&hpsa_scan_mutex); - if (list_empty(&hpsa_scan_q)) { - mutex_unlock(&hpsa_scan_mutex); - break; - } - h = list_entry(hpsa_scan_q.next, struct ctlr_info, - scan_list); - list_del(&h->scan_list); - h->busy_scanning = 1; - mutex_unlock(&hpsa_scan_mutex); - host_no = h->scsi_host ? h->scsi_host->host_no : -1; - hpsa_scan_start(h->scsi_host); - complete_all(&h->scan_wait); - mutex_lock(&hpsa_scan_mutex); - h->busy_scanning = 0; - mutex_unlock(&hpsa_scan_mutex); - } - } - return 0; -} - static int check_for_unit_attention(struct ctlr_info *h, struct CommandList *c) { @@ -356,21 +229,8 @@ static int check_for_unit_attention(struct ctlr_info *h, break; case REPORT_LUNS_CHANGED: dev_warn(&h->pdev->dev, "hpsa%d: report LUN data " - "changed\n", h->ctlr); + "changed, action required\n", h->ctlr); /* - * Here, we could call add_to_scan_list and wake up the scan thread, - * except that it's quite likely that we will get more than one - * REPORT_LUNS_CHANGED condition in quick succession, which means - * that those which occur after the first one will likely happen - * *during* the hpsa_scan_thread's rescan. And the rescan code is not - * robust enough to restart in the middle, undoing what it has already - * done, and it's not clear that it's even possible to do this, since - * part of what it does is notify the SCSI mid layer, which starts - * doing it's own i/o to read partition tables and so on, and the - * driver doesn't have visibility to know what might need undoing. - * In any event, if possible, it is horribly complicated to get right - * so we just don't do it for now. - * * Note: this REPORT_LUNS_CHANGED condition only occurs on the MSA2012. */ break; @@ -397,10 +257,7 @@ static ssize_t host_store_rescan(struct device *dev, struct ctlr_info *h; struct Scsi_Host *shost = class_to_shost(dev); h = shost_to_hba(shost); - if (add_to_scan_list(h)) { - wake_up_process(hpsa_scan_thread); - wait_for_completion_interruptible(&h->scan_wait); - } + hpsa_scan_start(h->scsi_host); return count; } @@ -3553,8 +3410,6 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev, h->busy_initializing = 1; INIT_HLIST_HEAD(&h->cmpQ); INIT_HLIST_HEAD(&h->reqQ); - mutex_init(&h->busy_shutting_down); - init_completion(&h->scan_wait); rc = hpsa_pci_init(h, pdev); if (rc != 0) goto clean1; @@ -3702,8 +3557,6 @@ static void __devexit hpsa_remove_one(struct pci_dev *pdev) return; } h = pci_get_drvdata(pdev); - mutex_lock(&h->busy_shutting_down); - remove_from_scan_list(h); hpsa_unregister_scsi(h); /* unhook from SCSI subsystem */ hpsa_shutdown(pdev); iounmap(h->vaddr); @@ -3724,7 +3577,6 @@ static void __devexit hpsa_remove_one(struct pci_dev *pdev) */ pci_release_regions(pdev); pci_set_drvdata(pdev, NULL); - mutex_unlock(&h->busy_shutting_down); kfree(h); } @@ -3878,23 +3730,12 @@ clean_up: */ static int __init hpsa_init(void) { - int err; - /* Start the scan thread */ - hpsa_scan_thread = kthread_run(hpsa_scan_func, NULL, "hpsa_scan"); - if (IS_ERR(hpsa_scan_thread)) { - err = PTR_ERR(hpsa_scan_thread); - return -ENODEV; - } - err = pci_register_driver(&hpsa_pci_driver); - if (err) - kthread_stop(hpsa_scan_thread); - return err; + return pci_register_driver(&hpsa_pci_driver); } static void __exit hpsa_cleanup(void) { pci_unregister_driver(&hpsa_pci_driver); - kthread_stop(hpsa_scan_thread); } module_init(hpsa_init); diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h index a0502b3..fc15215 100644 --- a/drivers/scsi/hpsa.h +++ b/drivers/scsi/hpsa.h @@ -97,9 +97,6 @@ struct ctlr_info { int scan_finished; spinlock_t scan_lock; wait_queue_head_t scan_wait_queue; - struct mutex busy_shutting_down; - struct list_head scan_list; - struct completion scan_wait; struct Scsi_Host *scsi_host; spinlock_t devlock; /* to protect hba[ctlr]->dev[]; */ -- cgit v0.10.2 From ff9fea94546afa2a496c15354533f06088347f6e Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Thu, 25 Feb 2010 14:03:17 -0600 Subject: [SCSI] hpsa: mark hpsa_pci_init as __devinit Signed-off-by: Stephen M. Cameron Signed-off-by: James Bottomley diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 3d43bb2..2e1edce 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -3174,7 +3174,7 @@ default_int_mode: h->intr[PERF_MODE_INT] = pdev->irq; } -static int hpsa_pci_init(struct ctlr_info *h, struct pci_dev *pdev) +static int __devinit hpsa_pci_init(struct ctlr_info *h, struct pci_dev *pdev) { ushort subsystem_vendor_id, subsystem_device_id, command; u32 board_id, scratchpad = 0; -- cgit v0.10.2 From db61bfcfe2a68dc71402c270686cd73b80971efc Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Thu, 25 Feb 2010 14:03:22 -0600 Subject: [SCSI] hpsa: Clarify calculation of padding for commandlist structure Signed-off-by: Stephen M. Cameron Signed-off-by: James Bottomley diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h index 3e0abdf..43b6f1c 100644 --- a/drivers/scsi/hpsa_cmd.h +++ b/drivers/scsi/hpsa_cmd.h @@ -313,12 +313,18 @@ struct CommandList { void *scsi_cmd; /* on 64 bit architectures, to get this to be 32-byte-aligned - * it so happens we need no padding, on 32 bit systems, - * we need 8 bytes of padding. This does that. + * it so happens we need PAD_64 bytes of padding, on 32 bit systems, + * we need PAD_32 bytes of padding (see below). This does that. + * If it happens that 64 bit and 32 bit systems need different + * padding, PAD_32 and PAD_64 can be set independently, and. + * the code below will do the right thing. */ -#define COMMANDLIST_PAD ((8 - sizeof(long))/4 * 8) +#define IS_32_BIT ((8 - sizeof(long))/4) +#define IS_64_BIT (!IS_32_BIT) +#define PAD_32 (8) +#define PAD_64 (0) +#define COMMANDLIST_PAD (IS_32_BIT * PAD_32 + IS_64_BIT * PAD_64) u8 pad[COMMANDLIST_PAD]; - }; /* Configuration Table Structure */ -- cgit v0.10.2 From 33a2ffce51d9598380d73c515a27fc6cff3bd9c4 Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Thu, 25 Feb 2010 14:03:27 -0600 Subject: [SCSI] hpsa: Increase the number of scatter gather elements supported. This uses the scatter-gather chaining feature of Smart Array controllers. 32 scatter-gather elements are embedded in the "command list", and the last element in the list may be marked as a "chain pointer", and point to an additional block of scatter gather elements. The precise number of scatter gather elements supported is dependent on the particular kind of Smart Array, and is determined at runtime by querying the hardware. Signed-off-by: Stephen M. Cameron Signed-off-by: James Bottomley diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 2e1edce..183d3a4 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -187,7 +187,6 @@ static struct scsi_host_template hpsa_driver_template = { .scan_finished = hpsa_scan_finished, .change_queue_depth = hpsa_change_queue_depth, .this_id = -1, - .sg_tablesize = MAXSGENTRIES, .use_clustering = ENABLE_CLUSTERING, .eh_device_reset_handler = hpsa_eh_device_reset_handler, .ioctl = hpsa_ioctl, @@ -844,6 +843,76 @@ static void hpsa_scsi_setup(struct ctlr_info *h) spin_lock_init(&h->devlock); } +static void hpsa_free_sg_chain_blocks(struct ctlr_info *h) +{ + int i; + + if (!h->cmd_sg_list) + return; + for (i = 0; i < h->nr_cmds; i++) { + kfree(h->cmd_sg_list[i]); + h->cmd_sg_list[i] = NULL; + } + kfree(h->cmd_sg_list); + h->cmd_sg_list = NULL; +} + +static int hpsa_allocate_sg_chain_blocks(struct ctlr_info *h) +{ + int i; + + if (h->chainsize <= 0) + return 0; + + h->cmd_sg_list = kzalloc(sizeof(*h->cmd_sg_list) * h->nr_cmds, + GFP_KERNEL); + if (!h->cmd_sg_list) + return -ENOMEM; + for (i = 0; i < h->nr_cmds; i++) { + h->cmd_sg_list[i] = kmalloc(sizeof(*h->cmd_sg_list[i]) * + h->chainsize, GFP_KERNEL); + if (!h->cmd_sg_list[i]) + goto clean; + } + return 0; + +clean: + hpsa_free_sg_chain_blocks(h); + return -ENOMEM; +} + +static void hpsa_map_sg_chain_block(struct ctlr_info *h, + struct CommandList *c) +{ + struct SGDescriptor *chain_sg, *chain_block; + u64 temp64; + + chain_sg = &c->SG[h->max_cmd_sg_entries - 1]; + chain_block = h->cmd_sg_list[c->cmdindex]; + chain_sg->Ext = HPSA_SG_CHAIN; + chain_sg->Len = sizeof(*chain_sg) * + (c->Header.SGTotal - h->max_cmd_sg_entries); + temp64 = pci_map_single(h->pdev, chain_block, chain_sg->Len, + PCI_DMA_TODEVICE); + chain_sg->Addr.lower = (u32) (temp64 & 0x0FFFFFFFFULL); + chain_sg->Addr.upper = (u32) ((temp64 >> 32) & 0x0FFFFFFFFULL); +} + +static void hpsa_unmap_sg_chain_block(struct ctlr_info *h, + struct CommandList *c) +{ + struct SGDescriptor *chain_sg; + union u64bit temp64; + + if (c->Header.SGTotal <= h->max_cmd_sg_entries) + return; + + chain_sg = &c->SG[h->max_cmd_sg_entries - 1]; + temp64.val32.lower = chain_sg->Addr.lower; + temp64.val32.upper = chain_sg->Addr.upper; + pci_unmap_single(h->pdev, temp64.val, chain_sg->Len, PCI_DMA_TODEVICE); +} + static void complete_scsi_command(struct CommandList *cp, int timeout, u32 tag) { @@ -860,6 +929,8 @@ static void complete_scsi_command(struct CommandList *cp, h = cp->h; scsi_dma_unmap(cmd); /* undo the DMA mappings */ + if (cp->Header.SGTotal > h->max_cmd_sg_entries) + hpsa_unmap_sg_chain_block(h, cp); cmd->result = (DID_OK << 16); /* host byte */ cmd->result |= (COMMAND_COMPLETE << 8); /* msg byte */ @@ -1064,6 +1135,7 @@ static int hpsa_scsi_detect(struct ctlr_info *h) sh->max_id = HPSA_MAX_LUN; sh->can_queue = h->nr_cmds; sh->cmd_per_lun = h->nr_cmds; + sh->sg_tablesize = h->maxsgentries; h->scsi_host = sh; sh->hostdata[0] = (unsigned long) h; sh->irq = h->intr[PERF_MODE_INT]; @@ -1765,16 +1837,17 @@ out: * dma mapping and fills in the scatter gather entries of the * hpsa command, cp. */ -static int hpsa_scatter_gather(struct pci_dev *pdev, +static int hpsa_scatter_gather(struct ctlr_info *h, struct CommandList *cp, struct scsi_cmnd *cmd) { unsigned int len; struct scatterlist *sg; u64 addr64; - int use_sg, i; + int use_sg, i, sg_index, chained; + struct SGDescriptor *curr_sg; - BUG_ON(scsi_sg_count(cmd) > MAXSGENTRIES); + BUG_ON(scsi_sg_count(cmd) > h->maxsgentries); use_sg = scsi_dma_map(cmd); if (use_sg < 0) @@ -1783,15 +1856,33 @@ static int hpsa_scatter_gather(struct pci_dev *pdev, if (!use_sg) goto sglist_finished; + curr_sg = cp->SG; + chained = 0; + sg_index = 0; scsi_for_each_sg(cmd, sg, use_sg, i) { + if (i == h->max_cmd_sg_entries - 1 && + use_sg > h->max_cmd_sg_entries) { + chained = 1; + curr_sg = h->cmd_sg_list[cp->cmdindex]; + sg_index = 0; + } addr64 = (u64) sg_dma_address(sg); len = sg_dma_len(sg); - cp->SG[i].Addr.lower = - (u32) (addr64 & (u64) 0x00000000FFFFFFFF); - cp->SG[i].Addr.upper = - (u32) ((addr64 >> 32) & (u64) 0x00000000FFFFFFFF); - cp->SG[i].Len = len; - cp->SG[i].Ext = 0; /* we are not chaining */ + curr_sg->Addr.lower = (u32) (addr64 & 0x0FFFFFFFFULL); + curr_sg->Addr.upper = (u32) ((addr64 >> 32) & 0x0FFFFFFFFULL); + curr_sg->Len = len; + curr_sg->Ext = 0; /* we are not chaining */ + curr_sg++; + } + + if (use_sg + chained > h->maxSG) + h->maxSG = use_sg + chained; + + if (chained) { + cp->Header.SGList = h->max_cmd_sg_entries; + cp->Header.SGTotal = (u16) (use_sg + 1); + hpsa_map_sg_chain_block(h, cp); + return 0; } sglist_finished: @@ -1887,7 +1978,7 @@ static int hpsa_scsi_queue_command(struct scsi_cmnd *cmd, break; } - if (hpsa_scatter_gather(h->pdev, c, cmd) < 0) { /* Fill SG list */ + if (hpsa_scatter_gather(h, c, cmd) < 0) { /* Fill SG list */ cmd_free(h, c); return SCSI_MLQUEUE_HOST_BUSY; } @@ -3283,6 +3374,23 @@ static int __devinit hpsa_pci_init(struct ctlr_info *h, struct pci_dev *pdev) h->board_id = board_id; h->max_commands = readl(&(h->cfgtable->MaxPerformantModeCommands)); + h->maxsgentries = readl(&(h->cfgtable->MaxScatterGatherElements)); + + /* + * Limit in-command s/g elements to 32 save dma'able memory. + * Howvever spec says if 0, use 31 + */ + + h->max_cmd_sg_entries = 31; + if (h->maxsgentries > 512) { + h->max_cmd_sg_entries = 32; + h->chainsize = h->maxsgentries - h->max_cmd_sg_entries + 1; + h->maxsgentries--; /* save one for chain pointer */ + } else { + h->maxsgentries = 31; /* default to traditional values */ + h->chainsize = 0; + } + h->product_name = products[prod_index].product_name; h->access = *(products[prod_index].access); /* Allow room for some ioctls */ @@ -3463,6 +3571,8 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev, rc = -ENOMEM; goto clean4; } + if (hpsa_allocate_sg_chain_blocks(h)) + goto clean4; spin_lock_init(&h->lock); spin_lock_init(&h->scan_lock); init_waitqueue_head(&h->scan_wait_queue); @@ -3485,6 +3595,7 @@ static int __devinit hpsa_init_one(struct pci_dev *pdev, return 1; clean4: + hpsa_free_sg_chain_blocks(h); kfree(h->cmd_pool_bits); if (h->cmd_pool) pci_free_consistent(h->pdev, @@ -3560,6 +3671,7 @@ static void __devexit hpsa_remove_one(struct pci_dev *pdev) hpsa_unregister_scsi(h); /* unhook from SCSI subsystem */ hpsa_shutdown(pdev); iounmap(h->vaddr); + hpsa_free_sg_chain_blocks(h); pci_free_consistent(h->pdev, h->nr_cmds * sizeof(struct CommandList), h->cmd_pool, h->cmd_pool_dhandle); diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h index fc15215..1bb5233 100644 --- a/drivers/scsi/hpsa.h +++ b/drivers/scsi/hpsa.h @@ -83,6 +83,10 @@ struct ctlr_info { unsigned int maxQsinceinit; unsigned int maxSG; spinlock_t lock; + int maxsgentries; + u8 max_cmd_sg_entries; + int chainsize; + struct SGDescriptor **cmd_sg_list; /* pointers to command and error info pool */ struct CommandList *cmd_pool; diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h index 43b6f1c..cb0c238 100644 --- a/drivers/scsi/hpsa_cmd.h +++ b/drivers/scsi/hpsa_cmd.h @@ -23,7 +23,8 @@ /* general boundary defintions */ #define SENSEINFOBYTES 32 /* may vary between hbas */ -#define MAXSGENTRIES 31 +#define MAXSGENTRIES 32 +#define HPSA_SG_CHAIN 0x80000000 #define MAXREPLYQS 256 /* Command Status value */ @@ -321,8 +322,8 @@ struct CommandList { */ #define IS_32_BIT ((8 - sizeof(long))/4) #define IS_64_BIT (!IS_32_BIT) -#define PAD_32 (8) -#define PAD_64 (0) +#define PAD_32 (24) +#define PAD_64 (16) #define COMMANDLIST_PAD (IS_32_BIT * PAD_32 + IS_64_BIT * PAD_64) u8 pad[COMMANDLIST_PAD]; }; -- cgit v0.10.2 From 43aebfa12e7631124472237dc945c27af54ca646 Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Thu, 25 Feb 2010 14:03:32 -0600 Subject: [SCSI] hpsa: remove unused members next, prev, and retry_count from command list structure. Signed-off-by: Stephen M. Cameron Signed-off-by: James Bottomley diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h index cb0c238..56fb982 100644 --- a/drivers/scsi/hpsa_cmd.h +++ b/drivers/scsi/hpsa_cmd.h @@ -306,11 +306,8 @@ struct CommandList { int cmd_type; long cmdindex; struct hlist_node list; - struct CommandList *prev; - struct CommandList *next; struct request *rq; struct completion *waiting; - int retry_count; void *scsi_cmd; /* on 64 bit architectures, to get this to be 32-byte-aligned @@ -322,8 +319,8 @@ struct CommandList { */ #define IS_32_BIT ((8 - sizeof(long))/4) #define IS_64_BIT (!IS_32_BIT) -#define PAD_32 (24) -#define PAD_64 (16) +#define PAD_32 (4) +#define PAD_64 (4) #define COMMANDLIST_PAD (IS_32_BIT * PAD_32 + IS_64_BIT * PAD_64) u8 pad[COMMANDLIST_PAD]; }; -- cgit v0.10.2 From 9f1177a3f8eee22427eb97e6e00b62ff0be2871f Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 26 Feb 2010 14:12:57 -0500 Subject: [SCSI] lpfc 8.3.10: Fix Initialization issues - Add NULL checks to the pointers for the config_async mailbox and dump_wakeup_params mailbox. - Add code to check return value of lpfc_read_sparams everywhere and handle failures appropriately. Signed-off-by: James Smart Signed-off-by: James Bottomley diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 2359d0b..e58d8ae 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -2024,8 +2024,6 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) int rc; struct fcf_record *fcf_record; - sparam_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); - spin_lock_irq(&phba->hbalock); switch (la->UlnkSpeed) { case LA_1GHZ_LINK: @@ -2117,18 +2115,24 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) spin_unlock_irq(&phba->hbalock); lpfc_linkup(phba); - if (sparam_mbox) { - lpfc_read_sparam(phba, sparam_mbox, 0); - sparam_mbox->vport = vport; - sparam_mbox->mbox_cmpl = lpfc_mbx_cmpl_read_sparam; - rc = lpfc_sli_issue_mbox(phba, sparam_mbox, MBX_NOWAIT); - if (rc == MBX_NOT_FINISHED) { - mp = (struct lpfc_dmabuf *) sparam_mbox->context1; - lpfc_mbuf_free(phba, mp->virt, mp->phys); - kfree(mp); - mempool_free(sparam_mbox, phba->mbox_mem_pool); - goto out; - } + sparam_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); + if (!sparam_mbox) + goto out; + + rc = lpfc_read_sparam(phba, sparam_mbox, 0); + if (rc) { + mempool_free(sparam_mbox, phba->mbox_mem_pool); + goto out; + } + sparam_mbox->vport = vport; + sparam_mbox->mbox_cmpl = lpfc_mbx_cmpl_read_sparam; + rc = lpfc_sli_issue_mbox(phba, sparam_mbox, MBX_NOWAIT); + if (rc == MBX_NOT_FINISHED) { + mp = (struct lpfc_dmabuf *) sparam_mbox->context1; + lpfc_mbuf_free(phba, mp->virt, mp->phys); + kfree(mp); + mempool_free(sparam_mbox, phba->mbox_mem_pool); + goto out; } if (!(phba->hba_flag & HBA_FCOE_SUPPORT)) { diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index d29ac7c..b64ceca 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -350,7 +350,12 @@ lpfc_config_port_post(struct lpfc_hba *phba) mb = &pmb->u.mb; /* Get login parameters for NID. */ - lpfc_read_sparam(phba, pmb, 0); + rc = lpfc_read_sparam(phba, pmb, 0); + if (rc) { + mempool_free(pmb, phba->mbox_mem_pool); + return -ENOMEM; + } + pmb->vport = vport; if (lpfc_sli_issue_mbox(phba, pmb, MBX_POLL) != MBX_SUCCESS) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, @@ -359,7 +364,7 @@ lpfc_config_port_post(struct lpfc_hba *phba) mb->mbxCommand, mb->mbxStatus); phba->link_state = LPFC_HBA_ERROR; mp = (struct lpfc_dmabuf *) pmb->context1; - mempool_free( pmb, phba->mbox_mem_pool); + mempool_free(pmb, phba->mbox_mem_pool); lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); return -EIO; @@ -571,6 +576,11 @@ lpfc_config_port_post(struct lpfc_hba *phba) } /* MBOX buffer will be freed in mbox compl */ pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); + if (!pmb) { + phba->link_state = LPFC_HBA_ERROR; + return -ENOMEM; + } + lpfc_config_async(phba, pmb, LPFC_ELS_RING); pmb->mbox_cmpl = lpfc_config_async_cmpl; pmb->vport = phba->pport; @@ -588,6 +598,11 @@ lpfc_config_port_post(struct lpfc_hba *phba) /* Get Option rom version */ pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); + if (!pmb) { + phba->link_state = LPFC_HBA_ERROR; + return -ENOMEM; + } + lpfc_dump_wakeup_param(phba, pmb); pmb->mbox_cmpl = lpfc_dump_wakeup_param_cmpl; pmb->vport = phba->pport; diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 35e3b96..d51ee7e 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -4388,7 +4388,13 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) spin_unlock_irq(&phba->hbalock); /* Read the port's service parameters. */ - lpfc_read_sparam(phba, mboxq, vport->vpi); + rc = lpfc_read_sparam(phba, mboxq, vport->vpi); + if (rc) { + phba->link_state = LPFC_HBA_ERROR; + rc = -ENOMEM; + goto out_free_vpd; + } + mboxq->vport = vport; rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); mp = (struct lpfc_dmabuf *) mboxq->context1; diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c index dc86e87..869f76c 100644 --- a/drivers/scsi/lpfc/lpfc_vport.c +++ b/drivers/scsi/lpfc/lpfc_vport.c @@ -123,7 +123,12 @@ lpfc_vport_sparm(struct lpfc_hba *phba, struct lpfc_vport *vport) } mb = &pmb->u.mb; - lpfc_read_sparam(phba, pmb, vport->vpi); + rc = lpfc_read_sparam(phba, pmb, vport->vpi); + if (rc) { + mempool_free(pmb, phba->mbox_mem_pool); + return -ENOMEM; + } + /* * Grab buffer pointer and clear context1 so we can use * lpfc_sli_issue_box_wait -- cgit v0.10.2 From e40a02c12581f710877da372b5d7e15b68a1c5c3 Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 26 Feb 2010 14:13:54 -0500 Subject: [SCSI] lpfc 8.3.10: Fix user interface issues - Add Logging message for critial errors. - Remove unused variable from lpfc_nodev_tmo_show - Update supress_link_up parameter with #define values. Signed-off-by: James Smart Signed-off-by: James Bottomley diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 84b6964..ce0599d 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -623,6 +623,9 @@ struct lpfc_hba { uint32_t cfg_log_verbose; uint32_t cfg_aer_support; uint32_t cfg_suppress_link_up; +#define LPFC_INITIALIZE_LINK 0 /* do normal init_link mbox */ +#define LPFC_DELAY_INIT_LINK 1 /* layered driver hold off */ +#define LPFC_DELAY_INIT_LINK_INDEFINITELY 2 /* wait, manual intervention */ lpfc_vpd_t vpd; /* vital product data */ diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index c992e83..64cd17e 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -1939,7 +1939,9 @@ static DEVICE_ATTR(lpfc_enable_npiv, S_IRUGO, # 0x2 = never bring up link # Default value is 0. */ -LPFC_ATTR_R(suppress_link_up, 0, 0, 2, "Suppress Link Up at initialization"); +LPFC_ATTR_R(suppress_link_up, LPFC_INITIALIZE_LINK, LPFC_INITIALIZE_LINK, + LPFC_DELAY_INIT_LINK_INDEFINITELY, + "Suppress Link Up at initialization"); /* # lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear @@ -1966,8 +1968,7 @@ lpfc_nodev_tmo_show(struct device *dev, struct device_attribute *attr, { struct Scsi_Host *shost = class_to_shost(dev); struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; - int val = 0; - val = vport->cfg_devloss_tmo; + return snprintf(buf, PAGE_SIZE, "%d\n", vport->cfg_devloss_tmo); } diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 08b6634..4623323 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -806,9 +806,8 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, } /* FLOGI failure */ - lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, - "0100 FLOGI failure Data: x%x x%x " - "x%x\n", + lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, + "0100 FLOGI failure Status:x%x/x%x TMO:x%x\n", irsp->ulpStatus, irsp->un.ulpWord[4], irsp->ulpTimeout); goto flogifail; @@ -1409,6 +1408,10 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, goto out; } /* PLOGI failed */ + lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, + "2753 PLOGI failure DID:%06X Status:x%x/x%x\n", + ndlp->nlp_DID, irsp->ulpStatus, + irsp->un.ulpWord[4]); /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ if (lpfc_error_lost_link(irsp)) rc = NLP_STE_FREED_NODE; @@ -1577,6 +1580,10 @@ lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, goto out; } /* PRLI failed */ + lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, + "2754 PRLI failure DID:%06X Status:x%x/x%x\n", + ndlp->nlp_DID, irsp->ulpStatus, + irsp->un.ulpWord[4]); /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ if (lpfc_error_lost_link(irsp)) goto out; @@ -1860,6 +1867,10 @@ lpfc_cmpl_els_adisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, goto out; } /* ADISC failed */ + lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, + "2755 ADISC failure DID:%06X Status:x%x/x%x\n", + ndlp->nlp_DID, irsp->ulpStatus, + irsp->un.ulpWord[4]); /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ if (!lpfc_error_lost_link(irsp)) lpfc_disc_state_machine(vport, ndlp, cmdiocb, @@ -2009,6 +2020,10 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, /* ELS command is being retried */ goto out; /* LOGO failed */ + lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, + "2756 LOGO failure DID:%06X Status:x%x/x%x\n", + ndlp->nlp_DID, irsp->ulpStatus, + irsp->un.ulpWord[4]); /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ if (lpfc_error_lost_link(irsp)) goto out; diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index b64ceca..437ddc9 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -549,7 +549,7 @@ lpfc_config_port_post(struct lpfc_hba *phba) mempool_free(pmb, phba->mbox_mem_pool); return -EIO; } - } else if (phba->cfg_suppress_link_up == 0) { + } else if (phba->cfg_suppress_link_up == LPFC_INITIALIZE_LINK) { lpfc_init_link(phba, pmb, phba->cfg_topology, phba->cfg_link_speed); pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; @@ -667,7 +667,7 @@ lpfc_hba_init_link(struct lpfc_hba *phba) mempool_free(pmb, phba->mbox_mem_pool); return -EIO; } - phba->cfg_suppress_link_up = 0; + phba->cfg_suppress_link_up = LPFC_INITIALIZE_LINK; return 0; } diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 7f21b47..889a7b9 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -2079,8 +2079,7 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, if (resp_info & RSP_LEN_VALID) { rsplen = be32_to_cpu(fcprsp->rspRspLen); - if ((rsplen != 0 && rsplen != 4 && rsplen != 8) || - (fcprsp->rspInfo3 != RSP_NO_FAILURE)) { + if (rsplen != 0 && rsplen != 4 && rsplen != 8) { lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, "2719 Invalid response length: " "tgt x%x lun x%x cmnd x%x rsplen x%x\n", @@ -2090,6 +2089,17 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, host_status = DID_ERROR; goto out; } + if (fcprsp->rspInfo3 != RSP_NO_FAILURE) { + lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, + "2757 Protocol failure detected during " + "processing of FCP I/O op: " + "tgt x%x lun x%x cmnd x%x rspInfo3 x%x\n", + cmnd->device->id, + cmnd->device->lun, cmnd->cmnd[0], + fcprsp->rspInfo3); + host_status = DID_ERROR; + goto out; + } } if ((resp_info & SNS_LEN_VALID) && fcprsp->rspSnsLen) { diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index d51ee7e..49bed3e 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -3091,6 +3091,12 @@ lpfc_sli_brdready_s3(struct lpfc_hba *phba, uint32_t mask) /* Check to see if any errors occurred during init */ if ((status & HS_FFERM) || (i >= 20)) { + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, + "2751 Adapter failed to restart, " + "status reg x%x, FW Data: A8 x%x AC x%x\n", + status, + readl(phba->MBslimaddr + 0xa8), + readl(phba->MBslimaddr + 0xac)); phba->link_state = LPFC_HBA_ERROR; retval = 1; } @@ -3278,6 +3284,9 @@ lpfc_sli_brdkill(struct lpfc_hba *phba) if (retval != MBX_SUCCESS) { if (retval != MBX_BUSY) mempool_free(pmb, phba->mbox_mem_pool); + lpfc_printf_log(phba, KERN_ERR, LOG_SLI, + "2752 KILL_BOARD command failed retval %d\n", + retval); spin_lock_irq(&phba->hbalock); phba->link_flag &= ~LS_IGNORE_ERATT; spin_unlock_irq(&phba->hbalock); @@ -4035,7 +4044,7 @@ lpfc_sli_hba_setup(struct lpfc_hba *phba) lpfc_sli_hba_setup_error: phba->link_state = LPFC_HBA_ERROR; - lpfc_printf_log(phba, KERN_INFO, LOG_INIT, + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "0445 Firmware initialization failed\n"); return rc; } -- cgit v0.10.2 From 0f65ff680f90281d49ee864965f06774eba9657d Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 26 Feb 2010 14:14:23 -0500 Subject: [SCSI] lpfc 8.3.10: Update SLI interface areas - Clear LPFC_DRIVER_ABORTED on FCP command completion. - Clear exchange busy flag when I/O is aborted and found on aborted list. - Free sglq when XRI_ABORTED event is processed before release of IOCB. - Only process iocb as aborted when LPFC_DRIVER_ABORTED is set. Signed-off-by: James Smart Signed-off-by: James Bottomley diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index ce0599d..4d45e69 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -509,7 +509,6 @@ struct lpfc_hba { int (*lpfc_hba_down_link) (struct lpfc_hba *); - /* SLI4 specific HBA data structure */ struct lpfc_sli4_hba sli4_hba; diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index 6f0fb51..e7f5482 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -385,7 +385,7 @@ void lpfc_parse_fcoe_conf(struct lpfc_hba *, uint8_t *, uint32_t); int lpfc_parse_vpd(struct lpfc_hba *, uint8_t *, int); void lpfc_start_fdiscs(struct lpfc_hba *phba); struct lpfc_vport *lpfc_find_vport_by_vpid(struct lpfc_hba *, uint16_t); - +struct lpfc_sglq *__lpfc_get_active_sglq(struct lpfc_hba *, uint16_t); #define ScsiResult(host_code, scsi_code) (((host_code) << 16) | scsi_code) #define HBA_EVENT_RSCN 5 #define HBA_EVENT_LINK_UP 2 diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 4623323..6a2135a 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -6234,7 +6234,8 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, lpfc_mbx_unreg_vpi(vport); spin_lock_irq(shost->host_lock); vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; - vport->fc_flag |= FC_VPORT_NEEDS_INIT_VPI; + if (phba->sli_rev == LPFC_SLI_REV4) + vport->fc_flag |= FC_VPORT_NEEDS_INIT_VPI; spin_unlock_irq(shost->host_lock); } @@ -6812,21 +6813,27 @@ lpfc_sli4_els_xri_aborted(struct lpfc_hba *phba, struct lpfc_sglq *sglq_entry = NULL, *sglq_next = NULL; unsigned long iflag = 0; - spin_lock_irqsave(&phba->sli4_hba.abts_sgl_list_lock, iflag); + spin_lock_irqsave(&phba->hbalock, iflag); + spin_lock(&phba->sli4_hba.abts_sgl_list_lock); list_for_each_entry_safe(sglq_entry, sglq_next, &phba->sli4_hba.lpfc_abts_els_sgl_list, list) { if (sglq_entry->sli4_xritag == xri) { list_del(&sglq_entry->list); - spin_unlock_irqrestore( - &phba->sli4_hba.abts_sgl_list_lock, - iflag); - spin_lock_irqsave(&phba->hbalock, iflag); - list_add_tail(&sglq_entry->list, &phba->sli4_hba.lpfc_sgl_list); + sglq_entry->state = SGL_FREED; + spin_unlock(&phba->sli4_hba.abts_sgl_list_lock); spin_unlock_irqrestore(&phba->hbalock, iflag); return; } } - spin_unlock_irqrestore(&phba->sli4_hba.abts_sgl_list_lock, iflag); + spin_unlock(&phba->sli4_hba.abts_sgl_list_lock); + sglq_entry = __lpfc_get_active_sglq(phba, xri); + if (!sglq_entry || (sglq_entry->sli4_xritag != xri)) { + spin_unlock_irqrestore(&phba->hbalock, iflag); + return; + } + sglq_entry->state = SGL_XRI_ABORTED; + spin_unlock_irqrestore(&phba->hbalock, iflag); + return; } diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 437ddc9..b7889c5 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -822,6 +822,8 @@ lpfc_hba_down_post_s4(struct lpfc_hba *phba) LIST_HEAD(aborts); int ret; unsigned long iflag = 0; + struct lpfc_sglq *sglq_entry = NULL; + ret = lpfc_hba_down_post_s3(phba); if (ret) return ret; @@ -837,6 +839,10 @@ lpfc_hba_down_post_s4(struct lpfc_hba *phba) * list. */ spin_lock(&phba->sli4_hba.abts_sgl_list_lock); + list_for_each_entry(sglq_entry, + &phba->sli4_hba.lpfc_abts_els_sgl_list, list) + sglq_entry->state = SGL_FREED; + list_splice_init(&phba->sli4_hba.lpfc_abts_els_sgl_list, &phba->sli4_hba.lpfc_sgl_list); spin_unlock(&phba->sli4_hba.abts_sgl_list_lock); @@ -4412,6 +4418,7 @@ lpfc_init_sgl_list(struct lpfc_hba *phba) /* The list order is used by later block SGL registraton */ spin_lock_irq(&phba->hbalock); + sglq_entry->state = SGL_FREED; list_add_tail(&sglq_entry->list, &phba->sli4_hba.lpfc_sgl_list); phba->sli4_hba.lpfc_els_sgl_array[i] = sglq_entry; phba->sli4_hba.total_sglq_bufs++; diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 889a7b9..a4881f2 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -620,23 +620,40 @@ lpfc_sli4_fcp_xri_aborted(struct lpfc_hba *phba, uint16_t xri = bf_get(lpfc_wcqe_xa_xri, axri); struct lpfc_scsi_buf *psb, *next_psb; unsigned long iflag = 0; + struct lpfc_iocbq *iocbq; + int i; - spin_lock_irqsave(&phba->sli4_hba.abts_scsi_buf_list_lock, iflag); + spin_lock_irqsave(&phba->hbalock, iflag); + spin_lock(&phba->sli4_hba.abts_scsi_buf_list_lock); list_for_each_entry_safe(psb, next_psb, &phba->sli4_hba.lpfc_abts_scsi_buf_list, list) { if (psb->cur_iocbq.sli4_xritag == xri) { list_del(&psb->list); psb->exch_busy = 0; psb->status = IOSTAT_SUCCESS; - spin_unlock_irqrestore( - &phba->sli4_hba.abts_scsi_buf_list_lock, - iflag); + spin_unlock( + &phba->sli4_hba.abts_scsi_buf_list_lock); + spin_unlock_irqrestore(&phba->hbalock, iflag); lpfc_release_scsi_buf_s4(phba, psb); return; } } - spin_unlock_irqrestore(&phba->sli4_hba.abts_scsi_buf_list_lock, - iflag); + spin_unlock(&phba->sli4_hba.abts_scsi_buf_list_lock); + for (i = 1; i <= phba->sli.last_iotag; i++) { + iocbq = phba->sli.iocbq_lookup[i]; + + if (!(iocbq->iocb_flag & LPFC_IO_FCP) || + (iocbq->iocb_flag & LPFC_IO_LIBDFC)) + continue; + if (iocbq->sli4_xritag != xri) + continue; + psb = container_of(iocbq, struct lpfc_scsi_buf, cur_iocbq); + psb->exch_busy = 0; + spin_unlock_irqrestore(&phba->hbalock, iflag); + return; + + } + spin_unlock_irqrestore(&phba->hbalock, iflag); } /** @@ -1006,6 +1023,7 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) struct scatterlist *sgel = NULL; struct fcp_cmnd *fcp_cmnd = lpfc_cmd->fcp_cmnd; struct ulp_bde64 *bpl = lpfc_cmd->fcp_bpl; + struct lpfc_iocbq *iocbq = &lpfc_cmd->cur_iocbq; IOCB_t *iocb_cmd = &lpfc_cmd->cur_iocbq.iocb; struct ulp_bde64 *data_bde = iocb_cmd->unsli3.fcp_ext.dbde; dma_addr_t physaddr; @@ -1056,6 +1074,7 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) physaddr = sg_dma_address(sgel); if (phba->sli_rev == 3 && !(phba->sli3_options & LPFC_SLI3_BG_ENABLED) && + !(iocbq->iocb_flag & DSS_SECURITY_OP) && nseg <= LPFC_EXT_DATA_BDE_COUNT) { data_bde->tus.f.bdeFlags = BUFF_TYPE_BDE_64; data_bde->tus.f.bdeSize = sg_dma_len(sgel); @@ -1082,7 +1101,8 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) * explicitly reinitialized since all iocb memory resources are reused. */ if (phba->sli_rev == 3 && - !(phba->sli3_options & LPFC_SLI3_BG_ENABLED)) { + !(phba->sli3_options & LPFC_SLI3_BG_ENABLED) && + !(iocbq->iocb_flag & DSS_SECURITY_OP)) { if (num_bde > LPFC_EXT_DATA_BDE_COUNT) { /* * The extended IOCB format can only fit 3 BDE or a BPL. @@ -1107,6 +1127,7 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) } else { iocb_cmd->un.fcpi64.bdl.bdeSize = ((num_bde + 2) * sizeof(struct ulp_bde64)); + iocb_cmd->unsli3.fcp_ext.ebde_count = (num_bde + 1); } fcp_cmnd->fcpDl = cpu_to_be32(scsi_bufflen(scsi_cmnd)); diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 49bed3e..9feeaff 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -494,7 +494,7 @@ __lpfc_clear_active_sglq(struct lpfc_hba *phba, uint16_t xritag) * * Returns sglq ponter = success, NULL = Failure. **/ -static struct lpfc_sglq * +struct lpfc_sglq * __lpfc_get_active_sglq(struct lpfc_hba *phba, uint16_t xritag) { uint16_t adj_xri; @@ -526,6 +526,7 @@ __lpfc_sli_get_sglq(struct lpfc_hba *phba) return NULL; adj_xri = sglq->sli4_xritag - phba->sli4_hba.max_cfg_param.xri_base; phba->sli4_hba.lpfc_sglq_active_list[adj_xri] = sglq; + sglq->state = SGL_ALLOCATED; return sglq; } @@ -580,15 +581,18 @@ __lpfc_sli_release_iocbq_s4(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq) else sglq = __lpfc_clear_active_sglq(phba, iocbq->sli4_xritag); if (sglq) { - if (iocbq->iocb_flag & LPFC_EXCHANGE_BUSY) { + if ((iocbq->iocb_flag & LPFC_EXCHANGE_BUSY) && + (sglq->state != SGL_XRI_ABORTED)) { spin_lock_irqsave(&phba->sli4_hba.abts_sgl_list_lock, iflag); list_add(&sglq->list, &phba->sli4_hba.lpfc_abts_els_sgl_list); spin_unlock_irqrestore( &phba->sli4_hba.abts_sgl_list_lock, iflag); - } else + } else { + sglq->state = SGL_FREED; list_add(&sglq->list, &phba->sli4_hba.lpfc_sgl_list); + } } @@ -2258,41 +2262,56 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, spin_unlock_irqrestore(&phba->hbalock, iflag); } - if ((phba->sli_rev == LPFC_SLI_REV4) && - (saveq->iocb_flag & LPFC_EXCHANGE_BUSY)) { - /* Set cmdiocb flag for the exchange - * busy so sgl (xri) will not be - * released until the abort xri is - * received from hba, clear the - * LPFC_DRIVER_ABORTED bit in case - * it was driver initiated abort. - */ - spin_lock_irqsave(&phba->hbalock, - iflag); - cmdiocbp->iocb_flag &= - ~LPFC_DRIVER_ABORTED; - cmdiocbp->iocb_flag |= - LPFC_EXCHANGE_BUSY; - spin_unlock_irqrestore(&phba->hbalock, - iflag); - cmdiocbp->iocb.ulpStatus = - IOSTAT_LOCAL_REJECT; - cmdiocbp->iocb.un.ulpWord[4] = - IOERR_ABORT_REQUESTED; - /* - * For SLI4, irsiocb contains NO_XRI - * in sli_xritag, it shall not affect - * releasing sgl (xri) process. - */ - saveq->iocb.ulpStatus = - IOSTAT_LOCAL_REJECT; - saveq->iocb.un.ulpWord[4] = - IOERR_SLI_ABORTED; - spin_lock_irqsave(&phba->hbalock, - iflag); - saveq->iocb_flag |= LPFC_DELAY_MEM_FREE; - spin_unlock_irqrestore(&phba->hbalock, - iflag); + if (phba->sli_rev == LPFC_SLI_REV4) { + if (saveq->iocb_flag & + LPFC_EXCHANGE_BUSY) { + /* Set cmdiocb flag for the + * exchange busy so sgl (xri) + * will not be released until + * the abort xri is received + * from hba. + */ + spin_lock_irqsave( + &phba->hbalock, iflag); + cmdiocbp->iocb_flag |= + LPFC_EXCHANGE_BUSY; + spin_unlock_irqrestore( + &phba->hbalock, iflag); + } + if (cmdiocbp->iocb_flag & + LPFC_DRIVER_ABORTED) { + /* + * Clear LPFC_DRIVER_ABORTED + * bit in case it was driver + * initiated abort. + */ + spin_lock_irqsave( + &phba->hbalock, iflag); + cmdiocbp->iocb_flag &= + ~LPFC_DRIVER_ABORTED; + spin_unlock_irqrestore( + &phba->hbalock, iflag); + cmdiocbp->iocb.ulpStatus = + IOSTAT_LOCAL_REJECT; + cmdiocbp->iocb.un.ulpWord[4] = + IOERR_ABORT_REQUESTED; + /* + * For SLI4, irsiocb contains + * NO_XRI in sli_xritag, it + * shall not affect releasing + * sgl (xri) process. + */ + saveq->iocb.ulpStatus = + IOSTAT_LOCAL_REJECT; + saveq->iocb.un.ulpWord[4] = + IOERR_SLI_ABORTED; + spin_lock_irqsave( + &phba->hbalock, iflag); + saveq->iocb_flag |= + LPFC_DELAY_MEM_FREE; + spin_unlock_irqrestore( + &phba->hbalock, iflag); + } } } (cmdiocbp->iocb_cmpl) (phba, cmdiocbp, saveq); @@ -2515,14 +2534,16 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba *phba, cmdiocbq = lpfc_sli_iocbq_lookup(phba, pring, &rspiocbq); - if ((cmdiocbq) && (cmdiocbq->iocb_cmpl)) { - spin_unlock_irqrestore(&phba->hbalock, - iflag); - (cmdiocbq->iocb_cmpl)(phba, cmdiocbq, - &rspiocbq); - spin_lock_irqsave(&phba->hbalock, - iflag); - } + if (unlikely(!cmdiocbq)) + break; + if (cmdiocbq->iocb_flag & LPFC_DRIVER_ABORTED) + cmdiocbq->iocb_flag &= ~LPFC_DRIVER_ABORTED; + if (cmdiocbq->iocb_cmpl) { + spin_unlock_irqrestore(&phba->hbalock, iflag); + (cmdiocbq->iocb_cmpl)(phba, cmdiocbq, + &rspiocbq); + spin_lock_irqsave(&phba->hbalock, iflag); + } break; case LPFC_UNSOL_IOCB: spin_unlock_irqrestore(&phba->hbalock, iflag); @@ -7451,6 +7472,7 @@ lpfc_sli_wake_iocb_wait(struct lpfc_hba *phba, { wait_queue_head_t *pdone_q; unsigned long iflags; + struct lpfc_scsi_buf *lpfc_cmd; spin_lock_irqsave(&phba->hbalock, iflags); cmdiocbq->iocb_flag |= LPFC_IO_WAKE; @@ -7458,6 +7480,14 @@ lpfc_sli_wake_iocb_wait(struct lpfc_hba *phba, memcpy(&((struct lpfc_iocbq *)cmdiocbq->context2)->iocb, &rspiocbq->iocb, sizeof(IOCB_t)); + /* Set the exchange busy flag for task management commands */ + if ((cmdiocbq->iocb_flag & LPFC_IO_FCP) && + !(cmdiocbq->iocb_flag & LPFC_IO_LIBDFC)) { + lpfc_cmd = container_of(cmdiocbq, struct lpfc_scsi_buf, + cur_iocbq); + lpfc_cmd->exch_busy = rspiocbq->iocb_flag & LPFC_EXCHANGE_BUSY; + } + pdone_q = cmdiocbq->context_un.wait_queue; if (pdone_q) wake_up(pdone_q); @@ -9076,6 +9106,12 @@ lpfc_sli4_fp_handle_fcp_wcqe(struct lpfc_hba *phba, /* Fake the irspiocb and copy necessary response information */ lpfc_sli4_iocb_param_transfer(phba, &irspiocbq, cmdiocbq, wcqe); + if (cmdiocbq->iocb_flag & LPFC_DRIVER_ABORTED) { + spin_lock_irqsave(&phba->hbalock, iflags); + cmdiocbq->iocb_flag &= ~LPFC_DRIVER_ABORTED; + spin_unlock_irqrestore(&phba->hbalock, iflags); + } + /* Pass the cmd_iocb and the rsp state to the upper layer */ (cmdiocbq->iocb_cmpl)(phba, cmdiocbq, &irspiocbq); } diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h index dfcf543..b4a639c 100644 --- a/drivers/scsi/lpfc/lpfc_sli.h +++ b/drivers/scsi/lpfc/lpfc_sli.h @@ -62,6 +62,7 @@ struct lpfc_iocbq { #define LPFC_DELAY_MEM_FREE 0x20 /* Defer free'ing of FC data */ #define LPFC_EXCHANGE_BUSY 0x40 /* SLI4 hba reported XB in response */ #define LPFC_USE_FCPWQIDX 0x80 /* Submit to specified FCPWQ index */ +#define DSS_SECURITY_OP 0x100 /* security IO */ #define LPFC_FIP_ELS_ID_MASK 0xc000 /* ELS_ID range 0-3, non-shifted mask */ #define LPFC_FIP_ELS_ID_SHIFT 14 diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index 86308836..04fd782 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h @@ -431,11 +431,18 @@ enum lpfc_sge_type { SCSI_BUFF_TYPE }; +enum lpfc_sgl_state { + SGL_FREED, + SGL_ALLOCATED, + SGL_XRI_ABORTED +}; + struct lpfc_sglq { /* lpfc_sglqs are used in double linked lists */ struct list_head list; struct list_head clist; enum lpfc_sge_type buff_type; /* is this a scsi sgl */ + enum lpfc_sgl_state state; uint16_t iotag; /* pre-assigned IO tag */ uint16_t sli4_xritag; /* pre-assigned XRI, (OXID) tag. */ struct sli4_sge *sgl; /* pre-assigned SGL */ -- cgit v0.10.2 From e2aed29f29d0d289df3b0b627b122832d4dc80fe Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 26 Feb 2010 14:15:00 -0500 Subject: [SCSI] lpfc 8.3.10: Added management for LP21000 through BSG. Signed-off-by: James Smart Signed-off-by: James Bottomley diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 4d45e69..565e16d 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -37,6 +37,9 @@ struct lpfc_sli2_slim; the NameServer before giving up. */ #define LPFC_CMD_PER_LUN 3 /* max outstanding cmds per lun */ #define LPFC_DEFAULT_SG_SEG_CNT 64 /* sg element count per scsi cmnd */ +#define LPFC_DEFAULT_MENLO_SG_SEG_CNT 128 /* sg element count per scsi + cmnd for menlo needs nearly twice as for firmware + downloads using bsg */ #define LPFC_DEFAULT_PROT_SG_SEG_CNT 4096 /* sg protection elements count */ #define LPFC_MAX_SG_SEG_CNT 4096 /* sg element count per scsi cmnd */ #define LPFC_MAX_PROT_SG_SEG_CNT 4096 /* prot sg element count per scsi cmd*/ @@ -806,6 +809,9 @@ struct lpfc_hba { struct list_head ct_ev_waiters; struct unsol_rcv_ct_ctx ct_ctx[64]; uint32_t ctx_idx; + + uint8_t menlo_flag; /* menlo generic flags */ +#define HBA_MENLO_SUPPORT 0x1 /* HBA supports menlo commands */ }; static inline struct Scsi_Host * diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c index f3f1bf1..692c29f 100644 --- a/drivers/scsi/lpfc/lpfc_bsg.c +++ b/drivers/scsi/lpfc/lpfc_bsg.c @@ -83,15 +83,28 @@ struct lpfc_bsg_mbox { struct fc_bsg_job *set_job; }; +#define MENLO_DID 0x0000FC0E + +struct lpfc_bsg_menlo { + struct lpfc_iocbq *cmdiocbq; + struct lpfc_iocbq *rspiocbq; + struct lpfc_dmabuf *bmp; + + /* job waiting for this iocb to finish */ + struct fc_bsg_job *set_job; +}; + #define TYPE_EVT 1 #define TYPE_IOCB 2 #define TYPE_MBOX 3 +#define TYPE_MENLO 4 struct bsg_job_data { uint32_t type; union { struct lpfc_bsg_event *evt; struct lpfc_bsg_iocb iocb; struct lpfc_bsg_mbox mbox; + struct lpfc_bsg_menlo menlo; } context_un; }; @@ -2456,6 +2469,18 @@ static int lpfc_bsg_check_cmd_access(struct lpfc_hba *phba, case MBX_PORT_IOV_CONTROL: break; case MBX_SET_VARIABLE: + lpfc_printf_log(phba, KERN_INFO, LOG_INIT, + "1226 mbox: set_variable 0x%x, 0x%x\n", + mb->un.varWords[0], + mb->un.varWords[1]); + if ((mb->un.varWords[0] == SETVAR_MLOMNT) + && (mb->un.varWords[1] == 1)) { + phba->wait_4_mlo_maint_flg = 1; + } else if (mb->un.varWords[0] == SETVAR_MLORST) { + phba->link_flag &= ~LS_LOOPBACK_MODE; + phba->fc_topology = TOPOLOGY_PT_PT; + } + break; case MBX_RUN_BIU_DIAG64: case MBX_READ_EVENT_LOG: case MBX_READ_SPARM64: @@ -2638,6 +2663,297 @@ job_error: } /** + * lpfc_bsg_menlo_cmd_cmp - lpfc_menlo_cmd completion handler + * @phba: Pointer to HBA context object. + * @cmdiocbq: Pointer to command iocb. + * @rspiocbq: Pointer to response iocb. + * + * This function is the completion handler for iocbs issued using + * lpfc_menlo_cmd function. This function is called by the + * ring event handler function without any lock held. This function + * can be called from both worker thread context and interrupt + * context. This function also can be called from another thread which + * cleans up the SLI layer objects. + * This function copies the contents of the response iocb to the + * response iocb memory object provided by the caller of + * lpfc_sli_issue_iocb_wait and then wakes up the thread which + * sleeps for the iocb completion. + **/ +static void +lpfc_bsg_menlo_cmd_cmp(struct lpfc_hba *phba, + struct lpfc_iocbq *cmdiocbq, + struct lpfc_iocbq *rspiocbq) +{ + struct bsg_job_data *dd_data; + struct fc_bsg_job *job; + IOCB_t *rsp; + struct lpfc_dmabuf *bmp; + struct lpfc_bsg_menlo *menlo; + unsigned long flags; + struct menlo_response *menlo_resp; + int rc = 0; + + spin_lock_irqsave(&phba->ct_ev_lock, flags); + dd_data = cmdiocbq->context1; + if (!dd_data) { + spin_unlock_irqrestore(&phba->ct_ev_lock, flags); + return; + } + + menlo = &dd_data->context_un.menlo; + job = menlo->set_job; + job->dd_data = NULL; /* so timeout handler does not reply */ + + spin_lock_irqsave(&phba->hbalock, flags); + cmdiocbq->iocb_flag |= LPFC_IO_WAKE; + if (cmdiocbq->context2 && rspiocbq) + memcpy(&((struct lpfc_iocbq *)cmdiocbq->context2)->iocb, + &rspiocbq->iocb, sizeof(IOCB_t)); + spin_unlock_irqrestore(&phba->hbalock, flags); + + bmp = menlo->bmp; + rspiocbq = menlo->rspiocbq; + rsp = &rspiocbq->iocb; + + pci_unmap_sg(phba->pcidev, job->request_payload.sg_list, + job->request_payload.sg_cnt, DMA_TO_DEVICE); + pci_unmap_sg(phba->pcidev, job->reply_payload.sg_list, + job->reply_payload.sg_cnt, DMA_FROM_DEVICE); + + /* always return the xri, this would be used in the case + * of a menlo download to allow the data to be sent as a continuation + * of the exchange. + */ + menlo_resp = (struct menlo_response *) + job->reply->reply_data.vendor_reply.vendor_rsp; + menlo_resp->xri = rsp->ulpContext; + if (rsp->ulpStatus) { + if (rsp->ulpStatus == IOSTAT_LOCAL_REJECT) { + switch (rsp->un.ulpWord[4] & 0xff) { + case IOERR_SEQUENCE_TIMEOUT: + rc = -ETIMEDOUT; + break; + case IOERR_INVALID_RPI: + rc = -EFAULT; + break; + default: + rc = -EACCES; + break; + } + } else + rc = -EACCES; + } else + job->reply->reply_payload_rcv_len = + rsp->un.genreq64.bdl.bdeSize; + + lpfc_mbuf_free(phba, bmp->virt, bmp->phys); + lpfc_sli_release_iocbq(phba, rspiocbq); + lpfc_sli_release_iocbq(phba, cmdiocbq); + kfree(bmp); + kfree(dd_data); + /* make error code available to userspace */ + job->reply->result = rc; + /* complete the job back to userspace */ + job->job_done(job); + spin_unlock_irqrestore(&phba->ct_ev_lock, flags); + return; +} + +/** + * lpfc_menlo_cmd - send an ioctl for menlo hardware + * @job: fc_bsg_job to handle + * + * This function issues a gen request 64 CR ioctl for all menlo cmd requests, + * all the command completions will return the xri for the command. + * For menlo data requests a gen request 64 CX is used to continue the exchange + * supplied in the menlo request header xri field. + **/ +static int +lpfc_menlo_cmd(struct fc_bsg_job *job) +{ + struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata; + struct lpfc_hba *phba = vport->phba; + struct lpfc_iocbq *cmdiocbq, *rspiocbq; + IOCB_t *cmd, *rsp; + int rc = 0; + struct menlo_command *menlo_cmd; + struct menlo_response *menlo_resp; + struct lpfc_dmabuf *bmp = NULL; + int request_nseg; + int reply_nseg; + struct scatterlist *sgel = NULL; + int numbde; + dma_addr_t busaddr; + struct bsg_job_data *dd_data; + struct ulp_bde64 *bpl = NULL; + + /* in case no data is returned return just the return code */ + job->reply->reply_payload_rcv_len = 0; + + if (job->request_len < + sizeof(struct fc_bsg_request) + + sizeof(struct menlo_command)) { + lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC, + "2784 Received MENLO_CMD request below " + "minimum size\n"); + rc = -ERANGE; + goto no_dd_data; + } + + if (job->reply_len < + sizeof(struct fc_bsg_request) + sizeof(struct menlo_response)) { + lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC, + "2785 Received MENLO_CMD reply below " + "minimum size\n"); + rc = -ERANGE; + goto no_dd_data; + } + + if (!(phba->menlo_flag & HBA_MENLO_SUPPORT)) { + lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC, + "2786 Adapter does not support menlo " + "commands\n"); + rc = -EPERM; + goto no_dd_data; + } + + menlo_cmd = (struct menlo_command *) + job->request->rqst_data.h_vendor.vendor_cmd; + + menlo_resp = (struct menlo_response *) + job->reply->reply_data.vendor_reply.vendor_rsp; + + /* allocate our bsg tracking structure */ + dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL); + if (!dd_data) { + lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC, + "2787 Failed allocation of dd_data\n"); + rc = -ENOMEM; + goto no_dd_data; + } + + bmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); + if (!bmp) { + rc = -ENOMEM; + goto free_dd; + } + + cmdiocbq = lpfc_sli_get_iocbq(phba); + if (!cmdiocbq) { + rc = -ENOMEM; + goto free_bmp; + } + + rspiocbq = lpfc_sli_get_iocbq(phba); + if (!rspiocbq) { + rc = -ENOMEM; + goto free_cmdiocbq; + } + + rsp = &rspiocbq->iocb; + + bmp->virt = lpfc_mbuf_alloc(phba, 0, &bmp->phys); + if (!bmp->virt) { + rc = -ENOMEM; + goto free_rspiocbq; + } + + INIT_LIST_HEAD(&bmp->list); + bpl = (struct ulp_bde64 *) bmp->virt; + request_nseg = pci_map_sg(phba->pcidev, job->request_payload.sg_list, + job->request_payload.sg_cnt, DMA_TO_DEVICE); + for_each_sg(job->request_payload.sg_list, sgel, request_nseg, numbde) { + busaddr = sg_dma_address(sgel); + bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64; + bpl->tus.f.bdeSize = sg_dma_len(sgel); + bpl->tus.w = cpu_to_le32(bpl->tus.w); + bpl->addrLow = cpu_to_le32(putPaddrLow(busaddr)); + bpl->addrHigh = cpu_to_le32(putPaddrHigh(busaddr)); + bpl++; + } + + reply_nseg = pci_map_sg(phba->pcidev, job->reply_payload.sg_list, + job->reply_payload.sg_cnt, DMA_FROM_DEVICE); + for_each_sg(job->reply_payload.sg_list, sgel, reply_nseg, numbde) { + busaddr = sg_dma_address(sgel); + bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64I; + bpl->tus.f.bdeSize = sg_dma_len(sgel); + bpl->tus.w = cpu_to_le32(bpl->tus.w); + bpl->addrLow = cpu_to_le32(putPaddrLow(busaddr)); + bpl->addrHigh = cpu_to_le32(putPaddrHigh(busaddr)); + bpl++; + } + + cmd = &cmdiocbq->iocb; + cmd->un.genreq64.bdl.ulpIoTag32 = 0; + cmd->un.genreq64.bdl.addrHigh = putPaddrHigh(bmp->phys); + cmd->un.genreq64.bdl.addrLow = putPaddrLow(bmp->phys); + cmd->un.genreq64.bdl.bdeFlags = BUFF_TYPE_BLP_64; + cmd->un.genreq64.bdl.bdeSize = + (request_nseg + reply_nseg) * sizeof(struct ulp_bde64); + cmd->un.genreq64.w5.hcsw.Fctl = (SI | LA); + cmd->un.genreq64.w5.hcsw.Dfctl = 0; + cmd->un.genreq64.w5.hcsw.Rctl = FC_RCTL_DD_UNSOL_CMD; + cmd->un.genreq64.w5.hcsw.Type = MENLO_TRANSPORT_TYPE; /* 0xfe */ + cmd->ulpBdeCount = 1; + cmd->ulpClass = CLASS3; + cmd->ulpOwner = OWN_CHIP; + cmd->ulpLe = 1; /* Limited Edition */ + cmdiocbq->iocb_flag |= LPFC_IO_LIBDFC; + cmdiocbq->vport = phba->pport; + /* We want the firmware to timeout before we do */ + cmd->ulpTimeout = MENLO_TIMEOUT - 5; + cmdiocbq->context3 = bmp; + cmdiocbq->context2 = rspiocbq; + cmdiocbq->iocb_cmpl = lpfc_bsg_menlo_cmd_cmp; + cmdiocbq->context1 = dd_data; + cmdiocbq->context2 = rspiocbq; + if (menlo_cmd->cmd == LPFC_BSG_VENDOR_MENLO_CMD) { + cmd->ulpCommand = CMD_GEN_REQUEST64_CR; + cmd->ulpPU = MENLO_PU; /* 3 */ + cmd->un.ulpWord[4] = MENLO_DID; /* 0x0000FC0E */ + cmd->ulpContext = MENLO_CONTEXT; /* 0 */ + } else { + cmd->ulpCommand = CMD_GEN_REQUEST64_CX; + cmd->ulpPU = 1; + cmd->un.ulpWord[4] = 0; + cmd->ulpContext = menlo_cmd->xri; + } + + dd_data->type = TYPE_MENLO; + dd_data->context_un.menlo.cmdiocbq = cmdiocbq; + dd_data->context_un.menlo.rspiocbq = rspiocbq; + dd_data->context_un.menlo.set_job = job; + dd_data->context_un.menlo.bmp = bmp; + + rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, cmdiocbq, + MENLO_TIMEOUT - 5); + if (rc == IOCB_SUCCESS) + return 0; /* done for now */ + + /* iocb failed so cleanup */ + pci_unmap_sg(phba->pcidev, job->request_payload.sg_list, + job->request_payload.sg_cnt, DMA_TO_DEVICE); + pci_unmap_sg(phba->pcidev, job->reply_payload.sg_list, + job->reply_payload.sg_cnt, DMA_FROM_DEVICE); + + lpfc_mbuf_free(phba, bmp->virt, bmp->phys); + +free_rspiocbq: + lpfc_sli_release_iocbq(phba, rspiocbq); +free_cmdiocbq: + lpfc_sli_release_iocbq(phba, cmdiocbq); +free_bmp: + kfree(bmp); +free_dd: + kfree(dd_data); +no_dd_data: + /* make error code available to userspace */ + job->reply->result = rc; + job->dd_data = NULL; + return rc; +} +/** * lpfc_bsg_hst_vendor - process a vendor-specific fc_bsg_job * @job: fc_bsg_job to handle **/ @@ -2669,6 +2985,10 @@ lpfc_bsg_hst_vendor(struct fc_bsg_job *job) case LPFC_BSG_VENDOR_MBOX: rc = lpfc_bsg_mbox_cmd(job); break; + case LPFC_BSG_VENDOR_MENLO_CMD: + case LPFC_BSG_VENDOR_MENLO_DATA: + rc = lpfc_menlo_cmd(job); + break; default: rc = -EINVAL; job->reply->reply_payload_rcv_len = 0; @@ -2728,6 +3048,7 @@ lpfc_bsg_timeout(struct fc_bsg_job *job) struct lpfc_bsg_event *evt; struct lpfc_bsg_iocb *iocb; struct lpfc_bsg_mbox *mbox; + struct lpfc_bsg_menlo *menlo; struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING]; struct bsg_job_data *dd_data; unsigned long flags; @@ -2775,6 +3096,17 @@ lpfc_bsg_timeout(struct fc_bsg_job *job) spin_unlock_irqrestore(&phba->ct_ev_lock, flags); job->job_done(job); break; + case TYPE_MENLO: + menlo = &dd_data->context_un.menlo; + cmdiocb = menlo->cmdiocbq; + /* hint to completion handler that the job timed out */ + job->reply->result = -EAGAIN; + spin_unlock_irqrestore(&phba->ct_ev_lock, flags); + /* this will call our completion handler */ + spin_lock_irq(&phba->hbalock); + lpfc_sli_issue_abort_iotag(phba, pring, cmdiocb); + spin_unlock_irq(&phba->hbalock); + break; default: spin_unlock_irqrestore(&phba->ct_ev_lock, flags); break; diff --git a/drivers/scsi/lpfc/lpfc_bsg.h b/drivers/scsi/lpfc/lpfc_bsg.h index 6c8f87e..5bc6308 100644 --- a/drivers/scsi/lpfc/lpfc_bsg.h +++ b/drivers/scsi/lpfc/lpfc_bsg.h @@ -31,6 +31,8 @@ #define LPFC_BSG_VENDOR_DIAG_TEST 5 #define LPFC_BSG_VENDOR_GET_MGMT_REV 6 #define LPFC_BSG_VENDOR_MBOX 7 +#define LPFC_BSG_VENDOR_MENLO_CMD 8 +#define LPFC_BSG_VENDOR_MENLO_DATA 9 struct set_ct_event { uint32_t command; @@ -96,3 +98,13 @@ struct dfc_mbox_req { uint8_t mbOffset; }; +/* Used for menlo command or menlo data. The xri is only used for menlo data */ +struct menlo_command { + uint32_t cmd; + uint32_t xri; +}; + +struct menlo_response { + uint32_t xri; /* return the xri of the iocb exchange */ +}; + diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index b7889c5..88e02a4 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -2597,6 +2597,14 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev) init_timer(&vport->els_tmofunc); vport->els_tmofunc.function = lpfc_els_timeout; vport->els_tmofunc.data = (unsigned long)vport; + if (phba->pcidev->device == PCI_DEVICE_ID_HORNET) { + phba->menlo_flag |= HBA_MENLO_SUPPORT; + /* check for menlo minimum sg count */ + if (phba->cfg_sg_seg_cnt < LPFC_DEFAULT_MENLO_SG_SEG_CNT) { + phba->cfg_sg_seg_cnt = LPFC_DEFAULT_MENLO_SG_SEG_CNT; + shost->sg_tablesize = phba->cfg_sg_seg_cnt; + } + } error = scsi_add_host_with_dma(shost, dev, &phba->pcidev->dev); if (error) -- cgit v0.10.2 From fc2b989be9190f3311a5ae41289828e24897a20e Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 26 Feb 2010 14:15:29 -0500 Subject: [SCSI] lpfc 8.3.10: Fix Discovery issues - Prevent Vport discovery after reg_new_vport completes when physical logged in using FDISC. - Remove fast FCF failover fabric name matching. Allow failover to FCFs connected to different fabrics. - Added fast FCF failover in response to FCF DEAD event on current FCF record. Signed-off-by: James Smart Signed-off-by: James Bottomley diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index e7f5482..39739a7 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -221,6 +221,7 @@ void lpfc_unregister_fcf_rescan(struct lpfc_hba *); void lpfc_unregister_unused_fcf(struct lpfc_hba *); int lpfc_sli4_redisc_fcf_table(struct lpfc_hba *); void lpfc_fcf_redisc_wait_start_timer(struct lpfc_hba *); +void lpfc_sli4_fcf_dead_failthrough(struct lpfc_hba *); int lpfc_mem_alloc(struct lpfc_hba *, int align); void lpfc_mem_free(struct lpfc_hba *); diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 6a2135a..a81d433 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -6004,7 +6004,12 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) if (phba->sli_rev < LPFC_SLI_REV4) lpfc_issue_fabric_reglogin(vport); else { - lpfc_start_fdiscs(phba); + /* + * If the physical port is instantiated using + * FDISC, do not start vport discovery. + */ + if (vport->port_state != LPFC_FDISC) + lpfc_start_fdiscs(phba); lpfc_do_scr_ns_plogi(phba, vport); } } else diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index e58d8ae..f28ce40 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -1504,7 +1504,9 @@ lpfc_check_pending_fcoe_event(struct lpfc_hba *phba, uint8_t unreg_fcf) */ spin_lock_irq(&phba->hbalock); phba->hba_flag &= ~FCF_DISC_INPROGRESS; - phba->fcf.fcf_flag &= ~FCF_REDISC_FOV; + phba->fcf.fcf_flag &= ~(FCF_REDISC_FOV | + FCF_DEAD_FOVER | + FCF_CVL_FOVER); spin_unlock_irq(&phba->hbalock); } @@ -1649,7 +1651,9 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) __lpfc_sli4_stop_fcf_redisc_wait_timer(phba); else if (phba->fcf.fcf_flag & FCF_REDISC_FOV) /* If in fast failover, mark it's completed */ - phba->fcf.fcf_flag &= ~FCF_REDISC_FOV; + phba->fcf.fcf_flag &= ~(FCF_REDISC_FOV | + FCF_DEAD_FOVER | + FCF_CVL_FOVER); spin_unlock_irqrestore(&phba->hbalock, iflags); goto out; } @@ -1669,14 +1673,9 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) * Update on failover FCF record only if it's in FCF fast-failover * period; otherwise, update on current FCF record. */ - if (phba->fcf.fcf_flag & FCF_REDISC_FOV) { - /* Fast FCF failover only to the same fabric name */ - if (lpfc_fab_name_match(phba->fcf.current_rec.fabric_name, - new_fcf_record)) - fcf_rec = &phba->fcf.failover_rec; - else - goto read_next_fcf; - } else + if (phba->fcf.fcf_flag & FCF_REDISC_FOV) + fcf_rec = &phba->fcf.failover_rec; + else fcf_rec = &phba->fcf.current_rec; if (phba->fcf.fcf_flag & FCF_AVAILABLE) { @@ -1705,8 +1704,7 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) * If the new hba FCF record has lower priority value * than the driver FCF record, use the new record. */ - if (lpfc_fab_name_match(fcf_rec->fabric_name, new_fcf_record) && - (new_fcf_record->fip_priority < fcf_rec->priority)) { + if (new_fcf_record->fip_priority < fcf_rec->priority) { /* Choose this FCF record */ __lpfc_update_fcf_record(phba, fcf_rec, new_fcf_record, addr_mode, vlan_id, 0); @@ -1762,7 +1760,9 @@ read_next_fcf: sizeof(struct lpfc_fcf_rec)); /* mark the FCF fast failover completed */ spin_lock_irqsave(&phba->hbalock, iflags); - phba->fcf.fcf_flag &= ~FCF_REDISC_FOV; + phba->fcf.fcf_flag &= ~(FCF_REDISC_FOV | + FCF_DEAD_FOVER | + FCF_CVL_FOVER); spin_unlock_irqrestore(&phba->hbalock, iflags); /* Register to the new FCF record */ lpfc_register_fcf(phba); @@ -4760,6 +4760,7 @@ lpfc_unregister_fcf_rescan(struct lpfc_hba *phba) return; /* Reset HBA FCF states after successful unregister FCF */ phba->fcf.fcf_flag = 0; + phba->fcf.current_rec.flag = 0; /* * If driver is not unloading, check if there is any other diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 88e02a4..ff45e33 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -2199,8 +2199,10 @@ lpfc_stop_vport_timers(struct lpfc_vport *vport) void __lpfc_sli4_stop_fcf_redisc_wait_timer(struct lpfc_hba *phba) { - /* Clear pending FCF rediscovery wait timer */ - phba->fcf.fcf_flag &= ~FCF_REDISC_PEND; + /* Clear pending FCF rediscovery wait and failover in progress flags */ + phba->fcf.fcf_flag &= ~(FCF_REDISC_PEND | + FCF_DEAD_FOVER | + FCF_CVL_FOVER); /* Now, try to stop the timer */ del_timer(&phba->fcf.redisc_wait); } @@ -3212,6 +3214,68 @@ out_free_pmb: } /** + * lpfc_sli4_perform_vport_cvl - Perform clear virtual link on a vport + * @vport: pointer to vport data structure. + * + * This routine is to perform Clear Virtual Link (CVL) on a vport in + * response to a CVL event. + * + * Return the pointer to the ndlp with the vport if successful, otherwise + * return NULL. + **/ +static struct lpfc_nodelist * +lpfc_sli4_perform_vport_cvl(struct lpfc_vport *vport) +{ + struct lpfc_nodelist *ndlp; + struct Scsi_Host *shost; + struct lpfc_hba *phba; + + if (!vport) + return NULL; + ndlp = lpfc_findnode_did(vport, Fabric_DID); + if (!ndlp) + return NULL; + phba = vport->phba; + if (!phba) + return NULL; + if (phba->pport->port_state <= LPFC_FLOGI) + return NULL; + /* If virtual link is not yet instantiated ignore CVL */ + if (vport->port_state <= LPFC_FDISC) + return NULL; + shost = lpfc_shost_from_vport(vport); + if (!shost) + return NULL; + lpfc_linkdown_port(vport); + lpfc_cleanup_pending_mbox(vport); + spin_lock_irq(shost->host_lock); + vport->fc_flag |= FC_VPORT_CVL_RCVD; + spin_unlock_irq(shost->host_lock); + + return ndlp; +} + +/** + * lpfc_sli4_perform_all_vport_cvl - Perform clear virtual link on all vports + * @vport: pointer to lpfc hba data structure. + * + * This routine is to perform Clear Virtual Link (CVL) on all vports in + * response to a FCF dead event. + **/ +static void +lpfc_sli4_perform_all_vport_cvl(struct lpfc_hba *phba) +{ + struct lpfc_vport **vports; + int i; + + vports = lpfc_create_vport_work_array(phba); + if (vports) + for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) + lpfc_sli4_perform_vport_cvl(vports[i]); + lpfc_destroy_vport_work_array(phba, vports); +} + +/** * lpfc_sli4_async_fcoe_evt - Process the asynchronous fcoe event * @phba: pointer to lpfc hba data structure. * @acqe_link: pointer to the async fcoe completion queue entry. @@ -3227,7 +3291,6 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, struct lpfc_vport *vport; struct lpfc_nodelist *ndlp; struct Scsi_Host *shost; - uint32_t link_state; int active_vlink_present; struct lpfc_vport **vports; int i; @@ -3284,16 +3347,35 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, /* If the event is not for currently used fcf do nothing */ if (phba->fcf.current_rec.fcf_indx != acqe_fcoe->index) break; - /* - * Currently, driver support only one FCF - so treat this as - * a link down, but save the link state because we don't want - * it to be changed to Link Down unless it is already down. + /* We request port to rediscover the entire FCF table for + * a fast recovery from case that the current FCF record + * is no longer valid if the last CVL event hasn't already + * triggered process. */ - link_state = phba->link_state; - lpfc_linkdown(phba); - phba->link_state = link_state; - /* Unregister FCF if no devices connected to it */ - lpfc_unregister_unused_fcf(phba); + spin_lock_irq(&phba->hbalock); + if (phba->fcf.fcf_flag & FCF_CVL_FOVER) { + spin_unlock_irq(&phba->hbalock); + break; + } + /* Mark the fast failover process in progress */ + phba->fcf.fcf_flag |= FCF_DEAD_FOVER; + spin_unlock_irq(&phba->hbalock); + rc = lpfc_sli4_redisc_fcf_table(phba); + if (rc) { + spin_lock_irq(&phba->hbalock); + phba->fcf.fcf_flag &= ~FCF_DEAD_FOVER; + spin_unlock_irq(&phba->hbalock); + /* + * Last resort will fail over by treating this + * as a link down to FCF registration. + */ + lpfc_sli4_fcf_dead_failthrough(phba); + } else + /* Handling fast FCF failover to a DEAD FCF event + * is considered equalivant to receiving CVL to all + * vports. + */ + lpfc_sli4_perform_all_vport_cvl(phba); break; case LPFC_FCOE_EVENT_TYPE_CVL: lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, @@ -3301,23 +3383,9 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, " tag 0x%x\n", acqe_fcoe->index, acqe_fcoe->event_tag); vport = lpfc_find_vport_by_vpid(phba, acqe_fcoe->index - phba->vpi_base); - if (!vport) - break; - ndlp = lpfc_findnode_did(vport, Fabric_DID); + ndlp = lpfc_sli4_perform_vport_cvl(vport); if (!ndlp) break; - shost = lpfc_shost_from_vport(vport); - if (phba->pport->port_state <= LPFC_FLOGI) - break; - /* If virtual link is not yet instantiated ignore CVL */ - if (vport->port_state <= LPFC_FDISC) - break; - - lpfc_linkdown_port(vport); - lpfc_cleanup_pending_mbox(vport); - spin_lock_irq(shost->host_lock); - vport->fc_flag |= FC_VPORT_CVL_RCVD; - spin_unlock_irq(shost->host_lock); active_vlink_present = 0; vports = lpfc_create_vport_work_array(phba); @@ -3340,6 +3408,7 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, * re-instantiate the Vlink using FDISC. */ mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); + shost = lpfc_shost_from_vport(vport); spin_lock_irq(shost->host_lock); ndlp->nlp_flag |= NLP_DELAY_TMO; spin_unlock_irq(shost->host_lock); @@ -3350,15 +3419,28 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, * Otherwise, we request port to rediscover * the entire FCF table for a fast recovery * from possible case that the current FCF - * is no longer valid. + * is no longer valid if the FCF_DEAD event + * hasn't already triggered process. */ + spin_lock_irq(&phba->hbalock); + if (phba->fcf.fcf_flag & FCF_DEAD_FOVER) { + spin_unlock_irq(&phba->hbalock); + break; + } + /* Mark the fast failover process in progress */ + phba->fcf.fcf_flag |= FCF_CVL_FOVER; + spin_unlock_irq(&phba->hbalock); rc = lpfc_sli4_redisc_fcf_table(phba); - if (rc) + if (rc) { + spin_lock_irq(&phba->hbalock); + phba->fcf.fcf_flag &= ~FCF_CVL_FOVER; + spin_unlock_irq(&phba->hbalock); /* * Last resort will be re-try on the * the current registered FCF entry. */ lpfc_retry_pport_discovery(phba); + } } break; default: diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 9feeaff..bb6a442 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -4519,6 +4519,10 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) /* Post receive buffers to the device */ lpfc_sli4_rb_setup(phba); + /* Reset HBA FCF states after HBA reset */ + phba->fcf.fcf_flag = 0; + phba->fcf.current_rec.flag = 0; + /* Start the ELS watchdog timer */ mod_timer(&vport->els_tmofunc, jiffies + HZ * (phba->fc_ratov * 2)); @@ -12069,11 +12073,26 @@ lpfc_mbx_cmpl_redisc_fcf_table(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox) "2746 Requesting for FCF rediscovery failed " "status x%x add_status x%x\n", shdr_status, shdr_add_status); - /* - * Request failed, last resort to re-try current - * registered FCF entry - */ - lpfc_retry_pport_discovery(phba); + if (phba->fcf.fcf_flag & FCF_CVL_FOVER) { + spin_lock_irq(&phba->hbalock); + phba->fcf.fcf_flag &= ~FCF_CVL_FOVER; + spin_unlock_irq(&phba->hbalock); + /* + * CVL event triggered FCF rediscover request failed, + * last resort to re-try current registered FCF entry. + */ + lpfc_retry_pport_discovery(phba); + } else { + spin_lock_irq(&phba->hbalock); + phba->fcf.fcf_flag &= ~FCF_DEAD_FOVER; + spin_unlock_irq(&phba->hbalock); + /* + * DEAD FCF event triggered FCF rediscover request + * failed, last resort to fail over as a link down + * to FCF registration. + */ + lpfc_sli4_fcf_dead_failthrough(phba); + } } else /* * Start FCF rediscovery wait timer for pending FCF @@ -12129,6 +12148,31 @@ lpfc_sli4_redisc_fcf_table(struct lpfc_hba *phba) } /** + * lpfc_sli4_fcf_dead_failthrough - Failthrough routine to fcf dead event + * @phba: pointer to lpfc hba data structure. + * + * This function is the failover routine as a last resort to the FCF DEAD + * event when driver failed to perform fast FCF failover. + **/ +void +lpfc_sli4_fcf_dead_failthrough(struct lpfc_hba *phba) +{ + uint32_t link_state; + + /* + * Last resort as FCF DEAD event failover will treat this as + * a link down, but save the link state because we don't want + * it to be changed to Link Down unless it is already down. + */ + link_state = phba->link_state; + lpfc_linkdown(phba); + phba->link_state = link_state; + + /* Unregister FCF if no devices connected to it */ + lpfc_unregister_unused_fcf(phba); +} + +/** * lpfc_sli_read_link_ste - Read region 23 to decide if link is disabled. * @phba: pointer to lpfc hba data structure. * diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index 04fd782..2169cd2 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h @@ -153,9 +153,11 @@ struct lpfc_fcf { #define FCF_REGISTERED 0x02 /* FCF registered with FW */ #define FCF_SCAN_DONE 0x04 /* FCF table scan done */ #define FCF_IN_USE 0x08 /* Atleast one discovery completed */ -#define FCF_REDISC_PEND 0x10 /* FCF rediscovery pending */ -#define FCF_REDISC_EVT 0x20 /* FCF rediscovery event to worker thread */ -#define FCF_REDISC_FOV 0x40 /* Post FCF rediscovery fast failover */ +#define FCF_DEAD_FOVER 0x10 /* FCF DEAD triggered fast FCF failover */ +#define FCF_CVL_FOVER 0x20 /* CVL triggered fast FCF failover */ +#define FCF_REDISC_PEND 0x40 /* FCF rediscovery pending */ +#define FCF_REDISC_EVT 0x80 /* FCF rediscovery event to worker thread */ +#define FCF_REDISC_FOV 0x100 /* Post FCF rediscovery fast failover */ uint32_t addr_mode; struct lpfc_fcf_rec current_rec; struct lpfc_fcf_rec failover_rec; -- cgit v0.10.2 From 0c9ab6f5cb28199ef5de84874d135ed44f64d92b Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 26 Feb 2010 14:15:57 -0500 Subject: [SCSI] lpfc 8.3.10: Added round robin FCF failover - Added round robin FCF failover on initial or FCF rediscovery FLOGI failure. Signed-off-by: James Smart Signed-off-by: James Bottomley diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index 39739a7..5087c42 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -63,6 +63,7 @@ void lpfc_linkdown_port(struct lpfc_vport *); void lpfc_port_link_failure(struct lpfc_vport *); void lpfc_mbx_cmpl_read_la(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_init_vpi_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *); +void lpfc_cancel_all_vport_retry_delay_timer(struct lpfc_hba *); void lpfc_retry_pport_discovery(struct lpfc_hba *); void lpfc_mbx_cmpl_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); @@ -222,6 +223,9 @@ void lpfc_unregister_unused_fcf(struct lpfc_hba *); int lpfc_sli4_redisc_fcf_table(struct lpfc_hba *); void lpfc_fcf_redisc_wait_start_timer(struct lpfc_hba *); void lpfc_sli4_fcf_dead_failthrough(struct lpfc_hba *); +uint16_t lpfc_sli4_fcf_rr_next_index_get(struct lpfc_hba *); +int lpfc_sli4_fcf_rr_index_set(struct lpfc_hba *, uint16_t); +void lpfc_sli4_fcf_rr_index_clear(struct lpfc_hba *, uint16_t); int lpfc_mem_alloc(struct lpfc_hba *, int align); void lpfc_mem_free(struct lpfc_hba *); diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index a81d433..d807f36 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -771,6 +771,7 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_nodelist *ndlp = cmdiocb->context1; struct lpfc_dmabuf *pcmd = cmdiocb->context2, *prsp; struct serv_parm *sp; + uint16_t fcf_index; int rc; /* Check to see if link went down during discovery */ @@ -788,6 +789,54 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, vport->port_state); if (irsp->ulpStatus) { + /* + * In case of FIP mode, perform round robin FCF failover + * due to new FCF discovery + */ + if ((phba->hba_flag & HBA_FIP_SUPPORT) && + (phba->fcf.fcf_flag & FCF_DISCOVERY)) { + lpfc_printf_log(phba, KERN_WARNING, LOG_FIP | LOG_ELS, + "2611 FLOGI failed on registered " + "FCF record fcf_index:%d, trying " + "to perform round robin failover\n", + phba->fcf.current_rec.fcf_indx); + fcf_index = lpfc_sli4_fcf_rr_next_index_get(phba); + if (fcf_index == LPFC_FCOE_FCF_NEXT_NONE) { + /* + * Exhausted the eligible FCF record list, + * fail through to retry FLOGI on current + * FCF record. + */ + lpfc_printf_log(phba, KERN_WARNING, + LOG_FIP | LOG_ELS, + "2760 FLOGI exhausted FCF " + "round robin failover list, " + "retry FLOGI on the current " + "registered FCF index:%d\n", + phba->fcf.current_rec.fcf_indx); + spin_lock_irq(&phba->hbalock); + phba->fcf.fcf_flag &= ~FCF_DISCOVERY; + spin_unlock_irq(&phba->hbalock); + } else { + rc = lpfc_sli4_fcf_rr_read_fcf_rec(phba, + fcf_index); + if (rc) { + lpfc_printf_log(phba, KERN_WARNING, + LOG_FIP | LOG_ELS, + "2761 FLOGI round " + "robin FCF failover " + "read FCF failed " + "rc:x%x, fcf_index:" + "%d\n", rc, + phba->fcf.current_rec.fcf_indx); + spin_lock_irq(&phba->hbalock); + phba->fcf.fcf_flag &= ~FCF_DISCOVERY; + spin_unlock_irq(&phba->hbalock); + } else + goto out; + } + } + /* Check for retry */ if (lpfc_els_retry(phba, cmdiocb, rspiocb)) goto out; @@ -841,8 +890,18 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, else rc = lpfc_cmpl_els_flogi_nport(vport, ndlp, sp); - if (!rc) + if (!rc) { + /* Mark the FCF discovery process done */ + lpfc_printf_vlog(vport, KERN_INFO, LOG_FIP | LOG_ELS, + "2769 FLOGI successful on FCF record: " + "current_fcf_index:x%x, terminate FCF " + "round robin failover process\n", + phba->fcf.current_rec.fcf_indx); + spin_lock_irq(&phba->hbalock); + phba->fcf.fcf_flag &= ~FCF_DISCOVERY; + spin_unlock_irq(&phba->hbalock); goto out; + } } flogifail: @@ -6075,21 +6134,18 @@ mbox_err_exit: } /** - * lpfc_retry_pport_discovery - Start timer to retry FLOGI. + * lpfc_cancel_all_vport_retry_delay_timer - Cancel all vport retry delay timer * @phba: pointer to lpfc hba data structure. * - * This routine abort all pending discovery commands and - * start a timer to retry FLOGI for the physical port - * discovery. + * This routine cancels the retry delay timers to all the vports. **/ void -lpfc_retry_pport_discovery(struct lpfc_hba *phba) +lpfc_cancel_all_vport_retry_delay_timer(struct lpfc_hba *phba) { struct lpfc_vport **vports; struct lpfc_nodelist *ndlp; - struct Scsi_Host *shost; - int i; uint32_t link_state; + int i; /* Treat this failure as linkdown for all vports */ link_state = phba->link_state; @@ -6107,13 +6163,30 @@ lpfc_retry_pport_discovery(struct lpfc_hba *phba) } lpfc_destroy_vport_work_array(phba, vports); } +} + +/** + * lpfc_retry_pport_discovery - Start timer to retry FLOGI. + * @phba: pointer to lpfc hba data structure. + * + * This routine abort all pending discovery commands and + * start a timer to retry FLOGI for the physical port + * discovery. + **/ +void +lpfc_retry_pport_discovery(struct lpfc_hba *phba) +{ + struct lpfc_nodelist *ndlp; + struct Scsi_Host *shost; + + /* Cancel the all vports retry delay retry timers */ + lpfc_cancel_all_vport_retry_delay_timer(phba); /* If fabric require FLOGI, then re-instantiate physical login */ ndlp = lpfc_findnode_did(phba->pport, Fabric_DID); if (!ndlp) return; - shost = lpfc_shost_from_vport(phba->pport); mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); spin_lock_irq(shost->host_lock); diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index f28ce40..c555e3b 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -1481,8 +1481,6 @@ lpfc_match_fcf_conn_list(struct lpfc_hba *phba, int lpfc_check_pending_fcoe_event(struct lpfc_hba *phba, uint8_t unreg_fcf) { - LPFC_MBOXQ_t *mbox; - int rc; /* * If the Link is up and no FCoE events while in the * FCF discovery, no need to restart FCF discovery. @@ -1491,88 +1489,70 @@ lpfc_check_pending_fcoe_event(struct lpfc_hba *phba, uint8_t unreg_fcf) (phba->fcoe_eventtag == phba->fcoe_eventtag_at_fcf_scan)) return 0; + lpfc_printf_log(phba, KERN_INFO, LOG_FIP, + "2768 Pending link or FCF event during current " + "handling of the previous event: link_state:x%x, " + "evt_tag_at_scan:x%x, evt_tag_current:x%x\n", + phba->link_state, phba->fcoe_eventtag_at_fcf_scan, + phba->fcoe_eventtag); + spin_lock_irq(&phba->hbalock); phba->fcf.fcf_flag &= ~FCF_AVAILABLE; spin_unlock_irq(&phba->hbalock); - if (phba->link_state >= LPFC_LINK_UP) - lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST); - else { + if (phba->link_state >= LPFC_LINK_UP) { + lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY, + "2780 Restart FCF table scan due to " + "pending FCF event:evt_tag_at_scan:x%x, " + "evt_tag_current:x%x\n", + phba->fcoe_eventtag_at_fcf_scan, + phba->fcoe_eventtag); + lpfc_sli4_fcf_scan_read_fcf_rec(phba, LPFC_FCOE_FCF_GET_FIRST); + } else { /* * Do not continue FCF discovery and clear FCF_DISC_INPROGRESS * flag */ spin_lock_irq(&phba->hbalock); phba->hba_flag &= ~FCF_DISC_INPROGRESS; - phba->fcf.fcf_flag &= ~(FCF_REDISC_FOV | - FCF_DEAD_FOVER | - FCF_CVL_FOVER); + phba->fcf.fcf_flag &= ~(FCF_REDISC_FOV | FCF_DISCOVERY); spin_unlock_irq(&phba->hbalock); } + /* Unregister the currently registered FCF if required */ if (unreg_fcf) { spin_lock_irq(&phba->hbalock); phba->fcf.fcf_flag &= ~FCF_REGISTERED; spin_unlock_irq(&phba->hbalock); - mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); - if (!mbox) { - lpfc_printf_log(phba, KERN_ERR, - LOG_DISCOVERY|LOG_MBOX, - "2610 UNREG_FCFI mbox allocation failed\n"); - return 1; - } - lpfc_unreg_fcfi(mbox, phba->fcf.fcfi); - mbox->vport = phba->pport; - mbox->mbox_cmpl = lpfc_unregister_fcfi_cmpl; - rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); - if (rc == MBX_NOT_FINISHED) { - lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, - "2611 UNREG_FCFI issue mbox failed\n"); - mempool_free(mbox, phba->mbox_mem_pool); - } + lpfc_sli4_unregister_fcf(phba); } - return 1; } /** - * lpfc_mbx_cmpl_read_fcf_record - Completion handler for read_fcf mbox. + * lpfc_sli4_fcf_rec_mbox_parse - parse non-embedded fcf record mailbox command * @phba: pointer to lpfc hba data structure. * @mboxq: pointer to mailbox object. + * @next_fcf_index: pointer to holder of next fcf index. * - * This function iterate through all the fcf records available in - * HBA and choose the optimal FCF record for discovery. After finding - * the FCF for discovery it register the FCF record and kick start - * discovery. - * If FCF_IN_USE flag is set in currently used FCF, the routine try to - * use a FCF record which match fabric name and mac address of the - * currently used FCF record. - * If the driver support only one FCF, it will try to use the FCF record - * used by BOOT_BIOS. + * This routine parses the non-embedded fcf mailbox command by performing the + * necessarily error checking, non-embedded read FCF record mailbox command + * SGE parsing, and endianness swapping. + * + * Returns the pointer to the new FCF record in the non-embedded mailbox + * command DMA memory if successfully, other NULL. */ -void -lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) +static struct fcf_record * +lpfc_sli4_fcf_rec_mbox_parse(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq, + uint16_t *next_fcf_index) { void *virt_addr; dma_addr_t phys_addr; - uint8_t *bytep; struct lpfc_mbx_sge sge; struct lpfc_mbx_read_fcf_tbl *read_fcf; uint32_t shdr_status, shdr_add_status; union lpfc_sli4_cfg_shdr *shdr; struct fcf_record *new_fcf_record; - uint32_t boot_flag, addr_mode; - uint32_t next_fcf_index; - struct lpfc_fcf_rec *fcf_rec = NULL; - unsigned long iflags; - uint16_t vlan_id; - int rc; - - /* If there is pending FCoE event restart FCF table scan */ - if (lpfc_check_pending_fcoe_event(phba, 0)) { - lpfc_sli4_mbox_cmd_free(phba, mboxq); - return; - } /* Get the first SGE entry from the non-embedded DMA memory. This * routine only uses a single SGE. @@ -1583,59 +1563,183 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, "2524 Failed to get the non-embedded SGE " "virtual address\n"); - goto out; + return NULL; } virt_addr = mboxq->sge_array->addr[0]; shdr = (union lpfc_sli4_cfg_shdr *)virt_addr; shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); - shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, - &shdr->response); - /* - * The FCF Record was read and there is no reason for the driver - * to maintain the FCF record data or memory. Instead, just need - * to book keeping the FCFIs can be used. - */ + shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response); if (shdr_status || shdr_add_status) { - if (shdr_status == STATUS_FCF_TABLE_EMPTY) { - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, + if (shdr_status == STATUS_FCF_TABLE_EMPTY) + lpfc_printf_log(phba, KERN_ERR, LOG_FIP, "2726 READ_FCF_RECORD Indicates empty " "FCF table.\n"); - } else { - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, + else + lpfc_printf_log(phba, KERN_ERR, LOG_FIP, "2521 READ_FCF_RECORD mailbox failed " - "with status x%x add_status x%x, mbx\n", - shdr_status, shdr_add_status); - } - goto out; + "with status x%x add_status x%x, " + "mbx\n", shdr_status, shdr_add_status); + return NULL; } - /* Interpreting the returned information of FCF records */ + + /* Interpreting the returned information of the FCF record */ read_fcf = (struct lpfc_mbx_read_fcf_tbl *)virt_addr; lpfc_sli_pcimem_bcopy(read_fcf, read_fcf, sizeof(struct lpfc_mbx_read_fcf_tbl)); - next_fcf_index = bf_get(lpfc_mbx_read_fcf_tbl_nxt_vindx, read_fcf); - + *next_fcf_index = bf_get(lpfc_mbx_read_fcf_tbl_nxt_vindx, read_fcf); new_fcf_record = (struct fcf_record *)(virt_addr + sizeof(struct lpfc_mbx_read_fcf_tbl)); lpfc_sli_pcimem_bcopy(new_fcf_record, new_fcf_record, sizeof(struct fcf_record)); - bytep = virt_addr + sizeof(union lpfc_sli4_cfg_shdr); + return new_fcf_record; +} + +/** + * lpfc_sli4_log_fcf_record_info - Log the information of a fcf record + * @phba: pointer to lpfc hba data structure. + * @fcf_record: pointer to the fcf record. + * @vlan_id: the lowest vlan identifier associated to this fcf record. + * @next_fcf_index: the index to the next fcf record in hba's fcf table. + * + * This routine logs the detailed FCF record if the LOG_FIP loggin is + * enabled. + **/ +static void +lpfc_sli4_log_fcf_record_info(struct lpfc_hba *phba, + struct fcf_record *fcf_record, + uint16_t vlan_id, + uint16_t next_fcf_index) +{ + lpfc_printf_log(phba, KERN_INFO, LOG_FIP, + "2764 READ_FCF_RECORD:\n" + "\tFCF_Index : x%x\n" + "\tFCF_Avail : x%x\n" + "\tFCF_Valid : x%x\n" + "\tFIP_Priority : x%x\n" + "\tMAC_Provider : x%x\n" + "\tLowest VLANID : x%x\n" + "\tFCF_MAC Addr : x%x:%x:%x:%x:%x:%x\n" + "\tFabric_Name : x%x:%x:%x:%x:%x:%x:%x:%x\n" + "\tSwitch_Name : x%x:%x:%x:%x:%x:%x:%x:%x\n" + "\tNext_FCF_Index: x%x\n", + bf_get(lpfc_fcf_record_fcf_index, fcf_record), + bf_get(lpfc_fcf_record_fcf_avail, fcf_record), + bf_get(lpfc_fcf_record_fcf_valid, fcf_record), + fcf_record->fip_priority, + bf_get(lpfc_fcf_record_mac_addr_prov, fcf_record), + vlan_id, + bf_get(lpfc_fcf_record_mac_0, fcf_record), + bf_get(lpfc_fcf_record_mac_1, fcf_record), + bf_get(lpfc_fcf_record_mac_2, fcf_record), + bf_get(lpfc_fcf_record_mac_3, fcf_record), + bf_get(lpfc_fcf_record_mac_4, fcf_record), + bf_get(lpfc_fcf_record_mac_5, fcf_record), + bf_get(lpfc_fcf_record_fab_name_0, fcf_record), + bf_get(lpfc_fcf_record_fab_name_1, fcf_record), + bf_get(lpfc_fcf_record_fab_name_2, fcf_record), + bf_get(lpfc_fcf_record_fab_name_3, fcf_record), + bf_get(lpfc_fcf_record_fab_name_4, fcf_record), + bf_get(lpfc_fcf_record_fab_name_5, fcf_record), + bf_get(lpfc_fcf_record_fab_name_6, fcf_record), + bf_get(lpfc_fcf_record_fab_name_7, fcf_record), + bf_get(lpfc_fcf_record_switch_name_0, fcf_record), + bf_get(lpfc_fcf_record_switch_name_1, fcf_record), + bf_get(lpfc_fcf_record_switch_name_2, fcf_record), + bf_get(lpfc_fcf_record_switch_name_3, fcf_record), + bf_get(lpfc_fcf_record_switch_name_4, fcf_record), + bf_get(lpfc_fcf_record_switch_name_5, fcf_record), + bf_get(lpfc_fcf_record_switch_name_6, fcf_record), + bf_get(lpfc_fcf_record_switch_name_7, fcf_record), + next_fcf_index); +} + +/** + * lpfc_mbx_cmpl_fcf_scan_read_fcf_rec - fcf scan read_fcf mbox cmpl handler. + * @phba: pointer to lpfc hba data structure. + * @mboxq: pointer to mailbox object. + * + * This function iterates through all the fcf records available in + * HBA and chooses the optimal FCF record for discovery. After finding + * the FCF for discovery it registers the FCF record and kicks start + * discovery. + * If FCF_IN_USE flag is set in currently used FCF, the routine tries to + * use an FCF record which matches fabric name and mac address of the + * currently used FCF record. + * If the driver supports only one FCF, it will try to use the FCF record + * used by BOOT_BIOS. + */ +void +lpfc_mbx_cmpl_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) +{ + struct fcf_record *new_fcf_record; + uint32_t boot_flag, addr_mode; + uint16_t fcf_index, next_fcf_index; + struct lpfc_fcf_rec *fcf_rec = NULL; + uint16_t vlan_id; + int rc; + + /* If there is pending FCoE event restart FCF table scan */ + if (lpfc_check_pending_fcoe_event(phba, 0)) { + lpfc_sli4_mbox_cmd_free(phba, mboxq); + return; + } + + /* Parse the FCF record from the non-embedded mailbox command */ + new_fcf_record = lpfc_sli4_fcf_rec_mbox_parse(phba, mboxq, + &next_fcf_index); + if (!new_fcf_record) { + lpfc_printf_log(phba, KERN_WARNING, LOG_FIP, + "2765 Mailbox command READ_FCF_RECORD " + "failed to retrieve a FCF record.\n"); + /* Let next new FCF event trigger fast failover */ + spin_lock_irq(&phba->hbalock); + phba->hba_flag &= ~FCF_DISC_INPROGRESS; + spin_unlock_irq(&phba->hbalock); + lpfc_sli4_mbox_cmd_free(phba, mboxq); + return; + } + + /* Check the FCF record against the connection list */ rc = lpfc_match_fcf_conn_list(phba, new_fcf_record, &boot_flag, &addr_mode, &vlan_id); + + /* Log the FCF record information if turned on */ + lpfc_sli4_log_fcf_record_info(phba, new_fcf_record, vlan_id, + next_fcf_index); + /* * If the fcf record does not match with connect list entries - * read the next entry. + * read the next entry; otherwise, this is an eligible FCF + * record for round robin FCF failover. */ - if (!rc) + if (!rc) { + lpfc_printf_log(phba, KERN_WARNING, LOG_FIP, + "2781 FCF record fcf_index:x%x failed FCF " + "connection list check, fcf_avail:x%x, " + "fcf_valid:x%x\n", + bf_get(lpfc_fcf_record_fcf_index, + new_fcf_record), + bf_get(lpfc_fcf_record_fcf_avail, + new_fcf_record), + bf_get(lpfc_fcf_record_fcf_valid, + new_fcf_record)); goto read_next_fcf; + } else { + fcf_index = bf_get(lpfc_fcf_record_fcf_index, new_fcf_record); + rc = lpfc_sli4_fcf_rr_index_set(phba, fcf_index); + if (rc) + goto read_next_fcf; + } + /* * If this is not the first FCF discovery of the HBA, use last * FCF record for the discovery. The condition that a rescan * matches the in-use FCF record: fabric name, switch name, mac * address, and vlan_id. */ - spin_lock_irqsave(&phba->hbalock, iflags); + spin_lock_irq(&phba->hbalock); if (phba->fcf.fcf_flag & FCF_IN_USE) { if (lpfc_fab_name_match(phba->fcf.current_rec.fabric_name, new_fcf_record) && @@ -1652,9 +1756,8 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) else if (phba->fcf.fcf_flag & FCF_REDISC_FOV) /* If in fast failover, mark it's completed */ phba->fcf.fcf_flag &= ~(FCF_REDISC_FOV | - FCF_DEAD_FOVER | - FCF_CVL_FOVER); - spin_unlock_irqrestore(&phba->hbalock, iflags); + FCF_DISCOVERY); + spin_unlock_irq(&phba->hbalock); goto out; } /* @@ -1665,7 +1768,7 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) * next candidate. */ if (!(phba->fcf.fcf_flag & FCF_REDISC_FOV)) { - spin_unlock_irqrestore(&phba->hbalock, iflags); + spin_unlock_irq(&phba->hbalock); goto read_next_fcf; } } @@ -1688,7 +1791,7 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) /* Choose this FCF record */ __lpfc_update_fcf_record(phba, fcf_rec, new_fcf_record, addr_mode, vlan_id, BOOT_ENABLE); - spin_unlock_irqrestore(&phba->hbalock, iflags); + spin_unlock_irq(&phba->hbalock); goto read_next_fcf; } /* @@ -1697,7 +1800,7 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) * the next FCF record. */ if (!boot_flag && (fcf_rec->flag & BOOT_ENABLE)) { - spin_unlock_irqrestore(&phba->hbalock, iflags); + spin_unlock_irq(&phba->hbalock); goto read_next_fcf; } /* @@ -1709,7 +1812,7 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) __lpfc_update_fcf_record(phba, fcf_rec, new_fcf_record, addr_mode, vlan_id, 0); } - spin_unlock_irqrestore(&phba->hbalock, iflags); + spin_unlock_irq(&phba->hbalock); goto read_next_fcf; } /* @@ -1722,7 +1825,7 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) BOOT_ENABLE : 0)); phba->fcf.fcf_flag |= FCF_AVAILABLE; } - spin_unlock_irqrestore(&phba->hbalock, iflags); + spin_unlock_irq(&phba->hbalock); goto read_next_fcf; read_next_fcf: @@ -1738,9 +1841,22 @@ read_next_fcf: * FCF scan inprogress, and do nothing */ if (!(phba->fcf.failover_rec.flag & RECORD_VALID)) { - spin_lock_irqsave(&phba->hbalock, iflags); + lpfc_printf_log(phba, KERN_WARNING, LOG_FIP, + "2782 No suitable FCF record " + "found during this round of " + "post FCF rediscovery scan: " + "fcf_evt_tag:x%x, fcf_index: " + "x%x\n", + phba->fcoe_eventtag_at_fcf_scan, + bf_get(lpfc_fcf_record_fcf_index, + new_fcf_record)); + /* + * Let next new FCF event trigger fast + * failover + */ + spin_lock_irq(&phba->hbalock); phba->hba_flag &= ~FCF_DISC_INPROGRESS; - spin_unlock_irqrestore(&phba->hbalock, iflags); + spin_unlock_irq(&phba->hbalock); return; } /* @@ -1752,18 +1868,23 @@ read_next_fcf: * record. */ - /* unregister the current in-use FCF record */ + /* Unregister the current in-use FCF record */ lpfc_unregister_fcf(phba); - /* replace in-use record with the new record */ + + /* Replace in-use record with the new record */ memcpy(&phba->fcf.current_rec, &phba->fcf.failover_rec, sizeof(struct lpfc_fcf_rec)); /* mark the FCF fast failover completed */ - spin_lock_irqsave(&phba->hbalock, iflags); - phba->fcf.fcf_flag &= ~(FCF_REDISC_FOV | - FCF_DEAD_FOVER | - FCF_CVL_FOVER); - spin_unlock_irqrestore(&phba->hbalock, iflags); + spin_lock_irq(&phba->hbalock); + phba->fcf.fcf_flag &= ~FCF_REDISC_FOV; + spin_unlock_irq(&phba->hbalock); + /* + * Set up the initial registered FCF index for FLOGI + * round robin FCF failover. + */ + phba->fcf.fcf_rr_init_indx = + phba->fcf.failover_rec.fcf_indx; /* Register to the new FCF record */ lpfc_register_fcf(phba); } else { @@ -1776,13 +1897,25 @@ read_next_fcf: return; /* * Otherwise, initial scan or post linkdown rescan, - * register with the best fit FCF record found so - * far through the scanning process. + * register with the best FCF record found so far + * through the FCF scanning process. + */ + + /* mark the initial FCF discovery completed */ + spin_lock_irq(&phba->hbalock); + phba->fcf.fcf_flag &= ~FCF_INIT_DISC; + spin_unlock_irq(&phba->hbalock); + /* + * Set up the initial registered FCF index for FLOGI + * round robin FCF failover */ + phba->fcf.fcf_rr_init_indx = + phba->fcf.current_rec.fcf_indx; + /* Register to the new FCF record */ lpfc_register_fcf(phba); } } else - lpfc_sli4_read_fcf_record(phba, next_fcf_index); + lpfc_sli4_fcf_scan_read_fcf_rec(phba, next_fcf_index); return; out: @@ -1793,6 +1926,141 @@ out: } /** + * lpfc_mbx_cmpl_fcf_rr_read_fcf_rec - fcf round robin read_fcf mbox cmpl hdler + * @phba: pointer to lpfc hba data structure. + * @mboxq: pointer to mailbox object. + * + * This is the callback function for FLOGI failure round robin FCF failover + * read FCF record mailbox command from the eligible FCF record bmask for + * performing the failover. If the FCF read back is not valid/available, it + * fails through to retrying FLOGI to the currently registered FCF again. + * Otherwise, if the FCF read back is valid and available, it will set the + * newly read FCF record to the failover FCF record, unregister currently + * registered FCF record, copy the failover FCF record to the current + * FCF record, and then register the current FCF record before proceeding + * to trying FLOGI on the new failover FCF. + */ +void +lpfc_mbx_cmpl_fcf_rr_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) +{ + struct fcf_record *new_fcf_record; + uint32_t boot_flag, addr_mode; + uint16_t next_fcf_index; + uint16_t current_fcf_index; + uint16_t vlan_id; + + /* If link state is not up, stop the round robin failover process */ + if (phba->link_state < LPFC_LINK_UP) { + spin_lock_irq(&phba->hbalock); + phba->fcf.fcf_flag &= ~FCF_DISCOVERY; + spin_unlock_irq(&phba->hbalock); + lpfc_sli4_mbox_cmd_free(phba, mboxq); + return; + } + + /* Parse the FCF record from the non-embedded mailbox command */ + new_fcf_record = lpfc_sli4_fcf_rec_mbox_parse(phba, mboxq, + &next_fcf_index); + if (!new_fcf_record) { + lpfc_printf_log(phba, KERN_WARNING, LOG_FIP, + "2766 Mailbox command READ_FCF_RECORD " + "failed to retrieve a FCF record.\n"); + goto out; + } + + /* Get the needed parameters from FCF record */ + lpfc_match_fcf_conn_list(phba, new_fcf_record, &boot_flag, + &addr_mode, &vlan_id); + + /* Log the FCF record information if turned on */ + lpfc_sli4_log_fcf_record_info(phba, new_fcf_record, vlan_id, + next_fcf_index); + + /* Upload new FCF record to the failover FCF record */ + spin_lock_irq(&phba->hbalock); + __lpfc_update_fcf_record(phba, &phba->fcf.failover_rec, + new_fcf_record, addr_mode, vlan_id, + (boot_flag ? BOOT_ENABLE : 0)); + spin_unlock_irq(&phba->hbalock); + + current_fcf_index = phba->fcf.current_rec.fcf_indx; + + /* Unregister the current in-use FCF record */ + lpfc_unregister_fcf(phba); + + /* Replace in-use record with the new record */ + memcpy(&phba->fcf.current_rec, &phba->fcf.failover_rec, + sizeof(struct lpfc_fcf_rec)); + + lpfc_printf_log(phba, KERN_INFO, LOG_FIP, + "2783 FLOGI round robin FCF failover from FCF " + "(index:x%x) to FCF (index:x%x).\n", + current_fcf_index, + bf_get(lpfc_fcf_record_fcf_index, new_fcf_record)); + +out: + lpfc_sli4_mbox_cmd_free(phba, mboxq); + lpfc_register_fcf(phba); +} + +/** + * lpfc_mbx_cmpl_read_fcf_rec - read fcf completion handler. + * @phba: pointer to lpfc hba data structure. + * @mboxq: pointer to mailbox object. + * + * This is the callback function of read FCF record mailbox command for + * updating the eligible FCF bmask for FLOGI failure round robin FCF + * failover when a new FCF event happened. If the FCF read back is + * valid/available and it passes the connection list check, it updates + * the bmask for the eligible FCF record for round robin failover. + */ +void +lpfc_mbx_cmpl_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) +{ + struct fcf_record *new_fcf_record; + uint32_t boot_flag, addr_mode; + uint16_t fcf_index, next_fcf_index; + uint16_t vlan_id; + int rc; + + /* If link state is not up, no need to proceed */ + if (phba->link_state < LPFC_LINK_UP) + goto out; + + /* If FCF discovery period is over, no need to proceed */ + if (phba->fcf.fcf_flag & FCF_DISCOVERY) + goto out; + + /* Parse the FCF record from the non-embedded mailbox command */ + new_fcf_record = lpfc_sli4_fcf_rec_mbox_parse(phba, mboxq, + &next_fcf_index); + if (!new_fcf_record) { + lpfc_printf_log(phba, KERN_INFO, LOG_FIP, + "2767 Mailbox command READ_FCF_RECORD " + "failed to retrieve a FCF record.\n"); + goto out; + } + + /* Check the connection list for eligibility */ + rc = lpfc_match_fcf_conn_list(phba, new_fcf_record, &boot_flag, + &addr_mode, &vlan_id); + + /* Log the FCF record information if turned on */ + lpfc_sli4_log_fcf_record_info(phba, new_fcf_record, vlan_id, + next_fcf_index); + + if (!rc) + goto out; + + /* Update the eligible FCF record index bmask */ + fcf_index = bf_get(lpfc_fcf_record_fcf_index, new_fcf_record); + rc = lpfc_sli4_fcf_rr_index_set(phba, fcf_index); + +out: + lpfc_sli4_mbox_cmd_free(phba, mboxq); +} + +/** * lpfc_init_vpi_cmpl - Completion handler for init_vpi mbox command. * @phba: pointer to lpfc hba data structure. * @mboxq: pointer to mailbox data structure. @@ -2190,10 +2458,20 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) spin_unlock_irq(&phba->hbalock); return; } + /* This is the initial FCF discovery scan */ + phba->fcf.fcf_flag |= FCF_INIT_DISC; spin_unlock_irq(&phba->hbalock); - rc = lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST); - if (rc) + lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY, + "2778 Start FCF table scan at linkup\n"); + + rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba, + LPFC_FCOE_FCF_GET_FIRST); + if (rc) { + spin_lock_irq(&phba->hbalock); + phba->fcf.fcf_flag &= ~FCF_INIT_DISC; + spin_unlock_irq(&phba->hbalock); goto out; + } } return; @@ -3383,8 +3661,12 @@ lpfc_unreg_hba_rpis(struct lpfc_hba *phba) shost = lpfc_shost_from_vport(vports[i]); spin_lock_irq(shost->host_lock); list_for_each_entry(ndlp, &vports[i]->fc_nodes, nlp_listp) { - if (ndlp->nlp_flag & NLP_RPI_VALID) + if (ndlp->nlp_flag & NLP_RPI_VALID) { + /* The mempool_alloc might sleep */ + spin_unlock_irq(shost->host_lock); lpfc_unreg_rpi(vports[i], ndlp); + spin_lock_irq(shost->host_lock); + } } spin_unlock_irq(shost->host_lock); } @@ -4770,13 +5052,21 @@ lpfc_unregister_fcf_rescan(struct lpfc_hba *phba) (phba->link_state < LPFC_LINK_UP)) return; - rc = lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST); + /* This is considered as the initial FCF discovery scan */ + spin_lock_irq(&phba->hbalock); + phba->fcf.fcf_flag |= FCF_INIT_DISC; + spin_unlock_irq(&phba->hbalock); + rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba, LPFC_FCOE_FCF_GET_FIRST); - if (rc) + if (rc) { + spin_lock_irq(&phba->hbalock); + phba->fcf.fcf_flag &= ~FCF_INIT_DISC; + spin_unlock_irq(&phba->hbalock); lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, "2553 lpfc_unregister_unused_fcf failed " "to read FCF record HBA state x%x\n", phba->pport->port_state); + } } /** diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index ff45e33..ea44239 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -2201,8 +2201,8 @@ __lpfc_sli4_stop_fcf_redisc_wait_timer(struct lpfc_hba *phba) { /* Clear pending FCF rediscovery wait and failover in progress flags */ phba->fcf.fcf_flag &= ~(FCF_REDISC_PEND | - FCF_DEAD_FOVER | - FCF_CVL_FOVER); + FCF_DEAD_DISC | + FCF_ACVL_DISC); /* Now, try to stop the timer */ del_timer(&phba->fcf.redisc_wait); } @@ -2943,6 +2943,9 @@ lpfc_sli4_fcf_redisc_wait_tmo(unsigned long ptr) /* FCF rediscovery event to worker thread */ phba->fcf.fcf_flag |= FCF_REDISC_EVT; spin_unlock_irq(&phba->hbalock); + lpfc_printf_log(phba, KERN_INFO, LOG_FIP, + "2776 FCF rediscover wait timer expired, post " + "a worker thread event for FCF table scan\n"); /* wake up worker thread */ lpfc_worker_wake_up(phba); } @@ -3300,10 +3303,11 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, switch (event_type) { case LPFC_FCOE_EVENT_TYPE_NEW_FCF: case LPFC_FCOE_EVENT_TYPE_FCF_PARAM_MOD: - lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, - "2546 New FCF found index 0x%x tag 0x%x\n", - acqe_fcoe->index, - acqe_fcoe->event_tag); + lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY, + "2546 New FCF found/FCF parameter modified event: " + "evt_tag:x%x, fcf_index:x%x\n", + acqe_fcoe->event_tag, acqe_fcoe->index); + spin_lock_irq(&phba->hbalock); if ((phba->fcf.fcf_flag & FCF_SCAN_DONE) || (phba->hba_flag & FCF_DISC_INPROGRESS)) { @@ -3314,6 +3318,7 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, spin_unlock_irq(&phba->hbalock); break; } + if (phba->fcf.fcf_flag & FCF_REDISC_EVT) { /* * If fast FCF failover rescan event is pending, @@ -3324,12 +3329,33 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, } spin_unlock_irq(&phba->hbalock); - /* Read the FCF table and re-discover SAN. */ - rc = lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST); + if ((phba->fcf.fcf_flag & FCF_DISCOVERY) && + !(phba->fcf.fcf_flag & FCF_REDISC_FOV)) { + /* + * During period of FCF discovery, read the FCF + * table record indexed by the event to update + * FCF round robin failover eligible FCF bmask. + */ + lpfc_printf_log(phba, KERN_INFO, LOG_FIP | + LOG_DISCOVERY, + "2779 Read new FCF record with " + "fcf_index:x%x for updating FCF " + "round robin failover bmask\n", + acqe_fcoe->index); + rc = lpfc_sli4_read_fcf_rec(phba, acqe_fcoe->index); + } + + /* Otherwise, scan the entire FCF table and re-discover SAN */ + lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY, + "2770 Start FCF table scan due to new FCF " + "event: evt_tag:x%x, fcf_index:x%x\n", + acqe_fcoe->event_tag, acqe_fcoe->index); + rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba, + LPFC_FCOE_FCF_GET_FIRST); if (rc) - lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, - "2547 Read FCF record failed 0x%x\n", - rc); + lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY, + "2547 Issue FCF scan read FCF mailbox " + "command failed 0x%x\n", rc); break; case LPFC_FCOE_EVENT_TYPE_FCF_TABLE_FULL: @@ -3340,7 +3366,7 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, break; case LPFC_FCOE_EVENT_TYPE_FCF_DEAD: - lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, + lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY, "2549 FCF disconnected from network index 0x%x" " tag 0x%x\n", acqe_fcoe->index, acqe_fcoe->event_tag); @@ -3349,21 +3375,32 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, break; /* We request port to rediscover the entire FCF table for * a fast recovery from case that the current FCF record - * is no longer valid if the last CVL event hasn't already - * triggered process. + * is no longer valid if we are not in the middle of FCF + * failover process already. */ spin_lock_irq(&phba->hbalock); - if (phba->fcf.fcf_flag & FCF_CVL_FOVER) { + if (phba->fcf.fcf_flag & FCF_DISCOVERY) { spin_unlock_irq(&phba->hbalock); + /* Update FLOGI FCF failover eligible FCF bmask */ + lpfc_sli4_fcf_rr_index_clear(phba, acqe_fcoe->index); break; } /* Mark the fast failover process in progress */ - phba->fcf.fcf_flag |= FCF_DEAD_FOVER; + phba->fcf.fcf_flag |= FCF_DEAD_DISC; spin_unlock_irq(&phba->hbalock); + lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY, + "2771 Start FCF fast failover process due to " + "FCF DEAD event: evt_tag:x%x, fcf_index:x%x " + "\n", acqe_fcoe->event_tag, acqe_fcoe->index); rc = lpfc_sli4_redisc_fcf_table(phba); if (rc) { + lpfc_printf_log(phba, KERN_ERR, LOG_FIP | + LOG_DISCOVERY, + "2772 Issue FCF rediscover mabilbox " + "command failed, fail through to FCF " + "dead event\n"); spin_lock_irq(&phba->hbalock); - phba->fcf.fcf_flag &= ~FCF_DEAD_FOVER; + phba->fcf.fcf_flag &= ~FCF_DEAD_DISC; spin_unlock_irq(&phba->hbalock); /* * Last resort will fail over by treating this @@ -3378,7 +3415,7 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, lpfc_sli4_perform_all_vport_cvl(phba); break; case LPFC_FCOE_EVENT_TYPE_CVL: - lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, + lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY, "2718 Clear Virtual Link Received for VPI 0x%x" " tag 0x%x\n", acqe_fcoe->index, acqe_fcoe->event_tag); vport = lpfc_find_vport_by_vpid(phba, @@ -3419,21 +3456,31 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, * Otherwise, we request port to rediscover * the entire FCF table for a fast recovery * from possible case that the current FCF - * is no longer valid if the FCF_DEAD event - * hasn't already triggered process. + * is no longer valid if we are not already + * in the FCF failover process. */ spin_lock_irq(&phba->hbalock); - if (phba->fcf.fcf_flag & FCF_DEAD_FOVER) { + if (phba->fcf.fcf_flag & FCF_DISCOVERY) { spin_unlock_irq(&phba->hbalock); break; } /* Mark the fast failover process in progress */ - phba->fcf.fcf_flag |= FCF_CVL_FOVER; + phba->fcf.fcf_flag |= FCF_ACVL_DISC; spin_unlock_irq(&phba->hbalock); + lpfc_printf_log(phba, KERN_INFO, LOG_FIP | + LOG_DISCOVERY, + "2773 Start FCF fast failover due " + "to CVL event: evt_tag:x%x\n", + acqe_fcoe->event_tag); rc = lpfc_sli4_redisc_fcf_table(phba); if (rc) { + lpfc_printf_log(phba, KERN_ERR, LOG_FIP | + LOG_DISCOVERY, + "2774 Issue FCF rediscover " + "mabilbox command failed, " + "through to CVL event\n"); spin_lock_irq(&phba->hbalock); - phba->fcf.fcf_flag &= ~FCF_CVL_FOVER; + phba->fcf.fcf_flag &= ~FCF_ACVL_DISC; spin_unlock_irq(&phba->hbalock); /* * Last resort will be re-try on the @@ -3537,11 +3584,14 @@ void lpfc_sli4_fcf_redisc_event_proc(struct lpfc_hba *phba) spin_unlock_irq(&phba->hbalock); /* Scan FCF table from the first entry to re-discover SAN */ - rc = lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST); + lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY, + "2777 Start FCF table scan after FCF " + "rediscovery quiescent period over\n"); + rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba, LPFC_FCOE_FCF_GET_FIRST); if (rc) - lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, - "2747 Post FCF rediscovery read FCF record " - "failed 0x%x\n", rc); + lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY, + "2747 Issue FCF scan read FCF mailbox " + "command failed 0x%x\n", rc); } /** @@ -3833,6 +3883,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) int rc, i, hbq_count, buf_size, dma_buf_size, max_buf_size; uint8_t pn_page[LPFC_MAX_SUPPORTED_PAGES] = {0}; struct lpfc_mqe *mqe; + int longs; /* Before proceed, wait for POST done and device ready */ rc = lpfc_sli4_post_status_check(phba); @@ -4009,13 +4060,24 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) goto out_free_active_sgl; } + /* Allocate eligible FCF bmask memory for FCF round robin failover */ + longs = (LPFC_SLI4_FCF_TBL_INDX_MAX + BITS_PER_LONG - 1)/BITS_PER_LONG; + phba->fcf.fcf_rr_bmask = kzalloc(longs * sizeof(unsigned long), + GFP_KERNEL); + if (!phba->fcf.fcf_rr_bmask) { + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, + "2759 Failed allocate memory for FCF round " + "robin failover bmask\n"); + goto out_remove_rpi_hdrs; + } + phba->sli4_hba.fcp_eq_hdl = kzalloc((sizeof(struct lpfc_fcp_eq_hdl) * phba->cfg_fcp_eq_count), GFP_KERNEL); if (!phba->sli4_hba.fcp_eq_hdl) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "2572 Failed allocate memory for fast-path " "per-EQ handle array\n"); - goto out_remove_rpi_hdrs; + goto out_free_fcf_rr_bmask; } phba->sli4_hba.msix_entries = kzalloc((sizeof(struct msix_entry) * @@ -4068,6 +4130,8 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) out_free_fcp_eq_hdl: kfree(phba->sli4_hba.fcp_eq_hdl); +out_free_fcf_rr_bmask: + kfree(phba->fcf.fcf_rr_bmask); out_remove_rpi_hdrs: lpfc_sli4_remove_rpi_hdrs(phba); out_free_active_sgl: @@ -4113,6 +4177,9 @@ lpfc_sli4_driver_resource_unset(struct lpfc_hba *phba) lpfc_sli4_remove_rpi_hdrs(phba); lpfc_sli4_remove_rpis(phba); + /* Free eligible FCF index bmask */ + kfree(phba->fcf.fcf_rr_bmask); + /* Free the ELS sgl list */ lpfc_free_active_sgl(phba); lpfc_free_sgl_list(phba); diff --git a/drivers/scsi/lpfc/lpfc_logmsg.h b/drivers/scsi/lpfc/lpfc_logmsg.h index 954ba57..bb59e92 100644 --- a/drivers/scsi/lpfc/lpfc_logmsg.h +++ b/drivers/scsi/lpfc/lpfc_logmsg.h @@ -35,6 +35,7 @@ #define LOG_VPORT 0x00004000 /* NPIV events */ #define LOF_SECURITY 0x00008000 /* Security events */ #define LOG_EVENT 0x00010000 /* CT,TEMP,DUMP, logging */ +#define LOG_FIP 0x00020000 /* FIP events */ #define LOG_ALL_MSG 0xffffffff /* LOG all messages */ #define lpfc_printf_vlog(vport, level, mask, fmt, arg...) \ diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c index 6c4dce1..1e61ae3 100644 --- a/drivers/scsi/lpfc/lpfc_mbox.c +++ b/drivers/scsi/lpfc/lpfc_mbox.c @@ -1748,7 +1748,7 @@ lpfc_sli4_mbox_opcode_get(struct lpfc_hba *phba, struct lpfcMboxq *mbox) } /** - * lpfc_sli4_mbx_read_fcf_record - Allocate and construct read fcf mbox cmd + * lpfc_sli4_mbx_read_fcf_rec - Allocate and construct read fcf mbox cmd * @phba: pointer to lpfc hba data structure. * @fcf_index: index to fcf table. * @@ -1759,9 +1759,9 @@ lpfc_sli4_mbox_opcode_get(struct lpfc_hba *phba, struct lpfcMboxq *mbox) * NULL. **/ int -lpfc_sli4_mbx_read_fcf_record(struct lpfc_hba *phba, - struct lpfcMboxq *mboxq, - uint16_t fcf_index) +lpfc_sli4_mbx_read_fcf_rec(struct lpfc_hba *phba, + struct lpfcMboxq *mboxq, + uint16_t fcf_index) { void *virt_addr; dma_addr_t phys_addr; diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index bb6a442..fe6660c 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -11996,15 +11996,19 @@ lpfc_sli4_build_dflt_fcf_record(struct lpfc_hba *phba, } /** - * lpfc_sli4_read_fcf_record - Read the driver's default FCF Record. + * lpfc_sli4_fcf_scan_read_fcf_rec - Read hba fcf record for fcf scan. * @phba: pointer to lpfc hba data structure. * @fcf_index: FCF table entry offset. * - * This routine is invoked to read up to @fcf_num of FCF record from the - * device starting with the given @fcf_index. + * This routine is invoked to scan the entire FCF table by reading FCF + * record and processing it one at a time starting from the @fcf_index + * for initial FCF discovery or fast FCF failover rediscovery. + * + * Return 0 if the mailbox command is submitted sucessfully, none 0 + * otherwise. **/ int -lpfc_sli4_read_fcf_record(struct lpfc_hba *phba, uint16_t fcf_index) +lpfc_sli4_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, uint16_t fcf_index) { int rc = 0, error; LPFC_MBOXQ_t *mboxq; @@ -12016,17 +12020,17 @@ lpfc_sli4_read_fcf_record(struct lpfc_hba *phba, uint16_t fcf_index) "2000 Failed to allocate mbox for " "READ_FCF cmd\n"); error = -ENOMEM; - goto fail_fcfscan; + goto fail_fcf_scan; } /* Construct the read FCF record mailbox command */ - rc = lpfc_sli4_mbx_read_fcf_record(phba, mboxq, fcf_index); + rc = lpfc_sli4_mbx_read_fcf_rec(phba, mboxq, fcf_index); if (rc) { error = -EINVAL; - goto fail_fcfscan; + goto fail_fcf_scan; } /* Issue the mailbox command asynchronously */ mboxq->vport = phba->pport; - mboxq->mbox_cmpl = lpfc_mbx_cmpl_read_fcf_record; + mboxq->mbox_cmpl = lpfc_mbx_cmpl_fcf_scan_read_fcf_rec; rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT); if (rc == MBX_NOT_FINISHED) error = -EIO; @@ -12034,9 +12038,13 @@ lpfc_sli4_read_fcf_record(struct lpfc_hba *phba, uint16_t fcf_index) spin_lock_irq(&phba->hbalock); phba->hba_flag |= FCF_DISC_INPROGRESS; spin_unlock_irq(&phba->hbalock); + /* Reset FCF round robin index bmask for new scan */ + if (fcf_index == LPFC_FCOE_FCF_GET_FIRST) + memset(phba->fcf.fcf_rr_bmask, 0, + sizeof(*phba->fcf.fcf_rr_bmask)); error = 0; } -fail_fcfscan: +fail_fcf_scan: if (error) { if (mboxq) lpfc_sli4_mbox_cmd_free(phba, mboxq); @@ -12049,6 +12057,181 @@ fail_fcfscan: } /** + * lpfc_sli4_fcf_rr_read_fcf_rec - Read hba fcf record for round robin fcf. + * @phba: pointer to lpfc hba data structure. + * @fcf_index: FCF table entry offset. + * + * This routine is invoked to read an FCF record indicated by @fcf_index + * and to use it for FLOGI round robin FCF failover. + * + * Return 0 if the mailbox command is submitted sucessfully, none 0 + * otherwise. + **/ +int +lpfc_sli4_fcf_rr_read_fcf_rec(struct lpfc_hba *phba, uint16_t fcf_index) +{ + int rc = 0, error; + LPFC_MBOXQ_t *mboxq; + + mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); + if (!mboxq) { + lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_INIT, + "2763 Failed to allocate mbox for " + "READ_FCF cmd\n"); + error = -ENOMEM; + goto fail_fcf_read; + } + /* Construct the read FCF record mailbox command */ + rc = lpfc_sli4_mbx_read_fcf_rec(phba, mboxq, fcf_index); + if (rc) { + error = -EINVAL; + goto fail_fcf_read; + } + /* Issue the mailbox command asynchronously */ + mboxq->vport = phba->pport; + mboxq->mbox_cmpl = lpfc_mbx_cmpl_fcf_rr_read_fcf_rec; + rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT); + if (rc == MBX_NOT_FINISHED) + error = -EIO; + else + error = 0; + +fail_fcf_read: + if (error && mboxq) + lpfc_sli4_mbox_cmd_free(phba, mboxq); + return error; +} + +/** + * lpfc_sli4_read_fcf_rec - Read hba fcf record for update eligible fcf bmask. + * @phba: pointer to lpfc hba data structure. + * @fcf_index: FCF table entry offset. + * + * This routine is invoked to read an FCF record indicated by @fcf_index to + * determine whether it's eligible for FLOGI round robin failover list. + * + * Return 0 if the mailbox command is submitted sucessfully, none 0 + * otherwise. + **/ +int +lpfc_sli4_read_fcf_rec(struct lpfc_hba *phba, uint16_t fcf_index) +{ + int rc = 0, error; + LPFC_MBOXQ_t *mboxq; + + mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); + if (!mboxq) { + lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_INIT, + "2758 Failed to allocate mbox for " + "READ_FCF cmd\n"); + error = -ENOMEM; + goto fail_fcf_read; + } + /* Construct the read FCF record mailbox command */ + rc = lpfc_sli4_mbx_read_fcf_rec(phba, mboxq, fcf_index); + if (rc) { + error = -EINVAL; + goto fail_fcf_read; + } + /* Issue the mailbox command asynchronously */ + mboxq->vport = phba->pport; + mboxq->mbox_cmpl = lpfc_mbx_cmpl_read_fcf_rec; + rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT); + if (rc == MBX_NOT_FINISHED) + error = -EIO; + else + error = 0; + +fail_fcf_read: + if (error && mboxq) + lpfc_sli4_mbox_cmd_free(phba, mboxq); + return error; +} + +/** + * lpfc_sli4_fcf_rr_next_index_get - Get next eligible fcf record index + * @phba: pointer to lpfc hba data structure. + * + * This routine is to get the next eligible FCF record index in a round + * robin fashion. If the next eligible FCF record index equals to the + * initial round robin FCF record index, LPFC_FCOE_FCF_NEXT_NONE (0xFFFF) + * shall be returned, otherwise, the next eligible FCF record's index + * shall be returned. + **/ +uint16_t +lpfc_sli4_fcf_rr_next_index_get(struct lpfc_hba *phba) +{ + uint16_t next_fcf_index; + + /* Search from the currently registered FCF index */ + next_fcf_index = find_next_bit(phba->fcf.fcf_rr_bmask, + LPFC_SLI4_FCF_TBL_INDX_MAX, + phba->fcf.current_rec.fcf_indx); + /* Wrap around condition on phba->fcf.fcf_rr_bmask */ + if (next_fcf_index >= LPFC_SLI4_FCF_TBL_INDX_MAX) + next_fcf_index = find_next_bit(phba->fcf.fcf_rr_bmask, + LPFC_SLI4_FCF_TBL_INDX_MAX, 0); + /* Round robin failover stop condition */ + if (next_fcf_index == phba->fcf.fcf_rr_init_indx) + return LPFC_FCOE_FCF_NEXT_NONE; + + return next_fcf_index; +} + +/** + * lpfc_sli4_fcf_rr_index_set - Set bmask with eligible fcf record index + * @phba: pointer to lpfc hba data structure. + * + * This routine sets the FCF record index in to the eligible bmask for + * round robin failover search. It checks to make sure that the index + * does not go beyond the range of the driver allocated bmask dimension + * before setting the bit. + * + * Returns 0 if the index bit successfully set, otherwise, it returns + * -EINVAL. + **/ +int +lpfc_sli4_fcf_rr_index_set(struct lpfc_hba *phba, uint16_t fcf_index) +{ + if (fcf_index >= LPFC_SLI4_FCF_TBL_INDX_MAX) { + lpfc_printf_log(phba, KERN_ERR, LOG_FIP, + "2610 HBA FCF index reached driver's " + "book keeping dimension: fcf_index:%d, " + "driver_bmask_max:%d\n", + fcf_index, LPFC_SLI4_FCF_TBL_INDX_MAX); + return -EINVAL; + } + /* Set the eligible FCF record index bmask */ + set_bit(fcf_index, phba->fcf.fcf_rr_bmask); + + return 0; +} + +/** + * lpfc_sli4_fcf_rr_index_set - Clear bmask from eligible fcf record index + * @phba: pointer to lpfc hba data structure. + * + * This routine clears the FCF record index from the eligible bmask for + * round robin failover search. It checks to make sure that the index + * does not go beyond the range of the driver allocated bmask dimension + * before clearing the bit. + **/ +void +lpfc_sli4_fcf_rr_index_clear(struct lpfc_hba *phba, uint16_t fcf_index) +{ + if (fcf_index >= LPFC_SLI4_FCF_TBL_INDX_MAX) { + lpfc_printf_log(phba, KERN_ERR, LOG_FIP, + "2762 HBA FCF index goes beyond driver's " + "book keeping dimension: fcf_index:%d, " + "driver_bmask_max:%d\n", + fcf_index, LPFC_SLI4_FCF_TBL_INDX_MAX); + return; + } + /* Clear the eligible FCF record index bmask */ + clear_bit(fcf_index, phba->fcf.fcf_rr_bmask); +} + +/** * lpfc_mbx_cmpl_redisc_fcf_table - completion routine for rediscover FCF table * @phba: pointer to lpfc hba data structure. * @@ -12069,13 +12252,13 @@ lpfc_mbx_cmpl_redisc_fcf_table(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox) shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &redisc_fcf->header.cfg_shdr.response); if (shdr_status || shdr_add_status) { - lpfc_printf_log(phba, KERN_ERR, LOG_SLI, + lpfc_printf_log(phba, KERN_ERR, LOG_FIP, "2746 Requesting for FCF rediscovery failed " "status x%x add_status x%x\n", shdr_status, shdr_add_status); - if (phba->fcf.fcf_flag & FCF_CVL_FOVER) { + if (phba->fcf.fcf_flag & FCF_ACVL_DISC) { spin_lock_irq(&phba->hbalock); - phba->fcf.fcf_flag &= ~FCF_CVL_FOVER; + phba->fcf.fcf_flag &= ~FCF_ACVL_DISC; spin_unlock_irq(&phba->hbalock); /* * CVL event triggered FCF rediscover request failed, @@ -12084,7 +12267,7 @@ lpfc_mbx_cmpl_redisc_fcf_table(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox) lpfc_retry_pport_discovery(phba); } else { spin_lock_irq(&phba->hbalock); - phba->fcf.fcf_flag &= ~FCF_DEAD_FOVER; + phba->fcf.fcf_flag &= ~FCF_DEAD_DISC; spin_unlock_irq(&phba->hbalock); /* * DEAD FCF event triggered FCF rediscover request @@ -12093,12 +12276,16 @@ lpfc_mbx_cmpl_redisc_fcf_table(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox) */ lpfc_sli4_fcf_dead_failthrough(phba); } - } else + } else { + lpfc_printf_log(phba, KERN_INFO, LOG_FIP, + "2775 Start FCF rediscovery quiescent period " + "wait timer before scaning FCF table\n"); /* * Start FCF rediscovery wait timer for pending FCF * before rescan FCF record table. */ lpfc_fcf_redisc_wait_start_timer(phba); + } mempool_free(mbox, phba->mbox_mem_pool); } @@ -12117,6 +12304,9 @@ lpfc_sli4_redisc_fcf_table(struct lpfc_hba *phba) struct lpfc_mbx_redisc_fcf_tbl *redisc_fcf; int rc, length; + /* Cancel retry delay timers to all vports before FCF rediscover */ + lpfc_cancel_all_vport_retry_delay_timer(phba); + mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); if (!mbox) { lpfc_printf_log(phba, KERN_ERR, LOG_SLI, diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index 2169cd2..4a35e7b 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h @@ -153,17 +153,27 @@ struct lpfc_fcf { #define FCF_REGISTERED 0x02 /* FCF registered with FW */ #define FCF_SCAN_DONE 0x04 /* FCF table scan done */ #define FCF_IN_USE 0x08 /* Atleast one discovery completed */ -#define FCF_DEAD_FOVER 0x10 /* FCF DEAD triggered fast FCF failover */ -#define FCF_CVL_FOVER 0x20 /* CVL triggered fast FCF failover */ -#define FCF_REDISC_PEND 0x40 /* FCF rediscovery pending */ -#define FCF_REDISC_EVT 0x80 /* FCF rediscovery event to worker thread */ -#define FCF_REDISC_FOV 0x100 /* Post FCF rediscovery fast failover */ +#define FCF_INIT_DISC 0x10 /* Initial FCF discovery */ +#define FCF_DEAD_DISC 0x20 /* FCF DEAD fast FCF failover discovery */ +#define FCF_ACVL_DISC 0x40 /* All CVL fast FCF failover discovery */ +#define FCF_DISCOVERY (FCF_INIT_DISC | FCF_DEAD_DISC | FCF_ACVL_DISC) +#define FCF_REDISC_PEND 0x80 /* FCF rediscovery pending */ +#define FCF_REDISC_EVT 0x100 /* FCF rediscovery event to worker thread */ +#define FCF_REDISC_FOV 0x200 /* Post FCF rediscovery fast failover */ uint32_t addr_mode; + uint16_t fcf_rr_init_indx; struct lpfc_fcf_rec current_rec; struct lpfc_fcf_rec failover_rec; struct timer_list redisc_wait; + unsigned long *fcf_rr_bmask; /* Eligible FCF indexes for RR failover */ }; +/* + * Maximum FCF table index, it is for driver internal book keeping, it + * just needs to be no less than the supported HBA's FCF table size. + */ +#define LPFC_SLI4_FCF_TBL_INDX_MAX 32 + #define LPFC_REGION23_SIGNATURE "RG23" #define LPFC_REGION23_VERSION 1 #define LPFC_REGION23_LAST_REC 0xff @@ -472,8 +482,8 @@ void lpfc_sli4_mbox_cmd_free(struct lpfc_hba *, struct lpfcMboxq *); void lpfc_sli4_mbx_sge_set(struct lpfcMboxq *, uint32_t, dma_addr_t, uint32_t); void lpfc_sli4_mbx_sge_get(struct lpfcMboxq *, uint32_t, struct lpfc_mbx_sge *); -int lpfc_sli4_mbx_read_fcf_record(struct lpfc_hba *, struct lpfcMboxq *, - uint16_t); +int lpfc_sli4_mbx_read_fcf_rec(struct lpfc_hba *, struct lpfcMboxq *, + uint16_t); void lpfc_sli4_hba_reset(struct lpfc_hba *); struct lpfc_queue *lpfc_sli4_queue_alloc(struct lpfc_hba *, uint32_t, @@ -532,8 +542,13 @@ int lpfc_sli4_init_vpi(struct lpfc_hba *, uint16_t); uint32_t lpfc_sli4_cq_release(struct lpfc_queue *, bool); uint32_t lpfc_sli4_eq_release(struct lpfc_queue *, bool); void lpfc_sli4_fcfi_unreg(struct lpfc_hba *, uint16_t); -int lpfc_sli4_read_fcf_record(struct lpfc_hba *, uint16_t); -void lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *, LPFC_MBOXQ_t *); +int lpfc_sli4_fcf_scan_read_fcf_rec(struct lpfc_hba *, uint16_t); +int lpfc_sli4_fcf_rr_read_fcf_rec(struct lpfc_hba *, uint16_t); +int lpfc_sli4_read_fcf_rec(struct lpfc_hba *, uint16_t); +void lpfc_mbx_cmpl_fcf_scan_read_fcf_rec(struct lpfc_hba *, LPFC_MBOXQ_t *); +void lpfc_mbx_cmpl_fcf_rr_read_fcf_rec(struct lpfc_hba *, LPFC_MBOXQ_t *); +void lpfc_mbx_cmpl_read_fcf_rec(struct lpfc_hba *, LPFC_MBOXQ_t *); +int lpfc_sli4_unregister_fcf(struct lpfc_hba *); int lpfc_sli4_post_status_check(struct lpfc_hba *); uint8_t lpfc_sli4_mbox_opcode_get(struct lpfc_hba *, struct lpfcMboxq *); -- cgit v0.10.2 From 74315ad00b8ed41e9f97fe322942fa9883517ed1 Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 26 Feb 2010 14:16:25 -0500 Subject: [SCSI] lpfc 8.3.10: Update Driver version to 8.3.10 Signed-off-by: James Smart Signed-off-by: James Bottomley diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index ac276aa..013deec 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.h @@ -18,7 +18,7 @@ * included with this package. * *******************************************************************/ -#define LPFC_DRIVER_VERSION "8.3.9" +#define LPFC_DRIVER_VERSION "8.3.10" #define LPFC_DRIVER_NAME "lpfc" #define LPFC_SP_DRIVER_HANDLER_NAME "lpfc:sp" #define LPFC_FP_DRIVER_HANDLER_NAME "lpfc:fp" -- cgit v0.10.2 From bb2d3de1885cd69a5fc92af99c4e0c05eb5fc122 Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Tue, 2 Mar 2010 08:44:34 -0500 Subject: [SCSI] sd: Fix VPD buffer allocations Commit e3deec09 incorrectly assumed that the B0 and B1 page lengths were limited to 32 bytes. The B0 VPD page length is defined to be 64 bytes when the device supports thin provisioning. B1 is always defined to be 64 bytes. Signed-off-by: Martin K. Petersen Reported-by: Dan Carpenter Signed-off-by: James Bottomley diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 1dd4d84..f999538 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1948,7 +1948,7 @@ static void sd_read_block_limits(struct scsi_disk *sdkp) { struct request_queue *q = sdkp->disk->queue; unsigned int sector_sz = sdkp->device->sector_size; - const int vpd_len = 32; + const int vpd_len = 64; unsigned char *buffer = kmalloc(vpd_len, GFP_KERNEL); if (!buffer || @@ -1998,7 +1998,7 @@ static void sd_read_block_characteristics(struct scsi_disk *sdkp) { unsigned char *buffer; u16 rot; - const int vpd_len = 32; + const int vpd_len = 64; buffer = kmalloc(vpd_len, GFP_KERNEL); -- cgit v0.10.2 From 98e1e0f07c3f1820b8ac424569ee9e9916d3665b Mon Sep 17 00:00:00 2001 From: Boaz Harrosh Date: Fri, 19 Feb 2010 11:46:24 -0800 Subject: [SCSI] libosd: Fix unchecked err return found by smatch Doing CHECK="smatch --two-passes gives: drivers/scsi/osd/osd_initiator.c +1435 osd_finalize_request warning: assignment to 'ret' was never used Which is an unchecked possible allocation failure, Fixed. Reported-by: Dan Carpenter Signed-off-by: Boaz Harrosh Signed-off-by: James Bottomley diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c index 2422347..60de850 100644 --- a/drivers/scsi/osd/osd_initiator.c +++ b/drivers/scsi/osd/osd_initiator.c @@ -1433,6 +1433,10 @@ int osd_finalize_request(struct osd_request *or, cdbh->command_specific_options |= or->attributes_mode; if (or->attributes_mode == OSD_CDB_GET_ATTR_PAGE_SET_ONE) { ret = _osd_req_finalize_attr_page(or); + if (ret) { + OSD_DEBUG("_osd_req_finalize_attr_page failed\n"); + return ret; + } } else { /* TODO: I think that for the GET_ATTR command these 2 should * be reversed to keep them in execution order (for embeded -- cgit v0.10.2 From fac829fdcaf451a20106cbc468ff886466320956 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Wed, 3 Mar 2010 11:06:56 +0530 Subject: [SCSI] raid_attrs: fix dependency problems RAID attributes uses scsi_is_sdev_device() to gate some SCSI specific checking code. This causes two problems. Firstly if SCSI == n just defining scsi_is_sdev_device() to return false might not be enough to prevent gcc from emitting the code (and thus referring to undefined symbols), so this needs surrounding with an ifdef. Secondly, using scsi_is_sdev_device() when SCSI is either y or m gives a subtle problem in the m case: raid_attrs must also be m to use the symbol. Do the usual Kconfig jiggery-pokery to fix this. Reported-by: Randy Dunlap Signed-off-by: James Bottomley diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 9191d1e..75f2336 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -1,9 +1,15 @@ menu "SCSI device support" +config SCSI_MOD + tristate + default y if SCSI=n || SCSI=y + default m if SCSI=m + config RAID_ATTRS tristate "RAID Transport Class" default n depends on BLOCK + depends on SCSI_MOD ---help--- Provides RAID diff --git a/drivers/scsi/raid_class.c b/drivers/scsi/raid_class.c index bd88349..2c146b4 100644 --- a/drivers/scsi/raid_class.c +++ b/drivers/scsi/raid_class.c @@ -63,6 +63,7 @@ static int raid_match(struct attribute_container *cont, struct device *dev) * emulated RAID devices, so start with SCSI */ struct raid_internal *i = ac_to_raid_internal(cont); +#if defined(CONFIG_SCSI) || defined(CONFIG_SCSI_MODULE) if (scsi_is_sdev_device(dev)) { struct scsi_device *sdev = to_scsi_device(dev); @@ -71,6 +72,7 @@ static int raid_match(struct attribute_container *cont, struct device *dev) return i->f->is_raid(dev); } +#endif /* FIXME: look at other subsystems too */ return 0; } -- cgit v0.10.2 From 4fa004373133ece3d9b1c0a7e243b0e53760b165 Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 1 Mar 2010 14:42:57 +0530 Subject: mac80211: Fix HT rate control configuration Handling HT configuration changes involved setting the channel with the new HT parameters and then issuing a rate_update() notification to the driver. This behavior changed after the off-channel changes. Now, the channel is not updated with the new HT params in enable_ht() - instead, it is now done when the scan work terminates. This results in the driver depending on stale information, defaulting to non-HT mode always. Fix this by passing the new channel type to the driver. Cc: stable@kernel.org Signed-off-by: Sujith Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index ac34a05..0e79e58 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -1323,7 +1323,7 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband, static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband, struct ieee80211_sta *sta, void *priv_sta, - u32 changed) + u32 changed, enum nl80211_channel_type oper_chan_type) { struct ath_softc *sc = priv; struct ath_rate_priv *ath_rc_priv = priv_sta; @@ -1340,8 +1340,8 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband, if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION) return; - if (sc->hw->conf.channel_type == NL80211_CHAN_HT40MINUS || - sc->hw->conf.channel_type == NL80211_CHAN_HT40PLUS) + if (oper_chan_type == NL80211_CHAN_HT40MINUS || + oper_chan_type == NL80211_CHAN_HT40PLUS) oper_cw40 = true; oper_sgi40 = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 80eb7cc..45d7d44 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -2426,7 +2426,8 @@ struct rate_control_ops { struct ieee80211_sta *sta, void *priv_sta); void (*rate_update)(void *priv, struct ieee80211_supported_band *sband, struct ieee80211_sta *sta, - void *priv_sta, u32 changed); + void *priv_sta, u32 changed, + enum nl80211_channel_type oper_chan_type); void (*free_sta)(void *priv, struct ieee80211_sta *sta, void *priv_sta); diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 5a26876..0ab284c 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -177,7 +177,8 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, sta = sta_info_get(sdata, bssid); if (sta) rate_control_rate_update(local, sband, sta, - IEEE80211_RC_HT_CHANGED); + IEEE80211_RC_HT_CHANGED, + local->oper_channel_type); rcu_read_unlock(); } diff --git a/net/mac80211/rate.h b/net/mac80211/rate.h index b6108bc..065a9619 100644 --- a/net/mac80211/rate.h +++ b/net/mac80211/rate.h @@ -66,7 +66,8 @@ static inline void rate_control_rate_init(struct sta_info *sta) static inline void rate_control_rate_update(struct ieee80211_local *local, struct ieee80211_supported_band *sband, - struct sta_info *sta, u32 changed) + struct sta_info *sta, u32 changed, + enum nl80211_channel_type oper_chan_type) { struct rate_control_ref *ref = local->rate_ctrl; struct ieee80211_sta *ista = &sta->sta; @@ -74,7 +75,7 @@ static inline void rate_control_rate_update(struct ieee80211_local *local, if (ref && ref->ops->rate_update) ref->ops->rate_update(ref->priv, sband, ista, - priv_sta, changed); + priv_sta, changed, oper_chan_type); } static inline void *rate_control_alloc_sta(struct rate_control_ref *ref, -- cgit v0.10.2 From 31f66be44a657a14e0ab3536e4877c66c9ce031e Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Wed, 3 Mar 2010 17:42:55 +0100 Subject: rt2x00: Export rt2x00soc_probe from rt2x00soc Export rt2x00soc_probe from rt2x00soc as it is used in rt2800pci. Otherwise loading rt2800pci gives "rt2800pci: Unknown symbol rt2x00soc_probe". Signed-off-by: Helmut Schaa Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/rt2x00/rt2x00soc.c b/drivers/net/wireless/rt2x00/rt2x00soc.c index 4efdc96..111c0ff 100644 --- a/drivers/net/wireless/rt2x00/rt2x00soc.c +++ b/drivers/net/wireless/rt2x00/rt2x00soc.c @@ -112,6 +112,7 @@ exit_free_device: return retval; } +EXPORT_SYMBOL_GPL(rt2x00soc_probe); int rt2x00soc_remove(struct platform_device *pdev) { -- cgit v0.10.2 From 122e4519cd5c224d4b8e681d368132b643e28f60 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Tue, 2 Mar 2010 13:32:44 +0000 Subject: IPv6: addrconf dad timer unnecessary bh_disable Timer code runs in bottom half, so there is no need for using _bh form of locking. Also check if device is not ready to avoid race with address that is no longer active. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 88fd8c5..e6cba9c 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -2850,9 +2850,9 @@ static void addrconf_dad_timer(unsigned long data) struct inet6_dev *idev = ifp->idev; struct in6_addr mcaddr; - read_lock_bh(&idev->lock); - if (idev->dead) { - read_unlock_bh(&idev->lock); + read_lock(&idev->lock); + if (idev->dead || !(idev->if_flags & IF_READY)) { + read_unlock(&idev->lock); goto out; } @@ -2864,7 +2864,7 @@ static void addrconf_dad_timer(unsigned long data) ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED); spin_unlock(&ifp->lock); - read_unlock_bh(&idev->lock); + read_unlock(&idev->lock); addrconf_dad_completed(ifp); @@ -2874,7 +2874,7 @@ static void addrconf_dad_timer(unsigned long data) ifp->probes--; addrconf_mod_timer(ifp, AC_DAD, ifp->idev->nd_parms->retrans_time); spin_unlock(&ifp->lock); - read_unlock_bh(&idev->lock); + read_unlock(&idev->lock); /* send a neighbour solicitation for our addr */ addrconf_addr_solict_mult(&ifp->addr, &mcaddr); -- cgit v0.10.2 From 5b2a19539c5f59c5a038d213ede723f0245d97cf Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Tue, 2 Mar 2010 13:32:45 +0000 Subject: IPv6: addrconf timer race The Router Solicitation timer races with device state changes because it doesn't lock the device. Use local variable to avoid one repeated dereference. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index e6cba9c..5f582f3 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -2739,28 +2739,29 @@ static int addrconf_ifdown(struct net_device *dev, int how) static void addrconf_rs_timer(unsigned long data) { struct inet6_ifaddr *ifp = (struct inet6_ifaddr *) data; + struct inet6_dev *idev = ifp->idev; - if (ifp->idev->cnf.forwarding) + read_lock(&idev->lock); + if (idev->dead || !(idev->if_flags & IF_READY)) goto out; - if (ifp->idev->if_flags & IF_RA_RCVD) { - /* - * Announcement received after solicitation - * was sent - */ + if (idev->cnf.forwarding) + goto out; + + /* Announcement received after solicitation was sent */ + if (idev->if_flags & IF_RA_RCVD) goto out; - } spin_lock(&ifp->lock); - if (ifp->probes++ < ifp->idev->cnf.rtr_solicits) { + if (ifp->probes++ < idev->cnf.rtr_solicits) { /* The wait after the last probe can be shorter */ addrconf_mod_timer(ifp, AC_RS, - (ifp->probes == ifp->idev->cnf.rtr_solicits) ? - ifp->idev->cnf.rtr_solicit_delay : - ifp->idev->cnf.rtr_solicit_interval); + (ifp->probes == idev->cnf.rtr_solicits) ? + idev->cnf.rtr_solicit_delay : + idev->cnf.rtr_solicit_interval); spin_unlock(&ifp->lock); - ndisc_send_rs(ifp->idev->dev, &ifp->addr, &in6addr_linklocal_allrouters); + ndisc_send_rs(idev->dev, &ifp->addr, &in6addr_linklocal_allrouters); } else { spin_unlock(&ifp->lock); /* @@ -2768,10 +2769,11 @@ static void addrconf_rs_timer(unsigned long data) * assumption any longer. */ printk(KERN_DEBUG "%s: no IPv6 routers present\n", - ifp->idev->dev->name); + idev->dev->name); } out: + read_unlock(&idev->lock); in6_ifa_put(ifp); } -- cgit v0.10.2 From 84e8b803f1e16f3a2b8b80f80a63fa2f2f8a9be6 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Tue, 2 Mar 2010 13:32:46 +0000 Subject: IPv6: addrconf notify when address is unavailable My recent change in net-next to retain permanent addresses caused regression. Device refcount would not go to zero when device was unregistered because left over anycast reference would hold ipv6 dev reference which would hold device references... The correct procedure is to call notify chain when address is no longer available for use. When interface comes back DAD timer will notify back that address is available. Also, link local addresses should be purged when interface is brought down. The address might be changed. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 5f582f3..7a4bf76 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -2649,11 +2649,11 @@ static int addrconf_ifdown(struct net_device *dev, int how) write_lock_bh(&addrconf_hash_lock); while ((ifa = *bifa) != NULL) { if (ifa->idev == idev && - (how || !(ifa->flags&IFA_F_PERMANENT))) { + (how || !(ifa->flags&IFA_F_PERMANENT) || + ipv6_addr_type(&ifa->addr) & IPV6_ADDR_LINKLOCAL)) { *bifa = ifa->lst_next; ifa->lst_next = NULL; - addrconf_del_timer(ifa); - in6_ifa_put(ifa); + __in6_ifa_put(ifa); continue; } bifa = &ifa->lst_next; @@ -2691,28 +2691,40 @@ static int addrconf_ifdown(struct net_device *dev, int how) #endif bifa = &idev->addr_list; while ((ifa = *bifa) != NULL) { - if (how == 0 && (ifa->flags&IFA_F_PERMANENT)) { - /* Retain permanent address on admin down */ + addrconf_del_timer(ifa); + + /* If just doing link down, and address is permanent + and not link-local, then retain it. */ + if (how == 0 && + (ifa->flags&IFA_F_PERMANENT) && + !(ipv6_addr_type(&ifa->addr) & IPV6_ADDR_LINKLOCAL)) { bifa = &ifa->if_next; - /* Restart DAD if needed when link comes back up */ - if ( !((dev->flags&(IFF_NOARP|IFF_LOOPBACK)) || - idev->cnf.accept_dad <= 0 || - (ifa->flags & IFA_F_NODAD))) - ifa->flags |= IFA_F_TENTATIVE; + /* If not doing DAD on this address, just keep it. */ + if ((dev->flags&(IFF_NOARP|IFF_LOOPBACK)) || + idev->cnf.accept_dad <= 0 || + (ifa->flags & IFA_F_NODAD)) + continue; + + /* If it was tentative already, no need to notify */ + if (ifa->flags & IFA_F_TENTATIVE) + continue; + + /* Flag it for later restoration when link comes up */ + ifa->flags |= IFA_F_TENTATIVE; + in6_ifa_hold(ifa); } else { *bifa = ifa->if_next; ifa->if_next = NULL; - ifa->dead = 1; - write_unlock_bh(&idev->lock); + } + write_unlock_bh(&idev->lock); - __ipv6_ifa_notify(RTM_DELADDR, ifa); - atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifa); - in6_ifa_put(ifa); + __ipv6_ifa_notify(RTM_DELADDR, ifa); + atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifa); + in6_ifa_put(ifa); - write_lock_bh(&idev->lock); - } + write_lock_bh(&idev->lock); } write_unlock_bh(&idev->lock); -- cgit v0.10.2 From 8f37ada5b5f6bfb4d251a7f510f249cb855b77b3 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Wed, 3 Mar 2010 08:19:59 +0000 Subject: IPv6: fix race between cleanup and add/delete address This solves a potential race problem during the cleanup process. The issue is that addrconf_ifdown() needs to traverse address list, but then drop lock to call the notifier. The version in -next could get confused if add/delete happened during this window. Original code (2.6.32 and earlier) was okay because all addresses were always deleted. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 7a4bf76..6cf3ee1 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -2615,7 +2615,7 @@ static void addrconf_bonding_change(struct net_device *dev, unsigned long event) static int addrconf_ifdown(struct net_device *dev, int how) { struct inet6_dev *idev; - struct inet6_ifaddr *ifa, **bifa; + struct inet6_ifaddr *ifa, *keep_list, **bifa; struct net *net = dev_net(dev); int i; @@ -2689,8 +2689,12 @@ static int addrconf_ifdown(struct net_device *dev, int how) write_lock_bh(&idev->lock); } #endif - bifa = &idev->addr_list; - while ((ifa = *bifa) != NULL) { + keep_list = NULL; + bifa = &keep_list; + while ((ifa = idev->addr_list) != NULL) { + idev->addr_list = ifa->if_next; + ifa->if_next = NULL; + addrconf_del_timer(ifa); /* If just doing link down, and address is permanent @@ -2698,6 +2702,9 @@ static int addrconf_ifdown(struct net_device *dev, int how) if (how == 0 && (ifa->flags&IFA_F_PERMANENT) && !(ipv6_addr_type(&ifa->addr) & IPV6_ADDR_LINKLOCAL)) { + + /* Move to holding list */ + *bifa = ifa; bifa = &ifa->if_next; /* If not doing DAD on this address, just keep it. */ @@ -2714,8 +2721,6 @@ static int addrconf_ifdown(struct net_device *dev, int how) ifa->flags |= IFA_F_TENTATIVE; in6_ifa_hold(ifa); } else { - *bifa = ifa->if_next; - ifa->if_next = NULL; ifa->dead = 1; } write_unlock_bh(&idev->lock); @@ -2726,6 +2731,9 @@ static int addrconf_ifdown(struct net_device *dev, int how) write_lock_bh(&idev->lock); } + + idev->addr_list = keep_list; + write_unlock_bh(&idev->lock); /* Step 5: Discard multicast list */ -- cgit v0.10.2 From c839d30a41dd92eb32d7fcfa2b4e99042fc64bf2 Mon Sep 17 00:00:00 2001 From: Mike Galbraith Date: Wed, 3 Mar 2010 04:46:50 +0000 Subject: net: add scheduler sync hint to tcp_prequeue(). Decreases the odds wakee will suffer from frequent cache misses. Signed-off-by: Mike Galbraith Signed-off-by: David S. Miller diff --git a/include/net/tcp.h b/include/net/tcp.h index 56f0aec..75be5a2 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -939,7 +939,7 @@ static inline int tcp_prequeue(struct sock *sk, struct sk_buff *skb) tp->ucopy.memory = 0; } else if (skb_queue_len(&tp->ucopy.prequeue) == 1) { - wake_up_interruptible_poll(sk->sk_sleep, + wake_up_interruptible_sync_poll(sk->sk_sleep, POLLIN | POLLRDNORM | POLLRDBAND); if (!inet_csk_ack_scheduled(sk)) inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK, -- cgit v0.10.2 From 6d55cb91a0020ac0d78edcad61efd6c8cf5785a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Wed, 3 Mar 2010 04:01:13 +0000 Subject: gre: fix hard header destination address checking ipgre_header() can be called with zero daddr when the gre device is configured as multipoint tunnel and still has the NOARP flag set (which is typically cleared by the userspace arp daemon). If the NOARP packets are not dropped, ipgre_tunnel_xmit() will take rt->rt_gateway (= NBMA IP) and use that for route look up (and may lead to bogus xfrm acquires). The multicast address check is removed as sending to multicast group should be ok. In fact, if gre device has a multicast address as destination ipgre_header is always called with multicast address. Signed-off-by: Timo Teras Signed-off-by: David S. Miller diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index c0c5274..f47c9f7 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -1144,12 +1144,9 @@ static int ipgre_header(struct sk_buff *skb, struct net_device *dev, if (saddr) memcpy(&iph->saddr, saddr, 4); - - if (daddr) { + if (daddr) memcpy(&iph->daddr, daddr, 4); - return t->hlen; - } - if (iph->daddr && !ipv4_is_multicast(iph->daddr)) + if (iph->daddr) return t->hlen; return -t->hlen; -- cgit v0.10.2 From d0021b252eaf65ca07ed14f0d66425dd9ccab9a6 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Wed, 3 Mar 2010 08:31:23 +0000 Subject: tipc: Fix oops on send prior to entering networked mode (v3) Fix TIPC to disallow sending to remote addresses prior to entering NET_MODE user programs can oops the kernel by sending datagrams via AF_TIPC prior to entering networked mode. The following backtrace has been observed: ID: 13459 TASK: ffff810014640040 CPU: 0 COMMAND: "tipc-client" [exception RIP: tipc_node_select_next_hop+90] RIP: ffffffff8869d3c3 RSP: ffff81002d9a5ab8 RFLAGS: 00010202 RAX: 0000000000000001 RBX: 0000000000000001 RCX: 0000000000000001 RDX: 0000000000000000 RSI: 0000000000000001 RDI: 0000000001001001 RBP: 0000000001001001 R8: 0074736575716552 R9: 0000000000000000 R10: ffff81003fbd0680 R11: 00000000000000c8 R12: 0000000000000008 R13: 0000000000000001 R14: 0000000000000001 R15: ffff810015c6ca00 ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018 RIP: 0000003cbd8d49a3 RSP: 00007fffc84e0be8 RFLAGS: 00010206 RAX: 000000000000002c RBX: ffffffff8005d116 RCX: 0000000000000000 RDX: 0000000000000008 RSI: 00007fffc84e0c00 RDI: 0000000000000003 RBP: 0000000000000000 R8: 00007fffc84e0c10 R9: 0000000000000010 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 00007fffc84e0d10 R14: 0000000000000000 R15: 00007fffc84e0c30 ORIG_RAX: 000000000000002c CS: 0033 SS: 002b What happens is that, when the tipc module in inserted it enters a standalone node mode in which communication to its own address is allowed <0.0.0> but not to other addresses, since the appropriate data structures have not been allocated yet (specifically the tipc_net pointer). There is nothing stopping a client from trying to send such a message however, and if that happens, we attempt to dereference tipc_net.zones while the pointer is still NULL, and explode. The fix is pretty straightforward. Since these oopses all arise from the dereference of global pointers prior to their assignment to allocated values, and since these allocations are small (about 2k total), lets convert these pointers to static arrays of the appropriate size. All the accesses to these bits consider 0/NULL to be a non match when searching, so all the lookups still work properly, and there is no longer a chance of a bad dererence anywhere. As a bonus, this lets us eliminate the setup/teardown routines for those pointers, and elimnates the need to preform any locking around them to prevent access while their being allocated/freed. I've updated the tipc_net structure to behave this way to fix the exact reported problem, and also fixed up the tipc_bearers and media_list arrays to fix an obvious simmilar problem that arises from issuing tipc-config commands to manipulate bearers/links prior to entering networked mode I've tested this for a few hours by running the sanity tests and stress test with the tipcutils suite, and nothing has fallen over. There have been a few lockdep warnings, but those were there before, and can be addressed later, as they didn't actually result in any deadlock. Signed-off-by: Neil Horman CC: Allan Stephens CC: David S. Miller CC: tipc-discussion@lists.sourceforge.net bearer.c | 37 ++++++------------------------------- bearer.h | 2 +- net.c | 25 ++++--------------------- 3 files changed, 11 insertions(+), 53 deletions(-) Signed-off-by: David S. Miller diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 327011f..7809137 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c @@ -45,10 +45,10 @@ #define MAX_ADDR_STR 32 -static struct media *media_list = NULL; +static struct media media_list[MAX_MEDIA]; static u32 media_count = 0; -struct bearer *tipc_bearers = NULL; +struct bearer tipc_bearers[MAX_BEARERS]; /** * media_name_valid - validate media name @@ -108,9 +108,11 @@ int tipc_register_media(u32 media_type, int res = -EINVAL; write_lock_bh(&tipc_net_lock); - if (!media_list) - goto exit; + if (tipc_mode != TIPC_NET_MODE) { + warn("Media <%s> rejected, not in networked mode yet\n", name); + goto exit; + } if (!media_name_valid(name)) { warn("Media <%s> rejected, illegal name\n", name); goto exit; @@ -660,33 +662,10 @@ int tipc_disable_bearer(const char *name) -int tipc_bearer_init(void) -{ - int res; - - write_lock_bh(&tipc_net_lock); - tipc_bearers = kcalloc(MAX_BEARERS, sizeof(struct bearer), GFP_ATOMIC); - media_list = kcalloc(MAX_MEDIA, sizeof(struct media), GFP_ATOMIC); - if (tipc_bearers && media_list) { - res = 0; - } else { - kfree(tipc_bearers); - kfree(media_list); - tipc_bearers = NULL; - media_list = NULL; - res = -ENOMEM; - } - write_unlock_bh(&tipc_net_lock); - return res; -} - void tipc_bearer_stop(void) { u32 i; - if (!tipc_bearers) - return; - for (i = 0; i < MAX_BEARERS; i++) { if (tipc_bearers[i].active) tipc_bearers[i].publ.blocked = 1; @@ -695,10 +674,6 @@ void tipc_bearer_stop(void) if (tipc_bearers[i].active) bearer_disable(tipc_bearers[i].publ.name); } - kfree(tipc_bearers); - kfree(media_list); - tipc_bearers = NULL; - media_list = NULL; media_count = 0; } diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h index ca57348..000228e 100644 --- a/net/tipc/bearer.h +++ b/net/tipc/bearer.h @@ -114,7 +114,7 @@ struct bearer_name { struct link; -extern struct bearer *tipc_bearers; +extern struct bearer tipc_bearers[]; void tipc_media_addr_printf(struct print_buf *pb, struct tipc_media_addr *a); struct sk_buff *tipc_media_get_names(void); diff --git a/net/tipc/net.c b/net/tipc/net.c index 7906608..f25b1cd 100644 --- a/net/tipc/net.c +++ b/net/tipc/net.c @@ -116,7 +116,8 @@ */ DEFINE_RWLOCK(tipc_net_lock); -struct network tipc_net = { NULL }; +struct _zone *tipc_zones[256] = { NULL, }; +struct network tipc_net = { tipc_zones }; struct tipc_node *tipc_net_select_remote_node(u32 addr, u32 ref) { @@ -158,28 +159,12 @@ void tipc_net_send_external_routes(u32 dest) } } -static int net_init(void) -{ - memset(&tipc_net, 0, sizeof(tipc_net)); - tipc_net.zones = kcalloc(tipc_max_zones + 1, sizeof(struct _zone *), GFP_ATOMIC); - if (!tipc_net.zones) { - return -ENOMEM; - } - return 0; -} - static void net_stop(void) { u32 z_num; - if (!tipc_net.zones) - return; - - for (z_num = 1; z_num <= tipc_max_zones; z_num++) { + for (z_num = 1; z_num <= tipc_max_zones; z_num++) tipc_zone_delete(tipc_net.zones[z_num]); - } - kfree(tipc_net.zones); - tipc_net.zones = NULL; } static void net_route_named_msg(struct sk_buff *buf) @@ -282,9 +267,7 @@ int tipc_net_start(u32 addr) tipc_named_reinit(); tipc_port_reinit(); - if ((res = tipc_bearer_init()) || - (res = net_init()) || - (res = tipc_cltr_init()) || + if ((res = tipc_cltr_init()) || (res = tipc_bclink_init())) { return res; } -- cgit v0.10.2 From 4c020a961a812ffae9846b917304cea504c3a733 Mon Sep 17 00:00:00 2001 From: David Dillow Date: Wed, 3 Mar 2010 16:33:10 +0000 Subject: r8169: use correct barrier between cacheable and non-cacheable memory r8169 needs certain writes to be visible to other CPUs or the NIC before touching the hardware, but was using smp_wmb() which is only required to order cacheable memory access. Switch to wmb() which is required to order both cacheable and non-cacheable memory. Noticed by Catalin Marinas and Paul Mackerras. Signed-off-by: David Dillow Signed-off-by: David S. Miller diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index dfc3573..9d3ebf3 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -4270,7 +4270,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, tp->cur_tx += frags + 1; - smp_wmb(); + wmb(); RTL_W8(TxPoll, NPQ); /* set polling bit */ @@ -4621,7 +4621,7 @@ static int rtl8169_poll(struct napi_struct *napi, int budget) * until it does. */ tp->intr_mask = 0xffff; - smp_wmb(); + wmb(); RTL_W16(IntrMask, tp->intr_event); } -- cgit v0.10.2 From 0eddba525cf4c3a4aab9feaf36b12b465290d4a7 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Wed, 3 Mar 2010 08:18:58 +0000 Subject: gianfar: Fix TX ring processing on SMP machines Starting with commit a3bc1f11e9b867a4f49505 ("gianfar: Revive SKB recycling") gianfar driver sooner or later stops transmitting any packets on SMP machines. start_xmit() prepares new skb for transmitting, generally it does three things: 1. sets up all BDs (marks them ready to send), except the first one. 2. stores skb into tx_queue->tx_skbuff so that clean_tx_ring() would cleanup it later. 3. sets up the first BD, i.e. marks it ready. Here is what clean_tx_ring() does: 1. reads skbs from tx_queue->tx_skbuff 2. checks if the *last* BD is ready. If it's still ready [to send] then it it isn't transmitted, so clean_tx_ring() returns. Otherwise it actually cleanups BDs. All is OK. Now, if there is just one BD, code flow: - start_xmit(): stores skb into tx_skbuff. Note that the first BD (which is also the last one) isn't marked as ready, yet. - clean_tx_ring(): sees that skb is not null, *and* its lstatus says that it is NOT ready (like if BD was sent), so it cleans it up (bad!) - start_xmit(): marks BD as ready [to send], but it's too late. We can fix this simply by reordering lstatus/tx_skbuff writes. Reported-by: Martyn Welch Bisected-by: Paul Gortmaker Signed-off-by: Anton Vorontsov Tested-by: Paul Gortmaker Tested-by: Martyn Welch Cc: Sandeep Gopalpet Cc: Stable [2.6.33] Signed-off-by: David S. Miller diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 6aa526e..c3f0619 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -2021,7 +2021,6 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) } /* setup the TxBD length and buffer pointer for the first BD */ - tx_queue->tx_skbuff[tx_queue->skb_curtx] = skb; txbdp_start->bufPtr = dma_map_single(&priv->ofdev->dev, skb->data, skb_headlen(skb), DMA_TO_DEVICE); @@ -2053,6 +2052,10 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) txbdp_start->lstatus = lstatus; + eieio(); /* force lstatus write before tx_skbuff */ + + tx_queue->tx_skbuff[tx_queue->skb_curtx] = skb; + /* Update the current skb pointer to the next entry we will use * (wrapping if necessary) */ tx_queue->skb_curtx = (tx_queue->skb_curtx + 1) & -- cgit v0.10.2 From a6f018e324ba91d0464cca6895447c2b89e6d578 Mon Sep 17 00:00:00 2001 From: Divy Le Ray Date: Wed, 3 Mar 2010 09:49:47 +0000 Subject: cxgb3: fix hot plug removal crash queue restart tasklets need to be stopped after napi handlers are stopped since the latter can restart them. So stop them after stopping napi. Signed-off-by: Divy Le Ray Signed-off-by: David S. Miller diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index 6fd968a..cecdec1 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c @@ -1280,6 +1280,7 @@ static void cxgb_down(struct adapter *adapter) free_irq_resources(adapter); quiesce_rx(adapter); + t3_sge_stop(adapter); flush_workqueue(cxgb3_wq); /* wait for external IRQ handler */ } -- cgit v0.10.2 From 4c32531324b83672f100692354b680625bcd7fba Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 4 Mar 2010 00:42:30 -0800 Subject: MAINTAINERS: Add netdev to bridge entry. Noticed by Ingo Molnar. Signed-off-by: David S. Miller diff --git a/MAINTAINERS b/MAINTAINERS index 34f52a1..dad4f57 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2095,6 +2095,7 @@ F: drivers/net/eexpress.* ETHERNET BRIDGE M: Stephen Hemminger L: bridge@lists.linux-foundation.org +L: netdev@vger.kernel.org W: http://www.linux-foundation.org/en/Net:Bridge S: Maintained F: include/linux/netfilter_bridge/ -- cgit v0.10.2 From 4c147dd81966bd4ba7f026476237ba67ea72d5d9 Mon Sep 17 00:00:00 2001 From: Krishna Gudipati Date: Wed, 3 Mar 2010 17:42:11 -0800 Subject: [SCSI] bfa: Added separate MSI-X module parameters. Added separate MSI-X module parameters to selectively enable / disable MSI-X interrupts for both Brocade HBA and CNA's. Signed-off-by: Krishna Gudipati Signed-off-by: James Bottomley diff --git a/drivers/scsi/bfa/bfad_attr.c b/drivers/scsi/bfa/bfad_attr.c index 9129ae3..adf801d 100644 --- a/drivers/scsi/bfa/bfad_attr.c +++ b/drivers/scsi/bfa/bfad_attr.c @@ -229,7 +229,9 @@ bfad_im_get_host_speed(struct Scsi_Host *shost) (struct bfad_im_port_s *) shost->hostdata[0]; struct bfad_s *bfad = im_port->bfad; struct bfa_pport_attr_s attr; + unsigned long flags; + spin_lock_irqsave(shost->host_lock, flags); bfa_pport_get_attr(&bfad->bfa, &attr); switch (attr.speed) { case BFA_PPORT_SPEED_8GBPS: @@ -248,6 +250,7 @@ bfad_im_get_host_speed(struct Scsi_Host *shost) fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN; break; } + spin_unlock_irqrestore(shost->host_lock, flags); } /** diff --git a/drivers/scsi/bfa/bfad_intr.c b/drivers/scsi/bfa/bfad_intr.c index 7de8832..2b7dbec 100644 --- a/drivers/scsi/bfa/bfad_intr.c +++ b/drivers/scsi/bfa/bfad_intr.c @@ -23,8 +23,10 @@ BFA_TRC_FILE(LDRV, INTR); /** * bfa_isr BFA driver interrupt functions */ -static int msix_disable; -module_param(msix_disable, int, S_IRUGO | S_IWUSR); +static int msix_disable_cb; +static int msix_disable_ct; +module_param(msix_disable_cb, int, S_IRUGO | S_IWUSR); +module_param(msix_disable_ct, int, S_IRUGO | S_IWUSR); /** * Line based interrupt handler. */ @@ -141,6 +143,7 @@ bfad_setup_intr(struct bfad_s *bfad) int error = 0; u32 mask = 0, i, num_bit = 0, max_bit = 0; struct msix_entry msix_entries[MAX_MSIX_ENTRY]; + struct pci_dev *pdev = bfad->pcidev; /* Call BFA to get the msix map for this PCI function. */ bfa_msix_getvecs(&bfad->bfa, &mask, &num_bit, &max_bit); @@ -148,7 +151,9 @@ bfad_setup_intr(struct bfad_s *bfad) /* Set up the msix entry table */ bfad_init_msix_entry(bfad, msix_entries, mask, max_bit); - if (!msix_disable) { + if ((pdev->device == BFA_PCI_DEVICE_ID_CT && !msix_disable_ct) || + (pdev->device != BFA_PCI_DEVICE_ID_CT && !msix_disable_cb)) { + error = pci_enable_msix(bfad->pcidev, msix_entries, bfad->nvec); if (error) { /* -- cgit v0.10.2 From 5c1fb1d55672a74d1c318f67cdddbb599df9a76c Mon Sep 17 00:00:00 2001 From: Krishna Gudipati Date: Wed, 3 Mar 2010 17:42:39 -0800 Subject: [SCSI] bfa: Defined a new LPS event to clear virtual link on a vport Clear virtual links was not propagated upwards to bfa from fw. This resulted in HBA and switch being in an inconsistent state. So defined a new LPS event for clear virtual link on a vport, and also now clear virtual link on a baseport, is sent as a link down event from the fw. Signed-off-by: Krishna Gudipati Signed-off-by: James Bottomley diff --git a/drivers/scsi/bfa/bfa_lps.c b/drivers/scsi/bfa/bfa_lps.c index 9844b45..c8c2564 100644 --- a/drivers/scsi/bfa/bfa_lps.c +++ b/drivers/scsi/bfa/bfa_lps.c @@ -49,7 +49,7 @@ static void bfa_lps_send_login(struct bfa_lps_s *lps); static void bfa_lps_send_logout(struct bfa_lps_s *lps); static void bfa_lps_login_comp(struct bfa_lps_s *lps); static void bfa_lps_logout_comp(struct bfa_lps_s *lps); - +static void bfa_lps_cvl_event(struct bfa_lps_s *lps); /** * lps_pvt BFA LPS private functions @@ -62,6 +62,7 @@ enum bfa_lps_event { BFA_LPS_SM_RESUME = 4, /* space present in reqq queue */ BFA_LPS_SM_DELETE = 5, /* lps delete from user */ BFA_LPS_SM_OFFLINE = 6, /* Link is offline */ + BFA_LPS_SM_RX_CVL = 7, /* Rx clear virtual link */ }; static void bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event); @@ -101,6 +102,7 @@ bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event) bfa_lps_free(lps); break; + case BFA_LPS_SM_RX_CVL: case BFA_LPS_SM_OFFLINE: break; @@ -162,6 +164,14 @@ bfa_lps_sm_loginwait(struct bfa_lps_s *lps, enum bfa_lps_event event) bfa_reqq_wcancel(&lps->wqe); break; + case BFA_LPS_SM_RX_CVL: + /* + * Login was not even sent out; so when getting out + * of this state, it will appear like a login retry + * after Clear virtual link + */ + break; + default: bfa_assert(0); } @@ -187,6 +197,15 @@ bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event) } break; + case BFA_LPS_SM_RX_CVL: + bfa_sm_set_state(lps, bfa_lps_sm_init); + + /* Let the vport module know about this event */ + bfa_lps_cvl_event(lps); + bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, + BFA_PL_EID_FIP_FCF_CVL, 0, "FCF Clear Virt. Link Rx"); + break; + case BFA_LPS_SM_OFFLINE: case BFA_LPS_SM_DELETE: bfa_sm_set_state(lps, bfa_lps_sm_init); @@ -396,6 +415,20 @@ bfa_lps_logout_rsp(struct bfa_s *bfa, struct bfi_lps_logout_rsp_s *rsp) } /** + * Firmware received a Clear virtual link request (for FCoE) + */ +static void +bfa_lps_rx_cvl_event(struct bfa_s *bfa, struct bfi_lps_cvl_event_s *cvl) +{ + struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); + struct bfa_lps_s *lps; + + lps = BFA_LPS_FROM_TAG(mod, cvl->lp_tag); + + bfa_sm_send_event(lps, BFA_LPS_SM_RX_CVL); +} + +/** * Space is available in request queue, resume queueing request to firmware. */ static void @@ -531,7 +564,39 @@ bfa_lps_logout_comp(struct bfa_lps_s *lps) bfa_cb_lps_flogo_comp(lps->bfa->bfad, lps->uarg); } +/** + * Clear virtual link completion handler for non-fcs + */ +static void +bfa_lps_cvl_event_cb(void *arg, bfa_boolean_t complete) +{ + struct bfa_lps_s *lps = arg; + + if (!complete) + return; + + /* Clear virtual link to base port will result in link down */ + if (lps->fdisc) + bfa_cb_lps_cvl_event(lps->bfa->bfad, lps->uarg); +} + +/** + * Received Clear virtual link event --direct call for fcs, + * queue for others + */ +static void +bfa_lps_cvl_event(struct bfa_lps_s *lps) +{ + if (!lps->bfa->fcs) { + bfa_cb_queue(lps->bfa, &lps->hcb_qe, bfa_lps_cvl_event_cb, + lps); + return; + } + /* Clear virtual link to base port will result in link down */ + if (lps->fdisc) + bfa_cb_lps_cvl_event(lps->bfa->bfad, lps->uarg); +} /** * lps_public BFA LPS public functions @@ -773,6 +838,10 @@ bfa_lps_isr(struct bfa_s *bfa, struct bfi_msg_s *m) bfa_lps_logout_rsp(bfa, msg.logout_rsp); break; + case BFI_LPS_H2I_CVL_EVENT: + bfa_lps_rx_cvl_event(bfa, msg.cvl_event); + break; + default: bfa_trc(bfa, m->mhdr.msg_id); bfa_assert(0); diff --git a/drivers/scsi/bfa/include/bfa_svc.h b/drivers/scsi/bfa/include/bfa_svc.h index 268d956..2e4372f 100644 --- a/drivers/scsi/bfa/include/bfa_svc.h +++ b/drivers/scsi/bfa/include/bfa_svc.h @@ -319,6 +319,7 @@ void bfa_cb_lps_flogi_comp(void *bfad, void *uarg, bfa_status_t status); void bfa_cb_lps_flogo_comp(void *bfad, void *uarg); void bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status); void bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg); +void bfa_cb_lps_cvl_event(void *bfad, void *uarg); #endif /* __BFA_SVC_H__ */ diff --git a/drivers/scsi/bfa/include/bfi/bfi_lps.h b/drivers/scsi/bfa/include/bfi/bfi_lps.h index c59d47b..7ed31bb 100644 --- a/drivers/scsi/bfa/include/bfi/bfi_lps.h +++ b/drivers/scsi/bfa/include/bfi/bfi_lps.h @@ -30,6 +30,7 @@ enum bfi_lps_h2i_msgs { enum bfi_lps_i2h_msgs { BFI_LPS_H2I_LOGIN_RSP = BFA_I2HM(1), BFI_LPS_H2I_LOGOUT_RSP = BFA_I2HM(2), + BFI_LPS_H2I_CVL_EVENT = BFA_I2HM(3), }; struct bfi_lps_login_req_s { @@ -77,6 +78,12 @@ struct bfi_lps_logout_rsp_s { u8 rsvd[2]; }; +struct bfi_lps_cvl_event_s { + struct bfi_mhdr_s mh; /* common msg header */ + u8 lp_tag; + u8 rsvd[3]; +}; + union bfi_lps_h2i_msg_u { struct bfi_mhdr_s *msg; struct bfi_lps_login_req_s *login_req; @@ -87,6 +94,7 @@ union bfi_lps_i2h_msg_u { struct bfi_msg_s *msg; struct bfi_lps_login_rsp_s *login_rsp; struct bfi_lps_logout_rsp_s *logout_rsp; + struct bfi_lps_cvl_event_s *cvl_event; }; #pragma pack() diff --git a/drivers/scsi/bfa/include/cs/bfa_plog.h b/drivers/scsi/bfa/include/cs/bfa_plog.h index 670f86e..f5bef63 100644 --- a/drivers/scsi/bfa/include/cs/bfa_plog.h +++ b/drivers/scsi/bfa/include/cs/bfa_plog.h @@ -80,7 +80,8 @@ enum bfa_plog_mid { BFA_PL_MID_HAL_FCXP = 4, BFA_PL_MID_HAL_UF = 5, BFA_PL_MID_FCS = 6, - BFA_PL_MID_MAX = 7 + BFA_PL_MID_LPS = 7, + BFA_PL_MID_MAX = 8 }; #define BFA_PL_MID_STRLEN 8 @@ -118,7 +119,11 @@ enum bfa_plog_eid { BFA_PL_EID_RSCN = 17, BFA_PL_EID_DEBUG = 18, BFA_PL_EID_MISC = 19, - BFA_PL_EID_MAX = 20 + BFA_PL_EID_FIP_FCF_DISC = 20, + BFA_PL_EID_FIP_FCF_CVL = 21, + BFA_PL_EID_LOGIN = 22, + BFA_PL_EID_LOGO = 23, + BFA_PL_EID_MAX = 24 }; #define BFA_PL_ENAME_STRLEN 8 diff --git a/drivers/scsi/bfa/vport.c b/drivers/scsi/bfa/vport.c index e90f1e3..8d18589 100644 --- a/drivers/scsi/bfa/vport.c +++ b/drivers/scsi/bfa/vport.c @@ -888,4 +888,15 @@ bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg) bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK); } +/** + * Received clear virtual link + */ +void +bfa_cb_lps_cvl_event(void *bfad, void *uarg) +{ + struct bfa_fcs_vport_s *vport = uarg; + /* Send an Offline followed by an ONLINE */ + bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_OFFLINE); + bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_ONLINE); +} -- cgit v0.10.2 From 2f9b8857a914b71ba1b84fb23a0a20a87de41c91 Mon Sep 17 00:00:00 2001 From: Krishna Gudipati Date: Wed, 3 Mar 2010 17:42:51 -0800 Subject: [SCSI] bfa: Enable IOC auto-recovery and IOC type fix. bfa_ioc.c: - Enable IOC auto-recovery by default. - When CNA is in FC mode, return IOC type as FC (not FCoE) bfa_iocfc.c: - Set fcmode before pci initialization/setup. Signed-off-by: Krishna Gudipati Signed-off-by: James Bottomley diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c index 397d7e9..569b35d 100644 --- a/drivers/scsi/bfa/bfa_ioc.c +++ b/drivers/scsi/bfa/bfa_ioc.c @@ -56,7 +56,7 @@ BFA_TRC_FILE(HAL, IOC); #define BFA_FLASH_CHUNK_NO(off) (off / BFI_FLASH_CHUNK_SZ_WORDS) #define BFA_FLASH_OFFSET_IN_CHUNK(off) (off % BFI_FLASH_CHUNK_SZ_WORDS) #define BFA_FLASH_CHUNK_ADDR(chunkno) (chunkno * BFI_FLASH_CHUNK_SZ_WORDS) -bfa_boolean_t bfa_auto_recover = BFA_FALSE; +bfa_boolean_t bfa_auto_recover = BFA_TRUE; /* * forward declarations @@ -1642,7 +1642,7 @@ bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_param) void bfa_ioc_auto_recover(bfa_boolean_t auto_recover) { - bfa_auto_recover = BFA_FALSE; + bfa_auto_recover = auto_recover; } @@ -2082,7 +2082,7 @@ bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr) ioc_attr->state = bfa_sm_to_state(ioc_sm_table, ioc->fsm); ioc_attr->port_id = ioc->port_id; - if (!ioc->ctdev) + if (!ioc->ctdev || ioc->fcmode) ioc_attr->ioc_type = BFA_IOC_TYPE_FC; else if (ioc->ioc_mc == BFI_MC_IOCFC) ioc_attr->ioc_type = BFA_IOC_TYPE_FCoE; diff --git a/drivers/scsi/bfa/bfa_iocfc.c b/drivers/scsi/bfa/bfa_iocfc.c index d7ab792..b5e7224 100644 --- a/drivers/scsi/bfa/bfa_iocfc.c +++ b/drivers/scsi/bfa/bfa_iocfc.c @@ -619,8 +619,6 @@ bfa_iocfc_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, bfa_ioc_attach(&bfa->ioc, bfa, &bfa_iocfc_cbfn, &bfa->timer_mod, bfa->trcmod, bfa->aen, bfa->logm); - bfa_ioc_pci_init(&bfa->ioc, pcidev, BFI_MC_IOCFC); - bfa_ioc_mbox_register(&bfa->ioc, bfa_mbox_isrs); /** * Choose FC (ssid: 0x1C) v/s FCoE (ssid: 0x14) mode. @@ -628,6 +626,9 @@ bfa_iocfc_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, if (0) bfa_ioc_set_fcmode(&bfa->ioc); + bfa_ioc_pci_init(&bfa->ioc, pcidev, BFI_MC_IOCFC); + bfa_ioc_mbox_register(&bfa->ioc, bfa_mbox_isrs); + bfa_iocfc_init_mem(bfa, bfad, cfg, pcidev); bfa_iocfc_mem_claim(bfa, cfg, meminfo); bfa_timer_init(&bfa->timer_mod); -- cgit v0.10.2 From ab5336189a12b6561a1b5708d782a4e27e2e3b79 Mon Sep 17 00:00:00 2001 From: Krishna Gudipati Date: Wed, 3 Mar 2010 17:43:09 -0800 Subject: [SCSI] bfa: Enable new halt interrupt in BFA. bfa_intr.c: Enable new halt interrupt in BFA. bfi_ctreg.h: Expose new halt interrupt bit definition to host. Signed-off-by: Krishna Gudipati Signed-off-by: James Bottomley diff --git a/drivers/scsi/bfa/bfa_intr.c b/drivers/scsi/bfa/bfa_intr.c index b36540e..ab463db 100644 --- a/drivers/scsi/bfa/bfa_intr.c +++ b/drivers/scsi/bfa/bfa_intr.c @@ -15,7 +15,7 @@ * General Public License for more details. */ #include -#include +#include #include #include #include @@ -96,7 +96,8 @@ bfa_isr_enable(struct bfa_s *bfa) bfa_msix_install(bfa); intr_unmask = (__HFN_INT_ERR_EMC | __HFN_INT_ERR_LPU0 | - __HFN_INT_ERR_LPU1 | __HFN_INT_ERR_PSS); + __HFN_INT_ERR_LPU1 | __HFN_INT_ERR_PSS | + __HFN_INT_LL_HALT); if (pci_func == 0) intr_unmask |= (__HFN_INT_CPE_Q0 | __HFN_INT_CPE_Q1 | @@ -205,7 +206,7 @@ bfa_msix_lpu_err(struct bfa_s *bfa, int vec) if (intr & (__HFN_INT_ERR_EMC | __HFN_INT_ERR_LPU0 | __HFN_INT_ERR_LPU1 | - __HFN_INT_ERR_PSS)) + __HFN_INT_ERR_PSS | __HFN_INT_LL_HALT)) bfa_msix_errint(bfa, intr); } diff --git a/drivers/scsi/bfa/include/bfi/bfi_ctreg.h b/drivers/scsi/bfa/include/bfi/bfi_ctreg.h index d3caa58..dd2992c 100644 --- a/drivers/scsi/bfa/include/bfi/bfi_ctreg.h +++ b/drivers/scsi/bfa/include/bfi/bfi_ctreg.h @@ -589,6 +589,7 @@ enum { #define __HFN_INT_MBOX_LPU1 0x00200000U #define __HFN_INT_MBOX1_LPU0 0x00400000U #define __HFN_INT_MBOX1_LPU1 0x00800000U +#define __HFN_INT_LL_HALT 0x01000000U #define __HFN_INT_CPE_MASK 0x000000ffU #define __HFN_INT_RME_MASK 0x0000ff00U -- cgit v0.10.2 From 5b098082e22c168b7df4c5c3cd924047cee7d995 Mon Sep 17 00:00:00 2001 From: Krishna Gudipati Date: Wed, 3 Mar 2010 17:43:19 -0800 Subject: [SCSI] bfa: Changes to support FDMI Driver Parameter Added a FCS function to be called during driver init, to set the FDMI Driver parameter. fdmi.c: Created a disabled state when fdmi is disabled. bfad.c: * Added fdmi_enable driver parameter. * Added support to call bfa_fcs_set_fdmi_param() to initialize fcs fdmi setting. Signed-off-by: Krishna Gudipati Signed-off-by: James Bottomley diff --git a/drivers/scsi/bfa/bfa_fcs.c b/drivers/scsi/bfa/bfa_fcs.c index 7cb39a3..50120c2 100644 --- a/drivers/scsi/bfa/bfa_fcs.c +++ b/drivers/scsi/bfa/bfa_fcs.c @@ -127,6 +127,23 @@ bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs, } /** + * @brief + * FCS FDMI Driver Parameter Initialization + * + * @param[in] fcs FCS instance + * @param[in] fdmi_enable TRUE/FALSE + * + * @return None + */ +void +bfa_fcs_set_fdmi_param(struct bfa_fcs_s *fcs, bfa_boolean_t fdmi_enable) +{ + + fcs->fdmi_enabled = fdmi_enable; + +} + +/** * FCS instance cleanup and exit. * * param[in] fcs FCS instance diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c index b52b773..8e2b2a2 100644 --- a/drivers/scsi/bfa/bfad.c +++ b/drivers/scsi/bfa/bfad.c @@ -53,6 +53,7 @@ static int log_level = BFA_LOG_WARNING; static int ioc_auto_recover = BFA_TRUE; static int ipfc_enable = BFA_FALSE; static int ipfc_mtu = -1; +static int fdmi_enable = BFA_TRUE; int bfa_lun_queue_depth = BFAD_LUN_QUEUE_DEPTH; int bfa_linkup_delay = -1; @@ -74,6 +75,7 @@ module_param(log_level, int, S_IRUGO | S_IWUSR); module_param(ioc_auto_recover, int, S_IRUGO | S_IWUSR); module_param(ipfc_enable, int, S_IRUGO | S_IWUSR); module_param(ipfc_mtu, int, S_IRUGO | S_IWUSR); +module_param(fdmi_enable, int, S_IRUGO | S_IWUSR); module_param(bfa_linkup_delay, int, S_IRUGO | S_IWUSR); /* @@ -748,6 +750,7 @@ bfad_drv_init(struct bfad_s *bfad) bfa_fcs_aen_init(&bfad->bfa_fcs, bfad->aen); bfa_fcs_init(&bfad->bfa_fcs, &bfad->bfa, bfad, BFA_FALSE); bfa_fcs_driver_info_init(&bfad->bfa_fcs, &driver_info); + bfa_fcs_set_fdmi_param(&bfad->bfa_fcs, fdmi_enable); spin_unlock_irqrestore(&bfad->bfad_lock, flags); bfad->bfad_flags |= BFAD_DRV_INIT_DONE; diff --git a/drivers/scsi/bfa/fdmi.c b/drivers/scsi/bfa/fdmi.c index df2a1e5..d76d922 100644 --- a/drivers/scsi/bfa/fdmi.c +++ b/drivers/scsi/bfa/fdmi.c @@ -116,6 +116,9 @@ static void bfa_fcs_port_fdmi_sm_rpa_retry(struct bfa_fcs_port_fdmi_s *fdmi, enum port_fdmi_event event); static void bfa_fcs_port_fdmi_sm_online(struct bfa_fcs_port_fdmi_s *fdmi, enum port_fdmi_event event); +static void bfa_fcs_port_fdmi_sm_disabled(struct bfa_fcs_port_fdmi_s *fdmi, + enum port_fdmi_event event); + /** * Start in offline state - awaiting MS to send start. */ @@ -479,6 +482,20 @@ bfa_fcs_port_fdmi_sm_online(struct bfa_fcs_port_fdmi_s *fdmi, } } +/** + * FDMI is disabled state. + */ +static void +bfa_fcs_port_fdmi_sm_disabled(struct bfa_fcs_port_fdmi_s *fdmi, + enum port_fdmi_event event) +{ + struct bfa_fcs_port_s *port = fdmi->ms->port; + + bfa_trc(port->fcs, port->port_cfg.pwwn); + bfa_trc(port->fcs, event); + + /* No op State. It can only be enabled at Driver Init. */ +} /** * RHBA : Register HBA Attributes. @@ -1201,7 +1218,10 @@ bfa_fcs_port_fdmi_init(struct bfa_fcs_port_ms_s *ms) struct bfa_fcs_port_fdmi_s *fdmi = &ms->fdmi; fdmi->ms = ms; - bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline); + if (ms->port->fcs->fdmi_enabled) + bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline); + else + bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_disabled); } void diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs.h b/drivers/scsi/bfa/include/fcs/bfa_fcs.h index 627669c..0396ec4 100644 --- a/drivers/scsi/bfa/include/fcs/bfa_fcs.h +++ b/drivers/scsi/bfa/include/fcs/bfa_fcs.h @@ -49,6 +49,7 @@ struct bfa_fcs_s { struct bfa_trc_mod_s *trcmod; /* tracing module */ struct bfa_aen_s *aen; /* aen component */ bfa_boolean_t vf_enabled; /* VF mode is enabled */ + bfa_boolean_t fdmi_enabled; /*!< FDMI is enabled */ bfa_boolean_t min_cfg; /* min cfg enabled/disabled */ u16 port_vfid; /* port default VF ID */ struct bfa_fcs_driver_info_s driver_info; @@ -64,6 +65,7 @@ void bfa_fcs_init(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad, bfa_boolean_t min_cfg); void bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs, struct bfa_fcs_driver_info_s *driver_info); +void bfa_fcs_set_fdmi_param(struct bfa_fcs_s *fcs, bfa_boolean_t fdmi_enable); void bfa_fcs_exit(struct bfa_fcs_s *fcs); void bfa_fcs_trc_init(struct bfa_fcs_s *fcs, struct bfa_trc_mod_s *trcmod); void bfa_fcs_log_init(struct bfa_fcs_s *fcs, struct bfa_log_mod_s *logmod); -- cgit v0.10.2 From 82794a2e4153657d12a0c29272e40b47eaadb748 Mon Sep 17 00:00:00 2001 From: Krishna Gudipati Date: Wed, 3 Mar 2010 17:43:30 -0800 Subject: [SCSI] bfa: New interface to handle firmware upgrade scenario Split bfa_fcs_init() into bfa_fcs_attach() and bfa_fcs_init(). Removed empty function definitions in FCS modules Modified driver to call bfa_fcs_attach() and bfa_fcs_init() as needed. Signed-off-by: Krishna Gudipati Signed-off-by: James Bottomley diff --git a/drivers/scsi/bfa/bfa_fcs.c b/drivers/scsi/bfa/bfa_fcs.c index 50120c2..3516172 100644 --- a/drivers/scsi/bfa/bfa_fcs.c +++ b/drivers/scsi/bfa/bfa_fcs.c @@ -36,6 +36,7 @@ * FCS sub-modules */ struct bfa_fcs_mod_s { + void (*attach) (struct bfa_fcs_s *fcs); void (*modinit) (struct bfa_fcs_s *fcs); void (*modexit) (struct bfa_fcs_s *fcs); }; @@ -43,12 +44,10 @@ struct bfa_fcs_mod_s { #define BFA_FCS_MODULE(_mod) { _mod ## _modinit, _mod ## _modexit } static struct bfa_fcs_mod_s fcs_modules[] = { - BFA_FCS_MODULE(bfa_fcs_pport), - BFA_FCS_MODULE(bfa_fcs_uf), - BFA_FCS_MODULE(bfa_fcs_fabric), - BFA_FCS_MODULE(bfa_fcs_vport), - BFA_FCS_MODULE(bfa_fcs_rport), - BFA_FCS_MODULE(bfa_fcs_fcpim), + { bfa_fcs_pport_attach, NULL, NULL }, + { bfa_fcs_uf_attach, NULL, NULL }, + { bfa_fcs_fabric_attach, bfa_fcs_fabric_modinit, + bfa_fcs_fabric_modexit }, }; /** @@ -71,16 +70,10 @@ bfa_fcs_exit_comp(void *fcs_cbarg) */ /** - * FCS instance initialization. - * - * param[in] fcs FCS instance - * param[in] bfa BFA instance - * param[in] bfad BFA driver instance - * - * return None + * fcs attach -- called once to initialize data structures at driver attach time */ void -bfa_fcs_init(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad, +bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad, bfa_boolean_t min_cfg) { int i; @@ -95,7 +88,24 @@ bfa_fcs_init(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad, for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) { mod = &fcs_modules[i]; - mod->modinit(fcs); + if (mod->attach) + mod->attach(fcs); + } +} + +/** + * fcs initialization, called once after bfa initialization is complete + */ +void +bfa_fcs_init(struct bfa_fcs_s *fcs) +{ + int i; + struct bfa_fcs_mod_s *mod; + + for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) { + mod = &fcs_modules[i]; + if (mod->modinit) + mod->modinit(fcs); } } @@ -160,10 +170,12 @@ bfa_fcs_exit(struct bfa_fcs_s *fcs) nmods = sizeof(fcs_modules) / sizeof(fcs_modules[0]); for (i = 0; i < nmods; i++) { - bfa_wc_up(&fcs->wc); mod = &fcs_modules[i]; - mod->modexit(fcs); + if (mod->modexit) { + bfa_wc_up(&fcs->wc); + mod->modexit(fcs); + } } bfa_wc_wait(&fcs->wc); diff --git a/drivers/scsi/bfa/bfa_fcs_port.c b/drivers/scsi/bfa/bfa_fcs_port.c index 9c4b24e..53808d0 100644 --- a/drivers/scsi/bfa/bfa_fcs_port.c +++ b/drivers/scsi/bfa/bfa_fcs_port.c @@ -55,14 +55,7 @@ bfa_fcs_pport_event_handler(void *cbarg, bfa_pport_event_t event) } void -bfa_fcs_pport_modinit(struct bfa_fcs_s *fcs) +bfa_fcs_pport_attach(struct bfa_fcs_s *fcs) { - bfa_pport_event_register(fcs->bfa, bfa_fcs_pport_event_handler, - fcs); -} - -void -bfa_fcs_pport_modexit(struct bfa_fcs_s *fcs) -{ - bfa_fcs_modexit_comp(fcs); + bfa_pport_event_register(fcs->bfa, bfa_fcs_pport_event_handler, fcs); } diff --git a/drivers/scsi/bfa/bfa_fcs_uf.c b/drivers/scsi/bfa/bfa_fcs_uf.c index ad01db6..3d57d48 100644 --- a/drivers/scsi/bfa/bfa_fcs_uf.c +++ b/drivers/scsi/bfa/bfa_fcs_uf.c @@ -93,13 +93,7 @@ bfa_fcs_uf_recv(void *cbarg, struct bfa_uf_s *uf) } void -bfa_fcs_uf_modinit(struct bfa_fcs_s *fcs) +bfa_fcs_uf_attach(struct bfa_fcs_s *fcs) { bfa_uf_recv_register(fcs->bfa, bfa_fcs_uf_recv, fcs); } - -void -bfa_fcs_uf_modexit(struct bfa_fcs_s *fcs) -{ - bfa_fcs_modexit_comp(fcs); -} diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c index 8e2b2a2..965dfb5 100644 --- a/drivers/scsi/bfa/bfad.c +++ b/drivers/scsi/bfa/bfad.c @@ -748,7 +748,8 @@ bfad_drv_init(struct bfad_s *bfad) bfa_fcs_log_init(&bfad->bfa_fcs, bfad->logmod); bfa_fcs_trc_init(&bfad->bfa_fcs, bfad->trcmod); bfa_fcs_aen_init(&bfad->bfa_fcs, bfad->aen); - bfa_fcs_init(&bfad->bfa_fcs, &bfad->bfa, bfad, BFA_FALSE); + bfa_fcs_attach(&bfad->bfa_fcs, &bfad->bfa, bfad, BFA_FALSE); + bfa_fcs_init(&bfad->bfa_fcs); bfa_fcs_driver_info_init(&bfad->bfa_fcs, &driver_info); bfa_fcs_set_fdmi_param(&bfad->bfa_fcs, fdmi_enable); spin_unlock_irqrestore(&bfad->bfad_lock, flags); diff --git a/drivers/scsi/bfa/fabric.c b/drivers/scsi/bfa/fabric.c index a4b5dd4..e229898 100644 --- a/drivers/scsi/bfa/fabric.c +++ b/drivers/scsi/bfa/fabric.c @@ -814,10 +814,10 @@ bfa_fcs_fabric_delete_comp(void *cbarg) */ /** - * Module initialization + * Attach time initialization */ void -bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs) +bfa_fcs_fabric_attach(struct bfa_fcs_s *fcs) { struct bfa_fcs_fabric_s *fabric; @@ -841,7 +841,12 @@ bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs) bfa_wc_up(&fabric->wc); /* For the base port */ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit); - bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_CREATE); +} + +void +bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs) +{ + bfa_sm_send_event(&fcs->fabric, BFA_FCS_FABRIC_SM_CREATE); bfa_trc(fcs, 0); } diff --git a/drivers/scsi/bfa/fcpim.c b/drivers/scsi/bfa/fcpim.c index 1f3c06e..06f8a46 100644 --- a/drivers/scsi/bfa/fcpim.c +++ b/drivers/scsi/bfa/fcpim.c @@ -822,22 +822,3 @@ void bfa_fcs_itnim_resume(struct bfa_fcs_itnim_s *itnim) { } - -/** - * Module initialization - */ -void -bfa_fcs_fcpim_modinit(struct bfa_fcs_s *fcs) -{ -} - -/** - * Module cleanup - */ -void -bfa_fcs_fcpim_modexit(struct bfa_fcs_s *fcs) -{ - bfa_fcs_modexit_comp(fcs); -} - - diff --git a/drivers/scsi/bfa/fcs_fabric.h b/drivers/scsi/bfa/fcs_fabric.h index eee9608..8237bd5 100644 --- a/drivers/scsi/bfa/fcs_fabric.h +++ b/drivers/scsi/bfa/fcs_fabric.h @@ -29,6 +29,7 @@ /* * fcs friend functions: only between fcs modules */ +void bfa_fcs_fabric_attach(struct bfa_fcs_s *fcs); void bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs); void bfa_fcs_fabric_modexit(struct bfa_fcs_s *fcs); void bfa_fcs_fabric_modsusp(struct bfa_fcs_s *fcs); diff --git a/drivers/scsi/bfa/fcs_fcpim.h b/drivers/scsi/bfa/fcs_fcpim.h index 61e9e26..11e6e7b 100644 --- a/drivers/scsi/bfa/fcs_fcpim.h +++ b/drivers/scsi/bfa/fcs_fcpim.h @@ -34,11 +34,6 @@ void bfa_fcs_itnim_is_initiator(struct bfa_fcs_itnim_s *itnim); void bfa_fcs_itnim_pause(struct bfa_fcs_itnim_s *itnim); void bfa_fcs_itnim_resume(struct bfa_fcs_itnim_s *itnim); -/* - * Modudle init/cleanup routines. - */ -void bfa_fcs_fcpim_modinit(struct bfa_fcs_s *fcs); -void bfa_fcs_fcpim_modexit(struct bfa_fcs_s *fcs); void bfa_fcs_fcpim_uf_recv(struct bfa_fcs_itnim_s *itnim, struct fchs_s *fchs, u16 len); #endif /* __FCS_FCPIM_H__ */ diff --git a/drivers/scsi/bfa/fcs_port.h b/drivers/scsi/bfa/fcs_port.h index abb6519..408c06a 100644 --- a/drivers/scsi/bfa/fcs_port.h +++ b/drivers/scsi/bfa/fcs_port.h @@ -26,7 +26,6 @@ /* * fcs friend functions: only between fcs modules */ -void bfa_fcs_pport_modinit(struct bfa_fcs_s *fcs); -void bfa_fcs_pport_modexit(struct bfa_fcs_s *fcs); +void bfa_fcs_pport_attach(struct bfa_fcs_s *fcs); #endif /* __FCS_PPORT_H__ */ diff --git a/drivers/scsi/bfa/fcs_rport.h b/drivers/scsi/bfa/fcs_rport.h index f601e9d..9c8d1d2 100644 --- a/drivers/scsi/bfa/fcs_rport.h +++ b/drivers/scsi/bfa/fcs_rport.h @@ -24,9 +24,6 @@ #include -void bfa_fcs_rport_modinit(struct bfa_fcs_s *fcs); -void bfa_fcs_rport_modexit(struct bfa_fcs_s *fcs); - void bfa_fcs_rport_uf_recv(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs, u16 len); void bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport); diff --git a/drivers/scsi/bfa/fcs_uf.h b/drivers/scsi/bfa/fcs_uf.h index 96f1bdc..f591072 100644 --- a/drivers/scsi/bfa/fcs_uf.h +++ b/drivers/scsi/bfa/fcs_uf.h @@ -26,7 +26,6 @@ /* * fcs friend functions: only between fcs modules */ -void bfa_fcs_uf_modinit(struct bfa_fcs_s *fcs); -void bfa_fcs_uf_modexit(struct bfa_fcs_s *fcs); +void bfa_fcs_uf_attach(struct bfa_fcs_s *fcs); #endif /* __FCS_UF_H__ */ diff --git a/drivers/scsi/bfa/fcs_vport.h b/drivers/scsi/bfa/fcs_vport.h index 9e80b6a..32565ba 100644 --- a/drivers/scsi/bfa/fcs_vport.h +++ b/drivers/scsi/bfa/fcs_vport.h @@ -22,13 +22,6 @@ #include #include -/* - * Modudle init/cleanup routines. - */ - -void bfa_fcs_vport_modinit(struct bfa_fcs_s *fcs); -void bfa_fcs_vport_modexit(struct bfa_fcs_s *fcs); - void bfa_fcs_vport_cleanup(struct bfa_fcs_vport_s *vport); void bfa_fcs_vport_online(struct bfa_fcs_vport_s *vport); void bfa_fcs_vport_offline(struct bfa_fcs_vport_s *vport); diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs.h b/drivers/scsi/bfa/include/fcs/bfa_fcs.h index 0396ec4..f2fd35f 100644 --- a/drivers/scsi/bfa/include/fcs/bfa_fcs.h +++ b/drivers/scsi/bfa/include/fcs/bfa_fcs.h @@ -61,8 +61,9 @@ struct bfa_fcs_s { /* * bfa fcs API functions */ -void bfa_fcs_init(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad, +void bfa_fcs_attach(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad, bfa_boolean_t min_cfg); +void bfa_fcs_init(struct bfa_fcs_s *fcs); void bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs, struct bfa_fcs_driver_info_s *driver_info); void bfa_fcs_set_fdmi_param(struct bfa_fcs_s *fcs, bfa_boolean_t fdmi_enable); diff --git a/drivers/scsi/bfa/rport.c b/drivers/scsi/bfa/rport.c index 9cf58bb..df714dc 100644 --- a/drivers/scsi/bfa/rport.c +++ b/drivers/scsi/bfa/rport.c @@ -2575,23 +2575,6 @@ bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs, } /** - * Module initialization - */ -void -bfa_fcs_rport_modinit(struct bfa_fcs_s *fcs) -{ -} - -/** - * Module cleanup - */ -void -bfa_fcs_rport_modexit(struct bfa_fcs_s *fcs) -{ - bfa_fcs_modexit_comp(fcs); -} - -/** * Return state of rport. */ int diff --git a/drivers/scsi/bfa/vport.c b/drivers/scsi/bfa/vport.c index 8d18589..75d6f05 100644 --- a/drivers/scsi/bfa/vport.c +++ b/drivers/scsi/bfa/vport.c @@ -616,23 +616,6 @@ bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s *vport) bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELCOMP); } -/** - * Module initialization - */ -void -bfa_fcs_vport_modinit(struct bfa_fcs_s *fcs) -{ -} - -/** - * Module cleanup - */ -void -bfa_fcs_vport_modexit(struct bfa_fcs_s *fcs) -{ - bfa_fcs_modexit_comp(fcs); -} - u32 bfa_fcs_vport_get_max(struct bfa_fcs_s *fcs) { -- cgit v0.10.2 From a046bf0559018ba3d16c412fc4e1aa2be5f11f36 Mon Sep 17 00:00:00 2001 From: Krishna Gudipati Date: Wed, 3 Mar 2010 17:43:45 -0800 Subject: [SCSI] bfa: Fix to allow creation of only 190 vports on CNA. Brocade CNA currently supports only 190 vports (instead of 191), since there are only 192 unicast cam entries reserved for FCoE. Brocade CNA has a total of 256 unicast cam entries (192 FCoE + 64 LL) 192 cam entries = 1 burned in mac + 1 baseport FPMA mac + 190 vport FPMA macs. Made changes to the code to support only 190 vports. Signed-off-by: Krishna Gudipati Signed-off-by: James Bottomley diff --git a/drivers/scsi/bfa/bfa_lps.c b/drivers/scsi/bfa/bfa_lps.c index c8c2564..66b9b15 100644 --- a/drivers/scsi/bfa/bfa_lps.c +++ b/drivers/scsi/bfa/bfa_lps.c @@ -18,6 +18,7 @@ #include #include #include +#include BFA_TRC_FILE(HAL, LPS); BFA_MODULE(lps); @@ -25,6 +26,12 @@ BFA_MODULE(lps); #define BFA_LPS_MIN_LPORTS (1) #define BFA_LPS_MAX_LPORTS (256) +/* + * Maximum Vports supported per physical port or vf. + */ +#define BFA_LPS_MAX_VPORTS_SUPP_CB 255 +#define BFA_LPS_MAX_VPORTS_SUPP_CT 190 + /** * forward declarations */ @@ -598,6 +605,19 @@ bfa_lps_cvl_event(struct bfa_lps_s *lps) bfa_cb_lps_cvl_event(lps->bfa->bfad, lps->uarg); } +u32 +bfa_lps_get_max_vport(struct bfa_s *bfa) +{ + struct bfa_ioc_attr_s ioc_attr; + + bfa_get_attr(bfa, &ioc_attr); + + if (ioc_attr.pci_attr.device_id == BFA_PCI_DEVICE_ID_CT) + return (BFA_LPS_MAX_VPORTS_SUPP_CT); + else + return (BFA_LPS_MAX_VPORTS_SUPP_CB); +} + /** * lps_public BFA LPS public functions */ diff --git a/drivers/scsi/bfa/fcs_vport.h b/drivers/scsi/bfa/fcs_vport.h index 32565ba..13c32eb 100644 --- a/drivers/scsi/bfa/fcs_vport.h +++ b/drivers/scsi/bfa/fcs_vport.h @@ -26,7 +26,6 @@ void bfa_fcs_vport_cleanup(struct bfa_fcs_vport_s *vport); void bfa_fcs_vport_online(struct bfa_fcs_vport_s *vport); void bfa_fcs_vport_offline(struct bfa_fcs_vport_s *vport); void bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s *vport); -u32 bfa_fcs_vport_get_max(struct bfa_fcs_s *fcs); #endif /* __FCS_VPORT_H__ */ diff --git a/drivers/scsi/bfa/include/bfa_svc.h b/drivers/scsi/bfa/include/bfa_svc.h index 2e4372f..0d7ed4d 100644 --- a/drivers/scsi/bfa/include/bfa_svc.h +++ b/drivers/scsi/bfa/include/bfa_svc.h @@ -293,6 +293,7 @@ void bfa_uf_free(struct bfa_uf_s *uf); * bfa lport service api */ +u32 bfa_lps_get_max_vport(struct bfa_s *bfa); struct bfa_lps_s *bfa_lps_alloc(struct bfa_s *bfa); void bfa_lps_delete(struct bfa_lps_s *lps); void bfa_lps_discard(struct bfa_lps_s *lps); diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h b/drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h index 967ceb0..ceaefd3 100644 --- a/drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h +++ b/drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h @@ -34,14 +34,6 @@ struct bfa_fcs_s; struct bfa_fcs_fabric_s; /* -* @todo : need to move to a global config file. - * Maximum Vports supported per physical port or vf. - */ -#define BFA_FCS_MAX_VPORTS_SUPP_CB 255 -#define BFA_FCS_MAX_VPORTS_SUPP_CT 191 - -/* -* @todo : need to move to a global config file. * Maximum Rports supported per port (physical/logical). */ #define BFA_FCS_MAX_RPORTS_SUPP 256 /* @todo : tentative value */ diff --git a/drivers/scsi/bfa/lport_api.c b/drivers/scsi/bfa/lport_api.c index 1e06792..4a4ccce 100644 --- a/drivers/scsi/bfa/lport_api.c +++ b/drivers/scsi/bfa/lport_api.c @@ -235,7 +235,8 @@ bfa_fcs_port_get_info(struct bfa_fcs_port_s *port, port_info->port_wwn = bfa_fcs_port_get_pwwn(port); port_info->node_wwn = bfa_fcs_port_get_nwwn(port); - port_info->max_vports_supp = bfa_fcs_vport_get_max(port->fcs); + port_info->max_vports_supp = + bfa_lps_get_max_vport(port->fcs->bfa); port_info->num_vports_inuse = bfa_fcs_fabric_vport_count(port->fabric); port_info->max_rports_supp = BFA_FCS_MAX_RPORTS_SUPP; diff --git a/drivers/scsi/bfa/vport.c b/drivers/scsi/bfa/vport.c index 75d6f05..3dce9e1 100644 --- a/drivers/scsi/bfa/vport.c +++ b/drivers/scsi/bfa/vport.c @@ -616,21 +616,6 @@ bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s *vport) bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELCOMP); } -u32 -bfa_fcs_vport_get_max(struct bfa_fcs_s *fcs) -{ - struct bfa_ioc_attr_s ioc_attr; - - bfa_get_attr(fcs->bfa, &ioc_attr); - - if (ioc_attr.pci_attr.device_id == BFA_PCI_DEVICE_ID_CT) - return BFA_FCS_MAX_VPORTS_SUPP_CT; - else - return BFA_FCS_MAX_VPORTS_SUPP_CB; -} - - - /** * fcs_vport_api Virtual port API */ @@ -667,7 +652,7 @@ bfa_fcs_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs, return BFA_STATUS_VPORT_EXISTS; if (bfa_fcs_fabric_vport_count(&fcs->fabric) == - bfa_fcs_vport_get_max(fcs)) + bfa_lps_get_max_vport(fcs->bfa)) return BFA_STATUS_VPORT_MAX; vport->lps = bfa_lps_alloc(fcs->bfa); -- cgit v0.10.2 From db1466b3e1bd1727375cdbfcbea4bcce2f860f61 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Wed, 3 Mar 2010 07:46:56 -0800 Subject: rcu: Use wrapper function instead of exporting tasklist_lock Lockdep-RCU commit d11c563d exported tasklist_lock, which is not a good thing. This patch instead exports a function that uses lockdep to check whether tasklist_lock is held. Suggested-by: Christoph Hellwig Signed-off-by: Paul E. McKenney Cc: laijs@cn.fujitsu.com Cc: dipankar@in.ibm.com Cc: mathieu.desnoyers@polymtl.ca Cc: josh@joshtriplett.org Cc: dvhltc@us.ibm.com Cc: niv@us.ibm.com Cc: peterz@infradead.org Cc: rostedt@goodmis.org Cc: Valdis.Kletnieks@vt.edu Cc: dhowells@redhat.com Cc: Christoph Hellwig LKML-Reference: <1267631219-8713-1-git-send-email-paulmck@linux.vnet.ibm.com> Signed-off-by: Ingo Molnar diff --git a/include/linux/cred.h b/include/linux/cred.h index 4db09f8..52507c3 100644 --- a/include/linux/cred.h +++ b/include/linux/cred.h @@ -280,7 +280,7 @@ static inline void put_cred(const struct cred *_cred) * task or by holding tasklist_lock to prevent it from being unlinked. */ #define __task_cred(task) \ - ((const struct cred *)(rcu_dereference_check((task)->real_cred, rcu_read_lock_held() || lockdep_is_held(&tasklist_lock)))) + ((const struct cred *)(rcu_dereference_check((task)->real_cred, rcu_read_lock_held() || lockdep_tasklist_lock_is_held()))) /** * get_task_cred - Get another task's objective credentials diff --git a/include/linux/sched.h b/include/linux/sched.h index 0eef87b..a47af20 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -258,6 +258,10 @@ extern spinlock_t mmlist_lock; struct task_struct; +#ifdef CONFIG_PROVE_RCU +extern int lockdep_tasklist_lock_is_held(void); +#endif /* #ifdef CONFIG_PROVE_RCU */ + extern void sched_init(void); extern void sched_init_smp(void); extern asmlinkage void schedule_tail(struct task_struct *prev); diff --git a/kernel/exit.c b/kernel/exit.c index 45ed043..fed3a4d 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -87,7 +87,7 @@ static void __exit_signal(struct task_struct *tsk) sighand = rcu_dereference_check(tsk->sighand, rcu_read_lock_held() || - lockdep_is_held(&tasklist_lock)); + lockdep_tasklist_lock_is_held()); spin_lock(&sighand->siglock); posix_cpu_timers_exit(tsk); diff --git a/kernel/fork.c b/kernel/fork.c index 17bbf09..8691c54 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -86,7 +86,14 @@ int max_threads; /* tunable limit on nr_threads */ DEFINE_PER_CPU(unsigned long, process_counts) = 0; __cacheline_aligned DEFINE_RWLOCK(tasklist_lock); /* outer */ -EXPORT_SYMBOL_GPL(tasklist_lock); + +#ifdef CONFIG_PROVE_RCU +int lockdep_tasklist_lock_is_held(void) +{ + return lockdep_is_held(&tasklist_lock); +} +EXPORT_SYMBOL_GPL(lockdep_tasklist_lock_is_held); +#endif /* #ifdef CONFIG_PROVE_RCU */ int nr_processes(void) { diff --git a/kernel/pid.c b/kernel/pid.c index b08e697..b606440 100644 --- a/kernel/pid.c +++ b/kernel/pid.c @@ -367,7 +367,9 @@ struct task_struct *pid_task(struct pid *pid, enum pid_type type) struct task_struct *result = NULL; if (pid) { struct hlist_node *first; - first = rcu_dereference_check(pid->tasks[type].first, rcu_read_lock_held() || lockdep_is_held(&tasklist_lock)); + first = rcu_dereference_check(pid->tasks[type].first, + rcu_read_lock_held() || + lockdep_tasklist_lock_is_held()); if (first) result = hlist_entry(first, struct task_struct, pids[(type)].node); } -- cgit v0.10.2 From e67143243a1a6b47e1bdcda189ffac46d2a8744d Mon Sep 17 00:00:00 2001 From: Krishna Gudipati Date: Wed, 3 Mar 2010 17:44:02 -0800 Subject: [SCSI] bfa: Resume BFA operations after firmware mismatch is resolved. bfad.c & bfad_drv.h: * Created a kernel thread from pci_probe that does the bfad start operations after BFA init done on a firmware mismatch. * The kernel thread on a fw mismatch waits for an event from IOC call back and is woken up from bfa_cb_init() on BFA init success. * In normal cases of no firmware mismatch this thread is terminated in pci_probe. bfa_fcs_lport.c, fabric.c, fcs_lport.h & vport.c: * Split the lport init to attach time and init time code, so that proper config attributes are set after firmware mismatch. bfa_iocfc.c: * Handle an IOC timer issue, where the IOC timer would expire before the init completion and send Init fail event to the driver, however IOC init continues and completes successfully at the later stage. The bfa and driver were not handling this kind of deferred init completion. Signed-off-by: Krishna Gudipati Signed-off-by: James Bottomley diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c index c7ab257..3d62e45 100644 --- a/drivers/scsi/bfa/bfa_fcs_lport.c +++ b/drivers/scsi/bfa/bfa_fcs_lport.c @@ -873,36 +873,46 @@ bfa_fcs_port_is_online(struct bfa_fcs_port_s *port) } /** - * Logical port initialization of base or virtual port. - * Called by fabric for base port or by vport for virtual ports. + * Attach time initialization of logical ports. */ void -bfa_fcs_lport_init(struct bfa_fcs_port_s *lport, struct bfa_fcs_s *fcs, - u16 vf_id, struct bfa_port_cfg_s *port_cfg, - struct bfa_fcs_vport_s *vport) +bfa_fcs_lport_attach(struct bfa_fcs_port_s *lport, struct bfa_fcs_s *fcs, + uint16_t vf_id, struct bfa_fcs_vport_s *vport) { lport->fcs = fcs; lport->fabric = bfa_fcs_vf_lookup(fcs, vf_id); - bfa_os_assign(lport->port_cfg, *port_cfg); lport->vport = vport; lport->lp_tag = (vport) ? bfa_lps_get_tag(vport->lps) : bfa_lps_get_tag(lport->fabric->lps); INIT_LIST_HEAD(&lport->rport_q); lport->num_rports = 0; +} + +/** + * Logical port initialization of base or virtual port. + * Called by fabric for base port or by vport for virtual ports. + */ - lport->bfad_port = - bfa_fcb_port_new(fcs->bfad, lport, lport->port_cfg.roles, +void +bfa_fcs_lport_init(struct bfa_fcs_port_s *lport, + struct bfa_port_cfg_s *port_cfg) +{ + struct bfa_fcs_vport_s *vport = lport->vport; + + bfa_os_assign(lport->port_cfg, *port_cfg); + + lport->bfad_port = bfa_fcb_port_new(lport->fcs->bfad, lport, + lport->port_cfg.roles, lport->fabric->vf_drv, vport ? vport->vport_drv : NULL); + bfa_fcs_port_aen_post(lport, BFA_LPORT_AEN_NEW); bfa_sm_set_state(lport, bfa_fcs_port_sm_uninit); bfa_sm_send_event(lport, BFA_FCS_PORT_SM_CREATE); } - - /** * fcs_lport_api */ diff --git a/drivers/scsi/bfa/bfa_iocfc.c b/drivers/scsi/bfa/bfa_iocfc.c index b5e7224..137591c 100644 --- a/drivers/scsi/bfa/bfa_iocfc.c +++ b/drivers/scsi/bfa/bfa_iocfc.c @@ -336,8 +336,10 @@ bfa_iocfc_init_cb(void *bfa_arg, bfa_boolean_t complete) bfa_cb_init(bfa->bfad, BFA_STATUS_OK); else bfa_cb_init(bfa->bfad, BFA_STATUS_FAILED); - } else - bfa->iocfc.action = BFA_IOCFC_ACT_NONE; + } else { + if (bfa->iocfc.cfgdone) + bfa->iocfc.action = BFA_IOCFC_ACT_NONE; + } } static void diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c index 965dfb5..4ccaeae 100644 --- a/drivers/scsi/bfa/bfad.c +++ b/drivers/scsi/bfa/bfad.c @@ -20,6 +20,7 @@ */ #include +#include #include "bfad_drv.h" #include "bfad_im.h" #include "bfad_tm.h" @@ -97,6 +98,8 @@ bfad_fc4_probe(struct bfad_s *bfad) if (ipfc_enable) bfad_ipfc_probe(bfad); + + bfad->bfad_flags |= BFAD_FC4_PROBE_DONE; ext: return rc; } @@ -108,6 +111,7 @@ bfad_fc4_probe_undo(struct bfad_s *bfad) bfad_tm_probe_undo(bfad); if (ipfc_enable) bfad_ipfc_probe_undo(bfad); + bfad->bfad_flags &= ~BFAD_FC4_PROBE_DONE; } static void @@ -175,9 +179,19 @@ bfa_cb_init(void *drv, bfa_status_t init_status) { struct bfad_s *bfad = drv; - if (init_status == BFA_STATUS_OK) + if (init_status == BFA_STATUS_OK) { bfad->bfad_flags |= BFAD_HAL_INIT_DONE; + /* If BFAD_HAL_INIT_FAIL flag is set: + * Wake up the kernel thread to start + * the bfad operations after HAL init done + */ + if ((bfad->bfad_flags & BFAD_HAL_INIT_FAIL)) { + bfad->bfad_flags &= ~BFAD_HAL_INIT_FAIL; + wake_up_process(bfad->bfad_tsk); + } + } + complete(&bfad->comp); } @@ -749,7 +763,13 @@ bfad_drv_init(struct bfad_s *bfad) bfa_fcs_trc_init(&bfad->bfa_fcs, bfad->trcmod); bfa_fcs_aen_init(&bfad->bfa_fcs, bfad->aen); bfa_fcs_attach(&bfad->bfa_fcs, &bfad->bfa, bfad, BFA_FALSE); - bfa_fcs_init(&bfad->bfa_fcs); + + /* Do FCS init only when HAL init is done */ + if ((bfad->bfad_flags & BFAD_HAL_INIT_DONE)) { + bfa_fcs_init(&bfad->bfa_fcs); + bfad->bfad_flags |= BFAD_FCS_INIT_DONE; + } + bfa_fcs_driver_info_init(&bfad->bfa_fcs, &driver_info); bfa_fcs_set_fdmi_param(&bfad->bfa_fcs, fdmi_enable); spin_unlock_irqrestore(&bfad->bfad_lock, flags); @@ -767,12 +787,22 @@ out_hal_mem_alloc_failure: void bfad_drv_uninit(struct bfad_s *bfad) { + unsigned long flags; + + spin_lock_irqsave(&bfad->bfad_lock, flags); + init_completion(&bfad->comp); + bfa_stop(&bfad->bfa); + spin_unlock_irqrestore(&bfad->bfad_lock, flags); + wait_for_completion(&bfad->comp); + del_timer_sync(&bfad->hal_tmo); bfa_isr_disable(&bfad->bfa); bfa_detach(&bfad->bfa); bfad_remove_intr(bfad); bfa_assert(list_empty(&bfad->file_q)); bfad_hal_mem_release(bfad); + + bfad->bfad_flags &= ~BFAD_DRV_INIT_DONE; } void @@ -863,6 +893,86 @@ bfad_drv_log_level_set(struct bfad_s *bfad) bfa_log_set_level_all(&bfad->log_data, log_level); } +bfa_status_t +bfad_start_ops(struct bfad_s *bfad) +{ + int retval; + + /* PPORT FCS config */ + bfad_fcs_port_cfg(bfad); + + retval = bfad_cfg_pport(bfad, BFA_PORT_ROLE_FCP_IM); + if (retval != BFA_STATUS_OK) + goto out_cfg_pport_failure; + + /* BFAD level FC4 (IM/TM/IPFC) specific resource allocation */ + retval = bfad_fc4_probe(bfad); + if (retval != BFA_STATUS_OK) { + printk(KERN_WARNING "bfad_fc4_probe failed\n"); + goto out_fc4_probe_failure; + } + + bfad_drv_start(bfad); + + /* + * If bfa_linkup_delay is set to -1 default; try to retrive the + * value using the bfad_os_get_linkup_delay(); else use the + * passed in module param value as the bfa_linkup_delay. + */ + if (bfa_linkup_delay < 0) { + + bfa_linkup_delay = bfad_os_get_linkup_delay(bfad); + bfad_os_rport_online_wait(bfad); + bfa_linkup_delay = -1; + + } else { + bfad_os_rport_online_wait(bfad); + } + + bfa_log(bfad->logmod, BFA_LOG_LINUX_DEVICE_CLAIMED, bfad->pci_name); + + return BFA_STATUS_OK; + +out_fc4_probe_failure: + bfad_fc4_probe_undo(bfad); + bfad_uncfg_pport(bfad); +out_cfg_pport_failure: + return BFA_STATUS_FAILED; +} + +int +bfad_worker (void *ptr) +{ + struct bfad_s *bfad; + unsigned long flags; + + bfad = (struct bfad_s *)ptr; + + while (!kthread_should_stop()) { + + /* Check if the FCS init is done from bfad_drv_init; + * if not done do FCS init and set the flag. + */ + if (!(bfad->bfad_flags & BFAD_FCS_INIT_DONE)) { + spin_lock_irqsave(&bfad->bfad_lock, flags); + bfa_fcs_init(&bfad->bfa_fcs); + bfad->bfad_flags |= BFAD_FCS_INIT_DONE; + spin_unlock_irqrestore(&bfad->bfad_lock, flags); + } + + /* Start the bfad operations after HAL init done */ + bfad_start_ops(bfad); + + spin_lock_irqsave(&bfad->bfad_lock, flags); + bfad->bfad_tsk = NULL; + spin_unlock_irqrestore(&bfad->bfad_lock, flags); + + break; + } + + return 0; +} + /* * PCI_entry PCI driver entries * { */ @@ -937,57 +1047,39 @@ bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid) bfad->ref_count = 0; bfad->pport.bfad = bfad; + bfad->bfad_tsk = kthread_create(bfad_worker, (void *) bfad, "%s", + "bfad_worker"); + if (IS_ERR(bfad->bfad_tsk)) { + printk(KERN_INFO "bfad[%d]: Kernel thread" + " creation failed!\n", + bfad->inst_no); + goto out_kthread_create_failure; + } + retval = bfad_drv_init(bfad); if (retval != BFA_STATUS_OK) goto out_drv_init_failure; if (!(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) { + bfad->bfad_flags |= BFAD_HAL_INIT_FAIL; printk(KERN_WARNING "bfad%d: hal init failed\n", bfad->inst_no); goto ok; } - /* - * PPORT FCS config - */ - bfad_fcs_port_cfg(bfad); - - retval = bfad_cfg_pport(bfad, BFA_PORT_ROLE_FCP_IM); + retval = bfad_start_ops(bfad); if (retval != BFA_STATUS_OK) - goto out_cfg_pport_failure; + goto out_start_ops_failure; - /* - * BFAD level FC4 (IM/TM/IPFC) specific resource allocation - */ - retval = bfad_fc4_probe(bfad); - if (retval != BFA_STATUS_OK) { - printk(KERN_WARNING "bfad_fc4_probe failed\n"); - goto out_fc4_probe_failure; - } - - bfad_drv_start(bfad); + kthread_stop(bfad->bfad_tsk); + bfad->bfad_tsk = NULL; - /* - * If bfa_linkup_delay is set to -1 default; try to retrive the - * value using the bfad_os_get_linkup_delay(); else use the - * passed in module param value as the bfa_linkup_delay. - */ - if (bfa_linkup_delay < 0) { - bfa_linkup_delay = bfad_os_get_linkup_delay(bfad); - bfad_os_rport_online_wait(bfad); - bfa_linkup_delay = -1; - } else { - bfad_os_rport_online_wait(bfad); - } - - bfa_log(bfad->logmod, BFA_LOG_LINUX_DEVICE_CLAIMED, bfad->pci_name); ok: return 0; -out_fc4_probe_failure: - bfad_fc4_probe_undo(bfad); - bfad_uncfg_pport(bfad); -out_cfg_pport_failure: +out_start_ops_failure: bfad_drv_uninit(bfad); out_drv_init_failure: + kthread_stop(bfad->bfad_tsk); +out_kthread_create_failure: mutex_lock(&bfad_mutex); bfad_inst--; list_del(&bfad->list_entry); @@ -1012,6 +1104,11 @@ bfad_pci_remove(struct pci_dev *pdev) bfa_trc(bfad, bfad->inst_no); + spin_lock_irqsave(&bfad->bfad_lock, flags); + if (bfad->bfad_tsk != NULL) + kthread_stop(bfad->bfad_tsk); + spin_unlock_irqrestore(&bfad->bfad_lock, flags); + if ((bfad->bfad_flags & BFAD_DRV_INIT_DONE) && !(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) { @@ -1028,13 +1125,25 @@ bfad_pci_remove(struct pci_dev *pdev) goto remove_sysfs; } - if (bfad->bfad_flags & BFAD_HAL_START_DONE) + if (bfad->bfad_flags & BFAD_HAL_START_DONE) { bfad_drv_stop(bfad); + } else if (bfad->bfad_flags & BFAD_DRV_INIT_DONE) { + /* Invoking bfa_stop() before bfa_detach + * when HAL and DRV init are success + * but HAL start did not occur. + */ + spin_lock_irqsave(&bfad->bfad_lock, flags); + init_completion(&bfad->comp); + bfa_stop(&bfad->bfa); + spin_unlock_irqrestore(&bfad->bfad_lock, flags); + wait_for_completion(&bfad->comp); + } bfad_remove_intr(bfad); - del_timer_sync(&bfad->hal_tmo); - bfad_fc4_probe_undo(bfad); + + if (bfad->bfad_flags & BFAD_FC4_PROBE_DONE) + bfad_fc4_probe_undo(bfad); if (bfad->bfad_flags & BFAD_CFG_PPORT_DONE) bfad_uncfg_pport(bfad); diff --git a/drivers/scsi/bfa/bfad_drv.h b/drivers/scsi/bfa/bfad_drv.h index 172c81e..9fa801a 100644 --- a/drivers/scsi/bfa/bfad_drv.h +++ b/drivers/scsi/bfa/bfad_drv.h @@ -62,7 +62,9 @@ #define BFAD_HAL_START_DONE 0x00000010 #define BFAD_PORT_ONLINE 0x00000020 #define BFAD_RPORT_ONLINE 0x00000040 - +#define BFAD_FCS_INIT_DONE 0x00000080 +#define BFAD_HAL_INIT_FAIL 0x00000100 +#define BFAD_FC4_PROBE_DONE 0x00000200 #define BFAD_PORT_DELETE 0x00000001 /* @@ -168,6 +170,7 @@ struct bfad_s { u32 inst_no; /* BFAD instance number */ u32 bfad_flags; spinlock_t bfad_lock; + struct task_struct *bfad_tsk; struct bfad_cfg_param_s cfg_data; struct bfad_msix_s msix_tab[MAX_MSIX_ENTRY]; int nvec; @@ -258,6 +261,7 @@ bfa_status_t bfad_vf_create(struct bfad_s *bfad, u16 vf_id, struct bfa_port_cfg_s *port_cfg); bfa_status_t bfad_cfg_pport(struct bfad_s *bfad, enum bfa_port_role role); bfa_status_t bfad_drv_init(struct bfad_s *bfad); +bfa_status_t bfad_start_ops(struct bfad_s *bfad); void bfad_drv_start(struct bfad_s *bfad); void bfad_uncfg_pport(struct bfad_s *bfad); void bfad_drv_stop(struct bfad_s *bfad); @@ -280,6 +284,12 @@ void bfad_drv_log_level_set(struct bfad_s *bfad); bfa_status_t bfad_fc4_module_init(void); void bfad_fc4_module_exit(void); +bfa_status_t bfad_os_kthread_create(struct bfad_s *bfad); +void bfad_os_kthread_stop(struct bfad_s *bfad); +void bfad_os_kthread_wakeup(struct bfad_s *bfad); +int bfad_os_kthread_should_stop(void); +int bfad_worker (void *ptr); + void bfad_pci_remove(struct pci_dev *pdev); int bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid); void bfad_os_rport_online_wait(struct bfad_s *bfad); diff --git a/drivers/scsi/bfa/fabric.c b/drivers/scsi/bfa/fabric.c index e229898..20a686a 100644 --- a/drivers/scsi/bfa/fabric.c +++ b/drivers/scsi/bfa/fabric.c @@ -136,8 +136,7 @@ bfa_fcs_fabric_sm_uninit(struct bfa_fcs_fabric_s *fabric, case BFA_FCS_FABRIC_SM_CREATE: bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_created); bfa_fcs_fabric_init(fabric); - bfa_fcs_lport_init(&fabric->bport, fabric->fcs, FC_VF_ID_NULL, - &fabric->bport.port_cfg, NULL); + bfa_fcs_lport_init(&fabric->bport, &fabric->bport.port_cfg); break; case BFA_FCS_FABRIC_SM_LINK_UP: @@ -841,6 +840,7 @@ bfa_fcs_fabric_attach(struct bfa_fcs_s *fcs) bfa_wc_up(&fabric->wc); /* For the base port */ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit); + bfa_fcs_lport_attach(&fabric->bport, fabric->fcs, FC_VF_ID_NULL, NULL); } void diff --git a/drivers/scsi/bfa/fcs_lport.h b/drivers/scsi/bfa/fcs_lport.h index ae744ba..a6508c8 100644 --- a/drivers/scsi/bfa/fcs_lport.h +++ b/drivers/scsi/bfa/fcs_lport.h @@ -84,9 +84,10 @@ void bfa_fcs_port_uf_recv(struct bfa_fcs_port_s *lport, struct fchs_s *fchs, * Following routines will be called by Fabric to indicate port * online/offline to vport. */ -void bfa_fcs_lport_init(struct bfa_fcs_port_s *lport, struct bfa_fcs_s *fcs, - u16 vf_id, struct bfa_port_cfg_s *port_cfg, - struct bfa_fcs_vport_s *vport); +void bfa_fcs_lport_attach(struct bfa_fcs_port_s *lport, struct bfa_fcs_s *fcs, + uint16_t vf_id, struct bfa_fcs_vport_s *vport); +void bfa_fcs_lport_init(struct bfa_fcs_port_s *lport, + struct bfa_port_cfg_s *port_cfg); void bfa_fcs_port_online(struct bfa_fcs_port_s *port); void bfa_fcs_port_offline(struct bfa_fcs_port_s *port); void bfa_fcs_port_delete(struct bfa_fcs_port_s *port); diff --git a/drivers/scsi/bfa/vport.c b/drivers/scsi/bfa/vport.c index 3dce9e1..13f7371 100644 --- a/drivers/scsi/bfa/vport.c +++ b/drivers/scsi/bfa/vport.c @@ -662,7 +662,8 @@ bfa_fcs_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs, vport->vport_drv = vport_drv; bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit); - bfa_fcs_lport_init(&vport->lport, fcs, vf_id, vport_cfg, vport); + bfa_fcs_lport_attach(&vport->lport, fcs, vf_id, vport); + bfa_fcs_lport_init(&vport->lport, vport_cfg); bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_CREATE); -- cgit v0.10.2 From 5ed42b8113667c06a6ff2c72717395b5044d30a1 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Wed, 3 Mar 2010 07:46:58 -0800 Subject: rcu, cgroup: Relax the check in task_subsys_state() as early boot is now handled by lockdep-RCU This patch removes the check for !rcu_scheduler_active because this check has been incorporated into rcu_dereference_check(). Signed-off-by: Paul E. McKenney Cc: laijs@cn.fujitsu.com Cc: dipankar@in.ibm.com Cc: mathieu.desnoyers@polymtl.ca Cc: josh@joshtriplett.org Cc: dvhltc@us.ibm.com Cc: niv@us.ibm.com Cc: peterz@infradead.org Cc: rostedt@goodmis.org Cc: Valdis.Kletnieks@vt.edu Cc: dhowells@redhat.com LKML-Reference: <1267631219-8713-3-git-send-email-paulmck@linux.vnet.ibm.com> Signed-off-by: Ingo Molnar diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index a73e1ce..c9bbcb2 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -489,7 +489,6 @@ static inline struct cgroup_subsys_state *task_subsys_state( { return rcu_dereference_check(task->cgroups->subsys[subsys_id], rcu_read_lock_held() || - !rcu_scheduler_active || cgroup_lock_is_held()); } -- cgit v0.10.2 From cc5b83a9f884fe8722a275069a5a6fde39988455 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Wed, 3 Mar 2010 07:46:59 -0800 Subject: rcu: Add control variables to lockdep_rcu_dereference() diagnostics Add the values of rcu_scheduler_active() and debug_locks() to the lockdep_rcu_dereference() output to help diagnose RCU lockdep splats that occur shortly after the scheduler starts. Signed-off-by: Paul E. McKenney Cc: laijs@cn.fujitsu.com Cc: dipankar@in.ibm.com Cc: mathieu.desnoyers@polymtl.ca Cc: josh@joshtriplett.org Cc: dvhltc@us.ibm.com Cc: niv@us.ibm.com Cc: peterz@infradead.org Cc: rostedt@goodmis.org Cc: Valdis.Kletnieks@vt.edu Cc: dhowells@redhat.com LKML-Reference: <1267631219-8713-4-git-send-email-paulmck@linux.vnet.ibm.com> Signed-off-by: Ingo Molnar diff --git a/kernel/lockdep.c b/kernel/lockdep.c index 0c30d04..681bc2e 100644 --- a/kernel/lockdep.c +++ b/kernel/lockdep.c @@ -3822,6 +3822,7 @@ void lockdep_rcu_dereference(const char *file, const int line) printk("%s:%d invoked rcu_dereference_check() without protection!\n", file, line); printk("\nother info that might help us debug this:\n\n"); + printk("\nrcu_scheduler_active = %d, debug_locks = %d\n", rcu_scheduler_active, debug_locks); lockdep_print_held_locks(curr); printk("\nstack backtrace:\n"); dump_stack(); -- cgit v0.10.2 From e6033e3b307fcfae08408e0673266db38392bda4 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Wed, 3 Mar 2010 17:50:16 -0800 Subject: rcu: Make rcu_read_lock_sched_held() handle !PREEMPT The rcu_read_lock_sched_held() needs to unconditionally return the value "1" in a !PREEMPT kernel, because under !PREEMPT, -all- kernel code is implicitly preempt-disabled. This patch makes this happen. Signed-off-by: Paul E. McKenney Cc: laijs@cn.fujitsu.com Cc: dipankar@in.ibm.com Cc: mathieu.desnoyers@polymtl.ca Cc: josh@joshtriplett.org Cc: dvhltc@us.ibm.com Cc: niv@us.ibm.com Cc: peterz@infradead.org Cc: rostedt@goodmis.org Cc: Valdis.Kletnieks@vt.edu Cc: dhowells@redhat.com LKML-Reference: <1267667418-32233-1-git-send-email-paulmck@linux.vnet.ibm.com> Signed-off-by: Ingo Molnar diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index c843736..e22960ec 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -136,6 +136,7 @@ static inline int rcu_read_lock_bh_held(void) * can prove otherwise. Note that disabling of preemption (including * disabling irqs) counts as an RCU-sched read-side critical section. */ +#ifdef CONFIG_PREEMPT static inline int rcu_read_lock_sched_held(void) { int lockdep_opinion = 0; @@ -144,6 +145,12 @@ static inline int rcu_read_lock_sched_held(void) lockdep_opinion = lock_is_held(&rcu_sched_lock_map); return lockdep_opinion || preempt_count() != 0 || !rcu_scheduler_active; } +#else /* #ifdef CONFIG_PREEMPT */ +static inline int rcu_read_lock_sched_held(void) +{ + return 1; +} +#endif /* #else #ifdef CONFIG_PREEMPT */ #else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */ @@ -164,10 +171,17 @@ static inline int rcu_read_lock_bh_held(void) return 1; } +#ifdef CONFIG_PREEMPT static inline int rcu_read_lock_sched_held(void) { return preempt_count() != 0 || !rcu_scheduler_active; } +#else /* #ifdef CONFIG_PREEMPT */ +static inline int rcu_read_lock_sched_held(void) +{ + return 1; +} +#endif /* #else #ifdef CONFIG_PREEMPT */ #endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */ -- cgit v0.10.2 From 99ee4ca746dda71326db7645463b4075ac1d665c Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Wed, 3 Mar 2010 17:50:17 -0800 Subject: rcu: Suppress __mpol_dup() false positive from RCU lockdep Common code is used during task creation and after the task has started running. RCU protection is not needed during task creation because no other CPU has access to the under-construction task. Provide the RCU protection anyway to suppress the false positive, as there does not appear to be a good way for the common code to recognize that the task is only accessible to the CPU creating it. Signed-off-by: Paul E. McKenney Cc: Paul Menage Cc: laijs@cn.fujitsu.com Cc: dipankar@in.ibm.com Cc: mathieu.desnoyers@polymtl.ca Cc: josh@joshtriplett.org Cc: dvhltc@us.ibm.com Cc: niv@us.ibm.com Cc: peterz@infradead.org Cc: rostedt@goodmis.org Cc: Valdis.Kletnieks@vt.edu Cc: dhowells@redhat.com LKML-Reference: <1267667418-32233-2-git-send-email-paulmck@linux.vnet.ibm.com> Signed-off-by: Ingo Molnar diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 290fb5b..3cec080 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -1730,10 +1730,12 @@ struct mempolicy *__mpol_dup(struct mempolicy *old) if (!new) return ERR_PTR(-ENOMEM); + rcu_read_lock(); if (current_cpuset_is_being_rebound()) { nodemask_t mems = cpuset_mems_allowed(current); mpol_rebind_policy(old, &mems); } + rcu_read_unlock(); *new = *old; atomic_set(&new->refcnt, 1); return new; -- cgit v0.10.2 From 8d53dd546f36073e0d29b0cfc24c665db301e3e7 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Wed, 3 Mar 2010 17:50:18 -0800 Subject: rcu, ftrace: Fix RCU lockdep splat in ftrace_perf_buf_prepare() Change the pair of rcu_dereference() calls in ftrace_perf_buf_prepare() to rcu_dereference_sched(). Signed-off-by: Paul E. McKenney Acked-by: Frederic Weisbecker Cc: Steven Rostedt Cc: laijs@cn.fujitsu.com Cc: dipankar@in.ibm.com Cc: mathieu.desnoyers@polymtl.ca Cc: josh@joshtriplett.org Cc: dvhltc@us.ibm.com Cc: niv@us.ibm.com Cc: peterz@infradead.org Cc: Valdis.Kletnieks@vt.edu Cc: dhowells@redhat.com Cc: Frederic Weisbecker LKML-Reference: <1267667418-32233-3-git-send-email-paulmck@linux.vnet.ibm.com> Signed-off-by: Ingo Molnar diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h index 0804cd5..601ad77 100644 --- a/include/trace/ftrace.h +++ b/include/trace/ftrace.h @@ -699,9 +699,9 @@ __attribute__((section("_ftrace_events"))) event_##call = { \ * __cpu = smp_processor_id(); * * if (in_nmi()) - * trace_buf = rcu_dereference(perf_trace_buf_nmi); + * trace_buf = rcu_dereference_sched(perf_trace_buf_nmi); * else - * trace_buf = rcu_dereference(perf_trace_buf); + * trace_buf = rcu_dereference_sched(perf_trace_buf); * * if (!trace_buf) * goto end; diff --git a/kernel/trace/trace_event_profile.c b/kernel/trace/trace_event_profile.c index f0d6930..c1cc3ab 100644 --- a/kernel/trace/trace_event_profile.c +++ b/kernel/trace/trace_event_profile.c @@ -138,9 +138,9 @@ __kprobes void *ftrace_perf_buf_prepare(int size, unsigned short type, cpu = smp_processor_id(); if (in_nmi()) - trace_buf = rcu_dereference(perf_trace_buf_nmi); + trace_buf = rcu_dereference_sched(perf_trace_buf_nmi); else - trace_buf = rcu_dereference(perf_trace_buf); + trace_buf = rcu_dereference_sched(perf_trace_buf); if (!trace_buf) goto err; -- cgit v0.10.2 From 54dbf96c921513bf98484a20ef366d51944a4c4d Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Wed, 3 Mar 2010 07:46:57 -0800 Subject: rcu: Suppress RCU lockdep warnings during early boot RCU is used during very early boot, before RCU and lockdep have been initialized. So make the underlying primitives (rcu_read_lock_held(), rcu_read_lock_bh_held(), rcu_read_lock_sched_held(), and rcu_dereference_check()) check for early boot via the rcu_scheduler_active flag. This will suppress false positives. Also introduce a debug_lockdep_rcu_enabled() static inline helper function, which tags the CONTINUE_PROVE_RCU case as likely(), as suggested by Ingo Molnar. Signed-off-by: Paul E. McKenney Cc: laijs@cn.fujitsu.com Cc: dipankar@in.ibm.com Cc: mathieu.desnoyers@polymtl.ca Cc: josh@joshtriplett.org Cc: dvhltc@us.ibm.com Cc: niv@us.ibm.com Cc: peterz@infradead.org Cc: rostedt@goodmis.org Cc: Valdis.Kletnieks@vt.edu Cc: dhowells@redhat.com LKML-Reference: <1267631219-8713-2-git-send-email-paulmck@linux.vnet.ibm.com> [ v2: removed incomplete debug_lockdep_rcu_update() bits ] Signed-off-by: Ingo Molnar diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index e22960ec..75921b8 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -97,6 +97,11 @@ extern struct lockdep_map rcu_sched_lock_map; # define rcu_read_release_sched() \ lock_release(&rcu_sched_lock_map, 1, _THIS_IP_) +static inline int debug_lockdep_rcu_enabled(void) +{ + return likely(rcu_scheduler_active && debug_locks); +} + /** * rcu_read_lock_held - might we be in RCU read-side critical section? * @@ -104,12 +109,14 @@ extern struct lockdep_map rcu_sched_lock_map; * an RCU read-side critical section. In absence of CONFIG_PROVE_LOCKING, * this assumes we are in an RCU read-side critical section unless it can * prove otherwise. + * + * Check rcu_scheduler_active to prevent false positives during boot. */ static inline int rcu_read_lock_held(void) { - if (debug_locks) - return lock_is_held(&rcu_lock_map); - return 1; + if (!debug_lockdep_rcu_enabled()) + return 1; + return lock_is_held(&rcu_lock_map); } /** @@ -119,12 +126,14 @@ static inline int rcu_read_lock_held(void) * an RCU-bh read-side critical section. In absence of CONFIG_PROVE_LOCKING, * this assumes we are in an RCU-bh read-side critical section unless it can * prove otherwise. + * + * Check rcu_scheduler_active to prevent false positives during boot. */ static inline int rcu_read_lock_bh_held(void) { - if (debug_locks) - return lock_is_held(&rcu_bh_lock_map); - return 1; + if (!debug_lockdep_rcu_enabled()) + return 1; + return lock_is_held(&rcu_bh_lock_map); } /** @@ -135,15 +144,19 @@ static inline int rcu_read_lock_bh_held(void) * this assumes we are in an RCU-sched read-side critical section unless it * can prove otherwise. Note that disabling of preemption (including * disabling irqs) counts as an RCU-sched read-side critical section. + * + * Check rcu_scheduler_active to prevent false positives during boot. */ #ifdef CONFIG_PREEMPT static inline int rcu_read_lock_sched_held(void) { int lockdep_opinion = 0; + if (!debug_lockdep_rcu_enabled()) + return 1; if (debug_locks) lockdep_opinion = lock_is_held(&rcu_sched_lock_map); - return lockdep_opinion || preempt_count() != 0 || !rcu_scheduler_active; + return lockdep_opinion || preempt_count() != 0; } #else /* #ifdef CONFIG_PREEMPT */ static inline int rcu_read_lock_sched_held(void) @@ -174,7 +187,7 @@ static inline int rcu_read_lock_bh_held(void) #ifdef CONFIG_PREEMPT static inline int rcu_read_lock_sched_held(void) { - return preempt_count() != 0 || !rcu_scheduler_active; + return !rcu_scheduler_active || preempt_count() != 0; } #else /* #ifdef CONFIG_PREEMPT */ static inline int rcu_read_lock_sched_held(void) @@ -198,7 +211,7 @@ static inline int rcu_read_lock_sched_held(void) */ #define rcu_dereference_check(p, c) \ ({ \ - if (debug_locks && !(c)) \ + if (debug_lockdep_rcu_enabled() && !(c)) \ lockdep_rcu_dereference(__FILE__, __LINE__); \ rcu_dereference_raw(p); \ }) -- cgit v0.10.2 From da7196e1f986c846ffa8b2ec385223fad38e8518 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Wed, 3 Mar 2010 11:47:58 +0000 Subject: perf, ARM: Modify kuser rmb() call to compile for Thumb-2 The Thumb-2 instruction set does not provide an encoding for sub pc, r0, #95 as present in the rmb() definition used by perf. This results in compilation failure when using a compiler targetting an instruction set other than ARM. This patch redefines rmb() for ARM by casting the address of the kuser helper to a function pointer, therefore getting the compiler to take care of making the call. Patch taken against tip/master. Signed-off-by: Will Deacon Cc: Russell King - ARM Linux Cc: Jamie Iles Cc: Peter Zijlstra Cc: Mike Galbraith Cc: Paul Mackerras Cc: Arnaldo Carvalho de Melo Cc: Frederic Weisbecker LKML-Reference: <1267616878-2154-1-git-send-email-will.deacon@arm.com> Signed-off-by: Ingo Molnar diff --git a/tools/perf/perf.h b/tools/perf/perf.h index 75f941b..6fb379b 100644 --- a/tools/perf/perf.h +++ b/tools/perf/perf.h @@ -65,9 +65,7 @@ * Use the __kuser_memory_barrier helper in the CPU helper page. See * arch/arm/kernel/entry-armv.S in the kernel source for details. */ -#define rmb() asm volatile("mov r0, #0xffff0fff; mov lr, pc;" \ - "sub pc, r0, #95" ::: "r0", "lr", "cc", \ - "memory") +#define rmb() ((void(*)(void))0xffff0fa0)() #define cpu_relax() asm volatile("":::"memory") #endif -- cgit v0.10.2 From 10c95f4f41889daaa8130e0bd12209825dbe8d39 Mon Sep 17 00:00:00 2001 From: Tom Zanussi Date: Wed, 3 Mar 2010 01:04:32 -0600 Subject: perf trace/scripting: Remove extraneous header read perf_header__read() is already done in perf_session__open(), so remove it from the script gen case. Signed-off-by: Tom Zanussi Cc: fweisbec@gmail.com Cc: rostedt@goodmis.org LKML-Reference: <1267599873-8193-2-git-send-email-tzanussi@gmail.com> Signed-off-by: Ingo Molnar diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 5db687f..b8153db 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -608,7 +608,6 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used) return -1; } - perf_header__read(&session->header, input); err = scripting_ops->generate_script("perf-trace"); goto out; } -- cgit v0.10.2 From cf4fee50282312528e1f8adf73b1831d1d6ae389 Mon Sep 17 00:00:00 2001 From: Tom Zanussi Date: Wed, 3 Mar 2010 01:04:33 -0600 Subject: perf trace: Don't use pager if scripting It's useful for paging through raw traces, but just gets in the way when scripting. Signed-off-by: Tom Zanussi Cc: fweisbec@gmail.com Cc: rostedt@goodmis.org LKML-Reference: <1267599873-8193-3-git-send-email-tzanussi@gmail.com> Signed-off-by: Ingo Molnar diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index b8153db..407041d 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -573,7 +573,8 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used) if (symbol__init() < 0) return -1; - setup_pager(); + if (!script_name) + setup_pager(); session = perf_session__new(input_name, O_RDONLY, 0); if (session == NULL) -- cgit v0.10.2 From 12c3400a84742f8bb0e4edc822e9ccba58781e0c Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Thu, 4 Mar 2010 03:32:16 -0800 Subject: rndis_wlan: correct multicast_list handling V3 My previous patch (655ffee284dfcf9a24ac0343f3e5ee6db85b85c5) added locking in a bad way. Because rndis_set_oid can sleep, there is need to prepare multicast addresses into local buffer under netif_addr_lock first, then call rndis_set_oid outside. This caused reorganizing of the whole function. Signed-off-by: Jiri Pirko Reported-by: Jussi Kivilinna Signed-off-by: David S. Miller diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 9f6d6bf..2887047 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -1496,51 +1496,67 @@ static void set_multicast_list(struct usbnet *usbdev) { struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); struct dev_mc_list *mclist; - __le32 filter; - int ret, i, size; - char *buf; + __le32 filter, basefilter; + int ret; + char *mc_addrs = NULL; + int mc_count; - filter = RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST; + basefilter = filter = RNDIS_PACKET_TYPE_DIRECTED | + RNDIS_PACKET_TYPE_BROADCAST; - netif_addr_lock_bh(usbdev->net); if (usbdev->net->flags & IFF_PROMISC) { filter |= RNDIS_PACKET_TYPE_PROMISCUOUS | RNDIS_PACKET_TYPE_ALL_LOCAL; - } else if (usbdev->net->flags & IFF_ALLMULTI || - netdev_mc_count(usbdev->net) > priv->multicast_size) { + } else if (usbdev->net->flags & IFF_ALLMULTI) { + filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST; + } + + if (filter != basefilter) + goto set_filter; + + /* + * mc_list should be accessed holding the lock, so copy addresses to + * local buffer first. + */ + netif_addr_lock_bh(usbdev->net); + mc_count = netdev_mc_count(usbdev->net); + if (mc_count > priv->multicast_size) { filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST; - } else if (!netdev_mc_empty(usbdev->net)) { - size = min(priv->multicast_size, netdev_mc_count(usbdev->net)); - buf = kmalloc(size * ETH_ALEN, GFP_KERNEL); - if (!buf) { + } else if (mc_count) { + int i = 0; + + mc_addrs = kmalloc(mc_count * ETH_ALEN, GFP_ATOMIC); + if (!mc_addrs) { netdev_warn(usbdev->net, "couldn't alloc %d bytes of memory\n", - size * ETH_ALEN); + mc_count * ETH_ALEN); netif_addr_unlock_bh(usbdev->net); return; } - i = 0; - netdev_for_each_mc_addr(mclist, usbdev->net) { - if (i == size) - break; - memcpy(buf + i++ * ETH_ALEN, mclist->dmi_addr, ETH_ALEN); - } + netdev_for_each_mc_addr(mclist, usbdev->net) + memcpy(mc_addrs + i++ * ETH_ALEN, + mclist->dmi_addr, ETH_ALEN); + } + netif_addr_unlock_bh(usbdev->net); - ret = rndis_set_oid(usbdev, OID_802_3_MULTICAST_LIST, buf, - i * ETH_ALEN); - if (ret == 0 && i > 0) + if (filter != basefilter) + goto set_filter; + + if (mc_count) { + ret = rndis_set_oid(usbdev, OID_802_3_MULTICAST_LIST, mc_addrs, + mc_count * ETH_ALEN); + kfree(mc_addrs); + if (ret == 0) filter |= RNDIS_PACKET_TYPE_MULTICAST; else filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST; netdev_dbg(usbdev->net, "OID_802_3_MULTICAST_LIST(%d, max: %d) -> %d\n", - i, priv->multicast_size, ret); - - kfree(buf); + mc_count, priv->multicast_size, ret); } - netif_addr_unlock_bh(usbdev->net); +set_filter: ret = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &filter, sizeof(filter)); if (ret < 0) { -- cgit v0.10.2 From 422d2cb8f9afadba1ecd3614f658b6daaaa480fb Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Fri, 26 Feb 2010 15:32:31 -0800 Subject: ceph: reset osd after relevant messages timed out This simplifies the process of timing out messages. We keep lru of current messages that are in flight. If a timeout has passed, we reset the osd connection, so that messages will be retransmitted. This is a failsafe in case we hit some sort of problem sending out message to the OSD. Normally, we'll get notification via an updated osdmap if there are problems. If a request is older than the keepalive timeout, send a keepalive to ensure we detect any breaks in the TCP connection. Signed-off-by: Yehuda Sadeh Signed-off-by: Sage Weil diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index c4763bf..dbe63db9 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -17,6 +17,8 @@ #define OSD_OPREPLY_FRONT_LEN 512 const static struct ceph_connection_operations osd_con_ops; +static int __kick_requests(struct ceph_osd_client *osdc, + struct ceph_osd *kickosd); static void kick_requests(struct ceph_osd_client *osdc, struct ceph_osd *osd); @@ -339,6 +341,7 @@ static struct ceph_osd *create_osd(struct ceph_osd_client *osdc) osd->o_con.ops = &osd_con_ops; osd->o_con.peer_name.type = CEPH_ENTITY_TYPE_OSD; + INIT_LIST_HEAD(&osd->o_keepalive_item); return osd; } @@ -461,6 +464,16 @@ static struct ceph_osd *__lookup_osd(struct ceph_osd_client *osdc, int o) return NULL; } +static void __schedule_osd_timeout(struct ceph_osd_client *osdc) +{ + schedule_delayed_work(&osdc->timeout_work, + osdc->client->mount_args->osd_keepalive_timeout * HZ); +} + +static void __cancel_osd_timeout(struct ceph_osd_client *osdc) +{ + cancel_delayed_work(&osdc->timeout_work); +} /* * Register request, assign tid. If this is the first request, set up @@ -472,21 +485,16 @@ static void register_request(struct ceph_osd_client *osdc, mutex_lock(&osdc->request_mutex); req->r_tid = ++osdc->last_tid; req->r_request->hdr.tid = cpu_to_le64(req->r_tid); + INIT_LIST_HEAD(&req->r_req_lru_item); dout("register_request %p tid %lld\n", req, req->r_tid); __insert_request(osdc, req); ceph_osdc_get_request(req); osdc->num_requests++; - req->r_timeout_stamp = - jiffies + osdc->client->mount_args->osd_timeout*HZ; - if (osdc->num_requests == 1) { - osdc->timeout_tid = req->r_tid; - dout(" timeout on tid %llu at %lu\n", req->r_tid, - req->r_timeout_stamp); - schedule_delayed_work(&osdc->timeout_work, - round_jiffies_relative(req->r_timeout_stamp - jiffies)); + dout(" first request, scheduling timeout\n"); + __schedule_osd_timeout(osdc); } mutex_unlock(&osdc->request_mutex); } @@ -513,21 +521,10 @@ static void __unregister_request(struct ceph_osd_client *osdc, ceph_osdc_put_request(req); - if (req->r_tid == osdc->timeout_tid) { - if (osdc->num_requests == 0) { - dout("no requests, canceling timeout\n"); - osdc->timeout_tid = 0; - cancel_delayed_work(&osdc->timeout_work); - } else { - req = rb_entry(rb_first(&osdc->requests), - struct ceph_osd_request, r_node); - osdc->timeout_tid = req->r_tid; - dout("rescheduled timeout on tid %llu at %lu\n", - req->r_tid, req->r_timeout_stamp); - schedule_delayed_work(&osdc->timeout_work, - round_jiffies_relative(req->r_timeout_stamp - - jiffies)); - } + list_del_init(&req->r_req_lru_item); + if (osdc->num_requests == 0) { + dout(" no requests, canceling timeout\n"); + __cancel_osd_timeout(osdc); } } @@ -540,6 +537,7 @@ static void __cancel_request(struct ceph_osd_request *req) ceph_con_revoke(&req->r_osd->o_con, req->r_request); req->r_sent = 0; } + list_del_init(&req->r_req_lru_item); } /* @@ -635,7 +633,8 @@ static int __send_request(struct ceph_osd_client *osdc, reqhead->flags |= cpu_to_le32(req->r_flags); /* e.g., RETRY */ reqhead->reassert_version = req->r_reassert_version; - req->r_timeout_stamp = jiffies+osdc->client->mount_args->osd_timeout*HZ; + req->r_sent_stamp = jiffies; + list_move_tail(&osdc->req_lru, &req->r_req_lru_item); ceph_msg_get(req->r_request); /* send consumes a ref */ ceph_con_send(&req->r_osd->o_con, req->r_request); @@ -656,11 +655,14 @@ static void handle_timeout(struct work_struct *work) { struct ceph_osd_client *osdc = container_of(work, struct ceph_osd_client, timeout_work.work); - struct ceph_osd_request *req; + struct ceph_osd_request *req, *last_req = NULL; struct ceph_osd *osd; unsigned long timeout = osdc->client->mount_args->osd_timeout * HZ; - unsigned long next_timeout = timeout + jiffies; + unsigned long keepalive = + osdc->client->mount_args->osd_keepalive_timeout * HZ; + unsigned long last_sent = 0; struct rb_node *p; + struct list_head slow_osds; dout("timeout\n"); down_read(&osdc->map_sem); @@ -683,25 +685,56 @@ static void handle_timeout(struct work_struct *work) continue; } } - for (p = rb_first(&osdc->osds); p; p = rb_next(p)) { - osd = rb_entry(p, struct ceph_osd, o_node); - if (list_empty(&osd->o_requests)) - continue; - req = list_first_entry(&osd->o_requests, - struct ceph_osd_request, r_osd_item); - if (time_before(jiffies, req->r_timeout_stamp)) - continue; - dout(" tid %llu (at least) timed out on osd%d\n", + /* + * reset osds that appear to be _really_ unresponsive. this + * is a failsafe measure.. we really shouldn't be getting to + * this point if the system is working properly. the monitors + * should mark the osd as failed and we should find out about + * it from an updated osd map. + */ + while (!list_empty(&osdc->req_lru)) { + req = list_entry(osdc->req_lru.next, struct ceph_osd_request, + r_req_lru_item); + + if (time_before(jiffies, req->r_sent_stamp + timeout)) + break; + + BUG_ON(req == last_req && req->r_sent_stamp == last_sent); + last_req = req; + last_sent = req->r_sent_stamp; + + osd = req->r_osd; + BUG_ON(!osd); + pr_warning(" tid %llu timed out on osd%d, will reset osd\n", + req->r_tid, osd->o_osd); + __kick_requests(osdc, osd); + } + + /* + * ping osds that are a bit slow. this ensures that if there + * is a break in the TCP connection we will notice, and reopen + * a connection with that osd (from the fault callback). + */ + INIT_LIST_HEAD(&slow_osds); + list_for_each_entry(req, &osdc->req_lru, r_req_lru_item) { + if (time_before(jiffies, req->r_sent_stamp + keepalive)) + break; + + osd = req->r_osd; + BUG_ON(!osd); + dout(" tid %llu is slow, will send keepalive on osd%d\n", req->r_tid, osd->o_osd); - req->r_timeout_stamp = next_timeout; + list_move_tail(&osd->o_keepalive_item, &slow_osds); + } + while (!list_empty(&slow_osds)) { + osd = list_entry(slow_osds.next, struct ceph_osd, + o_keepalive_item); + list_del_init(&osd->o_keepalive_item); ceph_con_keepalive(&osd->o_con); } - if (osdc->timeout_tid) - schedule_delayed_work(&osdc->timeout_work, - round_jiffies_relative(timeout)); - + __schedule_osd_timeout(osdc); mutex_unlock(&osdc->request_mutex); up_read(&osdc->map_sem); @@ -819,18 +852,7 @@ bad: } -/* - * Resubmit osd requests whose osd or osd address has changed. Request - * a new osd map if osds are down, or we are otherwise unable to determine - * how to direct a request. - * - * Close connections to down osds. - * - * If @who is specified, resubmit requests for that specific osd. - * - * Caller should hold map_sem for read and request_mutex. - */ -static void kick_requests(struct ceph_osd_client *osdc, +static int __kick_requests(struct ceph_osd_client *osdc, struct ceph_osd *kickosd) { struct ceph_osd_request *req; @@ -839,7 +861,6 @@ static void kick_requests(struct ceph_osd_client *osdc, int err; dout("kick_requests osd%d\n", kickosd ? kickosd->o_osd : -1); - mutex_lock(&osdc->request_mutex); if (kickosd) { __reset_osd(osdc, kickosd); } else { @@ -900,14 +921,36 @@ kick: req->r_resend = true; } } + + return needmap; +} + +/* + * Resubmit osd requests whose osd or osd address has changed. Request + * a new osd map if osds are down, or we are otherwise unable to determine + * how to direct a request. + * + * Close connections to down osds. + * + * If @who is specified, resubmit requests for that specific osd. + * + * Caller should hold map_sem for read and request_mutex. + */ +static void kick_requests(struct ceph_osd_client *osdc, + struct ceph_osd *kickosd) +{ + int needmap; + + mutex_lock(&osdc->request_mutex); + needmap = __kick_requests(osdc, kickosd); mutex_unlock(&osdc->request_mutex); if (needmap) { dout("%d requests for down osds, need new map\n", needmap); ceph_monc_request_next_osdmap(&osdc->client->monc); } -} +} /* * Process updated osd map. * @@ -1164,11 +1207,11 @@ int ceph_osdc_init(struct ceph_osd_client *osdc, struct ceph_client *client) init_completion(&osdc->map_waiters); osdc->last_requested_map = 0; mutex_init(&osdc->request_mutex); - osdc->timeout_tid = 0; osdc->last_tid = 0; osdc->osds = RB_ROOT; INIT_LIST_HEAD(&osdc->osd_lru); osdc->requests = RB_ROOT; + INIT_LIST_HEAD(&osdc->req_lru); osdc->num_requests = 0; INIT_DELAYED_WORK(&osdc->timeout_work, handle_timeout); INIT_DELAYED_WORK(&osdc->osds_timeout_work, handle_osds_timeout); diff --git a/fs/ceph/osd_client.h b/fs/ceph/osd_client.h index f256eba..1b1a3ca 100644 --- a/fs/ceph/osd_client.h +++ b/fs/ceph/osd_client.h @@ -36,12 +36,15 @@ struct ceph_osd { void *o_authorizer_buf, *o_authorizer_reply_buf; size_t o_authorizer_buf_len, o_authorizer_reply_buf_len; unsigned long lru_ttl; + int o_marked_for_keepalive; + struct list_head o_keepalive_item; }; /* an in-flight request */ struct ceph_osd_request { u64 r_tid; /* unique for this client */ struct rb_node r_node; + struct list_head r_req_lru_item; struct list_head r_osd_item; struct ceph_osd *r_osd; struct ceph_pg r_pgid; @@ -67,7 +70,7 @@ struct ceph_osd_request { char r_oid[40]; /* object name */ int r_oid_len; - unsigned long r_timeout_stamp; + unsigned long r_sent_stamp; bool r_resend; /* msg send failed, needs retry */ struct ceph_file_layout r_file_layout; @@ -92,6 +95,7 @@ struct ceph_osd_client { u64 timeout_tid; /* tid of timeout triggering rq */ u64 last_tid; /* tid of last request */ struct rb_root requests; /* pending requests */ + struct list_head req_lru; /* pending requests lru */ int num_requests; struct delayed_work timeout_work; struct delayed_work osds_timeout_work; diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 74953be..4290a6e 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -292,6 +292,7 @@ enum { Opt_wsize, Opt_rsize, Opt_osdtimeout, + Opt_osdkeepalivetimeout, Opt_mount_timeout, Opt_osd_idle_ttl, Opt_caps_wanted_delay_min, @@ -322,6 +323,7 @@ static match_table_t arg_tokens = { {Opt_wsize, "wsize=%d"}, {Opt_rsize, "rsize=%d"}, {Opt_osdtimeout, "osdtimeout=%d"}, + {Opt_osdkeepalivetimeout, "osdkeepalive=%d"}, {Opt_mount_timeout, "mount_timeout=%d"}, {Opt_osd_idle_ttl, "osd_idle_ttl=%d"}, {Opt_caps_wanted_delay_min, "caps_wanted_delay_min=%d"}, @@ -367,7 +369,8 @@ static struct ceph_mount_args *parse_mount_args(int flags, char *options, /* start with defaults */ args->sb_flags = flags; args->flags = CEPH_OPT_DEFAULT; - args->osd_timeout = 5; /* seconds */ + args->osd_timeout = CEPH_OSD_TIMEOUT_DEFAULT; + args->osd_keepalive_timeout = CEPH_OSD_KEEPALIVE_DEFAULT; args->mount_timeout = CEPH_MOUNT_TIMEOUT_DEFAULT; /* seconds */ args->osd_idle_ttl = CEPH_OSD_IDLE_TTL_DEFAULT; /* seconds */ args->caps_wanted_delay_min = CEPH_CAPS_WANTED_DELAY_MIN_DEFAULT; @@ -468,6 +471,9 @@ static struct ceph_mount_args *parse_mount_args(int flags, char *options, case Opt_osdtimeout: args->osd_timeout = intval; break; + case Opt_osdkeepalivetimeout: + args->osd_keepalive_timeout = intval; + break; case Opt_mount_timeout: args->mount_timeout = intval; break; diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 6a778f2..02c0ddc 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -62,6 +62,7 @@ struct ceph_mount_args { int max_readdir; /* max readdir size */ int congestion_kb; /* max readdir size */ int osd_timeout; + int osd_keepalive_timeout; char *snapdir_name; /* default ".snap" */ char *name; char *secret; @@ -72,6 +73,8 @@ struct ceph_mount_args { * defaults */ #define CEPH_MOUNT_TIMEOUT_DEFAULT 60 +#define CEPH_OSD_TIMEOUT_DEFAULT 60 /* seconds */ +#define CEPH_OSD_KEEPALIVE_DEFAULT 5 #define CEPH_OSD_IDLE_TTL_DEFAULT 60 #define CEPH_MOUNT_RSIZE_DEFAULT (512*1024) /* readahead */ -- cgit v0.10.2 From 5bc923c505926af927d4f3011da92c243787d6a7 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 5 Mar 2010 00:31:33 -0800 Subject: Input: gamecon - fix off by one range check It should be >= GC_MAX not > GC_MAX. Signed-off-by: Dan Carpenter Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c index ae998d9..7a55714 100644 --- a/drivers/input/joystick/gamecon.c +++ b/drivers/input/joystick/gamecon.c @@ -819,7 +819,7 @@ static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type) int i; int err; - if (pad_type < 1 || pad_type > GC_MAX) { + if (pad_type < 1 || pad_type >= GC_MAX) { pr_err("Pad type %d unknown\n", pad_type); return -EINVAL; } -- cgit v0.10.2 From 776943fd6f104a6e8457dc95a17282e69e963666 Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Thu, 4 Mar 2010 21:50:59 -0800 Subject: Input: wacom - merge out and in prox events Process out and in prox events for Graphire and Tablet PC devices in the same loop to simplify the data parsing logic. Signed-off-by: Ping Cheng Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 4a852d8..b3ba343 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c @@ -155,19 +155,19 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) { struct wacom_features *features = &wacom->features; unsigned char *data = wacom->data; - int x, y, rw; - static int penData = 0; + int x, y, prox; + int rw = 0; + int retval = 0; if (data[0] != WACOM_REPORT_PENABLED) { dbg("wacom_graphire_irq: received unknown report #%d", data[0]); - return 0; + goto exit; } - if (data[1] & 0x80) { - /* in prox and not a pad data */ - penData = 1; - - switch ((data[1] >> 5) & 3) { + prox = data[1] & 0x80; + if (prox || wacom->id[0]) { + if (prox) { + switch ((data[1] >> 5) & 3) { case 0: /* Pen */ wacom->tool[0] = BTN_TOOL_PEN; @@ -181,23 +181,13 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) case 2: /* Mouse with wheel */ wacom_report_key(wcombo, BTN_MIDDLE, data[1] & 0x04); - if (features->type == WACOM_G4 || features->type == WACOM_MO) { - rw = data[7] & 0x04 ? (data[7] & 0x03)-4 : (data[7] & 0x03); - wacom_report_rel(wcombo, REL_WHEEL, -rw); - } else - wacom_report_rel(wcombo, REL_WHEEL, -(signed char) data[6]); /* fall through */ case 3: /* Mouse without wheel */ wacom->tool[0] = BTN_TOOL_MOUSE; wacom->id[0] = CURSOR_DEVICE_ID; - wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01); - wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02); - if (features->type == WACOM_G4 || features->type == WACOM_MO) - wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f); - else - wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f); break; + } } x = wacom_le16_to_cpu(&data[2]); y = wacom_le16_to_cpu(&data[4]); @@ -208,36 +198,32 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x01); wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x04); - } - wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */ - wacom_report_key(wcombo, wacom->tool[0], 1); - } else if (wacom->id[0]) { - wacom_report_abs(wcombo, ABS_X, 0); - wacom_report_abs(wcombo, ABS_Y, 0); - if (wacom->tool[0] == BTN_TOOL_MOUSE) { - wacom_report_key(wcombo, BTN_LEFT, 0); - wacom_report_key(wcombo, BTN_RIGHT, 0); - wacom_report_abs(wcombo, ABS_DISTANCE, 0); } else { - wacom_report_abs(wcombo, ABS_PRESSURE, 0); - wacom_report_key(wcombo, BTN_TOUCH, 0); - wacom_report_key(wcombo, BTN_STYLUS, 0); - wacom_report_key(wcombo, BTN_STYLUS2, 0); + wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01); + wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02); + if (features->type == WACOM_G4 || + features->type == WACOM_MO) { + wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f); + rw = (signed)(data[7] & 0x04) - (data[7] & 0x03); + } else { + wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f); + rw = -(signed)data[6]; + } + wacom_report_rel(wcombo, REL_WHEEL, rw); } - wacom->id[0] = 0; - wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */ - wacom_report_key(wcombo, wacom->tool[0], 0); + + if (!prox) + wacom->id[0] = 0; + wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */ + wacom_report_key(wcombo, wacom->tool[0], prox); + wacom_input_sync(wcombo); /* sync last event */ } /* send pad data */ switch (features->type) { case WACOM_G4: - if (data[7] & 0xf8) { - if (penData) { - wacom_input_sync(wcombo); /* sync last event */ - if (!wacom->id[0]) - penData = 0; - } + prox = data[7] & 0xf8; + if (prox || wacom->id[1]) { wacom->id[1] = PAD_DEVICE_ID; wacom_report_key(wcombo, BTN_0, (data[7] & 0x40)); wacom_report_key(wcombo, BTN_4, (data[7] & 0x80)); @@ -245,29 +231,16 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) wacom_report_rel(wcombo, REL_WHEEL, rw); wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0); wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); - wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); - } else if (wacom->id[1]) { - if (penData) { - wacom_input_sync(wcombo); /* sync last event */ - if (!wacom->id[0]) - penData = 0; - } - wacom->id[1] = 0; - wacom_report_key(wcombo, BTN_0, (data[7] & 0x40)); - wacom_report_key(wcombo, BTN_4, (data[7] & 0x80)); - wacom_report_rel(wcombo, REL_WHEEL, 0); - wacom_report_key(wcombo, BTN_TOOL_FINGER, 0); - wacom_report_abs(wcombo, ABS_MISC, 0); + if (!prox) + wacom->id[1] = 0; + wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); } + retval = 1; break; case WACOM_MO: - if ((data[7] & 0xf8) || (data[8] & 0xff)) { - if (penData) { - wacom_input_sync(wcombo); /* sync last event */ - if (!wacom->id[0]) - penData = 0; - } + prox = (data[7] & 0xf8) || data[8]; + if (prox || wacom->id[1]) { wacom->id[1] = PAD_DEVICE_ID; wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); @@ -275,27 +248,16 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) wacom_report_key(wcombo, BTN_5, (data[7] & 0x40)); wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f)); wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0); + if (!prox) + wacom->id[1] = 0; wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); - } else if (wacom->id[1]) { - if (penData) { - wacom_input_sync(wcombo); /* sync last event */ - if (!wacom->id[0]) - penData = 0; - } - wacom->id[1] = 0; - wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); - wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); - wacom_report_key(wcombo, BTN_4, (data[7] & 0x10)); - wacom_report_key(wcombo, BTN_5, (data[7] & 0x40)); - wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f)); - wacom_report_key(wcombo, BTN_TOOL_FINGER, 0); - wacom_report_abs(wcombo, ABS_MISC, 0); - wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); } + retval = 1; break; } - return 1; +exit: + return retval; } static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo) @@ -636,9 +598,9 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) static void wacom_tpc_finger_in(struct wacom_wac *wacom, void *wcombo, char *data, int idx) { wacom_report_abs(wcombo, ABS_X, - (data[2 + idx * 2] & 0xff) | ((data[3 + idx * 2] & 0x7f) << 8)); + data[2 + idx * 2] | ((data[3 + idx * 2] & 0x7f) << 8)); wacom_report_abs(wcombo, ABS_Y, - (data[6 + idx * 2] & 0xff) | ((data[7 + idx * 2] & 0x7f) << 8)); + data[6 + idx * 2] | ((data[7 + idx * 2] & 0x7f) << 8)); wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); wacom_report_key(wcombo, wacom->tool[idx], 1); if (idx) @@ -782,31 +744,24 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo) touchInProx = 0; - if (prox) { /* in prox */ - if (!wacom->id[0]) { - /* Going into proximity select tool */ - wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; - if (wacom->tool[0] == BTN_TOOL_PEN) - wacom->id[0] = STYLUS_DEVICE_ID; - else - wacom->id[0] = ERASER_DEVICE_ID; - } - wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); - wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10); - wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2])); - wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4])); - pressure = ((data[7] & 0x01) << 8) | data[6]; - if (pressure < 0) - pressure = features->pressure_max + pressure + 1; - wacom_report_abs(wcombo, ABS_PRESSURE, pressure); - wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x05); - } else { - wacom_report_abs(wcombo, ABS_X, 0); - wacom_report_abs(wcombo, ABS_Y, 0); - wacom_report_abs(wcombo, ABS_PRESSURE, 0); - wacom_report_key(wcombo, BTN_STYLUS, 0); - wacom_report_key(wcombo, BTN_STYLUS2, 0); - wacom_report_key(wcombo, BTN_TOUCH, 0); + if (!wacom->id[0]) { /* first in prox */ + /* Going into proximity select tool */ + wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; + if (wacom->tool[0] == BTN_TOOL_PEN) + wacom->id[0] = STYLUS_DEVICE_ID; + else + wacom->id[0] = ERASER_DEVICE_ID; + } + wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); + wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10); + wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2])); + wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4])); + pressure = ((data[7] & 0x01) << 8) | data[6]; + if (pressure < 0) + pressure = features->pressure_max + pressure + 1; + wacom_report_abs(wcombo, ABS_PRESSURE, pressure); + wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x05); + if (!prox) { /* out-prox */ wacom->id[0] = 0; /* pen is out so touch can be enabled now */ touchInProx = 1; -- cgit v0.10.2 From 8eae939f1400326b06d0c9afe53d2a484a326871 Mon Sep 17 00:00:00 2001 From: Zhu Yi Date: Thu, 4 Mar 2010 18:01:40 +0000 Subject: net: add limit for socket backlog We got system OOM while running some UDP netperf testing on the loopback device. The case is multiple senders sent stream UDP packets to a single receiver via loopback on local host. Of course, the receiver is not able to handle all the packets in time. But we surprisingly found that these packets were not discarded due to the receiver's sk->sk_rcvbuf limit. Instead, they are kept queuing to sk->sk_backlog and finally ate up all the memory. We believe this is a secure hole that a none privileged user can crash the system. The root cause for this problem is, when the receiver is doing __release_sock() (i.e. after userspace recv, kernel udp_recvmsg -> skb_free_datagram_locked -> release_sock), it moves skbs from backlog to sk_receive_queue with the softirq enabled. In the above case, multiple busy senders will almost make it an endless loop. The skbs in the backlog end up eat all the system memory. The issue is not only for UDP. Any protocols using socket backlog is potentially affected. The patch adds limit for socket backlog so that the backlog size cannot be expanded endlessly. Reported-by: Alex Shi Cc: David Miller Cc: Arnaldo Carvalho de Melo Cc: Alexey Kuznetsov Cc: Patrick McHardy Cc: Vlad Yasevich Cc: Sridhar Samudrala Cc: Jon Maloy Cc: Allan Stephens Cc: Andrew Hendry Signed-off-by: Zhu Yi Signed-off-by: Eric Dumazet Acked-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller diff --git a/include/net/sock.h b/include/net/sock.h index 6cb1676..2516d76 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -253,6 +253,8 @@ struct sock { struct { struct sk_buff *head; struct sk_buff *tail; + int len; + int limit; } sk_backlog; wait_queue_head_t *sk_sleep; struct dst_entry *sk_dst_cache; @@ -589,7 +591,7 @@ static inline int sk_stream_memory_free(struct sock *sk) return sk->sk_wmem_queued < sk->sk_sndbuf; } -/* The per-socket spinlock must be held here. */ +/* OOB backlog add */ static inline void sk_add_backlog(struct sock *sk, struct sk_buff *skb) { if (!sk->sk_backlog.tail) { @@ -601,6 +603,17 @@ static inline void sk_add_backlog(struct sock *sk, struct sk_buff *skb) skb->next = NULL; } +/* The per-socket spinlock must be held here. */ +static inline int sk_add_backlog_limited(struct sock *sk, struct sk_buff *skb) +{ + if (sk->sk_backlog.len >= max(sk->sk_backlog.limit, sk->sk_rcvbuf << 1)) + return -ENOBUFS; + + sk_add_backlog(sk, skb); + sk->sk_backlog.len += skb->truesize; + return 0; +} + static inline int sk_backlog_rcv(struct sock *sk, struct sk_buff *skb) { return sk->sk_backlog_rcv(sk, skb); diff --git a/net/core/sock.c b/net/core/sock.c index fcd397a..6e22dc9 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -340,8 +340,12 @@ int sk_receive_skb(struct sock *sk, struct sk_buff *skb, const int nested) rc = sk_backlog_rcv(sk, skb); mutex_release(&sk->sk_lock.dep_map, 1, _RET_IP_); - } else - sk_add_backlog(sk, skb); + } else if (sk_add_backlog_limited(sk, skb)) { + bh_unlock_sock(sk); + atomic_inc(&sk->sk_drops); + goto discard_and_relse; + } + bh_unlock_sock(sk); out: sock_put(sk); @@ -1139,6 +1143,7 @@ struct sock *sk_clone(const struct sock *sk, const gfp_t priority) sock_lock_init(newsk); bh_lock_sock(newsk); newsk->sk_backlog.head = newsk->sk_backlog.tail = NULL; + newsk->sk_backlog.len = 0; atomic_set(&newsk->sk_rmem_alloc, 0); /* @@ -1542,6 +1547,12 @@ static void __release_sock(struct sock *sk) bh_lock_sock(sk); } while ((skb = sk->sk_backlog.head) != NULL); + + /* + * Doing the zeroing here guarantee we can not loop forever + * while a wild producer attempts to flood us. + */ + sk->sk_backlog.len = 0; } /** @@ -1874,6 +1885,7 @@ void sock_init_data(struct socket *sock, struct sock *sk) sk->sk_allocation = GFP_KERNEL; sk->sk_rcvbuf = sysctl_rmem_default; sk->sk_sndbuf = sysctl_wmem_default; + sk->sk_backlog.limit = sk->sk_rcvbuf << 1; sk->sk_state = TCP_CLOSE; sk_set_socket(sk, sock); -- cgit v0.10.2 From 6b03a53a5ab7ccf2d5d69f96cf1c739c4d2a8fb9 Mon Sep 17 00:00:00 2001 From: Zhu Yi Date: Thu, 4 Mar 2010 18:01:41 +0000 Subject: tcp: use limited socket backlog Make tcp adapt to the limited socket backlog change. Cc: "David S. Miller" Cc: Alexey Kuznetsov Cc: "Pekka Savola (ipv6)" Cc: Patrick McHardy Signed-off-by: Zhu Yi Acked-by: Eric Dumazet Signed-off-by: David S. Miller diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index c3588b4..4baf194 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1682,8 +1682,10 @@ process: if (!tcp_prequeue(sk, skb)) ret = tcp_v4_do_rcv(sk, skb); } - } else - sk_add_backlog(sk, skb); + } else if (sk_add_backlog_limited(sk, skb)) { + bh_unlock_sock(sk); + goto discard_and_relse; + } bh_unlock_sock(sk); sock_put(sk); diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 6963a6b..c4ea9d5 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1740,8 +1740,10 @@ process: if (!tcp_prequeue(sk, skb)) ret = tcp_v6_do_rcv(sk, skb); } - } else - sk_add_backlog(sk, skb); + } else if (sk_add_backlog_limited(sk, skb)) { + bh_unlock_sock(sk); + goto discard_and_relse; + } bh_unlock_sock(sk); sock_put(sk); -- cgit v0.10.2 From 55349790d7cbf0d381873a7ece1dcafcffd4aaa9 Mon Sep 17 00:00:00 2001 From: Zhu Yi Date: Thu, 4 Mar 2010 18:01:42 +0000 Subject: udp: use limited socket backlog Make udp adapt to the limited socket backlog change. Cc: "David S. Miller" Cc: Alexey Kuznetsov Cc: "Pekka Savola (ipv6)" Cc: Patrick McHardy Signed-off-by: Zhu Yi Acked-by: Eric Dumazet Signed-off-by: David S. Miller diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 608a544..e7eb47f 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1371,8 +1371,10 @@ int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) bh_lock_sock(sk); if (!sock_owned_by_user(sk)) rc = __udp_queue_rcv_skb(sk, skb); - else - sk_add_backlog(sk, skb); + else if (sk_add_backlog_limited(sk, skb)) { + bh_unlock_sock(sk); + goto drop; + } bh_unlock_sock(sk); return rc; diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 52b8347..6480491 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -583,16 +583,20 @@ static void flush_stack(struct sock **stack, unsigned int count, bh_lock_sock(sk); if (!sock_owned_by_user(sk)) udpv6_queue_rcv_skb(sk, skb1); - else - sk_add_backlog(sk, skb1); + else if (sk_add_backlog_limited(sk, skb1)) { + kfree_skb(skb1); + bh_unlock_sock(sk); + goto drop; + } bh_unlock_sock(sk); - } else { - atomic_inc(&sk->sk_drops); - UDP6_INC_STATS_BH(sock_net(sk), - UDP_MIB_RCVBUFERRORS, IS_UDPLITE(sk)); - UDP6_INC_STATS_BH(sock_net(sk), - UDP_MIB_INERRORS, IS_UDPLITE(sk)); + continue; } +drop: + atomic_inc(&sk->sk_drops); + UDP6_INC_STATS_BH(sock_net(sk), + UDP_MIB_RCVBUFERRORS, IS_UDPLITE(sk)); + UDP6_INC_STATS_BH(sock_net(sk), + UDP_MIB_INERRORS, IS_UDPLITE(sk)); } } /* @@ -754,8 +758,12 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, bh_lock_sock(sk); if (!sock_owned_by_user(sk)) udpv6_queue_rcv_skb(sk, skb); - else - sk_add_backlog(sk, skb); + else if (sk_add_backlog_limited(sk, skb)) { + atomic_inc(&sk->sk_drops); + bh_unlock_sock(sk); + sock_put(sk); + goto discard; + } bh_unlock_sock(sk); sock_put(sk); return 0; -- cgit v0.10.2 From 79545b681961d7001c1f4c3eb9ffb87bed4485db Mon Sep 17 00:00:00 2001 From: Zhu Yi Date: Thu, 4 Mar 2010 18:01:43 +0000 Subject: llc: use limited socket backlog Make llc adapt to the limited socket backlog change. Cc: Arnaldo Carvalho de Melo Signed-off-by: Zhu Yi Acked-by: Eric Dumazet Acked-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c index a8dde9b..c0539ff 100644 --- a/net/llc/llc_conn.c +++ b/net/llc/llc_conn.c @@ -827,7 +827,8 @@ void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb) else { dprintk("%s: adding to backlog...\n", __func__); llc_set_backlog_type(skb, LLC_PACKET); - sk_add_backlog(sk, skb); + if (sk_add_backlog_limited(sk, skb)) + goto drop_unlock; } out: bh_unlock_sock(sk); -- cgit v0.10.2 From 50b1a782f845140f4138f14a1ce8a4a6dd0cc82f Mon Sep 17 00:00:00 2001 From: Zhu Yi Date: Thu, 4 Mar 2010 18:01:44 +0000 Subject: sctp: use limited socket backlog Make sctp adapt to the limited socket backlog change. Cc: Vlad Yasevich Cc: Sridhar Samudrala Signed-off-by: Zhu Yi Signed-off-by: David S. Miller diff --git a/net/sctp/input.c b/net/sctp/input.c index c0c973e..cbc0636 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c @@ -75,7 +75,7 @@ static struct sctp_association *__sctp_lookup_association( const union sctp_addr *peer, struct sctp_transport **pt); -static void sctp_add_backlog(struct sock *sk, struct sk_buff *skb); +static int sctp_add_backlog(struct sock *sk, struct sk_buff *skb); /* Calculate the SCTP checksum of an SCTP packet. */ @@ -265,8 +265,13 @@ int sctp_rcv(struct sk_buff *skb) } if (sock_owned_by_user(sk)) { + if (sctp_add_backlog(sk, skb)) { + sctp_bh_unlock_sock(sk); + sctp_chunk_free(chunk); + skb = NULL; /* sctp_chunk_free already freed the skb */ + goto discard_release; + } SCTP_INC_STATS_BH(SCTP_MIB_IN_PKT_BACKLOG); - sctp_add_backlog(sk, skb); } else { SCTP_INC_STATS_BH(SCTP_MIB_IN_PKT_SOFTIRQ); sctp_inq_push(&chunk->rcvr->inqueue, chunk); @@ -336,8 +341,10 @@ int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb) sctp_bh_lock_sock(sk); if (sock_owned_by_user(sk)) { - sk_add_backlog(sk, skb); - backloged = 1; + if (sk_add_backlog_limited(sk, skb)) + sctp_chunk_free(chunk); + else + backloged = 1; } else sctp_inq_push(inqueue, chunk); @@ -362,22 +369,27 @@ done: return 0; } -static void sctp_add_backlog(struct sock *sk, struct sk_buff *skb) +static int sctp_add_backlog(struct sock *sk, struct sk_buff *skb) { struct sctp_chunk *chunk = SCTP_INPUT_CB(skb)->chunk; struct sctp_ep_common *rcvr = chunk->rcvr; + int ret; - /* Hold the assoc/ep while hanging on the backlog queue. - * This way, we know structures we need will not disappear from us - */ - if (SCTP_EP_TYPE_ASSOCIATION == rcvr->type) - sctp_association_hold(sctp_assoc(rcvr)); - else if (SCTP_EP_TYPE_SOCKET == rcvr->type) - sctp_endpoint_hold(sctp_ep(rcvr)); - else - BUG(); + ret = sk_add_backlog_limited(sk, skb); + if (!ret) { + /* Hold the assoc/ep while hanging on the backlog queue. + * This way, we know structures we need will not disappear + * from us + */ + if (SCTP_EP_TYPE_ASSOCIATION == rcvr->type) + sctp_association_hold(sctp_assoc(rcvr)); + else if (SCTP_EP_TYPE_SOCKET == rcvr->type) + sctp_endpoint_hold(sctp_ep(rcvr)); + else + BUG(); + } + return ret; - sk_add_backlog(sk, skb); } /* Handle icmp frag needed error. */ diff --git a/net/sctp/socket.c b/net/sctp/socket.c index f6d1e59..dfc5c12 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -3720,6 +3720,9 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk) SCTP_DBG_OBJCNT_INC(sock); percpu_counter_inc(&sctp_sockets_allocated); + /* Set socket backlog limit. */ + sk->sk_backlog.limit = sysctl_sctp_rmem[1]; + local_bh_disable(); sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); local_bh_enable(); -- cgit v0.10.2 From 53eecb1be5ae499d399d2923933937a9ea1a284f Mon Sep 17 00:00:00 2001 From: Zhu Yi Date: Thu, 4 Mar 2010 18:01:45 +0000 Subject: tipc: use limited socket backlog Make tipc adapt to the limited socket backlog change. Cc: Jon Maloy Cc: Allan Stephens Signed-off-by: Zhu Yi Acked-by: Eric Dumazet Acked-by: Allan Stephens Signed-off-by: David S. Miller diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 1ea64f0..22bfbc3 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -1322,8 +1322,10 @@ static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf) if (!sock_owned_by_user(sk)) { res = filter_rcv(sk, buf); } else { - sk_add_backlog(sk, buf); - res = TIPC_OK; + if (sk_add_backlog_limited(sk, buf)) + res = TIPC_ERR_OVERLOAD; + else + res = TIPC_OK; } bh_unlock_sock(sk); -- cgit v0.10.2 From 2499849ee8f513e795b9f2c19a42d6356e4943a4 Mon Sep 17 00:00:00 2001 From: Zhu Yi Date: Thu, 4 Mar 2010 18:01:46 +0000 Subject: x25: use limited socket backlog Make x25 adapt to the limited socket backlog change. Cc: Andrew Hendry Signed-off-by: Zhu Yi Acked-by: Eric Dumazet Signed-off-by: David S. Miller diff --git a/net/x25/x25_dev.c b/net/x25/x25_dev.c index 3e1efe5..a9da0dc 100644 --- a/net/x25/x25_dev.c +++ b/net/x25/x25_dev.c @@ -53,7 +53,7 @@ static int x25_receive_data(struct sk_buff *skb, struct x25_neigh *nb) if (!sock_owned_by_user(sk)) { queued = x25_process_rx_frame(sk, skb); } else { - sk_add_backlog(sk, skb); + queued = !sk_add_backlog_limited(sk, skb); } bh_unlock_sock(sk); sock_put(sk); -- cgit v0.10.2 From a3a858ff18a72a8d388e31ab0d98f7e944841a62 Mon Sep 17 00:00:00 2001 From: Zhu Yi Date: Thu, 4 Mar 2010 18:01:47 +0000 Subject: net: backlog functions rename sk_add_backlog -> __sk_add_backlog sk_add_backlog_limited -> sk_add_backlog Signed-off-by: Zhu Yi Acked-by: Eric Dumazet Signed-off-by: David S. Miller diff --git a/include/net/sock.h b/include/net/sock.h index 2516d76..170353d 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -592,7 +592,7 @@ static inline int sk_stream_memory_free(struct sock *sk) } /* OOB backlog add */ -static inline void sk_add_backlog(struct sock *sk, struct sk_buff *skb) +static inline void __sk_add_backlog(struct sock *sk, struct sk_buff *skb) { if (!sk->sk_backlog.tail) { sk->sk_backlog.head = sk->sk_backlog.tail = skb; @@ -604,12 +604,12 @@ static inline void sk_add_backlog(struct sock *sk, struct sk_buff *skb) } /* The per-socket spinlock must be held here. */ -static inline int sk_add_backlog_limited(struct sock *sk, struct sk_buff *skb) +static inline int sk_add_backlog(struct sock *sk, struct sk_buff *skb) { if (sk->sk_backlog.len >= max(sk->sk_backlog.limit, sk->sk_rcvbuf << 1)) return -ENOBUFS; - sk_add_backlog(sk, skb); + __sk_add_backlog(sk, skb); sk->sk_backlog.len += skb->truesize; return 0; } diff --git a/net/core/sock.c b/net/core/sock.c index 6e22dc9..61a65a2 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -340,7 +340,7 @@ int sk_receive_skb(struct sock *sk, struct sk_buff *skb, const int nested) rc = sk_backlog_rcv(sk, skb); mutex_release(&sk->sk_lock.dep_map, 1, _RET_IP_); - } else if (sk_add_backlog_limited(sk, skb)) { + } else if (sk_add_backlog(sk, skb)) { bh_unlock_sock(sk); atomic_inc(&sk->sk_drops); goto discard_and_relse; diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c index af226a0..0d508c3 100644 --- a/net/dccp/minisocks.c +++ b/net/dccp/minisocks.c @@ -254,7 +254,7 @@ int dccp_child_process(struct sock *parent, struct sock *child, * in main socket hash table and lock on listening * socket does not protect us more. */ - sk_add_backlog(child, skb); + __sk_add_backlog(child, skb); } bh_unlock_sock(child); diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 4baf194..1915f7d 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1682,7 +1682,7 @@ process: if (!tcp_prequeue(sk, skb)) ret = tcp_v4_do_rcv(sk, skb); } - } else if (sk_add_backlog_limited(sk, skb)) { + } else if (sk_add_backlog(sk, skb)) { bh_unlock_sock(sk); goto discard_and_relse; } diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index f206ee5..4199bc6 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -728,7 +728,7 @@ int tcp_child_process(struct sock *parent, struct sock *child, * in main socket hash table and lock on listening * socket does not protect us more. */ - sk_add_backlog(child, skb); + __sk_add_backlog(child, skb); } bh_unlock_sock(child); diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index e7eb47f..7af756d 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1371,7 +1371,7 @@ int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) bh_lock_sock(sk); if (!sock_owned_by_user(sk)) rc = __udp_queue_rcv_skb(sk, skb); - else if (sk_add_backlog_limited(sk, skb)) { + else if (sk_add_backlog(sk, skb)) { bh_unlock_sock(sk); goto drop; } diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index c4ea9d5..2c378b1 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1740,7 +1740,7 @@ process: if (!tcp_prequeue(sk, skb)) ret = tcp_v6_do_rcv(sk, skb); } - } else if (sk_add_backlog_limited(sk, skb)) { + } else if (sk_add_backlog(sk, skb)) { bh_unlock_sock(sk); goto discard_and_relse; } diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 6480491..3c0c9c7 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -583,7 +583,7 @@ static void flush_stack(struct sock **stack, unsigned int count, bh_lock_sock(sk); if (!sock_owned_by_user(sk)) udpv6_queue_rcv_skb(sk, skb1); - else if (sk_add_backlog_limited(sk, skb1)) { + else if (sk_add_backlog(sk, skb1)) { kfree_skb(skb1); bh_unlock_sock(sk); goto drop; @@ -758,7 +758,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, bh_lock_sock(sk); if (!sock_owned_by_user(sk)) udpv6_queue_rcv_skb(sk, skb); - else if (sk_add_backlog_limited(sk, skb)) { + else if (sk_add_backlog(sk, skb)) { atomic_inc(&sk->sk_drops); bh_unlock_sock(sk); sock_put(sk); diff --git a/net/llc/llc_c_ac.c b/net/llc/llc_c_ac.c index 019c780..86d6985 100644 --- a/net/llc/llc_c_ac.c +++ b/net/llc/llc_c_ac.c @@ -1437,7 +1437,7 @@ static void llc_process_tmr_ev(struct sock *sk, struct sk_buff *skb) llc_conn_state_process(sk, skb); else { llc_set_backlog_type(skb, LLC_EVENT); - sk_add_backlog(sk, skb); + __sk_add_backlog(sk, skb); } } } diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c index c0539ff..a12144d 100644 --- a/net/llc/llc_conn.c +++ b/net/llc/llc_conn.c @@ -827,7 +827,7 @@ void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb) else { dprintk("%s: adding to backlog...\n", __func__); llc_set_backlog_type(skb, LLC_PACKET); - if (sk_add_backlog_limited(sk, skb)) + if (sk_add_backlog(sk, skb)) goto drop_unlock; } out: diff --git a/net/sctp/input.c b/net/sctp/input.c index cbc0636..3d74b26 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c @@ -341,7 +341,7 @@ int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb) sctp_bh_lock_sock(sk); if (sock_owned_by_user(sk)) { - if (sk_add_backlog_limited(sk, skb)) + if (sk_add_backlog(sk, skb)) sctp_chunk_free(chunk); else backloged = 1; @@ -375,7 +375,7 @@ static int sctp_add_backlog(struct sock *sk, struct sk_buff *skb) struct sctp_ep_common *rcvr = chunk->rcvr; int ret; - ret = sk_add_backlog_limited(sk, skb); + ret = sk_add_backlog(sk, skb); if (!ret) { /* Hold the assoc/ep while hanging on the backlog queue. * This way, we know structures we need will not disappear diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 22bfbc3..4b235fc 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -1322,7 +1322,7 @@ static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf) if (!sock_owned_by_user(sk)) { res = filter_rcv(sk, buf); } else { - if (sk_add_backlog_limited(sk, buf)) + if (sk_add_backlog(sk, buf)) res = TIPC_ERR_OVERLOAD; else res = TIPC_OK; diff --git a/net/x25/x25_dev.c b/net/x25/x25_dev.c index a9da0dc..52e3042 100644 --- a/net/x25/x25_dev.c +++ b/net/x25/x25_dev.c @@ -53,7 +53,7 @@ static int x25_receive_data(struct sk_buff *skb, struct x25_neigh *nb) if (!sock_owned_by_user(sk)) { queued = x25_process_rx_frame(sk, skb); } else { - queued = !sk_add_backlog_limited(sk, skb); + queued = !sk_add_backlog(sk, skb); } bh_unlock_sock(sk); sock_put(sk); -- cgit v0.10.2 From 4b79a1aedcb9dd6e3f27b970dcb553aefcd97254 Mon Sep 17 00:00:00 2001 From: David Brown Date: Fri, 5 Mar 2010 09:12:34 +0000 Subject: net: smc91x: Support Qualcomm MSM development boards. Signed-off-by: David Brown Signed-off-by: Daniel Walker Acked-by: Nicolas Pitre Signed-off-by: David S. Miller diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h index 5479954..a6ee883 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h @@ -330,6 +330,20 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r, #include +#elif defined(CONFIG_ARCH_MSM) + +#define SMC_CAN_USE_8BIT 0 +#define SMC_CAN_USE_16BIT 1 +#define SMC_CAN_USE_32BIT 0 +#define SMC_NOWAIT 1 + +#define SMC_inw(a, r) readw((a) + (r)) +#define SMC_outw(v, a, r) writew(v, (a) + (r)) +#define SMC_insw(a, r, p, l) readsw((a) + (r), p, l) +#define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) + +#define SMC_IRQ_FLAGS IRQF_TRIGGER_HIGH + #else /* -- cgit v0.10.2 From 723b2f57ad83ee7087acf9a95e8e289414b1f521 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Wed, 3 Mar 2010 22:51:50 +0000 Subject: ethtool: Add direct access to ops->get_sset_count This patch is an alternative approach for accessing string counts, vs. the drvinfo indirect approach. This way the drvinfo space doesn't run out, and we don't break ABI later. Signed-off-by: Jeff Garzik Signed-off-by: Peter P Waskiewicz Jr Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index cca1c3d..f6f961fe 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -253,6 +253,17 @@ struct ethtool_gstrings { __u8 data[0]; }; +struct ethtool_sset_info { + __u32 cmd; /* ETHTOOL_GSSET_INFO */ + __u32 reserved; + __u64 sset_mask; /* input: each bit selects an sset to query */ + /* output: each bit a returned sset */ + __u32 data[0]; /* ETH_SS_xxx count, in order, based on bits + in sset_mask. One bit implies one + __u32, two bits implies two + __u32's, etc. */ +}; + enum ethtool_test_flags { ETH_TEST_FL_OFFLINE = (1 << 0), /* online / offline */ ETH_TEST_FL_FAILED = (1 << 1), /* test passed / failed */ @@ -606,9 +617,9 @@ struct ethtool_ops { #define ETHTOOL_SRXCLSRLINS 0x00000032 /* Insert RX classification rule */ #define ETHTOOL_FLASHDEV 0x00000033 /* Flash firmware to device */ #define ETHTOOL_RESET 0x00000034 /* Reset hardware */ - -#define ETHTOOL_SRXNTUPLE 0x00000035 /* Add an n-tuple filter to device */ -#define ETHTOOL_GRXNTUPLE 0x00000036 /* Get n-tuple filters from device */ +#define ETHTOOL_SRXNTUPLE 0x00000035 /* Add an n-tuple filter to device */ +#define ETHTOOL_GRXNTUPLE 0x00000036 /* Get n-tuple filters from device */ +#define ETHTOOL_GSSET_INFO 0x00000037 /* Get string set info */ /* compatibility with older code */ #define SPARC_ETH_GSET ETHTOOL_GSET diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 0f2f821..70075c4 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -214,6 +214,10 @@ static noinline int ethtool_get_drvinfo(struct net_device *dev, void __user *use info.cmd = ETHTOOL_GDRVINFO; ops->get_drvinfo(dev, &info); + /* + * this method of obtaining string set info is deprecated; + * consider using ETHTOOL_GSSET_INFO instead + */ if (ops->get_sset_count) { int rc; @@ -240,6 +244,71 @@ static noinline int ethtool_get_drvinfo(struct net_device *dev, void __user *use /* * noinline attribute so that gcc doesnt use too much stack in dev_ethtool() */ +static noinline int ethtool_get_sset_info(struct net_device *dev, + void __user *useraddr) +{ + struct ethtool_sset_info info; + const struct ethtool_ops *ops = dev->ethtool_ops; + u64 sset_mask; + int i, idx = 0, n_bits = 0, ret, rc; + u32 *info_buf = NULL; + + if (!ops->get_sset_count) + return -EOPNOTSUPP; + + if (copy_from_user(&info, useraddr, sizeof(info))) + return -EFAULT; + + /* store copy of mask, because we zero struct later on */ + sset_mask = info.sset_mask; + if (!sset_mask) + return 0; + + /* calculate size of return buffer */ + for (i = 0; i < 64; i++) + if (sset_mask & (1ULL << i)) + n_bits++; + + memset(&info, 0, sizeof(info)); + info.cmd = ETHTOOL_GSSET_INFO; + + info_buf = kzalloc(n_bits * sizeof(u32), GFP_USER); + if (!info_buf) + return -ENOMEM; + + /* + * fill return buffer based on input bitmask and successful + * get_sset_count return + */ + for (i = 0; i < 64; i++) { + if (!(sset_mask & (1ULL << i))) + continue; + + rc = ops->get_sset_count(dev, i); + if (rc >= 0) { + info.sset_mask |= (1ULL << i); + info_buf[idx++] = rc; + } + } + + ret = -EFAULT; + if (copy_to_user(useraddr, &info, sizeof(info))) + goto out; + + useraddr += offsetof(struct ethtool_sset_info, data); + if (copy_to_user(useraddr, info_buf, idx * sizeof(u32))) + goto out; + + ret = 0; + +out: + kfree(info_buf); + return ret; +} + +/* + * noinline attribute so that gcc doesnt use too much stack in dev_ethtool() + */ static noinline int ethtool_set_rxnfc(struct net_device *dev, void __user *useraddr) { struct ethtool_rxnfc cmd; @@ -1471,6 +1540,9 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) case ETHTOOL_GRXNTUPLE: rc = ethtool_get_rx_ntuple(dev, useraddr); break; + case ETHTOOL_GSSET_INFO: + rc = ethtool_get_sset_info(dev, useraddr); + break; default: rc = -EOPNOTSUPP; } -- cgit v0.10.2 From d17792ebdf90289c9fd1bce888076d3d60ecd53b Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Thu, 4 Mar 2010 08:21:53 +0000 Subject: ethtool: Add direct access to ops->get_sset_count On 03/04/2010 09:26 AM, Ben Hutchings wrote: > On Thu, 2010-03-04 at 00:51 -0800, Jeff Kirsher wrote: >> From: Jeff Garzik >> >> This patch is an alternative approach for accessing string >> counts, vs. the drvinfo indirect approach. This way the drvinfo >> space doesn't run out, and we don't break ABI later. > [...] >> --- a/net/core/ethtool.c >> +++ b/net/core/ethtool.c >> @@ -214,6 +214,10 @@ static noinline int ethtool_get_drvinfo(struct net_device *dev, void __user *use >> info.cmd = ETHTOOL_GDRVINFO; >> ops->get_drvinfo(dev,&info); >> >> + /* >> + * this method of obtaining string set info is deprecated; >> + * consider using ETHTOOL_GSSET_INFO instead >> + */ > > This comment belongs on the interface (ethtool.h) not the > implementation. Debatable -- the current comment is located at the callsite of ops->get_sset_count(), which is where an implementor might think to add a new call. Not all the numeric fields in ethtool_drvinfo are obtained from ->get_sset_count(). Hence the "some" in the attached patch to include/linux/ethtool.h, addressing your comment. > [...] >> +static noinline int ethtool_get_sset_info(struct net_device *dev, >> + void __user *useraddr) >> +{ > [...] >> + /* calculate size of return buffer */ >> + for (i = 0; i< 64; i++) >> + if (sset_mask& (1ULL<< i)) >> + n_bits++; > [...] > > We have a function for this: > > n_bits = hweight64(sset_mask); Agreed. I've attached a follow-up patch, which should enable my/Jeff's kernel patch to be applied, followed by this one. Signed-off-by: Jeff Garzik Signed-off-by: David S. Miller diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index f6f961fe..b33f316 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -61,6 +61,13 @@ struct ethtool_drvinfo { /* For PCI devices, use pci_name(pci_dev). */ char reserved1[32]; char reserved2[12]; + /* + * Some struct members below are filled in + * using ops->get_sset_count(). Obtaining + * this info from ethtool_drvinfo is now + * deprecated; Use ETHTOOL_GSSET_INFO + * instead. + */ __u32 n_priv_flags; /* number of flags valid in ETHTOOL_GPFLAGS */ __u32 n_stats; /* number of u64's from ETHTOOL_GSTATS */ __u32 testinfo_len; diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 70075c4..33d2ded 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -17,6 +17,7 @@ #include #include #include +#include #include /* @@ -216,7 +217,7 @@ static noinline int ethtool_get_drvinfo(struct net_device *dev, void __user *use /* * this method of obtaining string set info is deprecated; - * consider using ETHTOOL_GSSET_INFO instead + * Use ETHTOOL_GSSET_INFO instead. */ if (ops->get_sset_count) { int rc; @@ -265,9 +266,7 @@ static noinline int ethtool_get_sset_info(struct net_device *dev, return 0; /* calculate size of return buffer */ - for (i = 0; i < 64; i++) - if (sset_mask & (1ULL << i)) - n_bits++; + n_bits = hweight64(sset_mask); memset(&info, 0, sizeof(info)); info.cmd = ETHTOOL_GSSET_INFO; -- cgit v0.10.2 From 5fe88eae26dbd24eed73eb0b681e13981fd486b3 Mon Sep 17 00:00:00 2001 From: David Dillow Date: Thu, 4 Mar 2010 04:37:16 +0000 Subject: typhoon: fix incorrect use of smp_wmb() The typhoon driver was incorrectly using smp_wmb() to order memory accesses against IO to the NIC in a few instances. Use wmb() instead, which is required to actually order between memory types. Signed-off-by: David Dillow Signed-off-by: David S. Miller diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index e3ddcb8..1cf012d 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c @@ -480,7 +480,7 @@ typhoon_hello(struct typhoon *tp) typhoon_inc_cmd_index(&ring->lastWrite, 1); INIT_COMMAND_NO_RESPONSE(cmd, TYPHOON_CMD_HELLO_RESP); - smp_wmb(); + wmb(); iowrite32(ring->lastWrite, tp->ioaddr + TYPHOON_REG_CMD_READY); spin_unlock(&tp->command_lock); } @@ -1311,13 +1311,15 @@ typhoon_init_interface(struct typhoon *tp) tp->txlo_dma_addr = le32_to_cpu(iface->txLoAddr); tp->card_state = Sleeping; - smp_wmb(); tp->offload = TYPHOON_OFFLOAD_IP_CHKSUM | TYPHOON_OFFLOAD_TCP_CHKSUM; tp->offload |= TYPHOON_OFFLOAD_UDP_CHKSUM | TSO_OFFLOAD_ON; spin_lock_init(&tp->command_lock); spin_lock_init(&tp->state_lock); + + /* Force the writes to the shared memory area out before continuing. */ + wmb(); } static void -- cgit v0.10.2 From a80483d3722b603dae8a52495f8d88a7d4b1bf1c Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Fri, 5 Mar 2010 02:21:44 +0000 Subject: e1000e: fix packet corruption and tx hang during NFSv2 when receiving a particular type of NFS v2 UDP traffic, the hardware could DMA some bad data and then hang, possibly corrupting memory. Disable the NFS parsing in this hardware, verified to fix the bug. Originally reported and reproduced by RedHat's Neil Horman CC: nhorman@tuxdriver.com Signed-off-by: Jesse Brandeburg Signed-off-by: Jeff Kirsher Acked-by: Neil Horman Signed-off-by: David S. Miller diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h index db05ec3..e301e26 100644 --- a/drivers/net/e1000e/defines.h +++ b/drivers/net/e1000e/defines.h @@ -320,6 +320,8 @@ #define E1000_RXCSUM_IPPCSE 0x00001000 /* IP payload checksum enable */ /* Header split receive */ +#define E1000_RFCTL_NFSW_DIS 0x00000040 +#define E1000_RFCTL_NFSR_DIS 0x00000080 #define E1000_RFCTL_ACK_DIS 0x00001000 #define E1000_RFCTL_EXTEN 0x00008000 #define E1000_RFCTL_IPV6_EX_DIS 0x00010000 diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index 54d03a0..8b5e157 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c @@ -2740,6 +2740,16 @@ static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw) reg &= ~(1 << 31); ew32(STATUS, reg); } + + /* + * work-around descriptor data corruption issue during nfs v2 udp + * traffic, just disable the nfs filtering capability + */ + reg = er32(RFCTL); + reg |= (E1000_RFCTL_NFSW_DIS | E1000_RFCTL_NFSR_DIS); + ew32(RFCTL, reg); + + return; } /** -- cgit v0.10.2 From 3a22813a5aaf8e8c72be575dabe0ba26f9352f4d Mon Sep 17 00:00:00 2001 From: Breno Leitao Date: Thu, 4 Mar 2010 10:40:44 +0000 Subject: s2io: Fixing debug message Currently s2io is dumping debug messages using the interface name before it was allocated, showing a message like the following: s2io: eth%d: Ring Mem PHY: 0x7ef80000 s2io: s2io_reset: Resetting XFrame card eth%d This patch just fixes it, printing the pci bus information for the card instead of the interface name. Signed-off-by: Breno Leitao Signed-off-by: David S. Miller diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 43bc66a..df70657 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -923,8 +923,8 @@ static int init_shared_mem(struct s2io_nic *nic) tmp_v_addr = mac_control->stats_mem; mac_control->stats_info = (struct stat_block *)tmp_v_addr; memset(tmp_v_addr, 0, size); - DBG_PRINT(INIT_DBG, "%s: Ring Mem PHY: 0x%llx\n", dev->name, - (unsigned long long)tmp_p_addr); + DBG_PRINT(INIT_DBG, "%s: Ring Mem PHY: 0x%llx\n", + dev_name(&nic->pdev->dev), (unsigned long long)tmp_p_addr); mac_control->stats_info->sw_stat.mem_allocated += mem_allocated; return SUCCESS; } @@ -3480,7 +3480,7 @@ static void s2io_reset(struct s2io_nic *sp) struct swStat *swstats; DBG_PRINT(INIT_DBG, "%s: Resetting XFrame card %s\n", - __func__, sp->dev->name); + __func__, pci_name(sp->pdev)); /* Back up the PCI-X CMD reg, dont want to lose MMRBC, OST settings */ pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, &(pci_cmd)); -- cgit v0.10.2 From f1a3d57213fe264b4cf584e78bac36aaf9998729 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 18 Jan 2010 11:53:08 +1100 Subject: ceph: update for write_inode API change Signed-off-by: Stephen Rothwell Signed-off-by: Sage Weil diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 8b89b91..db122bb 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "super.h" #include "decode.h" @@ -1801,12 +1802,13 @@ int ceph_fsync(struct file *file, struct dentry *dentry, int datasync) * get by with fewer MDS messages if we wait for data writeback to * complete first. */ -int ceph_write_inode(struct inode *inode, int wait) +int ceph_write_inode(struct inode *inode, struct writeback_control *wbc) { struct ceph_inode_info *ci = ceph_inode(inode); unsigned flush_tid; int err = 0; int dirty; + int wait = wbc->sync_mode == WB_SYNC_ALL; dout("write_inode %p wait=%d\n", inode, wait); if (wait) { diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 02c0ddc..65d1203 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -11,6 +11,7 @@ #include #include #include +#include #include "types.h" #include "messenger.h" @@ -811,7 +812,7 @@ static inline void ceph_remove_cap(struct ceph_cap *cap) extern void ceph_put_cap(struct ceph_cap *cap); extern void ceph_queue_caps_release(struct inode *inode); -extern int ceph_write_inode(struct inode *inode, int unused); +extern int ceph_write_inode(struct inode *inode, struct writeback_control *wbc); extern int ceph_fsync(struct file *file, struct dentry *dentry, int datasync); extern void ceph_kick_flushing_caps(struct ceph_mds_client *mdsc, struct ceph_mds_session *session); -- cgit v0.10.2 From 801c29fd1fdeb84f60241beb445ff5db154450ae Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 5 Mar 2010 20:02:19 -0500 Subject: function-graph: Fix unused reference to ftrace_set_func() The declaration of ftrace_set_func() is at the start of the ftrace.c file and wrapped with a #ifdef CONFIG_FUNCTION_GRAPH condition. If function graph tracing is enabled but CONFIG_DYNAMIC_FTRACE is not, a warning about that function being declared static and unused is given. This really should have been placed within the CONFIG_FUNCTION_GRAPH condition that uses ftrace_set_func(). Moving the declaration down fixes the warning and makes the code cleaner. Reported-by: Peter Zijlstra Signed-off-by: Steven Rostedt diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index d996353..d0407c9 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -85,10 +85,6 @@ ftrace_func_t ftrace_trace_function __read_mostly = ftrace_stub; ftrace_func_t __ftrace_trace_function __read_mostly = ftrace_stub; ftrace_func_t ftrace_pid_function __read_mostly = ftrace_stub; -#ifdef CONFIG_FUNCTION_GRAPH_TRACER -static int ftrace_set_func(unsigned long *array, int *idx, char *buffer); -#endif - static void ftrace_list_func(unsigned long ip, unsigned long parent_ip) { struct ftrace_ops *op = ftrace_list; @@ -2300,6 +2296,8 @@ __setup("ftrace_filter=", set_ftrace_filter); #ifdef CONFIG_FUNCTION_GRAPH_TRACER static char ftrace_graph_buf[FTRACE_FILTER_SIZE] __initdata; +static int ftrace_set_func(unsigned long *array, int *idx, char *buffer); + static int __init set_graph_function(char *str) { strlcpy(ftrace_graph_buf, str, FTRACE_FILTER_SIZE); -- cgit v0.10.2 From a094fe04c751698a18c3a0d376a3bdb117f1e0d8 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 5 Mar 2010 20:08:58 -0500 Subject: function-graph: Use comment notation for func names of dangling '}' When a '}' does not have a matching function start, the name is printed within parenthesis. But this makes it confusing between ending '}' and function starts. This patch makes the function name appear in C comment notation. Old view: 3) 1.281 us | } (might_fault) 3) 3.620 us | } (filldir) 3) 5.251 us | } (call_filldir) 3) | call_filldir() { 3) | filldir() { New view: 3) 1.281 us | } /* might_fault */ 3) 3.620 us | } /* filldir */ 3) 5.251 us | } /* call_filldir */ 3) | call_filldir() { 3) | filldir() { Requested-by: Ingo Molnar Signed-off-by: Steven Rostedt diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c index e998a82..7b1f246 100644 --- a/kernel/trace/trace_functions_graph.c +++ b/kernel/trace/trace_functions_graph.c @@ -920,7 +920,7 @@ print_graph_return(struct ftrace_graph_ret *trace, struct trace_seq *s, if (!ret) return TRACE_TYPE_PARTIAL_LINE; } else { - ret = trace_seq_printf(s, "} (%ps)\n", (void *)trace->func); + ret = trace_seq_printf(s, "} /* %ps */\n", (void *)trace->func); if (!ret) return TRACE_TYPE_PARTIAL_LINE; } -- cgit v0.10.2 From 1acaa1b2d9b5904c9cce06122990a2d71046ce16 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 5 Mar 2010 18:23:50 -0300 Subject: tracing: Update the comm field in the right variable in update_max_tr The latency output showed: # | task: -3 (uid:0 nice:0 policy:1 rt_prio:99) The comm is missing in the "task:" and it looks like a minus 3 is the output. The correct display should be: # | task: migration/0-3 (uid:0 nice:0 policy:1 rt_prio:99) The problem is that the comm is being stored in the wrong data structure. The max_tr.data[cpu] is what stores the comm, not the tr->data[cpu]. Before this patch the max_tr.data[cpu]->comm was zeroed and the /debug/trace ended up showing just the '-' sign followed by the pid. Also remove a needless initialization of max_data. Signed-off-by: Arnaldo Carvalho de Melo LKML-Reference: <1267824230-23861-1-git-send-email-acme@infradead.org> Signed-off-by: Steven Rostedt diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 032c57c..6efd5cb 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -592,7 +592,7 @@ static void __update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu) { struct trace_array_cpu *data = tr->data[cpu]; - struct trace_array_cpu *max_data = tr->data[cpu]; + struct trace_array_cpu *max_data; max_tr.cpu = cpu; max_tr.time_start = data->preempt_timestamp; @@ -602,7 +602,7 @@ __update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu) max_data->critical_start = data->critical_start; max_data->critical_end = data->critical_end; - memcpy(data->comm, tsk->comm, TASK_COMM_LEN); + memcpy(max_data->comm, tsk->comm, TASK_COMM_LEN); max_data->pid = tsk->pid; max_data->uid = task_uid(tsk); max_data->nice = tsk->static_prio - 20 - MAX_RT_PRIO; -- cgit v0.10.2 From 0e95017355dcf43031da6d0e360a748717e56df1 Mon Sep 17 00:00:00 2001 From: Tim Bird Date: Thu, 25 Feb 2010 15:36:43 -0800 Subject: function-graph: Add tracing_thresh support to function_graph tracer Add support for tracing_thresh to the function_graph tracer. This version of this feature isolates the checks into new entry and return functions, to avoid adding more conditional code into the main function_graph paths. When the tracing_thresh is set and the function graph tracer is enabled, only the functions that took longer than the time in microseconds that was set in tracing_thresh are recorded. To do this efficiently, only the function exits are recorded: [tracing]# echo 100 > tracing_thresh [tracing]# echo function_graph > current_tracer [tracing]# cat trace # tracer: function_graph # # CPU DURATION FUNCTION CALLS # | | | | | | | 1) ! 119.214 us | } /* smp_apic_timer_interrupt */ 1) <========== | 0) ! 101.527 us | } /* __rcu_process_callbacks */ 0) ! 126.461 us | } /* rcu_process_callbacks */ 0) ! 145.111 us | } /* __do_softirq */ 0) ! 149.667 us | } /* do_softirq */ 0) ! 168.817 us | } /* irq_exit */ 0) ! 248.254 us | } /* smp_apic_timer_interrupt */ Also, add support for specifying tracing_thresh on the kernel command line. When used like so: "tracing_thresh=200 ftrace=function_graph" this can be used to analyse system startup. It is important to disable tracing soon after boot, in order to avoid losing the trace data. Acked-by: Frederic Weisbecker Signed-off-by: Tim Bird LKML-Reference: <4B87098B.4040308@am.sony.com> Signed-off-by: Steven Rostedt diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 6efd5cb..ababedb 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -374,6 +374,21 @@ static int __init set_buf_size(char *str) } __setup("trace_buf_size=", set_buf_size); +static int __init set_tracing_thresh(char *str) +{ + unsigned long threshhold; + int ret; + + if (!str) + return 0; + ret = strict_strtoul(str, 0, &threshhold); + if (ret < 0) + return 0; + tracing_thresh = threshhold * 1000; + return 1; +} +__setup("tracing_thresh=", set_tracing_thresh); + unsigned long nsecs_to_usecs(unsigned long nsecs) { return nsecs / 1000; @@ -579,9 +594,10 @@ static ssize_t trace_seq_to_buffer(struct trace_seq *s, void *buf, size_t cnt) static arch_spinlock_t ftrace_max_lock = (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED; +unsigned long __read_mostly tracing_thresh; + #ifdef CONFIG_TRACER_MAX_TRACE unsigned long __read_mostly tracing_max_latency; -unsigned long __read_mostly tracing_thresh; /* * Copy the new maximum trace into the separate maximum-trace @@ -4248,10 +4264,10 @@ static __init int tracer_init_debugfs(void) #ifdef CONFIG_TRACER_MAX_TRACE trace_create_file("tracing_max_latency", 0644, d_tracer, &tracing_max_latency, &tracing_max_lat_fops); +#endif trace_create_file("tracing_thresh", 0644, d_tracer, &tracing_thresh, &tracing_max_lat_fops); -#endif trace_create_file("README", 0444, d_tracer, NULL, &tracing_readme_fops); diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index fd05bca..1bc8cd1 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -396,9 +396,10 @@ extern int process_new_ksym_entry(char *ksymname, int op, unsigned long addr); extern unsigned long nsecs_to_usecs(unsigned long nsecs); +extern unsigned long tracing_thresh; + #ifdef CONFIG_TRACER_MAX_TRACE extern unsigned long tracing_max_latency; -extern unsigned long tracing_thresh; void update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu); void update_max_tr_single(struct trace_array *tr, diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c index 7b1f246..e9df04b 100644 --- a/kernel/trace/trace_functions_graph.c +++ b/kernel/trace/trace_functions_graph.c @@ -237,6 +237,14 @@ int trace_graph_entry(struct ftrace_graph_ent *trace) return ret; } +int trace_graph_thresh_entry(struct ftrace_graph_ent *trace) +{ + if (tracing_thresh) + return 1; + else + return trace_graph_entry(trace); +} + static void __trace_graph_return(struct trace_array *tr, struct ftrace_graph_ret *trace, unsigned long flags, @@ -290,13 +298,26 @@ void set_graph_array(struct trace_array *tr) smp_mb(); } +void trace_graph_thresh_return(struct ftrace_graph_ret *trace) +{ + if (tracing_thresh && + (trace->rettime - trace->calltime < tracing_thresh)) + return; + else + trace_graph_return(trace); +} + static int graph_trace_init(struct trace_array *tr) { int ret; set_graph_array(tr); - ret = register_ftrace_graph(&trace_graph_return, - &trace_graph_entry); + if (tracing_thresh) + ret = register_ftrace_graph(&trace_graph_thresh_return, + &trace_graph_thresh_entry); + else + ret = register_ftrace_graph(&trace_graph_return, + &trace_graph_entry); if (ret) return ret; tracing_start_cmdline_record(); -- cgit v0.10.2 From df2cf170c823ba779ca339e3ede347c87f4dc6a9 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Fri, 12 Feb 2010 07:44:16 -0500 Subject: cifs: overhaul cifs_revalidate and rename to cifs_revalidate_dentry cifs_revalidate is renamed to cifs_revalidate_dentry as a later patch will add a by-filehandle variant. Add a new "invalid_mapping" flag to the cifsInodeInfo that indicates that the pagecache is considered invalid. Add a new routine to check inode attributes whenever they're updated and set that flag if the inode has changed on the server. cifs_revalidate_dentry is then changed to just update the attrcache if needed and then to zap the pagecache if it's not valid. There are some other behavior changes in here as well. Open files are now allowed to have their caches invalidated. I see no reason why we'd want to keep stale data around just because a file is open. Also, cifs_revalidate_cache uses the server_eof for revalidating the file size since that should more closely match the size of the file on the server. Signed-off-by: Jeff Layton Signed-off-by: Steve French diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 8c6a036..cf85a41 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -312,6 +312,7 @@ cifs_alloc_inode(struct super_block *sb) cifs_inode->clientCanCacheRead = false; cifs_inode->clientCanCacheAll = false; cifs_inode->delete_pending = false; + cifs_inode->invalid_mapping = false; cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */ cifs_inode->server_eof = 0; @@ -638,7 +639,7 @@ static loff_t cifs_llseek(struct file *file, loff_t offset, int origin) setting the revalidate time to zero */ CIFS_I(file->f_path.dentry->d_inode)->time = 0; - retval = cifs_revalidate(file->f_path.dentry); + retval = cifs_revalidate_dentry(file->f_path.dentry); if (retval < 0) return (loff_t)retval; } diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 78c1b86..2af995c 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h @@ -61,7 +61,7 @@ extern int cifs_mkdir(struct inode *, struct dentry *, int); extern int cifs_rmdir(struct inode *, struct dentry *); extern int cifs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); -extern int cifs_revalidate(struct dentry *); +extern int cifs_revalidate_dentry(struct dentry *); extern int cifs_getattr(struct vfsmount *, struct dentry *, struct kstat *); extern int cifs_setattr(struct dentry *, struct iattr *); diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index a1c817e..63c89d1 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -389,6 +389,7 @@ struct cifsInodeInfo { bool clientCanCacheRead:1; /* read oplock */ bool clientCanCacheAll:1; /* read and writebehind oplock */ bool delete_pending:1; /* DELETE_ON_CLOSE is set */ + bool invalid_mapping:1; /* pagecache is invalid */ u64 server_eof; /* current file size on server */ u64 uniqueid; /* server inode number */ struct inode vfs_inode; diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 6ccf726..e9f7ecc 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -739,7 +739,7 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd) int isValid = 1; if (direntry->d_inode) { - if (cifs_revalidate(direntry)) + if (cifs_revalidate_dentry(direntry)) return 0; } else { cFYI(1, ("neg dentry 0x%p name = %s", diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 3d8f8a9..b90f8f2 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -1894,7 +1894,7 @@ int cifs_file_mmap(struct file *file, struct vm_area_struct *vma) int rc, xid; xid = GetXid(); - rc = cifs_revalidate(dentry); + rc = cifs_revalidate_dentry(dentry); if (rc) { cFYI(1, ("Validation prior to mmap failed, error=%d", rc)); FreeXid(xid); diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 8bdbc81..f050dba 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -77,6 +77,41 @@ static void cifs_set_ops(struct inode *inode, const bool is_dfs_referral) } } +/* check inode attributes against fattr. If they don't match, tag the + * inode for cache invalidation + */ +static void +cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr) +{ + struct cifsInodeInfo *cifs_i = CIFS_I(inode); + + cFYI(1, ("%s: revalidating inode %llu", __func__, cifs_i->uniqueid)); + + if (inode->i_state & I_NEW) { + cFYI(1, ("%s: inode %llu is new", __func__, cifs_i->uniqueid)); + return; + } + + /* don't bother with revalidation if we have an oplock */ + if (cifs_i->clientCanCacheRead) { + cFYI(1, ("%s: inode %llu is oplocked", __func__, + cifs_i->uniqueid)); + return; + } + + /* revalidate if mtime or size have changed */ + if (timespec_equal(&inode->i_mtime, &fattr->cf_mtime) && + cifs_i->server_eof == fattr->cf_eof) { + cFYI(1, ("%s: inode %llu is unchanged", __func__, + cifs_i->uniqueid)); + return; + } + + cFYI(1, ("%s: invalidating inode %llu mapping", __func__, + cifs_i->uniqueid)); + cifs_i->invalid_mapping = true; +} + /* populate an inode with info from a cifs_fattr struct */ void cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr) @@ -85,6 +120,8 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr) struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); unsigned long oldtime = cifs_i->time; + cifs_revalidate_cache(inode, fattr); + inode->i_atime = fattr->cf_atime; inode->i_mtime = fattr->cf_mtime; inode->i_ctime = fattr->cf_ctime; @@ -1389,135 +1426,83 @@ cifs_rename_exit: return rc; } -int cifs_revalidate(struct dentry *direntry) +static bool +cifs_inode_needs_reval(struct inode *inode) { - int xid; - int rc = 0, wbrc = 0; - char *full_path; - struct cifs_sb_info *cifs_sb; - struct cifsInodeInfo *cifsInode; - loff_t local_size; - struct timespec local_mtime; - bool invalidate_inode = false; + struct cifsInodeInfo *cifs_i = CIFS_I(inode); - if (direntry->d_inode == NULL) - return -ENOENT; + if (cifs_i->clientCanCacheRead) + return false; - cifsInode = CIFS_I(direntry->d_inode); + if (!lookupCacheEnabled) + return true; - if (cifsInode == NULL) - return -ENOENT; + if (cifs_i->time == 0) + return true; - /* no sense revalidating inode info on file that no one can write */ - if (CIFS_I(direntry->d_inode)->clientCanCacheRead) - return rc; + /* FIXME: the actimeo should be tunable */ + if (time_after_eq(jiffies, cifs_i->time + HZ)) + return true; + + return false; +} + +/* check invalid_mapping flag and zap the cache if it's set */ +static void +cifs_invalidate_mapping(struct inode *inode) +{ + int rc; + struct cifsInodeInfo *cifs_i = CIFS_I(inode); + + cifs_i->invalid_mapping = false; + + /* write back any cached data */ + if (inode->i_mapping && inode->i_mapping->nrpages != 0) { + rc = filemap_write_and_wait(inode->i_mapping); + if (rc) + cifs_i->write_behind_rc = rc; + } + invalidate_remote_inode(inode); +} + +/* revalidate a dentry's inode attributes */ +int cifs_revalidate_dentry(struct dentry *dentry) +{ + int xid; + int rc = 0; + char *full_path = NULL; + struct inode *inode = dentry->d_inode; + struct super_block *sb = dentry->d_sb; + + if (inode == NULL) + return -ENOENT; xid = GetXid(); - cifs_sb = CIFS_SB(direntry->d_sb); + if (!cifs_inode_needs_reval(inode)) + goto check_inval; /* can not safely grab the rename sem here if rename calls revalidate since that would deadlock */ - full_path = build_path_from_dentry(direntry); + full_path = build_path_from_dentry(dentry); if (full_path == NULL) { rc = -ENOMEM; - FreeXid(xid); - return rc; + goto check_inval; } - cFYI(1, ("Revalidate: %s inode 0x%p count %d dentry: 0x%p d_time %ld " - "jiffies %ld", full_path, direntry->d_inode, - direntry->d_inode->i_count.counter, direntry, - direntry->d_time, jiffies)); - - if (cifsInode->time == 0) { - /* was set to zero previously to force revalidate */ - } else if (time_before(jiffies, cifsInode->time + HZ) && - lookupCacheEnabled) { - if ((S_ISREG(direntry->d_inode->i_mode) == 0) || - (direntry->d_inode->i_nlink == 1)) { - kfree(full_path); - FreeXid(xid); - return rc; - } else { - cFYI(1, ("Have to revalidate file due to hardlinks")); - } - } - - /* save mtime and size */ - local_mtime = direntry->d_inode->i_mtime; - local_size = direntry->d_inode->i_size; - if (cifs_sb->tcon->unix_ext) { - rc = cifs_get_inode_info_unix(&direntry->d_inode, full_path, - direntry->d_sb, xid); - if (rc) { - cFYI(1, ("error on getting revalidate info %d", rc)); -/* if (rc != -ENOENT) - rc = 0; */ /* BB should we cache info on - certain errors? */ - } - } else { - rc = cifs_get_inode_info(&direntry->d_inode, full_path, NULL, - direntry->d_sb, xid, NULL); - if (rc) { - cFYI(1, ("error on getting revalidate info %d", rc)); -/* if (rc != -ENOENT) - rc = 0; */ /* BB should we cache info on - certain errors? */ - } - } - /* should we remap certain errors, access denied?, to zero */ - - /* if not oplocked, we invalidate inode pages if mtime or file size - had changed on server */ + cFYI(1, ("Revalidate: %s inode 0x%p count %d dentry: 0x%p d_time %ld " + "jiffies %ld", full_path, inode, inode->i_count.counter, + dentry, dentry->d_time, jiffies)); - if (timespec_equal(&local_mtime, &direntry->d_inode->i_mtime) && - (local_size == direntry->d_inode->i_size)) { - cFYI(1, ("cifs_revalidate - inode unchanged")); - } else { - /* file may have changed on server */ - if (cifsInode->clientCanCacheRead) { - /* no need to invalidate inode pages since we were the - only ones who could have modified the file and the - server copy is staler than ours */ - } else { - invalidate_inode = true; - } - } + if (CIFS_SB(sb)->tcon->unix_ext) + rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid); + else + rc = cifs_get_inode_info(&inode, full_path, NULL, sb, + xid, NULL); - /* can not grab this sem since kernel filesys locking documentation - indicates i_mutex may be taken by the kernel on lookup and rename - which could deadlock if we grab the i_mutex here as well */ -/* mutex_lock(&direntry->d_inode->i_mutex);*/ - /* need to write out dirty pages here */ - if (direntry->d_inode->i_mapping) { - /* do we need to lock inode until after invalidate completes - below? */ - wbrc = filemap_fdatawrite(direntry->d_inode->i_mapping); - if (wbrc) - CIFS_I(direntry->d_inode)->write_behind_rc = wbrc; - } - if (invalidate_inode) { - /* shrink_dcache not necessary now that cifs dentry ops - are exported for negative dentries */ -/* if (S_ISDIR(direntry->d_inode->i_mode)) - shrink_dcache_parent(direntry); */ - if (S_ISREG(direntry->d_inode->i_mode)) { - if (direntry->d_inode->i_mapping) { - wbrc = filemap_fdatawait(direntry->d_inode->i_mapping); - if (wbrc) - CIFS_I(direntry->d_inode)->write_behind_rc = wbrc; - } - /* may eventually have to do this for open files too */ - if (list_empty(&(cifsInode->openFileList))) { - /* changed on server - flush read ahead pages */ - cFYI(1, ("Invalidating read ahead data on " - "closed file")); - invalidate_remote_inode(direntry->d_inode); - } - } - } -/* mutex_unlock(&direntry->d_inode->i_mutex); */ +check_inval: + if (CIFS_I(inode)->invalid_mapping) + cifs_invalidate_mapping(inode); kfree(full_path); FreeXid(xid); @@ -1527,7 +1512,7 @@ int cifs_revalidate(struct dentry *direntry) int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) { - int err = cifs_revalidate(dentry); + int err = cifs_revalidate_dentry(dentry); if (!err) { generic_fillattr(dentry->d_inode, stat); stat->blksize = CIFS_MAX_MSGSIZE; -- cgit v0.10.2 From bcd5357f430363376565d07ca542127d6d36602c Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Fri, 12 Feb 2010 07:44:16 -0500 Subject: cifs: add a CIFSSMBQFileInfo function ...to get inode attributes via filehandle instead of by path. In some places, we need to revalidate an inode on an open filehandle, but we can't necessarily guarantee that the dentry associated with it will still be valid. When we have an open filehandle already, it makes more sense to do a filehandle based operation anyway. Signed-off-by: Jeff Layton Signed-off-by: Steve French diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 88e2bc4..bf2bff1 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -142,6 +142,8 @@ extern int CIFSFindNext(const int xid, struct cifsTconInfo *tcon, extern int CIFSFindClose(const int, struct cifsTconInfo *tcon, const __u16 search_handle); +extern int CIFSSMBQFileInfo(const int xid, struct cifsTconInfo *tcon, + u16 netfid, FILE_ALL_INFO *pFindData); extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, const unsigned char *searchName, FILE_ALL_INFO *findData, diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 9d17df3..4ed9782 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -3230,8 +3230,72 @@ QInfRetry: return rc; } +int +CIFSSMBQFileInfo(const int xid, struct cifsTconInfo *tcon, + u16 netfid, FILE_ALL_INFO *pFindData) +{ + struct smb_t2_qfi_req *pSMB = NULL; + struct smb_t2_qfi_rsp *pSMBr = NULL; + int rc = 0; + int bytes_returned; + __u16 params, byte_count; + +QFileInfoRetry: + rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, + (void **) &pSMBr); + if (rc) + return rc; + + params = 2 /* level */ + 2 /* fid */; + pSMB->t2.TotalDataCount = 0; + pSMB->t2.MaxParameterCount = cpu_to_le16(4); + /* BB find exact max data count below from sess structure BB */ + pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize); + pSMB->t2.MaxSetupCount = 0; + pSMB->t2.Reserved = 0; + pSMB->t2.Flags = 0; + pSMB->t2.Timeout = 0; + pSMB->t2.Reserved2 = 0; + pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req, + Fid) - 4); + pSMB->t2.DataCount = 0; + pSMB->t2.DataOffset = 0; + pSMB->t2.SetupCount = 1; + pSMB->t2.Reserved3 = 0; + pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION); + byte_count = params + 1 /* pad */ ; + pSMB->t2.TotalParameterCount = cpu_to_le16(params); + pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount; + pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO); + pSMB->Pad = 0; + pSMB->Fid = netfid; + pSMB->hdr.smb_buf_length += byte_count; + + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + (struct smb_hdr *) pSMBr, &bytes_returned, 0); + if (rc) { + cFYI(1, ("Send error in QPathInfo = %d", rc)); + } else { /* decode response */ + rc = validate_t2((struct smb_t2_rsp *)pSMBr); + if (rc) /* BB add auto retry on EOPNOTSUPP? */ + rc = -EIO; + else if (pSMBr->ByteCount < 40) + rc = -EIO; /* bad smb */ + else if (pFindData) { + __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); + memcpy((char *) pFindData, + (char *) &pSMBr->hdr.Protocol + + data_offset, sizeof(FILE_ALL_INFO)); + } else + rc = -ENOMEM; + } + cifs_buf_release(pSMB); + if (rc == -EAGAIN) + goto QFileInfoRetry; + return rc; +} int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, -- cgit v0.10.2 From c8634fd3115497ac311f57be9c12f993437745cf Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Fri, 12 Feb 2010 07:44:17 -0500 Subject: cifs: add a CIFSSMBUnixQFileInfo function ...to allow us to get unix attrs via filehandle. Signed-off-by: Jeff Layton Signed-off-by: Steve French diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index bf2bff1..ce9199f 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -154,6 +154,8 @@ extern int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon, FILE_ALL_INFO *findData, const struct nls_table *nls_codepage, int remap); +extern int CIFSSMBUnixQFileInfo(const int xid, struct cifsTconInfo *tcon, + u16 netfid, FILE_UNIX_BASIC_INFO *pFindData); extern int CIFSSMBUnixQPathInfo(const int xid, struct cifsTconInfo *tcon, const unsigned char *searchName, diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 4ed9782..903d538 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -3399,6 +3399,75 @@ QPathInfoRetry: } int +CIFSSMBUnixQFileInfo(const int xid, struct cifsTconInfo *tcon, + u16 netfid, FILE_UNIX_BASIC_INFO *pFindData) +{ + struct smb_t2_qfi_req *pSMB = NULL; + struct smb_t2_qfi_rsp *pSMBr = NULL; + int rc = 0; + int bytes_returned; + __u16 params, byte_count; + +UnixQFileInfoRetry: + rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, + (void **) &pSMBr); + if (rc) + return rc; + + params = 2 /* level */ + 2 /* fid */; + pSMB->t2.TotalDataCount = 0; + pSMB->t2.MaxParameterCount = cpu_to_le16(4); + /* BB find exact max data count below from sess structure BB */ + pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize); + pSMB->t2.MaxSetupCount = 0; + pSMB->t2.Reserved = 0; + pSMB->t2.Flags = 0; + pSMB->t2.Timeout = 0; + pSMB->t2.Reserved2 = 0; + pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req, + Fid) - 4); + pSMB->t2.DataCount = 0; + pSMB->t2.DataOffset = 0; + pSMB->t2.SetupCount = 1; + pSMB->t2.Reserved3 = 0; + pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION); + byte_count = params + 1 /* pad */ ; + pSMB->t2.TotalParameterCount = cpu_to_le16(params); + pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount; + pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC); + pSMB->Pad = 0; + pSMB->Fid = netfid; + pSMB->hdr.smb_buf_length += byte_count; + + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + (struct smb_hdr *) pSMBr, &bytes_returned, 0); + if (rc) { + cFYI(1, ("Send error in QPathInfo = %d", rc)); + } else { /* decode response */ + rc = validate_t2((struct smb_t2_rsp *)pSMBr); + + if (rc || (pSMBr->ByteCount < sizeof(FILE_UNIX_BASIC_INFO))) { + cERROR(1, ("Malformed FILE_UNIX_BASIC_INFO response.\n" + "Unix Extensions can be disabled on mount " + "by specifying the nosfu mount option.")); + rc = -EIO; /* bad smb */ + } else { + __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); + memcpy((char *) pFindData, + (char *) &pSMBr->hdr.Protocol + + data_offset, + sizeof(FILE_UNIX_BASIC_INFO)); + } + } + + cifs_buf_release(pSMB); + if (rc == -EAGAIN) + goto UnixQFileInfoRetry; + + return rc; +} + +int CIFSSMBUnixQPathInfo(const int xid, struct cifsTconInfo *tcon, const unsigned char *searchName, FILE_UNIX_BASIC_INFO *pFindData, -- cgit v0.10.2 From 0a20de446c76529028cb239bf2a13cb0f05b263a Mon Sep 17 00:00:00 2001 From: Krishna Gudipati Date: Fri, 5 Mar 2010 19:34:20 -0800 Subject: [SCSI] bfa: IOC changes: Support faster recovery and split bfa_ioc.c into ASIC specific code. Add support for faster IOC recovery after failure. Split bfa_ioc.c into three files: bfa_ioc.c: Common code shared between crossbow and catapult ASIC's. bfa_ioc_cb.c: Code specific to the crossbow, reg mapping and interrupt related routines. bfa_ioc_ct.c: Code specific to the catapult, reg mapping and interrupt related routines. Fix to make sure IOC reinitialize's properly on enable request - update the ioc_fwstate reg with BFI_IOC_FAIL on ioc disable mbox cmd timeout. Makefile changes to support the 2 newly added files bfa_ioc_cb.c and bfa_ioc_ct.c. Signed-off-by: Krishna Gudipati Signed-off-by: James Bottomley diff --git a/drivers/scsi/bfa/Makefile b/drivers/scsi/bfa/Makefile index 1d60094..17e06ca 100644 --- a/drivers/scsi/bfa/Makefile +++ b/drivers/scsi/bfa/Makefile @@ -2,14 +2,14 @@ obj-$(CONFIG_SCSI_BFA_FC) := bfa.o bfa-y := bfad.o bfad_intr.o bfad_os.o bfad_im.o bfad_attr.o bfad_fwimg.o -bfa-y += bfa_core.o bfa_ioc.o bfa_iocfc.o bfa_fcxp.o bfa_lps.o -bfa-y += bfa_hw_cb.o bfa_hw_ct.o bfa_intr.o bfa_timer.o bfa_rport.o +bfa-y += bfa_core.o bfa_ioc.o bfa_ioc_ct.o bfa_ioc_cb.o bfa_iocfc.o bfa_fcxp.o +bfa-y += bfa_lps.o bfa_hw_cb.o bfa_hw_ct.o bfa_intr.o bfa_timer.o bfa_rport.o bfa-y += bfa_fcport.o bfa_port.o bfa_uf.o bfa_sgpg.o bfa_module.o bfa_ioim.o bfa-y += bfa_itnim.o bfa_fcpim.o bfa_tskim.o bfa_log.o bfa_log_module.o bfa-y += bfa_csdebug.o bfa_sm.o plog.o -bfa-y += fcbuild.o fabric.o fcpim.o vfapi.o fcptm.o bfa_fcs.o bfa_fcs_port.o +bfa-y += fcbuild.o fabric.o fcpim.o vfapi.o fcptm.o bfa_fcs.o bfa_fcs_port.o bfa-y += bfa_fcs_uf.o bfa_fcs_lport.o fab.o fdmi.o ms.o ns.o scn.o loop.o bfa-y += lport_api.o n2n.o rport.o rport_api.o rport_ftrs.o vport.o -ccflags-y := -I$(obj) -I$(obj)/include -I$(obj)/include/cna +ccflags-y := -I$(obj) -I$(obj)/include -I$(obj)/include/cna -DBFA_PERF_BUILD diff --git a/drivers/scsi/bfa/bfa_core.c b/drivers/scsi/bfa/bfa_core.c index 44e2d11..72e3f2f 100644 --- a/drivers/scsi/bfa/bfa_core.c +++ b/drivers/scsi/bfa/bfa_core.c @@ -399,4 +399,14 @@ bfa_debug_fwtrc(struct bfa_s *bfa, void *trcdata, int *trclen) { return bfa_ioc_debug_fwtrc(&bfa->ioc, trcdata, trclen); } + +/** + * Reset hw semaphore & usage cnt regs and initialize. + */ +void +bfa_chip_reset(struct bfa_s *bfa) +{ + bfa_ioc_ownership_reset(&bfa->ioc); + bfa_ioc_pll_init(&bfa->ioc); +} #endif diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c index 569b35d..a5f9745 100644 --- a/drivers/scsi/bfa/bfa_ioc.c +++ b/drivers/scsi/bfa/bfa_ioc.c @@ -33,12 +33,11 @@ BFA_TRC_FILE(HAL, IOC); * IOC local definitions */ #define BFA_IOC_TOV 2000 /* msecs */ -#define BFA_IOC_HB_TOV 1000 /* msecs */ -#define BFA_IOC_HB_FAIL_MAX 4 -#define BFA_IOC_HWINIT_MAX 2 +#define BFA_IOC_HWSEM_TOV 500 /* msecs */ +#define BFA_IOC_HB_TOV 500 /* msecs */ +#define BFA_IOC_HWINIT_MAX 2 #define BFA_IOC_FWIMG_MINSZ (16 * 1024) -#define BFA_IOC_TOV_RECOVER (BFA_IOC_HB_FAIL_MAX * BFA_IOC_HB_TOV \ - + BFA_IOC_TOV) +#define BFA_IOC_TOV_RECOVER BFA_IOC_HB_TOV #define bfa_ioc_timer_start(__ioc) \ bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->ioc_timer, \ @@ -51,11 +50,24 @@ BFA_TRC_FILE(HAL, IOC); (sizeof(struct bfa_trc_mod_s) - \ BFA_TRC_MAX * sizeof(struct bfa_trc_s))) #define BFA_DBG_FWTRC_OFF(_fn) (BFI_IOC_TRC_OFF + BFA_DBG_FWTRC_LEN * (_fn)) -#define bfa_ioc_stats(_ioc, _stats) ((_ioc)->stats._stats++) -#define BFA_FLASH_CHUNK_NO(off) (off / BFI_FLASH_CHUNK_SZ_WORDS) -#define BFA_FLASH_OFFSET_IN_CHUNK(off) (off % BFI_FLASH_CHUNK_SZ_WORDS) -#define BFA_FLASH_CHUNK_ADDR(chunkno) (chunkno * BFI_FLASH_CHUNK_SZ_WORDS) +/** + * Asic specific macros : see bfa_hw_cb.c and bfa_hw_ct.c for details. + */ + +#define bfa_ioc_firmware_lock(__ioc) \ + ((__ioc)->ioc_hwif->ioc_firmware_lock(__ioc)) +#define bfa_ioc_firmware_unlock(__ioc) \ + ((__ioc)->ioc_hwif->ioc_firmware_unlock(__ioc)) +#define bfa_ioc_fwimg_get_chunk(__ioc, __off) \ + ((__ioc)->ioc_hwif->ioc_fwimg_get_chunk(__ioc, __off)) +#define bfa_ioc_fwimg_get_size(__ioc) \ + ((__ioc)->ioc_hwif->ioc_fwimg_get_size(__ioc)) +#define bfa_ioc_reg_init(__ioc) ((__ioc)->ioc_hwif->ioc_reg_init(__ioc)) +#define bfa_ioc_map_port(__ioc) ((__ioc)->ioc_hwif->ioc_map_port(__ioc)) +#define bfa_ioc_notify_hbfail(__ioc) \ + ((__ioc)->ioc_hwif->ioc_notify_hbfail(__ioc)) + bfa_boolean_t bfa_auto_recover = BFA_TRUE; /* @@ -64,7 +76,6 @@ bfa_boolean_t bfa_auto_recover = BFA_TRUE; static void bfa_ioc_aen_post(struct bfa_ioc_s *bfa, enum bfa_ioc_aen_event event); static void bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc); -static void bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc); static void bfa_ioc_hw_sem_get_cancel(struct bfa_ioc_s *ioc); static void bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force); static void bfa_ioc_timeout(void *ioc); @@ -77,8 +88,6 @@ static void bfa_ioc_reset(struct bfa_ioc_s *ioc, bfa_boolean_t force); static void bfa_ioc_mbox_poll(struct bfa_ioc_s *ioc); static void bfa_ioc_mbox_hbfail(struct bfa_ioc_s *ioc); static void bfa_ioc_recover(struct bfa_ioc_s *ioc); -static bfa_boolean_t bfa_ioc_firmware_lock(struct bfa_ioc_s *ioc); -static void bfa_ioc_firmware_unlock(struct bfa_ioc_s *ioc); static void bfa_ioc_disable_comp(struct bfa_ioc_s *ioc); static void bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc); @@ -508,14 +517,19 @@ bfa_ioc_sm_disabling(struct bfa_ioc_s *ioc, enum ioc_event event) bfa_trc(ioc, event); switch (event) { - case IOC_E_HWERROR: case IOC_E_FWRSP_DISABLE: bfa_ioc_timer_stop(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); + break; + + case IOC_E_HWERROR: + bfa_ioc_timer_stop(ioc); /* * !!! fall through !!! */ case IOC_E_TIMEOUT: + bfa_reg_write(ioc->ioc_regs.ioc_fwstate, BFI_IOC_FAIL); bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); break; @@ -608,15 +622,12 @@ bfa_ioc_sm_hbfail_entry(struct bfa_ioc_s *ioc) * Mark IOC as failed in hardware and stop firmware. */ bfa_ioc_lpu_stop(ioc); - bfa_reg_write(ioc->ioc_regs.ioc_fwstate, BFI_IOC_HBFAIL); + bfa_reg_write(ioc->ioc_regs.ioc_fwstate, BFI_IOC_FAIL); - if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) { - bfa_reg_write(ioc->ioc_regs.ll_halt, __FW_INIT_HALT_P); - /* - * Wait for halt to take effect - */ - bfa_reg_read(ioc->ioc_regs.ll_halt); - } + /** + * Notify other functions on HB failure. + */ + bfa_ioc_notify_hbfail(ioc); /** * Notify driver and common modules registered for notification. @@ -672,6 +683,12 @@ bfa_ioc_sm_hbfail(struct bfa_ioc_s *ioc, enum ioc_event event) */ break; + case IOC_E_HWERROR: + /* + * HB failure notification, ignore. + */ + break; + default: bfa_sm_fault(ioc, event); } @@ -700,7 +717,7 @@ bfa_ioc_disable_comp(struct bfa_ioc_s *ioc) } } -static void +void bfa_ioc_sem_timeout(void *ioc_arg) { struct bfa_ioc_s *ioc = (struct bfa_ioc_s *)ioc_arg; @@ -708,26 +725,32 @@ bfa_ioc_sem_timeout(void *ioc_arg) bfa_ioc_hw_sem_get(ioc); } -static void -bfa_ioc_usage_sem_get(struct bfa_ioc_s *ioc) +bfa_boolean_t +bfa_ioc_sem_get(bfa_os_addr_t sem_reg) { - u32 r32; - int cnt = 0; -#define BFA_SEM_SPINCNT 1000 + u32 r32; + int cnt = 0; +#define BFA_SEM_SPINCNT 3000 - do { - r32 = bfa_reg_read(ioc->ioc_regs.ioc_usage_sem_reg); + r32 = bfa_reg_read(sem_reg); + + while (r32 && (cnt < BFA_SEM_SPINCNT)) { cnt++; - if (cnt > BFA_SEM_SPINCNT) - break; - } while (r32 != 0); + bfa_os_udelay(2); + r32 = bfa_reg_read(sem_reg); + } + + if (r32 == 0) + return BFA_TRUE; + bfa_assert(cnt < BFA_SEM_SPINCNT); + return BFA_FALSE; } -static void -bfa_ioc_usage_sem_release(struct bfa_ioc_s *ioc) +void +bfa_ioc_sem_release(bfa_os_addr_t sem_reg) { - bfa_reg_write(ioc->ioc_regs.ioc_usage_sem_reg, 1); + bfa_reg_write(sem_reg, 1); } static void @@ -737,7 +760,7 @@ bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc) /** * First read to the semaphore register will return 0, subsequent reads - * will return 1. Semaphore is released by writing 0 to the register + * will return 1. Semaphore is released by writing 1 to the register */ r32 = bfa_reg_read(ioc->ioc_regs.ioc_sem_reg); if (r32 == 0) { @@ -746,10 +769,10 @@ bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc) } bfa_timer_begin(ioc->timer_mod, &ioc->sem_timer, bfa_ioc_sem_timeout, - ioc, BFA_IOC_TOV); + ioc, BFA_IOC_HWSEM_TOV); } -static void +void bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc) { bfa_reg_write(ioc->ioc_regs.ioc_sem_reg, 1); @@ -828,7 +851,7 @@ bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc) /** * Get driver and firmware versions. */ -static void +void bfa_ioc_fwver_get(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr) { u32 pgnum, pgoff; @@ -847,24 +870,10 @@ bfa_ioc_fwver_get(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr) } } -static u32 * -bfa_ioc_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off) -{ - if (ioc->ctdev) - return bfi_image_ct_get_chunk(off); - return bfi_image_cb_get_chunk(off); -} - -static u32 -bfa_ioc_fwimg_get_size(struct bfa_ioc_s *ioc) -{ -return (ioc->ctdev) ? bfi_image_ct_size : bfi_image_cb_size; -} - /** * Returns TRUE if same. */ -static bfa_boolean_t +bfa_boolean_t bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr) { struct bfi_ioc_image_hdr_s *drv_fwhdr; @@ -921,95 +930,6 @@ bfa_ioc_fwver_valid(struct bfa_ioc_s *ioc) } /** - * Return true if firmware of current driver matches the running firmware. - */ -static bfa_boolean_t -bfa_ioc_firmware_lock(struct bfa_ioc_s *ioc) -{ - enum bfi_ioc_state ioc_fwstate; - u32 usecnt; - struct bfi_ioc_image_hdr_s fwhdr; - - /** - * Firmware match check is relevant only for CNA. - */ - if (!ioc->cna) - return BFA_TRUE; - - /** - * If bios boot (flash based) -- do not increment usage count - */ - if (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ) - return BFA_TRUE; - - bfa_ioc_usage_sem_get(ioc); - usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg); - - /** - * If usage count is 0, always return TRUE. - */ - if (usecnt == 0) { - bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, 1); - bfa_ioc_usage_sem_release(ioc); - bfa_trc(ioc, usecnt); - return BFA_TRUE; - } - - ioc_fwstate = bfa_reg_read(ioc->ioc_regs.ioc_fwstate); - bfa_trc(ioc, ioc_fwstate); - - /** - * Use count cannot be non-zero and chip in uninitialized state. - */ - bfa_assert(ioc_fwstate != BFI_IOC_UNINIT); - - /** - * Check if another driver with a different firmware is active - */ - bfa_ioc_fwver_get(ioc, &fwhdr); - if (!bfa_ioc_fwver_cmp(ioc, &fwhdr)) { - bfa_ioc_usage_sem_release(ioc); - bfa_trc(ioc, usecnt); - return BFA_FALSE; - } - - /** - * Same firmware version. Increment the reference count. - */ - usecnt++; - bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt); - bfa_ioc_usage_sem_release(ioc); - bfa_trc(ioc, usecnt); - return BFA_TRUE; -} - -static void -bfa_ioc_firmware_unlock(struct bfa_ioc_s *ioc) -{ - u32 usecnt; - - /** - * Firmware lock is relevant only for CNA. - * If bios boot (flash based) -- do not decrement usage count - */ - if (!ioc->cna || (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)) - return; - - /** - * decrement usage count - */ - bfa_ioc_usage_sem_get(ioc); - usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg); - bfa_assert(usecnt > 0); - - usecnt--; - bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt); - bfa_trc(ioc, usecnt); - - bfa_ioc_usage_sem_release(ioc); -} - -/** * Conditionally flush any pending message from firmware at start. */ static void @@ -1152,33 +1072,27 @@ bfa_ioc_send_getattr(struct bfa_ioc_s *ioc) static void bfa_ioc_hb_check(void *cbarg) { - struct bfa_ioc_s *ioc = cbarg; - u32 hb_count; + struct bfa_ioc_s *ioc = cbarg; + u32 hb_count; hb_count = bfa_reg_read(ioc->ioc_regs.heartbeat); if (ioc->hb_count == hb_count) { - ioc->hb_fail++; - } else { - ioc->hb_count = hb_count; - ioc->hb_fail = 0; - } - - if (ioc->hb_fail >= BFA_IOC_HB_FAIL_MAX) { - bfa_log(ioc->logm, BFA_LOG_HAL_HEARTBEAT_FAILURE, hb_count); - ioc->hb_fail = 0; + bfa_log(ioc->logm, BFA_LOG_HAL_HEARTBEAT_FAILURE, + hb_count); bfa_ioc_recover(ioc); return; + } else { + ioc->hb_count = hb_count; } bfa_ioc_mbox_poll(ioc); - bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer, bfa_ioc_hb_check, ioc, - BFA_IOC_HB_TOV); + bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer, bfa_ioc_hb_check, + ioc, BFA_IOC_HB_TOV); } static void bfa_ioc_hb_monitor(struct bfa_ioc_s *ioc) { - ioc->hb_fail = 0; ioc->hb_count = bfa_reg_read(ioc->ioc_regs.heartbeat); bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer, bfa_ioc_hb_check, ioc, BFA_IOC_HB_TOV); @@ -1191,112 +1105,6 @@ bfa_ioc_hb_stop(struct bfa_ioc_s *ioc) } /** - * Host to LPU mailbox message addresses - */ -static struct { - u32 hfn_mbox, lpu_mbox, hfn_pgn; -} iocreg_fnreg[] = { - { - HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0}, { - HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1}, { - HOSTFN2_LPU_MBOX0_0, LPU_HOSTFN2_MBOX0_0, HOST_PAGE_NUM_FN2}, { - HOSTFN3_LPU_MBOX0_8, LPU_HOSTFN3_MBOX0_8, HOST_PAGE_NUM_FN3} -}; - -/** - * Host <-> LPU mailbox command/status registers - port 0 - */ -static struct { - u32 hfn, lpu; -} iocreg_mbcmd_p0[] = { - { - HOSTFN0_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN0_MBOX0_CMD_STAT}, { - HOSTFN1_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN1_MBOX0_CMD_STAT}, { - HOSTFN2_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN2_MBOX0_CMD_STAT}, { - HOSTFN3_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN3_MBOX0_CMD_STAT} -}; - -/** - * Host <-> LPU mailbox command/status registers - port 1 - */ -static struct { - u32 hfn, lpu; -} iocreg_mbcmd_p1[] = { - { - HOSTFN0_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN0_MBOX0_CMD_STAT}, { - HOSTFN1_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN1_MBOX0_CMD_STAT}, { - HOSTFN2_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN2_MBOX0_CMD_STAT}, { - HOSTFN3_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN3_MBOX0_CMD_STAT} -}; - -/** - * Shared IRQ handling in INTX mode - */ -static struct { - u32 isr, msk; -} iocreg_shirq_next[] = { - { - HOSTFN1_INT_STATUS, HOSTFN1_INT_MSK}, { - HOSTFN2_INT_STATUS, HOSTFN2_INT_MSK}, { - HOSTFN3_INT_STATUS, HOSTFN3_INT_MSK}, { -HOSTFN0_INT_STATUS, HOSTFN0_INT_MSK},}; - -static void -bfa_ioc_reg_init(struct bfa_ioc_s *ioc) -{ - bfa_os_addr_t rb; - int pcifn = bfa_ioc_pcifn(ioc); - - rb = bfa_ioc_bar0(ioc); - - ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox; - ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox; - ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn; - - if (ioc->port_id == 0) { - ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG; - ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG; - ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].hfn; - ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].lpu; - ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0; - } else { - ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG); - ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG); - ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].hfn; - ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].lpu; - ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1; - } - - /** - * Shared IRQ handling in INTX mode - */ - ioc->ioc_regs.shirq_isr_next = rb + iocreg_shirq_next[pcifn].isr; - ioc->ioc_regs.shirq_msk_next = rb + iocreg_shirq_next[pcifn].msk; - - /* - * PSS control registers - */ - ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG); - ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_425_CTL_REG); - ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_312_CTL_REG); - - /* - * IOC semaphore registers and serialization - */ - ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG); - ioc->ioc_regs.ioc_usage_sem_reg = (rb + HOST_SEM1_REG); - ioc->ioc_regs.ioc_usage_reg = (rb + BFA_FW_USE_COUNT); - - /** - * sram memory access - */ - ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START); - ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CB; - if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) - ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CT; -} - -/** * Initiate a full firmware download. */ static void @@ -1332,17 +1140,17 @@ bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type, for (i = 0; i < bfa_ioc_fwimg_get_size(ioc); i++) { - if (BFA_FLASH_CHUNK_NO(i) != chunkno) { - chunkno = BFA_FLASH_CHUNK_NO(i); + if (BFA_IOC_FLASH_CHUNK_NO(i) != chunkno) { + chunkno = BFA_IOC_FLASH_CHUNK_NO(i); fwimg = bfa_ioc_fwimg_get_chunk(ioc, - BFA_FLASH_CHUNK_ADDR(chunkno)); + BFA_IOC_FLASH_CHUNK_ADDR(chunkno)); } /** * write smem */ bfa_mem_write(ioc->ioc_regs.smem_page_start, loff, - fwimg[BFA_FLASH_OFFSET_IN_CHUNK(i)]); + fwimg[BFA_IOC_FLASH_OFFSET_IN_CHUNK(i)]); loff += sizeof(u32); @@ -1440,168 +1248,10 @@ bfa_ioc_mbox_hbfail(struct bfa_ioc_s *ioc) } /** - * Initialize IOC to port mapping. - */ - -#define FNC_PERS_FN_SHIFT(__fn) ((__fn) * 8) -static void -bfa_ioc_map_port(struct bfa_ioc_s *ioc) -{ - bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva; - u32 r32; - - /** - * For crossbow, port id is same as pci function. - */ - if (ioc->pcidev.device_id != BFA_PCI_DEVICE_ID_CT) { - ioc->port_id = bfa_ioc_pcifn(ioc); - return; - } - - /** - * For catapult, base port id on personality register and IOC type - */ - r32 = bfa_reg_read(rb + FNC_PERS_REG); - r32 >>= FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)); - ioc->port_id = (r32 & __F0_PORT_MAP_MK) >> __F0_PORT_MAP_SH; - - bfa_trc(ioc, bfa_ioc_pcifn(ioc)); - bfa_trc(ioc, ioc->port_id); -} - - - -/** * bfa_ioc_public */ /** -* Set interrupt mode for a function: INTX or MSIX - */ -void -bfa_ioc_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix) -{ - bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva; - u32 r32, mode; - - r32 = bfa_reg_read(rb + FNC_PERS_REG); - bfa_trc(ioc, r32); - - mode = (r32 >> FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))) & - __F0_INTX_STATUS; - - /** - * If already in desired mode, do not change anything - */ - if (!msix && mode) - return; - - if (msix) - mode = __F0_INTX_STATUS_MSIX; - else - mode = __F0_INTX_STATUS_INTA; - - r32 &= ~(__F0_INTX_STATUS << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))); - r32 |= (mode << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))); - bfa_trc(ioc, r32); - - bfa_reg_write(rb + FNC_PERS_REG, r32); -} - -bfa_status_t -bfa_ioc_pll_init(struct bfa_ioc_s *ioc) -{ - bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva; - u32 pll_sclk, pll_fclk, r32; - - if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) { - pll_sclk = - __APP_PLL_312_ENABLE | __APP_PLL_312_LRESETN | - __APP_PLL_312_RSEL200500 | __APP_PLL_312_P0_1(0U) | - __APP_PLL_312_JITLMT0_1(3U) | - __APP_PLL_312_CNTLMT0_1(1U); - pll_fclk = - __APP_PLL_425_ENABLE | __APP_PLL_425_LRESETN | - __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(0U) | - __APP_PLL_425_JITLMT0_1(3U) | - __APP_PLL_425_CNTLMT0_1(1U); - - /** - * For catapult, choose operational mode FC/FCoE - */ - if (ioc->fcmode) { - bfa_reg_write((rb + OP_MODE), 0); - bfa_reg_write((rb + ETH_MAC_SER_REG), - __APP_EMS_CMLCKSEL | __APP_EMS_REFCKBUFEN2 - | __APP_EMS_CHANNEL_SEL); - } else { - ioc->pllinit = BFA_TRUE; - bfa_reg_write((rb + OP_MODE), __GLOBAL_FCOE_MODE); - bfa_reg_write((rb + ETH_MAC_SER_REG), - __APP_EMS_REFCKBUFEN1); - } - } else { - pll_sclk = - __APP_PLL_312_ENABLE | __APP_PLL_312_LRESETN | - __APP_PLL_312_P0_1(3U) | __APP_PLL_312_JITLMT0_1(3U) | - __APP_PLL_312_CNTLMT0_1(3U); - pll_fclk = - __APP_PLL_425_ENABLE | __APP_PLL_425_LRESETN | - __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(3U) | - __APP_PLL_425_JITLMT0_1(3U) | - __APP_PLL_425_CNTLMT0_1(3U); - } - - bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_UNINIT); - bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_UNINIT); - - bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU); - bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU); - bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU); - bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU); - bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU); - bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU); - - bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, - __APP_PLL_312_LOGIC_SOFT_RESET); - bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, - __APP_PLL_312_BYPASS | __APP_PLL_312_LOGIC_SOFT_RESET); - bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, - __APP_PLL_425_LOGIC_SOFT_RESET); - bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, - __APP_PLL_425_BYPASS | __APP_PLL_425_LOGIC_SOFT_RESET); - bfa_os_udelay(2); - bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, - __APP_PLL_312_LOGIC_SOFT_RESET); - bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, - __APP_PLL_425_LOGIC_SOFT_RESET); - - bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, - pll_sclk | __APP_PLL_312_LOGIC_SOFT_RESET); - bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, - pll_fclk | __APP_PLL_425_LOGIC_SOFT_RESET); - - /** - * Wait for PLLs to lock. - */ - bfa_os_udelay(2000); - bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU); - bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU); - - bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk); - bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk); - - if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) { - bfa_reg_write((rb + MBIST_CTL_REG), __EDRAM_BISTR_START); - bfa_os_udelay(1000); - r32 = bfa_reg_read((rb + MBIST_STAT_REG)); - bfa_trc(ioc, r32); - } - - return BFA_STATUS_OK; -} - -/** * Interface used by diag module to do firmware boot with memory test * as the entry vector. */ @@ -1764,6 +1414,14 @@ bfa_ioc_pci_init(struct bfa_ioc_s *ioc, struct bfa_pcidev_s *pcidev, ioc->ctdev = (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT); ioc->cna = ioc->ctdev && !ioc->fcmode; + /** + * Set asic specific interfaces. See bfa_ioc_cb.c and bfa_ioc_ct.c + */ + if (ioc->ctdev) + bfa_ioc_set_ct_hwif(ioc); + else + bfa_ioc_set_cb_hwif(ioc); + bfa_ioc_map_port(ioc); bfa_ioc_reg_init(ioc); } @@ -1973,7 +1631,7 @@ bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc) ((__sm) == BFI_IOC_INITING) || \ ((__sm) == BFI_IOC_HWINIT) || \ ((__sm) == BFI_IOC_DISABLED) || \ - ((__sm) == BFI_IOC_HBFAIL) || \ + ((__sm) == BFI_IOC_FAIL) || \ ((__sm) == BFI_IOC_CFG_DISABLED)) /** @@ -2195,29 +1853,6 @@ bfa_ioc_get_fcmode(struct bfa_ioc_s *ioc) } /** - * Return true if interrupt should be claimed. - */ -bfa_boolean_t -bfa_ioc_intx_claim(struct bfa_ioc_s *ioc) -{ - u32 isr, msk; - - /** - * Always claim if not catapult. - */ - if (!ioc->ctdev) - return BFA_TRUE; - - /** - * FALSE if next device is claiming interrupt. - * TRUE if next device is not interrupting or not present. - */ - msk = bfa_reg_read(ioc->ioc_regs.shirq_msk_next); - isr = bfa_reg_read(ioc->ioc_regs.shirq_isr_next); - return !(isr & ~msk); -} - -/** * Send AEN notification */ static void @@ -2304,6 +1939,13 @@ bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata, int *trclen) pgnum = bfa_ioc_smem_pgnum(ioc, loff); loff = bfa_ioc_smem_pgoff(ioc, loff); + + /* + * Hold semaphore to serialize pll init and fwtrc. + */ + if (BFA_FALSE == bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg)) + return BFA_STATUS_FAILED; + bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum); tlen = *trclen; @@ -2329,6 +1971,12 @@ bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata, int *trclen) } bfa_reg_write(ioc->ioc_regs.host_page_num_fn, bfa_ioc_smem_pgnum(ioc, 0)); + + /* + * release semaphore. + */ + bfa_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg); + bfa_trc(ioc, pgnum); *trclen = tlen * sizeof(u32); diff --git a/drivers/scsi/bfa/bfa_ioc.h b/drivers/scsi/bfa/bfa_ioc.h index 7c30f05..1633a50 100644 --- a/drivers/scsi/bfa/bfa_ioc.h +++ b/drivers/scsi/bfa/bfa_ioc.h @@ -78,11 +78,13 @@ struct bfa_ioc_regs_s { bfa_os_addr_t app_pll_slow_ctl_reg; bfa_os_addr_t ioc_sem_reg; bfa_os_addr_t ioc_usage_sem_reg; + bfa_os_addr_t ioc_init_sem_reg; bfa_os_addr_t ioc_usage_reg; bfa_os_addr_t host_page_num_fn; bfa_os_addr_t heartbeat; bfa_os_addr_t ioc_fwstate; bfa_os_addr_t ll_halt; + bfa_os_addr_t err_set; bfa_os_addr_t shirq_isr_next; bfa_os_addr_t shirq_msk_next; bfa_os_addr_t smem_page_start; @@ -154,7 +156,6 @@ struct bfa_ioc_s { struct bfa_timer_s ioc_timer; struct bfa_timer_s sem_timer; u32 hb_count; - u32 hb_fail; u32 retry_count; struct list_head hb_notify_q; void *dbg_fwsave; @@ -177,6 +178,22 @@ struct bfa_ioc_s { struct bfi_ioc_attr_s *attr; struct bfa_ioc_cbfn_s *cbfn; struct bfa_ioc_mbox_mod_s mbox_mod; + struct bfa_ioc_hwif_s *ioc_hwif; +}; + +struct bfa_ioc_hwif_s { + bfa_status_t (*ioc_pll_init) (struct bfa_ioc_s *ioc); + bfa_boolean_t (*ioc_firmware_lock) (struct bfa_ioc_s *ioc); + void (*ioc_firmware_unlock) (struct bfa_ioc_s *ioc); + u32 * (*ioc_fwimg_get_chunk) (struct bfa_ioc_s *ioc, + u32 off); + u32 (*ioc_fwimg_get_size) (struct bfa_ioc_s *ioc); + void (*ioc_reg_init) (struct bfa_ioc_s *ioc); + void (*ioc_map_port) (struct bfa_ioc_s *ioc); + void (*ioc_isr_mode_set) (struct bfa_ioc_s *ioc, + bfa_boolean_t msix); + void (*ioc_notify_hbfail) (struct bfa_ioc_s *ioc); + void (*ioc_ownership_reset) (struct bfa_ioc_s *ioc); }; #define bfa_ioc_pcifn(__ioc) ((__ioc)->pcidev.pci_func) @@ -191,6 +208,15 @@ struct bfa_ioc_s { #define bfa_ioc_rx_bbcredit(__ioc) ((__ioc)->attr->rx_bbcredit) #define bfa_ioc_speed_sup(__ioc) \ BFI_ADAPTER_GETP(SPEED, (__ioc)->attr->adapter_prop) +#define bfa_ioc_get_nports(__ioc) \ + BFI_ADAPTER_GETP(NPORTS, (__ioc)->attr->adapter_prop) + +#define bfa_ioc_stats(_ioc, _stats) ((_ioc)->stats._stats++) +#define BFA_IOC_FWIMG_MINSZ (16 * 1024) + +#define BFA_IOC_FLASH_CHUNK_NO(off) (off / BFI_FLASH_CHUNK_SZ_WORDS) +#define BFA_IOC_FLASH_OFFSET_IN_CHUNK(off) (off % BFI_FLASH_CHUNK_SZ_WORDS) +#define BFA_IOC_FLASH_CHUNK_ADDR(chunkno) (chunkno * BFI_FLASH_CHUNK_SZ_WORDS) /** * IOC mailbox interface @@ -207,6 +233,14 @@ void bfa_ioc_mbox_regisr(struct bfa_ioc_s *ioc, enum bfi_mclass mc, /** * IOC interfaces */ +#define bfa_ioc_pll_init(__ioc) ((__ioc)->ioc_hwif->ioc_pll_init(__ioc)) +#define bfa_ioc_isr_mode_set(__ioc, __msix) \ + ((__ioc)->ioc_hwif->ioc_isr_mode_set(__ioc, __msix)) +#define bfa_ioc_ownership_reset(__ioc) \ + ((__ioc)->ioc_hwif->ioc_ownership_reset(__ioc)) + +void bfa_ioc_set_ct_hwif(struct bfa_ioc_s *ioc); +void bfa_ioc_set_cb_hwif(struct bfa_ioc_s *ioc); void bfa_ioc_attach(struct bfa_ioc_s *ioc, void *bfa, struct bfa_ioc_cbfn_s *cbfn, struct bfa_timer_mod_s *timer_mod, struct bfa_trc_mod_s *trcmod, @@ -223,8 +257,6 @@ bfa_boolean_t bfa_ioc_intx_claim(struct bfa_ioc_s *ioc); void bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_param); void bfa_ioc_isr(struct bfa_ioc_s *ioc, struct bfi_mbmsg_s *msg); void bfa_ioc_error_isr(struct bfa_ioc_s *ioc); -void bfa_ioc_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t intx); -bfa_status_t bfa_ioc_pll_init(struct bfa_ioc_s *ioc); bfa_boolean_t bfa_ioc_is_operational(struct bfa_ioc_s *ioc); bfa_boolean_t bfa_ioc_is_disabled(struct bfa_ioc_s *ioc); bfa_boolean_t bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc); @@ -245,6 +277,13 @@ void bfa_ioc_set_fcmode(struct bfa_ioc_s *ioc); bfa_boolean_t bfa_ioc_get_fcmode(struct bfa_ioc_s *ioc); void bfa_ioc_hbfail_register(struct bfa_ioc_s *ioc, struct bfa_ioc_hbfail_notify_s *notify); +bfa_boolean_t bfa_ioc_sem_get(bfa_os_addr_t sem_reg); +void bfa_ioc_sem_release(bfa_os_addr_t sem_reg); +void bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc); +void bfa_ioc_fwver_get(struct bfa_ioc_s *ioc, + struct bfi_ioc_image_hdr_s *fwhdr); +bfa_boolean_t bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc, + struct bfi_ioc_image_hdr_s *fwhdr); /* * bfa mfg wwn API functions diff --git a/drivers/scsi/bfa/bfa_ioc_cb.c b/drivers/scsi/bfa/bfa_ioc_cb.c new file mode 100644 index 0000000..d1d625b --- /dev/null +++ b/drivers/scsi/bfa/bfa_ioc_cb.c @@ -0,0 +1,273 @@ +/* + * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + * + * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +BFA_TRC_FILE(CNA, IOC_CB); + +/* + * forward declarations + */ +static bfa_status_t bfa_ioc_cb_pll_init(struct bfa_ioc_s *ioc); +static bfa_boolean_t bfa_ioc_cb_firmware_lock(struct bfa_ioc_s *ioc); +static void bfa_ioc_cb_firmware_unlock(struct bfa_ioc_s *ioc); +static u32 *bfa_ioc_cb_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off); +static u32 bfa_ioc_cb_fwimg_get_size(struct bfa_ioc_s *ioc); +static void bfa_ioc_cb_reg_init(struct bfa_ioc_s *ioc); +static void bfa_ioc_cb_map_port(struct bfa_ioc_s *ioc); +static void bfa_ioc_cb_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix); +static void bfa_ioc_cb_notify_hbfail(struct bfa_ioc_s *ioc); +static void bfa_ioc_cb_ownership_reset(struct bfa_ioc_s *ioc); + +struct bfa_ioc_hwif_s hwif_cb = { + bfa_ioc_cb_pll_init, + bfa_ioc_cb_firmware_lock, + bfa_ioc_cb_firmware_unlock, + bfa_ioc_cb_fwimg_get_chunk, + bfa_ioc_cb_fwimg_get_size, + bfa_ioc_cb_reg_init, + bfa_ioc_cb_map_port, + bfa_ioc_cb_isr_mode_set, + bfa_ioc_cb_notify_hbfail, + bfa_ioc_cb_ownership_reset, +}; + +/** + * Called from bfa_ioc_attach() to map asic specific calls. + */ +void +bfa_ioc_set_cb_hwif(struct bfa_ioc_s *ioc) +{ + ioc->ioc_hwif = &hwif_cb; +} + +static uint32_t * +bfa_ioc_cb_fwimg_get_chunk(struct bfa_ioc_s *ioc, uint32_t off) +{ + return bfi_image_cb_get_chunk(off); +} + +static uint32_t +bfa_ioc_cb_fwimg_get_size(struct bfa_ioc_s *ioc) +{ + return bfi_image_cb_size; +} + +/** + * Return true if firmware of current driver matches the running firmware. + */ +static bfa_boolean_t +bfa_ioc_cb_firmware_lock(struct bfa_ioc_s *ioc) +{ + return BFA_TRUE; +} + +static void +bfa_ioc_cb_firmware_unlock(struct bfa_ioc_s *ioc) +{ +} + +/** + * Notify other functions on HB failure. + */ +static void +bfa_ioc_cb_notify_hbfail(struct bfa_ioc_s *ioc) +{ + bfa_reg_write(ioc->ioc_regs.err_set, __PSS_ERR_STATUS_SET); + bfa_reg_read(ioc->ioc_regs.err_set); +} + +/** + * Host to LPU mailbox message addresses + */ +static struct { uint32_t hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = { + { HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0 }, + { HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1 } +}; + +/** + * Host <-> LPU mailbox command/status registers + */ +static struct { uint32_t hfn, lpu; } iocreg_mbcmd[] = { + { HOSTFN0_LPU0_CMD_STAT, LPU0_HOSTFN0_CMD_STAT }, + { HOSTFN1_LPU1_CMD_STAT, LPU1_HOSTFN1_CMD_STAT } +}; + +static void +bfa_ioc_cb_reg_init(struct bfa_ioc_s *ioc) +{ + bfa_os_addr_t rb; + int pcifn = bfa_ioc_pcifn(ioc); + + rb = bfa_ioc_bar0(ioc); + + ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox; + ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox; + ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn; + + if (ioc->port_id == 0) { + ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG; + ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG; + } else { + ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG); + ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG); + } + + /** + * Host <-> LPU mailbox command/status registers + */ + ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd[pcifn].hfn; + ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd[pcifn].lpu; + + /* + * PSS control registers + */ + ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG); + ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_400_CTL_REG); + ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_212_CTL_REG); + + /* + * IOC semaphore registers and serialization + */ + ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG); + ioc->ioc_regs.ioc_init_sem_reg = (rb + HOST_SEM2_REG); + + /** + * sram memory access + */ + ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START); + ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CB; + + /* + * err set reg : for notification of hb failure + */ + ioc->ioc_regs.err_set = (rb + ERR_SET_REG); +} + +/** + * Initialize IOC to port mapping. + */ +static void +bfa_ioc_cb_map_port(struct bfa_ioc_s *ioc) +{ + /** + * For crossbow, port id is same as pci function. + */ + ioc->port_id = bfa_ioc_pcifn(ioc); + bfa_trc(ioc, ioc->port_id); +} + +/** + * Set interrupt mode for a function: INTX or MSIX + */ +static void +bfa_ioc_cb_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix) +{ +} + +static bfa_status_t +bfa_ioc_cb_pll_init(struct bfa_ioc_s *ioc) +{ + bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva; + uint32_t pll_sclk, pll_fclk; + + /* + * Hold semaphore so that nobody can access the chip during init. + */ + bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg); + + pll_sclk = __APP_PLL_212_ENABLE | __APP_PLL_212_LRESETN | + __APP_PLL_212_P0_1(3U) | + __APP_PLL_212_JITLMT0_1(3U) | + __APP_PLL_212_CNTLMT0_1(3U); + pll_fclk = __APP_PLL_400_ENABLE | __APP_PLL_400_LRESETN | + __APP_PLL_400_RSEL200500 | __APP_PLL_400_P0_1(3U) | + __APP_PLL_400_JITLMT0_1(3U) | + __APP_PLL_400_CNTLMT0_1(3U); + + bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_UNINIT); + bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_UNINIT); + + bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU); + bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU); + bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU); + bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU); + bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU); + bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU); + + bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, + __APP_PLL_212_LOGIC_SOFT_RESET); + bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, + __APP_PLL_212_BYPASS | + __APP_PLL_212_LOGIC_SOFT_RESET); + bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, + __APP_PLL_400_LOGIC_SOFT_RESET); + bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, + __APP_PLL_400_BYPASS | + __APP_PLL_400_LOGIC_SOFT_RESET); + bfa_os_udelay(2); + bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, + __APP_PLL_212_LOGIC_SOFT_RESET); + bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, + __APP_PLL_400_LOGIC_SOFT_RESET); + + bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, + pll_sclk | __APP_PLL_212_LOGIC_SOFT_RESET); + bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, + pll_fclk | __APP_PLL_400_LOGIC_SOFT_RESET); + + /** + * Wait for PLLs to lock. + */ + bfa_os_udelay(2000); + bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU); + bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU); + + bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk); + bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk); + + /* + * release semaphore. + */ + bfa_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg); + + return BFA_STATUS_OK; +} + +/** + * Cleanup hw semaphore and usecnt registers + */ +static void +bfa_ioc_cb_ownership_reset(struct bfa_ioc_s *ioc) +{ + + /* + * Read the hw sem reg to make sure that it is locked + * before we clear it. If it is not locked, writing 1 + * will lock it instead of clearing it. + */ + bfa_reg_read(ioc->ioc_regs.ioc_sem_reg); + bfa_ioc_hw_sem_release(ioc); +} diff --git a/drivers/scsi/bfa/bfa_ioc_ct.c b/drivers/scsi/bfa/bfa_ioc_ct.c new file mode 100644 index 0000000..5de9c24 --- /dev/null +++ b/drivers/scsi/bfa/bfa_ioc_ct.c @@ -0,0 +1,422 @@ +/* + * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + * + * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +BFA_TRC_FILE(CNA, IOC_CT); + +/* + * forward declarations + */ +static bfa_status_t bfa_ioc_ct_pll_init(struct bfa_ioc_s *ioc); +static bfa_boolean_t bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc); +static void bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc); +static uint32_t* bfa_ioc_ct_fwimg_get_chunk(struct bfa_ioc_s *ioc, + uint32_t off); +static uint32_t bfa_ioc_ct_fwimg_get_size(struct bfa_ioc_s *ioc); +static void bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc); +static void bfa_ioc_ct_map_port(struct bfa_ioc_s *ioc); +static void bfa_ioc_ct_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix); +static void bfa_ioc_ct_notify_hbfail(struct bfa_ioc_s *ioc); +static void bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc); + +struct bfa_ioc_hwif_s hwif_ct = { + bfa_ioc_ct_pll_init, + bfa_ioc_ct_firmware_lock, + bfa_ioc_ct_firmware_unlock, + bfa_ioc_ct_fwimg_get_chunk, + bfa_ioc_ct_fwimg_get_size, + bfa_ioc_ct_reg_init, + bfa_ioc_ct_map_port, + bfa_ioc_ct_isr_mode_set, + bfa_ioc_ct_notify_hbfail, + bfa_ioc_ct_ownership_reset, +}; + +/** + * Called from bfa_ioc_attach() to map asic specific calls. + */ +void +bfa_ioc_set_ct_hwif(struct bfa_ioc_s *ioc) +{ + ioc->ioc_hwif = &hwif_ct; +} + +static uint32_t* +bfa_ioc_ct_fwimg_get_chunk(struct bfa_ioc_s *ioc, uint32_t off) +{ + return bfi_image_ct_get_chunk(off); +} + +static uint32_t +bfa_ioc_ct_fwimg_get_size(struct bfa_ioc_s *ioc) +{ + return bfi_image_ct_size; +} + +/** + * Return true if firmware of current driver matches the running firmware. + */ +static bfa_boolean_t +bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc) +{ + enum bfi_ioc_state ioc_fwstate; + uint32_t usecnt; + struct bfi_ioc_image_hdr_s fwhdr; + + /** + * Firmware match check is relevant only for CNA. + */ + if (!ioc->cna) + return BFA_TRUE; + + /** + * If bios boot (flash based) -- do not increment usage count + */ + if (bfa_ioc_ct_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ) + return BFA_TRUE; + + bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg); + usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg); + + /** + * If usage count is 0, always return TRUE. + */ + if (usecnt == 0) { + bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, 1); + bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); + bfa_trc(ioc, usecnt); + return BFA_TRUE; + } + + ioc_fwstate = bfa_reg_read(ioc->ioc_regs.ioc_fwstate); + bfa_trc(ioc, ioc_fwstate); + + /** + * Use count cannot be non-zero and chip in uninitialized state. + */ + bfa_assert(ioc_fwstate != BFI_IOC_UNINIT); + + /** + * Check if another driver with a different firmware is active + */ + bfa_ioc_fwver_get(ioc, &fwhdr); + if (!bfa_ioc_fwver_cmp(ioc, &fwhdr)) { + bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); + bfa_trc(ioc, usecnt); + return BFA_FALSE; + } + + /** + * Same firmware version. Increment the reference count. + */ + usecnt++; + bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt); + bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); + bfa_trc(ioc, usecnt); + return BFA_TRUE; +} + +static void +bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc) +{ + uint32_t usecnt; + + /** + * Firmware lock is relevant only for CNA. + * If bios boot (flash based) -- do not decrement usage count + */ + if (!ioc->cna || bfa_ioc_ct_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ) + return; + + /** + * decrement usage count + */ + bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg); + usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg); + bfa_assert(usecnt > 0); + + usecnt--; + bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt); + bfa_trc(ioc, usecnt); + + bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); +} + +/** + * Notify other functions on HB failure. + */ +static void +bfa_ioc_ct_notify_hbfail(struct bfa_ioc_s *ioc) +{ + + bfa_reg_write(ioc->ioc_regs.ll_halt, __FW_INIT_HALT_P); + /* Wait for halt to take effect */ + bfa_reg_read(ioc->ioc_regs.ll_halt); +} + +/** + * Host to LPU mailbox message addresses + */ +static struct { uint32_t hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = { + { HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0 }, + { HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1 }, + { HOSTFN2_LPU_MBOX0_0, LPU_HOSTFN2_MBOX0_0, HOST_PAGE_NUM_FN2 }, + { HOSTFN3_LPU_MBOX0_8, LPU_HOSTFN3_MBOX0_8, HOST_PAGE_NUM_FN3 } +}; + +/** + * Host <-> LPU mailbox command/status registers - port 0 + */ +static struct { uint32_t hfn, lpu; } iocreg_mbcmd_p0[] = { + { HOSTFN0_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN0_MBOX0_CMD_STAT }, + { HOSTFN1_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN1_MBOX0_CMD_STAT }, + { HOSTFN2_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN2_MBOX0_CMD_STAT }, + { HOSTFN3_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN3_MBOX0_CMD_STAT } +}; + +/** + * Host <-> LPU mailbox command/status registers - port 1 + */ +static struct { uint32_t hfn, lpu; } iocreg_mbcmd_p1[] = { + { HOSTFN0_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN0_MBOX0_CMD_STAT }, + { HOSTFN1_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN1_MBOX0_CMD_STAT }, + { HOSTFN2_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN2_MBOX0_CMD_STAT }, + { HOSTFN3_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN3_MBOX0_CMD_STAT } +}; + +static void +bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc) +{ + bfa_os_addr_t rb; + int pcifn = bfa_ioc_pcifn(ioc); + + rb = bfa_ioc_bar0(ioc); + + ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox; + ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox; + ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn; + + if (ioc->port_id == 0) { + ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG; + ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG; + ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].hfn; + ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].lpu; + ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0; + } else { + ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG); + ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG); + ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].hfn; + ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].lpu; + ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1; + } + + /* + * PSS control registers + */ + ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG); + ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_425_CTL_REG); + ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_312_CTL_REG); + + /* + * IOC semaphore registers and serialization + */ + ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG); + ioc->ioc_regs.ioc_usage_sem_reg = (rb + HOST_SEM1_REG); + ioc->ioc_regs.ioc_init_sem_reg = (rb + HOST_SEM2_REG); + ioc->ioc_regs.ioc_usage_reg = (rb + BFA_FW_USE_COUNT); + + /** + * sram memory access + */ + ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START); + ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CT; +} + +/** + * Initialize IOC to port mapping. + */ + +#define FNC_PERS_FN_SHIFT(__fn) ((__fn) * 8) +static void +bfa_ioc_ct_map_port(struct bfa_ioc_s *ioc) +{ + bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva; + uint32_t r32; + + /** + * For catapult, base port id on personality register and IOC type + */ + r32 = bfa_reg_read(rb + FNC_PERS_REG); + r32 >>= FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)); + ioc->port_id = (r32 & __F0_PORT_MAP_MK) >> __F0_PORT_MAP_SH; + + bfa_trc(ioc, bfa_ioc_pcifn(ioc)); + bfa_trc(ioc, ioc->port_id); +} + +/** + * Set interrupt mode for a function: INTX or MSIX + */ +static void +bfa_ioc_ct_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix) +{ + bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva; + uint32_t r32, mode; + + r32 = bfa_reg_read(rb + FNC_PERS_REG); + bfa_trc(ioc, r32); + + mode = (r32 >> FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))) & + __F0_INTX_STATUS; + + /** + * If already in desired mode, do not change anything + */ + if (!msix && mode) + return; + + if (msix) + mode = __F0_INTX_STATUS_MSIX; + else + mode = __F0_INTX_STATUS_INTA; + + r32 &= ~(__F0_INTX_STATUS << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))); + r32 |= (mode << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))); + bfa_trc(ioc, r32); + + bfa_reg_write(rb + FNC_PERS_REG, r32); +} + +static bfa_status_t +bfa_ioc_ct_pll_init(struct bfa_ioc_s *ioc) +{ + bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva; + uint32_t pll_sclk, pll_fclk, r32; + + /* + * Hold semaphore so that nobody can access the chip during init. + */ + bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg); + + pll_sclk = __APP_PLL_312_ENABLE | __APP_PLL_312_LRESETN | + __APP_PLL_312_RSEL200500 | __APP_PLL_312_P0_1(0U) | + __APP_PLL_312_JITLMT0_1(3U) | + __APP_PLL_312_CNTLMT0_1(1U); + pll_fclk = __APP_PLL_425_ENABLE | __APP_PLL_425_LRESETN | + __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(0U) | + __APP_PLL_425_JITLMT0_1(3U) | + __APP_PLL_425_CNTLMT0_1(1U); + + /** + * For catapult, choose operational mode FC/FCoE + */ + if (ioc->fcmode) { + bfa_reg_write((rb + OP_MODE), 0); + bfa_reg_write((rb + ETH_MAC_SER_REG), + __APP_EMS_CMLCKSEL | + __APP_EMS_REFCKBUFEN2 | + __APP_EMS_CHANNEL_SEL); + } else { + ioc->pllinit = BFA_TRUE; + bfa_reg_write((rb + OP_MODE), __GLOBAL_FCOE_MODE); + bfa_reg_write((rb + ETH_MAC_SER_REG), + __APP_EMS_REFCKBUFEN1); + } + + bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_UNINIT); + bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_UNINIT); + + bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU); + bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU); + bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU); + bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU); + bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU); + bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU); + + bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, + __APP_PLL_312_LOGIC_SOFT_RESET); + bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, + __APP_PLL_312_BYPASS | + __APP_PLL_312_LOGIC_SOFT_RESET); + bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, + __APP_PLL_425_LOGIC_SOFT_RESET); + bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, + __APP_PLL_425_BYPASS | + __APP_PLL_425_LOGIC_SOFT_RESET); + bfa_os_udelay(2); + bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, + __APP_PLL_312_LOGIC_SOFT_RESET); + bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, + __APP_PLL_425_LOGIC_SOFT_RESET); + + bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, + pll_sclk | __APP_PLL_312_LOGIC_SOFT_RESET); + bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, + pll_fclk | __APP_PLL_425_LOGIC_SOFT_RESET); + + /** + * Wait for PLLs to lock. + */ + bfa_os_udelay(2000); + bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU); + bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU); + + bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk); + bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk); + + bfa_reg_write((rb + MBIST_CTL_REG), __EDRAM_BISTR_START); + bfa_os_udelay(1000); + r32 = bfa_reg_read((rb + MBIST_STAT_REG)); + bfa_trc(ioc, r32); + /* + * release semaphore. + */ + bfa_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg); + + return BFA_STATUS_OK; +} + +/** + * Cleanup hw semaphore and usecnt registers + */ +static void +bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc) +{ + + if (ioc->cna) { + bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg); + bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, 0); + bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); + } + + /* + * Read the hw sem reg to make sure that it is locked + * before we clear it. If it is not locked, writing 1 + * will lock it instead of clearing it. + */ + bfa_reg_read(ioc->ioc_regs.ioc_sem_reg); + bfa_ioc_hw_sem_release(ioc); +} diff --git a/drivers/scsi/bfa/include/bfa.h b/drivers/scsi/bfa/include/bfa.h index d4bc0d9..942ae64 100644 --- a/drivers/scsi/bfa/include/bfa.h +++ b/drivers/scsi/bfa/include/bfa.h @@ -161,6 +161,7 @@ bfa_status_t bfa_iocfc_israttr_set(struct bfa_s *bfa, void bfa_iocfc_enable(struct bfa_s *bfa); void bfa_iocfc_disable(struct bfa_s *bfa); void bfa_ioc_auto_recover(bfa_boolean_t auto_recover); +void bfa_chip_reset(struct bfa_s *bfa); void bfa_cb_ioc_disable(void *bfad); void bfa_timer_tick(struct bfa_s *bfa); #define bfa_timer_start(_bfa, _timer, _timercb, _arg, _timeout) \ diff --git a/drivers/scsi/bfa/include/bfa_timer.h b/drivers/scsi/bfa/include/bfa_timer.h index e407103..f710874 100644 --- a/drivers/scsi/bfa/include/bfa_timer.h +++ b/drivers/scsi/bfa/include/bfa_timer.h @@ -41,7 +41,7 @@ struct bfa_timer_mod_s { struct list_head timer_q; }; -#define BFA_TIMER_FREQ 500 /**< specified in millisecs */ +#define BFA_TIMER_FREQ 200 /**< specified in millisecs */ void bfa_timer_beat(struct bfa_timer_mod_s *mod); void bfa_timer_init(struct bfa_timer_mod_s *mod); diff --git a/drivers/scsi/bfa/include/bfi/bfi_cbreg.h b/drivers/scsi/bfa/include/bfi/bfi_cbreg.h index b3bb52b..781cefa 100644 --- a/drivers/scsi/bfa/include/bfi/bfi_cbreg.h +++ b/drivers/scsi/bfa/include/bfi/bfi_cbreg.h @@ -177,7 +177,8 @@ #define __PSS_LMEM_INIT_EN 0x00000100 #define __PSS_LPU1_RESET 0x00000002 #define __PSS_LPU0_RESET 0x00000001 - +#define ERR_SET_REG 0x00018818 +#define __PSS_ERR_STATUS_SET 0x00000fff /* * These definitions are either in error/missing in spec. Its auto-generated diff --git a/drivers/scsi/bfa/include/bfi/bfi_ctreg.h b/drivers/scsi/bfa/include/bfi/bfi_ctreg.h index dd2992c..d84ebae 100644 --- a/drivers/scsi/bfa/include/bfi/bfi_ctreg.h +++ b/drivers/scsi/bfa/include/bfi/bfi_ctreg.h @@ -430,6 +430,8 @@ enum { #define __PSS_LMEM_INIT_EN 0x00000100 #define __PSS_LPU1_RESET 0x00000002 #define __PSS_LPU0_RESET 0x00000001 +#define ERR_SET_REG 0x00018818 +#define __PSS_ERR_STATUS_SET 0x003fffff #define HQM_QSET0_RXQ_DRBL_P0 0x00038000 #define __RXQ0_ADD_VECTORS_P 0x80000000 #define __RXQ0_STOP_P 0x40000000 diff --git a/drivers/scsi/bfa/include/bfi/bfi_ioc.h b/drivers/scsi/bfa/include/bfi/bfi_ioc.h index 96ef056..a0158aa 100644 --- a/drivers/scsi/bfa/include/bfi/bfi_ioc.h +++ b/drivers/scsi/bfa/include/bfi/bfi_ioc.h @@ -123,7 +123,7 @@ enum bfi_ioc_state { BFI_IOC_DISABLING = 5, /* IOC is being disabled */ BFI_IOC_DISABLED = 6, /* IOC is disabled */ BFI_IOC_CFG_DISABLED = 7, /* IOC is being disabled;transient */ - BFI_IOC_HBFAIL = 8, /* IOC heart-beat failure */ + BFI_IOC_FAIL = 8, /* IOC heart-beat failure */ BFI_IOC_MEMTEST = 9, /* IOC is doing memtest */ }; diff --git a/drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h b/drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h index 43ba706..a75a1f3 100644 --- a/drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h +++ b/drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h @@ -31,6 +31,10 @@ enum { BFA_TRC_CNA_CEE = 1, BFA_TRC_CNA_PORT = 2, + BFA_TRC_CNA_IOC = 3, + BFA_TRC_CNA_DIAG = 4, + BFA_TRC_CNA_IOC_CB = 5, + BFA_TRC_CNA_IOC_CT = 6, }; #endif /* __BFA_CNA_TRCMOD_H__ */ -- cgit v0.10.2 From 8b651b4294e67789028982d18779a9ebe75c2b8a Mon Sep 17 00:00:00 2001 From: Krishna Gudipati Date: Fri, 5 Mar 2010 19:34:44 -0800 Subject: [SCSI] bfa: Clear LL_HALT and PSS_ERR bit when IOC crashes. Clear LL_HALT and PSS_ERR bit in the interrupt status register on an IOC crash. Signed-off-by: Krishna Gudipati Signed-off-by: James Bottomley diff --git a/drivers/scsi/bfa/bfa_intr.c b/drivers/scsi/bfa/bfa_intr.c index ab463db..c422546 100644 --- a/drivers/scsi/bfa/bfa_intr.c +++ b/drivers/scsi/bfa/bfa_intr.c @@ -197,17 +197,44 @@ bfa_msix_rspq(struct bfa_s *bfa, int rsp_qid) void bfa_msix_lpu_err(struct bfa_s *bfa, int vec) { - u32 intr; + u32 intr, curr_value; intr = bfa_reg_read(bfa->iocfc.bfa_regs.intr_status); if (intr & (__HFN_INT_MBOX_LPU0 | __HFN_INT_MBOX_LPU1)) bfa_msix_lpu(bfa); - if (intr & (__HFN_INT_ERR_EMC | - __HFN_INT_ERR_LPU0 | __HFN_INT_ERR_LPU1 | - __HFN_INT_ERR_PSS | __HFN_INT_LL_HALT)) + intr &= (__HFN_INT_ERR_EMC | __HFN_INT_ERR_LPU0 | + __HFN_INT_ERR_LPU1 | __HFN_INT_ERR_PSS | __HFN_INT_LL_HALT); + + if (intr) { + if (intr & __HFN_INT_LL_HALT) { + /** + * If LL_HALT bit is set then FW Init Halt LL Port + * Register needs to be cleared as well so Interrupt + * Status Register will be cleared. + */ + curr_value = bfa_reg_read(bfa->ioc.ioc_regs.ll_halt); + curr_value &= ~__FW_INIT_HALT_P; + bfa_reg_write(bfa->ioc.ioc_regs.ll_halt, curr_value); + } + + if (intr & __HFN_INT_ERR_PSS) { + /** + * ERR_PSS bit needs to be cleared as well in case + * interrups are shared so driver's interrupt handler is + * still called eventhough it is already masked out. + */ + curr_value = bfa_reg_read( + bfa->ioc.ioc_regs.pss_err_status_reg); + curr_value &= __PSS_ERR_STATUS_SET; + bfa_reg_write(bfa->ioc.ioc_regs.pss_err_status_reg, + curr_value); + } + + bfa_reg_write(bfa->iocfc.bfa_regs.intr_status, intr); bfa_msix_errint(bfa, intr); + } } void diff --git a/drivers/scsi/bfa/bfa_ioc.h b/drivers/scsi/bfa/bfa_ioc.h index 1633a50..853cc31 100644 --- a/drivers/scsi/bfa/bfa_ioc.h +++ b/drivers/scsi/bfa/bfa_ioc.h @@ -74,6 +74,7 @@ struct bfa_ioc_regs_s { bfa_os_addr_t lpu_mbox_cmd; bfa_os_addr_t lpu_mbox; bfa_os_addr_t pss_ctl_reg; + bfa_os_addr_t pss_err_status_reg; bfa_os_addr_t app_pll_fast_ctl_reg; bfa_os_addr_t app_pll_slow_ctl_reg; bfa_os_addr_t ioc_sem_reg; diff --git a/drivers/scsi/bfa/bfa_ioc_cb.c b/drivers/scsi/bfa/bfa_ioc_cb.c index d1d625b..1fa052e 100644 --- a/drivers/scsi/bfa/bfa_ioc_cb.c +++ b/drivers/scsi/bfa/bfa_ioc_cb.c @@ -145,6 +145,7 @@ bfa_ioc_cb_reg_init(struct bfa_ioc_s *ioc) * PSS control registers */ ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG); + ioc->ioc_regs.pss_err_status_reg = (rb + PSS_ERR_STATUS_REG); ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_400_CTL_REG); ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_212_CTL_REG); diff --git a/drivers/scsi/bfa/bfa_ioc_ct.c b/drivers/scsi/bfa/bfa_ioc_ct.c index 5de9c24..0430edd 100644 --- a/drivers/scsi/bfa/bfa_ioc_ct.c +++ b/drivers/scsi/bfa/bfa_ioc_ct.c @@ -237,6 +237,7 @@ bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc) * PSS control registers */ ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG); + ioc->ioc_regs.pss_err_status_reg = (rb + PSS_ERR_STATUS_REG); ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_425_CTL_REG); ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_312_CTL_REG); diff --git a/drivers/scsi/bfa/include/bfi/bfi_cbreg.h b/drivers/scsi/bfa/include/bfi/bfi_cbreg.h index 781cefa..a51ee61 100644 --- a/drivers/scsi/bfa/include/bfi/bfi_cbreg.h +++ b/drivers/scsi/bfa/include/bfi/bfi_cbreg.h @@ -177,6 +177,19 @@ #define __PSS_LMEM_INIT_EN 0x00000100 #define __PSS_LPU1_RESET 0x00000002 #define __PSS_LPU0_RESET 0x00000001 +#define PSS_ERR_STATUS_REG 0x00018810 +#define __PSS_LMEM1_CORR_ERR 0x00000800 +#define __PSS_LMEM0_CORR_ERR 0x00000400 +#define __PSS_LMEM1_UNCORR_ERR 0x00000200 +#define __PSS_LMEM0_UNCORR_ERR 0x00000100 +#define __PSS_BAL_PERR 0x00000080 +#define __PSS_DIP_IF_ERR 0x00000040 +#define __PSS_IOH_IF_ERR 0x00000020 +#define __PSS_TDS_IF_ERR 0x00000010 +#define __PSS_RDS_IF_ERR 0x00000008 +#define __PSS_SGM_IF_ERR 0x00000004 +#define __PSS_LPU1_RAM_ERR 0x00000002 +#define __PSS_LPU0_RAM_ERR 0x00000001 #define ERR_SET_REG 0x00018818 #define __PSS_ERR_STATUS_SET 0x00000fff diff --git a/drivers/scsi/bfa/include/bfi/bfi_ctreg.h b/drivers/scsi/bfa/include/bfi/bfi_ctreg.h index d84ebae..57a8497 100644 --- a/drivers/scsi/bfa/include/bfi/bfi_ctreg.h +++ b/drivers/scsi/bfa/include/bfi/bfi_ctreg.h @@ -430,6 +430,29 @@ enum { #define __PSS_LMEM_INIT_EN 0x00000100 #define __PSS_LPU1_RESET 0x00000002 #define __PSS_LPU0_RESET 0x00000001 +#define PSS_ERR_STATUS_REG 0x00018810 +#define __PSS_LPU1_TCM_READ_ERR 0x00200000 +#define __PSS_LPU0_TCM_READ_ERR 0x00100000 +#define __PSS_LMEM5_CORR_ERR 0x00080000 +#define __PSS_LMEM4_CORR_ERR 0x00040000 +#define __PSS_LMEM3_CORR_ERR 0x00020000 +#define __PSS_LMEM2_CORR_ERR 0x00010000 +#define __PSS_LMEM1_CORR_ERR 0x00008000 +#define __PSS_LMEM0_CORR_ERR 0x00004000 +#define __PSS_LMEM5_UNCORR_ERR 0x00002000 +#define __PSS_LMEM4_UNCORR_ERR 0x00001000 +#define __PSS_LMEM3_UNCORR_ERR 0x00000800 +#define __PSS_LMEM2_UNCORR_ERR 0x00000400 +#define __PSS_LMEM1_UNCORR_ERR 0x00000200 +#define __PSS_LMEM0_UNCORR_ERR 0x00000100 +#define __PSS_BAL_PERR 0x00000080 +#define __PSS_DIP_IF_ERR 0x00000040 +#define __PSS_IOH_IF_ERR 0x00000020 +#define __PSS_TDS_IF_ERR 0x00000010 +#define __PSS_RDS_IF_ERR 0x00000008 +#define __PSS_SGM_IF_ERR 0x00000004 +#define __PSS_LPU1_RAM_ERR 0x00000002 +#define __PSS_LPU0_RAM_ERR 0x00000001 #define ERR_SET_REG 0x00018818 #define __PSS_ERR_STATUS_SET 0x003fffff #define HQM_QSET0_RXQ_DRBL_P0 0x00038000 -- cgit v0.10.2 From e641de37e67953fa9ecad72608942481a5d66a1d Mon Sep 17 00:00:00 2001 From: Krishna Gudipati Date: Fri, 5 Mar 2010 19:35:02 -0800 Subject: [SCSI] bfa: Replace bfa_assert() with bfa_sm_fault() Replace bfa_assert() with bfa_sm_fault() to get unhandled events for debugging. Signed-off-by: Krishna Gudipati Signed-off-by: James Bottomley diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c index 3d62e45..960ae1a 100644 --- a/drivers/scsi/bfa/bfa_fcs_lport.c +++ b/drivers/scsi/bfa/bfa_fcs_lport.c @@ -114,7 +114,7 @@ bfa_fcs_port_sm_uninit(struct bfa_fcs_port_s *port, break; default: - bfa_assert(0); + bfa_sm_fault(port->fcs, event); } } @@ -136,7 +136,7 @@ bfa_fcs_port_sm_init(struct bfa_fcs_port_s *port, enum bfa_fcs_port_event event) break; default: - bfa_assert(0); + bfa_sm_fault(port->fcs, event); } } @@ -176,7 +176,7 @@ bfa_fcs_port_sm_online(struct bfa_fcs_port_s *port, break; default: - bfa_assert(0); + bfa_sm_fault(port->fcs, event); } } @@ -214,7 +214,7 @@ bfa_fcs_port_sm_offline(struct bfa_fcs_port_s *port, break; default: - bfa_assert(0); + bfa_sm_fault(port->fcs, event); } } @@ -234,7 +234,7 @@ bfa_fcs_port_sm_deleting(struct bfa_fcs_port_s *port, break; default: - bfa_assert(0); + bfa_sm_fault(port->fcs, event); } } diff --git a/drivers/scsi/bfa/bfa_ioim.c b/drivers/scsi/bfa/bfa_ioim.c index f81d359..5b107ab 100644 --- a/drivers/scsi/bfa/bfa_ioim.c +++ b/drivers/scsi/bfa/bfa_ioim.c @@ -149,7 +149,7 @@ bfa_ioim_sm_uninit(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) break; default: - bfa_assert(0); + bfa_sm_fault(ioim->bfa, event); } } @@ -194,7 +194,7 @@ bfa_ioim_sm_sgalloc(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) break; default: - bfa_assert(0); + bfa_sm_fault(ioim->bfa, event); } } @@ -259,7 +259,7 @@ bfa_ioim_sm_active(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) break; default: - bfa_assert(0); + bfa_sm_fault(ioim->bfa, event); } } @@ -317,7 +317,7 @@ bfa_ioim_sm_abort(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) break; default: - bfa_assert(0); + bfa_sm_fault(ioim->bfa, event); } } @@ -377,7 +377,7 @@ bfa_ioim_sm_cleanup(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) break; default: - bfa_assert(0); + bfa_sm_fault(ioim->bfa, event); } } @@ -419,7 +419,7 @@ bfa_ioim_sm_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) break; default: - bfa_assert(0); + bfa_sm_fault(ioim->bfa, event); } } @@ -467,7 +467,7 @@ bfa_ioim_sm_abort_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) break; default: - bfa_assert(0); + bfa_sm_fault(ioim->bfa, event); } } @@ -516,7 +516,7 @@ bfa_ioim_sm_cleanup_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) break; default: - bfa_assert(0); + bfa_sm_fault(ioim->bfa, event); } } @@ -544,7 +544,7 @@ bfa_ioim_sm_hcb(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) break; default: - bfa_assert(0); + bfa_sm_fault(ioim->bfa, event); } } @@ -577,7 +577,7 @@ bfa_ioim_sm_hcb_free(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) break; default: - bfa_assert(0); + bfa_sm_fault(ioim->bfa, event); } } @@ -605,7 +605,7 @@ bfa_ioim_sm_resfree(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) break; default: - bfa_assert(0); + bfa_sm_fault(ioim->bfa, event); } } diff --git a/drivers/scsi/bfa/bfa_itnim.c b/drivers/scsi/bfa/bfa_itnim.c index eabf7d3..a914ff2 100644 --- a/drivers/scsi/bfa/bfa_itnim.c +++ b/drivers/scsi/bfa/bfa_itnim.c @@ -144,7 +144,7 @@ bfa_itnim_sm_uninit(struct bfa_itnim_s *itnim, enum bfa_itnim_event event) break; default: - bfa_assert(0); + bfa_sm_fault(itnim->bfa, event); } } @@ -175,7 +175,7 @@ bfa_itnim_sm_created(struct bfa_itnim_s *itnim, enum bfa_itnim_event event) break; default: - bfa_assert(0); + bfa_sm_fault(itnim->bfa, event); } } @@ -212,7 +212,7 @@ bfa_itnim_sm_fwcreate(struct bfa_itnim_s *itnim, enum bfa_itnim_event event) break; default: - bfa_assert(0); + bfa_sm_fault(itnim->bfa, event); } } @@ -247,7 +247,7 @@ bfa_itnim_sm_fwcreate_qfull(struct bfa_itnim_s *itnim, break; default: - bfa_assert(0); + bfa_sm_fault(itnim->bfa, event); } } @@ -275,7 +275,7 @@ bfa_itnim_sm_delete_pending(struct bfa_itnim_s *itnim, break; default: - bfa_assert(0); + bfa_sm_fault(itnim->bfa, event); } } @@ -317,7 +317,7 @@ bfa_itnim_sm_online(struct bfa_itnim_s *itnim, enum bfa_itnim_event event) break; default: - bfa_assert(0); + bfa_sm_fault(itnim->bfa, event); } } @@ -348,7 +348,7 @@ bfa_itnim_sm_sler(struct bfa_itnim_s *itnim, enum bfa_itnim_event event) break; default: - bfa_assert(0); + bfa_sm_fault(itnim->bfa, event); } } @@ -385,7 +385,7 @@ bfa_itnim_sm_cleanup_offline(struct bfa_itnim_s *itnim, break; default: - bfa_assert(0); + bfa_sm_fault(itnim->bfa, event); } } @@ -413,7 +413,7 @@ bfa_itnim_sm_cleanup_delete(struct bfa_itnim_s *itnim, break; default: - bfa_assert(0); + bfa_sm_fault(itnim->bfa, event); } } @@ -442,7 +442,7 @@ bfa_itnim_sm_fwdelete(struct bfa_itnim_s *itnim, enum bfa_itnim_event event) break; default: - bfa_assert(0); + bfa_sm_fault(itnim->bfa, event); } } @@ -470,7 +470,7 @@ bfa_itnim_sm_fwdelete_qfull(struct bfa_itnim_s *itnim, break; default: - bfa_assert(0); + bfa_sm_fault(itnim->bfa, event); } } @@ -502,7 +502,7 @@ bfa_itnim_sm_offline(struct bfa_itnim_s *itnim, enum bfa_itnim_event event) break; default: - bfa_assert(0); + bfa_sm_fault(itnim->bfa, event); } } @@ -538,7 +538,7 @@ bfa_itnim_sm_iocdisable(struct bfa_itnim_s *itnim, break; default: - bfa_assert(0); + bfa_sm_fault(itnim->bfa, event); } } @@ -559,7 +559,7 @@ bfa_itnim_sm_deleting(struct bfa_itnim_s *itnim, enum bfa_itnim_event event) break; default: - bfa_assert(0); + bfa_sm_fault(itnim->bfa, event); } } @@ -583,7 +583,7 @@ bfa_itnim_sm_deleting_qfull(struct bfa_itnim_s *itnim, break; default: - bfa_assert(0); + bfa_sm_fault(itnim->bfa, event); } } diff --git a/drivers/scsi/bfa/bfa_lps.c b/drivers/scsi/bfa/bfa_lps.c index 66b9b15..4c98bda 100644 --- a/drivers/scsi/bfa/bfa_lps.c +++ b/drivers/scsi/bfa/bfa_lps.c @@ -121,7 +121,7 @@ bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event) break; default: - bfa_assert(0); + bfa_sm_fault(lps->bfa, event); } } @@ -148,7 +148,7 @@ bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event) break; default: - bfa_assert(0); + bfa_sm_fault(lps->bfa, event); } } @@ -180,7 +180,7 @@ bfa_lps_sm_loginwait(struct bfa_lps_s *lps, enum bfa_lps_event event) break; default: - bfa_assert(0); + bfa_sm_fault(lps->bfa, event); } } @@ -219,7 +219,7 @@ bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event) break; default: - bfa_assert(0); + bfa_sm_fault(lps->bfa, event); } } @@ -243,7 +243,7 @@ bfa_lps_sm_logout(struct bfa_lps_s *lps, enum bfa_lps_event event) break; default: - bfa_assert(0); + bfa_sm_fault(lps->bfa, event); } } @@ -268,7 +268,7 @@ bfa_lps_sm_logowait(struct bfa_lps_s *lps, enum bfa_lps_event event) break; default: - bfa_assert(0); + bfa_sm_fault(lps->bfa, event); } } diff --git a/drivers/scsi/bfa/bfa_rport.c b/drivers/scsi/bfa/bfa_rport.c index 3e1990a..7c509fa 100644 --- a/drivers/scsi/bfa/bfa_rport.c +++ b/drivers/scsi/bfa/bfa_rport.c @@ -114,7 +114,7 @@ bfa_rport_sm_uninit(struct bfa_rport_s *rp, enum bfa_rport_event event) default: bfa_stats(rp, sm_un_unexp); - bfa_assert(0); + bfa_sm_fault(rp->bfa, event); } } @@ -146,7 +146,7 @@ bfa_rport_sm_created(struct bfa_rport_s *rp, enum bfa_rport_event event) default: bfa_stats(rp, sm_cr_unexp); - bfa_assert(0); + bfa_sm_fault(rp->bfa, event); } } @@ -183,7 +183,7 @@ bfa_rport_sm_fwcreate(struct bfa_rport_s *rp, enum bfa_rport_event event) default: bfa_stats(rp, sm_fwc_unexp); - bfa_assert(0); + bfa_sm_fault(rp->bfa, event); } } @@ -224,7 +224,7 @@ bfa_rport_sm_fwcreate_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event) default: bfa_stats(rp, sm_fwc_unexp); - bfa_assert(0); + bfa_sm_fault(rp->bfa, event); } } @@ -296,7 +296,7 @@ bfa_rport_sm_online(struct bfa_rport_s *rp, enum bfa_rport_event event) default: bfa_stats(rp, sm_on_unexp); - bfa_assert(0); + bfa_sm_fault(rp->bfa, event); } } @@ -329,7 +329,7 @@ bfa_rport_sm_fwdelete(struct bfa_rport_s *rp, enum bfa_rport_event event) default: bfa_stats(rp, sm_fwd_unexp); - bfa_assert(0); + bfa_sm_fault(rp->bfa, event); } } @@ -359,7 +359,7 @@ bfa_rport_sm_fwdelete_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event) default: bfa_stats(rp, sm_fwd_unexp); - bfa_assert(0); + bfa_sm_fault(rp->bfa, event); } } @@ -394,7 +394,7 @@ bfa_rport_sm_offline(struct bfa_rport_s *rp, enum bfa_rport_event event) default: bfa_stats(rp, sm_off_unexp); - bfa_assert(0); + bfa_sm_fault(rp->bfa, event); } } @@ -421,7 +421,7 @@ bfa_rport_sm_deleting(struct bfa_rport_s *rp, enum bfa_rport_event event) break; default: - bfa_assert(0); + bfa_sm_fault(rp->bfa, event); } } @@ -446,7 +446,7 @@ bfa_rport_sm_deleting_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event) break; default: - bfa_assert(0); + bfa_sm_fault(rp->bfa, event); } } @@ -477,7 +477,7 @@ bfa_rport_sm_delete_pending(struct bfa_rport_s *rp, default: bfa_stats(rp, sm_delp_unexp); - bfa_assert(0); + bfa_sm_fault(rp->bfa, event); } } @@ -512,7 +512,7 @@ bfa_rport_sm_offline_pending(struct bfa_rport_s *rp, default: bfa_stats(rp, sm_offp_unexp); - bfa_assert(0); + bfa_sm_fault(rp->bfa, event); } } @@ -550,7 +550,7 @@ bfa_rport_sm_iocdisable(struct bfa_rport_s *rp, enum bfa_rport_event event) default: bfa_stats(rp, sm_iocd_unexp); - bfa_assert(0); + bfa_sm_fault(rp->bfa, event); } } diff --git a/drivers/scsi/bfa/bfa_tskim.c b/drivers/scsi/bfa/bfa_tskim.c index ff7a4dc..ad9aaae 100644 --- a/drivers/scsi/bfa/bfa_tskim.c +++ b/drivers/scsi/bfa/bfa_tskim.c @@ -110,7 +110,7 @@ bfa_tskim_sm_uninit(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) break; default: - bfa_assert(0); + bfa_sm_fault(tskim->bfa, event); } } @@ -146,7 +146,7 @@ bfa_tskim_sm_active(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) break; default: - bfa_assert(0); + bfa_sm_fault(tskim->bfa, event); } } @@ -178,7 +178,7 @@ bfa_tskim_sm_cleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) break; default: - bfa_assert(0); + bfa_sm_fault(tskim->bfa, event); } } @@ -207,7 +207,7 @@ bfa_tskim_sm_iocleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) break; default: - bfa_assert(0); + bfa_sm_fault(tskim->bfa, event); } } @@ -242,7 +242,7 @@ bfa_tskim_sm_qfull(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) break; default: - bfa_assert(0); + bfa_sm_fault(tskim->bfa, event); } } @@ -277,7 +277,7 @@ bfa_tskim_sm_cleanup_qfull(struct bfa_tskim_s *tskim, break; default: - bfa_assert(0); + bfa_sm_fault(tskim->bfa, event); } } @@ -303,7 +303,7 @@ bfa_tskim_sm_hcb(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) break; default: - bfa_assert(0); + bfa_sm_fault(tskim->bfa, event); } } diff --git a/drivers/scsi/bfa/fcpim.c b/drivers/scsi/bfa/fcpim.c index 06f8a46..71d23d1 100644 --- a/drivers/scsi/bfa/fcpim.c +++ b/drivers/scsi/bfa/fcpim.c @@ -126,7 +126,7 @@ bfa_fcs_itnim_sm_offline(struct bfa_fcs_itnim_s *itnim, break; default: - bfa_assert(0); + bfa_sm_fault(itnim->fcs, event); } } @@ -161,7 +161,7 @@ bfa_fcs_itnim_sm_prli_send(struct bfa_fcs_itnim_s *itnim, break; default: - bfa_assert(0); + bfa_sm_fault(itnim->fcs, event); } } @@ -205,7 +205,7 @@ bfa_fcs_itnim_sm_prli(struct bfa_fcs_itnim_s *itnim, break; default: - bfa_assert(0); + bfa_sm_fault(itnim->fcs, event); } } @@ -240,7 +240,7 @@ bfa_fcs_itnim_sm_prli_retry(struct bfa_fcs_itnim_s *itnim, break; default: - bfa_assert(0); + bfa_sm_fault(itnim->fcs, event); } } @@ -270,7 +270,7 @@ bfa_fcs_itnim_sm_hcb_online(struct bfa_fcs_itnim_s *itnim, break; default: - bfa_assert(0); + bfa_sm_fault(itnim->fcs, event); } } @@ -298,7 +298,7 @@ bfa_fcs_itnim_sm_online(struct bfa_fcs_itnim_s *itnim, break; default: - bfa_assert(0); + bfa_sm_fault(itnim->fcs, event); } } @@ -321,7 +321,7 @@ bfa_fcs_itnim_sm_hcb_offline(struct bfa_fcs_itnim_s *itnim, break; default: - bfa_assert(0); + bfa_sm_fault(itnim->fcs, event); } } @@ -354,7 +354,7 @@ bfa_fcs_itnim_sm_initiator(struct bfa_fcs_itnim_s *itnim, break; default: - bfa_assert(0); + bfa_sm_fault(itnim->fcs, event); } } diff --git a/drivers/scsi/bfa/fdmi.c b/drivers/scsi/bfa/fdmi.c index d76d922..e812086 100644 --- a/drivers/scsi/bfa/fdmi.c +++ b/drivers/scsi/bfa/fdmi.c @@ -158,7 +158,7 @@ bfa_fcs_port_fdmi_sm_offline(struct bfa_fcs_port_fdmi_s *fdmi, break; default: - bfa_assert(0); + bfa_sm_fault(port->fcs, event); } } @@ -183,7 +183,7 @@ bfa_fcs_port_fdmi_sm_sending_rhba(struct bfa_fcs_port_fdmi_s *fdmi, break; default: - bfa_assert(0); + bfa_sm_fault(port->fcs, event); } } @@ -230,7 +230,7 @@ bfa_fcs_port_fdmi_sm_rhba(struct bfa_fcs_port_fdmi_s *fdmi, break; default: - bfa_assert(0); + bfa_sm_fault(port->fcs, event); } } @@ -258,7 +258,7 @@ bfa_fcs_port_fdmi_sm_rhba_retry(struct bfa_fcs_port_fdmi_s *fdmi, break; default: - bfa_assert(0); + bfa_sm_fault(port->fcs, event); } } @@ -286,7 +286,7 @@ bfa_fcs_port_fdmi_sm_sending_rprt(struct bfa_fcs_port_fdmi_s *fdmi, break; default: - bfa_assert(0); + bfa_sm_fault(port->fcs, event); } } @@ -331,7 +331,7 @@ bfa_fcs_port_fdmi_sm_rprt(struct bfa_fcs_port_fdmi_s *fdmi, break; default: - bfa_assert(0); + bfa_sm_fault(port->fcs, event); } } @@ -359,7 +359,7 @@ bfa_fcs_port_fdmi_sm_rprt_retry(struct bfa_fcs_port_fdmi_s *fdmi, break; default: - bfa_assert(0); + bfa_sm_fault(port->fcs, event); } } @@ -387,7 +387,7 @@ bfa_fcs_port_fdmi_sm_sending_rpa(struct bfa_fcs_port_fdmi_s *fdmi, break; default: - bfa_assert(0); + bfa_sm_fault(port->fcs, event); } } @@ -431,7 +431,7 @@ bfa_fcs_port_fdmi_sm_rpa(struct bfa_fcs_port_fdmi_s *fdmi, break; default: - bfa_assert(0); + bfa_sm_fault(port->fcs, event); } } @@ -459,7 +459,7 @@ bfa_fcs_port_fdmi_sm_rpa_retry(struct bfa_fcs_port_fdmi_s *fdmi, break; default: - bfa_assert(0); + bfa_sm_fault(port->fcs, event); } } @@ -478,7 +478,7 @@ bfa_fcs_port_fdmi_sm_online(struct bfa_fcs_port_fdmi_s *fdmi, break; default: - bfa_assert(0); + bfa_sm_fault(port->fcs, event); } } diff --git a/drivers/scsi/bfa/ms.c b/drivers/scsi/bfa/ms.c index c96b3ca..f0275a4 100644 --- a/drivers/scsi/bfa/ms.c +++ b/drivers/scsi/bfa/ms.c @@ -118,7 +118,7 @@ bfa_fcs_port_ms_sm_offline(struct bfa_fcs_port_ms_s *ms, break; default: - bfa_assert(0); + bfa_sm_fault(ms->port->fcs, event); } } @@ -141,7 +141,7 @@ bfa_fcs_port_ms_sm_plogi_sending(struct bfa_fcs_port_ms_s *ms, break; default: - bfa_assert(0); + bfa_sm_fault(ms->port->fcs, event); } } @@ -190,7 +190,7 @@ bfa_fcs_port_ms_sm_plogi(struct bfa_fcs_port_ms_s *ms, enum port_ms_event event) break; default: - bfa_assert(0); + bfa_sm_fault(ms->port->fcs, event); } } @@ -216,7 +216,7 @@ bfa_fcs_port_ms_sm_plogi_retry(struct bfa_fcs_port_ms_s *ms, break; default: - bfa_assert(0); + bfa_sm_fault(ms->port->fcs, event); } } @@ -243,7 +243,7 @@ bfa_fcs_port_ms_sm_online(struct bfa_fcs_port_ms_s *ms, break; default: - bfa_assert(0); + bfa_sm_fault(ms->port->fcs, event); } } @@ -266,7 +266,7 @@ bfa_fcs_port_ms_sm_gmal_sending(struct bfa_fcs_port_ms_s *ms, break; default: - bfa_assert(0); + bfa_sm_fault(ms->port->fcs, event); } } @@ -304,7 +304,7 @@ bfa_fcs_port_ms_sm_gmal(struct bfa_fcs_port_ms_s *ms, enum port_ms_event event) break; default: - bfa_assert(0); + bfa_sm_fault(ms->port->fcs, event); } } @@ -330,7 +330,7 @@ bfa_fcs_port_ms_sm_gmal_retry(struct bfa_fcs_port_ms_s *ms, break; default: - bfa_assert(0); + bfa_sm_fault(ms->port->fcs, event); } } @@ -466,7 +466,7 @@ bfa_fcs_port_ms_sm_gfn_sending(struct bfa_fcs_port_ms_s *ms, break; default: - bfa_assert(0); + bfa_sm_fault(ms->port->fcs, event); } } @@ -502,7 +502,7 @@ bfa_fcs_port_ms_sm_gfn(struct bfa_fcs_port_ms_s *ms, enum port_ms_event event) break; default: - bfa_assert(0); + bfa_sm_fault(ms->port->fcs, event); } } @@ -528,7 +528,7 @@ bfa_fcs_port_ms_sm_gfn_retry(struct bfa_fcs_port_ms_s *ms, break; default: - bfa_assert(0); + bfa_sm_fault(ms->port->fcs, event); } } diff --git a/drivers/scsi/bfa/ns.c b/drivers/scsi/bfa/ns.c index 2f8b880..6de06a5 100644 --- a/drivers/scsi/bfa/ns.c +++ b/drivers/scsi/bfa/ns.c @@ -164,7 +164,7 @@ bfa_fcs_port_ns_sm_offline(struct bfa_fcs_port_ns_s *ns, break; default: - bfa_assert(0); + bfa_sm_fault(ns->port->fcs, event); } } @@ -187,7 +187,7 @@ bfa_fcs_port_ns_sm_plogi_sending(struct bfa_fcs_port_ns_s *ns, break; default: - bfa_assert(0); + bfa_sm_fault(ns->port->fcs, event); } } @@ -221,7 +221,7 @@ bfa_fcs_port_ns_sm_plogi(struct bfa_fcs_port_ns_s *ns, break; default: - bfa_assert(0); + bfa_sm_fault(ns->port->fcs, event); } } @@ -247,7 +247,7 @@ bfa_fcs_port_ns_sm_plogi_retry(struct bfa_fcs_port_ns_s *ns, break; default: - bfa_assert(0); + bfa_sm_fault(ns->port->fcs, event); } } @@ -270,7 +270,7 @@ bfa_fcs_port_ns_sm_sending_rspn_id(struct bfa_fcs_port_ns_s *ns, break; default: - bfa_assert(0); + bfa_sm_fault(ns->port->fcs, event); } } @@ -304,7 +304,7 @@ bfa_fcs_port_ns_sm_rspn_id(struct bfa_fcs_port_ns_s *ns, break; default: - bfa_assert(0); + bfa_sm_fault(ns->port->fcs, event); } } @@ -330,7 +330,7 @@ bfa_fcs_port_ns_sm_rspn_id_retry(struct bfa_fcs_port_ns_s *ns, break; default: - bfa_assert(0); + bfa_sm_fault(ns->port->fcs, event); } } @@ -353,7 +353,7 @@ bfa_fcs_port_ns_sm_sending_rft_id(struct bfa_fcs_port_ns_s *ns, break; default: - bfa_assert(0); + bfa_sm_fault(ns->port->fcs, event); } } @@ -390,7 +390,7 @@ bfa_fcs_port_ns_sm_rft_id(struct bfa_fcs_port_ns_s *ns, break; default: - bfa_assert(0); + bfa_sm_fault(ns->port->fcs, event); } } @@ -413,7 +413,7 @@ bfa_fcs_port_ns_sm_rft_id_retry(struct bfa_fcs_port_ns_s *ns, break; default: - bfa_assert(0); + bfa_sm_fault(ns->port->fcs, event); } } @@ -436,7 +436,7 @@ bfa_fcs_port_ns_sm_sending_rff_id(struct bfa_fcs_port_ns_s *ns, break; default: - bfa_assert(0); + bfa_sm_fault(ns->port->fcs, event); } } @@ -494,7 +494,7 @@ bfa_fcs_port_ns_sm_rff_id(struct bfa_fcs_port_ns_s *ns, break; default: - bfa_assert(0); + bfa_sm_fault(ns->port->fcs, event); } } @@ -517,7 +517,7 @@ bfa_fcs_port_ns_sm_rff_id_retry(struct bfa_fcs_port_ns_s *ns, break; default: - bfa_assert(0); + bfa_sm_fault(ns->port->fcs, event); } } static void @@ -539,7 +539,7 @@ bfa_fcs_port_ns_sm_sending_gid_ft(struct bfa_fcs_port_ns_s *ns, break; default: - bfa_assert(0); + bfa_sm_fault(ns->port->fcs, event); } } @@ -575,7 +575,7 @@ bfa_fcs_port_ns_sm_gid_ft(struct bfa_fcs_port_ns_s *ns, break; default: - bfa_assert(0); + bfa_sm_fault(ns->port->fcs, event); } } @@ -598,7 +598,7 @@ bfa_fcs_port_ns_sm_gid_ft_retry(struct bfa_fcs_port_ns_s *ns, break; default: - bfa_assert(0); + bfa_sm_fault(ns->port->fcs, event); } } @@ -626,7 +626,7 @@ bfa_fcs_port_ns_sm_online(struct bfa_fcs_port_ns_s *ns, break; default: - bfa_assert(0); + bfa_sm_fault(ns->port->fcs, event); } } diff --git a/drivers/scsi/bfa/rport.c b/drivers/scsi/bfa/rport.c index df714dc..32cf180 100644 --- a/drivers/scsi/bfa/rport.c +++ b/drivers/scsi/bfa/rport.c @@ -224,7 +224,7 @@ bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport, enum rport_event event) break; default: - bfa_assert(0); + bfa_sm_fault(rport->fcs, event); } } @@ -276,7 +276,7 @@ bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s *rport, break; default: - bfa_assert(0); + bfa_sm_fault(rport->fcs, event); } } @@ -332,7 +332,7 @@ bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport, break; default: - bfa_assert(0); + bfa_sm_fault(rport->fcs, event); } } @@ -406,7 +406,7 @@ bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport, break; default: - bfa_assert(0); + bfa_sm_fault(rport->fcs, event); } } @@ -481,7 +481,7 @@ bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, enum rport_event event) break; default: - bfa_assert(0); + bfa_sm_fault(rport->fcs, event); } } @@ -534,7 +534,7 @@ bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport, break; default: - bfa_assert(0); + bfa_sm_fault(rport->fcs, event); } } @@ -589,7 +589,7 @@ bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport, enum rport_event event) break; default: - bfa_assert(0); + bfa_sm_fault(rport->fcs, event); } } @@ -646,7 +646,7 @@ bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport, break; default: - bfa_assert(0); + bfa_sm_fault(rport->fcs, event); } } @@ -704,7 +704,7 @@ bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, enum rport_event event) break; default: - bfa_assert(0); + bfa_sm_fault(rport->fcs, event); } } @@ -754,7 +754,7 @@ bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport, break; default: - bfa_assert(0); + bfa_sm_fault(rport->fcs, event); } } @@ -816,7 +816,7 @@ bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport, enum rport_event event) break; default: - bfa_assert(0); + bfa_sm_fault(rport->fcs, event); } } @@ -846,7 +846,7 @@ bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport, break; default: - bfa_assert(0); + bfa_sm_fault(rport->fcs, event); } } @@ -869,7 +869,7 @@ bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s *rport, break; default: - bfa_assert(0); + bfa_sm_fault(rport->fcs, event); } } @@ -905,7 +905,7 @@ bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport, break; default: - bfa_assert(0); + bfa_sm_fault(rport->fcs, event); } } @@ -951,7 +951,7 @@ bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport, break; default: - bfa_assert(0); + bfa_sm_fault(rport->fcs, event); } } @@ -1011,7 +1011,7 @@ bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport, break; default: - bfa_assert(0); + bfa_sm_fault(rport->fcs, event); } } @@ -1038,7 +1038,7 @@ bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport, break; default: - bfa_assert(0); + bfa_sm_fault(rport->fcs, event); } } @@ -1073,7 +1073,7 @@ bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport, break; default: - bfa_assert(0); + bfa_sm_fault(rport->fcs, event); } } @@ -1132,7 +1132,7 @@ bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport, enum rport_event event) break; default: - bfa_assert(0); + bfa_sm_fault(rport->fcs, event); } } @@ -1188,7 +1188,7 @@ bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport, break; default: - bfa_assert(0); + bfa_sm_fault(rport->fcs, event); } } @@ -1249,7 +1249,7 @@ bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport, break; default: - bfa_assert(0); + bfa_sm_fault(rport->fcs, event); } } @@ -1334,7 +1334,7 @@ bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport, break; default: - bfa_assert(0); + bfa_sm_fault(rport->fcs, event); } } diff --git a/drivers/scsi/bfa/rport_ftrs.c b/drivers/scsi/bfa/rport_ftrs.c index e1932c8..ae7bba6 100644 --- a/drivers/scsi/bfa/rport_ftrs.c +++ b/drivers/scsi/bfa/rport_ftrs.c @@ -91,7 +91,7 @@ bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) break; default: - bfa_assert(0); + bfa_sm_fault(rport->fcs, event); } } @@ -114,7 +114,7 @@ bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) break; default: - bfa_assert(0); + bfa_sm_fault(rport->fcs, event); } } @@ -160,7 +160,7 @@ bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) break; default: - bfa_assert(0); + bfa_sm_fault(rport->fcs, event); } } @@ -186,7 +186,7 @@ bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) break; default: - bfa_assert(0); + bfa_sm_fault(rport->fcs, event); } } @@ -206,7 +206,7 @@ bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) break; default: - bfa_assert(0); + bfa_sm_fault(rport->fcs, event); } } @@ -229,7 +229,7 @@ bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) break; default: - bfa_assert(0); + bfa_sm_fault(rport->fcs, event); } } /** diff --git a/drivers/scsi/bfa/scn.c b/drivers/scsi/bfa/scn.c index bd4771f..8fe09ba 100644 --- a/drivers/scsi/bfa/scn.c +++ b/drivers/scsi/bfa/scn.c @@ -90,7 +90,7 @@ bfa_fcs_port_scn_sm_offline(struct bfa_fcs_port_scn_s *scn, break; default: - bfa_assert(0); + bfa_sm_fault(scn->port->fcs, event); } } @@ -109,7 +109,7 @@ bfa_fcs_port_scn_sm_sending_scr(struct bfa_fcs_port_scn_s *scn, break; default: - bfa_assert(0); + bfa_sm_fault(scn->port->fcs, event); } } @@ -137,7 +137,7 @@ bfa_fcs_port_scn_sm_scr(struct bfa_fcs_port_scn_s *scn, break; default: - bfa_assert(0); + bfa_sm_fault(scn->port->fcs, event); } } @@ -157,7 +157,7 @@ bfa_fcs_port_scn_sm_scr_retry(struct bfa_fcs_port_scn_s *scn, break; default: - bfa_assert(0); + bfa_sm_fault(scn->port->fcs, event); } } @@ -171,7 +171,7 @@ bfa_fcs_port_scn_sm_online(struct bfa_fcs_port_scn_s *scn, break; default: - bfa_assert(0); + bfa_sm_fault(scn->port->fcs, event); } } diff --git a/drivers/scsi/bfa/vport.c b/drivers/scsi/bfa/vport.c index 13f7371..14fb7ac 100644 --- a/drivers/scsi/bfa/vport.c +++ b/drivers/scsi/bfa/vport.c @@ -122,7 +122,7 @@ bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport, break; default: - bfa_assert(0); + bfa_sm_fault(__vport_fcs(vport), event); } } @@ -165,7 +165,7 @@ bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport, break; default: - bfa_assert(0); + bfa_sm_fault(__vport_fcs(vport), event); } } @@ -202,7 +202,7 @@ bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s *vport, break; default: - bfa_assert(0); + bfa_sm_fault(__vport_fcs(vport), event); } } @@ -249,7 +249,7 @@ bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport, break; default: - bfa_assert(0); + bfa_sm_fault(__vport_fcs(vport), event); } } @@ -283,7 +283,7 @@ bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport, break; default: - bfa_assert(0); + bfa_sm_fault(__vport_fcs(vport), event); } } @@ -310,7 +310,7 @@ bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport, break; default: - bfa_assert(0); + bfa_sm_fault(__vport_fcs(vport), event); } } @@ -339,7 +339,7 @@ bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s *vport, break; default: - bfa_assert(0); + bfa_sm_fault(__vport_fcs(vport), event); } } @@ -387,7 +387,7 @@ bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport, break; default: - bfa_assert(0); + bfa_sm_fault(__vport_fcs(vport), event); } } @@ -419,7 +419,7 @@ bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport, break; default: - bfa_assert(0); + bfa_sm_fault(__vport_fcs(vport), event); } } -- cgit v0.10.2 From 72041ed8fc8ed92c11af90949bab7b08f3e34fd3 Mon Sep 17 00:00:00 2001 From: Krishna Gudipati Date: Fri, 5 Mar 2010 19:35:16 -0800 Subject: [SCSI] bfa: RPORT state machine: direct attach mode fix. Make sure that in direct attach mode, we do not query the name server after a target is marked offline. Signed-off-by: Krishna Gudipati Signed-off-by: James Bottomley diff --git a/drivers/scsi/bfa/rport.c b/drivers/scsi/bfa/rport.c index 32cf180..80592e3 100644 --- a/drivers/scsi/bfa/rport.c +++ b/drivers/scsi/bfa/rport.c @@ -925,10 +925,17 @@ bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport, case RPSM_EVENT_HCB_OFFLINE: case RPSM_EVENT_ADDRESS_CHANGE: if (bfa_fcs_port_is_online(rport->port)) { - bfa_sm_set_state(rport, - bfa_fcs_rport_sm_nsdisc_sending); - rport->ns_retries = 0; - bfa_fcs_rport_send_gidpn(rport, NULL); + if (bfa_fcs_fabric_is_switched(rport->port->fabric)) { + bfa_sm_set_state(rport, + bfa_fcs_rport_sm_nsdisc_sending); + rport->ns_retries = 0; + bfa_fcs_rport_send_gidpn(rport, NULL); + } else { + bfa_sm_set_state(rport, + bfa_fcs_rport_sm_plogi_sending); + rport->plogi_retries = 0; + bfa_fcs_rport_send_plogi(rport, NULL); + } } else { rport->pid = 0; bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); -- cgit v0.10.2 From 86e32dabbad0d860b2be3c30a33c10a134d4ccf1 Mon Sep 17 00:00:00 2001 From: Krishna Gudipati Date: Fri, 5 Mar 2010 19:35:33 -0800 Subject: [SCSI] bfa: Fix to copy fpma MAC when requested by user space application. Copy fpma MAC when requested by user space application. Added FPMA mac address to the lport attributes structure. Signed-off-by: Krishna Gudipati Signed-off-by: James Bottomley diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c index 960ae1a..7bb182d 100644 --- a/drivers/scsi/bfa/bfa_fcs_lport.c +++ b/drivers/scsi/bfa/bfa_fcs_lport.c @@ -936,8 +936,13 @@ bfa_fcs_port_get_attr(struct bfa_fcs_port_s *port, bfa_fcs_port_get_fabric_ipaddr(port), BFA_FCS_FABRIC_IPADDR_SZ); - if (port->vport != NULL) + if (port->vport != NULL) { port_attr->port_type = BFA_PPORT_TYPE_VPORT; + port_attr->fpma_mac = + bfa_lps_get_lp_mac(port->vport->lps); + } else + port_attr->fpma_mac = + bfa_lps_get_lp_mac(port->fabric->lps); } else { port_attr->port_type = BFA_PPORT_TYPE_UNKNOWN; diff --git a/drivers/scsi/bfa/bfa_lps.c b/drivers/scsi/bfa/bfa_lps.c index 4c98bda..730616f 100644 --- a/drivers/scsi/bfa/bfa_lps.c +++ b/drivers/scsi/bfa/bfa_lps.c @@ -613,9 +613,9 @@ bfa_lps_get_max_vport(struct bfa_s *bfa) bfa_get_attr(bfa, &ioc_attr); if (ioc_attr.pci_attr.device_id == BFA_PCI_DEVICE_ID_CT) - return (BFA_LPS_MAX_VPORTS_SUPP_CT); + return BFA_LPS_MAX_VPORTS_SUPP_CT; else - return (BFA_LPS_MAX_VPORTS_SUPP_CB); + return BFA_LPS_MAX_VPORTS_SUPP_CB; } /** @@ -837,6 +837,14 @@ bfa_lps_get_lsrjt_expl(struct bfa_lps_s *lps) return lps->lsrjt_expl; } +/** + * Return fpma/spma MAC for lport + */ +struct mac_s +bfa_lps_get_lp_mac(struct bfa_lps_s *lps) +{ + return lps->lp_mac; +} /** * LPS firmware message class handler. diff --git a/drivers/scsi/bfa/include/bfa_svc.h b/drivers/scsi/bfa/include/bfa_svc.h index 0d7ed4d..71ffb75 100644 --- a/drivers/scsi/bfa/include/bfa_svc.h +++ b/drivers/scsi/bfa/include/bfa_svc.h @@ -316,6 +316,7 @@ wwn_t bfa_lps_get_peer_pwwn(struct bfa_lps_s *lps); wwn_t bfa_lps_get_peer_nwwn(struct bfa_lps_s *lps); u8 bfa_lps_get_lsrjt_rsn(struct bfa_lps_s *lps); u8 bfa_lps_get_lsrjt_expl(struct bfa_lps_s *lps); +mac_t bfa_lps_get_lp_mac(struct bfa_lps_s *lps); void bfa_cb_lps_flogi_comp(void *bfad, void *uarg, bfa_status_t status); void bfa_cb_lps_flogo_comp(void *bfad, void *uarg); void bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status); diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_port.h b/drivers/scsi/bfa/include/defs/bfa_defs_port.h index de0696c..1c74a8b 100644 --- a/drivers/scsi/bfa/include/defs/bfa_defs_port.h +++ b/drivers/scsi/bfa/include/defs/bfa_defs_port.h @@ -185,6 +185,8 @@ struct bfa_port_attr_s { wwn_t fabric_name; /* attached switch's nwwn */ u8 fabric_ip_addr[BFA_FCS_FABRIC_IPADDR_SZ]; /* attached * fabric's ip addr */ + struct mac_s fpma_mac; /* Lport's FPMA Mac address */ + u16 authfail; /* auth failed state */ }; /** @@ -235,7 +237,7 @@ struct bfa_port_aen_data_s { enum bfa_ioc_type_e ioc_type; wwn_t pwwn; /* WWN of the physical port */ wwn_t fwwn; /* WWN of the fabric port */ - mac_t mac; /* MAC addres of the ethernet port, + mac_t mac; /* MAC address of the ethernet port, * applicable to CNA port only */ int phy_port_num; /*! For SFP related events */ enum bfa_port_aen_sfp_pom level; /* Only transitions will -- cgit v0.10.2 From 7af074dc9d343f69bab4bfd699e6d7ba09915fd9 Mon Sep 17 00:00:00 2001 From: Krishna Gudipati Date: Fri, 5 Mar 2010 19:35:45 -0800 Subject: [SCSI] bfa: PCI VPD, FIP and include file changes. Changed PCI VPD to incorporate specific OEM vendors. Added FCoE specific interrupt latency and delay params. Added some variables needed by FIP 2.0. Added some new logging and tracing definitions. Added reserved members to make the structures (IOC, IOCFC) 64bit aligned. Changed the module identifiers, as some files were moved. Signed-off-by: Krishna Gudipati Signed-off-by: James Bottomley diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c index a5f9745..8a6361c 100644 --- a/drivers/scsi/bfa/bfa_ioc.c +++ b/drivers/scsi/bfa/bfa_ioc.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include #include @@ -27,7 +27,7 @@ #include #include -BFA_TRC_FILE(HAL, IOC); +BFA_TRC_FILE(CNA, IOC); /** * IOC local definitions diff --git a/drivers/scsi/bfa/bfa_trcmod_priv.h b/drivers/scsi/bfa/bfa_trcmod_priv.h index b3562dc..3d947d4 100644 --- a/drivers/scsi/bfa/bfa_trcmod_priv.h +++ b/drivers/scsi/bfa/bfa_trcmod_priv.h @@ -29,38 +29,36 @@ * !!! needed between trace utility and driver version */ enum { - BFA_TRC_HAL_IOC = 1, - BFA_TRC_HAL_INTR = 2, - BFA_TRC_HAL_FCXP = 3, - BFA_TRC_HAL_UF = 4, - BFA_TRC_HAL_DIAG = 5, - BFA_TRC_HAL_RPORT = 6, - BFA_TRC_HAL_FCPIM = 7, - BFA_TRC_HAL_IOIM = 8, - BFA_TRC_HAL_TSKIM = 9, - BFA_TRC_HAL_ITNIM = 10, - BFA_TRC_HAL_PPORT = 11, - BFA_TRC_HAL_SGPG = 12, - BFA_TRC_HAL_FLASH = 13, - BFA_TRC_HAL_DEBUG = 14, - BFA_TRC_HAL_WWN = 15, - BFA_TRC_HAL_FLASH_RAW = 16, - BFA_TRC_HAL_SBOOT = 17, - BFA_TRC_HAL_SBOOT_IO = 18, - BFA_TRC_HAL_SBOOT_INTR = 19, - BFA_TRC_HAL_SBTEST = 20, - BFA_TRC_HAL_IPFC = 21, - BFA_TRC_HAL_IOCFC = 22, - BFA_TRC_HAL_FCPTM = 23, - BFA_TRC_HAL_IOTM = 24, - BFA_TRC_HAL_TSKTM = 25, - BFA_TRC_HAL_TIN = 26, - BFA_TRC_HAL_LPS = 27, - BFA_TRC_HAL_FCDIAG = 28, - BFA_TRC_HAL_PBIND = 29, - BFA_TRC_HAL_IOCFC_CT = 30, - BFA_TRC_HAL_IOCFC_CB = 31, - BFA_TRC_HAL_IOCFC_Q = 32, + BFA_TRC_HAL_INTR = 1, + BFA_TRC_HAL_FCXP = 2, + BFA_TRC_HAL_UF = 3, + BFA_TRC_HAL_RPORT = 4, + BFA_TRC_HAL_FCPIM = 5, + BFA_TRC_HAL_IOIM = 6, + BFA_TRC_HAL_TSKIM = 7, + BFA_TRC_HAL_ITNIM = 8, + BFA_TRC_HAL_PPORT = 9, + BFA_TRC_HAL_SGPG = 10, + BFA_TRC_HAL_FLASH = 11, + BFA_TRC_HAL_DEBUG = 12, + BFA_TRC_HAL_WWN = 13, + BFA_TRC_HAL_FLASH_RAW = 14, + BFA_TRC_HAL_SBOOT = 15, + BFA_TRC_HAL_SBOOT_IO = 16, + BFA_TRC_HAL_SBOOT_INTR = 17, + BFA_TRC_HAL_SBTEST = 18, + BFA_TRC_HAL_IPFC = 19, + BFA_TRC_HAL_IOCFC = 20, + BFA_TRC_HAL_FCPTM = 21, + BFA_TRC_HAL_IOTM = 22, + BFA_TRC_HAL_TSKTM = 23, + BFA_TRC_HAL_TIN = 24, + BFA_TRC_HAL_LPS = 25, + BFA_TRC_HAL_FCDIAG = 26, + BFA_TRC_HAL_PBIND = 27, + BFA_TRC_HAL_IOCFC_CT = 28, + BFA_TRC_HAL_IOCFC_CB = 29, + BFA_TRC_HAL_IOCFC_Q = 30, }; #endif /* __BFA_TRCMOD_PRIV_H__ */ diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_cee.h b/drivers/scsi/bfa/include/defs/bfa_defs_cee.h index 520a22f..b0ac9ac 100644 --- a/drivers/scsi/bfa/include/defs/bfa_defs_cee.h +++ b/drivers/scsi/bfa/include/defs/bfa_defs_cee.h @@ -28,10 +28,6 @@ #define BFA_CEE_LLDP_MAX_STRING_LEN (128) - -/* FIXME: this is coming from the protocol spec. Can the host & apps share the - protocol .h files ? - */ #define BFA_CEE_LLDP_SYS_CAP_OTHER 0x0001 #define BFA_CEE_LLDP_SYS_CAP_REPEATER 0x0002 #define BFA_CEE_LLDP_SYS_CAP_MAC_BRIDGE 0x0004 @@ -94,9 +90,10 @@ struct bfa_cee_dcbx_cfg_s { /* CEE status */ /* Making this to tri-state for the benefit of port list command */ enum bfa_cee_status_e { - CEE_PHY_DOWN = 0, - CEE_PHY_UP = 1, - CEE_UP = 2, + CEE_UP = 0, + CEE_PHY_UP = 1, + CEE_LOOPBACK = 2, + CEE_PHY_DOWN = 3, }; /* CEE Query */ @@ -107,7 +104,8 @@ struct bfa_cee_attr_s { struct bfa_cee_dcbx_cfg_s dcbx_remote; mac_t src_mac; u8 link_speed; - u8 filler[3]; + u8 nw_priority; + u8 filler[2]; }; diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_ioc.h b/drivers/scsi/bfa/include/defs/bfa_defs_ioc.h index b1d532d..6c721b1 100644 --- a/drivers/scsi/bfa/include/defs/bfa_defs_ioc.h +++ b/drivers/scsi/bfa/include/defs/bfa_defs_ioc.h @@ -126,6 +126,7 @@ struct bfa_ioc_attr_s { struct bfa_ioc_driver_attr_s driver_attr; /* driver attr */ struct bfa_ioc_pci_attr_s pci_attr; u8 port_id; /* port number */ + u8 rsvd[7]; /*!< 64bit align */ }; /** diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h b/drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h index d76bcbd..87f0401 100644 --- a/drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h +++ b/drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h @@ -26,6 +26,8 @@ #define BFA_IOCFC_INTR_DELAY 1125 #define BFA_IOCFC_INTR_LATENCY 225 +#define BFA_IOCFCOE_INTR_DELAY 25 +#define BFA_IOCFCOE_INTR_LATENCY 5 /** * Interrupt coalescing configuration. @@ -50,7 +52,7 @@ struct bfa_iocfc_fwcfg_s { u16 num_fcxp_reqs; /* unassisted FC exchanges */ u16 num_uf_bufs; /* unsolicited recv buffers */ u8 num_cqs; - u8 rsvd; + u8 rsvd[5]; }; struct bfa_iocfc_drvcfg_s { @@ -224,6 +226,11 @@ struct bfa_fw_port_physm_stats_s { struct bfa_fw_fip_stats_s { + u32 vlan_req; /* vlan discovery requests */ + u32 vlan_notify; /* vlan notifications */ + u32 vlan_err; /* vlan response error */ + u32 vlan_timeouts; /* vlan disvoery timeouts */ + u32 vlan_invalids; /* invalid vlan in discovery advert. */ u32 disc_req; /* Discovery solicit requests */ u32 disc_rsp; /* Discovery solicit response */ u32 disc_err; /* Discovery advt. parse errors */ @@ -235,7 +242,7 @@ struct bfa_fw_fip_stats_s { u32 clrvlink_req; /* Clear virtual link req */ u32 op_unsupp; /* Unsupported FIP operation */ u32 untagged; /* Untagged frames (ignored) */ - u32 rsvd; + u32 invalid_version; /*!< Invalid FIP version */ }; diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_mfg.h b/drivers/scsi/bfa/include/defs/bfa_defs_mfg.h index 13fd4ab..c5bd9c3 100644 --- a/drivers/scsi/bfa/include/defs/bfa_defs_mfg.h +++ b/drivers/scsi/bfa/include/defs/bfa_defs_mfg.h @@ -22,7 +22,47 @@ /** * Manufacturing block version */ -#define BFA_MFG_VERSION 1 +#define BFA_MFG_VERSION 2 + +/** + * Manufacturing block encrypted version + */ +#define BFA_MFG_ENC_VER 2 + +/** + * Manufacturing block version 1 length + */ +#define BFA_MFG_VER1_LEN 128 + +/** + * Manufacturing block header length + */ +#define BFA_MFG_HDR_LEN 4 + +/** + * Checksum size + */ +#define BFA_MFG_CHKSUM_SIZE 16 + +/** + * Manufacturing block encrypted version + */ +#define BFA_MFG_ENC_VER 2 + +/** + * Manufacturing block version 1 length + */ +#define BFA_MFG_VER1_LEN 128 + +/** + * Manufacturing block header length + */ +#define BFA_MFG_HDR_LEN 4 + +/** + * Checksum size + */ +#define BFA_MFG_CHKSUM_SIZE 16 /** * Manufacturing block format @@ -30,29 +70,74 @@ #define BFA_MFG_SERIALNUM_SIZE 11 #define BFA_MFG_PARTNUM_SIZE 14 #define BFA_MFG_SUPPLIER_ID_SIZE 10 -#define BFA_MFG_SUPPLIER_PARTNUM_SIZE 20 -#define BFA_MFG_SUPPLIER_SERIALNUM_SIZE 20 -#define BFA_MFG_SUPPLIER_REVISION_SIZE 4 +#define BFA_MFG_SUPPLIER_PARTNUM_SIZE 20 +#define BFA_MFG_SUPPLIER_SERIALNUM_SIZE 20 +#define BFA_MFG_SUPPLIER_REVISION_SIZE 4 #define STRSZ(_n) (((_n) + 4) & ~3) /** + * Manufacturing card type + */ +enum { + BFA_MFG_TYPE_CB_MAX = 825, /* Crossbow card type max */ + BFA_MFG_TYPE_FC8P2 = 825, /* 8G 2port FC card */ + BFA_MFG_TYPE_FC8P1 = 815, /* 8G 1port FC card */ + BFA_MFG_TYPE_FC4P2 = 425, /* 4G 2port FC card */ + BFA_MFG_TYPE_FC4P1 = 415, /* 4G 1port FC card */ + BFA_MFG_TYPE_CNA10P2 = 1020, /* 10G 2port CNA card */ + BFA_MFG_TYPE_CNA10P1 = 1010, /* 10G 1port CNA card */ +}; + +#pragma pack(1) + +/** + * Card type to port number conversion + */ +#define bfa_mfg_type2port_num(card_type) (((card_type) / 10) % 10) + + +/** + * All numerical fields are in big-endian format. + */ +struct bfa_mfg_block_s { +}; + +/** * VPD data length */ -#define BFA_MFG_VPD_LEN 256 +#define BFA_MFG_VPD_LEN 512 + +#define BFA_MFG_VPD_PCI_HDR_OFF 137 +#define BFA_MFG_VPD_PCI_VER_MASK 0x07 /* version mask 3 bits */ +#define BFA_MFG_VPD_PCI_VDR_MASK 0xf8 /* vendor mask 5 bits */ + +/** + * VPD vendor tag + */ +enum { + BFA_MFG_VPD_UNKNOWN = 0, /* vendor unknown */ + BFA_MFG_VPD_IBM = 1, /* vendor IBM */ + BFA_MFG_VPD_HP = 2, /* vendor HP */ + BFA_MFG_VPD_DELL = 3, /* vendor DELL */ + BFA_MFG_VPD_PCI_IBM = 0x08, /* PCI VPD IBM */ + BFA_MFG_VPD_PCI_HP = 0x10, /* PCI VPD HP */ + BFA_MFG_VPD_PCI_DELL = 0x20, /* PCI VPD DELL */ + BFA_MFG_VPD_PCI_BRCD = 0xf8, /* PCI VPD Brocade */ +}; /** * All numerical fields are in big-endian format. */ struct bfa_mfg_vpd_s { - u8 version; /* vpd data version */ - u8 vpd_sig[3]; /* characters 'V', 'P', 'D' */ - u8 chksum; /* u8 checksum */ - u8 vendor; /* vendor */ - u8 len; /* vpd data length excluding header */ - u8 rsv; - u8 data[BFA_MFG_VPD_LEN]; /* vpd data */ + u8 version; /* vpd data version */ + u8 vpd_sig[3]; /* characters 'V', 'P', 'D' */ + u8 chksum; /* u8 checksum */ + u8 vendor; /* vendor */ + u8 len; /* vpd data length excluding header */ + u8 rsv; + u8 data[BFA_MFG_VPD_LEN]; /* vpd data */ }; -#pragma pack(1) +#pragma pack() #endif /* __BFA_DEFS_MFG_H__ */ diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_status.h b/drivers/scsi/bfa/include/defs/bfa_defs_status.h index cdceaeb..d8a74eb 100644 --- a/drivers/scsi/bfa/include/defs/bfa_defs_status.h +++ b/drivers/scsi/bfa/include/defs/bfa_defs_status.h @@ -180,8 +180,8 @@ enum bfa_status { BFA_STATUS_IM_ADAPT_ALREADY_IN_TEAM = 114, /* Given adapter is part * of another team */ BFA_STATUS_IM_ADAPT_HAS_VLANS = 115, /* Adapter has VLANs configured. - * Delete all VLANs before - * creating team */ + * Delete all VLANs to become + * part of the team */ BFA_STATUS_IM_PVID_MISMATCH = 116, /* Mismatching PVIDs configured * for adapters */ BFA_STATUS_IM_LINK_SPEED_MISMATCH = 117, /* Mismatching link speeds @@ -242,6 +242,14 @@ enum bfa_status { * failed */ BFA_STATUS_IM_UNBIND_FAILED = 149, /* ! < IM Driver unbind operation * failed */ + BFA_STATUS_IM_PORT_IN_TEAM = 150, /* Port is already part of the + * team */ + BFA_STATUS_IM_VLAN_NOT_FOUND = 151, /* VLAN ID doesn't exists */ + BFA_STATUS_IM_TEAM_NOT_FOUND = 152, /* Teaming configuration doesn't + * exists */ + BFA_STATUS_IM_TEAM_CFG_NOT_ALLOWED = 153, /* Given settings are not + * allowed for the current + * Teaming mode */ BFA_STATUS_MAX_VAL /* Unknown error code */ }; #define bfa_status_t enum bfa_status diff --git a/drivers/scsi/bfa/include/log/bfa_log_hal.h b/drivers/scsi/bfa/include/log/bfa_log_hal.h index 0412aea..5f8f5e3 100644 --- a/drivers/scsi/bfa/include/log/bfa_log_hal.h +++ b/drivers/scsi/bfa/include/log/bfa_log_hal.h @@ -27,4 +27,10 @@ (((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 3) #define BFA_LOG_HAL_SM_ASSERT \ (((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 4) +#define BFA_LOG_HAL_DRIVER_ERROR \ + (((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 5) +#define BFA_LOG_HAL_DRIVER_CONFIG_ERROR \ + (((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 6) +#define BFA_LOG_HAL_MBOX_ERROR \ + (((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 7) #endif diff --git a/drivers/scsi/bfa/include/log/bfa_log_linux.h b/drivers/scsi/bfa/include/log/bfa_log_linux.h index 317c054..bd451db 100644 --- a/drivers/scsi/bfa/include/log/bfa_log_linux.h +++ b/drivers/scsi/bfa/include/log/bfa_log_linux.h @@ -41,4 +41,20 @@ (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 10) #define BFA_LOG_LINUX_SCSI_ABORT_COMP \ (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 11) +#define BFA_LOG_LINUX_DRIVER_CONFIG_ERROR \ + (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 12) +#define BFA_LOG_LINUX_BNA_STATE_MACHINE \ + (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 13) +#define BFA_LOG_LINUX_IOC_ERROR \ + (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 14) +#define BFA_LOG_LINUX_RESOURCE_ALLOC_ERROR \ + (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 15) +#define BFA_LOG_LINUX_RING_BUFFER_ERROR \ + (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 16) +#define BFA_LOG_LINUX_DRIVER_ERROR \ + (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 17) +#define BFA_LOG_LINUX_DRIVER_DIAG \ + (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 18) +#define BFA_LOG_LINUX_DRIVER_AEN \ + (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 19) #endif -- cgit v0.10.2 From f926a05f5c1507aeae0e36175a03c0a19c201187 Mon Sep 17 00:00:00 2001 From: Krishna Gudipati Date: Fri, 5 Mar 2010 19:36:00 -0800 Subject: [SCSI] bfa: FCS authentication related changes. Made FCS authentication related changes to state machines and header files. Made changes in FCS state machines to handle the case when secret string is NULL. Signed-off-by: Krishna Gudipati Signed-off-by: James Bottomley diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c index 7bb182d..4a51aac 100644 --- a/drivers/scsi/bfa/bfa_fcs_lport.c +++ b/drivers/scsi/bfa/bfa_fcs_lport.c @@ -931,6 +931,8 @@ bfa_fcs_port_get_attr(struct bfa_fcs_port_s *port, if (port->fabric) { port_attr->port_type = bfa_fcs_fabric_port_type(port->fabric); port_attr->loopback = bfa_fcs_fabric_is_loopback(port->fabric); + port_attr->authfail = + bfa_fcs_fabric_is_auth_failed(port->fabric); port_attr->fabric_name = bfa_fcs_port_get_fabric_name(port); memcpy(port_attr->fabric_ip_addr, bfa_fcs_port_get_fabric_ipaddr(port), diff --git a/drivers/scsi/bfa/fabric.c b/drivers/scsi/bfa/fabric.c index 20a686a..b02ed76 100644 --- a/drivers/scsi/bfa/fabric.c +++ b/drivers/scsi/bfa/fabric.c @@ -895,6 +895,12 @@ bfa_fcs_fabric_is_loopback(struct bfa_fcs_fabric_s *fabric) return bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_loopback); } +bfa_boolean_t +bfa_fcs_fabric_is_auth_failed(struct bfa_fcs_fabric_s *fabric) +{ + return bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_auth_failed); +} + enum bfa_pport_type bfa_fcs_fabric_port_type(struct bfa_fcs_fabric_s *fabric) { diff --git a/drivers/scsi/bfa/fcs_fabric.h b/drivers/scsi/bfa/fcs_fabric.h index 8237bd5..244c3f0 100644 --- a/drivers/scsi/bfa/fcs_fabric.h +++ b/drivers/scsi/bfa/fcs_fabric.h @@ -47,6 +47,7 @@ void bfa_fcs_fabric_uf_recv(struct bfa_fcs_fabric_s *fabric, struct fchs_s *fchs, u16 len); u16 bfa_fcs_fabric_vport_count(struct bfa_fcs_fabric_s *fabric); bfa_boolean_t bfa_fcs_fabric_is_loopback(struct bfa_fcs_fabric_s *fabric); +bfa_boolean_t bfa_fcs_fabric_is_auth_failed(struct bfa_fcs_fabric_s *fabric); enum bfa_pport_type bfa_fcs_fabric_port_type(struct bfa_fcs_fabric_s *fabric); void bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric); void bfa_fcs_fabric_port_delete_comp(struct bfa_fcs_fabric_s *fabric); diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_auth.h b/drivers/scsi/bfa/include/defs/bfa_defs_auth.h index dd19c83..45df328 100644 --- a/drivers/scsi/bfa/include/defs/bfa_defs_auth.h +++ b/drivers/scsi/bfa/include/defs/bfa_defs_auth.h @@ -23,6 +23,7 @@ #define PRIVATE_KEY 19009 #define KEY_LEN 32399 #define BFA_AUTH_SECRET_STRING_LEN 256 +#define BFA_AUTH_FAIL_NO_PASSWORD 0xFE #define BFA_AUTH_FAIL_TIMEOUT 0xFF /** @@ -41,6 +42,27 @@ enum bfa_auth_status { BFA_AUTH_STATUS_UNKNOWN = 9, /* authentication status unknown */ }; +enum bfa_auth_rej_code { + BFA_AUTH_RJT_CODE_AUTH_FAILURE = 1, /* auth failure */ + BFA_AUTH_RJT_CODE_LOGICAL_ERR = 2, /* logical error */ +}; + +/** + * Authentication reject codes + */ +enum bfa_auth_rej_code_exp { + BFA_AUTH_MECH_NOT_USABLE = 1, /* auth. mechanism not usable */ + BFA_AUTH_DH_GROUP_NOT_USABLE = 2, /* DH Group not usable */ + BFA_AUTH_HASH_FUNC_NOT_USABLE = 3, /* hash Function not usable */ + BFA_AUTH_AUTH_XACT_STARTED = 4, /* auth xact started */ + BFA_AUTH_AUTH_FAILED = 5, /* auth failed */ + BFA_AUTH_INCORRECT_PLD = 6, /* incorrect payload */ + BFA_AUTH_INCORRECT_PROTO_MSG = 7, /* incorrect proto msg */ + BFA_AUTH_RESTART_AUTH_PROTO = 8, /* restart auth protocol */ + BFA_AUTH_AUTH_CONCAT_NOT_SUPP = 9, /* auth concat not supported */ + BFA_AUTH_PROTO_VER_NOT_SUPP = 10,/* proto version not supported */ +}; + struct auth_proto_stats_s { u32 auth_rjts; u32 auth_negs; diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_pport.h b/drivers/scsi/bfa/include/defs/bfa_defs_pport.h index bf32041..88662a1 100644 --- a/drivers/scsi/bfa/include/defs/bfa_defs_pport.h +++ b/drivers/scsi/bfa/include/defs/bfa_defs_pport.h @@ -232,7 +232,7 @@ struct bfa_pport_attr_s { u32 pid; /* port ID */ enum bfa_pport_type port_type; /* current topology */ u32 loopback; /* external loopback */ - u32 rsvd1; + u32 authfail; /* auth fail state */ u32 rsvd2; /* padding for 64 bit */ }; @@ -247,7 +247,7 @@ struct bfa_pport_fc_stats_s { u64 rx_words; /* received words */ u64 lip_count; /* LIPs seen */ u64 nos_count; /* NOS count */ - u64 error_frames; /* errored frames (sent?) */ + u64 error_frames; /* errored frames */ u64 dropped_frames; /* dropped frames */ u64 link_failures; /* link failure count */ u64 loss_of_syncs; /* loss of sync count */ -- cgit v0.10.2 From 738c9e66dcb7e17a962a7d65c976386b970d10ca Mon Sep 17 00:00:00 2001 From: Krishna Gudipati Date: Fri, 5 Mar 2010 19:36:19 -0800 Subject: [SCSI] bfa: Added firmware save clear feature for BFA driver. Signed-off-by: Krishna Gudipati Signed-off-by: James Bottomley diff --git a/drivers/scsi/bfa/bfa_core.c b/drivers/scsi/bfa/bfa_core.c index 72e3f2f..0c08e18 100644 --- a/drivers/scsi/bfa/bfa_core.c +++ b/drivers/scsi/bfa/bfa_core.c @@ -385,6 +385,15 @@ bfa_debug_fwsave(struct bfa_s *bfa, void *trcdata, int *trclen) } /** + * Clear the saved firmware trace information of an IOC. + */ +void +bfa_debug_fwsave_clear(struct bfa_s *bfa) +{ + bfa_ioc_debug_fwsave_clear(&bfa->ioc); +} + +/** * Fetch firmware trace data. * * @param[in] bfa BFA instance diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c index 8a6361c..0019ff7 100644 --- a/drivers/scsi/bfa/bfa_ioc.c +++ b/drivers/scsi/bfa/bfa_ioc.c @@ -1488,7 +1488,6 @@ return (auto_recover) ? BFA_DBG_FWTRC_LEN : 0; void bfa_ioc_debug_memclaim(struct bfa_ioc_s *ioc, void *dbg_fwsave) { - bfa_assert(ioc->auto_recover); ioc->dbg_fwsave = dbg_fwsave; ioc->dbg_fwsave_len = bfa_ioc_debug_trcsz(ioc->auto_recover); } @@ -1925,6 +1924,15 @@ bfa_ioc_debug_fwsave(struct bfa_ioc_s *ioc, void *trcdata, int *trclen) } /** + * Clear saved firmware trace + */ +void +bfa_ioc_debug_fwsave_clear(struct bfa_ioc_s *ioc) +{ + ioc->dbg_fwsave_once = BFA_TRUE; +} + +/** * Retrieve saved firmware trace from a prior IOC failure. */ bfa_status_t diff --git a/drivers/scsi/bfa/bfa_ioc.h b/drivers/scsi/bfa/bfa_ioc.h index 853cc31..4b73efa 100644 --- a/drivers/scsi/bfa/bfa_ioc.h +++ b/drivers/scsi/bfa/bfa_ioc.h @@ -270,6 +270,7 @@ int bfa_ioc_debug_trcsz(bfa_boolean_t auto_recover); void bfa_ioc_debug_memclaim(struct bfa_ioc_s *ioc, void *dbg_fwsave); bfa_status_t bfa_ioc_debug_fwsave(struct bfa_ioc_s *ioc, void *trcdata, int *trclen); +void bfa_ioc_debug_fwsave_clear(struct bfa_ioc_s *ioc); bfa_status_t bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata, int *trclen); u32 bfa_ioc_smem_pgnum(struct bfa_ioc_s *ioc, u32 fmaddr); diff --git a/drivers/scsi/bfa/include/bfa.h b/drivers/scsi/bfa/include/bfa.h index 942ae64..17654ca 100644 --- a/drivers/scsi/bfa/include/bfa.h +++ b/drivers/scsi/bfa/include/bfa.h @@ -172,6 +172,7 @@ void bfa_timer_tick(struct bfa_s *bfa); */ bfa_status_t bfa_debug_fwtrc(struct bfa_s *bfa, void *trcdata, int *trclen); bfa_status_t bfa_debug_fwsave(struct bfa_s *bfa, void *trcdata, int *trclen); +void bfa_debug_fwsave_clear(struct bfa_s *bfa); #include "bfa_priv.h" -- cgit v0.10.2 From 9693e7dff5c2911b4e445f5f656ef57b3a5bffac Mon Sep 17 00:00:00 2001 From: Krishna Gudipati Date: Fri, 5 Mar 2010 19:36:30 -0800 Subject: [SCSI] bfa: Introduce a link notification state machine. Introduce a link notification state machine to handle next incoming link events while the current event is being delivered to the driver. When the event has been processed by the driver, the link notification state machine will queue the next event (if there is any) to the driver. Signed-off-by: Krishna Gudipati Signed-off-by: James Bottomley diff --git a/drivers/scsi/bfa/bfa_fcport.c b/drivers/scsi/bfa/bfa_fcport.c index aef648b..4ed048b 100644 --- a/drivers/scsi/bfa/bfa_fcport.c +++ b/drivers/scsi/bfa/bfa_fcport.c @@ -26,16 +26,6 @@ BFA_TRC_FILE(HAL, PPORT); BFA_MODULE(pport); -#define bfa_pport_callback(__pport, __event) do { \ - if ((__pport)->bfa->fcs) { \ - (__pport)->event_cbfn((__pport)->event_cbarg, (__event)); \ - } else { \ - (__pport)->hcb_event = (__event); \ - bfa_cb_queue((__pport)->bfa, &(__pport)->hcb_qe, \ - __bfa_cb_port_event, (__pport)); \ - } \ -} while (0) - /* * The port is considered disabled if corresponding physical port or IOC are * disabled explicitly @@ -57,7 +47,10 @@ static void __bfa_cb_port_stats(void *cbarg, bfa_boolean_t complete); static void __bfa_cb_port_stats_clr(void *cbarg, bfa_boolean_t complete); static void bfa_port_stats_timeout(void *cbarg); static void bfa_port_stats_clr_timeout(void *cbarg); - +static void bfa_pport_callback(struct bfa_pport_s *pport, + enum bfa_pport_linkstate event); +static void bfa_pport_queue_cb(struct bfa_pport_ln_s *ln, + enum bfa_pport_linkstate event); /** * bfa_pport_private */ @@ -77,6 +70,16 @@ enum bfa_pport_sm_event { BFA_PPORT_SM_HWFAIL = 9, /* IOC h/w failure */ }; +/** + * BFA port link notification state machine events + */ + +enum bfa_pport_ln_sm_event { + BFA_PPORT_LN_SM_LINKUP = 1, /* linkup event */ + BFA_PPORT_LN_SM_LINKDOWN = 2, /* linkdown event */ + BFA_PPORT_LN_SM_NOTIFICATION = 3 /* done notification */ +}; + static void bfa_pport_sm_uninit(struct bfa_pport_s *pport, enum bfa_pport_sm_event event); static void bfa_pport_sm_enabling_qwait(struct bfa_pport_s *pport, @@ -100,6 +103,21 @@ static void bfa_pport_sm_iocdown(struct bfa_pport_s *pport, static void bfa_pport_sm_iocfail(struct bfa_pport_s *pport, enum bfa_pport_sm_event event); +static void bfa_pport_ln_sm_dn(struct bfa_pport_ln_s *ln, + enum bfa_pport_ln_sm_event event); +static void bfa_pport_ln_sm_dn_nf(struct bfa_pport_ln_s *ln, + enum bfa_pport_ln_sm_event event); +static void bfa_pport_ln_sm_dn_up_nf(struct bfa_pport_ln_s *ln, + enum bfa_pport_ln_sm_event event); +static void bfa_pport_ln_sm_up(struct bfa_pport_ln_s *ln, + enum bfa_pport_ln_sm_event event); +static void bfa_pport_ln_sm_up_nf(struct bfa_pport_ln_s *ln, + enum bfa_pport_ln_sm_event event); +static void bfa_pport_ln_sm_up_dn_nf(struct bfa_pport_ln_s *ln, + enum bfa_pport_ln_sm_event event); +static void bfa_pport_ln_sm_up_dn_up_nf(struct bfa_pport_ln_s *ln, + enum bfa_pport_ln_sm_event event); + static struct bfa_sm_table_s hal_pport_sm_table[] = { {BFA_SM(bfa_pport_sm_uninit), BFA_PPORT_ST_UNINIT}, {BFA_SM(bfa_pport_sm_enabling_qwait), BFA_PPORT_ST_ENABLING_QWAIT}, @@ -619,7 +637,163 @@ bfa_pport_sm_iocfail(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) } } +/** + * Link state is down + */ +static void +bfa_pport_ln_sm_dn(struct bfa_pport_ln_s *ln, + enum bfa_pport_ln_sm_event event) +{ + bfa_trc(ln->pport->bfa, event); + + switch (event) { + case BFA_PPORT_LN_SM_LINKUP: + bfa_sm_set_state(ln, bfa_pport_ln_sm_up_nf); + bfa_pport_queue_cb(ln, BFA_PPORT_LINKUP); + break; + + default: + bfa_sm_fault(ln->pport->bfa, event); + } +} + +/** + * Link state is waiting for down notification + */ +static void +bfa_pport_ln_sm_dn_nf(struct bfa_pport_ln_s *ln, + enum bfa_pport_ln_sm_event event) +{ + bfa_trc(ln->pport->bfa, event); + + switch (event) { + case BFA_PPORT_LN_SM_LINKUP: + bfa_sm_set_state(ln, bfa_pport_ln_sm_dn_up_nf); + break; + + case BFA_PPORT_LN_SM_NOTIFICATION: + bfa_sm_set_state(ln, bfa_pport_ln_sm_dn); + break; + + default: + bfa_sm_fault(ln->pport->bfa, event); + } +} + +/** + * Link state is waiting for down notification and there is a pending up + */ +static void +bfa_pport_ln_sm_dn_up_nf(struct bfa_pport_ln_s *ln, + enum bfa_pport_ln_sm_event event) +{ + bfa_trc(ln->pport->bfa, event); + + switch (event) { + case BFA_PPORT_LN_SM_LINKDOWN: + bfa_sm_set_state(ln, bfa_pport_ln_sm_dn_nf); + break; + + case BFA_PPORT_LN_SM_NOTIFICATION: + bfa_sm_set_state(ln, bfa_pport_ln_sm_up_nf); + bfa_pport_queue_cb(ln, BFA_PPORT_LINKUP); + break; + + default: + bfa_sm_fault(ln->pport->bfa, event); + } +} + +/** + * Link state is up + */ +static void +bfa_pport_ln_sm_up(struct bfa_pport_ln_s *ln, + enum bfa_pport_ln_sm_event event) +{ + bfa_trc(ln->pport->bfa, event); + + switch (event) { + case BFA_PPORT_LN_SM_LINKDOWN: + bfa_sm_set_state(ln, bfa_pport_ln_sm_dn_nf); + bfa_pport_queue_cb(ln, BFA_PPORT_LINKDOWN); + break; + + default: + bfa_sm_fault(ln->pport->bfa, event); + } +} + +/** + * Link state is waiting for up notification + */ +static void +bfa_pport_ln_sm_up_nf(struct bfa_pport_ln_s *ln, + enum bfa_pport_ln_sm_event event) +{ + bfa_trc(ln->pport->bfa, event); + + switch (event) { + case BFA_PPORT_LN_SM_LINKDOWN: + bfa_sm_set_state(ln, bfa_pport_ln_sm_up_dn_nf); + break; + + case BFA_PPORT_LN_SM_NOTIFICATION: + bfa_sm_set_state(ln, bfa_pport_ln_sm_up); + break; + + default: + bfa_sm_fault(ln->pport->bfa, event); + } +} + +/** + * Link state is waiting for up notification and there is a pending down + */ +static void +bfa_pport_ln_sm_up_dn_nf(struct bfa_pport_ln_s *ln, + enum bfa_pport_ln_sm_event event) +{ + bfa_trc(ln->pport->bfa, event); + switch (event) { + case BFA_PPORT_LN_SM_LINKUP: + bfa_sm_set_state(ln, bfa_pport_ln_sm_up_dn_up_nf); + break; + + case BFA_PPORT_LN_SM_NOTIFICATION: + bfa_sm_set_state(ln, bfa_pport_ln_sm_dn_nf); + bfa_pport_queue_cb(ln, BFA_PPORT_LINKDOWN); + break; + + default: + bfa_sm_fault(ln->pport->bfa, event); + } +} + +/** + * Link state is waiting for up notification and there are pending down and up + */ +static void +bfa_pport_ln_sm_up_dn_up_nf(struct bfa_pport_ln_s *ln, + enum bfa_pport_ln_sm_event event) +{ + bfa_trc(ln->pport->bfa, event); + + switch (event) { + case BFA_PPORT_LN_SM_LINKDOWN: + bfa_sm_set_state(ln, bfa_pport_ln_sm_up_dn_nf); + break; + + case BFA_PPORT_LN_SM_NOTIFICATION: + bfa_sm_set_state(ln, bfa_pport_ln_sm_dn_up_nf); + bfa_pport_queue_cb(ln, BFA_PPORT_LINKDOWN); + break; + + default: + bfa_sm_fault(ln->pport->bfa, event); + } +} /** * bfa_pport_private @@ -628,10 +802,12 @@ bfa_pport_sm_iocfail(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) static void __bfa_cb_port_event(void *cbarg, bfa_boolean_t complete) { - struct bfa_pport_s *pport = cbarg; + struct bfa_pport_ln_s *ln = cbarg; if (complete) - pport->event_cbfn(pport->event_cbarg, pport->hcb_event); + ln->pport->event_cbfn(ln->pport->event_cbarg, ln->ln_event); + else + bfa_sm_send_event(ln, BFA_PPORT_LN_SM_NOTIFICATION); } #define PPORT_STATS_DMA_SZ (BFA_ROUNDUP(sizeof(union bfa_pport_stats_u), \ @@ -681,13 +857,16 @@ bfa_pport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, { struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); struct bfa_pport_cfg_s *port_cfg = &pport->cfg; + struct bfa_pport_ln_s *ln = &pport->ln; bfa_os_memset(pport, 0, sizeof(struct bfa_pport_s)); pport->bfa = bfa; + ln->pport = pport; bfa_pport_mem_claim(pport, meminfo); bfa_sm_set_state(pport, bfa_pport_sm_uninit); + bfa_sm_set_state(ln, bfa_pport_ln_sm_dn); /** * initialize and set default configuration @@ -1369,6 +1548,33 @@ bfa_port_stats_clr_timeout(void *cbarg) } static void +bfa_pport_callback(struct bfa_pport_s *pport, enum bfa_pport_linkstate event) +{ + if (pport->bfa->fcs) { + pport->event_cbfn(pport->event_cbarg, event); + return; + } + + switch (event) { + case BFA_PPORT_LINKUP: + bfa_sm_send_event(&pport->ln, BFA_PPORT_LN_SM_LINKUP); + break; + case BFA_PPORT_LINKDOWN: + bfa_sm_send_event(&pport->ln, BFA_PPORT_LN_SM_LINKDOWN); + break; + default: + bfa_assert(0); + } +} + +static void +bfa_pport_queue_cb(struct bfa_pport_ln_s *ln, enum bfa_pport_linkstate event) +{ + ln->ln_event = event; + bfa_cb_queue(ln->pport->bfa, &ln->ln_qe, __bfa_cb_port_event, ln); +} + +static void __bfa_cb_port_stats(void *cbarg, bfa_boolean_t complete) { struct bfa_pport_s *port = cbarg; diff --git a/drivers/scsi/bfa/bfa_port_priv.h b/drivers/scsi/bfa/bfa_port_priv.h index 51f698a..f29701b 100644 --- a/drivers/scsi/bfa/bfa_port_priv.h +++ b/drivers/scsi/bfa/bfa_port_priv.h @@ -23,6 +23,16 @@ #include "bfa_intr_priv.h" /** + * Link notification data structure + */ +struct bfa_pport_ln_s { + struct bfa_pport_s *pport; + bfa_sm_t sm; + struct bfa_cb_qe_s ln_qe; /* BFA callback queue elem for ln */ + enum bfa_pport_linkstate ln_event; /* ln event for callback */ +}; + +/** * BFA physical port data structure */ struct bfa_pport_s { @@ -52,9 +62,8 @@ struct bfa_pport_s { union bfi_pport_i2h_msg_u i2hmsg; } event_arg; void *bfad; /* BFA driver handle */ + struct bfa_pport_ln_s ln; /* Link Notification */ struct bfa_cb_qe_s hcb_qe; /* BFA callback queue elem */ - enum bfa_pport_linkstate hcb_event; - /* link event for callback */ u32 msgtag; /* fimrware msg tag for reply */ u8 *stats_kva; u64 stats_pa; -- cgit v0.10.2 From 2993cc71d1bff61999ade7f2b6b3ea2dd1e2c8d9 Mon Sep 17 00:00:00 2001 From: Krishna Gudipati Date: Fri, 5 Mar 2010 19:36:47 -0800 Subject: [SCSI] bfa: AEN and byte alignment fixes. Replace enum types with int and rearrange the fields to fix some alignment issue. Local var ioc_attr is causing the stack to overflow, so removed the usage of the local ioc_attr var and now invoking an API to return the ioc_type. Fix some AEN issues. Signed-off-by: Krishna Gudipati Signed-off-by: James Bottomley diff --git a/drivers/scsi/bfa/bfa_fcport.c b/drivers/scsi/bfa/bfa_fcport.c index 4ed048b..bdea7f0 100644 --- a/drivers/scsi/bfa/bfa_fcport.c +++ b/drivers/scsi/bfa/bfa_fcport.c @@ -142,6 +142,7 @@ bfa_pport_aen_post(struct bfa_pport_s *pport, enum bfa_port_aen_event event) char pwwn_ptr[BFA_STRING_32]; struct bfa_ioc_attr_s ioc_attr; + memset(&aen_data, 0, sizeof(aen_data)); wwn2str(pwwn_ptr, pwwn); switch (event) { case BFA_PORT_AEN_ONLINE: diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c index 0019ff7..2f09d17 100644 --- a/drivers/scsi/bfa/bfa_ioc.c +++ b/drivers/scsi/bfa/bfa_ioc.c @@ -1731,6 +1731,21 @@ bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc, ad_attr->cna_capable = ioc->cna; } +enum bfa_ioc_type_e +bfa_ioc_get_type(struct bfa_ioc_s *ioc) +{ + if (!ioc->ctdev || ioc->fcmode) + return BFA_IOC_TYPE_FC; + else if (ioc->ioc_mc == BFI_MC_IOCFC) + return BFA_IOC_TYPE_FCoE; + else if (ioc->ioc_mc == BFI_MC_LL) + return BFA_IOC_TYPE_LL; + else { + bfa_assert(ioc->ioc_mc == BFI_MC_LL); + return BFA_IOC_TYPE_LL; + } +} + void bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr) { @@ -1739,12 +1754,7 @@ bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr) ioc_attr->state = bfa_sm_to_state(ioc_sm_table, ioc->fsm); ioc_attr->port_id = ioc->port_id; - if (!ioc->ctdev || ioc->fcmode) - ioc_attr->ioc_type = BFA_IOC_TYPE_FC; - else if (ioc->ioc_mc == BFI_MC_IOCFC) - ioc_attr->ioc_type = BFA_IOC_TYPE_FCoE; - else if (ioc->ioc_mc == BFI_MC_LL) - ioc_attr->ioc_type = BFA_IOC_TYPE_LL; + ioc_attr->ioc_type = bfa_ioc_get_type(ioc); bfa_ioc_get_adapter_attr(ioc, &ioc_attr->adapter_attr); @@ -1860,7 +1870,7 @@ bfa_ioc_aen_post(struct bfa_ioc_s *ioc, enum bfa_ioc_aen_event event) union bfa_aen_data_u aen_data; struct bfa_log_mod_s *logmod = ioc->logm; s32 inst_num = 0; - struct bfa_ioc_attr_s ioc_attr; + enum bfa_ioc_type_e ioc_type; switch (event) { case BFA_IOC_AEN_HBGOOD: @@ -1884,8 +1894,8 @@ bfa_ioc_aen_post(struct bfa_ioc_s *ioc, enum bfa_ioc_aen_event event) memset(&aen_data.ioc.pwwn, 0, sizeof(aen_data.ioc.pwwn)); memset(&aen_data.ioc.mac, 0, sizeof(aen_data.ioc.mac)); - bfa_ioc_get_attr(ioc, &ioc_attr); - switch (ioc_attr.ioc_type) { + ioc_type = bfa_ioc_get_type(ioc); + switch (ioc_type) { case BFA_IOC_TYPE_FC: aen_data.ioc.pwwn = bfa_ioc_get_pwwn(ioc); break; @@ -1897,10 +1907,10 @@ bfa_ioc_aen_post(struct bfa_ioc_s *ioc, enum bfa_ioc_aen_event event) aen_data.ioc.mac = bfa_ioc_get_mac(ioc); break; default: - bfa_assert(ioc_attr.ioc_type == BFA_IOC_TYPE_FC); + bfa_assert(ioc_type == BFA_IOC_TYPE_FC); break; } - aen_data.ioc.ioc_type = ioc_attr.ioc_type; + aen_data.ioc.ioc_type = ioc_type; } /** diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c index 4ccaeae..79956c1 100644 --- a/drivers/scsi/bfa/bfad.c +++ b/drivers/scsi/bfa/bfad.c @@ -677,7 +677,6 @@ bfad_drv_init(struct bfad_s *bfad) bfa_status_t rc; unsigned long flags; struct bfa_fcs_driver_info_s driver_info; - int i; bfad->cfg_data.rport_del_timeout = rport_del_timeout; bfad->cfg_data.lun_queue_depth = bfa_lun_queue_depth; @@ -697,12 +696,7 @@ bfad_drv_init(struct bfad_s *bfad) bfa_init_log(&bfad->bfa, bfad->logmod); bfa_init_trc(&bfad->bfa, bfad->trcmod); bfa_init_aen(&bfad->bfa, bfad->aen); - INIT_LIST_HEAD(&bfad->file_q); - INIT_LIST_HEAD(&bfad->file_free_q); - for (i = 0; i < BFAD_AEN_MAX_APPS; i++) { - bfa_q_qe_init(&bfad->file_buf[i].qe); - list_add_tail(&bfad->file_buf[i].qe, &bfad->file_free_q); - } + memset(bfad->file_map, 0, sizeof(bfad->file_map)); bfa_init_plog(&bfad->bfa, &bfad->plog_buf); bfa_plog_init(&bfad->plog_buf); bfa_plog_str(&bfad->plog_buf, BFA_PL_MID_DRVR, BFA_PL_EID_DRIVER_START, @@ -799,7 +793,6 @@ bfad_drv_uninit(struct bfad_s *bfad) bfa_isr_disable(&bfad->bfa); bfa_detach(&bfad->bfa); bfad_remove_intr(bfad); - bfa_assert(list_empty(&bfad->file_q)); bfad_hal_mem_release(bfad); bfad->bfad_flags &= ~BFAD_DRV_INIT_DONE; diff --git a/drivers/scsi/bfa/bfad_drv.h b/drivers/scsi/bfa/bfad_drv.h index 9fa801a..94f4d84 100644 --- a/drivers/scsi/bfa/bfad_drv.h +++ b/drivers/scsi/bfa/bfad_drv.h @@ -139,14 +139,6 @@ struct bfad_cfg_param_s { u32 binding_method; }; -#define BFAD_AEN_MAX_APPS 8 -struct bfad_aen_file_s { - struct list_head qe; - struct bfad_s *bfad; - s32 ri; - s32 app_id; -}; - /* * BFAD (PCI function) data structure */ @@ -186,9 +178,7 @@ struct bfad_s { struct bfa_log_mod_s *logmod; struct bfa_aen_s *aen; struct bfa_aen_s aen_buf; - struct bfad_aen_file_s file_buf[BFAD_AEN_MAX_APPS]; - struct list_head file_q; - struct list_head file_free_q; + void *file_map[BFA_AEN_MAX_APP]; struct bfa_plog_s plog_buf; int ref_count; bfa_boolean_t ipfc_enabled; diff --git a/drivers/scsi/bfa/include/aen/bfa_aen.h b/drivers/scsi/bfa/include/aen/bfa_aen.h index d9cbc2a..6abbab0 100644 --- a/drivers/scsi/bfa/include/aen/bfa_aen.h +++ b/drivers/scsi/bfa/include/aen/bfa_aen.h @@ -18,21 +18,24 @@ #define __BFA_AEN_H__ #include "defs/bfa_defs_aen.h" +#include "defs/bfa_defs_status.h" +#include "cs/bfa_debug.h" -#define BFA_AEN_MAX_ENTRY 512 +#define BFA_AEN_MAX_ENTRY 512 -extern s32 bfa_aen_max_cfg_entry; +extern int bfa_aen_max_cfg_entry; struct bfa_aen_s { void *bfad; - s32 max_entry; - s32 write_index; - s32 read_index; - u32 bfad_num; - u32 seq_num; + int max_entry; + int write_index; + int read_index; + int bfad_num; + int seq_num; void (*aen_cb_notify)(void *bfad); void (*gettimeofday)(struct bfa_timeval_s *tv); - struct bfa_trc_mod_s *trcmod; - struct bfa_aen_entry_s list[BFA_AEN_MAX_ENTRY]; /* Must be the last */ + struct bfa_trc_mod_s *trcmod; + int app_ri[BFA_AEN_MAX_APP]; /* For multiclient support */ + struct bfa_aen_entry_s list[BFA_AEN_MAX_ENTRY]; /* Must be the last */ }; @@ -45,48 +48,49 @@ bfa_aen_set_max_cfg_entry(int max_entry) bfa_aen_max_cfg_entry = max_entry; } -static inline s32 +static inline int bfa_aen_get_max_cfg_entry(void) { return bfa_aen_max_cfg_entry; } -static inline s32 +static inline int bfa_aen_get_meminfo(void) { return sizeof(struct bfa_aen_entry_s) * bfa_aen_get_max_cfg_entry(); } -static inline s32 +static inline int bfa_aen_get_wi(struct bfa_aen_s *aen) { return aen->write_index; } -static inline s32 +static inline int bfa_aen_get_ri(struct bfa_aen_s *aen) { return aen->read_index; } -static inline s32 -bfa_aen_fetch_count(struct bfa_aen_s *aen, s32 read_index) +static inline int +bfa_aen_fetch_count(struct bfa_aen_s *aen, enum bfa_aen_app app_id) { - return ((aen->write_index + aen->max_entry) - read_index) + bfa_assert((app_id < BFA_AEN_MAX_APP) && (app_id >= bfa_aen_app_bcu)); + return ((aen->write_index + aen->max_entry) - aen->app_ri[app_id]) % aen->max_entry; } -s32 bfa_aen_init(struct bfa_aen_s *aen, struct bfa_trc_mod_s *trcmod, - void *bfad, u32 inst_id, void (*aen_cb_notify)(void *), +int bfa_aen_init(struct bfa_aen_s *aen, struct bfa_trc_mod_s *trcmod, + void *bfad, int bfad_num, void (*aen_cb_notify)(void *), void (*gettimeofday)(struct bfa_timeval_s *)); -s32 bfa_aen_post(struct bfa_aen_s *aen, enum bfa_aen_category aen_category, +void bfa_aen_post(struct bfa_aen_s *aen, enum bfa_aen_category aen_category, int aen_type, union bfa_aen_data_u *aen_data); -s32 bfa_aen_fetch(struct bfa_aen_s *aen, struct bfa_aen_entry_s *aen_entry, - s32 entry_space, s32 rii, s32 *ri_arr, - s32 ri_arr_cnt); +bfa_status_t bfa_aen_fetch(struct bfa_aen_s *aen, + struct bfa_aen_entry_s *aen_entry, + int entry_req, enum bfa_aen_app app_id, int *entry_ret); -s32 bfa_aen_get_inst(struct bfa_aen_s *aen); +int bfa_aen_get_inst(struct bfa_aen_s *aen); #endif /* __BFA_AEN_H__ */ diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_aen.h b/drivers/scsi/bfa/include/defs/bfa_defs_aen.h index 4c81a61..3524469 100644 --- a/drivers/scsi/bfa/include/defs/bfa_defs_aen.h +++ b/drivers/scsi/bfa/include/defs/bfa_defs_aen.h @@ -30,6 +30,16 @@ #include #include +#define BFA_AEN_MAX_APP 5 + +enum bfa_aen_app { + bfa_aen_app_bcu = 0, /* No thread for bcu */ + bfa_aen_app_hcm = 1, + bfa_aen_app_cim = 2, + bfa_aen_app_snia = 3, + bfa_aen_app_test = 4, /* To be removed after unit test */ +}; + enum bfa_aen_category { BFA_AEN_CAT_ADAPTER = 1, BFA_AEN_CAT_PORT = 2, diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_ioc.h b/drivers/scsi/bfa/include/defs/bfa_defs_ioc.h index 6c721b1..8d8e6a9 100644 --- a/drivers/scsi/bfa/include/defs/bfa_defs_ioc.h +++ b/drivers/scsi/bfa/include/defs/bfa_defs_ioc.h @@ -144,8 +144,8 @@ enum bfa_ioc_aen_event { * BFA IOC level event data, now just a place holder */ struct bfa_ioc_aen_data_s { - enum bfa_ioc_type_e ioc_type; wwn_t pwwn; + s16 ioc_type; mac_t mac; }; diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_lport.h b/drivers/scsi/bfa/include/defs/bfa_defs_lport.h index 7359f82..0952a13 100644 --- a/drivers/scsi/bfa/include/defs/bfa_defs_lport.h +++ b/drivers/scsi/bfa/include/defs/bfa_defs_lport.h @@ -59,8 +59,8 @@ enum bfa_lport_aen_event { */ struct bfa_lport_aen_data_s { u16 vf_id; /* vf_id of this logical port */ - u16 rsvd; - enum bfa_port_role roles; /* Logical port mode,IM/TM/IP etc */ + s16 roles; /* Logical port mode,IM/TM/IP etc */ + u32 rsvd; wwn_t ppwwn; /* WWN of its physical port */ wwn_t lpwwn; /* WWN of this logical port */ }; diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_port.h b/drivers/scsi/bfa/include/defs/bfa_defs_port.h index 1c74a8b..501bc97 100644 --- a/drivers/scsi/bfa/include/defs/bfa_defs_port.h +++ b/drivers/scsi/bfa/include/defs/bfa_defs_port.h @@ -234,14 +234,15 @@ enum bfa_port_aen_sfp_pom { }; struct bfa_port_aen_data_s { - enum bfa_ioc_type_e ioc_type; - wwn_t pwwn; /* WWN of the physical port */ - wwn_t fwwn; /* WWN of the fabric port */ - mac_t mac; /* MAC address of the ethernet port, - * applicable to CNA port only */ - int phy_port_num; /*! For SFP related events */ - enum bfa_port_aen_sfp_pom level; /* Only transitions will - * be informed */ + wwn_t pwwn; /* WWN of the physical port */ + wwn_t fwwn; /* WWN of the fabric port */ + s32 phy_port_num; /*! For SFP related events */ + s16 ioc_type; + s16 level; /* Only transitions will + * be informed */ + struct mac_s mac; /* MAC address of the ethernet port, + * applicable to CNA port only */ + s16 rsvd; }; #endif /* __BFA_DEFS_PORT_H__ */ -- cgit v0.10.2 From 816e49b8ed209e5e08d4c43359635cbca17e7196 Mon Sep 17 00:00:00 2001 From: Krishna Gudipati Date: Fri, 5 Mar 2010 19:36:56 -0800 Subject: [SCSI] bfa: IOC recovery fix in fcmode. ioc_recover failed to work in fcmode. Fixed the code to initialize the ioc_regs.err_set during the notify_hbfail. Signed-off-by: Krishna Gudipati Signed-off-by: James Bottomley diff --git a/drivers/scsi/bfa/bfa_ioc_ct.c b/drivers/scsi/bfa/bfa_ioc_ct.c index 0430edd..469da95 100644 --- a/drivers/scsi/bfa/bfa_ioc_ct.c +++ b/drivers/scsi/bfa/bfa_ioc_ct.c @@ -171,10 +171,14 @@ bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc) static void bfa_ioc_ct_notify_hbfail(struct bfa_ioc_s *ioc) { - - bfa_reg_write(ioc->ioc_regs.ll_halt, __FW_INIT_HALT_P); - /* Wait for halt to take effect */ - bfa_reg_read(ioc->ioc_regs.ll_halt); + if (ioc->cna) { + bfa_reg_write(ioc->ioc_regs.ll_halt, __FW_INIT_HALT_P); + /* Wait for halt to take effect */ + bfa_reg_read(ioc->ioc_regs.ll_halt); + } else { + bfa_reg_write(ioc->ioc_regs.err_set, __PSS_ERR_STATUS_SET); + bfa_reg_read(ioc->ioc_regs.err_set); + } } /** @@ -254,6 +258,11 @@ bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc) */ ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START); ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CT; + + /* + * err set reg : for notification of hb failure in fcmode + */ + ioc->ioc_regs.err_set = (rb + ERR_SET_REG); } /** -- cgit v0.10.2 From f5713c5dfb4d61cd77debf61d3873eb36877ff1f Mon Sep 17 00:00:00 2001 From: Krishna Gudipati Date: Fri, 5 Mar 2010 19:37:09 -0800 Subject: [SCSI] bfa: Fix Command Queue (CPE) full condition check and ack CPE interrupt. Fixed the issue of not acknowledging the command queue full-to-non-full interrupt. Implemented separate acknowledging functions for different ASIC and interrupt mode. Fixed the case of missing CPE interrupt by always processing the pending requests in the completion path. Signed-off-by: Krishna Gudipati Signed-off-by: James Bottomley diff --git a/drivers/scsi/bfa/bfa_hw_cb.c b/drivers/scsi/bfa/bfa_hw_cb.c index ede1438..871a4e2 100644 --- a/drivers/scsi/bfa/bfa_hw_cb.c +++ b/drivers/scsi/bfa/bfa_hw_cb.c @@ -53,6 +53,18 @@ bfa_hwcb_reginit(struct bfa_s *bfa) } void +bfa_hwcb_reqq_ack(struct bfa_s *bfa, int reqq) +{ +} + +static void +bfa_hwcb_reqq_ack_msix(struct bfa_s *bfa, int reqq) +{ + bfa_reg_write(bfa->iocfc.bfa_regs.intr_status, + __HFN_INT_CPE_Q0 << CPE_Q_NUM(bfa_ioc_pcifn(&bfa->ioc), reqq)); +} + +void bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq) { } @@ -136,6 +148,7 @@ bfa_hwcb_msix_uninstall(struct bfa_s *bfa) void bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix) { + bfa->iocfc.hwif.hw_reqq_ack = bfa_hwcb_reqq_ack_msix; bfa->iocfc.hwif.hw_rspq_ack = bfa_hwcb_rspq_ack_msix; } diff --git a/drivers/scsi/bfa/bfa_hw_ct.c b/drivers/scsi/bfa/bfa_hw_ct.c index 51ae574..76ceb9a 100644 --- a/drivers/scsi/bfa/bfa_hw_ct.c +++ b/drivers/scsi/bfa/bfa_hw_ct.c @@ -85,6 +85,15 @@ bfa_hwct_reginit(struct bfa_s *bfa) } void +bfa_hwct_reqq_ack(struct bfa_s *bfa, int reqq) +{ + u32 r32; + + r32 = bfa_reg_read(bfa->iocfc.bfa_regs.cpe_q_ctrl[reqq]); + bfa_reg_write(bfa->iocfc.bfa_regs.cpe_q_ctrl[reqq], r32); +} + +void bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq) { u32 r32; diff --git a/drivers/scsi/bfa/bfa_intr.c b/drivers/scsi/bfa/bfa_intr.c index c422546..0eba3f9 100644 --- a/drivers/scsi/bfa/bfa_intr.c +++ b/drivers/scsi/bfa/bfa_intr.c @@ -34,6 +34,26 @@ bfa_msix_lpu(struct bfa_s *bfa) bfa_ioc_mbox_isr(&bfa->ioc); } +static void +bfa_reqq_resume(struct bfa_s *bfa, int qid) +{ + struct list_head *waitq, *qe, *qen; + struct bfa_reqq_wait_s *wqe; + + waitq = bfa_reqq(bfa, qid); + list_for_each_safe(qe, qen, waitq) { + /** + * Callback only as long as there is room in request queue + */ + if (bfa_reqq_full(bfa, qid)) + break; + + list_del(qe); + wqe = (struct bfa_reqq_wait_s *) qe; + wqe->qresume(wqe->cbarg); + } +} + void bfa_msix_all(struct bfa_s *bfa, int vec) { @@ -128,23 +148,18 @@ bfa_isr_disable(struct bfa_s *bfa) void bfa_msix_reqq(struct bfa_s *bfa, int qid) { - struct list_head *waitq, *qe, *qen; - struct bfa_reqq_wait_s *wqe; + struct list_head *waitq; qid &= (BFI_IOC_MAX_CQS - 1); - waitq = bfa_reqq(bfa, qid); - list_for_each_safe(qe, qen, waitq) { - /** - * Callback only as long as there is room in request queue - */ - if (bfa_reqq_full(bfa, qid)) - break; + bfa->iocfc.hwif.hw_reqq_ack(bfa, qid); - list_del(qe); - wqe = (struct bfa_reqq_wait_s *) qe; - wqe->qresume(wqe->cbarg); - } + /** + * Resume any pending requests in the corresponding reqq. + */ + waitq = bfa_reqq(bfa, qid); + if (!list_empty(waitq)) + bfa_reqq_resume(bfa, qid); } void @@ -158,26 +173,27 @@ bfa_isr_unhandled(struct bfa_s *bfa, struct bfi_msg_s *m) } void -bfa_msix_rspq(struct bfa_s *bfa, int rsp_qid) +bfa_msix_rspq(struct bfa_s *bfa, int qid) { - struct bfi_msg_s *m; - u32 pi, ci; + struct bfi_msg_s *m; + u32 pi, ci; + struct list_head *waitq; - bfa_trc_fp(bfa, rsp_qid); + bfa_trc_fp(bfa, qid); - rsp_qid &= (BFI_IOC_MAX_CQS - 1); + qid &= (BFI_IOC_MAX_CQS - 1); - bfa->iocfc.hwif.hw_rspq_ack(bfa, rsp_qid); + bfa->iocfc.hwif.hw_rspq_ack(bfa, qid); - ci = bfa_rspq_ci(bfa, rsp_qid); - pi = bfa_rspq_pi(bfa, rsp_qid); + ci = bfa_rspq_ci(bfa, qid); + pi = bfa_rspq_pi(bfa, qid); bfa_trc_fp(bfa, ci); bfa_trc_fp(bfa, pi); if (bfa->rme_process) { while (ci != pi) { - m = bfa_rspq_elem(bfa, rsp_qid, ci); + m = bfa_rspq_elem(bfa, qid, ci); bfa_assert_fp(m->mhdr.msg_class < BFI_MC_MAX); bfa_isrs[m->mhdr.msg_class] (bfa, m); @@ -189,9 +205,16 @@ bfa_msix_rspq(struct bfa_s *bfa, int rsp_qid) /** * update CI */ - bfa_rspq_ci(bfa, rsp_qid) = pi; - bfa_reg_write(bfa->iocfc.bfa_regs.rme_q_ci[rsp_qid], pi); + bfa_rspq_ci(bfa, qid) = pi; + bfa_reg_write(bfa->iocfc.bfa_regs.rme_q_ci[qid], pi); bfa_os_mmiowb(); + + /** + * Resume any pending requests in the corresponding reqq. + */ + waitq = bfa_reqq(bfa, qid); + if (!list_empty(waitq)) + bfa_reqq_resume(bfa, qid); } void diff --git a/drivers/scsi/bfa/bfa_iocfc.c b/drivers/scsi/bfa/bfa_iocfc.c index 137591c..a5551db 100644 --- a/drivers/scsi/bfa/bfa_iocfc.c +++ b/drivers/scsi/bfa/bfa_iocfc.c @@ -172,6 +172,7 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, */ if (bfa_ioc_devid(&bfa->ioc) == BFA_PCI_DEVICE_ID_CT) { iocfc->hwif.hw_reginit = bfa_hwct_reginit; + iocfc->hwif.hw_reqq_ack = bfa_hwct_reqq_ack; iocfc->hwif.hw_rspq_ack = bfa_hwct_rspq_ack; iocfc->hwif.hw_msix_init = bfa_hwct_msix_init; iocfc->hwif.hw_msix_install = bfa_hwct_msix_install; @@ -180,6 +181,7 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, iocfc->hwif.hw_msix_getvecs = bfa_hwct_msix_getvecs; } else { iocfc->hwif.hw_reginit = bfa_hwcb_reginit; + iocfc->hwif.hw_reqq_ack = bfa_hwcb_reqq_ack; iocfc->hwif.hw_rspq_ack = bfa_hwcb_rspq_ack; iocfc->hwif.hw_msix_init = bfa_hwcb_msix_init; iocfc->hwif.hw_msix_install = bfa_hwcb_msix_install; diff --git a/drivers/scsi/bfa/bfa_iocfc.h b/drivers/scsi/bfa/bfa_iocfc.h index ce9a830..fbb4bdc 100644 --- a/drivers/scsi/bfa/bfa_iocfc.h +++ b/drivers/scsi/bfa/bfa_iocfc.h @@ -54,6 +54,7 @@ struct bfa_msix_s { */ struct bfa_hwif_s { void (*hw_reginit)(struct bfa_s *bfa); + void (*hw_reqq_ack)(struct bfa_s *bfa, int reqq); void (*hw_rspq_ack)(struct bfa_s *bfa, int rspq); void (*hw_msix_init)(struct bfa_s *bfa, int nvecs); void (*hw_msix_install)(struct bfa_s *bfa); @@ -143,6 +144,7 @@ void bfa_msix_rspq(struct bfa_s *bfa, int vec); void bfa_msix_lpu_err(struct bfa_s *bfa, int vec); void bfa_hwcb_reginit(struct bfa_s *bfa); +void bfa_hwcb_reqq_ack(struct bfa_s *bfa, int rspq); void bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq); void bfa_hwcb_msix_init(struct bfa_s *bfa, int nvecs); void bfa_hwcb_msix_install(struct bfa_s *bfa); @@ -151,6 +153,7 @@ void bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix); void bfa_hwcb_msix_getvecs(struct bfa_s *bfa, u32 *vecmap, u32 *nvecs, u32 *maxvec); void bfa_hwct_reginit(struct bfa_s *bfa); +void bfa_hwct_reqq_ack(struct bfa_s *bfa, int rspq); void bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq); void bfa_hwct_msix_init(struct bfa_s *bfa, int nvecs); void bfa_hwct_msix_install(struct bfa_s *bfa); -- cgit v0.10.2 From 78f915f7b095dda76970c8c9568489fa779ef73f Mon Sep 17 00:00:00 2001 From: Krishna Gudipati Date: Fri, 5 Mar 2010 19:37:18 -0800 Subject: [SCSI] bfa: In MSIX mode, ignore spurious RME interrupts when FCoE ports are in FW mismatch state. Use dummy interrupt handlers till chip initialization is complete. Install real interrupt handlers after chip initialization. Also removed msix installation code in bfa_iocfc_init(). Signed-off-by: Krishna Gudipati Signed-off-by: James Bottomley diff --git a/drivers/scsi/bfa/bfa_ioc_ct.c b/drivers/scsi/bfa/bfa_ioc_ct.c index 469da95..2431922 100644 --- a/drivers/scsi/bfa/bfa_ioc_ct.c +++ b/drivers/scsi/bfa/bfa_ioc_ct.c @@ -331,12 +331,12 @@ bfa_ioc_ct_pll_init(struct bfa_ioc_s *ioc) */ bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg); - pll_sclk = __APP_PLL_312_ENABLE | __APP_PLL_312_LRESETN | - __APP_PLL_312_RSEL200500 | __APP_PLL_312_P0_1(0U) | + pll_sclk = __APP_PLL_312_LRESETN | __APP_PLL_312_ENARST | + __APP_PLL_312_RSEL200500 | __APP_PLL_312_P0_1(3U) | __APP_PLL_312_JITLMT0_1(3U) | __APP_PLL_312_CNTLMT0_1(1U); - pll_fclk = __APP_PLL_425_ENABLE | __APP_PLL_425_LRESETN | - __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(0U) | + pll_fclk = __APP_PLL_425_LRESETN | __APP_PLL_425_ENARST | + __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(3U) | __APP_PLL_425_JITLMT0_1(3U) | __APP_PLL_425_CNTLMT0_1(1U); @@ -366,36 +366,27 @@ bfa_ioc_ct_pll_init(struct bfa_ioc_s *ioc) bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU); bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU); - bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, - __APP_PLL_312_LOGIC_SOFT_RESET); - bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, - __APP_PLL_312_BYPASS | - __APP_PLL_312_LOGIC_SOFT_RESET); - bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, - __APP_PLL_425_LOGIC_SOFT_RESET); - bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, - __APP_PLL_425_BYPASS | - __APP_PLL_425_LOGIC_SOFT_RESET); - bfa_os_udelay(2); - bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, - __APP_PLL_312_LOGIC_SOFT_RESET); - bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, - __APP_PLL_425_LOGIC_SOFT_RESET); - - bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, - pll_sclk | __APP_PLL_312_LOGIC_SOFT_RESET); - bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, - pll_fclk | __APP_PLL_425_LOGIC_SOFT_RESET); + bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk | + __APP_PLL_312_LOGIC_SOFT_RESET); + bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk | + __APP_PLL_425_LOGIC_SOFT_RESET); + bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk | + __APP_PLL_312_LOGIC_SOFT_RESET | __APP_PLL_312_ENABLE); + bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk | + __APP_PLL_425_LOGIC_SOFT_RESET | __APP_PLL_425_ENABLE); /** * Wait for PLLs to lock. */ + bfa_reg_read(rb + HOSTFN0_INT_MSK); bfa_os_udelay(2000); bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU); bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU); - bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk); - bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk); + bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk | + __APP_PLL_312_ENABLE); + bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk | + __APP_PLL_425_ENABLE); bfa_reg_write((rb + MBIST_CTL_REG), __EDRAM_BISTR_START); bfa_os_udelay(1000); diff --git a/drivers/scsi/bfa/bfa_iocfc.c b/drivers/scsi/bfa/bfa_iocfc.c index a5551db..6677f83 100644 --- a/drivers/scsi/bfa/bfa_iocfc.c +++ b/drivers/scsi/bfa/bfa_iocfc.c @@ -659,7 +659,6 @@ bfa_iocfc_init(struct bfa_s *bfa) { bfa->iocfc.action = BFA_IOCFC_ACT_INIT; bfa_ioc_enable(&bfa->ioc); - bfa_msix_install(bfa); } /** -- cgit v0.10.2 From 13cc20c5e764e6ef8d57f33980ab8c386c25fb4d Mon Sep 17 00:00:00 2001 From: Krishna Gudipati Date: Fri, 5 Mar 2010 19:37:29 -0800 Subject: [SCSI] bfa: IOC fixes, check for IOC down condition. Currently BFA was not checking for IOC down condition when issuing getstats/clearstats Add check to see if IOC is operational, before issuing getstats/clearstats. Signed-off-by: Krishna Gudipati Signed-off-by: James Bottomley diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c index 2f09d17..4d9a47c 100644 --- a/drivers/scsi/bfa/bfa_ioc.c +++ b/drivers/scsi/bfa/bfa_ioc.c @@ -1129,9 +1129,6 @@ bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type, if (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ) boot_type = BFI_BOOT_TYPE_FLASH; fwimg = bfa_ioc_fwimg_get_chunk(ioc, chunkno); - fwimg[BFI_BOOT_TYPE_OFF / sizeof(u32)] = bfa_os_swap32(boot_type); - fwimg[BFI_BOOT_PARAM_OFF / sizeof(u32)] = - bfa_os_swap32(boot_param); pgnum = bfa_ioc_smem_pgnum(ioc, loff); pgoff = bfa_ioc_smem_pgoff(ioc, loff); @@ -1166,6 +1163,14 @@ bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type, bfa_reg_write(ioc->ioc_regs.host_page_num_fn, bfa_ioc_smem_pgnum(ioc, 0)); + + /* + * Set boot type and boot param at the end. + */ + bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_BOOT_TYPE_OFF, + bfa_os_swap32(boot_type)); + bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_BOOT_PARAM_OFF, + bfa_os_swap32(boot_param)); } static void diff --git a/drivers/scsi/bfa/bfa_iocfc.c b/drivers/scsi/bfa/bfa_iocfc.c index 6677f83..a76de26 100644 --- a/drivers/scsi/bfa/bfa_iocfc.c +++ b/drivers/scsi/bfa/bfa_iocfc.c @@ -801,6 +801,11 @@ bfa_iocfc_get_stats(struct bfa_s *bfa, struct bfa_iocfc_stats_s *stats, return BFA_STATUS_DEVBUSY; } + if (!bfa_iocfc_is_operational(bfa)) { + bfa_trc(bfa, 0); + return BFA_STATUS_IOC_NON_OP; + } + iocfc->stats_busy = BFA_TRUE; iocfc->stats_ret = stats; iocfc->stats_cbfn = cbfn; @@ -821,6 +826,11 @@ bfa_iocfc_clear_stats(struct bfa_s *bfa, bfa_cb_ioc_t cbfn, void *cbarg) return BFA_STATUS_DEVBUSY; } + if (!bfa_iocfc_is_operational(bfa)) { + bfa_trc(bfa, 0); + return BFA_STATUS_IOC_NON_OP; + } + iocfc->stats_busy = BFA_TRUE; iocfc->stats_cbfn = cbfn; iocfc->stats_cbarg = cbarg; -- cgit v0.10.2 From 1c8a4c37494932acd59079b4fc8d8f69fb329c2a Mon Sep 17 00:00:00 2001 From: Krishna Gudipati Date: Fri, 5 Mar 2010 19:37:37 -0800 Subject: [SCSI] bfa: Rename pport to fcport in BFA FCS. Rename pport structures to fcport in BFA FCS, to resolve confusion about the port structures in the firmware, and make sure the SG page is setup correctly. Signed-off-by: Krishna Gudipati Signed-off-by: James Bottomley diff --git a/drivers/scsi/bfa/bfa_fcport.c b/drivers/scsi/bfa/bfa_fcport.c index bdea7f0..f392a7f 100644 --- a/drivers/scsi/bfa/bfa_fcport.c +++ b/drivers/scsi/bfa/bfa_fcport.c @@ -23,34 +23,40 @@ #include #include -BFA_TRC_FILE(HAL, PPORT); -BFA_MODULE(pport); +BFA_TRC_FILE(HAL, FCPORT); +BFA_MODULE(fcport); /* * The port is considered disabled if corresponding physical port or IOC are * disabled explicitly */ #define BFA_PORT_IS_DISABLED(bfa) \ - ((bfa_pport_is_disabled(bfa) == BFA_TRUE) || \ + ((bfa_fcport_is_disabled(bfa) == BFA_TRUE) || \ (bfa_ioc_is_disabled(&bfa->ioc) == BFA_TRUE)) /* * forward declarations */ -static bfa_boolean_t bfa_pport_send_enable(struct bfa_pport_s *port); -static bfa_boolean_t bfa_pport_send_disable(struct bfa_pport_s *port); -static void bfa_pport_update_linkinfo(struct bfa_pport_s *pport); -static void bfa_pport_reset_linkinfo(struct bfa_pport_s *pport); -static void bfa_pport_set_wwns(struct bfa_pport_s *port); -static void __bfa_cb_port_event(void *cbarg, bfa_boolean_t complete); +static bfa_boolean_t bfa_fcport_send_enable(struct bfa_fcport_s *fcport); +static bfa_boolean_t bfa_fcport_send_disable(struct bfa_fcport_s *fcport); +static void bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport); +static void bfa_fcport_reset_linkinfo(struct bfa_fcport_s *fcport); +static void bfa_fcport_set_wwns(struct bfa_fcport_s *fcport); +static void __bfa_cb_fcport_event(void *cbarg, bfa_boolean_t complete); +static void bfa_fcport_callback(struct bfa_fcport_s *fcport, + enum bfa_pport_linkstate event); +static void bfa_fcport_queue_cb(struct bfa_fcport_ln_s *ln, + enum bfa_pport_linkstate event); +static void __bfa_cb_fcport_stats(void *cbarg, bfa_boolean_t complete); +static void __bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete); +static void bfa_fcport_stats_timeout(void *cbarg); +static void bfa_fcport_stats_clr_timeout(void *cbarg); + static void __bfa_cb_port_stats(void *cbarg, bfa_boolean_t complete); static void __bfa_cb_port_stats_clr(void *cbarg, bfa_boolean_t complete); static void bfa_port_stats_timeout(void *cbarg); static void bfa_port_stats_clr_timeout(void *cbarg); -static void bfa_pport_callback(struct bfa_pport_s *pport, - enum bfa_pport_linkstate event); -static void bfa_pport_queue_cb(struct bfa_pport_ln_s *ln, - enum bfa_pport_linkstate event); + /** * bfa_pport_private */ @@ -58,87 +64,86 @@ static void bfa_pport_queue_cb(struct bfa_pport_ln_s *ln, /** * BFA port state machine events */ -enum bfa_pport_sm_event { - BFA_PPORT_SM_START = 1, /* start port state machine */ - BFA_PPORT_SM_STOP = 2, /* stop port state machine */ - BFA_PPORT_SM_ENABLE = 3, /* enable port */ - BFA_PPORT_SM_DISABLE = 4, /* disable port state machine */ - BFA_PPORT_SM_FWRSP = 5, /* firmware enable/disable rsp */ - BFA_PPORT_SM_LINKUP = 6, /* firmware linkup event */ - BFA_PPORT_SM_LINKDOWN = 7, /* firmware linkup down */ - BFA_PPORT_SM_QRESUME = 8, /* CQ space available */ - BFA_PPORT_SM_HWFAIL = 9, /* IOC h/w failure */ +enum bfa_fcport_sm_event { + BFA_FCPORT_SM_START = 1, /* start port state machine */ + BFA_FCPORT_SM_STOP = 2, /* stop port state machine */ + BFA_FCPORT_SM_ENABLE = 3, /* enable port */ + BFA_FCPORT_SM_DISABLE = 4, /* disable port state machine */ + BFA_FCPORT_SM_FWRSP = 5, /* firmware enable/disable rsp */ + BFA_FCPORT_SM_LINKUP = 6, /* firmware linkup event */ + BFA_FCPORT_SM_LINKDOWN = 7, /* firmware linkup down */ + BFA_FCPORT_SM_QRESUME = 8, /* CQ space available */ + BFA_FCPORT_SM_HWFAIL = 9, /* IOC h/w failure */ }; /** * BFA port link notification state machine events */ -enum bfa_pport_ln_sm_event { - BFA_PPORT_LN_SM_LINKUP = 1, /* linkup event */ - BFA_PPORT_LN_SM_LINKDOWN = 2, /* linkdown event */ - BFA_PPORT_LN_SM_NOTIFICATION = 3 /* done notification */ +enum bfa_fcport_ln_sm_event { + BFA_FCPORT_LN_SM_LINKUP = 1, /* linkup event */ + BFA_FCPORT_LN_SM_LINKDOWN = 2, /* linkdown event */ + BFA_FCPORT_LN_SM_NOTIFICATION = 3 /* done notification */ }; -static void bfa_pport_sm_uninit(struct bfa_pport_s *pport, - enum bfa_pport_sm_event event); -static void bfa_pport_sm_enabling_qwait(struct bfa_pport_s *pport, - enum bfa_pport_sm_event event); -static void bfa_pport_sm_enabling(struct bfa_pport_s *pport, - enum bfa_pport_sm_event event); -static void bfa_pport_sm_linkdown(struct bfa_pport_s *pport, - enum bfa_pport_sm_event event); -static void bfa_pport_sm_linkup(struct bfa_pport_s *pport, - enum bfa_pport_sm_event event); -static void bfa_pport_sm_disabling(struct bfa_pport_s *pport, - enum bfa_pport_sm_event event); -static void bfa_pport_sm_disabling_qwait(struct bfa_pport_s *pport, - enum bfa_pport_sm_event event); -static void bfa_pport_sm_disabled(struct bfa_pport_s *pport, - enum bfa_pport_sm_event event); -static void bfa_pport_sm_stopped(struct bfa_pport_s *pport, - enum bfa_pport_sm_event event); -static void bfa_pport_sm_iocdown(struct bfa_pport_s *pport, - enum bfa_pport_sm_event event); -static void bfa_pport_sm_iocfail(struct bfa_pport_s *pport, - enum bfa_pport_sm_event event); - -static void bfa_pport_ln_sm_dn(struct bfa_pport_ln_s *ln, - enum bfa_pport_ln_sm_event event); -static void bfa_pport_ln_sm_dn_nf(struct bfa_pport_ln_s *ln, - enum bfa_pport_ln_sm_event event); -static void bfa_pport_ln_sm_dn_up_nf(struct bfa_pport_ln_s *ln, - enum bfa_pport_ln_sm_event event); -static void bfa_pport_ln_sm_up(struct bfa_pport_ln_s *ln, - enum bfa_pport_ln_sm_event event); -static void bfa_pport_ln_sm_up_nf(struct bfa_pport_ln_s *ln, - enum bfa_pport_ln_sm_event event); -static void bfa_pport_ln_sm_up_dn_nf(struct bfa_pport_ln_s *ln, - enum bfa_pport_ln_sm_event event); -static void bfa_pport_ln_sm_up_dn_up_nf(struct bfa_pport_ln_s *ln, - enum bfa_pport_ln_sm_event event); +static void bfa_fcport_sm_uninit(struct bfa_fcport_s *fcport, + enum bfa_fcport_sm_event event); +static void bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport, + enum bfa_fcport_sm_event event); +static void bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport, + enum bfa_fcport_sm_event event); +static void bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport, + enum bfa_fcport_sm_event event); +static void bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport, + enum bfa_fcport_sm_event event); +static void bfa_fcport_sm_disabling(struct bfa_fcport_s *fcport, + enum bfa_fcport_sm_event event); +static void bfa_fcport_sm_disabling_qwait(struct bfa_fcport_s *fcport, + enum bfa_fcport_sm_event event); +static void bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport, + enum bfa_fcport_sm_event event); +static void bfa_fcport_sm_stopped(struct bfa_fcport_s *fcport, + enum bfa_fcport_sm_event event); +static void bfa_fcport_sm_iocdown(struct bfa_fcport_s *fcport, + enum bfa_fcport_sm_event event); +static void bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport, + enum bfa_fcport_sm_event event); + +static void bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln, + enum bfa_fcport_ln_sm_event event); +static void bfa_fcport_ln_sm_dn_nf(struct bfa_fcport_ln_s *ln, + enum bfa_fcport_ln_sm_event event); +static void bfa_fcport_ln_sm_dn_up_nf(struct bfa_fcport_ln_s *ln, + enum bfa_fcport_ln_sm_event event); +static void bfa_fcport_ln_sm_up(struct bfa_fcport_ln_s *ln, + enum bfa_fcport_ln_sm_event event); +static void bfa_fcport_ln_sm_up_nf(struct bfa_fcport_ln_s *ln, + enum bfa_fcport_ln_sm_event event); +static void bfa_fcport_ln_sm_up_dn_nf(struct bfa_fcport_ln_s *ln, + enum bfa_fcport_ln_sm_event event); +static void bfa_fcport_ln_sm_up_dn_up_nf(struct bfa_fcport_ln_s *ln, + enum bfa_fcport_ln_sm_event event); static struct bfa_sm_table_s hal_pport_sm_table[] = { - {BFA_SM(bfa_pport_sm_uninit), BFA_PPORT_ST_UNINIT}, - {BFA_SM(bfa_pport_sm_enabling_qwait), BFA_PPORT_ST_ENABLING_QWAIT}, - {BFA_SM(bfa_pport_sm_enabling), BFA_PPORT_ST_ENABLING}, - {BFA_SM(bfa_pport_sm_linkdown), BFA_PPORT_ST_LINKDOWN}, - {BFA_SM(bfa_pport_sm_linkup), BFA_PPORT_ST_LINKUP}, - {BFA_SM(bfa_pport_sm_disabling_qwait), - BFA_PPORT_ST_DISABLING_QWAIT}, - {BFA_SM(bfa_pport_sm_disabling), BFA_PPORT_ST_DISABLING}, - {BFA_SM(bfa_pport_sm_disabled), BFA_PPORT_ST_DISABLED}, - {BFA_SM(bfa_pport_sm_stopped), BFA_PPORT_ST_STOPPED}, - {BFA_SM(bfa_pport_sm_iocdown), BFA_PPORT_ST_IOCDOWN}, - {BFA_SM(bfa_pport_sm_iocfail), BFA_PPORT_ST_IOCDOWN}, + {BFA_SM(bfa_fcport_sm_uninit), BFA_PPORT_ST_UNINIT}, + {BFA_SM(bfa_fcport_sm_enabling_qwait), BFA_PPORT_ST_ENABLING_QWAIT}, + {BFA_SM(bfa_fcport_sm_enabling), BFA_PPORT_ST_ENABLING}, + {BFA_SM(bfa_fcport_sm_linkdown), BFA_PPORT_ST_LINKDOWN}, + {BFA_SM(bfa_fcport_sm_linkup), BFA_PPORT_ST_LINKUP}, + {BFA_SM(bfa_fcport_sm_disabling_qwait), BFA_PPORT_ST_DISABLING_QWAIT}, + {BFA_SM(bfa_fcport_sm_disabling), BFA_PPORT_ST_DISABLING}, + {BFA_SM(bfa_fcport_sm_disabled), BFA_PPORT_ST_DISABLED}, + {BFA_SM(bfa_fcport_sm_stopped), BFA_PPORT_ST_STOPPED}, + {BFA_SM(bfa_fcport_sm_iocdown), BFA_PPORT_ST_IOCDOWN}, + {BFA_SM(bfa_fcport_sm_iocfail), BFA_PPORT_ST_IOCDOWN}, }; static void -bfa_pport_aen_post(struct bfa_pport_s *pport, enum bfa_port_aen_event event) +bfa_fcport_aen_post(struct bfa_fcport_s *fcport, enum bfa_port_aen_event event) { union bfa_aen_data_u aen_data; - struct bfa_log_mod_s *logmod = pport->bfa->logm; - wwn_t pwwn = pport->pwwn; + struct bfa_log_mod_s *logmod = fcport->bfa->logm; + wwn_t pwwn = fcport->pwwn; char pwwn_ptr[BFA_STRING_32]; struct bfa_ioc_attr_s ioc_attr; @@ -167,28 +172,29 @@ bfa_pport_aen_post(struct bfa_pport_s *pport, enum bfa_port_aen_event event) break; } - bfa_ioc_get_attr(&pport->bfa->ioc, &ioc_attr); + bfa_ioc_get_attr(&fcport->bfa->ioc, &ioc_attr); aen_data.port.ioc_type = ioc_attr.ioc_type; aen_data.port.pwwn = pwwn; } static void -bfa_pport_sm_uninit(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) +bfa_fcport_sm_uninit(struct bfa_fcport_s *fcport, + enum bfa_fcport_sm_event event) { - bfa_trc(pport->bfa, event); + bfa_trc(fcport->bfa, event); switch (event) { - case BFA_PPORT_SM_START: + case BFA_FCPORT_SM_START: /** * Start event after IOC is configured and BFA is started. */ - if (bfa_pport_send_enable(pport)) - bfa_sm_set_state(pport, bfa_pport_sm_enabling); + if (bfa_fcport_send_enable(fcport)) + bfa_sm_set_state(fcport, bfa_fcport_sm_enabling); else - bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait); + bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait); break; - case BFA_PPORT_SM_ENABLE: + case BFA_FCPORT_SM_ENABLE: /** * Port is persistently configured to be in enabled state. Do * not change state. Port enabling is done when START event is @@ -196,389 +202,395 @@ bfa_pport_sm_uninit(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) */ break; - case BFA_PPORT_SM_DISABLE: + case BFA_FCPORT_SM_DISABLE: /** * If a port is persistently configured to be disabled, the * first event will a port disable request. */ - bfa_sm_set_state(pport, bfa_pport_sm_disabled); + bfa_sm_set_state(fcport, bfa_fcport_sm_disabled); break; - case BFA_PPORT_SM_HWFAIL: - bfa_sm_set_state(pport, bfa_pport_sm_iocdown); + case BFA_FCPORT_SM_HWFAIL: + bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); break; default: - bfa_sm_fault(pport->bfa, event); + bfa_sm_fault(fcport->bfa, event); } } static void -bfa_pport_sm_enabling_qwait(struct bfa_pport_s *pport, - enum bfa_pport_sm_event event) +bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport, + enum bfa_fcport_sm_event event) { - bfa_trc(pport->bfa, event); + bfa_trc(fcport->bfa, event); switch (event) { - case BFA_PPORT_SM_QRESUME: - bfa_sm_set_state(pport, bfa_pport_sm_enabling); - bfa_pport_send_enable(pport); + case BFA_FCPORT_SM_QRESUME: + bfa_sm_set_state(fcport, bfa_fcport_sm_enabling); + bfa_fcport_send_enable(fcport); break; - case BFA_PPORT_SM_STOP: - bfa_reqq_wcancel(&pport->reqq_wait); - bfa_sm_set_state(pport, bfa_pport_sm_stopped); + case BFA_FCPORT_SM_STOP: + bfa_reqq_wcancel(&fcport->reqq_wait); + bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); break; - case BFA_PPORT_SM_ENABLE: + case BFA_FCPORT_SM_ENABLE: /** * Already enable is in progress. */ break; - case BFA_PPORT_SM_DISABLE: + case BFA_FCPORT_SM_DISABLE: /** * Just send disable request to firmware when room becomes * available in request queue. */ - bfa_sm_set_state(pport, bfa_pport_sm_disabled); - bfa_reqq_wcancel(&pport->reqq_wait); - bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL, + bfa_sm_set_state(fcport, bfa_fcport_sm_disabled); + bfa_reqq_wcancel(&fcport->reqq_wait); + bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); - bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE); + bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE); break; - case BFA_PPORT_SM_LINKUP: - case BFA_PPORT_SM_LINKDOWN: + case BFA_FCPORT_SM_LINKUP: + case BFA_FCPORT_SM_LINKDOWN: /** * Possible to get link events when doing back-to-back * enable/disables. */ break; - case BFA_PPORT_SM_HWFAIL: - bfa_reqq_wcancel(&pport->reqq_wait); - bfa_sm_set_state(pport, bfa_pport_sm_iocdown); + case BFA_FCPORT_SM_HWFAIL: + bfa_reqq_wcancel(&fcport->reqq_wait); + bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); break; default: - bfa_sm_fault(pport->bfa, event); + bfa_sm_fault(fcport->bfa, event); } } static void -bfa_pport_sm_enabling(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) +bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport, + enum bfa_fcport_sm_event event) { - bfa_trc(pport->bfa, event); + bfa_trc(fcport->bfa, event); switch (event) { - case BFA_PPORT_SM_FWRSP: - case BFA_PPORT_SM_LINKDOWN: - bfa_sm_set_state(pport, bfa_pport_sm_linkdown); + case BFA_FCPORT_SM_FWRSP: + case BFA_FCPORT_SM_LINKDOWN: + bfa_sm_set_state(fcport, bfa_fcport_sm_linkdown); break; - case BFA_PPORT_SM_LINKUP: - bfa_pport_update_linkinfo(pport); - bfa_sm_set_state(pport, bfa_pport_sm_linkup); + case BFA_FCPORT_SM_LINKUP: + bfa_fcport_update_linkinfo(fcport); + bfa_sm_set_state(fcport, bfa_fcport_sm_linkup); - bfa_assert(pport->event_cbfn); - bfa_pport_callback(pport, BFA_PPORT_LINKUP); + bfa_assert(fcport->event_cbfn); + bfa_fcport_callback(fcport, BFA_PPORT_LINKUP); break; - case BFA_PPORT_SM_ENABLE: + case BFA_FCPORT_SM_ENABLE: /** * Already being enabled. */ break; - case BFA_PPORT_SM_DISABLE: - if (bfa_pport_send_disable(pport)) - bfa_sm_set_state(pport, bfa_pport_sm_disabling); + case BFA_FCPORT_SM_DISABLE: + if (bfa_fcport_send_disable(fcport)) + bfa_sm_set_state(fcport, bfa_fcport_sm_disabling); else - bfa_sm_set_state(pport, bfa_pport_sm_disabling_qwait); + bfa_sm_set_state(fcport, bfa_fcport_sm_disabling_qwait); - bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL, + bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); - bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE); + bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE); break; - case BFA_PPORT_SM_STOP: - bfa_sm_set_state(pport, bfa_pport_sm_stopped); + case BFA_FCPORT_SM_STOP: + bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); break; - case BFA_PPORT_SM_HWFAIL: - bfa_sm_set_state(pport, bfa_pport_sm_iocdown); + case BFA_FCPORT_SM_HWFAIL: + bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); break; default: - bfa_sm_fault(pport->bfa, event); + bfa_sm_fault(fcport->bfa, event); } } static void -bfa_pport_sm_linkdown(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) +bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport, + enum bfa_fcport_sm_event event) { - bfa_trc(pport->bfa, event); + bfa_trc(fcport->bfa, event); switch (event) { - case BFA_PPORT_SM_LINKUP: - bfa_pport_update_linkinfo(pport); - bfa_sm_set_state(pport, bfa_pport_sm_linkup); - bfa_assert(pport->event_cbfn); - bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL, + case BFA_FCPORT_SM_LINKUP: + bfa_fcport_update_linkinfo(fcport); + bfa_sm_set_state(fcport, bfa_fcport_sm_linkup); + bfa_assert(fcport->event_cbfn); + bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkup"); - bfa_pport_callback(pport, BFA_PPORT_LINKUP); - bfa_pport_aen_post(pport, BFA_PORT_AEN_ONLINE); + bfa_fcport_callback(fcport, BFA_PPORT_LINKUP); + bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ONLINE); /** * If QoS is enabled and it is not online, * Send a separate event. */ - if ((pport->cfg.qos_enabled) - && (bfa_os_ntohl(pport->qos_attr.state) != BFA_QOS_ONLINE)) - bfa_pport_aen_post(pport, BFA_PORT_AEN_QOS_NEG); + if ((fcport->cfg.qos_enabled) + && (bfa_os_ntohl(fcport->qos_attr.state) != BFA_QOS_ONLINE)) + bfa_fcport_aen_post(fcport, BFA_PORT_AEN_QOS_NEG); break; - case BFA_PPORT_SM_LINKDOWN: + case BFA_FCPORT_SM_LINKDOWN: /** * Possible to get link down event. */ break; - case BFA_PPORT_SM_ENABLE: + case BFA_FCPORT_SM_ENABLE: /** * Already enabled. */ break; - case BFA_PPORT_SM_DISABLE: - if (bfa_pport_send_disable(pport)) - bfa_sm_set_state(pport, bfa_pport_sm_disabling); + case BFA_FCPORT_SM_DISABLE: + if (bfa_fcport_send_disable(fcport)) + bfa_sm_set_state(fcport, bfa_fcport_sm_disabling); else - bfa_sm_set_state(pport, bfa_pport_sm_disabling_qwait); + bfa_sm_set_state(fcport, bfa_fcport_sm_disabling_qwait); - bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL, + bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); - bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE); + bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE); break; - case BFA_PPORT_SM_STOP: - bfa_sm_set_state(pport, bfa_pport_sm_stopped); + case BFA_FCPORT_SM_STOP: + bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); break; - case BFA_PPORT_SM_HWFAIL: - bfa_sm_set_state(pport, bfa_pport_sm_iocdown); + case BFA_FCPORT_SM_HWFAIL: + bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); break; default: - bfa_sm_fault(pport->bfa, event); + bfa_sm_fault(fcport->bfa, event); } } static void -bfa_pport_sm_linkup(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) +bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport, + enum bfa_fcport_sm_event event) { - bfa_trc(pport->bfa, event); + bfa_trc(fcport->bfa, event); switch (event) { - case BFA_PPORT_SM_ENABLE: + case BFA_FCPORT_SM_ENABLE: /** * Already enabled. */ break; - case BFA_PPORT_SM_DISABLE: - if (bfa_pport_send_disable(pport)) - bfa_sm_set_state(pport, bfa_pport_sm_disabling); + case BFA_FCPORT_SM_DISABLE: + if (bfa_fcport_send_disable(fcport)) + bfa_sm_set_state(fcport, bfa_fcport_sm_disabling); else - bfa_sm_set_state(pport, bfa_pport_sm_disabling_qwait); + bfa_sm_set_state(fcport, bfa_fcport_sm_disabling_qwait); - bfa_pport_reset_linkinfo(pport); - bfa_pport_callback(pport, BFA_PPORT_LINKDOWN); - bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL, + bfa_fcport_reset_linkinfo(fcport); + bfa_fcport_callback(fcport, BFA_PPORT_LINKDOWN); + bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); - bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE); - bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE); + bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE); + bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE); break; - case BFA_PPORT_SM_LINKDOWN: - bfa_sm_set_state(pport, bfa_pport_sm_linkdown); - bfa_pport_reset_linkinfo(pport); - bfa_pport_callback(pport, BFA_PPORT_LINKDOWN); - bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL, + case BFA_FCPORT_SM_LINKDOWN: + bfa_sm_set_state(fcport, bfa_fcport_sm_linkdown); + bfa_fcport_reset_linkinfo(fcport); + bfa_fcport_callback(fcport, BFA_PPORT_LINKDOWN); + bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkdown"); - if (BFA_PORT_IS_DISABLED(pport->bfa)) - bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE); + if (BFA_PORT_IS_DISABLED(fcport->bfa)) + bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE); else - bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT); + bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT); break; - case BFA_PPORT_SM_STOP: - bfa_sm_set_state(pport, bfa_pport_sm_stopped); - bfa_pport_reset_linkinfo(pport); - if (BFA_PORT_IS_DISABLED(pport->bfa)) - bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE); + case BFA_FCPORT_SM_STOP: + bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); + bfa_fcport_reset_linkinfo(fcport); + if (BFA_PORT_IS_DISABLED(fcport->bfa)) + bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE); else - bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT); + bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT); break; - case BFA_PPORT_SM_HWFAIL: - bfa_sm_set_state(pport, bfa_pport_sm_iocdown); - bfa_pport_reset_linkinfo(pport); - bfa_pport_callback(pport, BFA_PPORT_LINKDOWN); - if (BFA_PORT_IS_DISABLED(pport->bfa)) - bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE); + case BFA_FCPORT_SM_HWFAIL: + bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); + bfa_fcport_reset_linkinfo(fcport); + bfa_fcport_callback(fcport, BFA_PPORT_LINKDOWN); + if (BFA_PORT_IS_DISABLED(fcport->bfa)) + bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE); else - bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT); + bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT); break; default: - bfa_sm_fault(pport->bfa, event); + bfa_sm_fault(fcport->bfa, event); } } static void -bfa_pport_sm_disabling_qwait(struct bfa_pport_s *pport, - enum bfa_pport_sm_event event) +bfa_fcport_sm_disabling_qwait(struct bfa_fcport_s *fcport, + enum bfa_fcport_sm_event event) { - bfa_trc(pport->bfa, event); + bfa_trc(fcport->bfa, event); switch (event) { - case BFA_PPORT_SM_QRESUME: - bfa_sm_set_state(pport, bfa_pport_sm_disabling); - bfa_pport_send_disable(pport); + case BFA_FCPORT_SM_QRESUME: + bfa_sm_set_state(fcport, bfa_fcport_sm_disabling); + bfa_fcport_send_disable(fcport); break; - case BFA_PPORT_SM_STOP: - bfa_sm_set_state(pport, bfa_pport_sm_stopped); - bfa_reqq_wcancel(&pport->reqq_wait); + case BFA_FCPORT_SM_STOP: + bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); + bfa_reqq_wcancel(&fcport->reqq_wait); break; - case BFA_PPORT_SM_DISABLE: + case BFA_FCPORT_SM_DISABLE: /** * Already being disabled. */ break; - case BFA_PPORT_SM_LINKUP: - case BFA_PPORT_SM_LINKDOWN: + case BFA_FCPORT_SM_LINKUP: + case BFA_FCPORT_SM_LINKDOWN: /** * Possible to get link events when doing back-to-back * enable/disables. */ break; - case BFA_PPORT_SM_HWFAIL: - bfa_sm_set_state(pport, bfa_pport_sm_iocfail); - bfa_reqq_wcancel(&pport->reqq_wait); + case BFA_FCPORT_SM_HWFAIL: + bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail); + bfa_reqq_wcancel(&fcport->reqq_wait); break; default: - bfa_sm_fault(pport->bfa, event); + bfa_sm_fault(fcport->bfa, event); } } static void -bfa_pport_sm_disabling(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) +bfa_fcport_sm_disabling(struct bfa_fcport_s *fcport, + enum bfa_fcport_sm_event event) { - bfa_trc(pport->bfa, event); + bfa_trc(fcport->bfa, event); switch (event) { - case BFA_PPORT_SM_FWRSP: - bfa_sm_set_state(pport, bfa_pport_sm_disabled); + case BFA_FCPORT_SM_FWRSP: + bfa_sm_set_state(fcport, bfa_fcport_sm_disabled); break; - case BFA_PPORT_SM_DISABLE: + case BFA_FCPORT_SM_DISABLE: /** * Already being disabled. */ break; - case BFA_PPORT_SM_ENABLE: - if (bfa_pport_send_enable(pport)) - bfa_sm_set_state(pport, bfa_pport_sm_enabling); + case BFA_FCPORT_SM_ENABLE: + if (bfa_fcport_send_enable(fcport)) + bfa_sm_set_state(fcport, bfa_fcport_sm_enabling); else - bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait); + bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait); - bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL, + bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, BFA_PL_EID_PORT_ENABLE, 0, "Port Enable"); - bfa_pport_aen_post(pport, BFA_PORT_AEN_ENABLE); + bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ENABLE); break; - case BFA_PPORT_SM_STOP: - bfa_sm_set_state(pport, bfa_pport_sm_stopped); + case BFA_FCPORT_SM_STOP: + bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); break; - case BFA_PPORT_SM_LINKUP: - case BFA_PPORT_SM_LINKDOWN: + case BFA_FCPORT_SM_LINKUP: + case BFA_FCPORT_SM_LINKDOWN: /** * Possible to get link events when doing back-to-back * enable/disables. */ break; - case BFA_PPORT_SM_HWFAIL: - bfa_sm_set_state(pport, bfa_pport_sm_iocfail); + case BFA_FCPORT_SM_HWFAIL: + bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail); break; default: - bfa_sm_fault(pport->bfa, event); + bfa_sm_fault(fcport->bfa, event); } } static void -bfa_pport_sm_disabled(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) +bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport, + enum bfa_fcport_sm_event event) { - bfa_trc(pport->bfa, event); + bfa_trc(fcport->bfa, event); switch (event) { - case BFA_PPORT_SM_START: + case BFA_FCPORT_SM_START: /** * Ignore start event for a port that is disabled. */ break; - case BFA_PPORT_SM_STOP: - bfa_sm_set_state(pport, bfa_pport_sm_stopped); + case BFA_FCPORT_SM_STOP: + bfa_sm_set_state(fcport, bfa_fcport_sm_stopped); break; - case BFA_PPORT_SM_ENABLE: - if (bfa_pport_send_enable(pport)) - bfa_sm_set_state(pport, bfa_pport_sm_enabling); + case BFA_FCPORT_SM_ENABLE: + if (bfa_fcport_send_enable(fcport)) + bfa_sm_set_state(fcport, bfa_fcport_sm_enabling); else - bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait); + bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait); - bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL, + bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, BFA_PL_EID_PORT_ENABLE, 0, "Port Enable"); - bfa_pport_aen_post(pport, BFA_PORT_AEN_ENABLE); + bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ENABLE); break; - case BFA_PPORT_SM_DISABLE: + case BFA_FCPORT_SM_DISABLE: /** * Already disabled. */ break; - case BFA_PPORT_SM_HWFAIL: - bfa_sm_set_state(pport, bfa_pport_sm_iocfail); + case BFA_FCPORT_SM_HWFAIL: + bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail); break; default: - bfa_sm_fault(pport->bfa, event); + bfa_sm_fault(fcport->bfa, event); } } static void -bfa_pport_sm_stopped(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) +bfa_fcport_sm_stopped(struct bfa_fcport_s *fcport, + enum bfa_fcport_sm_event event) { - bfa_trc(pport->bfa, event); + bfa_trc(fcport->bfa, event); switch (event) { - case BFA_PPORT_SM_START: - if (bfa_pport_send_enable(pport)) - bfa_sm_set_state(pport, bfa_pport_sm_enabling); + case BFA_FCPORT_SM_START: + if (bfa_fcport_send_enable(fcport)) + bfa_sm_set_state(fcport, bfa_fcport_sm_enabling); else - bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait); + bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait); break; default: @@ -593,16 +605,17 @@ bfa_pport_sm_stopped(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) * Port is enabled. IOC is down/failed. */ static void -bfa_pport_sm_iocdown(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) +bfa_fcport_sm_iocdown(struct bfa_fcport_s *fcport, + enum bfa_fcport_sm_event event) { - bfa_trc(pport->bfa, event); + bfa_trc(fcport->bfa, event); switch (event) { - case BFA_PPORT_SM_START: - if (bfa_pport_send_enable(pport)) - bfa_sm_set_state(pport, bfa_pport_sm_enabling); + case BFA_FCPORT_SM_START: + if (bfa_fcport_send_enable(fcport)) + bfa_sm_set_state(fcport, bfa_fcport_sm_enabling); else - bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait); + bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait); break; default: @@ -617,17 +630,18 @@ bfa_pport_sm_iocdown(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) * Port is disabled. IOC is down/failed. */ static void -bfa_pport_sm_iocfail(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) +bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport, + enum bfa_fcport_sm_event event) { - bfa_trc(pport->bfa, event); + bfa_trc(fcport->bfa, event); switch (event) { - case BFA_PPORT_SM_START: - bfa_sm_set_state(pport, bfa_pport_sm_disabled); + case BFA_FCPORT_SM_START: + bfa_sm_set_state(fcport, bfa_fcport_sm_disabled); break; - case BFA_PPORT_SM_ENABLE: - bfa_sm_set_state(pport, bfa_pport_sm_iocdown); + case BFA_FCPORT_SM_ENABLE: + bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown); break; default: @@ -642,19 +656,19 @@ bfa_pport_sm_iocfail(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) * Link state is down */ static void -bfa_pport_ln_sm_dn(struct bfa_pport_ln_s *ln, - enum bfa_pport_ln_sm_event event) +bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln, + enum bfa_fcport_ln_sm_event event) { - bfa_trc(ln->pport->bfa, event); + bfa_trc(ln->fcport->bfa, event); switch (event) { - case BFA_PPORT_LN_SM_LINKUP: - bfa_sm_set_state(ln, bfa_pport_ln_sm_up_nf); - bfa_pport_queue_cb(ln, BFA_PPORT_LINKUP); + case BFA_FCPORT_LN_SM_LINKUP: + bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_nf); + bfa_fcport_queue_cb(ln, BFA_PPORT_LINKUP); break; default: - bfa_sm_fault(ln->pport->bfa, event); + bfa_sm_fault(ln->fcport->bfa, event); } } @@ -662,22 +676,22 @@ bfa_pport_ln_sm_dn(struct bfa_pport_ln_s *ln, * Link state is waiting for down notification */ static void -bfa_pport_ln_sm_dn_nf(struct bfa_pport_ln_s *ln, - enum bfa_pport_ln_sm_event event) +bfa_fcport_ln_sm_dn_nf(struct bfa_fcport_ln_s *ln, + enum bfa_fcport_ln_sm_event event) { - bfa_trc(ln->pport->bfa, event); + bfa_trc(ln->fcport->bfa, event); switch (event) { - case BFA_PPORT_LN_SM_LINKUP: - bfa_sm_set_state(ln, bfa_pport_ln_sm_dn_up_nf); + case BFA_FCPORT_LN_SM_LINKUP: + bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_up_nf); break; - case BFA_PPORT_LN_SM_NOTIFICATION: - bfa_sm_set_state(ln, bfa_pport_ln_sm_dn); + case BFA_FCPORT_LN_SM_NOTIFICATION: + bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn); break; default: - bfa_sm_fault(ln->pport->bfa, event); + bfa_sm_fault(ln->fcport->bfa, event); } } @@ -685,23 +699,23 @@ bfa_pport_ln_sm_dn_nf(struct bfa_pport_ln_s *ln, * Link state is waiting for down notification and there is a pending up */ static void -bfa_pport_ln_sm_dn_up_nf(struct bfa_pport_ln_s *ln, - enum bfa_pport_ln_sm_event event) +bfa_fcport_ln_sm_dn_up_nf(struct bfa_fcport_ln_s *ln, + enum bfa_fcport_ln_sm_event event) { - bfa_trc(ln->pport->bfa, event); + bfa_trc(ln->fcport->bfa, event); switch (event) { - case BFA_PPORT_LN_SM_LINKDOWN: - bfa_sm_set_state(ln, bfa_pport_ln_sm_dn_nf); + case BFA_FCPORT_LN_SM_LINKDOWN: + bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf); break; - case BFA_PPORT_LN_SM_NOTIFICATION: - bfa_sm_set_state(ln, bfa_pport_ln_sm_up_nf); - bfa_pport_queue_cb(ln, BFA_PPORT_LINKUP); + case BFA_FCPORT_LN_SM_NOTIFICATION: + bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_nf); + bfa_fcport_queue_cb(ln, BFA_PPORT_LINKUP); break; default: - bfa_sm_fault(ln->pport->bfa, event); + bfa_sm_fault(ln->fcport->bfa, event); } } @@ -709,19 +723,19 @@ bfa_pport_ln_sm_dn_up_nf(struct bfa_pport_ln_s *ln, * Link state is up */ static void -bfa_pport_ln_sm_up(struct bfa_pport_ln_s *ln, - enum bfa_pport_ln_sm_event event) +bfa_fcport_ln_sm_up(struct bfa_fcport_ln_s *ln, + enum bfa_fcport_ln_sm_event event) { - bfa_trc(ln->pport->bfa, event); + bfa_trc(ln->fcport->bfa, event); switch (event) { - case BFA_PPORT_LN_SM_LINKDOWN: - bfa_sm_set_state(ln, bfa_pport_ln_sm_dn_nf); - bfa_pport_queue_cb(ln, BFA_PPORT_LINKDOWN); + case BFA_FCPORT_LN_SM_LINKDOWN: + bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf); + bfa_fcport_queue_cb(ln, BFA_PPORT_LINKDOWN); break; default: - bfa_sm_fault(ln->pport->bfa, event); + bfa_sm_fault(ln->fcport->bfa, event); } } @@ -729,22 +743,22 @@ bfa_pport_ln_sm_up(struct bfa_pport_ln_s *ln, * Link state is waiting for up notification */ static void -bfa_pport_ln_sm_up_nf(struct bfa_pport_ln_s *ln, - enum bfa_pport_ln_sm_event event) +bfa_fcport_ln_sm_up_nf(struct bfa_fcport_ln_s *ln, + enum bfa_fcport_ln_sm_event event) { - bfa_trc(ln->pport->bfa, event); + bfa_trc(ln->fcport->bfa, event); switch (event) { - case BFA_PPORT_LN_SM_LINKDOWN: - bfa_sm_set_state(ln, bfa_pport_ln_sm_up_dn_nf); + case BFA_FCPORT_LN_SM_LINKDOWN: + bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_nf); break; - case BFA_PPORT_LN_SM_NOTIFICATION: - bfa_sm_set_state(ln, bfa_pport_ln_sm_up); + case BFA_FCPORT_LN_SM_NOTIFICATION: + bfa_sm_set_state(ln, bfa_fcport_ln_sm_up); break; default: - bfa_sm_fault(ln->pport->bfa, event); + bfa_sm_fault(ln->fcport->bfa, event); } } @@ -752,23 +766,23 @@ bfa_pport_ln_sm_up_nf(struct bfa_pport_ln_s *ln, * Link state is waiting for up notification and there is a pending down */ static void -bfa_pport_ln_sm_up_dn_nf(struct bfa_pport_ln_s *ln, - enum bfa_pport_ln_sm_event event) +bfa_fcport_ln_sm_up_dn_nf(struct bfa_fcport_ln_s *ln, + enum bfa_fcport_ln_sm_event event) { - bfa_trc(ln->pport->bfa, event); + bfa_trc(ln->fcport->bfa, event); switch (event) { - case BFA_PPORT_LN_SM_LINKUP: - bfa_sm_set_state(ln, bfa_pport_ln_sm_up_dn_up_nf); + case BFA_FCPORT_LN_SM_LINKUP: + bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_up_nf); break; - case BFA_PPORT_LN_SM_NOTIFICATION: - bfa_sm_set_state(ln, bfa_pport_ln_sm_dn_nf); - bfa_pport_queue_cb(ln, BFA_PPORT_LINKDOWN); + case BFA_FCPORT_LN_SM_NOTIFICATION: + bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf); + bfa_fcport_queue_cb(ln, BFA_PPORT_LINKDOWN); break; default: - bfa_sm_fault(ln->pport->bfa, event); + bfa_sm_fault(ln->fcport->bfa, event); } } @@ -776,23 +790,23 @@ bfa_pport_ln_sm_up_dn_nf(struct bfa_pport_ln_s *ln, * Link state is waiting for up notification and there are pending down and up */ static void -bfa_pport_ln_sm_up_dn_up_nf(struct bfa_pport_ln_s *ln, - enum bfa_pport_ln_sm_event event) +bfa_fcport_ln_sm_up_dn_up_nf(struct bfa_fcport_ln_s *ln, + enum bfa_fcport_ln_sm_event event) { - bfa_trc(ln->pport->bfa, event); + bfa_trc(ln->fcport->bfa, event); switch (event) { - case BFA_PPORT_LN_SM_LINKDOWN: - bfa_sm_set_state(ln, bfa_pport_ln_sm_up_dn_nf); + case BFA_FCPORT_LN_SM_LINKDOWN: + bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_nf); break; - case BFA_PPORT_LN_SM_NOTIFICATION: - bfa_sm_set_state(ln, bfa_pport_ln_sm_dn_up_nf); - bfa_pport_queue_cb(ln, BFA_PPORT_LINKDOWN); + case BFA_FCPORT_LN_SM_NOTIFICATION: + bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_up_nf); + bfa_fcport_queue_cb(ln, BFA_PPORT_LINKDOWN); break; default: - bfa_sm_fault(ln->pport->bfa, event); + bfa_sm_fault(ln->fcport->bfa, event); } } @@ -801,36 +815,40 @@ bfa_pport_ln_sm_up_dn_up_nf(struct bfa_pport_ln_s *ln, */ static void -__bfa_cb_port_event(void *cbarg, bfa_boolean_t complete) +__bfa_cb_fcport_event(void *cbarg, bfa_boolean_t complete) { - struct bfa_pport_ln_s *ln = cbarg; + struct bfa_fcport_ln_s *ln = cbarg; if (complete) - ln->pport->event_cbfn(ln->pport->event_cbarg, ln->ln_event); + ln->fcport->event_cbfn(ln->fcport->event_cbarg, ln->ln_event); else - bfa_sm_send_event(ln, BFA_PPORT_LN_SM_NOTIFICATION); + bfa_sm_send_event(ln, BFA_FCPORT_LN_SM_NOTIFICATION); } -#define PPORT_STATS_DMA_SZ (BFA_ROUNDUP(sizeof(union bfa_pport_stats_u), \ +#define PPORT_STATS_DMA_SZ (BFA_ROUNDUP(sizeof(union bfa_fcport_stats_u), \ + BFA_CACHELINE_SZ)) + +#define FCPORT_STATS_DMA_SZ (BFA_ROUNDUP(sizeof(union bfa_fcport_stats_u), \ BFA_CACHELINE_SZ)) static void -bfa_pport_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len, +bfa_fcport_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len, u32 *dm_len) { *dm_len += PPORT_STATS_DMA_SZ; + *dm_len += PPORT_STATS_DMA_SZ; } static void -bfa_pport_qresume(void *cbarg) +bfa_fcport_qresume(void *cbarg) { - struct bfa_pport_s *port = cbarg; + struct bfa_fcport_s *port = cbarg; - bfa_sm_send_event(port, BFA_PPORT_SM_QRESUME); + bfa_sm_send_event(port, BFA_FCPORT_SM_QRESUME); } static void -bfa_pport_mem_claim(struct bfa_pport_s *pport, struct bfa_meminfo_s *meminfo) +bfa_fcport_mem_claim(struct bfa_fcport_s *fcport, struct bfa_meminfo_s *meminfo) { u8 *dm_kva; u64 dm_pa; @@ -838,13 +856,22 @@ bfa_pport_mem_claim(struct bfa_pport_s *pport, struct bfa_meminfo_s *meminfo) dm_kva = bfa_meminfo_dma_virt(meminfo); dm_pa = bfa_meminfo_dma_phys(meminfo); - pport->stats_kva = dm_kva; - pport->stats_pa = dm_pa; - pport->stats = (union bfa_pport_stats_u *)dm_kva; + fcport->stats_kva = dm_kva; + fcport->stats_pa = dm_pa; + fcport->stats = (union bfa_pport_stats_u *)dm_kva; dm_kva += PPORT_STATS_DMA_SZ; dm_pa += PPORT_STATS_DMA_SZ; + /* FC port stats */ + + fcport->fcport_stats_kva = dm_kva; + fcport->fcport_stats_pa = dm_pa; + fcport->fcport_stats = (union bfa_fcport_stats_u *) dm_kva; + + dm_kva += FCPORT_STATS_DMA_SZ; + dm_pa += FCPORT_STATS_DMA_SZ; + bfa_meminfo_dma_virt(meminfo) = dm_kva; bfa_meminfo_dma_phys(meminfo) = dm_pa; } @@ -853,21 +880,21 @@ bfa_pport_mem_claim(struct bfa_pport_s *pport, struct bfa_meminfo_s *meminfo) * Memory initialization. */ static void -bfa_pport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, +bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev) { - struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); - struct bfa_pport_cfg_s *port_cfg = &pport->cfg; - struct bfa_pport_ln_s *ln = &pport->ln; + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); + struct bfa_pport_cfg_s *port_cfg = &fcport->cfg; + struct bfa_fcport_ln_s *ln = &fcport->ln; - bfa_os_memset(pport, 0, sizeof(struct bfa_pport_s)); - pport->bfa = bfa; - ln->pport = pport; + bfa_os_memset(fcport, 0, sizeof(struct bfa_fcport_s)); + fcport->bfa = bfa; + ln->fcport = fcport; - bfa_pport_mem_claim(pport, meminfo); + bfa_fcport_mem_claim(fcport, meminfo); - bfa_sm_set_state(pport, bfa_pport_sm_uninit); - bfa_sm_set_state(ln, bfa_pport_ln_sm_dn); + bfa_sm_set_state(fcport, bfa_fcport_sm_uninit); + bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn); /** * initialize and set default configuration @@ -879,30 +906,30 @@ bfa_pport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, port_cfg->trl_def_speed = BFA_PPORT_SPEED_1GBPS; - bfa_reqq_winit(&pport->reqq_wait, bfa_pport_qresume, pport); + bfa_reqq_winit(&fcport->reqq_wait, bfa_fcport_qresume, fcport); } static void -bfa_pport_initdone(struct bfa_s *bfa) +bfa_fcport_initdone(struct bfa_s *bfa) { - struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); /** * Initialize port attributes from IOC hardware data. */ - bfa_pport_set_wwns(pport); - if (pport->cfg.maxfrsize == 0) - pport->cfg.maxfrsize = bfa_ioc_maxfrsize(&bfa->ioc); - pport->cfg.rx_bbcredit = bfa_ioc_rx_bbcredit(&bfa->ioc); - pport->speed_sup = bfa_ioc_speed_sup(&bfa->ioc); + bfa_fcport_set_wwns(fcport); + if (fcport->cfg.maxfrsize == 0) + fcport->cfg.maxfrsize = bfa_ioc_maxfrsize(&bfa->ioc); + fcport->cfg.rx_bbcredit = bfa_ioc_rx_bbcredit(&bfa->ioc); + fcport->speed_sup = bfa_ioc_speed_sup(&bfa->ioc); - bfa_assert(pport->cfg.maxfrsize); - bfa_assert(pport->cfg.rx_bbcredit); - bfa_assert(pport->speed_sup); + bfa_assert(fcport->cfg.maxfrsize); + bfa_assert(fcport->cfg.rx_bbcredit); + bfa_assert(fcport->speed_sup); } static void -bfa_pport_detach(struct bfa_s *bfa) +bfa_fcport_detach(struct bfa_s *bfa) { } @@ -910,62 +937,63 @@ bfa_pport_detach(struct bfa_s *bfa) * Called when IOC is ready. */ static void -bfa_pport_start(struct bfa_s *bfa) +bfa_fcport_start(struct bfa_s *bfa) { - bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_START); + bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_START); } /** * Called before IOC is stopped. */ static void -bfa_pport_stop(struct bfa_s *bfa) +bfa_fcport_stop(struct bfa_s *bfa) { - bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_STOP); + bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_STOP); } /** * Called when IOC failure is detected. */ static void -bfa_pport_iocdisable(struct bfa_s *bfa) +bfa_fcport_iocdisable(struct bfa_s *bfa) { - bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_HWFAIL); + bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_HWFAIL); } static void -bfa_pport_update_linkinfo(struct bfa_pport_s *pport) +bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport) { - struct bfi_pport_event_s *pevent = pport->event_arg.i2hmsg.event; + struct bfi_pport_event_s *pevent = fcport->event_arg.i2hmsg.event; - pport->speed = pevent->link_state.speed; - pport->topology = pevent->link_state.topology; + fcport->speed = pevent->link_state.speed; + fcport->topology = pevent->link_state.topology; - if (pport->topology == BFA_PPORT_TOPOLOGY_LOOP) - pport->myalpa = pevent->link_state.tl.loop_info.myalpa; + if (fcport->topology == BFA_PPORT_TOPOLOGY_LOOP) + fcport->myalpa = + pevent->link_state.tl.loop_info.myalpa; /* * QoS Details */ - bfa_os_assign(pport->qos_attr, pevent->link_state.qos_attr); - bfa_os_assign(pport->qos_vc_attr, pevent->link_state.qos_vc_attr); + bfa_os_assign(fcport->qos_attr, pevent->link_state.qos_attr); + bfa_os_assign(fcport->qos_vc_attr, pevent->link_state.qos_vc_attr); - bfa_trc(pport->bfa, pport->speed); - bfa_trc(pport->bfa, pport->topology); + bfa_trc(fcport->bfa, fcport->speed); + bfa_trc(fcport->bfa, fcport->topology); } static void -bfa_pport_reset_linkinfo(struct bfa_pport_s *pport) +bfa_fcport_reset_linkinfo(struct bfa_fcport_s *fcport) { - pport->speed = BFA_PPORT_SPEED_UNKNOWN; - pport->topology = BFA_PPORT_TOPOLOGY_NONE; + fcport->speed = BFA_PPORT_SPEED_UNKNOWN; + fcport->topology = BFA_PPORT_TOPOLOGY_NONE; } /** * Send port enable message to firmware. */ static bfa_boolean_t -bfa_pport_send_enable(struct bfa_pport_s *port) +bfa_fcport_send_enable(struct bfa_fcport_s *fcport) { struct bfi_pport_enable_req_s *m; @@ -973,32 +1001,34 @@ bfa_pport_send_enable(struct bfa_pport_s *port) * Increment message tag before queue check, so that responses to old * requests are discarded. */ - port->msgtag++; + fcport->msgtag++; /** * check for room in queue to send request now */ - m = bfa_reqq_next(port->bfa, BFA_REQQ_PORT); + m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT); if (!m) { - bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->reqq_wait); + bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT, + &fcport->reqq_wait); return BFA_FALSE; } bfi_h2i_set(m->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_ENABLE_REQ, - bfa_lpuid(port->bfa)); - m->nwwn = port->nwwn; - m->pwwn = port->pwwn; - m->port_cfg = port->cfg; - m->msgtag = port->msgtag; - m->port_cfg.maxfrsize = bfa_os_htons(port->cfg.maxfrsize); - bfa_dma_be_addr_set(m->stats_dma_addr, port->stats_pa); - bfa_trc(port->bfa, m->stats_dma_addr.a32.addr_lo); - bfa_trc(port->bfa, m->stats_dma_addr.a32.addr_hi); + bfa_lpuid(fcport->bfa)); + m->nwwn = fcport->nwwn; + m->pwwn = fcport->pwwn; + m->port_cfg = fcport->cfg; + m->msgtag = fcport->msgtag; + m->port_cfg.maxfrsize = bfa_os_htons(fcport->cfg.maxfrsize); + bfa_dma_be_addr_set(m->stats_dma_addr, fcport->stats_pa); + bfa_dma_be_addr_set(m->fcport_stats_dma_addr, fcport->fcport_stats_pa); + bfa_trc(fcport->bfa, m->stats_dma_addr.a32.addr_lo); + bfa_trc(fcport->bfa, m->stats_dma_addr.a32.addr_hi); /** * queue I/O message to firmware */ - bfa_reqq_produce(port->bfa, BFA_REQQ_PORT); + bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT); return BFA_TRUE; } @@ -1006,7 +1036,7 @@ bfa_pport_send_enable(struct bfa_pport_s *port) * Send port disable message to firmware. */ static bfa_boolean_t -bfa_pport_send_disable(struct bfa_pport_s *port) +bfa_fcport_send_disable(struct bfa_fcport_s *fcport) { bfi_pport_disable_req_t *m; @@ -1014,63 +1044,64 @@ bfa_pport_send_disable(struct bfa_pport_s *port) * Increment message tag before queue check, so that responses to old * requests are discarded. */ - port->msgtag++; + fcport->msgtag++; /** * check for room in queue to send request now */ - m = bfa_reqq_next(port->bfa, BFA_REQQ_PORT); + m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT); if (!m) { - bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->reqq_wait); + bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT, + &fcport->reqq_wait); return BFA_FALSE; } bfi_h2i_set(m->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_DISABLE_REQ, - bfa_lpuid(port->bfa)); - m->msgtag = port->msgtag; + bfa_lpuid(fcport->bfa)); + m->msgtag = fcport->msgtag; /** * queue I/O message to firmware */ - bfa_reqq_produce(port->bfa, BFA_REQQ_PORT); + bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT); return BFA_TRUE; } static void -bfa_pport_set_wwns(struct bfa_pport_s *port) +bfa_fcport_set_wwns(struct bfa_fcport_s *fcport) { - port->pwwn = bfa_ioc_get_pwwn(&port->bfa->ioc); - port->nwwn = bfa_ioc_get_nwwn(&port->bfa->ioc); + fcport->pwwn = bfa_ioc_get_pwwn(&fcport->bfa->ioc); + fcport->nwwn = bfa_ioc_get_nwwn(&fcport->bfa->ioc); - bfa_trc(port->bfa, port->pwwn); - bfa_trc(port->bfa, port->nwwn); + bfa_trc(fcport->bfa, fcport->pwwn); + bfa_trc(fcport->bfa, fcport->nwwn); } static void -bfa_port_send_txcredit(void *port_cbarg) +bfa_fcport_send_txcredit(void *port_cbarg) { - struct bfa_pport_s *port = port_cbarg; + struct bfa_fcport_s *fcport = port_cbarg; struct bfi_pport_set_svc_params_req_s *m; /** * check for room in queue to send request now */ - m = bfa_reqq_next(port->bfa, BFA_REQQ_PORT); + m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT); if (!m) { - bfa_trc(port->bfa, port->cfg.tx_bbcredit); + bfa_trc(fcport->bfa, fcport->cfg.tx_bbcredit); return; } bfi_h2i_set(m->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_SET_SVC_PARAMS_REQ, - bfa_lpuid(port->bfa)); - m->tx_bbcredit = bfa_os_htons((u16) port->cfg.tx_bbcredit); + bfa_lpuid(fcport->bfa)); + m->tx_bbcredit = bfa_os_htons((u16) fcport->cfg.tx_bbcredit); /** * queue I/O message to firmware */ - bfa_reqq_produce(port->bfa, BFA_REQQ_PORT); + bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT); } @@ -1083,32 +1114,32 @@ bfa_port_send_txcredit(void *port_cbarg) * Firmware message handler. */ void -bfa_pport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg) +bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg) { - struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); union bfi_pport_i2h_msg_u i2hmsg; i2hmsg.msg = msg; - pport->event_arg.i2hmsg = i2hmsg; + fcport->event_arg.i2hmsg = i2hmsg; switch (msg->mhdr.msg_id) { case BFI_PPORT_I2H_ENABLE_RSP: - if (pport->msgtag == i2hmsg.enable_rsp->msgtag) - bfa_sm_send_event(pport, BFA_PPORT_SM_FWRSP); + if (fcport->msgtag == i2hmsg.enable_rsp->msgtag) + bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP); break; case BFI_PPORT_I2H_DISABLE_RSP: - if (pport->msgtag == i2hmsg.enable_rsp->msgtag) - bfa_sm_send_event(pport, BFA_PPORT_SM_FWRSP); + if (fcport->msgtag == i2hmsg.enable_rsp->msgtag) + bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP); break; case BFI_PPORT_I2H_EVENT: switch (i2hmsg.event->link_state.linkstate) { case BFA_PPORT_LINKUP: - bfa_sm_send_event(pport, BFA_PPORT_SM_LINKUP); + bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKUP); break; case BFA_PPORT_LINKDOWN: - bfa_sm_send_event(pport, BFA_PPORT_SM_LINKDOWN); + bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKDOWN); break; case BFA_PPORT_TRUNK_LINKDOWN: /** todo: event notification */ @@ -1121,32 +1152,63 @@ bfa_pport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg) /* * check for timer pop before processing the rsp */ - if (pport->stats_busy == BFA_FALSE - || pport->stats_status == BFA_STATUS_ETIMER) + if (fcport->stats_busy == BFA_FALSE + || fcport->stats_status == BFA_STATUS_ETIMER) break; - bfa_timer_stop(&pport->timer); - pport->stats_status = i2hmsg.getstats_rsp->status; - bfa_cb_queue(pport->bfa, &pport->hcb_qe, __bfa_cb_port_stats, - pport); + bfa_timer_stop(&fcport->timer); + fcport->stats_status = i2hmsg.getstats_rsp->status; + bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, __bfa_cb_port_stats, + fcport); break; case BFI_PPORT_I2H_CLEAR_STATS_RSP: case BFI_PPORT_I2H_CLEAR_QOS_STATS_RSP: /* * check for timer pop before processing the rsp */ - if (pport->stats_busy == BFA_FALSE - || pport->stats_status == BFA_STATUS_ETIMER) + if (fcport->stats_busy == BFA_FALSE + || fcport->stats_status == BFA_STATUS_ETIMER) break; - bfa_timer_stop(&pport->timer); - pport->stats_status = BFA_STATUS_OK; - bfa_cb_queue(pport->bfa, &pport->hcb_qe, - __bfa_cb_port_stats_clr, pport); + bfa_timer_stop(&fcport->timer); + fcport->stats_status = BFA_STATUS_OK; + bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, + __bfa_cb_port_stats_clr, fcport); + break; + + case BFI_FCPORT_I2H_GET_STATS_RSP: + /* + * check for timer pop before processing the rsp + */ + if (fcport->stats_busy == BFA_FALSE || + fcport->stats_status == BFA_STATUS_ETIMER) { + break; + } + + bfa_timer_stop(&fcport->timer); + fcport->stats_status = i2hmsg.getstats_rsp->status; + bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, + __bfa_cb_fcport_stats, fcport); + break; + + case BFI_FCPORT_I2H_CLEAR_STATS_RSP: + /* + * check for timer pop before processing the rsp + */ + if (fcport->stats_busy == BFA_FALSE || + fcport->stats_status == BFA_STATUS_ETIMER) { + break; + } + + bfa_timer_stop(&fcport->timer); + fcport->stats_status = BFA_STATUS_OK; + bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, + __bfa_cb_fcport_stats_clr, fcport); break; default: bfa_assert(0); + break; } } @@ -1160,35 +1222,35 @@ bfa_pport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg) * Registered callback for port events. */ void -bfa_pport_event_register(struct bfa_s *bfa, +bfa_fcport_event_register(struct bfa_s *bfa, void (*cbfn) (void *cbarg, bfa_pport_event_t event), void *cbarg) { - struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); - pport->event_cbfn = cbfn; - pport->event_cbarg = cbarg; + fcport->event_cbfn = cbfn; + fcport->event_cbarg = cbarg; } bfa_status_t -bfa_pport_enable(struct bfa_s *bfa) +bfa_fcport_enable(struct bfa_s *bfa) { - struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); - if (pport->diag_busy) + if (fcport->diag_busy) return BFA_STATUS_DIAG_BUSY; else if (bfa_sm_cmp_state - (BFA_PORT_MOD(bfa), bfa_pport_sm_disabling_qwait)) + (BFA_FCPORT_MOD(bfa), bfa_fcport_sm_disabling_qwait)) return BFA_STATUS_DEVBUSY; - bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_ENABLE); + bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_ENABLE); return BFA_STATUS_OK; } bfa_status_t -bfa_pport_disable(struct bfa_s *bfa) +bfa_fcport_disable(struct bfa_s *bfa) { - bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_DISABLE); + bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DISABLE); return BFA_STATUS_OK; } @@ -1196,18 +1258,18 @@ bfa_pport_disable(struct bfa_s *bfa) * Configure port speed. */ bfa_status_t -bfa_pport_cfg_speed(struct bfa_s *bfa, enum bfa_pport_speed speed) +bfa_fcport_cfg_speed(struct bfa_s *bfa, enum bfa_pport_speed speed) { - struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); bfa_trc(bfa, speed); - if ((speed != BFA_PPORT_SPEED_AUTO) && (speed > pport->speed_sup)) { - bfa_trc(bfa, pport->speed_sup); + if ((speed != BFA_PPORT_SPEED_AUTO) && (speed > fcport->speed_sup)) { + bfa_trc(bfa, fcport->speed_sup); return BFA_STATUS_UNSUPP_SPEED; } - pport->cfg.speed = speed; + fcport->cfg.speed = speed; return BFA_STATUS_OK; } @@ -1216,23 +1278,23 @@ bfa_pport_cfg_speed(struct bfa_s *bfa, enum bfa_pport_speed speed) * Get current speed. */ enum bfa_pport_speed -bfa_pport_get_speed(struct bfa_s *bfa) +bfa_fcport_get_speed(struct bfa_s *bfa) { - struct bfa_pport_s *port = BFA_PORT_MOD(bfa); + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); - return port->speed; + return fcport->speed; } /** * Configure port topology. */ bfa_status_t -bfa_pport_cfg_topology(struct bfa_s *bfa, enum bfa_pport_topology topology) +bfa_fcport_cfg_topology(struct bfa_s *bfa, enum bfa_pport_topology topology) { - struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); bfa_trc(bfa, topology); - bfa_trc(bfa, pport->cfg.topology); + bfa_trc(bfa, fcport->cfg.topology); switch (topology) { case BFA_PPORT_TOPOLOGY_P2P: @@ -1244,7 +1306,7 @@ bfa_pport_cfg_topology(struct bfa_s *bfa, enum bfa_pport_topology topology) return BFA_STATUS_EINVAL; } - pport->cfg.topology = topology; + fcport->cfg.topology = topology; return BFA_STATUS_OK; } @@ -1252,64 +1314,64 @@ bfa_pport_cfg_topology(struct bfa_s *bfa, enum bfa_pport_topology topology) * Get current topology. */ enum bfa_pport_topology -bfa_pport_get_topology(struct bfa_s *bfa) +bfa_fcport_get_topology(struct bfa_s *bfa) { - struct bfa_pport_s *port = BFA_PORT_MOD(bfa); + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); - return port->topology; + return fcport->topology; } bfa_status_t -bfa_pport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa) +bfa_fcport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa) { - struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); bfa_trc(bfa, alpa); - bfa_trc(bfa, pport->cfg.cfg_hardalpa); - bfa_trc(bfa, pport->cfg.hardalpa); + bfa_trc(bfa, fcport->cfg.cfg_hardalpa); + bfa_trc(bfa, fcport->cfg.hardalpa); - pport->cfg.cfg_hardalpa = BFA_TRUE; - pport->cfg.hardalpa = alpa; + fcport->cfg.cfg_hardalpa = BFA_TRUE; + fcport->cfg.hardalpa = alpa; return BFA_STATUS_OK; } bfa_status_t -bfa_pport_clr_hardalpa(struct bfa_s *bfa) +bfa_fcport_clr_hardalpa(struct bfa_s *bfa) { - struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); - bfa_trc(bfa, pport->cfg.cfg_hardalpa); - bfa_trc(bfa, pport->cfg.hardalpa); + bfa_trc(bfa, fcport->cfg.cfg_hardalpa); + bfa_trc(bfa, fcport->cfg.hardalpa); - pport->cfg.cfg_hardalpa = BFA_FALSE; + fcport->cfg.cfg_hardalpa = BFA_FALSE; return BFA_STATUS_OK; } bfa_boolean_t -bfa_pport_get_hardalpa(struct bfa_s *bfa, u8 *alpa) +bfa_fcport_get_hardalpa(struct bfa_s *bfa, u8 *alpa) { - struct bfa_pport_s *port = BFA_PORT_MOD(bfa); + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); - *alpa = port->cfg.hardalpa; - return port->cfg.cfg_hardalpa; + *alpa = fcport->cfg.hardalpa; + return fcport->cfg.cfg_hardalpa; } u8 -bfa_pport_get_myalpa(struct bfa_s *bfa) +bfa_fcport_get_myalpa(struct bfa_s *bfa) { - struct bfa_pport_s *port = BFA_PORT_MOD(bfa); + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); - return port->myalpa; + return fcport->myalpa; } bfa_status_t -bfa_pport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxfrsize) +bfa_fcport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxfrsize) { - struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); bfa_trc(bfa, maxfrsize); - bfa_trc(bfa, pport->cfg.maxfrsize); + bfa_trc(bfa, fcport->cfg.maxfrsize); /* * with in range @@ -1323,41 +1385,41 @@ bfa_pport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxfrsize) if ((maxfrsize != FC_MAX_PDUSZ) && (maxfrsize & (maxfrsize - 1))) return BFA_STATUS_INVLD_DFSZ; - pport->cfg.maxfrsize = maxfrsize; + fcport->cfg.maxfrsize = maxfrsize; return BFA_STATUS_OK; } u16 -bfa_pport_get_maxfrsize(struct bfa_s *bfa) +bfa_fcport_get_maxfrsize(struct bfa_s *bfa) { - struct bfa_pport_s *port = BFA_PORT_MOD(bfa); + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); - return port->cfg.maxfrsize; + return fcport->cfg.maxfrsize; } u32 -bfa_pport_mypid(struct bfa_s *bfa) +bfa_fcport_mypid(struct bfa_s *bfa) { - struct bfa_pport_s *port = BFA_PORT_MOD(bfa); + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); - return port->mypid; + return fcport->mypid; } u8 -bfa_pport_get_rx_bbcredit(struct bfa_s *bfa) +bfa_fcport_get_rx_bbcredit(struct bfa_s *bfa) { - struct bfa_pport_s *port = BFA_PORT_MOD(bfa); + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); - return port->cfg.rx_bbcredit; + return fcport->cfg.rx_bbcredit; } void -bfa_pport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit) +bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit) { - struct bfa_pport_s *port = BFA_PORT_MOD(bfa); + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); - port->cfg.tx_bbcredit = (u8) tx_bbcredit; - bfa_port_send_txcredit(port); + fcport->cfg.tx_bbcredit = (u8) tx_bbcredit; + bfa_fcport_send_txcredit(fcport); } /** @@ -1365,78 +1427,79 @@ bfa_pport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit) */ wwn_t -bfa_pport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node) +bfa_fcport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node) { - struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); if (node) - return pport->nwwn; + return fcport->nwwn; else - return pport->pwwn; + return fcport->pwwn; } void -bfa_pport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr) +bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr) { - struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); bfa_os_memset(attr, 0, sizeof(struct bfa_pport_attr_s)); - attr->nwwn = pport->nwwn; - attr->pwwn = pport->pwwn; + attr->nwwn = fcport->nwwn; + attr->pwwn = fcport->pwwn; - bfa_os_memcpy(&attr->pport_cfg, &pport->cfg, + bfa_os_memcpy(&attr->pport_cfg, &fcport->cfg, sizeof(struct bfa_pport_cfg_s)); /* * speed attributes */ - attr->pport_cfg.speed = pport->cfg.speed; - attr->speed_supported = pport->speed_sup; - attr->speed = pport->speed; + attr->pport_cfg.speed = fcport->cfg.speed; + attr->speed_supported = fcport->speed_sup; + attr->speed = fcport->speed; attr->cos_supported = FC_CLASS_3; /* * topology attributes */ - attr->pport_cfg.topology = pport->cfg.topology; - attr->topology = pport->topology; + attr->pport_cfg.topology = fcport->cfg.topology; + attr->topology = fcport->topology; /* * beacon attributes */ - attr->beacon = pport->beacon; - attr->link_e2e_beacon = pport->link_e2e_beacon; - attr->plog_enabled = bfa_plog_get_setting(pport->bfa->plog); + attr->beacon = fcport->beacon; + attr->link_e2e_beacon = fcport->link_e2e_beacon; + attr->plog_enabled = bfa_plog_get_setting(fcport->bfa->plog); attr->pport_cfg.path_tov = bfa_fcpim_path_tov_get(bfa); attr->pport_cfg.q_depth = bfa_fcpim_qdepth_get(bfa); - attr->port_state = bfa_sm_to_state(hal_pport_sm_table, pport->sm); - if (bfa_ioc_is_disabled(&pport->bfa->ioc)) + attr->port_state = bfa_sm_to_state(hal_pport_sm_table, fcport->sm); + if (bfa_ioc_is_disabled(&fcport->bfa->ioc)) attr->port_state = BFA_PPORT_ST_IOCDIS; - else if (bfa_ioc_fw_mismatch(&pport->bfa->ioc)) + else if (bfa_ioc_fw_mismatch(&fcport->bfa->ioc)) attr->port_state = BFA_PPORT_ST_FWMISMATCH; } static void bfa_port_stats_query(void *cbarg) { - struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg; + struct bfa_fcport_s *fcport = (struct bfa_fcport_s *)cbarg; bfi_pport_get_stats_req_t *msg; - msg = bfa_reqq_next(port->bfa, BFA_REQQ_PORT); + msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT); if (!msg) { - port->stats_qfull = BFA_TRUE; - bfa_reqq_winit(&port->stats_reqq_wait, bfa_port_stats_query, - port); - bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->stats_reqq_wait); + fcport->stats_qfull = BFA_TRUE; + bfa_reqq_winit(&fcport->stats_reqq_wait, bfa_port_stats_query, + fcport); + bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT, + &fcport->stats_reqq_wait); return; } - port->stats_qfull = BFA_FALSE; + fcport->stats_qfull = BFA_FALSE; bfa_os_memset(msg, 0, sizeof(bfi_pport_get_stats_req_t)); bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_GET_STATS_REQ, - bfa_lpuid(port->bfa)); - bfa_reqq_produce(port->bfa, BFA_REQQ_PORT); + bfa_lpuid(fcport->bfa)); + bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT); return; } @@ -1444,65 +1507,111 @@ bfa_port_stats_query(void *cbarg) static void bfa_port_stats_clear(void *cbarg) { - struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg; + struct bfa_fcport_s *fcport = (struct bfa_fcport_s *)cbarg; bfi_pport_clear_stats_req_t *msg; - msg = bfa_reqq_next(port->bfa, BFA_REQQ_PORT); + msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT); if (!msg) { - port->stats_qfull = BFA_TRUE; - bfa_reqq_winit(&port->stats_reqq_wait, bfa_port_stats_clear, - port); - bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->stats_reqq_wait); + fcport->stats_qfull = BFA_TRUE; + bfa_reqq_winit(&fcport->stats_reqq_wait, bfa_port_stats_clear, + fcport); + bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT, + &fcport->stats_reqq_wait); return; } - port->stats_qfull = BFA_FALSE; + fcport->stats_qfull = BFA_FALSE; bfa_os_memset(msg, 0, sizeof(bfi_pport_clear_stats_req_t)); bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_CLEAR_STATS_REQ, - bfa_lpuid(port->bfa)); - bfa_reqq_produce(port->bfa, BFA_REQQ_PORT); + bfa_lpuid(fcport->bfa)); + bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT); return; } static void +bfa_fcport_stats_query(void *cbarg) +{ + struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg; + bfi_pport_get_stats_req_t *msg; + + msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT); + + if (!msg) { + fcport->stats_qfull = BFA_TRUE; + bfa_reqq_winit(&fcport->stats_reqq_wait, + bfa_fcport_stats_query, fcport); + bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT, + &fcport->stats_reqq_wait); + return; + } + fcport->stats_qfull = BFA_FALSE; + + bfa_os_memset(msg, 0, sizeof(bfi_pport_get_stats_req_t)); + bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_FCPORT_H2I_GET_STATS_REQ, + bfa_lpuid(fcport->bfa)); + bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT); +} + +static void +bfa_fcport_stats_clear(void *cbarg) +{ + struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg; + bfi_pport_clear_stats_req_t *msg; + + msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT); + + if (!msg) { + fcport->stats_qfull = BFA_TRUE; + bfa_reqq_winit(&fcport->stats_reqq_wait, + bfa_fcport_stats_clear, fcport); + bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT, + &fcport->stats_reqq_wait); + return; + } + fcport->stats_qfull = BFA_FALSE; + + bfa_os_memset(msg, 0, sizeof(bfi_pport_clear_stats_req_t)); + bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_FCPORT_H2I_CLEAR_STATS_REQ, + bfa_lpuid(fcport->bfa)); + bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT); +} + +static void bfa_port_qos_stats_clear(void *cbarg) { - struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg; + struct bfa_fcport_s *fcport = (struct bfa_fcport_s *)cbarg; bfi_pport_clear_qos_stats_req_t *msg; - msg = bfa_reqq_next(port->bfa, BFA_REQQ_PORT); + msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT); if (!msg) { - port->stats_qfull = BFA_TRUE; - bfa_reqq_winit(&port->stats_reqq_wait, bfa_port_qos_stats_clear, - port); - bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->stats_reqq_wait); + fcport->stats_qfull = BFA_TRUE; + bfa_reqq_winit(&fcport->stats_reqq_wait, + bfa_port_qos_stats_clear, fcport); + bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT, + &fcport->stats_reqq_wait); return; } - port->stats_qfull = BFA_FALSE; + fcport->stats_qfull = BFA_FALSE; bfa_os_memset(msg, 0, sizeof(bfi_pport_clear_qos_stats_req_t)); bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_CLEAR_QOS_STATS_REQ, - bfa_lpuid(port->bfa)); - bfa_reqq_produce(port->bfa, BFA_REQQ_PORT); + bfa_lpuid(fcport->bfa)); + bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT); return; } static void -bfa_pport_stats_swap(union bfa_pport_stats_u *d, union bfa_pport_stats_u *s) +bfa_fcport_stats_swap(union bfa_fcport_stats_u *d, union bfa_fcport_stats_u *s) { - u32 *dip = (u32 *) d; - u32 *sip = (u32 *) s; + u32 *dip = (u32 *) d; + u32 *sip = (u32 *) s; int i; - /* - * Do 64 bit fields swap first - */ - for (i = 0; - i < - ((sizeof(union bfa_pport_stats_u) - - sizeof(struct bfa_qos_stats_s)) / sizeof(u32)); i = i + 2) { + /* Do 64 bit fields swap first */ + for (i = 0; i < ((sizeof(union bfa_fcport_stats_u) - + sizeof(struct bfa_qos_stats_s))/sizeof(u32)); i = i + 2) { #ifdef __BIGENDIAN dip[i] = bfa_os_ntohl(sip[i]); dip[i + 1] = bfa_os_ntohl(sip[i + 1]); @@ -1512,56 +1621,88 @@ bfa_pport_stats_swap(union bfa_pport_stats_u *d, union bfa_pport_stats_u *s) #endif } - /* - * Now swap the 32 bit fields - */ - for (; i < (sizeof(union bfa_pport_stats_u) / sizeof(u32)); ++i) + /* Now swap the 32 bit fields */ + for (; i < (sizeof(union bfa_fcport_stats_u)/sizeof(u32)); ++i) + dip[i] = bfa_os_ntohl(sip[i]); +} + +static void +bfa_port_stats_swap(union bfa_pport_stats_u *d, union bfa_pport_stats_u *s) +{ + u32 *dip = (u32 *) d; + u32 *sip = (u32 *) s; + int i; + + /* Do 64 bit fields swap first */ + for (i = 0; i < (sizeof(union bfa_pport_stats_u) / sizeof(u32)); + i = i + 2) { +#ifdef __BIGENDIAN dip[i] = bfa_os_ntohl(sip[i]); + dip[i + 1] = bfa_os_ntohl(sip[i + 1]); +#else + dip[i] = bfa_os_ntohl(sip[i + 1]); + dip[i + 1] = bfa_os_ntohl(sip[i]); +#endif + } } static void __bfa_cb_port_stats_clr(void *cbarg, bfa_boolean_t complete) { - struct bfa_pport_s *port = cbarg; + struct bfa_fcport_s *fcport = cbarg; if (complete) { - port->stats_cbfn(port->stats_cbarg, port->stats_status); + fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status); } else { - port->stats_busy = BFA_FALSE; - port->stats_status = BFA_STATUS_OK; + fcport->stats_busy = BFA_FALSE; + fcport->stats_status = BFA_STATUS_OK; + } +} + +static void +__bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete) +{ + struct bfa_fcport_s *fcport = cbarg; + + if (complete) { + fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status); + } else { + fcport->stats_busy = BFA_FALSE; + fcport->stats_status = BFA_STATUS_OK; } } static void bfa_port_stats_clr_timeout(void *cbarg) { - struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg; + struct bfa_fcport_s *fcport = (struct bfa_fcport_s *)cbarg; - bfa_trc(port->bfa, port->stats_qfull); + bfa_trc(fcport->bfa, fcport->stats_qfull); - if (port->stats_qfull) { - bfa_reqq_wcancel(&port->stats_reqq_wait); - port->stats_qfull = BFA_FALSE; + if (fcport->stats_qfull) { + bfa_reqq_wcancel(&fcport->stats_reqq_wait); + fcport->stats_qfull = BFA_FALSE; } - port->stats_status = BFA_STATUS_ETIMER; - bfa_cb_queue(port->bfa, &port->hcb_qe, __bfa_cb_port_stats_clr, port); + fcport->stats_status = BFA_STATUS_ETIMER; + bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, + __bfa_cb_port_stats_clr, fcport); } static void -bfa_pport_callback(struct bfa_pport_s *pport, enum bfa_pport_linkstate event) +bfa_fcport_callback(struct bfa_fcport_s *fcport, enum bfa_pport_linkstate event) { - if (pport->bfa->fcs) { - pport->event_cbfn(pport->event_cbarg, event); + if (fcport->bfa->fcs) { + fcport->event_cbfn(fcport->event_cbarg, event); return; } switch (event) { case BFA_PPORT_LINKUP: - bfa_sm_send_event(&pport->ln, BFA_PPORT_LN_SM_LINKUP); + bfa_sm_send_event(&fcport->ln, BFA_FCPORT_LN_SM_LINKUP); break; case BFA_PPORT_LINKDOWN: - bfa_sm_send_event(&pport->ln, BFA_PPORT_LN_SM_LINKDOWN); + bfa_sm_send_event(&fcport->ln, BFA_FCPORT_LN_SM_LINKDOWN); break; default: bfa_assert(0); @@ -1569,41 +1710,92 @@ bfa_pport_callback(struct bfa_pport_s *pport, enum bfa_pport_linkstate event) } static void -bfa_pport_queue_cb(struct bfa_pport_ln_s *ln, enum bfa_pport_linkstate event) +bfa_fcport_queue_cb(struct bfa_fcport_ln_s *ln, enum bfa_pport_linkstate event) { ln->ln_event = event; - bfa_cb_queue(ln->pport->bfa, &ln->ln_qe, __bfa_cb_port_event, ln); + bfa_cb_queue(ln->fcport->bfa, &ln->ln_qe, __bfa_cb_fcport_event, ln); +} + +static void +bfa_fcport_stats_clr_timeout(void *cbarg) +{ + struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg; + + bfa_trc(fcport->bfa, fcport->stats_qfull); + + if (fcport->stats_qfull) { + bfa_reqq_wcancel(&fcport->stats_reqq_wait); + fcport->stats_qfull = BFA_FALSE; + } + + fcport->stats_status = BFA_STATUS_ETIMER; + bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, __bfa_cb_fcport_stats_clr, + fcport); } static void __bfa_cb_port_stats(void *cbarg, bfa_boolean_t complete) { - struct bfa_pport_s *port = cbarg; + struct bfa_fcport_s *fcport = cbarg; if (complete) { - if (port->stats_status == BFA_STATUS_OK) - bfa_pport_stats_swap(port->stats_ret, port->stats); - port->stats_cbfn(port->stats_cbarg, port->stats_status); + if (fcport->stats_status == BFA_STATUS_OK) + bfa_port_stats_swap(fcport->stats_ret, fcport->stats); + fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status); } else { - port->stats_busy = BFA_FALSE; - port->stats_status = BFA_STATUS_OK; + fcport->stats_busy = BFA_FALSE; + fcport->stats_status = BFA_STATUS_OK; } } static void bfa_port_stats_timeout(void *cbarg) { - struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg; + struct bfa_fcport_s *fcport = (struct bfa_fcport_s *)cbarg; - bfa_trc(port->bfa, port->stats_qfull); + bfa_trc(fcport->bfa, fcport->stats_qfull); - if (port->stats_qfull) { - bfa_reqq_wcancel(&port->stats_reqq_wait); - port->stats_qfull = BFA_FALSE; + if (fcport->stats_qfull) { + bfa_reqq_wcancel(&fcport->stats_reqq_wait); + fcport->stats_qfull = BFA_FALSE; } - port->stats_status = BFA_STATUS_ETIMER; - bfa_cb_queue(port->bfa, &port->hcb_qe, __bfa_cb_port_stats, port); + fcport->stats_status = BFA_STATUS_ETIMER; + bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, __bfa_cb_port_stats, fcport); +} + +static void +__bfa_cb_fcport_stats(void *cbarg, bfa_boolean_t complete) +{ + struct bfa_fcport_s *fcport = cbarg; + + if (complete) { + if (fcport->stats_status == BFA_STATUS_OK) { + bfa_fcport_stats_swap(fcport->fcport_stats_ret, + fcport->fcport_stats); + } + fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status); + } else { + fcport->stats_busy = BFA_FALSE; + fcport->stats_status = BFA_STATUS_OK; + } +} + +static void +bfa_fcport_stats_timeout(void *cbarg) +{ + struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg; + + bfa_trc(fcport->bfa, fcport->stats_qfull); + + if (fcport->stats_qfull) { + bfa_reqq_wcancel(&fcport->stats_reqq_wait); + fcport->stats_qfull = BFA_FALSE; + } + + fcport->stats_status = BFA_STATUS_ETIMER; + bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, __bfa_cb_fcport_stats, + fcport); } #define BFA_PORT_STATS_TOV 1000 @@ -1615,21 +1807,21 @@ bfa_status_t bfa_pport_get_stats(struct bfa_s *bfa, union bfa_pport_stats_u *stats, bfa_cb_pport_t cbfn, void *cbarg) { - struct bfa_pport_s *port = BFA_PORT_MOD(bfa); + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); - if (port->stats_busy) { - bfa_trc(bfa, port->stats_busy); + if (fcport->stats_busy) { + bfa_trc(bfa, fcport->stats_busy); return BFA_STATUS_DEVBUSY; } - port->stats_busy = BFA_TRUE; - port->stats_ret = stats; - port->stats_cbfn = cbfn; - port->stats_cbarg = cbarg; + fcport->stats_busy = BFA_TRUE; + fcport->stats_ret = stats; + fcport->stats_cbfn = cbfn; + fcport->stats_cbarg = cbarg; - bfa_port_stats_query(port); + bfa_port_stats_query(fcport); - bfa_timer_start(bfa, &port->timer, bfa_port_stats_timeout, port, + bfa_timer_start(bfa, &fcport->timer, bfa_port_stats_timeout, fcport, BFA_PORT_STATS_TOV); return BFA_STATUS_OK; } @@ -1637,57 +1829,111 @@ bfa_pport_get_stats(struct bfa_s *bfa, union bfa_pport_stats_u *stats, bfa_status_t bfa_pport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg) { - struct bfa_pport_s *port = BFA_PORT_MOD(bfa); + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); + + if (fcport->stats_busy) { + bfa_trc(bfa, fcport->stats_busy); + return BFA_STATUS_DEVBUSY; + } + + fcport->stats_busy = BFA_TRUE; + fcport->stats_cbfn = cbfn; + fcport->stats_cbarg = cbarg; + + bfa_port_stats_clear(fcport); + + bfa_timer_start(bfa, &fcport->timer, bfa_port_stats_clr_timeout, + fcport, BFA_PORT_STATS_TOV); + return BFA_STATUS_OK; +} + +/** + * @brief + * Fetch FCPort statistics. + * Todo TBD: sharing timer,stats_busy and other resources of fcport for now - + * ideally we want to create seperate ones for fcport once bfa_fcport_s is + * decided. + * + */ +bfa_status_t +bfa_fcport_get_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats, + bfa_cb_pport_t cbfn, void *cbarg) +{ + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); - if (port->stats_busy) { - bfa_trc(bfa, port->stats_busy); + if (fcport->stats_busy) { + bfa_trc(bfa, fcport->stats_busy); return BFA_STATUS_DEVBUSY; } - port->stats_busy = BFA_TRUE; - port->stats_cbfn = cbfn; - port->stats_cbarg = cbarg; + fcport->stats_busy = BFA_TRUE; + fcport->fcport_stats_ret = stats; + fcport->stats_cbfn = cbfn; + fcport->stats_cbarg = cbarg; - bfa_port_stats_clear(port); + bfa_fcport_stats_query(fcport); - bfa_timer_start(bfa, &port->timer, bfa_port_stats_clr_timeout, port, + bfa_timer_start(bfa, &fcport->timer, bfa_fcport_stats_timeout, fcport, BFA_PORT_STATS_TOV); + + return BFA_STATUS_OK; +} + +bfa_status_t +bfa_fcport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg) +{ + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); + + if (fcport->stats_busy) { + bfa_trc(bfa, fcport->stats_busy); + return BFA_STATUS_DEVBUSY; + } + + fcport->stats_busy = BFA_TRUE; + fcport->stats_cbfn = cbfn; + fcport->stats_cbarg = cbarg; + + bfa_fcport_stats_clear(fcport); + + bfa_timer_start(bfa, &fcport->timer, bfa_fcport_stats_clr_timeout, + fcport, BFA_PORT_STATS_TOV); + return BFA_STATUS_OK; } bfa_status_t -bfa_pport_trunk_enable(struct bfa_s *bfa, u8 bitmap) +bfa_fcport_trunk_enable(struct bfa_s *bfa, u8 bitmap) { - struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); bfa_trc(bfa, bitmap); - bfa_trc(bfa, pport->cfg.trunked); - bfa_trc(bfa, pport->cfg.trunk_ports); + bfa_trc(bfa, fcport->cfg.trunked); + bfa_trc(bfa, fcport->cfg.trunk_ports); if (!bitmap || (bitmap & (bitmap - 1))) return BFA_STATUS_EINVAL; - pport->cfg.trunked = BFA_TRUE; - pport->cfg.trunk_ports = bitmap; + fcport->cfg.trunked = BFA_TRUE; + fcport->cfg.trunk_ports = bitmap; return BFA_STATUS_OK; } void -bfa_pport_qos_get_attr(struct bfa_s *bfa, struct bfa_qos_attr_s *qos_attr) +bfa_fcport_qos_get_attr(struct bfa_s *bfa, struct bfa_qos_attr_s *qos_attr) { - struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); - qos_attr->state = bfa_os_ntohl(pport->qos_attr.state); - qos_attr->total_bb_cr = bfa_os_ntohl(pport->qos_attr.total_bb_cr); + qos_attr->state = bfa_os_ntohl(fcport->qos_attr.state); + qos_attr->total_bb_cr = bfa_os_ntohl(fcport->qos_attr.total_bb_cr); } void -bfa_pport_qos_get_vc_attr(struct bfa_s *bfa, +bfa_fcport_qos_get_vc_attr(struct bfa_s *bfa, struct bfa_qos_vc_attr_s *qos_vc_attr) { - struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); - struct bfa_qos_vc_attr_s *bfa_vc_attr = &pport->qos_vc_attr; + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); + struct bfa_qos_vc_attr_s *bfa_vc_attr = &fcport->qos_vc_attr; u32 i = 0; qos_vc_attr->total_vc_count = bfa_os_ntohs(bfa_vc_attr->total_vc_count); @@ -1713,7 +1959,7 @@ bfa_pport_qos_get_vc_attr(struct bfa_s *bfa, * Fetch QoS Stats. */ bfa_status_t -bfa_pport_get_qos_stats(struct bfa_s *bfa, union bfa_pport_stats_u *stats, +bfa_fcport_get_qos_stats(struct bfa_s *bfa, union bfa_pport_stats_u *stats, bfa_cb_pport_t cbfn, void *cbarg) { /* @@ -1723,23 +1969,23 @@ bfa_pport_get_qos_stats(struct bfa_s *bfa, union bfa_pport_stats_u *stats, } bfa_status_t -bfa_pport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg) +bfa_fcport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg) { - struct bfa_pport_s *port = BFA_PORT_MOD(bfa); + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); - if (port->stats_busy) { - bfa_trc(bfa, port->stats_busy); + if (fcport->stats_busy) { + bfa_trc(bfa, fcport->stats_busy); return BFA_STATUS_DEVBUSY; } - port->stats_busy = BFA_TRUE; - port->stats_cbfn = cbfn; - port->stats_cbarg = cbarg; + fcport->stats_busy = BFA_TRUE; + fcport->stats_cbfn = cbfn; + fcport->stats_cbarg = cbarg; - bfa_port_qos_stats_clear(port); + bfa_port_qos_stats_clear(fcport); - bfa_timer_start(bfa, &port->timer, bfa_port_stats_clr_timeout, port, - BFA_PORT_STATS_TOV); + bfa_timer_start(bfa, &fcport->timer, bfa_port_stats_clr_timeout, + fcport, BFA_PORT_STATS_TOV); return BFA_STATUS_OK; } @@ -1747,82 +1993,82 @@ bfa_pport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg) * Fetch port attributes. */ bfa_status_t -bfa_pport_trunk_disable(struct bfa_s *bfa) +bfa_fcport_trunk_disable(struct bfa_s *bfa) { return BFA_STATUS_OK; } bfa_boolean_t -bfa_pport_trunk_query(struct bfa_s *bfa, u32 *bitmap) +bfa_fcport_trunk_query(struct bfa_s *bfa, u32 *bitmap) { - struct bfa_pport_s *port = BFA_PORT_MOD(bfa); + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); - *bitmap = port->cfg.trunk_ports; - return port->cfg.trunked; + *bitmap = fcport->cfg.trunk_ports; + return fcport->cfg.trunked; } bfa_boolean_t -bfa_pport_is_disabled(struct bfa_s *bfa) +bfa_fcport_is_disabled(struct bfa_s *bfa) { - struct bfa_pport_s *port = BFA_PORT_MOD(bfa); + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); - return bfa_sm_to_state(hal_pport_sm_table, port->sm) == + return bfa_sm_to_state(hal_pport_sm_table, fcport->sm) == BFA_PPORT_ST_DISABLED; } bfa_boolean_t -bfa_pport_is_ratelim(struct bfa_s *bfa) +bfa_fcport_is_ratelim(struct bfa_s *bfa) { - struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); - return pport->cfg.ratelimit ? BFA_TRUE : BFA_FALSE; + return fcport->cfg.ratelimit ? BFA_TRUE : BFA_FALSE; } void -bfa_pport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off) +bfa_fcport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off) { - struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); bfa_trc(bfa, on_off); - bfa_trc(bfa, pport->cfg.qos_enabled); + bfa_trc(bfa, fcport->cfg.qos_enabled); - pport->cfg.qos_enabled = on_off; + fcport->cfg.qos_enabled = on_off; } void -bfa_pport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off) +bfa_fcport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off) { - struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); bfa_trc(bfa, on_off); - bfa_trc(bfa, pport->cfg.ratelimit); + bfa_trc(bfa, fcport->cfg.ratelimit); - pport->cfg.ratelimit = on_off; - if (pport->cfg.trl_def_speed == BFA_PPORT_SPEED_UNKNOWN) - pport->cfg.trl_def_speed = BFA_PPORT_SPEED_1GBPS; + fcport->cfg.ratelimit = on_off; + if (fcport->cfg.trl_def_speed == BFA_PPORT_SPEED_UNKNOWN) + fcport->cfg.trl_def_speed = BFA_PPORT_SPEED_1GBPS; } /** * Configure default minimum ratelim speed */ bfa_status_t -bfa_pport_cfg_ratelim_speed(struct bfa_s *bfa, enum bfa_pport_speed speed) +bfa_fcport_cfg_ratelim_speed(struct bfa_s *bfa, enum bfa_pport_speed speed) { - struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); bfa_trc(bfa, speed); /* * Auto and speeds greater than the supported speed, are invalid */ - if ((speed == BFA_PPORT_SPEED_AUTO) || (speed > pport->speed_sup)) { - bfa_trc(bfa, pport->speed_sup); + if ((speed == BFA_PPORT_SPEED_AUTO) || (speed > fcport->speed_sup)) { + bfa_trc(bfa, fcport->speed_sup); return BFA_STATUS_UNSUPP_SPEED; } - pport->cfg.trl_def_speed = speed; + fcport->cfg.trl_def_speed = speed; return BFA_STATUS_OK; } @@ -1831,45 +2077,45 @@ bfa_pport_cfg_ratelim_speed(struct bfa_s *bfa, enum bfa_pport_speed speed) * Get default minimum ratelim speed */ enum bfa_pport_speed -bfa_pport_get_ratelim_speed(struct bfa_s *bfa) +bfa_fcport_get_ratelim_speed(struct bfa_s *bfa) { - struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); - bfa_trc(bfa, pport->cfg.trl_def_speed); - return pport->cfg.trl_def_speed; + bfa_trc(bfa, fcport->cfg.trl_def_speed); + return fcport->cfg.trl_def_speed; } void -bfa_pport_busy(struct bfa_s *bfa, bfa_boolean_t status) +bfa_fcport_busy(struct bfa_s *bfa, bfa_boolean_t status) { - struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); bfa_trc(bfa, status); - bfa_trc(bfa, pport->diag_busy); + bfa_trc(bfa, fcport->diag_busy); - pport->diag_busy = status; + fcport->diag_busy = status; } void -bfa_pport_beacon(struct bfa_s *bfa, bfa_boolean_t beacon, +bfa_fcport_beacon(struct bfa_s *bfa, bfa_boolean_t beacon, bfa_boolean_t link_e2e_beacon) { - struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); + struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); bfa_trc(bfa, beacon); bfa_trc(bfa, link_e2e_beacon); - bfa_trc(bfa, pport->beacon); - bfa_trc(bfa, pport->link_e2e_beacon); + bfa_trc(bfa, fcport->beacon); + bfa_trc(bfa, fcport->link_e2e_beacon); - pport->beacon = beacon; - pport->link_e2e_beacon = link_e2e_beacon; + fcport->beacon = beacon; + fcport->link_e2e_beacon = link_e2e_beacon; } bfa_boolean_t -bfa_pport_is_linkup(struct bfa_s *bfa) +bfa_fcport_is_linkup(struct bfa_s *bfa) { - return bfa_sm_cmp_state(BFA_PORT_MOD(bfa), bfa_pport_sm_linkup); + return bfa_sm_cmp_state(BFA_FCPORT_MOD(bfa), bfa_fcport_sm_linkup); } diff --git a/drivers/scsi/bfa/bfa_fcs_port.c b/drivers/scsi/bfa/bfa_fcs_port.c index 53808d0..3c27788 100644 --- a/drivers/scsi/bfa/bfa_fcs_port.c +++ b/drivers/scsi/bfa/bfa_fcs_port.c @@ -57,5 +57,5 @@ bfa_fcs_pport_event_handler(void *cbarg, bfa_pport_event_t event) void bfa_fcs_pport_attach(struct bfa_fcs_s *fcs) { - bfa_pport_event_register(fcs->bfa, bfa_fcs_pport_event_handler, fcs); + bfa_fcport_event_register(fcs->bfa, bfa_fcs_pport_event_handler, fcs); } diff --git a/drivers/scsi/bfa/bfa_module.c b/drivers/scsi/bfa/bfa_module.c index 32eda8e..a7fcc80 100644 --- a/drivers/scsi/bfa/bfa_module.c +++ b/drivers/scsi/bfa/bfa_module.c @@ -24,7 +24,7 @@ */ struct bfa_module_s *hal_mods[] = { &hal_mod_sgpg, - &hal_mod_pport, + &hal_mod_fcport, &hal_mod_fcxp, &hal_mod_lps, &hal_mod_uf, @@ -45,7 +45,7 @@ bfa_isr_func_t bfa_isrs[BFI_MC_MAX] = { bfa_isr_unhandled, /* BFI_MC_DIAG */ bfa_isr_unhandled, /* BFI_MC_FLASH */ bfa_isr_unhandled, /* BFI_MC_CEE */ - bfa_pport_isr, /* BFI_MC_PORT */ + bfa_fcport_isr, /* BFI_MC_FCPORT */ bfa_isr_unhandled, /* BFI_MC_IOCFC */ bfa_isr_unhandled, /* BFI_MC_LL */ bfa_uf_isr, /* BFI_MC_UF */ diff --git a/drivers/scsi/bfa/bfa_modules_priv.h b/drivers/scsi/bfa/bfa_modules_priv.h index 96f7053..f554c2f 100644 --- a/drivers/scsi/bfa/bfa_modules_priv.h +++ b/drivers/scsi/bfa/bfa_modules_priv.h @@ -29,7 +29,7 @@ struct bfa_modules_s { - struct bfa_pport_s pport; /* physical port module */ + struct bfa_fcport_s fcport; /* fc port module */ struct bfa_fcxp_mod_s fcxp_mod; /* fcxp module */ struct bfa_lps_mod_s lps_mod; /* fcxp module */ struct bfa_uf_mod_s uf_mod; /* unsolicited frame module */ diff --git a/drivers/scsi/bfa/bfa_port_priv.h b/drivers/scsi/bfa/bfa_port_priv.h index f29701b..6d315ff 100644 --- a/drivers/scsi/bfa/bfa_port_priv.h +++ b/drivers/scsi/bfa/bfa_port_priv.h @@ -25,17 +25,17 @@ /** * Link notification data structure */ -struct bfa_pport_ln_s { - struct bfa_pport_s *pport; +struct bfa_fcport_ln_s { + struct bfa_fcport_s *fcport; bfa_sm_t sm; struct bfa_cb_qe_s ln_qe; /* BFA callback queue elem for ln */ enum bfa_pport_linkstate ln_event; /* ln event for callback */ }; /** - * BFA physical port data structure + * BFA FC port data structure */ -struct bfa_pport_s { +struct bfa_fcport_s { struct bfa_s *bfa; /* parent BFA instance */ bfa_sm_t sm; /* port state machine */ wwn_t nwwn; /* node wwn of physical port */ @@ -62,7 +62,7 @@ struct bfa_pport_s { union bfi_pport_i2h_msg_u i2hmsg; } event_arg; void *bfad; /* BFA driver handle */ - struct bfa_pport_ln_s ln; /* Link Notification */ + struct bfa_fcport_ln_s ln; /* Link Notification */ struct bfa_cb_qe_s hcb_qe; /* BFA callback queue elem */ u32 msgtag; /* fimrware msg tag for reply */ u8 *stats_kva; @@ -88,12 +88,17 @@ struct bfa_pport_s { /* driver callback function */ void *stats_cbarg; /* *!< user callback arg */ + /* FCport stats */ + u8 *fcport_stats_kva; + u64 fcport_stats_pa; + union bfa_fcport_stats_u *fcport_stats; + union bfa_fcport_stats_u *fcport_stats_ret; }; -#define BFA_PORT_MOD(__bfa) (&(__bfa)->modules.pport) +#define BFA_FCPORT_MOD(__bfa) (&(__bfa)->modules.fcport) /* * public functions */ -void bfa_pport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg); +void bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg); #endif /* __BFA_PORT_PRIV_H__ */ diff --git a/drivers/scsi/bfa/bfa_priv.h b/drivers/scsi/bfa/bfa_priv.h index 0747a6b..be80fc7 100644 --- a/drivers/scsi/bfa/bfa_priv.h +++ b/drivers/scsi/bfa/bfa_priv.h @@ -101,7 +101,7 @@ extern bfa_boolean_t bfa_auto_recover; extern struct bfa_module_s hal_mod_flash; extern struct bfa_module_s hal_mod_fcdiag; extern struct bfa_module_s hal_mod_sgpg; -extern struct bfa_module_s hal_mod_pport; +extern struct bfa_module_s hal_mod_fcport; extern struct bfa_module_s hal_mod_fcxp; extern struct bfa_module_s hal_mod_lps; extern struct bfa_module_s hal_mod_uf; diff --git a/drivers/scsi/bfa/bfa_trcmod_priv.h b/drivers/scsi/bfa/bfa_trcmod_priv.h index 3d947d4..a7a8261 100644 --- a/drivers/scsi/bfa/bfa_trcmod_priv.h +++ b/drivers/scsi/bfa/bfa_trcmod_priv.h @@ -37,7 +37,7 @@ enum { BFA_TRC_HAL_IOIM = 6, BFA_TRC_HAL_TSKIM = 7, BFA_TRC_HAL_ITNIM = 8, - BFA_TRC_HAL_PPORT = 9, + BFA_TRC_HAL_FCPORT = 9, BFA_TRC_HAL_SGPG = 10, BFA_TRC_HAL_FLASH = 11, BFA_TRC_HAL_DEBUG = 12, diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c index 79956c1..a8a529d 100644 --- a/drivers/scsi/bfa/bfad.c +++ b/drivers/scsi/bfa/bfad.c @@ -664,7 +664,7 @@ bfad_fcs_port_cfg(struct bfad_s *bfad) sprintf(symname, "%s-%d", BFAD_DRIVER_NAME, bfad->inst_no); memcpy(port_cfg.sym_name.symname, symname, strlen(symname)); - bfa_pport_get_attr(&bfad->bfa, &attr); + bfa_fcport_get_attr(&bfad->bfa, &attr); port_cfg.nwwn = attr.nwwn; port_cfg.pwwn = attr.pwwn; diff --git a/drivers/scsi/bfa/bfad_attr.c b/drivers/scsi/bfa/bfad_attr.c index adf801d..a691133 100644 --- a/drivers/scsi/bfa/bfad_attr.c +++ b/drivers/scsi/bfa/bfad_attr.c @@ -141,7 +141,7 @@ bfad_im_get_host_port_type(struct Scsi_Host *shost) struct bfad_s *bfad = im_port->bfad; struct bfa_pport_attr_s attr; - bfa_pport_get_attr(&bfad->bfa, &attr); + bfa_fcport_get_attr(&bfad->bfa, &attr); switch (attr.port_type) { case BFA_PPORT_TYPE_NPORT: @@ -173,7 +173,7 @@ bfad_im_get_host_port_state(struct Scsi_Host *shost) struct bfad_s *bfad = im_port->bfad; struct bfa_pport_attr_s attr; - bfa_pport_get_attr(&bfad->bfa, &attr); + bfa_fcport_get_attr(&bfad->bfa, &attr); switch (attr.port_state) { case BFA_PPORT_ST_LINKDOWN: @@ -232,7 +232,7 @@ bfad_im_get_host_speed(struct Scsi_Host *shost) unsigned long flags; spin_lock_irqsave(shost->host_lock, flags); - bfa_pport_get_attr(&bfad->bfa, &attr); + bfa_fcport_get_attr(&bfad->bfa, &attr); switch (attr.speed) { case BFA_PPORT_SPEED_8GBPS: fc_host_speed(shost) = FC_PORTSPEED_8GBIT; diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c index f788c2a..23390b4 100644 --- a/drivers/scsi/bfa/bfad_im.c +++ b/drivers/scsi/bfa/bfad_im.c @@ -966,7 +966,7 @@ bfad_os_fc_host_init(struct bfad_im_port_s *im_port) FC_PORTSPEED_1GBIT; memset(&attr.pattr, 0, sizeof(attr.pattr)); - bfa_pport_get_attr(&bfad->bfa, &attr.pattr); + bfa_fcport_get_attr(&bfad->bfa, &attr.pattr); fc_host_maxframe_size(host) = attr.pattr.pport_cfg.maxfrsize; } diff --git a/drivers/scsi/bfa/fabric.c b/drivers/scsi/bfa/fabric.c index b02ed76..e1a4b31 100644 --- a/drivers/scsi/bfa/fabric.c +++ b/drivers/scsi/bfa/fabric.c @@ -37,7 +37,7 @@ BFA_TRC_FILE(FCS, FABRIC); #define BFA_FCS_FABRIC_CLEANUP_DELAY (10000) /* Milliseconds */ #define bfa_fcs_fabric_set_opertype(__fabric) do { \ - if (bfa_pport_get_topology((__fabric)->fcs->bfa) \ + if (bfa_fcport_get_topology((__fabric)->fcs->bfa) \ == BFA_PPORT_TOPOLOGY_P2P) \ (__fabric)->oper_type = BFA_PPORT_TYPE_NPORT; \ else \ @@ -160,7 +160,7 @@ bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s *fabric, switch (event) { case BFA_FCS_FABRIC_SM_START: - if (bfa_pport_is_linkup(fabric->fcs->bfa)) { + if (bfa_fcport_is_linkup(fabric->fcs->bfa)) { bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi); bfa_fcs_fabric_login(fabric); } else @@ -224,7 +224,7 @@ bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric, switch (event) { case BFA_FCS_FABRIC_SM_CONT_OP: - bfa_pport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit); + bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit); fabric->fab_type = BFA_FCS_FABRIC_SWITCHED; if (fabric->auth_reqd && fabric->is_auth) { @@ -251,7 +251,7 @@ bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric, case BFA_FCS_FABRIC_SM_NO_FABRIC: fabric->fab_type = BFA_FCS_FABRIC_N2N; - bfa_pport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit); + bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit); bfa_fcs_fabric_notify_online(fabric); bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_nofabric); break; @@ -418,7 +418,7 @@ bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s *fabric, case BFA_FCS_FABRIC_SM_NO_FABRIC: bfa_trc(fabric->fcs, fabric->bb_credit); - bfa_pport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit); + bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit); break; default: @@ -718,10 +718,10 @@ bfa_fcs_fabric_login(struct bfa_fcs_fabric_s *fabric) struct bfa_port_cfg_s *pcfg = &fabric->bport.port_cfg; u8 alpa = 0; - if (bfa_pport_get_topology(bfa) == BFA_PPORT_TOPOLOGY_LOOP) - alpa = bfa_pport_get_myalpa(bfa); + if (bfa_fcport_get_topology(bfa) == BFA_PPORT_TOPOLOGY_LOOP) + alpa = bfa_fcport_get_myalpa(bfa); - bfa_lps_flogi(fabric->lps, fabric, alpa, bfa_pport_get_maxfrsize(bfa), + bfa_lps_flogi(fabric->lps, fabric, alpa, bfa_fcport_get_maxfrsize(bfa), pcfg->pwwn, pcfg->nwwn, fabric->auth_reqd); fabric->stats.flogi_sent++; @@ -1176,8 +1176,8 @@ bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s *fabric) reqlen = fc_flogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), bfa_os_hton3b(FC_FABRIC_PORT), n2n_port->reply_oxid, pcfg->pwwn, - pcfg->nwwn, bfa_pport_get_maxfrsize(bfa), - bfa_pport_get_rx_bbcredit(bfa)); + pcfg->nwwn, bfa_fcport_get_maxfrsize(bfa), + bfa_fcport_get_rx_bbcredit(bfa)); bfa_fcxp_send(fcxp, NULL, fabric->vf_id, bfa_lps_get_tag(fabric->lps), BFA_FALSE, FC_CLASS_3, reqlen, &fchs, diff --git a/drivers/scsi/bfa/fdmi.c b/drivers/scsi/bfa/fdmi.c index e812086..2c9e713 100644 --- a/drivers/scsi/bfa/fdmi.c +++ b/drivers/scsi/bfa/fdmi.c @@ -1175,7 +1175,7 @@ bfa_fcs_fdmi_get_portattr(struct bfa_fcs_port_fdmi_s *fdmi, /* * get pport attributes from hal */ - bfa_pport_get_attr(port->fcs->bfa, &pport_attr); + bfa_fcport_get_attr(port->fcs->bfa, &pport_attr); /* * get FC4 type Bitmask diff --git a/drivers/scsi/bfa/include/bfa_svc.h b/drivers/scsi/bfa/include/bfa_svc.h index 71ffb75..f2c3085 100644 --- a/drivers/scsi/bfa/include/bfa_svc.h +++ b/drivers/scsi/bfa/include/bfa_svc.h @@ -26,6 +26,7 @@ struct bfa_fcxp_s; #include #include #include +#include #include #include @@ -151,60 +152,67 @@ struct bfa_lps_s { bfa_eproto_status_t ext_status; }; +#define BFA_FCPORT(_bfa) (&((_bfa)->modules.port)) + /* * bfa pport API functions */ -bfa_status_t bfa_pport_enable(struct bfa_s *bfa); -bfa_status_t bfa_pport_disable(struct bfa_s *bfa); -bfa_status_t bfa_pport_cfg_speed(struct bfa_s *bfa, +bfa_status_t bfa_fcport_enable(struct bfa_s *bfa); +bfa_status_t bfa_fcport_disable(struct bfa_s *bfa); +bfa_status_t bfa_fcport_cfg_speed(struct bfa_s *bfa, enum bfa_pport_speed speed); -enum bfa_pport_speed bfa_pport_get_speed(struct bfa_s *bfa); -bfa_status_t bfa_pport_cfg_topology(struct bfa_s *bfa, +enum bfa_pport_speed bfa_fcport_get_speed(struct bfa_s *bfa); +bfa_status_t bfa_fcport_cfg_topology(struct bfa_s *bfa, enum bfa_pport_topology topo); -enum bfa_pport_topology bfa_pport_get_topology(struct bfa_s *bfa); -bfa_status_t bfa_pport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa); -bfa_boolean_t bfa_pport_get_hardalpa(struct bfa_s *bfa, u8 *alpa); -u8 bfa_pport_get_myalpa(struct bfa_s *bfa); -bfa_status_t bfa_pport_clr_hardalpa(struct bfa_s *bfa); -bfa_status_t bfa_pport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxsize); -u16 bfa_pport_get_maxfrsize(struct bfa_s *bfa); -u32 bfa_pport_mypid(struct bfa_s *bfa); -u8 bfa_pport_get_rx_bbcredit(struct bfa_s *bfa); -bfa_status_t bfa_pport_trunk_enable(struct bfa_s *bfa, u8 bitmap); -bfa_status_t bfa_pport_trunk_disable(struct bfa_s *bfa); -bfa_boolean_t bfa_pport_trunk_query(struct bfa_s *bfa, u32 *bitmap); -void bfa_pport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr); -wwn_t bfa_pport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node); +enum bfa_pport_topology bfa_fcport_get_topology(struct bfa_s *bfa); +bfa_status_t bfa_fcport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa); +bfa_boolean_t bfa_fcport_get_hardalpa(struct bfa_s *bfa, u8 *alpa); +u8 bfa_fcport_get_myalpa(struct bfa_s *bfa); +bfa_status_t bfa_fcport_clr_hardalpa(struct bfa_s *bfa); +bfa_status_t bfa_fcport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxsize); +u16 bfa_fcport_get_maxfrsize(struct bfa_s *bfa); +u32 bfa_fcport_mypid(struct bfa_s *bfa); +u8 bfa_fcport_get_rx_bbcredit(struct bfa_s *bfa); +bfa_status_t bfa_fcport_trunk_enable(struct bfa_s *bfa, u8 bitmap); +bfa_status_t bfa_fcport_trunk_disable(struct bfa_s *bfa); +bfa_boolean_t bfa_fcport_trunk_query(struct bfa_s *bfa, u32 *bitmap); +void bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr); +wwn_t bfa_fcport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node); bfa_status_t bfa_pport_get_stats(struct bfa_s *bfa, union bfa_pport_stats_u *stats, bfa_cb_pport_t cbfn, void *cbarg); bfa_status_t bfa_pport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg); -void bfa_pport_event_register(struct bfa_s *bfa, +void bfa_fcport_event_register(struct bfa_s *bfa, void (*event_cbfn) (void *cbarg, bfa_pport_event_t event), void *event_cbarg); -bfa_boolean_t bfa_pport_is_disabled(struct bfa_s *bfa); -void bfa_pport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off); -void bfa_pport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off); -bfa_status_t bfa_pport_cfg_ratelim_speed(struct bfa_s *bfa, +bfa_boolean_t bfa_fcport_is_disabled(struct bfa_s *bfa); +void bfa_fcport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off); +void bfa_fcport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off); +bfa_status_t bfa_fcport_cfg_ratelim_speed(struct bfa_s *bfa, enum bfa_pport_speed speed); -enum bfa_pport_speed bfa_pport_get_ratelim_speed(struct bfa_s *bfa); +enum bfa_pport_speed bfa_fcport_get_ratelim_speed(struct bfa_s *bfa); -void bfa_pport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit); -void bfa_pport_busy(struct bfa_s *bfa, bfa_boolean_t status); -void bfa_pport_beacon(struct bfa_s *bfa, bfa_boolean_t beacon, +void bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit); +void bfa_fcport_busy(struct bfa_s *bfa, bfa_boolean_t status); +void bfa_fcport_beacon(struct bfa_s *bfa, bfa_boolean_t beacon, bfa_boolean_t link_e2e_beacon); void bfa_cb_pport_event(void *cbarg, bfa_pport_event_t event); -void bfa_pport_qos_get_attr(struct bfa_s *bfa, struct bfa_qos_attr_s *qos_attr); -void bfa_pport_qos_get_vc_attr(struct bfa_s *bfa, +void bfa_fcport_qos_get_attr(struct bfa_s *bfa, struct bfa_qos_attr_s *qos_attr); +void bfa_fcport_qos_get_vc_attr(struct bfa_s *bfa, struct bfa_qos_vc_attr_s *qos_vc_attr); -bfa_status_t bfa_pport_get_qos_stats(struct bfa_s *bfa, +bfa_status_t bfa_fcport_get_qos_stats(struct bfa_s *bfa, union bfa_pport_stats_u *stats, bfa_cb_pport_t cbfn, void *cbarg); -bfa_status_t bfa_pport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, +bfa_status_t bfa_fcport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg); -bfa_boolean_t bfa_pport_is_ratelim(struct bfa_s *bfa); -bfa_boolean_t bfa_pport_is_linkup(struct bfa_s *bfa); +bfa_boolean_t bfa_fcport_is_ratelim(struct bfa_s *bfa); +bfa_boolean_t bfa_fcport_is_linkup(struct bfa_s *bfa); +bfa_status_t bfa_fcport_get_stats(struct bfa_s *bfa, + union bfa_fcport_stats_u *stats, + bfa_cb_pport_t cbfn, void *cbarg); +bfa_status_t bfa_fcport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, + void *cbarg); /* * bfa rport API functions diff --git a/drivers/scsi/bfa/include/bfi/bfi_pport.h b/drivers/scsi/bfa/include/bfi/bfi_pport.h index c96d246..5c3d289 100644 --- a/drivers/scsi/bfa/include/bfi/bfi_pport.h +++ b/drivers/scsi/bfa/include/bfi/bfi_pport.h @@ -32,6 +32,8 @@ enum bfi_pport_h2i { BFI_PPORT_H2I_ENABLE_TX_VF_TAG_REQ = (7), BFI_PPORT_H2I_GET_QOS_STATS_REQ = (8), BFI_PPORT_H2I_CLEAR_QOS_STATS_REQ = (9), + BFI_FCPORT_H2I_GET_STATS_REQ = (10), + BFI_FCPORT_H2I_CLEAR_STATS_REQ = (11), }; enum bfi_pport_i2h { @@ -45,6 +47,8 @@ enum bfi_pport_i2h { BFI_PPORT_I2H_EVENT = BFA_I2HM(8), BFI_PPORT_I2H_GET_QOS_STATS_RSP = BFA_I2HM(9), BFI_PPORT_I2H_CLEAR_QOS_STATS_RSP = BFA_I2HM(10), + BFI_FCPORT_I2H_GET_STATS_RSP = BFA_I2HM(11), + BFI_FCPORT_I2H_CLEAR_STATS_RSP = BFA_I2HM(12), }; /** @@ -75,6 +79,7 @@ struct bfi_pport_enable_req_s { wwn_t pwwn; /* port wwn of physical port */ struct bfa_pport_cfg_s port_cfg; /* port configuration */ union bfi_addr_u stats_dma_addr; /* DMA address for stats */ + union bfi_addr_u fcport_stats_dma_addr;/*!< DMA address for stats */ u32 msgtag; /* msgtag for reply */ u32 rsvd2; }; diff --git a/drivers/scsi/bfa/include/cs/bfa_sm.h b/drivers/scsi/bfa/include/cs/bfa_sm.h index b0a92ba..11fba90 100644 --- a/drivers/scsi/bfa/include/cs/bfa_sm.h +++ b/drivers/scsi/bfa/include/cs/bfa_sm.h @@ -23,6 +23,14 @@ #define __BFA_SM_H__ typedef void (*bfa_sm_t)(void *sm, int event); +/** + * oc - object class eg. bfa_ioc + * st - state, eg. reset + * otype - object type, eg. struct bfa_ioc_s + * etype - object type, eg. enum ioc_event + */ +#define bfa_sm_state_decl(oc, st, otype, etype) \ + static void oc ## _sm_ ## st(otype * fsm, etype event) #define bfa_sm_set_state(_sm, _state) ((_sm)->sm = (bfa_sm_t)(_state)) #define bfa_sm_send_event(_sm, _event) ((_sm)->sm((_sm), (_event))) diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_ethport.h b/drivers/scsi/bfa/include/defs/bfa_defs_ethport.h index 79f9b3e..b4fa092 100644 --- a/drivers/scsi/bfa/include/defs/bfa_defs_ethport.h +++ b/drivers/scsi/bfa/include/defs/bfa_defs_ethport.h @@ -19,6 +19,7 @@ #define __BFA_DEFS_ETHPORT_H__ #include +#include #include #include #include diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_fcport.h b/drivers/scsi/bfa/include/defs/bfa_defs_fcport.h new file mode 100644 index 0000000..a07ef4a --- /dev/null +++ b/drivers/scsi/bfa/include/defs/bfa_defs_fcport.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + * + * bfa_defs_fcport.h + * + * Linux driver for Brocade Fibre Channel Host Bus Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +#ifndef __BFA_DEFS_FCPORT_H__ +#define __BFA_DEFS_FCPORT_H__ + +#include +#include + +#pragma pack(1) + +/** + * FCoE statistics + */ +struct bfa_fcoe_stats_s { + u64 secs_reset; /* Seconds since stats reset */ + u64 cee_linkups; /* CEE link up */ + u64 cee_linkdns; /* CEE link down */ + u64 fip_linkups; /* FIP link up */ + u64 fip_linkdns; /* FIP link down */ + u64 fip_fails; /* FIP failures */ + u64 mac_invalids; /* Invalid mac assignments */ + u64 vlan_req; /* Vlan requests */ + u64 vlan_notify; /* Vlan notifications */ + u64 vlan_err; /* Vlan notification errors */ + u64 vlan_timeouts; /* Vlan request timeouts */ + u64 vlan_invalids; /* Vlan invalids */ + u64 disc_req; /* Discovery requests */ + u64 disc_rsp; /* Discovery responses */ + u64 disc_err; /* Discovery error frames */ + u64 disc_unsol; /* Discovery unsolicited */ + u64 disc_timeouts; /* Discovery timeouts */ + u64 disc_fcf_unavail; /* Discovery FCF not avail */ + u64 linksvc_unsupp; /* FIP link service req unsupp. */ + u64 linksvc_err; /* FIP link service req errors */ + u64 logo_req; /* FIP logo */ + u64 clrvlink_req; /* Clear virtual link requests */ + u64 op_unsupp; /* FIP operation unsupp. */ + u64 untagged; /* FIP untagged frames */ + u64 txf_ucast; /* Tx FCoE unicast frames */ + u64 txf_ucast_vlan; /* Tx FCoE unicast vlan frames */ + u64 txf_ucast_octets; /* Tx FCoE unicast octets */ + u64 txf_mcast; /* Tx FCoE mutlicast frames */ + u64 txf_mcast_vlan; /* Tx FCoE mutlicast vlan frames */ + u64 txf_mcast_octets; /* Tx FCoE multicast octets */ + u64 txf_bcast; /* Tx FCoE broadcast frames */ + u64 txf_bcast_vlan; /* Tx FCoE broadcast vlan frames */ + u64 txf_bcast_octets; /* Tx FCoE broadcast octets */ + u64 txf_timeout; /* Tx timeouts */ + u64 txf_parity_errors; /* Transmit parity err */ + u64 txf_fid_parity_errors; /* Transmit FID parity err */ + u64 tx_pause; /* Tx pause frames */ + u64 tx_zero_pause; /* Tx zero pause frames */ + u64 tx_first_pause; /* Tx first pause frames */ + u64 rx_pause; /* Rx pause frames */ + u64 rx_zero_pause; /* Rx zero pause frames */ + u64 rx_first_pause; /* Rx first pause frames */ + u64 rxf_ucast_octets; /* Rx unicast octets */ + u64 rxf_ucast; /* Rx unicast frames */ + u64 rxf_ucast_vlan; /* Rx unicast vlan frames */ + u64 rxf_mcast_octets; /* Rx multicast octets */ + u64 rxf_mcast; /* Rx multicast frames */ + u64 rxf_mcast_vlan; /* Rx multicast vlan frames */ + u64 rxf_bcast_octets; /* Rx broadcast octests */ + u64 rxf_bcast; /* Rx broadcast frames */ + u64 rxf_bcast_vlan; /* Rx broadcast vlan frames */ +}; + +/** + * QoS or FCoE stats (fcport stats excluding physical FC port stats) + */ +union bfa_fcport_stats_u { + struct bfa_qos_stats_s fcqos; + struct bfa_fcoe_stats_s fcoe; +}; + +#pragma pack() + +#endif /* __BFA_DEFS_FCPORT_H__ */ diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h b/drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h index 87f0401..c290fb1 100644 --- a/drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h +++ b/drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h @@ -236,6 +236,7 @@ struct bfa_fw_fip_stats_s { u32 disc_err; /* Discovery advt. parse errors */ u32 disc_unsol; /* Discovery unsolicited */ u32 disc_timeouts; /* Discovery timeouts */ + u32 disc_fcf_unavail; /* Discovery FCF Not Avail. */ u32 linksvc_unsupp; /* Unsupported link service req */ u32 linksvc_err; /* Parse error in link service req */ u32 logo_req; /* Number of FIP logos received */ diff --git a/drivers/scsi/bfa/loop.c b/drivers/scsi/bfa/loop.c index f7c7f4f..f6342ef 100644 --- a/drivers/scsi/bfa/loop.c +++ b/drivers/scsi/bfa/loop.c @@ -162,7 +162,7 @@ bfa_fcs_port_loop_send_plogi(struct bfa_fcs_port_s *port, u8 alpa) len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), alpa, bfa_fcs_port_get_fcid(port), 0, port->port_cfg.pwwn, port->port_cfg.nwwn, - bfa_pport_get_maxfrsize(port->fcs->bfa)); + bfa_fcport_get_maxfrsize(port->fcs->bfa)); bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, FC_CLASS_3, len, &fchs, diff --git a/drivers/scsi/bfa/lport_api.c b/drivers/scsi/bfa/lport_api.c index 4a4ccce..d3907d1 100644 --- a/drivers/scsi/bfa/lport_api.c +++ b/drivers/scsi/bfa/lport_api.c @@ -156,7 +156,7 @@ bfa_fcs_port_get_rport_max_speed(struct bfa_fcs_port_s *port) /* * Get Physical port's current speed */ - bfa_pport_get_attr(port->fcs->bfa, &pport_attr); + bfa_fcport_get_attr(port->fcs->bfa, &pport_attr); pport_speed = pport_attr.speed; bfa_trc(fcs, pport_speed); diff --git a/drivers/scsi/bfa/ms.c b/drivers/scsi/bfa/ms.c index f0275a4..e6db5fd 100644 --- a/drivers/scsi/bfa/ms.c +++ b/drivers/scsi/bfa/ms.c @@ -637,7 +637,7 @@ bfa_fcs_port_ms_send_plogi(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced) bfa_os_hton3b(FC_MGMT_SERVER), bfa_fcs_port_get_fcid(port), 0, port->port_cfg.pwwn, port->port_cfg.nwwn, - bfa_pport_get_maxfrsize(port->fcs->bfa)); + bfa_fcport_get_maxfrsize(port->fcs->bfa)); bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, FC_CLASS_3, len, &fchs, bfa_fcs_port_ms_plogi_response, diff --git a/drivers/scsi/bfa/ns.c b/drivers/scsi/bfa/ns.c index 6de06a5..d20dd7e 100644 --- a/drivers/scsi/bfa/ns.c +++ b/drivers/scsi/bfa/ns.c @@ -660,7 +660,7 @@ bfa_fcs_port_ns_send_plogi(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) bfa_os_hton3b(FC_NAME_SERVER), bfa_fcs_port_get_fcid(port), 0, port->port_cfg.pwwn, port->port_cfg.nwwn, - bfa_pport_get_maxfrsize(port->fcs->bfa)); + bfa_fcport_get_maxfrsize(port->fcs->bfa)); bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_plogi_response, diff --git a/drivers/scsi/bfa/rport.c b/drivers/scsi/bfa/rport.c index 80592e3..8c5969c 100644 --- a/drivers/scsi/bfa/rport.c +++ b/drivers/scsi/bfa/rport.c @@ -1373,7 +1373,7 @@ bfa_fcs_rport_send_plogi(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced) len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid, bfa_fcs_port_get_fcid(port), 0, port->port_cfg.pwwn, port->port_cfg.nwwn, - bfa_pport_get_maxfrsize(port->fcs->bfa)); + bfa_fcport_get_maxfrsize(port->fcs->bfa)); bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, FC_CLASS_3, len, &fchs, bfa_fcs_rport_plogi_response, @@ -1485,7 +1485,7 @@ bfa_fcs_rport_send_plogiacc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced) len = fc_plogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid, bfa_fcs_port_get_fcid(port), rport->reply_oxid, port->port_cfg.pwwn, port->port_cfg.nwwn, - bfa_pport_get_maxfrsize(port->fcs->bfa)); + bfa_fcport_get_maxfrsize(port->fcs->bfa)); bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0); @@ -1820,7 +1820,7 @@ bfa_fcs_rport_process_rpsc(struct bfa_fcs_rport_s *rport, /* * get curent speed from pport attributes from BFA */ - bfa_pport_get_attr(port->fcs->bfa, &pport_attr); + bfa_fcport_get_attr(port->fcs->bfa, &pport_attr); speeds.port_op_speed = fc_bfa_speed_to_rpsc_operspeed(pport_attr.speed); @@ -2171,7 +2171,7 @@ bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport, struct fc_logi_s *plogi) bfa_trc(port->fcs, port->fabric->bb_credit); port->fabric->bb_credit = bfa_os_ntohs(plogi->csp.bbcred); - bfa_pport_set_tx_bbcredit(port->fcs->bfa, + bfa_fcport_set_tx_bbcredit(port->fcs->bfa, port->fabric->bb_credit); } diff --git a/drivers/scsi/bfa/rport_api.c b/drivers/scsi/bfa/rport_api.c index 3dae177..a441f41 100644 --- a/drivers/scsi/bfa/rport_api.c +++ b/drivers/scsi/bfa/rport_api.c @@ -102,7 +102,7 @@ bfa_fcs_rport_get_attr(struct bfa_fcs_rport_s *rport, rport_attr->qos_attr = qos_attr; rport_attr->trl_enforced = BFA_FALSE; - if (bfa_pport_is_ratelim(port->fcs->bfa)) { + if (bfa_fcport_is_ratelim(port->fcs->bfa)) { if ((rport->rpf.rpsc_speed == BFA_PPORT_SPEED_UNKNOWN) || (rport->rpf.rpsc_speed < bfa_fcs_port_get_rport_max_speed(port))) diff --git a/drivers/scsi/bfa/vport.c b/drivers/scsi/bfa/vport.c index 14fb7ac..c5e534eb 100644 --- a/drivers/scsi/bfa/vport.c +++ b/drivers/scsi/bfa/vport.c @@ -478,7 +478,7 @@ static void bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport) { bfa_lps_fdisc(vport->lps, vport, - bfa_pport_get_maxfrsize(__vport_bfa(vport)), + bfa_fcport_get_maxfrsize(__vport_bfa(vport)), __vport_pwwn(vport), __vport_nwwn(vport)); vport->vport_stats.fdisc_sent++; } -- cgit v0.10.2 From f58e9ebbf78bd36c6cf1ca651280d39efe73a7c0 Mon Sep 17 00:00:00 2001 From: Krishna Gudipati Date: Fri, 5 Mar 2010 19:37:45 -0800 Subject: [SCSI] bfa: New portlog entries for events (FIP/FLOGI/FDISC/LOGO). Signed-off-by: Krishna Gudipati Signed-off-by: James Bottomley diff --git a/drivers/scsi/bfa/bfa_fcport.c b/drivers/scsi/bfa/bfa_fcport.c index f392a7f..a48413c 100644 --- a/drivers/scsi/bfa/bfa_fcport.c +++ b/drivers/scsi/bfa/bfa_fcport.c @@ -326,6 +326,7 @@ static void bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport, enum bfa_fcport_sm_event event) { + struct bfi_pport_event_s *pevent = fcport->event_arg.i2hmsg.event; bfa_trc(fcport->bfa, event); switch (event) { @@ -335,6 +336,22 @@ bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport, bfa_assert(fcport->event_cbfn); bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkup"); + + if (!bfa_ioc_get_fcmode(&fcport->bfa->ioc)) { + + bfa_trc(fcport->bfa, pevent->link_state.fcf.fipenabled); + bfa_trc(fcport->bfa, pevent->link_state.fcf.fipfailed); + + if (pevent->link_state.fcf.fipfailed) + bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, + BFA_PL_EID_FIP_FCF_DISC, 0, + "FIP FCF Discovery Failed"); + else + bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, + BFA_PL_EID_FIP_FCF_DISC, 0, + "FIP FCF Discovered"); + } + bfa_fcport_callback(fcport, BFA_PPORT_LINKUP); bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ONLINE); /** @@ -1500,8 +1517,6 @@ bfa_port_stats_query(void *cbarg) bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_GET_STATS_REQ, bfa_lpuid(fcport->bfa)); bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT); - - return; } static void @@ -1526,7 +1541,6 @@ bfa_port_stats_clear(void *cbarg) bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_CLEAR_STATS_REQ, bfa_lpuid(fcport->bfa)); bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT); - return; } static void @@ -1599,7 +1613,6 @@ bfa_port_qos_stats_clear(void *cbarg) bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_CLEAR_QOS_STATS_REQ, bfa_lpuid(fcport->bfa)); bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT); - return; } static void diff --git a/drivers/scsi/bfa/bfa_lps.c b/drivers/scsi/bfa/bfa_lps.c index 730616f..d2d48a6 100644 --- a/drivers/scsi/bfa/bfa_lps.c +++ b/drivers/scsi/bfa/bfa_lps.c @@ -99,6 +99,12 @@ bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event) bfa_sm_set_state(lps, bfa_lps_sm_login); bfa_lps_send_login(lps); } + if (lps->fdisc) + bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, + BFA_PL_EID_LOGIN, 0, "FDISC Request"); + else + bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, + BFA_PL_EID_LOGIN, 0, "FLOGI Request"); break; case BFA_LPS_SM_LOGOUT: @@ -136,10 +142,25 @@ bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event) switch (event) { case BFA_LPS_SM_FWRSP: - if (lps->status == BFA_STATUS_OK) + if (lps->status == BFA_STATUS_OK) { bfa_sm_set_state(lps, bfa_lps_sm_online); - else + if (lps->fdisc) + bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, + BFA_PL_EID_LOGIN, 0, "FDISC Accept"); + else + bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, + BFA_PL_EID_LOGIN, 0, "FLOGI Accept"); + } else { bfa_sm_set_state(lps, bfa_lps_sm_init); + if (lps->fdisc) + bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, + BFA_PL_EID_LOGIN, 0, + "FDISC Fail (RJT or timeout)"); + else + bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, + BFA_PL_EID_LOGIN, 0, + "FLOGI Fail (RJT or timeout)"); + } bfa_lps_login_comp(lps); break; @@ -202,6 +223,8 @@ bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event) bfa_sm_set_state(lps, bfa_lps_sm_logout); bfa_lps_send_logout(lps); } + bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, + BFA_PL_EID_LOGO, 0, "Logout"); break; case BFA_LPS_SM_RX_CVL: diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_pport.h b/drivers/scsi/bfa/include/defs/bfa_defs_pport.h index 88662a1..164cfbe 100644 --- a/drivers/scsi/bfa/include/defs/bfa_defs_pport.h +++ b/drivers/scsi/bfa/include/defs/bfa_defs_pport.h @@ -333,8 +333,7 @@ struct bfa_pport_fcpmap_s { }; /** - * Port RNID info. - */ + * Port RNI */ struct bfa_pport_rnid_s { wwn_t wwn; u32 unittype; @@ -347,6 +346,23 @@ struct bfa_pport_rnid_s { u16 topologydiscoveryflags; }; +struct bfa_fcport_fcf_s { + wwn_t name; /* FCF name */ + wwn_t fabric_name; /* Fabric Name */ + u8 fipenabled; /* FIP enabled or not */ + u8 fipfailed; /* FIP failed or not */ + u8 resv[2]; + u8 pri; /* FCF priority */ + u8 version; /* FIP version used */ + u8 available; /* Available for login */ + u8 fka_disabled; /* FKA is disabled */ + u8 maxsz_verified; /* FCoE max size verified */ + u8 fc_map[3]; /* FC map */ + u16 vlan; /* FCoE vlan tag/priority */ + u32 fka_adv_per; /* FIP ka advert. period */ + struct mac_s mac; /* FCF mac */ +}; + /** * Link state information */ @@ -378,6 +394,7 @@ struct bfa_pport_link_s { struct fc_alpabm_s alpabm; /* alpa bitmap */ } loop_info; } tl; + struct bfa_fcport_fcf_s fcf; /*!< FCF information (for FCoE) */ }; #endif /* __BFA_DEFS_PPORT_H__ */ diff --git a/drivers/scsi/bfa/include/protocol/fc.h b/drivers/scsi/bfa/include/protocol/fc.h index 14969ee..8d10380 100644 --- a/drivers/scsi/bfa/include/protocol/fc.h +++ b/drivers/scsi/bfa/include/protocol/fc.h @@ -50,6 +50,11 @@ struct fchs_s { u32 ro; /* relative offset */ }; + +#define FC_SOF_LEN 4 +#define FC_EOF_LEN 4 +#define FC_CRC_LEN 4 + /* * Fibre Channel BB_E Header Structure */ -- cgit v0.10.2 From 0a4b1fc0b24fc7adbaf8413f2992ce1395991a78 Mon Sep 17 00:00:00 2001 From: Krishna Gudipati Date: Fri, 5 Mar 2010 19:37:57 -0800 Subject: [SCSI] bfa: Replace bfa_get_attr() with specific APIs bfa_ioc_attr_s is a big structure and some times could cause stack overflow if defined locally, so add specific APIs that are needed to replace the use of ioc_attr local var. Signed-off-by: Krishna Gudipati Signed-off-by: James Bottomley diff --git a/drivers/scsi/bfa/bfa_fcport.c b/drivers/scsi/bfa/bfa_fcport.c index a48413c..0da6120 100644 --- a/drivers/scsi/bfa/bfa_fcport.c +++ b/drivers/scsi/bfa/bfa_fcport.c @@ -145,35 +145,12 @@ bfa_fcport_aen_post(struct bfa_fcport_s *fcport, enum bfa_port_aen_event event) struct bfa_log_mod_s *logmod = fcport->bfa->logm; wwn_t pwwn = fcport->pwwn; char pwwn_ptr[BFA_STRING_32]; - struct bfa_ioc_attr_s ioc_attr; memset(&aen_data, 0, sizeof(aen_data)); wwn2str(pwwn_ptr, pwwn); - switch (event) { - case BFA_PORT_AEN_ONLINE: - bfa_log(logmod, BFA_AEN_PORT_ONLINE, pwwn_ptr); - break; - case BFA_PORT_AEN_OFFLINE: - bfa_log(logmod, BFA_AEN_PORT_OFFLINE, pwwn_ptr); - break; - case BFA_PORT_AEN_ENABLE: - bfa_log(logmod, BFA_AEN_PORT_ENABLE, pwwn_ptr); - break; - case BFA_PORT_AEN_DISABLE: - bfa_log(logmod, BFA_AEN_PORT_DISABLE, pwwn_ptr); - break; - case BFA_PORT_AEN_DISCONNECT: - bfa_log(logmod, BFA_AEN_PORT_DISCONNECT, pwwn_ptr); - break; - case BFA_PORT_AEN_QOS_NEG: - bfa_log(logmod, BFA_AEN_PORT_QOS_NEG, pwwn_ptr); - break; - default: - break; - } + bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, event), pwwn_ptr); - bfa_ioc_get_attr(&fcport->bfa->ioc, &ioc_attr); - aen_data.port.ioc_type = ioc_attr.ioc_type; + aen_data.port.ioc_type = bfa_get_type(fcport->bfa); aen_data.port.pwwn = pwwn; } @@ -2043,11 +2020,15 @@ void bfa_fcport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off) { struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); + enum bfa_ioc_type_e ioc_type = bfa_get_type(bfa); bfa_trc(bfa, on_off); bfa_trc(bfa, fcport->cfg.qos_enabled); - fcport->cfg.qos_enabled = on_off; + bfa_trc(bfa, ioc_type); + + if (ioc_type == BFA_IOC_TYPE_FC) + fcport->cfg.qos_enabled = on_off; } void diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c index 4a51aac..7c1251c 100644 --- a/drivers/scsi/bfa/bfa_fcs_lport.c +++ b/drivers/scsi/bfa/bfa_fcs_lport.c @@ -263,30 +263,8 @@ bfa_fcs_port_aen_post(struct bfa_fcs_port_s *port, bfa_assert(role <= BFA_PORT_ROLE_FCP_MAX); - switch (event) { - case BFA_LPORT_AEN_ONLINE: - bfa_log(logmod, BFA_AEN_LPORT_ONLINE, lpwwn_ptr, - role_str[role / 2]); - break; - case BFA_LPORT_AEN_OFFLINE: - bfa_log(logmod, BFA_AEN_LPORT_OFFLINE, lpwwn_ptr, - role_str[role / 2]); - break; - case BFA_LPORT_AEN_NEW: - bfa_log(logmod, BFA_AEN_LPORT_NEW, lpwwn_ptr, - role_str[role / 2]); - break; - case BFA_LPORT_AEN_DELETE: - bfa_log(logmod, BFA_AEN_LPORT_DELETE, lpwwn_ptr, - role_str[role / 2]); - break; - case BFA_LPORT_AEN_DISCONNECT: - bfa_log(logmod, BFA_AEN_LPORT_DISCONNECT, lpwwn_ptr, - role_str[role / 2]); - break; - default: - break; - } + bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, event), lpwwn_ptr, + role_str[role/2]); aen_data.lport.vf_id = port->fabric->vf_id; aen_data.lport.roles = role; diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c index 4d9a47c..e038bc9 100644 --- a/drivers/scsi/bfa/bfa_ioc.c +++ b/drivers/scsi/bfa/bfa_ioc.c @@ -1679,46 +1679,28 @@ bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc, struct bfa_adapter_attr_s *ad_attr) { struct bfi_ioc_attr_s *ioc_attr; - char model[BFA_ADAPTER_MODEL_NAME_LEN]; ioc_attr = ioc->attr; - bfa_os_memcpy((void *)&ad_attr->serial_num, - (void *)ioc_attr->brcd_serialnum, - BFA_ADAPTER_SERIAL_NUM_LEN); - - bfa_os_memcpy(&ad_attr->fw_ver, ioc_attr->fw_version, BFA_VERSION_LEN); - bfa_os_memcpy(&ad_attr->optrom_ver, ioc_attr->optrom_version, - BFA_VERSION_LEN); - bfa_os_memcpy(&ad_attr->manufacturer, BFA_MFG_NAME, - BFA_ADAPTER_MFG_NAME_LEN); + + bfa_ioc_get_adapter_serial_num(ioc, ad_attr->serial_num); + bfa_ioc_get_adapter_fw_ver(ioc, ad_attr->fw_ver); + bfa_ioc_get_adapter_optrom_ver(ioc, ad_attr->optrom_ver); + bfa_ioc_get_adapter_manufacturer(ioc, ad_attr->manufacturer); bfa_os_memcpy(&ad_attr->vpd, &ioc_attr->vpd, sizeof(struct bfa_mfg_vpd_s)); - ad_attr->nports = BFI_ADAPTER_GETP(NPORTS, ioc_attr->adapter_prop); - ad_attr->max_speed = BFI_ADAPTER_GETP(SPEED, ioc_attr->adapter_prop); + ad_attr->nports = bfa_ioc_get_nports(ioc); + ad_attr->max_speed = bfa_ioc_speed_sup(ioc); - /** - * model name - */ - if (BFI_ADAPTER_GETP(SPEED, ioc_attr->adapter_prop) == 10) { - strcpy(model, "BR-10?0"); - model[5] = '0' + ad_attr->nports; - } else { - strcpy(model, "Brocade-??5"); - model[8] = - '0' + BFI_ADAPTER_GETP(SPEED, ioc_attr->adapter_prop); - model[9] = '0' + ad_attr->nports; - } + bfa_ioc_get_adapter_model(ioc, ad_attr->model); + /* For now, model descr uses same model string */ + bfa_ioc_get_adapter_model(ioc, ad_attr->model_descr); if (BFI_ADAPTER_IS_SPECIAL(ioc_attr->adapter_prop)) ad_attr->prototype = 1; else ad_attr->prototype = 0; - bfa_os_memcpy(&ad_attr->model, model, BFA_ADAPTER_MODEL_NAME_LEN); - bfa_os_memcpy(&ad_attr->model_descr, &ad_attr->model, - BFA_ADAPTER_MODEL_NAME_LEN); - ad_attr->pwwn = bfa_ioc_get_pwwn(ioc); ad_attr->mac = bfa_ioc_get_mac(ioc); @@ -1726,12 +1708,8 @@ bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc, ad_attr->pcie_lanes = ioc_attr->pcie_lanes; ad_attr->pcie_lanes_orig = ioc_attr->pcie_lanes_orig; ad_attr->asic_rev = ioc_attr->asic_rev; - ad_attr->hw_ver[0] = 'R'; - ad_attr->hw_ver[1] = 'e'; - ad_attr->hw_ver[2] = 'v'; - ad_attr->hw_ver[3] = '-'; - ad_attr->hw_ver[4] = ioc_attr->asic_rev; - ad_attr->hw_ver[5] = '\0'; + + bfa_ioc_get_pci_chip_rev(ioc, ad_attr->hw_ver); ad_attr->cna_capable = ioc->cna; } @@ -1752,11 +1730,91 @@ bfa_ioc_get_type(struct bfa_ioc_s *ioc) } void +bfa_ioc_get_adapter_serial_num(struct bfa_ioc_s *ioc, char *serial_num) +{ + bfa_os_memset((void *)serial_num, 0, BFA_ADAPTER_SERIAL_NUM_LEN); + bfa_os_memcpy((void *)serial_num, + (void *)ioc->attr->brcd_serialnum, + BFA_ADAPTER_SERIAL_NUM_LEN); +} + +void +bfa_ioc_get_adapter_fw_ver(struct bfa_ioc_s *ioc, char *fw_ver) +{ + bfa_os_memset((void *)fw_ver, 0, BFA_VERSION_LEN); + bfa_os_memcpy(fw_ver, ioc->attr->fw_version, BFA_VERSION_LEN); +} + +void +bfa_ioc_get_pci_chip_rev(struct bfa_ioc_s *ioc, char *chip_rev) +{ + bfa_assert(chip_rev); + + bfa_os_memset((void *)chip_rev, 0, BFA_IOC_CHIP_REV_LEN); + + chip_rev[0] = 'R'; + chip_rev[1] = 'e'; + chip_rev[2] = 'v'; + chip_rev[3] = '-'; + chip_rev[4] = ioc->attr->asic_rev; + chip_rev[5] = '\0'; +} + +void +bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc_s *ioc, char *optrom_ver) +{ + bfa_os_memset((void *)optrom_ver, 0, BFA_VERSION_LEN); + bfa_os_memcpy(optrom_ver, ioc->attr->optrom_version, + BFA_VERSION_LEN); +} + +void +bfa_ioc_get_adapter_manufacturer(struct bfa_ioc_s *ioc, char *manufacturer) +{ + bfa_os_memset((void *)manufacturer, 0, BFA_ADAPTER_MFG_NAME_LEN); + bfa_os_memcpy(manufacturer, BFA_MFG_NAME, BFA_ADAPTER_MFG_NAME_LEN); +} + +void +bfa_ioc_get_adapter_model(struct bfa_ioc_s *ioc, char *model) +{ + struct bfi_ioc_attr_s *ioc_attr; + u8 nports; + u8 max_speed; + + bfa_assert(model); + bfa_os_memset((void *)model, 0, BFA_ADAPTER_MODEL_NAME_LEN); + + ioc_attr = ioc->attr; + + nports = bfa_ioc_get_nports(ioc); + max_speed = bfa_ioc_speed_sup(ioc); + + /** + * model name + */ + if (max_speed == 10) { + strcpy(model, "BR-10?0"); + model[5] = '0' + nports; + } else { + strcpy(model, "Brocade-??5"); + model[8] = '0' + max_speed; + model[9] = '0' + nports; + } +} + +enum bfa_ioc_state +bfa_ioc_get_state(struct bfa_ioc_s *ioc) +{ + return bfa_sm_to_state(ioc_sm_table, ioc->fsm); +} + +void bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr) { bfa_os_memset((void *)ioc_attr, 0, sizeof(struct bfa_ioc_attr_s)); - ioc_attr->state = bfa_sm_to_state(ioc_sm_table, ioc->fsm); + ioc_attr->state = bfa_ioc_get_state(ioc); ioc_attr->port_id = ioc->port_id; ioc_attr->ioc_type = bfa_ioc_get_type(ioc); @@ -1765,12 +1823,7 @@ bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr) ioc_attr->pci_attr.device_id = ioc->pcidev.device_id; ioc_attr->pci_attr.pcifn = ioc->pcidev.pci_func; - ioc_attr->pci_attr.chip_rev[0] = 'R'; - ioc_attr->pci_attr.chip_rev[1] = 'e'; - ioc_attr->pci_attr.chip_rev[2] = 'v'; - ioc_attr->pci_attr.chip_rev[3] = '-'; - ioc_attr->pci_attr.chip_rev[4] = ioc_attr->adapter_attr.asic_rev; - ioc_attr->pci_attr.chip_rev[5] = '\0'; + bfa_ioc_get_pci_chip_rev(ioc, ioc_attr->pci_attr.chip_rev); } /** @@ -1877,25 +1930,7 @@ bfa_ioc_aen_post(struct bfa_ioc_s *ioc, enum bfa_ioc_aen_event event) s32 inst_num = 0; enum bfa_ioc_type_e ioc_type; - switch (event) { - case BFA_IOC_AEN_HBGOOD: - bfa_log(logmod, BFA_AEN_IOC_HBGOOD, inst_num); - break; - case BFA_IOC_AEN_HBFAIL: - bfa_log(logmod, BFA_AEN_IOC_HBFAIL, inst_num); - break; - case BFA_IOC_AEN_ENABLE: - bfa_log(logmod, BFA_AEN_IOC_ENABLE, inst_num); - break; - case BFA_IOC_AEN_DISABLE: - bfa_log(logmod, BFA_AEN_IOC_DISABLE, inst_num); - break; - case BFA_IOC_AEN_FWMISMATCH: - bfa_log(logmod, BFA_AEN_IOC_FWMISMATCH, inst_num); - break; - default: - break; - } + bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_IOC, event), inst_num); memset(&aen_data.ioc.pwwn, 0, sizeof(aen_data.ioc.pwwn)); memset(&aen_data.ioc.mac, 0, sizeof(aen_data.ioc.mac)); diff --git a/drivers/scsi/bfa/bfa_ioc.h b/drivers/scsi/bfa/bfa_ioc.h index 4b73efa..d080440 100644 --- a/drivers/scsi/bfa/bfa_ioc.h +++ b/drivers/scsi/bfa/bfa_ioc.h @@ -263,6 +263,16 @@ bfa_boolean_t bfa_ioc_is_disabled(struct bfa_ioc_s *ioc); bfa_boolean_t bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc); bfa_boolean_t bfa_ioc_adapter_is_disabled(struct bfa_ioc_s *ioc); void bfa_ioc_cfg_complete(struct bfa_ioc_s *ioc); +enum bfa_ioc_type_e bfa_ioc_get_type(struct bfa_ioc_s *ioc); +void bfa_ioc_get_adapter_serial_num(struct bfa_ioc_s *ioc, char *serial_num); +void bfa_ioc_get_adapter_fw_ver(struct bfa_ioc_s *ioc, char *fw_ver); +void bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc_s *ioc, char *optrom_ver); +void bfa_ioc_get_adapter_model(struct bfa_ioc_s *ioc, char *model); +void bfa_ioc_get_adapter_manufacturer(struct bfa_ioc_s *ioc, + char *manufacturer); +void bfa_ioc_get_pci_chip_rev(struct bfa_ioc_s *ioc, char *chip_rev); +enum bfa_ioc_state bfa_ioc_get_state(struct bfa_ioc_s *ioc); + void bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr); void bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc, struct bfa_adapter_attr_s *ad_attr); diff --git a/drivers/scsi/bfa/bfa_lps.c b/drivers/scsi/bfa/bfa_lps.c index d2d48a6..ad06f61 100644 --- a/drivers/scsi/bfa/bfa_lps.c +++ b/drivers/scsi/bfa/bfa_lps.c @@ -631,11 +631,7 @@ bfa_lps_cvl_event(struct bfa_lps_s *lps) u32 bfa_lps_get_max_vport(struct bfa_s *bfa) { - struct bfa_ioc_attr_s ioc_attr; - - bfa_get_attr(bfa, &ioc_attr); - - if (ioc_attr.pci_attr.device_id == BFA_PCI_DEVICE_ID_CT) + if (bfa_ioc_devid(&bfa->ioc) == BFA_PCI_DEVICE_ID_CT) return BFA_LPS_MAX_VPORTS_SUPP_CT; else return BFA_LPS_MAX_VPORTS_SUPP_CB; diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c index a8a529d..6bff08e 100644 --- a/drivers/scsi/bfa/bfad.c +++ b/drivers/scsi/bfa/bfad.c @@ -978,7 +978,6 @@ bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid) { struct bfad_s *bfad; int error = -ENODEV, retval; - char buf[16]; /* * For single port cards - only claim function 0 @@ -1009,8 +1008,7 @@ bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid) bfa_trc(bfad, bfad_inst); bfad->logmod = &bfad->log_data; - sprintf(buf, "%d", bfad_inst); - bfa_log_init(bfad->logmod, buf, bfa_os_printf); + bfa_log_init(bfad->logmod, (char *)pci_name(pdev), bfa_os_printf); bfad_drv_log_level_set(bfad); diff --git a/drivers/scsi/bfa/bfad_attr.c b/drivers/scsi/bfa/bfad_attr.c index a691133..dd5cb20 100644 --- a/drivers/scsi/bfa/bfad_attr.c +++ b/drivers/scsi/bfa/bfad_attr.c @@ -424,12 +424,10 @@ bfad_im_serial_num_show(struct device *dev, struct device_attribute *attr, struct bfad_im_port_s *im_port = (struct bfad_im_port_s *) shost->hostdata[0]; struct bfad_s *bfad = im_port->bfad; - struct bfa_ioc_attr_s ioc_attr; + char serial_num[BFA_ADAPTER_SERIAL_NUM_LEN]; - memset(&ioc_attr, 0, sizeof(ioc_attr)); - bfa_get_attr(&bfad->bfa, &ioc_attr); - return snprintf(buf, PAGE_SIZE, "%s\n", - ioc_attr.adapter_attr.serial_num); + bfa_get_adapter_serial_num(&bfad->bfa, serial_num); + return snprintf(buf, PAGE_SIZE, "%s\n", serial_num); } static ssize_t @@ -440,11 +438,10 @@ bfad_im_model_show(struct device *dev, struct device_attribute *attr, struct bfad_im_port_s *im_port = (struct bfad_im_port_s *) shost->hostdata[0]; struct bfad_s *bfad = im_port->bfad; - struct bfa_ioc_attr_s ioc_attr; + char model[BFA_ADAPTER_MODEL_NAME_LEN]; - memset(&ioc_attr, 0, sizeof(ioc_attr)); - bfa_get_attr(&bfad->bfa, &ioc_attr); - return snprintf(buf, PAGE_SIZE, "%s\n", ioc_attr.adapter_attr.model); + bfa_get_adapter_model(&bfad->bfa, model); + return snprintf(buf, PAGE_SIZE, "%s\n", model); } static ssize_t @@ -455,12 +452,10 @@ bfad_im_model_desc_show(struct device *dev, struct device_attribute *attr, struct bfad_im_port_s *im_port = (struct bfad_im_port_s *) shost->hostdata[0]; struct bfad_s *bfad = im_port->bfad; - struct bfa_ioc_attr_s ioc_attr; + char model_descr[BFA_ADAPTER_MODEL_DESCR_LEN]; - memset(&ioc_attr, 0, sizeof(ioc_attr)); - bfa_get_attr(&bfad->bfa, &ioc_attr); - return snprintf(buf, PAGE_SIZE, "%s\n", - ioc_attr.adapter_attr.model_descr); + bfa_get_adapter_model(&bfad->bfa, model_descr); + return snprintf(buf, PAGE_SIZE, "%s\n", model_descr); } static ssize_t @@ -485,14 +480,13 @@ bfad_im_symbolic_name_show(struct device *dev, struct device_attribute *attr, struct bfad_im_port_s *im_port = (struct bfad_im_port_s *) shost->hostdata[0]; struct bfad_s *bfad = im_port->bfad; - struct bfa_ioc_attr_s ioc_attr; - - memset(&ioc_attr, 0, sizeof(ioc_attr)); - bfa_get_attr(&bfad->bfa, &ioc_attr); + char model[BFA_ADAPTER_MODEL_NAME_LEN]; + char fw_ver[BFA_VERSION_LEN]; + bfa_get_adapter_model(&bfad->bfa, model); + bfa_get_adapter_fw_ver(&bfad->bfa, fw_ver); return snprintf(buf, PAGE_SIZE, "Brocade %s FV%s DV%s\n", - ioc_attr.adapter_attr.model, - ioc_attr.adapter_attr.fw_ver, BFAD_DRIVER_VERSION); + model, fw_ver, BFAD_DRIVER_VERSION); } static ssize_t @@ -503,11 +497,10 @@ bfad_im_hw_version_show(struct device *dev, struct device_attribute *attr, struct bfad_im_port_s *im_port = (struct bfad_im_port_s *) shost->hostdata[0]; struct bfad_s *bfad = im_port->bfad; - struct bfa_ioc_attr_s ioc_attr; + char hw_ver[BFA_VERSION_LEN]; - memset(&ioc_attr, 0, sizeof(ioc_attr)); - bfa_get_attr(&bfad->bfa, &ioc_attr); - return snprintf(buf, PAGE_SIZE, "%s\n", ioc_attr.adapter_attr.hw_ver); + bfa_get_pci_chip_rev(&bfad->bfa, hw_ver); + return snprintf(buf, PAGE_SIZE, "%s\n", hw_ver); } static ssize_t @@ -525,12 +518,10 @@ bfad_im_optionrom_version_show(struct device *dev, struct bfad_im_port_s *im_port = (struct bfad_im_port_s *) shost->hostdata[0]; struct bfad_s *bfad = im_port->bfad; - struct bfa_ioc_attr_s ioc_attr; + char optrom_ver[BFA_VERSION_LEN]; - memset(&ioc_attr, 0, sizeof(ioc_attr)); - bfa_get_attr(&bfad->bfa, &ioc_attr); - return snprintf(buf, PAGE_SIZE, "%s\n", - ioc_attr.adapter_attr.optrom_ver); + bfa_get_adapter_optrom_ver(&bfad->bfa, optrom_ver); + return snprintf(buf, PAGE_SIZE, "%s\n", optrom_ver); } static ssize_t @@ -541,11 +532,10 @@ bfad_im_fw_version_show(struct device *dev, struct device_attribute *attr, struct bfad_im_port_s *im_port = (struct bfad_im_port_s *) shost->hostdata[0]; struct bfad_s *bfad = im_port->bfad; - struct bfa_ioc_attr_s ioc_attr; + char fw_ver[BFA_VERSION_LEN]; - memset(&ioc_attr, 0, sizeof(ioc_attr)); - bfa_get_attr(&bfad->bfa, &ioc_attr); - return snprintf(buf, PAGE_SIZE, "%s\n", ioc_attr.adapter_attr.fw_ver); + bfa_get_adapter_fw_ver(&bfad->bfa, fw_ver); + return snprintf(buf, PAGE_SIZE, "%s\n", fw_ver); } static ssize_t @@ -556,11 +546,9 @@ bfad_im_num_of_ports_show(struct device *dev, struct device_attribute *attr, struct bfad_im_port_s *im_port = (struct bfad_im_port_s *) shost->hostdata[0]; struct bfad_s *bfad = im_port->bfad; - struct bfa_ioc_attr_s ioc_attr; - memset(&ioc_attr, 0, sizeof(ioc_attr)); - bfa_get_attr(&bfad->bfa, &ioc_attr); - return snprintf(buf, PAGE_SIZE, "%d\n", ioc_attr.adapter_attr.nports); + return snprintf(buf, PAGE_SIZE, "%d\n", + bfa_get_nports(&bfad->bfa)); } static ssize_t diff --git a/drivers/scsi/bfa/bfad_drv.h b/drivers/scsi/bfa/bfad_drv.h index 94f4d84..8617a1a 100644 --- a/drivers/scsi/bfa/bfad_drv.h +++ b/drivers/scsi/bfa/bfad_drv.h @@ -139,6 +139,18 @@ struct bfad_cfg_param_s { u32 binding_method; }; +union bfad_tmp_buf { + /* From struct bfa_adapter_attr_s */ + char manufacturer[BFA_ADAPTER_MFG_NAME_LEN]; + char serial_num[BFA_ADAPTER_SERIAL_NUM_LEN]; + char model[BFA_ADAPTER_MODEL_NAME_LEN]; + char fw_ver[BFA_VERSION_LEN]; + char optrom_ver[BFA_VERSION_LEN]; + + /* From struct bfa_ioc_pci_attr_s */ + u8 chip_rev[BFA_IOC_CHIP_REV_LEN]; /* chip revision */ +}; + /* * BFAD (PCI function) data structure */ @@ -182,6 +194,7 @@ struct bfad_s { struct bfa_plog_s plog_buf; int ref_count; bfa_boolean_t ipfc_enabled; + union bfad_tmp_buf tmp_buf; struct fc_host_statistics link_stats; struct kobject *bfa_kobj; diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c index 23390b4..cee3d89 100644 --- a/drivers/scsi/bfa/bfad_im.c +++ b/drivers/scsi/bfa/bfad_im.c @@ -167,17 +167,15 @@ bfad_im_info(struct Scsi_Host *shost) static char bfa_buf[256]; struct bfad_im_port_s *im_port = (struct bfad_im_port_s *) shost->hostdata[0]; - struct bfa_ioc_attr_s ioc_attr; struct bfad_s *bfad = im_port->bfad; + char model[BFA_ADAPTER_MODEL_NAME_LEN]; - memset(&ioc_attr, 0, sizeof(ioc_attr)); - bfa_get_attr(&bfad->bfa, &ioc_attr); + bfa_get_adapter_model(&bfad->bfa, model); memset(bfa_buf, 0, sizeof(bfa_buf)); snprintf(bfa_buf, sizeof(bfa_buf), - "Brocade FC/FCOE Adapter, " "model: %s hwpath: %s driver: %s", - ioc_attr.adapter_attr.model, bfad->pci_name, - BFAD_DRIVER_VERSION); + "Brocade FC/FCOE Adapter, " "model: %s hwpath: %s driver: %s", + model, bfad->pci_name, BFAD_DRIVER_VERSION); return bfa_buf; } @@ -931,10 +929,9 @@ bfad_os_fc_host_init(struct bfad_im_port_s *im_port) struct Scsi_Host *host = im_port->shost; struct bfad_s *bfad = im_port->bfad; struct bfad_port_s *port = im_port->port; - union attr { - struct bfa_pport_attr_s pattr; - struct bfa_ioc_attr_s ioc_attr; - } attr; + struct bfa_pport_attr_s pattr; + char model[BFA_ADAPTER_MODEL_NAME_LEN]; + char fw_ver[BFA_VERSION_LEN]; fc_host_node_name(host) = bfa_os_htonll((bfa_fcs_port_get_nwwn(port->fcs_port))); @@ -954,20 +951,18 @@ bfad_os_fc_host_init(struct bfad_im_port_s *im_port) /* For fibre channel services type 0x20 */ fc_host_supported_fc4s(host)[7] = 1; - memset(&attr.ioc_attr, 0, sizeof(attr.ioc_attr)); - bfa_get_attr(&bfad->bfa, &attr.ioc_attr); + bfa_get_adapter_model(&bfad->bfa, model); + bfa_get_adapter_fw_ver(&bfad->bfa, fw_ver); sprintf(fc_host_symbolic_name(host), "Brocade %s FV%s DV%s", - attr.ioc_attr.adapter_attr.model, - attr.ioc_attr.adapter_attr.fw_ver, BFAD_DRIVER_VERSION); + model, fw_ver, BFAD_DRIVER_VERSION); fc_host_supported_speeds(host) = 0; fc_host_supported_speeds(host) |= FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT | FC_PORTSPEED_2GBIT | FC_PORTSPEED_1GBIT; - memset(&attr.pattr, 0, sizeof(attr.pattr)); - bfa_fcport_get_attr(&bfad->bfa, &attr.pattr); - fc_host_maxframe_size(host) = attr.pattr.pport_cfg.maxfrsize; + bfa_fcport_get_attr(&bfad->bfa, &pattr); + fc_host_maxframe_size(host) = pattr.pport_cfg.maxfrsize; } static void diff --git a/drivers/scsi/bfa/fabric.c b/drivers/scsi/bfa/fabric.c index e1a4b31..b4e05ad 100644 --- a/drivers/scsi/bfa/fabric.c +++ b/drivers/scsi/bfa/fabric.c @@ -1235,14 +1235,8 @@ bfa_fcs_fabric_aen_post(struct bfa_fcs_port_s *port, wwn2str(pwwn_ptr, pwwn); wwn2str(fwwn_ptr, fwwn); - switch (event) { - case BFA_PORT_AEN_FABRIC_NAME_CHANGE: - bfa_log(logmod, BFA_AEN_PORT_FABRIC_NAME_CHANGE, pwwn_ptr, - fwwn_ptr); - break; - default: - break; - } + bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, event), + pwwn_ptr, fwwn_ptr); aen_data.port.pwwn = pwwn; aen_data.port.fwwn = fwwn; diff --git a/drivers/scsi/bfa/fcpim.c b/drivers/scsi/bfa/fcpim.c index 71d23d1..ef50ec2 100644 --- a/drivers/scsi/bfa/fcpim.c +++ b/drivers/scsi/bfa/fcpim.c @@ -385,19 +385,8 @@ bfa_fcs_itnim_aen_post(struct bfa_fcs_itnim_s *itnim, wwn2str(lpwwn_ptr, lpwwn); wwn2str(rpwwn_ptr, rpwwn); - switch (event) { - case BFA_ITNIM_AEN_ONLINE: - bfa_log(logmod, BFA_AEN_ITNIM_ONLINE, rpwwn_ptr, lpwwn_ptr); - break; - case BFA_ITNIM_AEN_OFFLINE: - bfa_log(logmod, BFA_AEN_ITNIM_OFFLINE, rpwwn_ptr, lpwwn_ptr); - break; - case BFA_ITNIM_AEN_DISCONNECT: - bfa_log(logmod, BFA_AEN_ITNIM_DISCONNECT, rpwwn_ptr, lpwwn_ptr); - break; - default: - break; - } + bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_ITNIM, event), + rpwwn_ptr, lpwwn_ptr); aen_data.itnim.vf_id = rport->port->fabric->vf_id; aen_data.itnim.ppwwn = diff --git a/drivers/scsi/bfa/include/bfa.h b/drivers/scsi/bfa/include/bfa.h index 17654ca..1f5966c 100644 --- a/drivers/scsi/bfa/include/bfa.h +++ b/drivers/scsi/bfa/include/bfa.h @@ -106,6 +106,26 @@ struct bfa_sge_s { bfa_ioc_fetch_stats(&(__bfa)->ioc, __ioc_stats) #define bfa_ioc_clear_stats(__bfa) \ bfa_ioc_clr_stats(&(__bfa)->ioc) +#define bfa_get_nports(__bfa) \ + bfa_ioc_get_nports(&(__bfa)->ioc) +#define bfa_get_adapter_manufacturer(__bfa, __manufacturer) \ + bfa_ioc_get_adapter_manufacturer(&(__bfa)->ioc, __manufacturer) +#define bfa_get_adapter_model(__bfa, __model) \ + bfa_ioc_get_adapter_model(&(__bfa)->ioc, __model) +#define bfa_get_adapter_serial_num(__bfa, __serial_num) \ + bfa_ioc_get_adapter_serial_num(&(__bfa)->ioc, __serial_num) +#define bfa_get_adapter_fw_ver(__bfa, __fw_ver) \ + bfa_ioc_get_adapter_fw_ver(&(__bfa)->ioc, __fw_ver) +#define bfa_get_adapter_optrom_ver(__bfa, __optrom_ver) \ + bfa_ioc_get_adapter_optrom_ver(&(__bfa)->ioc, __optrom_ver) +#define bfa_get_pci_chip_rev(__bfa, __chip_rev) \ + bfa_ioc_get_pci_chip_rev(&(__bfa)->ioc, __chip_rev) +#define bfa_get_ioc_state(__bfa) \ + bfa_ioc_get_state(&(__bfa)->ioc) +#define bfa_get_type(__bfa) \ + bfa_ioc_get_type(&(__bfa)->ioc) +#define bfa_get_mac(__bfa) \ + bfa_ioc_get_mac(&(__bfa)->ioc) /* * bfa API functions diff --git a/drivers/scsi/bfa/include/cs/bfa_log.h b/drivers/scsi/bfa/include/cs/bfa_log.h index 761cbe2..bc334e0 100644 --- a/drivers/scsi/bfa/include/cs/bfa_log.h +++ b/drivers/scsi/bfa/include/cs/bfa_log.h @@ -157,7 +157,7 @@ typedef void (*bfa_log_cb_t)(struct bfa_log_mod_s *log_mod, u32 msg_id, struct bfa_log_mod_s { - char instance_info[16]; /* instance info */ + char instance_info[BFA_STRING_32]; /* instance info */ int log_level[BFA_LOG_MODULE_ID_MAX + 1]; /* log level for modules */ bfa_log_cb_t cbfn; /* callback function */ diff --git a/drivers/scsi/bfa/rport.c b/drivers/scsi/bfa/rport.c index 8c5969c..8e73dd9 100644 --- a/drivers/scsi/bfa/rport.c +++ b/drivers/scsi/bfa/rport.c @@ -2039,13 +2039,10 @@ bfa_fcs_rport_aen_post(struct bfa_fcs_rport_s *rport, switch (event) { case BFA_RPORT_AEN_ONLINE: - bfa_log(logmod, BFA_AEN_RPORT_ONLINE, rpwwn_ptr, lpwwn_ptr); - break; case BFA_RPORT_AEN_OFFLINE: - bfa_log(logmod, BFA_AEN_RPORT_OFFLINE, rpwwn_ptr, lpwwn_ptr); - break; case BFA_RPORT_AEN_DISCONNECT: - bfa_log(logmod, BFA_AEN_RPORT_DISCONNECT, rpwwn_ptr, lpwwn_ptr); + bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_RPORT, event), + rpwwn_ptr, lpwwn_ptr); break; case BFA_RPORT_AEN_QOS_PRIO: aen_data.rport.priv.qos = data->priv.qos; diff --git a/drivers/scsi/bfa/vport.c b/drivers/scsi/bfa/vport.c index c5e534eb..27cd619 100644 --- a/drivers/scsi/bfa/vport.c +++ b/drivers/scsi/bfa/vport.c @@ -447,22 +447,8 @@ bfa_fcs_vport_aen_post(bfa_fcs_lport_t *port, enum bfa_lport_aen_event event) bfa_assert(role <= BFA_PORT_ROLE_FCP_MAX); - switch (event) { - case BFA_LPORT_AEN_NPIV_DUP_WWN: - bfa_log(logmod, BFA_AEN_LPORT_NPIV_DUP_WWN, lpwwn_ptr, - role_str[role / 2]); - break; - case BFA_LPORT_AEN_NPIV_FABRIC_MAX: - bfa_log(logmod, BFA_AEN_LPORT_NPIV_FABRIC_MAX, lpwwn_ptr, - role_str[role / 2]); - break; - case BFA_LPORT_AEN_NPIV_UNKNOWN: - bfa_log(logmod, BFA_AEN_LPORT_NPIV_UNKNOWN, lpwwn_ptr, - role_str[role / 2]); - break; - default: - break; - } + bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, event), lpwwn_ptr, + role_str[role/2]); aen_data.lport.vf_id = port->fabric->vf_id; aen_data.lport.roles = role; -- cgit v0.10.2 From ca8b4327e405820966971236224db0e0724b5673 Mon Sep 17 00:00:00 2001 From: Krishna Gudipati Date: Fri, 5 Mar 2010 19:38:07 -0800 Subject: [SCSI] bfa: Modified the portstats get/clear logic Modified the portstats get/clear logic for port physical/FCoE/QoS stats. Added more stats to FC Fixed some issues with FCoE stats collection. Signed-off-by: Krishna Gudipati Signed-off-by: James Bottomley diff --git a/drivers/scsi/bfa/bfa_fcport.c b/drivers/scsi/bfa/bfa_fcport.c index 0da6120..d109e65 100644 --- a/drivers/scsi/bfa/bfa_fcport.c +++ b/drivers/scsi/bfa/bfa_fcport.c @@ -47,16 +47,10 @@ static void bfa_fcport_callback(struct bfa_fcport_s *fcport, enum bfa_pport_linkstate event); static void bfa_fcport_queue_cb(struct bfa_fcport_ln_s *ln, enum bfa_pport_linkstate event); -static void __bfa_cb_fcport_stats(void *cbarg, bfa_boolean_t complete); static void __bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete); -static void bfa_fcport_stats_timeout(void *cbarg); +static void bfa_fcport_stats_get_timeout(void *cbarg); static void bfa_fcport_stats_clr_timeout(void *cbarg); -static void __bfa_cb_port_stats(void *cbarg, bfa_boolean_t complete); -static void __bfa_cb_port_stats_clr(void *cbarg, bfa_boolean_t complete); -static void bfa_port_stats_timeout(void *cbarg); -static void bfa_port_stats_clr_timeout(void *cbarg); - /** * bfa_pport_private */ @@ -303,7 +297,7 @@ static void bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport, enum bfa_fcport_sm_event event) { - struct bfi_pport_event_s *pevent = fcport->event_arg.i2hmsg.event; + struct bfi_fcport_event_s *pevent = fcport->event_arg.i2hmsg.event; bfa_trc(fcport->bfa, event); switch (event) { @@ -819,8 +813,32 @@ __bfa_cb_fcport_event(void *cbarg, bfa_boolean_t complete) bfa_sm_send_event(ln, BFA_FCPORT_LN_SM_NOTIFICATION); } -#define PPORT_STATS_DMA_SZ (BFA_ROUNDUP(sizeof(union bfa_fcport_stats_u), \ - BFA_CACHELINE_SZ)) +static void +bfa_fcport_callback(struct bfa_fcport_s *fcport, enum bfa_pport_linkstate event) +{ + if (fcport->bfa->fcs) { + fcport->event_cbfn(fcport->event_cbarg, event); + return; + } + + switch (event) { + case BFA_PPORT_LINKUP: + bfa_sm_send_event(&fcport->ln, BFA_FCPORT_LN_SM_LINKUP); + break; + case BFA_PPORT_LINKDOWN: + bfa_sm_send_event(&fcport->ln, BFA_FCPORT_LN_SM_LINKDOWN); + break; + default: + bfa_assert(0); + } +} + +static void +bfa_fcport_queue_cb(struct bfa_fcport_ln_s *ln, enum bfa_pport_linkstate event) +{ + ln->ln_event = event; + bfa_cb_queue(ln->fcport->bfa, &ln->ln_qe, __bfa_cb_fcport_event, ln); +} #define FCPORT_STATS_DMA_SZ (BFA_ROUNDUP(sizeof(union bfa_fcport_stats_u), \ BFA_CACHELINE_SZ)) @@ -829,8 +847,7 @@ static void bfa_fcport_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len, u32 *dm_len) { - *dm_len += PPORT_STATS_DMA_SZ; - *dm_len += PPORT_STATS_DMA_SZ; + *dm_len += FCPORT_STATS_DMA_SZ; } static void @@ -852,16 +869,7 @@ bfa_fcport_mem_claim(struct bfa_fcport_s *fcport, struct bfa_meminfo_s *meminfo) fcport->stats_kva = dm_kva; fcport->stats_pa = dm_pa; - fcport->stats = (union bfa_pport_stats_u *)dm_kva; - - dm_kva += PPORT_STATS_DMA_SZ; - dm_pa += PPORT_STATS_DMA_SZ; - - /* FC port stats */ - - fcport->fcport_stats_kva = dm_kva; - fcport->fcport_stats_pa = dm_pa; - fcport->fcport_stats = (union bfa_fcport_stats_u *) dm_kva; + fcport->stats = (union bfa_fcport_stats_u *)dm_kva; dm_kva += FCPORT_STATS_DMA_SZ; dm_pa += FCPORT_STATS_DMA_SZ; @@ -957,7 +965,7 @@ bfa_fcport_iocdisable(struct bfa_s *bfa) static void bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport) { - struct bfi_pport_event_s *pevent = fcport->event_arg.i2hmsg.event; + struct bfi_fcport_event_s *pevent = fcport->event_arg.i2hmsg.event; fcport->speed = pevent->link_state.speed; fcport->topology = pevent->link_state.topology; @@ -989,7 +997,7 @@ bfa_fcport_reset_linkinfo(struct bfa_fcport_s *fcport) static bfa_boolean_t bfa_fcport_send_enable(struct bfa_fcport_s *fcport) { - struct bfi_pport_enable_req_s *m; + struct bfi_fcport_enable_req_s *m; /** * Increment message tag before queue check, so that responses to old @@ -1007,15 +1015,14 @@ bfa_fcport_send_enable(struct bfa_fcport_s *fcport) return BFA_FALSE; } - bfi_h2i_set(m->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_ENABLE_REQ, - bfa_lpuid(fcport->bfa)); + bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_ENABLE_REQ, + bfa_lpuid(fcport->bfa)); m->nwwn = fcport->nwwn; m->pwwn = fcport->pwwn; m->port_cfg = fcport->cfg; m->msgtag = fcport->msgtag; m->port_cfg.maxfrsize = bfa_os_htons(fcport->cfg.maxfrsize); bfa_dma_be_addr_set(m->stats_dma_addr, fcport->stats_pa); - bfa_dma_be_addr_set(m->fcport_stats_dma_addr, fcport->fcport_stats_pa); bfa_trc(fcport->bfa, m->stats_dma_addr.a32.addr_lo); bfa_trc(fcport->bfa, m->stats_dma_addr.a32.addr_hi); @@ -1032,7 +1039,7 @@ bfa_fcport_send_enable(struct bfa_fcport_s *fcport) static bfa_boolean_t bfa_fcport_send_disable(struct bfa_fcport_s *fcport) { - bfi_pport_disable_req_t *m; + struct bfi_fcport_req_s *m; /** * Increment message tag before queue check, so that responses to old @@ -1050,8 +1057,8 @@ bfa_fcport_send_disable(struct bfa_fcport_s *fcport) return BFA_FALSE; } - bfi_h2i_set(m->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_DISABLE_REQ, - bfa_lpuid(fcport->bfa)); + bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_DISABLE_REQ, + bfa_lpuid(fcport->bfa)); m->msgtag = fcport->msgtag; /** @@ -1077,7 +1084,7 @@ bfa_fcport_send_txcredit(void *port_cbarg) { struct bfa_fcport_s *fcport = port_cbarg; - struct bfi_pport_set_svc_params_req_s *m; + struct bfi_fcport_set_svc_params_req_s *m; /** * check for room in queue to send request now @@ -1088,8 +1095,8 @@ bfa_fcport_send_txcredit(void *port_cbarg) return; } - bfi_h2i_set(m->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_SET_SVC_PARAMS_REQ, - bfa_lpuid(fcport->bfa)); + bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_SET_SVC_PARAMS_REQ, + bfa_lpuid(fcport->bfa)); m->tx_bbcredit = bfa_os_htons((u16) fcport->cfg.tx_bbcredit); /** @@ -1098,7 +1105,158 @@ bfa_fcport_send_txcredit(void *port_cbarg) bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT); } +static void +bfa_fcport_qos_stats_swap(struct bfa_qos_stats_s *d, + struct bfa_qos_stats_s *s) +{ + u32 *dip = (u32 *) d; + u32 *sip = (u32 *) s; + int i; + + /* Now swap the 32 bit fields */ + for (i = 0; i < (sizeof(struct bfa_qos_stats_s)/sizeof(u32)); ++i) + dip[i] = bfa_os_ntohl(sip[i]); +} + +static void +bfa_fcport_fcoe_stats_swap(struct bfa_fcoe_stats_s *d, + struct bfa_fcoe_stats_s *s) +{ + u32 *dip = (u32 *) d; + u32 *sip = (u32 *) s; + int i; + + for (i = 0; i < ((sizeof(struct bfa_fcoe_stats_s))/sizeof(u32)); + i = i + 2) { +#ifdef __BIGENDIAN + dip[i] = bfa_os_ntohl(sip[i]); + dip[i + 1] = bfa_os_ntohl(sip[i + 1]); +#else + dip[i] = bfa_os_ntohl(sip[i + 1]); + dip[i + 1] = bfa_os_ntohl(sip[i]); +#endif + } +} + +static void +__bfa_cb_fcport_stats_get(void *cbarg, bfa_boolean_t complete) +{ + struct bfa_fcport_s *fcport = cbarg; + + if (complete) { + if (fcport->stats_status == BFA_STATUS_OK) { + + /* Swap FC QoS or FCoE stats */ + if (bfa_ioc_get_fcmode(&fcport->bfa->ioc)) + bfa_fcport_qos_stats_swap( + &fcport->stats_ret->fcqos, + &fcport->stats->fcqos); + else + bfa_fcport_fcoe_stats_swap( + &fcport->stats_ret->fcoe, + &fcport->stats->fcoe); + } + fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status); + } else { + fcport->stats_busy = BFA_FALSE; + fcport->stats_status = BFA_STATUS_OK; + } +} + +static void +bfa_fcport_stats_get_timeout(void *cbarg) +{ + struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg; + + bfa_trc(fcport->bfa, fcport->stats_qfull); + + if (fcport->stats_qfull) { + bfa_reqq_wcancel(&fcport->stats_reqq_wait); + fcport->stats_qfull = BFA_FALSE; + } + + fcport->stats_status = BFA_STATUS_ETIMER; + bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, __bfa_cb_fcport_stats_get, + fcport); +} + +static void +bfa_fcport_send_stats_get(void *cbarg) +{ + struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg; + struct bfi_fcport_req_s *msg; + + msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT); + + if (!msg) { + fcport->stats_qfull = BFA_TRUE; + bfa_reqq_winit(&fcport->stats_reqq_wait, + bfa_fcport_send_stats_get, fcport); + bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT, + &fcport->stats_reqq_wait); + return; + } + fcport->stats_qfull = BFA_FALSE; + + bfa_os_memset(msg, 0, sizeof(struct bfi_fcport_req_s)); + bfi_h2i_set(msg->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_STATS_GET_REQ, + bfa_lpuid(fcport->bfa)); + bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT); +} + +static void +__bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete) +{ + struct bfa_fcport_s *fcport = cbarg; + + if (complete) { + fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status); + } else { + fcport->stats_busy = BFA_FALSE; + fcport->stats_status = BFA_STATUS_OK; + } +} + +static void +bfa_fcport_stats_clr_timeout(void *cbarg) +{ + struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg; + + bfa_trc(fcport->bfa, fcport->stats_qfull); + + if (fcport->stats_qfull) { + bfa_reqq_wcancel(&fcport->stats_reqq_wait); + fcport->stats_qfull = BFA_FALSE; + } + + fcport->stats_status = BFA_STATUS_ETIMER; + bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, + __bfa_cb_fcport_stats_clr, fcport); +} + +static void +bfa_fcport_send_stats_clear(void *cbarg) +{ + struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg; + struct bfi_fcport_req_s *msg; + msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT); + + if (!msg) { + fcport->stats_qfull = BFA_TRUE; + bfa_reqq_winit(&fcport->stats_reqq_wait, + bfa_fcport_send_stats_clear, fcport); + bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT, + &fcport->stats_reqq_wait); + return; + } + fcport->stats_qfull = BFA_FALSE; + + bfa_os_memset(msg, 0, sizeof(struct bfi_fcport_req_s)); + bfi_h2i_set(msg->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_STATS_CLEAR_REQ, + bfa_lpuid(fcport->bfa)); + bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT); +} /** * bfa_pport_public @@ -1111,23 +1269,23 @@ void bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg) { struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); - union bfi_pport_i2h_msg_u i2hmsg; + union bfi_fcport_i2h_msg_u i2hmsg; i2hmsg.msg = msg; fcport->event_arg.i2hmsg = i2hmsg; switch (msg->mhdr.msg_id) { - case BFI_PPORT_I2H_ENABLE_RSP: - if (fcport->msgtag == i2hmsg.enable_rsp->msgtag) + case BFI_FCPORT_I2H_ENABLE_RSP: + if (fcport->msgtag == i2hmsg.penable_rsp->msgtag) bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP); break; - case BFI_PPORT_I2H_DISABLE_RSP: - if (fcport->msgtag == i2hmsg.enable_rsp->msgtag) + case BFI_FCPORT_I2H_DISABLE_RSP: + if (fcport->msgtag == i2hmsg.penable_rsp->msgtag) bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP); break; - case BFI_PPORT_I2H_EVENT: + case BFI_FCPORT_I2H_EVENT: switch (i2hmsg.event->link_state.linkstate) { case BFA_PPORT_LINKUP: bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKUP); @@ -1141,58 +1299,27 @@ bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg) } break; - case BFI_PPORT_I2H_GET_STATS_RSP: - case BFI_PPORT_I2H_GET_QOS_STATS_RSP: - /* - * check for timer pop before processing the rsp - */ - if (fcport->stats_busy == BFA_FALSE - || fcport->stats_status == BFA_STATUS_ETIMER) - break; - - bfa_timer_stop(&fcport->timer); - fcport->stats_status = i2hmsg.getstats_rsp->status; - bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, __bfa_cb_port_stats, - fcport); - break; - case BFI_PPORT_I2H_CLEAR_STATS_RSP: - case BFI_PPORT_I2H_CLEAR_QOS_STATS_RSP: - /* - * check for timer pop before processing the rsp - */ - if (fcport->stats_busy == BFA_FALSE - || fcport->stats_status == BFA_STATUS_ETIMER) - break; - - bfa_timer_stop(&fcport->timer); - fcport->stats_status = BFA_STATUS_OK; - bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, - __bfa_cb_port_stats_clr, fcport); - break; - - case BFI_FCPORT_I2H_GET_STATS_RSP: + case BFI_FCPORT_I2H_STATS_GET_RSP: /* * check for timer pop before processing the rsp */ if (fcport->stats_busy == BFA_FALSE || - fcport->stats_status == BFA_STATUS_ETIMER) { + fcport->stats_status == BFA_STATUS_ETIMER) break; - } bfa_timer_stop(&fcport->timer); - fcport->stats_status = i2hmsg.getstats_rsp->status; + fcport->stats_status = i2hmsg.pstatsget_rsp->status; bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, - __bfa_cb_fcport_stats, fcport); + __bfa_cb_fcport_stats_get, fcport); break; - case BFI_FCPORT_I2H_CLEAR_STATS_RSP: + case BFI_FCPORT_I2H_STATS_CLEAR_RSP: /* * check for timer pop before processing the rsp */ if (fcport->stats_busy == BFA_FALSE || - fcport->stats_status == BFA_STATUS_ETIMER) { + fcport->stats_status == BFA_STATUS_ETIMER) break; - } bfa_timer_stop(&fcport->timer); fcport->stats_status = BFA_STATUS_OK; @@ -1206,8 +1333,6 @@ bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg) } } - - /** * bfa_pport_api */ @@ -1472,329 +1597,13 @@ bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr) attr->port_state = BFA_PPORT_ST_FWMISMATCH; } -static void -bfa_port_stats_query(void *cbarg) -{ - struct bfa_fcport_s *fcport = (struct bfa_fcport_s *)cbarg; - bfi_pport_get_stats_req_t *msg; - - msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT); - - if (!msg) { - fcport->stats_qfull = BFA_TRUE; - bfa_reqq_winit(&fcport->stats_reqq_wait, bfa_port_stats_query, - fcport); - bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT, - &fcport->stats_reqq_wait); - return; - } - fcport->stats_qfull = BFA_FALSE; - - bfa_os_memset(msg, 0, sizeof(bfi_pport_get_stats_req_t)); - bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_GET_STATS_REQ, - bfa_lpuid(fcport->bfa)); - bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT); -} - -static void -bfa_port_stats_clear(void *cbarg) -{ - struct bfa_fcport_s *fcport = (struct bfa_fcport_s *)cbarg; - bfi_pport_clear_stats_req_t *msg; - - msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT); - - if (!msg) { - fcport->stats_qfull = BFA_TRUE; - bfa_reqq_winit(&fcport->stats_reqq_wait, bfa_port_stats_clear, - fcport); - bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT, - &fcport->stats_reqq_wait); - return; - } - fcport->stats_qfull = BFA_FALSE; - - bfa_os_memset(msg, 0, sizeof(bfi_pport_clear_stats_req_t)); - bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_CLEAR_STATS_REQ, - bfa_lpuid(fcport->bfa)); - bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT); -} - -static void -bfa_fcport_stats_query(void *cbarg) -{ - struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg; - bfi_pport_get_stats_req_t *msg; - - msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT); - - if (!msg) { - fcport->stats_qfull = BFA_TRUE; - bfa_reqq_winit(&fcport->stats_reqq_wait, - bfa_fcport_stats_query, fcport); - bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT, - &fcport->stats_reqq_wait); - return; - } - fcport->stats_qfull = BFA_FALSE; - - bfa_os_memset(msg, 0, sizeof(bfi_pport_get_stats_req_t)); - bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_FCPORT_H2I_GET_STATS_REQ, - bfa_lpuid(fcport->bfa)); - bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT); -} - -static void -bfa_fcport_stats_clear(void *cbarg) -{ - struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg; - bfi_pport_clear_stats_req_t *msg; - - msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT); - - if (!msg) { - fcport->stats_qfull = BFA_TRUE; - bfa_reqq_winit(&fcport->stats_reqq_wait, - bfa_fcport_stats_clear, fcport); - bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT, - &fcport->stats_reqq_wait); - return; - } - fcport->stats_qfull = BFA_FALSE; - - bfa_os_memset(msg, 0, sizeof(bfi_pport_clear_stats_req_t)); - bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_FCPORT_H2I_CLEAR_STATS_REQ, - bfa_lpuid(fcport->bfa)); - bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT); -} - -static void -bfa_port_qos_stats_clear(void *cbarg) -{ - struct bfa_fcport_s *fcport = (struct bfa_fcport_s *)cbarg; - bfi_pport_clear_qos_stats_req_t *msg; - - msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT); - - if (!msg) { - fcport->stats_qfull = BFA_TRUE; - bfa_reqq_winit(&fcport->stats_reqq_wait, - bfa_port_qos_stats_clear, fcport); - bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT, - &fcport->stats_reqq_wait); - return; - } - fcport->stats_qfull = BFA_FALSE; - - bfa_os_memset(msg, 0, sizeof(bfi_pport_clear_qos_stats_req_t)); - bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_CLEAR_QOS_STATS_REQ, - bfa_lpuid(fcport->bfa)); - bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT); -} - -static void -bfa_fcport_stats_swap(union bfa_fcport_stats_u *d, union bfa_fcport_stats_u *s) -{ - u32 *dip = (u32 *) d; - u32 *sip = (u32 *) s; - int i; - - /* Do 64 bit fields swap first */ - for (i = 0; i < ((sizeof(union bfa_fcport_stats_u) - - sizeof(struct bfa_qos_stats_s))/sizeof(u32)); i = i + 2) { -#ifdef __BIGENDIAN - dip[i] = bfa_os_ntohl(sip[i]); - dip[i + 1] = bfa_os_ntohl(sip[i + 1]); -#else - dip[i] = bfa_os_ntohl(sip[i + 1]); - dip[i + 1] = bfa_os_ntohl(sip[i]); -#endif - } - - /* Now swap the 32 bit fields */ - for (; i < (sizeof(union bfa_fcport_stats_u)/sizeof(u32)); ++i) - dip[i] = bfa_os_ntohl(sip[i]); -} - -static void -bfa_port_stats_swap(union bfa_pport_stats_u *d, union bfa_pport_stats_u *s) -{ - u32 *dip = (u32 *) d; - u32 *sip = (u32 *) s; - int i; - - /* Do 64 bit fields swap first */ - for (i = 0; i < (sizeof(union bfa_pport_stats_u) / sizeof(u32)); - i = i + 2) { -#ifdef __BIGENDIAN - dip[i] = bfa_os_ntohl(sip[i]); - dip[i + 1] = bfa_os_ntohl(sip[i + 1]); -#else - dip[i] = bfa_os_ntohl(sip[i + 1]); - dip[i + 1] = bfa_os_ntohl(sip[i]); -#endif - } -} - -static void -__bfa_cb_port_stats_clr(void *cbarg, bfa_boolean_t complete) -{ - struct bfa_fcport_s *fcport = cbarg; - - if (complete) { - fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status); - } else { - fcport->stats_busy = BFA_FALSE; - fcport->stats_status = BFA_STATUS_OK; - } -} - -static void -__bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete) -{ - struct bfa_fcport_s *fcport = cbarg; - - if (complete) { - fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status); - } else { - fcport->stats_busy = BFA_FALSE; - fcport->stats_status = BFA_STATUS_OK; - } -} - -static void -bfa_port_stats_clr_timeout(void *cbarg) -{ - struct bfa_fcport_s *fcport = (struct bfa_fcport_s *)cbarg; - - bfa_trc(fcport->bfa, fcport->stats_qfull); - - if (fcport->stats_qfull) { - bfa_reqq_wcancel(&fcport->stats_reqq_wait); - fcport->stats_qfull = BFA_FALSE; - } - - fcport->stats_status = BFA_STATUS_ETIMER; - bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, - __bfa_cb_port_stats_clr, fcport); -} - -static void -bfa_fcport_callback(struct bfa_fcport_s *fcport, enum bfa_pport_linkstate event) -{ - if (fcport->bfa->fcs) { - fcport->event_cbfn(fcport->event_cbarg, event); - return; - } - - switch (event) { - case BFA_PPORT_LINKUP: - bfa_sm_send_event(&fcport->ln, BFA_FCPORT_LN_SM_LINKUP); - break; - case BFA_PPORT_LINKDOWN: - bfa_sm_send_event(&fcport->ln, BFA_FCPORT_LN_SM_LINKDOWN); - break; - default: - bfa_assert(0); - } -} - -static void -bfa_fcport_queue_cb(struct bfa_fcport_ln_s *ln, enum bfa_pport_linkstate event) -{ - ln->ln_event = event; - bfa_cb_queue(ln->fcport->bfa, &ln->ln_qe, __bfa_cb_fcport_event, ln); -} - -static void -bfa_fcport_stats_clr_timeout(void *cbarg) -{ - struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg; - - bfa_trc(fcport->bfa, fcport->stats_qfull); - - if (fcport->stats_qfull) { - bfa_reqq_wcancel(&fcport->stats_reqq_wait); - fcport->stats_qfull = BFA_FALSE; - } - - fcport->stats_status = BFA_STATUS_ETIMER; - bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, __bfa_cb_fcport_stats_clr, - fcport); -} - -static void -__bfa_cb_port_stats(void *cbarg, bfa_boolean_t complete) -{ - struct bfa_fcport_s *fcport = cbarg; - - if (complete) { - if (fcport->stats_status == BFA_STATUS_OK) - bfa_port_stats_swap(fcport->stats_ret, fcport->stats); - fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status); - } else { - fcport->stats_busy = BFA_FALSE; - fcport->stats_status = BFA_STATUS_OK; - } -} - -static void -bfa_port_stats_timeout(void *cbarg) -{ - struct bfa_fcport_s *fcport = (struct bfa_fcport_s *)cbarg; - - bfa_trc(fcport->bfa, fcport->stats_qfull); - - if (fcport->stats_qfull) { - bfa_reqq_wcancel(&fcport->stats_reqq_wait); - fcport->stats_qfull = BFA_FALSE; - } - - fcport->stats_status = BFA_STATUS_ETIMER; - bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, __bfa_cb_port_stats, fcport); -} - -static void -__bfa_cb_fcport_stats(void *cbarg, bfa_boolean_t complete) -{ - struct bfa_fcport_s *fcport = cbarg; - - if (complete) { - if (fcport->stats_status == BFA_STATUS_OK) { - bfa_fcport_stats_swap(fcport->fcport_stats_ret, - fcport->fcport_stats); - } - fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status); - } else { - fcport->stats_busy = BFA_FALSE; - fcport->stats_status = BFA_STATUS_OK; - } -} - -static void -bfa_fcport_stats_timeout(void *cbarg) -{ - struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg; - - bfa_trc(fcport->bfa, fcport->stats_qfull); - - if (fcport->stats_qfull) { - bfa_reqq_wcancel(&fcport->stats_reqq_wait); - fcport->stats_qfull = BFA_FALSE; - } - - fcport->stats_status = BFA_STATUS_ETIMER; - bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, __bfa_cb_fcport_stats, - fcport); -} - -#define BFA_PORT_STATS_TOV 1000 +#define BFA_FCPORT_STATS_TOV 1000 /** - * Fetch port attributes. + * Fetch port attributes (FCQoS or FCoE). */ bfa_status_t -bfa_pport_get_stats(struct bfa_s *bfa, union bfa_pport_stats_u *stats, +bfa_fcport_get_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats, bfa_cb_pport_t cbfn, void *cbarg) { struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); @@ -1804,20 +1613,23 @@ bfa_pport_get_stats(struct bfa_s *bfa, union bfa_pport_stats_u *stats, return BFA_STATUS_DEVBUSY; } - fcport->stats_busy = BFA_TRUE; - fcport->stats_ret = stats; - fcport->stats_cbfn = cbfn; + fcport->stats_busy = BFA_TRUE; + fcport->stats_ret = stats; + fcport->stats_cbfn = cbfn; fcport->stats_cbarg = cbarg; - bfa_port_stats_query(fcport); + bfa_fcport_send_stats_get(fcport); - bfa_timer_start(bfa, &fcport->timer, bfa_port_stats_timeout, fcport, - BFA_PORT_STATS_TOV); + bfa_timer_start(bfa, &fcport->timer, bfa_fcport_stats_get_timeout, + fcport, BFA_FCPORT_STATS_TOV); return BFA_STATUS_OK; } +/** + * Reset port statistics (FCQoS or FCoE). + */ bfa_status_t -bfa_pport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg) +bfa_fcport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg) { struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); @@ -1830,65 +1642,61 @@ bfa_pport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg) fcport->stats_cbfn = cbfn; fcport->stats_cbarg = cbarg; - bfa_port_stats_clear(fcport); + bfa_fcport_send_stats_clear(fcport); - bfa_timer_start(bfa, &fcport->timer, bfa_port_stats_clr_timeout, - fcport, BFA_PORT_STATS_TOV); + bfa_timer_start(bfa, &fcport->timer, bfa_fcport_stats_clr_timeout, + fcport, BFA_FCPORT_STATS_TOV); return BFA_STATUS_OK; } /** - * @brief - * Fetch FCPort statistics. - * Todo TBD: sharing timer,stats_busy and other resources of fcport for now - - * ideally we want to create seperate ones for fcport once bfa_fcport_s is - * decided. - * + * Fetch FCQoS port statistics */ bfa_status_t -bfa_fcport_get_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats, - bfa_cb_pport_t cbfn, void *cbarg) +bfa_fcport_get_qos_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats, + bfa_cb_pport_t cbfn, void *cbarg) { - struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); - - if (fcport->stats_busy) { - bfa_trc(bfa, fcport->stats_busy); - return BFA_STATUS_DEVBUSY; - } - - fcport->stats_busy = BFA_TRUE; - fcport->fcport_stats_ret = stats; - fcport->stats_cbfn = cbfn; - fcport->stats_cbarg = cbarg; + /* Meaningful only for FC mode */ + bfa_assert(bfa_ioc_get_fcmode(&bfa->ioc)); - bfa_fcport_stats_query(fcport); - - bfa_timer_start(bfa, &fcport->timer, bfa_fcport_stats_timeout, fcport, - BFA_PORT_STATS_TOV); - - return BFA_STATUS_OK; + return bfa_fcport_get_stats(bfa, stats, cbfn, cbarg); } +/** + * Reset FCoE port statistics + */ bfa_status_t -bfa_fcport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg) +bfa_fcport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg) { - struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); + /* Meaningful only for FC mode */ + bfa_assert(bfa_ioc_get_fcmode(&bfa->ioc)); - if (fcport->stats_busy) { - bfa_trc(bfa, fcport->stats_busy); - return BFA_STATUS_DEVBUSY; - } + return bfa_fcport_clear_stats(bfa, cbfn, cbarg); +} - fcport->stats_busy = BFA_TRUE; - fcport->stats_cbfn = cbfn; - fcport->stats_cbarg = cbarg; +/** + * Fetch FCQoS port statistics + */ +bfa_status_t +bfa_fcport_get_fcoe_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats, + bfa_cb_pport_t cbfn, void *cbarg) +{ + /* Meaningful only for FCoE mode */ + bfa_assert(!bfa_ioc_get_fcmode(&bfa->ioc)); - bfa_fcport_stats_clear(fcport); + return bfa_fcport_get_stats(bfa, stats, cbfn, cbarg); +} - bfa_timer_start(bfa, &fcport->timer, bfa_fcport_stats_clr_timeout, - fcport, BFA_PORT_STATS_TOV); +/** + * Reset FCoE port statistics + */ +bfa_status_t +bfa_fcport_clear_fcoe_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg) +{ + /* Meaningful only for FCoE mode */ + bfa_assert(!bfa_ioc_get_fcmode(&bfa->ioc)); - return BFA_STATUS_OK; + return bfa_fcport_clear_stats(bfa, cbfn, cbarg); } bfa_status_t @@ -1946,40 +1754,6 @@ bfa_fcport_qos_get_vc_attr(struct bfa_s *bfa, } /** - * Fetch QoS Stats. - */ -bfa_status_t -bfa_fcport_get_qos_stats(struct bfa_s *bfa, union bfa_pport_stats_u *stats, - bfa_cb_pport_t cbfn, void *cbarg) -{ - /* - * QoS stats is embedded in port stats - */ - return bfa_pport_get_stats(bfa, stats, cbfn, cbarg); -} - -bfa_status_t -bfa_fcport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg) -{ - struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); - - if (fcport->stats_busy) { - bfa_trc(bfa, fcport->stats_busy); - return BFA_STATUS_DEVBUSY; - } - - fcport->stats_busy = BFA_TRUE; - fcport->stats_cbfn = cbfn; - fcport->stats_cbarg = cbarg; - - bfa_port_qos_stats_clear(fcport); - - bfa_timer_start(bfa, &fcport->timer, bfa_port_stats_clr_timeout, - fcport, BFA_PORT_STATS_TOV); - return BFA_STATUS_OK; -} - -/** * Fetch port attributes. */ bfa_status_t diff --git a/drivers/scsi/bfa/bfa_port_priv.h b/drivers/scsi/bfa/bfa_port_priv.h index 6d315ff..40e256e 100644 --- a/drivers/scsi/bfa/bfa_port_priv.h +++ b/drivers/scsi/bfa/bfa_port_priv.h @@ -46,6 +46,8 @@ struct bfa_fcport_s { enum bfa_pport_topology topology; /* current topology */ u8 myalpa; /* my ALPA in LOOP topology */ u8 rsvd[3]; + u32 mypid:24; + u32 rsvd_b:8; struct bfa_pport_cfg_s cfg; /* current port configuration */ struct bfa_qos_attr_s qos_attr; /* QoS Attributes */ struct bfa_qos_vc_attr_s qos_vc_attr; /* VC info from ELP */ @@ -59,40 +61,25 @@ struct bfa_fcport_s { void (*event_cbfn) (void *cbarg, bfa_pport_event_t event); union { - union bfi_pport_i2h_msg_u i2hmsg; + union bfi_fcport_i2h_msg_u i2hmsg; } event_arg; void *bfad; /* BFA driver handle */ struct bfa_fcport_ln_s ln; /* Link Notification */ struct bfa_cb_qe_s hcb_qe; /* BFA callback queue elem */ + struct bfa_timer_s timer; /* timer */ u32 msgtag; /* fimrware msg tag for reply */ u8 *stats_kva; u64 stats_pa; - union bfa_pport_stats_u *stats; /* pport stats */ - u32 mypid:24; - u32 rsvd_b:8; - struct bfa_timer_s timer; /* timer */ - union bfa_pport_stats_u *stats_ret; - /* driver stats location */ - bfa_status_t stats_status; - /* stats/statsclr status */ - bfa_boolean_t stats_busy; - /* outstanding stats/statsclr */ - bfa_boolean_t stats_qfull; - bfa_boolean_t diag_busy; - /* diag busy status */ - bfa_boolean_t beacon; - /* port beacon status */ - bfa_boolean_t link_e2e_beacon; - /* link beacon status */ - bfa_cb_pport_t stats_cbfn; - /* driver callback function */ - void *stats_cbarg; - /* *!< user callback arg */ - /* FCport stats */ - u8 *fcport_stats_kva; - u64 fcport_stats_pa; - union bfa_fcport_stats_u *fcport_stats; - union bfa_fcport_stats_u *fcport_stats_ret; + union bfa_fcport_stats_u *stats; + union bfa_fcport_stats_u *stats_ret; /* driver stats location */ + bfa_status_t stats_status; /* stats/statsclr status */ + bfa_boolean_t stats_busy; /* outstanding stats/statsclr */ + bfa_boolean_t stats_qfull; + bfa_cb_pport_t stats_cbfn; /* driver callback function */ + void *stats_cbarg; /* *!< user callback arg */ + bfa_boolean_t diag_busy; /* diag busy status */ + bfa_boolean_t beacon; /* port beacon status */ + bfa_boolean_t link_e2e_beacon; /* link beacon status */ }; #define BFA_FCPORT_MOD(__bfa) (&(__bfa)->modules.fcport) diff --git a/drivers/scsi/bfa/bfad_attr.c b/drivers/scsi/bfa/bfad_attr.c index dd5cb20..d97f691 100644 --- a/drivers/scsi/bfa/bfad_attr.c +++ b/drivers/scsi/bfa/bfad_attr.c @@ -288,7 +288,7 @@ bfad_im_get_stats(struct Scsi_Host *shost) init_completion(&fcomp.comp); spin_lock_irqsave(&bfad->bfad_lock, flags); memset(hstats, 0, sizeof(struct fc_host_statistics)); - rc = bfa_pport_get_stats(&bfad->bfa, + rc = bfa_port_get_stats(BFA_FCPORT(&bfad->bfa), (union bfa_pport_stats_u *) hstats, bfad_hcb_comp, &fcomp); spin_unlock_irqrestore(&bfad->bfad_lock, flags); @@ -315,7 +315,8 @@ bfad_im_reset_stats(struct Scsi_Host *shost) init_completion(&fcomp.comp); spin_lock_irqsave(&bfad->bfad_lock, flags); - rc = bfa_pport_clear_stats(&bfad->bfa, bfad_hcb_comp, &fcomp); + rc = bfa_port_clear_stats(BFA_FCPORT(&bfad->bfa), bfad_hcb_comp, + &fcomp); spin_unlock_irqrestore(&bfad->bfad_lock, flags); if (rc != BFA_STATUS_OK) diff --git a/drivers/scsi/bfa/include/bfa_svc.h b/drivers/scsi/bfa/include/bfa_svc.h index f2c3085..1349b99 100644 --- a/drivers/scsi/bfa/include/bfa_svc.h +++ b/drivers/scsi/bfa/include/bfa_svc.h @@ -36,7 +36,7 @@ struct bfa_fcxp_s; struct bfa_rport_info_s { u16 max_frmsz; /* max rcv pdu size */ u32 pid:24, /* remote port ID */ - lp_tag:8; + lp_tag:8; /* tag */ u32 local_pid:24, /* local port ID */ cisc:8; /* CIRO supported */ u8 fc_class; /* supported FC classes. enum fc_cos */ @@ -55,7 +55,7 @@ struct bfa_rport_s { void *rport_drv; /* fcs/driver rport object */ u16 fw_handle; /* firmware rport handle */ u16 rport_tag; /* BFA rport tag */ - struct bfa_rport_info_s rport_info; /* rport info from *fcs/driver */ + struct bfa_rport_info_s rport_info; /* rport info from fcs/driver */ struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */ struct bfa_cb_qe_s hcb_qe; /* BFA callback qelem */ struct bfa_rport_hal_stats_s stats; /* BFA rport statistics */ @@ -102,7 +102,7 @@ struct bfa_uf_buf_s { struct bfa_uf_s { struct list_head qe; /* queue element */ struct bfa_s *bfa; /* bfa instance */ - u16 uf_tag; /* identifying tag f/w messages */ + u16 uf_tag; /* identifying tag fw msgs */ u16 vf_id; u16 src_rport_handle; u16 rsvd; @@ -128,7 +128,7 @@ struct bfa_lps_s { u8 reqq; /* lport request queue */ u8 alpa; /* ALPA for loop topologies */ u32 lp_pid; /* lport port ID */ - bfa_boolean_t fdisc; /* send FDISC instead of FLOGI*/ + bfa_boolean_t fdisc; /* send FDISC instead of FLOGI */ bfa_boolean_t auth_en; /* enable authentication */ bfa_boolean_t auth_req; /* authentication required */ bfa_boolean_t npiv_en; /* NPIV is allowed by peer */ @@ -178,11 +178,6 @@ bfa_status_t bfa_fcport_trunk_disable(struct bfa_s *bfa); bfa_boolean_t bfa_fcport_trunk_query(struct bfa_s *bfa, u32 *bitmap); void bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr); wwn_t bfa_fcport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node); -bfa_status_t bfa_pport_get_stats(struct bfa_s *bfa, - union bfa_pport_stats_u *stats, - bfa_cb_pport_t cbfn, void *cbarg); -bfa_status_t bfa_pport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, - void *cbarg); void bfa_fcport_event_register(struct bfa_s *bfa, void (*event_cbfn) (void *cbarg, bfa_pport_event_t event), void *event_cbarg); @@ -198,14 +193,21 @@ void bfa_fcport_busy(struct bfa_s *bfa, bfa_boolean_t status); void bfa_fcport_beacon(struct bfa_s *bfa, bfa_boolean_t beacon, bfa_boolean_t link_e2e_beacon); void bfa_cb_pport_event(void *cbarg, bfa_pport_event_t event); -void bfa_fcport_qos_get_attr(struct bfa_s *bfa, struct bfa_qos_attr_s *qos_attr); +void bfa_fcport_qos_get_attr(struct bfa_s *bfa, + struct bfa_qos_attr_s *qos_attr); void bfa_fcport_qos_get_vc_attr(struct bfa_s *bfa, struct bfa_qos_vc_attr_s *qos_vc_attr); bfa_status_t bfa_fcport_get_qos_stats(struct bfa_s *bfa, - union bfa_pport_stats_u *stats, + union bfa_fcport_stats_u *stats, bfa_cb_pport_t cbfn, void *cbarg); bfa_status_t bfa_fcport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg); +bfa_status_t bfa_fcport_get_fcoe_stats(struct bfa_s *bfa, + union bfa_fcport_stats_u *stats, + bfa_cb_pport_t cbfn, void *cbarg); +bfa_status_t bfa_fcport_clear_fcoe_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, + void *cbarg); + bfa_boolean_t bfa_fcport_is_ratelim(struct bfa_s *bfa); bfa_boolean_t bfa_fcport_is_linkup(struct bfa_s *bfa); bfa_status_t bfa_fcport_get_stats(struct bfa_s *bfa, diff --git a/drivers/scsi/bfa/include/bfi/bfi.h b/drivers/scsi/bfa/include/bfi/bfi.h index 7042c18..a550e80 100644 --- a/drivers/scsi/bfa/include/bfi/bfi.h +++ b/drivers/scsi/bfa/include/bfi/bfi.h @@ -143,8 +143,8 @@ enum bfi_mclass { BFI_MC_IOC = 1, /* IO Controller (IOC) */ BFI_MC_DIAG = 2, /* Diagnostic Msgs */ BFI_MC_FLASH = 3, /* Flash message class */ - BFI_MC_CEE = 4, - BFI_MC_FC_PORT = 5, /* FC port */ + BFI_MC_CEE = 4, /* CEE */ + BFI_MC_FCPORT = 5, /* FC port */ BFI_MC_IOCFC = 6, /* FC - IO Controller (IOC) */ BFI_MC_LL = 7, /* Link Layer */ BFI_MC_UF = 8, /* Unsolicited frame receive */ diff --git a/drivers/scsi/bfa/include/bfi/bfi_pport.h b/drivers/scsi/bfa/include/bfi/bfi_pport.h index 5c3d289..50dcf45 100644 --- a/drivers/scsi/bfa/include/bfi/bfi_pport.h +++ b/drivers/scsi/bfa/include/bfi/bfi_pport.h @@ -22,168 +22,97 @@ #pragma pack(1) -enum bfi_pport_h2i { - BFI_PPORT_H2I_ENABLE_REQ = (1), - BFI_PPORT_H2I_DISABLE_REQ = (2), - BFI_PPORT_H2I_GET_STATS_REQ = (3), - BFI_PPORT_H2I_CLEAR_STATS_REQ = (4), - BFI_PPORT_H2I_SET_SVC_PARAMS_REQ = (5), - BFI_PPORT_H2I_ENABLE_RX_VF_TAG_REQ = (6), - BFI_PPORT_H2I_ENABLE_TX_VF_TAG_REQ = (7), - BFI_PPORT_H2I_GET_QOS_STATS_REQ = (8), - BFI_PPORT_H2I_CLEAR_QOS_STATS_REQ = (9), - BFI_FCPORT_H2I_GET_STATS_REQ = (10), - BFI_FCPORT_H2I_CLEAR_STATS_REQ = (11), +enum bfi_fcport_h2i { + BFI_FCPORT_H2I_ENABLE_REQ = (1), + BFI_FCPORT_H2I_DISABLE_REQ = (2), + BFI_FCPORT_H2I_SET_SVC_PARAMS_REQ = (3), + BFI_FCPORT_H2I_STATS_GET_REQ = (4), + BFI_FCPORT_H2I_STATS_CLEAR_REQ = (5), }; -enum bfi_pport_i2h { - BFI_PPORT_I2H_ENABLE_RSP = BFA_I2HM(1), - BFI_PPORT_I2H_DISABLE_RSP = BFA_I2HM(2), - BFI_PPORT_I2H_GET_STATS_RSP = BFA_I2HM(3), - BFI_PPORT_I2H_CLEAR_STATS_RSP = BFA_I2HM(4), - BFI_PPORT_I2H_SET_SVC_PARAMS_RSP = BFA_I2HM(5), - BFI_PPORT_I2H_ENABLE_RX_VF_TAG_RSP = BFA_I2HM(6), - BFI_PPORT_I2H_ENABLE_TX_VF_TAG_RSP = BFA_I2HM(7), - BFI_PPORT_I2H_EVENT = BFA_I2HM(8), - BFI_PPORT_I2H_GET_QOS_STATS_RSP = BFA_I2HM(9), - BFI_PPORT_I2H_CLEAR_QOS_STATS_RSP = BFA_I2HM(10), - BFI_FCPORT_I2H_GET_STATS_RSP = BFA_I2HM(11), - BFI_FCPORT_I2H_CLEAR_STATS_RSP = BFA_I2HM(12), +enum bfi_fcport_i2h { + BFI_FCPORT_I2H_ENABLE_RSP = BFA_I2HM(1), + BFI_FCPORT_I2H_DISABLE_RSP = BFA_I2HM(2), + BFI_FCPORT_I2H_SET_SVC_PARAMS_RSP = BFA_I2HM(3), + BFI_FCPORT_I2H_STATS_GET_RSP = BFA_I2HM(4), + BFI_FCPORT_I2H_STATS_CLEAR_RSP = BFA_I2HM(5), + BFI_FCPORT_I2H_EVENT = BFA_I2HM(6), }; /** * Generic REQ type */ -struct bfi_pport_generic_req_s { +struct bfi_fcport_req_s { struct bfi_mhdr_s mh; /* msg header */ - u32 msgtag; /* msgtag for reply */ + u32 msgtag; /* msgtag for reply */ }; /** * Generic RSP type */ -struct bfi_pport_generic_rsp_s { +struct bfi_fcport_rsp_s { struct bfi_mhdr_s mh; /* common msg header */ - u8 status; /* port enable status */ - u8 rsvd[3]; - u32 msgtag; /* msgtag for reply */ + u8 status; /* port enable status */ + u8 rsvd[3]; + u32 msgtag; /* msgtag for reply */ }; /** - * BFI_PPORT_H2I_ENABLE_REQ + * BFI_FCPORT_H2I_ENABLE_REQ */ -struct bfi_pport_enable_req_s { +struct bfi_fcport_enable_req_s { struct bfi_mhdr_s mh; /* msg header */ - u32 rsvd1; - wwn_t nwwn; /* node wwn of physical port */ - wwn_t pwwn; /* port wwn of physical port */ - struct bfa_pport_cfg_s port_cfg; /* port configuration */ - union bfi_addr_u stats_dma_addr; /* DMA address for stats */ - union bfi_addr_u fcport_stats_dma_addr;/*!< DMA address for stats */ - u32 msgtag; /* msgtag for reply */ - u32 rsvd2; + u32 rsvd1; + wwn_t nwwn; /* node wwn of physical port */ + wwn_t pwwn; /* port wwn of physical port */ + struct bfa_pport_cfg_s port_cfg; /* port configuration */ + union bfi_addr_u stats_dma_addr; /* DMA address for stats */ + u32 msgtag; /* msgtag for reply */ + u32 rsvd2; }; /** - * BFI_PPORT_I2H_ENABLE_RSP + * BFI_FCPORT_H2I_SET_SVC_PARAMS_REQ */ -#define bfi_pport_enable_rsp_t struct bfi_pport_generic_rsp_s - -/** - * BFI_PPORT_H2I_DISABLE_REQ - */ -#define bfi_pport_disable_req_t struct bfi_pport_generic_req_s - -/** - * BFI_PPORT_I2H_DISABLE_RSP - */ -#define bfi_pport_disable_rsp_t struct bfi_pport_generic_rsp_s - -/** - * BFI_PPORT_H2I_GET_STATS_REQ - */ -#define bfi_pport_get_stats_req_t struct bfi_pport_generic_req_s - -/** - * BFI_PPORT_I2H_GET_STATS_RSP - */ -#define bfi_pport_get_stats_rsp_t struct bfi_pport_generic_rsp_s - -/** - * BFI_PPORT_H2I_CLEAR_STATS_REQ - */ -#define bfi_pport_clear_stats_req_t struct bfi_pport_generic_req_s - -/** - * BFI_PPORT_I2H_CLEAR_STATS_RSP - */ -#define bfi_pport_clear_stats_rsp_t struct bfi_pport_generic_rsp_s - -/** - * BFI_PPORT_H2I_GET_QOS_STATS_REQ - */ -#define bfi_pport_get_qos_stats_req_t struct bfi_pport_generic_req_s - -/** - * BFI_PPORT_H2I_GET_QOS_STATS_RSP - */ -#define bfi_pport_get_qos_stats_rsp_t struct bfi_pport_generic_rsp_s - -/** - * BFI_PPORT_H2I_CLEAR_QOS_STATS_REQ - */ -#define bfi_pport_clear_qos_stats_req_t struct bfi_pport_generic_req_s - -/** - * BFI_PPORT_H2I_CLEAR_QOS_STATS_RSP - */ -#define bfi_pport_clear_qos_stats_rsp_t struct bfi_pport_generic_rsp_s - -/** - * BFI_PPORT_H2I_SET_SVC_PARAMS_REQ - */ -struct bfi_pport_set_svc_params_req_s { +struct bfi_fcport_set_svc_params_req_s { struct bfi_mhdr_s mh; /* msg header */ - u16 tx_bbcredit; /* Tx credits */ - u16 rsvd; + u16 tx_bbcredit; /* Tx credits */ + u16 rsvd; }; /** - * BFI_PPORT_I2H_SET_SVC_PARAMS_RSP - */ - -/** - * BFI_PPORT_I2H_EVENT + * BFI_FCPORT_I2H_EVENT */ -struct bfi_pport_event_s { +struct bfi_fcport_event_s { struct bfi_mhdr_s mh; /* common msg header */ struct bfa_pport_link_s link_state; }; -union bfi_pport_h2i_msg_u { +/** + * fcport H2I message + */ +union bfi_fcport_h2i_msg_u { struct bfi_mhdr_s *mhdr; - struct bfi_pport_enable_req_s *penable; - struct bfi_pport_generic_req_s *pdisable; - struct bfi_pport_generic_req_s *pgetstats; - struct bfi_pport_generic_req_s *pclearstats; - struct bfi_pport_set_svc_params_req_s *psetsvcparams; - struct bfi_pport_get_qos_stats_req_s *pgetqosstats; - struct bfi_pport_generic_req_s *pclearqosstats; + struct bfi_fcport_enable_req_s *penable; + struct bfi_fcport_req_s *pdisable; + struct bfi_fcport_set_svc_params_req_s *psetsvcparams; + struct bfi_fcport_req_s *pstatsget; + struct bfi_fcport_req_s *pstatsclear; }; -union bfi_pport_i2h_msg_u { +/** + * fcport I2H message + */ +union bfi_fcport_i2h_msg_u { struct bfi_msg_s *msg; - struct bfi_pport_generic_rsp_s *enable_rsp; - struct bfi_pport_disable_rsp_s *disable_rsp; - struct bfi_pport_generic_rsp_s *getstats_rsp; - struct bfi_pport_clear_stats_rsp_s *clearstats_rsp; - struct bfi_pport_set_svc_params_rsp_s *setsvcparasm_rsp; - struct bfi_pport_get_qos_stats_rsp_s *getqosstats_rsp; - struct bfi_pport_clear_qos_stats_rsp_s *clearqosstats_rsp; - struct bfi_pport_event_s *event; + struct bfi_fcport_rsp_s *penable_rsp; + struct bfi_fcport_rsp_s *pdisable_rsp; + struct bfi_fcport_rsp_s *psetsvcparams_rsp; + struct bfi_fcport_rsp_s *pstatsget_rsp; + struct bfi_fcport_rsp_s *pstatsclear_rsp; + struct bfi_fcport_event_s *event; }; #pragma pack() #endif /* __BFI_PPORT_H__ */ - diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_pport.h b/drivers/scsi/bfa/include/defs/bfa_defs_pport.h index 164cfbe..26e5cc7 100644 --- a/drivers/scsi/bfa/include/defs/bfa_defs_pport.h +++ b/drivers/scsi/bfa/include/defs/bfa_defs_pport.h @@ -240,73 +240,79 @@ struct bfa_pport_attr_s { * FC Port statistics. */ struct bfa_pport_fc_stats_s { - u64 secs_reset; /* seconds since stats is reset */ - u64 tx_frames; /* transmitted frames */ - u64 tx_words; /* transmitted words */ - u64 rx_frames; /* received frames */ - u64 rx_words; /* received words */ - u64 lip_count; /* LIPs seen */ - u64 nos_count; /* NOS count */ - u64 error_frames; /* errored frames */ - u64 dropped_frames; /* dropped frames */ - u64 link_failures; /* link failure count */ - u64 loss_of_syncs; /* loss of sync count */ - u64 loss_of_signals;/* loss of signal count */ - u64 primseq_errs; /* primitive sequence protocol */ - u64 bad_os_count; /* invalid ordered set */ - u64 err_enc_out; /* Encoding error outside frame */ - u64 invalid_crcs; /* frames received with invalid CRC*/ - u64 undersized_frm; /* undersized frames */ - u64 oversized_frm; /* oversized frames */ - u64 bad_eof_frm; /* frames with bad EOF */ - struct bfa_qos_stats_s qos_stats; /* QoS statistics */ + u64 secs_reset; /* Seconds since stats is reset */ + u64 tx_frames; /* Tx frames */ + u64 tx_words; /* Tx words */ + u64 tx_lip; /* TX LIP */ + u64 tx_nos; /* Tx NOS */ + u64 tx_ols; /* Tx OLS */ + u64 tx_lr; /* Tx LR */ + u64 tx_lrr; /* Tx LRR */ + u64 rx_frames; /* Rx frames */ + u64 rx_words; /* Rx words */ + u64 lip_count; /* Rx LIP */ + u64 nos_count; /* Rx NOS */ + u64 ols_count; /* Rx OLS */ + u64 lr_count; /* Rx LR */ + u64 lrr_count; /* Rx LRR */ + u64 invalid_crcs; /* Rx CRC err frames */ + u64 invalid_crc_gd_eof; /* Rx CRC err good EOF frames */ + u64 undersized_frm; /* Rx undersized frames */ + u64 oversized_frm; /* Rx oversized frames */ + u64 bad_eof_frm; /* Rx frames with bad EOF */ + u64 error_frames; /* Errored frames */ + u64 dropped_frames; /* Dropped frames */ + u64 link_failures; /* Link Failure (LF) count */ + u64 loss_of_syncs; /* Loss of sync count */ + u64 loss_of_signals;/* Loss of signal count */ + u64 primseq_errs; /* Primitive sequence protocol err. */ + u64 bad_os_count; /* Invalid ordered sets */ + u64 err_enc_out; /* Encoding err nonframe_8b10b */ + u64 err_enc; /* Encoding err frame_8b10b */ }; /** * Eth Port statistics. */ struct bfa_pport_eth_stats_s { - u64 secs_reset; /* seconds since stats is reset */ - u64 frame_64; /* both rx and tx counter */ - u64 frame_65_127; /* both rx and tx counter */ - u64 frame_128_255; /* both rx and tx counter */ - u64 frame_256_511; /* both rx and tx counter */ - u64 frame_512_1023; /* both rx and tx counter */ - u64 frame_1024_1518; /* both rx and tx counter */ - u64 frame_1519_1522; /* both rx and tx counter */ - - u64 tx_bytes; - u64 tx_packets; - u64 tx_mcast_packets; - u64 tx_bcast_packets; - u64 tx_control_frame; - u64 tx_drop; - u64 tx_jabber; - u64 tx_fcs_error; - u64 tx_fragments; - - u64 rx_bytes; - u64 rx_packets; - u64 rx_mcast_packets; - u64 rx_bcast_packets; - u64 rx_control_frames; - u64 rx_unknown_opcode; - u64 rx_drop; - u64 rx_jabber; - u64 rx_fcs_error; - u64 rx_alignment_error; - u64 rx_frame_length_error; - u64 rx_code_error; - u64 rx_fragments; - - u64 rx_pause; /* BPC */ - u64 rx_zero_pause; /* BPC Pause cancellation */ - u64 tx_pause; /* BPC */ - u64 tx_zero_pause; /* BPC Pause cancellation */ - u64 rx_fcoe_pause; /* BPC */ - u64 rx_fcoe_zero_pause; /* BPC Pause cancellation */ - u64 tx_fcoe_pause; /* BPC */ - u64 tx_fcoe_zero_pause; /* BPC Pause cancellation */ + u64 secs_reset; /* Seconds since stats is reset */ + u64 frame_64; /* Frames 64 bytes */ + u64 frame_65_127; /* Frames 65-127 bytes */ + u64 frame_128_255; /* Frames 128-255 bytes */ + u64 frame_256_511; /* Frames 256-511 bytes */ + u64 frame_512_1023; /* Frames 512-1023 bytes */ + u64 frame_1024_1518; /* Frames 1024-1518 bytes */ + u64 frame_1519_1522; /* Frames 1519-1522 bytes */ + u64 tx_bytes; /* Tx bytes */ + u64 tx_packets; /* Tx packets */ + u64 tx_mcast_packets; /* Tx multicast packets */ + u64 tx_bcast_packets; /* Tx broadcast packets */ + u64 tx_control_frame; /* Tx control frame */ + u64 tx_drop; /* Tx drops */ + u64 tx_jabber; /* Tx jabber */ + u64 tx_fcs_error; /* Tx FCS error */ + u64 tx_fragments; /* Tx fragments */ + u64 rx_bytes; /* Rx bytes */ + u64 rx_packets; /* Rx packets */ + u64 rx_mcast_packets; /* Rx multicast packets */ + u64 rx_bcast_packets; /* Rx broadcast packets */ + u64 rx_control_frames; /* Rx control frames */ + u64 rx_unknown_opcode; /* Rx unknown opcode */ + u64 rx_drop; /* Rx drops */ + u64 rx_jabber; /* Rx jabber */ + u64 rx_fcs_error; /* Rx FCS errors */ + u64 rx_alignment_error; /* Rx alignment errors */ + u64 rx_frame_length_error; /* Rx frame len errors */ + u64 rx_code_error; /* Rx code errors */ + u64 rx_fragments; /* Rx fragments */ + u64 rx_pause; /* Rx pause */ + u64 rx_zero_pause; /* Rx zero pause */ + u64 tx_pause; /* Tx pause */ + u64 tx_zero_pause; /* Tx zero pause */ + u64 rx_fcoe_pause; /* Rx fcoe pause */ + u64 rx_fcoe_zero_pause; /* Rx FCoE zero pause */ + u64 tx_fcoe_pause; /* Tx FCoE pause */ + u64 tx_fcoe_zero_pause; /* Tx FCoE zero pause */ }; /** -- cgit v0.10.2 From 25e2934c26f5efaea156c9fda4457d01a8bb44e1 Mon Sep 17 00:00:00 2001 From: Krishna Gudipati Date: Fri, 5 Mar 2010 19:38:17 -0800 Subject: [SCSI] bfa: FCS and include file changes. MS module did not invoke fdmi offline in all cases, call fdmi offline when ms module receives a port offline, so that fdmi offline is from one place in the ms module. Make changes to handle 10G speed in the conversion routine. Replaced the usage of bfa_adapter_attr_s struct with specific API's. Signed-off-by: Krishna Gudipati Signed-off-by: James Bottomley diff --git a/drivers/scsi/bfa/fabric.c b/drivers/scsi/bfa/fabric.c index b4e05ad..8166e97 100644 --- a/drivers/scsi/bfa/fabric.c +++ b/drivers/scsi/bfa/fabric.c @@ -562,17 +562,15 @@ void bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric) { struct bfa_port_cfg_s *port_cfg = &fabric->bport.port_cfg; - struct bfa_adapter_attr_s adapter_attr; + char model[BFA_ADAPTER_MODEL_NAME_LEN] = {0}; struct bfa_fcs_driver_info_s *driver_info = &fabric->fcs->driver_info; - bfa_os_memset((void *)&adapter_attr, 0, - sizeof(struct bfa_adapter_attr_s)); - bfa_ioc_get_adapter_attr(&fabric->fcs->bfa->ioc, &adapter_attr); + bfa_ioc_get_adapter_model(&fabric->fcs->bfa->ioc, model); /* * Model name/number */ - strncpy((char *)&port_cfg->sym_name, adapter_attr.model, + strncpy((char *)&port_cfg->sym_name, model, BFA_FCS_PORT_SYMBNAME_MODEL_SZ); strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR, sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR)); diff --git a/drivers/scsi/bfa/fcbuild.h b/drivers/scsi/bfa/fcbuild.h index 8fa7f27..981d98d 100644 --- a/drivers/scsi/bfa/fcbuild.h +++ b/drivers/scsi/bfa/fcbuild.h @@ -72,6 +72,9 @@ fc_rpsc_operspeed_to_bfa_speed(enum fc_rpsc_op_speed_s speed) case RPSC_OP_SPEED_8G: return BFA_PPORT_SPEED_8GBPS; + case RPSC_OP_SPEED_10G: + return BFA_PPORT_SPEED_10GBPS; + default: return BFA_PPORT_SPEED_UNKNOWN; } @@ -97,6 +100,9 @@ fc_bfa_speed_to_rpsc_operspeed(enum bfa_pport_speed op_speed) case BFA_PPORT_SPEED_8GBPS: return RPSC_OP_SPEED_8G; + case BFA_PPORT_SPEED_10GBPS: + return RPSC_OP_SPEED_10G; + default: return RPSC_OP_SPEED_NOT_EST; } diff --git a/drivers/scsi/bfa/fdmi.c b/drivers/scsi/bfa/fdmi.c index 2c9e713..8f17076 100644 --- a/drivers/scsi/bfa/fdmi.c +++ b/drivers/scsi/bfa/fdmi.c @@ -1114,36 +1114,23 @@ bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_port_fdmi_s *fdmi, { struct bfa_fcs_port_s *port = fdmi->ms->port; struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info; - struct bfa_adapter_attr_s adapter_attr; bfa_os_memset(hba_attr, 0, sizeof(struct bfa_fcs_fdmi_hba_attr_s)); - bfa_os_memset(&adapter_attr, 0, sizeof(struct bfa_adapter_attr_s)); - bfa_ioc_get_adapter_attr(&port->fcs->bfa->ioc, &adapter_attr); - - strncpy(hba_attr->manufacturer, adapter_attr.manufacturer, - sizeof(adapter_attr.manufacturer)); - - strncpy(hba_attr->serial_num, adapter_attr.serial_num, - sizeof(adapter_attr.serial_num)); - - strncpy(hba_attr->model, adapter_attr.model, sizeof(hba_attr->model)); - - strncpy(hba_attr->model_desc, adapter_attr.model_descr, - sizeof(hba_attr->model_desc)); - - strncpy(hba_attr->hw_version, adapter_attr.hw_ver, - sizeof(hba_attr->hw_version)); + bfa_ioc_get_adapter_manufacturer(&port->fcs->bfa->ioc, + hba_attr->manufacturer); + bfa_ioc_get_adapter_serial_num(&port->fcs->bfa->ioc, + hba_attr->serial_num); + bfa_ioc_get_adapter_model(&port->fcs->bfa->ioc, hba_attr->model); + bfa_ioc_get_adapter_model(&port->fcs->bfa->ioc, hba_attr->model_desc); + bfa_ioc_get_pci_chip_rev(&port->fcs->bfa->ioc, hba_attr->hw_version); + bfa_ioc_get_adapter_optrom_ver(&port->fcs->bfa->ioc, + hba_attr->option_rom_ver); + bfa_ioc_get_adapter_fw_ver(&port->fcs->bfa->ioc, hba_attr->fw_version); strncpy(hba_attr->driver_version, (char *)driver_info->version, sizeof(hba_attr->driver_version)); - strncpy(hba_attr->option_rom_ver, adapter_attr.optrom_ver, - sizeof(hba_attr->option_rom_ver)); - - strncpy(hba_attr->fw_version, adapter_attr.fw_ver, - sizeof(hba_attr->fw_version)); - strncpy(hba_attr->os_name, driver_info->host_os_name, sizeof(hba_attr->os_name)); diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_status.h b/drivers/scsi/bfa/include/defs/bfa_defs_status.h index d8a74eb..4374494 100644 --- a/drivers/scsi/bfa/include/defs/bfa_defs_status.h +++ b/drivers/scsi/bfa/include/defs/bfa_defs_status.h @@ -213,7 +213,7 @@ enum bfa_status { * loaded */ BFA_STATUS_CARD_TYPE_MISMATCH = 131, /* Card type mismatch */ BFA_STATUS_BAD_ASICBLK = 132, /* Bad ASIC block */ - BFA_STATUS_NO_DRIVER = 133, /* Storage/Ethernet driver not loaded */ + BFA_STATUS_NO_DRIVER = 133, /* Brocade adapter/driver not installed or loaded */ BFA_STATUS_INVALID_MAC = 134, /* Invalid mac address */ BFA_STATUS_IM_NO_VLAN = 135, /* No VLANs configured on the adapter */ BFA_STATUS_IM_ETH_LB_FAILED = 136, /* Ethernet loopback test failed */ @@ -228,8 +228,7 @@ enum bfa_status { BFA_STATUS_IM_GET_INETCFG_FAILED = 142, /* Acquiring Network Subsytem * handle Failed. Please try * after some time */ - BFA_STATUS_IM_NOT_BOUND = 143, /* Brocade 10G Ethernet Service is not - * Enabled on this port */ + BFA_STATUS_IM_NOT_BOUND = 143, /* IM driver is not active */ BFA_STATUS_INSUFFICIENT_PERMS = 144, /* User doesn't have sufficient * permissions to execute the BCU * application */ diff --git a/drivers/scsi/bfa/ms.c b/drivers/scsi/bfa/ms.c index e6db5fd..5e8c8de 100644 --- a/drivers/scsi/bfa/ms.c +++ b/drivers/scsi/bfa/ms.c @@ -230,10 +230,6 @@ bfa_fcs_port_ms_sm_online(struct bfa_fcs_port_ms_s *ms, switch (event) { case MSSM_EVENT_PORT_OFFLINE: bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline); - /* - * now invoke MS related sub-modules - */ - bfa_fcs_port_fdmi_offline(ms); break; case MSSM_EVENT_PORT_FABRIC_RSCN: @@ -735,6 +731,7 @@ bfa_fcs_port_ms_offline(struct bfa_fcs_port_s *port) ms->port = port; bfa_sm_send_event(ms, MSSM_EVENT_PORT_OFFLINE); + bfa_fcs_port_fdmi_offline(ms); } void -- cgit v0.10.2 From 95aa060decd2472d319c3f12b0b1b699a5f35058 Mon Sep 17 00:00:00 2001 From: Krishna Gudipati Date: Fri, 5 Mar 2010 19:38:27 -0800 Subject: [SCSI] bfa: Handle SCSI IO underrun case. When IO is completed with underrun and with good SCSI status, check if the transferred bytes against scsi_cmnd->underflow, which is set to minimum number of bytes that must be transferred for this command, if is less than required minimum, complete the IO with DID_ERROR. Signed-off-by: Krishna Gudipati Signed-off-by: James Bottomley diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c index cee3d89..fb7aefa 100644 --- a/drivers/scsi/bfa/bfad_im.c +++ b/drivers/scsi/bfa/bfad_im.c @@ -43,11 +43,11 @@ bfa_cb_ioim_done(void *drv, struct bfad_ioim_s *dio, struct bfad_s *bfad = drv; struct bfad_itnim_data_s *itnim_data; struct bfad_itnim_s *itnim; + u8 host_status = DID_OK; switch (io_status) { case BFI_IOIM_STS_OK: bfa_trc(bfad, scsi_status); - cmnd->result = ScsiResult(DID_OK, scsi_status); scsi_set_resid(cmnd, 0); if (sns_len > 0) { @@ -56,8 +56,18 @@ bfa_cb_ioim_done(void *drv, struct bfad_ioim_s *dio, sns_len = SCSI_SENSE_BUFFERSIZE; memcpy(cmnd->sense_buffer, sns_info, sns_len); } - if (residue > 0) + if (residue > 0) { + bfa_trc(bfad, residue); scsi_set_resid(cmnd, residue); + if (!sns_len && (scsi_status == SAM_STAT_GOOD) && + (scsi_bufflen(cmnd) - residue) < + cmnd->underflow) { + bfa_trc(bfad, 0); + host_status = DID_ERROR; + } + } + cmnd->result = ScsiResult(host_status, scsi_status); + break; case BFI_IOIM_STS_ABORTED: -- cgit v0.10.2 From d1c61f8ef582055569de76a86fa1984f9b6698cf Mon Sep 17 00:00:00 2001 From: Krishna Gudipati Date: Fri, 5 Mar 2010 19:38:44 -0800 Subject: [SCSI] bfa: Remove unused header files and did some cleanup. Signed-off-by: Krishna Gudipati Signed-off-by: James Bottomley diff --git a/drivers/scsi/bfa/bfa_fcport.c b/drivers/scsi/bfa/bfa_fcport.c index d109e65..c589488 100644 --- a/drivers/scsi/bfa/bfa_fcport.c +++ b/drivers/scsi/bfa/bfa_fcport.c @@ -853,9 +853,9 @@ bfa_fcport_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len, static void bfa_fcport_qresume(void *cbarg) { - struct bfa_fcport_s *port = cbarg; + struct bfa_fcport_s *fcport = cbarg; - bfa_sm_send_event(port, BFA_FCPORT_SM_QRESUME); + bfa_sm_send_event(fcport, BFA_FCPORT_SM_QRESUME); } static void diff --git a/drivers/scsi/bfa/bfa_ioc_cb.c b/drivers/scsi/bfa/bfa_ioc_cb.c index 1fa052e..3ce8531 100644 --- a/drivers/scsi/bfa/bfa_ioc_cb.c +++ b/drivers/scsi/bfa/bfa_ioc_cb.c @@ -63,13 +63,13 @@ bfa_ioc_set_cb_hwif(struct bfa_ioc_s *ioc) ioc->ioc_hwif = &hwif_cb; } -static uint32_t * -bfa_ioc_cb_fwimg_get_chunk(struct bfa_ioc_s *ioc, uint32_t off) +static u32 * +bfa_ioc_cb_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off) { return bfi_image_cb_get_chunk(off); } -static uint32_t +static u32 bfa_ioc_cb_fwimg_get_size(struct bfa_ioc_s *ioc) { return bfi_image_cb_size; @@ -102,7 +102,7 @@ bfa_ioc_cb_notify_hbfail(struct bfa_ioc_s *ioc) /** * Host to LPU mailbox message addresses */ -static struct { uint32_t hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = { +static struct { u32 hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = { { HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0 }, { HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1 } }; @@ -110,7 +110,7 @@ static struct { uint32_t hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = { /** * Host <-> LPU mailbox command/status registers */ -static struct { uint32_t hfn, lpu; } iocreg_mbcmd[] = { +static struct { u32 hfn, lpu; } iocreg_mbcmd[] = { { HOSTFN0_LPU0_CMD_STAT, LPU0_HOSTFN0_CMD_STAT }, { HOSTFN1_LPU1_CMD_STAT, LPU1_HOSTFN1_CMD_STAT } }; @@ -192,7 +192,7 @@ static bfa_status_t bfa_ioc_cb_pll_init(struct bfa_ioc_s *ioc) { bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva; - uint32_t pll_sclk, pll_fclk; + u32 pll_sclk, pll_fclk; /* * Hold semaphore so that nobody can access the chip during init. diff --git a/drivers/scsi/bfa/bfa_ioc_ct.c b/drivers/scsi/bfa/bfa_ioc_ct.c index 2431922..20b58ad 100644 --- a/drivers/scsi/bfa/bfa_ioc_ct.c +++ b/drivers/scsi/bfa/bfa_ioc_ct.c @@ -33,9 +33,9 @@ BFA_TRC_FILE(CNA, IOC_CT); static bfa_status_t bfa_ioc_ct_pll_init(struct bfa_ioc_s *ioc); static bfa_boolean_t bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc); static void bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc); -static uint32_t* bfa_ioc_ct_fwimg_get_chunk(struct bfa_ioc_s *ioc, - uint32_t off); -static uint32_t bfa_ioc_ct_fwimg_get_size(struct bfa_ioc_s *ioc); +static u32* bfa_ioc_ct_fwimg_get_chunk(struct bfa_ioc_s *ioc, + u32 off); +static u32 bfa_ioc_ct_fwimg_get_size(struct bfa_ioc_s *ioc); static void bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc); static void bfa_ioc_ct_map_port(struct bfa_ioc_s *ioc); static void bfa_ioc_ct_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix); @@ -64,13 +64,13 @@ bfa_ioc_set_ct_hwif(struct bfa_ioc_s *ioc) ioc->ioc_hwif = &hwif_ct; } -static uint32_t* -bfa_ioc_ct_fwimg_get_chunk(struct bfa_ioc_s *ioc, uint32_t off) +static u32* +bfa_ioc_ct_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off) { return bfi_image_ct_get_chunk(off); } -static uint32_t +static u32 bfa_ioc_ct_fwimg_get_size(struct bfa_ioc_s *ioc) { return bfi_image_ct_size; @@ -83,7 +83,7 @@ static bfa_boolean_t bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc) { enum bfi_ioc_state ioc_fwstate; - uint32_t usecnt; + u32 usecnt; struct bfi_ioc_image_hdr_s fwhdr; /** @@ -142,7 +142,7 @@ bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc) static void bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc) { - uint32_t usecnt; + u32 usecnt; /** * Firmware lock is relevant only for CNA. @@ -184,7 +184,7 @@ bfa_ioc_ct_notify_hbfail(struct bfa_ioc_s *ioc) /** * Host to LPU mailbox message addresses */ -static struct { uint32_t hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = { +static struct { u32 hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = { { HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0 }, { HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1 }, { HOSTFN2_LPU_MBOX0_0, LPU_HOSTFN2_MBOX0_0, HOST_PAGE_NUM_FN2 }, @@ -194,7 +194,7 @@ static struct { uint32_t hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = { /** * Host <-> LPU mailbox command/status registers - port 0 */ -static struct { uint32_t hfn, lpu; } iocreg_mbcmd_p0[] = { +static struct { u32 hfn, lpu; } iocreg_mbcmd_p0[] = { { HOSTFN0_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN0_MBOX0_CMD_STAT }, { HOSTFN1_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN1_MBOX0_CMD_STAT }, { HOSTFN2_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN2_MBOX0_CMD_STAT }, @@ -204,7 +204,7 @@ static struct { uint32_t hfn, lpu; } iocreg_mbcmd_p0[] = { /** * Host <-> LPU mailbox command/status registers - port 1 */ -static struct { uint32_t hfn, lpu; } iocreg_mbcmd_p1[] = { +static struct { u32 hfn, lpu; } iocreg_mbcmd_p1[] = { { HOSTFN0_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN0_MBOX0_CMD_STAT }, { HOSTFN1_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN1_MBOX0_CMD_STAT }, { HOSTFN2_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN2_MBOX0_CMD_STAT }, @@ -274,7 +274,7 @@ static void bfa_ioc_ct_map_port(struct bfa_ioc_s *ioc) { bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva; - uint32_t r32; + u32 r32; /** * For catapult, base port id on personality register and IOC type @@ -294,7 +294,7 @@ static void bfa_ioc_ct_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix) { bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva; - uint32_t r32, mode; + u32 r32, mode; r32 = bfa_reg_read(rb + FNC_PERS_REG); bfa_trc(ioc, r32); @@ -324,7 +324,7 @@ static bfa_status_t bfa_ioc_ct_pll_init(struct bfa_ioc_s *ioc) { bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva; - uint32_t pll_sclk, pll_fclk, r32; + u32 pll_sclk, pll_fclk, r32; /* * Hold semaphore so that nobody can access the chip during init. diff --git a/drivers/scsi/bfa/bfad_attr.h b/drivers/scsi/bfa/bfad_attr.h index 4d3312d..bf01020 100644 --- a/drivers/scsi/bfa/bfad_attr.h +++ b/drivers/scsi/bfa/bfad_attr.h @@ -17,9 +17,6 @@ #ifndef __BFAD_ATTR_H__ #define __BFAD_ATTR_H__ -/** - * bfad_attr.h VMware driver configuration interface module. - */ /** * FC_transport_template FC transport template @@ -52,12 +49,6 @@ bfad_im_get_starget_port_name(struct scsi_target *starget); void bfad_im_get_host_port_id(struct Scsi_Host *shost); -/** - * FC transport template entry, issue a LIP. - */ -int -bfad_im_issue_fc_host_lip(struct Scsi_Host *shost); - struct Scsi_Host* bfad_os_starget_to_shost(struct scsi_target *starget); diff --git a/drivers/scsi/bfa/bfad_drv.h b/drivers/scsi/bfa/bfad_drv.h index 8617a1a..2ccd0f2 100644 --- a/drivers/scsi/bfa/bfad_drv.h +++ b/drivers/scsi/bfa/bfad_drv.h @@ -196,11 +196,6 @@ struct bfad_s { bfa_boolean_t ipfc_enabled; union bfad_tmp_buf tmp_buf; struct fc_host_statistics link_stats; - - struct kobject *bfa_kobj; - struct kobject *ioc_kobj; - struct kobject *pport_kobj; - struct kobject *lport_kobj; }; /* @@ -286,11 +281,6 @@ void bfad_drv_uninit(struct bfad_s *bfad); void bfad_drv_log_level_set(struct bfad_s *bfad); bfa_status_t bfad_fc4_module_init(void); void bfad_fc4_module_exit(void); - -bfa_status_t bfad_os_kthread_create(struct bfad_s *bfad); -void bfad_os_kthread_stop(struct bfad_s *bfad); -void bfad_os_kthread_wakeup(struct bfad_s *bfad); -int bfad_os_kthread_should_stop(void); int bfad_worker (void *ptr); void bfad_pci_remove(struct pci_dev *pdev); diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c index fb7aefa..f9fc67a 100644 --- a/drivers/scsi/bfa/bfad_im.c +++ b/drivers/scsi/bfa/bfad_im.c @@ -509,16 +509,6 @@ void bfa_fcb_itnim_tov(struct bfad_itnim_s *itnim) } /** - * Path TOV processing begin notification -- dummy for linux - */ -void -bfa_fcb_itnim_tov_begin(struct bfad_itnim_s *itnim) -{ -} - - - -/** * Allocate a Scsi_Host for a port. */ int diff --git a/drivers/scsi/bfa/bfad_im.h b/drivers/scsi/bfa/bfad_im.h index 189a5b2..85ab2da 100644 --- a/drivers/scsi/bfa/bfad_im.h +++ b/drivers/scsi/bfa/bfad_im.h @@ -23,7 +23,6 @@ #define FCPI_NAME " fcpim" -void bfad_flags_set(struct bfad_s *bfad, u32 flags); bfa_status_t bfad_im_module_init(void); void bfad_im_module_exit(void); bfa_status_t bfad_im_probe(struct bfad_s *bfad); @@ -126,7 +125,6 @@ bfa_status_t bfad_os_thread_workq(struct bfad_s *bfad); void bfad_os_destroy_workq(struct bfad_im_s *im); void bfad_os_itnim_process(struct bfad_itnim_s *itnim_drv); void bfad_os_fc_host_init(struct bfad_im_port_s *im_port); -void bfad_os_init_work(struct bfad_im_port_s *im_port); void bfad_os_scsi_host_free(struct bfad_s *bfad, struct bfad_im_port_s *im_port); void bfad_os_ramp_up_qdepth(struct bfad_itnim_s *itnim, @@ -136,9 +134,6 @@ struct bfad_itnim_s *bfad_os_get_itnim(struct bfad_im_port_s *im_port, int id); int bfad_os_scsi_add_host(struct Scsi_Host *shost, struct bfad_im_port_s *im_port, struct bfad_s *bfad); -/* - * scsi_host_template entries - */ void bfad_im_itnim_unmap(struct bfad_im_port_s *im_port, struct bfad_itnim_s *itnim); diff --git a/drivers/scsi/bfa/fcpim.c b/drivers/scsi/bfa/fcpim.c index ef50ec2..8ae4a2cf 100644 --- a/drivers/scsi/bfa/fcpim.c +++ b/drivers/scsi/bfa/fcpim.c @@ -678,7 +678,6 @@ bfa_cb_itnim_tov_begin(void *cb_arg) struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *)cb_arg; bfa_trc(itnim->fcs, itnim->rport->pwwn); - bfa_fcb_itnim_tov_begin(itnim->itnim_drv); } /** diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_driver.h b/drivers/scsi/bfa/include/defs/bfa_defs_driver.h index 5704980..50382dd 100644 --- a/drivers/scsi/bfa/include/defs/bfa_defs_driver.h +++ b/drivers/scsi/bfa/include/defs/bfa_defs_driver.h @@ -21,6 +21,7 @@ /** * Driver statistics */ +struct bfa_driver_stats_s { u16 tm_io_abort; u16 tm_io_abort_comp; u16 tm_lun_reset; @@ -34,7 +35,7 @@ u64 output_req; u64 input_words; u64 output_words; -} bfa_driver_stats_t; +}; #endif /* __BFA_DEFS_DRIVER_H__ */ diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_im_common.h b/drivers/scsi/bfa/include/defs/bfa_defs_im_common.h deleted file mode 100644 index 9ccf53b..0000000 --- a/drivers/scsi/bfa/include/defs/bfa_defs_im_common.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. - * All rights reserved - * www.brocade.com - * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License (GPL) Version 2 as - * published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - */ - -#ifndef __BFA_DEFS_IM_COMMON_H__ -#define __BFA_DEFS_IM_COMMON_H__ - -#define BFA_ADAPTER_NAME_LEN 256 -#define BFA_ADAPTER_GUID_LEN 256 -#define RESERVED_VLAN_NAME L"PORT VLAN" -#define PASSTHRU_VLAN_NAME L"PASSTHRU VLAN" - - u64 tx_pkt_cnt; - u64 rx_pkt_cnt; - u32 duration; - u8 status; -} bfa_im_stats_t, *pbfa_im_stats_t; - -#endif /* __BFA_DEFS_IM_COMMON_H__ */ diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_im_team.h b/drivers/scsi/bfa/include/defs/bfa_defs_im_team.h deleted file mode 100644 index a486a7e..0000000 --- a/drivers/scsi/bfa/include/defs/bfa_defs_im_team.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. - * All rights reserved - * www.brocade.com - * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License (GPL) Version 2 as - * published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - */ - -#ifndef __BFA_DEFS_IM_TEAM_H__ -#define __BFA_DEFS_IM_TEAM_H__ - -#include - -#define BFA_TEAM_MAX_PORTS 8 -#define BFA_TEAM_NAME_LEN 256 -#define BFA_MAX_NUM_TEAMS 16 -#define BFA_TEAM_INVALID_DELAY -1 - - BFA_LACP_RATE_SLOW = 1, - BFA_LACP_RATE_FAST -} bfa_im_lacp_rate_t; - - BFA_TEAM_MODE_FAIL_OVER = 1, - BFA_TEAM_MODE_FAIL_BACK, - BFA_TEAM_MODE_LACP, - BFA_TEAM_MODE_NONE -} bfa_im_team_mode_t; - - BFA_XMIT_POLICY_L2 = 1, - BFA_XMIT_POLICY_L3_L4 -} bfa_im_xmit_policy_t; - - bfa_im_team_mode_t team_mode; - bfa_im_lacp_rate_t lacp_rate; - bfa_im_xmit_policy_t xmit_policy; - int delay; - wchar_t primary[BFA_ADAPTER_NAME_LEN]; - wchar_t preferred_primary[BFA_ADAPTER_NAME_LEN]; - mac_t mac; - u16 num_ports; - u16 num_vlans; - u16 vlan_list[BFA_MAX_VLANS_PER_PORT]; - wchar_t team_guid_list[BFA_TEAM_MAX_PORTS][BFA_ADAPTER_GUID_LEN]; - wchar_t ioc_name_list[BFA_TEAM_MAX_PORTS][BFA_ADAPTER_NAME_LEN]; -} bfa_im_team_attr_t; - - wchar_t team_name[BFA_TEAM_NAME_LEN]; - bfa_im_xmit_policy_t xmit_policy; - int delay; - wchar_t primary[BFA_ADAPTER_NAME_LEN]; - wchar_t preferred_primary[BFA_ADAPTER_NAME_LEN]; -} bfa_im_team_edit_t, *pbfa_im_team_edit_t; - - wchar_t team_name[BFA_TEAM_NAME_LEN]; - bfa_im_team_mode_t team_mode; - mac_t mac; -} bfa_im_team_info_t; - - bfa_im_team_info_t team_info[BFA_MAX_NUM_TEAMS]; - u16 num_teams; -} bfa_im_team_list_t, *pbfa_im_team_list_t; - -#endif /* __BFA_DEFS_IM_TEAM_H__ */ diff --git a/drivers/scsi/bfa/include/fcb/bfa_fcb_fcpim.h b/drivers/scsi/bfa/include/fcb/bfa_fcb_fcpim.h index a6c70ae..52585d3 100644 --- a/drivers/scsi/bfa/include/fcb/bfa_fcb_fcpim.h +++ b/drivers/scsi/bfa/include/fcb/bfa_fcb_fcpim.h @@ -70,7 +70,6 @@ void bfa_fcb_itnim_online(struct bfad_itnim_s *itnim_drv); */ void bfa_fcb_itnim_offline(struct bfad_itnim_s *itnim_drv); -void bfa_fcb_itnim_tov_begin(struct bfad_itnim_s *itnim_drv); void bfa_fcb_itnim_tov(struct bfad_itnim_s *itnim_drv); #endif /* __BFAD_FCB_FCPIM_H__ */ diff --git a/drivers/scsi/bfa/include/protocol/pcifw.h b/drivers/scsi/bfa/include/protocol/pcifw.h deleted file mode 100644 index 6830dc3..0000000 --- a/drivers/scsi/bfa/include/protocol/pcifw.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. - * All rights reserved - * www.brocade.com - * - * Linux driver for Brocade Fibre Channel Host Bus Adapter. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License (GPL) Version 2 as - * published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - */ - -/** - * pcifw.h PCI FW related headers - */ - -#ifndef __PCIFW_H__ -#define __PCIFW_H__ - -#pragma pack(1) - -struct pnp_hdr_s{ - u32 signature; /* "$PnP" */ - u8 rev; /* Struct revision */ - u8 len; /* Header structure len in multiples - * of 16 bytes */ - u16 off; /* Offset to next header 00 if none */ - u8 rsvd; /* Reserved byte */ - u8 cksum; /* 8-bit checksum for this header */ - u32 pnp_dev_id; /* PnP Device Id */ - u16 mfstr; /* Pointer to manufacturer string */ - u16 prstr; /* Pointer to product string */ - u8 devtype[3]; /* Device Type Code */ - u8 devind; /* Device Indicator */ - u16 bcventr; /* Bootstrap entry vector */ - u16 rsvd2; /* Reserved */ - u16 sriv; /* Static resource information vector */ -}; - -struct pci_3_0_ds_s{ - u32 sig; /* Signature "PCIR" */ - u16 vendid; /* Vendor ID */ - u16 devid; /* Device ID */ - u16 devlistoff; /* Device List Offset */ - u16 len; /* PCI Data Structure Length */ - u8 rev; /* PCI Data Structure Revision */ - u8 clcode[3]; /* Class Code */ - u16 imglen; /* Code image length in multiples of - * 512 bytes */ - u16 coderev; /* Revision level of code/data */ - u8 codetype; /* Code type 0x00 - BIOS */ - u8 indr; /* Last image indicator */ - u16 mrtimglen; /* Max Run Time Image Length */ - u16 cuoff; /* Config Utility Code Header Offset */ - u16 dmtfclp; /* DMTF CLP entry point offset */ -}; - -struct pci_optrom_hdr_s{ - u16 sig; /* Signature 0x55AA */ - u8 len; /* Option ROM length in units of 512 bytes */ - u8 inivec[3]; /* Initialization vector */ - u8 rsvd[16]; /* Reserved field */ - u16 verptr; /* Pointer to version string - private */ - u16 pcids; /* Pointer to PCI data structure */ - u16 pnphdr; /* Pointer to PnP expansion header */ -}; - -#pragma pack() - -#endif -- cgit v0.10.2 From d55f88f0275e4b21435957d3d354a79bb9edeec7 Mon Sep 17 00:00:00 2001 From: Krishna Gudipati Date: Fri, 5 Mar 2010 19:38:52 -0800 Subject: [SCSI] bfa: Update the driver version to 2.1.2.1. Upgrade the upstream driver from 2.0.0.0 to 2.1.2.1. Signed-off-by: Krishna Gudipati Signed-off-by: James Bottomley diff --git a/drivers/scsi/bfa/bfad_drv.h b/drivers/scsi/bfa/bfad_drv.h index 2ccd0f2..107848c 100644 --- a/drivers/scsi/bfa/bfad_drv.h +++ b/drivers/scsi/bfa/bfad_drv.h @@ -46,7 +46,7 @@ #ifdef BFA_DRIVER_VERSION #define BFAD_DRIVER_VERSION BFA_DRIVER_VERSION #else -#define BFAD_DRIVER_VERSION "2.0.0.0" +#define BFAD_DRIVER_VERSION "2.1.2.1" #endif -- cgit v0.10.2 From 1dace8c801ac531022bd31a7316a6b4351837617 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Thu, 4 Mar 2010 16:10:14 -0500 Subject: vhost: fix error path in vhost_net_set_backend An error could cause vhost_net_set_backend to exit without unlocking vq->mutex. Fix this. Signed-off-by: Jeff Dike Signed-off-by: Michael S. Tsirkin diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index ad37da2..fcafb6b 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c @@ -508,12 +508,12 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd) /* Verify that ring has been setup correctly. */ if (!vhost_vq_access_ok(vq)) { r = -EFAULT; - goto err; + goto err_vq; } sock = get_socket(fd); if (IS_ERR(sock)) { r = PTR_ERR(sock); - goto err; + goto err_vq; } /* start polling new socket */ @@ -524,12 +524,14 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd) vhost_net_disable_vq(n, vq); rcu_assign_pointer(vq->private_data, sock); vhost_net_enable_vq(n, vq); - mutex_unlock(&vq->mutex); done: if (oldsock) { vhost_net_flush_vq(n, index); fput(oldsock->file); } + +err_vq: + mutex_unlock(&vq->mutex); err: mutex_unlock(&n->dev.mutex); return r; -- cgit v0.10.2 From b96b894c518bc7399e6b86b635b5e8cd7356a8e9 Mon Sep 17 00:00:00 2001 From: "Figo.zhang" Date: Fri, 5 Mar 2010 16:36:02 +0000 Subject: fix a race in ks8695_poll fix a race at the end of NAPI processing in ks8695_poll() function. Signed-off-by:Figo.zhang Signed-off-by: David S. Miller diff --git a/drivers/net/arm/ks8695net.c b/drivers/net/arm/ks8695net.c index 8ca6391..a1d4188 100644 --- a/drivers/net/arm/ks8695net.c +++ b/drivers/net/arm/ks8695net.c @@ -575,9 +575,9 @@ static int ks8695_poll(struct napi_struct *napi, int budget) if (work_done < budget) { unsigned long flags; spin_lock_irqsave(&ksp->rx_lock, flags); + __napi_complete(napi); /*enable rx interrupt*/ writel(isr | mask_bit, KS8695_IRQ_VA + KS8695_INTEN); - __napi_complete(napi); spin_unlock_irqrestore(&ksp->rx_lock, flags); } return work_done; -- cgit v0.10.2 From 02a780c014c40973cbe71d04cec7a24e6629995f Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 6 Mar 2010 01:14:09 +0000 Subject: bridge: cleanup: remove unneed check We dereference "port" on the lines immediately before and immediately after the test so port should hopefully never be null here. Signed-off-by: Dan Carpenter Signed-off-by: Herbert Xu Signed-off-by: David S. Miller diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 2559fb5..8b25887 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -627,8 +627,8 @@ static void br_multicast_port_query_expired(unsigned long data) struct net_bridge *br = port->br; spin_lock(&br->multicast_lock); - if (port && (port->state == BR_STATE_DISABLED || - port->state == BR_STATE_BLOCKING)) + if (port->state == BR_STATE_DISABLED || + port->state == BR_STATE_BLOCKING) goto out; if (port->multicast_startup_queries_sent < -- cgit v0.10.2 From ea3fb371b2a391958670f2a65e1203f7dba61671 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 6 Mar 2010 01:11:38 +0000 Subject: ems_usb: cleanup: remove uneeded check "skb" is alway non-null here, but even if it were null the check isn't needed because dev_kfree_skb() can handle it. This eliminates a smatch warning about dereferencing a variable before checking that it is non-null. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c index 11c8784..3345109 100644 --- a/drivers/net/can/usb/ems_usb.c +++ b/drivers/net/can/usb/ems_usb.c @@ -876,9 +876,7 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne return NETDEV_TX_OK; nomem: - if (skb) - dev_kfree_skb(skb); - + dev_kfree_skb(skb); stats->tx_dropped++; return NETDEV_TX_OK; -- cgit v0.10.2 From 72150e9b7fec217fbd646a29ea2f65a3d4d55ea9 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 6 Mar 2010 01:04:45 +0000 Subject: sock.c: potential null dereference We test that "prot->rsk_prot" is non-null right before we dereference it on this line. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller diff --git a/net/core/sock.c b/net/core/sock.c index 61a65a2..c5812bb 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -2288,7 +2288,8 @@ out_free_request_sock_slab: prot->rsk_prot->slab = NULL; } out_free_request_sock_slab_name: - kfree(prot->rsk_prot->slab_name); + if (prot->rsk_prot) + kfree(prot->rsk_prot->slab_name); out_free_sock_slab: kmem_cache_destroy(prot->slab); prot->slab = NULL; -- cgit v0.10.2 From 0e2b807234c42fab59f98ec913db30dfda0e63a7 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sun, 7 Mar 2010 02:35:42 +0000 Subject: irda-usb: add error handling and fix leak If the call to kcalloc() fails then we should return -ENOMEM. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c index e8e33bb..2c9b3af 100644 --- a/drivers/net/irda/irda-usb.c +++ b/drivers/net/irda/irda-usb.c @@ -1651,6 +1651,8 @@ static int irda_usb_probe(struct usb_interface *intf, self->rx_urb = kcalloc(self->max_rx_urb, sizeof(struct urb *), GFP_KERNEL); + if (!self->rx_urb) + goto err_free_net; for (i = 0; i < self->max_rx_urb; i++) { self->rx_urb[i] = usb_alloc_urb(0, GFP_KERNEL); @@ -1783,6 +1785,8 @@ err_out_2: err_out_1: for (i = 0; i < self->max_rx_urb; i++) usb_free_urb(self->rx_urb[i]); + kfree(self->rx_urb); +err_free_net: free_netdev(net); err_out: return ret; -- cgit v0.10.2 From e7111eac8ebda724d1e4d9e6aaf4569744a584d5 Mon Sep 17 00:00:00 2001 From: Petko Manolov Date: Sun, 7 Mar 2010 06:10:01 +0000 Subject: another pegasus usb net device This one removes trailing whitespace in pegasus.h and more importantly adds new Pegasus compatible device. Signed-off-by: Julian Brown Signed-off-by: Petko Manolov Signed-off-by: David S. Miller diff --git a/drivers/net/usb/pegasus.h b/drivers/net/usb/pegasus.h index 5d02f02..b90d876 100644 --- a/drivers/net/usb/pegasus.h +++ b/drivers/net/usb/pegasus.h @@ -177,7 +177,7 @@ PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x400c, PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0xabc1, DEFAULT_GPIO_RESET ) PEGASUS_DEV( "USB 10/100 Fast Ethernet", VENDOR_ABOCOM, 0x200c, - DEFAULT_GPIO_RESET | PEGASUS_II ) + DEFAULT_GPIO_RESET | PEGASUS_II ) PEGASUS_DEV( "Accton USB 10/100 Ethernet Adapter", VENDOR_ACCTON, 0x1046, DEFAULT_GPIO_RESET ) PEGASUS_DEV( "SpeedStream USB 10/100 Ethernet", VENDOR_ACCTON, 0x5046, @@ -208,6 +208,8 @@ PEGASUS_DEV( "Allied Telesyn Int. AT-USB100", VENDOR_ALLIEDTEL, 0xb100, */ PEGASUS_DEV_CLASS( "Belkin F5D5050 USB Ethernet", VENDOR_BELKIN, 0x0121, 0x00, DEFAULT_GPIO_RESET | PEGASUS_II ) +PEGASUS_DEV( "Belkin F5U122 10/100 USB Ethernet", VENDOR_BELKIN, 0x0122, + DEFAULT_GPIO_RESET | PEGASUS_II ) PEGASUS_DEV( "Billionton USB-100", VENDOR_BILLIONTON, 0x0986, DEFAULT_GPIO_RESET ) PEGASUS_DEV( "Billionton USBLP-100", VENDOR_BILLIONTON, 0x0987, @@ -249,7 +251,7 @@ PEGASUS_DEV( "GIGABYTE GN-BR402W Wireless Router", VENDOR_GIGABYTE, 0x8002, PEGASUS_DEV( "Hawking UF100 10/100 Ethernet", VENDOR_HAWKING, 0x400c, DEFAULT_GPIO_RESET | PEGASUS_II ) PEGASUS_DEV( "HP hn210c Ethernet USB", VENDOR_HP, 0x811c, - DEFAULT_GPIO_RESET | PEGASUS_II ) + DEFAULT_GPIO_RESET | PEGASUS_II ) PEGASUS_DEV( "IO DATA USB ET/TX", VENDOR_IODATA, 0x0904, DEFAULT_GPIO_RESET ) PEGASUS_DEV( "IO DATA USB ET/TX-S", VENDOR_IODATA, 0x0913, -- cgit v0.10.2 From 8d15d3864a733476931f7e0b3d82824cddc766c2 Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Sat, 6 Mar 2010 08:31:50 +0000 Subject: MAINTAINER: Correct CAN Maintainer responsibilities and paths Update the CAN Maintainer responsibilities and add source paths. Additional the SocketCAN core ML is not subscribers-only anymore. Signed-off-by: Oliver Hartkopp Acked-by: Wolfgang Grandegger Signed-off-by: David S. Miller diff --git a/MAINTAINERS b/MAINTAINERS index dad4f57..66418dd 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1372,20 +1372,28 @@ F: arch/x86/include/asm/calgary.h F: arch/x86/include/asm/tce.h CAN NETWORK LAYER -M: Urs Thuermann +M: Oliver Hartkopp M: Oliver Hartkopp -L: socketcan-core@lists.berlios.de (subscribers-only) +M: Urs Thuermann +L: socketcan-core@lists.berlios.de W: http://developer.berlios.de/projects/socketcan/ S: Maintained -F: drivers/net/can/ -F: include/linux/can/ +F: net/can/ F: include/linux/can.h +F: include/linux/can/core.h +F: include/linux/can/bcm.h +F: include/linux/can/raw.h CAN NETWORK DRIVERS M: Wolfgang Grandegger -L: socketcan-core@lists.berlios.de (subscribers-only) +L: socketcan-core@lists.berlios.de W: http://developer.berlios.de/projects/socketcan/ S: Maintained +F: drivers/net/can/ +F: include/linux/can/dev.h +F: include/linux/can/error.h +F: include/linux/can/netlink.h +F: include/linux/can/platform/ CELL BROADBAND ENGINE ARCHITECTURE M: Arnd Bergmann -- cgit v0.10.2 From 30765d0502905a9248e5de72fc7ac83c23422861 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Sun, 7 Mar 2010 00:55:26 +0000 Subject: cpmac: fix the receiving of 802.1q frames Despite what the comment above CPMAC_SKB_SIZE says, the hardware also needs to account for the FCS length in a received frame. This patch fix the receiving of 802.1q frames which have 4 more bytes. While at it unhardcode the definition and use the one from if_vlan.h. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c index 9d48942..55ee055 100644 --- a/drivers/net/cpmac.c +++ b/drivers/net/cpmac.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -56,8 +57,8 @@ MODULE_PARM_DESC(debug_level, "Number of NETIF_MSG bits to enable"); MODULE_PARM_DESC(dumb_switch, "Assume switch is not connected to MDIO bus"); #define CPMAC_VERSION "0.5.1" -/* frame size + 802.1q tag */ -#define CPMAC_SKB_SIZE (ETH_FRAME_LEN + 4) +/* frame size + 802.1q tag + FCS size */ +#define CPMAC_SKB_SIZE (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN) #define CPMAC_QUEUES 8 /* Ethernet registers */ -- cgit v0.10.2 From 9fba1c31f4f3f9f860a4afee0b409cde27d06741 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Sun, 7 Mar 2010 00:55:47 +0000 Subject: cpmac: fallback to switch mode if no PHY chip found If we were unable to detect a PHY on any of the MDIO bus id we tried instead of bailing out with -ENODEV, assume the MAC is connected to a switch and use MDIO bus 0. This unbreaks quite a lot of devices out there whose switch cannot be detected. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c index 55ee055..baeb5ba 100644 --- a/drivers/net/cpmac.c +++ b/drivers/net/cpmac.c @@ -1137,8 +1137,9 @@ static int __devinit cpmac_probe(struct platform_device *pdev) } if (phy_id == PHY_MAX_ADDR) { - dev_err(&pdev->dev, "no PHY present\n"); - return -ENODEV; + dev_err(&pdev->dev, "no PHY present, falling back to switch on MDIO bus 0\n"); + strncpy(mdio_bus_id, "0", MII_BUS_ID_SIZE); /* fixed phys bus */ + phy_id = pdev->id; } dev = alloc_etherdev_mq(sizeof(*priv), CPMAC_QUEUES); -- cgit v0.10.2 From 25dc27d17dc868aae78fd03bef3113cf586b12e5 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Sun, 7 Mar 2010 00:55:50 +0000 Subject: cpmac: bump version to 0.5.2 Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c index baeb5ba..60777fd 100644 --- a/drivers/net/cpmac.c +++ b/drivers/net/cpmac.c @@ -56,7 +56,7 @@ module_param(dumb_switch, int, 0444); MODULE_PARM_DESC(debug_level, "Number of NETIF_MSG bits to enable"); MODULE_PARM_DESC(dumb_switch, "Assume switch is not connected to MDIO bus"); -#define CPMAC_VERSION "0.5.1" +#define CPMAC_VERSION "0.5.2" /* frame size + 802.1q tag + FCS size */ #define CPMAC_SKB_SIZE (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN) #define CPMAC_QUEUES 8 -- cgit v0.10.2 From 0c9a2ac1f8a2e55b3382dfc27256878a58ea49e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?YOSHIFUJI=20Hideaki=20/=20=E5=90=89=E8=97=A4=E8=8B=B1?= =?UTF-8?q?=E6=98=8E?= Date: Sun, 7 Mar 2010 00:14:44 +0000 Subject: ipv6: Optmize translation between IPV6_PREFER_SRC_xxx and RT6_LOOKUP_F_xxx. IPV6_PREFER_SRC_xxx definitions: | #define IPV6_PREFER_SRC_TMP 0x0001 | #define IPV6_PREFER_SRC_PUBLIC 0x0002 | #define IPV6_PREFER_SRC_COA 0x0004 RT6_LOOKUP_F_xxx definitions: | #define RT6_LOOKUP_F_SRCPREF_TMP 0x00000008 | #define RT6_LOOKUP_F_SRCPREF_PUBLIC 0x00000010 | #define RT6_LOOKUP_F_SRCPREF_COA 0x00000020 So, we can translate between these two groups by shift operation instead of multiple 'if's. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: David S. Miller diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index 4a808de..68f6783 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h @@ -37,6 +37,24 @@ struct route_info { #define RT6_LOOKUP_F_SRCPREF_PUBLIC 0x00000010 #define RT6_LOOKUP_F_SRCPREF_COA 0x00000020 +/* + * rt6_srcprefs2flags() and rt6_flags2srcprefs() translate + * between IPV6_ADDR_PREFERENCES socket option values + * IPV6_PREFER_SRC_TMP = 0x1 + * IPV6_PREFER_SRC_PUBLIC = 0x2 + * IPV6_PREFER_SRC_COA = 0x4 + * and above RT6_LOOKUP_F_SRCPREF_xxx flags. + */ +static inline int rt6_srcprefs2flags(unsigned int srcprefs) +{ + /* No need to bitmask because srcprefs have only 3 bits. */ + return srcprefs << 3; +} + +static inline unsigned int rt6_flags2srcprefs(int flags) +{ + return (flags >> 3) & 7; +} extern void ip6_route_input(struct sk_buff *skb); diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index 551882b..5e463c43 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c @@ -84,18 +84,11 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp, if ((rule->flags & FIB_RULE_FIND_SADDR) && r->src.plen && !(flags & RT6_LOOKUP_F_HAS_SADDR)) { struct in6_addr saddr; - unsigned int srcprefs = 0; - - if (flags & RT6_LOOKUP_F_SRCPREF_TMP) - srcprefs |= IPV6_PREFER_SRC_TMP; - if (flags & RT6_LOOKUP_F_SRCPREF_PUBLIC) - srcprefs |= IPV6_PREFER_SRC_PUBLIC; - if (flags & RT6_LOOKUP_F_SRCPREF_COA) - srcprefs |= IPV6_PREFER_SRC_COA; if (ipv6_dev_get_saddr(net, ip6_dst_idev(&rt->u.dst)->dev, - &flp->fl6_dst, srcprefs, + &flp->fl6_dst, + rt6_flags2srcprefs(flags), &saddr)) goto again; if (!ipv6_prefix_equal(&saddr, &r->src.addr, diff --git a/net/ipv6/route.c b/net/ipv6/route.c index b08879e..52cd3ef 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -819,15 +819,8 @@ struct dst_entry * ip6_route_output(struct net *net, struct sock *sk, if (!ipv6_addr_any(&fl->fl6_src)) flags |= RT6_LOOKUP_F_HAS_SADDR; - else if (sk) { - unsigned int prefs = inet6_sk(sk)->srcprefs; - if (prefs & IPV6_PREFER_SRC_TMP) - flags |= RT6_LOOKUP_F_SRCPREF_TMP; - if (prefs & IPV6_PREFER_SRC_PUBLIC) - flags |= RT6_LOOKUP_F_SRCPREF_PUBLIC; - if (prefs & IPV6_PREFER_SRC_COA) - flags |= RT6_LOOKUP_F_SRCPREF_COA; - } + else if (sk) + flags |= rt6_srcprefs2flags(inet6_sk(sk)->srcprefs); return fib6_rule_lookup(net, fl, flags, ip6_pol_route_output); } -- cgit v0.10.2 From 49f5fcfd4ac3df24aa66520e1c5f37db5dfa8c10 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Fri, 5 Mar 2010 21:07:39 +0000 Subject: bridge: Use RCU list primitive in __br_mdb_ip_get As Paul McKenney correctly pointed out, __br_mdb_ip_get needs to use the RCU list walking primitive in order to work correctly on platforms where data-dependency ordering is not guaranteed. Reported-by: Paul E. McKenney Signed-off-by: Herbert Xu Signed-off-by: David S. Miller diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 8b25887..a1ffe15 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -38,7 +38,7 @@ static struct net_bridge_mdb_entry *__br_mdb_ip_get( struct net_bridge_mdb_entry *mp; struct hlist_node *p; - hlist_for_each_entry(mp, p, &mdb->mhash[hash], hlist[mdb->ver]) { + hlist_for_each_entry_rcu(mp, p, &mdb->mhash[hash], hlist[mdb->ver]) { if (dst == mp->addr) return mp; } -- cgit v0.10.2 From 10cc2b50eb4b01ca4dc014af2094d28b4ebe20d7 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Fri, 5 Mar 2010 21:03:35 +0000 Subject: bridge: Fix RCU race in br_multicast_stop Thanks to Paul McKenny for pointing out that it is incorrect to use synchronize_rcu_bh to ensure that pending callbacks have completed. Instead we should use rcu_barrier_bh. Reported-by: Paul E. McKenney Signed-off-by: Herbert Xu Signed-off-by: David S. Miller diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index a1ffe15..12ce1ea 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -1135,7 +1135,7 @@ void br_multicast_stop(struct net_bridge *br) if (mdb->old) { spin_unlock_bh(&br->multicast_lock); - synchronize_rcu_bh(); + rcu_barrier_bh(); spin_lock_bh(&br->multicast_lock); WARN_ON(mdb->old); } -- cgit v0.10.2 From a8941dad1f12b4e8a87a517ed27f29d0209c817c Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 8 Mar 2010 13:33:17 +0900 Subject: sh: Support CPU affinity masks for INTC controllers. This hooks up the ->set_affinity() for the INTC controllers, which can be done as just a simple copy of the cpumask. The enable/disable paths already handle SMP register strides, so we just test the affinity mask in these paths to determine which strides to skip over. The early enable/disable path happens prior to the IRQs being registered, so we have no affinity mask established at that point, in which case we just default to CPU_MASK_ALL. This is left as it is to permit the force enable/disable code to retain existing semantics. Signed-off-by: Paul Mundt diff --git a/drivers/sh/intc.c b/drivers/sh/intc.c index 3a5a17d..b8983fe 100644 --- a/drivers/sh/intc.c +++ b/drivers/sh/intc.c @@ -2,7 +2,7 @@ * Shared interrupt handling code for IPR and INTC2 types of IRQs. * * Copyright (C) 2007, 2008 Magnus Damm - * Copyright (C) 2009 Paul Mundt + * Copyright (C) 2009, 2010 Paul Mundt * * Based on intc2.c and ipr.c * @@ -26,6 +26,7 @@ #include #include #include +#include #define _INTC_MK(fn, mode, addr_e, addr_d, width, shift) \ ((shift) | ((width) << 5) | ((fn) << 9) | ((mode) << 13) | \ @@ -234,6 +235,10 @@ static inline void _intc_enable(unsigned int irq, unsigned long handle) unsigned int cpu; for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_E(handle)); cpu++) { +#ifdef CONFIG_SMP + if (!cpumask_test_cpu(cpu, irq_to_desc(irq)->affinity)) + continue; +#endif addr = INTC_REG(d, _INTC_ADDR_E(handle), cpu); intc_enable_fns[_INTC_MODE(handle)](addr, handle, intc_reg_fns\ [_INTC_FN(handle)], irq); @@ -253,6 +258,10 @@ static void intc_disable(unsigned int irq) unsigned int cpu; for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_D(handle)); cpu++) { +#ifdef CONFIG_SMP + if (!cpumask_test_cpu(cpu, irq_to_desc(irq)->affinity)) + continue; +#endif addr = INTC_REG(d, _INTC_ADDR_D(handle), cpu); intc_disable_fns[_INTC_MODE(handle)](addr, handle,intc_reg_fns\ [_INTC_FN(handle)], irq); @@ -301,6 +310,23 @@ static int intc_set_wake(unsigned int irq, unsigned int on) return 0; /* allow wakeup, but setup hardware in intc_suspend() */ } +#ifdef CONFIG_SMP +/* + * This is held with the irq desc lock held, so we don't require any + * additional locking here at the intc desc level. The affinity mask is + * later tested in the enable/disable paths. + */ +static int intc_set_affinity(unsigned int irq, const struct cpumask *cpumask) +{ + if (!cpumask_intersects(cpumask, cpu_online_mask)) + return -1; + + cpumask_copy(irq_to_desc(irq)->affinity, cpumask); + + return 0; +} +#endif + static void intc_mask_ack(unsigned int irq) { struct intc_desc_int *d = get_intc_desc(irq); @@ -843,6 +869,9 @@ void __init register_intc_controller(struct intc_desc *desc) d->chip.shutdown = intc_disable; d->chip.set_type = intc_set_sense; d->chip.set_wake = intc_set_wake; +#ifdef CONFIG_SMP + d->chip.set_affinity = intc_set_affinity; +#endif if (hw->ack_regs) { for (i = 0; i < hw->nr_ack_regs; i++) -- cgit v0.10.2 From 8bf8c376ab2eefaf0386f4e003e720e1434fa43d Mon Sep 17 00:00:00 2001 From: Dmitry Monakhov Date: Wed, 3 Mar 2010 06:28:06 +0300 Subject: blkdev: fix merge_bvec_fn return value checks v2 merge_bvec_fn() returns bvec->bv_len on success. So we have to check against this value. But in case of fs_optimization merge we compare with wrong value. This patch must be included in b428cd6da7e6559aca69aa2e3a526037d3f20403 But accidentally i've forgot to add this in the initial patch. To make things straight let's replace all such checks. In fact this makes code easy to understand. Signed-off-by: Dmitry Monakhov Signed-off-by: Jens Axboe diff --git a/fs/bio.c b/fs/bio.c index dc17afd..d89e019 100644 --- a/fs/bio.c +++ b/fs/bio.c @@ -555,7 +555,7 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page .bi_rw = bio->bi_rw, }; - if (q->merge_bvec_fn(q, &bvm, prev) < len) { + if (q->merge_bvec_fn(q, &bvm, prev) < prev->bv_len) { prev->bv_len -= len; return 0; } @@ -608,7 +608,7 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page * merge_bvec_fn() returns number of bytes it can accept * at this offset */ - if (q->merge_bvec_fn(q, &bvm, bvec) < len) { + if (q->merge_bvec_fn(q, &bvm, bvec) < bvec->bv_len) { bvec->bv_page = NULL; bvec->bv_len = 0; bvec->bv_offset = 0; -- cgit v0.10.2 From c2282adbdea3548ae0271c1b1b2deec5f56ad224 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Mon, 8 Mar 2010 09:11:07 +0100 Subject: Documentation: fix block/biodoc.txt dma mapping description - It looks incorrect to use blk_rq_map_sg with pci_map_page here about DMA mappings. dma_map_sg? - better to use dma_map_page instead of pci_map_page. http://marc.info/?l=linux-kernel&m=126596737604808&w=2 Signed-off-by: FUJITA Tomonori Signed-off-by: Jens Axboe diff --git a/Documentation/block/biodoc.txt b/Documentation/block/biodoc.txt index 6fab97e..508b5b2 100644 --- a/Documentation/block/biodoc.txt +++ b/Documentation/block/biodoc.txt @@ -1162,8 +1162,8 @@ where a driver received a request ala this before: As mentioned, there is no virtual mapping of a bio. For DMA, this is not a problem as the driver probably never will need a virtual mapping. -Instead it needs a bus mapping (pci_map_page for a single segment or -use blk_rq_map_sg for scatter gather) to be able to ship it to the driver. For +Instead it needs a bus mapping (dma_map_page for a single segment or +use dma_map_sg for scatter gather) to be able to ship it to the driver. For PIO drivers (or drivers that need to revert to PIO transfer once in a while (IDE for example)), where the CPU is doing the actual data transfer a virtual mapping is needed. If the driver supports highmem I/O, -- cgit v0.10.2 From 50ae0aa8f55813b2cc5e5b7f589f328b8fcd45ec Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 8 Mar 2010 12:09:59 +0100 Subject: ALSA: hda - Fix wrong model range check for ALC268 Fix a wrong value passed to snd_hda_check_board_codec_sid_config() as the upper-limit in parse_alc268(), so that any wrong value can't be passed. So far, no bogus value was set in the quirk entries, so this won't give any behavioral changes. Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 5d2fbb8..dcd8a2c 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -13201,7 +13201,7 @@ static int patch_alc268(struct hda_codec *codec) if (board_config < 0 || board_config >= ALC268_MODEL_LAST) board_config = snd_hda_check_board_codec_sid_config(codec, - ALC882_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl); + ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl); if (board_config < 0 || board_config >= ALC268_MODEL_LAST) { printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", -- cgit v0.10.2 From 5311114d4867113c00f78829d4ce14be458ec925 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 8 Mar 2010 12:13:07 +0100 Subject: ALSA: hda - Fix input source elements of secondary ADCs on Realtek Since alc_auto_create_input_ctls() doesn't set the elements for the secondary ADCs, "Input Source" elemtns for these also get empty, resulting in buggy outputs of alsactl like: control.14 { comment.access 'read write' comment.type ENUMERATED comment.count 1 iface MIXER name 'Input Source' index 1 value 0 } This patch fixes alc_mux_enum_*() (and others) to fall back to the first entry if the secondary input mux is empty. Signed-off-by: Takashi Iwai Cc: diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index dcd8a2c..3a83719 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -411,6 +411,8 @@ static int alc_mux_enum_info(struct snd_kcontrol *kcontrol, unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id); if (mux_idx >= spec->num_mux_defs) mux_idx = 0; + if (!spec->input_mux[mux_idx].num_items && mux_idx > 0) + mux_idx = 0; return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo); } @@ -439,6 +441,8 @@ static int alc_mux_enum_put(struct snd_kcontrol *kcontrol, mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; imux = &spec->input_mux[mux_idx]; + if (!imux->num_items && mux_idx > 0) + imux = &spec->input_mux[0]; type = get_wcaps_type(get_wcaps(codec, nid)); if (type == AC_WID_AUD_MIX) { @@ -10105,6 +10109,8 @@ static void alc882_auto_init_input_src(struct hda_codec *codec) continue; mux_idx = c >= spec->num_mux_defs ? 0 : c; imux = &spec->input_mux[mux_idx]; + if (!imux->num_items && mux_idx > 0) + imux = &spec->input_mux[0]; for (idx = 0; idx < conns; idx++) { /* if the current connection is the selected one, * unmute it as default - otherwise mute it -- cgit v0.10.2 From 40d1f0048289b1baed859baee06878417fae540e Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 8 Mar 2010 21:03:21 +0900 Subject: sh: Fix up uncached offset for legacy 29-bit mode. The uncached_start was being set up properly for 32-bit but managed to break 29-bit in the process, fix it up. Signed-off-by: Paul Mundt diff --git a/arch/sh/mm/uncached.c b/arch/sh/mm/uncached.c index cf20a5c..2ef57ef 100644 --- a/arch/sh/mm/uncached.c +++ b/arch/sh/mm/uncached.c @@ -1,6 +1,7 @@ #include #include #include +#include /* * This is the offset of the uncached section from its cached alias. @@ -23,7 +24,11 @@ int virt_addr_uncached(unsigned long kaddr) void __init uncached_init(void) { +#ifdef CONFIG_29BIT + uncached_start = P2SEG; +#else uncached_start = memory_end; +#endif uncached_end = uncached_start + uncached_size; } -- cgit v0.10.2 From 8b408fe4f853dcfa18d133aa4cf1d7546b4c3870 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Mon, 8 Mar 2010 14:20:07 +0100 Subject: x86/amd-iommu: Use helper function to destroy domain In the amd_iommu_domain_destroy the protection_domain_free function is partly reimplemented. The 'partly' is the bug here because the domain is not deleted from the domain list. This results in use-after-free errors and data-corruption. Fix it by just using protection_domain_free instead. Cc: stable@kernel.org Signed-off-by: Joerg Roedel diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index 0c04254..b06f29e 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c @@ -2380,9 +2380,7 @@ static void amd_iommu_domain_destroy(struct iommu_domain *dom) free_pagetable(domain); - domain_id_free(domain->id); - - kfree(domain); + protection_domain_free(domain); dom->priv = NULL; } -- cgit v0.10.2 From 0d9dc7c8b9b7fa0f53647423b41056ee1beed735 Mon Sep 17 00:00:00 2001 From: Gal Rosen Date: Thu, 21 Jan 2010 10:15:32 +0200 Subject: [SCSI] scsi_transport_fc: Fix synchronization issue while deleting vport The issue occur while deleting 60 virtual ports through the sys interface /sys/class/fc_vports/vport-X/vport_delete. It happen while in a mistake each request sent twice for the same vport. This interface is asynchronous, entering the delete request into a work queue, allowing more than one request to enter to the delete work queue. The result is a NULL pointer. The first request already delete the vport, while the second request got a pointer to the vport before the device destroyed. Re-create vport later cause system freeze. Solution: Check vport flags before entering the request to the work queue. [jejb: fixed int<->long problem on spinlock flags variable] Signed-off-by: Gal Rosen Acked-by: James Smart Cc: Stable Tree Signed-off-by: James Bottomley diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index 79660ee..1d5b721 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -1232,6 +1232,15 @@ store_fc_vport_delete(struct device *dev, struct device_attribute *attr, { struct fc_vport *vport = transport_class_to_vport(dev); struct Scsi_Host *shost = vport_to_shost(vport); + unsigned long flags; + + spin_lock_irqsave(shost->host_lock, flags); + if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING)) { + spin_unlock_irqrestore(shost->host_lock, flags); + return -EBUSY; + } + vport->flags |= FC_VPORT_DELETING; + spin_unlock_irqrestore(shost->host_lock, flags); fc_queue_work(shost, &vport->vport_delete_work); return count; @@ -1821,6 +1830,9 @@ store_fc_host_vport_delete(struct device *dev, struct device_attribute *attr, list_for_each_entry(vport, &fc_host->vports, peers) { if ((vport->channel == 0) && (vport->port_name == wwpn) && (vport->node_name == wwnn)) { + if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING)) + break; + vport->flags |= FC_VPORT_DELETING; match = 1; break; } @@ -3370,18 +3382,6 @@ fc_vport_terminate(struct fc_vport *vport) unsigned long flags; int stat; - spin_lock_irqsave(shost->host_lock, flags); - if (vport->flags & FC_VPORT_CREATING) { - spin_unlock_irqrestore(shost->host_lock, flags); - return -EBUSY; - } - if (vport->flags & (FC_VPORT_DEL)) { - spin_unlock_irqrestore(shost->host_lock, flags); - return -EALREADY; - } - vport->flags |= FC_VPORT_DELETING; - spin_unlock_irqrestore(shost->host_lock, flags); - if (i->f->vport_delete) stat = i->f->vport_delete(vport); else -- cgit v0.10.2 From 89c0ac7cab2440a771ba1e2ab953186bc9c29786 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 8 Mar 2010 09:32:42 -0800 Subject: sound: fix opti92x-ad1848 build Fix 'else' placement in ifdef block so that build succeeds: sound/isa/opti9xx/opti92x-ad1848.c:221: error: 'else' without a previous 'if' Signed-off-by: Randy Dunlap Signed-off-by: Takashi Iwai diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index becd90d..4d2d040 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c @@ -217,8 +217,9 @@ static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip, if (isapnp && chip->mc_base) /* PnP resource gives the least 10 bits */ chip->mc_base |= 0xc00; + else #endif /* CONFIG_PNP */ - else { + { chip->mc_base = 0xf8c; chip->mc_base_size = opti9xx_mc_size[hardware]; } -- cgit v0.10.2 From 4045635318538d3ddd2007720412fdc4b08f6a62 Mon Sep 17 00:00:00 2001 From: Zhu Yi Date: Sun, 7 Mar 2010 16:21:39 +0000 Subject: net: add __must_check to sk_add_backlog Add the "__must_check" tag to sk_add_backlog() so that any failure to check and drop packets will be warned about. Signed-off-by: Zhu Yi Signed-off-by: David S. Miller diff --git a/include/net/sock.h b/include/net/sock.h index 170353d..092b055 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -604,7 +604,7 @@ static inline void __sk_add_backlog(struct sock *sk, struct sk_buff *skb) } /* The per-socket spinlock must be held here. */ -static inline int sk_add_backlog(struct sock *sk, struct sk_buff *skb) +static inline __must_check int sk_add_backlog(struct sock *sk, struct sk_buff *skb) { if (sk->sk_backlog.len >= max(sk->sk_backlog.limit, sk->sk_rcvbuf << 1)) return -ENOBUFS; -- cgit v0.10.2 From 6cce09f87a04797fae5b947ef2626c14a78f0b49 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 7 Mar 2010 23:21:57 +0000 Subject: tcp: Add SNMP counters for backlog and min_ttl drops Commit 6b03a53a (tcp: use limited socket backlog) added the possibility of dropping frames when backlog queue is full. Commit d218d111 (tcp: Generalized TTL Security Mechanism) added the possibility of dropping frames when TTL is under a given limit. This patch adds new SNMP MIB entries, named TCPBacklogDrop and TCPMinTTLDrop, published in /proc/net/netstat in TcpExt: line netstat -s | egrep "TCPBacklogDrop|TCPMinTTLDrop" TCPBacklogDrop: 0 TCPMinTTLDrop: 0 Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller diff --git a/include/linux/snmp.h b/include/linux/snmp.h index e28f5a0..4435d10 100644 --- a/include/linux/snmp.h +++ b/include/linux/snmp.h @@ -225,6 +225,8 @@ enum LINUX_MIB_SACKSHIFTED, LINUX_MIB_SACKMERGED, LINUX_MIB_SACKSHIFTFALLBACK, + LINUX_MIB_TCPBACKLOGDROP, + LINUX_MIB_TCPMINTTLDROP, /* RFC 5082 */ __LINUX_MIB_MAX }; diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index 242ed23..4f1f337 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c @@ -249,6 +249,8 @@ static const struct snmp_mib snmp4_net_list[] = { SNMP_MIB_ITEM("TCPSackShifted", LINUX_MIB_SACKSHIFTED), SNMP_MIB_ITEM("TCPSackMerged", LINUX_MIB_SACKMERGED), SNMP_MIB_ITEM("TCPSackShiftFallback", LINUX_MIB_SACKSHIFTFALLBACK), + SNMP_MIB_ITEM("TCPBacklogDrop", LINUX_MIB_TCPBACKLOGDROP), + SNMP_MIB_ITEM("TCPMinTTLDrop", LINUX_MIB_TCPMINTTLDROP), SNMP_MIB_SENTINEL }; diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 1915f7d..8d51d39 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1651,8 +1651,10 @@ int tcp_v4_rcv(struct sk_buff *skb) if (!sk) goto no_tcp_socket; - if (iph->ttl < inet_sk(sk)->min_ttl) + if (unlikely(iph->ttl < inet_sk(sk)->min_ttl)) { + NET_INC_STATS_BH(net, LINUX_MIB_TCPMINTTLDROP); goto discard_and_relse; + } process: if (sk->sk_state == TCP_TIME_WAIT) @@ -1682,8 +1684,9 @@ process: if (!tcp_prequeue(sk, skb)) ret = tcp_v4_do_rcv(sk, skb); } - } else if (sk_add_backlog(sk, skb)) { + } else if (unlikely(sk_add_backlog(sk, skb))) { bh_unlock_sock(sk); + NET_INC_STATS_BH(net, LINUX_MIB_TCPBACKLOGDROP); goto discard_and_relse; } bh_unlock_sock(sk); diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 2c378b1..9b6dbba 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1740,8 +1740,9 @@ process: if (!tcp_prequeue(sk, skb)) ret = tcp_v6_do_rcv(sk, skb); } - } else if (sk_add_backlog(sk, skb)) { + } else if (unlikely(sk_add_backlog(sk, skb))) { bh_unlock_sock(sk); + NET_INC_STATS_BH(net, LINUX_MIB_TCPBACKLOGDROP); goto discard_and_relse; } bh_unlock_sock(sk); -- cgit v0.10.2 From 500ca9ba241304937c54c379e515b24400379353 Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Sun, 7 Mar 2010 14:21:27 +0000 Subject: be2net: remove usage of be_pci_func When PCI functions are virtuialized in applications by assigning PCI functions to VM (PCI passthrough), the be2net driver in the VM sees a different function number. So, use of PCI function number in any calculation will break existing code. This patch takes care of it. Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index be81fb2..8f07525 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -290,11 +290,6 @@ extern const struct ethtool_ops be_ethtool_ops; #define drvr_stats(adapter) (&adapter->stats.drvr_stats) -static inline unsigned int be_pci_func(struct be_adapter *adapter) -{ - return PCI_FUNC(adapter->pdev->devfn); -} - #define BE_SET_NETDEV_OPS(netdev, ops) (netdev->netdev_ops = ops) #define PAGE_SHIFT_4K 12 diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 4b1f805..c592153 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -465,8 +465,6 @@ int be_cmd_eq_create(struct be_adapter *adapter, req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size)); - AMAP_SET_BITS(struct amap_eq_context, func, req->context, - be_pci_func(adapter)); AMAP_SET_BITS(struct amap_eq_context, valid, req->context, 1); /* 4byte eqe*/ AMAP_SET_BITS(struct amap_eq_context, size, req->context, 0); @@ -629,7 +627,6 @@ int be_cmd_cq_create(struct be_adapter *adapter, AMAP_SET_BITS(struct amap_cq_context, eventable, ctxt, 1); AMAP_SET_BITS(struct amap_cq_context, eqid, ctxt, eq->id); AMAP_SET_BITS(struct amap_cq_context, armed, ctxt, 1); - AMAP_SET_BITS(struct amap_cq_context, func, ctxt, be_pci_func(adapter)); be_dws_cpu_to_le(ctxt, sizeof(req->context)); be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem); @@ -678,7 +675,6 @@ int be_cmd_mccq_create(struct be_adapter *adapter, req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size); - AMAP_SET_BITS(struct amap_mcc_context, fid, ctxt, be_pci_func(adapter)); AMAP_SET_BITS(struct amap_mcc_context, valid, ctxt, 1); AMAP_SET_BITS(struct amap_mcc_context, ring_size, ctxt, be_encoded_q_len(mccq->len)); @@ -727,8 +723,6 @@ int be_cmd_txq_create(struct be_adapter *adapter, AMAP_SET_BITS(struct amap_tx_context, tx_ring_size, ctxt, be_encoded_q_len(txq->len)); - AMAP_SET_BITS(struct amap_tx_context, pci_func_id, ctxt, - be_pci_func(adapter)); AMAP_SET_BITS(struct amap_tx_context, ctx_valid, ctxt, 1); AMAP_SET_BITS(struct amap_tx_context, cq_id_send, ctxt, cq->id); diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 22f787f..7c9b57e 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -1382,7 +1382,7 @@ rx_eq_free: /* There are 8 evt ids per func. Retruns the evt id's bit number */ static inline int be_evt_bit_get(struct be_adapter *adapter, u32 eq_id) { - return eq_id - 8 * be_pci_func(adapter); + return eq_id % 8; } static irqreturn_t be_intx(int irq, void *dev) -- cgit v0.10.2 From 7e8a9298adf7531c58d73ba9c499353e3807cf19 Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Sun, 7 Mar 2010 14:23:44 +0000 Subject: be2net: remove unused code in be_load_fw This patch cleans up some unused code from be_load_fw(). Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 7c9b57e..43e8032 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -1993,16 +1993,7 @@ int be_load_fw(struct be_adapter *adapter, u8 *func) struct be_dma_mem flash_cmd; int status, i = 0; const u8 *p; - char fw_ver[FW_VER_LEN]; - char fw_cfg; - status = be_cmd_get_fw_ver(adapter, fw_ver); - if (status) - return status; - - fw_cfg = *(fw_ver + 2); - if (fw_cfg == '0') - fw_cfg = '1'; strcpy(fw_file, func); status = request_firmware(&fw, fw_file, &adapter->pdev->dev); -- cgit v0.10.2 From 8bae5698616ac336938684ce7a7370299bd55d01 Mon Sep 17 00:00:00 2001 From: Sucheta Chakraborty Date: Mon, 8 Mar 2010 00:14:45 +0000 Subject: qlcnic: fix tx csum status Kernel default tx csum function (ethtool_op_get_tx_csum) doesn't show correct csum status. It takes various FLAGS (NETIF_F_ALL_CSUM) in account to show tx csum status, which driver doesn't set while disabling tx csum. Signed-off-by: Sucheta Chakraborty Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c index 8da6ec8..ef12792 100644 --- a/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/qlcnic/qlcnic_ethtool.c @@ -785,6 +785,11 @@ qlcnic_get_ethtool_stats(struct net_device *dev, } } +static u32 qlcnic_get_tx_csum(struct net_device *dev) +{ + return dev->features & NETIF_F_IP_CSUM; +} + static u32 qlcnic_get_rx_csum(struct net_device *dev) { struct qlcnic_adapter *adapter = netdev_priv(dev); @@ -995,6 +1000,7 @@ const struct ethtool_ops qlcnic_ethtool_ops = { .set_ringparam = qlcnic_set_ringparam, .get_pauseparam = qlcnic_get_pauseparam, .set_pauseparam = qlcnic_set_pauseparam, + .get_tx_csum = qlcnic_get_tx_csum, .set_tx_csum = ethtool_op_set_tx_csum, .set_sg = ethtool_op_set_sg, .get_tso = qlcnic_get_tso, -- cgit v0.10.2 From 8bfe8b91b8b877066c8ac788f59a40324eaac6d8 Mon Sep 17 00:00:00 2001 From: Sucheta Chakraborty Date: Mon, 8 Mar 2010 00:14:46 +0000 Subject: qlcnic: additional driver statistics. Statistics added for lro/lso bytes, count for tx stop queue and wake queue and skb alloc failure count. Signed-off-by: Sucheta Chakraborty Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index b40a851..9897b69 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -423,6 +423,11 @@ struct qlcnic_adapter_stats { u64 lro_pkts; u64 rxbytes; u64 txbytes; + u64 lrobytes; + u64 lso_frames; + u64 xmit_on; + u64 xmit_off; + u64 skb_alloc_failure; }; /* diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c index ef12792..f83e15f 100644 --- a/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/qlcnic/qlcnic_ethtool.c @@ -59,6 +59,17 @@ static const struct qlcnic_stats qlcnic_gstrings_stats[] = { QLC_SIZEOF(stats.rxbytes), QLC_OFF(stats.rxbytes)}, {"tx_bytes", QLC_SIZEOF(stats.txbytes), QLC_OFF(stats.txbytes)}, + {"lrobytes", + QLC_SIZEOF(stats.lrobytes), QLC_OFF(stats.lrobytes)}, + {"lso_frames", + QLC_SIZEOF(stats.lso_frames), QLC_OFF(stats.lso_frames)}, + {"xmit_on", + QLC_SIZEOF(stats.xmit_on), QLC_OFF(stats.xmit_on)}, + {"xmit_off", + QLC_SIZEOF(stats.xmit_off), QLC_OFF(stats.xmit_off)}, + {"skb_alloc_failure", QLC_SIZEOF(stats.skb_alloc_failure), + QLC_OFF(stats.skb_alloc_failure)}, + }; #define QLCNIC_STATS_LEN ARRAY_SIZE(qlcnic_gstrings_stats) diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c index 99a4d13..e95646b 100644 --- a/drivers/net/qlcnic/qlcnic_hw.c +++ b/drivers/net/qlcnic/qlcnic_hw.c @@ -349,6 +349,7 @@ qlcnic_send_cmd_descs(struct qlcnic_adapter *adapter, if (nr_desc >= qlcnic_tx_avail(tx_ring)) { netif_tx_stop_queue(tx_ring->txq); __netif_tx_unlock_bh(tx_ring->txq); + adapter->stats.xmit_off++; return -EBUSY; } diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index ea00ab4..f0df971 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c @@ -1114,8 +1114,10 @@ qlcnic_alloc_rx_skb(struct qlcnic_adapter *adapter, struct pci_dev *pdev = adapter->pdev; buffer->skb = dev_alloc_skb(rds_ring->skb_size); - if (!buffer->skb) + if (!buffer->skb) { + adapter->stats.skb_alloc_failure++; return -ENOMEM; + } skb = buffer->skb; @@ -1289,7 +1291,7 @@ qlcnic_process_lro(struct qlcnic_adapter *adapter, netif_receive_skb(skb); adapter->stats.lro_pkts++; - adapter->stats.rxbytes += length; + adapter->stats.lrobytes += length; return buffer; } @@ -1505,6 +1507,8 @@ qlcnic_process_rcv_diag(struct qlcnic_adapter *adapter, adapter->diag_cnt++; dev_kfree_skb_any(skb); + adapter->stats.rx_pkts++; + adapter->stats.rxbytes += length; return buffer; } diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 665e8e5..fc72156 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -118,6 +118,7 @@ qlcnic_update_cmd_producer(struct qlcnic_adapter *adapter, if (qlcnic_tx_avail(tx_ring) <= TX_STOP_THRESH) { netif_stop_queue(adapter->netdev); smp_mb(); + adapter->stats.xmit_off++; } } @@ -1385,6 +1386,7 @@ qlcnic_tso_check(struct net_device *netdev, int copied, offset, copy_len, hdr_len = 0, tso = 0, vlan_oob = 0; struct cmd_desc_type0 *hwdesc; struct vlan_ethhdr *vh; + struct qlcnic_adapter *adapter = netdev_priv(netdev); if (protocol == cpu_to_be16(ETH_P_8021Q)) { @@ -1494,6 +1496,7 @@ qlcnic_tso_check(struct net_device *netdev, tx_ring->producer = producer; barrier(); + adapter->stats.lso_frames++; } static int @@ -1573,6 +1576,7 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) if (unlikely(no_of_desc + 2 > qlcnic_tx_avail(tx_ring))) { netif_stop_queue(netdev); + adapter->stats.xmit_off++; return NETDEV_TX_BUSY; } @@ -1880,6 +1884,7 @@ static int qlcnic_process_cmd_ring(struct qlcnic_adapter *adapter) if (qlcnic_tx_avail(tx_ring) > TX_STOP_THRESH) { netif_wake_queue(netdev); adapter->tx_timeo_cnt = 0; + adapter->stats.xmit_on++; } __netif_tx_unlock(tx_ring->txq); } -- cgit v0.10.2 From 9ab17b3968f9521bb4fffd8767953d2b0148aad0 Mon Sep 17 00:00:00 2001 From: Sucheta Chakraborty Date: Mon, 8 Mar 2010 00:14:47 +0000 Subject: qlcnic: fix multicast handling For promiscuous mode, driver send request to device for deleting multicast addresses and again it send request for adding them back while exiting from this mode, this is bad for performance. Just setting device in promiscuous mode is enough, no need to del/add multicast addresses. Signed-off-by: Sucheta Chakraborty Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c index e95646b..da00e16 100644 --- a/drivers/net/qlcnic/qlcnic_hw.c +++ b/drivers/net/qlcnic/qlcnic_hw.c @@ -398,20 +398,16 @@ qlcnic_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr, return qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); } -static int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter, - u8 *addr, struct list_head *del_list) +static int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter, u8 *addr) { struct list_head *head; struct qlcnic_mac_list_s *cur; /* look up if already exists */ - list_for_each(head, del_list) { + list_for_each(head, &adapter->mac_list) { cur = list_entry(head, struct qlcnic_mac_list_s, list); - - if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0) { - list_move_tail(head, &adapter->mac_list); + if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0) return 0; - } } cur = kzalloc(sizeof(struct qlcnic_mac_list_s), GFP_ATOMIC); @@ -433,14 +429,9 @@ void qlcnic_set_multi(struct net_device *netdev) struct dev_mc_list *mc_ptr; u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; u32 mode = VPORT_MISS_MODE_DROP; - LIST_HEAD(del_list); - struct list_head *head; - struct qlcnic_mac_list_s *cur; - list_splice_tail_init(&adapter->mac_list, &del_list); - - qlcnic_nic_add_mac(adapter, adapter->mac_addr, &del_list); - qlcnic_nic_add_mac(adapter, bcast_addr, &del_list); + qlcnic_nic_add_mac(adapter, adapter->mac_addr); + qlcnic_nic_add_mac(adapter, bcast_addr); if (netdev->flags & IFF_PROMISC) { mode = VPORT_MISS_MODE_ACCEPT_ALL; @@ -455,22 +446,12 @@ void qlcnic_set_multi(struct net_device *netdev) if (!netdev_mc_empty(netdev)) { netdev_for_each_mc_addr(mc_ptr, netdev) { - qlcnic_nic_add_mac(adapter, mc_ptr->dmi_addr, - &del_list); + qlcnic_nic_add_mac(adapter, mc_ptr->dmi_addr); } } send_fw_cmd: qlcnic_nic_set_promisc(adapter, mode); - head = &del_list; - while (!list_empty(head)) { - cur = list_entry(head->next, struct qlcnic_mac_list_s, list); - - qlcnic_sre_macaddr_change(adapter, - cur->mac_addr, QLCNIC_MAC_DEL); - list_del(&cur->list); - kfree(cur); - } } int qlcnic_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode) -- cgit v0.10.2 From b7eff1007fea3d153a9a5c0f872304ec19412bbb Mon Sep 17 00:00:00 2001 From: Sucheta Chakraborty Date: Mon, 8 Mar 2010 00:14:48 +0000 Subject: qlcnic: validate unified fw image Validate all sections of unified fw image, before accessing them, to avoid seg fault. Signed-off-by: Sucheta Chakraborty Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index f0df971..21a6e9f 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c @@ -568,21 +568,123 @@ struct uni_table_desc *qlcnic_get_table_desc(const u8 *unirom, int section) return NULL; } +#define FILEHEADER_SIZE (14 * 4) + static int -qlcnic_set_product_offs(struct qlcnic_adapter *adapter) +qlcnic_validate_header(struct qlcnic_adapter *adapter) { - struct uni_table_desc *ptab_descr; const u8 *unirom = adapter->fw->data; - u32 i; + struct uni_table_desc *directory = (struct uni_table_desc *) &unirom[0]; + __le32 fw_file_size = adapter->fw->size; __le32 entries; + __le32 entry_size; + __le32 tab_size; + + if (fw_file_size < FILEHEADER_SIZE) + return -EINVAL; + + entries = cpu_to_le32(directory->num_entries); + entry_size = cpu_to_le32(directory->entry_size); + tab_size = cpu_to_le32(directory->findex) + (entries * entry_size); + + if (fw_file_size < tab_size) + return -EINVAL; + + return 0; +} + +static int +qlcnic_validate_bootld(struct qlcnic_adapter *adapter) +{ + struct uni_table_desc *tab_desc; + struct uni_data_desc *descr; + const u8 *unirom = adapter->fw->data; + int idx = cpu_to_le32(*((int *)&unirom[adapter->file_prd_off] + + QLCNIC_UNI_BOOTLD_IDX_OFF)); + __le32 offs; + __le32 tab_size; + __le32 data_size; + + tab_desc = qlcnic_get_table_desc(unirom, QLCNIC_UNI_DIR_SECT_BOOTLD); + + if (!tab_desc) + return -EINVAL; + + tab_size = cpu_to_le32(tab_desc->findex) + + (cpu_to_le32(tab_desc->entry_size * (idx + 1))); + + if (adapter->fw->size < tab_size) + return -EINVAL; + + offs = cpu_to_le32(tab_desc->findex) + + (cpu_to_le32(tab_desc->entry_size) * (idx)); + descr = (struct uni_data_desc *)&unirom[offs]; + + data_size = descr->findex + cpu_to_le32(descr->size); + + if (adapter->fw->size < data_size) + return -EINVAL; + + return 0; +} + +static int +qlcnic_validate_fw(struct qlcnic_adapter *adapter) +{ + struct uni_table_desc *tab_desc; + struct uni_data_desc *descr; + const u8 *unirom = adapter->fw->data; + int idx = cpu_to_le32(*((int *)&unirom[adapter->file_prd_off] + + QLCNIC_UNI_FIRMWARE_IDX_OFF)); + __le32 offs; + __le32 tab_size; + __le32 data_size; + + tab_desc = qlcnic_get_table_desc(unirom, QLCNIC_UNI_DIR_SECT_FW); + + if (!tab_desc) + return -EINVAL; + + tab_size = cpu_to_le32(tab_desc->findex) + + (cpu_to_le32(tab_desc->entry_size * (idx + 1))); + + if (adapter->fw->size < tab_size) + return -EINVAL; + + offs = cpu_to_le32(tab_desc->findex) + + (cpu_to_le32(tab_desc->entry_size) * (idx)); + descr = (struct uni_data_desc *)&unirom[offs]; + data_size = descr->findex + cpu_to_le32(descr->size); + + if (adapter->fw->size < data_size) + return -EINVAL; + + return 0; +} + +static int +qlcnic_validate_product_offs(struct qlcnic_adapter *adapter) +{ + struct uni_table_desc *ptab_descr; + const u8 *unirom = adapter->fw->data; int mn_present = qlcnic_has_mn(adapter); + __le32 entries; + __le32 entry_size; + __le32 tab_size; + u32 i; ptab_descr = qlcnic_get_table_desc(unirom, QLCNIC_UNI_DIR_SECT_PRODUCT_TBL); - if (ptab_descr == NULL) - return -1; + if (!ptab_descr) + return -EINVAL; entries = cpu_to_le32(ptab_descr->num_entries); + entry_size = cpu_to_le32(ptab_descr->entry_size); + tab_size = cpu_to_le32(ptab_descr->findex) + (entries * entry_size); + + if (adapter->fw->size < tab_size) + return -EINVAL; + nomn: for (i = 0; i < entries; i++) { @@ -609,7 +711,37 @@ nomn: mn_present = 0; goto nomn; } - return -1; + return -EINVAL; +} + +static int +qlcnic_validate_unified_romimage(struct qlcnic_adapter *adapter) +{ + if (qlcnic_validate_header(adapter)) { + dev_err(&adapter->pdev->dev, + "unified image: header validation failed\n"); + return -EINVAL; + } + + if (qlcnic_validate_product_offs(adapter)) { + dev_err(&adapter->pdev->dev, + "unified image: product validation failed\n"); + return -EINVAL; + } + + if (qlcnic_validate_bootld(adapter)) { + dev_err(&adapter->pdev->dev, + "unified image: bootld validation failed\n"); + return -EINVAL; + } + + if (qlcnic_validate_fw(adapter)) { + dev_err(&adapter->pdev->dev, + "unified image: firmware validation failed\n"); + return -EINVAL; + } + + return 0; } static @@ -858,7 +990,7 @@ qlcnic_validate_firmware(struct qlcnic_adapter *adapter) u8 fw_type = adapter->fw_type; if (fw_type == QLCNIC_UNIFIED_ROMIMAGE) { - if (qlcnic_set_product_offs(adapter)) + if (qlcnic_validate_unified_romimage(adapter)) return -EINVAL; min_size = QLCNIC_UNI_FW_MIN_SIZE; -- cgit v0.10.2 From addd5abf49be31787aeb6203d266e0bd31a3fadd Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Mon, 8 Mar 2010 00:14:49 +0000 Subject: qlcnic: fix bios version check Bios sub version from unified fw image is calculated incorrect. Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index 21a6e9f..7c34e4e 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c @@ -847,7 +847,7 @@ qlcnic_get_bios_version(struct qlcnic_adapter *adapter) bios_ver = cpu_to_le32(*((u32 *) (&fw->data[prd_off]) + QLCNIC_UNI_BIOS_VERSION_OFF)); - return (bios_ver << 24) + ((bios_ver >> 8) & 0xff00) + (bios_ver >> 24); + return (bios_ver << 16) + ((bios_ver >> 8) & 0xff00) + (bios_ver >> 24); } int -- cgit v0.10.2 From 1515faf2f995add976d4428bbc1583a4a0c81e5f Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Mon, 8 Mar 2010 00:14:50 +0000 Subject: qlcnic: remove extra space from board names Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 9897b69..0da94b2 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -1100,11 +1100,11 @@ struct qlcnic_brdinfo { static const struct qlcnic_brdinfo qlcnic_boards[] = { {0x1077, 0x8020, 0x1077, 0x203, - "8200 Series Single Port 10GbE Converged Network Adapter \ - (TCP/IP Networking)"}, + "8200 Series Single Port 10GbE Converged Network Adapter " + "(TCP/IP Networking)"}, {0x1077, 0x8020, 0x1077, 0x207, - "8200 Series Dual Port 10GbE Converged Network Adapter \ - (TCP/IP Networking)"}, + "8200 Series Dual Port 10GbE Converged Network Adapter " + "(TCP/IP Networking)"}, {0x1077, 0x8020, 0x1077, 0x20b, "3200 Series Dual Port 10Gb Intelligent Ethernet Adapter"}, {0x1077, 0x8020, 0x1077, 0x20c, -- cgit v0.10.2 From 9837638727488922727b0cfd438039fa73364183 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 8 Mar 2010 03:20:00 +0000 Subject: net: fix route cache rebuilds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We added an automatic route cache rebuilding in commit 1080d709fb9d8cd43 but had to correct few bugs. One of the assumption of original patch, was that entries where kept sorted in a given way. This assumption is known to be wrong (commit 1ddbcb005c395518 gave an explanation of this and corrected a leak) and expensive to respect. Paweł Staszewski reported to me one of his machine got its routing cache disabled after few messages like : [ 2677.850065] Route hash chain too long! [ 2677.850080] Adjust your secret_interval! [82839.662993] Route hash chain too long! [82839.662996] Adjust your secret_interval! [155843.731650] Route hash chain too long! [155843.731664] Adjust your secret_interval! [155843.811881] Route hash chain too long! [155843.811891] Adjust your secret_interval! [155843.858209] vlan0811: 5 rebuilds is over limit, route caching disabled [155843.858212] Route hash chain too long! [155843.858213] Adjust your secret_interval! This is because rt_intern_hash() might be fooled when computing a chain length, because multiple entries with same keys can differ because of TOS (or mark/oif) bits. In the rare case the fast algorithm see a too long chain, and before taking expensive path, we call a helper function in order to not count duplicates of same routes, that only differ with tos/mark/oif bits. This helper works with data already in cpu cache and is not be very expensive, despite its O(N^2) implementation. Paweł Staszewski sucessfully tested this patch on his loaded router. Reported-and-tested-by: Paweł Staszewski Signed-off-by: Eric Dumazet Acked-by: Neil Horman Signed-off-by: David S. Miller diff --git a/net/ipv4/route.c b/net/ipv4/route.c index b2ba558..d9b4024 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -146,7 +146,6 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst); static void ipv4_link_failure(struct sk_buff *skb); static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu); static int rt_garbage_collect(struct dst_ops *ops); -static void rt_emergency_hash_rebuild(struct net *net); static struct dst_ops ipv4_dst_ops = { @@ -780,11 +779,30 @@ static void rt_do_flush(int process_context) #define FRACT_BITS 3 #define ONE (1UL << FRACT_BITS) +/* + * Given a hash chain and an item in this hash chain, + * find if a previous entry has the same hash_inputs + * (but differs on tos, mark or oif) + * Returns 0 if an alias is found. + * Returns ONE if rth has no alias before itself. + */ +static int has_noalias(const struct rtable *head, const struct rtable *rth) +{ + const struct rtable *aux = head; + + while (aux != rth) { + if (compare_hash_inputs(&aux->fl, &rth->fl)) + return 0; + aux = aux->u.dst.rt_next; + } + return ONE; +} + static void rt_check_expire(void) { static unsigned int rover; unsigned int i = rover, goal; - struct rtable *rth, *aux, **rthp; + struct rtable *rth, **rthp; unsigned long samples = 0; unsigned long sum = 0, sum2 = 0; unsigned long delta; @@ -835,15 +853,7 @@ nofree: * attributes don't unfairly skew * the length computation */ - for (aux = rt_hash_table[i].chain;;) { - if (aux == rth) { - length += ONE; - break; - } - if (compare_hash_inputs(&aux->fl, &rth->fl)) - break; - aux = aux->u.dst.rt_next; - } + length += has_noalias(rt_hash_table[i].chain, rth); continue; } } else if (!rt_may_expire(rth, tmo, ip_rt_gc_timeout)) @@ -1073,6 +1083,21 @@ work_done: out: return 0; } +/* + * Returns number of entries in a hash chain that have different hash_inputs + */ +static int slow_chain_length(const struct rtable *head) +{ + int length = 0; + const struct rtable *rth = head; + + while (rth) { + length += has_noalias(head, rth); + rth = rth->u.dst.rt_next; + } + return length >> FRACT_BITS; +} + static int rt_intern_hash(unsigned hash, struct rtable *rt, struct rtable **rp, struct sk_buff *skb) { @@ -1185,7 +1210,8 @@ restart: rt_free(cand); } } else { - if (chain_length > rt_chain_length_max) { + if (chain_length > rt_chain_length_max && + slow_chain_length(rt_hash_table[hash].chain) > rt_chain_length_max) { struct net *net = dev_net(rt->u.dst.dev); int num = ++net->ipv4.current_rt_cache_rebuild_count; if (!rt_caching(dev_net(rt->u.dst.dev))) { -- cgit v0.10.2 From 77d3926306bf4eecac50150ba5625797219f14ba Mon Sep 17 00:00:00 2001 From: Meelis Roos Date: Mon, 8 Mar 2010 10:53:08 -0800 Subject: qlogicpti: Remove slash in QlogicPTI irq name qlogicpti driver registers its irq with a name containing slash. This results in [ 71.049735] WARNING: at fs/proc/generic.c:316 __xlate_proc_name+0xa8/0xb8() [ 71.132815] name 'Qlogic/PTI' because proc_mkdir with the name of the irq fails. Fix it by just removing the slash from irq name. Discovered and tested on real hardware (Sun Ultra 1). Signed-off-by: Meelis Roos Signed-off-by: David S. Miller diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c index fa34b92..1b82170 100644 --- a/drivers/scsi/qlogicpti.c +++ b/drivers/scsi/qlogicpti.c @@ -738,7 +738,7 @@ static int __devinit qpti_register_irq(struct qlogicpti *qpti) * sanely maintain. */ if (request_irq(qpti->irq, qpti_intr, - IRQF_SHARED, "Qlogic/PTI", qpti)) + IRQF_SHARED, "QlogicPTI", qpti)) goto fail; printk("qlogicpti%d: IRQ %d ", qpti->qpti_id, qpti->irq); -- cgit v0.10.2 From 5fe46e9d733f19a880ef7e516002bd4c2b833e14 Mon Sep 17 00:00:00 2001 From: Bian Naimeng Date: Mon, 8 Mar 2010 14:49:01 +0800 Subject: rpc client can not deal with ENOSOCK, so translate it into ENOCONN If NFSv4 client send a request before connect, or the old connection was broken because a ETIMEOUT error catched by call_status, ->send_request will return ENOSOCK, but rpc layer can not deal with it, so make sure ->send_request can translate ENOSOCK into ENOCONN. Signed-off-by: Bian Naimeng Signed-off-by: Trond Myklebust diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 7124129..abb8a58 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c @@ -549,8 +549,6 @@ static int xs_udp_send_request(struct rpc_task *task) /* Still some bytes left; set up for a retry later. */ status = -EAGAIN; } - if (!transport->sock) - goto out; switch (status) { case -ENOTSOCK: @@ -570,7 +568,7 @@ static int xs_udp_send_request(struct rpc_task *task) * prompts ECONNREFUSED. */ clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags); } -out: + return status; } @@ -652,8 +650,6 @@ static int xs_tcp_send_request(struct rpc_task *task) status = -EAGAIN; break; } - if (!transport->sock) - goto out; switch (status) { case -ENOTSOCK: @@ -673,7 +669,7 @@ static int xs_tcp_send_request(struct rpc_task *task) case -ENOTCONN: clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags); } -out: + return status; } -- cgit v0.10.2 From 7dd08a570dcf45d52155996fee688405635ee481 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 6 Mar 2010 15:02:22 +0300 Subject: nfs: fix unlikely memory leak I'll admit that it's unlikely for the first allocation to fail and the second one to succeed. I won't be offended if you ignore this patch. Signed-off-by: Dan Carpenter Signed-off-by: Trond Myklebust diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index eda74c4..f9254fb 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -5107,6 +5107,7 @@ static int nfs41_proc_async_sequence(struct nfs_client *clp, res = kzalloc(sizeof(*res), GFP_KERNEL); if (!args || !res) { kfree(args); + kfree(res); nfs_put_client(clp); return -ENOMEM; } -- cgit v0.10.2 From f6bb13aa1ea3bb26a4c783822347873f085b9000 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 4 Mar 2010 01:52:58 +0100 Subject: ACPI / EC / PM: Close race between EC and resume from hibernation There is a race between resume from hibernation and the EC driver that may result in restoring the hibernation image in the middle of an EC transaction in progress, which in turn may lead to unpredictable behavior of the platform. To remove that race condition, add a helpers for suspending and resuming EC transactions in a safe way to be executed by the ACPI platform hibernate pre-restore and restore cleanup callbacks. http://bugzilla.kernel.org/show_bug.cgi?id=14668 Signed-off-by: Rafael J. Wysocki Reported-and-tested-by: Maxim Levitsky Signed-off-by: Len Brown diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index d6471bb..19f93e1 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -76,8 +76,9 @@ enum ec_command { enum { EC_FLAGS_QUERY_PENDING, /* Query is pending */ EC_FLAGS_GPE_STORM, /* GPE storm detected */ - EC_FLAGS_HANDLERS_INSTALLED /* Handlers for GPE and + EC_FLAGS_HANDLERS_INSTALLED, /* Handlers for GPE and * OpReg are installed */ + EC_FLAGS_FROZEN, /* Transactions are suspended */ }; /* If we find an EC via the ECDT, we need to keep a ptr to its context */ @@ -291,6 +292,10 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) if (t->rdata) memset(t->rdata, 0, t->rlen); mutex_lock(&ec->lock); + if (test_bit(EC_FLAGS_FROZEN, &ec->flags)) { + status = -EINVAL; + goto unlock; + } if (ec->global_lock) { status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); if (ACPI_FAILURE(status)) { @@ -445,6 +450,32 @@ int ec_transaction(u8 command, EXPORT_SYMBOL(ec_transaction); +void acpi_ec_suspend_transactions(void) +{ + struct acpi_ec *ec = first_ec; + + if (!ec) + return; + + mutex_lock(&ec->lock); + /* Prevent transactions from being carried out */ + set_bit(EC_FLAGS_FROZEN, &ec->flags); + mutex_unlock(&ec->lock); +} + +void acpi_ec_resume_transactions(void) +{ + struct acpi_ec *ec = first_ec; + + if (!ec) + return; + + mutex_lock(&ec->lock); + /* Allow transactions to be carried out again */ + clear_bit(EC_FLAGS_FROZEN, &ec->flags); + mutex_unlock(&ec->lock); +} + static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 * data) { int result; diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index cb28e05..7874246 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -51,6 +51,8 @@ void acpi_early_processor_set_pdc(void); int acpi_ec_init(void); int acpi_ec_ecdt_probe(void); int acpi_boot_ec_enable(void); +void acpi_ec_suspend_transactions(void); +void acpi_ec_resume_transactions(void); /*-------------------------------------------------------------------------- Suspend/Resume diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 79d33d9..f01f8e8 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -552,8 +552,17 @@ static void acpi_hibernation_leave(void) hibernate_nvs_restore(); } -static void acpi_pm_enable_gpes(void) +static int acpi_pm_pre_restore(void) { + acpi_disable_all_gpes(); + acpi_os_wait_events_complete(NULL); + acpi_ec_suspend_transactions(); + return 0; +} + +static void acpi_pm_restore_cleanup(void) +{ + acpi_ec_resume_transactions(); acpi_enable_all_runtime_gpes(); } @@ -565,8 +574,8 @@ static struct platform_hibernation_ops acpi_hibernation_ops = { .prepare = acpi_pm_prepare, .enter = acpi_hibernation_enter, .leave = acpi_hibernation_leave, - .pre_restore = acpi_pm_disable_gpes, - .restore_cleanup = acpi_pm_enable_gpes, + .pre_restore = acpi_pm_pre_restore, + .restore_cleanup = acpi_pm_restore_cleanup, }; /** @@ -618,8 +627,8 @@ static struct platform_hibernation_ops acpi_hibernation_ops_old = { .prepare = acpi_pm_disable_gpes, .enter = acpi_hibernation_enter, .leave = acpi_hibernation_leave, - .pre_restore = acpi_pm_disable_gpes, - .restore_cleanup = acpi_pm_enable_gpes, + .pre_restore = acpi_pm_pre_restore, + .restore_cleanup = acpi_pm_restore_cleanup, .recover = acpi_pm_finish, }; #endif /* CONFIG_HIBERNATION */ -- cgit v0.10.2 From 28b2774a0d5852236dab77a4147b8b88548110f1 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 8 Mar 2010 11:32:01 -0800 Subject: tcp: Fix tcp_make_synack() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 4957faad (TCPCT part 1g: Responder Cookie => Initiator), part of TCP_COOKIE_TRANSACTION implementation, forgot to correctly size synack skb in case user data must be included. Many thanks to Mika Pentillä for spotting this error. Reported-by: Penttillä Mika Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 4a1605d..f181b78 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -2395,13 +2395,17 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, struct tcp_extend_values *xvp = tcp_xv(rvp); struct inet_request_sock *ireq = inet_rsk(req); struct tcp_sock *tp = tcp_sk(sk); + const struct tcp_cookie_values *cvp = tp->cookie_values; struct tcphdr *th; struct sk_buff *skb; struct tcp_md5sig_key *md5; int tcp_header_size; int mss; + int s_data_desired = 0; - skb = sock_wmalloc(sk, MAX_TCP_HEADER + 15, 1, GFP_ATOMIC); + if (cvp != NULL && cvp->s_data_constant && cvp->s_data_desired) + s_data_desired = cvp->s_data_desired; + skb = sock_wmalloc(sk, MAX_TCP_HEADER + 15 + s_data_desired, 1, GFP_ATOMIC); if (skb == NULL) return NULL; @@ -2457,16 +2461,12 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, TCPCB_FLAG_SYN | TCPCB_FLAG_ACK); if (OPTION_COOKIE_EXTENSION & opts.options) { - const struct tcp_cookie_values *cvp = tp->cookie_values; - - if (cvp != NULL && - cvp->s_data_constant && - cvp->s_data_desired > 0) { - u8 *buf = skb_put(skb, cvp->s_data_desired); + if (s_data_desired) { + u8 *buf = skb_put(skb, s_data_desired); /* copy data directly from the listening socket. */ - memcpy(buf, cvp->s_data_payload, cvp->s_data_desired); - TCP_SKB_CB(skb)->end_seq += cvp->s_data_desired; + memcpy(buf, cvp->s_data_payload, s_data_desired); + TCP_SKB_CB(skb)->end_seq += s_data_desired; } if (opts.hash_size > 0) { -- cgit v0.10.2 From 49697ee79242d5f8ac88f1ebc62e583d16bcc687 Mon Sep 17 00:00:00 2001 From: Steve Dickson Date: Tue, 13 Oct 2009 16:07:33 -0400 Subject: nfs4: Make the v4 callback service hidden To avoid hangs in the svc_unregister(), on version 4 mounts (and unmounts), when rpcbind is not running, make the nfs4 callback program an 'hidden' service by setting the 'vs_hidden' flag in the nfs4_callback_version structure. Signed-off-by: Steve Dickson Signed-off-by: Trond Myklebust diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c index db30c0b..a2b8b4d 100644 --- a/fs/nfs/callback_xdr.c +++ b/fs/nfs/callback_xdr.c @@ -782,6 +782,7 @@ struct svc_version nfs4_callback_version1 = { .vs_proc = nfs4_callback_procedures1, .vs_xdrsize = NFS4_CALLBACK_XDRSIZE, .vs_dispatch = NULL, + .vs_hidden = 1, }; struct svc_version nfs4_callback_version4 = { -- cgit v0.10.2 From e9dcd1613f0ac0b3573b7d813a2c5672cd8302eb Mon Sep 17 00:00:00 2001 From: Barry Song Date: Mon, 8 Mar 2010 12:13:57 -0800 Subject: can: fix bfin_can build error after alloc_candev() change Looks like commit a6e4bc530403 didn't include updates to drivers so the Blackfin CAN driver fails to build now. Signed-off-by: Barry Song Signed-off-by: Mike Frysinger Acked-by: Wolfgang Grandegger Signed-off-by: David S. Miller diff --git a/drivers/net/can/bfin_can.c b/drivers/net/can/bfin_can.c index bf7f9ba..866905f 100644 --- a/drivers/net/can/bfin_can.c +++ b/drivers/net/can/bfin_can.c @@ -26,6 +26,7 @@ #define DRV_NAME "bfin_can" #define BFIN_CAN_TIMEOUT 100 +#define TX_ECHO_SKB_MAX 1 /* * transmit and receive channels @@ -593,7 +594,7 @@ struct net_device *alloc_bfin_candev(void) struct net_device *dev; struct bfin_can_priv *priv; - dev = alloc_candev(sizeof(*priv)); + dev = alloc_candev(sizeof(*priv), TX_ECHO_SKB_MAX); if (!dev) return NULL; -- cgit v0.10.2 From fc0b579168cbe737c83c6b9bbfe265d3ae6baca6 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 8 Mar 2010 12:15:28 -0800 Subject: net/sunrpc: Remove uses of NIPQUAD, use %pI4 Originally submitted Jan 1, 2010 http://patchwork.kernel.org/patch/71221/ Convert NIPQUAD to the %pI4 format extension where possible Convert %02x%02x%02x%02x/NIPQUAD to %08x/ntohl Signed-off-by: Joe Perches Signed-off-by: David S. Miller diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c index 7018eef..83d339f 100644 --- a/net/sunrpc/xprtrdma/transport.c +++ b/net/sunrpc/xprtrdma/transport.c @@ -165,8 +165,7 @@ xprt_rdma_format_addresses(struct rpc_xprt *xprt) xprt->address_strings[RPC_DISPLAY_PROTO] = "rdma"; - (void)snprintf(buf, sizeof(buf), "%02x%02x%02x%02x", - NIPQUAD(sin->sin_addr.s_addr)); + (void)snprintf(buf, sizeof(buf), "%08x", ntohl(sin->sin_addr.s_addr)); xprt->address_strings[RPC_DISPLAY_HEX_ADDR] = kstrdup(buf, GFP_KERNEL); (void)snprintf(buf, sizeof(buf), "%4hx", rpc_get_port(sap)); diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 3d739e5..86234bc 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c @@ -297,12 +297,11 @@ static void xs_format_common_peer_addresses(struct rpc_xprt *xprt) switch (sap->sa_family) { case AF_INET: sin = xs_addr_in(xprt); - (void)snprintf(buf, sizeof(buf), "%02x%02x%02x%02x", - NIPQUAD(sin->sin_addr.s_addr)); + snprintf(buf, sizeof(buf), "%08x", ntohl(sin->sin_addr.s_addr)); break; case AF_INET6: sin6 = xs_addr_in6(xprt); - (void)snprintf(buf, sizeof(buf), "%pi6", &sin6->sin6_addr); + snprintf(buf, sizeof(buf), "%pi6", &sin6->sin6_addr); break; default: BUG(); -- cgit v0.10.2 From 81160e66cca3d3a16b7d88e0e2dccfc5c76f36f9 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 8 Mar 2010 12:15:59 -0800 Subject: net/sunrpc: Convert (void)snprintf to snprintf (Applies on top of "Remove uses of NIPQUAD, use %pI4") Casts to void of snprintf are most uncommon in kernel source. 9 use casts, 1301 do not. Remove the remaining uses in net/sunrpc/ Signed-off-by: Joe Perches Signed-off-by: David S. Miller diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c index 83d339f..f96c2fe 100644 --- a/net/sunrpc/xprtrdma/transport.c +++ b/net/sunrpc/xprtrdma/transport.c @@ -160,15 +160,15 @@ xprt_rdma_format_addresses(struct rpc_xprt *xprt) (void)rpc_ntop(sap, buf, sizeof(buf)); xprt->address_strings[RPC_DISPLAY_ADDR] = kstrdup(buf, GFP_KERNEL); - (void)snprintf(buf, sizeof(buf), "%u", rpc_get_port(sap)); + snprintf(buf, sizeof(buf), "%u", rpc_get_port(sap)); xprt->address_strings[RPC_DISPLAY_PORT] = kstrdup(buf, GFP_KERNEL); xprt->address_strings[RPC_DISPLAY_PROTO] = "rdma"; - (void)snprintf(buf, sizeof(buf), "%08x", ntohl(sin->sin_addr.s_addr)); + snprintf(buf, sizeof(buf), "%08x", ntohl(sin->sin_addr.s_addr)); xprt->address_strings[RPC_DISPLAY_HEX_ADDR] = kstrdup(buf, GFP_KERNEL); - (void)snprintf(buf, sizeof(buf), "%4hx", rpc_get_port(sap)); + snprintf(buf, sizeof(buf), "%4hx", rpc_get_port(sap)); xprt->address_strings[RPC_DISPLAY_HEX_PORT] = kstrdup(buf, GFP_KERNEL); /* netid */ diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 86234bc..4f55ab7 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c @@ -314,10 +314,10 @@ static void xs_format_common_peer_ports(struct rpc_xprt *xprt) struct sockaddr *sap = xs_addr(xprt); char buf[128]; - (void)snprintf(buf, sizeof(buf), "%u", rpc_get_port(sap)); + snprintf(buf, sizeof(buf), "%u", rpc_get_port(sap)); xprt->address_strings[RPC_DISPLAY_PORT] = kstrdup(buf, GFP_KERNEL); - (void)snprintf(buf, sizeof(buf), "%4hx", rpc_get_port(sap)); + snprintf(buf, sizeof(buf), "%4hx", rpc_get_port(sap)); xprt->address_strings[RPC_DISPLAY_HEX_PORT] = kstrdup(buf, GFP_KERNEL); } -- cgit v0.10.2 From f5c445ed4148434f142be0263a8ad7cb58503e8a Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 8 Mar 2010 12:17:04 -0800 Subject: ethtool: Use noinline_for_stack Use self documenting noinline_for_stack instead of duplicated comments. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 33d2ded..f4cb6b6 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -200,10 +200,7 @@ static int ethtool_set_settings(struct net_device *dev, void __user *useraddr) return dev->ethtool_ops->set_settings(dev, &cmd); } -/* - * noinline attribute so that gcc doesnt use too much stack in dev_ethtool() - */ -static noinline int ethtool_get_drvinfo(struct net_device *dev, void __user *useraddr) +static noinline_for_stack int ethtool_get_drvinfo(struct net_device *dev, void __user *useraddr) { struct ethtool_drvinfo info; const struct ethtool_ops *ops = dev->ethtool_ops; @@ -242,10 +239,7 @@ static noinline int ethtool_get_drvinfo(struct net_device *dev, void __user *use return 0; } -/* - * noinline attribute so that gcc doesnt use too much stack in dev_ethtool() - */ -static noinline int ethtool_get_sset_info(struct net_device *dev, +static noinline_for_stack int ethtool_get_sset_info(struct net_device *dev, void __user *useraddr) { struct ethtool_sset_info info; @@ -305,10 +299,7 @@ out: return ret; } -/* - * noinline attribute so that gcc doesnt use too much stack in dev_ethtool() - */ -static noinline int ethtool_set_rxnfc(struct net_device *dev, void __user *useraddr) +static noinline_for_stack int ethtool_set_rxnfc(struct net_device *dev, void __user *useraddr) { struct ethtool_rxnfc cmd; @@ -321,10 +312,7 @@ static noinline int ethtool_set_rxnfc(struct net_device *dev, void __user *usera return dev->ethtool_ops->set_rxnfc(dev, &cmd); } -/* - * noinline attribute so that gcc doesnt use too much stack in dev_ethtool() - */ -static noinline int ethtool_get_rxnfc(struct net_device *dev, void __user *useraddr) +static noinline_for_stack int ethtool_get_rxnfc(struct net_device *dev, void __user *useraddr) { struct ethtool_rxnfc info; const struct ethtool_ops *ops = dev->ethtool_ops; @@ -396,10 +384,7 @@ static void __rx_ntuple_filter_add(struct ethtool_rx_ntuple_list *list, list->count++; } -/* - * noinline attribute so that gcc doesnt use too much stack in dev_ethtool() - */ -static noinline int ethtool_set_rx_ntuple(struct net_device *dev, void __user *useraddr) +static noinline_for_stack int ethtool_set_rx_ntuple(struct net_device *dev, void __user *useraddr) { struct ethtool_rx_ntuple cmd; const struct ethtool_ops *ops = dev->ethtool_ops; @@ -867,10 +852,7 @@ static int ethtool_set_eeprom(struct net_device *dev, void __user *useraddr) return ret; } -/* - * noinline attribute so that gcc doesnt use too much stack in dev_ethtool() - */ -static noinline int ethtool_get_coalesce(struct net_device *dev, void __user *useraddr) +static noinline_for_stack int ethtool_get_coalesce(struct net_device *dev, void __user *useraddr) { struct ethtool_coalesce coalesce = { .cmd = ETHTOOL_GCOALESCE }; @@ -884,10 +866,7 @@ static noinline int ethtool_get_coalesce(struct net_device *dev, void __user *us return 0; } -/* - * noinline attribute so that gcc doesnt use too much stack in dev_ethtool() - */ -static noinline int ethtool_set_coalesce(struct net_device *dev, void __user *useraddr) +static noinline_for_stack int ethtool_set_coalesce(struct net_device *dev, void __user *useraddr) { struct ethtool_coalesce coalesce; @@ -1297,10 +1276,7 @@ static int ethtool_set_value(struct net_device *dev, char __user *useraddr, return actor(dev, edata.data); } -/* - * noinline attribute so that gcc doesnt use too much stack in dev_ethtool() - */ -static noinline int ethtool_flash_device(struct net_device *dev, char __user *useraddr) +static noinline_for_stack int ethtool_flash_device(struct net_device *dev, char __user *useraddr) { struct ethtool_flash efl; -- cgit v0.10.2 From d88dca79d3852a3623f606f781e013d61486828a Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Mon, 8 Mar 2010 12:20:58 -0800 Subject: tipc: fix endianness on tipc subscriber messages Remove htohl implementation from tipc I was working on forward porting the downstream commits for TIPC and ran accross this one: http://tipc.cslab.ericsson.net/cgi-bin/gitweb.cgi?p=people/allan/tipc.git;a=commitdiff;h=894279b9437b63cbb02405ad5b8e033b51e4e31e I was going to just take it, when I looked closer and noted what it was doing. This is basically a routine to byte swap fields of data in sent/received packets for tipc, dependent upon the receivers guessed endianness of the peer when a connection is established. Asside from just seeming silly to me, it appears to violate the latest RFC draft for tipc: http://tipc.sourceforge.net/doc/draft-spec-tipc-02.txt Which, according to section 4.2 and 4.3.3, requires that all fields of all commands be sent in network byte order. So instead of just taking this patch, instead I'm removing the htohl function and replacing the calls with calls to ntohl in the rx path and htonl in the send path. As part of this fix, I'm also changing the subscr_cancel function, which searches the list of subscribers, using a memcmp of the entire subscriber list, for the entry to tear down. unfortunately it memcmps the entire tipc_subscr structure which has several bits that are private to the local side, so nothing will ever match. section 5.2 of the draft spec indicates the tuple should uniquely identify a subscriber, so convert subscr_cancel to just match on those fields (properly endian swapped). I've tested this using the tipc test suite, and its passed without issue. Signed-off-by: Neil Horman Signed-off-by: David S. Miller diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c index ac91f0d..ff123e5 100644 --- a/net/tipc/subscr.c +++ b/net/tipc/subscr.c @@ -76,19 +76,6 @@ struct top_srv { static struct top_srv topsrv = { 0 }; /** - * htohl - convert value to endianness used by destination - * @in: value to convert - * @swap: non-zero if endianness must be reversed - * - * Returns converted value - */ - -static u32 htohl(u32 in, int swap) -{ - return swap ? swab32(in) : in; -} - -/** * subscr_send_event - send a message containing a tipc_event to the subscriber * * Note: Must not hold subscriber's server port lock, since tipc_send() will @@ -107,11 +94,11 @@ static void subscr_send_event(struct subscription *sub, msg_sect.iov_base = (void *)&sub->evt; msg_sect.iov_len = sizeof(struct tipc_event); - sub->evt.event = htohl(event, sub->swap); - sub->evt.found_lower = htohl(found_lower, sub->swap); - sub->evt.found_upper = htohl(found_upper, sub->swap); - sub->evt.port.ref = htohl(port_ref, sub->swap); - sub->evt.port.node = htohl(node, sub->swap); + sub->evt.event = htonl(event); + sub->evt.found_lower = htonl(found_lower); + sub->evt.found_upper = htonl(found_upper); + sub->evt.port.ref = htonl(port_ref); + sub->evt.port.node = htonl(node); tipc_send(sub->server_ref, 1, &msg_sect); } @@ -287,16 +274,23 @@ static void subscr_cancel(struct tipc_subscr *s, { struct subscription *sub; struct subscription *sub_temp; + __u32 type, lower, upper; int found = 0; /* Find first matching subscription, exit if not found */ + type = ntohl(s->seq.type); + lower = ntohl(s->seq.lower); + upper = ntohl(s->seq.upper); + list_for_each_entry_safe(sub, sub_temp, &subscriber->subscription_list, subscription_list) { - if (!memcmp(s, &sub->evt.s, sizeof(struct tipc_subscr))) { - found = 1; - break; - } + if ((type == sub->seq.type) && + (lower == sub->seq.lower) && + (upper == sub->seq.upper)) { + found = 1; + break; + } } if (!found) return; @@ -325,16 +319,10 @@ static struct subscription *subscr_subscribe(struct tipc_subscr *s, struct subscriber *subscriber) { struct subscription *sub; - int swap; - - /* Determine subscriber's endianness */ - - swap = !(s->filter & (TIPC_SUB_PORTS | TIPC_SUB_SERVICE)); /* Detect & process a subscription cancellation request */ - if (s->filter & htohl(TIPC_SUB_CANCEL, swap)) { - s->filter &= ~htohl(TIPC_SUB_CANCEL, swap); + if (ntohl(s->filter) & TIPC_SUB_CANCEL) { subscr_cancel(s, subscriber); return NULL; } @@ -359,11 +347,11 @@ static struct subscription *subscr_subscribe(struct tipc_subscr *s, /* Initialize subscription object */ - sub->seq.type = htohl(s->seq.type, swap); - sub->seq.lower = htohl(s->seq.lower, swap); - sub->seq.upper = htohl(s->seq.upper, swap); - sub->timeout = htohl(s->timeout, swap); - sub->filter = htohl(s->filter, swap); + sub->seq.type = ntohl(s->seq.type); + sub->seq.lower = ntohl(s->seq.lower); + sub->seq.upper = ntohl(s->seq.upper); + sub->timeout = ntohl(s->timeout); + sub->filter = ntohl(s->filter); if ((!(sub->filter & TIPC_SUB_PORTS) == !(sub->filter & TIPC_SUB_SERVICE)) || (sub->seq.lower > sub->seq.upper)) { @@ -376,7 +364,6 @@ static struct subscription *subscr_subscribe(struct tipc_subscr *s, INIT_LIST_HEAD(&sub->nameseq_list); list_add(&sub->subscription_list, &subscriber->subscription_list); sub->server_ref = subscriber->port_ref; - sub->swap = swap; memcpy(&sub->evt.s, s, sizeof(struct tipc_subscr)); atomic_inc(&topsrv.subscription_count); if (sub->timeout != TIPC_WAIT_FOREVER) { diff --git a/net/tipc/subscr.h b/net/tipc/subscr.h index 45d89bf..c20f496 100644 --- a/net/tipc/subscr.h +++ b/net/tipc/subscr.h @@ -53,7 +53,6 @@ typedef void (*tipc_subscr_event) (struct subscription *sub, * @nameseq_list: adjacent subscriptions in name sequence's subscription list * @subscription_list: adjacent subscriptions in subscriber's subscription list * @server_ref: object reference of server port associated with subscription - * @swap: indicates if subscriber uses opposite endianness in its messages * @evt: template for events generated by subscription */ @@ -66,7 +65,6 @@ struct subscription { struct list_head nameseq_list; struct list_head subscription_list; u32 server_ref; - int swap; struct tipc_event evt; }; -- cgit v0.10.2 From de5865714621e23d65c52955ca2125dbb074c242 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Mon, 8 Mar 2010 12:43:56 -0800 Subject: tipc: filter out messages not intended for this host Port commit 20deb48d16fdd07ce2fdc8d03ea317362217e085 from git://tipc.cslab.ericsson.net/pub/git/people/allan/tipc.git Part of the large effort I'm trying to help with getting all the downstreamed code from windriver forward ported to the upstream tree Origional commit message Restore check to filter out inadverdently received messages This patch reimplements a check that allows TIPC to discard messages that are not intended for it. This check was present in TIPC 1.5/1.6, but was removed by accident during the development of TIPC 1.7; it has now been updated to account for new features present in TIPC 1.7 and reinserted into TIPC. The main benefit of this check is to filter out messages arriving from orphaned link endpoints, which can arise when a node exits the network and then re-enters it with a different TIPC network address (i.e. value). Signed-off-by: Neil Horman Origionally-authored-by: Allan Stephens Signed-off-by: David S. Miller diff --git a/net/tipc/link.c b/net/tipc/link.c index 6f50f64..1a7e466 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -1882,6 +1882,15 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr) (msg_destnode(msg) != tipc_own_addr))) goto cont; + /* Discard non-routeable messages destined for another node */ + + if (unlikely(!msg_isdata(msg) && + (msg_destnode(msg) != tipc_own_addr))) { + if ((msg_user(msg) != CONN_MANAGER) && + (msg_user(msg) != MSG_FRAGMENTER)) + goto cont; + } + /* Locate unicast link endpoint that should handle message */ n_ptr = tipc_node_find(msg_prevnode(msg)); -- cgit v0.10.2 From 42d38041a94cef1e38f7b8ab9827881022a183a9 Mon Sep 17 00:00:00 2001 From: Wolfgang Grandegger Date: Mon, 8 Mar 2010 12:51:41 -0800 Subject: MAINTAINERS: add netdev to CAN network layer and drivers entries Signed-off-by: Wolfgang Grandegger Signed-off-by: David S. Miller diff --git a/MAINTAINERS b/MAINTAINERS index 66418dd..c685ee2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1376,6 +1376,7 @@ M: Oliver Hartkopp M: Oliver Hartkopp M: Urs Thuermann L: socketcan-core@lists.berlios.de +L: netdev@vger.kernel.org W: http://developer.berlios.de/projects/socketcan/ S: Maintained F: net/can/ @@ -1387,6 +1388,7 @@ F: include/linux/can/raw.h CAN NETWORK DRIVERS M: Wolfgang Grandegger L: socketcan-core@lists.berlios.de +L: netdev@vger.kernel.org W: http://developer.berlios.de/projects/socketcan/ S: Maintained F: drivers/net/can/ -- cgit v0.10.2 From 6bd1fbea2e8bff9346a5afb44ca948b4e4ed74a5 Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Wed, 9 Sep 2009 10:46:19 +0000 Subject: Blackfin: move on-chip UART resources to boards files Rather than keeping the pins in the actual driver and worrying about a mess of Kconfig options, declare all the desired pin resources in the boards file. This lets people easily select the specific pins/ports for the normal UART as well as GPIOs for CTS/RTS. Signed-off-by: Sonic Zhang Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf518/boards/ezbrd.c b/arch/blackfin/mach-bf518/boards/ezbrd.c index 01975c0..0d1b021 100644 --- a/arch/blackfin/mach-bf518/boards/ezbrd.c +++ b/arch/blackfin/mach-bf518/boards/ezbrd.c @@ -382,30 +382,93 @@ static struct platform_device bfin_spi1_device = { #endif /* spi master and devices */ #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) -static struct resource bfin_uart_resources[] = { #ifdef CONFIG_SERIAL_BFIN_UART0 +static struct resource bfin_uart0_resources[] = { { - .start = 0xFFC00400, - .end = 0xFFC004FF, + .start = UART0_THR, + .end = UART0_GCTL+2, .flags = IORESOURCE_MEM, }, + { + .start = IRQ_UART0_RX, + .end = IRQ_UART0_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART0_ERROR, + .end = IRQ_UART0_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART0_TX, + .end = CH_UART0_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART0_RX, + .end = CH_UART0_RX, + .flags = IORESOURCE_DMA, + }, +}; + +unsigned short bfin_uart0_peripherals[] = { + P_UART0_TX, P_UART0_RX, 0 +}; + +static struct platform_device bfin_uart0_device = { + .name = "bfin-uart", + .id = 0, + .num_resources = ARRAY_SIZE(bfin_uart0_resources), + .resource = bfin_uart0_resources, + .dev = { + .platform_data = &bfin_uart0_peripherals, /* Passed to driver */ + }, +}; #endif #ifdef CONFIG_SERIAL_BFIN_UART1 +static struct resource bfin_uart1_resources[] = { { - .start = 0xFFC02000, - .end = 0xFFC020FF, + .start = UART1_THR, + .end = UART1_GCTL+2, .flags = IORESOURCE_MEM, }, -#endif + { + .start = IRQ_UART1_RX, + .end = IRQ_UART1_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART1_ERROR, + .end = IRQ_UART1_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART1_TX, + .end = CH_UART1_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART1_RX, + .end = CH_UART1_RX, + .flags = IORESOURCE_DMA, + }, }; -static struct platform_device bfin_uart_device = { +unsigned short bfin_uart1_peripherals[] = { + P_UART1_TX, P_UART1_RX, 0 +}; + +static struct platform_device bfin_uart1_device = { .name = "bfin-uart", .id = 1, - .num_resources = ARRAY_SIZE(bfin_uart_resources), - .resource = bfin_uart_resources, + .num_resources = ARRAY_SIZE(bfin_uart1_resources), + .resource = bfin_uart1_resources, + .dev = { + .platform_data = &bfin_uart1_peripherals, /* Passed to driver */ + }, }; #endif +#endif #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) #ifdef CONFIG_BFIN_SIR0 @@ -593,7 +656,12 @@ static struct platform_device *stamp_devices[] __initdata = { #endif #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) - &bfin_uart_device, +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART1 + &bfin_uart1_device, +#endif #endif #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) diff --git a/arch/blackfin/mach-bf527/boards/cm_bf527.c b/arch/blackfin/mach-bf527/boards/cm_bf527.c index 7ab0800..2d93c1f 100644 --- a/arch/blackfin/mach-bf527/boards/cm_bf527.c +++ b/arch/blackfin/mach-bf527/boards/cm_bf527.c @@ -603,30 +603,105 @@ static struct platform_device cm_flash_device = { #endif #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) -static struct resource bfin_uart_resources[] = { #ifdef CONFIG_SERIAL_BFIN_UART0 +static struct resource bfin_uart0_resources[] = { { - .start = 0xFFC00400, - .end = 0xFFC004FF, + .start = UART0_THR, + .end = UART0_GCTL+2, .flags = IORESOURCE_MEM, }, + { + .start = IRQ_UART0_RX, + .end = IRQ_UART0_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART0_ERROR, + .end = IRQ_UART0_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART0_TX, + .end = CH_UART0_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART0_RX, + .end = CH_UART0_RX, + .flags = IORESOURCE_DMA, + }, +}; + +unsigned short bfin_uart0_peripherals[] = { + P_UART0_TX, P_UART0_RX, 0 +}; + +static struct platform_device bfin_uart0_device = { + .name = "bfin-uart", + .id = 0, + .num_resources = ARRAY_SIZE(bfin_uart0_resources), + .resource = bfin_uart0_resources, + .dev = { + .platform_data = &bfin_uart0_peripherals, /* Passed to driver */ + }, +}; #endif #ifdef CONFIG_SERIAL_BFIN_UART1 +static struct resource bfin_uart1_resources[] = { { - .start = 0xFFC02000, - .end = 0xFFC020FF, + .start = UART1_THR, + .end = UART1_GCTL+2, .flags = IORESOURCE_MEM, }, + { + .start = IRQ_UART1_RX, + .end = IRQ_UART1_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART1_ERROR, + .end = IRQ_UART1_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART1_TX, + .end = CH_UART1_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART1_RX, + .end = CH_UART1_RX, + .flags = IORESOURCE_DMA, + }, +#ifdef CONFIG_BFIN_UART1_CTSRTS + { /* CTS pin */ + .start = GPIO_PF9, + .end = GPIO_PF9, + .flags = IORESOURCE_IO, + }, + { /* RTS pin */ + .start = GPIO_PF10, + .end = GPIO_PF10, + .flags = IORESOURCE_IO, + }, #endif }; -static struct platform_device bfin_uart_device = { +unsigned short bfin_uart1_peripherals[] = { + P_UART1_TX, P_UART1_RX, 0 +}; + +static struct platform_device bfin_uart1_device = { .name = "bfin-uart", .id = 1, - .num_resources = ARRAY_SIZE(bfin_uart_resources), - .resource = bfin_uart_resources, + .num_resources = ARRAY_SIZE(bfin_uart1_resources), + .resource = bfin_uart1_resources, + .dev = { + .platform_data = &bfin_uart1_peripherals, /* Passed to driver */ + }, }; #endif +#endif #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) #ifdef CONFIG_BFIN_SIR0 @@ -829,7 +904,12 @@ static struct platform_device *cmbf527_devices[] __initdata = { #endif #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) - &bfin_uart_device, +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART1 + &bfin_uart1_device, +#endif #endif #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) diff --git a/arch/blackfin/mach-bf527/boards/ezbrd.c b/arch/blackfin/mach-bf527/boards/ezbrd.c index cad23b1..3a981e8 100644 --- a/arch/blackfin/mach-bf527/boards/ezbrd.c +++ b/arch/blackfin/mach-bf527/boards/ezbrd.c @@ -439,30 +439,105 @@ static struct platform_device bfin_spi0_device = { #endif /* spi master and devices */ #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) -static struct resource bfin_uart_resources[] = { #ifdef CONFIG_SERIAL_BFIN_UART0 +static struct resource bfin_uart0_resources[] = { { - .start = 0xFFC00400, - .end = 0xFFC004FF, + .start = UART0_THR, + .end = UART0_GCTL+2, .flags = IORESOURCE_MEM, }, + { + .start = IRQ_UART0_RX, + .end = IRQ_UART0_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART0_ERROR, + .end = IRQ_UART0_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART0_TX, + .end = CH_UART0_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART0_RX, + .end = CH_UART0_RX, + .flags = IORESOURCE_DMA, + }, +}; + +unsigned short bfin_uart0_peripherals[] = { + P_UART0_TX, P_UART0_RX, 0 +}; + +static struct platform_device bfin_uart0_device = { + .name = "bfin-uart", + .id = 0, + .num_resources = ARRAY_SIZE(bfin_uart0_resources), + .resource = bfin_uart0_resources, + .dev = { + .platform_data = &bfin_uart0_peripherals, /* Passed to driver */ + }, +}; #endif #ifdef CONFIG_SERIAL_BFIN_UART1 +static struct resource bfin_uart1_resources[] = { { - .start = 0xFFC02000, - .end = 0xFFC020FF, + .start = UART1_THR, + .end = UART1_GCTL+2, .flags = IORESOURCE_MEM, }, + { + .start = IRQ_UART1_RX, + .end = IRQ_UART1_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART1_ERROR, + .end = IRQ_UART1_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART1_TX, + .end = CH_UART1_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART1_RX, + .end = CH_UART1_RX, + .flags = IORESOURCE_DMA, + }, +#ifdef CONFIG_BFIN_UART1_CTSRTS + { /* CTS pin */ + .start = GPIO_PG0, + .end = GPIO_PG0, + .flags = IORESOURCE_IO, + }, + { /* RTS pin */ + .start = GPIO_PF10, + .end = GPIO_PF10, + .flags = IORESOURCE_IO, + }, #endif }; -static struct platform_device bfin_uart_device = { +unsigned short bfin_uart1_peripherals[] = { + P_UART1_TX, P_UART1_RX, 0 +}; + +static struct platform_device bfin_uart1_device = { .name = "bfin-uart", .id = 1, - .num_resources = ARRAY_SIZE(bfin_uart_resources), - .resource = bfin_uart_resources, + .num_resources = ARRAY_SIZE(bfin_uart1_resources), + .resource = bfin_uart1_resources, + .dev = { + .platform_data = &bfin_uart1_peripherals, /* Passed to driver */ + }, }; #endif +#endif #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) #ifdef CONFIG_BFIN_SIR0 @@ -665,7 +740,12 @@ static struct platform_device *stamp_devices[] __initdata = { #endif #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) - &bfin_uart_device, +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART1 + &bfin_uart1_device, +#endif #endif #if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE) diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c index 5294fdd..0750e65 100644 --- a/arch/blackfin/mach-bf527/boards/ezkit.c +++ b/arch/blackfin/mach-bf527/boards/ezkit.c @@ -647,30 +647,105 @@ static struct platform_device bfin_spi0_device = { #endif /* spi master and devices */ #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) -static struct resource bfin_uart_resources[] = { #ifdef CONFIG_SERIAL_BFIN_UART0 +static struct resource bfin_uart0_resources[] = { { - .start = 0xFFC00400, - .end = 0xFFC004FF, + .start = UART0_THR, + .end = UART0_GCTL+2, .flags = IORESOURCE_MEM, }, + { + .start = IRQ_UART0_RX, + .end = IRQ_UART0_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART0_ERROR, + .end = IRQ_UART0_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART0_TX, + .end = CH_UART0_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART0_RX, + .end = CH_UART0_RX, + .flags = IORESOURCE_DMA, + }, +}; + +unsigned short bfin_uart0_peripherals[] = { + P_UART0_TX, P_UART0_RX, 0 +}; + +static struct platform_device bfin_uart0_device = { + .name = "bfin-uart", + .id = 0, + .num_resources = ARRAY_SIZE(bfin_uart0_resources), + .resource = bfin_uart0_resources, + .dev = { + .platform_data = &bfin_uart0_peripherals, /* Passed to driver */ + }, +}; #endif #ifdef CONFIG_SERIAL_BFIN_UART1 +static struct resource bfin_uart1_resources[] = { { - .start = 0xFFC02000, - .end = 0xFFC020FF, + .start = UART1_THR, + .end = UART1_GCTL+2, .flags = IORESOURCE_MEM, }, + { + .start = IRQ_UART1_RX, + .end = IRQ_UART1_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART1_ERROR, + .end = IRQ_UART1_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART1_TX, + .end = CH_UART1_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART1_RX, + .end = CH_UART1_RX, + .flags = IORESOURCE_DMA, + }, +#ifdef CONFIG_BFIN_UART1_CTSRTS + { /* CTS pin */ + .start = GPIO_PF9, + .end = GPIO_PF9, + .flags = IORESOURCE_IO, + }, + { /* RTS pin */ + .start = GPIO_PF10, + .end = GPIO_PF10, + .flags = IORESOURCE_IO, + }, #endif }; -static struct platform_device bfin_uart_device = { +unsigned short bfin_uart1_peripherals[] = { + P_UART1_TX, P_UART1_RX, 0 +}; + +static struct platform_device bfin_uart1_device = { .name = "bfin-uart", .id = 1, - .num_resources = ARRAY_SIZE(bfin_uart_resources), - .resource = bfin_uart_resources, + .num_resources = ARRAY_SIZE(bfin_uart1_resources), + .resource = bfin_uart1_resources, + .dev = { + .platform_data = &bfin_uart1_peripherals, /* Passed to driver */ + }, }; #endif +#endif #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) #ifdef CONFIG_BFIN_SIR0 @@ -910,7 +985,12 @@ static struct platform_device *stamp_devices[] __initdata = { #endif #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) - &bfin_uart_device, +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART1 + &bfin_uart1_device, +#endif #endif #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) diff --git a/arch/blackfin/mach-bf533/boards/H8606.c b/arch/blackfin/mach-bf533/boards/H8606.c index 4adceb0..cb3b74f 100644 --- a/arch/blackfin/mach-bf533/boards/H8606.c +++ b/arch/blackfin/mach-bf533/boards/H8606.c @@ -257,21 +257,50 @@ static struct platform_device bfin_spi0_device = { #endif /* spi master and devices */ #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) -static struct resource bfin_uart_resources[] = { +#ifdef CONFIG_SERIAL_BFIN_UART0 +static struct resource bfin_uart0_resources[] = { { - .start = 0xFFC00400, - .end = 0xFFC004FF, + .start = BFIN_UART_THR, + .end = BFIN_UART_GCTL+2, .flags = IORESOURCE_MEM, }, + { + .start = IRQ_UART0_RX, + .end = IRQ_UART0_RX + 1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART0_ERROR, + .end = IRQ_UART0_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART0_TX, + .end = CH_UART0_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART0_RX, + .end = CH_UART0_RX, + .flags = IORESOURCE_DMA, + }, +}; + +unsigned short bfin_uart0_peripherals[] = { + P_UART0_TX, P_UART0_RX, 0 }; -static struct platform_device bfin_uart_device = { +static struct platform_device bfin_uart0_device = { .name = "bfin-uart", - .id = 1, - .num_resources = ARRAY_SIZE(bfin_uart_resources), - .resource = bfin_uart_resources, + .id = 0, + .num_resources = ARRAY_SIZE(bfin_uart0_resources), + .resource = bfin_uart0_resources, + .dev = { + .platform_data = &bfin_uart0_peripherals, /* Passed to driver */ + }, }; #endif +#endif #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) #ifdef CONFIG_BFIN_SIR0 @@ -394,7 +423,9 @@ static struct platform_device *h8606_devices[] __initdata = { #endif #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) - &bfin_uart_device, +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif #endif #if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE) diff --git a/arch/blackfin/mach-bf533/boards/blackstamp.c b/arch/blackfin/mach-bf533/boards/blackstamp.c index b580884..50ce3ec 100644 --- a/arch/blackfin/mach-bf533/boards/blackstamp.c +++ b/arch/blackfin/mach-bf533/boards/blackstamp.c @@ -195,21 +195,50 @@ static struct platform_device bfin_spi0_device = { #endif /* spi master and devices */ #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) -static struct resource bfin_uart_resources[] = { +#ifdef CONFIG_SERIAL_BFIN_UART0 +static struct resource bfin_uart0_resources[] = { { - .start = 0xFFC00400, - .end = 0xFFC004FF, + .start = BFIN_UART_THR, + .end = BFIN_UART_GCTL+2, .flags = IORESOURCE_MEM, }, + { + .start = IRQ_UART0_RX, + .end = IRQ_UART0_RX + 1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART0_ERROR, + .end = IRQ_UART0_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART0_TX, + .end = CH_UART0_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART0_RX, + .end = CH_UART0_RX, + .flags = IORESOURCE_DMA, + }, +}; + +unsigned short bfin_uart0_peripherals[] = { + P_UART0_TX, P_UART0_RX, 0 }; -static struct platform_device bfin_uart_device = { +static struct platform_device bfin_uart0_device = { .name = "bfin-uart", - .id = 1, - .num_resources = ARRAY_SIZE(bfin_uart_resources), - .resource = bfin_uart_resources, + .id = 0, + .num_resources = ARRAY_SIZE(bfin_uart0_resources), + .resource = bfin_uart0_resources, + .dev = { + .platform_data = &bfin_uart0_peripherals, /* Passed to driver */ + }, }; #endif +#endif #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) #ifdef CONFIG_BFIN_SIR0 @@ -344,7 +373,9 @@ static struct platform_device *stamp_devices[] __initdata = { #endif #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) - &bfin_uart_device, +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif #endif #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) diff --git a/arch/blackfin/mach-bf533/boards/cm_bf533.c b/arch/blackfin/mach-bf533/boards/cm_bf533.c index 7fc3b86..f707faf 100644 --- a/arch/blackfin/mach-bf533/boards/cm_bf533.c +++ b/arch/blackfin/mach-bf533/boards/cm_bf533.c @@ -242,21 +242,50 @@ static struct platform_device smsc911x_device = { #endif #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) -static struct resource bfin_uart_resources[] = { +#ifdef CONFIG_SERIAL_BFIN_UART0 +static struct resource bfin_uart0_resources[] = { { - .start = 0xFFC00400, - .end = 0xFFC004FF, + .start = BFIN_UART_THR, + .end = BFIN_UART_GCTL+2, .flags = IORESOURCE_MEM, }, + { + .start = IRQ_UART0_RX, + .end = IRQ_UART0_RX + 1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART0_ERROR, + .end = IRQ_UART0_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART0_TX, + .end = CH_UART0_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART0_RX, + .end = CH_UART0_RX, + .flags = IORESOURCE_DMA, + }, +}; + +unsigned short bfin_uart0_peripherals[] = { + P_UART0_TX, P_UART0_RX, 0 }; -static struct platform_device bfin_uart_device = { +static struct platform_device bfin_uart0_device = { .name = "bfin-uart", - .id = 1, - .num_resources = ARRAY_SIZE(bfin_uart_resources), - .resource = bfin_uart_resources, + .id = 0, + .num_resources = ARRAY_SIZE(bfin_uart0_resources), + .resource = bfin_uart0_resources, + .dev = { + .platform_data = &bfin_uart0_peripherals, /* Passed to driver */ + }, }; #endif +#endif #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) #ifdef CONFIG_BFIN_SIR0 @@ -432,7 +461,9 @@ static struct platform_device *cm_bf533_devices[] __initdata = { &bfin_dpmc, #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) - &bfin_uart_device, +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif #endif #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) diff --git a/arch/blackfin/mach-bf533/boards/ezkit.c b/arch/blackfin/mach-bf533/boards/ezkit.c index d4689dc..5039247 100644 --- a/arch/blackfin/mach-bf533/boards/ezkit.c +++ b/arch/blackfin/mach-bf533/boards/ezkit.c @@ -320,21 +320,50 @@ static struct platform_device bfin_spi0_device = { #endif /* spi master and devices */ #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) -static struct resource bfin_uart_resources[] = { +#ifdef CONFIG_SERIAL_BFIN_UART0 +static struct resource bfin_uart0_resources[] = { { - .start = 0xFFC00400, - .end = 0xFFC004FF, + .start = BFIN_UART_THR, + .end = BFIN_UART_GCTL+2, .flags = IORESOURCE_MEM, }, + { + .start = IRQ_UART0_RX, + .end = IRQ_UART0_RX + 1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART0_ERROR, + .end = IRQ_UART0_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART0_TX, + .end = CH_UART0_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART0_RX, + .end = CH_UART0_RX, + .flags = IORESOURCE_DMA, + }, +}; + +unsigned short bfin_uart0_peripherals[] = { + P_UART0_TX, P_UART0_RX, 0 }; -static struct platform_device bfin_uart_device = { +static struct platform_device bfin_uart0_device = { .name = "bfin-uart", - .id = 1, - .num_resources = ARRAY_SIZE(bfin_uart_resources), - .resource = bfin_uart_resources, + .id = 0, + .num_resources = ARRAY_SIZE(bfin_uart0_resources), + .resource = bfin_uart0_resources, + .dev = { + .platform_data = &bfin_uart0_peripherals, /* Passed to driver */ + }, }; #endif +#endif #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) #ifdef CONFIG_BFIN_SIR0 @@ -471,7 +500,9 @@ static struct platform_device *ezkit_devices[] __initdata = { #endif #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) - &bfin_uart_device, +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif #endif #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) diff --git a/arch/blackfin/mach-bf533/boards/ip0x.c b/arch/blackfin/mach-bf533/boards/ip0x.c index 8ec42ba..a60d036 100644 --- a/arch/blackfin/mach-bf533/boards/ip0x.c +++ b/arch/blackfin/mach-bf533/boards/ip0x.c @@ -19,6 +19,7 @@ #include #endif #include +#include #include #include @@ -143,21 +144,50 @@ static struct platform_device spi_bfin_master_device = { #endif /* spi master and devices */ #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) -static struct resource bfin_uart_resources[] = { +#ifdef CONFIG_SERIAL_BFIN_UART0 +static struct resource bfin_uart0_resources[] = { { - .start = 0xFFC00400, - .end = 0xFFC004FF, + .start = BFIN_UART_THR, + .end = BFIN_UART_GCTL+2, .flags = IORESOURCE_MEM, }, + { + .start = IRQ_UART0_RX, + .end = IRQ_UART0_RX + 1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART0_ERROR, + .end = IRQ_UART0_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART0_TX, + .end = CH_UART0_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART0_RX, + .end = CH_UART0_RX, + .flags = IORESOURCE_DMA, + }, +}; + +unsigned short bfin_uart0_peripherals[] = { + P_UART0_TX, P_UART0_RX, 0 }; -static struct platform_device bfin_uart_device = { +static struct platform_device bfin_uart0_device = { .name = "bfin-uart", - .id = 1, - .num_resources = ARRAY_SIZE(bfin_uart_resources), - .resource = bfin_uart_resources, + .id = 0, + .num_resources = ARRAY_SIZE(bfin_uart0_resources), + .resource = bfin_uart0_resources, + .dev = { + .platform_data = &bfin_uart0_peripherals, /* Passed to driver */ + }, }; #endif +#endif #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) #ifdef CONFIG_BFIN_SIR0 @@ -241,7 +271,9 @@ static struct platform_device *ip0x_devices[] __initdata = { #endif #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) - &bfin_uart_device, +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif #endif #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) diff --git a/arch/blackfin/mach-bf533/boards/stamp.c b/arch/blackfin/mach-bf533/boards/stamp.c index 6d68dcf..2683e5f 100644 --- a/arch/blackfin/mach-bf533/boards/stamp.c +++ b/arch/blackfin/mach-bf533/boards/stamp.c @@ -322,21 +322,50 @@ static struct platform_device bfin_spi0_device = { #endif /* spi master and devices */ #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) -static struct resource bfin_uart_resources[] = { +#ifdef CONFIG_SERIAL_BFIN_UART0 +static struct resource bfin_uart0_resources[] = { { - .start = 0xFFC00400, - .end = 0xFFC004FF, + .start = BFIN_UART_THR, + .end = BFIN_UART_GCTL+2, .flags = IORESOURCE_MEM, }, + { + .start = IRQ_UART0_RX, + .end = IRQ_UART0_RX + 1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART0_ERROR, + .end = IRQ_UART0_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART0_TX, + .end = CH_UART0_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART0_RX, + .end = CH_UART0_RX, + .flags = IORESOURCE_DMA, + }, +}; + +unsigned short bfin_uart0_peripherals[] = { + P_UART0_TX, P_UART0_RX, 0 }; -static struct platform_device bfin_uart_device = { +static struct platform_device bfin_uart0_device = { .name = "bfin-uart", - .id = 1, - .num_resources = ARRAY_SIZE(bfin_uart_resources), - .resource = bfin_uart_resources, + .id = 0, + .num_resources = ARRAY_SIZE(bfin_uart0_resources), + .resource = bfin_uart0_resources, + .dev = { + .platform_data = &bfin_uart0_peripherals, /* Passed to driver */ + }, }; #endif +#endif #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) #ifdef CONFIG_BFIN_SIR0 @@ -495,7 +524,9 @@ static struct platform_device *stamp_devices[] __initdata = { #endif #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) - &bfin_uart_device, +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif #endif #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537e.c b/arch/blackfin/mach-bf537/boards/cm_bf537e.c index c85f4d7..abb32dd 100644 --- a/arch/blackfin/mach-bf537/boards/cm_bf537e.c +++ b/arch/blackfin/mach-bf537/boards/cm_bf537e.c @@ -329,8 +329,8 @@ static struct platform_device cm_flash_device = { #ifdef CONFIG_SERIAL_BFIN_UART0 static struct resource bfin_uart0_resources[] = { { - .start = 0xFFC00400, - .end = 0xFFC004FF, + .start = UART0_THR, + .end = UART0_GCTL+2, .flags = IORESOURCE_MEM, }, { @@ -373,18 +373,25 @@ static struct resource bfin_uart0_resources[] = { #endif }; +unsigned short bfin_uart0_peripherals[] = { + P_UART0_TX, P_UART0_RX, 0 +}; + static struct platform_device bfin_uart0_device = { .name = "bfin-uart", .id = 0, .num_resources = ARRAY_SIZE(bfin_uart0_resources), .resource = bfin_uart0_resources, + .dev = { + .platform_data = &bfin_uart0_peripherals, /* Passed to driver */ + }, }; #endif #ifdef CONFIG_SERIAL_BFIN_UART1 static struct resource bfin_uart1_resources[] = { { - .start = 0xFFC02000, - .end = 0xFFC020FF, + .start = UART1_THR, + .end = UART1_GCTL+2, .flags = IORESOURCE_MEM, }, { @@ -427,11 +434,18 @@ static struct resource bfin_uart1_resources[] = { #endif }; +unsigned short bfin_uart1_peripherals[] = { + P_UART1_TX, P_UART1_RX, 0 +}; + static struct platform_device bfin_uart1_device = { .name = "bfin-uart", .id = 1, .num_resources = ARRAY_SIZE(bfin_uart1_resources), .resource = bfin_uart1_resources, + .dev = { + .platform_data = &bfin_uart1_peripherals, /* Passed to driver */ + }, }; #endif #endif diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537u.c b/arch/blackfin/mach-bf537/boards/cm_bf537u.c index ea11aa8..b3182fa 100644 --- a/arch/blackfin/mach-bf537/boards/cm_bf537u.c +++ b/arch/blackfin/mach-bf537/boards/cm_bf537u.c @@ -327,25 +327,93 @@ static struct platform_device cm_flash_device = { #endif #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) -static struct resource bfin_uart_resources[] = { +#ifdef CONFIG_SERIAL_BFIN_UART0 +static struct resource bfin_uart0_resources[] = { { - .start = 0xFFC00400, - .end = 0xFFC004FF, + .start = UART0_THR, + .end = UART0_GCTL+2, .flags = IORESOURCE_MEM, - }, { - .start = 0xFFC02000, - .end = 0xFFC020FF, + }, + { + .start = IRQ_UART0_RX, + .end = IRQ_UART0_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART0_ERROR, + .end = IRQ_UART0_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART0_TX, + .end = CH_UART0_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART0_RX, + .end = CH_UART0_RX, + .flags = IORESOURCE_DMA, + }, +}; + +unsigned short bfin_uart0_peripherals[] = { + P_UART0_TX, P_UART0_RX, 0 +}; + +static struct platform_device bfin_uart0_device = { + .name = "bfin-uart", + .id = 0, + .num_resources = ARRAY_SIZE(bfin_uart0_resources), + .resource = bfin_uart0_resources, + .dev = { + .platform_data = &bfin_uart0_peripherals, /* Passed to driver */ + }, +}; +#endif +#ifdef CONFIG_SERIAL_BFIN_UART1 +static struct resource bfin_uart1_resources[] = { + { + .start = UART1_THR, + .end = UART1_GCTL+2, .flags = IORESOURCE_MEM, }, + { + .start = IRQ_UART1_RX, + .end = IRQ_UART1_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART1_ERROR, + .end = IRQ_UART1_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART1_TX, + .end = CH_UART1_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART1_RX, + .end = CH_UART1_RX, + .flags = IORESOURCE_DMA, + }, }; -static struct platform_device bfin_uart_device = { +unsigned short bfin_uart1_peripherals[] = { + P_UART1_TX, P_UART1_RX, 0 +}; + +static struct platform_device bfin_uart1_device = { .name = "bfin-uart", .id = 1, - .num_resources = ARRAY_SIZE(bfin_uart_resources), - .resource = bfin_uart_resources, + .num_resources = ARRAY_SIZE(bfin_uart1_resources), + .resource = bfin_uart1_resources, + .dev = { + .platform_data = &bfin_uart1_peripherals, /* Passed to driver */ + }, }; #endif +#endif #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) #ifdef CONFIG_BFIN_SIR0 @@ -522,7 +590,12 @@ static struct platform_device *cm_bf537u_devices[] __initdata = { #endif #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) - &bfin_uart_device, +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART1 + &bfin_uart1_device, +#endif #endif #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) diff --git a/arch/blackfin/mach-bf537/boards/minotaur.c b/arch/blackfin/mach-bf537/boards/minotaur.c index 0da9272..58d6a20 100644 --- a/arch/blackfin/mach-bf537/boards/minotaur.c +++ b/arch/blackfin/mach-bf537/boards/minotaur.c @@ -211,25 +211,93 @@ static struct platform_device bfin_spi0_device = { #endif /* spi master and devices */ #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) -static struct resource bfin_uart_resources[] = { +#ifdef CONFIG_SERIAL_BFIN_UART0 +static struct resource bfin_uart0_resources[] = { { - .start = 0xFFC00400, - .end = 0xFFC004FF, + .start = UART0_THR, + .end = UART0_GCTL+2, .flags = IORESOURCE_MEM, - }, { - .start = 0xFFC02000, - .end = 0xFFC020FF, + }, + { + .start = IRQ_UART0_RX, + .end = IRQ_UART0_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART0_ERROR, + .end = IRQ_UART0_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART0_TX, + .end = CH_UART0_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART0_RX, + .end = CH_UART0_RX, + .flags = IORESOURCE_DMA, + }, +}; + +unsigned short bfin_uart0_peripherals[] = { + P_UART0_TX, P_UART0_RX, 0 +}; + +static struct platform_device bfin_uart0_device = { + .name = "bfin-uart", + .id = 0, + .num_resources = ARRAY_SIZE(bfin_uart0_resources), + .resource = bfin_uart0_resources, + .dev = { + .platform_data = &bfin_uart0_peripherals, /* Passed to driver */ + }, +}; +#endif +#ifdef CONFIG_SERIAL_BFIN_UART1 +static struct resource bfin_uart1_resources[] = { + { + .start = UART1_THR, + .end = UART1_GCTL+2, .flags = IORESOURCE_MEM, }, + { + .start = IRQ_UART1_RX, + .end = IRQ_UART1_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART1_ERROR, + .end = IRQ_UART1_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART1_TX, + .end = CH_UART1_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART1_RX, + .end = CH_UART1_RX, + .flags = IORESOURCE_DMA, + }, }; -static struct platform_device bfin_uart_device = { +unsigned short bfin_uart1_peripherals[] = { + P_UART1_TX, P_UART1_RX, 0 +}; + +static struct platform_device bfin_uart1_device = { .name = "bfin-uart", .id = 1, - .num_resources = ARRAY_SIZE(bfin_uart_resources), - .resource = bfin_uart_resources, + .num_resources = ARRAY_SIZE(bfin_uart1_resources), + .resource = bfin_uart1_resources, + .dev = { + .platform_data = &bfin_uart1_peripherals, /* Passed to driver */ + }, }; #endif +#endif #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) #ifdef CONFIG_BFIN_SIR0 @@ -343,7 +411,12 @@ static struct platform_device *minotaur_devices[] __initdata = { #endif #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) - &bfin_uart_device, +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART1 + &bfin_uart1_device, +#endif #endif #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) diff --git a/arch/blackfin/mach-bf537/boards/pnav10.c b/arch/blackfin/mach-bf537/boards/pnav10.c index 4e0afda..3c36abd 100644 --- a/arch/blackfin/mach-bf537/boards/pnav10.c +++ b/arch/blackfin/mach-bf537/boards/pnav10.c @@ -362,25 +362,93 @@ static struct platform_device bfin_fb_device = { #endif #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) -static struct resource bfin_uart_resources[] = { +#ifdef CONFIG_SERIAL_BFIN_UART0 +static struct resource bfin_uart0_resources[] = { { - .start = 0xFFC00400, - .end = 0xFFC004FF, + .start = UART0_THR, + .end = UART0_GCTL+2, .flags = IORESOURCE_MEM, - }, { - .start = 0xFFC02000, - .end = 0xFFC020FF, + }, + { + .start = IRQ_UART0_RX, + .end = IRQ_UART0_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART0_ERROR, + .end = IRQ_UART0_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART0_TX, + .end = CH_UART0_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART0_RX, + .end = CH_UART0_RX, + .flags = IORESOURCE_DMA, + }, +}; + +unsigned short bfin_uart0_peripherals[] = { + P_UART0_TX, P_UART0_RX, 0 +}; + +static struct platform_device bfin_uart0_device = { + .name = "bfin-uart", + .id = 0, + .num_resources = ARRAY_SIZE(bfin_uart0_resources), + .resource = bfin_uart0_resources, + .dev = { + .platform_data = &bfin_uart0_peripherals, /* Passed to driver */ + }, +}; +#endif +#ifdef CONFIG_SERIAL_BFIN_UART1 +static struct resource bfin_uart1_resources[] = { + { + .start = UART1_THR, + .end = UART1_GCTL+2, .flags = IORESOURCE_MEM, }, + { + .start = IRQ_UART1_RX, + .end = IRQ_UART1_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART1_ERROR, + .end = IRQ_UART1_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART1_TX, + .end = CH_UART1_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART1_RX, + .end = CH_UART1_RX, + .flags = IORESOURCE_DMA, + }, }; -static struct platform_device bfin_uart_device = { +unsigned short bfin_uart1_peripherals[] = { + P_UART1_TX, P_UART1_RX, 0 +}; + +static struct platform_device bfin_uart1_device = { .name = "bfin-uart", .id = 1, - .num_resources = ARRAY_SIZE(bfin_uart_resources), - .resource = bfin_uart_resources, + .num_resources = ARRAY_SIZE(bfin_uart1_resources), + .resource = bfin_uart1_resources, + .dev = { + .platform_data = &bfin_uart1_peripherals, /* Passed to driver */ + }, }; #endif +#endif #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) #ifdef CONFIG_BFIN_SIR0 @@ -472,7 +540,12 @@ static struct platform_device *stamp_devices[] __initdata = { #endif #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) - &bfin_uart_device, +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART1 + &bfin_uart1_device, +#endif #endif #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index ac9b52e..9842288 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -1157,30 +1157,105 @@ static struct platform_device bfin_lq035q1_device = { #endif #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) -static struct resource bfin_uart_resources[] = { #ifdef CONFIG_SERIAL_BFIN_UART0 +static struct resource bfin_uart0_resources[] = { { - .start = 0xFFC00400, - .end = 0xFFC004FF, + .start = UART0_THR, + .end = UART0_GCTL+2, .flags = IORESOURCE_MEM, }, + { + .start = IRQ_UART0_RX, + .end = IRQ_UART0_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART0_ERROR, + .end = IRQ_UART0_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART0_TX, + .end = CH_UART0_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART0_RX, + .end = CH_UART0_RX, + .flags = IORESOURCE_DMA, + }, +#ifdef CONFIG_BFIN_UART0_CTSRTS + { /* CTS pin */ + .start = GPIO_PG7, + .end = GPIO_PG7, + .flags = IORESOURCE_IO, + }, + { /* RTS pin */ + .start = GPIO_PG6, + .end = GPIO_PG6, + .flags = IORESOURCE_IO, + }, +#endif +}; + +unsigned short bfin_uart0_peripherals[] = { + P_UART0_TX, P_UART0_RX, 0 +}; + +static struct platform_device bfin_uart0_device = { + .name = "bfin-uart", + .id = 0, + .num_resources = ARRAY_SIZE(bfin_uart0_resources), + .resource = bfin_uart0_resources, + .dev = { + .platform_data = &bfin_uart0_peripherals, /* Passed to driver */ + }, +}; #endif #ifdef CONFIG_SERIAL_BFIN_UART1 +static struct resource bfin_uart1_resources[] = { { - .start = 0xFFC02000, - .end = 0xFFC020FF, + .start = UART1_THR, + .end = UART1_GCTL+2, .flags = IORESOURCE_MEM, }, -#endif + { + .start = IRQ_UART1_RX, + .end = IRQ_UART1_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART1_ERROR, + .end = IRQ_UART1_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART1_TX, + .end = CH_UART1_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART1_RX, + .end = CH_UART1_RX, + .flags = IORESOURCE_DMA, + }, +}; + +unsigned short bfin_uart1_peripherals[] = { + P_UART1_TX, P_UART1_RX, 0 }; -static struct platform_device bfin_uart_device = { +static struct platform_device bfin_uart1_device = { .name = "bfin-uart", .id = 1, - .num_resources = ARRAY_SIZE(bfin_uart_resources), - .resource = bfin_uart_resources, + .num_resources = ARRAY_SIZE(bfin_uart1_resources), + .resource = bfin_uart1_resources, + .dev = { + .platform_data = &bfin_uart1_peripherals, /* Passed to driver */ + }, }; #endif +#endif #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) #ifdef CONFIG_BFIN_SIR0 @@ -1771,7 +1846,12 @@ static struct platform_device *stamp_devices[] __initdata = { #endif #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) - &bfin_uart_device, +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART1 + &bfin_uart1_device, +#endif #endif #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) diff --git a/arch/blackfin/mach-bf537/boards/tcm_bf537.c b/arch/blackfin/mach-bf537/boards/tcm_bf537.c index 57163b6..d77ca5b 100644 --- a/arch/blackfin/mach-bf537/boards/tcm_bf537.c +++ b/arch/blackfin/mach-bf537/boards/tcm_bf537.c @@ -327,25 +327,93 @@ static struct platform_device cm_flash_device = { #endif #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) -static struct resource bfin_uart_resources[] = { +#ifdef CONFIG_SERIAL_BFIN_UART0 +static struct resource bfin_uart0_resources[] = { { - .start = 0xFFC00400, - .end = 0xFFC004FF, + .start = UART0_THR, + .end = UART0_GCTL+2, .flags = IORESOURCE_MEM, - }, { - .start = 0xFFC02000, - .end = 0xFFC020FF, + }, + { + .start = IRQ_UART0_RX, + .end = IRQ_UART0_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART0_ERROR, + .end = IRQ_UART0_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART0_TX, + .end = CH_UART0_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART0_RX, + .end = CH_UART0_RX, + .flags = IORESOURCE_DMA, + }, +}; + +unsigned short bfin_uart0_peripherals[] = { + P_UART0_TX, P_UART0_RX, 0 +}; + +static struct platform_device bfin_uart0_device = { + .name = "bfin-uart", + .id = 0, + .num_resources = ARRAY_SIZE(bfin_uart0_resources), + .resource = bfin_uart0_resources, + .dev = { + .platform_data = &bfin_uart0_peripherals, /* Passed to driver */ + }, +}; +#endif +#ifdef CONFIG_SERIAL_BFIN_UART1 +static struct resource bfin_uart1_resources[] = { + { + .start = UART1_THR, + .end = UART1_GCTL+2, .flags = IORESOURCE_MEM, }, + { + .start = IRQ_UART1_RX, + .end = IRQ_UART1_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART1_ERROR, + .end = IRQ_UART1_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART1_TX, + .end = CH_UART1_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART1_RX, + .end = CH_UART1_RX, + .flags = IORESOURCE_DMA, + }, }; -static struct platform_device bfin_uart_device = { +unsigned short bfin_uart1_peripherals[] = { + P_UART1_TX, P_UART1_RX, 0 +}; + +static struct platform_device bfin_uart1_device = { .name = "bfin-uart", .id = 1, - .num_resources = ARRAY_SIZE(bfin_uart_resources), - .resource = bfin_uart_resources, + .num_resources = ARRAY_SIZE(bfin_uart1_resources), + .resource = bfin_uart1_resources, + .dev = { + .platform_data = &bfin_uart1_peripherals, /* Passed to driver */ + }, }; #endif +#endif #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) #ifdef CONFIG_BFIN_SIR0 @@ -524,7 +592,12 @@ static struct platform_device *cm_bf537_devices[] __initdata = { #endif #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) - &bfin_uart_device, +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART1 + &bfin_uart1_device, +#endif #endif #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) diff --git a/arch/blackfin/mach-bf538/boards/ezkit.c b/arch/blackfin/mach-bf538/boards/ezkit.c index c296bb1..1912bc4 100644 --- a/arch/blackfin/mach-bf538/boards/ezkit.c +++ b/arch/blackfin/mach-bf538/boards/ezkit.c @@ -41,37 +41,148 @@ static struct platform_device rtc_device = { #endif #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) -static struct resource bfin_uart_resources[] = { #ifdef CONFIG_SERIAL_BFIN_UART0 +static struct resource bfin_uart0_resources[] = { { - .start = 0xFFC00400, - .end = 0xFFC004FF, + .start = UART0_THR, + .end = UART0_GCTL+2, .flags = IORESOURCE_MEM, }, + { + .start = IRQ_UART0_RX, + .end = IRQ_UART0_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART0_ERROR, + .end = IRQ_UART0_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART0_TX, + .end = CH_UART0_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART0_RX, + .end = CH_UART0_RX, + .flags = IORESOURCE_DMA, + }, +#ifdef CONFIG_BFIN_UART0_CTSRTS + { /* CTS pin */ + .start = GPIO_PG7, + .end = GPIO_PG7, + .flags = IORESOURCE_IO, + }, + { /* RTS pin */ + .start = GPIO_PG6, + .end = GPIO_PG6, + .flags = IORESOURCE_IO, + }, +#endif +}; + +unsigned short bfin_uart0_peripherals[] = { + P_UART0_TX, P_UART0_RX, 0 +}; + +static struct platform_device bfin_uart0_device = { + .name = "bfin-uart", + .id = 0, + .num_resources = ARRAY_SIZE(bfin_uart0_resources), + .resource = bfin_uart0_resources, + .dev = { + .platform_data = &bfin_uart0_peripherals, /* Passed to driver */ + }, +}; #endif #ifdef CONFIG_SERIAL_BFIN_UART1 +static struct resource bfin_uart1_resources[] = { { - .start = 0xFFC02000, - .end = 0xFFC020FF, + .start = UART1_THR, + .end = UART1_GCTL+2, .flags = IORESOURCE_MEM, }, + { + .start = IRQ_UART1_RX, + .end = IRQ_UART1_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART1_ERROR, + .end = IRQ_UART1_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART1_TX, + .end = CH_UART1_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART1_RX, + .end = CH_UART1_RX, + .flags = IORESOURCE_DMA, + }, +}; + +unsigned short bfin_uart1_peripherals[] = { + P_UART1_TX, P_UART1_RX, 0 +}; + +static struct platform_device bfin_uart1_device = { + .name = "bfin-uart", + .id = 1, + .num_resources = ARRAY_SIZE(bfin_uart1_resources), + .resource = bfin_uart1_resources, + .dev = { + .platform_data = &bfin_uart1_peripherals, /* Passed to driver */ + }, +}; #endif #ifdef CONFIG_SERIAL_BFIN_UART2 +static struct resource bfin_uart2_resources[] = { { - .start = 0xFFC02100, - .end = 0xFFC021FF, + .start = UART2_THR, + .end = UART2_GCTL+2, .flags = IORESOURCE_MEM, }, -#endif + { + .start = IRQ_UART2_RX, + .end = IRQ_UART2_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART2_ERROR, + .end = IRQ_UART2_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART2_TX, + .end = CH_UART2_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART2_RX, + .end = CH_UART2_RX, + .flags = IORESOURCE_DMA, + }, }; -static struct platform_device bfin_uart_device = { +unsigned short bfin_uart2_peripherals[] = { + P_UART2_TX, P_UART2_RX, 0 +}; + +static struct platform_device bfin_uart2_device = { .name = "bfin-uart", - .id = 1, - .num_resources = ARRAY_SIZE(bfin_uart_resources), - .resource = bfin_uart_resources, + .id = 2, + .num_resources = ARRAY_SIZE(bfin_uart2_resources), + .resource = bfin_uart2_resources, + .dev = { + .platform_data = &bfin_uart2_peripherals, /* Passed to driver */ + }, }; #endif +#endif #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) #ifdef CONFIG_BFIN_SIR0 @@ -622,7 +733,15 @@ static struct platform_device *cm_bf538_devices[] __initdata = { #endif #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) - &bfin_uart_device, +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART1 + &bfin_uart1_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART2 + &bfin_uart2_device, +#endif #endif #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) diff --git a/arch/blackfin/mach-bf548/boards/cm_bf548.c b/arch/blackfin/mach-bf548/boards/cm_bf548.c index ccdcd6d..635f9272 100644 --- a/arch/blackfin/mach-bf548/boards/cm_bf548.c +++ b/arch/blackfin/mach-bf548/boards/cm_bf548.c @@ -127,44 +127,211 @@ static struct platform_device rtc_device = { #endif #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) -static struct resource bfin_uart_resources[] = { #ifdef CONFIG_SERIAL_BFIN_UART0 +static struct resource bfin_uart0_resources[] = { { - .start = 0xFFC00400, - .end = 0xFFC004FF, + .start = UART0_DLL, + .end = UART0_RBR+2, .flags = IORESOURCE_MEM, }, + { + .start = IRQ_UART0_RX, + .end = IRQ_UART0_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART0_ERROR, + .end = IRQ_UART0_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART0_TX, + .end = CH_UART0_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART0_RX, + .end = CH_UART0_RX, + .flags = IORESOURCE_DMA, + }, +}; + +unsigned short bfin_uart0_peripherals[] = { + P_UART0_TX, P_UART0_RX, 0 +}; + +static struct platform_device bfin_uart0_device = { + .name = "bfin-uart", + .id = 0, + .num_resources = ARRAY_SIZE(bfin_uart0_resources), + .resource = bfin_uart0_resources, + .dev = { + .platform_data = &bfin_uart0_peripherals, /* Passed to driver */ + }, +}; #endif #ifdef CONFIG_SERIAL_BFIN_UART1 +static struct resource bfin_uart1_resources[] = { { - .start = 0xFFC02000, - .end = 0xFFC020FF, + .start = UART1_DLL, + .end = UART1_RBR+2, .flags = IORESOURCE_MEM, }, + { + .start = IRQ_UART1_RX, + .end = IRQ_UART1_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART1_ERROR, + .end = IRQ_UART1_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART1_TX, + .end = CH_UART1_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART1_RX, + .end = CH_UART1_RX, + .flags = IORESOURCE_DMA, + }, +#ifdef CONFIG_BFIN_UART1_CTSRTS + { /* CTS pin -- 0 means not supported */ + .start = GPIO_PE10, + .end = GPIO_PE10, + .flags = IORESOURCE_IO, + }, + { /* RTS pin -- 0 means not supported */ + .start = GPIO_PE9, + .end = GPIO_PE9, + .flags = IORESOURCE_IO, + }, +#endif +}; + +unsigned short bfin_uart1_peripherals[] = { + P_UART1_TX, P_UART1_RX, +#ifdef CONFIG_BFIN_UART1_CTSRTS + P_UART1_RTS, P_UART1_CTS, +#endif + 0 +}; + +static struct platform_device bfin_uart1_device = { + .name = "bfin-uart", + .id = 1, + .num_resources = ARRAY_SIZE(bfin_uart1_resources), + .resource = bfin_uart1_resources, + .dev = { + .platform_data = &bfin_uart1_peripherals, /* Passed to driver */ + }, +}; #endif #ifdef CONFIG_SERIAL_BFIN_UART2 +static struct resource bfin_uart2_resources[] = { { - .start = 0xFFC02100, - .end = 0xFFC021FF, + .start = UART2_DLL, + .end = UART2_RBR+2, .flags = IORESOURCE_MEM, }, + { + .start = IRQ_UART2_RX, + .end = IRQ_UART2_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART2_ERROR, + .end = IRQ_UART2_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART2_TX, + .end = CH_UART2_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART2_RX, + .end = CH_UART2_RX, + .flags = IORESOURCE_DMA, + }, +}; + +unsigned short bfin_uart2_peripherals[] = { + P_UART2_TX, P_UART2_RX, 0 +}; + +static struct platform_device bfin_uart2_device = { + .name = "bfin-uart", + .id = 2, + .num_resources = ARRAY_SIZE(bfin_uart2_resources), + .resource = bfin_uart2_resources, + .dev = { + .platform_data = &bfin_uart2_peripherals, /* Passed to driver */ + }, +}; #endif #ifdef CONFIG_SERIAL_BFIN_UART3 +static struct resource bfin_uart3_resources[] = { { - .start = 0xFFC03100, - .end = 0xFFC031FF, + .start = UART3_DLL, + .end = UART3_RBR+2, .flags = IORESOURCE_MEM, }, + { + .start = IRQ_UART3_RX, + .end = IRQ_UART3_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART3_ERROR, + .end = IRQ_UART3_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART3_TX, + .end = CH_UART3_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART3_RX, + .end = CH_UART3_RX, + .flags = IORESOURCE_DMA, + }, +#ifdef CONFIG_BFIN_UART3_CTSRTS + { /* CTS pin -- 0 means not supported */ + .start = GPIO_PB3, + .end = GPIO_PB3, + .flags = IORESOURCE_IO, + }, + { /* RTS pin -- 0 means not supported */ + .start = GPIO_PB2, + .end = GPIO_PB2, + .flags = IORESOURCE_IO, + }, #endif }; -static struct platform_device bfin_uart_device = { +unsigned short bfin_uart3_peripherals[] = { + P_UART3_TX, P_UART3_RX, +#ifdef CONFIG_BFIN_UART3_CTSRTS + P_UART3_RTS, P_UART3_CTS, +#endif + 0 +}; + +static struct platform_device bfin_uart3_device = { .name = "bfin-uart", - .id = 1, - .num_resources = ARRAY_SIZE(bfin_uart_resources), - .resource = bfin_uart_resources, + .id = 3, + .num_resources = ARRAY_SIZE(bfin_uart3_resources), + .resource = bfin_uart3_resources, + .dev = { + .platform_data = &bfin_uart3_peripherals, /* Passed to driver */ + }, }; #endif +#endif #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) #ifdef CONFIG_BFIN_SIR0 @@ -752,7 +919,18 @@ static struct platform_device *cm_bf548_devices[] __initdata = { #endif #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) - &bfin_uart_device, +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART1 + &bfin_uart1_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART2 + &bfin_uart2_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART3 + &bfin_uart3_device, +#endif #endif #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c index 60193f7..1ed0261 100644 --- a/arch/blackfin/mach-bf548/boards/ezkit.c +++ b/arch/blackfin/mach-bf548/boards/ezkit.c @@ -232,44 +232,211 @@ static struct platform_device rtc_device = { #endif #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) -static struct resource bfin_uart_resources[] = { #ifdef CONFIG_SERIAL_BFIN_UART0 +static struct resource bfin_uart0_resources[] = { { - .start = 0xFFC00400, - .end = 0xFFC004FF, + .start = UART0_DLL, + .end = UART0_RBR+2, .flags = IORESOURCE_MEM, }, + { + .start = IRQ_UART0_RX, + .end = IRQ_UART0_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART0_ERROR, + .end = IRQ_UART0_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART0_TX, + .end = CH_UART0_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART0_RX, + .end = CH_UART0_RX, + .flags = IORESOURCE_DMA, + }, +}; + +unsigned short bfin_uart0_peripherals[] = { + P_UART0_TX, P_UART0_RX, 0 +}; + +static struct platform_device bfin_uart0_device = { + .name = "bfin-uart", + .id = 0, + .num_resources = ARRAY_SIZE(bfin_uart0_resources), + .resource = bfin_uart0_resources, + .dev = { + .platform_data = &bfin_uart0_peripherals, /* Passed to driver */ + }, +}; #endif #ifdef CONFIG_SERIAL_BFIN_UART1 +static struct resource bfin_uart1_resources[] = { { - .start = 0xFFC02000, - .end = 0xFFC020FF, + .start = UART1_DLL, + .end = UART1_RBR+2, .flags = IORESOURCE_MEM, }, + { + .start = IRQ_UART1_RX, + .end = IRQ_UART1_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART1_ERROR, + .end = IRQ_UART1_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART1_TX, + .end = CH_UART1_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART1_RX, + .end = CH_UART1_RX, + .flags = IORESOURCE_DMA, + }, +#ifdef CONFIG_BFIN_UART1_CTSRTS + { /* CTS pin -- 0 means not supported */ + .start = GPIO_PE10, + .end = GPIO_PE10, + .flags = IORESOURCE_IO, + }, + { /* RTS pin -- 0 means not supported */ + .start = GPIO_PE9, + .end = GPIO_PE9, + .flags = IORESOURCE_IO, + }, +#endif +}; + +unsigned short bfin_uart1_peripherals[] = { + P_UART1_TX, P_UART1_RX, +#ifdef CONFIG_BFIN_UART1_CTSRTS + P_UART1_RTS, P_UART1_CTS, +#endif + 0 +}; + +static struct platform_device bfin_uart1_device = { + .name = "bfin-uart", + .id = 1, + .num_resources = ARRAY_SIZE(bfin_uart1_resources), + .resource = bfin_uart1_resources, + .dev = { + .platform_data = &bfin_uart1_peripherals, /* Passed to driver */ + }, +}; #endif #ifdef CONFIG_SERIAL_BFIN_UART2 +static struct resource bfin_uart2_resources[] = { { - .start = 0xFFC02100, - .end = 0xFFC021FF, + .start = UART2_DLL, + .end = UART2_RBR+2, .flags = IORESOURCE_MEM, }, + { + .start = IRQ_UART2_RX, + .end = IRQ_UART2_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART2_ERROR, + .end = IRQ_UART2_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART2_TX, + .end = CH_UART2_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART2_RX, + .end = CH_UART2_RX, + .flags = IORESOURCE_DMA, + }, +}; + +unsigned short bfin_uart2_peripherals[] = { + P_UART2_TX, P_UART2_RX, 0 +}; + +static struct platform_device bfin_uart2_device = { + .name = "bfin-uart", + .id = 2, + .num_resources = ARRAY_SIZE(bfin_uart2_resources), + .resource = bfin_uart2_resources, + .dev = { + .platform_data = &bfin_uart2_peripherals, /* Passed to driver */ + }, +}; #endif #ifdef CONFIG_SERIAL_BFIN_UART3 +static struct resource bfin_uart3_resources[] = { { - .start = 0xFFC03100, - .end = 0xFFC031FF, + .start = UART3_DLL, + .end = UART3_RBR+2, .flags = IORESOURCE_MEM, }, + { + .start = IRQ_UART3_RX, + .end = IRQ_UART3_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART3_ERROR, + .end = IRQ_UART3_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART3_TX, + .end = CH_UART3_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART3_RX, + .end = CH_UART3_RX, + .flags = IORESOURCE_DMA, + }, +#ifdef CONFIG_BFIN_UART3_CTSRTS + { /* CTS pin -- 0 means not supported */ + .start = GPIO_PB3, + .end = GPIO_PB3, + .flags = IORESOURCE_IO, + }, + { /* RTS pin -- 0 means not supported */ + .start = GPIO_PB2, + .end = GPIO_PB2, + .flags = IORESOURCE_IO, + }, #endif }; -static struct platform_device bfin_uart_device = { +unsigned short bfin_uart3_peripherals[] = { + P_UART3_TX, P_UART3_RX, +#ifdef CONFIG_BFIN_UART3_CTSRTS + P_UART3_RTS, P_UART3_CTS, +#endif + 0 +}; + +static struct platform_device bfin_uart3_device = { .name = "bfin-uart", - .id = 1, - .num_resources = ARRAY_SIZE(bfin_uart_resources), - .resource = bfin_uart_resources, + .id = 3, + .num_resources = ARRAY_SIZE(bfin_uart3_resources), + .resource = bfin_uart3_resources, + .dev = { + .platform_data = &bfin_uart3_peripherals, /* Passed to driver */ + }, }; #endif +#endif #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) #ifdef CONFIG_BFIN_SIR0 @@ -960,7 +1127,18 @@ static struct platform_device *ezkit_devices[] __initdata = { #endif #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) - &bfin_uart_device, +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART1 + &bfin_uart1_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART2 + &bfin_uart2_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART3 + &bfin_uart3_device, +#endif #endif #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) diff --git a/arch/blackfin/mach-bf561/boards/cm_bf561.c b/arch/blackfin/mach-bf561/boards/cm_bf561.c index dfc8d5b..818266f 100644 --- a/arch/blackfin/mach-bf561/boards/cm_bf561.c +++ b/arch/blackfin/mach-bf561/boards/cm_bf561.c @@ -305,21 +305,50 @@ static struct platform_device isp1362_hcd_device = { #endif #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) -static struct resource bfin_uart_resources[] = { +#ifdef CONFIG_SERIAL_BFIN_UART0 +static struct resource bfin_uart0_resources[] = { { - .start = 0xFFC00400, - .end = 0xFFC004FF, + .start = BFIN_UART_THR, + .end = BFIN_UART_GCTL+2, .flags = IORESOURCE_MEM, }, + { + .start = IRQ_UART_RX, + .end = IRQ_UART_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART_ERROR, + .end = IRQ_UART_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART_TX, + .end = CH_UART_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART_RX, + .end = CH_UART_RX, + .flags = IORESOURCE_DMA, + }, +}; + +unsigned short bfin_uart0_peripherals[] = { + P_UART0_TX, P_UART0_RX, 0 }; -static struct platform_device bfin_uart_device = { +static struct platform_device bfin_uart0_device = { .name = "bfin-uart", - .id = 1, - .num_resources = ARRAY_SIZE(bfin_uart_resources), - .resource = bfin_uart_resources, + .id = 0, + .num_resources = ARRAY_SIZE(bfin_uart0_resources), + .resource = bfin_uart0_resources, + .dev = { + .platform_data = &bfin_uart0_peripherals, /* Passed to driver */ + }, }; #endif +#endif #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) #ifdef CONFIG_BFIN_SIR0 @@ -463,7 +492,9 @@ static struct platform_device *cm_bf561_devices[] __initdata = { #endif #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) - &bfin_uart_device, +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif #endif #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) diff --git a/arch/blackfin/mach-bf561/boards/ezkit.c b/arch/blackfin/mach-bf561/boards/ezkit.c index ffd3e6a..c59041c 100644 --- a/arch/blackfin/mach-bf561/boards/ezkit.c +++ b/arch/blackfin/mach-bf561/boards/ezkit.c @@ -160,21 +160,50 @@ static struct platform_device smc91x_device = { #endif #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) -static struct resource bfin_uart_resources[] = { +#ifdef CONFIG_SERIAL_BFIN_UART0 +static struct resource bfin_uart0_resources[] = { { - .start = 0xFFC00400, - .end = 0xFFC004FF, + .start = BFIN_UART_THR, + .end = BFIN_UART_GCTL+2, .flags = IORESOURCE_MEM, }, + { + .start = IRQ_UART_RX, + .end = IRQ_UART_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART_ERROR, + .end = IRQ_UART_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART_TX, + .end = CH_UART_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART_RX, + .end = CH_UART_RX, + .flags = IORESOURCE_DMA, + }, +}; + +unsigned short bfin_uart0_peripherals[] = { + P_UART0_TX, P_UART0_RX, 0 }; -static struct platform_device bfin_uart_device = { +static struct platform_device bfin_uart0_device = { .name = "bfin-uart", - .id = 1, - .num_resources = ARRAY_SIZE(bfin_uart_resources), - .resource = bfin_uart_resources, + .id = 0, + .num_resources = ARRAY_SIZE(bfin_uart0_resources), + .resource = bfin_uart0_resources, + .dev = { + .platform_data = &bfin_uart0_peripherals, /* Passed to driver */ + }, }; #endif +#endif #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) #ifdef CONFIG_BFIN_SIR0 @@ -412,7 +441,9 @@ static struct platform_device *ezkit_devices[] __initdata = { #endif #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) - &bfin_uart_device, +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif #endif #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) diff --git a/arch/blackfin/mach-bf561/boards/tepla.c b/arch/blackfin/mach-bf561/boards/tepla.c index 8ba7252..6c33397 100644 --- a/arch/blackfin/mach-bf561/boards/tepla.c +++ b/arch/blackfin/mach-bf561/boards/tepla.c @@ -42,6 +42,52 @@ static struct platform_device smc91x_device = { .resource = smc91x_resources, }; +#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) +#ifdef CONFIG_SERIAL_BFIN_UART0 +static struct resource bfin_uart0_resources[] = { + { + .start = BFIN_UART_THR, + .end = BFIN_UART_GCTL+2, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_UART_RX, + .end = IRQ_UART_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART_ERROR, + .end = IRQ_UART_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART_TX, + .end = CH_UART_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART_RX, + .end = CH_UART_RX, + .flags = IORESOURCE_DMA, + }, +}; + +unsigned short bfin_uart0_peripherals[] = { + P_UART0_TX, P_UART0_RX, 0 +}; + +static struct platform_device bfin_uart0_device = { + .name = "bfin-uart", + .id = 0, + .num_resources = ARRAY_SIZE(bfin_uart0_resources), + .resource = bfin_uart0_resources, + .dev = { + .platform_data = &bfin_uart0_peripherals, /* Passed to driver */ + }, +}; +#endif +#endif + #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) #ifdef CONFIG_BFIN_SIR0 static struct resource bfin_sir0_resources[] = { @@ -73,6 +119,13 @@ static struct platform_device bfin_sir0_device = { static struct platform_device *tepla_devices[] __initdata = { &smc91x_device, + +#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#endif + #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) #ifdef CONFIG_BFIN_SIR0 &bfin_sir0_device, -- cgit v0.10.2 From 08a54bffaf7d5dc9391518323234ce9f9ea4be8e Mon Sep 17 00:00:00 2001 From: Barry Song Date: Fri, 18 Sep 2009 09:14:38 +0000 Subject: Blackfin: bf537-stamp: ad1938: switch to GPIO CS Signed-off-by: Barry Song Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 9842288..554f82d 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -528,7 +528,6 @@ static struct bfin5xx_spi_chip ad1836_spi_chip_info = { static struct bfin5xx_spi_chip ad1938_spi_chip_info = { .enable_dma = 0, .bits_per_word = 8, - .cs_gpio = GPIO_PF5, }; #endif @@ -910,7 +909,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { .modalias = "ad1938", .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ .bus_num = 0, - .chip_select = 0,/* CONFIG_SND_BLACKFIN_SPI_PFBIT */ + .chip_select = 5, .controller_data = &ad1938_spi_chip_info, .mode = SPI_MODE_3, }, -- cgit v0.10.2 From df5de261306d9bfc1ed9121595593b10a7626b95 Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Wed, 23 Sep 2009 05:01:56 +0000 Subject: Blackfin: move SPORT UART resources to boards files Rather than keeping the pins in the actual driver and worrying about a mess of Kconfig options, declare all the desired pin resources in the boards file. This lets people easily select the specific pins/ports for the normal emulated UART as well as GPIOs for CTS/RTS. Signed-off-by: Sonic Zhang Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf518/boards/ezbrd.c b/arch/blackfin/mach-bf518/boards/ezbrd.c index 0d1b021..06e4316 100644 --- a/arch/blackfin/mach-bf518/boards/ezbrd.c +++ b/arch/blackfin/mach-bf518/boards/ezbrd.c @@ -562,16 +562,75 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { }; #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART +static struct resource bfin_sport0_uart_resources[] = { + { + .start = SPORT0_TCR1, + .end = SPORT0_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT0_RX, + .end = IRQ_SPORT0_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT0_ERROR, + .end = IRQ_SPORT0_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +unsigned short bfin_sport0_peripherals[] = { + P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, + P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0 +}; + static struct platform_device bfin_sport0_uart_device = { .name = "bfin-sport-uart", .id = 0, + .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources), + .resource = bfin_sport0_uart_resources, + .dev = { + .platform_data = &bfin_sport0_peripherals, /* Passed to driver */ + }, +}; +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART +static struct resource bfin_sport1_uart_resources[] = { + { + .start = SPORT1_TCR1, + .end = SPORT1_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT1_RX, + .end = IRQ_SPORT1_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT1_ERROR, + .end = IRQ_SPORT1_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +unsigned short bfin_sport1_peripherals[] = { + P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, + P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0 }; static struct platform_device bfin_sport1_uart_device = { .name = "bfin-sport-uart", .id = 1, + .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources), + .resource = bfin_sport1_uart_resources, + .dev = { + .platform_data = &bfin_sport1_peripherals, /* Passed to driver */ + }, }; #endif +#endif #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) #include @@ -678,9 +737,13 @@ static struct platform_device *stamp_devices[] __initdata = { #endif #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART &bfin_sport0_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART &bfin_sport1_uart_device, #endif +#endif #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) &bfin_device_gpiokeys, diff --git a/arch/blackfin/mach-bf527/boards/cm_bf527.c b/arch/blackfin/mach-bf527/boards/cm_bf527.c index 2d93c1f..3543bdf 100644 --- a/arch/blackfin/mach-bf527/boards/cm_bf527.c +++ b/arch/blackfin/mach-bf527/boards/cm_bf527.c @@ -800,16 +800,75 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { }; #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART +static struct resource bfin_sport0_uart_resources[] = { + { + .start = SPORT0_TCR1, + .end = SPORT0_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT0_RX, + .end = IRQ_SPORT0_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT0_ERROR, + .end = IRQ_SPORT0_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +unsigned short bfin_sport0_peripherals[] = { + P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, + P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0 +}; + static struct platform_device bfin_sport0_uart_device = { .name = "bfin-sport-uart", .id = 0, + .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources), + .resource = bfin_sport0_uart_resources, + .dev = { + .platform_data = &bfin_sport0_peripherals, /* Passed to driver */ + }, +}; +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART +static struct resource bfin_sport1_uart_resources[] = { + { + .start = SPORT1_TCR1, + .end = SPORT1_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT1_RX, + .end = IRQ_SPORT1_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT1_ERROR, + .end = IRQ_SPORT1_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +unsigned short bfin_sport1_peripherals[] = { + P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, + P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0 }; static struct platform_device bfin_sport1_uart_device = { .name = "bfin-sport-uart", .id = 1, + .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources), + .resource = bfin_sport1_uart_resources, + .dev = { + .platform_data = &bfin_sport1_peripherals, /* Passed to driver */ + }, }; #endif +#endif #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) #include @@ -926,9 +985,13 @@ static struct platform_device *cmbf527_devices[] __initdata = { #endif #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART &bfin_sport0_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART &bfin_sport1_uart_device, #endif +#endif #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) &bfin_device_gpiokeys, diff --git a/arch/blackfin/mach-bf527/boards/ezbrd.c b/arch/blackfin/mach-bf527/boards/ezbrd.c index 3a981e8..a99955d 100644 --- a/arch/blackfin/mach-bf527/boards/ezbrd.c +++ b/arch/blackfin/mach-bf527/boards/ezbrd.c @@ -631,16 +631,75 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { }; #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART +static struct resource bfin_sport0_uart_resources[] = { + { + .start = SPORT0_TCR1, + .end = SPORT0_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT0_RX, + .end = IRQ_SPORT0_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT0_ERROR, + .end = IRQ_SPORT0_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +unsigned short bfin_sport0_peripherals[] = { + P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, + P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0 +}; + static struct platform_device bfin_sport0_uart_device = { .name = "bfin-sport-uart", .id = 0, + .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources), + .resource = bfin_sport0_uart_resources, + .dev = { + .platform_data = &bfin_sport0_peripherals, /* Passed to driver */ + }, +}; +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART +static struct resource bfin_sport1_uart_resources[] = { + { + .start = SPORT1_TCR1, + .end = SPORT1_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT1_RX, + .end = IRQ_SPORT1_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT1_ERROR, + .end = IRQ_SPORT1_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +unsigned short bfin_sport1_peripherals[] = { + P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, + P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0 }; static struct platform_device bfin_sport1_uart_device = { .name = "bfin-sport-uart", .id = 1, + .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources), + .resource = bfin_sport1_uart_resources, + .dev = { + .platform_data = &bfin_sport1_peripherals, /* Passed to driver */ + }, }; #endif +#endif #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) #include @@ -766,9 +825,13 @@ static struct platform_device *stamp_devices[] __initdata = { #endif #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART &bfin_sport0_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART &bfin_sport1_uart_device, #endif +#endif #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) &bfin_device_gpiokeys, diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c index 0750e65..f93323d 100644 --- a/arch/blackfin/mach-bf527/boards/ezkit.c +++ b/arch/blackfin/mach-bf527/boards/ezkit.c @@ -844,16 +844,75 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { }; #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART +static struct resource bfin_sport0_uart_resources[] = { + { + .start = SPORT0_TCR1, + .end = SPORT0_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT0_RX, + .end = IRQ_SPORT0_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT0_ERROR, + .end = IRQ_SPORT0_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +unsigned short bfin_sport0_peripherals[] = { + P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, + P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0 +}; + static struct platform_device bfin_sport0_uart_device = { .name = "bfin-sport-uart", .id = 0, + .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources), + .resource = bfin_sport0_uart_resources, + .dev = { + .platform_data = &bfin_sport0_peripherals, /* Passed to driver */ + }, +}; +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART +static struct resource bfin_sport1_uart_resources[] = { + { + .start = SPORT1_TCR1, + .end = SPORT1_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT1_RX, + .end = IRQ_SPORT1_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT1_ERROR, + .end = IRQ_SPORT1_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +unsigned short bfin_sport1_peripherals[] = { + P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, + P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0 }; static struct platform_device bfin_sport1_uart_device = { .name = "bfin-sport-uart", .id = 1, + .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources), + .resource = bfin_sport1_uart_resources, + .dev = { + .platform_data = &bfin_sport1_peripherals, /* Passed to driver */ + }, }; #endif +#endif #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) #include @@ -1007,9 +1066,13 @@ static struct platform_device *stamp_devices[] __initdata = { #endif #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART &bfin_sport0_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART &bfin_sport1_uart_device, #endif +#endif #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) &bfin_device_gpiokeys, diff --git a/arch/blackfin/mach-bf533/boards/blackstamp.c b/arch/blackfin/mach-bf533/boards/blackstamp.c index 50ce3ec..4d92946 100644 --- a/arch/blackfin/mach-bf533/boards/blackstamp.c +++ b/arch/blackfin/mach-bf533/boards/blackstamp.c @@ -270,16 +270,75 @@ static struct platform_device bfin_sir0_device = { #endif #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART +static struct resource bfin_sport0_uart_resources[] = { + { + .start = SPORT0_TCR1, + .end = SPORT0_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT0_RX, + .end = IRQ_SPORT0_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT0_ERROR, + .end = IRQ_SPORT0_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +unsigned short bfin_sport0_peripherals[] = { + P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, + P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0 +}; + static struct platform_device bfin_sport0_uart_device = { .name = "bfin-sport-uart", .id = 0, + .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources), + .resource = bfin_sport0_uart_resources, + .dev = { + .platform_data = &bfin_sport0_peripherals, /* Passed to driver */ + }, +}; +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART +static struct resource bfin_sport1_uart_resources[] = { + { + .start = SPORT1_TCR1, + .end = SPORT1_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT1_RX, + .end = IRQ_SPORT1_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT1_ERROR, + .end = IRQ_SPORT1_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +unsigned short bfin_sport1_peripherals[] = { + P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, + P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0 }; static struct platform_device bfin_sport1_uart_device = { .name = "bfin-sport-uart", .id = 1, + .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources), + .resource = bfin_sport1_uart_resources, + .dev = { + .platform_data = &bfin_sport1_peripherals, /* Passed to driver */ + }, }; #endif +#endif #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) #include @@ -385,9 +444,13 @@ static struct platform_device *stamp_devices[] __initdata = { #endif #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART &bfin_sport0_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART &bfin_sport1_uart_device, #endif +#endif #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) &bfin_device_gpiokeys, diff --git a/arch/blackfin/mach-bf533/boards/cm_bf533.c b/arch/blackfin/mach-bf533/boards/cm_bf533.c index f707faf..33ff27a 100644 --- a/arch/blackfin/mach-bf533/boards/cm_bf533.c +++ b/arch/blackfin/mach-bf533/boards/cm_bf533.c @@ -317,16 +317,75 @@ static struct platform_device bfin_sir0_device = { #endif #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART +static struct resource bfin_sport0_uart_resources[] = { + { + .start = SPORT0_TCR1, + .end = SPORT0_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT0_RX, + .end = IRQ_SPORT0_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT0_ERROR, + .end = IRQ_SPORT0_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +unsigned short bfin_sport0_peripherals[] = { + P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, + P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0 +}; + static struct platform_device bfin_sport0_uart_device = { .name = "bfin-sport-uart", .id = 0, + .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources), + .resource = bfin_sport0_uart_resources, + .dev = { + .platform_data = &bfin_sport0_peripherals, /* Passed to driver */ + }, +}; +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART +static struct resource bfin_sport1_uart_resources[] = { + { + .start = SPORT1_TCR1, + .end = SPORT1_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT1_RX, + .end = IRQ_SPORT1_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT1_ERROR, + .end = IRQ_SPORT1_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +unsigned short bfin_sport1_peripherals[] = { + P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, + P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0 }; static struct platform_device bfin_sport1_uart_device = { .name = "bfin-sport-uart", .id = 1, + .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources), + .resource = bfin_sport1_uart_resources, + .dev = { + .platform_data = &bfin_sport1_peripherals, /* Passed to driver */ + }, }; #endif +#endif #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) static struct resource isp1362_hcd_resources[] = { @@ -473,9 +532,13 @@ static struct platform_device *cm_bf533_devices[] __initdata = { #endif #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART &bfin_sport0_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART &bfin_sport1_uart_device, #endif +#endif #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) &rtc_device, diff --git a/arch/blackfin/mach-bf533/boards/stamp.c b/arch/blackfin/mach-bf533/boards/stamp.c index 2683e5f..428f724 100644 --- a/arch/blackfin/mach-bf533/boards/stamp.c +++ b/arch/blackfin/mach-bf533/boards/stamp.c @@ -397,16 +397,75 @@ static struct platform_device bfin_sir0_device = { #endif #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART +static struct resource bfin_sport0_uart_resources[] = { + { + .start = SPORT0_TCR1, + .end = SPORT0_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT0_RX, + .end = IRQ_SPORT0_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT0_ERROR, + .end = IRQ_SPORT0_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +unsigned short bfin_sport0_peripherals[] = { + P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, + P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0 +}; + static struct platform_device bfin_sport0_uart_device = { .name = "bfin-sport-uart", .id = 0, + .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources), + .resource = bfin_sport0_uart_resources, + .dev = { + .platform_data = &bfin_sport0_peripherals, /* Passed to driver */ + }, +}; +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART +static struct resource bfin_sport1_uart_resources[] = { + { + .start = SPORT1_TCR1, + .end = SPORT1_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT1_RX, + .end = IRQ_SPORT1_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT1_ERROR, + .end = IRQ_SPORT1_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +unsigned short bfin_sport1_peripherals[] = { + P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, + P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0 }; static struct platform_device bfin_sport1_uart_device = { .name = "bfin-sport-uart", .id = 1, + .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources), + .resource = bfin_sport1_uart_resources, + .dev = { + .platform_data = &bfin_sport1_peripherals, /* Passed to driver */ + }, }; #endif +#endif #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) #include @@ -536,9 +595,13 @@ static struct platform_device *stamp_devices[] __initdata = { #endif #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART &bfin_sport0_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART &bfin_sport1_uart_device, #endif +#endif #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) &bfin_device_gpiokeys, diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537e.c b/arch/blackfin/mach-bf537/boards/cm_bf537e.c index abb32dd..b483777 100644 --- a/arch/blackfin/mach-bf537/boards/cm_bf537e.c +++ b/arch/blackfin/mach-bf537/boards/cm_bf537e.c @@ -526,16 +526,75 @@ static struct platform_device i2c_bfin_twi_device = { #endif #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART +static struct resource bfin_sport0_uart_resources[] = { + { + .start = SPORT0_TCR1, + .end = SPORT0_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT0_RX, + .end = IRQ_SPORT0_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT0_ERROR, + .end = IRQ_SPORT0_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +unsigned short bfin_sport0_peripherals[] = { + P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, + P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0 +}; + static struct platform_device bfin_sport0_uart_device = { .name = "bfin-sport-uart", .id = 0, + .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources), + .resource = bfin_sport0_uart_resources, + .dev = { + .platform_data = &bfin_sport0_peripherals, /* Passed to driver */ + }, +}; +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART +static struct resource bfin_sport1_uart_resources[] = { + { + .start = SPORT1_TCR1, + .end = SPORT1_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT1_RX, + .end = IRQ_SPORT1_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT1_ERROR, + .end = IRQ_SPORT1_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +unsigned short bfin_sport1_peripherals[] = { + P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, + P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0 }; static struct platform_device bfin_sport1_uart_device = { .name = "bfin-sport-uart", .id = 1, + .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources), + .resource = bfin_sport1_uart_resources, + .dev = { + .platform_data = &bfin_sport1_peripherals, /* Passed to driver */ + }, }; #endif +#endif #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) static struct platform_device bfin_mii_bus = { @@ -647,9 +706,13 @@ static struct platform_device *cm_bf537e_devices[] __initdata = { #endif #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART &bfin_sport0_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART &bfin_sport1_uart_device, #endif +#endif #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) &isp1362_hcd_device, diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537u.c b/arch/blackfin/mach-bf537/boards/cm_bf537u.c index b3182fa..c6802be 100644 --- a/arch/blackfin/mach-bf537/boards/cm_bf537u.c +++ b/arch/blackfin/mach-bf537/boards/cm_bf537u.c @@ -491,16 +491,75 @@ static struct platform_device i2c_bfin_twi_device = { #endif #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART +static struct resource bfin_sport0_uart_resources[] = { + { + .start = SPORT0_TCR1, + .end = SPORT0_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT0_RX, + .end = IRQ_SPORT0_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT0_ERROR, + .end = IRQ_SPORT0_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +unsigned short bfin_sport0_peripherals[] = { + P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, + P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0 +}; + static struct platform_device bfin_sport0_uart_device = { .name = "bfin-sport-uart", .id = 0, + .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources), + .resource = bfin_sport0_uart_resources, + .dev = { + .platform_data = &bfin_sport0_peripherals, /* Passed to driver */ + }, +}; +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART +static struct resource bfin_sport1_uart_resources[] = { + { + .start = SPORT1_TCR1, + .end = SPORT1_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT1_RX, + .end = IRQ_SPORT1_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT1_ERROR, + .end = IRQ_SPORT1_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +unsigned short bfin_sport1_peripherals[] = { + P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, + P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0 }; static struct platform_device bfin_sport1_uart_device = { .name = "bfin-sport-uart", .id = 1, + .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources), + .resource = bfin_sport1_uart_resources, + .dev = { + .platform_data = &bfin_sport1_peripherals, /* Passed to driver */ + }, }; #endif +#endif #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) static struct platform_device bfin_mii_bus = { @@ -612,9 +671,13 @@ static struct platform_device *cm_bf537u_devices[] __initdata = { #endif #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART &bfin_sport0_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART &bfin_sport1_uart_device, #endif +#endif #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) &isp1362_hcd_device, diff --git a/arch/blackfin/mach-bf537/boards/minotaur.c b/arch/blackfin/mach-bf537/boards/minotaur.c index 58d6a20..6403964 100644 --- a/arch/blackfin/mach-bf537/boards/minotaur.c +++ b/arch/blackfin/mach-bf537/boards/minotaur.c @@ -377,16 +377,75 @@ static struct platform_device i2c_bfin_twi_device = { #endif #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART +static struct resource bfin_sport0_uart_resources[] = { + { + .start = SPORT0_TCR1, + .end = SPORT0_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT0_RX, + .end = IRQ_SPORT0_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT0_ERROR, + .end = IRQ_SPORT0_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +unsigned short bfin_sport0_peripherals[] = { + P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, + P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0 +}; + static struct platform_device bfin_sport0_uart_device = { .name = "bfin-sport-uart", .id = 0, + .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources), + .resource = bfin_sport0_uart_resources, + .dev = { + .platform_data = &bfin_sport0_peripherals, /* Passed to driver */ + }, +}; +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART +static struct resource bfin_sport1_uart_resources[] = { + { + .start = SPORT1_TCR1, + .end = SPORT1_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT1_RX, + .end = IRQ_SPORT1_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT1_ERROR, + .end = IRQ_SPORT1_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +unsigned short bfin_sport1_peripherals[] = { + P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, + P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0 }; static struct platform_device bfin_sport1_uart_device = { .name = "bfin-sport-uart", .id = 1, + .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources), + .resource = bfin_sport1_uart_resources, + .dev = { + .platform_data = &bfin_sport1_peripherals, /* Passed to driver */ + }, }; #endif +#endif static struct platform_device *minotaur_devices[] __initdata = { #if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE) @@ -433,9 +492,13 @@ static struct platform_device *minotaur_devices[] __initdata = { #endif #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART &bfin_sport0_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART &bfin_sport1_uart_device, #endif +#endif }; diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 554f82d..df4b6b5 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -1677,16 +1677,75 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { }; #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART +static struct resource bfin_sport0_uart_resources[] = { + { + .start = SPORT0_TCR1, + .end = SPORT0_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT0_RX, + .end = IRQ_SPORT0_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT0_ERROR, + .end = IRQ_SPORT0_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +unsigned short bfin_sport0_peripherals[] = { + P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, + P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0 +}; + static struct platform_device bfin_sport0_uart_device = { .name = "bfin-sport-uart", .id = 0, + .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources), + .resource = bfin_sport0_uart_resources, + .dev = { + .platform_data = &bfin_sport0_peripherals, /* Passed to driver */ + }, +}; +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART +static struct resource bfin_sport1_uart_resources[] = { + { + .start = SPORT1_TCR1, + .end = SPORT1_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT1_RX, + .end = IRQ_SPORT1_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT1_ERROR, + .end = IRQ_SPORT1_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +unsigned short bfin_sport1_peripherals[] = { + P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, + P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0 }; static struct platform_device bfin_sport1_uart_device = { .name = "bfin-sport-uart", .id = 1, + .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources), + .resource = bfin_sport1_uart_resources, + .dev = { + .platform_data = &bfin_sport1_peripherals, /* Passed to driver */ + }, }; #endif +#endif #if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE) #define CF_IDE_NAND_CARD_USE_HDD_INTERFACE @@ -1867,9 +1926,13 @@ static struct platform_device *stamp_devices[] __initdata = { #endif #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART &bfin_sport0_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART &bfin_sport1_uart_device, #endif +#endif #if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE) &bfin_pata_device, @@ -1895,10 +1958,10 @@ static struct platform_device *stamp_devices[] __initdata = { static int __init stamp_init(void) { printk(KERN_INFO "%s(): registering device resources\n", __func__); - i2c_register_board_info(0, bfin_i2c_board_info, - ARRAY_SIZE(bfin_i2c_board_info)); bfin_plat_nand_init(); platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices)); + i2c_register_board_info(0, bfin_i2c_board_info, + ARRAY_SIZE(bfin_i2c_board_info)); spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); return 0; diff --git a/arch/blackfin/mach-bf537/boards/tcm_bf537.c b/arch/blackfin/mach-bf537/boards/tcm_bf537.c index d77ca5b..69a2fb8 100644 --- a/arch/blackfin/mach-bf537/boards/tcm_bf537.c +++ b/arch/blackfin/mach-bf537/boards/tcm_bf537.c @@ -493,16 +493,75 @@ static struct platform_device i2c_bfin_twi_device = { #endif #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART +static struct resource bfin_sport0_uart_resources[] = { + { + .start = SPORT0_TCR1, + .end = SPORT0_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT0_RX, + .end = IRQ_SPORT0_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT0_ERROR, + .end = IRQ_SPORT0_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +unsigned short bfin_sport0_peripherals[] = { + P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, + P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0 +}; + static struct platform_device bfin_sport0_uart_device = { .name = "bfin-sport-uart", .id = 0, + .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources), + .resource = bfin_sport0_uart_resources, + .dev = { + .platform_data = &bfin_sport0_peripherals, /* Passed to driver */ + }, +}; +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART +static struct resource bfin_sport1_uart_resources[] = { + { + .start = SPORT1_TCR1, + .end = SPORT1_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT1_RX, + .end = IRQ_SPORT1_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT1_ERROR, + .end = IRQ_SPORT1_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +unsigned short bfin_sport1_peripherals[] = { + P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, + P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0 }; static struct platform_device bfin_sport1_uart_device = { .name = "bfin-sport-uart", .id = 1, + .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources), + .resource = bfin_sport1_uart_resources, + .dev = { + .platform_data = &bfin_sport1_peripherals, /* Passed to driver */ + }, }; #endif +#endif #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) static struct platform_device bfin_mii_bus = { @@ -614,9 +673,13 @@ static struct platform_device *cm_bf537_devices[] __initdata = { #endif #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART &bfin_sport0_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART &bfin_sport1_uart_device, #endif +#endif #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) &isp1362_hcd_device, diff --git a/arch/blackfin/mach-bf538/boards/ezkit.c b/arch/blackfin/mach-bf538/boards/ezkit.c index 1912bc4..d7c6b9f 100644 --- a/arch/blackfin/mach-bf538/boards/ezkit.c +++ b/arch/blackfin/mach-bf538/boards/ezkit.c @@ -262,6 +262,145 @@ static struct platform_device bfin_sir2_device = { #endif #endif +#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART +static struct resource bfin_sport0_uart_resources[] = { + { + .start = SPORT0_TCR1, + .end = SPORT0_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT0_RX, + .end = IRQ_SPORT0_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT0_ERROR, + .end = IRQ_SPORT0_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +unsigned short bfin_sport0_peripherals[] = { + P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, + P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0 +}; + +static struct platform_device bfin_sport0_uart_device = { + .name = "bfin-sport-uart", + .id = 0, + .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources), + .resource = bfin_sport0_uart_resources, + .dev = { + .platform_data = &bfin_sport0_peripherals, /* Passed to driver */ + }, +}; +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART +static struct resource bfin_sport1_uart_resources[] = { + { + .start = SPORT1_TCR1, + .end = SPORT1_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT1_RX, + .end = IRQ_SPORT1_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT1_ERROR, + .end = IRQ_SPORT1_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +unsigned short bfin_sport1_peripherals[] = { + P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, + P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0 +}; + +static struct platform_device bfin_sport1_uart_device = { + .name = "bfin-sport-uart", + .id = 1, + .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources), + .resource = bfin_sport1_uart_resources, + .dev = { + .platform_data = &bfin_sport1_peripherals, /* Passed to driver */ + }, +}; +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART +static struct resource bfin_sport2_uart_resources[] = { + { + .start = SPORT2_TCR1, + .end = SPORT2_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT2_RX, + .end = IRQ_SPORT2_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT2_ERROR, + .end = IRQ_SPORT2_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +unsigned short bfin_sport2_peripherals[] = { + P_SPORT2_TFS, P_SPORT2_DTPRI, P_SPORT2_TSCLK, P_SPORT2_RFS, + P_SPORT2_DRPRI, P_SPORT2_RSCLK, P_SPORT2_DRSEC, P_SPORT2_DTSEC, 0 +}; + +static struct platform_device bfin_sport2_uart_device = { + .name = "bfin-sport-uart", + .id = 2, + .num_resources = ARRAY_SIZE(bfin_sport2_uart_resources), + .resource = bfin_sport2_uart_resources, + .dev = { + .platform_data = &bfin_sport2_peripherals, /* Passed to driver */ + }, +}; +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT3_UART +static struct resource bfin_sport3_uart_resources[] = { + { + .start = SPORT3_TCR1, + .end = SPORT3_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT3_RX, + .end = IRQ_SPORT3_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT3_ERROR, + .end = IRQ_SPORT3_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +unsigned short bfin_sport3_peripherals[] = { + P_SPORT3_TFS, P_SPORT3_DTPRI, P_SPORT3_TSCLK, P_SPORT3_RFS, + P_SPORT3_DRPRI, P_SPORT3_RSCLK, P_SPORT3_DRSEC, P_SPORT3_DTSEC, 0 +}; + +static struct platform_device bfin_sport3_uart_device = { + .name = "bfin-sport-uart", + .id = 3, + .num_resources = ARRAY_SIZE(bfin_sport3_uart_resources), + .resource = bfin_sport3_uart_resources, + .dev = { + .platform_data = &bfin_sport3_peripherals, /* Passed to driver */ + }, +}; +#endif +#endif + #if defined(CONFIG_CAN_BFIN) || defined(CONFIG_CAN_BFIN_MODULE) unsigned short bfin_can_peripherals[] = { P_CAN0_RX, P_CAN0_TX, 0 @@ -767,6 +906,21 @@ static struct platform_device *cm_bf538_devices[] __initdata = { #endif #endif +#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART + &bfin_sport0_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART + &bfin_sport1_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART + &bfin_sport2_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT3_UART + &bfin_sport3_uart_device, +#endif +#endif + #if defined(CONFIG_CAN_BFIN) || defined(CONFIG_CAN_BFIN_MODULE) &bfin_can_device, #endif diff --git a/arch/blackfin/mach-bf548/boards/cm_bf548.c b/arch/blackfin/mach-bf548/boards/cm_bf548.c index 635f9272..cb74587 100644 --- a/arch/blackfin/mach-bf548/boards/cm_bf548.c +++ b/arch/blackfin/mach-bf548/boards/cm_bf548.c @@ -526,6 +526,145 @@ static struct platform_device musb_device = { }; #endif +#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART +static struct resource bfin_sport0_uart_resources[] = { + { + .start = SPORT0_TCR1, + .end = SPORT0_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT0_RX, + .end = IRQ_SPORT0_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT0_ERROR, + .end = IRQ_SPORT0_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +unsigned short bfin_sport0_peripherals[] = { + P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, + P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0 +}; + +static struct platform_device bfin_sport0_uart_device = { + .name = "bfin-sport-uart", + .id = 0, + .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources), + .resource = bfin_sport0_uart_resources, + .dev = { + .platform_data = &bfin_sport0_peripherals, /* Passed to driver */ + }, +}; +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART +static struct resource bfin_sport1_uart_resources[] = { + { + .start = SPORT1_TCR1, + .end = SPORT1_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT1_RX, + .end = IRQ_SPORT1_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT1_ERROR, + .end = IRQ_SPORT1_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +unsigned short bfin_sport1_peripherals[] = { + P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, + P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0 +}; + +static struct platform_device bfin_sport1_uart_device = { + .name = "bfin-sport-uart", + .id = 1, + .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources), + .resource = bfin_sport1_uart_resources, + .dev = { + .platform_data = &bfin_sport1_peripherals, /* Passed to driver */ + }, +}; +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART +static struct resource bfin_sport2_uart_resources[] = { + { + .start = SPORT2_TCR1, + .end = SPORT2_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT2_RX, + .end = IRQ_SPORT2_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT2_ERROR, + .end = IRQ_SPORT2_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +unsigned short bfin_sport2_peripherals[] = { + P_SPORT2_TFS, P_SPORT2_DTPRI, P_SPORT2_TSCLK, P_SPORT2_RFS, + P_SPORT2_DRPRI, P_SPORT2_RSCLK, P_SPORT2_DRSEC, P_SPORT2_DTSEC, 0 +}; + +static struct platform_device bfin_sport2_uart_device = { + .name = "bfin-sport-uart", + .id = 2, + .num_resources = ARRAY_SIZE(bfin_sport2_uart_resources), + .resource = bfin_sport2_uart_resources, + .dev = { + .platform_data = &bfin_sport2_peripherals, /* Passed to driver */ + }, +}; +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT3_UART +static struct resource bfin_sport3_uart_resources[] = { + { + .start = SPORT3_TCR1, + .end = SPORT3_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT3_RX, + .end = IRQ_SPORT3_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT3_ERROR, + .end = IRQ_SPORT3_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +unsigned short bfin_sport3_peripherals[] = { + P_SPORT3_TFS, P_SPORT3_DTPRI, P_SPORT3_TSCLK, P_SPORT3_RFS, + P_SPORT3_DRPRI, P_SPORT3_RSCLK, P_SPORT3_DRSEC, P_SPORT3_DTSEC, 0 +}; + +static struct platform_device bfin_sport3_uart_device = { + .name = "bfin-sport-uart", + .id = 3, + .num_resources = ARRAY_SIZE(bfin_sport3_uart_resources), + .resource = bfin_sport3_uart_resources, + .dev = { + .platform_data = &bfin_sport3_peripherals, /* Passed to driver */ + }, +}; +#endif +#endif + #if defined(CONFIG_PATA_BF54X) || defined(CONFIG_PATA_BF54X_MODULE) static struct resource bfin_atapi_resources[] = { { @@ -960,6 +1099,21 @@ static struct platform_device *cm_bf548_devices[] __initdata = { &musb_device, #endif +#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART + &bfin_sport0_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART + &bfin_sport1_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART + &bfin_sport2_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT3_UART + &bfin_sport3_uart_device, +#endif +#endif + #if defined(CONFIG_PATA_BF54X) || defined(CONFIG_PATA_BF54X_MODULE) &bfin_atapi_device, #endif diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c index 1ed0261..97033fe 100644 --- a/arch/blackfin/mach-bf548/boards/ezkit.c +++ b/arch/blackfin/mach-bf548/boards/ezkit.c @@ -631,6 +631,145 @@ static struct platform_device musb_device = { }; #endif +#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART +static struct resource bfin_sport0_uart_resources[] = { + { + .start = SPORT0_TCR1, + .end = SPORT0_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT0_RX, + .end = IRQ_SPORT0_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT0_ERROR, + .end = IRQ_SPORT0_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +unsigned short bfin_sport0_peripherals[] = { + P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, + P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0 +}; + +static struct platform_device bfin_sport0_uart_device = { + .name = "bfin-sport-uart", + .id = 0, + .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources), + .resource = bfin_sport0_uart_resources, + .dev = { + .platform_data = &bfin_sport0_peripherals, /* Passed to driver */ + }, +}; +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART +static struct resource bfin_sport1_uart_resources[] = { + { + .start = SPORT1_TCR1, + .end = SPORT1_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT1_RX, + .end = IRQ_SPORT1_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT1_ERROR, + .end = IRQ_SPORT1_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +unsigned short bfin_sport1_peripherals[] = { + P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, + P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0 +}; + +static struct platform_device bfin_sport1_uart_device = { + .name = "bfin-sport-uart", + .id = 1, + .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources), + .resource = bfin_sport1_uart_resources, + .dev = { + .platform_data = &bfin_sport1_peripherals, /* Passed to driver */ + }, +}; +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART +static struct resource bfin_sport2_uart_resources[] = { + { + .start = SPORT2_TCR1, + .end = SPORT2_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT2_RX, + .end = IRQ_SPORT2_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT2_ERROR, + .end = IRQ_SPORT2_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +unsigned short bfin_sport2_peripherals[] = { + P_SPORT2_TFS, P_SPORT2_DTPRI, P_SPORT2_TSCLK, P_SPORT2_RFS, + P_SPORT2_DRPRI, P_SPORT2_RSCLK, P_SPORT2_DRSEC, P_SPORT2_DTSEC, 0 +}; + +static struct platform_device bfin_sport2_uart_device = { + .name = "bfin-sport-uart", + .id = 2, + .num_resources = ARRAY_SIZE(bfin_sport2_uart_resources), + .resource = bfin_sport2_uart_resources, + .dev = { + .platform_data = &bfin_sport2_peripherals, /* Passed to driver */ + }, +}; +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT3_UART +static struct resource bfin_sport3_uart_resources[] = { + { + .start = SPORT3_TCR1, + .end = SPORT3_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT3_RX, + .end = IRQ_SPORT3_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT3_ERROR, + .end = IRQ_SPORT3_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +unsigned short bfin_sport3_peripherals[] = { + P_SPORT3_TFS, P_SPORT3_DTPRI, P_SPORT3_TSCLK, P_SPORT3_RFS, + P_SPORT3_DRPRI, P_SPORT3_RSCLK, P_SPORT3_DRSEC, P_SPORT3_DTSEC, 0 +}; + +static struct platform_device bfin_sport3_uart_device = { + .name = "bfin-sport-uart", + .id = 3, + .num_resources = ARRAY_SIZE(bfin_sport3_uart_resources), + .resource = bfin_sport3_uart_resources, + .dev = { + .platform_data = &bfin_sport3_peripherals, /* Passed to driver */ + }, +}; +#endif +#endif + #if defined(CONFIG_CAN_BFIN) || defined(CONFIG_CAN_BFIN_MODULE) unsigned short bfin_can_peripherals[] = { P_CAN0_RX, P_CAN0_TX, 0 @@ -1172,6 +1311,21 @@ static struct platform_device *ezkit_devices[] __initdata = { &bfin_isp1760_device, #endif +#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART + &bfin_sport0_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART + &bfin_sport1_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART + &bfin_sport2_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT3_UART + &bfin_sport3_uart_device, +#endif +#endif + #if defined(CONFIG_CAN_BFIN) || defined(CONFIG_CAN_BFIN_MODULE) &bfin_can_device, #endif -- cgit v0.10.2 From b635f1912da764c960c044ffd58ba27157aa2c85 Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Wed, 23 Sep 2009 08:06:25 +0000 Subject: Blackfin: allow boards to register early devices Signed-off-by: Sonic Zhang Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index 95448ae..69cbc1a 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c @@ -792,10 +792,17 @@ static inline int __init get_mem_size(void) BUG(); } +__attribute__((weak)) +void __init native_machine_early_platform_add_devices(void) +{ +} + void __init setup_arch(char **cmdline_p) { unsigned long sclk, cclk; + native_machine_early_platform_add_devices(); + enable_shadow_console(); /* Check to make sure we are running on the right processor */ -- cgit v0.10.2 From c13ce9fd26c3a0e32b3bf0b00929181e66114ed2 Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Wed, 23 Sep 2009 09:37:46 +0000 Subject: Blackfin: add UART/SPORT early platform resources This lets people easily select the UART/SPORT consoles for early printk while leveraging the pins declared in the boards file. Signed-off-by: Sonic Zhang Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf518/boards/ezbrd.c b/arch/blackfin/mach-bf518/boards/ezbrd.c index 06e4316..44d6d52 100644 --- a/arch/blackfin/mach-bf518/boards/ezbrd.c +++ b/arch/blackfin/mach-bf518/boards/ezbrd.c @@ -775,6 +775,33 @@ static int __init ezbrd_init(void) arch_initcall(ezbrd_init); +static struct platform_device *ezbrd_early_devices[] __initdata = { +#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK) +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART1 + &bfin_uart1_device, +#endif +#endif + +#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART + &bfin_sport0_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART + &bfin_sport1_uart_device, +#endif +#endif +}; + +void __init native_machine_early_platform_add_devices(void) +{ + printk(KERN_INFO "register early platform devices\n"); + early_platform_add_devices(ezbrd_early_devices, + ARRAY_SIZE(ezbrd_early_devices)); +} + void native_machine_restart(char *cmd) { /* workaround reboot hang when booting from SPI */ diff --git a/arch/blackfin/mach-bf527/boards/cm_bf527.c b/arch/blackfin/mach-bf527/boards/cm_bf527.c index 3543bdf..eaa0131 100644 --- a/arch/blackfin/mach-bf527/boards/cm_bf527.c +++ b/arch/blackfin/mach-bf527/boards/cm_bf527.c @@ -1014,6 +1014,33 @@ static int __init cm_init(void) arch_initcall(cm_init); +static struct platform_device *cmbf527_early_devices[] __initdata = { +#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK) +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART1 + &bfin_uart1_device, +#endif +#endif + +#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART + &bfin_sport0_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART + &bfin_sport1_uart_device, +#endif +#endif +}; + +void __init native_machine_early_platform_add_devices(void) +{ + printk(KERN_INFO "register early platform devices\n"); + early_platform_add_devices(cmbf527_early_devices, + ARRAY_SIZE(cmbf527_early_devices)); +} + void native_machine_restart(char *cmd) { /* workaround reboot hang when booting from SPI */ diff --git a/arch/blackfin/mach-bf527/boards/ezbrd.c b/arch/blackfin/mach-bf527/boards/ezbrd.c index a99955d..3ff61e6 100644 --- a/arch/blackfin/mach-bf527/boards/ezbrd.c +++ b/arch/blackfin/mach-bf527/boards/ezbrd.c @@ -854,6 +854,33 @@ static int __init ezbrd_init(void) arch_initcall(ezbrd_init); +static struct platform_device *ezbrd_early_devices[] __initdata = { +#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK) +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART1 + &bfin_uart1_device, +#endif +#endif + +#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART + &bfin_sport0_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART + &bfin_sport1_uart_device, +#endif +#endif +}; + +void __init native_machine_early_platform_add_devices(void) +{ + printk(KERN_INFO "register early platform devices\n"); + early_platform_add_devices(ezbrd_early_devices, + ARRAY_SIZE(ezbrd_early_devices)); +} + void native_machine_restart(char *cmd) { /* workaround reboot hang when booting from SPI */ diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c index f93323d..6138b47 100644 --- a/arch/blackfin/mach-bf527/boards/ezkit.c +++ b/arch/blackfin/mach-bf527/boards/ezkit.c @@ -1099,6 +1099,33 @@ static int __init ezkit_init(void) arch_initcall(ezkit_init); +static struct platform_device *ezkit_early_devices[] __initdata = { +#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK) +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART1 + &bfin_uart1_device, +#endif +#endif + +#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART + &bfin_sport0_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART + &bfin_sport1_uart_device, +#endif +#endif +}; + +void __init native_machine_early_platform_add_devices(void) +{ + printk(KERN_INFO "register early platform devices\n"); + early_platform_add_devices(ezkit_early_devices, + ARRAY_SIZE(ezkit_early_devices)); +} + void native_machine_restart(char *cmd) { /* workaround reboot hang when booting from SPI */ diff --git a/arch/blackfin/mach-bf533/boards/H8606.c b/arch/blackfin/mach-bf533/boards/H8606.c index cb3b74f..d10c8e8 100644 --- a/arch/blackfin/mach-bf533/boards/H8606.c +++ b/arch/blackfin/mach-bf533/boards/H8606.c @@ -455,3 +455,18 @@ static int __init H8606_init(void) } arch_initcall(H8606_init); + +static struct platform_device *H8606_early_devices[] __initdata = { +#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK) +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#endif +}; + +void __init native_machine_early_platform_add_devices(void) +{ + printk(KERN_INFO "register early platform devices\n"); + early_platform_add_devices(H8606_early_devices, + ARRAY_SIZE(H8606_early_devices)); +} diff --git a/arch/blackfin/mach-bf533/boards/blackstamp.c b/arch/blackfin/mach-bf533/boards/blackstamp.c index 4d92946..842b4fa 100644 --- a/arch/blackfin/mach-bf533/boards/blackstamp.c +++ b/arch/blackfin/mach-bf533/boards/blackstamp.c @@ -486,3 +486,27 @@ static int __init blackstamp_init(void) } arch_initcall(blackstamp_init); + +static struct platform_device *stamp_early_devices[] __initdata = { +#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK) +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#endif + +#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART + &bfin_sport0_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART + &bfin_sport1_uart_device, +#endif +#endif +}; + +void __init native_machine_early_platform_add_devices(void) +{ + printk(KERN_INFO "register early platform devices\n"); + early_platform_add_devices(stamp_early_devices, + ARRAY_SIZE(stamp_early_devices)); +} diff --git a/arch/blackfin/mach-bf533/boards/cm_bf533.c b/arch/blackfin/mach-bf533/boards/cm_bf533.c index 33ff27a..0592fe0 100644 --- a/arch/blackfin/mach-bf533/boards/cm_bf533.c +++ b/arch/blackfin/mach-bf533/boards/cm_bf533.c @@ -580,3 +580,27 @@ static int __init cm_bf533_init(void) } arch_initcall(cm_bf533_init); + +static struct platform_device *cm_bf533_early_devices[] __initdata = { +#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK) +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#endif + +#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART + &bfin_sport0_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART + &bfin_sport1_uart_device, +#endif +#endif +}; + +void __init native_machine_early_platform_add_devices(void) +{ + printk(KERN_INFO "register early platform devices\n"); + early_platform_add_devices(cm_bf533_early_devices, + ARRAY_SIZE(cm_bf533_early_devices)); +} diff --git a/arch/blackfin/mach-bf533/boards/ezkit.c b/arch/blackfin/mach-bf533/boards/ezkit.c index 5039247..5332c98 100644 --- a/arch/blackfin/mach-bf533/boards/ezkit.c +++ b/arch/blackfin/mach-bf533/boards/ezkit.c @@ -531,3 +531,18 @@ static int __init ezkit_init(void) } arch_initcall(ezkit_init); + +static struct platform_device *ezkit_early_devices[] __initdata = { +#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK) +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#endif +}; + +void __init native_machine_early_platform_add_devices(void) +{ + printk(KERN_INFO "register early platform devices\n"); + early_platform_add_devices(ezkit_early_devices, + ARRAY_SIZE(ezkit_early_devices)); +} diff --git a/arch/blackfin/mach-bf533/boards/ip0x.c b/arch/blackfin/mach-bf533/boards/ip0x.c index a60d036..7349970 100644 --- a/arch/blackfin/mach-bf533/boards/ip0x.c +++ b/arch/blackfin/mach-bf533/boards/ip0x.c @@ -308,3 +308,18 @@ static int __init ip0x_init(void) } arch_initcall(ip0x_init); + +static struct platform_device *ip0x_early_devices[] __initdata = { +#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK) +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#endif +}; + +void __init native_machine_early_platform_add_devices(void) +{ + printk(KERN_INFO "register early platform devices\n"); + early_platform_add_devices(ip0x_early_devices, + ARRAY_SIZE(ip0x_early_devices)); +} diff --git a/arch/blackfin/mach-bf533/boards/stamp.c b/arch/blackfin/mach-bf533/boards/stamp.c index 428f724..3e80a79 100644 --- a/arch/blackfin/mach-bf533/boards/stamp.c +++ b/arch/blackfin/mach-bf533/boards/stamp.c @@ -642,6 +642,30 @@ static int __init stamp_init(void) arch_initcall(stamp_init); +static struct platform_device *stamp_early_devices[] __initdata = { +#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK) +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#endif + +#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART + &bfin_sport0_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART + &bfin_sport1_uart_device, +#endif +#endif +}; + +void __init native_machine_early_platform_add_devices(void) +{ + printk(KERN_INFO "register early platform devices\n"); + early_platform_add_devices(stamp_early_devices, + ARRAY_SIZE(stamp_early_devices)); +} + void native_machine_restart(char *cmd) { /* workaround pull up on cpld / flash pin not being strong enough */ diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537e.c b/arch/blackfin/mach-bf537/boards/cm_bf537e.c index b483777..c543312 100644 --- a/arch/blackfin/mach-bf537/boards/cm_bf537e.c +++ b/arch/blackfin/mach-bf537/boards/cm_bf537e.c @@ -760,6 +760,33 @@ static int __init cm_bf537e_init(void) arch_initcall(cm_bf537e_init); +static struct platform_device *cm_bf537e_early_devices[] __initdata = { +#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK) +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART1 + &bfin_uart1_device, +#endif +#endif + +#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART + &bfin_sport0_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART + &bfin_sport1_uart_device, +#endif +#endif +}; + +void __init native_machine_early_platform_add_devices(void) +{ + printk(KERN_INFO "register early platform devices\n"); + early_platform_add_devices(cm_bf537e_early_devices, + ARRAY_SIZE(cm_bf537e_early_devices)); +} + void bfin_get_ether_addr(char *addr) { random_ether_addr(addr); diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537u.c b/arch/blackfin/mach-bf537/boards/cm_bf537u.c index c6802be..18daacb 100644 --- a/arch/blackfin/mach-bf537/boards/cm_bf537u.c +++ b/arch/blackfin/mach-bf537/boards/cm_bf537u.c @@ -725,6 +725,33 @@ static int __init cm_bf537u_init(void) arch_initcall(cm_bf537u_init); +static struct platform_device *cm_bf537u_early_devices[] __initdata = { +#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK) +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART1 + &bfin_uart1_device, +#endif +#endif + +#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART + &bfin_sport0_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART + &bfin_sport1_uart_device, +#endif +#endif +}; + +void __init native_machine_early_platform_add_devices(void) +{ + printk(KERN_INFO "register early platform devices\n"); + early_platform_add_devices(cm_bf537u_early_devices, + ARRAY_SIZE(cm_bf537u_early_devices)); +} + void bfin_get_ether_addr(char *addr) { random_ether_addr(addr); diff --git a/arch/blackfin/mach-bf537/boards/minotaur.c b/arch/blackfin/mach-bf537/boards/minotaur.c index 6403964..c489d60 100644 --- a/arch/blackfin/mach-bf537/boards/minotaur.c +++ b/arch/blackfin/mach-bf537/boards/minotaur.c @@ -516,6 +516,33 @@ static int __init minotaur_init(void) arch_initcall(minotaur_init); +static struct platform_device *minotaur_early_devices[] __initdata = { +#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK) +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART1 + &bfin_uart1_device, +#endif +#endif + +#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART + &bfin_sport0_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART + &bfin_sport1_uart_device, +#endif +#endif +}; + +void __init native_machine_early_platform_add_devices(void) +{ + printk(KERN_INFO "register early platform devices\n"); + early_platform_add_devices(minotaur_early_devices, + ARRAY_SIZE(minotaur_early_devices)); +} + void native_machine_restart(char *cmd) { /* workaround reboot hang when booting from SPI */ diff --git a/arch/blackfin/mach-bf537/boards/pnav10.c b/arch/blackfin/mach-bf537/boards/pnav10.c index 3c36abd..f08533d 100644 --- a/arch/blackfin/mach-bf537/boards/pnav10.c +++ b/arch/blackfin/mach-bf537/boards/pnav10.c @@ -571,6 +571,24 @@ static int __init pnav_init(void) arch_initcall(pnav_init); +static struct platform_device *stamp_early_devices[] __initdata = { +#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK) +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART1 + &bfin_uart1_device, +#endif +#endif +}; + +void __init native_machine_early_platform_add_devices(void) +{ + printk(KERN_INFO "register early platform devices\n"); + early_platform_add_devices(stamp_early_devices, + ARRAY_SIZE(stamp_early_devices)); +} + void bfin_get_ether_addr(char *addr) { random_ether_addr(addr); diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index df4b6b5..3cb20d7 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -1969,6 +1969,34 @@ static int __init stamp_init(void) arch_initcall(stamp_init); + +static struct platform_device *stamp_early_devices[] __initdata = { +#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK) +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART1 + &bfin_uart1_device, +#endif +#endif + +#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART + &bfin_sport0_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART + &bfin_sport1_uart_device, +#endif +#endif +}; + +void __init native_machine_early_platform_add_devices(void) +{ + printk(KERN_INFO "register early platform devices\n"); + early_platform_add_devices(stamp_early_devices, + ARRAY_SIZE(stamp_early_devices)); +} + void native_machine_restart(char *cmd) { /* workaround reboot hang when booting from SPI */ diff --git a/arch/blackfin/mach-bf537/boards/tcm_bf537.c b/arch/blackfin/mach-bf537/boards/tcm_bf537.c index 69a2fb8..59951cd 100644 --- a/arch/blackfin/mach-bf537/boards/tcm_bf537.c +++ b/arch/blackfin/mach-bf537/boards/tcm_bf537.c @@ -727,6 +727,33 @@ static int __init tcm_bf537_init(void) arch_initcall(tcm_bf537_init); +static struct platform_device *cm_bf537_early_devices[] __initdata = { +#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK) +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART1 + &bfin_uart1_device, +#endif +#endif + +#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART + &bfin_sport0_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART + &bfin_sport1_uart_device, +#endif +#endif +}; + +void __init native_machine_early_platform_add_devices(void) +{ + printk(KERN_INFO "register early platform devices\n"); + early_platform_add_devices(cm_bf537_early_devices, + ARRAY_SIZE(cm_bf537_early_devices)); +} + void bfin_get_ether_addr(char *addr) { random_ether_addr(addr); diff --git a/arch/blackfin/mach-bf538/boards/ezkit.c b/arch/blackfin/mach-bf538/boards/ezkit.c index d7c6b9f..20387fe 100644 --- a/arch/blackfin/mach-bf538/boards/ezkit.c +++ b/arch/blackfin/mach-bf538/boards/ezkit.c @@ -956,3 +956,39 @@ static int __init ezkit_init(void) } arch_initcall(ezkit_init); + +static struct platform_device *ezkit_early_devices[] __initdata = { +#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK) +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART1 + &bfin_uart1_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART2 + &bfin_uart2_device, +#endif +#endif + +#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART + &bfin_sport0_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART + &bfin_sport1_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART + &bfin_sport2_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT3_UART + &bfin_sport3_uart_device, +#endif +#endif +}; + +void __init native_machine_early_platform_add_devices(void) +{ + printk(KERN_INFO "register early platform devices\n"); + early_platform_add_devices(ezkit_early_devices, + ARRAY_SIZE(ezkit_early_devices)); +} diff --git a/arch/blackfin/mach-bf548/boards/cm_bf548.c b/arch/blackfin/mach-bf548/boards/cm_bf548.c index cb74587..f60c333 100644 --- a/arch/blackfin/mach-bf548/boards/cm_bf548.c +++ b/arch/blackfin/mach-bf548/boards/cm_bf548.c @@ -1165,3 +1165,42 @@ static int __init cm_bf548_init(void) } arch_initcall(cm_bf548_init); + +static struct platform_device *cm_bf548_early_devices[] __initdata = { +#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK) +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART1 + &bfin_uart1_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART2 + &bfin_uart2_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART3 + &bfin_uart3_device, +#endif +#endif + +#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART + &bfin_sport0_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART + &bfin_sport1_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART + &bfin_sport2_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT3_UART + &bfin_sport3_uart_device, +#endif +#endif +}; + +void __init native_machine_early_platform_add_devices(void) +{ + printk(KERN_INFO "register early platform devices\n"); + early_platform_add_devices(cm_bf548_early_devices, + ARRAY_SIZE(cm_bf548_early_devices)); +} diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c index 97033fe..b5d8ea1 100644 --- a/arch/blackfin/mach-bf548/boards/ezkit.c +++ b/arch/blackfin/mach-bf548/boards/ezkit.c @@ -1390,3 +1390,42 @@ static int __init ezkit_init(void) } arch_initcall(ezkit_init); + +static struct platform_device *ezkit_early_devices[] __initdata = { +#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK) +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART1 + &bfin_uart1_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART2 + &bfin_uart2_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART3 + &bfin_uart3_device, +#endif +#endif + +#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART + &bfin_sport0_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART + &bfin_sport1_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT2_UART + &bfin_sport2_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT3_UART + &bfin_sport3_uart_device, +#endif +#endif +}; + +void __init native_machine_early_platform_add_devices(void) +{ + printk(KERN_INFO "register early platform devices\n"); + early_platform_add_devices(ezkit_early_devices, + ARRAY_SIZE(ezkit_early_devices)); +} diff --git a/arch/blackfin/mach-bf561/boards/cm_bf561.c b/arch/blackfin/mach-bf561/boards/cm_bf561.c index 818266f..37dd375 100644 --- a/arch/blackfin/mach-bf561/boards/cm_bf561.c +++ b/arch/blackfin/mach-bf561/boards/cm_bf561.c @@ -547,3 +547,18 @@ static int __init cm_bf561_init(void) } arch_initcall(cm_bf561_init); + +static struct platform_device *cm_bf561_early_devices[] __initdata = { +#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK) +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#endif +}; + +void __init native_machine_early_platform_add_devices(void) +{ + printk(KERN_INFO "register early platform devices\n"); + early_platform_add_devices(cm_bf561_early_devices, + ARRAY_SIZE(cm_bf561_early_devices)); +} diff --git a/arch/blackfin/mach-bf561/boards/ezkit.c b/arch/blackfin/mach-bf561/boards/ezkit.c index c59041c..c7a5db7 100644 --- a/arch/blackfin/mach-bf561/boards/ezkit.c +++ b/arch/blackfin/mach-bf561/boards/ezkit.c @@ -489,3 +489,18 @@ static int __init ezkit_init(void) } arch_initcall(ezkit_init); + +static struct platform_device *ezkit_early_devices[] __initdata = { +#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK) +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#endif +}; + +void __init native_machine_early_platform_add_devices(void) +{ + printk(KERN_INFO "register early platform devices\n"); + early_platform_add_devices(ezkit_early_devices, + ARRAY_SIZE(ezkit_early_devices)); +} diff --git a/arch/blackfin/mach-bf561/boards/tepla.c b/arch/blackfin/mach-bf561/boards/tepla.c index 6c33397..d3017e5 100644 --- a/arch/blackfin/mach-bf561/boards/tepla.c +++ b/arch/blackfin/mach-bf561/boards/tepla.c @@ -140,3 +140,18 @@ static int __init tepla_init(void) } arch_initcall(tepla_init); + +static struct platform_device *tepla_early_devices[] __initdata = { +#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK) +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#endif +}; + +void __init native_machine_early_platform_add_devices(void) +{ + printk(KERN_INFO "register early platform devices\n"); + early_platform_add_devices(tepla_early_devices, + ARRAY_SIZE(tepla_early_devices)); +} -- cgit v0.10.2 From 3630ac34b0ab346ff0910401dbed7af624be7027 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 17 Nov 2009 04:26:22 +0000 Subject: Blackfin: bfin_sport: unify & standardize SPORT masks Rather than have every SPORT driver copy & paste things, declare the C structure and MMR bitmasks in one place for everyone to use. Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/bfin_sport.h b/arch/blackfin/include/asm/bfin_sport.h index b558908..9626cf7 100644 --- a/arch/blackfin/include/asm/bfin_sport.h +++ b/arch/blackfin/include/asm/bfin_sport.h @@ -1,7 +1,7 @@ /* - * bfin_sport.h - userspace header for bfin sport driver + * bfin_sport.h - interface to Blackfin SPORTs * - * Copyright 2004-2008 Analog Devices Inc. + * Copyright 2004-2009 Analog Devices Inc. * * Licensed under the GPL-2 or later. */ @@ -9,16 +9,6 @@ #ifndef __BFIN_SPORT_H__ #define __BFIN_SPORT_H__ -#ifdef __KERNEL__ -#include -#include -#include -#include -#endif - -#define SPORT_MAJOR 237 -#define SPORT_NR_DEVS 2 - /* Sport mode: it can be set to TDM, i2s or others */ #define NORM_MODE 0x0 #define TDM_MODE 0x1 @@ -35,7 +25,7 @@ struct sport_config { unsigned int mode:3; /* if TDM mode is selected, channels must be set */ - int channels; /* Must be in 8 units */ + int channels; /* Must be in 8 units */ unsigned int frame_delay:4; /* Delay between frame sync pulse and first bit */ /* I2S mode */ @@ -69,94 +59,137 @@ struct sport_config { #ifdef __KERNEL__ -struct sport_register { - unsigned short tcr1; - unsigned short reserved0; - unsigned short tcr2; - unsigned short reserved1; - unsigned short tclkdiv; - unsigned short reserved2; - unsigned short tfsdiv; - unsigned short reserved3; - unsigned long tx; - unsigned long reserved_l0; - unsigned long rx; - unsigned long reserved_l1; - unsigned short rcr1; - unsigned short reserved4; - unsigned short rcr2; - unsigned short reserved5; - unsigned short rclkdiv; - unsigned short reserved6; - unsigned short rfsdiv; - unsigned short reserved7; - unsigned short stat; - unsigned short reserved8; - unsigned short chnl; - unsigned short reserved9; - unsigned short mcmc1; - unsigned short reserved10; - unsigned short mcmc2; - unsigned short reserved11; - unsigned long mtcs0; - unsigned long mtcs1; - unsigned long mtcs2; - unsigned long mtcs3; - unsigned long mrcs0; - unsigned long mrcs1; - unsigned long mrcs2; - unsigned long mrcs3; -}; - -struct sport_dev { - struct cdev cdev; /* Char device structure */ - - int sport_num; +#include - int dma_rx_chan; - int dma_tx_chan; - - int rx_irq; - unsigned char *rx_buf; /* Buffer store the received data */ - int rx_len; /* How many bytes will be received */ - int rx_received; /* How many bytes has been received */ - - int tx_irq; - const unsigned char *tx_buf; - int tx_len; - int tx_sent; - - int err_irq; - - struct mutex mutex; /* mutual exclusion semaphore */ - struct task_struct *task; - - wait_queue_head_t waitq; - int wait_con; - struct sport_register *regs; - struct sport_config config; +/* + * All Blackfin system MMRs are padded to 32bits even if the register + * itself is only 16bits. So use a helper macro to streamline this. + */ +#define __BFP(m) u16 m; u16 __pad_##m +struct sport_register { + __BFP(tcr1); + __BFP(tcr2); + __BFP(tclkdiv); + __BFP(tfsdiv); + union { + u32 tx32; + u16 tx16; + }; + u32 __pad_tx; + union { + u32 rx32; /* use the anomaly wrapper below */ + u16 rx16; + }; + u32 __pad_rx; + __BFP(rcr1); + __BFP(rcr2); + __BFP(rclkdiv); + __BFP(rfsdiv); + __BFP(stat); + __BFP(chnl); + __BFP(mcmc1); + __BFP(mcmc2); + u32 mtcs0; + u32 mtcs1; + u32 mtcs2; + u32 mtcs3; + u32 mrcs0; + u32 mrcs1; + u32 mrcs2; + u32 mrcs3; }; +#undef __BFP + +#define bfin_read_sport_rx32(base) \ +({ \ + struct sport_register *__mmrs = (void *)base; \ + u32 __ret; \ + unsigned long flags; \ + if (ANOMALY_05000473) \ + local_irq_save(flags); \ + __ret = __mmrs->rx32; \ + if (ANOMALY_05000473) \ + local_irq_restore(flags); \ + __ret; \ +}) #endif -#define SPORT_TCR1 0 -#define SPORT_TCR2 1 -#define SPORT_TCLKDIV 2 -#define SPORT_TFSDIV 3 -#define SPORT_RCR1 8 -#define SPORT_RCR2 9 -#define SPORT_RCLKDIV 10 -#define SPORT_RFSDIV 11 -#define SPORT_CHANNEL 13 -#define SPORT_MCMC1 14 -#define SPORT_MCMC2 15 -#define SPORT_MTCS0 16 -#define SPORT_MTCS1 17 -#define SPORT_MTCS2 18 -#define SPORT_MTCS3 19 -#define SPORT_MRCS0 20 -#define SPORT_MRCS1 21 -#define SPORT_MRCS2 22 -#define SPORT_MRCS3 23 +/* Workaround defBF*.h SPORT MMRs till they get cleansed */ +#undef DTYPE_NORM +#undef SLEN +#undef SP_WOFF +#undef SP_WSIZE + +/* SPORT_TCR1 Masks */ +#define TSPEN 0x0001 /* TX enable */ +#define ITCLK 0x0002 /* Internal TX Clock Select */ +#define TDTYPE 0x000C /* TX Data Formatting Select */ +#define DTYPE_NORM 0x0000 /* Data Format Normal */ +#define DTYPE_ULAW 0x0008 /* Compand Using u-Law */ +#define DTYPE_ALAW 0x000C /* Compand Using A-Law */ +#define TLSBIT 0x0010 /* TX Bit Order */ +#define ITFS 0x0200 /* Internal TX Frame Sync Select */ +#define TFSR 0x0400 /* TX Frame Sync Required Select */ +#define DITFS 0x0800 /* Data Independent TX Frame Sync Select */ +#define LTFS 0x1000 /* Low TX Frame Sync Select */ +#define LATFS 0x2000 /* Late TX Frame Sync Select */ +#define TCKFE 0x4000 /* TX Clock Falling Edge Select */ + +/* SPORT_TCR2 Masks */ +#define SLEN 0x001F /* SPORT TX Word Length (2 - 31) */ +#define DP_SLEN(x) BFIN_DEPOSIT(SLEN, x) +#define EX_SLEN(x) BFIN_EXTRACT(SLEN, x) +#define TXSE 0x0100 /* TX Secondary Enable */ +#define TSFSE 0x0200 /* TX Stereo Frame Sync Enable */ +#define TRFST 0x0400 /* TX Right-First Data Order */ + +/* SPORT_RCR1 Masks */ +#define RSPEN 0x0001 /* RX enable */ +#define IRCLK 0x0002 /* Internal RX Clock Select */ +#define RDTYPE 0x000C /* RX Data Formatting Select */ +/* DTYPE_* defined above */ +#define RLSBIT 0x0010 /* RX Bit Order */ +#define IRFS 0x0200 /* Internal RX Frame Sync Select */ +#define RFSR 0x0400 /* RX Frame Sync Required Select */ +#define LRFS 0x1000 /* Low RX Frame Sync Select */ +#define LARFS 0x2000 /* Late RX Frame Sync Select */ +#define RCKFE 0x4000 /* RX Clock Falling Edge Select */ + +/* SPORT_RCR2 Masks */ +/* SLEN defined above */ +#define RXSE 0x0100 /* RX Secondary Enable */ +#define RSFSE 0x0200 /* RX Stereo Frame Sync Enable */ +#define RRFST 0x0400 /* Right-First Data Order */ + +/* SPORT_STAT Masks */ +#define RXNE 0x0001 /* RX FIFO Not Empty Status */ +#define RUVF 0x0002 /* RX Underflow Status */ +#define ROVF 0x0004 /* RX Overflow Status */ +#define TXF 0x0008 /* TX FIFO Full Status */ +#define TUVF 0x0010 /* TX Underflow Status */ +#define TOVF 0x0020 /* TX Overflow Status */ +#define TXHRE 0x0040 /* TX Hold Register Empty */ + +/* SPORT_MCMC1 Masks */ +#define SP_WOFF 0x03FF /* Multichannel Window Offset Field */ +#define DP_SP_WOFF(x) BFIN_DEPOSIT(SP_WOFF, x) +#define EX_SP_WOFF(x) BFIN_EXTRACT(SP_WOFF, x) +#define SP_WSIZE 0xF000 /* Multichannel Window Size Field */ +#define DP_SP_WSIZE(x) BFIN_DEPOSIT(SP_WSIZE, x) +#define EX_SP_WSIZE(x) BFIN_EXTRACT(SP_WSIZE, x) + +/* SPORT_MCMC2 Masks */ +#define MCCRM 0x0003 /* Multichannel Clock Recovery Mode */ +#define REC_BYPASS 0x0000 /* Bypass Mode (No Clock Recovery) */ +#define REC_2FROM4 0x0002 /* Recover 2 MHz Clock from 4 MHz Clock */ +#define REC_8FROM16 0x0003 /* Recover 8 MHz Clock from 16 MHz Clock */ +#define MCDTXPE 0x0004 /* Multichannel DMA Transmit Packing */ +#define MCDRXPE 0x0008 /* Multichannel DMA Receive Packing */ +#define MCMEN 0x0010 /* Multichannel Frame Mode Enable */ +#define FSDR 0x0080 /* Multichannel Frame Sync to Data Relationship */ +#define MFD 0xF000 /* Multichannel Frame Delay */ +#define DP_MFD(x) BFIN_DEPOSIT(MFD, x) +#define EX_MFD(x) BFIN_EXTRACT(MFD, x) #endif diff --git a/arch/blackfin/include/asm/def_LPBlackfin.h b/arch/blackfin/include/asm/def_LPBlackfin.h index 2590646..e521f8e 100644 --- a/arch/blackfin/include/asm/def_LPBlackfin.h +++ b/arch/blackfin/include/asm/def_LPBlackfin.h @@ -12,6 +12,8 @@ #include #define MK_BMSK_(x) (1<> __ffs(mask)) #ifndef __ASSEMBLY__ -- cgit v0.10.2 From c9784ebb23be1e2ef23f537d6df04e0ea0206802 Mon Sep 17 00:00:00 2001 From: Yi Li Date: Fri, 4 Dec 2009 06:56:21 +0000 Subject: Blackfin: flush caches on SMP when one core calls another via IPI Sometimes a SMP system will randomly panic at boot. This is due to caches being out of sync when one core tries to signal the other. So when one core calls another via IPI, flush the data caches. Signed-off-by: Yi Li Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c index 369e687..eddb720 100644 --- a/arch/blackfin/mach-common/smp.c +++ b/arch/blackfin/mach-common/smp.c @@ -122,9 +122,17 @@ static void ipi_call_function(unsigned int cpu, struct ipi_message *msg) wait = msg->call_struct.wait; cpu_clear(cpu, msg->call_struct.pending); func(info); - if (wait) + if (wait) { +#ifdef __ARCH_SYNC_CORE_DCACHE + /* + * 'wait' usually means synchronization between CPUs. + * Invalidate D cache in case shared data was changed + * by func() to ensure cache coherence. + */ + resync_core_dcache(); +#endif cpu_clear(cpu, msg->call_struct.waitmask); - else + } else kfree(msg); } @@ -219,6 +227,13 @@ int smp_call_function(void (*func)(void *info), void *info, int wait) blackfin_dcache_invalidate_range( (unsigned long)(&msg->call_struct.waitmask), (unsigned long)(&msg->call_struct.waitmask)); +#ifdef __ARCH_SYNC_CORE_DCACHE + /* + * Invalidate D cache in case shared data was changed by + * other processors to ensure cache coherence. + */ + resync_core_dcache(); +#endif kfree(msg); } return 0; @@ -261,6 +276,13 @@ int smp_call_function_single(int cpuid, void (*func) (void *info), void *info, blackfin_dcache_invalidate_range( (unsigned long)(&msg->call_struct.waitmask), (unsigned long)(&msg->call_struct.waitmask)); +#ifdef __ARCH_SYNC_CORE_DCACHE + /* + * Invalidate D cache in case shared data was changed by + * other processors to ensure cache coherence. + */ + resync_core_dcache(); +#endif kfree(msg); } return 0; -- cgit v0.10.2 From e18e7dd33454f277b9438af66d25984362278021 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Mon, 7 Dec 2009 10:05:58 +0000 Subject: Blackfin: fix MPU page permission masks overflow when dealing with async memory Attempting to use the MPU while doing XIP out of parallel flash hooked up to the async memory bus would often result in random crashes as the MPU slowly corrupted memory. The fallout here is that the async banks gain MPU protection from user space too. So any accesses have to go through the mmap() interface rather than just using hardcoded pointers. Signed-off-by: Barry Song Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/mmu_context.h b/arch/blackfin/include/asm/mmu_context.h index ae8ef4f..7f363d7 100644 --- a/arch/blackfin/include/asm/mmu_context.h +++ b/arch/blackfin/include/asm/mmu_context.h @@ -13,6 +13,7 @@ #include #include #include +#include /* Note: L1 stacks are CPU-private things, so we bluntly disable this feature in SMP mode, and use the per-CPU scratch SRAM bank only to @@ -117,9 +118,16 @@ static inline void protect_page(struct mm_struct *mm, unsigned long addr, unsigned long flags) { unsigned long *mask = mm->context.page_rwx_mask; - unsigned long page = addr >> 12; - unsigned long idx = page >> 5; - unsigned long bit = 1 << (page & 31); + unsigned long page; + unsigned long idx; + unsigned long bit; + + if (unlikely(addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE)) + page = (addr - (ASYNC_BANK0_BASE - _ramend)) >> 12; + else + page = addr >> 12; + idx = page >> 5; + bit = 1 << (page & 31); if (flags & VM_READ) mask[idx] |= bit; diff --git a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c index 930c01c..d4cc53a 100644 --- a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c +++ b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c @@ -114,10 +114,15 @@ static noinline int dcplb_miss(unsigned int cpu) d_data = L2_DMEMORY; } else if (addr >= physical_mem_end) { if (addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE) { - addr &= ~(4 * 1024 * 1024 - 1); - d_data &= ~PAGE_SIZE_4KB; - d_data |= PAGE_SIZE_4MB; - d_data |= CPLB_USER_RD | CPLB_USER_WR; + mask = current_rwx_mask[cpu]; + if (mask) { + int page = (addr - (ASYNC_BANK0_BASE - _ramend)) >> PAGE_SHIFT; + int idx = page >> 5; + int bit = 1 << (page & 31); + + if (mask[idx] & bit) + d_data |= CPLB_USER_RD; + } } else if (addr >= BOOT_ROM_START && addr < BOOT_ROM_START + BOOT_ROM_LENGTH && (status & (FAULT_RW | FAULT_USERSUPV)) == FAULT_USERSUPV) { addr &= ~(1 * 1024 * 1024 - 1); @@ -204,10 +209,19 @@ static noinline int icplb_miss(unsigned int cpu) i_data = L2_IMEMORY; } else if (addr >= physical_mem_end) { if (addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE) { - addr &= ~(4 * 1024 * 1024 - 1); - i_data &= ~PAGE_SIZE_4KB; - i_data |= PAGE_SIZE_4MB; - i_data |= CPLB_USER_RD; + if (!(status & FAULT_USERSUPV)) { + unsigned long *mask = current_rwx_mask[cpu]; + + if (mask) { + int page = (addr - (ASYNC_BANK0_BASE - _ramend)) >> PAGE_SHIFT; + int idx = page >> 5; + int bit = 1 << (page & 31); + + mask += 2 * page_mask_nelts; + if (mask[idx] & bit) + i_data |= CPLB_USER_RD; + } + } } else if (addr >= BOOT_ROM_START && addr < BOOT_ROM_START + BOOT_ROM_LENGTH && (status & FAULT_USERSUPV)) { addr &= ~(1 * 1024 * 1024 - 1); diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index 69cbc1a..8dc7ee1 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c @@ -597,7 +597,12 @@ static __init void memory_setup(void) } #ifdef CONFIG_MPU +#if defined(CONFIG_ROMFS_ON_MTD) && defined(CONFIG_MTD_ROM) + page_mask_nelts = (((_ramend + ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE - + ASYNC_BANK0_BASE) >> PAGE_SHIFT) + 31) / 32; +#else page_mask_nelts = ((_ramend >> PAGE_SHIFT) + 31) / 32; +#endif page_mask_order = get_order(3 * page_mask_nelts * sizeof(long)); #endif -- cgit v0.10.2 From 6924dfb0588dab02a331a3a526f8a8fae7d1b3cc Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Mon, 7 Dec 2009 13:41:28 +0000 Subject: Blackfin: bf527-ezkit: add support for V2.1 boards Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index 53c1e1d..9409ae3 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -349,7 +349,7 @@ config MEM_MT48LC8M32B2B5_7 config MEM_MT48LC32M16A2TG_75 bool - depends on (BFIN527_EZKIT || BFIN532_IP0X || BLACKSTAMP) + depends on (BFIN527_EZKIT || BFIN527_EZKIT_V2 || BFIN532_IP0X || BLACKSTAMP) default y config MEM_MT48LC32M8A2_75 @@ -448,7 +448,7 @@ config VCO_MULT range 1 64 default "22" if BFIN533_EZKIT default "45" if BFIN533_STAMP - default "20" if (BFIN537_STAMP || BFIN527_EZKIT || BFIN548_EZKIT || BFIN548_BLUETECHNIX_CM || BFIN538_EZKIT) + default "20" if (BFIN537_STAMP || BFIN527_EZKIT || BFIN527_EZKIT_V2 || BFIN548_EZKIT || BFIN548_BLUETECHNIX_CM || BFIN538_EZKIT) default "22" if BFIN533_BLUETECHNIX_CM default "20" if (BFIN537_BLUETECHNIX_CM_E || BFIN537_BLUETECHNIX_CM_U || BFIN527_BLUETECHNIX_CM || BFIN561_BLUETECHNIX_CM) default "20" if BFIN561_EZKIT diff --git a/arch/blackfin/configs/BF527-EZKIT-V2_defconfig b/arch/blackfin/configs/BF527-EZKIT-V2_defconfig new file mode 100644 index 0000000..d2dfcb0 --- /dev/null +++ b/arch/blackfin/configs/BF527-EZKIT-V2_defconfig @@ -0,0 +1,1811 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.32.2 +# +# CONFIG_MMU is not set +# CONFIG_FPU is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_BLACKFIN=y +CONFIG_GENERIC_CSUM=y +CONFIG_GENERIC_BUG=y +CONFIG_ZONE_DMA=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_GENERIC_GPIO=y +CONFIG_FORCE_MAX_ZONEORDER=14 +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_BZIP2=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set +# CONFIG_SYSFS_DEPRECATED_V2 is not set +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +# CONFIG_ELF_CORE is not set +CONFIG_BASE_FULL=y +# CONFIG_FUTEX is not set +CONFIG_EPOLL=y +# CONFIG_SIGNALFD is not set +# CONFIG_TIMERFD is not set +# CONFIG_EVENTFD is not set +# CONFIG_AIO is not set + +# +# Kernel Performance Events And Counters +# +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_COMPAT_BRK=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_MMAP_ALLOW_UNINITIALIZED=y +# CONFIG_PROFILING is not set +CONFIG_HAVE_OPROFILE=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +# CONFIG_SLOW_WORK is not set +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +CONFIG_SLABINFO=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_BLOCK=y +# CONFIG_LBDAF is not set +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +# CONFIG_IOSCHED_DEADLINE is not set +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_PREEMPT is not set +# CONFIG_FREEZER is not set + +# +# Blackfin Processor Options +# + +# +# Processor and Board Settings +# +# CONFIG_BF512 is not set +# CONFIG_BF514 is not set +# CONFIG_BF516 is not set +# CONFIG_BF518 is not set +# CONFIG_BF522 is not set +# CONFIG_BF523 is not set +# CONFIG_BF524 is not set +# CONFIG_BF525 is not set +# CONFIG_BF526 is not set +CONFIG_BF527=y +# CONFIG_BF531 is not set +# CONFIG_BF532 is not set +# CONFIG_BF533 is not set +# CONFIG_BF534 is not set +# CONFIG_BF536 is not set +# CONFIG_BF537 is not set +# CONFIG_BF538 is not set +# CONFIG_BF539 is not set +# CONFIG_BF542_std is not set +# CONFIG_BF542M is not set +# CONFIG_BF544_std is not set +# CONFIG_BF544M is not set +# CONFIG_BF547_std is not set +# CONFIG_BF547M is not set +# CONFIG_BF548_std is not set +# CONFIG_BF548M is not set +# CONFIG_BF549_std is not set +# CONFIG_BF549M is not set +# CONFIG_BF561 is not set +CONFIG_BF_REV_MIN=0 +CONFIG_BF_REV_MAX=2 +# CONFIG_BF_REV_0_0 is not set +# CONFIG_BF_REV_0_1 is not set +CONFIG_BF_REV_0_2=y +# CONFIG_BF_REV_0_3 is not set +# CONFIG_BF_REV_0_4 is not set +# CONFIG_BF_REV_0_5 is not set +# CONFIG_BF_REV_0_6 is not set +# CONFIG_BF_REV_ANY is not set +# CONFIG_BF_REV_NONE is not set +CONFIG_MEM_MT48LC32M16A2TG_75=y +CONFIG_IRQ_PLL_WAKEUP=7 +CONFIG_IRQ_DMA0_ERROR=7 +CONFIG_IRQ_DMAR0_BLK=7 +CONFIG_IRQ_DMAR1_BLK=7 +CONFIG_IRQ_DMAR0_OVR=7 +CONFIG_IRQ_DMAR1_OVR=7 +CONFIG_IRQ_PPI_ERROR=7 +CONFIG_IRQ_MAC_ERROR=7 +CONFIG_IRQ_SPORT0_ERROR=7 +CONFIG_IRQ_SPORT1_ERROR=7 +CONFIG_IRQ_UART0_ERROR=7 +CONFIG_IRQ_UART1_ERROR=7 +CONFIG_IRQ_RTC=8 +CONFIG_IRQ_PPI=8 +CONFIG_IRQ_SPORT0_RX=9 +CONFIG_IRQ_SPORT0_TX=9 +CONFIG_IRQ_SPORT1_RX=9 +CONFIG_IRQ_SPORT1_TX=9 +CONFIG_IRQ_TWI=10 +CONFIG_IRQ_UART0_RX=10 +CONFIG_IRQ_UART0_TX=10 +CONFIG_IRQ_UART1_RX=10 +CONFIG_IRQ_UART1_TX=10 +CONFIG_IRQ_OPTSEC=11 +CONFIG_IRQ_CNT=11 +CONFIG_IRQ_MAC_RX=11 +CONFIG_IRQ_PORTH_INTA=11 +CONFIG_IRQ_MAC_TX=11 +CONFIG_IRQ_PORTH_INTB=11 +CONFIG_IRQ_TIMER0=8 +CONFIG_IRQ_TIMER1=12 +CONFIG_IRQ_TIMER2=12 +CONFIG_IRQ_TIMER3=12 +CONFIG_IRQ_TIMER4=12 +CONFIG_IRQ_TIMER5=12 +CONFIG_IRQ_TIMER6=12 +CONFIG_IRQ_TIMER7=12 +CONFIG_IRQ_PORTG_INTA=12 +CONFIG_IRQ_PORTG_INTB=12 +CONFIG_IRQ_MEM_DMA0=13 +CONFIG_IRQ_MEM_DMA1=13 +CONFIG_IRQ_WATCH=13 +CONFIG_IRQ_PORTF_INTA=13 +CONFIG_IRQ_PORTF_INTB=13 +CONFIG_BF52x=y +# CONFIG_BFIN527_EZKIT is not set +CONFIG_BFIN527_EZKIT_V2=y +# CONFIG_BFIN527_BLUETECHNIX_CM is not set +# CONFIG_BFIN526_EZBRD is not set + +# +# BF527 Specific Configuration +# + +# +# Alternative Multiplexing Scheme +# +# CONFIG_BF527_SPORT0_PORTF is not set +CONFIG_BF527_SPORT0_PORTG=y +CONFIG_BF527_SPORT0_TSCLK_PG10=y +# CONFIG_BF527_SPORT0_TSCLK_PG14 is not set +CONFIG_BF527_UART1_PORTF=y +# CONFIG_BF527_UART1_PORTG is not set +# CONFIG_BF527_NAND_D_PORTF is not set +CONFIG_BF527_NAND_D_PORTH=y + +# +# Interrupt Priority Assignment +# + +# +# Priority +# +CONFIG_IRQ_SPI=10 +CONFIG_IRQ_SPI_ERROR=7 +CONFIG_IRQ_NFC_ERROR=7 +CONFIG_IRQ_HDMA_ERROR=7 +CONFIG_IRQ_HDMA=7 +CONFIG_IRQ_USB_EINT=10 +CONFIG_IRQ_USB_INT0=11 +CONFIG_IRQ_USB_INT1=11 +CONFIG_IRQ_USB_INT2=11 +CONFIG_IRQ_USB_DMA=11 + +# +# Board customizations +# +# CONFIG_CMDLINE_BOOL is not set +CONFIG_BOOT_LOAD=0x1000 + +# +# Clock/PLL Setup +# +CONFIG_CLKIN_HZ=25000000 +# CONFIG_BFIN_KERNEL_CLOCK is not set +CONFIG_MAX_VCO_HZ=600000000 +CONFIG_MIN_VCO_HZ=50000000 +CONFIG_MAX_SCLK_HZ=133333333 +CONFIG_MIN_SCLK_HZ=27000000 + +# +# Kernel Timer/Scheduler +# +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +# CONFIG_SCHED_HRTICK is not set +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +# CONFIG_TICKSOURCE_GPTMR0 is not set +CONFIG_TICKSOURCE_CORETMR=y +# CONFIG_CYCLES_CLOCKSOURCE is not set +# CONFIG_GPTMR0_CLOCKSOURCE is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y + +# +# Misc +# +CONFIG_BFIN_SCRATCH_REG_RETN=y +# CONFIG_BFIN_SCRATCH_REG_RETE is not set +# CONFIG_BFIN_SCRATCH_REG_CYCLES is not set + +# +# Blackfin Kernel Optimizations +# + +# +# Memory Optimizations +# +CONFIG_I_ENTRY_L1=y +CONFIG_EXCPT_IRQ_SYSC_L1=y +CONFIG_DO_IRQ_L1=y +CONFIG_CORE_TIMER_IRQ_L1=y +CONFIG_IDLE_L1=y +# CONFIG_SCHEDULE_L1 is not set +CONFIG_ARITHMETIC_OPS_L1=y +CONFIG_ACCESS_OK_L1=y +# CONFIG_MEMSET_L1 is not set +# CONFIG_MEMCPY_L1 is not set +# CONFIG_SYS_BFIN_SPINLOCK_L1 is not set +# CONFIG_IP_CHECKSUM_L1 is not set +CONFIG_CACHELINE_ALIGNED_L1=y +# CONFIG_SYSCALL_TAB_L1 is not set +# CONFIG_CPLB_SWITCH_TAB_L1 is not set +CONFIG_APP_STACK_L1=y + +# +# Speed Optimizations +# +CONFIG_BFIN_INS_LOWOVERHEAD=y +CONFIG_RAMKERNEL=y +# CONFIG_ROMKERNEL is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_VIRT_TO_BUS=y +CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0 +CONFIG_BFIN_GPTIMERS=y +# CONFIG_DMA_UNCACHED_4M is not set +# CONFIG_DMA_UNCACHED_2M is not set +CONFIG_DMA_UNCACHED_1M=y +# CONFIG_DMA_UNCACHED_512K is not set +# CONFIG_DMA_UNCACHED_256K is not set +# CONFIG_DMA_UNCACHED_128K is not set +# CONFIG_DMA_UNCACHED_NONE is not set + +# +# Cache Support +# +CONFIG_BFIN_ICACHE=y +CONFIG_BFIN_EXTMEM_ICACHEABLE=y +CONFIG_BFIN_DCACHE=y +# CONFIG_BFIN_DCACHE_BANKA is not set +CONFIG_BFIN_EXTMEM_DCACHEABLE=y +CONFIG_BFIN_EXTMEM_WRITEBACK=y +# CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set + +# +# Memory Protection Unit +# +# CONFIG_MPU is not set + +# +# Asynchronous Memory Configuration +# + +# +# EBIU_AMGCTL Global Control +# +CONFIG_C_AMCKEN=y +CONFIG_C_CDPRIO=y +# CONFIG_C_AMBEN is not set +# CONFIG_C_AMBEN_B0 is not set +# CONFIG_C_AMBEN_B0_B1 is not set +# CONFIG_C_AMBEN_B0_B1_B2 is not set +CONFIG_C_AMBEN_ALL=y + +# +# EBIU_AMBCTL Control +# +CONFIG_BANK_0=0x7BB0 +CONFIG_BANK_1=0x7BB0 +CONFIG_BANK_2=0x7BB0 +CONFIG_BANK_3=0x99B2 + +# +# Bus options (PCI, PCMCIA, EISA, MCA, ISA) +# +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF_FDPIC=y +CONFIG_BINFMT_FLAT=y +CONFIG_BINFMT_ZFLAT=y +# CONFIG_BINFMT_SHARED_FLAT is not set +# CONFIG_HAVE_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +# CONFIG_PM is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETLABEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +CONFIG_IRDA=m + +# +# IrDA protocols +# +CONFIG_IRLAN=m +CONFIG_IRCOMM=m +# CONFIG_IRDA_ULTRA is not set + +# +# IrDA options +# +# CONFIG_IRDA_CACHE_LAST_LSAP is not set +# CONFIG_IRDA_FAST_RR is not set +# CONFIG_IRDA_DEBUG is not set + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +CONFIG_IRTTY_SIR=m +CONFIG_BFIN_SIR=m +CONFIG_BFIN_SIR0=y +CONFIG_SIR_BFIN_DMA=y +# CONFIG_SIR_BFIN_PIO is not set + +# +# Dongle support +# +# CONFIG_DONGLE is not set +# CONFIG_KINGSUN_DONGLE is not set +# CONFIG_KSDAZZLE_DONGLE is not set +# CONFIG_KS959_DONGLE is not set + +# +# FIR device drivers +# +# CONFIG_USB_IRDA is not set +# CONFIG_SIGMATEL_FIR is not set +# CONFIG_MCS_FIR is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +# CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=m +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_GEN_PROBE=m +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_CFI_INTELEXT is not set +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_RAM=y +CONFIG_MTD_ROM=m +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +CONFIG_MTD_COMPLEX_MAPPINGS=y +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_GPIO_ADDR is not set +# CONFIG_MTD_UCLINUX is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_DATAFLASH is not set +CONFIG_MTD_M25P80=y +CONFIG_M25PXX_USE_FAST_READ=y +# CONFIG_MTD_SST25L is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=m +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_IDS=m +# CONFIG_MTD_NAND_BF5XX is not set +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ALAUDA is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_MISC_DEVICES=y +# CONFIG_AD525X_DPOT is not set +# CONFIG_ICS932S401 is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_ISL29003 is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EEPROM_93CX6 is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_SCSI_PROC_FS is not set + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +# CONFIG_SCSI_LOWLEVEL is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_BFIN_MAC=y +CONFIG_BFIN_MAC_USE_L1=y +CONFIG_BFIN_TX_DESC_NUM=10 +CONFIG_BFIN_RX_DESC_NUM=20 +CONFIG_BFIN_MAC_RMII=y +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set +# CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set +# CONFIG_ADF702X is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set +# CONFIG_WLAN is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +CONFIG_INPUT_FF_MEMLESS=m +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ADP5520=y +# CONFIG_KEYBOARD_ADP5588 is not set +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_QT2160 is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_GPIO is not set +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_LM8323 is not set +# CONFIG_KEYBOARD_MAX7359 is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_AD7877 is not set +CONFIG_TOUCHSCREEN_AD7879_I2C=y +CONFIG_TOUCHSCREEN_AD7879=y +# CONFIG_TOUCHSCREEN_EETI is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +# CONFIG_TOUCHSCREEN_MCS5000 is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_INEXIO is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_WM97XX is not set +# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set +# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_ATI_REMOTE is not set +# CONFIG_INPUT_ATI_REMOTE2 is not set +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +# CONFIG_INPUT_POWERMATE is not set +# CONFIG_INPUT_YEALINK is not set +# CONFIG_INPUT_CM109 is not set +# CONFIG_INPUT_UINPUT is not set +# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set +# CONFIG_INPUT_BFIN_ROTARY is not set +# CONFIG_INPUT_AD714X is not set +# CONFIG_INPUT_ADXL34X is not set +# CONFIG_INPUT_PCF8574 is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_BFIN_DMA_INTERFACE=m +# CONFIG_BFIN_PPI is not set +# CONFIG_BFIN_PPIFCD is not set +# CONFIG_BFIN_SIMPLE_TIMER is not set +# CONFIG_BFIN_SPI_ADC is not set +CONFIG_BFIN_SPORT=m +# CONFIG_BFIN_TWI_LCD is not set +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_DEVKMEM is not set +CONFIG_BFIN_JTAG_COMM=m +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_MAX3100 is not set +CONFIG_SERIAL_BFIN=y +CONFIG_SERIAL_BFIN_CONSOLE=y +CONFIG_SERIAL_BFIN_DMA=y +# CONFIG_SERIAL_BFIN_PIO is not set +# CONFIG_SERIAL_BFIN_UART0 is not set +CONFIG_SERIAL_BFIN_UART1=y +# CONFIG_BFIN_UART1_CTSRTS is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_BFIN_SPORT is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +# CONFIG_LEGACY_PTYS is not set +CONFIG_BFIN_OTP=y +# CONFIG_BFIN_OTP_WRITE_ENABLE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=m +CONFIG_I2C_HELPER_AUTO=y + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +CONFIG_I2C_BLACKFIN_TWI=y +CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100 +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_SIMTEC is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_STUB is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_DS1682 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +CONFIG_SPI_BFIN=y +# CONFIG_SPI_BFIN_LOCK is not set +# CONFIG_SPI_BFIN_SPORT is not set +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set + +# +# SPI Protocol Masters +# +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set + +# +# PPS support +# +# CONFIG_PPS is not set +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_DEBUG_GPIO is not set +CONFIG_GPIO_SYSFS=y + +# +# Memory mapped GPIO expanders: +# + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_ADP5520 is not set +# CONFIG_GPIO_ADP5588 is not set + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set + +# +# AC97 GPIO expanders: +# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_BFIN_WDT=y + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_UCB1400_CORE is not set +# CONFIG_TPS65010 is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_PMIC_DA903X is not set +CONFIG_PMIC_ADP5520=y +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13783 is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_BFIN_T350MCQB is not set +CONFIG_FB_BFIN_LQ035Q1=y +# CONFIG_FB_BFIN_7393 is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_LCD_CLASS_DEVICE=m +# CONFIG_LCD_LMS283GF05 is not set +# CONFIG_LCD_LTV350QV is not set +# CONFIG_LCD_ILI9320 is not set +# CONFIG_LCD_TDO24M is not set +# CONFIG_LCD_VGG2432A4 is not set +# CONFIG_LCD_PLATFORM is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=m +CONFIG_BACKLIGHT_GENERIC=m +# CONFIG_BACKLIGHT_ADP5520 is not set +# CONFIG_BACKLIGHT_ADP8870 is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +# CONFIG_LOGO_LINUX_CLUT224 is not set +# CONFIG_LOGO_BLACKFIN_VGA16 is not set +CONFIG_LOGO_BLACKFIN_CLUT224=y +CONFIG_SOUND=m +# CONFIG_SOUND_OSS_CORE is not set +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +CONFIG_SND_JACK=y +# CONFIG_SND_SEQUENCER is not set +# CONFIG_SND_MIXER_OSS is not set +# CONFIG_SND_PCM_OSS is not set +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +# CONFIG_SND_RAWMIDI_SEQ is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +CONFIG_SND_DRIVERS=y +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set +CONFIG_SND_SPI=y + +# +# ALSA Blackfin devices +# +# CONFIG_SND_BFIN_AD73322 is not set +CONFIG_SND_USB=y +# CONFIG_SND_USB_AUDIO is not set +# CONFIG_SND_USB_CAIAQ is not set +CONFIG_SND_SOC=m +CONFIG_SND_SOC_AC97_BUS=y +CONFIG_SND_BF5XX_I2S=m +CONFIG_SND_BF5XX_SOC_SSM2602=m +# CONFIG_SND_BF5XX_SOC_AD73311 is not set +# CONFIG_SND_BF5XX_SOC_ADAU1371 is not set +# CONFIG_SND_BF5XX_SOC_ADAU1761 is not set +# CONFIG_SND_BF5XX_TDM is not set +CONFIG_SND_BF5XX_AC97=m +CONFIG_SND_BF5XX_MMAP_SUPPORT=y +# CONFIG_SND_BF5XX_MULTICHAN_SUPPORT is not set +# CONFIG_SND_BF5XX_HAVE_COLD_RESET is not set +CONFIG_SND_BF5XX_SOC_AD1980=m +CONFIG_SND_BF5XX_SOC_SPORT=m +CONFIG_SND_BF5XX_SOC_I2S=m +CONFIG_SND_BF5XX_SOC_AC97=m +CONFIG_SND_BF5XX_SPORT_NUM=0 +CONFIG_SND_SOC_I2C_AND_SPI=m +# CONFIG_SND_SOC_ALL_CODECS is not set +CONFIG_SND_SOC_AD1980=m +CONFIG_SND_SOC_SSM2602=m +# CONFIG_SOUND_PRIME is not set +CONFIG_AC97_BUS=m +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HIDRAW is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_HID_PID is not set +# CONFIG_USB_HIDDEV is not set + +# +# Special HID drivers +# +CONFIG_HID_A4TECH=y +CONFIG_HID_APPLE=y +CONFIG_HID_BELKIN=y +CONFIG_HID_CHERRY=y +CONFIG_HID_CHICONY=y +CONFIG_HID_CYPRESS=y +# CONFIG_HID_DRAGONRISE is not set +CONFIG_HID_EZKEY=y +# CONFIG_HID_KYE is not set +CONFIG_HID_GYRATION=y +# CONFIG_HID_TWINHAN is not set +# CONFIG_HID_KENSINGTON is not set +CONFIG_HID_LOGITECH=y +# CONFIG_LOGITECH_FF is not set +# CONFIG_LOGIRUMBLEPAD2_FF is not set +CONFIG_HID_MICROSOFT=y +CONFIG_HID_MONTEREY=y +# CONFIG_HID_NTRIG is not set +CONFIG_HID_PANTHERLORD=y +# CONFIG_PANTHERLORD_FF is not set +CONFIG_HID_PETALYNX=y +CONFIG_HID_SAMSUNG=y +CONFIG_HID_SONY=y +CONFIG_HID_SUNPLUS=y +# CONFIG_HID_GREENASIA is not set +# CONFIG_HID_SMARTJOYPLUS is not set +# CONFIG_HID_TOPSEED is not set +# CONFIG_HID_THRUSTMASTER is not set +# CONFIG_HID_ZEROPLUS is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICE_CLASS is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_WHITELIST is not set +CONFIG_USB_OTG_BLACKLIST_HUB=y +CONFIG_USB_MON=y +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_HWA_HCD is not set +CONFIG_USB_MUSB_HDRC=y +CONFIG_USB_MUSB_SOC=y + +# +# Blackfin high speed USB Support +# +CONFIG_USB_MUSB_HOST=y +# CONFIG_USB_MUSB_PERIPHERAL is not set +# CONFIG_USB_MUSB_OTG is not set +CONFIG_USB_MUSB_HDRC_HCD=y +# CONFIG_MUSB_PIO_ONLY is not set +CONFIG_USB_INVENTRA_DMA=y +# CONFIG_USB_TI_CPPI_DMA is not set +# CONFIG_USB_MUSB_DEBUG is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB port drivers +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_VST is not set +# CONFIG_USB_GADGET is not set + +# +# OTG and related infrastructure +# +CONFIG_USB_OTG_UTILS=y +# CONFIG_USB_GPIO_VBUS is not set +CONFIG_NOP_USB_XCEIV=y +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +# CONFIG_LEDS_PCA9532 is not set +# CONFIG_LEDS_GPIO is not set +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_BD2802 is not set +CONFIG_LEDS_ADP5520=y + +# +# LED Triggers +# +# CONFIG_LEDS_TRIGGERS is not set +# CONFIG_ACCESSIBILITY is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +CONFIG_RTC_DRV_BFIN=y +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set + +# +# TI VLYNQ +# +# CONFIG_STAGING is not set + +# +# Firmware Drivers +# +# CONFIG_FIRMWARE_MEMMAP is not set +# CONFIG_SIGMA is not set + +# +# File systems +# +CONFIG_EXT2_FS=m +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +# CONFIG_DNOTIFY is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +# CONFIG_ZISOFS is not set +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +# CONFIG_MSDOS_FS is not set +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFSD is not set +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=m +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=m +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +CONFIG_NLS_CODEPAGE_936=m +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=m +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=m +# CONFIG_DLM is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_SECTION_MISMATCH=y +CONFIG_DEBUG_KERNEL=y +CONFIG_DEBUG_SHIRQ=y +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_NOMMU_REGIONS is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set +# CONFIG_FRAME_POINTER is not set +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_PAGE_POISONING is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_BRANCH_PROFILE_NONE is not set +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_DEBUG_STACK_USAGE is not set +CONFIG_DEBUG_VERBOSE=y +CONFIG_DEBUG_MMRS=y +CONFIG_DEBUG_HWERR=y +CONFIG_EXACT_HWERR=y +CONFIG_DEBUG_DOUBLEFAULT=y +CONFIG_DEBUG_DOUBLEFAULT_PRINT=y +# CONFIG_DEBUG_DOUBLEFAULT_RESET is not set +# CONFIG_DEBUG_ICACHE_CHECK is not set +CONFIG_DEBUG_HUNT_FOR_ZERO=y +CONFIG_DEBUG_BFIN_HWTRACE_ON=y +# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF is not set +CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_ONE=y +# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_TWO is not set +CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=1 +# CONFIG_DEBUG_BFIN_HWTRACE_EXPAND is not set +CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE=y +CONFIG_EARLY_PRINTK=y +CONFIG_CPLB_INFO=y +CONFIG_ACCESS_CHECK=y +# CONFIG_BFIN_ISRAM_SELF_TEST is not set + +# +# Security options +# +# CONFIG_KEYS is not set +CONFIG_SECURITY=y +# CONFIG_SECURITYFS is not set +# CONFIG_SECURITY_NETWORK is not set +# CONFIG_SECURITY_PATH is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_SECURITY_ROOTPLUG is not set +# CONFIG_SECURITY_TOMOYO is not set +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_MANAGER is not set +# CONFIG_CRYPTO_MANAGER2 is not set +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +# CONFIG_CRYPTO_CBC is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +# CONFIG_CRYPTO_ECB is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +CONFIG_CRC_CCITT=m +# CONFIG_CRC16 is not set +# CONFIG_CRC_T10DIF is not set +CONFIG_CRC_ITU_T=m +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=m +CONFIG_DECOMPRESS_GZIP=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff --git a/arch/blackfin/mach-bf527/boards/Kconfig b/arch/blackfin/mach-bf527/boards/Kconfig index df224d0..b14c288 100644 --- a/arch/blackfin/mach-bf527/boards/Kconfig +++ b/arch/blackfin/mach-bf527/boards/Kconfig @@ -9,6 +9,11 @@ config BFIN527_EZKIT help BF527-EZKIT-LITE board support. +config BFIN527_EZKIT_V2 + bool "BF527-EZKIT-V2" + help + BF527-EZKIT-LITE V2.1+ board support. + config BFIN527_BLUETECHNIX_CM bool "Bluetechnix CM-BF527" help diff --git a/arch/blackfin/mach-bf527/boards/Makefile b/arch/blackfin/mach-bf527/boards/Makefile index eb6ed33..51a5817 100644 --- a/arch/blackfin/mach-bf527/boards/Makefile +++ b/arch/blackfin/mach-bf527/boards/Makefile @@ -3,5 +3,6 @@ # obj-$(CONFIG_BFIN527_EZKIT) += ezkit.o +obj-$(CONFIG_BFIN527_EZKIT_V2) += ezkit.o obj-$(CONFIG_BFIN527_BLUETECHNIX_CM) += cm_bf527.o obj-$(CONFIG_BFIN526_EZBRD) += ezbrd.o diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c index 6138b47..9db506b 100644 --- a/arch/blackfin/mach-bf527/boards/ezkit.c +++ b/arch/blackfin/mach-bf527/boards/ezkit.c @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include #include #include @@ -29,7 +31,11 @@ /* * Name the Board for the /proc/cpuinfo */ +#ifdef CONFIG_BFIN527_EZKIT_V2 +const char bfin_board_name[] = "ADI BF527-EZKIT V2"; +#else const char bfin_board_name[] = "ADI BF527-EZKIT"; +#endif /* * Driver needs to know address, irq and flag pin. @@ -143,6 +149,32 @@ static struct platform_device bf52x_t350mcqb_device = { }; #endif +#if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE) +#include + +static struct bfin_lq035q1fb_disp_info bfin_lq035q1_data = { + .mode = LQ035_NORM | LQ035_RGB | LQ035_RL | LQ035_TB, +}; + +static struct resource bfin_lq035q1_resources[] = { + { + .start = IRQ_PPI_ERROR, + .end = IRQ_PPI_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device bfin_lq035q1_device = { + .name = "bfin-lq035q1", + .id = -1, + .num_resources = ARRAY_SIZE(bfin_lq035q1_resources), + .resource = bfin_lq035q1_resources, + .dev = { + .platform_data = &bfin_lq035q1_data, + }, +}; +#endif + #if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) static struct mtd_partition ezkit_partitions[] = { { @@ -500,14 +532,6 @@ static struct bfin5xx_spi_chip spi_ad7879_chip_info = { }; #endif -#if defined(CONFIG_SND_SOC_WM8731) || defined(CONFIG_SND_SOC_WM8731_MODULE) \ - && defined(CONFIG_SND_SOC_WM8731_SPI) -static struct bfin5xx_spi_chip spi_wm8731_chip_info = { - .enable_dma = 0, - .bits_per_word = 16, -}; -#endif - #if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE) static struct bfin5xx_spi_chip spidev_chip_info = { .enable_dma = 0, @@ -515,6 +539,13 @@ static struct bfin5xx_spi_chip spidev_chip_info = { }; #endif +#if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE) +static struct bfin5xx_spi_chip lq035q1_spi_chip_info = { + .enable_dma = 0, + .bits_per_word = 8, +}; +#endif + static struct spi_board_info bfin_spi_board_info[] __initdata = { #if defined(CONFIG_MTD_M25P80) \ || defined(CONFIG_MTD_M25P80_MODULE) @@ -586,17 +617,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { .mode = SPI_CPHA | SPI_CPOL, }, #endif -#if defined(CONFIG_SND_SOC_WM8731) || defined(CONFIG_SND_SOC_WM8731_MODULE) \ - && defined(CONFIG_SND_SOC_WM8731_SPI) - { - .modalias = "wm8731", - .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 5, - .controller_data = &spi_wm8731_chip_info, - .mode = SPI_MODE_0, - }, -#endif #if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE) { .modalias = "spidev", @@ -606,6 +626,16 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { .controller_data = &spidev_chip_info, }, #endif +#if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE) + { + .modalias = "bfin-lq035q1-spi", + .max_speed_hz = 20000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, + .chip_select = 7, + .controller_data = &lq035q1_spi_chip_info, + .mode = SPI_CPHA | SPI_CPOL, + }, +#endif }; #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) @@ -824,6 +854,71 @@ static struct platform_device i2c_bfin_twi_device = { }; #endif +#if defined(CONFIG_PMIC_ADP5520) || defined(CONFIG_PMIC_ADP5520_MODULE) +#include + + /* + * ADP5520/5501 LEDs Data + */ + +static struct led_info adp5520_leds[] = { + { + .name = "adp5520-led1", + .default_trigger = "none", + .flags = FLAG_ID_ADP5520_LED1_ADP5501_LED0 | ADP5520_LED_OFFT_600ms, + }, +}; + +static struct adp5520_leds_platform_data adp5520_leds_data = { + .num_leds = ARRAY_SIZE(adp5520_leds), + .leds = adp5520_leds, + .fade_in = ADP5520_FADE_T_600ms, + .fade_out = ADP5520_FADE_T_600ms, + .led_on_time = ADP5520_LED_ONT_600ms, +}; + + /* + * ADP5520 Keypad Data + */ + +static const unsigned short adp5520_keymap[ADP5520_KEYMAPSIZE] = { + [ADP5520_KEY(3, 3)] = KEY_1, + [ADP5520_KEY(2, 3)] = KEY_2, + [ADP5520_KEY(1, 3)] = KEY_3, + [ADP5520_KEY(0, 3)] = KEY_UP, + [ADP5520_KEY(3, 2)] = KEY_4, + [ADP5520_KEY(2, 2)] = KEY_5, + [ADP5520_KEY(1, 2)] = KEY_6, + [ADP5520_KEY(0, 2)] = KEY_DOWN, + [ADP5520_KEY(3, 1)] = KEY_7, + [ADP5520_KEY(2, 1)] = KEY_8, + [ADP5520_KEY(1, 1)] = KEY_9, + [ADP5520_KEY(0, 1)] = KEY_DOT, + [ADP5520_KEY(3, 0)] = KEY_BACKSPACE, + [ADP5520_KEY(2, 0)] = KEY_0, + [ADP5520_KEY(1, 0)] = KEY_HELP, + [ADP5520_KEY(0, 0)] = KEY_ENTER, +}; + +static struct adp5520_keys_platform_data adp5520_keys_data = { + .rows_en_mask = ADP5520_ROW_R3 | ADP5520_ROW_R2 | ADP5520_ROW_R1 | ADP5520_ROW_R0, + .cols_en_mask = ADP5520_COL_C3 | ADP5520_COL_C2 | ADP5520_COL_C1 | ADP5520_COL_C0, + .keymap = adp5520_keymap, + .keymapsize = ARRAY_SIZE(adp5520_keymap), + .repeat = 0, +}; + + /* + * ADP5520/5501 Multifuction Device Init Data + */ + +static struct adp5520_platform_data adp5520_pdev_data = { + .leds = &adp5520_leds_data, + .keys = &adp5520_keys_data, +}; + +#endif + static struct i2c_board_info __initdata bfin_i2c_board_info[] = { #if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE) { @@ -841,6 +936,20 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { I2C_BOARD_INFO("bfin-adv7393", 0x2B), }, #endif +#if defined(CONFIG_TOUCHSCREEN_AD7879_I2C) || defined(CONFIG_TOUCHSCREEN_AD7879_I2C_MODULE) + { + I2C_BOARD_INFO("ad7879", 0x2C), + .irq = IRQ_PF8, + .platform_data = (void *)&bfin_ad7879_ts_info, + }, +#endif +#if defined(CONFIG_PMIC_ADP5520) || defined(CONFIG_PMIC_ADP5520_MODULE) + { + I2C_BOARD_INFO("pmic-adp5520", 0x32), + .irq = IRQ_PF9, + .platform_data = (void *)&adp5520_pdev_data, + }, +#endif }; #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) @@ -915,7 +1024,6 @@ static struct platform_device bfin_sport1_uart_device = { #endif #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) -#include #include static struct gpio_keys_button bfin_gpio_keys_table[] = { @@ -937,7 +1045,6 @@ static struct platform_device bfin_device_gpiokeys = { #endif #if defined(CONFIG_INPUT_BFIN_ROTARY) || defined(CONFIG_INPUT_BFIN_ROTARY_MODULE) -#include #include static struct bfin_rotary_platform_data bfin_rotary_data = { @@ -1043,6 +1150,10 @@ static struct platform_device *stamp_devices[] __initdata = { &bf52x_t350mcqb_device, #endif +#if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE) + &bfin_lq035q1_device, +#endif + #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) #ifdef CONFIG_SERIAL_BFIN_UART0 &bfin_uart0_device, -- cgit v0.10.2 From d94a1aa44ed6bfe8d8ab36c02de652d4fcf0d2c3 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Tue, 8 Dec 2009 11:45:55 +0000 Subject: Blackfin: extend bfin-lq035q1-fb resources to include PPI mode This lets us support the new BF527-EZKIT V2.1 via platform resources tweaks only. Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/bfin-lq035q1.h b/arch/blackfin/include/asm/bfin-lq035q1.h index 57bc21a..8368951 100644 --- a/arch/blackfin/include/asm/bfin-lq035q1.h +++ b/arch/blackfin/include/asm/bfin-lq035q1.h @@ -8,6 +8,9 @@ #ifndef BFIN_LQ035Q1_H #define BFIN_LQ035Q1_H +/* + * LCD Modes + */ #define LQ035_RL (0 << 8) /* Right -> Left Scan */ #define LQ035_LR (1 << 8) /* Left -> Right Scan */ #define LQ035_TB (1 << 9) /* Top -> Botton Scan */ @@ -17,9 +20,18 @@ #define LQ035_NORM (1 << 13) /* Reversal */ #define LQ035_REV (0 << 13) /* Reversal */ +/* + * PPI Modes + */ + +#define USE_RGB565_16_BIT_PPI 1 +#define USE_RGB565_8_BIT_PPI 2 +#define USE_RGB888_8_BIT_PPI 3 + struct bfin_lq035q1fb_disp_info { unsigned mode; + unsigned ppi_mode; /* GPIOs */ int use_bl; unsigned gpio_bl; diff --git a/arch/blackfin/mach-bf527/boards/ezbrd.c b/arch/blackfin/mach-bf527/boards/ezbrd.c index 3ff61e6..faede2b 100644 --- a/arch/blackfin/mach-bf527/boards/ezbrd.c +++ b/arch/blackfin/mach-bf527/boards/ezbrd.c @@ -749,9 +749,10 @@ static struct platform_device bfin_dpmc = { #include static struct bfin_lq035q1fb_disp_info bfin_lq035q1_data = { - .mode = LQ035_NORM | LQ035_RGB | LQ035_RL | LQ035_TB, - .use_bl = 1, - .gpio_bl = GPIO_PG12, + .mode = LQ035_NORM | LQ035_RGB | LQ035_RL | LQ035_TB, + .ppi_mode = USE_RGB565_16_BIT_PPI, + .use_bl = 1, + .gpio_bl = GPIO_PG12, }; static struct resource bfin_lq035q1_resources[] = { diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c index 9db506b..fdfe8ca 100644 --- a/arch/blackfin/mach-bf527/boards/ezkit.c +++ b/arch/blackfin/mach-bf527/boards/ezkit.c @@ -154,6 +154,7 @@ static struct platform_device bf52x_t350mcqb_device = { static struct bfin_lq035q1fb_disp_info bfin_lq035q1_data = { .mode = LQ035_NORM | LQ035_RGB | LQ035_RL | LQ035_TB, + .ppi_mode = USE_RGB565_8_BIT_PPI, }; static struct resource bfin_lq035q1_resources[] = { diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 3cb20d7..538bff8 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -1131,9 +1131,10 @@ static struct platform_device bfin_fb_device = { #include static struct bfin_lq035q1fb_disp_info bfin_lq035q1_data = { - .mode = LQ035_NORM | LQ035_RGB | LQ035_RL | LQ035_TB, - .use_bl = 0, /* let something else control the LCD Blacklight */ - .gpio_bl = GPIO_PF7, + .mode = LQ035_NORM | LQ035_RGB | LQ035_RL | LQ035_TB, + .ppi_mode = USE_RGB565_16_BIT_PPI, + .use_bl = 0, /* let something else control the LCD Blacklight */ + .gpio_bl = GPIO_PF7, }; static struct resource bfin_lq035q1_resources[] = { @@ -1147,8 +1148,8 @@ static struct resource bfin_lq035q1_resources[] = { static struct platform_device bfin_lq035q1_device = { .name = "bfin-lq035q1", .id = -1, - .num_resources = ARRAY_SIZE(bfin_lq035q1_resources), - .resource = bfin_lq035q1_resources, + .num_resources = ARRAY_SIZE(bfin_lq035q1_resources), + .resource = bfin_lq035q1_resources, .dev = { .platform_data = &bfin_lq035q1_data, }, diff --git a/arch/blackfin/mach-bf538/boards/ezkit.c b/arch/blackfin/mach-bf538/boards/ezkit.c index 20387fe..d2d06f0 100644 --- a/arch/blackfin/mach-bf538/boards/ezkit.c +++ b/arch/blackfin/mach-bf538/boards/ezkit.c @@ -534,9 +534,10 @@ static struct bfin5xx_spi_chip spi_ad7879_chip_info = { #include static struct bfin_lq035q1fb_disp_info bfin_lq035q1_data = { - .mode = LQ035_NORM | LQ035_RGB | LQ035_RL | LQ035_TB, - .use_bl = 0, /* let something else control the LCD Blacklight */ - .gpio_bl = GPIO_PF7, + .mode = LQ035_NORM | LQ035_RGB | LQ035_RL | LQ035_TB, + .ppi_mode = USE_RGB565_16_BIT_PPI, + .use_bl = 0, /* let something else control the LCD Blacklight */ + .gpio_bl = GPIO_PF7, }; static struct resource bfin_lq035q1_resources[] = { -- cgit v0.10.2 From 5792ab2a0a22fdaef33056ca2b31847a28b1af60 Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Wed, 9 Dec 2009 07:01:50 +0000 Subject: Blackfin: MPU: handle caches for reserved memory We weren't handling the user-specified cache behavior for the reserved memory regions (via mem=/max_mem=). The no-MPU code already takes care of this, so add support to the MPU code as well. Signed-off-by: Sonic Zhang Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c index d4cc53a..7e6383d 100644 --- a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c +++ b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c @@ -131,7 +131,9 @@ static noinline int dcplb_miss(unsigned int cpu) } else return CPLB_PROT_VIOL; } else if (addr >= _ramend) { - d_data |= CPLB_USER_RD | CPLB_USER_WR; + d_data |= CPLB_USER_RD | CPLB_USER_WR; + if (reserved_mem_dcache_on) + d_data |= CPLB_L1_CHBL; } else { mask = current_rwx_mask[cpu]; if (mask) { @@ -231,6 +233,8 @@ static noinline int icplb_miss(unsigned int cpu) return CPLB_PROT_VIOL; } else if (addr >= _ramend) { i_data |= CPLB_USER_RD; + if (reserved_mem_icache_on) + i_data |= CPLB_L1_CHBL; } else { /* * Two cases to distinguish - a supervisor access must -- cgit v0.10.2 From ead9b1156d4b128db9f13ee8be32cbcd3f255db9 Mon Sep 17 00:00:00 2001 From: Graf Yang Date: Mon, 14 Dec 2009 08:01:08 +0000 Subject: Blackfin: SMP: enable HAVE_LEGACY_PER_CPU_AREA The current Blackfin SMP code relies on the legacy cpu area code, so select it until we port things to the newer code. Signed-off-by: Graf Yang Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index 9409ae3..1f075be 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -258,6 +258,10 @@ config IRQ_PER_CPU depends on SMP default y +config HAVE_LEGACY_PER_CPU_AREA + def_bool y + depends on SMP + config BF_REV_MIN int default 0 if (BF51x || BF52x || (BF54x && !BF54xM)) -- cgit v0.10.2 From 360adee8a5c249f221de43d7d46073391359a4ba Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 15 Dec 2009 05:08:36 +0000 Subject: Blackfin: wire up the various memory related syscalls These all just go to the stub syscall at the moment, so this is largely future proofing. Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S index 01b2f58..0df7ef2 100644 --- a/arch/blackfin/mach-common/entry.S +++ b/arch/blackfin/mach-common/entry.S @@ -1357,7 +1357,7 @@ ENTRY(_sys_call_table) .long _sys_newuname .long _sys_ni_syscall /* old sys_modify_ldt */ .long _sys_adjtimex - .long _sys_ni_syscall /* 125 */ /* sys_mprotect */ + .long _sys_mprotect /* 125 */ .long _sys_ni_syscall /* old sys_sigprocmask */ .long _sys_ni_syscall /* old "creat_module" */ .long _sys_init_module @@ -1376,16 +1376,16 @@ ENTRY(_sys_call_table) .long _sys_getdents .long _sys_ni_syscall /* sys_select */ .long _sys_flock - .long _sys_ni_syscall /* sys_msync */ + .long _sys_msync .long _sys_readv /* 145 */ .long _sys_writev .long _sys_getsid .long _sys_fdatasync .long _sys_sysctl - .long _sys_ni_syscall /* 150 */ /* sys_mlock */ - .long _sys_ni_syscall /* sys_munlock */ - .long _sys_ni_syscall /* sys_mlockall */ - .long _sys_ni_syscall /* sys_munlockall */ + .long _sys_mlock /* 150 */ + .long _sys_munlock + .long _sys_mlockall + .long _sys_munlockall .long _sys_sched_setparam .long _sys_sched_getparam /* 155 */ .long _sys_sched_setscheduler @@ -1450,8 +1450,8 @@ ENTRY(_sys_call_table) .long _sys_setfsuid /* 215 */ .long _sys_setfsgid .long _sys_pivot_root - .long _sys_ni_syscall /* sys_mincore */ - .long _sys_ni_syscall /* sys_madvise */ + .long _sys_mincore + .long _sys_madvise .long _sys_getdents64 /* 220 */ .long _sys_fcntl64 .long _sys_ni_syscall /* reserved for TUX */ @@ -1507,7 +1507,7 @@ ENTRY(_sys_call_table) .long _sys_utimes .long _sys_fadvise64_64 .long _sys_ni_syscall /* vserver */ - .long _sys_ni_syscall /* 275, mbind */ + .long _sys_mbind /* 275 */ .long _sys_ni_syscall /* get_mempolicy */ .long _sys_ni_syscall /* set_mempolicy */ .long _sys_mq_open -- cgit v0.10.2 From 0e64268ced7975ddcfed3e47a26b8df534f8e3ed Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 15 Dec 2009 13:33:19 +0000 Subject: Blackfin: merge common CAN defines into one headers Rather than copy and paste the MMR defines and register layout, consolidate everything in one place. Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/bfin_can.h b/arch/blackfin/include/asm/bfin_can.h new file mode 100644 index 0000000..eec0076 --- /dev/null +++ b/arch/blackfin/include/asm/bfin_can.h @@ -0,0 +1,725 @@ +/* + * bfin_can.h - interface to Blackfin CANs + * + * Copyright 2004-2009 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#ifndef __ASM_BFIN_CAN_H__ +#define __ASM_BFIN_CAN_H__ + +/* + * transmit and receive channels + */ +#define TRANSMIT_CHL 24 +#define RECEIVE_STD_CHL 0 +#define RECEIVE_EXT_CHL 4 +#define RECEIVE_RTR_CHL 8 +#define RECEIVE_EXT_RTR_CHL 12 +#define MAX_CHL_NUMBER 32 + +/* + * All Blackfin system MMRs are padded to 32bits even if the register + * itself is only 16bits. So use a helper macro to streamline this. + */ +#define __BFP(m) u16 m; u16 __pad_##m + +/* + * bfin can registers layout + */ +struct bfin_can_mask_regs { + __BFP(aml); + __BFP(amh); +}; + +struct bfin_can_channel_regs { + u16 data[8]; + __BFP(dlc); + __BFP(tsv); + __BFP(id0); + __BFP(id1); +}; + +struct bfin_can_regs { + /* + * global control and status registers + */ + __BFP(mc1); /* offset 0x00 */ + __BFP(md1); /* offset 0x04 */ + __BFP(trs1); /* offset 0x08 */ + __BFP(trr1); /* offset 0x0c */ + __BFP(ta1); /* offset 0x10 */ + __BFP(aa1); /* offset 0x14 */ + __BFP(rmp1); /* offset 0x18 */ + __BFP(rml1); /* offset 0x1c */ + __BFP(mbtif1); /* offset 0x20 */ + __BFP(mbrif1); /* offset 0x24 */ + __BFP(mbim1); /* offset 0x28 */ + __BFP(rfh1); /* offset 0x2c */ + __BFP(opss1); /* offset 0x30 */ + u32 __pad1[3]; + __BFP(mc2); /* offset 0x40 */ + __BFP(md2); /* offset 0x44 */ + __BFP(trs2); /* offset 0x48 */ + __BFP(trr2); /* offset 0x4c */ + __BFP(ta2); /* offset 0x50 */ + __BFP(aa2); /* offset 0x54 */ + __BFP(rmp2); /* offset 0x58 */ + __BFP(rml2); /* offset 0x5c */ + __BFP(mbtif2); /* offset 0x60 */ + __BFP(mbrif2); /* offset 0x64 */ + __BFP(mbim2); /* offset 0x68 */ + __BFP(rfh2); /* offset 0x6c */ + __BFP(opss2); /* offset 0x70 */ + u32 __pad2[3]; + __BFP(clock); /* offset 0x80 */ + __BFP(timing); /* offset 0x84 */ + __BFP(debug); /* offset 0x88 */ + __BFP(status); /* offset 0x8c */ + __BFP(cec); /* offset 0x90 */ + __BFP(gis); /* offset 0x94 */ + __BFP(gim); /* offset 0x98 */ + __BFP(gif); /* offset 0x9c */ + __BFP(control); /* offset 0xa0 */ + __BFP(intr); /* offset 0xa4 */ + u32 __pad3[1]; + __BFP(mbtd); /* offset 0xac */ + __BFP(ewr); /* offset 0xb0 */ + __BFP(esr); /* offset 0xb4 */ + u32 __pad4[2]; + __BFP(ucreg); /* offset 0xc0 */ + __BFP(uccnt); /* offset 0xc4 */ + __BFP(ucrc); /* offset 0xc8 */ + __BFP(uccnf); /* offset 0xcc */ + u32 __pad5[12]; + + /* + * channel(mailbox) mask and message registers + */ + struct bfin_can_mask_regs msk[MAX_CHL_NUMBER]; /* offset 0x100 */ + struct bfin_can_channel_regs chl[MAX_CHL_NUMBER]; /* offset 0x200 */ +}; + +#undef __BFP + +/* CAN_CONTROL Masks */ +#define SRS 0x0001 /* Software Reset */ +#define DNM 0x0002 /* Device Net Mode */ +#define ABO 0x0004 /* Auto-Bus On Enable */ +#define TXPRIO 0x0008 /* TX Priority (Priority/Mailbox*) */ +#define WBA 0x0010 /* Wake-Up On CAN Bus Activity Enable */ +#define SMR 0x0020 /* Sleep Mode Request */ +#define CSR 0x0040 /* CAN Suspend Mode Request */ +#define CCR 0x0080 /* CAN Configuration Mode Request */ + +/* CAN_STATUS Masks */ +#define WT 0x0001 /* TX Warning Flag */ +#define WR 0x0002 /* RX Warning Flag */ +#define EP 0x0004 /* Error Passive Mode */ +#define EBO 0x0008 /* Error Bus Off Mode */ +#define SMA 0x0020 /* Sleep Mode Acknowledge */ +#define CSA 0x0040 /* Suspend Mode Acknowledge */ +#define CCA 0x0080 /* Configuration Mode Acknowledge */ +#define MBPTR 0x1F00 /* Mailbox Pointer */ +#define TRM 0x4000 /* Transmit Mode */ +#define REC 0x8000 /* Receive Mode */ + +/* CAN_CLOCK Masks */ +#define BRP 0x03FF /* Bit-Rate Pre-Scaler */ + +/* CAN_TIMING Masks */ +#define TSEG1 0x000F /* Time Segment 1 */ +#define TSEG2 0x0070 /* Time Segment 2 */ +#define SAM 0x0080 /* Sampling */ +#define SJW 0x0300 /* Synchronization Jump Width */ + +/* CAN_DEBUG Masks */ +#define DEC 0x0001 /* Disable CAN Error Counters */ +#define DRI 0x0002 /* Disable CAN RX Input */ +#define DTO 0x0004 /* Disable CAN TX Output */ +#define DIL 0x0008 /* Disable CAN Internal Loop */ +#define MAA 0x0010 /* Mode Auto-Acknowledge Enable */ +#define MRB 0x0020 /* Mode Read Back Enable */ +#define CDE 0x8000 /* CAN Debug Enable */ + +/* CAN_CEC Masks */ +#define RXECNT 0x00FF /* Receive Error Counter */ +#define TXECNT 0xFF00 /* Transmit Error Counter */ + +/* CAN_INTR Masks */ +#define MBRIRQ 0x0001 /* Mailbox Receive Interrupt */ +#define MBTIRQ 0x0002 /* Mailbox Transmit Interrupt */ +#define GIRQ 0x0004 /* Global Interrupt */ +#define SMACK 0x0008 /* Sleep Mode Acknowledge */ +#define CANTX 0x0040 /* CAN TX Bus Value */ +#define CANRX 0x0080 /* CAN RX Bus Value */ + +/* CAN_MBxx_ID1 and CAN_MBxx_ID0 Masks */ +#define DFC 0xFFFF /* Data Filtering Code (If Enabled) (ID0) */ +#define EXTID_LO 0xFFFF /* Lower 16 Bits of Extended Identifier (ID0) */ +#define EXTID_HI 0x0003 /* Upper 2 Bits of Extended Identifier (ID1) */ +#define BASEID 0x1FFC /* Base Identifier */ +#define IDE 0x2000 /* Identifier Extension */ +#define RTR 0x4000 /* Remote Frame Transmission Request */ +#define AME 0x8000 /* Acceptance Mask Enable */ + +/* CAN_MBxx_TIMESTAMP Masks */ +#define TSV 0xFFFF /* Timestamp */ + +/* CAN_MBxx_LENGTH Masks */ +#define DLC 0x000F /* Data Length Code */ + +/* CAN_AMxxH and CAN_AMxxL Masks */ +#define DFM 0xFFFF /* Data Field Mask (If Enabled) (CAN_AMxxL) */ +#define EXTID_LO 0xFFFF /* Lower 16 Bits of Extended Identifier (CAN_AMxxL) */ +#define EXTID_HI 0x0003 /* Upper 2 Bits of Extended Identifier (CAN_AMxxH) */ +#define BASEID 0x1FFC /* Base Identifier */ +#define AMIDE 0x2000 /* Acceptance Mask ID Extension Enable */ +#define FMD 0x4000 /* Full Mask Data Field Enable */ +#define FDF 0x8000 /* Filter On Data Field Enable */ + +/* CAN_MC1 Masks */ +#define MC0 0x0001 /* Enable Mailbox 0 */ +#define MC1 0x0002 /* Enable Mailbox 1 */ +#define MC2 0x0004 /* Enable Mailbox 2 */ +#define MC3 0x0008 /* Enable Mailbox 3 */ +#define MC4 0x0010 /* Enable Mailbox 4 */ +#define MC5 0x0020 /* Enable Mailbox 5 */ +#define MC6 0x0040 /* Enable Mailbox 6 */ +#define MC7 0x0080 /* Enable Mailbox 7 */ +#define MC8 0x0100 /* Enable Mailbox 8 */ +#define MC9 0x0200 /* Enable Mailbox 9 */ +#define MC10 0x0400 /* Enable Mailbox 10 */ +#define MC11 0x0800 /* Enable Mailbox 11 */ +#define MC12 0x1000 /* Enable Mailbox 12 */ +#define MC13 0x2000 /* Enable Mailbox 13 */ +#define MC14 0x4000 /* Enable Mailbox 14 */ +#define MC15 0x8000 /* Enable Mailbox 15 */ + +/* CAN_MC2 Masks */ +#define MC16 0x0001 /* Enable Mailbox 16 */ +#define MC17 0x0002 /* Enable Mailbox 17 */ +#define MC18 0x0004 /* Enable Mailbox 18 */ +#define MC19 0x0008 /* Enable Mailbox 19 */ +#define MC20 0x0010 /* Enable Mailbox 20 */ +#define MC21 0x0020 /* Enable Mailbox 21 */ +#define MC22 0x0040 /* Enable Mailbox 22 */ +#define MC23 0x0080 /* Enable Mailbox 23 */ +#define MC24 0x0100 /* Enable Mailbox 24 */ +#define MC25 0x0200 /* Enable Mailbox 25 */ +#define MC26 0x0400 /* Enable Mailbox 26 */ +#define MC27 0x0800 /* Enable Mailbox 27 */ +#define MC28 0x1000 /* Enable Mailbox 28 */ +#define MC29 0x2000 /* Enable Mailbox 29 */ +#define MC30 0x4000 /* Enable Mailbox 30 */ +#define MC31 0x8000 /* Enable Mailbox 31 */ + +/* CAN_MD1 Masks */ +#define MD0 0x0001 /* Enable Mailbox 0 For Receive */ +#define MD1 0x0002 /* Enable Mailbox 1 For Receive */ +#define MD2 0x0004 /* Enable Mailbox 2 For Receive */ +#define MD3 0x0008 /* Enable Mailbox 3 For Receive */ +#define MD4 0x0010 /* Enable Mailbox 4 For Receive */ +#define MD5 0x0020 /* Enable Mailbox 5 For Receive */ +#define MD6 0x0040 /* Enable Mailbox 6 For Receive */ +#define MD7 0x0080 /* Enable Mailbox 7 For Receive */ +#define MD8 0x0100 /* Enable Mailbox 8 For Receive */ +#define MD9 0x0200 /* Enable Mailbox 9 For Receive */ +#define MD10 0x0400 /* Enable Mailbox 10 For Receive */ +#define MD11 0x0800 /* Enable Mailbox 11 For Receive */ +#define MD12 0x1000 /* Enable Mailbox 12 For Receive */ +#define MD13 0x2000 /* Enable Mailbox 13 For Receive */ +#define MD14 0x4000 /* Enable Mailbox 14 For Receive */ +#define MD15 0x8000 /* Enable Mailbox 15 For Receive */ + +/* CAN_MD2 Masks */ +#define MD16 0x0001 /* Enable Mailbox 16 For Receive */ +#define MD17 0x0002 /* Enable Mailbox 17 For Receive */ +#define MD18 0x0004 /* Enable Mailbox 18 For Receive */ +#define MD19 0x0008 /* Enable Mailbox 19 For Receive */ +#define MD20 0x0010 /* Enable Mailbox 20 For Receive */ +#define MD21 0x0020 /* Enable Mailbox 21 For Receive */ +#define MD22 0x0040 /* Enable Mailbox 22 For Receive */ +#define MD23 0x0080 /* Enable Mailbox 23 For Receive */ +#define MD24 0x0100 /* Enable Mailbox 24 For Receive */ +#define MD25 0x0200 /* Enable Mailbox 25 For Receive */ +#define MD26 0x0400 /* Enable Mailbox 26 For Receive */ +#define MD27 0x0800 /* Enable Mailbox 27 For Receive */ +#define MD28 0x1000 /* Enable Mailbox 28 For Receive */ +#define MD29 0x2000 /* Enable Mailbox 29 For Receive */ +#define MD30 0x4000 /* Enable Mailbox 30 For Receive */ +#define MD31 0x8000 /* Enable Mailbox 31 For Receive */ + +/* CAN_RMP1 Masks */ +#define RMP0 0x0001 /* RX Message Pending In Mailbox 0 */ +#define RMP1 0x0002 /* RX Message Pending In Mailbox 1 */ +#define RMP2 0x0004 /* RX Message Pending In Mailbox 2 */ +#define RMP3 0x0008 /* RX Message Pending In Mailbox 3 */ +#define RMP4 0x0010 /* RX Message Pending In Mailbox 4 */ +#define RMP5 0x0020 /* RX Message Pending In Mailbox 5 */ +#define RMP6 0x0040 /* RX Message Pending In Mailbox 6 */ +#define RMP7 0x0080 /* RX Message Pending In Mailbox 7 */ +#define RMP8 0x0100 /* RX Message Pending In Mailbox 8 */ +#define RMP9 0x0200 /* RX Message Pending In Mailbox 9 */ +#define RMP10 0x0400 /* RX Message Pending In Mailbox 10 */ +#define RMP11 0x0800 /* RX Message Pending In Mailbox 11 */ +#define RMP12 0x1000 /* RX Message Pending In Mailbox 12 */ +#define RMP13 0x2000 /* RX Message Pending In Mailbox 13 */ +#define RMP14 0x4000 /* RX Message Pending In Mailbox 14 */ +#define RMP15 0x8000 /* RX Message Pending In Mailbox 15 */ + +/* CAN_RMP2 Masks */ +#define RMP16 0x0001 /* RX Message Pending In Mailbox 16 */ +#define RMP17 0x0002 /* RX Message Pending In Mailbox 17 */ +#define RMP18 0x0004 /* RX Message Pending In Mailbox 18 */ +#define RMP19 0x0008 /* RX Message Pending In Mailbox 19 */ +#define RMP20 0x0010 /* RX Message Pending In Mailbox 20 */ +#define RMP21 0x0020 /* RX Message Pending In Mailbox 21 */ +#define RMP22 0x0040 /* RX Message Pending In Mailbox 22 */ +#define RMP23 0x0080 /* RX Message Pending In Mailbox 23 */ +#define RMP24 0x0100 /* RX Message Pending In Mailbox 24 */ +#define RMP25 0x0200 /* RX Message Pending In Mailbox 25 */ +#define RMP26 0x0400 /* RX Message Pending In Mailbox 26 */ +#define RMP27 0x0800 /* RX Message Pending In Mailbox 27 */ +#define RMP28 0x1000 /* RX Message Pending In Mailbox 28 */ +#define RMP29 0x2000 /* RX Message Pending In Mailbox 29 */ +#define RMP30 0x4000 /* RX Message Pending In Mailbox 30 */ +#define RMP31 0x8000 /* RX Message Pending In Mailbox 31 */ + +/* CAN_RML1 Masks */ +#define RML0 0x0001 /* RX Message Lost In Mailbox 0 */ +#define RML1 0x0002 /* RX Message Lost In Mailbox 1 */ +#define RML2 0x0004 /* RX Message Lost In Mailbox 2 */ +#define RML3 0x0008 /* RX Message Lost In Mailbox 3 */ +#define RML4 0x0010 /* RX Message Lost In Mailbox 4 */ +#define RML5 0x0020 /* RX Message Lost In Mailbox 5 */ +#define RML6 0x0040 /* RX Message Lost In Mailbox 6 */ +#define RML7 0x0080 /* RX Message Lost In Mailbox 7 */ +#define RML8 0x0100 /* RX Message Lost In Mailbox 8 */ +#define RML9 0x0200 /* RX Message Lost In Mailbox 9 */ +#define RML10 0x0400 /* RX Message Lost In Mailbox 10 */ +#define RML11 0x0800 /* RX Message Lost In Mailbox 11 */ +#define RML12 0x1000 /* RX Message Lost In Mailbox 12 */ +#define RML13 0x2000 /* RX Message Lost In Mailbox 13 */ +#define RML14 0x4000 /* RX Message Lost In Mailbox 14 */ +#define RML15 0x8000 /* RX Message Lost In Mailbox 15 */ + +/* CAN_RML2 Masks */ +#define RML16 0x0001 /* RX Message Lost In Mailbox 16 */ +#define RML17 0x0002 /* RX Message Lost In Mailbox 17 */ +#define RML18 0x0004 /* RX Message Lost In Mailbox 18 */ +#define RML19 0x0008 /* RX Message Lost In Mailbox 19 */ +#define RML20 0x0010 /* RX Message Lost In Mailbox 20 */ +#define RML21 0x0020 /* RX Message Lost In Mailbox 21 */ +#define RML22 0x0040 /* RX Message Lost In Mailbox 22 */ +#define RML23 0x0080 /* RX Message Lost In Mailbox 23 */ +#define RML24 0x0100 /* RX Message Lost In Mailbox 24 */ +#define RML25 0x0200 /* RX Message Lost In Mailbox 25 */ +#define RML26 0x0400 /* RX Message Lost In Mailbox 26 */ +#define RML27 0x0800 /* RX Message Lost In Mailbox 27 */ +#define RML28 0x1000 /* RX Message Lost In Mailbox 28 */ +#define RML29 0x2000 /* RX Message Lost In Mailbox 29 */ +#define RML30 0x4000 /* RX Message Lost In Mailbox 30 */ +#define RML31 0x8000 /* RX Message Lost In Mailbox 31 */ + +/* CAN_OPSS1 Masks */ +#define OPSS0 0x0001 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 0 */ +#define OPSS1 0x0002 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 1 */ +#define OPSS2 0x0004 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 2 */ +#define OPSS3 0x0008 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 3 */ +#define OPSS4 0x0010 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 4 */ +#define OPSS5 0x0020 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 5 */ +#define OPSS6 0x0040 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 6 */ +#define OPSS7 0x0080 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 7 */ +#define OPSS8 0x0100 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 8 */ +#define OPSS9 0x0200 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 9 */ +#define OPSS10 0x0400 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 10 */ +#define OPSS11 0x0800 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 11 */ +#define OPSS12 0x1000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 12 */ +#define OPSS13 0x2000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 13 */ +#define OPSS14 0x4000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 14 */ +#define OPSS15 0x8000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 15 */ + +/* CAN_OPSS2 Masks */ +#define OPSS16 0x0001 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 16 */ +#define OPSS17 0x0002 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 17 */ +#define OPSS18 0x0004 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 18 */ +#define OPSS19 0x0008 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 19 */ +#define OPSS20 0x0010 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 20 */ +#define OPSS21 0x0020 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 21 */ +#define OPSS22 0x0040 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 22 */ +#define OPSS23 0x0080 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 23 */ +#define OPSS24 0x0100 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 24 */ +#define OPSS25 0x0200 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 25 */ +#define OPSS26 0x0400 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 26 */ +#define OPSS27 0x0800 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 27 */ +#define OPSS28 0x1000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 28 */ +#define OPSS29 0x2000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 29 */ +#define OPSS30 0x4000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 30 */ +#define OPSS31 0x8000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 31 */ + +/* CAN_TRR1 Masks */ +#define TRR0 0x0001 /* Deny But Don't Lock Access To Mailbox 0 */ +#define TRR1 0x0002 /* Deny But Don't Lock Access To Mailbox 1 */ +#define TRR2 0x0004 /* Deny But Don't Lock Access To Mailbox 2 */ +#define TRR3 0x0008 /* Deny But Don't Lock Access To Mailbox 3 */ +#define TRR4 0x0010 /* Deny But Don't Lock Access To Mailbox 4 */ +#define TRR5 0x0020 /* Deny But Don't Lock Access To Mailbox 5 */ +#define TRR6 0x0040 /* Deny But Don't Lock Access To Mailbox 6 */ +#define TRR7 0x0080 /* Deny But Don't Lock Access To Mailbox 7 */ +#define TRR8 0x0100 /* Deny But Don't Lock Access To Mailbox 8 */ +#define TRR9 0x0200 /* Deny But Don't Lock Access To Mailbox 9 */ +#define TRR10 0x0400 /* Deny But Don't Lock Access To Mailbox 10 */ +#define TRR11 0x0800 /* Deny But Don't Lock Access To Mailbox 11 */ +#define TRR12 0x1000 /* Deny But Don't Lock Access To Mailbox 12 */ +#define TRR13 0x2000 /* Deny But Don't Lock Access To Mailbox 13 */ +#define TRR14 0x4000 /* Deny But Don't Lock Access To Mailbox 14 */ +#define TRR15 0x8000 /* Deny But Don't Lock Access To Mailbox 15 */ + +/* CAN_TRR2 Masks */ +#define TRR16 0x0001 /* Deny But Don't Lock Access To Mailbox 16 */ +#define TRR17 0x0002 /* Deny But Don't Lock Access To Mailbox 17 */ +#define TRR18 0x0004 /* Deny But Don't Lock Access To Mailbox 18 */ +#define TRR19 0x0008 /* Deny But Don't Lock Access To Mailbox 19 */ +#define TRR20 0x0010 /* Deny But Don't Lock Access To Mailbox 20 */ +#define TRR21 0x0020 /* Deny But Don't Lock Access To Mailbox 21 */ +#define TRR22 0x0040 /* Deny But Don't Lock Access To Mailbox 22 */ +#define TRR23 0x0080 /* Deny But Don't Lock Access To Mailbox 23 */ +#define TRR24 0x0100 /* Deny But Don't Lock Access To Mailbox 24 */ +#define TRR25 0x0200 /* Deny But Don't Lock Access To Mailbox 25 */ +#define TRR26 0x0400 /* Deny But Don't Lock Access To Mailbox 26 */ +#define TRR27 0x0800 /* Deny But Don't Lock Access To Mailbox 27 */ +#define TRR28 0x1000 /* Deny But Don't Lock Access To Mailbox 28 */ +#define TRR29 0x2000 /* Deny But Don't Lock Access To Mailbox 29 */ +#define TRR30 0x4000 /* Deny But Don't Lock Access To Mailbox 30 */ +#define TRR31 0x8000 /* Deny But Don't Lock Access To Mailbox 31 */ + +/* CAN_TRS1 Masks */ +#define TRS0 0x0001 /* Remote Frame Request For Mailbox 0 */ +#define TRS1 0x0002 /* Remote Frame Request For Mailbox 1 */ +#define TRS2 0x0004 /* Remote Frame Request For Mailbox 2 */ +#define TRS3 0x0008 /* Remote Frame Request For Mailbox 3 */ +#define TRS4 0x0010 /* Remote Frame Request For Mailbox 4 */ +#define TRS5 0x0020 /* Remote Frame Request For Mailbox 5 */ +#define TRS6 0x0040 /* Remote Frame Request For Mailbox 6 */ +#define TRS7 0x0080 /* Remote Frame Request For Mailbox 7 */ +#define TRS8 0x0100 /* Remote Frame Request For Mailbox 8 */ +#define TRS9 0x0200 /* Remote Frame Request For Mailbox 9 */ +#define TRS10 0x0400 /* Remote Frame Request For Mailbox 10 */ +#define TRS11 0x0800 /* Remote Frame Request For Mailbox 11 */ +#define TRS12 0x1000 /* Remote Frame Request For Mailbox 12 */ +#define TRS13 0x2000 /* Remote Frame Request For Mailbox 13 */ +#define TRS14 0x4000 /* Remote Frame Request For Mailbox 14 */ +#define TRS15 0x8000 /* Remote Frame Request For Mailbox 15 */ + +/* CAN_TRS2 Masks */ +#define TRS16 0x0001 /* Remote Frame Request For Mailbox 16 */ +#define TRS17 0x0002 /* Remote Frame Request For Mailbox 17 */ +#define TRS18 0x0004 /* Remote Frame Request For Mailbox 18 */ +#define TRS19 0x0008 /* Remote Frame Request For Mailbox 19 */ +#define TRS20 0x0010 /* Remote Frame Request For Mailbox 20 */ +#define TRS21 0x0020 /* Remote Frame Request For Mailbox 21 */ +#define TRS22 0x0040 /* Remote Frame Request For Mailbox 22 */ +#define TRS23 0x0080 /* Remote Frame Request For Mailbox 23 */ +#define TRS24 0x0100 /* Remote Frame Request For Mailbox 24 */ +#define TRS25 0x0200 /* Remote Frame Request For Mailbox 25 */ +#define TRS26 0x0400 /* Remote Frame Request For Mailbox 26 */ +#define TRS27 0x0800 /* Remote Frame Request For Mailbox 27 */ +#define TRS28 0x1000 /* Remote Frame Request For Mailbox 28 */ +#define TRS29 0x2000 /* Remote Frame Request For Mailbox 29 */ +#define TRS30 0x4000 /* Remote Frame Request For Mailbox 30 */ +#define TRS31 0x8000 /* Remote Frame Request For Mailbox 31 */ + +/* CAN_AA1 Masks */ +#define AA0 0x0001 /* Aborted Message In Mailbox 0 */ +#define AA1 0x0002 /* Aborted Message In Mailbox 1 */ +#define AA2 0x0004 /* Aborted Message In Mailbox 2 */ +#define AA3 0x0008 /* Aborted Message In Mailbox 3 */ +#define AA4 0x0010 /* Aborted Message In Mailbox 4 */ +#define AA5 0x0020 /* Aborted Message In Mailbox 5 */ +#define AA6 0x0040 /* Aborted Message In Mailbox 6 */ +#define AA7 0x0080 /* Aborted Message In Mailbox 7 */ +#define AA8 0x0100 /* Aborted Message In Mailbox 8 */ +#define AA9 0x0200 /* Aborted Message In Mailbox 9 */ +#define AA10 0x0400 /* Aborted Message In Mailbox 10 */ +#define AA11 0x0800 /* Aborted Message In Mailbox 11 */ +#define AA12 0x1000 /* Aborted Message In Mailbox 12 */ +#define AA13 0x2000 /* Aborted Message In Mailbox 13 */ +#define AA14 0x4000 /* Aborted Message In Mailbox 14 */ +#define AA15 0x8000 /* Aborted Message In Mailbox 15 */ + +/* CAN_AA2 Masks */ +#define AA16 0x0001 /* Aborted Message In Mailbox 16 */ +#define AA17 0x0002 /* Aborted Message In Mailbox 17 */ +#define AA18 0x0004 /* Aborted Message In Mailbox 18 */ +#define AA19 0x0008 /* Aborted Message In Mailbox 19 */ +#define AA20 0x0010 /* Aborted Message In Mailbox 20 */ +#define AA21 0x0020 /* Aborted Message In Mailbox 21 */ +#define AA22 0x0040 /* Aborted Message In Mailbox 22 */ +#define AA23 0x0080 /* Aborted Message In Mailbox 23 */ +#define AA24 0x0100 /* Aborted Message In Mailbox 24 */ +#define AA25 0x0200 /* Aborted Message In Mailbox 25 */ +#define AA26 0x0400 /* Aborted Message In Mailbox 26 */ +#define AA27 0x0800 /* Aborted Message In Mailbox 27 */ +#define AA28 0x1000 /* Aborted Message In Mailbox 28 */ +#define AA29 0x2000 /* Aborted Message In Mailbox 29 */ +#define AA30 0x4000 /* Aborted Message In Mailbox 30 */ +#define AA31 0x8000 /* Aborted Message In Mailbox 31 */ + +/* CAN_TA1 Masks */ +#define TA0 0x0001 /* Transmit Successful From Mailbox 0 */ +#define TA1 0x0002 /* Transmit Successful From Mailbox 1 */ +#define TA2 0x0004 /* Transmit Successful From Mailbox 2 */ +#define TA3 0x0008 /* Transmit Successful From Mailbox 3 */ +#define TA4 0x0010 /* Transmit Successful From Mailbox 4 */ +#define TA5 0x0020 /* Transmit Successful From Mailbox 5 */ +#define TA6 0x0040 /* Transmit Successful From Mailbox 6 */ +#define TA7 0x0080 /* Transmit Successful From Mailbox 7 */ +#define TA8 0x0100 /* Transmit Successful From Mailbox 8 */ +#define TA9 0x0200 /* Transmit Successful From Mailbox 9 */ +#define TA10 0x0400 /* Transmit Successful From Mailbox 10 */ +#define TA11 0x0800 /* Transmit Successful From Mailbox 11 */ +#define TA12 0x1000 /* Transmit Successful From Mailbox 12 */ +#define TA13 0x2000 /* Transmit Successful From Mailbox 13 */ +#define TA14 0x4000 /* Transmit Successful From Mailbox 14 */ +#define TA15 0x8000 /* Transmit Successful From Mailbox 15 */ + +/* CAN_TA2 Masks */ +#define TA16 0x0001 /* Transmit Successful From Mailbox 16 */ +#define TA17 0x0002 /* Transmit Successful From Mailbox 17 */ +#define TA18 0x0004 /* Transmit Successful From Mailbox 18 */ +#define TA19 0x0008 /* Transmit Successful From Mailbox 19 */ +#define TA20 0x0010 /* Transmit Successful From Mailbox 20 */ +#define TA21 0x0020 /* Transmit Successful From Mailbox 21 */ +#define TA22 0x0040 /* Transmit Successful From Mailbox 22 */ +#define TA23 0x0080 /* Transmit Successful From Mailbox 23 */ +#define TA24 0x0100 /* Transmit Successful From Mailbox 24 */ +#define TA25 0x0200 /* Transmit Successful From Mailbox 25 */ +#define TA26 0x0400 /* Transmit Successful From Mailbox 26 */ +#define TA27 0x0800 /* Transmit Successful From Mailbox 27 */ +#define TA28 0x1000 /* Transmit Successful From Mailbox 28 */ +#define TA29 0x2000 /* Transmit Successful From Mailbox 29 */ +#define TA30 0x4000 /* Transmit Successful From Mailbox 30 */ +#define TA31 0x8000 /* Transmit Successful From Mailbox 31 */ + +/* CAN_MBTD Masks */ +#define TDPTR 0x001F /* Mailbox To Temporarily Disable */ +#define TDA 0x0040 /* Temporary Disable Acknowledge */ +#define TDR 0x0080 /* Temporary Disable Request */ + +/* CAN_RFH1 Masks */ +#define RFH0 0x0001 /* Enable Automatic Remote Frame Handling For Mailbox 0 */ +#define RFH1 0x0002 /* Enable Automatic Remote Frame Handling For Mailbox 1 */ +#define RFH2 0x0004 /* Enable Automatic Remote Frame Handling For Mailbox 2 */ +#define RFH3 0x0008 /* Enable Automatic Remote Frame Handling For Mailbox 3 */ +#define RFH4 0x0010 /* Enable Automatic Remote Frame Handling For Mailbox 4 */ +#define RFH5 0x0020 /* Enable Automatic Remote Frame Handling For Mailbox 5 */ +#define RFH6 0x0040 /* Enable Automatic Remote Frame Handling For Mailbox 6 */ +#define RFH7 0x0080 /* Enable Automatic Remote Frame Handling For Mailbox 7 */ +#define RFH8 0x0100 /* Enable Automatic Remote Frame Handling For Mailbox 8 */ +#define RFH9 0x0200 /* Enable Automatic Remote Frame Handling For Mailbox 9 */ +#define RFH10 0x0400 /* Enable Automatic Remote Frame Handling For Mailbox 10 */ +#define RFH11 0x0800 /* Enable Automatic Remote Frame Handling For Mailbox 11 */ +#define RFH12 0x1000 /* Enable Automatic Remote Frame Handling For Mailbox 12 */ +#define RFH13 0x2000 /* Enable Automatic Remote Frame Handling For Mailbox 13 */ +#define RFH14 0x4000 /* Enable Automatic Remote Frame Handling For Mailbox 14 */ +#define RFH15 0x8000 /* Enable Automatic Remote Frame Handling For Mailbox 15 */ + +/* CAN_RFH2 Masks */ +#define RFH16 0x0001 /* Enable Automatic Remote Frame Handling For Mailbox 16 */ +#define RFH17 0x0002 /* Enable Automatic Remote Frame Handling For Mailbox 17 */ +#define RFH18 0x0004 /* Enable Automatic Remote Frame Handling For Mailbox 18 */ +#define RFH19 0x0008 /* Enable Automatic Remote Frame Handling For Mailbox 19 */ +#define RFH20 0x0010 /* Enable Automatic Remote Frame Handling For Mailbox 20 */ +#define RFH21 0x0020 /* Enable Automatic Remote Frame Handling For Mailbox 21 */ +#define RFH22 0x0040 /* Enable Automatic Remote Frame Handling For Mailbox 22 */ +#define RFH23 0x0080 /* Enable Automatic Remote Frame Handling For Mailbox 23 */ +#define RFH24 0x0100 /* Enable Automatic Remote Frame Handling For Mailbox 24 */ +#define RFH25 0x0200 /* Enable Automatic Remote Frame Handling For Mailbox 25 */ +#define RFH26 0x0400 /* Enable Automatic Remote Frame Handling For Mailbox 26 */ +#define RFH27 0x0800 /* Enable Automatic Remote Frame Handling For Mailbox 27 */ +#define RFH28 0x1000 /* Enable Automatic Remote Frame Handling For Mailbox 28 */ +#define RFH29 0x2000 /* Enable Automatic Remote Frame Handling For Mailbox 29 */ +#define RFH30 0x4000 /* Enable Automatic Remote Frame Handling For Mailbox 30 */ +#define RFH31 0x8000 /* Enable Automatic Remote Frame Handling For Mailbox 31 */ + +/* CAN_MBTIF1 Masks */ +#define MBTIF0 0x0001 /* TX Interrupt Active In Mailbox 0 */ +#define MBTIF1 0x0002 /* TX Interrupt Active In Mailbox 1 */ +#define MBTIF2 0x0004 /* TX Interrupt Active In Mailbox 2 */ +#define MBTIF3 0x0008 /* TX Interrupt Active In Mailbox 3 */ +#define MBTIF4 0x0010 /* TX Interrupt Active In Mailbox 4 */ +#define MBTIF5 0x0020 /* TX Interrupt Active In Mailbox 5 */ +#define MBTIF6 0x0040 /* TX Interrupt Active In Mailbox 6 */ +#define MBTIF7 0x0080 /* TX Interrupt Active In Mailbox 7 */ +#define MBTIF8 0x0100 /* TX Interrupt Active In Mailbox 8 */ +#define MBTIF9 0x0200 /* TX Interrupt Active In Mailbox 9 */ +#define MBTIF10 0x0400 /* TX Interrupt Active In Mailbox 10 */ +#define MBTIF11 0x0800 /* TX Interrupt Active In Mailbox 11 */ +#define MBTIF12 0x1000 /* TX Interrupt Active In Mailbox 12 */ +#define MBTIF13 0x2000 /* TX Interrupt Active In Mailbox 13 */ +#define MBTIF14 0x4000 /* TX Interrupt Active In Mailbox 14 */ +#define MBTIF15 0x8000 /* TX Interrupt Active In Mailbox 15 */ + +/* CAN_MBTIF2 Masks */ +#define MBTIF16 0x0001 /* TX Interrupt Active In Mailbox 16 */ +#define MBTIF17 0x0002 /* TX Interrupt Active In Mailbox 17 */ +#define MBTIF18 0x0004 /* TX Interrupt Active In Mailbox 18 */ +#define MBTIF19 0x0008 /* TX Interrupt Active In Mailbox 19 */ +#define MBTIF20 0x0010 /* TX Interrupt Active In Mailbox 20 */ +#define MBTIF21 0x0020 /* TX Interrupt Active In Mailbox 21 */ +#define MBTIF22 0x0040 /* TX Interrupt Active In Mailbox 22 */ +#define MBTIF23 0x0080 /* TX Interrupt Active In Mailbox 23 */ +#define MBTIF24 0x0100 /* TX Interrupt Active In Mailbox 24 */ +#define MBTIF25 0x0200 /* TX Interrupt Active In Mailbox 25 */ +#define MBTIF26 0x0400 /* TX Interrupt Active In Mailbox 26 */ +#define MBTIF27 0x0800 /* TX Interrupt Active In Mailbox 27 */ +#define MBTIF28 0x1000 /* TX Interrupt Active In Mailbox 28 */ +#define MBTIF29 0x2000 /* TX Interrupt Active In Mailbox 29 */ +#define MBTIF30 0x4000 /* TX Interrupt Active In Mailbox 30 */ +#define MBTIF31 0x8000 /* TX Interrupt Active In Mailbox 31 */ + +/* CAN_MBRIF1 Masks */ +#define MBRIF0 0x0001 /* RX Interrupt Active In Mailbox 0 */ +#define MBRIF1 0x0002 /* RX Interrupt Active In Mailbox 1 */ +#define MBRIF2 0x0004 /* RX Interrupt Active In Mailbox 2 */ +#define MBRIF3 0x0008 /* RX Interrupt Active In Mailbox 3 */ +#define MBRIF4 0x0010 /* RX Interrupt Active In Mailbox 4 */ +#define MBRIF5 0x0020 /* RX Interrupt Active In Mailbox 5 */ +#define MBRIF6 0x0040 /* RX Interrupt Active In Mailbox 6 */ +#define MBRIF7 0x0080 /* RX Interrupt Active In Mailbox 7 */ +#define MBRIF8 0x0100 /* RX Interrupt Active In Mailbox 8 */ +#define MBRIF9 0x0200 /* RX Interrupt Active In Mailbox 9 */ +#define MBRIF10 0x0400 /* RX Interrupt Active In Mailbox 10 */ +#define MBRIF11 0x0800 /* RX Interrupt Active In Mailbox 11 */ +#define MBRIF12 0x1000 /* RX Interrupt Active In Mailbox 12 */ +#define MBRIF13 0x2000 /* RX Interrupt Active In Mailbox 13 */ +#define MBRIF14 0x4000 /* RX Interrupt Active In Mailbox 14 */ +#define MBRIF15 0x8000 /* RX Interrupt Active In Mailbox 15 */ + +/* CAN_MBRIF2 Masks */ +#define MBRIF16 0x0001 /* RX Interrupt Active In Mailbox 16 */ +#define MBRIF17 0x0002 /* RX Interrupt Active In Mailbox 17 */ +#define MBRIF18 0x0004 /* RX Interrupt Active In Mailbox 18 */ +#define MBRIF19 0x0008 /* RX Interrupt Active In Mailbox 19 */ +#define MBRIF20 0x0010 /* RX Interrupt Active In Mailbox 20 */ +#define MBRIF21 0x0020 /* RX Interrupt Active In Mailbox 21 */ +#define MBRIF22 0x0040 /* RX Interrupt Active In Mailbox 22 */ +#define MBRIF23 0x0080 /* RX Interrupt Active In Mailbox 23 */ +#define MBRIF24 0x0100 /* RX Interrupt Active In Mailbox 24 */ +#define MBRIF25 0x0200 /* RX Interrupt Active In Mailbox 25 */ +#define MBRIF26 0x0400 /* RX Interrupt Active In Mailbox 26 */ +#define MBRIF27 0x0800 /* RX Interrupt Active In Mailbox 27 */ +#define MBRIF28 0x1000 /* RX Interrupt Active In Mailbox 28 */ +#define MBRIF29 0x2000 /* RX Interrupt Active In Mailbox 29 */ +#define MBRIF30 0x4000 /* RX Interrupt Active In Mailbox 30 */ +#define MBRIF31 0x8000 /* RX Interrupt Active In Mailbox 31 */ + +/* CAN_MBIM1 Masks */ +#define MBIM0 0x0001 /* Enable Interrupt For Mailbox 0 */ +#define MBIM1 0x0002 /* Enable Interrupt For Mailbox 1 */ +#define MBIM2 0x0004 /* Enable Interrupt For Mailbox 2 */ +#define MBIM3 0x0008 /* Enable Interrupt For Mailbox 3 */ +#define MBIM4 0x0010 /* Enable Interrupt For Mailbox 4 */ +#define MBIM5 0x0020 /* Enable Interrupt For Mailbox 5 */ +#define MBIM6 0x0040 /* Enable Interrupt For Mailbox 6 */ +#define MBIM7 0x0080 /* Enable Interrupt For Mailbox 7 */ +#define MBIM8 0x0100 /* Enable Interrupt For Mailbox 8 */ +#define MBIM9 0x0200 /* Enable Interrupt For Mailbox 9 */ +#define MBIM10 0x0400 /* Enable Interrupt For Mailbox 10 */ +#define MBIM11 0x0800 /* Enable Interrupt For Mailbox 11 */ +#define MBIM12 0x1000 /* Enable Interrupt For Mailbox 12 */ +#define MBIM13 0x2000 /* Enable Interrupt For Mailbox 13 */ +#define MBIM14 0x4000 /* Enable Interrupt For Mailbox 14 */ +#define MBIM15 0x8000 /* Enable Interrupt For Mailbox 15 */ + +/* CAN_MBIM2 Masks */ +#define MBIM16 0x0001 /* Enable Interrupt For Mailbox 16 */ +#define MBIM17 0x0002 /* Enable Interrupt For Mailbox 17 */ +#define MBIM18 0x0004 /* Enable Interrupt For Mailbox 18 */ +#define MBIM19 0x0008 /* Enable Interrupt For Mailbox 19 */ +#define MBIM20 0x0010 /* Enable Interrupt For Mailbox 20 */ +#define MBIM21 0x0020 /* Enable Interrupt For Mailbox 21 */ +#define MBIM22 0x0040 /* Enable Interrupt For Mailbox 22 */ +#define MBIM23 0x0080 /* Enable Interrupt For Mailbox 23 */ +#define MBIM24 0x0100 /* Enable Interrupt For Mailbox 24 */ +#define MBIM25 0x0200 /* Enable Interrupt For Mailbox 25 */ +#define MBIM26 0x0400 /* Enable Interrupt For Mailbox 26 */ +#define MBIM27 0x0800 /* Enable Interrupt For Mailbox 27 */ +#define MBIM28 0x1000 /* Enable Interrupt For Mailbox 28 */ +#define MBIM29 0x2000 /* Enable Interrupt For Mailbox 29 */ +#define MBIM30 0x4000 /* Enable Interrupt For Mailbox 30 */ +#define MBIM31 0x8000 /* Enable Interrupt For Mailbox 31 */ + +/* CAN_GIM Masks */ +#define EWTIM 0x0001 /* Enable TX Error Count Interrupt */ +#define EWRIM 0x0002 /* Enable RX Error Count Interrupt */ +#define EPIM 0x0004 /* Enable Error-Passive Mode Interrupt */ +#define BOIM 0x0008 /* Enable Bus Off Interrupt */ +#define WUIM 0x0010 /* Enable Wake-Up Interrupt */ +#define UIAIM 0x0020 /* Enable Access To Unimplemented Address Interrupt */ +#define AAIM 0x0040 /* Enable Abort Acknowledge Interrupt */ +#define RMLIM 0x0080 /* Enable RX Message Lost Interrupt */ +#define UCEIM 0x0100 /* Enable Universal Counter Overflow Interrupt */ +#define EXTIM 0x0200 /* Enable External Trigger Output Interrupt */ +#define ADIM 0x0400 /* Enable Access Denied Interrupt */ + +/* CAN_GIS Masks */ +#define EWTIS 0x0001 /* TX Error Count IRQ Status */ +#define EWRIS 0x0002 /* RX Error Count IRQ Status */ +#define EPIS 0x0004 /* Error-Passive Mode IRQ Status */ +#define BOIS 0x0008 /* Bus Off IRQ Status */ +#define WUIS 0x0010 /* Wake-Up IRQ Status */ +#define UIAIS 0x0020 /* Access To Unimplemented Address IRQ Status */ +#define AAIS 0x0040 /* Abort Acknowledge IRQ Status */ +#define RMLIS 0x0080 /* RX Message Lost IRQ Status */ +#define UCEIS 0x0100 /* Universal Counter Overflow IRQ Status */ +#define EXTIS 0x0200 /* External Trigger Output IRQ Status */ +#define ADIS 0x0400 /* Access Denied IRQ Status */ + +/* CAN_GIF Masks */ +#define EWTIF 0x0001 /* TX Error Count IRQ Flag */ +#define EWRIF 0x0002 /* RX Error Count IRQ Flag */ +#define EPIF 0x0004 /* Error-Passive Mode IRQ Flag */ +#define BOIF 0x0008 /* Bus Off IRQ Flag */ +#define WUIF 0x0010 /* Wake-Up IRQ Flag */ +#define UIAIF 0x0020 /* Access To Unimplemented Address IRQ Flag */ +#define AAIF 0x0040 /* Abort Acknowledge IRQ Flag */ +#define RMLIF 0x0080 /* RX Message Lost IRQ Flag */ +#define UCEIF 0x0100 /* Universal Counter Overflow IRQ Flag */ +#define EXTIF 0x0200 /* External Trigger Output IRQ Flag */ +#define ADIF 0x0400 /* Access Denied IRQ Flag */ + +/* CAN_UCCNF Masks */ +#define UCCNF 0x000F /* Universal Counter Mode */ +#define UC_STAMP 0x0001 /* Timestamp Mode */ +#define UC_WDOG 0x0002 /* Watchdog Mode */ +#define UC_AUTOTX 0x0003 /* Auto-Transmit Mode */ +#define UC_ERROR 0x0006 /* CAN Error Frame Count */ +#define UC_OVER 0x0007 /* CAN Overload Frame Count */ +#define UC_LOST 0x0008 /* Arbitration Lost During TX Count */ +#define UC_AA 0x0009 /* TX Abort Count */ +#define UC_TA 0x000A /* TX Successful Count */ +#define UC_REJECT 0x000B /* RX Message Rejected Count */ +#define UC_RML 0x000C /* RX Message Lost Count */ +#define UC_RX 0x000D /* Total Successful RX Messages Count */ +#define UC_RMP 0x000E /* Successful RX W/Matching ID Count */ +#define UC_ALL 0x000F /* Correct Message On CAN Bus Line Count */ +#define UCRC 0x0020 /* Universal Counter Reload/Clear */ +#define UCCT 0x0040 /* Universal Counter CAN Trigger */ +#define UCE 0x0080 /* Universal Counter Enable */ + +/* CAN_ESR Masks */ +#define ACKE 0x0004 /* Acknowledge Error */ +#define SER 0x0008 /* Stuff Error */ +#define CRCE 0x0010 /* CRC Error */ +#define SA0 0x0020 /* Stuck At Dominant Error */ +#define BEF 0x0040 /* Bit Error Flag */ +#define FER 0x0080 /* Form Error Flag */ + +/* CAN_EWR Masks */ +#define EWLREC 0x00FF /* RX Error Count Limit (For EWRIS) */ +#define EWLTEC 0xFF00 /* TX Error Count Limit (For EWTIS) */ + +#endif -- cgit v0.10.2 From 0c270807db7c6478d60ab2bc23511fd5868a7a80 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 15 Dec 2009 20:57:43 +0000 Subject: Blackfin: drop duplicate HOTPLUG Kconfig option The option already exists for everyone in init/Kconfig. Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index 1f075be..3bd8e83 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -1120,24 +1120,6 @@ config PCI source "drivers/pci/Kconfig" -config HOTPLUG - bool "Support for hot-pluggable device" - help - Say Y here if you want to plug devices into your computer while - the system is running, and be able to use them quickly. In many - cases, the devices can likewise be unplugged at any time too. - - One well known example of this is PCMCIA- or PC-cards, credit-card - size devices such as network cards, modems or hard drives which are - plugged into slots found on all modern laptop computers. Another - example, used on modern desktops as well as laptops, is USB. - - Enable HOTPLUG and build a modular kernel. Get agent software - (from ) and install it. - Then your kernel will automatically call out to a user mode "policy - agent" (/sbin/hotplug) to load modules and set up software needed - to use devices as you hotplug them. - source "drivers/pcmcia/Kconfig" source "drivers/pci/hotplug/Kconfig" -- cgit v0.10.2 From a3a6a590190ca77aedf9de871d941c1139a5a24c Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Wed, 16 Dec 2009 07:52:52 +0000 Subject: Blackfin: dma-mapping: fix thinko in constant optimization Make sure the non-constant version of the dma_sync functions actually complete instead of recursively calling itself forever. Signed-off-by: Sonic Zhang Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/dma-mapping.h b/arch/blackfin/include/asm/dma-mapping.h index f9172ff..e63f6d9 100644 --- a/arch/blackfin/include/asm/dma-mapping.h +++ b/arch/blackfin/include/asm/dma-mapping.h @@ -44,13 +44,8 @@ dma_mapping_error(struct device *dev, dma_addr_t dma_addr) extern void __dma_sync(dma_addr_t addr, size_t size, enum dma_data_direction dir); static inline void -_dma_sync(dma_addr_t addr, size_t size, enum dma_data_direction dir) +__dma_sync_inline(dma_addr_t addr, size_t size, enum dma_data_direction dir) { - if (!__builtin_constant_p(dir)) { - __dma_sync(addr, size, dir); - return; - } - switch (dir) { case DMA_NONE: BUG(); @@ -64,6 +59,14 @@ _dma_sync(dma_addr_t addr, size_t size, enum dma_data_direction dir) break; } } +static inline void +_dma_sync(dma_addr_t addr, size_t size, enum dma_data_direction dir) +{ + if (__builtin_constant_p(dir)) + __dma_sync_inline(addr, size, dir); + else + __dma_sync(addr, size, dir); +} /* * Map a single buffer of the indicated size for DMA in streaming mode. diff --git a/arch/blackfin/kernel/dma-mapping.c b/arch/blackfin/kernel/dma-mapping.c index e937f32..04ddcfe 100644 --- a/arch/blackfin/kernel/dma-mapping.c +++ b/arch/blackfin/kernel/dma-mapping.c @@ -116,7 +116,7 @@ EXPORT_SYMBOL(dma_free_coherent); void __dma_sync(dma_addr_t addr, size_t size, enum dma_data_direction dir) { - _dma_sync(addr, size, dir); + __dma_sync_inline(addr, size, dir); } EXPORT_SYMBOL(__dma_sync); -- cgit v0.10.2 From 15435a2a55a678b21b9bb75a7513b3c9ff69a68e Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Wed, 16 Dec 2009 08:39:58 +0000 Subject: Blackfin: pull in asm/bfin_can.h for interrupt masks Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c index 1873b2c..5202a60 100644 --- a/arch/blackfin/mach-common/ints-priority.c +++ b/arch/blackfin/mach-common/ints-priority.c @@ -28,6 +28,7 @@ #include #include #include +#include #define SIC_SYSIRQ(irq) (irq - (IRQ_CORETMR + 1)) -- cgit v0.10.2 From edd07992504e631b50d18d130c62addbcb16269e Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Wed, 16 Dec 2009 08:45:17 +0000 Subject: Blackfin: gpio: use shorter name The gpio label size is 16 char, but the current code uses a longer name resulting in chopped display. So use a shorter name. Reported-by: Peter Meerwald Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c index a174596..0dd9cf9 100644 --- a/arch/blackfin/kernel/bfin_gpio.c +++ b/arch/blackfin/kernel/bfin_gpio.c @@ -1320,7 +1320,7 @@ void bfin_gpiolib_gpio_free(struct gpio_chip *chip, unsigned gpio) } static struct gpio_chip bfin_chip = { - .label = "Blackfin-GPIOlib", + .label = "BFIN-GPIO", .direction_input = bfin_gpiolib_direction_input, .get = bfin_gpiolib_get_value, .direction_output = bfin_gpiolib_direction_output, -- cgit v0.10.2 From 244d34230b7447fba95221dbf39b39e94257939c Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Fri, 18 Dec 2009 09:29:39 +0000 Subject: Blackfin: update AD7879 resources to match the new gpiolib driver support Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf527/boards/ezbrd.c b/arch/blackfin/mach-bf527/boards/ezbrd.c index faede2b..55069af 100644 --- a/arch/blackfin/mach-bf527/boards/ezbrd.c +++ b/arch/blackfin/mach-bf527/boards/ezbrd.c @@ -274,8 +274,8 @@ static const struct ad7879_platform_data bfin_ad7879_ts_info = { .median = 2, /* do 8 measurements */ .averaging = 1, /* take the average of 4 middle samples */ .pen_down_acc_interval = 255, /* 9.4 ms */ - .gpio_output = 1, /* configure AUX/VBAT/GPIO as GPIO output */ - .gpio_default = 1, /* During initialization set GPIO = HIGH */ + .gpio_export = 1, /* Export GPIO to gpiolib */ + .gpio_base = -1, /* Dynamic allocation */ }; #endif diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c index fdfe8ca..0cc3581 100644 --- a/arch/blackfin/mach-bf527/boards/ezkit.c +++ b/arch/blackfin/mach-bf527/boards/ezkit.c @@ -521,8 +521,7 @@ static const struct ad7879_platform_data bfin_ad7879_ts_info = { .median = 2, /* do 8 measurements */ .averaging = 1, /* take the average of 4 middle samples */ .pen_down_acc_interval = 255, /* 9.4 ms */ - .gpio_output = 1, /* configure AUX/VBAT/GPIO as GPIO output */ - .gpio_default = 1, /* During initialization set GPIO = HIGH */ + .gpio_export = 0, /* Export GPIO to gpiolib */ }; #endif diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 538bff8..03e36bd 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -705,8 +705,8 @@ static const struct ad7879_platform_data bfin_ad7879_ts_info = { .median = 2, /* do 8 measurements */ .averaging = 1, /* take the average of 4 middle samples */ .pen_down_acc_interval = 255, /* 9.4 ms */ - .gpio_output = 1, /* configure AUX/VBAT/GPIO as GPIO output */ - .gpio_default = 1, /* During initialization set GPIO = HIGH */ + .gpio_export = 1, /* Export GPIO to gpiolib */ + .gpio_base = -1, /* Dynamic allocation */ }; #endif diff --git a/arch/blackfin/mach-bf538/boards/ezkit.c b/arch/blackfin/mach-bf538/boards/ezkit.c index d2d06f0..1a1f658 100644 --- a/arch/blackfin/mach-bf538/boards/ezkit.c +++ b/arch/blackfin/mach-bf538/boards/ezkit.c @@ -518,8 +518,8 @@ static const struct ad7879_platform_data bfin_ad7879_ts_info = { .median = 2, /* do 8 measurements */ .averaging = 1, /* take the average of 4 middle samples */ .pen_down_acc_interval = 255, /* 9.4 ms */ - .gpio_output = 1, /* configure AUX/VBAT/GPIO as GPIO output */ - .gpio_default = 1, /* During initialization set GPIO = HIGH */ + .gpio_export = 1, /* Export GPIO to gpiolib */ + .gpio_base = -1, /* Dynamic allocation */ }; #endif -- cgit v0.10.2 From 1dafdc513a20410e328b22b6d25d4ac78557516a Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Fri, 18 Dec 2009 12:30:04 +0000 Subject: Blackfin: BF51x: fix L1 Instruction SRAM size The BF51x's Instruction SRAM is 32kB, not 48kB. Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf518/include/mach/mem_map.h b/arch/blackfin/mach-bf518/include/mach/mem_map.h index 3c6777c..073b5d7 100644 --- a/arch/blackfin/mach-bf518/include/mach/mem_map.h +++ b/arch/blackfin/mach-bf518/include/mach/mem_map.h @@ -41,7 +41,7 @@ #define L1_DATA_A_START 0xFF800000 #define L1_DATA_B_START 0xFF900000 -#define L1_CODE_LENGTH 0xC000 +#define L1_CODE_LENGTH 0x8000 #ifdef CONFIG_BFIN_DCACHE -- cgit v0.10.2 From 3b781de6dd96d64c133a7ed774f385d35129575b Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 21 Dec 2009 15:04:03 +0000 Subject: Blackfin: drop unused SL811 platform resources from bf527/pnav boards These platforms don't hook up to this USB controller, so no point in declaring resources for it. Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf527/boards/cm_bf527.c b/arch/blackfin/mach-bf527/boards/cm_bf527.c index eaa0131..d6efdfa 100644 --- a/arch/blackfin/mach-bf527/boards/cm_bf527.c +++ b/arch/blackfin/mach-bf527/boards/cm_bf527.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -270,50 +269,6 @@ static struct platform_device dm9000_device = { }; #endif -#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE) -static struct resource sl811_hcd_resources[] = { - { - .start = 0x20340000, - .end = 0x20340000, - .flags = IORESOURCE_MEM, - }, { - .start = 0x20340004, - .end = 0x20340004, - .flags = IORESOURCE_MEM, - }, { - .start = CONFIG_USB_SL811_BFIN_IRQ, - .end = CONFIG_USB_SL811_BFIN_IRQ, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - }, -}; - -#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS) -void sl811_port_power(struct device *dev, int is_on) -{ - gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS"); - gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS, is_on); -} -#endif - -static struct sl811_platform_data sl811_priv = { - .potpg = 10, - .power = 250, /* == 500mA */ -#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS) - .port_power = &sl811_port_power, -#endif -}; - -static struct platform_device sl811_hcd_device = { - .name = "sl811-hcd", - .id = 0, - .dev = { - .platform_data = &sl811_priv, - }, - .num_resources = ARRAY_SIZE(sl811_hcd_resources), - .resource = sl811_hcd_resources, -}; -#endif - #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) static struct platform_device bfin_mii_bus = { .name = "bfin_mii_bus", @@ -929,10 +884,6 @@ static struct platform_device *cmbf527_devices[] __initdata = { &rtc_device, #endif -#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE) - &sl811_hcd_device, -#endif - #if defined(CONFIG_USB_ISP1760_HCD) || defined(CONFIG_USB_ISP1760_HCD_MODULE) &bfin_isp1760_device, #endif diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c index 0cc3581..a7beed5 100644 --- a/arch/blackfin/mach-bf527/boards/ezkit.c +++ b/arch/blackfin/mach-bf527/boards/ezkit.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -359,50 +358,6 @@ static struct platform_device dm9000_device = { }; #endif -#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE) -static struct resource sl811_hcd_resources[] = { - { - .start = 0x20340000, - .end = 0x20340000, - .flags = IORESOURCE_MEM, - }, { - .start = 0x20340004, - .end = 0x20340004, - .flags = IORESOURCE_MEM, - }, { - .start = CONFIG_USB_SL811_BFIN_IRQ, - .end = CONFIG_USB_SL811_BFIN_IRQ, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - }, -}; - -#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS) -void sl811_port_power(struct device *dev, int is_on) -{ - gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS"); - gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS, is_on); -} -#endif - -static struct sl811_platform_data sl811_priv = { - .potpg = 10, - .power = 250, /* == 500mA */ -#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS) - .port_power = &sl811_port_power, -#endif -}; - -static struct platform_device sl811_hcd_device = { - .name = "sl811-hcd", - .id = 0, - .dev = { - .platform_data = &sl811_priv, - }, - .num_resources = ARRAY_SIZE(sl811_hcd_resources), - .resource = sl811_hcd_resources, -}; -#endif - #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) static struct platform_device bfin_mii_bus = { .name = "bfin_mii_bus", @@ -1113,10 +1068,6 @@ static struct platform_device *stamp_devices[] __initdata = { &rtc_device, #endif -#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE) - &sl811_hcd_device, -#endif - #if defined(CONFIG_USB_ISP1760_HCD) || defined(CONFIG_USB_ISP1760_HCD_MODULE) &bfin_isp1760_device, #endif diff --git a/arch/blackfin/mach-bf537/boards/pnav10.c b/arch/blackfin/mach-bf537/boards/pnav10.c index f08533d..a0f64ff 100644 --- a/arch/blackfin/mach-bf537/boards/pnav10.c +++ b/arch/blackfin/mach-bf537/boards/pnav10.c @@ -17,7 +17,6 @@ #include #include #include -#include #include @@ -99,51 +98,6 @@ static struct platform_device smc91x_device = { }; #endif -#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE) -static struct resource sl811_hcd_resources[] = { - { - .start = 0x20340000, - .end = 0x20340000, - .flags = IORESOURCE_MEM, - }, { - .start = 0x20340004, - .end = 0x20340004, - .flags = IORESOURCE_MEM, - }, { - .start = CONFIG_USB_SL811_BFIN_IRQ, - .end = CONFIG_USB_SL811_BFIN_IRQ, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - }, -}; - -#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS) -void sl811_port_power(struct device *dev, int is_on) -{ - gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS"); - gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS, is_on); - -} -#endif - -static struct sl811_platform_data sl811_priv = { - .potpg = 10, - .power = 250, /* == 500mA */ -#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS) - .port_power = &sl811_port_power, -#endif -}; - -static struct platform_device sl811_hcd_device = { - .name = "sl811-hcd", - .id = 0, - .dev = { - .platform_data = &sl811_priv, - }, - .num_resources = ARRAY_SIZE(sl811_hcd_resources), - .resource = sl811_hcd_resources, -}; -#endif - #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) static struct platform_device bfin_mii_bus = { .name = "bfin_mii_bus", @@ -514,10 +468,6 @@ static struct platform_device *stamp_devices[] __initdata = { &rtc_device, #endif -#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE) - &sl811_hcd_device, -#endif - #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) &smc91x_device, #endif -- cgit v0.10.2 From 01218654cd97a1e970034b1e080ec5459172c3f6 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 21 Dec 2009 15:07:43 +0000 Subject: Blackfin: bf537-stamp: change CONFIG_USB_SL811_BFIN_IRQ to IRQ_PF4 The Kconfig option was never mainlined, so replace the define with the actual pin that it is hooked up to by default. Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 03e36bd..3402236 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -208,8 +208,8 @@ static struct resource sl811_hcd_resources[] = { .end = 0x20340004, .flags = IORESOURCE_MEM, }, { - .start = CONFIG_USB_SL811_BFIN_IRQ, - .end = CONFIG_USB_SL811_BFIN_IRQ, + .start = IRQ_PF4, + .end = IRQ_PF4, .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, }, }; -- cgit v0.10.2 From 7a9cc48907e05e61033b953a3860e55703625950 Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Tue, 22 Dec 2009 04:47:04 +0000 Subject: Blackfin: bf537-stamp: unify duplicated ADP5588 headers Signed-off-by: Sonic Zhang Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 3402236..27b9c9c 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -20,10 +20,11 @@ #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) #include #endif +#include +#include #include #include #include -#include #include #include #include @@ -1335,7 +1336,6 @@ static struct platform_device i2c_bfin_twi_device = { #endif #if defined(CONFIG_KEYBOARD_ADP5588) || defined(CONFIG_KEYBOARD_ADP5588_MODULE) -#include static const unsigned short adp5588_keymap[ADP5588_KEYMAPSIZE] = { [0] = KEY_GRAVE, [1] = KEY_1, @@ -1532,7 +1532,6 @@ static struct adp5520_platform_data adp5520_pdev_data = { #endif #if defined(CONFIG_GPIO_ADP5588) || defined(CONFIG_GPIO_ADP5588_MODULE) -#include static struct adp5588_gpio_platform_data adp5588_gpio_data = { .gpio_start = 50, .pullup_dis_mask = 0, -- cgit v0.10.2 From 252077cf7d44f1f261a5fdaedab88057f8379859 Mon Sep 17 00:00:00 2001 From: Valentin Yakovenkov Date: Tue, 22 Dec 2009 09:02:10 +0000 Subject: Blackfin: bf561-acvilon: save the smsc911x mac address Signed-off-by: Valentin Yakovenkov Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf561/boards/acvilon.c b/arch/blackfin/mach-bf561/boards/acvilon.c index 07e8dc8..5163e2c 100644 --- a/arch/blackfin/mach-bf561/boards/acvilon.c +++ b/arch/blackfin/mach-bf561/boards/acvilon.c @@ -176,7 +176,7 @@ static struct resource smsc911x_resources[] = { }; static struct smsc911x_platform_config smsc911x_config = { - .flags = SMSC911X_USE_32BIT, + .flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS, .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN, .phy_interface = PHY_INTERFACE_MODE_MII, -- cgit v0.10.2 From 0f7b468b6eace87ecdc59b3ec8476d50b0561ac2 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Tue, 22 Dec 2009 11:32:06 +0000 Subject: Blackfin: add optimized version of Hamming Weight functions Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index 3bd8e83..b483639 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -45,9 +45,6 @@ config ZONE_DMA config GENERIC_FIND_NEXT_BIT def_bool y -config GENERIC_HWEIGHT - def_bool y - config GENERIC_HARDIRQS def_bool y diff --git a/arch/blackfin/include/asm/bitops.h b/arch/blackfin/include/asm/bitops.h index a2ff3fb..605ba8e 100644 --- a/arch/blackfin/include/asm/bitops.h +++ b/arch/blackfin/include/asm/bitops.h @@ -7,22 +7,41 @@ #ifndef _BLACKFIN_BITOPS_H #define _BLACKFIN_BITOPS_H -#ifndef CONFIG_SMP -# include -#else +#include + +#include +#include +#include +#include +#include +#include #ifndef _LINUX_BITOPS_H #error only can be included directly #endif -#include -#include /* swab32 */ - -#include -#include #include -#include +#include +#include +#include +#include +#include + +#ifndef CONFIG_SMP +#include + +/* + * clear_bit may not imply a memory barrier + */ +#ifndef smp_mb__before_clear_bit +#define smp_mb__before_clear_bit() smp_mb() +#define smp_mb__after_clear_bit() smp_mb() +#endif +#include +#include +#else +#include /* swab32 */ #include asmlinkage int __raw_bit_set_asm(volatile unsigned long *addr, int nr); @@ -89,19 +108,36 @@ static inline int test_and_change_bit(int nr, volatile unsigned long *addr) #include -#include -#include -#include +#endif /* CONFIG_SMP */ -#include -#include +/* + * hweightN: returns the hamming weight (i.e. the number + * of bits set) of a N-bit word + */ -#include +static inline unsigned int hweight32(unsigned int w) +{ + unsigned int res; -#include -#include -#include + __asm__ ("%0.l = ONES %0;" + "%0 = %0.l (Z);" + : "=d" (res) : "d" (w)); + return res; +} -#endif /* CONFIG_SMP */ +static inline unsigned int hweight64(__u64 w) +{ + return hweight32((unsigned int)(w >> 32)) + hweight32((unsigned int)w); +} + +static inline unsigned int hweight16(unsigned int w) +{ + return hweight32(w & 0xffff); +} + +static inline unsigned int hweight8(unsigned int w) +{ + return hweight32(w & 0xff); +} #endif /* _BLACKFIN_BITOPS_H */ -- cgit v0.10.2 From 0ea19c64e30f3688d1a890217c382db2b0ca411c Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Wed, 23 Dec 2009 07:01:43 +0000 Subject: Blackfin: update defconfigs Signed-off-by: Sonic Zhang Signed-off-by: Barry Song Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/configs/BF518F-EZBRD_defconfig b/arch/blackfin/configs/BF518F-EZBRD_defconfig index e315594..cf7c9bc 100644 --- a/arch/blackfin/configs/BF518F-EZBRD_defconfig +++ b/arch/blackfin/configs/BF518F-EZBRD_defconfig @@ -1,22 +1,27 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.28.10 -# Thu May 21 05:50:01 2009 +# Linux kernel version: 2.6.32.2 # # CONFIG_MMU is not set # CONFIG_FPU is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_BLACKFIN=y +CONFIG_GENERIC_CSUM=y +CONFIG_GENERIC_BUG=y CONFIG_ZONE_DMA=y CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y CONFIG_GENERIC_GPIO=y CONFIG_FORCE_MAX_ZONEORDER=14 CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y # # General setup @@ -26,22 +31,41 @@ CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_BZIP2=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set # CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set # CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set # CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -62,6 +86,10 @@ CONFIG_EPOLL=y # CONFIG_TIMERFD is not set # CONFIG_EVENTFD is not set # CONFIG_AIO is not set + +# +# Kernel Performance Events And Counters +# CONFIG_VM_EVENT_COUNTERS=y CONFIG_COMPAT_BRK=y CONFIG_SLAB=y @@ -69,11 +97,15 @@ CONFIG_SLAB=y # CONFIG_SLOB is not set CONFIG_MMAP_ALLOW_UNINITIALIZED=y # CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +# CONFIG_SLOW_WORK is not set # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set CONFIG_SLABINFO=y -CONFIG_TINY_SHMEM=y CONFIG_BASE_SMALL=0 CONFIG_MODULES=y # CONFIG_MODULE_FORCE_LOAD is not set @@ -81,11 +113,8 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set +# CONFIG_LBDAF is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -101,7 +130,6 @@ CONFIG_IOSCHED_NOOP=y # CONFIG_DEFAULT_CFQ is not set CONFIG_DEFAULT_NOOP=y CONFIG_DEFAULT_IOSCHED="noop" -CONFIG_CLASSIC_RCU=y # CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set @@ -132,15 +160,15 @@ CONFIG_BF518=y # CONFIG_BF537 is not set # CONFIG_BF538 is not set # CONFIG_BF539 is not set -# CONFIG_BF542 is not set +# CONFIG_BF542_std is not set # CONFIG_BF542M is not set -# CONFIG_BF544 is not set +# CONFIG_BF544_std is not set # CONFIG_BF544M is not set -# CONFIG_BF547 is not set +# CONFIG_BF547_std is not set # CONFIG_BF547M is not set -# CONFIG_BF548 is not set +# CONFIG_BF548_std is not set # CONFIG_BF548M is not set -# CONFIG_BF549 is not set +# CONFIG_BF549_std is not set # CONFIG_BF549M is not set # CONFIG_BF561 is not set CONFIG_BF_REV_MIN=0 @@ -154,8 +182,8 @@ CONFIG_BF_REV_0_0=y # CONFIG_BF_REV_0_6 is not set # CONFIG_BF_REV_ANY is not set # CONFIG_BF_REV_NONE is not set -CONFIG_BF51x=y CONFIG_MEM_MT48LC32M8A2_75=y +CONFIG_BF51x=y CONFIG_BFIN518F_EZBRD=y # @@ -313,7 +341,6 @@ CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_VIRT_TO_BUS=y @@ -322,16 +349,18 @@ CONFIG_BFIN_GPTIMERS=m # CONFIG_DMA_UNCACHED_4M is not set # CONFIG_DMA_UNCACHED_2M is not set CONFIG_DMA_UNCACHED_1M=y +# CONFIG_DMA_UNCACHED_512K is not set +# CONFIG_DMA_UNCACHED_256K is not set +# CONFIG_DMA_UNCACHED_128K is not set # CONFIG_DMA_UNCACHED_NONE is not set # # Cache Support # CONFIG_BFIN_ICACHE=y -# CONFIG_BFIN_ICACHE_LOCK is not set +CONFIG_BFIN_EXTMEM_ICACHEABLE=y CONFIG_BFIN_DCACHE=y # CONFIG_BFIN_DCACHE_BANKA is not set -CONFIG_BFIN_EXTMEM_ICACHEABLE=y CONFIG_BFIN_EXTMEM_DCACHEABLE=y CONFIG_BFIN_EXTMEM_WRITEBACK=y # CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set @@ -342,7 +371,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y # CONFIG_MPU is not set # -# Asynchonous Memory Configuration +# Asynchronous Memory Configuration # # @@ -398,11 +427,6 @@ CONFIG_NET=y CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -426,7 +450,6 @@ CONFIG_IP_PNP=y # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set -CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" @@ -437,6 +460,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_NETFILTER is not set # CONFIG_IP_DCCP is not set # CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -450,7 +474,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_LAPB is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set # CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set # # Network testing @@ -461,13 +488,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set -# CONFIG_PHONET is not set -CONFIG_WIRELESS=y -# CONFIG_CFG80211 is not set -CONFIG_WIRELESS_OLD_REGULATORY=y -# CONFIG_WIRELESS_EXT is not set -# CONFIG_MAC80211 is not set -# CONFIG_IEEE80211 is not set +# CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -488,6 +510,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_CONNECTOR is not set CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set # CONFIG_MTD_CONCAT is not set CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_REDBOOT_PARTS is not set @@ -545,6 +568,7 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y # # CONFIG_MTD_DATAFLASH is not set # CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SST25L is not set # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set @@ -560,6 +584,11 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y # CONFIG_MTD_ONENAND is not set # +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# # UBI - Unsorted block images # # CONFIG_MTD_UBI is not set @@ -576,10 +605,20 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 # CONFIG_ATA_OVER_ETH is not set # CONFIG_BLK_DEV_HD is not set CONFIG_MISC_DEVICES=y -# CONFIG_EEPROM_93CX6 is not set +# CONFIG_AD525X_DPOT is not set # CONFIG_ICS932S401 is not set # CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_ISL29003 is not set # CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EEPROM_93CX6 is not set CONFIG_HAVE_IDE=y # CONFIG_IDE is not set @@ -614,6 +653,9 @@ CONFIG_PHYLIB=y # CONFIG_BROADCOM_PHY is not set # CONFIG_ICPLUS_PHY is not set # CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set # CONFIG_FIXED_PHY is not set # CONFIG_MDIO_BITBANG is not set CONFIG_NET_ETHERNET=y @@ -622,10 +664,14 @@ CONFIG_BFIN_MAC=y CONFIG_BFIN_TX_DESC_NUM=10 CONFIG_BFIN_RX_DESC_NUM=20 # CONFIG_BFIN_MAC_RMII is not set +CONFIG_BFIN_MAC_USE_HWSTAMP=y # CONFIG_SMC91X is not set -# CONFIG_SMSC911X is not set # CONFIG_DM9000 is not set # CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set +# CONFIG_ADF702X is not set # CONFIG_IBM_NEW_EMAC_ZMII is not set # CONFIG_IBM_NEW_EMAC_RGMII is not set # CONFIG_IBM_NEW_EMAC_TAH is not set @@ -634,15 +680,16 @@ CONFIG_BFIN_RX_DESC_NUM=20 # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set +# CONFIG_WLAN is not set # -# Wireless LAN +# Enable WiMAX (Networking options) to see the WiMAX drivers # -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set -# CONFIG_IWLWIFI_LEDS is not set # CONFIG_WAN is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -677,7 +724,10 @@ CONFIG_INPUT=y # CONFIG_INPUT_TOUCHSCREEN is not set CONFIG_INPUT_MISC=y # CONFIG_INPUT_UINPUT is not set -# CONFIG_CONFIG_INPUT_PCF8574 is not set +# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set +# CONFIG_INPUT_AD714X is not set +# CONFIG_INPUT_ADXL34X is not set +# CONFIG_INPUT_PCF8574 is not set # # Hardware I/O ports @@ -688,16 +738,13 @@ CONFIG_INPUT_MISC=y # # Character devices # -# CONFIG_AD9960 is not set CONFIG_BFIN_DMA_INTERFACE=m # CONFIG_BFIN_PPI is not set # CONFIG_BFIN_PPIFCD is not set # CONFIG_BFIN_SIMPLE_TIMER is not set # CONFIG_BFIN_SPI_ADC is not set # CONFIG_BFIN_SPORT is not set -# CONFIG_BFIN_TIMER_LATENCY is not set # CONFIG_BFIN_TWI_LCD is not set -CONFIG_SIMPLE_GPIO=m CONFIG_VT=y CONFIG_CONSOLE_TRANSLATIONS=y CONFIG_VT_CONSOLE=y @@ -715,6 +762,7 @@ CONFIG_BFIN_JTAG_COMM=m # # Non-8250 serial port support # +# CONFIG_SERIAL_MAX3100 is not set CONFIG_SERIAL_BFIN=y CONFIG_SERIAL_BFIN_CONSOLE=y CONFIG_SERIAL_BFIN_DMA=y @@ -726,12 +774,10 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_BFIN_SPORT is not set CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set - -# -# CAN, the car bus and industrial fieldbus -# -# CONFIG_CAN4LINUX is not set +CONFIG_BFIN_OTP=y +# CONFIG_BFIN_OTP_WRITE_ENABLE is not set # CONFIG_IPMI_HANDLER is not set # CONFIG_HW_RANDOM is not set # CONFIG_R3964 is not set @@ -739,6 +785,7 @@ CONFIG_UNIX98_PTYS=y # CONFIG_TCG_TPM is not set CONFIG_I2C=y CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_HELPER_AUTO=y @@ -771,14 +818,6 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100 # Miscellaneous I2C Chip support # # CONFIG_DS1682 is not set -# CONFIG_EEPROM_AT24 is not set -# CONFIG_SENSORS_AD5252 is not set -# CONFIG_EEPROM_LEGACY is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_PCF8575 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_MAX6875 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set @@ -795,13 +834,18 @@ CONFIG_SPI_BFIN=y # CONFIG_SPI_BFIN_LOCK is not set # CONFIG_SPI_BFIN_SPORT is not set # CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set # # SPI Protocol Masters # -# CONFIG_SPI_AT25 is not set # CONFIG_SPI_SPIDEV is not set # CONFIG_SPI_TLE62X0 is not set + +# +# PPS support +# +# CONFIG_PPS is not set CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y CONFIG_GPIOLIB=y # CONFIG_DEBUG_GPIO is not set @@ -817,6 +861,7 @@ CONFIG_GPIO_SYSFS=y # CONFIG_GPIO_MAX732X is not set # CONFIG_GPIO_PCA953X is not set # CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_ADP5588 is not set # # PCI GPIO expanders: @@ -827,11 +872,15 @@ CONFIG_GPIO_SYSFS=y # # CONFIG_GPIO_MAX7301 is not set # CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set + +# +# AC97 GPIO expanders: +# # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set # CONFIG_THERMAL is not set -# CONFIG_THERMAL_HWMON is not set CONFIG_WATCHDOG=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -853,28 +902,20 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set # CONFIG_HTC_PASIC3 is not set +# CONFIG_TPS65010 is not set +# CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set # CONFIG_PMIC_ADP5520 is not set # CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13783 is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_EZX_PCAP is not set # CONFIG_REGULATOR is not set - -# -# Multimedia devices -# - -# -# Multimedia core support -# -# CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -# CONFIG_VIDEO_MEDIA is not set - -# -# Multimedia drivers -# -# CONFIG_DAB is not set +# CONFIG_MEDIA_SUPPORT is not set # # Graphics support @@ -912,10 +953,11 @@ CONFIG_MMC_BLOCK_BOUNCE=y # MMC/SD/SDIO Host Controller Drivers # # CONFIG_MMC_SDHCI is not set +# CONFIG_MMC_AT91 is not set +# CONFIG_MMC_ATMELMCI is not set +# CONFIG_MMC_SPI is not set CONFIG_SDH_BFIN=m CONFIG_SDH_BFIN_MISSING_CMD_PULLUP_WORKAROUND=y -# CONFIG_SDH_BFIN_ENABLE_SDIO_IRQ is not set -# CONFIG_MMC_SPI is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set # CONFIG_ACCESSIBILITY is not set @@ -950,6 +992,7 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_S35390A is not set # CONFIG_RTC_DRV_FM3130 is not set # CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set # # SPI RTC drivers @@ -961,6 +1004,7 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_R9701 is not set # CONFIG_RTC_DRV_RS5C348 is not set # CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set # # Platform RTC drivers @@ -981,10 +1025,21 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_BFIN=y # CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set # CONFIG_UIO is not set + +# +# TI VLYNQ +# # CONFIG_STAGING is not set # +# Firmware Drivers +# +# CONFIG_FIRMWARE_MEMMAP is not set +# CONFIG_SIGMA is not set + +# # File systems # CONFIG_EXT2_FS=m @@ -994,9 +1049,13 @@ CONFIG_EXT2_FS=m # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set -CONFIG_FILE_LOCKING=y # CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y # CONFIG_DNOTIFY is not set CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y @@ -1006,6 +1065,11 @@ CONFIG_INOTIFY_USER=y # CONFIG_FUSE_FS is not set # +# Caches +# +# CONFIG_FSCACHE is not set + +# # CD-ROM/DVD Filesystems # # CONFIG_ISO9660_FS is not set @@ -1027,13 +1091,9 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" CONFIG_PROC_FS=y CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y -# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set # CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# +CONFIG_MISC_FILESYSTEMS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set @@ -1042,8 +1102,8 @@ CONFIG_SYSFS=y # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set # CONFIG_JFFS2_FS is not set -# CONFIG_YAFFS_FS is not set # CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_OMFS_FS is not set @@ -1062,7 +1122,6 @@ CONFIG_LOCKD=m CONFIG_LOCKD_V4=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=m -# CONFIG_SUNRPC_REGISTER_V4 is not set # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set CONFIG_SMB_FS=m @@ -1127,14 +1186,19 @@ CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y CONFIG_FRAME_WARN=1024 # CONFIG_MAGIC_SYSRQ is not set +# CONFIG_STRIP_ASM_SYMS is not set # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_SECTION_MISMATCH=y CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_SHIRQ=y CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set @@ -1142,31 +1206,39 @@ CONFIG_SCHED_DEBUG=y # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y CONFIG_DEBUG_INFO=y # CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_NOMMU_REGIONS is not set # CONFIG_DEBUG_WRITECOUNT is not set # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set # CONFIG_FRAME_POINTER is not set # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set # CONFIG_FAULT_INJECTION is not set - -# -# Tracers -# -# CONFIG_SCHED_TRACER is not set -# CONFIG_CONTEXT_SWITCH_TRACER is not set -# CONFIG_BOOT_TRACER is not set -# CONFIG_DYNAMIC_PRINTK_DEBUG is not set +# CONFIG_PAGE_POISONING is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_BRANCH_PROFILE_NONE is not set +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_DYNAMIC_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set @@ -1191,6 +1263,7 @@ CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE=y CONFIG_EARLY_PRINTK=y CONFIG_CPLB_INFO=y CONFIG_ACCESS_CHECK=y +# CONFIG_BFIN_ISRAM_SELF_TEST is not set # # Security options @@ -1199,14 +1272,14 @@ CONFIG_ACCESS_CHECK=y CONFIG_SECURITY=y # CONFIG_SECURITYFS is not set # CONFIG_SECURITY_NETWORK is not set +# CONFIG_SECURITY_PATH is not set # CONFIG_SECURITY_FILE_CAPABILITIES is not set -CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0 +# CONFIG_SECURITY_TOMOYO is not set CONFIG_CRYPTO=y # # Crypto core or helper # -# CONFIG_CRYPTO_FIPS is not set # CONFIG_CRYPTO_MANAGER is not set # CONFIG_CRYPTO_MANAGER2 is not set # CONFIG_CRYPTO_GF128MUL is not set @@ -1238,11 +1311,13 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_HMAC is not set # CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set # # Digest # # CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set # CONFIG_CRYPTO_MD4 is not set # CONFIG_CRYPTO_MD5 is not set # CONFIG_CRYPTO_MICHAEL_MIC is not set @@ -1279,6 +1354,7 @@ CONFIG_CRYPTO=y # Compression # # CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set # CONFIG_CRYPTO_LZO is not set # @@ -1286,11 +1362,13 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set # # Library routines # CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y CONFIG_CRC_CCITT=m # CONFIG_CRC16 is not set # CONFIG_CRC_T10DIF is not set @@ -1299,6 +1377,8 @@ CONFIG_CRC32=y # CONFIG_CRC7 is not set # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y +CONFIG_DECOMPRESS_GZIP=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff --git a/arch/blackfin/configs/BF526-EZBRD_defconfig b/arch/blackfin/configs/BF526-EZBRD_defconfig index 075e0fd..31c2a6d 100644 --- a/arch/blackfin/configs/BF526-EZBRD_defconfig +++ b/arch/blackfin/configs/BF526-EZBRD_defconfig @@ -1,22 +1,27 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.28.10 -# Thu May 21 05:50:01 2009 +# Linux kernel version: 2.6.32.2 # # CONFIG_MMU is not set # CONFIG_FPU is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_BLACKFIN=y +CONFIG_GENERIC_CSUM=y +CONFIG_GENERIC_BUG=y CONFIG_ZONE_DMA=y CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y CONFIG_GENERIC_GPIO=y CONFIG_FORCE_MAX_ZONEORDER=14 CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y # # General setup @@ -26,22 +31,41 @@ CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_BZIP2=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set # CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set # CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set # CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -62,6 +86,10 @@ CONFIG_EPOLL=y # CONFIG_TIMERFD is not set # CONFIG_EVENTFD is not set # CONFIG_AIO is not set + +# +# Kernel Performance Events And Counters +# CONFIG_VM_EVENT_COUNTERS=y CONFIG_COMPAT_BRK=y CONFIG_SLAB=y @@ -69,11 +97,15 @@ CONFIG_SLAB=y # CONFIG_SLOB is not set CONFIG_MMAP_ALLOW_UNINITIALIZED=y # CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +# CONFIG_SLOW_WORK is not set # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set CONFIG_SLABINFO=y -CONFIG_TINY_SHMEM=y CONFIG_BASE_SMALL=0 CONFIG_MODULES=y # CONFIG_MODULE_FORCE_LOAD is not set @@ -81,11 +113,8 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set +# CONFIG_LBDAF is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -101,7 +130,6 @@ CONFIG_IOSCHED_NOOP=y # CONFIG_DEFAULT_CFQ is not set CONFIG_DEFAULT_NOOP=y CONFIG_DEFAULT_IOSCHED="noop" -CONFIG_CLASSIC_RCU=y # CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set @@ -132,15 +160,15 @@ CONFIG_BF526=y # CONFIG_BF537 is not set # CONFIG_BF538 is not set # CONFIG_BF539 is not set -# CONFIG_BF542 is not set +# CONFIG_BF542_std is not set # CONFIG_BF542M is not set -# CONFIG_BF544 is not set +# CONFIG_BF544_std is not set # CONFIG_BF544M is not set -# CONFIG_BF547 is not set +# CONFIG_BF547_std is not set # CONFIG_BF547M is not set -# CONFIG_BF548 is not set +# CONFIG_BF548_std is not set # CONFIG_BF548M is not set -# CONFIG_BF549 is not set +# CONFIG_BF549_std is not set # CONFIG_BF549M is not set # CONFIG_BF561 is not set CONFIG_BF_REV_MIN=0 @@ -154,8 +182,7 @@ CONFIG_BF_REV_0_0=y # CONFIG_BF_REV_0_6 is not set # CONFIG_BF_REV_ANY is not set # CONFIG_BF_REV_NONE is not set -CONFIG_BF52x=y -CONFIG_MEM_MT48LC32M16A2TG_75=y +CONFIG_MEM_MT48H32M16LFCJ_75=y CONFIG_IRQ_PLL_WAKEUP=7 CONFIG_IRQ_DMA0_ERROR=7 CONFIG_IRQ_DMAR0_BLK=7 @@ -200,7 +227,9 @@ CONFIG_IRQ_MEM_DMA1=13 CONFIG_IRQ_WATCH=13 CONFIG_IRQ_PORTF_INTA=13 CONFIG_IRQ_PORTF_INTB=13 +CONFIG_BF52x=y # CONFIG_BFIN527_EZKIT is not set +# CONFIG_BFIN527_EZKIT_V2 is not set # CONFIG_BFIN527_BLUETECHNIX_CM is not set CONFIG_BFIN526_EZBRD=y @@ -318,7 +347,6 @@ CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_VIRT_TO_BUS=y @@ -327,16 +355,18 @@ CONFIG_BFIN_GPTIMERS=m # CONFIG_DMA_UNCACHED_4M is not set # CONFIG_DMA_UNCACHED_2M is not set CONFIG_DMA_UNCACHED_1M=y +# CONFIG_DMA_UNCACHED_512K is not set +# CONFIG_DMA_UNCACHED_256K is not set +# CONFIG_DMA_UNCACHED_128K is not set # CONFIG_DMA_UNCACHED_NONE is not set # # Cache Support # CONFIG_BFIN_ICACHE=y -# CONFIG_BFIN_ICACHE_LOCK is not set +CONFIG_BFIN_EXTMEM_ICACHEABLE=y CONFIG_BFIN_DCACHE=y # CONFIG_BFIN_DCACHE_BANKA is not set -CONFIG_BFIN_EXTMEM_ICACHEABLE=y CONFIG_BFIN_EXTMEM_DCACHEABLE=y CONFIG_BFIN_EXTMEM_WRITEBACK=y # CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set @@ -347,6 +377,10 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y # CONFIG_MPU is not set # +# Asynchronous Memory Configuration +# + +# # EBIU_AMGCTL Global Control # CONFIG_C_AMCKEN=y @@ -399,11 +433,6 @@ CONFIG_NET=y CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -427,7 +456,6 @@ CONFIG_IP_PNP=y # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set -CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" @@ -438,6 +466,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_NETFILTER is not set # CONFIG_IP_DCCP is not set # CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -451,7 +480,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_LAPB is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set # CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set # # Network testing @@ -462,13 +494,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set -# CONFIG_PHONET is not set -CONFIG_WIRELESS=y -# CONFIG_CFG80211 is not set -CONFIG_WIRELESS_OLD_REGULATORY=y -# CONFIG_WIRELESS_EXT is not set -# CONFIG_MAC80211 is not set -# CONFIG_IEEE80211 is not set +# CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -489,6 +516,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_CONNECTOR is not set CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set # CONFIG_MTD_CONCAT is not set CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_REDBOOT_PARTS is not set @@ -549,6 +577,7 @@ CONFIG_MTD_PHYSMAP=y # CONFIG_MTD_DATAFLASH is not set CONFIG_MTD_M25P80=y CONFIG_M25PXX_USE_FAST_READ=y +# CONFIG_MTD_SST25L is not set # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set @@ -564,11 +593,6 @@ CONFIG_MTD_NAND=m # CONFIG_MTD_NAND_VERIFY_WRITE is not set # CONFIG_MTD_NAND_ECC_SMC is not set # CONFIG_MTD_NAND_MUSEUM_IDS is not set -CONFIG_MTD_NAND_BFIN=m -CONFIG_BFIN_NAND_BASE=0x20212000 -CONFIG_BFIN_NAND_CLE=2 -CONFIG_BFIN_NAND_ALE=1 -CONFIG_BFIN_NAND_READY=3 CONFIG_MTD_NAND_IDS=m # CONFIG_MTD_NAND_BF5XX is not set # CONFIG_MTD_NAND_DISKONCHIP is not set @@ -578,6 +602,11 @@ CONFIG_MTD_NAND_IDS=m # CONFIG_MTD_ONENAND is not set # +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# # UBI - Unsorted block images # # CONFIG_MTD_UBI is not set @@ -595,10 +624,20 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 # CONFIG_ATA_OVER_ETH is not set # CONFIG_BLK_DEV_HD is not set CONFIG_MISC_DEVICES=y -# CONFIG_EEPROM_93CX6 is not set +# CONFIG_AD525X_DPOT is not set # CONFIG_ICS932S401 is not set # CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_ISL29003 is not set # CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EEPROM_93CX6 is not set CONFIG_HAVE_IDE=y # CONFIG_IDE is not set @@ -622,10 +661,6 @@ CONFIG_BLK_DEV_SR=m # CONFIG_BLK_DEV_SR_VENDOR is not set # CONFIG_CHR_DEV_SG is not set # CONFIG_CHR_DEV_SCH is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# # CONFIG_SCSI_MULTI_LUN is not set # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set @@ -642,6 +677,7 @@ CONFIG_SCSI_WAIT_SCAN=m # CONFIG_SCSI_SRP_ATTRS is not set # CONFIG_SCSI_LOWLEVEL is not set # CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set # CONFIG_ATA is not set # CONFIG_MD is not set CONFIG_NETDEVICES=y @@ -666,6 +702,9 @@ CONFIG_PHYLIB=y # CONFIG_BROADCOM_PHY is not set # CONFIG_ICPLUS_PHY is not set # CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set # CONFIG_FIXED_PHY is not set # CONFIG_MDIO_BITBANG is not set CONFIG_NET_ETHERNET=y @@ -675,9 +714,12 @@ CONFIG_BFIN_TX_DESC_NUM=10 CONFIG_BFIN_RX_DESC_NUM=20 CONFIG_BFIN_MAC_RMII=y # CONFIG_SMC91X is not set -# CONFIG_SMSC911X is not set # CONFIG_DM9000 is not set # CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set +# CONFIG_ADF702X is not set # CONFIG_IBM_NEW_EMAC_ZMII is not set # CONFIG_IBM_NEW_EMAC_RGMII is not set # CONFIG_IBM_NEW_EMAC_TAH is not set @@ -686,15 +728,16 @@ CONFIG_BFIN_MAC_RMII=y # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set +# CONFIG_WLAN is not set # -# Wireless LAN +# Enable WiMAX (Networking options) to see the WiMAX drivers # -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set -# CONFIG_IWLWIFI_LEDS is not set # # USB Network Adapters @@ -744,7 +787,11 @@ CONFIG_INPUT_MISC=y # CONFIG_INPUT_YEALINK is not set # CONFIG_INPUT_CM109 is not set # CONFIG_INPUT_UINPUT is not set -# CONFIG_CONFIG_INPUT_PCF8574 is not set +# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set +# CONFIG_INPUT_BFIN_ROTARY is not set +# CONFIG_INPUT_AD714X is not set +# CONFIG_INPUT_ADXL34X is not set +# CONFIG_INPUT_PCF8574 is not set # # Hardware I/O ports @@ -755,16 +802,13 @@ CONFIG_INPUT_MISC=y # # Character devices # -# CONFIG_AD9960 is not set CONFIG_BFIN_DMA_INTERFACE=m # CONFIG_BFIN_PPI is not set # CONFIG_BFIN_PPIFCD is not set # CONFIG_BFIN_SIMPLE_TIMER is not set # CONFIG_BFIN_SPI_ADC is not set # CONFIG_BFIN_SPORT is not set -# CONFIG_BFIN_TIMER_LATENCY is not set # CONFIG_BFIN_TWI_LCD is not set -CONFIG_SIMPLE_GPIO=m CONFIG_VT=y CONFIG_CONSOLE_TRANSLATIONS=y CONFIG_VT_CONSOLE=y @@ -782,6 +826,7 @@ CONFIG_BFIN_JTAG_COMM=m # # Non-8250 serial port support # +# CONFIG_SERIAL_MAX3100 is not set CONFIG_SERIAL_BFIN=y CONFIG_SERIAL_BFIN_CONSOLE=y CONFIG_SERIAL_BFIN_DMA=y @@ -793,14 +838,10 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_BFIN_SPORT is not set CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set CONFIG_BFIN_OTP=y # CONFIG_BFIN_OTP_WRITE_ENABLE is not set - -# -# CAN, the car bus and industrial fieldbus -# -# CONFIG_CAN4LINUX is not set # CONFIG_IPMI_HANDLER is not set # CONFIG_HW_RANDOM is not set # CONFIG_R3964 is not set @@ -808,6 +849,7 @@ CONFIG_BFIN_OTP=y # CONFIG_TCG_TPM is not set CONFIG_I2C=y CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y CONFIG_I2C_CHARDEV=m CONFIG_I2C_HELPER_AUTO=y @@ -841,14 +883,6 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100 # Miscellaneous I2C Chip support # # CONFIG_DS1682 is not set -# CONFIG_EEPROM_AT24 is not set -# CONFIG_SENSORS_AD5252 is not set -# CONFIG_EEPROM_LEGACY is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_PCF8575 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_MAX6875 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set @@ -865,13 +899,18 @@ CONFIG_SPI_BFIN=y # CONFIG_SPI_BFIN_LOCK is not set # CONFIG_SPI_BFIN_SPORT is not set # CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set # # SPI Protocol Masters # -# CONFIG_EEPROM_AT25 is not set # CONFIG_SPI_SPIDEV is not set # CONFIG_SPI_TLE62X0 is not set + +# +# PPS support +# +# CONFIG_PPS is not set CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y CONFIG_GPIOLIB=y # CONFIG_DEBUG_GPIO is not set @@ -887,6 +926,7 @@ CONFIG_GPIO_SYSFS=y # CONFIG_GPIO_MAX732X is not set # CONFIG_GPIO_PCA953X is not set # CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_ADP5588 is not set # # PCI GPIO expanders: @@ -897,11 +937,20 @@ CONFIG_GPIO_SYSFS=y # # CONFIG_GPIO_MAX7301 is not set # CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set + +# +# AC97 GPIO expanders: +# # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set CONFIG_HWMON=y # CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_AD5252 is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Native drivers +# # CONFIG_SENSORS_AD7414 is not set # CONFIG_SENSORS_AD7418 is not set # CONFIG_SENSORS_ADCXX is not set @@ -914,11 +963,13 @@ CONFIG_HWMON=y # CONFIG_SENSORS_ADT7462 is not set # CONFIG_SENSORS_ADT7470 is not set # CONFIG_SENSORS_ADT7473 is not set +# CONFIG_SENSORS_ADT7475 is not set # CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS1621 is not set # CONFIG_SENSORS_F71805F is not set # CONFIG_SENSORS_F71882FG is not set # CONFIG_SENSORS_F75375S is not set +# CONFIG_SENSORS_G760A is not set # CONFIG_SENSORS_GL518SM is not set # CONFIG_SENSORS_GL520SM is not set # CONFIG_SENSORS_IT87 is not set @@ -934,17 +985,24 @@ CONFIG_HWMON=y # CONFIG_SENSORS_LM90 is not set # CONFIG_SENSORS_LM92 is not set # CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_LTC4215 is not set +# CONFIG_SENSORS_LTC4245 is not set +# CONFIG_SENSORS_LM95241 is not set # CONFIG_SENSORS_MAX1111 is not set # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_MAX6650 is not set # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_SHT15 is not set # CONFIG_SENSORS_DME1737 is not set # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_SMSC47M192 is not set # CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_ADS7828 is not set # CONFIG_SENSORS_THMC50 is not set +# CONFIG_SENSORS_TMP401 is not set +# CONFIG_SENSORS_TMP421 is not set # CONFIG_SENSORS_VT1211 is not set # CONFIG_SENSORS_W83781D is not set # CONFIG_SENSORS_W83791D is not set @@ -954,9 +1012,8 @@ CONFIG_HWMON=y # CONFIG_SENSORS_W83L786NG is not set # CONFIG_SENSORS_W83627HF is not set # CONFIG_SENSORS_W83627EHF is not set -# CONFIG_HWMON_DEBUG_CHIP is not set +# CONFIG_SENSORS_LIS3_SPI is not set # CONFIG_THERMAL is not set -# CONFIG_THERMAL_HWMON is not set CONFIG_WATCHDOG=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -983,28 +1040,20 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set # CONFIG_HTC_PASIC3 is not set +# CONFIG_TPS65010 is not set +# CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set # CONFIG_PMIC_ADP5520 is not set # CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13783 is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_EZX_PCAP is not set # CONFIG_REGULATOR is not set - -# -# Multimedia devices -# - -# -# Multimedia core support -# -# CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -# CONFIG_VIDEO_MEDIA is not set - -# -# Multimedia drivers -# -# CONFIG_DAB is not set +# CONFIG_MEDIA_SUPPORT is not set # # Graphics support @@ -1026,7 +1075,6 @@ CONFIG_DUMMY_CONSOLE=y # CONFIG_SOUND is not set CONFIG_HID_SUPPORT=y CONFIG_HID=y -# CONFIG_HID_DEBUG is not set # CONFIG_HIDRAW is not set # @@ -1039,30 +1087,35 @@ CONFIG_USB_HID=y # # Special HID drivers # -CONFIG_HID_COMPAT=y CONFIG_HID_A4TECH=y CONFIG_HID_APPLE=y CONFIG_HID_BELKIN=y -CONFIG_HID_BRIGHT=y CONFIG_HID_CHERRY=y CONFIG_HID_CHICONY=y CONFIG_HID_CYPRESS=y -CONFIG_HID_DELL=y +# CONFIG_HID_DRAGONRISE is not set CONFIG_HID_EZKEY=y +# CONFIG_HID_KYE is not set CONFIG_HID_GYRATION=y +# CONFIG_HID_TWINHAN is not set +# CONFIG_HID_KENSINGTON is not set CONFIG_HID_LOGITECH=y # CONFIG_LOGITECH_FF is not set # CONFIG_LOGIRUMBLEPAD2_FF is not set CONFIG_HID_MICROSOFT=y CONFIG_HID_MONTEREY=y +# CONFIG_HID_NTRIG is not set CONFIG_HID_PANTHERLORD=y # CONFIG_PANTHERLORD_FF is not set CONFIG_HID_PETALYNX=y CONFIG_HID_SAMSUNG=y CONFIG_HID_SONY=y CONFIG_HID_SUNPLUS=y -CONFIG_THRUSTMASTER_FF=m -CONFIG_ZEROPLUS_FF=m +# CONFIG_HID_GREENASIA is not set +# CONFIG_HID_SMARTJOYPLUS is not set +# CONFIG_HID_TOPSEED is not set +# CONFIG_HID_THRUSTMASTER is not set +# CONFIG_HID_ZEROPLUS is not set CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y # CONFIG_USB_ARCH_HAS_OHCI is not set @@ -1088,6 +1141,7 @@ CONFIG_USB_MON=y # USB Host Controller Drivers # # CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_OXU210HP_HCD is not set # CONFIG_USB_ISP116X_HCD is not set # CONFIG_USB_ISP1760_HCD is not set # CONFIG_USB_ISP1362_HCD is not set @@ -1118,18 +1172,17 @@ CONFIG_USB_INVENTRA_DMA=y # CONFIG_USB_TMC is not set # -# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may # # -# see USB_STORAGE Help for more information +# also be needed; see USB_STORAGE Help for more info # CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_DEBUG is not set # CONFIG_USB_STORAGE_DATAFAB is not set # CONFIG_USB_STORAGE_FREECOM is not set # CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set # CONFIG_USB_STORAGE_USBAT is not set # CONFIG_USB_STORAGE_SDDR09 is not set # CONFIG_USB_STORAGE_SDDR55 is not set @@ -1165,7 +1218,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGET is not set # CONFIG_USB_IDMOUSE is not set # CONFIG_USB_FTDI_ELAN is not set # CONFIG_USB_APPLEDISPLAY is not set @@ -1177,6 +1229,13 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_ISIGHTFW is not set # CONFIG_USB_VST is not set # CONFIG_USB_GADGET is not set + +# +# OTG and related infrastructure +# +CONFIG_USB_OTG_UTILS=y +# CONFIG_USB_GPIO_VBUS is not set +CONFIG_NOP_USB_XCEIV=y # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set @@ -1212,6 +1271,7 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_S35390A is not set # CONFIG_RTC_DRV_FM3130 is not set # CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set # # SPI RTC drivers @@ -1223,6 +1283,7 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_R9701 is not set # CONFIG_RTC_DRV_RS5C348 is not set # CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set # # Platform RTC drivers @@ -1243,10 +1304,21 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_BFIN=y # CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set # CONFIG_UIO is not set + +# +# TI VLYNQ +# # CONFIG_STAGING is not set # +# Firmware Drivers +# +# CONFIG_FIRMWARE_MEMMAP is not set +# CONFIG_SIGMA is not set + +# # File systems # CONFIG_EXT2_FS=m @@ -1256,9 +1328,13 @@ CONFIG_EXT2_FS=m # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set -CONFIG_FILE_LOCKING=y # CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y # CONFIG_DNOTIFY is not set CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y @@ -1268,6 +1344,11 @@ CONFIG_INOTIFY_USER=y # CONFIG_FUSE_FS is not set # +# Caches +# +# CONFIG_FSCACHE is not set + +# # CD-ROM/DVD Filesystems # CONFIG_ISO9660_FS=m @@ -1291,13 +1372,9 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" CONFIG_PROC_FS=y CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y -# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set # CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# +CONFIG_MISC_FILESYSTEMS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set @@ -1316,17 +1393,8 @@ CONFIG_JFFS2_ZLIB=y # CONFIG_JFFS2_LZO is not set CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set -CONFIG_YAFFS_FS=m -CONFIG_YAFFS_YAFFS1=y -# CONFIG_YAFFS_9BYTE_TAGS is not set -# CONFIG_YAFFS_DOES_ECC is not set -CONFIG_YAFFS_YAFFS2=y -CONFIG_YAFFS_AUTO_YAFFS2=y -# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set -# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set -# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set -CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y # CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_OMFS_FS is not set @@ -1345,7 +1413,6 @@ CONFIG_LOCKD=m CONFIG_LOCKD_V4=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=m -# CONFIG_SUNRPC_REGISTER_V4 is not set # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set CONFIG_SMB_FS=m @@ -1360,7 +1427,7 @@ CONFIG_SMB_FS=m # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y -CONFIG_NLS=m +CONFIG_NLS=y CONFIG_NLS_DEFAULT="iso8859-1" CONFIG_NLS_CODEPAGE_437=m # CONFIG_NLS_CODEPAGE_737 is not set @@ -1410,14 +1477,19 @@ CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y CONFIG_FRAME_WARN=1024 # CONFIG_MAGIC_SYSRQ is not set +# CONFIG_STRIP_ASM_SYMS is not set # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_SECTION_MISMATCH=y CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_SHIRQ=y CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set @@ -1425,31 +1497,39 @@ CONFIG_SCHED_DEBUG=y # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y CONFIG_DEBUG_INFO=y # CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_NOMMU_REGIONS is not set # CONFIG_DEBUG_WRITECOUNT is not set # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set # CONFIG_FRAME_POINTER is not set # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set # CONFIG_FAULT_INJECTION is not set - -# -# Tracers -# -# CONFIG_SCHED_TRACER is not set -# CONFIG_CONTEXT_SWITCH_TRACER is not set -# CONFIG_BOOT_TRACER is not set -# CONFIG_DYNAMIC_PRINTK_DEBUG is not set +# CONFIG_PAGE_POISONING is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_BRANCH_PROFILE_NONE is not set +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_DYNAMIC_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set @@ -1474,6 +1554,7 @@ CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE=y CONFIG_EARLY_PRINTK=y CONFIG_CPLB_INFO=y CONFIG_ACCESS_CHECK=y +# CONFIG_BFIN_ISRAM_SELF_TEST is not set # # Security options @@ -1482,15 +1563,15 @@ CONFIG_ACCESS_CHECK=y CONFIG_SECURITY=y # CONFIG_SECURITYFS is not set # CONFIG_SECURITY_NETWORK is not set +# CONFIG_SECURITY_PATH is not set # CONFIG_SECURITY_FILE_CAPABILITIES is not set # CONFIG_SECURITY_ROOTPLUG is not set -CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0 +# CONFIG_SECURITY_TOMOYO is not set CONFIG_CRYPTO=y # # Crypto core or helper # -# CONFIG_CRYPTO_FIPS is not set # CONFIG_CRYPTO_MANAGER is not set # CONFIG_CRYPTO_MANAGER2 is not set # CONFIG_CRYPTO_GF128MUL is not set @@ -1522,11 +1603,13 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_HMAC is not set # CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set # # Digest # # CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set # CONFIG_CRYPTO_MD4 is not set # CONFIG_CRYPTO_MD5 is not set # CONFIG_CRYPTO_MICHAEL_MIC is not set @@ -1563,6 +1646,7 @@ CONFIG_CRYPTO=y # Compression # # CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set # CONFIG_CRYPTO_LZO is not set # @@ -1570,11 +1654,13 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set # # Library routines # CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y CONFIG_CRC_CCITT=m # CONFIG_CRC16 is not set # CONFIG_CRC_T10DIF is not set @@ -1584,6 +1670,8 @@ CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=m +CONFIG_DECOMPRESS_GZIP=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff --git a/arch/blackfin/configs/BF527-EZKIT_defconfig b/arch/blackfin/configs/BF527-EZKIT_defconfig index 6d1a623..edbb44d 100644 --- a/arch/blackfin/configs/BF527-EZKIT_defconfig +++ b/arch/blackfin/configs/BF527-EZKIT_defconfig @@ -1,22 +1,27 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.28.10 -# Thu May 21 05:50:01 2009 +# Linux kernel version: 2.6.32.2 # # CONFIG_MMU is not set # CONFIG_FPU is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_BLACKFIN=y +CONFIG_GENERIC_CSUM=y +CONFIG_GENERIC_BUG=y CONFIG_ZONE_DMA=y CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y CONFIG_GENERIC_GPIO=y CONFIG_FORCE_MAX_ZONEORDER=14 CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y # # General setup @@ -26,22 +31,41 @@ CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_BZIP2=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set # CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set # CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set # CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -62,6 +86,10 @@ CONFIG_EPOLL=y # CONFIG_TIMERFD is not set # CONFIG_EVENTFD is not set # CONFIG_AIO is not set + +# +# Kernel Performance Events And Counters +# CONFIG_VM_EVENT_COUNTERS=y CONFIG_COMPAT_BRK=y CONFIG_SLAB=y @@ -69,11 +97,15 @@ CONFIG_SLAB=y # CONFIG_SLOB is not set CONFIG_MMAP_ALLOW_UNINITIALIZED=y # CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +# CONFIG_SLOW_WORK is not set # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set CONFIG_SLABINFO=y -CONFIG_TINY_SHMEM=y CONFIG_BASE_SMALL=0 CONFIG_MODULES=y # CONFIG_MODULE_FORCE_LOAD is not set @@ -81,11 +113,8 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set +# CONFIG_LBDAF is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -101,7 +130,6 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" -CONFIG_CLASSIC_RCU=y # CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set @@ -132,29 +160,28 @@ CONFIG_BF527=y # CONFIG_BF537 is not set # CONFIG_BF538 is not set # CONFIG_BF539 is not set -# CONFIG_BF542 is not set +# CONFIG_BF542_std is not set # CONFIG_BF542M is not set -# CONFIG_BF544 is not set +# CONFIG_BF544_std is not set # CONFIG_BF544M is not set -# CONFIG_BF547 is not set +# CONFIG_BF547_std is not set # CONFIG_BF547M is not set -# CONFIG_BF548 is not set +# CONFIG_BF548_std is not set # CONFIG_BF548M is not set -# CONFIG_BF549 is not set +# CONFIG_BF549_std is not set # CONFIG_BF549M is not set # CONFIG_BF561 is not set CONFIG_BF_REV_MIN=0 CONFIG_BF_REV_MAX=2 # CONFIG_BF_REV_0_0 is not set -# CONFIG_BF_REV_0_1 is not set -CONFIG_BF_REV_0_2=y +CONFIG_BF_REV_0_1=y +# CONFIG_BF_REV_0_2 is not set # CONFIG_BF_REV_0_3 is not set # CONFIG_BF_REV_0_4 is not set # CONFIG_BF_REV_0_5 is not set # CONFIG_BF_REV_0_6 is not set # CONFIG_BF_REV_ANY is not set # CONFIG_BF_REV_NONE is not set -CONFIG_BF52x=y CONFIG_MEM_MT48LC32M16A2TG_75=y CONFIG_IRQ_PLL_WAKEUP=7 CONFIG_IRQ_DMA0_ERROR=7 @@ -200,7 +227,9 @@ CONFIG_IRQ_MEM_DMA1=13 CONFIG_IRQ_WATCH=13 CONFIG_IRQ_PORTF_INTA=13 CONFIG_IRQ_PORTF_INTB=13 +CONFIG_BF52x=y CONFIG_BFIN527_EZKIT=y +# CONFIG_BFIN527_EZKIT_V2 is not set # CONFIG_BFIN527_BLUETECHNIX_CM is not set # CONFIG_BFIN526_EZBRD is not set @@ -318,7 +347,6 @@ CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_VIRT_TO_BUS=y @@ -327,16 +355,18 @@ CONFIG_BFIN_GPTIMERS=y # CONFIG_DMA_UNCACHED_4M is not set # CONFIG_DMA_UNCACHED_2M is not set CONFIG_DMA_UNCACHED_1M=y +# CONFIG_DMA_UNCACHED_512K is not set +# CONFIG_DMA_UNCACHED_256K is not set +# CONFIG_DMA_UNCACHED_128K is not set # CONFIG_DMA_UNCACHED_NONE is not set # # Cache Support # CONFIG_BFIN_ICACHE=y -# CONFIG_BFIN_ICACHE_LOCK is not set +CONFIG_BFIN_EXTMEM_ICACHEABLE=y CONFIG_BFIN_DCACHE=y # CONFIG_BFIN_DCACHE_BANKA is not set -CONFIG_BFIN_EXTMEM_ICACHEABLE=y CONFIG_BFIN_EXTMEM_DCACHEABLE=y CONFIG_BFIN_EXTMEM_WRITEBACK=y # CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set @@ -347,7 +377,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y # CONFIG_MPU is not set # -# Asynchonous Memory Configuration +# Asynchronous Memory Configuration # # @@ -403,11 +433,6 @@ CONFIG_NET=y CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -431,7 +456,6 @@ CONFIG_IP_PNP=y # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set -CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" @@ -442,6 +466,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_NETFILTER is not set # CONFIG_IP_DCCP is not set # CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -455,7 +480,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_LAPB is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set # CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set # # Network testing @@ -508,13 +536,8 @@ CONFIG_SIR_BFIN_DMA=y # CONFIG_MCS_FIR is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set -# CONFIG_PHONET is not set -CONFIG_WIRELESS=y -# CONFIG_CFG80211 is not set -CONFIG_WIRELESS_OLD_REGULATORY=y -# CONFIG_WIRELESS_EXT is not set -# CONFIG_MAC80211 is not set -# CONFIG_IEEE80211 is not set +# CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -535,6 +558,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_CONNECTOR is not set CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set # CONFIG_MTD_CONCAT is not set CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_REDBOOT_PARTS is not set @@ -593,6 +617,7 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y # CONFIG_MTD_DATAFLASH is not set CONFIG_MTD_M25P80=y CONFIG_M25PXX_USE_FAST_READ=y +# CONFIG_MTD_SST25L is not set # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set @@ -608,11 +633,6 @@ CONFIG_MTD_NAND=m # CONFIG_MTD_NAND_VERIFY_WRITE is not set # CONFIG_MTD_NAND_ECC_SMC is not set # CONFIG_MTD_NAND_MUSEUM_IDS is not set -CONFIG_MTD_NAND_BFIN=m -CONFIG_BFIN_NAND_BASE=0x20212000 -CONFIG_BFIN_NAND_CLE=2 -CONFIG_BFIN_NAND_ALE=1 -CONFIG_BFIN_NAND_READY=3 CONFIG_MTD_NAND_IDS=m # CONFIG_MTD_NAND_BF5XX is not set # CONFIG_MTD_NAND_DISKONCHIP is not set @@ -622,6 +642,11 @@ CONFIG_MTD_NAND_IDS=m # CONFIG_MTD_ONENAND is not set # +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# # UBI - Unsorted block images # # CONFIG_MTD_UBI is not set @@ -639,10 +664,20 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 # CONFIG_ATA_OVER_ETH is not set # CONFIG_BLK_DEV_HD is not set CONFIG_MISC_DEVICES=y -# CONFIG_EEPROM_93CX6 is not set +# CONFIG_AD525X_DPOT is not set # CONFIG_ICS932S401 is not set # CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_ISL29003 is not set # CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EEPROM_93CX6 is not set CONFIG_HAVE_IDE=y # CONFIG_IDE is not set @@ -666,10 +701,6 @@ CONFIG_BLK_DEV_SR=m # CONFIG_BLK_DEV_SR_VENDOR is not set # CONFIG_CHR_DEV_SG is not set # CONFIG_CHR_DEV_SCH is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# # CONFIG_SCSI_MULTI_LUN is not set # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set @@ -686,6 +717,7 @@ CONFIG_SCSI_WAIT_SCAN=m # CONFIG_SCSI_SRP_ATTRS is not set # CONFIG_SCSI_LOWLEVEL is not set # CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set # CONFIG_ATA is not set # CONFIG_MD is not set CONFIG_NETDEVICES=y @@ -710,6 +742,9 @@ CONFIG_PHYLIB=y # CONFIG_BROADCOM_PHY is not set # CONFIG_ICPLUS_PHY is not set # CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set # CONFIG_FIXED_PHY is not set # CONFIG_MDIO_BITBANG is not set CONFIG_NET_ETHERNET=y @@ -720,9 +755,12 @@ CONFIG_BFIN_TX_DESC_NUM=10 CONFIG_BFIN_RX_DESC_NUM=20 CONFIG_BFIN_MAC_RMII=y # CONFIG_SMC91X is not set -# CONFIG_SMSC911X is not set # CONFIG_DM9000 is not set # CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set +# CONFIG_ADF702X is not set # CONFIG_IBM_NEW_EMAC_ZMII is not set # CONFIG_IBM_NEW_EMAC_RGMII is not set # CONFIG_IBM_NEW_EMAC_TAH is not set @@ -731,15 +769,16 @@ CONFIG_BFIN_MAC_RMII=y # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set +# CONFIG_WLAN is not set # -# Wireless LAN +# Enable WiMAX (Networking options) to see the WiMAX drivers # -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set -# CONFIG_IWLWIFI_LEDS is not set # # USB Network Adapters @@ -789,7 +828,11 @@ CONFIG_INPUT_MISC=y # CONFIG_INPUT_YEALINK is not set # CONFIG_INPUT_CM109 is not set # CONFIG_INPUT_UINPUT is not set -# CONFIG_CONFIG_INPUT_PCF8574 is not set +# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set +# CONFIG_INPUT_BFIN_ROTARY is not set +# CONFIG_INPUT_AD714X is not set +# CONFIG_INPUT_ADXL34X is not set +# CONFIG_INPUT_PCF8574 is not set # # Hardware I/O ports @@ -800,16 +843,13 @@ CONFIG_INPUT_MISC=y # # Character devices # -# CONFIG_AD9960 is not set CONFIG_BFIN_DMA_INTERFACE=m # CONFIG_BFIN_PPI is not set # CONFIG_BFIN_PPIFCD is not set # CONFIG_BFIN_SIMPLE_TIMER is not set # CONFIG_BFIN_SPI_ADC is not set CONFIG_BFIN_SPORT=m -# CONFIG_BFIN_TIMER_LATENCY is not set # CONFIG_BFIN_TWI_LCD is not set -CONFIG_SIMPLE_GPIO=m CONFIG_VT=y CONFIG_CONSOLE_TRANSLATIONS=y CONFIG_VT_CONSOLE=y @@ -827,6 +867,7 @@ CONFIG_BFIN_JTAG_COMM=m # # Non-8250 serial port support # +# CONFIG_SERIAL_MAX3100 is not set CONFIG_SERIAL_BFIN=y CONFIG_SERIAL_BFIN_CONSOLE=y CONFIG_SERIAL_BFIN_DMA=y @@ -838,14 +879,10 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_BFIN_SPORT is not set CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set CONFIG_BFIN_OTP=y # CONFIG_BFIN_OTP_WRITE_ENABLE is not set - -# -# CAN, the car bus and industrial fieldbus -# -# CONFIG_CAN4LINUX is not set # CONFIG_IPMI_HANDLER is not set # CONFIG_HW_RANDOM is not set # CONFIG_R3964 is not set @@ -853,6 +890,7 @@ CONFIG_BFIN_OTP=y # CONFIG_TCG_TPM is not set CONFIG_I2C=y CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y CONFIG_I2C_CHARDEV=m CONFIG_I2C_HELPER_AUTO=y @@ -886,14 +924,6 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100 # Miscellaneous I2C Chip support # # CONFIG_DS1682 is not set -# CONFIG_EEPROM_AT24 is not set -# CONFIG_SENSORS_AD5252 is not set -# CONFIG_EEPROM_LEGACY is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_PCF8575 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_MAX6875 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set @@ -910,13 +940,18 @@ CONFIG_SPI_BFIN=y # CONFIG_SPI_BFIN_LOCK is not set # CONFIG_SPI_BFIN_SPORT is not set # CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set # # SPI Protocol Masters # -# CONFIG_EEPROM_AT25 is not set # CONFIG_SPI_SPIDEV is not set # CONFIG_SPI_TLE62X0 is not set + +# +# PPS support +# +# CONFIG_PPS is not set CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y CONFIG_GPIOLIB=y # CONFIG_DEBUG_GPIO is not set @@ -932,6 +967,7 @@ CONFIG_GPIO_SYSFS=y # CONFIG_GPIO_MAX732X is not set # CONFIG_GPIO_PCA953X is not set # CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_ADP5588 is not set # # PCI GPIO expanders: @@ -942,11 +978,15 @@ CONFIG_GPIO_SYSFS=y # # CONFIG_GPIO_MAX7301 is not set # CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set + +# +# AC97 GPIO expanders: +# # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set # CONFIG_THERMAL is not set -# CONFIG_THERMAL_HWMON is not set CONFIG_WATCHDOG=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -973,28 +1013,21 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set # CONFIG_HTC_PASIC3 is not set +# CONFIG_UCB1400_CORE is not set +# CONFIG_TPS65010 is not set +# CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set # CONFIG_PMIC_ADP5520 is not set # CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13783 is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_EZX_PCAP is not set # CONFIG_REGULATOR is not set - -# -# Multimedia devices -# - -# -# Multimedia core support -# -# CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -# CONFIG_VIDEO_MEDIA is not set - -# -# Multimedia drivers -# -# CONFIG_DAB is not set +# CONFIG_MEDIA_SUPPORT is not set # # Graphics support @@ -1030,15 +1063,18 @@ CONFIG_FB_BFIN_T350MCQB=y # CONFIG_FB_VIRTUAL is not set # CONFIG_FB_METRONOME is not set # CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_LCD_CLASS_DEVICE=m +# CONFIG_LCD_LMS283GF05 is not set CONFIG_LCD_LTV350QV=m # CONFIG_LCD_ILI9320 is not set # CONFIG_LCD_TDO24M is not set # CONFIG_LCD_VGG2432A4 is not set # CONFIG_LCD_PLATFORM is not set CONFIG_BACKLIGHT_CLASS_DEVICE=m -# CONFIG_BACKLIGHT_CORGI is not set +CONFIG_BACKLIGHT_GENERIC=m +# CONFIG_BACKLIGHT_ADP8870 is not set # # Display device support @@ -1066,6 +1102,7 @@ CONFIG_SOUND=m CONFIG_SND=m CONFIG_SND_TIMER=m CONFIG_SND_PCM=m +CONFIG_SND_JACK=y # CONFIG_SND_SEQUENCER is not set # CONFIG_SND_MIXER_OSS is not set # CONFIG_SND_PCM_OSS is not set @@ -1074,6 +1111,11 @@ CONFIG_SND_SUPPORT_OLD_API=y CONFIG_SND_VERBOSE_PROCFS=y # CONFIG_SND_VERBOSE_PRINTK is not set # CONFIG_SND_DEBUG is not set +# CONFIG_SND_RAWMIDI_SEQ is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set CONFIG_SND_DRIVERS=y # CONFIG_SND_DUMMY is not set # CONFIG_SND_MTPAV is not set @@ -1084,7 +1126,6 @@ CONFIG_SND_SPI=y # # ALSA Blackfin devices # -# CONFIG_SND_BLACKFIN_AD1836 is not set # CONFIG_SND_BFIN_AD73322 is not set CONFIG_SND_USB=y # CONFIG_SND_USB_AUDIO is not set @@ -1094,15 +1135,19 @@ CONFIG_SND_SOC_AC97_BUS=y CONFIG_SND_BF5XX_I2S=m CONFIG_SND_BF5XX_SOC_SSM2602=m # CONFIG_SND_BF5XX_SOC_AD73311 is not set +# CONFIG_SND_BF5XX_SOC_ADAU1371 is not set +# CONFIG_SND_BF5XX_SOC_ADAU1761 is not set +# CONFIG_SND_BF5XX_TDM is not set CONFIG_SND_BF5XX_AC97=m CONFIG_SND_BF5XX_MMAP_SUPPORT=y # CONFIG_SND_BF5XX_MULTICHAN_SUPPORT is not set +# CONFIG_SND_BF5XX_HAVE_COLD_RESET is not set +CONFIG_SND_BF5XX_SOC_AD1980=m CONFIG_SND_BF5XX_SOC_SPORT=m CONFIG_SND_BF5XX_SOC_I2S=m CONFIG_SND_BF5XX_SOC_AC97=m -CONFIG_SND_BF5XX_SOC_AD1980=m CONFIG_SND_BF5XX_SPORT_NUM=0 -# CONFIG_SND_BF5XX_HAVE_COLD_RESET is not set +CONFIG_SND_SOC_I2C_AND_SPI=m # CONFIG_SND_SOC_ALL_CODECS is not set CONFIG_SND_SOC_AD1980=m CONFIG_SND_SOC_SSM2602=m @@ -1110,7 +1155,6 @@ CONFIG_SND_SOC_SSM2602=m CONFIG_AC97_BUS=m CONFIG_HID_SUPPORT=y CONFIG_HID=y -# CONFIG_HID_DEBUG is not set # CONFIG_HIDRAW is not set # @@ -1123,30 +1167,35 @@ CONFIG_USB_HID=y # # Special HID drivers # -CONFIG_HID_COMPAT=y CONFIG_HID_A4TECH=y CONFIG_HID_APPLE=y CONFIG_HID_BELKIN=y -CONFIG_HID_BRIGHT=y CONFIG_HID_CHERRY=y CONFIG_HID_CHICONY=y CONFIG_HID_CYPRESS=y -CONFIG_HID_DELL=y +# CONFIG_HID_DRAGONRISE is not set CONFIG_HID_EZKEY=y +# CONFIG_HID_KYE is not set CONFIG_HID_GYRATION=y +# CONFIG_HID_TWINHAN is not set +# CONFIG_HID_KENSINGTON is not set CONFIG_HID_LOGITECH=y # CONFIG_LOGITECH_FF is not set # CONFIG_LOGIRUMBLEPAD2_FF is not set CONFIG_HID_MICROSOFT=y CONFIG_HID_MONTEREY=y +# CONFIG_HID_NTRIG is not set CONFIG_HID_PANTHERLORD=y # CONFIG_PANTHERLORD_FF is not set CONFIG_HID_PETALYNX=y CONFIG_HID_SAMSUNG=y CONFIG_HID_SONY=y CONFIG_HID_SUNPLUS=y -CONFIG_THRUSTMASTER_FF=m -CONFIG_ZEROPLUS_FF=m +# CONFIG_HID_GREENASIA is not set +# CONFIG_HID_SMARTJOYPLUS is not set +# CONFIG_HID_TOPSEED is not set +# CONFIG_HID_THRUSTMASTER is not set +# CONFIG_HID_ZEROPLUS is not set CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y # CONFIG_USB_ARCH_HAS_OHCI is not set @@ -1172,6 +1221,7 @@ CONFIG_USB_MON=y # USB Host Controller Drivers # # CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_OXU210HP_HCD is not set # CONFIG_USB_ISP116X_HCD is not set # CONFIG_USB_ISP1760_HCD is not set # CONFIG_USB_ISP1362_HCD is not set @@ -1188,9 +1238,7 @@ CONFIG_USB_MUSB_HOST=y # CONFIG_USB_MUSB_PERIPHERAL is not set # CONFIG_USB_MUSB_OTG is not set CONFIG_USB_MUSB_HDRC_HCD=y -# CONFIG_MUSB_PIO_ONLY is not set -CONFIG_USB_INVENTRA_DMA=y -# CONFIG_USB_TI_CPPI_DMA is not set +CONFIG_MUSB_PIO_ONLY=y # CONFIG_USB_MUSB_DEBUG is not set # @@ -1202,18 +1250,17 @@ CONFIG_USB_INVENTRA_DMA=y # CONFIG_USB_TMC is not set # -# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may # # -# see USB_STORAGE Help for more information +# also be needed; see USB_STORAGE Help for more info # CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_DEBUG is not set # CONFIG_USB_STORAGE_DATAFAB is not set # CONFIG_USB_STORAGE_FREECOM is not set # CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set # CONFIG_USB_STORAGE_USBAT is not set # CONFIG_USB_STORAGE_SDDR09 is not set # CONFIG_USB_STORAGE_SDDR55 is not set @@ -1249,7 +1296,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGET is not set # CONFIG_USB_IDMOUSE is not set # CONFIG_USB_FTDI_ELAN is not set # CONFIG_USB_APPLEDISPLAY is not set @@ -1261,6 +1307,13 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_ISIGHTFW is not set # CONFIG_USB_VST is not set # CONFIG_USB_GADGET is not set + +# +# OTG and related infrastructure +# +CONFIG_USB_OTG_UTILS=y +# CONFIG_USB_GPIO_VBUS is not set +CONFIG_NOP_USB_XCEIV=y # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set @@ -1296,6 +1349,7 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_S35390A is not set # CONFIG_RTC_DRV_FM3130 is not set # CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set # # SPI RTC drivers @@ -1307,6 +1361,7 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_R9701 is not set # CONFIG_RTC_DRV_RS5C348 is not set # CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set # # Platform RTC drivers @@ -1327,10 +1382,21 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_BFIN=y # CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set # CONFIG_UIO is not set + +# +# TI VLYNQ +# # CONFIG_STAGING is not set # +# Firmware Drivers +# +# CONFIG_FIRMWARE_MEMMAP is not set +# CONFIG_SIGMA is not set + +# # File systems # CONFIG_EXT2_FS=m @@ -1340,9 +1406,13 @@ CONFIG_EXT2_FS=m # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set -CONFIG_FILE_LOCKING=y # CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y # CONFIG_DNOTIFY is not set CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y @@ -1352,6 +1422,11 @@ CONFIG_INOTIFY_USER=y # CONFIG_FUSE_FS is not set # +# Caches +# +# CONFIG_FSCACHE is not set + +# # CD-ROM/DVD Filesystems # CONFIG_ISO9660_FS=m @@ -1376,13 +1451,9 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" CONFIG_PROC_FS=y CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y -# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set # CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# +CONFIG_MISC_FILESYSTEMS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set @@ -1401,17 +1472,8 @@ CONFIG_JFFS2_ZLIB=y # CONFIG_JFFS2_LZO is not set CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set -CONFIG_YAFFS_FS=m -CONFIG_YAFFS_YAFFS1=y -# CONFIG_YAFFS_9BYTE_TAGS is not set -# CONFIG_YAFFS_DOES_ECC is not set -CONFIG_YAFFS_YAFFS2=y -CONFIG_YAFFS_AUTO_YAFFS2=y -# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set -# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set -# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set -CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y # CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_OMFS_FS is not set @@ -1430,7 +1492,6 @@ CONFIG_LOCKD=m CONFIG_LOCKD_V4=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=m -# CONFIG_SUNRPC_REGISTER_V4 is not set # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set CONFIG_SMB_FS=m @@ -1445,7 +1506,7 @@ CONFIG_SMB_FS=m # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y -CONFIG_NLS=m +CONFIG_NLS=y CONFIG_NLS_DEFAULT="iso8859-1" CONFIG_NLS_CODEPAGE_437=m # CONFIG_NLS_CODEPAGE_737 is not set @@ -1495,14 +1556,19 @@ CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y CONFIG_FRAME_WARN=1024 # CONFIG_MAGIC_SYSRQ is not set +# CONFIG_STRIP_ASM_SYMS is not set # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_SECTION_MISMATCH=y CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_SHIRQ=y CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set @@ -1510,31 +1576,39 @@ CONFIG_SCHED_DEBUG=y # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y CONFIG_DEBUG_INFO=y # CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_NOMMU_REGIONS is not set # CONFIG_DEBUG_WRITECOUNT is not set # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set # CONFIG_FRAME_POINTER is not set # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set # CONFIG_FAULT_INJECTION is not set - -# -# Tracers -# -# CONFIG_SCHED_TRACER is not set -# CONFIG_CONTEXT_SWITCH_TRACER is not set -# CONFIG_BOOT_TRACER is not set -# CONFIG_DYNAMIC_PRINTK_DEBUG is not set +# CONFIG_PAGE_POISONING is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_BRANCH_PROFILE_NONE is not set +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_DYNAMIC_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set @@ -1559,6 +1633,7 @@ CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE=y CONFIG_EARLY_PRINTK=y CONFIG_CPLB_INFO=y CONFIG_ACCESS_CHECK=y +# CONFIG_BFIN_ISRAM_SELF_TEST is not set # # Security options @@ -1567,15 +1642,15 @@ CONFIG_ACCESS_CHECK=y CONFIG_SECURITY=y # CONFIG_SECURITYFS is not set # CONFIG_SECURITY_NETWORK is not set +# CONFIG_SECURITY_PATH is not set # CONFIG_SECURITY_FILE_CAPABILITIES is not set # CONFIG_SECURITY_ROOTPLUG is not set -CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0 +# CONFIG_SECURITY_TOMOYO is not set CONFIG_CRYPTO=y # # Crypto core or helper # -# CONFIG_CRYPTO_FIPS is not set # CONFIG_CRYPTO_MANAGER is not set # CONFIG_CRYPTO_MANAGER2 is not set # CONFIG_CRYPTO_GF128MUL is not set @@ -1607,11 +1682,13 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_HMAC is not set # CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set # # Digest # # CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set # CONFIG_CRYPTO_MD4 is not set # CONFIG_CRYPTO_MD5 is not set # CONFIG_CRYPTO_MICHAEL_MIC is not set @@ -1648,6 +1725,7 @@ CONFIG_CRYPTO=y # Compression # # CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set # CONFIG_CRYPTO_LZO is not set # @@ -1655,11 +1733,13 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set # # Library routines # CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y CONFIG_CRC_CCITT=m # CONFIG_CRC16 is not set # CONFIG_CRC_T10DIF is not set @@ -1669,6 +1749,8 @@ CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=m +CONFIG_DECOMPRESS_GZIP=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff --git a/arch/blackfin/configs/BF533-EZKIT_defconfig b/arch/blackfin/configs/BF533-EZKIT_defconfig index 50f9a23..0b13d58 100644 --- a/arch/blackfin/configs/BF533-EZKIT_defconfig +++ b/arch/blackfin/configs/BF533-EZKIT_defconfig @@ -1,22 +1,27 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.28.10 -# Thu May 21 05:50:01 2009 +# Linux kernel version: 2.6.32.2 # # CONFIG_MMU is not set # CONFIG_FPU is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_BLACKFIN=y +CONFIG_GENERIC_CSUM=y +CONFIG_GENERIC_BUG=y CONFIG_ZONE_DMA=y CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y CONFIG_GENERIC_GPIO=y CONFIG_FORCE_MAX_ZONEORDER=14 CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y # # General setup @@ -26,22 +31,41 @@ CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_BZIP2=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set # CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set # CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set # CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -62,6 +86,10 @@ CONFIG_EPOLL=y # CONFIG_TIMERFD is not set # CONFIG_EVENTFD is not set # CONFIG_AIO is not set + +# +# Kernel Performance Events And Counters +# CONFIG_VM_EVENT_COUNTERS=y CONFIG_COMPAT_BRK=y CONFIG_SLAB=y @@ -69,11 +97,15 @@ CONFIG_SLAB=y # CONFIG_SLOB is not set CONFIG_MMAP_ALLOW_UNINITIALIZED=y # CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +# CONFIG_SLOW_WORK is not set # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set CONFIG_SLABINFO=y -CONFIG_TINY_SHMEM=y CONFIG_BASE_SMALL=0 CONFIG_MODULES=y # CONFIG_MODULE_FORCE_LOAD is not set @@ -81,11 +113,8 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set +# CONFIG_LBDAF is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -101,7 +130,6 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" -CONFIG_CLASSIC_RCU=y # CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set @@ -132,15 +160,15 @@ CONFIG_BF533=y # CONFIG_BF537 is not set # CONFIG_BF538 is not set # CONFIG_BF539 is not set -# CONFIG_BF542 is not set +# CONFIG_BF542_std is not set # CONFIG_BF542M is not set -# CONFIG_BF544 is not set +# CONFIG_BF544_std is not set # CONFIG_BF544M is not set -# CONFIG_BF547 is not set +# CONFIG_BF547_std is not set # CONFIG_BF547M is not set -# CONFIG_BF548 is not set +# CONFIG_BF548_std is not set # CONFIG_BF548M is not set -# CONFIG_BF549 is not set +# CONFIG_BF549_std is not set # CONFIG_BF549M is not set # CONFIG_BF561 is not set CONFIG_BF_REV_MIN=3 @@ -228,7 +256,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y # CONFIG_TICKSOURCE_GPTMR0 is not set CONFIG_TICKSOURCE_CORETMR=y -# CONFIG_CYCLES_CLOCKSOURCE is not set +CONFIG_CYCLES_CLOCKSOURCE=y # CONFIG_GPTMR0_CLOCKSOURCE is not set CONFIG_TICK_ONESHOT=y # CONFIG_NO_HZ is not set @@ -280,7 +308,6 @@ CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_VIRT_TO_BUS=y @@ -289,19 +316,18 @@ CONFIG_BFIN_GPTIMERS=m # CONFIG_DMA_UNCACHED_4M is not set # CONFIG_DMA_UNCACHED_2M is not set CONFIG_DMA_UNCACHED_1M=y +# CONFIG_DMA_UNCACHED_512K is not set +# CONFIG_DMA_UNCACHED_256K is not set +# CONFIG_DMA_UNCACHED_128K is not set # CONFIG_DMA_UNCACHED_NONE is not set # # Cache Support # -# -# Cache Support -# CONFIG_BFIN_ICACHE=y -# CONFIG_BFIN_ICACHE_LOCK is not set +CONFIG_BFIN_EXTMEM_ICACHEABLE=y CONFIG_BFIN_DCACHE=y # CONFIG_BFIN_DCACHE_BANKA is not set -CONFIG_BFIN_EXTMEM_ICACHEABLE=y CONFIG_BFIN_EXTMEM_DCACHEABLE=y CONFIG_BFIN_EXTMEM_WRITEBACK=y # CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set @@ -312,7 +338,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y # CONFIG_MPU is not set # -# Asynchonous Memory Configuration +# Asynchronous Memory Configuration # # @@ -358,6 +384,7 @@ CONFIG_PM=y CONFIG_PM_SLEEP=y CONFIG_SUSPEND=y CONFIG_SUSPEND_FREEZER=y +# CONFIG_PM_RUNTIME is not set CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_PM_BFIN_SLEEP_DEEPER=y # CONFIG_PM_BFIN_SLEEP is not set @@ -379,11 +406,6 @@ CONFIG_NET=y CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -407,7 +429,6 @@ CONFIG_IP_PNP=y # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set -CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" @@ -418,6 +439,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_NETFILTER is not set # CONFIG_IP_DCCP is not set # CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -431,7 +453,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_LAPB is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set # CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set # # Network testing @@ -475,13 +500,8 @@ CONFIG_IRTTY_SIR=m # # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set -# CONFIG_PHONET is not set -CONFIG_WIRELESS=y -# CONFIG_CFG80211 is not set -CONFIG_WIRELESS_OLD_REGULATORY=y -# CONFIG_WIRELESS_EXT is not set -# CONFIG_MAC80211 is not set -# CONFIG_IEEE80211 is not set +# CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -502,6 +522,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_CONNECTOR is not set CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set # CONFIG_MTD_CONCAT is not set CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_REDBOOT_PARTS is not set @@ -559,6 +580,7 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y # # CONFIG_MTD_DATAFLASH is not set # CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SST25L is not set # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set @@ -574,6 +596,11 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y # CONFIG_MTD_ONENAND is not set # +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# # UBI - Unsorted block images # # CONFIG_MTD_UBI is not set @@ -590,9 +617,14 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 # CONFIG_ATA_OVER_ETH is not set # CONFIG_BLK_DEV_HD is not set CONFIG_MISC_DEVICES=y -# CONFIG_EEPROM_93CX6 is not set # CONFIG_ENCLOSURE_SERVICES is not set # CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_93CX6 is not set CONFIG_HAVE_IDE=y # CONFIG_IDE is not set @@ -616,9 +648,12 @@ CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_MII=y CONFIG_SMC91X=y -# CONFIG_SMSC911X is not set # CONFIG_DM9000 is not set # CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set +# CONFIG_ADF702X is not set # CONFIG_IBM_NEW_EMAC_ZMII is not set # CONFIG_IBM_NEW_EMAC_RGMII is not set # CONFIG_IBM_NEW_EMAC_TAH is not set @@ -627,15 +662,16 @@ CONFIG_SMC91X=y # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set +# CONFIG_WLAN is not set # -# Wireless LAN +# Enable WiMAX (Networking options) to see the WiMAX drivers # -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set -# CONFIG_IWLWIFI_LEDS is not set # CONFIG_WAN is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -679,15 +715,12 @@ CONFIG_INPUT_EVDEV=m # # Character devices # -# CONFIG_AD9960 is not set CONFIG_BFIN_DMA_INTERFACE=m # CONFIG_BFIN_PPI is not set # CONFIG_BFIN_PPIFCD is not set # CONFIG_BFIN_SIMPLE_TIMER is not set # CONFIG_BFIN_SPI_ADC is not set CONFIG_BFIN_SPORT=y -# CONFIG_BFIN_TIMER_LATENCY is not set -CONFIG_SIMPLE_GPIO=m # CONFIG_VT is not set # CONFIG_DEVKMEM is not set CONFIG_BFIN_JTAG_COMM=m @@ -701,6 +734,7 @@ CONFIG_BFIN_JTAG_COMM=m # # Non-8250 serial port support # +# CONFIG_SERIAL_MAX3100 is not set CONFIG_SERIAL_BFIN=y CONFIG_SERIAL_BFIN_CONSOLE=y CONFIG_SERIAL_BFIN_DMA=y @@ -711,12 +745,8 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_BFIN_SPORT is not set CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set - -# -# CAN, the car bus and industrial fieldbus -# -# CONFIG_CAN4LINUX is not set # CONFIG_IPMI_HANDLER is not set # CONFIG_HW_RANDOM is not set # CONFIG_R3964 is not set @@ -734,13 +764,18 @@ CONFIG_SPI_BFIN=y # CONFIG_SPI_BFIN_LOCK is not set # CONFIG_SPI_BFIN_SPORT is not set # CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set # # SPI Protocol Masters # -# CONFIG_EEPROM_AT25 is not set # CONFIG_SPI_SPIDEV is not set # CONFIG_SPI_TLE62X0 is not set + +# +# PPS support +# +# CONFIG_PPS is not set CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y CONFIG_GPIOLIB=y # CONFIG_DEBUG_GPIO is not set @@ -753,9 +788,6 @@ CONFIG_GPIO_SYSFS=y # # I2C GPIO expanders: # -# CONFIG_GPIO_MAX732X is not set -# CONFIG_GPIO_PCA953X is not set -# CONFIG_GPIO_PCF857X is not set # # PCI GPIO expanders: @@ -766,11 +798,15 @@ CONFIG_GPIO_SYSFS=y # # CONFIG_GPIO_MAX7301 is not set # CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set + +# +# AC97 GPIO expanders: +# # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set # CONFIG_THERMAL is not set -# CONFIG_THERMAL_HWMON is not set CONFIG_WATCHDOG=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -793,23 +829,10 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_SM501 is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set +# CONFIG_MFD_MC13783 is not set +# CONFIG_EZX_PCAP is not set # CONFIG_REGULATOR is not set - -# -# Multimedia devices -# - -# -# Multimedia core support -# -# CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -# CONFIG_VIDEO_MEDIA is not set - -# -# Multimedia drivers -# -# CONFIG_DAB is not set +# CONFIG_MEDIA_SUPPORT is not set # # Graphics support @@ -826,14 +849,12 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_SOUND is not set CONFIG_HID_SUPPORT=y CONFIG_HID=m -# CONFIG_HID_DEBUG is not set # CONFIG_HIDRAW is not set # CONFIG_HID_PID is not set # # Special HID drivers # -CONFIG_HID_COMPAT=y # CONFIG_USB_SUPPORT is not set # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set @@ -864,6 +885,7 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_R9701 is not set # CONFIG_RTC_DRV_RS5C348 is not set # CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set # # Platform RTC drivers @@ -884,10 +906,20 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_BFIN=y # CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set # CONFIG_UIO is not set + +# +# TI VLYNQ +# # CONFIG_STAGING is not set # +# Firmware Drivers +# +# CONFIG_FIRMWARE_MEMMAP is not set + +# # File systems # # CONFIG_EXT2_FS is not set @@ -896,9 +928,13 @@ CONFIG_RTC_DRV_BFIN=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set -CONFIG_FILE_LOCKING=y # CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y # CONFIG_DNOTIFY is not set CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y @@ -908,6 +944,11 @@ CONFIG_INOTIFY_USER=y # CONFIG_FUSE_FS is not set # +# Caches +# +# CONFIG_FSCACHE is not set + +# # CD-ROM/DVD Filesystems # # CONFIG_ISO9660_FS is not set @@ -926,13 +967,9 @@ CONFIG_INOTIFY_USER=y CONFIG_PROC_FS=y CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y -# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set # CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# +CONFIG_MISC_FILESYSTEMS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set @@ -951,17 +988,8 @@ CONFIG_JFFS2_ZLIB=y # CONFIG_JFFS2_LZO is not set CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set -CONFIG_YAFFS_FS=m -CONFIG_YAFFS_YAFFS1=y -# CONFIG_YAFFS_9BYTE_TAGS is not set -# CONFIG_YAFFS_DOES_ECC is not set -CONFIG_YAFFS_YAFFS2=y -CONFIG_YAFFS_AUTO_YAFFS2=y -# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set -# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set -# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set -CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y # CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_OMFS_FS is not set @@ -980,7 +1008,6 @@ CONFIG_LOCKD=m CONFIG_LOCKD_V4=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=m -# CONFIG_SUNRPC_REGISTER_V4 is not set # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set CONFIG_SMB_FS=m @@ -1045,14 +1072,19 @@ CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y CONFIG_FRAME_WARN=1024 # CONFIG_MAGIC_SYSRQ is not set +# CONFIG_STRIP_ASM_SYMS is not set # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_SECTION_MISMATCH=y CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_SHIRQ=y CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set @@ -1060,31 +1092,39 @@ CONFIG_SCHED_DEBUG=y # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y CONFIG_DEBUG_INFO=y # CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_NOMMU_REGIONS is not set # CONFIG_DEBUG_WRITECOUNT is not set # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set # CONFIG_FRAME_POINTER is not set # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set # CONFIG_FAULT_INJECTION is not set - -# -# Tracers -# -# CONFIG_SCHED_TRACER is not set -# CONFIG_CONTEXT_SWITCH_TRACER is not set -# CONFIG_BOOT_TRACER is not set -# CONFIG_DYNAMIC_PRINTK_DEBUG is not set +# CONFIG_PAGE_POISONING is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_BRANCH_PROFILE_NONE is not set +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_DYNAMIC_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set @@ -1109,6 +1149,7 @@ CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE=y CONFIG_EARLY_PRINTK=y CONFIG_CPLB_INFO=y CONFIG_ACCESS_CHECK=y +# CONFIG_BFIN_ISRAM_SELF_TEST is not set # # Security options @@ -1117,14 +1158,14 @@ CONFIG_ACCESS_CHECK=y CONFIG_SECURITY=y # CONFIG_SECURITYFS is not set # CONFIG_SECURITY_NETWORK is not set +# CONFIG_SECURITY_PATH is not set # CONFIG_SECURITY_FILE_CAPABILITIES is not set -CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0 +# CONFIG_SECURITY_TOMOYO is not set CONFIG_CRYPTO=y # # Crypto core or helper # -# CONFIG_CRYPTO_FIPS is not set # CONFIG_CRYPTO_MANAGER is not set # CONFIG_CRYPTO_MANAGER2 is not set # CONFIG_CRYPTO_GF128MUL is not set @@ -1156,11 +1197,13 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_HMAC is not set # CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set # # Digest # # CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set # CONFIG_CRYPTO_MD4 is not set # CONFIG_CRYPTO_MD5 is not set # CONFIG_CRYPTO_MICHAEL_MIC is not set @@ -1197,6 +1240,7 @@ CONFIG_CRYPTO=y # Compression # # CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set # CONFIG_CRYPTO_LZO is not set # @@ -1204,11 +1248,13 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set # # Library routines # CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y CONFIG_CRC_CCITT=m # CONFIG_CRC16 is not set # CONFIG_CRC_T10DIF is not set @@ -1218,6 +1264,8 @@ CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=m +CONFIG_DECOMPRESS_GZIP=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff --git a/arch/blackfin/configs/BF533-STAMP_defconfig b/arch/blackfin/configs/BF533-STAMP_defconfig index 6c60c82..c3fe6e5 100644 --- a/arch/blackfin/configs/BF533-STAMP_defconfig +++ b/arch/blackfin/configs/BF533-STAMP_defconfig @@ -1,22 +1,27 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.28.10 -# Thu May 21 05:50:01 2009 +# Linux kernel version: 2.6.32.2 # # CONFIG_MMU is not set # CONFIG_FPU is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_BLACKFIN=y +CONFIG_GENERIC_CSUM=y +CONFIG_GENERIC_BUG=y CONFIG_ZONE_DMA=y CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y CONFIG_GENERIC_GPIO=y CONFIG_FORCE_MAX_ZONEORDER=14 CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y # # General setup @@ -26,22 +31,41 @@ CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_BZIP2=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set # CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set # CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set # CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -62,6 +86,10 @@ CONFIG_EPOLL=y # CONFIG_TIMERFD is not set # CONFIG_EVENTFD is not set # CONFIG_AIO is not set + +# +# Kernel Performance Events And Counters +# CONFIG_VM_EVENT_COUNTERS=y CONFIG_COMPAT_BRK=y CONFIG_SLAB=y @@ -69,11 +97,15 @@ CONFIG_SLAB=y # CONFIG_SLOB is not set CONFIG_MMAP_ALLOW_UNINITIALIZED=y # CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +# CONFIG_SLOW_WORK is not set # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set CONFIG_SLABINFO=y -CONFIG_TINY_SHMEM=y CONFIG_BASE_SMALL=0 CONFIG_MODULES=y # CONFIG_MODULE_FORCE_LOAD is not set @@ -81,11 +113,8 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set +# CONFIG_LBDAF is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -101,7 +130,6 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" -CONFIG_CLASSIC_RCU=y # CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set @@ -132,15 +160,15 @@ CONFIG_BF533=y # CONFIG_BF537 is not set # CONFIG_BF538 is not set # CONFIG_BF539 is not set -# CONFIG_BF542 is not set +# CONFIG_BF542_std is not set # CONFIG_BF542M is not set -# CONFIG_BF544 is not set +# CONFIG_BF544_std is not set # CONFIG_BF544M is not set -# CONFIG_BF547 is not set +# CONFIG_BF547_std is not set # CONFIG_BF547M is not set -# CONFIG_BF548 is not set +# CONFIG_BF548_std is not set # CONFIG_BF548M is not set -# CONFIG_BF549 is not set +# CONFIG_BF549_std is not set # CONFIG_BF549M is not set # CONFIG_BF561 is not set CONFIG_BF_REV_MIN=3 @@ -228,7 +256,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y # CONFIG_TICKSOURCE_GPTMR0 is not set CONFIG_TICKSOURCE_CORETMR=y -# CONFIG_CYCLES_CLOCKSOURCE is not set +CONFIG_CYCLES_CLOCKSOURCE=y # CONFIG_GPTMR0_CLOCKSOURCE is not set CONFIG_TICK_ONESHOT=y # CONFIG_NO_HZ is not set @@ -280,7 +308,6 @@ CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_VIRT_TO_BUS=y @@ -289,16 +316,18 @@ CONFIG_BFIN_GPTIMERS=m # CONFIG_DMA_UNCACHED_4M is not set # CONFIG_DMA_UNCACHED_2M is not set CONFIG_DMA_UNCACHED_1M=y +# CONFIG_DMA_UNCACHED_512K is not set +# CONFIG_DMA_UNCACHED_256K is not set +# CONFIG_DMA_UNCACHED_128K is not set # CONFIG_DMA_UNCACHED_NONE is not set # # Cache Support # CONFIG_BFIN_ICACHE=y -# CONFIG_BFIN_ICACHE_LOCK is not set +CONFIG_BFIN_EXTMEM_ICACHEABLE=y CONFIG_BFIN_DCACHE=y # CONFIG_BFIN_DCACHE_BANKA is not set -CONFIG_BFIN_EXTMEM_ICACHEABLE=y CONFIG_BFIN_EXTMEM_DCACHEABLE=y CONFIG_BFIN_EXTMEM_WRITEBACK=y # CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set @@ -309,7 +338,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y # CONFIG_MPU is not set # -# Asynchonous Memory Configuration +# Asynchronous Memory Configuration # # @@ -355,6 +384,7 @@ CONFIG_PM=y CONFIG_PM_SLEEP=y CONFIG_SUSPEND=y CONFIG_SUSPEND_FREEZER=y +# CONFIG_PM_RUNTIME is not set CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_PM_BFIN_SLEEP_DEEPER=y # CONFIG_PM_BFIN_SLEEP is not set @@ -376,11 +406,6 @@ CONFIG_NET=y CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -404,7 +429,6 @@ CONFIG_IP_PNP=y # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set -CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" @@ -415,6 +439,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_NETFILTER is not set # CONFIG_IP_DCCP is not set # CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -428,7 +453,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_LAPB is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set # CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set # # Network testing @@ -474,13 +502,8 @@ CONFIG_SIR_BFIN_DMA=y # # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set -# CONFIG_PHONET is not set -CONFIG_WIRELESS=y -# CONFIG_CFG80211 is not set -CONFIG_WIRELESS_OLD_REGULATORY=y -# CONFIG_WIRELESS_EXT is not set -# CONFIG_MAC80211 is not set -# CONFIG_IEEE80211 is not set +# CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -501,6 +524,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_CONNECTOR is not set CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set # CONFIG_MTD_CONCAT is not set CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_REDBOOT_PARTS is not set @@ -560,6 +584,7 @@ CONFIG_MTD_BFIN_ASYNC=m # # CONFIG_MTD_DATAFLASH is not set # CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SST25L is not set # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set @@ -575,6 +600,11 @@ CONFIG_MTD_BFIN_ASYNC=m # CONFIG_MTD_ONENAND is not set # +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# # UBI - Unsorted block images # # CONFIG_MTD_UBI is not set @@ -591,10 +621,20 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 # CONFIG_ATA_OVER_ETH is not set # CONFIG_BLK_DEV_HD is not set CONFIG_MISC_DEVICES=y -# CONFIG_EEPROM_93CX6 is not set +# CONFIG_AD525X_DPOT is not set # CONFIG_ICS932S401 is not set # CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_ISL29003 is not set # CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EEPROM_93CX6 is not set CONFIG_HAVE_IDE=y # CONFIG_IDE is not set @@ -618,9 +658,12 @@ CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_MII=y CONFIG_SMC91X=y -# CONFIG_SMSC911X is not set # CONFIG_DM9000 is not set # CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set +# CONFIG_ADF702X is not set # CONFIG_IBM_NEW_EMAC_ZMII is not set # CONFIG_IBM_NEW_EMAC_RGMII is not set # CONFIG_IBM_NEW_EMAC_TAH is not set @@ -629,15 +672,16 @@ CONFIG_SMC91X=y # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set +# CONFIG_WLAN is not set # -# Wireless LAN +# Enable WiMAX (Networking options) to see the WiMAX drivers # -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set -# CONFIG_IWLWIFI_LEDS is not set # CONFIG_WAN is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -672,7 +716,10 @@ CONFIG_INPUT_EVDEV=m # CONFIG_INPUT_TOUCHSCREEN is not set CONFIG_INPUT_MISC=y # CONFIG_INPUT_UINPUT is not set -CONFIG_CONFIG_INPUT_PCF8574=m +# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set +# CONFIG_INPUT_AD714X is not set +# CONFIG_INPUT_ADXL34X is not set +# CONFIG_INPUT_PCF8574 is not set # # Hardware I/O ports @@ -683,16 +730,13 @@ CONFIG_CONFIG_INPUT_PCF8574=m # # Character devices # -# CONFIG_AD9960 is not set CONFIG_BFIN_DMA_INTERFACE=m # CONFIG_BFIN_PPI is not set # CONFIG_BFIN_PPIFCD is not set # CONFIG_BFIN_SIMPLE_TIMER is not set # CONFIG_BFIN_SPI_ADC is not set CONFIG_BFIN_SPORT=m -# CONFIG_BFIN_TIMER_LATENCY is not set # CONFIG_BFIN_TWI_LCD is not set -CONFIG_SIMPLE_GPIO=m # CONFIG_VT is not set # CONFIG_DEVKMEM is not set CONFIG_BFIN_JTAG_COMM=m @@ -706,6 +750,7 @@ CONFIG_BFIN_JTAG_COMM=m # # Non-8250 serial port support # +# CONFIG_SERIAL_MAX3100 is not set CONFIG_SERIAL_BFIN=y CONFIG_SERIAL_BFIN_CONSOLE=y CONFIG_SERIAL_BFIN_DMA=y @@ -716,12 +761,8 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_BFIN_SPORT is not set CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set - -# -# CAN, the car bus and industrial fieldbus -# -# CONFIG_CAN4LINUX is not set # CONFIG_IPMI_HANDLER is not set # CONFIG_HW_RANDOM is not set # CONFIG_R3964 is not set @@ -729,6 +770,7 @@ CONFIG_UNIX98_PTYS=y # CONFIG_TCG_TPM is not set CONFIG_I2C=m CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y CONFIG_I2C_CHARDEV=m CONFIG_I2C_HELPER_AUTO=y @@ -759,14 +801,6 @@ CONFIG_I2C_HELPER_AUTO=y # Miscellaneous I2C Chip support # # CONFIG_DS1682 is not set -# CONFIG_EEPROM_AT24 is not set -# CONFIG_SENSORS_AD5252 is not set -# CONFIG_EEPROM_LEGACY is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_PCF8575 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_MAX6875 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set @@ -783,13 +817,18 @@ CONFIG_SPI_BFIN=y # CONFIG_SPI_BFIN_LOCK is not set # CONFIG_SPI_BFIN_SPORT is not set # CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set # # SPI Protocol Masters # -# CONFIG_EEPROM_AT25 is not set # CONFIG_SPI_SPIDEV is not set # CONFIG_SPI_TLE62X0 is not set + +# +# PPS support +# +# CONFIG_PPS is not set CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y CONFIG_GPIOLIB=y # CONFIG_DEBUG_GPIO is not set @@ -805,6 +844,7 @@ CONFIG_GPIO_SYSFS=y # CONFIG_GPIO_MAX732X is not set # CONFIG_GPIO_PCA953X is not set # CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_ADP5588 is not set # # PCI GPIO expanders: @@ -815,11 +855,15 @@ CONFIG_GPIO_SYSFS=y # # CONFIG_GPIO_MAX7301 is not set # CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set + +# +# AC97 GPIO expanders: +# # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set # CONFIG_THERMAL is not set -# CONFIG_THERMAL_HWMON is not set CONFIG_WATCHDOG=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -841,26 +885,18 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set # CONFIG_HTC_PASIC3 is not set +# CONFIG_UCB1400_CORE is not set +# CONFIG_TPS65010 is not set # CONFIG_MFD_TMIO is not set # CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13783 is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_EZX_PCAP is not set # CONFIG_REGULATOR is not set - -# -# Multimedia devices -# - -# -# Multimedia core support -# -# CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -# CONFIG_VIDEO_MEDIA is not set - -# -# Multimedia drivers -# -# CONFIG_DAB is not set +# CONFIG_MEDIA_SUPPORT is not set # # Graphics support @@ -904,6 +940,7 @@ CONFIG_ADV7393_1XMEM=y # CONFIG_FB_VIRTUAL is not set # CONFIG_FB_METRONOME is not set # CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set # CONFIG_BACKLIGHT_LCD_SUPPORT is not set # @@ -913,19 +950,27 @@ CONFIG_ADV7393_1XMEM=y # CONFIG_LOGO is not set CONFIG_SOUND=m CONFIG_SOUND_OSS_CORE=y +CONFIG_SOUND_OSS_CORE_PRECLAIM=y CONFIG_SND=m CONFIG_SND_TIMER=m CONFIG_SND_PCM=m +CONFIG_SND_JACK=y # CONFIG_SND_SEQUENCER is not set CONFIG_SND_OSSEMUL=y CONFIG_SND_MIXER_OSS=m CONFIG_SND_PCM_OSS=m CONFIG_SND_PCM_OSS_PLUGINS=y +# CONFIG_SND_HRTIMER is not set # CONFIG_SND_DYNAMIC_MINORS is not set CONFIG_SND_SUPPORT_OLD_API=y CONFIG_SND_VERBOSE_PROCFS=y # CONFIG_SND_VERBOSE_PRINTK is not set # CONFIG_SND_DEBUG is not set +# CONFIG_SND_RAWMIDI_SEQ is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set CONFIG_SND_DRIVERS=y # CONFIG_SND_DUMMY is not set # CONFIG_SND_MTPAV is not set @@ -936,13 +981,6 @@ CONFIG_SND_SPI=y # # ALSA Blackfin devices # -CONFIG_SND_BLACKFIN_AD1836=m -CONFIG_SND_BLACKFIN_AD1836_TDM=y -# CONFIG_SND_BLACKFIN_AD1836_I2S is not set -CONFIG_SND_BLACKFIN_AD1836_MULSUB=y -# CONFIG_SND_BLACKFIN_AD1836_5P1 is not set -CONFIG_SND_BLACKFIN_SPORT=0 -CONFIG_SND_BLACKFIN_SPI_PFBIT=4 CONFIG_SND_BFIN_SPORT=0 CONFIG_SND_BFIN_AD73322=m CONFIG_SND_BFIN_AD73322_SPORT0_SE=10 @@ -953,16 +991,20 @@ CONFIG_SND_SOC_AC97_BUS=y CONFIG_SND_BF5XX_I2S=m # CONFIG_SND_BF5XX_SOC_SSM2602 is not set CONFIG_SND_BF5XX_SOC_AD73311=m +# CONFIG_SND_BF5XX_SOC_ADAU1371 is not set +# CONFIG_SND_BF5XX_SOC_ADAU1761 is not set CONFIG_SND_BFIN_AD73311_SE=4 +# CONFIG_SND_BF5XX_TDM is not set CONFIG_SND_BF5XX_AC97=m CONFIG_SND_BF5XX_MMAP_SUPPORT=y # CONFIG_SND_BF5XX_MULTICHAN_SUPPORT is not set +# CONFIG_SND_BF5XX_HAVE_COLD_RESET is not set +CONFIG_SND_BF5XX_SOC_AD1980=m CONFIG_SND_BF5XX_SOC_SPORT=m CONFIG_SND_BF5XX_SOC_I2S=m CONFIG_SND_BF5XX_SOC_AC97=m -CONFIG_SND_BF5XX_SOC_AD1980=m CONFIG_SND_BF5XX_SPORT_NUM=0 -# CONFIG_SND_BF5XX_HAVE_COLD_RESET is not set +CONFIG_SND_SOC_I2C_AND_SPI=m # CONFIG_SND_SOC_ALL_CODECS is not set CONFIG_SND_SOC_AD1980=m CONFIG_SND_SOC_AD73311=m @@ -970,14 +1012,12 @@ CONFIG_SND_SOC_AD73311=m CONFIG_AC97_BUS=m CONFIG_HID_SUPPORT=y CONFIG_HID=y -# CONFIG_HID_DEBUG is not set # CONFIG_HIDRAW is not set # CONFIG_HID_PID is not set # # Special HID drivers # -CONFIG_HID_COMPAT=y # CONFIG_USB_SUPPORT is not set # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set @@ -1014,6 +1054,7 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_S35390A is not set # CONFIG_RTC_DRV_FM3130 is not set # CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set # # SPI RTC drivers @@ -1025,6 +1066,7 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_R9701 is not set # CONFIG_RTC_DRV_RS5C348 is not set # CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set # # Platform RTC drivers @@ -1045,10 +1087,21 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_BFIN=y # CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set # CONFIG_UIO is not set + +# +# TI VLYNQ +# # CONFIG_STAGING is not set # +# Firmware Drivers +# +# CONFIG_FIRMWARE_MEMMAP is not set +# CONFIG_SIGMA is not set + +# # File systems # # CONFIG_EXT2_FS is not set @@ -1057,9 +1110,13 @@ CONFIG_RTC_DRV_BFIN=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set -CONFIG_FILE_LOCKING=y # CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y # CONFIG_DNOTIFY is not set CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y @@ -1069,6 +1126,11 @@ CONFIG_INOTIFY_USER=y # CONFIG_FUSE_FS is not set # +# Caches +# +# CONFIG_FSCACHE is not set + +# # CD-ROM/DVD Filesystems # # CONFIG_ISO9660_FS is not set @@ -1087,13 +1149,9 @@ CONFIG_INOTIFY_USER=y CONFIG_PROC_FS=y CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y -# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set # CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# +CONFIG_MISC_FILESYSTEMS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set @@ -1112,17 +1170,8 @@ CONFIG_JFFS2_ZLIB=y # CONFIG_JFFS2_LZO is not set CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set -CONFIG_YAFFS_FS=m -CONFIG_YAFFS_YAFFS1=y -# CONFIG_YAFFS_9BYTE_TAGS is not set -# CONFIG_YAFFS_DOES_ECC is not set -CONFIG_YAFFS_YAFFS2=y -CONFIG_YAFFS_AUTO_YAFFS2=y -# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set -# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set -# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set -CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y # CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_OMFS_FS is not set @@ -1141,7 +1190,6 @@ CONFIG_LOCKD=m CONFIG_LOCKD_V4=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=m -# CONFIG_SUNRPC_REGISTER_V4 is not set # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set CONFIG_SMB_FS=m @@ -1206,14 +1254,19 @@ CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y CONFIG_FRAME_WARN=1024 # CONFIG_MAGIC_SYSRQ is not set +# CONFIG_STRIP_ASM_SYMS is not set # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_SECTION_MISMATCH=y CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_SHIRQ=y CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set @@ -1221,31 +1274,39 @@ CONFIG_SCHED_DEBUG=y # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y CONFIG_DEBUG_INFO=y # CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_NOMMU_REGIONS is not set # CONFIG_DEBUG_WRITECOUNT is not set # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set # CONFIG_FRAME_POINTER is not set # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set # CONFIG_FAULT_INJECTION is not set - -# -# Tracers -# -# CONFIG_SCHED_TRACER is not set -# CONFIG_CONTEXT_SWITCH_TRACER is not set -# CONFIG_BOOT_TRACER is not set -# CONFIG_DYNAMIC_PRINTK_DEBUG is not set +# CONFIG_PAGE_POISONING is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_BRANCH_PROFILE_NONE is not set +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_DYNAMIC_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set @@ -1270,6 +1331,7 @@ CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE=y CONFIG_EARLY_PRINTK=y CONFIG_CPLB_INFO=y CONFIG_ACCESS_CHECK=y +# CONFIG_BFIN_ISRAM_SELF_TEST is not set # # Security options @@ -1278,14 +1340,14 @@ CONFIG_ACCESS_CHECK=y CONFIG_SECURITY=y # CONFIG_SECURITYFS is not set # CONFIG_SECURITY_NETWORK is not set +# CONFIG_SECURITY_PATH is not set # CONFIG_SECURITY_FILE_CAPABILITIES is not set -CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0 +# CONFIG_SECURITY_TOMOYO is not set CONFIG_CRYPTO=y # # Crypto core or helper # -# CONFIG_CRYPTO_FIPS is not set # CONFIG_CRYPTO_MANAGER is not set # CONFIG_CRYPTO_MANAGER2 is not set # CONFIG_CRYPTO_GF128MUL is not set @@ -1317,11 +1379,13 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_HMAC is not set # CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set # # Digest # # CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set # CONFIG_CRYPTO_MD4 is not set # CONFIG_CRYPTO_MD5 is not set # CONFIG_CRYPTO_MICHAEL_MIC is not set @@ -1358,6 +1422,7 @@ CONFIG_CRYPTO=y # Compression # # CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set # CONFIG_CRYPTO_LZO is not set # @@ -1365,11 +1430,13 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set # # Library routines # CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y CONFIG_CRC_CCITT=m # CONFIG_CRC16 is not set # CONFIG_CRC_T10DIF is not set @@ -1379,6 +1446,8 @@ CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=m +CONFIG_DECOMPRESS_GZIP=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff --git a/arch/blackfin/configs/BF537-STAMP_defconfig b/arch/blackfin/configs/BF537-STAMP_defconfig index 2908595..7596cf7 100644 --- a/arch/blackfin/configs/BF537-STAMP_defconfig +++ b/arch/blackfin/configs/BF537-STAMP_defconfig @@ -1,22 +1,27 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.28.10 -# Thu May 21 05:50:01 2009 +# Linux kernel version: 2.6.32.2 # # CONFIG_MMU is not set # CONFIG_FPU is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_BLACKFIN=y +CONFIG_GENERIC_CSUM=y +CONFIG_GENERIC_BUG=y CONFIG_ZONE_DMA=y CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y CONFIG_GENERIC_GPIO=y CONFIG_FORCE_MAX_ZONEORDER=14 CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y # # General setup @@ -26,22 +31,41 @@ CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_BZIP2=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set # CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set # CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set # CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -62,6 +86,10 @@ CONFIG_EPOLL=y # CONFIG_TIMERFD is not set # CONFIG_EVENTFD is not set # CONFIG_AIO is not set + +# +# Kernel Performance Events And Counters +# CONFIG_VM_EVENT_COUNTERS=y CONFIG_COMPAT_BRK=y CONFIG_SLAB=y @@ -69,11 +97,15 @@ CONFIG_SLAB=y # CONFIG_SLOB is not set CONFIG_MMAP_ALLOW_UNINITIALIZED=y # CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +# CONFIG_SLOW_WORK is not set # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set CONFIG_SLABINFO=y -CONFIG_TINY_SHMEM=y CONFIG_BASE_SMALL=0 CONFIG_MODULES=y # CONFIG_MODULE_FORCE_LOAD is not set @@ -81,11 +113,8 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set +# CONFIG_LBDAF is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -101,7 +130,6 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" -CONFIG_CLASSIC_RCU=y # CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set @@ -132,15 +160,15 @@ CONFIG_FREEZER=y CONFIG_BF537=y # CONFIG_BF538 is not set # CONFIG_BF539 is not set -# CONFIG_BF542 is not set +# CONFIG_BF542_std is not set # CONFIG_BF542M is not set -# CONFIG_BF544 is not set +# CONFIG_BF544_std is not set # CONFIG_BF544M is not set -# CONFIG_BF547 is not set +# CONFIG_BF547_std is not set # CONFIG_BF547M is not set -# CONFIG_BF548 is not set +# CONFIG_BF548_std is not set # CONFIG_BF548M is not set -# CONFIG_BF549 is not set +# CONFIG_BF549_std is not set # CONFIG_BF549M is not set # CONFIG_BF561 is not set CONFIG_BF_REV_MIN=2 @@ -184,7 +212,8 @@ CONFIG_IRQ_MEM_DMA1=13 CONFIG_IRQ_WATCH=13 CONFIG_IRQ_SPI=10 CONFIG_BFIN537_STAMP=y -# CONFIG_BFIN537_BLUETECHNIX_CM is not set +# CONFIG_BFIN537_BLUETECHNIX_CM_E is not set +# CONFIG_BFIN537_BLUETECHNIX_CM_U is not set # CONFIG_BFIN537_BLUETECHNIX_TCM is not set # CONFIG_PNAV10 is not set # CONFIG_CAMSIG_MINOTAUR is not set @@ -235,7 +264,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y # CONFIG_TICKSOURCE_GPTMR0 is not set CONFIG_TICKSOURCE_CORETMR=y -# CONFIG_CYCLES_CLOCKSOURCE is not set +CONFIG_CYCLES_CLOCKSOURCE=y # CONFIG_GPTMR0_CLOCKSOURCE is not set CONFIG_TICK_ONESHOT=y # CONFIG_NO_HZ is not set @@ -287,7 +316,6 @@ CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_VIRT_TO_BUS=y @@ -296,16 +324,18 @@ CONFIG_BFIN_GPTIMERS=m # CONFIG_DMA_UNCACHED_4M is not set # CONFIG_DMA_UNCACHED_2M is not set CONFIG_DMA_UNCACHED_1M=y +# CONFIG_DMA_UNCACHED_512K is not set +# CONFIG_DMA_UNCACHED_256K is not set +# CONFIG_DMA_UNCACHED_128K is not set # CONFIG_DMA_UNCACHED_NONE is not set # # Cache Support # CONFIG_BFIN_ICACHE=y -# CONFIG_BFIN_ICACHE_LOCK is not set +CONFIG_BFIN_EXTMEM_ICACHEABLE=y CONFIG_BFIN_DCACHE=y # CONFIG_BFIN_DCACHE_BANKA is not set -CONFIG_BFIN_EXTMEM_ICACHEABLE=y CONFIG_BFIN_EXTMEM_DCACHEABLE=y CONFIG_BFIN_EXTMEM_WRITEBACK=y # CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set @@ -316,7 +346,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y # CONFIG_MPU is not set # -# Asynchonous Memory Configuration +# Asynchronous Memory Configuration # # @@ -362,6 +392,7 @@ CONFIG_PM=y CONFIG_PM_SLEEP=y CONFIG_SUSPEND=y CONFIG_SUSPEND_FREEZER=y +# CONFIG_PM_RUNTIME is not set CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_PM_BFIN_SLEEP_DEEPER=y # CONFIG_PM_BFIN_SLEEP is not set @@ -384,11 +415,6 @@ CONFIG_NET=y CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -412,7 +438,6 @@ CONFIG_IP_PNP=y # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set -CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" @@ -423,6 +448,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_NETFILTER is not set # CONFIG_IP_DCCP is not set # CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -436,14 +462,34 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_LAPB is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set # CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set # # Network testing # # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set -# CONFIG_CAN is not set +CONFIG_CAN=m +CONFIG_CAN_RAW=m +CONFIG_CAN_BCM=m + +# +# CAN Device Drivers +# +# CONFIG_CAN_VCAN is not set +CONFIG_CAN_DEV=m +# CONFIG_CAN_CALC_BITTIMING is not set +CONFIG_CAN_BFIN=m +# CONFIG_CAN_SJA1000 is not set + +# +# CAN USB interfaces +# +# CONFIG_CAN_EMS_USB is not set +# CONFIG_CAN_DEBUG_DEVICES is not set CONFIG_IRDA=m # @@ -483,13 +529,8 @@ CONFIG_SIR_BFIN_DMA=y # # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set -# CONFIG_PHONET is not set -CONFIG_WIRELESS=y -# CONFIG_CFG80211 is not set -CONFIG_WIRELESS_OLD_REGULATORY=y -# CONFIG_WIRELESS_EXT is not set -# CONFIG_MAC80211 is not set -# CONFIG_IEEE80211 is not set +# CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -510,6 +551,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_CONNECTOR is not set CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set # CONFIG_MTD_CONCAT is not set CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_REDBOOT_PARTS is not set @@ -568,6 +610,7 @@ CONFIG_MTD_PHYSMAP=m # # CONFIG_MTD_DATAFLASH is not set # CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SST25L is not set # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set @@ -583,6 +626,11 @@ CONFIG_MTD_PHYSMAP=m # CONFIG_MTD_ONENAND is not set # +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# # UBI - Unsorted block images # # CONFIG_MTD_UBI is not set @@ -599,10 +647,20 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 # CONFIG_ATA_OVER_ETH is not set # CONFIG_BLK_DEV_HD is not set CONFIG_MISC_DEVICES=y -# CONFIG_EEPROM_93CX6 is not set +# CONFIG_AD525X_DPOT is not set # CONFIG_ICS932S401 is not set # CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_ISL29003 is not set # CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EEPROM_93CX6 is not set CONFIG_HAVE_IDE=y # CONFIG_IDE is not set @@ -637,6 +695,9 @@ CONFIG_SMSC_PHY=y # CONFIG_BROADCOM_PHY is not set # CONFIG_ICPLUS_PHY is not set # CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set # CONFIG_FIXED_PHY is not set # CONFIG_MDIO_BITBANG is not set CONFIG_NET_ETHERNET=y @@ -647,9 +708,12 @@ CONFIG_BFIN_TX_DESC_NUM=10 CONFIG_BFIN_RX_DESC_NUM=20 # CONFIG_BFIN_MAC_RMII is not set # CONFIG_SMC91X is not set -# CONFIG_SMSC911X is not set # CONFIG_DM9000 is not set # CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set +# CONFIG_ADF702X is not set # CONFIG_IBM_NEW_EMAC_ZMII is not set # CONFIG_IBM_NEW_EMAC_RGMII is not set # CONFIG_IBM_NEW_EMAC_TAH is not set @@ -658,15 +722,16 @@ CONFIG_BFIN_RX_DESC_NUM=20 # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set +# CONFIG_WLAN is not set # -# Wireless LAN +# Enable WiMAX (Networking options) to see the WiMAX drivers # -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set -# CONFIG_IWLWIFI_LEDS is not set # CONFIG_WAN is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -701,7 +766,10 @@ CONFIG_INPUT_EVDEV=m # CONFIG_INPUT_TOUCHSCREEN is not set CONFIG_INPUT_MISC=y # CONFIG_INPUT_UINPUT is not set -CONFIG_CONFIG_INPUT_PCF8574=m +# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set +# CONFIG_INPUT_AD714X is not set +# CONFIG_INPUT_ADXL34X is not set +# CONFIG_INPUT_PCF8574 is not set # # Hardware I/O ports @@ -712,16 +780,13 @@ CONFIG_CONFIG_INPUT_PCF8574=m # # Character devices # -# CONFIG_AD9960 is not set CONFIG_BFIN_DMA_INTERFACE=m # CONFIG_BFIN_PPI is not set # CONFIG_BFIN_PPIFCD is not set # CONFIG_BFIN_SIMPLE_TIMER is not set # CONFIG_BFIN_SPI_ADC is not set CONFIG_BFIN_SPORT=m -# CONFIG_BFIN_TIMER_LATENCY is not set # CONFIG_BFIN_TWI_LCD is not set -CONFIG_SIMPLE_GPIO=m # CONFIG_VT is not set # CONFIG_DEVKMEM is not set CONFIG_BFIN_JTAG_COMM=m @@ -735,6 +800,7 @@ CONFIG_BFIN_JTAG_COMM=m # # Non-8250 serial port support # +# CONFIG_SERIAL_MAX3100 is not set CONFIG_SERIAL_BFIN=y CONFIG_SERIAL_BFIN_CONSOLE=y CONFIG_SERIAL_BFIN_DMA=y @@ -746,17 +812,8 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_BFIN_SPORT is not set CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set - -# -# CAN, the car bus and industrial fieldbus -# -CONFIG_CAN4LINUX=y - -# -# linux embedded drivers -# -CONFIG_CAN_BLACKFIN=m # CONFIG_IPMI_HANDLER is not set # CONFIG_HW_RANDOM is not set # CONFIG_R3964 is not set @@ -764,6 +821,7 @@ CONFIG_CAN_BLACKFIN=m # CONFIG_TCG_TPM is not set CONFIG_I2C=m CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y CONFIG_I2C_CHARDEV=m CONFIG_I2C_HELPER_AUTO=y @@ -796,14 +854,6 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100 # Miscellaneous I2C Chip support # # CONFIG_DS1682 is not set -# CONFIG_EEPROM_AT24 is not set -CONFIG_SENSORS_AD5252=m -# CONFIG_EEPROM_LEGACY is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_PCF8575 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_MAX6875 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set @@ -820,13 +870,18 @@ CONFIG_SPI_BFIN=y # CONFIG_SPI_BFIN_LOCK is not set # CONFIG_SPI_BFIN_SPORT is not set # CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set # # SPI Protocol Masters # -# CONFIG_EEPROM_AT25 is not set # CONFIG_SPI_SPIDEV is not set # CONFIG_SPI_TLE62X0 is not set + +# +# PPS support +# +# CONFIG_PPS is not set CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y CONFIG_GPIOLIB=y # CONFIG_DEBUG_GPIO is not set @@ -842,6 +897,7 @@ CONFIG_GPIO_SYSFS=y # CONFIG_GPIO_MAX732X is not set # CONFIG_GPIO_PCA953X is not set # CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_ADP5588 is not set # # PCI GPIO expanders: @@ -852,11 +908,15 @@ CONFIG_GPIO_SYSFS=y # # CONFIG_GPIO_MAX7301 is not set # CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set + +# +# AC97 GPIO expanders: +# # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set # CONFIG_THERMAL is not set -# CONFIG_THERMAL_HWMON is not set CONFIG_WATCHDOG=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -878,26 +938,18 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set # CONFIG_HTC_PASIC3 is not set +# CONFIG_UCB1400_CORE is not set +# CONFIG_TPS65010 is not set # CONFIG_MFD_TMIO is not set # CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13783 is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_EZX_PCAP is not set # CONFIG_REGULATOR is not set - -# -# Multimedia devices -# - -# -# Multimedia core support -# -# CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -# CONFIG_VIDEO_MEDIA is not set - -# -# Multimedia drivers -# -# CONFIG_DAB is not set +# CONFIG_MEDIA_SUPPORT is not set # # Graphics support @@ -929,9 +981,6 @@ CONFIG_FB_CFB_IMAGEBLIT=m # CONFIG_FB_BFIN_T350MCQB is not set # CONFIG_FB_BFIN_LQ035Q1 is not set CONFIG_FB_BF537_LQ035=m -CONFIG_LQ035_SLAVE_ADDR=0x58 -# CONFIG_FB_BFIN_LANDSCAPE is not set -# CONFIG_FB_BFIN_BGR is not set CONFIG_FB_BFIN_7393=m CONFIG_NTSC=y # CONFIG_PAL is not set @@ -946,15 +995,18 @@ CONFIG_ADV7393_1XMEM=y # CONFIG_FB_VIRTUAL is not set # CONFIG_FB_METRONOME is not set # CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_LCD_CLASS_DEVICE=m +# CONFIG_LCD_LMS283GF05 is not set # CONFIG_LCD_LTV350QV is not set # CONFIG_LCD_ILI9320 is not set # CONFIG_LCD_TDO24M is not set # CONFIG_LCD_VGG2432A4 is not set # CONFIG_LCD_PLATFORM is not set CONFIG_BACKLIGHT_CLASS_DEVICE=m -CONFIG_BACKLIGHT_CORGI=m +CONFIG_BACKLIGHT_GENERIC=m +# CONFIG_BACKLIGHT_ADP8870 is not set # # Display device support @@ -963,19 +1015,27 @@ CONFIG_BACKLIGHT_CORGI=m # CONFIG_LOGO is not set CONFIG_SOUND=m CONFIG_SOUND_OSS_CORE=y +CONFIG_SOUND_OSS_CORE_PRECLAIM=y CONFIG_SND=m CONFIG_SND_TIMER=m CONFIG_SND_PCM=m +CONFIG_SND_JACK=y # CONFIG_SND_SEQUENCER is not set CONFIG_SND_OSSEMUL=y CONFIG_SND_MIXER_OSS=m CONFIG_SND_PCM_OSS=m CONFIG_SND_PCM_OSS_PLUGINS=y +# CONFIG_SND_HRTIMER is not set # CONFIG_SND_DYNAMIC_MINORS is not set CONFIG_SND_SUPPORT_OLD_API=y CONFIG_SND_VERBOSE_PROCFS=y # CONFIG_SND_VERBOSE_PRINTK is not set # CONFIG_SND_DEBUG is not set +# CONFIG_SND_RAWMIDI_SEQ is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set CONFIG_SND_DRIVERS=y # CONFIG_SND_DUMMY is not set # CONFIG_SND_MTPAV is not set @@ -986,13 +1046,6 @@ CONFIG_SND_SPI=y # # ALSA Blackfin devices # -CONFIG_SND_BLACKFIN_AD1836=m -CONFIG_SND_BLACKFIN_AD1836_TDM=y -# CONFIG_SND_BLACKFIN_AD1836_I2S is not set -CONFIG_SND_BLACKFIN_AD1836_MULSUB=y -# CONFIG_SND_BLACKFIN_AD1836_5P1 is not set -CONFIG_SND_BLACKFIN_SPORT=0 -CONFIG_SND_BLACKFIN_SPI_PFBIT=4 CONFIG_SND_BFIN_SPORT=0 CONFIG_SND_BFIN_AD73322=m CONFIG_SND_BFIN_AD73322_SPORT0_SE=10 @@ -1003,16 +1056,20 @@ CONFIG_SND_SOC_AC97_BUS=y CONFIG_SND_BF5XX_I2S=m # CONFIG_SND_BF5XX_SOC_SSM2602 is not set CONFIG_SND_BF5XX_SOC_AD73311=m +# CONFIG_SND_BF5XX_SOC_ADAU1371 is not set +# CONFIG_SND_BF5XX_SOC_ADAU1761 is not set CONFIG_SND_BFIN_AD73311_SE=4 +# CONFIG_SND_BF5XX_TDM is not set CONFIG_SND_BF5XX_AC97=m CONFIG_SND_BF5XX_MMAP_SUPPORT=y # CONFIG_SND_BF5XX_MULTICHAN_SUPPORT is not set +# CONFIG_SND_BF5XX_HAVE_COLD_RESET is not set +CONFIG_SND_BF5XX_SOC_AD1980=m CONFIG_SND_BF5XX_SOC_SPORT=m CONFIG_SND_BF5XX_SOC_I2S=m CONFIG_SND_BF5XX_SOC_AC97=m -CONFIG_SND_BF5XX_SOC_AD1980=m CONFIG_SND_BF5XX_SPORT_NUM=0 -# CONFIG_SND_BF5XX_HAVE_COLD_RESET is not set +CONFIG_SND_SOC_I2C_AND_SPI=m # CONFIG_SND_SOC_ALL_CODECS is not set CONFIG_SND_SOC_AD1980=m CONFIG_SND_SOC_AD73311=m @@ -1020,14 +1077,12 @@ CONFIG_SND_SOC_AD73311=m CONFIG_AC97_BUS=m CONFIG_HID_SUPPORT=y CONFIG_HID=y -# CONFIG_HID_DEBUG is not set # CONFIG_HIDRAW is not set # CONFIG_HID_PID is not set # # Special HID drivers # -CONFIG_HID_COMPAT=y # CONFIG_USB_SUPPORT is not set # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set @@ -1064,6 +1119,7 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_S35390A is not set # CONFIG_RTC_DRV_FM3130 is not set # CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set # # SPI RTC drivers @@ -1075,6 +1131,7 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_R9701 is not set # CONFIG_RTC_DRV_RS5C348 is not set # CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set # # Platform RTC drivers @@ -1095,10 +1152,21 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_BFIN=y # CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set # CONFIG_UIO is not set + +# +# TI VLYNQ +# # CONFIG_STAGING is not set # +# Firmware Drivers +# +# CONFIG_FIRMWARE_MEMMAP is not set +# CONFIG_SIGMA is not set + +# # File systems # # CONFIG_EXT2_FS is not set @@ -1107,9 +1175,13 @@ CONFIG_RTC_DRV_BFIN=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set -CONFIG_FILE_LOCKING=y # CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y # CONFIG_DNOTIFY is not set CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y @@ -1119,6 +1191,11 @@ CONFIG_INOTIFY_USER=y # CONFIG_FUSE_FS is not set # +# Caches +# +# CONFIG_FSCACHE is not set + +# # CD-ROM/DVD Filesystems # # CONFIG_ISO9660_FS is not set @@ -1137,13 +1214,9 @@ CONFIG_INOTIFY_USER=y CONFIG_PROC_FS=y CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y -# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set # CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# +CONFIG_MISC_FILESYSTEMS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set @@ -1162,17 +1235,8 @@ CONFIG_JFFS2_ZLIB=y # CONFIG_JFFS2_LZO is not set CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set -CONFIG_YAFFS_FS=m -CONFIG_YAFFS_YAFFS1=y -# CONFIG_YAFFS_9BYTE_TAGS is not set -# CONFIG_YAFFS_DOES_ECC is not set -CONFIG_YAFFS_YAFFS2=y -CONFIG_YAFFS_AUTO_YAFFS2=y -# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set -# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set -# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set -CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y # CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_OMFS_FS is not set @@ -1191,7 +1255,6 @@ CONFIG_LOCKD=m CONFIG_LOCKD_V4=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=m -# CONFIG_SUNRPC_REGISTER_V4 is not set # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set CONFIG_SMB_FS=m @@ -1256,14 +1319,19 @@ CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y CONFIG_FRAME_WARN=1024 # CONFIG_MAGIC_SYSRQ is not set +# CONFIG_STRIP_ASM_SYMS is not set # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_SECTION_MISMATCH=y CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_SHIRQ=y CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set @@ -1271,31 +1339,39 @@ CONFIG_SCHED_DEBUG=y # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y CONFIG_DEBUG_INFO=y # CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_NOMMU_REGIONS is not set # CONFIG_DEBUG_WRITECOUNT is not set # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set # CONFIG_FRAME_POINTER is not set # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set # CONFIG_FAULT_INJECTION is not set - -# -# Tracers -# -# CONFIG_SCHED_TRACER is not set -# CONFIG_CONTEXT_SWITCH_TRACER is not set -# CONFIG_BOOT_TRACER is not set -# CONFIG_DYNAMIC_PRINTK_DEBUG is not set +# CONFIG_PAGE_POISONING is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_BRANCH_PROFILE_NONE is not set +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_DYNAMIC_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set @@ -1320,6 +1396,7 @@ CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE=y CONFIG_EARLY_PRINTK=y CONFIG_CPLB_INFO=y CONFIG_ACCESS_CHECK=y +# CONFIG_BFIN_ISRAM_SELF_TEST is not set # # Security options @@ -1328,14 +1405,14 @@ CONFIG_ACCESS_CHECK=y CONFIG_SECURITY=y # CONFIG_SECURITYFS is not set # CONFIG_SECURITY_NETWORK is not set +# CONFIG_SECURITY_PATH is not set # CONFIG_SECURITY_FILE_CAPABILITIES is not set -CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0 +# CONFIG_SECURITY_TOMOYO is not set CONFIG_CRYPTO=y # # Crypto core or helper # -# CONFIG_CRYPTO_FIPS is not set # CONFIG_CRYPTO_MANAGER is not set # CONFIG_CRYPTO_MANAGER2 is not set # CONFIG_CRYPTO_GF128MUL is not set @@ -1367,11 +1444,13 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_HMAC is not set # CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set # # Digest # # CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set # CONFIG_CRYPTO_MD4 is not set # CONFIG_CRYPTO_MD5 is not set # CONFIG_CRYPTO_MICHAEL_MIC is not set @@ -1408,6 +1487,7 @@ CONFIG_CRYPTO=y # Compression # # CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set # CONFIG_CRYPTO_LZO is not set # @@ -1415,11 +1495,13 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set # # Library routines # CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y CONFIG_CRC_CCITT=m # CONFIG_CRC16 is not set # CONFIG_CRC_T10DIF is not set @@ -1429,6 +1511,8 @@ CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=m +CONFIG_DECOMPRESS_GZIP=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff --git a/arch/blackfin/configs/BF538-EZKIT_defconfig b/arch/blackfin/configs/BF538-EZKIT_defconfig index 09ea249..bc1871d 100644 --- a/arch/blackfin/configs/BF538-EZKIT_defconfig +++ b/arch/blackfin/configs/BF538-EZKIT_defconfig @@ -1,22 +1,27 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.28.10 -# Thu May 21 05:50:01 2009 +# Linux kernel version: 2.6.32.2 # # CONFIG_MMU is not set # CONFIG_FPU is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_BLACKFIN=y +CONFIG_GENERIC_CSUM=y +CONFIG_GENERIC_BUG=y CONFIG_ZONE_DMA=y CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y CONFIG_GENERIC_GPIO=y CONFIG_FORCE_MAX_ZONEORDER=14 CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y # # General setup @@ -26,22 +31,41 @@ CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_BZIP2=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set # CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set # CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set # CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -62,6 +86,10 @@ CONFIG_EPOLL=y # CONFIG_TIMERFD is not set # CONFIG_EVENTFD is not set # CONFIG_AIO is not set + +# +# Kernel Performance Events And Counters +# CONFIG_VM_EVENT_COUNTERS=y CONFIG_COMPAT_BRK=y CONFIG_SLAB=y @@ -69,11 +97,15 @@ CONFIG_SLAB=y # CONFIG_SLOB is not set CONFIG_MMAP_ALLOW_UNINITIALIZED=y # CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +# CONFIG_SLOW_WORK is not set # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set CONFIG_SLABINFO=y -CONFIG_TINY_SHMEM=y CONFIG_BASE_SMALL=0 CONFIG_MODULES=y # CONFIG_MODULE_FORCE_LOAD is not set @@ -81,11 +113,8 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set +# CONFIG_LBDAF is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -101,7 +130,6 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" -CONFIG_CLASSIC_RCU=y # CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set @@ -132,15 +160,15 @@ CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_BF537 is not set CONFIG_BF538=y # CONFIG_BF539 is not set -# CONFIG_BF542 is not set +# CONFIG_BF542_std is not set # CONFIG_BF542M is not set -# CONFIG_BF544 is not set +# CONFIG_BF544_std is not set # CONFIG_BF544M is not set -# CONFIG_BF547 is not set +# CONFIG_BF547_std is not set # CONFIG_BF547M is not set -# CONFIG_BF548 is not set +# CONFIG_BF548_std is not set # CONFIG_BF548M is not set -# CONFIG_BF549 is not set +# CONFIG_BF549_std is not set # CONFIG_BF549M is not set # CONFIG_BF561 is not set CONFIG_BF_REV_MIN=4 @@ -246,7 +274,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y # CONFIG_TICKSOURCE_GPTMR0 is not set CONFIG_TICKSOURCE_CORETMR=y -# CONFIG_CYCLES_CLOCKSOURCE is not set +CONFIG_CYCLES_CLOCKSOURCE=y # CONFIG_GPTMR0_CLOCKSOURCE is not set CONFIG_TICK_ONESHOT=y # CONFIG_NO_HZ is not set @@ -298,7 +326,6 @@ CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_VIRT_TO_BUS=y @@ -307,16 +334,18 @@ CONFIG_BFIN_GPTIMERS=m # CONFIG_DMA_UNCACHED_4M is not set # CONFIG_DMA_UNCACHED_2M is not set CONFIG_DMA_UNCACHED_1M=y +# CONFIG_DMA_UNCACHED_512K is not set +# CONFIG_DMA_UNCACHED_256K is not set +# CONFIG_DMA_UNCACHED_128K is not set # CONFIG_DMA_UNCACHED_NONE is not set # # Cache Support # CONFIG_BFIN_ICACHE=y -# CONFIG_BFIN_ICACHE_LOCK is not set +CONFIG_BFIN_EXTMEM_ICACHEABLE=y CONFIG_BFIN_DCACHE=y # CONFIG_BFIN_DCACHE_BANKA is not set -CONFIG_BFIN_EXTMEM_ICACHEABLE=y CONFIG_BFIN_EXTMEM_DCACHEABLE=y CONFIG_BFIN_EXTMEM_WRITEBACK=y # CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set @@ -327,7 +356,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y # CONFIG_MPU is not set # -# Asynchonous Memory Configuration +# Asynchronous Memory Configuration # # @@ -383,11 +412,6 @@ CONFIG_NET=y CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -411,7 +435,6 @@ CONFIG_IP_PNP=y # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set -CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" @@ -422,6 +445,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_NETFILTER is not set # CONFIG_IP_DCCP is not set # CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -435,14 +459,34 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_LAPB is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set # CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set # # Network testing # # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set -# CONFIG_CAN is not set +CONFIG_CAN=m +CONFIG_CAN_RAW=m +CONFIG_CAN_BCM=m + +# +# CAN Device Drivers +# +# CONFIG_CAN_VCAN is not set +CONFIG_CAN_DEV=m +# CONFIG_CAN_CALC_BITTIMING is not set +CONFIG_CAN_BFIN=m +# CONFIG_CAN_SJA1000 is not set + +# +# CAN USB interfaces +# +# CONFIG_CAN_EMS_USB is not set +# CONFIG_CAN_DEBUG_DEVICES is not set CONFIG_IRDA=m # @@ -481,13 +525,8 @@ CONFIG_SIR_BFIN_DMA=y # # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set -# CONFIG_PHONET is not set -CONFIG_WIRELESS=y -# CONFIG_CFG80211 is not set -CONFIG_WIRELESS_OLD_REGULATORY=y -# CONFIG_WIRELESS_EXT is not set -# CONFIG_MAC80211 is not set -# CONFIG_IEEE80211 is not set +# CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -508,6 +547,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_CONNECTOR is not set CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set # CONFIG_MTD_CONCAT is not set CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_REDBOOT_PARTS is not set @@ -566,6 +606,7 @@ CONFIG_MTD_PHYSMAP=m # # CONFIG_MTD_DATAFLASH is not set # CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SST25L is not set # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set @@ -581,11 +622,6 @@ CONFIG_MTD_NAND=m # CONFIG_MTD_NAND_VERIFY_WRITE is not set # CONFIG_MTD_NAND_ECC_SMC is not set # CONFIG_MTD_NAND_MUSEUM_IDS is not set -CONFIG_MTD_NAND_BFIN=m -CONFIG_BFIN_NAND_BASE=0x20212000 -CONFIG_BFIN_NAND_CLE=2 -CONFIG_BFIN_NAND_ALE=1 -CONFIG_BFIN_NAND_READY=3 CONFIG_MTD_NAND_IDS=m # CONFIG_MTD_NAND_DISKONCHIP is not set # CONFIG_MTD_NAND_NANDSIM is not set @@ -593,6 +629,11 @@ CONFIG_MTD_NAND_IDS=m # CONFIG_MTD_ONENAND is not set # +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# # UBI - Unsorted block images # # CONFIG_MTD_UBI is not set @@ -643,14 +684,20 @@ CONFIG_SMSC_PHY=y # CONFIG_BROADCOM_PHY is not set # CONFIG_ICPLUS_PHY is not set # CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set # CONFIG_FIXED_PHY is not set # CONFIG_MDIO_BITBANG is not set CONFIG_NET_ETHERNET=y CONFIG_MII=y CONFIG_SMC91X=y -# CONFIG_SMSC911X is not set # CONFIG_DM9000 is not set # CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set +# CONFIG_ADF702X is not set # CONFIG_IBM_NEW_EMAC_ZMII is not set # CONFIG_IBM_NEW_EMAC_RGMII is not set # CONFIG_IBM_NEW_EMAC_TAH is not set @@ -659,15 +706,16 @@ CONFIG_SMC91X=y # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set +# CONFIG_WLAN is not set # -# Wireless LAN +# Enable WiMAX (Networking options) to see the WiMAX drivers # -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set -# CONFIG_IWLWIFI_LEDS is not set # CONFIG_WAN is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -700,14 +748,17 @@ CONFIG_INPUT_EVDEV=m # CONFIG_INPUT_JOYSTICK is not set # CONFIG_INPUT_TABLET is not set CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_ADS7846 is not set # CONFIG_TOUCHSCREEN_AD7877 is not set # CONFIG_TOUCHSCREEN_AD7879_I2C is not set CONFIG_TOUCHSCREEN_AD7879_SPI=y CONFIG_TOUCHSCREEN_AD7879=y -# CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_EETI is not set # CONFIG_TOUCHSCREEN_FUJITSU is not set # CONFIG_TOUCHSCREEN_GUNZE is not set # CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +# CONFIG_TOUCHSCREEN_MCS5000 is not set # CONFIG_TOUCHSCREEN_MTOUCH is not set # CONFIG_TOUCHSCREEN_INEXIO is not set # CONFIG_TOUCHSCREEN_MK712 is not set @@ -715,9 +766,13 @@ CONFIG_TOUCHSCREEN_AD7879=y # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set # CONFIG_TOUCHSCREEN_TOUCHWIN is not set # CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set CONFIG_INPUT_MISC=y # CONFIG_INPUT_UINPUT is not set -# CONFIG_CONFIG_INPUT_PCF8574 is not set +# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set +# CONFIG_INPUT_AD714X is not set +# CONFIG_INPUT_ADXL34X is not set +# CONFIG_INPUT_PCF8574 is not set # # Hardware I/O ports @@ -728,16 +783,13 @@ CONFIG_INPUT_MISC=y # # Character devices # -# CONFIG_AD9960 is not set CONFIG_BFIN_DMA_INTERFACE=m # CONFIG_BFIN_PPI is not set # CONFIG_BFIN_PPIFCD is not set # CONFIG_BFIN_SIMPLE_TIMER is not set # CONFIG_BFIN_SPI_ADC is not set CONFIG_BFIN_SPORT=m -# CONFIG_BFIN_TIMER_LATENCY is not set # CONFIG_BFIN_TWI_LCD is not set -CONFIG_SIMPLE_GPIO=m # CONFIG_VT is not set # CONFIG_DEVKMEM is not set CONFIG_BFIN_JTAG_COMM=m @@ -751,6 +803,7 @@ CONFIG_BFIN_JTAG_COMM=m # # Non-8250 serial port support # +# CONFIG_SERIAL_MAX3100 is not set CONFIG_SERIAL_BFIN=y CONFIG_SERIAL_BFIN_CONSOLE=y CONFIG_SERIAL_BFIN_DMA=y @@ -765,12 +818,8 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_BFIN_SPORT is not set CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set - -# -# CAN, the car bus and industrial fieldbus -# -# CONFIG_CAN4LINUX is not set # CONFIG_IPMI_HANDLER is not set # CONFIG_HW_RANDOM is not set # CONFIG_R3964 is not set @@ -778,6 +827,7 @@ CONFIG_UNIX98_PTYS=y # CONFIG_TCG_TPM is not set CONFIG_I2C=m CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y # CONFIG_I2C_CHARDEV is not set CONFIG_I2C_HELPER_AUTO=y @@ -810,14 +860,6 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100 # Miscellaneous I2C Chip support # # CONFIG_DS1682 is not set -# CONFIG_EEPROM_AT24 is not set -# CONFIG_SENSORS_AD5252 is not set -# CONFIG_EEPROM_LEGACY is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_PCF8575 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_MAX6875 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set @@ -834,13 +876,18 @@ CONFIG_SPI_BFIN=y # CONFIG_SPI_BFIN_LOCK is not set # CONFIG_SPI_BFIN_SPORT is not set # CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set # # SPI Protocol Masters # -# CONFIG_EEPROM_AT25 is not set # CONFIG_SPI_SPIDEV is not set # CONFIG_SPI_TLE62X0 is not set + +# +# PPS support +# +# CONFIG_PPS is not set CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y CONFIG_GPIOLIB=y # CONFIG_DEBUG_GPIO is not set @@ -856,6 +903,7 @@ CONFIG_GPIO_SYSFS=y # CONFIG_GPIO_MAX732X is not set # CONFIG_GPIO_PCA953X is not set # CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_ADP5588 is not set # # PCI GPIO expanders: @@ -866,11 +914,15 @@ CONFIG_GPIO_SYSFS=y # # CONFIG_GPIO_MAX7301 is not set # CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set + +# +# AC97 GPIO expanders: +# # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set # CONFIG_THERMAL is not set -# CONFIG_THERMAL_HWMON is not set CONFIG_WATCHDOG=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -892,26 +944,17 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set # CONFIG_HTC_PASIC3 is not set +# CONFIG_TPS65010 is not set # CONFIG_MFD_TMIO is not set # CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13783 is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_EZX_PCAP is not set # CONFIG_REGULATOR is not set - -# -# Multimedia devices -# - -# -# Multimedia core support -# -# CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -# CONFIG_VIDEO_MEDIA is not set - -# -# Multimedia drivers -# -# CONFIG_DAB is not set +# CONFIG_MEDIA_SUPPORT is not set # # Graphics support @@ -947,6 +990,7 @@ CONFIG_FB_BFIN_LQ035Q1=m # CONFIG_FB_VIRTUAL is not set # CONFIG_FB_METRONOME is not set # CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set # CONFIG_BACKLIGHT_LCD_SUPPORT is not set # @@ -957,14 +1001,12 @@ CONFIG_FB_BFIN_LQ035Q1=m # CONFIG_SOUND is not set CONFIG_HID_SUPPORT=y CONFIG_HID=y -# CONFIG_HID_DEBUG is not set # CONFIG_HIDRAW is not set # CONFIG_HID_PID is not set # # Special HID drivers # -CONFIG_HID_COMPAT=y # CONFIG_USB_SUPPORT is not set # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set @@ -1001,6 +1043,7 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_S35390A is not set # CONFIG_RTC_DRV_FM3130 is not set # CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set # # SPI RTC drivers @@ -1012,6 +1055,7 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_R9701 is not set # CONFIG_RTC_DRV_RS5C348 is not set # CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set # # Platform RTC drivers @@ -1032,10 +1076,21 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_BFIN=y # CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set # CONFIG_UIO is not set + +# +# TI VLYNQ +# # CONFIG_STAGING is not set # +# Firmware Drivers +# +# CONFIG_FIRMWARE_MEMMAP is not set +# CONFIG_SIGMA is not set + +# # File systems # # CONFIG_EXT2_FS is not set @@ -1044,9 +1099,13 @@ CONFIG_RTC_DRV_BFIN=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set -CONFIG_FILE_LOCKING=y # CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y # CONFIG_DNOTIFY is not set CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y @@ -1056,6 +1115,11 @@ CONFIG_INOTIFY_USER=y # CONFIG_FUSE_FS is not set # +# Caches +# +# CONFIG_FSCACHE is not set + +# # CD-ROM/DVD Filesystems # # CONFIG_ISO9660_FS is not set @@ -1074,13 +1138,9 @@ CONFIG_INOTIFY_USER=y CONFIG_PROC_FS=y CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y -# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set # CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# +CONFIG_MISC_FILESYSTEMS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set @@ -1099,17 +1159,8 @@ CONFIG_JFFS2_ZLIB=y # CONFIG_JFFS2_LZO is not set CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set -CONFIG_YAFFS_FS=m -CONFIG_YAFFS_YAFFS1=y -# CONFIG_YAFFS_9BYTE_TAGS is not set -# CONFIG_YAFFS_DOES_ECC is not set -CONFIG_YAFFS_YAFFS2=y -CONFIG_YAFFS_AUTO_YAFFS2=y -# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set -# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set -# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set -CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y # CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_OMFS_FS is not set @@ -1128,7 +1179,6 @@ CONFIG_LOCKD=m CONFIG_LOCKD_V4=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=m -# CONFIG_SUNRPC_REGISTER_V4 is not set # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set CONFIG_SMB_FS=m @@ -1193,14 +1243,19 @@ CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y CONFIG_FRAME_WARN=1024 # CONFIG_MAGIC_SYSRQ is not set +# CONFIG_STRIP_ASM_SYMS is not set # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_SECTION_MISMATCH=y CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_SHIRQ=y CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set @@ -1208,31 +1263,39 @@ CONFIG_SCHED_DEBUG=y # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y CONFIG_DEBUG_INFO=y # CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_NOMMU_REGIONS is not set # CONFIG_DEBUG_WRITECOUNT is not set # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set # CONFIG_FRAME_POINTER is not set # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set # CONFIG_FAULT_INJECTION is not set - -# -# Tracers -# -# CONFIG_SCHED_TRACER is not set -# CONFIG_CONTEXT_SWITCH_TRACER is not set -# CONFIG_BOOT_TRACER is not set -# CONFIG_DYNAMIC_PRINTK_DEBUG is not set +# CONFIG_PAGE_POISONING is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_BRANCH_PROFILE_NONE is not set +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_DYNAMIC_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set @@ -1257,6 +1320,7 @@ CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE=y CONFIG_EARLY_PRINTK=y CONFIG_CPLB_INFO=y CONFIG_ACCESS_CHECK=y +# CONFIG_BFIN_ISRAM_SELF_TEST is not set # # Security options @@ -1265,14 +1329,14 @@ CONFIG_ACCESS_CHECK=y CONFIG_SECURITY=y # CONFIG_SECURITYFS is not set # CONFIG_SECURITY_NETWORK is not set +# CONFIG_SECURITY_PATH is not set # CONFIG_SECURITY_FILE_CAPABILITIES is not set -CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0 +# CONFIG_SECURITY_TOMOYO is not set CONFIG_CRYPTO=y # # Crypto core or helper # -# CONFIG_CRYPTO_FIPS is not set # CONFIG_CRYPTO_MANAGER is not set # CONFIG_CRYPTO_MANAGER2 is not set # CONFIG_CRYPTO_GF128MUL is not set @@ -1304,11 +1368,13 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_HMAC is not set # CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set # # Digest # # CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set # CONFIG_CRYPTO_MD4 is not set # CONFIG_CRYPTO_MD5 is not set # CONFIG_CRYPTO_MICHAEL_MIC is not set @@ -1345,6 +1411,7 @@ CONFIG_CRYPTO=y # Compression # # CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set # CONFIG_CRYPTO_LZO is not set # @@ -1352,11 +1419,13 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set # # Library routines # CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y CONFIG_CRC_CCITT=m # CONFIG_CRC16 is not set # CONFIG_CRC_T10DIF is not set @@ -1366,6 +1435,8 @@ CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=m +CONFIG_DECOMPRESS_GZIP=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff --git a/arch/blackfin/configs/BF548-EZKIT_defconfig b/arch/blackfin/configs/BF548-EZKIT_defconfig index eb3e98b..ca309cf 100644 --- a/arch/blackfin/configs/BF548-EZKIT_defconfig +++ b/arch/blackfin/configs/BF548-EZKIT_defconfig @@ -1,7 +1,6 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31.5 -# Mon Nov 2 22:02:56 2009 +# Linux kernel version: 2.6.32.2 # # CONFIG_MMU is not set # CONFIG_FPU is not set @@ -12,7 +11,6 @@ CONFIG_GENERIC_CSUM=y CONFIG_GENERIC_BUG=y CONFIG_ZONE_DMA=y CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y @@ -49,11 +47,12 @@ CONFIG_SYSVIPC_SYSCTL=y # # RCU Subsystem # -CONFIG_CLASSIC_RCU=y -# CONFIG_TREE_RCU is not set -# CONFIG_PREEMPT_RCU is not set +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set # CONFIG_TREE_RCU_TRACE is not set -# CONFIG_PREEMPT_RCU_TRACE is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 @@ -89,24 +88,23 @@ CONFIG_EPOLL=y # CONFIG_AIO is not set # -# Performance Counters +# Kernel Performance Events And Counters # CONFIG_VM_EVENT_COUNTERS=y -# CONFIG_STRIP_ASM_SYMS is not set CONFIG_COMPAT_BRK=y CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set CONFIG_MMAP_ALLOW_UNINITIALIZED=y # CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y # # GCOV-based kernel profiling # # CONFIG_GCOV_KERNEL is not set -# CONFIG_SLOW_WORK is not set +CONFIG_SLOW_WORK=y +# CONFIG_SLOW_WORK_DEBUG is not set # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set CONFIG_SLABINFO=y CONFIG_BASE_SMALL=0 @@ -163,15 +161,15 @@ CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_BF537 is not set # CONFIG_BF538 is not set # CONFIG_BF539 is not set -# CONFIG_BF542 is not set +# CONFIG_BF542_std is not set # CONFIG_BF542M is not set -# CONFIG_BF544 is not set +# CONFIG_BF544_std is not set # CONFIG_BF544M is not set -# CONFIG_BF547 is not set +# CONFIG_BF547_std is not set # CONFIG_BF547M is not set CONFIG_BF548_std=y # CONFIG_BF548M is not set -# CONFIG_BF549 is not set +# CONFIG_BF549_std is not set # CONFIG_BF549M is not set # CONFIG_BF561 is not set CONFIG_BF_REV_MIN=0 @@ -185,7 +183,6 @@ CONFIG_BF_REV_0_2=y # CONFIG_BF_REV_0_6 is not set # CONFIG_BF_REV_ANY is not set # CONFIG_BF_REV_NONE is not set -CONFIG_BF54x=y CONFIG_IRQ_PLL_WAKEUP=7 CONFIG_IRQ_RTC=8 CONFIG_IRQ_SPORT0_RX=9 @@ -221,6 +218,8 @@ CONFIG_IRQ_SPI1=10 CONFIG_IRQ_SPI2=10 CONFIG_IRQ_TWI0=11 CONFIG_IRQ_TWI1=11 +CONFIG_BF548=y +CONFIG_BF54x=y CONFIG_BFIN548_EZKIT=y # CONFIG_BFIN548_BLUETECHNIX_CM is not set @@ -387,12 +386,14 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_VIRT_TO_BUS=y -CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0 CONFIG_BFIN_GPTIMERS=m # CONFIG_DMA_UNCACHED_4M is not set CONFIG_DMA_UNCACHED_2M=y # CONFIG_DMA_UNCACHED_1M is not set +# CONFIG_DMA_UNCACHED_512K is not set +# CONFIG_DMA_UNCACHED_256K is not set +# CONFIG_DMA_UNCACHED_128K is not set # CONFIG_DMA_UNCACHED_NONE is not set # @@ -505,6 +506,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_NETFILTER is not set # CONFIG_IP_DCCP is not set # CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -528,7 +530,24 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set -# CONFIG_CAN is not set +CONFIG_CAN=m +CONFIG_CAN_RAW=m +CONFIG_CAN_BCM=m + +# +# CAN Device Drivers +# +# CONFIG_CAN_VCAN is not set +CONFIG_CAN_DEV=m +# CONFIG_CAN_CALC_BITTIMING is not set +CONFIG_CAN_BFIN=m +# CONFIG_CAN_SJA1000 is not set + +# +# CAN USB interfaces +# +# CONFIG_CAN_EMS_USB is not set +# CONFIG_CAN_DEBUG_DEVICES is not set CONFIG_IRDA=m # @@ -663,6 +682,7 @@ CONFIG_MTD_PHYSMAP=y # CONFIG_MTD_DATAFLASH is not set CONFIG_MTD_M25P80=y CONFIG_M25PXX_USE_FAST_READ=y +# CONFIG_MTD_SST25L is not set # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set @@ -711,10 +731,10 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 # CONFIG_ATA_OVER_ETH is not set # CONFIG_BLK_DEV_HD is not set CONFIG_MISC_DEVICES=y +# CONFIG_AD525X_DPOT is not set # CONFIG_ICS932S401 is not set # CONFIG_ENCLOSURE_SERVICES is not set # CONFIG_ISL29003 is not set -# CONFIG_AD525X_DPOT is not set # CONFIG_C2PORT is not set # @@ -767,7 +787,8 @@ CONFIG_SCSI_WAIT_SCAN=m # CONFIG_SCSI_OSD_INITIATOR is not set CONFIG_ATA=y # CONFIG_ATA_NONSTANDARD is not set -CONFIG_SATA_PMP=y +CONFIG_ATA_VERBOSE_ERROR=y +# CONFIG_SATA_PMP is not set CONFIG_ATA_SFF=y # CONFIG_SATA_MV is not set # CONFIG_PATA_PLATFORM is not set @@ -808,6 +829,7 @@ CONFIG_MII=y # CONFIG_ETHOC is not set CONFIG_SMSC911X=y # CONFIG_DNET is not set +# CONFIG_ADF702X is not set # CONFIG_IBM_NEW_EMAC_ZMII is not set # CONFIG_IBM_NEW_EMAC_RGMII is not set # CONFIG_IBM_NEW_EMAC_TAH is not set @@ -818,12 +840,10 @@ CONFIG_SMSC911X=y # CONFIG_B44 is not set # CONFIG_KS8842 is not set # CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set - -# -# Wireless LAN -# +CONFIG_WLAN=y # CONFIG_WLAN_PRE80211 is not set CONFIG_WLAN_80211=y CONFIG_LIBERTAS=m @@ -877,10 +897,12 @@ CONFIG_INPUT_EVBUG=m CONFIG_INPUT_KEYBOARD=y # CONFIG_KEYBOARD_ADP5588 is not set # CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_QT2160 is not set CONFIG_KEYBOARD_BFIN=y # CONFIG_KEYBOARD_LKKBD is not set # CONFIG_KEYBOARD_GPIO is not set # CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_MAX7359 is not set # CONFIG_KEYBOARD_NEWTON is not set # CONFIG_KEYBOARD_OPENCORES is not set # CONFIG_KEYBOARD_STOWAWAY is not set @@ -900,6 +922,7 @@ CONFIG_TOUCHSCREEN_AD7877=m # CONFIG_TOUCHSCREEN_GUNZE is not set # CONFIG_TOUCHSCREEN_ELO is not set # CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +# CONFIG_TOUCHSCREEN_MCS5000 is not set # CONFIG_TOUCHSCREEN_MTOUCH is not set # CONFIG_TOUCHSCREEN_INEXIO is not set # CONFIG_TOUCHSCREEN_MK712 is not set @@ -910,7 +933,6 @@ CONFIG_TOUCHSCREEN_AD7877=m # CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set # CONFIG_TOUCHSCREEN_TOUCHIT213 is not set # CONFIG_TOUCHSCREEN_TSC2007 is not set -# CONFIG_TOUCHSCREEN_W90X900 is not set CONFIG_INPUT_MISC=y # CONFIG_INPUT_ATI_REMOTE is not set # CONFIG_INPUT_ATI_REMOTE2 is not set @@ -976,11 +998,6 @@ CONFIG_UNIX98_PTYS=y # CONFIG_LEGACY_PTYS is not set CONFIG_BFIN_OTP=y # CONFIG_BFIN_OTP_WRITE_ENABLE is not set - -# -# CAN, the car bus and industrial fieldbus -# -# CONFIG_CAN4LINUX is not set # CONFIG_IPMI_HANDLER is not set # CONFIG_HW_RANDOM is not set # CONFIG_R3964 is not set @@ -988,6 +1005,7 @@ CONFIG_BFIN_OTP=y # CONFIG_TCG_TPM is not set CONFIG_I2C=y CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_HELPER_AUTO=y @@ -1021,9 +1039,6 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100 # Miscellaneous I2C Chip support # # CONFIG_DS1682 is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_PCF8575 is not set -# CONFIG_SENSORS_PCA9539 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set @@ -1078,11 +1093,15 @@ CONFIG_GPIO_SYSFS=y # # CONFIG_GPIO_MAX7301 is not set # CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set + +# +# AC97 GPIO expanders: +# # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set # CONFIG_THERMAL is not set -# CONFIG_THERMAL_HWMON is not set CONFIG_WATCHDOG=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -1116,8 +1135,10 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_PMIC_DA903X is not set # CONFIG_PMIC_ADP5520 is not set # CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set # CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13783 is not set # CONFIG_AB3100_CORE is not set # CONFIG_EZX_PCAP is not set # CONFIG_REGULATOR is not set @@ -1192,6 +1213,7 @@ CONFIG_LOGO=y CONFIG_LOGO_BLACKFIN_CLUT224=y CONFIG_SOUND=y CONFIG_SOUND_OSS_CORE=y +CONFIG_SOUND_OSS_CORE_PRECLAIM=y CONFIG_SND=y CONFIG_SND_TIMER=y CONFIG_SND_PCM=y @@ -1245,7 +1267,6 @@ CONFIG_SND_SOC_AD1980=y CONFIG_AC97_BUS=y CONFIG_HID_SUPPORT=y CONFIG_HID=y -# CONFIG_HID_DEBUG is not set # CONFIG_HIDRAW is not set # @@ -1268,6 +1289,7 @@ CONFIG_HID_CYPRESS=y CONFIG_HID_EZKEY=y # CONFIG_HID_KYE is not set CONFIG_HID_GYRATION=y +# CONFIG_HID_TWINHAN is not set # CONFIG_HID_KENSINGTON is not set CONFIG_HID_LOGITECH=y # CONFIG_LOGITECH_FF is not set @@ -1422,10 +1444,11 @@ CONFIG_MMC_BLOCK_BOUNCE=y # MMC/SD/SDIO Host Controller Drivers # # CONFIG_MMC_SDHCI is not set +# CONFIG_MMC_AT91 is not set +# CONFIG_MMC_ATMELMCI is not set +# CONFIG_MMC_SPI is not set CONFIG_SDH_BFIN=y # CONFIG_SDH_BFIN_MISSING_CMD_PULLUP_WORKAROUND is not set -# CONFIG_SDH_BFIN_ENABLE_SDIO_IRQ is not set -# CONFIG_MMC_SPI is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set # CONFIG_ACCESSIBILITY is not set @@ -1472,6 +1495,7 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_R9701 is not set # CONFIG_RTC_DRV_RS5C348 is not set # CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set # # Platform RTC drivers @@ -1522,6 +1546,7 @@ CONFIG_FS_MBCACHE=y # CONFIG_XFS_FS is not set # CONFIG_OCFS2_FS is not set # CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_FILE_LOCKING=y CONFIG_FSNOTIFY=y # CONFIG_DNOTIFY is not set @@ -1563,7 +1588,6 @@ CONFIG_NTFS_RW=y CONFIG_PROC_FS=y CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y -# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set # CONFIG_CONFIGFS_FS is not set CONFIG_MISC_FILESYSTEMS=y @@ -1595,7 +1619,6 @@ CONFIG_JFFS2_RTIME=y # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set -# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=m CONFIG_NFS_V3=y @@ -1680,6 +1703,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y CONFIG_FRAME_WARN=1024 # CONFIG_MAGIC_SYSRQ is not set +# CONFIG_STRIP_ASM_SYMS is not set # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set @@ -1714,12 +1738,14 @@ CONFIG_DEBUG_INFO=y # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set # CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set # CONFIG_FRAME_POINTER is not set # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_PAGE_POISONING is not set CONFIG_HAVE_FUNCTION_TRACER=y @@ -1730,7 +1756,6 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set -# CONFIG_KMEMCHECK is not set # CONFIG_DEBUG_STACKOVERFLOW is not set # CONFIG_DEBUG_STACK_USAGE is not set CONFIG_DEBUG_VERBOSE=y @@ -1766,7 +1791,6 @@ CONFIG_CRYPTO=y # # Crypto core or helper # -# CONFIG_CRYPTO_FIPS is not set # CONFIG_CRYPTO_MANAGER is not set # CONFIG_CRYPTO_MANAGER2 is not set # CONFIG_CRYPTO_GF128MUL is not set @@ -1798,11 +1822,13 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_HMAC is not set # CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set # # Digest # # CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set # CONFIG_CRYPTO_MD4 is not set # CONFIG_CRYPTO_MD5 is not set # CONFIG_CRYPTO_MICHAEL_MIC is not set diff --git a/arch/blackfin/configs/BF561-ACVILON_defconfig b/arch/blackfin/configs/BF561-ACVILON_defconfig index b9b0f93..6a776ce 100644 --- a/arch/blackfin/configs/BF561-ACVILON_defconfig +++ b/arch/blackfin/configs/BF561-ACVILON_defconfig @@ -114,7 +114,7 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_BLOCK=y -CONFIG_LBDAF=y +# CONFIG_LBDAF is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -1486,19 +1486,10 @@ CONFIG_DEBUG_INFO=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_TRACING_SUPPORT=y -CONFIG_FTRACE=y -# CONFIG_FUNCTION_TRACER is not set -# CONFIG_IRQSOFF_TRACER is not set -# CONFIG_SCHED_TRACER is not set -# CONFIG_ENABLE_DEFAULT_TRACERS is not set -# CONFIG_BOOT_TRACER is not set -CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_FTRACE is not set +# CONFIG_BRANCH_PROFILE_NONE is not set # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set # CONFIG_PROFILE_ALL_BRANCHES is not set -# CONFIG_STACK_TRACER is not set -# CONFIG_KMEMTRACE is not set -# CONFIG_WORKQUEUE_TRACER is not set -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_DYNAMIC_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y diff --git a/arch/blackfin/configs/BF561-EZKIT_defconfig b/arch/blackfin/configs/BF561-EZKIT_defconfig index e3ecdcc..792ff09 100644 --- a/arch/blackfin/configs/BF561-EZKIT_defconfig +++ b/arch/blackfin/configs/BF561-EZKIT_defconfig @@ -1,7 +1,6 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.31.5 -# Mon Nov 2 21:59:31 2009 +# Linux kernel version: 2.6.32.2 # # CONFIG_MMU is not set # CONFIG_FPU is not set @@ -12,7 +11,6 @@ CONFIG_GENERIC_CSUM=y CONFIG_GENERIC_BUG=y CONFIG_ZONE_DMA=y CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y @@ -49,11 +47,12 @@ CONFIG_SYSVIPC_SYSCTL=y # # RCU Subsystem # -CONFIG_CLASSIC_RCU=y -# CONFIG_TREE_RCU is not set -# CONFIG_PREEMPT_RCU is not set +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set # CONFIG_TREE_RCU_TRACE is not set -# CONFIG_PREEMPT_RCU_TRACE is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 @@ -89,17 +88,15 @@ CONFIG_EPOLL=y # CONFIG_AIO is not set # -# Performance Counters +# Kernel Performance Events And Counters # CONFIG_VM_EVENT_COUNTERS=y -# CONFIG_STRIP_ASM_SYMS is not set CONFIG_COMPAT_BRK=y CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set CONFIG_MMAP_ALLOW_UNINITIALIZED=y # CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y # @@ -163,15 +160,15 @@ CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_BF537 is not set # CONFIG_BF538 is not set # CONFIG_BF539 is not set -# CONFIG_BF542 is not set +# CONFIG_BF542_std is not set # CONFIG_BF542M is not set -# CONFIG_BF544 is not set +# CONFIG_BF544_std is not set # CONFIG_BF544M is not set -# CONFIG_BF547 is not set +# CONFIG_BF547_std is not set # CONFIG_BF547M is not set -# CONFIG_BF548 is not set +# CONFIG_BF548_std is not set # CONFIG_BF548M is not set -# CONFIG_BF549 is not set +# CONFIG_BF549_std is not set # CONFIG_BF549M is not set CONFIG_BF561=y # CONFIG_SMP is not set @@ -180,9 +177,9 @@ CONFIG_BF_REV_MAX=5 # CONFIG_BF_REV_0_0 is not set # CONFIG_BF_REV_0_1 is not set # CONFIG_BF_REV_0_2 is not set -# CONFIG_BF_REV_0_3 is not set +CONFIG_BF_REV_0_3=y # CONFIG_BF_REV_0_4 is not set -CONFIG_BF_REV_0_5=y +# CONFIG_BF_REV_0_5 is not set # CONFIG_BF_REV_0_6 is not set # CONFIG_BF_REV_ANY is not set # CONFIG_BF_REV_NONE is not set @@ -298,7 +295,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y # CONFIG_TICKSOURCE_GPTMR0 is not set CONFIG_TICKSOURCE_CORETMR=y -# CONFIG_CYCLES_CLOCKSOURCE is not set +CONFIG_CYCLES_CLOCKSOURCE=y # CONFIG_GPTMR0_CLOCKSOURCE is not set CONFIG_TICK_ONESHOT=y # CONFIG_NO_HZ is not set @@ -353,12 +350,14 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_VIRT_TO_BUS=y -CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0 CONFIG_BFIN_GPTIMERS=m # CONFIG_DMA_UNCACHED_4M is not set # CONFIG_DMA_UNCACHED_2M is not set CONFIG_DMA_UNCACHED_1M=y +# CONFIG_DMA_UNCACHED_512K is not set +# CONFIG_DMA_UNCACHED_256K is not set +# CONFIG_DMA_UNCACHED_128K is not set # CONFIG_DMA_UNCACHED_NONE is not set # @@ -370,9 +369,11 @@ CONFIG_BFIN_EXTMEM_ICACHEABLE=y CONFIG_BFIN_DCACHE=y # CONFIG_BFIN_DCACHE_BANKA is not set CONFIG_BFIN_EXTMEM_DCACHEABLE=y -CONFIG_BFIN_EXTMEM_WRITEBACK=y -# CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set -# CONFIG_BFIN_L2_DCACHEABLE is not set +# CONFIG_BFIN_EXTMEM_WRITEBACK is not set +CONFIG_BFIN_EXTMEM_WRITETHROUGH=y +CONFIG_BFIN_L2_DCACHEABLE=y +# CONFIG_BFIN_L2_WRITEBACK is not set +CONFIG_BFIN_L2_WRITETHROUGH=y # # Memory Protection Unit @@ -472,6 +473,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_NETFILTER is not set # CONFIG_IP_DCCP is not set # CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -613,6 +615,7 @@ CONFIG_MTD_PHYSMAP=m # # CONFIG_MTD_DATAFLASH is not set # CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SST25L is not set # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set @@ -685,6 +688,7 @@ CONFIG_SMC91X=y # CONFIG_ETHOC is not set # CONFIG_SMSC911X is not set # CONFIG_DNET is not set +# CONFIG_ADF702X is not set # CONFIG_IBM_NEW_EMAC_ZMII is not set # CONFIG_IBM_NEW_EMAC_RGMII is not set # CONFIG_IBM_NEW_EMAC_TAH is not set @@ -695,14 +699,10 @@ CONFIG_SMC91X=y # CONFIG_B44 is not set # CONFIG_KS8842 is not set # CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set - -# -# Wireless LAN -# -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_WLAN is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers @@ -782,11 +782,6 @@ CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set - -# -# CAN, the car bus and industrial fieldbus -# -# CONFIG_CAN4LINUX is not set # CONFIG_IPMI_HANDLER is not set # CONFIG_HW_RANDOM is not set # CONFIG_R3964 is not set @@ -838,11 +833,15 @@ CONFIG_GPIO_SYSFS=y # # CONFIG_GPIO_MAX7301 is not set # CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set + +# +# AC97 GPIO expanders: +# # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set # CONFIG_THERMAL is not set -# CONFIG_THERMAL_HWMON is not set CONFIG_WATCHDOG=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -865,6 +864,7 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_SM501 is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set +# CONFIG_MFD_MC13783 is not set # CONFIG_EZX_PCAP is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -884,7 +884,6 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_SOUND is not set CONFIG_HID_SUPPORT=y CONFIG_HID=m -# CONFIG_HID_DEBUG is not set # CONFIG_HIDRAW is not set # CONFIG_HID_PID is not set @@ -923,6 +922,7 @@ CONFIG_HID=m # CONFIG_XFS_FS is not set # CONFIG_OCFS2_FS is not set # CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_FILE_LOCKING=y CONFIG_FSNOTIFY=y # CONFIG_DNOTIFY is not set @@ -957,7 +957,6 @@ CONFIG_INOTIFY_USER=y CONFIG_PROC_FS=y CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y -# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set # CONFIG_CONFIGFS_FS is not set CONFIG_MISC_FILESYSTEMS=y @@ -989,7 +988,6 @@ CONFIG_JFFS2_RTIME=y # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set -# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=m CONFIG_NFS_V3=y @@ -1064,6 +1062,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y CONFIG_FRAME_WARN=1024 # CONFIG_MAGIC_SYSRQ is not set +# CONFIG_STRIP_ASM_SYMS is not set # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set @@ -1098,26 +1097,24 @@ CONFIG_DEBUG_INFO=y # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set # CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set # CONFIG_FRAME_POINTER is not set # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_PAGE_POISONING is not set CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_TRACING_SUPPORT=y # CONFIG_FTRACE is not set -# CONFIG_BRANCH_PROFILE_NONE is not set -# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set -# CONFIG_PROFILE_ALL_BRANCHES is not set # CONFIG_DYNAMIC_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set -# CONFIG_KMEMCHECK is not set # CONFIG_DEBUG_STACKOVERFLOW is not set # CONFIG_DEBUG_STACK_USAGE is not set CONFIG_DEBUG_VERBOSE=y @@ -1153,7 +1150,6 @@ CONFIG_CRYPTO=y # # Crypto core or helper # -# CONFIG_CRYPTO_FIPS is not set # CONFIG_CRYPTO_MANAGER is not set # CONFIG_CRYPTO_MANAGER2 is not set # CONFIG_CRYPTO_GF128MUL is not set @@ -1185,11 +1181,13 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_HMAC is not set # CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set # # Digest # # CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set # CONFIG_CRYPTO_MD4 is not set # CONFIG_CRYPTO_MD5 is not set # CONFIG_CRYPTO_MICHAEL_MIC is not set diff --git a/arch/blackfin/configs/H8606_defconfig b/arch/blackfin/configs/H8606_defconfig index bc7fae3..ed0a7eb 100644 --- a/arch/blackfin/configs/H8606_defconfig +++ b/arch/blackfin/configs/H8606_defconfig @@ -834,13 +834,6 @@ CONFIG_SND_VERBOSE_PROCFS=y # # ALSA Blackfin devices # -CONFIG_SND_BLACKFIN_AD1836=m -CONFIG_SND_BLACKFIN_AD1836_TDM=y -# CONFIG_SND_BLACKFIN_AD1836_I2S is not set -CONFIG_SND_BLACKFIN_AD1836_MULSUB=y -# CONFIG_SND_BLACKFIN_AD1836_5P1 is not set -CONFIG_SND_BLACKFIN_SPORT=0 -CONFIG_SND_BLACKFIN_SPI_PFBIT=4 # CONFIG_SND_BFIN_AD73311 is not set # diff --git a/arch/blackfin/configs/PNAV-10_defconfig b/arch/blackfin/configs/PNAV-10_defconfig index 67d1276..ad58fed 100644 --- a/arch/blackfin/configs/PNAV-10_defconfig +++ b/arch/blackfin/configs/PNAV-10_defconfig @@ -1,21 +1,27 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.28.10 +# Linux kernel version: 2.6.32.2 # # CONFIG_MMU is not set # CONFIG_FPU is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_BLACKFIN=y +CONFIG_GENERIC_CSUM=y +CONFIG_GENERIC_BUG=y CONFIG_ZONE_DMA=y CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y CONFIG_GENERIC_GPIO=y CONFIG_FORCE_MAX_ZONEORDER=14 CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y # # General setup @@ -25,16 +31,32 @@ CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_BZIP2=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set # CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set # CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set # CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set @@ -58,6 +80,10 @@ CONFIG_SIGNALFD=y CONFIG_TIMERFD=y CONFIG_EVENTFD=y # CONFIG_AIO is not set + +# +# Kernel Performance Events And Counters +# CONFIG_VM_EVENT_COUNTERS=y CONFIG_COMPAT_BRK=y CONFIG_SLAB=y @@ -65,11 +91,14 @@ CONFIG_SLAB=y # CONFIG_SLOB is not set CONFIG_MMAP_ALLOW_UNINITIALIZED=y # CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y + +# +# GCOV-based kernel profiling +# +# CONFIG_SLOW_WORK is not set # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set CONFIG_SLABINFO=y -CONFIG_TINY_SHMEM=y CONFIG_BASE_SMALL=0 CONFIG_MODULES=y # CONFIG_MODULE_FORCE_LOAD is not set @@ -77,11 +106,8 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set +# CONFIG_LBDAF is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -97,7 +123,6 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" -CONFIG_CLASSIC_RCU=y # CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set @@ -128,15 +153,15 @@ CONFIG_PREEMPT_VOLUNTARY=y CONFIG_BF537=y # CONFIG_BF538 is not set # CONFIG_BF539 is not set -# CONFIG_BF542 is not set +# CONFIG_BF542_std is not set # CONFIG_BF542M is not set -# CONFIG_BF544 is not set +# CONFIG_BF544_std is not set # CONFIG_BF544M is not set -# CONFIG_BF547 is not set +# CONFIG_BF547_std is not set # CONFIG_BF547M is not set -# CONFIG_BF548 is not set +# CONFIG_BF548_std is not set # CONFIG_BF548M is not set -# CONFIG_BF549 is not set +# CONFIG_BF549_std is not set # CONFIG_BF549M is not set # CONFIG_BF561 is not set CONFIG_BF_REV_MIN=2 @@ -180,7 +205,8 @@ CONFIG_IRQ_MEM_DMA1=13 CONFIG_IRQ_WATCH=13 CONFIG_IRQ_SPI=10 # CONFIG_BFIN537_STAMP is not set -# CONFIG_BFIN537_BLUETECHNIX_CM is not set +# CONFIG_BFIN537_BLUETECHNIX_CM_E is not set +# CONFIG_BFIN537_BLUETECHNIX_CM_U is not set # CONFIG_BFIN537_BLUETECHNIX_TCM is not set CONFIG_PNAV10=y # CONFIG_CAMSIG_MINOTAUR is not set @@ -282,7 +308,6 @@ CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 CONFIG_VIRT_TO_BUS=y @@ -291,16 +316,18 @@ CONFIG_BFIN_GPTIMERS=y # CONFIG_DMA_UNCACHED_4M is not set # CONFIG_DMA_UNCACHED_2M is not set CONFIG_DMA_UNCACHED_1M=y +# CONFIG_DMA_UNCACHED_512K is not set +# CONFIG_DMA_UNCACHED_256K is not set +# CONFIG_DMA_UNCACHED_128K is not set # CONFIG_DMA_UNCACHED_NONE is not set # # Cache Support # CONFIG_BFIN_ICACHE=y -# CONFIG_BFIN_ICACHE_LOCK is not set +CONFIG_BFIN_EXTMEM_ICACHEABLE=y CONFIG_BFIN_DCACHE=y # CONFIG_BFIN_DCACHE_BANKA is not set -CONFIG_BFIN_EXTMEM_ICACHEABLE=y CONFIG_BFIN_EXTMEM_DCACHEABLE=y CONFIG_BFIN_EXTMEM_WRITEBACK=y # CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set @@ -311,7 +338,7 @@ CONFIG_BFIN_EXTMEM_WRITEBACK=y # CONFIG_MPU is not set # -# Asynchonous Memory Configuration +# Asynchronous Memory Configuration # # @@ -367,11 +394,6 @@ CONFIG_NET=y CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -395,7 +417,6 @@ CONFIG_IP_PNP=y # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set -CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" @@ -406,6 +427,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_NETFILTER is not set # CONFIG_IP_DCCP is not set # CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -419,7 +441,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_LAPB is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set # CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set # # Network testing @@ -430,13 +455,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set -# CONFIG_PHONET is not set -CONFIG_WIRELESS=y -# CONFIG_CFG80211 is not set -CONFIG_WIRELESS_OLD_REGULATORY=y -# CONFIG_WIRELESS_EXT is not set -# CONFIG_MAC80211 is not set -# CONFIG_IEEE80211 is not set +# CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -455,6 +475,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_CONNECTOR is not set CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set # CONFIG_MTD_CONCAT is not set CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_REDBOOT_PARTS is not set @@ -506,6 +527,7 @@ CONFIG_MTD_UCLINUX=y # # CONFIG_MTD_DATAFLASH is not set # CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SST25L is not set # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set @@ -521,11 +543,6 @@ CONFIG_MTD_NAND=y # CONFIG_MTD_NAND_VERIFY_WRITE is not set # CONFIG_MTD_NAND_ECC_SMC is not set # CONFIG_MTD_NAND_MUSEUM_IDS is not set -CONFIG_MTD_NAND_BFIN=y -CONFIG_BFIN_NAND_BASE=0x20100000 -CONFIG_BFIN_NAND_CLE=2 -CONFIG_BFIN_NAND_ALE=1 -CONFIG_BFIN_NAND_READY=44 CONFIG_MTD_NAND_IDS=y # CONFIG_MTD_NAND_DISKONCHIP is not set # CONFIG_MTD_NAND_NANDSIM is not set @@ -533,6 +550,11 @@ CONFIG_MTD_NAND_IDS=y # CONFIG_MTD_ONENAND is not set # +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# # UBI - Unsorted block images # # CONFIG_MTD_UBI is not set @@ -549,10 +571,20 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 # CONFIG_ATA_OVER_ETH is not set # CONFIG_BLK_DEV_HD is not set CONFIG_MISC_DEVICES=y -# CONFIG_EEPROM_93CX6 is not set +# CONFIG_AD525X_DPOT is not set # CONFIG_ICS932S401 is not set # CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_ISL29003 is not set # CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EEPROM_93CX6 is not set CONFIG_HAVE_IDE=y # CONFIG_IDE is not set @@ -587,6 +619,9 @@ CONFIG_PHYLIB=y # CONFIG_BROADCOM_PHY is not set # CONFIG_ICPLUS_PHY is not set # CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set # CONFIG_FIXED_PHY is not set # CONFIG_MDIO_BITBANG is not set CONFIG_NET_ETHERNET=y @@ -597,9 +632,12 @@ CONFIG_BFIN_TX_DESC_NUM=100 CONFIG_BFIN_RX_DESC_NUM=100 CONFIG_BFIN_MAC_RMII=y # CONFIG_SMC91X is not set -# CONFIG_SMSC911X is not set # CONFIG_DM9000 is not set # CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set +# CONFIG_ADF702X is not set # CONFIG_IBM_NEW_EMAC_ZMII is not set # CONFIG_IBM_NEW_EMAC_RGMII is not set # CONFIG_IBM_NEW_EMAC_TAH is not set @@ -608,15 +646,16 @@ CONFIG_BFIN_MAC_RMII=y # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set +# CONFIG_WLAN is not set # -# Wireless LAN +# Enable WiMAX (Networking options) to see the WiMAX drivers # -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set -# CONFIG_IWLWIFI_LEDS is not set # CONFIG_WAN is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -649,14 +688,17 @@ CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_JOYSTICK is not set # CONFIG_INPUT_TABLET is not set CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_ADS7846 is not set CONFIG_TOUCHSCREEN_AD7877=y # CONFIG_TOUCHSCREEN_AD7879_I2C is not set # CONFIG_TOUCHSCREEN_AD7879_SPI is not set # CONFIG_TOUCHSCREEN_AD7879 is not set -# CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_EETI is not set # CONFIG_TOUCHSCREEN_FUJITSU is not set # CONFIG_TOUCHSCREEN_GUNZE is not set # CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +# CONFIG_TOUCHSCREEN_MCS5000 is not set # CONFIG_TOUCHSCREEN_MTOUCH is not set # CONFIG_TOUCHSCREEN_INEXIO is not set # CONFIG_TOUCHSCREEN_MK712 is not set @@ -665,6 +707,7 @@ CONFIG_TOUCHSCREEN_AD7877=y # CONFIG_TOUCHSCREEN_TOUCHWIN is not set # CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set # CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set CONFIG_INPUT_MISC=y # CONFIG_INPUT_ATI_REMOTE is not set # CONFIG_INPUT_ATI_REMOTE2 is not set @@ -673,7 +716,9 @@ CONFIG_INPUT_MISC=y # CONFIG_INPUT_YEALINK is not set # CONFIG_INPUT_CM109 is not set CONFIG_INPUT_UINPUT=y -# CONFIG_CONFIG_INPUT_PCF8574 is not set +# CONFIG_INPUT_AD714X is not set +# CONFIG_INPUT_ADXL34X is not set +# CONFIG_INPUT_PCF8574 is not set # # Hardware I/O ports @@ -684,16 +729,13 @@ CONFIG_INPUT_UINPUT=y # # Character devices # -# CONFIG_AD9960 is not set CONFIG_BFIN_DMA_INTERFACE=m # CONFIG_BFIN_PPI is not set # CONFIG_BFIN_PPIFCD is not set # CONFIG_BFIN_SIMPLE_TIMER is not set # CONFIG_BFIN_SPI_ADC is not set CONFIG_BFIN_SPORT=y -# CONFIG_BFIN_TIMER_LATENCY is not set # CONFIG_BFIN_TWI_LCD is not set -# CONFIG_SIMPLE_GPIO is not set # CONFIG_VT is not set CONFIG_DEVKMEM=y # CONFIG_BFIN_JTAG_COMM is not set @@ -707,6 +749,7 @@ CONFIG_DEVKMEM=y # # Non-8250 serial port support # +# CONFIG_SERIAL_MAX3100 is not set CONFIG_SERIAL_BFIN=y CONFIG_SERIAL_BFIN_CONSOLE=y CONFIG_SERIAL_BFIN_DMA=y @@ -719,24 +762,17 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_BFIN_SPORT is not set CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set - -# -# CAN, the car bus and industrial fieldbus -# -CONFIG_CAN4LINUX=y - -# -# linux embedded drivers -# -CONFIG_CAN_BLACKFIN=m # CONFIG_IPMI_HANDLER is not set CONFIG_HW_RANDOM=y +# CONFIG_HW_RANDOM_TIMERIOMEM is not set # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set # CONFIG_TCG_TPM is not set CONFIG_I2C=y CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_HELPER_AUTO=y @@ -769,14 +805,6 @@ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100 # Miscellaneous I2C Chip support # # CONFIG_DS1682 is not set -# CONFIG_EEPROM_AT24 is not set -# CONFIG_SENSORS_AD5252 is not set -# CONFIG_EEPROM_LEGACY is not set -CONFIG_SENSORS_PCF8574=m -# CONFIG_PCF8575 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_MAX6875 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set @@ -792,20 +820,29 @@ CONFIG_SPI_BFIN=y # CONFIG_SPI_BFIN_LOCK is not set # CONFIG_SPI_BFIN_SPORT is not set # CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set # # SPI Protocol Masters # -# CONFIG_EEPROM_AT25 is not set # CONFIG_SPI_SPIDEV is not set # CONFIG_SPI_TLE62X0 is not set + +# +# PPS support +# +# CONFIG_PPS is not set CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y # CONFIG_GPIOLIB is not set # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set CONFIG_HWMON=y # CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_AD5252 is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Native drivers +# # CONFIG_SENSORS_AD7414 is not set # CONFIG_SENSORS_AD7418 is not set # CONFIG_SENSORS_ADCXX is not set @@ -818,11 +855,13 @@ CONFIG_HWMON=y # CONFIG_SENSORS_ADT7462 is not set # CONFIG_SENSORS_ADT7470 is not set # CONFIG_SENSORS_ADT7473 is not set +# CONFIG_SENSORS_ADT7475 is not set # CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS1621 is not set # CONFIG_SENSORS_F71805F is not set # CONFIG_SENSORS_F71882FG is not set # CONFIG_SENSORS_F75375S is not set +# CONFIG_SENSORS_G760A is not set # CONFIG_SENSORS_GL518SM is not set # CONFIG_SENSORS_GL520SM is not set # CONFIG_SENSORS_IT87 is not set @@ -838,17 +877,24 @@ CONFIG_HWMON=y # CONFIG_SENSORS_LM90 is not set # CONFIG_SENSORS_LM92 is not set # CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_LTC4215 is not set +# CONFIG_SENSORS_LTC4245 is not set +# CONFIG_SENSORS_LM95241 is not set # CONFIG_SENSORS_MAX1111 is not set # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_MAX6650 is not set # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_SHT15 is not set # CONFIG_SENSORS_DME1737 is not set # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_SMSC47M192 is not set # CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_ADS7828 is not set # CONFIG_SENSORS_THMC50 is not set +# CONFIG_SENSORS_TMP401 is not set +# CONFIG_SENSORS_TMP421 is not set # CONFIG_SENSORS_VT1211 is not set # CONFIG_SENSORS_W83781D is not set # CONFIG_SENSORS_W83791D is not set @@ -858,9 +904,8 @@ CONFIG_HWMON=y # CONFIG_SENSORS_W83L786NG is not set # CONFIG_SENSORS_W83627HF is not set # CONFIG_SENSORS_W83627EHF is not set -# CONFIG_HWMON_DEBUG_CHIP is not set +# CONFIG_SENSORS_LIS3_SPI is not set # CONFIG_THERMAL is not set -# CONFIG_THERMAL_HWMON is not set # CONFIG_WATCHDOG is not set CONFIG_SSB_POSSIBLE=y @@ -875,28 +920,19 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set # CONFIG_HTC_PASIC3 is not set +# CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set # CONFIG_PMIC_ADP5520 is not set # CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13783 is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_EZX_PCAP is not set # CONFIG_REGULATOR is not set - -# -# Multimedia devices -# - -# -# Multimedia core support -# -# CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -# CONFIG_VIDEO_MEDIA is not set - -# -# Multimedia drivers -# -CONFIG_DAB=y +# CONFIG_MEDIA_SUPPORT is not set # # Graphics support @@ -928,24 +964,24 @@ CONFIG_FB_CFB_IMAGEBLIT=y # CONFIG_FB_BFIN_T350MCQB is not set # CONFIG_FB_BFIN_LQ035Q1 is not set CONFIG_FB_BF537_LQ035=y -CONFIG_LQ035_SLAVE_ADDR=0x58 -CONFIG_FB_BFIN_LANDSCAPE=y -# CONFIG_FB_BFIN_BGR is not set # CONFIG_FB_BFIN_7393 is not set # CONFIG_FB_HITACHI_TX09 is not set # CONFIG_FB_S1D13XXX is not set # CONFIG_FB_VIRTUAL is not set # CONFIG_FB_METRONOME is not set # CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_LCD_CLASS_DEVICE=y +# CONFIG_LCD_LMS283GF05 is not set # CONFIG_LCD_LTV350QV is not set # CONFIG_LCD_ILI9320 is not set # CONFIG_LCD_TDO24M is not set # CONFIG_LCD_VGG2432A4 is not set # CONFIG_LCD_PLATFORM is not set CONFIG_BACKLIGHT_CLASS_DEVICE=y -# CONFIG_BACKLIGHT_CORGI is not set +CONFIG_BACKLIGHT_GENERIC=y +# CONFIG_BACKLIGHT_ADP8870 is not set # # Display device support @@ -954,6 +990,7 @@ CONFIG_BACKLIGHT_CLASS_DEVICE=y # CONFIG_LOGO is not set CONFIG_SOUND=y CONFIG_SOUND_OSS_CORE=y +CONFIG_SOUND_OSS_CORE_PRECLAIM=y CONFIG_SND=m # CONFIG_SND_SEQUENCER is not set # CONFIG_SND_MIXER_OSS is not set @@ -963,6 +1000,11 @@ CONFIG_SND=m # CONFIG_SND_VERBOSE_PROCFS is not set # CONFIG_SND_VERBOSE_PRINTK is not set # CONFIG_SND_DEBUG is not set +# CONFIG_SND_RAWMIDI_SEQ is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set CONFIG_SND_DRIVERS=y # CONFIG_SND_DUMMY is not set # CONFIG_SND_MTPAV is not set @@ -973,7 +1015,6 @@ CONFIG_SND_SPI=y # # ALSA Blackfin devices # -# CONFIG_SND_BLACKFIN_AD1836 is not set # CONFIG_SND_BFIN_AD73322 is not set # CONFIG_SND_SOC is not set CONFIG_SOUND_PRIME=y @@ -993,9 +1034,13 @@ CONFIG_USB_ARCH_HAS_HCD=y # # -# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may # # CONFIG_USB_GADGET is not set + +# +# OTG and related infrastructure +# # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set @@ -1031,6 +1076,7 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_S35390A is not set # CONFIG_RTC_DRV_FM3130 is not set # CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set # # SPI RTC drivers @@ -1042,6 +1088,7 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_R9701 is not set # CONFIG_RTC_DRV_RS5C348 is not set # CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set # # Platform RTC drivers @@ -1062,10 +1109,21 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_BFIN=y # CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set # CONFIG_UIO is not set + +# +# TI VLYNQ +# # CONFIG_STAGING is not set # +# Firmware Drivers +# +# CONFIG_FIRMWARE_MEMMAP is not set +# CONFIG_SIGMA is not set + +# # File systems # CONFIG_EXT2_FS=y @@ -1078,9 +1136,13 @@ CONFIG_FS_MBCACHE=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set -CONFIG_FILE_LOCKING=y # CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y # CONFIG_DNOTIFY is not set CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y @@ -1090,6 +1152,11 @@ CONFIG_INOTIFY_USER=y # CONFIG_FUSE_FS is not set # +# Caches +# +# CONFIG_FSCACHE is not set + +# # CD-ROM/DVD Filesystems # # CONFIG_ISO9660_FS is not set @@ -1108,13 +1175,9 @@ CONFIG_INOTIFY_USER=y CONFIG_PROC_FS=y CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y -# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set # CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# +CONFIG_MISC_FILESYSTEMS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set @@ -1123,17 +1186,8 @@ CONFIG_SYSFS=y # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set # CONFIG_JFFS2_FS is not set -CONFIG_YAFFS_FS=y -CONFIG_YAFFS_YAFFS1=y -# CONFIG_YAFFS_9BYTE_TAGS is not set -# CONFIG_YAFFS_DOES_ECC is not set -CONFIG_YAFFS_YAFFS2=y -CONFIG_YAFFS_AUTO_YAFFS2=y -# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set -# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set -# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set -CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y # CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_OMFS_FS is not set @@ -1152,7 +1206,6 @@ CONFIG_LOCKD=m CONFIG_LOCKD_V4=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=m -# CONFIG_SUNRPC_REGISTER_V4 is not set # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set CONFIG_SMB_FS=m @@ -1217,18 +1270,19 @@ CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y CONFIG_FRAME_WARN=1024 # CONFIG_MAGIC_SYSRQ is not set +# CONFIG_STRIP_ASM_SYMS is not set # CONFIG_UNUSED_SYMBOLS is not set # CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_SECTION_MISMATCH=y # CONFIG_DEBUG_KERNEL is not set # CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set - -# -# Tracers -# -# CONFIG_DYNAMIC_PRINTK_DEBUG is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y CONFIG_DEBUG_VERBOSE=y @@ -1245,6 +1299,7 @@ CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=0 # CONFIG_EARLY_PRINTK is not set # CONFIG_CPLB_INFO is not set # CONFIG_ACCESS_CHECK is not set +# CONFIG_BFIN_ISRAM_SELF_TEST is not set # # Security options @@ -1253,14 +1308,14 @@ CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=0 CONFIG_SECURITY=y # CONFIG_SECURITYFS is not set # CONFIG_SECURITY_NETWORK is not set +# CONFIG_SECURITY_PATH is not set # CONFIG_SECURITY_FILE_CAPABILITIES is not set -CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0 +# CONFIG_SECURITY_TOMOYO is not set CONFIG_CRYPTO=y # # Crypto core or helper # -# CONFIG_CRYPTO_FIPS is not set # CONFIG_CRYPTO_MANAGER is not set # CONFIG_CRYPTO_MANAGER2 is not set # CONFIG_CRYPTO_GF128MUL is not set @@ -1292,11 +1347,13 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_HMAC is not set # CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set # # Digest # # CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set # CONFIG_CRYPTO_MD4 is not set # CONFIG_CRYPTO_MD5 is not set # CONFIG_CRYPTO_MICHAEL_MIC is not set @@ -1333,6 +1390,7 @@ CONFIG_CRYPTO=y # Compression # # CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set # CONFIG_CRYPTO_LZO is not set # @@ -1340,11 +1398,13 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set # # Library routines # CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y CONFIG_CRC_CCITT=m # CONFIG_CRC16 is not set # CONFIG_CRC_T10DIF is not set @@ -1356,3 +1416,4 @@ CONFIG_ZLIB_INFLATE=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y +CONFIG_NLATTR=y -- cgit v0.10.2 From f05ede3a9416b6eff6c997c12fd749044fb4fdac Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 25 Dec 2009 15:34:08 +0000 Subject: Blackfin: isram: add unlikely to sanity checks Don't want the compiler assuming the rare sanity checks are the norm and optimize for those paths. Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mm/isram-driver.c b/arch/blackfin/mm/isram-driver.c index 84cdc5a..9213e23 100644 --- a/arch/blackfin/mm/isram-driver.c +++ b/arch/blackfin/mm/isram-driver.c @@ -62,7 +62,7 @@ static void isram_write(const void *addr, uint64_t data) uint32_t cmd; unsigned long flags; - if (addr >= (void *)(L1_CODE_START + L1_CODE_LENGTH)) + if (unlikely(addr >= (void *)(L1_CODE_START + L1_CODE_LENGTH))) return; cmd = IADDR2DTEST(addr) | 2; /* write */ @@ -93,7 +93,7 @@ static uint64_t isram_read(const void *addr) unsigned long flags; uint64_t ret; - if (addr > (void *)(L1_CODE_START + L1_CODE_LENGTH)) + if (unlikely(addr > (void *)(L1_CODE_START + L1_CODE_LENGTH))) return 0; cmd = IADDR2DTEST(addr) | 0; /* read */ @@ -120,7 +120,7 @@ static bool isram_check_addr(const void *addr, size_t n) { if ((addr >= (void *)L1_CODE_START) && (addr < (void *)(L1_CODE_START + L1_CODE_LENGTH))) { - if ((addr + n) > (void *)(L1_CODE_START + L1_CODE_LENGTH)) { + if (unlikely((addr + n) > (void *)(L1_CODE_START + L1_CODE_LENGTH))) { show_stack(NULL, NULL); pr_err("copy involving %p length (%zu) too long\n", addr, n); } -- cgit v0.10.2 From 69e1d8a61d5aa9e03676dc21fdfb750c5a97bb34 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 25 Dec 2009 21:06:06 +0000 Subject: Blackfin: unify MMR helpers Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/def_LPBlackfin.h b/arch/blackfin/include/asm/def_LPBlackfin.h index e521f8e..f342ff0 100644 --- a/arch/blackfin/include/asm/def_LPBlackfin.h +++ b/arch/blackfin/include/asm/def_LPBlackfin.h @@ -25,62 +25,30 @@ # define NOP_PAD_ANOMALY_05000198 #endif -#define bfin_read8(addr) ({ \ - uint32_t __v; \ +#define _bfin_readX(addr, size, asm_size, asm_ext) ({ \ + u32 __v; \ __asm__ __volatile__( \ NOP_PAD_ANOMALY_05000198 \ - "%0 = b[%1] (z);" \ + "%0 = " #asm_size "[%1]" #asm_ext ";" \ : "=d" (__v) \ : "a" (addr) \ ); \ __v; }) - -#define bfin_read16(addr) ({ \ - uint32_t __v; \ - __asm__ __volatile__( \ - NOP_PAD_ANOMALY_05000198 \ - "%0 = w[%1] (z);" \ - : "=d" (__v) \ - : "a" (addr) \ - ); \ - __v; }) - -#define bfin_read32(addr) ({ \ - uint32_t __v; \ - __asm__ __volatile__( \ - NOP_PAD_ANOMALY_05000198 \ - "%0 = [%1];" \ - : "=d" (__v) \ - : "a" (addr) \ - ); \ - __v; }) - -#define bfin_write8(addr, val) \ +#define _bfin_writeX(addr, val, size, asm_size) \ __asm__ __volatile__( \ NOP_PAD_ANOMALY_05000198 \ - "b[%0] = %1;" \ + #asm_size "[%0] = %1;" \ : \ - : "a" (addr), "d" ((uint8_t)(val)) \ + : "a" (addr), "d" ((u##size)(val)) \ : "memory" \ ) -#define bfin_write16(addr, val) \ - __asm__ __volatile__( \ - NOP_PAD_ANOMALY_05000198 \ - "w[%0] = %1;" \ - : \ - : "a" (addr), "d" ((uint16_t)(val)) \ - : "memory" \ - ) - -#define bfin_write32(addr, val) \ - __asm__ __volatile__( \ - NOP_PAD_ANOMALY_05000198 \ - "[%0] = %1;" \ - : \ - : "a" (addr), "d" (val) \ - : "memory" \ - ) +#define bfin_read8(addr) _bfin_readX(addr, 8, b, (z)) +#define bfin_read16(addr) _bfin_readX(addr, 16, w, (z)) +#define bfin_read32(addr) _bfin_readX(addr, 32, , ) +#define bfin_write8(addr, val) _bfin_writeX(addr, val, 8, b) +#define bfin_write16(addr, val) _bfin_writeX(addr, val, 16, w) +#define bfin_write32(addr, val) _bfin_writeX(addr, val, 32, ) #endif /* __ASSEMBLY__ */ -- cgit v0.10.2 From 0325f25a919ed09d11b16ec8eccf95618dc36601 Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Mon, 28 Dec 2009 07:29:57 +0000 Subject: Blackfin: SMP: add support for IRQ affinity Now that the Blackfin IRQ controller supports this, drivers get the normal functionality of controlling which CPU to bind IRQs to. Signed-off-by: Sonic Zhang Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c index 5202a60..a5d2434 100644 --- a/arch/blackfin/mach-common/ints-priority.c +++ b/arch/blackfin/mach-common/ints-priority.c @@ -173,7 +173,12 @@ static void bfin_internal_mask_irq(unsigned int irq) local_irq_restore_hw(flags); } +#ifdef CONFIG_SMP +static void bfin_internal_unmask_irq_affinity(unsigned int irq, + const struct cpumask *affinity) +#else static void bfin_internal_unmask_irq(unsigned int irq) +#endif { unsigned long flags; @@ -186,16 +191,38 @@ static void bfin_internal_unmask_irq(unsigned int irq) local_irq_save_hw(flags); mask_bank = SIC_SYSIRQ(irq) / 32; mask_bit = SIC_SYSIRQ(irq) % 32; - bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) | - (1 << mask_bit)); #ifdef CONFIG_SMP - bfin_write_SICB_IMASK(mask_bank, bfin_read_SICB_IMASK(mask_bank) | - (1 << mask_bit)); + if (cpumask_test_cpu(0, affinity)) +#endif + bfin_write_SIC_IMASK(mask_bank, + bfin_read_SIC_IMASK(mask_bank) | + (1 << mask_bit)); +#ifdef CONFIG_SMP + if (cpumask_test_cpu(1, affinity)) + bfin_write_SICB_IMASK(mask_bank, + bfin_read_SICB_IMASK(mask_bank) | + (1 << mask_bit)); #endif #endif local_irq_restore_hw(flags); } +#ifdef CONFIG_SMP +static void bfin_internal_unmask_irq(unsigned int irq) +{ + struct irq_desc *desc = irq_to_desc(irq); + bfin_internal_unmask_irq_affinity(irq, desc->affinity); +} + +static int bfin_internal_set_affinity(unsigned int irq, const struct cpumask *mask) +{ + bfin_internal_mask_irq(irq); + bfin_internal_unmask_irq_affinity(irq, mask); + + return 0; +} +#endif + #ifdef CONFIG_PM int bfin_internal_set_wake(unsigned int irq, unsigned int state) { @@ -271,6 +298,9 @@ static struct irq_chip bfin_internal_irqchip = { .mask_ack = bfin_internal_mask_irq, .disable = bfin_internal_mask_irq, .enable = bfin_internal_unmask_irq, +#ifdef CONFIG_SMP + .set_affinity = bfin_internal_set_affinity, +#endif #ifdef CONFIG_PM .set_wake = bfin_internal_set_wake, #endif -- cgit v0.10.2 From 682f5dc4ed7cdef1f55e40ee505c4346dfa6fa91 Mon Sep 17 00:00:00 2001 From: Graf Yang Date: Mon, 28 Dec 2009 09:27:27 +0000 Subject: Blackfin: drop cpu_callin_map on SMP systems Common API already provides functions for managing online CPUs. Signed-off-by: Graf Yang Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf561/smp.c b/arch/blackfin/mach-bf561/smp.c index 0192532..ec93f3e 100644 --- a/arch/blackfin/mach-bf561/smp.c +++ b/arch/blackfin/mach-bf561/smp.c @@ -14,8 +14,6 @@ static DEFINE_SPINLOCK(boot_lock); -static cpumask_t cpu_callin_map; - /* * platform_init_cpus() - Tell the world about how many cores we * have. This is called while setting up the architecture support @@ -72,7 +70,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu) bfin_setup_cpudata(cpu); /* We are done with local CPU inits, unblock the boot CPU. */ - cpu_set(cpu, cpu_callin_map); + set_cpu_online(cpu, true); spin_lock(&boot_lock); spin_unlock(&boot_lock); } @@ -95,14 +93,13 @@ int __cpuinit platform_boot_secondary(unsigned int cpu, struct task_struct *idle timeout = jiffies + 1 * HZ; while (time_before(jiffies, timeout)) { - if (cpu_isset(cpu, cpu_callin_map)) + if (cpu_online(cpu)) break; udelay(100); barrier(); } - if (cpu_isset(cpu, cpu_callin_map)) { - cpu_set(cpu, cpu_online_map); + if (cpu_online(cpu)) { /* release the lock and let coreb run */ spin_unlock(&boot_lock); return 0; -- cgit v0.10.2 From 0d152c27e336b5fd777da7dd3e814617e7305afd Mon Sep 17 00:00:00 2001 From: Yi Li Date: Mon, 28 Dec 2009 10:21:49 +0000 Subject: Blackfin: SMP: make core timers per-cpu clock events for HRT SMP systems require per-cpu local clock event devices in order to enable HRT support. One a BF561, we can use local core timer for this purpose. Originally, there was one global core-timer clock event device set up for core A. To accomplish this feat, we need to split the gptimer0/core timer logic so that each is a standalone clock event. There is no requirement that we only have one clock event source anyways. Once we have this, we just define per-cpu clock event devices for each local core timer. Signed-off-by: Yi Li Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index b483639..0bd26db 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -236,7 +236,7 @@ endchoice config SMP depends on BF561 - select GENERIC_CLOCKEVENTS + select TICKSOURCE_CORETMR bool "Symmetric multi-processing support" ---help--- This enables support for systems with more than one CPU, @@ -610,23 +610,23 @@ config GENERIC_CLOCKEVENTS bool "Generic clock events" default y -choice - prompt "Kernel Tick Source" +menu "Clock event device" depends on GENERIC_CLOCKEVENTS - default TICKSOURCE_CORETMR - config TICKSOURCE_GPTMR0 - bool "Gptimer0 (SCLK domain)" + bool "GPTimer0" + depends on !SMP select BFIN_GPTIMERS config TICKSOURCE_CORETMR - bool "Core timer (CCLK domain)" - -endchoice + bool "Core timer" + default y +endmenu -config CYCLES_CLOCKSOURCE - bool "Use 'CYCLES' as a clocksource" +menu "Clock souce" depends on GENERIC_CLOCKEVENTS +config CYCLES_CLOCKSOURCE + bool "CYCLES" + default y depends on !BFIN_SCRATCH_REG_CYCLES depends on !SMP help @@ -637,10 +637,10 @@ config CYCLES_CLOCKSOURCE writing the registers will most likely crash the kernel. config GPTMR0_CLOCKSOURCE - bool "Use GPTimer0 as a clocksource" + bool "GPTimer0" select BFIN_GPTIMERS - depends on GENERIC_CLOCKEVENTS depends on !TICKSOURCE_GPTMR0 +endmenu config ARCH_USES_GETTIMEOFFSET depends on !GENERIC_CLOCKEVENTS diff --git a/arch/blackfin/include/asm/time.h b/arch/blackfin/include/asm/time.h index 589e937..767b938 100644 --- a/arch/blackfin/include/asm/time.h +++ b/arch/blackfin/include/asm/time.h @@ -37,5 +37,9 @@ extern unsigned long long __bfin_cycles_off; extern unsigned int __bfin_cycles_mod; #endif -extern void __init setup_core_timer(void); +#if defined(CONFIG_TICKSOURCE_CORETMR) +extern void bfin_coretmr_init(void); +extern void bfin_coretmr_clockevent_init(void); +#endif + #endif diff --git a/arch/blackfin/kernel/time-ts.c b/arch/blackfin/kernel/time-ts.c index 17c38c5..a351f97 100644 --- a/arch/blackfin/kernel/time-ts.c +++ b/arch/blackfin/kernel/time-ts.c @@ -132,7 +132,6 @@ static int __init bfin_cs_gptimer0_init(void) # define bfin_cs_gptimer0_init() #endif - #if defined(CONFIG_GPTMR0_CLOCKSOURCE) || defined(CONFIG_CYCLES_CLOCKSOURCE) /* prefer to use cycles since it has higher rating */ notrace unsigned long long sched_clock(void) @@ -145,47 +144,8 @@ notrace unsigned long long sched_clock(void) } #endif -#ifdef CONFIG_CORE_TIMER_IRQ_L1 -__attribute__((l1_text)) -#endif -irqreturn_t timer_interrupt(int irq, void *dev_id); - -static int bfin_timer_set_next_event(unsigned long, \ - struct clock_event_device *); - -static void bfin_timer_set_mode(enum clock_event_mode, \ - struct clock_event_device *); - -static struct clock_event_device clockevent_bfin = { -#if defined(CONFIG_TICKSOURCE_GPTMR0) - .name = "bfin_gptimer0", - .rating = 300, - .irq = IRQ_TIMER0, -#else - .name = "bfin_core_timer", - .rating = 350, - .irq = IRQ_CORETMR, -#endif - .shift = 32, - .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, - .set_next_event = bfin_timer_set_next_event, - .set_mode = bfin_timer_set_mode, -}; - -static struct irqaction bfin_timer_irq = { -#if defined(CONFIG_TICKSOURCE_GPTMR0) - .name = "Blackfin GPTimer0", -#else - .name = "Blackfin CoreTimer", -#endif - .flags = IRQF_DISABLED | IRQF_TIMER | \ - IRQF_IRQPOLL | IRQF_PERCPU, - .handler = timer_interrupt, - .dev_id = &clockevent_bfin, -}; - #if defined(CONFIG_TICKSOURCE_GPTMR0) -static int bfin_timer_set_next_event(unsigned long cycles, +static int bfin_gptmr0_set_next_event(unsigned long cycles, struct clock_event_device *evt) { disable_gptimers(TIMER0bit); @@ -196,7 +156,7 @@ static int bfin_timer_set_next_event(unsigned long cycles, return 0; } -static void bfin_timer_set_mode(enum clock_event_mode mode, +static void bfin_gptmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) { switch (mode) { @@ -224,25 +184,65 @@ static void bfin_timer_set_mode(enum clock_event_mode mode, } } -static void bfin_timer_ack(void) +static void bfin_gptmr0_ack(void) { set_gptimer_status(TIMER_GROUP1, TIMER_STATUS_TIMIL0); } -static void __init bfin_timer_init(void) +static void __init bfin_gptmr0_init(void) { disable_gptimers(TIMER0bit); } -static unsigned long __init bfin_clockevent_check(void) +#ifdef CONFIG_CORE_TIMER_IRQ_L1 +__attribute__((l1_text)) +#endif +irqreturn_t bfin_gptmr0_interrupt(int irq, void *dev_id) { - setup_irq(IRQ_TIMER0, &bfin_timer_irq); - return get_sclk(); + struct clock_event_device *evt = dev_id; + smp_mb(); + evt->event_handler(evt); + bfin_gptmr0_ack(); + return IRQ_HANDLED; } -#else /* CONFIG_TICKSOURCE_CORETMR */ +static struct irqaction gptmr0_irq = { + .name = "Blackfin GPTimer0", + .flags = IRQF_DISABLED | IRQF_TIMER | \ + IRQF_IRQPOLL | IRQF_PERCPU, + .handler = bfin_gptmr0_interrupt, +}; -static int bfin_timer_set_next_event(unsigned long cycles, +static struct clock_event_device clockevent_gptmr0 = { + .name = "bfin_gptimer0", + .rating = 300, + .irq = IRQ_TIMER0, + .shift = 32, + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, + .set_next_event = bfin_gptmr0_set_next_event, + .set_mode = bfin_gptmr0_set_mode, +}; + +static void __init bfin_gptmr0_clockevent_init(struct clock_event_device *evt) +{ + unsigned long clock_tick; + + clock_tick = get_sclk(); + evt->mult = div_sc(clock_tick, NSEC_PER_SEC, evt->shift); + evt->max_delta_ns = clockevent_delta2ns(-1, evt); + evt->min_delta_ns = clockevent_delta2ns(100, evt); + + evt->cpumask = cpumask_of(0); + + clockevents_register_device(evt); +} +#endif /* CONFIG_TICKSOURCE_GPTMR0 */ + +#if defined(CONFIG_TICKSOURCE_CORETMR) +/* per-cpu local core timer */ +static DEFINE_PER_CPU(struct clock_event_device, coretmr_events); + +static int bfin_coretmr_set_next_event(unsigned long cycles, struct clock_event_device *evt) { bfin_write_TCNTL(TMPWR); @@ -253,7 +253,7 @@ static int bfin_timer_set_next_event(unsigned long cycles, return 0; } -static void bfin_timer_set_mode(enum clock_event_mode mode, +static void bfin_coretmr_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) { switch (mode) { @@ -285,19 +285,13 @@ static void bfin_timer_set_mode(enum clock_event_mode mode, } } -static void bfin_timer_ack(void) -{ -} - -static void __init bfin_timer_init(void) +void bfin_coretmr_init(void) { /* power up the timer, but don't enable it just yet */ bfin_write_TCNTL(TMPWR); CSYNC(); - /* - * the TSCALE prescaler counter. - */ + /* the TSCALE prescaler counter. */ bfin_write_TSCALE(TIME_SCALE - 1); bfin_write_TPERIOD(0); bfin_write_TCOUNT(0); @@ -305,48 +299,51 @@ static void __init bfin_timer_init(void) CSYNC(); } -static unsigned long __init bfin_clockevent_check(void) -{ - setup_irq(IRQ_CORETMR, &bfin_timer_irq); - return get_cclk() / TIME_SCALE; -} - -void __init setup_core_timer(void) +#ifdef CONFIG_CORE_TIMER_IRQ_L1 +__attribute__((l1_text)) +#endif +irqreturn_t bfin_coretmr_interrupt(int irq, void *dev_id) { - bfin_timer_init(); - bfin_timer_set_mode(CLOCK_EVT_MODE_PERIODIC, NULL); -} -#endif /* CONFIG_TICKSOURCE_GPTMR0 */ + int cpu = smp_processor_id(); + struct clock_event_device *evt = &per_cpu(coretmr_events, cpu); -/* - * timer_interrupt() needs to keep up the real-time clock, - * as well as call the "do_timer()" routine every clocktick - */ -irqreturn_t timer_interrupt(int irq, void *dev_id) -{ - struct clock_event_device *evt = dev_id; smp_mb(); evt->event_handler(evt); - bfin_timer_ack(); return IRQ_HANDLED; } -static int __init bfin_clockevent_init(void) -{ - unsigned long timer_clk; - - timer_clk = bfin_clockevent_check(); - - bfin_timer_init(); - - clockevent_bfin.mult = div_sc(timer_clk, NSEC_PER_SEC, clockevent_bfin.shift); - clockevent_bfin.max_delta_ns = clockevent_delta2ns(-1, &clockevent_bfin); - clockevent_bfin.min_delta_ns = clockevent_delta2ns(100, &clockevent_bfin); - clockevent_bfin.cpumask = cpumask_of(0); - clockevents_register_device(&clockevent_bfin); +static struct irqaction coretmr_irq = { + .name = "Blackfin CoreTimer", + .flags = IRQF_DISABLED | IRQF_TIMER | \ + IRQF_IRQPOLL | IRQF_PERCPU, + .handler = bfin_coretmr_interrupt, +}; - return 0; +void bfin_coretmr_clockevent_init(void) +{ + unsigned long clock_tick; + unsigned int cpu = smp_processor_id(); + struct clock_event_device *evt = &per_cpu(coretmr_events, cpu); + + evt->name = "bfin_core_timer"; + evt->rating = 350; + evt->irq = -1; + evt->shift = 32; + evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; + evt->set_next_event = bfin_coretmr_set_next_event; + evt->set_mode = bfin_coretmr_set_mode; + + clock_tick = get_cclk() / TIME_SCALE; + evt->mult = div_sc(clock_tick, NSEC_PER_SEC, evt->shift); + evt->max_delta_ns = clockevent_delta2ns(-1, evt); + evt->min_delta_ns = clockevent_delta2ns(100, evt); + + evt->cpumask = cpumask_of(cpu); + + clockevents_register_device(evt); } +#endif /* CONFIG_TICKSOURCE_CORETMR */ + void __init time_init(void) { @@ -370,5 +367,21 @@ void __init time_init(void) bfin_cs_cycles_init(); bfin_cs_gptimer0_init(); - bfin_clockevent_init(); + +#if defined(CONFIG_TICKSOURCE_CORETMR) + bfin_coretmr_init(); + setup_irq(IRQ_CORETMR, &coretmr_irq); + bfin_coretmr_clockevent_init(); +#endif + +#if defined(CONFIG_TICKSOURCE_GPTMR0) + bfin_gptmr0_init(); + setup_irq(IRQ_TIMER0, &gptmr0_irq); + gptmr0_irq.dev_id = &clockevent_gptmr0; + bfin_gptmr0_clockevent_init(&clockevent_gptmr0); +#endif + +#if !defined(CONFIG_TICKSOURCE_CORETMR) && !defined(CONFIG_TICKSOURCE_GPTMR0) +# error at least one clock event device is required +#endif } diff --git a/arch/blackfin/mach-bf561/include/mach/smp.h b/arch/blackfin/mach-bf561/include/mach/smp.h index 390c7f4..2c8c514 100644 --- a/arch/blackfin/mach-bf561/include/mach/smp.h +++ b/arch/blackfin/mach-bf561/include/mach/smp.h @@ -25,4 +25,6 @@ void platform_send_ipi_cpu(unsigned int cpu); void platform_clear_ipi(unsigned int cpu); +void bfin_local_timer_setup(void); + #endif /* !_MACH_BF561_SMP */ diff --git a/arch/blackfin/mach-bf561/smp.c b/arch/blackfin/mach-bf561/smp.c index ec93f3e..9036942 100644 --- a/arch/blackfin/mach-bf561/smp.c +++ b/arch/blackfin/mach-bf561/smp.c @@ -11,6 +11,7 @@ #include #include #include +#include static DEFINE_SPINLOCK(boot_lock); @@ -144,3 +145,20 @@ void platform_clear_ipi(unsigned int cpu) bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | (1 << (10 + cpu))); SSYNC(); } + +/* + * Setup core B's local core timer. + * In SMP, core timer is used for clock event device. + */ +void __cpuinit bfin_local_timer_setup(void) +{ +#if defined(CONFIG_TICKSOURCE_CORETMR) + bfin_coretmr_init(); + bfin_coretmr_clockevent_init(); + get_irq_chip(IRQ_CORETMR)->unmask(IRQ_CORETMR); +#else + /* Power down the core timer, just to play safe. */ + bfin_write_TCNTL(0); +#endif + +} diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c index a5d2434..efbdb6a 100644 --- a/arch/blackfin/mach-common/ints-priority.c +++ b/arch/blackfin/mach-common/ints-priority.c @@ -1073,9 +1073,6 @@ int __init init_arch_irq(void) #endif #ifdef CONFIG_SMP -#ifdef CONFIG_TICKSOURCE_GPTMR0 - case IRQ_TIMER0: -#endif #ifdef CONFIG_TICKSOURCE_CORETMR case IRQ_CORETMR: #endif diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c index eddb720..b343ab3 100644 --- a/arch/blackfin/mach-common/smp.c +++ b/arch/blackfin/mach-common/smp.c @@ -365,9 +365,6 @@ int __cpuinit __cpu_up(unsigned int cpu) static void __cpuinit setup_secondary(unsigned int cpu) { -#if !defined(CONFIG_TICKSOURCE_GPTMR0) - struct irq_desc *timer_desc; -#endif unsigned long ilat; bfin_write_IMASK(0); @@ -382,17 +379,6 @@ static void __cpuinit setup_secondary(unsigned int cpu) bfin_irq_flags |= IMASK_IVG15 | IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 | IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW; - -#if defined(CONFIG_TICKSOURCE_GPTMR0) - /* Power down the core timer, just to play safe. */ - bfin_write_TCNTL(0); - - /* system timer0 has been setup by CoreA. */ -#else - timer_desc = irq_desc + IRQ_CORETMR; - setup_core_timer(); - timer_desc->chip->enable(IRQ_CORETMR); -#endif } void __cpuinit secondary_start_kernel(void) @@ -435,6 +421,9 @@ void __cpuinit secondary_start_kernel(void) platform_secondary_init(cpu); + /* setup local core timer */ + bfin_local_timer_setup(); + local_irq_enable(); /* -- cgit v0.10.2 From 0b39db28b953945232719e7ff6fb802aa8a2be5f Mon Sep 17 00:00:00 2001 From: Graf Yang Date: Mon, 28 Dec 2009 11:13:51 +0000 Subject: Blackfin: SMP: add PM/CPU hotplug support Signed-off-by: Graf Yang Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index 0bd26db..c0d6d96 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -250,6 +250,11 @@ config NR_CPUS depends on SMP default 2 if BF561 +config HOTPLUG_CPU + bool "Support for hot-pluggable CPUs" + depends on SMP && HOTPLUG + default y + config IRQ_PER_CPU bool depends on SMP @@ -1130,7 +1135,6 @@ source "fs/Kconfig.binfmt" endmenu menu "Power management options" - depends on !SMP source "kernel/power/Kconfig" diff --git a/arch/blackfin/include/asm/smp.h b/arch/blackfin/include/asm/smp.h index 6a0fe94..29fb882 100644 --- a/arch/blackfin/include/asm/smp.h +++ b/arch/blackfin/include/asm/smp.h @@ -25,5 +25,12 @@ struct corelock_slot { void smp_icache_flush_range_others(unsigned long start, unsigned long end); +#ifdef CONFIG_HOTPLUG_CPU +void coreb_sleep(u32 sic_iwr0, u32 sic_iwr1, u32 sic_iwr2); +void cpu_die(void); +void platform_cpu_die(void); +int __cpu_disable(void); +int __cpu_die(unsigned int cpu); +#endif #endif /* !__ASM_BLACKFIN_SMP_H */ diff --git a/arch/blackfin/mach-bf561/Makefile b/arch/blackfin/mach-bf561/Makefile index 59e18af..b340297 100644 --- a/arch/blackfin/mach-bf561/Makefile +++ b/arch/blackfin/mach-bf561/Makefile @@ -6,3 +6,4 @@ obj-y := ints-priority.o dma.o obj-$(CONFIG_BF561_COREB) += coreb.o obj-$(CONFIG_SMP) += smp.o secondary.o atomic.o +obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o diff --git a/arch/blackfin/mach-bf561/hotplug.c b/arch/blackfin/mach-bf561/hotplug.c new file mode 100644 index 0000000..c95169b --- /dev/null +++ b/arch/blackfin/mach-bf561/hotplug.c @@ -0,0 +1,32 @@ +/* + * Copyright 2007-2009 Analog Devices Inc. + * Graff Yang + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#define SIC_SYSIRQ(irq) (irq - (IRQ_CORETMR + 1)) + +int hotplug_coreb; + +void platform_cpu_die(void) +{ + unsigned long iwr[2] = {0, 0}; + unsigned long bank = SIC_SYSIRQ(IRQ_SUPPLE_0) / 32; + unsigned long bit = 1 << (SIC_SYSIRQ(IRQ_SUPPLE_0) % 32); + + hotplug_coreb = 1; + + iwr[bank] = bit; + + /* disable core timer */ + bfin_write_TCNTL(0); + + /* clear ipi interrupt IRQ_SUPPLE_0 */ + bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | (1 << (10 + 1))); + SSYNC(); + + coreb_sleep(iwr[0], iwr[1], 0); +} diff --git a/arch/blackfin/mach-bf561/secondary.S b/arch/blackfin/mach-bf561/secondary.S index 8e60503..4624eeb 100644 --- a/arch/blackfin/mach-bf561/secondary.S +++ b/arch/blackfin/mach-bf561/secondary.S @@ -11,6 +11,7 @@ #include #include #include +#include __INIT @@ -62,6 +63,8 @@ ENTRY(_coreb_trampoline_start) M2 = r0; M3 = r0; + trace_buffer_init(p0,r0); + /* Turn off the icache */ p0.l = LO(IMEM_CONTROL); p0.h = HI(IMEM_CONTROL); @@ -159,6 +162,41 @@ ENTRY(_coreb_trampoline_start) ENDPROC(_coreb_trampoline_start) ENTRY(_coreb_trampoline_end) +.section ".text" +ENTRY(_set_sicb_iwr) + P0.H = hi(SICB_IWR0); + P0.L = lo(SICB_IWR0); + P1.H = hi(SICB_IWR1); + P1.L = lo(SICB_IWR1); + [P0] = R0; + [P1] = R1; + SSYNC; + RTS; +ENDPROC(_set_sicb_iwr) + +ENTRY(_coreb_sleep) + sp.l = lo(INITIAL_STACK); + sp.h = hi(INITIAL_STACK); + fp = sp; + usp = sp; + + call _set_sicb_iwr; + + CLI R2; + SSYNC; + IDLE; + STI R2; + + R0 = IWR_DISABLE_ALL; + R1 = IWR_DISABLE_ALL; + call _set_sicb_iwr; + + p0.h = hi(COREB_L1_CODE_START); + p0.l = lo(COREB_L1_CODE_START); + jump (p0); +ENDPROC(_coreb_sleep) + +__CPUINIT ENTRY(_coreb_start) [--sp] = reti; @@ -176,12 +214,20 @@ ENTRY(_coreb_start) sp = [p0]; usp = sp; fp = sp; +#ifdef CONFIG_HOTPLUG_CPU + p0.l = _hotplug_coreb; + p0.h = _hotplug_coreb; + r0 = [p0]; + cc = BITTST(r0, 0); + if cc jump 3f; +#endif sp += -12; call _init_pda sp += 12; +#ifdef CONFIG_HOTPLUG_CPU +3: +#endif call _secondary_start_kernel; .L_exit: jump.s .L_exit; ENDPROC(_coreb_start) - -__FINIT diff --git a/arch/blackfin/mach-bf561/smp.c b/arch/blackfin/mach-bf561/smp.c index 9036942..3b9a4bf 100644 --- a/arch/blackfin/mach-bf561/smp.c +++ b/arch/blackfin/mach-bf561/smp.c @@ -65,6 +65,8 @@ void __cpuinit platform_secondary_init(unsigned int cpu) bfin_write_SICB_IAR5(bfin_read_SICA_IAR5()); bfin_write_SICB_IAR6(bfin_read_SICA_IAR6()); bfin_write_SICB_IAR7(bfin_read_SICA_IAR7()); + bfin_write_SICB_IWR0(IWR_DISABLE_ALL); + bfin_write_SICB_IWR1(IWR_DISABLE_ALL); SSYNC(); /* Store CPU-private information to the cpu_data array. */ @@ -80,17 +82,18 @@ int __cpuinit platform_boot_secondary(unsigned int cpu, struct task_struct *idle { unsigned long timeout; - /* CoreB already running?! */ - BUG_ON((bfin_read_SICA_SYSCR() & COREB_SRAM_INIT) == 0); - printk(KERN_INFO "Booting Core B.\n"); spin_lock(&boot_lock); - /* Kick CoreB, which should start execution from CORE_SRAM_BASE. */ - SSYNC(); - bfin_write_SICA_SYSCR(bfin_read_SICA_SYSCR() & ~COREB_SRAM_INIT); - SSYNC(); + if ((bfin_read_SICA_SYSCR() & COREB_SRAM_INIT) == 0) { + /* CoreB already running, sending ipi to wakeup it */ + platform_send_ipi_cpu(cpu, IRQ_SUPPLE_0); + } else { + /* Kick CoreB, which should start execution from CORE_SRAM_BASE. */ + bfin_write_SICA_SYSCR(bfin_read_SICA_SYSCR() & ~COREB_SRAM_INIT); + SSYNC(); + } timeout = jiffies + 1 * HZ; while (time_before(jiffies, timeout)) { diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c index b343ab3..efc47ff 100644 --- a/arch/blackfin/mach-common/smp.c +++ b/arch/blackfin/mach-common/smp.c @@ -344,8 +344,11 @@ void smp_send_stop(void) int __cpuinit __cpu_up(unsigned int cpu) { - struct task_struct *idle; int ret; + static struct task_struct *idle; + + if (idle) + free_task(idle); idle = fork_idle(cpu); if (IS_ERR(idle)) { @@ -354,7 +357,6 @@ int __cpuinit __cpu_up(unsigned int cpu) } secondary_stack = task_stack_page(idle) + THREAD_SIZE; - smp_wmb(); ret = platform_boot_secondary(cpu, idle); @@ -413,7 +415,6 @@ void __cpuinit secondary_start_kernel(void) atomic_inc(&mm->mm_users); atomic_inc(&mm->mm_count); current->active_mm = mm; - BUG_ON(current->mm); /* Can't be, but better be safe than sorry. */ preempt_disable(); @@ -495,3 +496,34 @@ void resync_core_dcache(void) } EXPORT_SYMBOL(resync_core_dcache); #endif + +#ifdef CONFIG_HOTPLUG_CPU +int __cpuexit __cpu_disable(void) +{ + unsigned int cpu = smp_processor_id(); + + if (cpu == 0) + return -EPERM; + + set_cpu_online(cpu, false); + return 0; +} + +static DECLARE_COMPLETION(cpu_killed); + +int __cpuexit __cpu_die(unsigned int cpu) +{ + return wait_for_completion_timeout(&cpu_killed, 5000); +} + +void cpu_die(void) +{ + complete(&cpu_killed); + + atomic_dec(&init_mm.mm_users); + atomic_dec(&init_mm.mm_count); + + local_irq_disable(); + platform_cpu_die(); +} +#endif -- cgit v0.10.2 From 54536c5c6a807d0db7252c3b33638b88f34650ff Mon Sep 17 00:00:00 2001 From: Yi Li Date: Wed, 30 Dec 2009 04:04:07 +0000 Subject: Blackfin: simplify SMP handling in SRAM code There is no need to use {get,put}_cpu() when we already have a spinlock to protect against multiple processors running simultaneously. Signed-off-by: Yi Li Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mm/sram-alloc.c b/arch/blackfin/mm/sram-alloc.c index f068c11..5732da2 100644 --- a/arch/blackfin/mm/sram-alloc.c +++ b/arch/blackfin/mm/sram-alloc.c @@ -402,7 +402,7 @@ void *l1_data_A_sram_alloc(size_t size) void *addr; unsigned int cpu; - cpu = get_cpu(); + cpu = smp_processor_id(); /* add mutex operation */ spin_lock_irqsave(&per_cpu(l1_data_sram_lock, cpu), flags); @@ -411,7 +411,6 @@ void *l1_data_A_sram_alloc(size_t size) /* add mutex operation */ spin_unlock_irqrestore(&per_cpu(l1_data_sram_lock, cpu), flags); - put_cpu(); pr_debug("Allocated address in l1_data_A_sram_alloc is 0x%lx+0x%lx\n", (long unsigned int)addr, size); @@ -430,7 +429,7 @@ int l1_data_A_sram_free(const void *addr) int ret; unsigned int cpu; - cpu = get_cpu(); + cpu = smp_processor_id(); /* add mutex operation */ spin_lock_irqsave(&per_cpu(l1_data_sram_lock, cpu), flags); @@ -439,7 +438,6 @@ int l1_data_A_sram_free(const void *addr) /* add mutex operation */ spin_unlock_irqrestore(&per_cpu(l1_data_sram_lock, cpu), flags); - put_cpu(); return ret; #else @@ -455,7 +453,7 @@ void *l1_data_B_sram_alloc(size_t size) void *addr; unsigned int cpu; - cpu = get_cpu(); + cpu = smp_processor_id(); /* add mutex operation */ spin_lock_irqsave(&per_cpu(l1_data_sram_lock, cpu), flags); @@ -464,7 +462,6 @@ void *l1_data_B_sram_alloc(size_t size) /* add mutex operation */ spin_unlock_irqrestore(&per_cpu(l1_data_sram_lock, cpu), flags); - put_cpu(); pr_debug("Allocated address in l1_data_B_sram_alloc is 0x%lx+0x%lx\n", (long unsigned int)addr, size); @@ -483,7 +480,7 @@ int l1_data_B_sram_free(const void *addr) int ret; unsigned int cpu; - cpu = get_cpu(); + cpu = smp_processor_id(); /* add mutex operation */ spin_lock_irqsave(&per_cpu(l1_data_sram_lock, cpu), flags); @@ -492,7 +489,6 @@ int l1_data_B_sram_free(const void *addr) /* add mutex operation */ spin_unlock_irqrestore(&per_cpu(l1_data_sram_lock, cpu), flags); - put_cpu(); return ret; #else @@ -540,7 +536,7 @@ void *l1_inst_sram_alloc(size_t size) void *addr; unsigned int cpu; - cpu = get_cpu(); + cpu = smp_processor_id(); /* add mutex operation */ spin_lock_irqsave(&per_cpu(l1_inst_sram_lock, cpu), flags); @@ -549,7 +545,6 @@ void *l1_inst_sram_alloc(size_t size) /* add mutex operation */ spin_unlock_irqrestore(&per_cpu(l1_inst_sram_lock, cpu), flags); - put_cpu(); pr_debug("Allocated address in l1_inst_sram_alloc is 0x%lx+0x%lx\n", (long unsigned int)addr, size); @@ -568,7 +563,7 @@ int l1_inst_sram_free(const void *addr) int ret; unsigned int cpu; - cpu = get_cpu(); + cpu = smp_processor_id(); /* add mutex operation */ spin_lock_irqsave(&per_cpu(l1_inst_sram_lock, cpu), flags); @@ -577,7 +572,6 @@ int l1_inst_sram_free(const void *addr) /* add mutex operation */ spin_unlock_irqrestore(&per_cpu(l1_inst_sram_lock, cpu), flags); - put_cpu(); return ret; #else @@ -593,7 +587,7 @@ void *l1sram_alloc(size_t size) void *addr; unsigned int cpu; - cpu = get_cpu(); + cpu = smp_processor_id(); /* add mutex operation */ spin_lock_irqsave(&per_cpu(l1sram_lock, cpu), flags); @@ -602,7 +596,6 @@ void *l1sram_alloc(size_t size) /* add mutex operation */ spin_unlock_irqrestore(&per_cpu(l1sram_lock, cpu), flags); - put_cpu(); return addr; } @@ -614,7 +607,7 @@ void *l1sram_alloc_max(size_t *psize) void *addr; unsigned int cpu; - cpu = get_cpu(); + cpu = smp_processor_id(); /* add mutex operation */ spin_lock_irqsave(&per_cpu(l1sram_lock, cpu), flags); @@ -623,7 +616,6 @@ void *l1sram_alloc_max(size_t *psize) /* add mutex operation */ spin_unlock_irqrestore(&per_cpu(l1sram_lock, cpu), flags); - put_cpu(); return addr; } @@ -635,7 +627,7 @@ int l1sram_free(const void *addr) int ret; unsigned int cpu; - cpu = get_cpu(); + cpu = smp_processor_id(); /* add mutex operation */ spin_lock_irqsave(&per_cpu(l1sram_lock, cpu), flags); @@ -644,7 +636,6 @@ int l1sram_free(const void *addr) /* add mutex operation */ spin_unlock_irqrestore(&per_cpu(l1sram_lock, cpu), flags); - put_cpu(); return ret; } -- cgit v0.10.2 From cb191718fcca887fb4d5e3de833546ab12b433f9 Mon Sep 17 00:00:00 2001 From: Yi Li Date: Wed, 30 Dec 2009 07:12:50 +0000 Subject: Blackfin: try to simplify interrupt ifdef ugliness Signed-off-by: Yi Li Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c index efbdb6a..3589fe8 100644 --- a/arch/blackfin/mach-common/ints-priority.c +++ b/arch/blackfin/mach-common/ints-priority.c @@ -1062,7 +1062,6 @@ int __init init_arch_irq(void) #elif defined(CONFIG_BF538) || defined(CONFIG_BF539) case IRQ_PORTF_INTA: #endif - set_irq_chained_handler(irq, bfin_demux_gpio_irq); break; @@ -1073,24 +1072,30 @@ int __init init_arch_irq(void) #endif #ifdef CONFIG_SMP -#ifdef CONFIG_TICKSOURCE_CORETMR - case IRQ_CORETMR: -#endif case IRQ_SUPPLE_0: case IRQ_SUPPLE_1: set_irq_handler(irq, handle_percpu_irq); break; #endif -#ifdef CONFIG_IPIPE -#ifndef CONFIG_TICKSOURCE_CORETMR - case IRQ_TIMER0: +#ifdef CONFIG_TICKSOURCE_CORETMR + case IRQ_CORETMR: +# ifdef CONFIG_SMP + set_irq_handler(irq, handle_percpu_irq); + break; +# else set_irq_handler(irq, handle_simple_irq); break; +# endif #endif - case IRQ_CORETMR: + +#ifdef CONFIG_TICKSOURCE_GPTMR0 + case IRQ_TIMER0: set_irq_handler(irq, handle_simple_irq); break; +#endif + +#ifdef CONFIG_IPIPE default: set_irq_handler(irq, handle_level_irq); break; -- cgit v0.10.2 From 0afc272cc6044b7a4f1318eadbfb10c4be654441 Mon Sep 17 00:00:00 2001 From: Jie Zhang Date: Tue, 5 Jan 2010 04:22:33 +0000 Subject: Blackfin: fix relocation errors with large initramfs images Since we are now discarding .exit.text at runtime instead of link time, we need to place all .text sections ahead of the .data sections. Otherwise, a really large attached initramfs may cause link errors as it pushes the PC relative relocations behind the limits of the Blackfin ISA (~16meg). The instructions in the .exit.text are unable to call back into the .text sections leading to a link failure. Signed-off-by: Jie Zhang Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/kernel/vmlinux.lds.S b/arch/blackfin/kernel/vmlinux.lds.S index 66799e7..be4b1bb 100644 --- a/arch/blackfin/kernel/vmlinux.lds.S +++ b/arch/blackfin/kernel/vmlinux.lds.S @@ -104,18 +104,21 @@ SECTIONS ___init_begin = .; INIT_TEXT_SECTION(PAGE_SIZE) - . = ALIGN(16); - INIT_DATA_SECTION(16) - PERCPU(4) - /* we have to discard exit text and such at runtime, not link time, to + /* We have to discard exit text and such at runtime, not link time, to * handle embedded cross-section references (alt instructions, bug - * table, eh_frame, etc...) + * table, eh_frame, etc...). We need all of our .text up front and + * .data after it for PCREL call issues. */ .exit.text : { EXIT_TEXT } + + . = ALIGN(16); + INIT_DATA_SECTION(16) + PERCPU(4) + .exit.data : { EXIT_DATA -- cgit v0.10.2 From 6feda3a6530204ad73a2dc1713c051462a1d9c49 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Tue, 5 Jan 2010 07:05:50 +0000 Subject: Blackfin: replace harcoded define with proper THREAD_SIZE macro Signed-off-by: Barry Song Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index 8dc7ee1..a0bc7d3 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c @@ -635,7 +635,7 @@ static __init void memory_setup(void) __bss_start, __bss_stop, _sdata, _edata, (void *)&init_thread_union, - (void *)((int)(&init_thread_union) + 0x2000), + (void *)((int)(&init_thread_union) + THREAD_SIZE), __init_begin, __init_end, (void *)_ramstart, (void *)memory_end #ifdef CONFIG_MTD_UCLINUX -- cgit v0.10.2 From 8916a1499d958fcb9086a2c49a5fa3000689bb81 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Tue, 5 Jan 2010 07:16:32 +0000 Subject: Blackfin: fix the section name of init_thread_union Use the common attribute rather than setting the section name directly. The common linker script defines expect the newer naming. Signed-off-by: Barry Song Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/kernel/init_task.c b/arch/blackfin/kernel/init_task.c index 118c5b9..d3970e8 100644 --- a/arch/blackfin/kernel/init_task.c +++ b/arch/blackfin/kernel/init_task.c @@ -28,5 +28,5 @@ EXPORT_SYMBOL(init_task); * "init_task" linker map entry. */ union thread_union init_thread_union - __attribute__ ((__section__(".init_task.data"))) = { + __init_task_data = { INIT_THREAD_INFO(init_task)}; -- cgit v0.10.2 From aad16f32284030907b4f105e92e5fb534fd272bc Mon Sep 17 00:00:00 2001 From: Barry Song Date: Tue, 5 Jan 2010 07:25:24 +0000 Subject: Blackfin: fix initial stack pointer setup During very early init, the stack pointer is given a slightly incorrect value (&init_thread_union). The value is later adjusted to the right one during early init (&init_thread_union + THREAD_SIZE), but it is used a few times in between. While the few functions used don't actually put things onto the stack (due to optimization), it's best if we simply use the right value from the start. Signed-off-by: Barry Song Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-common/head.S b/arch/blackfin/mach-common/head.S index cab0a00..cf03778 100644 --- a/arch/blackfin/mach-common/head.S +++ b/arch/blackfin/mach-common/head.S @@ -144,8 +144,8 @@ ENTRY(__start) #endif /* Initialize stack pointer */ - sp.l = _init_thread_union; - sp.h = _init_thread_union; + sp.l = _init_thread_union + THREAD_SIZE; + sp.h = _init_thread_union + THREAD_SIZE; fp = sp; usp = sp; @@ -257,12 +257,7 @@ ENTRY(_real_start) R0 = R7; call _cmdline_init; - /* Load the current thread pointer and stack */ - p1 = THREAD_SIZE + 4 (z); /* +4 is for reti loading */ - sp = sp + p1; - usp = sp; - fp = sp; - sp += -12; + sp += -12 + 4; /* +4 is for reti loading above */ call _init_pda sp += 12; jump.l _start_kernel; -- cgit v0.10.2 From d86bfb1600db38e8387beee0aaab4263cfd728a2 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Thu, 7 Jan 2010 04:11:17 +0000 Subject: Blackfin: initial XIP support Signed-off-by: Barry Song Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index c0d6d96..f46db59 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -26,9 +26,9 @@ config BLACKFIN select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_TRACER select HAVE_IDE - select HAVE_KERNEL_GZIP - select HAVE_KERNEL_BZIP2 - select HAVE_KERNEL_LZMA + select HAVE_KERNEL_GZIP if RAMKERNEL + select HAVE_KERNEL_BZIP2 if RAMKERNEL + select HAVE_KERNEL_LZMA if RAMKERNEL select HAVE_OPROFILE select ARCH_WANT_OPTIONAL_GPIOLIB @@ -407,10 +407,18 @@ config BOOT_LOAD config ROM_BASE hex "Kernel ROM Base" depends on ROMKERNEL - default "0x20040000" + default "0x20040040" range 0x20000000 0x20400000 if !(BF54x || BF561) range 0x20000000 0x30000000 if (BF54x || BF561) help + Make sure your ROM base does not include any file-header + information that is prepended to the kernel. + + For example, the bootable U-Boot format (created with + mkimage) has a 64 byte header (0x40). So while the image + you write to flash might start at say 0x20080000, you have + to add 0x40 to get the kernel's ROM base as it will come + after the header. comment "Clock/PLL Setup" diff --git a/arch/blackfin/Makefile b/arch/blackfin/Makefile index d4c7177..ba84206 100644 --- a/arch/blackfin/Makefile +++ b/arch/blackfin/Makefile @@ -14,6 +14,9 @@ OBJCOPYFLAGS := -O binary -R .note -R .comment -S GZFLAGS := -9 KBUILD_CFLAGS += $(call cc-option,-mno-fdpic) +ifeq ($(CONFIG_ROMKERNEL),y) +KBUILD_CFLAGS += -mlong-calls +endif KBUILD_AFLAGS += $(call cc-option,-mno-fdpic) CFLAGS_MODULE += -mlong-calls LDFLAGS_MODULE += -m elf32bfin @@ -138,7 +141,7 @@ archclean: INSTALL_PATH ?= /tftpboot boot := arch/$(ARCH)/boot -BOOT_TARGETS = vmImage vmImage.bin vmImage.bz2 vmImage.gz vmImage.lzma +BOOT_TARGETS = vmImage vmImage.bin vmImage.bz2 vmImage.gz vmImage.lzma vmImage.xip PHONY += $(BOOT_TARGETS) install KBUILD_IMAGE := $(boot)/vmImage @@ -156,6 +159,7 @@ define archhelp echo ' vmImage.bz2 - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.bz2)' echo '* vmImage.gz - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.gz)' echo ' vmImage.lzma - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.lzma)' + echo ' vmImage.xip - XIP Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.xip)' echo ' install - Install kernel using' echo ' (your) ~/bin/$(INSTALLKERNEL) or' echo ' (distribution) PATH: $(INSTALLKERNEL) or' diff --git a/arch/blackfin/boot/Makefile b/arch/blackfin/boot/Makefile index e9c48c6..d1b3d60 100644 --- a/arch/blackfin/boot/Makefile +++ b/arch/blackfin/boot/Makefile @@ -8,14 +8,18 @@ MKIMAGE := $(srctree)/scripts/mkuboot.sh -targets := vmImage vmImage.bin vmImage.bz2 vmImage.gz vmImage.lzma -extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma +targets := vmImage vmImage.bin vmImage.bz2 vmImage.gz vmImage.lzma vmImage.xip +extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma vmlinux.bin.xip + +UIMAGE_OPTS-y := +UIMAGE_OPTS-$(CONFIG_RAMKERNEL) += -a $(CONFIG_BOOT_LOAD) +UIMAGE_OPTS-$(CONFIG_ROMKERNEL) += -a $(CONFIG_ROM_BASE) -x quiet_cmd_uimage = UIMAGE $@ cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A $(ARCH) -O linux -T kernel \ - -C $(2) -n '$(MACHINE)-$(KERNELRELEASE)' -a $(CONFIG_BOOT_LOAD) \ + -C $(2) -n '$(MACHINE)-$(KERNELRELEASE)' \ -e $(shell $(NM) vmlinux | awk '$$NF == "__start" {print $$1}') \ - -d $< $@ + $(UIMAGE_OPTS-y) -d $< $@ $(obj)/vmlinux.bin: vmlinux FORCE $(call if_changed,objcopy) @@ -29,6 +33,12 @@ $(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE $(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE $(call if_changed,lzma) +# The mkimage tool wants 64bytes prepended to the image +quiet_cmd_mk_bin_xip = BIN $@ + cmd_mk_bin_xip = ( printf '%64s' | tr ' ' '\377' ; cat $< ) > $@ +$(obj)/vmlinux.bin.xip: $(obj)/vmlinux.bin FORCE + $(call if_changed,mk_bin_xip) + $(obj)/vmImage.bin: $(obj)/vmlinux.bin $(call if_changed,uimage,none) @@ -41,10 +51,15 @@ $(obj)/vmImage.gz: $(obj)/vmlinux.bin.gz $(obj)/vmImage.lzma: $(obj)/vmlinux.bin.lzma $(call if_changed,uimage,lzma) +$(obj)/vmImage.xip: $(obj)/vmlinux.bin.xip + $(call if_changed,uimage,none) + suffix-y := bin suffix-$(CONFIG_KERNEL_GZIP) := gz suffix-$(CONFIG_KERNEL_BZIP2) := bz2 suffix-$(CONFIG_KERNEL_LZMA) := lzma +suffix-$(CONFIG_ROMKERNEL) := xip + $(obj)/vmImage: $(obj)/vmImage.$(suffix-y) @ln -sf $(notdir $<) $@ diff --git a/arch/blackfin/include/asm/context.S b/arch/blackfin/include/asm/context.S index 5dffaf5..fada8e9 100644 --- a/arch/blackfin/include/asm/context.S +++ b/arch/blackfin/include/asm/context.S @@ -374,3 +374,13 @@ (R7:0, P5:0) = [SP++]; .endm + +.macro pseudo_long_call func:req, scratch:req +#ifdef CONFIG_ROMKERNEL + \scratch\().l = \func; + \scratch\().h = \func; + call (\scratch); +#else + call \func; +#endif +.endm diff --git a/arch/blackfin/include/asm/sections.h b/arch/blackfin/include/asm/sections.h index 42f6c53..14a3e66 100644 --- a/arch/blackfin/include/asm/sections.h +++ b/arch/blackfin/include/asm/sections.h @@ -21,6 +21,9 @@ extern unsigned long memory_start, memory_end, physical_mem_end; extern char _stext_l1[], _etext_l1[], _text_l1_lma[], __weak _text_l1_len[]; extern char _sdata_l1[], _edata_l1[], _sbss_l1[], _ebss_l1[], _data_l1_lma[], __weak _data_l1_len[]; +#ifdef CONFIG_ROMKERNEL +extern char _data_lma[], _data_len[], _sinitdata[], _einitdata[], _init_data_lma[], _init_data_len[]; +#endif extern char _sdata_b_l1[], _edata_b_l1[], _sbss_b_l1[], _ebss_b_l1[], _data_b_l1_lma[], __weak _data_b_l1_len[]; extern char _stext_l2[], _etext_l2[], _sdata_l2[], _edata_l2[], diff --git a/arch/blackfin/kernel/cplb-mpu/cplbinit.c b/arch/blackfin/kernel/cplb-mpu/cplbinit.c index 8d42b9e..30fd641 100644 --- a/arch/blackfin/kernel/cplb-mpu/cplbinit.c +++ b/arch/blackfin/kernel/cplb-mpu/cplbinit.c @@ -64,6 +64,15 @@ void __init generate_cplb_tables_cpu(unsigned int cpu) icplb_tbl[cpu][i_i++].data = i_data | (addr == 0 ? CPLB_USER_RD : 0); } +#ifdef CONFIG_ROMKERNEL + /* Cover kernel XIP flash area */ + addr = CONFIG_ROM_BASE & ~(4 * 1024 * 1024 - 1); + dcplb_tbl[cpu][i_d].addr = addr; + dcplb_tbl[cpu][i_d++].data = d_data | CPLB_USER_RD; + icplb_tbl[cpu][i_i].addr = addr; + icplb_tbl[cpu][i_i++].data = i_data | CPLB_USER_RD; +#endif + /* Cover L1 memory. One 4M area for code and data each is enough. */ #if L1_DATA_A_LENGTH > 0 || L1_DATA_B_LENGTH > 0 dcplb_tbl[cpu][i_d].addr = get_l1_data_a_start_cpu(cpu); diff --git a/arch/blackfin/kernel/cplb-nompu/cplbinit.c b/arch/blackfin/kernel/cplb-nompu/cplbinit.c index 282a791..bfe75af 100644 --- a/arch/blackfin/kernel/cplb-nompu/cplbinit.c +++ b/arch/blackfin/kernel/cplb-nompu/cplbinit.c @@ -56,6 +56,15 @@ void __init generate_cplb_tables_cpu(unsigned int cpu) i_tbl[i_i++].data = SDRAM_IGENERIC | PAGE_SIZE_4MB; } +#ifdef CONFIG_ROMKERNEL + /* Cover kernel XIP flash area */ + addr = CONFIG_ROM_BASE & ~(4 * 1024 * 1024 - 1); + d_tbl[i_d].addr = addr; + d_tbl[i_d++].data = SDRAM_DGENERIC | PAGE_SIZE_4MB; + i_tbl[i_i].addr = addr; + i_tbl[i_i++].data = SDRAM_IGENERIC | PAGE_SIZE_4MB; +#endif + /* Cover L1 memory. One 4M area for code and data each is enough. */ if (cpu == 0) { if (L1_DATA_A_LENGTH || L1_DATA_B_LENGTH) { diff --git a/arch/blackfin/kernel/entry.S b/arch/blackfin/kernel/entry.S index f27dc22..686478f 100644 --- a/arch/blackfin/kernel/entry.S +++ b/arch/blackfin/kernel/entry.S @@ -44,7 +44,7 @@ ENTRY(_ret_from_fork) sti r4; #endif /* CONFIG_IPIPE */ SP += -12; - call _schedule_tail; + pseudo_long_call _schedule_tail, p5; SP += 12; r0 = [sp + PT_IPEND]; cc = bittst(r0,1); @@ -79,7 +79,7 @@ ENTRY(_sys_vfork) r0 += 24; [--sp] = rets; SP += -12; - call _bfin_vfork; + pseudo_long_call _bfin_vfork, p2; SP += 12; rets = [sp++]; rts; @@ -90,7 +90,7 @@ ENTRY(_sys_clone) r0 += 24; [--sp] = rets; SP += -12; - call _bfin_clone; + pseudo_long_call _bfin_clone, p2; SP += 12; rets = [sp++]; rts; @@ -101,7 +101,7 @@ ENTRY(_sys_rt_sigreturn) r0 += 24; [--sp] = rets; SP += -12; - call _do_rt_sigreturn; + pseudo_long_call _do_rt_sigreturn, p2; SP += 12; rets = [sp++]; rts; diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index a0bc7d3..b54ba45 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c @@ -220,6 +220,16 @@ void __init bfin_relocate_l1_mem(void) memcpy(_stext_l2, _l2_lma, l2_len); } +#ifdef CONFIG_ROMKERNEL +void __init bfin_relocate_xip_data(void) +{ + early_shadow_stamp(); + + memcpy(_sdata, _data_lma, (unsigned long)_data_len - THREAD_SIZE + sizeof(struct thread_info)); + memcpy(_sinitdata, _init_data_lma, (unsigned long)_init_data_len); +} +#endif + /* add_memory_region to memmap */ static void __init add_memory_region(unsigned long long start, unsigned long long size, int type) @@ -504,7 +514,7 @@ static __init void memory_setup(void) #endif unsigned long max_mem; - _rambase = (unsigned long)_stext; + _rambase = CONFIG_BOOT_LOAD; _ramstart = (unsigned long)_end; if (DMA_UNCACHED_REGION > (_ramend - _ramstart)) { @@ -1261,8 +1271,8 @@ static int show_cpuinfo(struct seq_file *m, void *v) seq_printf(m, "board memory\t: %ld kB (0x%p -> 0x%p)\n", physical_mem_end >> 10, (void *)0, (void *)physical_mem_end); seq_printf(m, "kernel memory\t: %d kB (0x%p -> 0x%p)\n", - ((int)memory_end - (int)_stext) >> 10, - _stext, + ((int)memory_end - (int)_rambase) >> 10, + (void *)_rambase, (void *)memory_end); seq_printf(m, "\n"); diff --git a/arch/blackfin/kernel/vmlinux.lds.S b/arch/blackfin/kernel/vmlinux.lds.S index be4b1bb..984c781 100644 --- a/arch/blackfin/kernel/vmlinux.lds.S +++ b/arch/blackfin/kernel/vmlinux.lds.S @@ -15,7 +15,12 @@ _jiffies = _jiffies_64; SECTIONS { +#ifdef CONFIG_RAMKERNEL . = CONFIG_BOOT_LOAD; +#else + . = CONFIG_ROM_BASE; +#endif + /* Neither the text, ro_data or bss section need to be aligned * So pack them back to back */ @@ -31,6 +36,12 @@ SECTIONS LOCK_TEXT IRQENTRY_TEXT KPROBES_TEXT +#ifdef CONFIG_ROMKERNEL + __sinittext = .; + INIT_TEXT + __einittext = .; + EXIT_TEXT +#endif *(.text.*) *(.fixup) @@ -50,8 +61,14 @@ SECTIONS /* Just in case the first read only is a 32-bit access */ RO_DATA(4) + __rodata_end = .; +#ifdef CONFIG_ROMKERNEL + . = CONFIG_BOOT_LOAD; + .bss : AT(__rodata_end) +#else .bss : +#endif { . = ALIGN(4); ___bss_start = .; @@ -67,7 +84,11 @@ SECTIONS ___bss_stop = .; } +#if defined(CONFIG_ROMKERNEL) + .data : AT(LOADADDR(.bss) + SIZEOF(.bss)) +#else .data : +#endif { __sdata = .; /* This gets done first, so the glob doesn't suck it in */ @@ -94,6 +115,8 @@ SECTIONS __edata = .; } + __data_lma = LOADADDR(.data); + __data_len = SIZEOF(.data); /* The init section should be last, so when we free it, it goes into * the general memory pool, and (hopefully) will decrease fragmentation @@ -103,6 +126,7 @@ SECTIONS . = ALIGN(PAGE_SIZE); ___init_begin = .; +#ifdef CONFIG_RAMKERNEL INIT_TEXT_SECTION(PAGE_SIZE) /* We have to discard exit text and such at runtime, not link time, to @@ -125,6 +149,35 @@ SECTIONS } .text_l1 L1_CODE_START : AT(LOADADDR(.exit.data) + SIZEOF(.exit.data)) +#else + .init.data : AT(__data_lma + __data_len) + { + __sinitdata = .; + INIT_DATA + INIT_SETUP(16) + INIT_CALLS + CON_INITCALL + SECURITY_INITCALL + INIT_RAM_FS + + . = ALIGN(4); + ___per_cpu_load = .; + ___per_cpu_start = .; + *(.data.percpu.first) + *(.data.percpu.page_aligned) + *(.data.percpu) + *(.data.percpu.shared_aligned) + ___per_cpu_end = .; + + EXIT_DATA + __einitdata = .; + } + __init_data_lma = LOADADDR(.init.data); + __init_data_len = SIZEOF(.init.data); + __init_data_end = .; + + .text_l1 L1_CODE_START : AT(__init_data_lma + __init_data_len) +#endif { . = ALIGN(4); __stext_l1 = .; @@ -205,7 +258,11 @@ SECTIONS /* Force trailing alignment of our init section so that when we * free our init memory, we don't leave behind a partial page. */ +#ifdef CONFIG_RAMKERNEL . = __l2_lma + __l2_len; +#else + . = __init_data_end; +#endif . = ALIGN(PAGE_SIZE); ___init_end = .; diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S index 0df7ef2..ccfa7c4 100644 --- a/arch/blackfin/mach-common/entry.S +++ b/arch/blackfin/mach-common/entry.S @@ -405,7 +405,7 @@ ENTRY(_double_fault) r0 = sp; /* stack frame pt_regs pointer argument ==> r0 */ SP += -12; - call _double_fault_c; + pseudo_long_call _double_fault_c, p5; SP += 12; .L_double_fault_panic: JUMP .L_double_fault_panic @@ -447,7 +447,7 @@ ENTRY(_exception_to_level5) r0 = sp; /* stack frame pt_regs pointer argument ==> r0 */ SP += -12; - call _trap_c; + pseudo_long_call _trap_c, p4; SP += 12; /* If interrupts were off during the exception (IPEND[4] = 1), turn them off @@ -551,7 +551,7 @@ ENTRY(_kernel_execve) p0 = sp; sp += -16; [sp + 12] = p0; - call _do_execve; + pseudo_long_call _do_execve, p5; SP += 16; cc = r0 == 0; if ! cc jump .Lexecve_failed; @@ -704,7 +704,7 @@ ENTRY(_system_call) sp += 4; SP += -12; - call _schedule; + pseudo_long_call _schedule, p4; SP += 12; jump .Lresume_userspace_1; @@ -723,7 +723,7 @@ ENTRY(_system_call) r0 = sp; SP += -12; - call _do_notify_resume; + pseudo_long_call _do_notify_resume, p5; SP += 12; .Lsyscall_really_exit: @@ -736,7 +736,7 @@ ENDPROC(_system_call) * this symbol need not be global anyways, so ... */ _sys_trace: - call _syscall_trace; + pseudo_long_call _syscall_trace, p5; /* Execute the appropriate system call */ @@ -760,7 +760,7 @@ _sys_trace: SP += 24; [sp + PT_R0] = r0; - call _syscall_trace; + pseudo_long_call _syscall_trace, p5; jump .Lresume_userspace; ENDPROC(_sys_trace) @@ -1007,7 +1007,8 @@ ENTRY(_schedule_and_signal_from_int) r0 = sp; sp += -12; - call _finish_atomic_sections; + + pseudo_long_call _finish_atomic_sections, p5; sp += 12; jump.s .Lresume_userspace; ENDPROC(_schedule_and_signal_from_int) diff --git a/arch/blackfin/mach-common/head.S b/arch/blackfin/mach-common/head.S index cf03778..4391621 100644 --- a/arch/blackfin/mach-common/head.S +++ b/arch/blackfin/mach-common/head.S @@ -186,6 +186,11 @@ ENTRY(__start) /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */ call _bfin_relocate_l1_mem; + +#ifdef CONFIG_ROMKERNEL + call _bfin_relocate_xip_data; +#endif + #ifdef CONFIG_BFIN_KERNEL_CLOCK /* Only use on-chip scratch space for stack when absolutely required * to avoid Anomaly 05000227 ... we know the init_clocks() func only diff --git a/arch/blackfin/mach-common/interrupt.S b/arch/blackfin/mach-common/interrupt.S index 8085ff1..df98496 100644 --- a/arch/blackfin/mach-common/interrupt.S +++ b/arch/blackfin/mach-common/interrupt.S @@ -109,10 +109,10 @@ __common_int_entry: cc = r0 == 0; if cc jump .Lcommon_restore_context; #else /* CONFIG_IPIPE */ - call _do_irq; + pseudo_long_call _do_irq, p2; SP += 12; #endif /* CONFIG_IPIPE */ - call _return_from_int; + pseudo_long_call _return_from_int, p2; .Lcommon_restore_context: RESTORE_CONTEXT rti; @@ -168,7 +168,7 @@ ENTRY(_evt_ivhw) r0 = sp; /* stack frame pt_regs pointer argument ==> r0 */ SP += -12; - call _trap_c; + pseudo_long_call _trap_c, p5; SP += 12; #ifdef EBIU_ERRMST @@ -179,7 +179,7 @@ ENTRY(_evt_ivhw) w[p0] = r0.l; #endif - call _ret_from_exception; + pseudo_long_call _ret_from_exception, p2; .Lcommon_restore_all_sys: RESTORE_ALL_SYS @@ -223,7 +223,7 @@ ENTRY(_evt_system_call) #ifdef CONFIG_FRAME_POINTER fp = 0; #endif - call _system_call; + pseudo_long_call _system_call, p2; jump .Lcommon_restore_context; ENDPROC(_evt_system_call) -- cgit v0.10.2 From 48a74f9d1b381471397097851531c4e392f97451 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Fri, 8 Jan 2010 20:06:22 +0100 Subject: Blackfin: fix decoding of opcodes 41-47 in decode_instruction() This condition allowed only decoding of opcode 0x0040 Signed-off-by: Roel Kluin Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index d3cbcd6..870d74b 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c @@ -712,7 +712,7 @@ static void decode_instruction(unsigned short *address) verbose_printk("RTE"); else if (opcode == 0x0025) verbose_printk("EMUEXCPT"); - else if (opcode == 0x0040 && opcode <= 0x0047) + else if (opcode >= 0x0040 && opcode <= 0x0047) verbose_printk("STI R%i", opcode & 7); else if (opcode >= 0x0050 && opcode <= 0x0057) verbose_printk("JUMP (P%i)", opcode & 7); -- cgit v0.10.2 From 8d0177dbcbad26ffd451b607c8fa74295d81e7b9 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sat, 9 Jan 2010 00:48:01 +0000 Subject: Blackfin: kgdb: mark all local funcs/structs static Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/kernel/kgdb.c b/arch/blackfin/kernel/kgdb.c index 34c7c3e..2c501ce 100644 --- a/arch/blackfin/kernel/kgdb.c +++ b/arch/blackfin/kernel/kgdb.c @@ -145,7 +145,7 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs) #endif } -struct hw_breakpoint { +static struct hw_breakpoint { unsigned int occupied:1; unsigned int skip:1; unsigned int enabled:1; @@ -155,7 +155,7 @@ struct hw_breakpoint { unsigned int addr; } breakinfo[HW_WATCHPOINT_NUM]; -int bfin_set_hw_break(unsigned long addr, int len, enum kgdb_bptype type) +static int bfin_set_hw_break(unsigned long addr, int len, enum kgdb_bptype type) { int breakno; int bfin_type; @@ -202,7 +202,7 @@ int bfin_set_hw_break(unsigned long addr, int len, enum kgdb_bptype type) return -ENOSPC; } -int bfin_remove_hw_break(unsigned long addr, int len, enum kgdb_bptype type) +static int bfin_remove_hw_break(unsigned long addr, int len, enum kgdb_bptype type) { int breakno; int bfin_type; @@ -230,7 +230,7 @@ int bfin_remove_hw_break(unsigned long addr, int len, enum kgdb_bptype type) return 0; } -void bfin_remove_all_hw_break(void) +static void bfin_remove_all_hw_break(void) { int breakno; @@ -242,7 +242,7 @@ void bfin_remove_all_hw_break(void) breakinfo[breakno].type = TYPE_DATA_WATCHPOINT; } -void bfin_correct_hw_break(void) +static void bfin_correct_hw_break(void) { int breakno; unsigned int wpiactl = 0; -- cgit v0.10.2 From 7e1082b7dbb60081b157d82106da33686cb9ea91 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Tue, 12 Jan 2010 03:59:18 +0000 Subject: Blackfin: bf533-{ezkit,stamp}: add sound platform devices Signed-off-by: Barry Song Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf533/boards/ezkit.c b/arch/blackfin/mach-bf533/boards/ezkit.c index 5332c98..84efda1 100644 --- a/arch/blackfin/mach-bf533/boards/ezkit.c +++ b/arch/blackfin/mach-bf533/boards/ezkit.c @@ -473,6 +473,30 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { #endif }; +#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE) +static struct platform_device bfin_i2s = { + .name = "bfin-i2s", + .id = CONFIG_SND_BF5XX_SPORT_NUM, + /* TODO: add platform data here */ +}; +#endif + +#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE) +static struct platform_device bfin_tdm = { + .name = "bfin-tdm", + .id = CONFIG_SND_BF5XX_SPORT_NUM, + /* TODO: add platform data here */ +}; +#endif + +#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE) +static struct platform_device bfin_ac97 = { + .name = "bfin-ac97", + .id = CONFIG_SND_BF5XX_SPORT_NUM, + /* TODO: add platform data here */ +}; +#endif + static struct platform_device *ezkit_devices[] __initdata = { &bfin_dpmc, @@ -518,6 +542,18 @@ static struct platform_device *ezkit_devices[] __initdata = { #if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) &i2c_gpio_device, #endif + +#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE) + &bfin_i2s, +#endif + +#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE) + &bfin_tdm, +#endif + +#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE) + &bfin_ac97, +#endif }; static int __init ezkit_init(void) diff --git a/arch/blackfin/mach-bf533/boards/stamp.c b/arch/blackfin/mach-bf533/boards/stamp.c index 3e80a79..e997d7f 100644 --- a/arch/blackfin/mach-bf533/boards/stamp.c +++ b/arch/blackfin/mach-bf533/boards/stamp.c @@ -562,6 +562,30 @@ static struct platform_device bfin_dpmc = { }, }; +#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE) +static struct platform_device bfin_i2s = { + .name = "bfin-i2s", + .id = CONFIG_SND_BF5XX_SPORT_NUM, + /* TODO: add platform data here */ +}; +#endif + +#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE) +static struct platform_device bfin_tdm = { + .name = "bfin-tdm", + .id = CONFIG_SND_BF5XX_SPORT_NUM, + /* TODO: add platform data here */ +}; +#endif + +#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE) +static struct platform_device bfin_ac97 = { + .name = "bfin-ac97", + .id = CONFIG_SND_BF5XX_SPORT_NUM, + /* TODO: add platform data here */ +}; +#endif + static struct platform_device *stamp_devices[] __initdata = { &bfin_dpmc, @@ -614,6 +638,18 @@ static struct platform_device *stamp_devices[] __initdata = { #if defined(CONFIG_MTD_BFIN_ASYNC) || defined(CONFIG_MTD_BFIN_ASYNC_MODULE) &stamp_flash_device, #endif + +#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE) + &bfin_i2s, +#endif + +#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE) + &bfin_tdm, +#endif + +#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE) + &bfin_ac97, +#endif }; static int __init stamp_init(void) -- cgit v0.10.2 From c6669c223a409199a45bb8f31a2e160ee26d19cc Mon Sep 17 00:00:00 2001 From: Graf Yang Date: Wed, 13 Jan 2010 06:09:34 +0000 Subject: Blackfin: fix up mm locking in address dumping The locking code in the address dumper needs to grab the mm's mmap_sem so that other CPUs do not get an inconsistent view. On UP systems this really wasn't a problem, but it is easy to trigger a race on SMP systems when another CPU removes a mapping. Signed-off-by: Graf Yang Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index 870d74b..8576680 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c @@ -138,6 +138,12 @@ static void decode_address(char *buf, unsigned long address) if (!mm) continue; + if (!down_read_trylock(&mm->mmap_sem)) { + if (!in_atomic) + mmput(mm); + continue; + } + for (n = rb_first(&mm->mm_rb); n; n = rb_next(n)) { struct vm_area_struct *vma; @@ -177,6 +183,7 @@ static void decode_address(char *buf, unsigned long address) sprintf(buf, "[ %s vma:0x%lx-0x%lx]", name, vma->vm_start, vma->vm_end); + up_read(&mm->mmap_sem); if (!in_atomic) mmput(mm); @@ -186,11 +193,16 @@ static void decode_address(char *buf, unsigned long address) goto done; } } + + up_read(&mm->mmap_sem); if (!in_atomic) mmput(mm); } - /* we were unable to find this address anywhere */ + /* + * we were unable to find this address anywhere, + * or some MMs were skipped because they were in use. + */ sprintf(buf, "/* kernel dynamic memory */"); done: -- cgit v0.10.2 From 29bb3bc0c71d867d50b18a0277bf28cd8dd3fca7 Mon Sep 17 00:00:00 2001 From: Cliff Cai Date: Thu, 14 Jan 2010 08:28:38 +0000 Subject: Blackfin: bf527-ezkit/bf537-stamp: add example SSM2602 I2C resources Signed-off-by: Cliff Cai Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c index a7beed5..9f2cb2b 100644 --- a/arch/blackfin/mach-bf527/boards/ezkit.c +++ b/arch/blackfin/mach-bf527/boards/ezkit.c @@ -905,6 +905,11 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { .platform_data = (void *)&adp5520_pdev_data, }, #endif +#if defined(CONFIG_SND_SOC_SSM2602) || defined(CONFIG_SND_SOC_SSM2602_MODULE) + { + I2C_BOARD_INFO("ssm2602", 0x1b), + }, +#endif }; #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 27b9c9c..d47f4ed 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -1674,6 +1674,11 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { I2C_BOARD_INFO("ad5258", 0x18), }, #endif +#if defined(CONFIG_SND_SOC_SSM2602) || defined(CONFIG_SND_SOC_SSM2602_MODULE) + { + I2C_BOARD_INFO("ssm2602", 0x1b), + }, +#endif }; #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) -- cgit v0.10.2 From 38e7673f24e6c19aba9ecff86760cb7981b91464 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Fri, 15 Jan 2010 03:24:39 +0000 Subject: Blackfin: bf537-stamp: declare parallel flash as ROM with XIP kernel When the kernel is executing out of parallel flash (XIP), we can't have the flash go into an erase/programming cycle, otherwise the instruction fetching steps fail and everything crashes. Signed-off-by: Barry Song Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index d47f4ed..2642970 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -455,6 +455,9 @@ static struct physmap_flash_data stamp_flash_data = { .width = 2, .parts = stamp_partitions, .nr_parts = ARRAY_SIZE(stamp_partitions), +#ifdef CONFIG_ROMKERNEL + .probe_type = "map_rom", +#endif }; static struct resource stamp_flash_resource = { -- cgit v0.10.2 From 5aff1642aee0fe3cb9be7339fcc09dd2bd1976f0 Mon Sep 17 00:00:00 2001 From: Harald Krapfenbauer Date: Fri, 15 Jan 2010 09:25:11 +0000 Subject: Blackfin: tcm-bf518: new board port Signed-off-by: Harald Krapfenbauer Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/configs/TCM-BF518_defconfig b/arch/blackfin/configs/TCM-BF518_defconfig new file mode 100644 index 0000000..4d31e2a --- /dev/null +++ b/arch/blackfin/configs/TCM-BF518_defconfig @@ -0,0 +1,1375 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.32.3 +# +# CONFIG_MMU is not set +# CONFIG_FPU is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_BLACKFIN=y +CONFIG_GENERIC_CSUM=y +CONFIG_GENERIC_BUG=y +CONFIG_ZONE_DMA=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_GENERIC_GPIO=y +CONFIG_FORCE_MAX_ZONEORDER=14 +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_BZIP2=y +CONFIG_HAVE_KERNEL_LZMA=y +# CONFIG_KERNEL_GZIP is not set +# CONFIG_KERNEL_BZIP2 is not set +CONFIG_KERNEL_LZMA=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set +# CONFIG_SYSFS_DEPRECATED_V2 is not set +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_RD_GZIP is not set +# CONFIG_RD_BZIP2 is not set +CONFIG_RD_LZMA=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +# CONFIG_ELF_CORE is not set +CONFIG_BASE_FULL=y +# CONFIG_FUTEX is not set +CONFIG_EPOLL=y +# CONFIG_SIGNALFD is not set +# CONFIG_TIMERFD is not set +# CONFIG_EVENTFD is not set +# CONFIG_AIO is not set + +# +# Kernel Performance Events And Counters +# +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_COMPAT_BRK=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_MMAP_ALLOW_UNINITIALIZED=y +# CONFIG_PROFILING is not set +CONFIG_HAVE_OPROFILE=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +# CONFIG_SLOW_WORK is not set +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +CONFIG_SLABINFO=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_BLOCK=y +# CONFIG_LBDAF is not set +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_NOOP=y +CONFIG_DEFAULT_IOSCHED="noop" +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_PREEMPT is not set +# CONFIG_FREEZER is not set + +# +# Blackfin Processor Options +# + +# +# Processor and Board Settings +# +# CONFIG_BF512 is not set +# CONFIG_BF514 is not set +# CONFIG_BF516 is not set +CONFIG_BF518=y +# CONFIG_BF522 is not set +# CONFIG_BF523 is not set +# CONFIG_BF524 is not set +# CONFIG_BF525 is not set +# CONFIG_BF526 is not set +# CONFIG_BF527 is not set +# CONFIG_BF531 is not set +# CONFIG_BF532 is not set +# CONFIG_BF533 is not set +# CONFIG_BF534 is not set +# CONFIG_BF536 is not set +# CONFIG_BF537 is not set +# CONFIG_BF538 is not set +# CONFIG_BF539 is not set +# CONFIG_BF542_std is not set +# CONFIG_BF542M is not set +# CONFIG_BF544_std is not set +# CONFIG_BF544M is not set +# CONFIG_BF547_std is not set +# CONFIG_BF547M is not set +# CONFIG_BF548_std is not set +# CONFIG_BF548M is not set +# CONFIG_BF549_std is not set +# CONFIG_BF549M is not set +# CONFIG_BF561 is not set +CONFIG_BF_REV_MIN=0 +CONFIG_BF_REV_MAX=2 +# CONFIG_BF_REV_0_0 is not set +CONFIG_BF_REV_0_1=y +# CONFIG_BF_REV_0_2 is not set +# CONFIG_BF_REV_0_3 is not set +# CONFIG_BF_REV_0_4 is not set +# CONFIG_BF_REV_0_5 is not set +# CONFIG_BF_REV_0_6 is not set +# CONFIG_BF_REV_ANY is not set +# CONFIG_BF_REV_NONE is not set +CONFIG_BF51x=y +# CONFIG_BFIN518F_EZBRD is not set +CONFIG_BFIN518F_TCM=y + +# +# BF518 Specific Configuration +# + +# +# Alternative Multiplexing Scheme +# +# CONFIG_BF518_SPORT0_PORTF is not set +CONFIG_BF518_SPORT0_PORTG=y +CONFIG_BF518_SPORT0_TSCLK_PG10=y +# CONFIG_BF518_SPORT0_TSCLK_PG14 is not set +CONFIG_BF518_UART1_PORTF=y +# CONFIG_BF518_UART1_PORTG is not set + +# +# Interrupt Priority Assignment +# + +# +# Priority +# +CONFIG_IRQ_PLL_WAKEUP=7 +CONFIG_IRQ_DMA0_ERROR=7 +CONFIG_IRQ_DMAR0_BLK=7 +CONFIG_IRQ_DMAR1_BLK=7 +CONFIG_IRQ_DMAR0_OVR=7 +CONFIG_IRQ_DMAR1_OVR=7 +CONFIG_IRQ_PPI_ERROR=7 +CONFIG_IRQ_MAC_ERROR=7 +CONFIG_IRQ_SPORT0_ERROR=7 +CONFIG_IRQ_SPORT1_ERROR=7 +CONFIG_IRQ_PTP_ERROR=7 +CONFIG_IRQ_UART0_ERROR=7 +CONFIG_IRQ_UART1_ERROR=7 +CONFIG_IRQ_RTC=8 +CONFIG_IRQ_PPI=8 +CONFIG_IRQ_SPORT0_RX=9 +CONFIG_IRQ_SPORT0_TX=9 +CONFIG_IRQ_SPORT1_RX=9 +CONFIG_IRQ_SPORT1_TX=9 +CONFIG_IRQ_TWI=10 +CONFIG_IRQ_SPI0=10 +CONFIG_IRQ_UART0_RX=10 +CONFIG_IRQ_UART0_TX=10 +CONFIG_IRQ_UART1_RX=10 +CONFIG_IRQ_UART1_TX=10 +CONFIG_IRQ_OPTSEC=11 +CONFIG_IRQ_CNT=11 +CONFIG_IRQ_MAC_RX=11 +CONFIG_IRQ_PORTH_INTA=11 +CONFIG_IRQ_MAC_TX=11 +CONFIG_IRQ_PORTH_INTB=11 +CONFIG_IRQ_TIMER0=12 +CONFIG_IRQ_TIMER1=12 +CONFIG_IRQ_TIMER2=12 +CONFIG_IRQ_TIMER3=12 +CONFIG_IRQ_TIMER4=12 +CONFIG_IRQ_TIMER5=12 +CONFIG_IRQ_TIMER6=12 +CONFIG_IRQ_TIMER7=12 +CONFIG_IRQ_PORTG_INTA=12 +CONFIG_IRQ_PORTG_INTB=12 +CONFIG_IRQ_MEM_DMA0=13 +CONFIG_IRQ_MEM_DMA1=13 +CONFIG_IRQ_WATCH=13 +CONFIG_IRQ_PORTF_INTA=13 +CONFIG_IRQ_PORTF_INTB=13 +CONFIG_IRQ_SPI0_ERROR=7 +CONFIG_IRQ_SPI1_ERROR=7 +CONFIG_IRQ_RSI_INT0=7 +CONFIG_IRQ_RSI_INT1=7 +CONFIG_IRQ_PWM_TRIP=10 +CONFIG_IRQ_PWM_SYNC=10 +CONFIG_IRQ_PTP_STAT=10 + +# +# Board customizations +# +# CONFIG_CMDLINE_BOOL is not set +CONFIG_BOOT_LOAD=0x1000 + +# +# Clock/PLL Setup +# +CONFIG_CLKIN_HZ=25000000 +# CONFIG_BFIN_KERNEL_CLOCK is not set +CONFIG_MAX_VCO_HZ=400000000 +CONFIG_MIN_VCO_HZ=50000000 +CONFIG_MAX_SCLK_HZ=133333333 +CONFIG_MIN_SCLK_HZ=27000000 + +# +# Kernel Timer/Scheduler +# +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +# CONFIG_SCHED_HRTICK is not set +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y + +# +# Clock event device +# +# CONFIG_TICKSOURCE_GPTMR0 is not set +CONFIG_TICKSOURCE_CORETMR=y + +# +# Clock souce +# +# CONFIG_CYCLES_CLOCKSOURCE is not set +# CONFIG_GPTMR0_CLOCKSOURCE is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y + +# +# Misc +# +CONFIG_BFIN_SCRATCH_REG_RETN=y +# CONFIG_BFIN_SCRATCH_REG_RETE is not set +# CONFIG_BFIN_SCRATCH_REG_CYCLES is not set + +# +# Blackfin Kernel Optimizations +# + +# +# Memory Optimizations +# +CONFIG_I_ENTRY_L1=y +CONFIG_EXCPT_IRQ_SYSC_L1=y +CONFIG_DO_IRQ_L1=y +CONFIG_CORE_TIMER_IRQ_L1=y +CONFIG_IDLE_L1=y +# CONFIG_SCHEDULE_L1 is not set +CONFIG_ARITHMETIC_OPS_L1=y +CONFIG_ACCESS_OK_L1=y +# CONFIG_MEMSET_L1 is not set +# CONFIG_MEMCPY_L1 is not set +# CONFIG_SYS_BFIN_SPINLOCK_L1 is not set +# CONFIG_IP_CHECKSUM_L1 is not set +CONFIG_CACHELINE_ALIGNED_L1=y +# CONFIG_SYSCALL_TAB_L1 is not set +# CONFIG_CPLB_SWITCH_TAB_L1 is not set +CONFIG_APP_STACK_L1=y + +# +# Speed Optimizations +# +CONFIG_BFIN_INS_LOWOVERHEAD=y +CONFIG_RAMKERNEL=y +# CONFIG_ROMKERNEL is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_VIRT_TO_BUS=y +CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0 +CONFIG_BFIN_GPTIMERS=m +# CONFIG_DMA_UNCACHED_4M is not set +# CONFIG_DMA_UNCACHED_2M is not set +CONFIG_DMA_UNCACHED_1M=y +# CONFIG_DMA_UNCACHED_512K is not set +# CONFIG_DMA_UNCACHED_256K is not set +# CONFIG_DMA_UNCACHED_128K is not set +# CONFIG_DMA_UNCACHED_NONE is not set + +# +# Cache Support +# +CONFIG_BFIN_ICACHE=y +CONFIG_BFIN_EXTMEM_ICACHEABLE=y +CONFIG_BFIN_DCACHE=y +# CONFIG_BFIN_DCACHE_BANKA is not set +CONFIG_BFIN_EXTMEM_DCACHEABLE=y +CONFIG_BFIN_EXTMEM_WRITEBACK=y +# CONFIG_BFIN_EXTMEM_WRITETHROUGH is not set + +# +# Memory Protection Unit +# +# CONFIG_MPU is not set + +# +# Asynchronous Memory Configuration +# + +# +# EBIU_AMGCTL Global Control +# +CONFIG_C_AMCKEN=y +CONFIG_C_CDPRIO=y +# CONFIG_C_AMBEN is not set +# CONFIG_C_AMBEN_B0 is not set +# CONFIG_C_AMBEN_B0_B1 is not set +# CONFIG_C_AMBEN_B0_B1_B2 is not set +CONFIG_C_AMBEN_ALL=y + +# +# EBIU_AMBCTL Control +# +CONFIG_BANK_0=0x7BB0 +CONFIG_BANK_1=0x7BB0 +CONFIG_BANK_2=0x7BB0 +CONFIG_BANK_3=0x99B2 + +# +# Bus options (PCI, PCMCIA, EISA, MCA, ISA) +# +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF_FDPIC=y +CONFIG_BINFMT_FLAT=y +CONFIG_BINFMT_ZFLAT=y +# CONFIG_BINFMT_SHARED_FLAT is not set +# CONFIG_HAVE_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +# CONFIG_PM is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETLABEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +# CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_TESTS is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set +CONFIG_MTD_MAP_BANK_WIDTH_2=y +# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +# CONFIG_MTD_CFI_I2 is not set +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_OTP is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +CONFIG_MTD_RAM=y +CONFIG_MTD_ROM=m +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +# CONFIG_MTD_PHYSMAP_COMPAT is not set +# CONFIG_MTD_UCLINUX is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_DATAFLASH is not set +# CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SST25L is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_MISC_DEVICES=y +# CONFIG_AD525X_DPOT is not set +# CONFIG_ICS932S401 is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_ISL29003 is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EEPROM_93CX6 is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_BFIN_MAC=y +CONFIG_BFIN_TX_DESC_NUM=10 +CONFIG_BFIN_RX_DESC_NUM=20 +# CONFIG_BFIN_MAC_RMII is not set +CONFIG_BFIN_MAC_USE_HWSTAMP=y +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set +# CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set +# CONFIG_ADF702X is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set +# CONFIG_WLAN is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_UINPUT is not set +# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set +# CONFIG_INPUT_AD714X is not set +# CONFIG_INPUT_ADXL34X is not set +# CONFIG_INPUT_PCF8574 is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_BFIN_DMA_INTERFACE=m +# CONFIG_BFIN_PPI is not set +# CONFIG_BFIN_PPIFCD is not set +# CONFIG_BFIN_SIMPLE_TIMER is not set +# CONFIG_BFIN_SPI_ADC is not set +# CONFIG_BFIN_SPORT is not set +# CONFIG_BFIN_TWI_LCD is not set +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_DEVKMEM is not set +CONFIG_BFIN_JTAG_COMM=m +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_MAX3100 is not set +CONFIG_SERIAL_BFIN=y +CONFIG_SERIAL_BFIN_CONSOLE=y +CONFIG_SERIAL_BFIN_DMA=y +# CONFIG_SERIAL_BFIN_PIO is not set +CONFIG_SERIAL_BFIN_UART0=y +# CONFIG_BFIN_UART0_CTSRTS is not set +# CONFIG_SERIAL_BFIN_UART1 is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_BFIN_SPORT is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +# CONFIG_LEGACY_PTYS is not set +CONFIG_BFIN_OTP=y +# CONFIG_BFIN_OTP_WRITE_ENABLE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_HELPER_AUTO=y + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +CONFIG_I2C_BLACKFIN_TWI=y +CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100 +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_SIMTEC is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_STUB is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_DS1682 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +CONFIG_SPI_BFIN=y +CONFIG_SPI_BFIN_LOCK=y +# CONFIG_SPI_BFIN_SPORT is not set +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set + +# +# SPI Protocol Masters +# +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set + +# +# PPS support +# +# CONFIG_PPS is not set +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_DEBUG_GPIO is not set +CONFIG_GPIO_SYSFS=y + +# +# Memory mapped GPIO expanders: +# + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_ADP5588 is not set + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set + +# +# AC97 GPIO expanders: +# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_BFIN_WDT=y +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_TPS65010 is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13783 is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +CONFIG_DUMMY_CONSOLE=y +# CONFIG_SOUND is not set +# CONFIG_HID_SUPPORT is not set +# CONFIG_USB_SUPPORT is not set +CONFIG_MMC=y +CONFIG_MMC_DEBUG=y +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_SDHCI is not set +# CONFIG_MMC_AT91 is not set +# CONFIG_MMC_ATMELMCI is not set +CONFIG_MMC_SPI=y +# CONFIG_SDH_BFIN is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +CONFIG_RTC_DRV_BFIN=y +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set + +# +# TI VLYNQ +# +# CONFIG_STAGING is not set + +# +# Firmware Drivers +# +# CONFIG_FIRMWARE_MEMMAP is not set +# CONFIG_SIGMA is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +# CONFIG_DNOTIFY is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +# CONFIG_MSDOS_FS is not set +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +# CONFIG_MISC_FILESYSTEMS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_NLS=m +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=m +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=m +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=m +# CONFIG_DLM is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_SECTION_MISMATCH=y +CONFIG_DEBUG_KERNEL=y +CONFIG_DEBUG_SHIRQ=y +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_NOMMU_REGIONS is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set +# CONFIG_FRAME_POINTER is not set +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_PAGE_POISONING is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_DEBUG_STACK_USAGE is not set +CONFIG_DEBUG_VERBOSE=y +CONFIG_DEBUG_MMRS=y +CONFIG_DEBUG_HWERR=y +CONFIG_EXACT_HWERR=y +CONFIG_DEBUG_DOUBLEFAULT=y +CONFIG_DEBUG_DOUBLEFAULT_PRINT=y +# CONFIG_DEBUG_DOUBLEFAULT_RESET is not set +# CONFIG_DEBUG_ICACHE_CHECK is not set +CONFIG_DEBUG_HUNT_FOR_ZERO=y +CONFIG_DEBUG_BFIN_HWTRACE_ON=y +# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF is not set +CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_ONE=y +# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_TWO is not set +CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=1 +# CONFIG_DEBUG_BFIN_HWTRACE_EXPAND is not set +CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE=y +CONFIG_EARLY_PRINTK=y +CONFIG_CPLB_INFO=y +CONFIG_ACCESS_CHECK=y +# CONFIG_BFIN_ISRAM_SELF_TEST is not set + +# +# Security options +# +# CONFIG_KEYS is not set +CONFIG_SECURITY=y +# CONFIG_SECURITYFS is not set +# CONFIG_SECURITY_NETWORK is not set +# CONFIG_SECURITY_PATH is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_SECURITY_TOMOYO is not set +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_MANAGER is not set +# CONFIG_CRYPTO_MANAGER2 is not set +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +# CONFIG_CRYPTO_CBC is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +# CONFIG_CRYPTO_ECB is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +CONFIG_CRC_CCITT=m +# CONFIG_CRC16 is not set +# CONFIG_CRC_T10DIF is not set +CONFIG_CRC_ITU_T=y +CONFIG_CRC32=y +CONFIG_CRC7=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_DECOMPRESS_LZMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff --git a/arch/blackfin/mach-bf518/boards/Kconfig b/arch/blackfin/mach-bf518/boards/Kconfig index 9616351..252261e 100644 --- a/arch/blackfin/mach-bf518/boards/Kconfig +++ b/arch/blackfin/mach-bf518/boards/Kconfig @@ -9,4 +9,9 @@ config BFIN518F_EZBRD help BF518-EZBRD board support. +config BFIN518F_TCM + bool "Bluetechnix TCM-BF518" + help + Bluetechnix TCM-BF518 board support. + endchoice diff --git a/arch/blackfin/mach-bf518/boards/Makefile b/arch/blackfin/mach-bf518/boards/Makefile index 172e859..a9ef25c 100644 --- a/arch/blackfin/mach-bf518/boards/Makefile +++ b/arch/blackfin/mach-bf518/boards/Makefile @@ -3,3 +3,4 @@ # obj-$(CONFIG_BFIN518F_EZBRD) += ezbrd.o +obj-$(CONFIG_BFIN518F_TCM) += tcm-bf518.o diff --git a/arch/blackfin/mach-bf518/boards/tcm-bf518.c b/arch/blackfin/mach-bf518/boards/tcm-bf518.c new file mode 100644 index 0000000..9b72e5c --- /dev/null +++ b/arch/blackfin/mach-bf518/boards/tcm-bf518.c @@ -0,0 +1,753 @@ +/* + * Copyright 2004-2009 Analog Devices Inc. + * 2005 National ICT Australia (NICTA) + * Aidan Williams + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Name the Board for the /proc/cpuinfo + */ +const char bfin_board_name[] = "Bluetechnix TCM-BF518"; + +/* + * Driver needs to know address, irq and flag pin. + */ + +#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) +static struct mtd_partition tcm_partitions[] = { + { + .name = "bootloader(nor)", + .size = 0x40000, + .offset = 0, + }, + { + .name = "linux(nor)", + .size = 0x1C0000, + .offset = MTDPART_OFS_APPEND, + } +}; + +static struct physmap_flash_data tcm_flash_data = { + .width = 2, + .parts = tcm_partitions, + .nr_parts = ARRAY_SIZE(tcm_partitions), +}; + +static struct resource tcm_flash_resource = { + .start = 0x20000000, + .end = 0x201fffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device tcm_flash_device = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &tcm_flash_data, + }, + .num_resources = 1, + .resource = &tcm_flash_resource, +}; +#endif + +#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) +static struct platform_device rtc_device = { + .name = "rtc-bfin", + .id = -1, +}; +#endif + +#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) +static struct platform_device bfin_mii_bus = { + .name = "bfin_mii_bus", +}; + +static struct platform_device bfin_mac_device = { + .name = "bfin_mac", + .dev.platform_data = &bfin_mii_bus, +}; +#endif + +#if defined(CONFIG_MTD_M25P80) \ + || defined(CONFIG_MTD_M25P80_MODULE) +static struct mtd_partition bfin_spi_flash_partitions[] = { + { + .name = "bootloader(spi)", + .size = 0x00040000, + .offset = 0, + .mask_flags = MTD_CAP_ROM + }, { + .name = "linux kernel(spi)", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, + } +}; + +static struct flash_platform_data bfin_spi_flash_data = { + .name = "m25p80", + .parts = bfin_spi_flash_partitions, + .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions), + .type = "m25p16", +}; + +/* SPI flash chip (m25p64) */ +static struct bfin5xx_spi_chip spi_flash_chip_info = { + .enable_dma = 0, /* use dma transfer with this chip*/ + .bits_per_word = 8, +}; +#endif + +#if defined(CONFIG_BFIN_SPI_ADC) \ + || defined(CONFIG_BFIN_SPI_ADC_MODULE) +/* SPI ADC chip */ +static struct bfin5xx_spi_chip spi_adc_chip_info = { + .enable_dma = 1, /* use dma transfer with this chip*/ + .bits_per_word = 16, +}; +#endif + +#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) +static struct bfin5xx_spi_chip mmc_spi_chip_info = { + .enable_dma = 0, + .bits_per_word = 8, +}; +#endif + +#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) +static struct bfin5xx_spi_chip spi_ad7877_chip_info = { + .enable_dma = 0, + .bits_per_word = 16, +}; + +static const struct ad7877_platform_data bfin_ad7877_ts_info = { + .model = 7877, + .vref_delay_usecs = 50, /* internal, no capacitor */ + .x_plate_ohms = 419, + .y_plate_ohms = 486, + .pressure_max = 1000, + .pressure_min = 0, + .stopacq_polarity = 1, + .first_conversion_delay = 3, + .acquisition_time = 1, + .averaging = 1, + .pen_down_acc_interval = 1, +}; +#endif + +#if defined(CONFIG_SND_SOC_WM8731) || defined(CONFIG_SND_SOC_WM8731_MODULE) \ + && defined(CONFIG_SND_SOC_WM8731_SPI) +static struct bfin5xx_spi_chip spi_wm8731_chip_info = { + .enable_dma = 0, + .bits_per_word = 16, +}; +#endif + +#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE) +static struct bfin5xx_spi_chip spidev_chip_info = { + .enable_dma = 0, + .bits_per_word = 8, +}; +#endif + +static struct spi_board_info bfin_spi_board_info[] __initdata = { +#if defined(CONFIG_MTD_M25P80) \ + || defined(CONFIG_MTD_M25P80_MODULE) + { + /* the modalias must be the same as spi device driver name */ + .modalias = "m25p80", /* Name of spi_driver for this device */ + .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, /* Framework bus number */ + .chip_select = 2, /* SPI0_SSEL2 */ + .platform_data = &bfin_spi_flash_data, + .controller_data = &spi_flash_chip_info, + .mode = SPI_MODE_3, + }, +#endif + +#if defined(CONFIG_BFIN_SPI_ADC) \ + || defined(CONFIG_BFIN_SPI_ADC_MODULE) + { + .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */ + .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, /* Framework bus number */ + .chip_select = 1, /* Framework chip select. */ + .platform_data = NULL, /* No spi_driver specific config */ + .controller_data = &spi_adc_chip_info, + }, +#endif + +#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) + { + .modalias = "mmc_spi", + .max_speed_hz = 20000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, + .chip_select = 5, + .controller_data = &mmc_spi_chip_info, + .mode = SPI_MODE_3, + }, +#endif +#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) + { + .modalias = "ad7877", + .platform_data = &bfin_ad7877_ts_info, + .irq = IRQ_PF8, + .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, + .chip_select = 2, + .controller_data = &spi_ad7877_chip_info, + }, +#endif +#if defined(CONFIG_SND_SOC_WM8731) || defined(CONFIG_SND_SOC_WM8731_MODULE) \ + && defined(CONFIG_SND_SOC_WM8731_SPI) + { + .modalias = "wm8731", + .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, + .chip_select = 5, + .controller_data = &spi_wm8731_chip_info, + .mode = SPI_MODE_0, + }, +#endif +#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE) + { + .modalias = "spidev", + .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, + .chip_select = 1, + .controller_data = &spidev_chip_info, + }, +#endif +#if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE) + { + .modalias = "bfin-lq035q1-spi", + .max_speed_hz = 20000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, + .chip_select = 1, + .controller_data = &lq035q1_spi_chip_info, + .mode = SPI_CPHA | SPI_CPOL, + }, +#endif +}; + +/* SPI controller data */ +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) +/* SPI (0) */ +static struct bfin5xx_spi_master bfin_spi0_info = { + .num_chipselect = 6, + .enable_dma = 1, /* master has the ability to do dma transfer */ + .pin_req = {P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0}, +}; + +static struct resource bfin_spi0_resource[] = { + [0] = { + .start = SPI0_REGBASE, + .end = SPI0_REGBASE + 0xFF, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = CH_SPI0, + .end = CH_SPI0, + .flags = IORESOURCE_DMA, + }, + [2] = { + .start = IRQ_SPI0, + .end = IRQ_SPI0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device bfin_spi0_device = { + .name = "bfin-spi", + .id = 0, /* Bus number */ + .num_resources = ARRAY_SIZE(bfin_spi0_resource), + .resource = bfin_spi0_resource, + .dev = { + .platform_data = &bfin_spi0_info, /* Passed to driver */ + }, +}; + +/* SPI (1) */ +static struct bfin5xx_spi_master bfin_spi1_info = { + .num_chipselect = 5, + .enable_dma = 1, /* master has the ability to do dma transfer */ + .pin_req = {P_SPI1_SCK, P_SPI1_MISO, P_SPI1_MOSI, 0}, +}; + +static struct resource bfin_spi1_resource[] = { + [0] = { + .start = SPI1_REGBASE, + .end = SPI1_REGBASE + 0xFF, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = CH_SPI1, + .end = CH_SPI1, + .flags = IORESOURCE_DMA, + }, + [2] = { + .start = IRQ_SPI1, + .end = IRQ_SPI1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device bfin_spi1_device = { + .name = "bfin-spi", + .id = 1, /* Bus number */ + .num_resources = ARRAY_SIZE(bfin_spi1_resource), + .resource = bfin_spi1_resource, + .dev = { + .platform_data = &bfin_spi1_info, /* Passed to driver */ + }, +}; +#endif /* spi master and devices */ + +#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) +#ifdef CONFIG_SERIAL_BFIN_UART0 +static struct resource bfin_uart0_resources[] = { + { + .start = UART0_THR, + .end = UART0_GCTL+2, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_UART0_RX, + .end = IRQ_UART0_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART0_ERROR, + .end = IRQ_UART0_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART0_TX, + .end = CH_UART0_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART0_RX, + .end = CH_UART0_RX, + .flags = IORESOURCE_DMA, + }, +}; + +unsigned short bfin_uart0_peripherals[] = { + P_UART0_TX, P_UART0_RX, 0 +}; + +static struct platform_device bfin_uart0_device = { + .name = "bfin-uart", + .id = 0, + .num_resources = ARRAY_SIZE(bfin_uart0_resources), + .resource = bfin_uart0_resources, + .dev = { + .platform_data = &bfin_uart0_peripherals, /* Passed to driver */ + }, +}; +#endif +#ifdef CONFIG_SERIAL_BFIN_UART1 +static struct resource bfin_uart1_resources[] = { + { + .start = UART1_THR, + .end = UART1_GCTL+2, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_UART1_RX, + .end = IRQ_UART1_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_UART1_ERROR, + .end = IRQ_UART1_ERROR, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART1_TX, + .end = CH_UART1_TX, + .flags = IORESOURCE_DMA, + }, + { + .start = CH_UART1_RX, + .end = CH_UART1_RX, + .flags = IORESOURCE_DMA, + }, +}; + +unsigned short bfin_uart1_peripherals[] = { + P_UART1_TX, P_UART1_RX, 0 +}; + +static struct platform_device bfin_uart1_device = { + .name = "bfin-uart", + .id = 1, + .num_resources = ARRAY_SIZE(bfin_uart1_resources), + .resource = bfin_uart1_resources, + .dev = { + .platform_data = &bfin_uart1_peripherals, /* Passed to driver */ + }, +}; +#endif +#endif + +#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) +#ifdef CONFIG_BFIN_SIR0 +static struct resource bfin_sir0_resources[] = { + { + .start = 0xFFC00400, + .end = 0xFFC004FF, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_UART0_RX, + .end = IRQ_UART0_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART0_RX, + .end = CH_UART0_RX+1, + .flags = IORESOURCE_DMA, + }, +}; + +static struct platform_device bfin_sir0_device = { + .name = "bfin_sir", + .id = 0, + .num_resources = ARRAY_SIZE(bfin_sir0_resources), + .resource = bfin_sir0_resources, +}; +#endif +#ifdef CONFIG_BFIN_SIR1 +static struct resource bfin_sir1_resources[] = { + { + .start = 0xFFC02000, + .end = 0xFFC020FF, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_UART1_RX, + .end = IRQ_UART1_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = CH_UART1_RX, + .end = CH_UART1_RX+1, + .flags = IORESOURCE_DMA, + }, +}; + +static struct platform_device bfin_sir1_device = { + .name = "bfin_sir", + .id = 1, + .num_resources = ARRAY_SIZE(bfin_sir1_resources), + .resource = bfin_sir1_resources, +}; +#endif +#endif + +#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) +static struct resource bfin_twi0_resource[] = { + [0] = { + .start = TWI0_REGBASE, + .end = TWI0_REGBASE, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_TWI, + .end = IRQ_TWI, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device i2c_bfin_twi_device = { + .name = "i2c-bfin-twi", + .id = 0, + .num_resources = ARRAY_SIZE(bfin_twi0_resource), + .resource = bfin_twi0_resource, +}; +#endif + +static struct i2c_board_info __initdata bfin_i2c_board_info[] = { +#if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE) + { + I2C_BOARD_INFO("pcf8574_lcd", 0x22), + }, +#endif +#if defined(CONFIG_INPUT_PCF8574) || defined(CONFIG_INPUT_PCF8574_MODULE) + { + I2C_BOARD_INFO("pcf8574_keypad", 0x27), + .irq = IRQ_PF8, + }, +#endif +}; + +#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART +static struct resource bfin_sport0_uart_resources[] = { + { + .start = SPORT0_TCR1, + .end = SPORT0_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT0_RX, + .end = IRQ_SPORT0_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT0_ERROR, + .end = IRQ_SPORT0_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +unsigned short bfin_sport0_peripherals[] = { + P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, + P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0 +}; + +static struct platform_device bfin_sport0_uart_device = { + .name = "bfin-sport-uart", + .id = 0, + .num_resources = ARRAY_SIZE(bfin_sport0_uart_resources), + .resource = bfin_sport0_uart_resources, + .dev = { + .platform_data = &bfin_sport0_peripherals, /* Passed to driver */ + }, +}; +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART +static struct resource bfin_sport1_uart_resources[] = { + { + .start = SPORT1_TCR1, + .end = SPORT1_MRCS3+4, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_SPORT1_RX, + .end = IRQ_SPORT1_RX+1, + .flags = IORESOURCE_IRQ, + }, + { + .start = IRQ_SPORT1_ERROR, + .end = IRQ_SPORT1_ERROR, + .flags = IORESOURCE_IRQ, + }, +}; + +unsigned short bfin_sport1_peripherals[] = { + P_SPORT1_TFS, P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, + P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_DRSEC, P_SPORT1_DTSEC, 0 +}; + +static struct platform_device bfin_sport1_uart_device = { + .name = "bfin-sport-uart", + .id = 1, + .num_resources = ARRAY_SIZE(bfin_sport1_uart_resources), + .resource = bfin_sport1_uart_resources, + .dev = { + .platform_data = &bfin_sport1_peripherals, /* Passed to driver */ + }, +}; +#endif +#endif + +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) +#include +#include + +static struct gpio_keys_button bfin_gpio_keys_table[] = { + {BTN_0, GPIO_PG0, 1, "gpio-keys: BTN0"}, + {BTN_1, GPIO_PG13, 1, "gpio-keys: BTN1"}, +}; + +static struct gpio_keys_platform_data bfin_gpio_keys_data = { + .buttons = bfin_gpio_keys_table, + .nbuttons = ARRAY_SIZE(bfin_gpio_keys_table), +}; + +static struct platform_device bfin_device_gpiokeys = { + .name = "gpio-keys", + .dev = { + .platform_data = &bfin_gpio_keys_data, + }, +}; +#endif + +#if defined(CONFIG_SDH_BFIN) || defined(CONFIG_SDH_BFIN_MODULE) + +static struct bfin_sd_host bfin_sdh_data = { + .dma_chan = CH_RSI, + .irq_int0 = IRQ_RSI_INT0, + .pin_req = {P_RSI_DATA0, P_RSI_DATA1, P_RSI_DATA2, P_RSI_DATA3, P_RSI_CMD, P_RSI_CLK, 0}, +}; + +static struct platform_device bf51x_sdh_device = { + .name = "bfin-sdh", + .id = 0, + .dev = { + .platform_data = &bfin_sdh_data, + }, +}; +#endif + +static const unsigned int cclk_vlev_datasheet[] = +{ + VRPAIR(VLEV_100, 400000000), + VRPAIR(VLEV_105, 426000000), + VRPAIR(VLEV_110, 500000000), + VRPAIR(VLEV_115, 533000000), + VRPAIR(VLEV_120, 600000000), +}; + +static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = { + .tuple_tab = cclk_vlev_datasheet, + .tabsize = ARRAY_SIZE(cclk_vlev_datasheet), + .vr_settling_time = 25 /* us */, +}; + +static struct platform_device bfin_dpmc = { + .name = "bfin dpmc", + .dev = { + .platform_data = &bfin_dmpc_vreg_data, + }, +}; + +static struct platform_device *tcm_devices[] __initdata = { + + &bfin_dpmc, + +#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) + &rtc_device, +#endif + +#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) + &bfin_mii_bus, + &bfin_mac_device, +#endif + +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) + &bfin_spi0_device, + &bfin_spi1_device, +#endif + +#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART1 + &bfin_uart1_device, +#endif +#endif + +#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) +#ifdef CONFIG_BFIN_SIR0 + &bfin_sir0_device, +#endif +#ifdef CONFIG_BFIN_SIR1 + &bfin_sir1_device, +#endif +#endif + +#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) + &i2c_bfin_twi_device, +#endif + +#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART + &bfin_sport0_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART + &bfin_sport1_uart_device, +#endif +#endif + +#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) + &bfin_device_gpiokeys, +#endif + +#if defined(CONFIG_SDH_BFIN) || defined(CONFIG_SDH_BFIN_MODULE) + &bf51x_sdh_device, +#endif + +#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) + &tcm_flash_device, +#endif +}; + +static int __init tcm_init(void) +{ + printk(KERN_INFO "%s(): registering device resources\n", __func__); + i2c_register_board_info(0, bfin_i2c_board_info, + ARRAY_SIZE(bfin_i2c_board_info)); + platform_add_devices(tcm_devices, ARRAY_SIZE(tcm_devices)); + spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); + return 0; +} + +arch_initcall(tcm_init); + +static struct platform_device *tcm_early_devices[] __initdata = { +#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK) +#ifdef CONFIG_SERIAL_BFIN_UART0 + &bfin_uart0_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_UART1 + &bfin_uart1_device, +#endif +#endif + +#if defined(CONFIG_SERIAL_BFIN_SPORT_CONSOLE) +#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART + &bfin_sport0_uart_device, +#endif +#ifdef CONFIG_SERIAL_BFIN_SPORT1_UART + &bfin_sport1_uart_device, +#endif +#endif +}; + +void __init native_machine_early_platform_add_devices(void) +{ + printk(KERN_INFO "register early platform devices\n"); + early_platform_add_devices(tcm_early_devices, + ARRAY_SIZE(tcm_early_devices)); +} + +void native_machine_restart(char *cmd) +{ + /* workaround reboot hang when booting from SPI */ + if ((bfin_read_SYSCR() & 0x7) == 0x3) + bfin_reset_boot_spi_cs(P_DEFAULT_BOOT_SPI_CS); +} + +void bfin_get_ether_addr(char *addr) +{ + random_ether_addr(addr); + printk(KERN_WARNING "%s:%s: Setting Ethernet MAC to a random one\n", __FILE__, __func__); +} +EXPORT_SYMBOL(bfin_get_ether_addr); -- cgit v0.10.2 From 441504df6b81302c06010083c8d63b1465ead405 Mon Sep 17 00:00:00 2001 From: Yi Li Date: Tue, 19 Jan 2010 04:35:28 +0000 Subject: Blackfin: add support for irqflags tracing Signed-off-by: Yi Li Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/context.S b/arch/blackfin/include/asm/context.S index fada8e9..1f90603 100644 --- a/arch/blackfin/include/asm/context.S +++ b/arch/blackfin/include/asm/context.S @@ -73,6 +73,11 @@ #else cli r0; #endif +#ifdef CONFIG_TRACE_IRQFLAGS + sp += -12; + call _trace_hardirqs_off; + sp += 12; +#endif [--sp] = RETI; /*orig_pc*/ /* Clear all L registers. */ r0 = 0 (x); @@ -279,6 +284,13 @@ RETN = [sp++]; RETX = [sp++]; RETI = [sp++]; + +#ifdef CONFIG_TRACE_IRQFLAGS + sp += -12; + call _trace_hardirqs_on; + sp += 12; +#endif + RETS = [sp++]; #ifdef CONFIG_SMP diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S index ccfa7c4..1fa414f 100644 --- a/arch/blackfin/mach-common/entry.S +++ b/arch/blackfin/mach-common/entry.S @@ -966,6 +966,13 @@ ENTRY(_evt_evt14) #else cli r0; #endif +#ifdef CONFIG_TRACE_IRQFLAGS + [--sp] = rets; + sp += -12; + call _trace_hardirqs_off; + sp += 12; + rets = [sp++]; +#endif [--sp] = RETI; SP += 4; rts; @@ -989,6 +996,14 @@ ENTRY(_schedule_and_signal_from_int) p1 = rets; [sp + PT_RESERVED] = p1; +#ifdef CONFIG_TRACE_IRQFLAGS + /* trace_hardirqs_on() checks if all irqs are disabled. But here IRQ 15 + * is turned on, so disable all irqs. */ + cli r0; + sp += -12; + call _trace_hardirqs_on; + sp += 12; +#endif #ifdef CONFIG_SMP GET_PDA(p0, r0); /* Fetch current PDA (can't migrate to other CPU here) */ r0 = [p0 + PDA_IRQFLAGS]; diff --git a/arch/blackfin/mach-common/interrupt.S b/arch/blackfin/mach-common/interrupt.S index df98496..0a0c088 100644 --- a/arch/blackfin/mach-common/interrupt.S +++ b/arch/blackfin/mach-common/interrupt.S @@ -88,6 +88,13 @@ __common_int_entry: #else cli r1; #endif +#ifdef CONFIG_TRACE_IRQFLAGS + [--sp] = r0; + sp += -12; + call _trace_hardirqs_off; + sp += 12; + r0 = [sp++]; +#endif [--sp] = RETI; /* orig_pc */ /* Clear all L registers. */ r1 = 0 (x); -- cgit v0.10.2 From 0531c467da6438f278e9420a30f73eea2fdb73bd Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 19 Jan 2010 07:04:29 +0000 Subject: Blackfin: bf537-stamp: move ADF7021 MAC storage into platform resources Just generate a random MAC on the demo board since the ADF702x lacks dedicated storage for such things. Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 2642970..f78861a 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -22,6 +22,7 @@ #endif #include #include +#include #include #include #include @@ -816,6 +817,12 @@ static struct adf702x_platform_data adf7021_platform_data = { .adf702x_regs = adf7021_regs, .tx_reg = TXREG, }; +static inline void adf702x_mac_init(void) +{ + random_ether_addr(adf7021_platform_data.mac_addr); +} +#else +static inline void adf702x_mac_init(void) {} #endif #if defined(CONFIG_MTD_DATAFLASH) \ @@ -1967,6 +1974,7 @@ static int __init stamp_init(void) { printk(KERN_INFO "%s(): registering device resources\n", __func__); bfin_plat_nand_init(); + adf702x_mac_init(); platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices)); i2c_register_board_info(0, bfin_i2c_board_info, ARRAY_SIZE(bfin_i2c_board_info)); -- cgit v0.10.2 From 5e8d3210b5bffbe64afca9152241284a46611c7e Mon Sep 17 00:00:00 2001 From: Barry Song Date: Tue, 19 Jan 2010 11:01:08 +0000 Subject: Blackfin: fill out the signal si_addr when sending a SIGBUS/SIGSEGV Some userspace applications use this member in diagnosing crashes. It also makes some LTP tests pass (i.e. the Blackfin arch behaves more like everyone else). Signed-off-by: Barry Song Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index 8576680..4eaca2d1 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c @@ -260,9 +260,7 @@ asmlinkage notrace void trap_c(struct pt_regs *fp) #ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON int j; #endif -#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO unsigned int cpu = raw_smp_processor_id(); -#endif const char *strerror = NULL; int sig = 0; siginfo_t info; @@ -651,7 +649,17 @@ asmlinkage notrace void trap_c(struct pt_regs *fp) { info.si_signo = sig; info.si_errno = 0; - info.si_addr = (void __user *)fp->pc; + switch (trapnr) { + case VEC_CPLB_VL: + case VEC_MISALI_D: + case VEC_CPLB_M: + case VEC_CPLB_MHIT: + info.si_addr = (void __user *)cpu_pda[cpu].dcplb_fault_addr; + break; + default: + info.si_addr = (void __user *)fp->pc; + break; + } force_sig_info(sig, &info, current); } -- cgit v0.10.2 From f3dec78333d6369161eb833dbd8c8f006f359fdf Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Tue, 19 Jan 2010 14:45:38 +0000 Subject: Blackfin: increase NR_IRQS beyond NR on-chip IRQs This makes room for off-chip IRQ controllers. Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/irq.h b/arch/blackfin/include/asm/irq.h index e7c0623..89de539 100644 --- a/arch/blackfin/include/asm/irq.h +++ b/arch/blackfin/include/asm/irq.h @@ -12,6 +12,9 @@ #include +/* IRQs that may be used by external irq_chip controllers */ +#define NR_SPARE_IRQS 32 + #include /* SYS_IRQS and NR_IRQS are defined in */ diff --git a/arch/blackfin/mach-bf518/include/mach/irq.h b/arch/blackfin/mach-bf518/include/mach/irq.h index 14e52ec..52edc84 100644 --- a/arch/blackfin/mach-bf518/include/mach/irq.h +++ b/arch/blackfin/mach-bf518/include/mach/irq.h @@ -151,7 +151,8 @@ #define GPIO_IRQ_BASE IRQ_PF0 -#define NR_IRQS (IRQ_PH15 + 1) +#define NR_MACH_IRQS (IRQ_PH15 + 1) +#define NR_IRQS (NR_MACH_IRQS + NR_SPARE_IRQS) #define IVG7 7 #define IVG8 8 diff --git a/arch/blackfin/mach-bf527/include/mach/irq.h b/arch/blackfin/mach-bf527/include/mach/irq.h index aa6579a..17604b4 100644 --- a/arch/blackfin/mach-bf527/include/mach/irq.h +++ b/arch/blackfin/mach-bf527/include/mach/irq.h @@ -151,7 +151,8 @@ #define GPIO_IRQ_BASE IRQ_PF0 -#define NR_IRQS (IRQ_PH15+1) +#define NR_MACH_IRQS (IRQ_PH15 + 1) +#define NR_IRQS (NR_MACH_IRQS + NR_SPARE_IRQS) #define IVG7 7 #define IVG8 8 diff --git a/arch/blackfin/mach-bf533/include/mach/irq.h b/arch/blackfin/mach-bf533/include/mach/irq.h index c31498b..1f7e976 100644 --- a/arch/blackfin/mach-bf533/include/mach/irq.h +++ b/arch/blackfin/mach-bf533/include/mach/irq.h @@ -104,7 +104,8 @@ Core Emulation ** #define GPIO_IRQ_BASE IRQ_PF0 -#define NR_IRQS (IRQ_PF15+1) +#define NR_MACH_IRQS (IRQ_PF15 + 1) +#define NR_IRQS (NR_MACH_IRQS + NR_SPARE_IRQS) #define IVG7 7 #define IVG8 8 diff --git a/arch/blackfin/mach-bf537/include/mach/irq.h b/arch/blackfin/mach-bf537/include/mach/irq.h index 0defa94..9b2cbca 100644 --- a/arch/blackfin/mach-bf537/include/mach/irq.h +++ b/arch/blackfin/mach-bf537/include/mach/irq.h @@ -134,7 +134,8 @@ #define GPIO_IRQ_BASE IRQ_PF0 -#define NR_IRQS (IRQ_PH15+1) +#define NR_MACH_IRQS (IRQ_PH15 + 1) +#define NR_IRQS (NR_MACH_IRQS + NR_SPARE_IRQS) #define IVG7 7 #define IVG8 8 diff --git a/arch/blackfin/mach-bf538/include/mach/irq.h b/arch/blackfin/mach-bf538/include/mach/irq.h index a4b7fcb..7a479d2 100644 --- a/arch/blackfin/mach-bf538/include/mach/irq.h +++ b/arch/blackfin/mach-bf538/include/mach/irq.h @@ -110,7 +110,8 @@ #define GPIO_IRQ_BASE IRQ_PF0 -#define NR_IRQS (IRQ_PF15+1) +#define NR_MACH_IRQS (IRQ_PF15 + 1) +#define NR_IRQS (NR_MACH_IRQS + NR_SPARE_IRQS) #define IVG7 7 #define IVG8 8 diff --git a/arch/blackfin/mach-bf548/include/mach/irq.h b/arch/blackfin/mach-bf548/include/mach/irq.h index 106db05..1f99b51 100644 --- a/arch/blackfin/mach-bf548/include/mach/irq.h +++ b/arch/blackfin/mach-bf548/include/mach/irq.h @@ -317,7 +317,8 @@ Events (highest priority) EMU 0 #define GPIO_IRQ_BASE IRQ_PA0 -#define NR_IRQS (IRQ_PJ15+1) +#define NR_MACH_IRQS (IRQ_PJ15 + 1) +#define NR_IRQS (NR_MACH_IRQS + NR_SPARE_IRQS) /* For compatibility reasons with existing code */ diff --git a/arch/blackfin/mach-bf561/include/mach/irq.h b/arch/blackfin/mach-bf561/include/mach/irq.h index 7b208db..c95566a 100644 --- a/arch/blackfin/mach-bf561/include/mach/irq.h +++ b/arch/blackfin/mach-bf561/include/mach/irq.h @@ -265,7 +265,8 @@ #define GPIO_IRQ_BASE IRQ_PF0 -#define NR_IRQS (IRQ_PF47 + 1) +#define NR_MACH_IRQS (IRQ_PF47 + 1) +#define NR_IRQS (NR_MACH_IRQS + NR_SPARE_IRQS) #define IVG7 7 #define IVG8 8 diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c index 3589fe8..ebf8860 100644 --- a/arch/blackfin/mach-common/ints-priority.c +++ b/arch/blackfin/mach-common/ints-priority.c @@ -1114,7 +1114,7 @@ int __init init_arch_irq(void) #endif /* if configured as edge, then will be changed to do_edge_IRQ */ - for (irq = GPIO_IRQ_BASE; irq < NR_IRQS; irq++) + for (irq = GPIO_IRQ_BASE; irq < NR_MACH_IRQS; irq++) set_irq_chip_and_handler(irq, &bfin_gpio_irqchip, handle_level_irq); -- cgit v0.10.2 From 439b486746df9f57524e002dfd6117bbc040e925 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Fri, 13 Nov 2009 02:41:07 +0000 Subject: Blackfin: bf548-ezkit: add ASoC CPU DAI resources Signed-off-by: Barry Song Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c index b5d8ea1..5b39299 100644 --- a/arch/blackfin/mach-bf548/boards/ezkit.c +++ b/arch/blackfin/mach-bf548/boards/ezkit.c @@ -1257,6 +1257,30 @@ static struct platform_device bfin_dpmc = { }, }; +#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE) +static struct platform_device bfin_i2s = { + .name = "bfin-i2s", + .id = CONFIG_SND_BF5XX_SPORT_NUM, + /* TODO: add platform data here */ +}; +#endif + +#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE) +static struct platform_device bfin_tdm = { + .name = "bfin-tdm", + .id = CONFIG_SND_BF5XX_SPORT_NUM, + /* TODO: add platform data here */ +}; +#endif + +#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE) +static struct platform_device bfin_ac97 = { + .name = "bfin-ac97", + .id = CONFIG_SND_BF5XX_SPORT_NUM, + /* TODO: add platform data here */ +}; +#endif + static struct platform_device *ezkit_devices[] __initdata = { &bfin_dpmc, @@ -1369,6 +1393,18 @@ static struct platform_device *ezkit_devices[] __initdata = { #if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) &ezkit_flash_device, #endif + +#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE) + &bfin_i2s, +#endif + +#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE) + &bfin_tdm, +#endif + +#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE) + &bfin_ac97, +#endif }; static int __init ezkit_init(void) -- cgit v0.10.2 From 336746ed8ee8ef503ba79bc4b6f0b5a40e8ab3ce Mon Sep 17 00:00:00 2001 From: Barry Song Date: Tue, 13 Oct 2009 09:19:18 +0000 Subject: Blackfin: bf537-stamp/bf527-ezkit: move ASoC SPORT resources to boards file Rather than declaring pin resources in the drivers, do it in the board. Signed-off-by: Barry Song Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c index 9f2cb2b..3d32a35 100644 --- a/arch/blackfin/mach-bf527/boards/ezkit.c +++ b/arch/blackfin/mach-bf527/boards/ezkit.c @@ -494,6 +494,22 @@ static struct bfin5xx_spi_chip spidev_chip_info = { }; #endif +#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE) +static struct platform_device bfin_i2s = { + .name = "bfin-i2s", + .id = CONFIG_SND_BF5XX_SPORT_NUM, + /* TODO: add platform data here */ +}; +#endif + +#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE) +static struct platform_device bfin_tdm = { + .name = "bfin-tdm", + .id = CONFIG_SND_BF5XX_SPORT_NUM, + /* TODO: add platform data here */ +}; +#endif + #if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE) static struct bfin5xx_spi_chip lq035q1_spi_chip_info = { .enable_dma = 0, @@ -1152,6 +1168,14 @@ static struct platform_device *stamp_devices[] __initdata = { #if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) &ezkit_flash_device, #endif + +#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE) + &bfin_i2s, +#endif + +#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE) + &bfin_tdm, +#endif }; static int __init ezkit_init(void) diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index f78861a..80b3b57 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -1849,9 +1849,26 @@ static struct platform_device bfin_dpmc = { }, }; +#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE) +static struct platform_device bfin_i2s = { + .name = "bfin-i2s", + .id = CONFIG_SND_BF5XX_SPORT_NUM, + /* TODO: add platform data here */ +}; +#endif + #if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE) static struct platform_device bfin_tdm = { .name = "bfin-tdm", + .id = CONFIG_SND_BF5XX_SPORT_NUM, + /* TODO: add platform data here */ +}; +#endif + +#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE) +static struct platform_device bfin_ac97 = { + .name = "bfin-ac97", + .id = CONFIG_SND_BF5XX_SPORT_NUM, /* TODO: add platform data here */ }; #endif @@ -1965,9 +1982,17 @@ static struct platform_device *stamp_devices[] __initdata = { &stamp_flash_device, #endif +#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE) + &bfin_i2s, +#endif + #if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE) &bfin_tdm, #endif + +#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE) + &bfin_ac97, +#endif }; static int __init stamp_init(void) -- cgit v0.10.2 From 726e96561e4704278bc5197238f6459e1a63aa77 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Wed, 20 Jan 2010 07:25:31 +0000 Subject: Blackfin: respect the L1 kconfig optimization in the MPU code Restore support for CONFIG_EXCPT_IRQ_SYSC_L1 in the MPU CPLB manager. Signed-off-by: Barry Song Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c index 7e6383d..87b25b1 100644 --- a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c +++ b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c @@ -31,6 +31,12 @@ int nr_dcplb_miss[NR_CPUS], nr_icplb_miss[NR_CPUS]; int nr_icplb_supv_miss[NR_CPUS], nr_dcplb_prot[NR_CPUS]; int nr_cplb_flush[NR_CPUS]; +#ifdef CONFIG_EXCPT_IRQ_SYSC_L1 +#define MGR_ATTR __attribute__((l1_text)) +#else +#define MGR_ATTR +#endif + /* * Given the contents of the status register, return the index of the * CPLB that caused the fault. @@ -59,7 +65,7 @@ static int icplb_rr_index[NR_CPUS], dcplb_rr_index[NR_CPUS]; /* * Find an ICPLB entry to be evicted and return its index. */ -static int evict_one_icplb(unsigned int cpu) +MGR_ATTR static int evict_one_icplb(unsigned int cpu) { int i; for (i = first_switched_icplb; i < MAX_CPLBS; i++) @@ -74,7 +80,7 @@ static int evict_one_icplb(unsigned int cpu) return i; } -static int evict_one_dcplb(unsigned int cpu) +MGR_ATTR static int evict_one_dcplb(unsigned int cpu) { int i; for (i = first_switched_dcplb; i < MAX_CPLBS; i++) @@ -89,7 +95,7 @@ static int evict_one_dcplb(unsigned int cpu) return i; } -static noinline int dcplb_miss(unsigned int cpu) +MGR_ATTR static noinline int dcplb_miss(unsigned int cpu) { unsigned long addr = bfin_read_DCPLB_FAULT_ADDR(); int status = bfin_read_DCPLB_STATUS(); @@ -163,7 +169,7 @@ static noinline int dcplb_miss(unsigned int cpu) return 0; } -static noinline int icplb_miss(unsigned int cpu) +MGR_ATTR static noinline int icplb_miss(unsigned int cpu) { unsigned long addr = bfin_read_ICPLB_FAULT_ADDR(); int status = bfin_read_ICPLB_STATUS(); @@ -269,7 +275,7 @@ static noinline int icplb_miss(unsigned int cpu) return 0; } -static noinline int dcplb_protection_fault(unsigned int cpu) +MGR_ATTR static noinline int dcplb_protection_fault(unsigned int cpu) { int status = bfin_read_DCPLB_STATUS(); @@ -289,7 +295,7 @@ static noinline int dcplb_protection_fault(unsigned int cpu) return CPLB_PROT_VIOL; } -int cplb_hdr(int seqstat, struct pt_regs *regs) +MGR_ATTR int cplb_hdr(int seqstat, struct pt_regs *regs) { int cause = seqstat & 0x3f; unsigned int cpu = raw_smp_processor_id(); -- cgit v0.10.2 From 60ffdb36547da2397d6cfefe9c752ebad16524f6 Mon Sep 17 00:00:00 2001 From: Graf Yang Date: Wed, 20 Jan 2010 10:56:24 +0000 Subject: Blackfin: implement nmi_watchdog for SMP on BF561 Signed-off-by: Graf Yang Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/Kconfig.debug b/arch/blackfin/Kconfig.debug index 87f195e..1460d7b 100644 --- a/arch/blackfin/Kconfig.debug +++ b/arch/blackfin/Kconfig.debug @@ -238,6 +238,15 @@ config EARLY_PRINTK all of this lives in the init section and is thrown away after the kernel boots completely. +config NMI_WATCHDOG + bool "Enable NMI watchdog to help debugging lockup on SMP" + default n + depends on (SMP && !BFIN_SCRATCH_REG_RETN) + help + If any CPU in the system does not execute the period local timer + interrupt for more than 5 seconds, then the NMI handler dumps debug + information. This information can be used to debug the lockup. + config CPLB_INFO bool "Display the CPLB information" help diff --git a/arch/blackfin/include/asm/irq.h b/arch/blackfin/include/asm/irq.h index 89de539..12f4060 100644 --- a/arch/blackfin/include/asm/irq.h +++ b/arch/blackfin/include/asm/irq.h @@ -38,4 +38,8 @@ #include +#ifdef CONFIG_NMI_WATCHDOG +# define ARCH_HAS_NMI_WATCHDOG +#endif + #endif /* _BFIN_IRQ_H_ */ diff --git a/arch/blackfin/include/asm/nmi.h b/arch/blackfin/include/asm/nmi.h new file mode 100644 index 0000000..b9caac4 --- /dev/null +++ b/arch/blackfin/include/asm/nmi.h @@ -0,0 +1,12 @@ +/* + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 + */ + +#ifndef _BFIN_NMI_H_ +#define _BFIN_NMI_H_ + +#include + +#endif diff --git a/arch/blackfin/include/asm/smp.h b/arch/blackfin/include/asm/smp.h index 29fb882..7f26de0 100644 --- a/arch/blackfin/include/asm/smp.h +++ b/arch/blackfin/include/asm/smp.h @@ -22,6 +22,7 @@ extern char coreb_trampoline_start, coreb_trampoline_end; struct corelock_slot { int lock; }; +extern struct corelock_slot corelock; void smp_icache_flush_range_others(unsigned long start, unsigned long end); diff --git a/arch/blackfin/kernel/Makefile b/arch/blackfin/kernel/Makefile index a8ddbc8..346a421 100644 --- a/arch/blackfin/kernel/Makefile +++ b/arch/blackfin/kernel/Makefile @@ -25,6 +25,7 @@ obj-$(CONFIG_CPLB_INFO) += cplbinfo.o obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_KGDB) += kgdb.o obj-$(CONFIG_KGDB_TESTS) += kgdb_test.o +obj-$(CONFIG_NMI_WATCHDOG) += nmi.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_EARLY_PRINTK) += shadow_console.o obj-$(CONFIG_STACKTRACE) += stacktrace.o diff --git a/arch/blackfin/kernel/nmi.c b/arch/blackfin/kernel/nmi.c new file mode 100644 index 0000000..19093c1 --- /dev/null +++ b/arch/blackfin/kernel/nmi.c @@ -0,0 +1,313 @@ +/* + * Blackfin nmi_watchdog Driver + * + * Originally based on bfin_wdt.c + * Copyright 2010-2010 Analog Devices Inc. + * Graff Yang + * + * Enter bugs at http://blackfin.uclinux.org/ + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Bit in WDOG_CTL that indicates watchdog has expired (WDR0) */ +#define WDOG_EXPIRED 0x8000 + +/* Masks for WDEV field in WDOG_CTL register */ +#define ICTL_RESET 0x0 +#define ICTL_NMI 0x2 +#define ICTL_GPI 0x4 +#define ICTL_NONE 0x6 +#define ICTL_MASK 0x6 + +/* Masks for WDEN field in WDOG_CTL register */ +#define WDEN_MASK 0x0FF0 +#define WDEN_ENABLE 0x0000 +#define WDEN_DISABLE 0x0AD0 + +#define DRV_NAME "nmi-wdt" + +#define NMI_WDT_TIMEOUT 5 /* 5 seconds */ +#define NMI_CHECK_TIMEOUT (4 * HZ) /* 4 seconds in jiffies */ +static int nmi_wdt_cpu = 1; + +static unsigned int timeout = NMI_WDT_TIMEOUT; +static int nmi_active; + +static unsigned short wdoga_ctl; +static unsigned int wdoga_cnt; +static struct corelock_slot saved_corelock; +static atomic_t nmi_touched[NR_CPUS]; +static struct timer_list ntimer; + +enum { + COREA_ENTER_NMI = 0, + COREA_EXIT_NMI, + COREB_EXIT_NMI, + + NMI_EVENT_NR, +}; +static unsigned long nmi_event __attribute__ ((__section__(".l2.bss"))); + +/* we are in nmi, non-atomic bit ops is safe */ +static inline void set_nmi_event(int event) +{ + __set_bit(event, &nmi_event); +} + +static inline void wait_nmi_event(int event) +{ + while (!test_bit(event, &nmi_event)) + barrier(); + __clear_bit(event, &nmi_event); +} + +static inline void send_corea_nmi(void) +{ + wdoga_ctl = bfin_read_WDOGA_CTL(); + wdoga_cnt = bfin_read_WDOGA_CNT(); + + bfin_write_WDOGA_CTL(WDEN_DISABLE); + bfin_write_WDOGA_CNT(0); + bfin_write_WDOGA_CTL(WDEN_ENABLE | ICTL_NMI); +} + +static inline void restore_corea_nmi(void) +{ + bfin_write_WDOGA_CTL(WDEN_DISABLE); + bfin_write_WDOGA_CTL(WDOG_EXPIRED | WDEN_DISABLE | ICTL_NONE); + + bfin_write_WDOGA_CNT(wdoga_cnt); + bfin_write_WDOGA_CTL(wdoga_ctl); +} + +static inline void save_corelock(void) +{ + saved_corelock = corelock; + corelock.lock = 0; +} + +static inline void restore_corelock(void) +{ + corelock = saved_corelock; +} + + +static inline void nmi_wdt_keepalive(void) +{ + bfin_write_WDOGB_STAT(0); +} + +static inline void nmi_wdt_stop(void) +{ + bfin_write_WDOGB_CTL(WDEN_DISABLE); +} + +/* before calling this function, you must stop the WDT */ +static inline void nmi_wdt_clear(void) +{ + /* clear TRO bit, disable event generation */ + bfin_write_WDOGB_CTL(WDOG_EXPIRED | WDEN_DISABLE | ICTL_NONE); +} + +static inline void nmi_wdt_start(void) +{ + bfin_write_WDOGB_CTL(WDEN_ENABLE | ICTL_NMI); +} + +static inline int nmi_wdt_running(void) +{ + return ((bfin_read_WDOGB_CTL() & WDEN_MASK) != WDEN_DISABLE); +} + +static inline int nmi_wdt_set_timeout(unsigned long t) +{ + u32 cnt, max_t, sclk; + int run; + + sclk = get_sclk(); + max_t = -1 / sclk; + cnt = t * sclk; + if (t > max_t) { + pr_warning("NMI: timeout value is too large\n"); + return -EINVAL; + } + + run = nmi_wdt_running(); + nmi_wdt_stop(); + bfin_write_WDOGB_CNT(cnt); + if (run) + nmi_wdt_start(); + + timeout = t; + + return 0; +} + +int check_nmi_wdt_touched(void) +{ + unsigned int this_cpu = smp_processor_id(); + unsigned int cpu; + + cpumask_t mask = cpu_online_map; + + if (!atomic_read(&nmi_touched[this_cpu])) + return 0; + + atomic_set(&nmi_touched[this_cpu], 0); + + cpu_clear(this_cpu, mask); + for_each_cpu_mask(cpu, mask) { + invalidate_dcache_range((unsigned long)(&nmi_touched[cpu]), + (unsigned long)(&nmi_touched[cpu])); + if (!atomic_read(&nmi_touched[cpu])) + return 0; + atomic_set(&nmi_touched[cpu], 0); + } + + return 1; +} + +static void nmi_wdt_timer(unsigned long data) +{ + if (check_nmi_wdt_touched()) + nmi_wdt_keepalive(); + + mod_timer(&ntimer, jiffies + NMI_CHECK_TIMEOUT); +} + +static int __init init_nmi_wdt(void) +{ + nmi_wdt_set_timeout(timeout); + nmi_wdt_start(); + nmi_active = true; + + init_timer(&ntimer); + ntimer.function = nmi_wdt_timer; + ntimer.expires = jiffies + NMI_CHECK_TIMEOUT; + add_timer(&ntimer); + + pr_info("nmi_wdt: initialized: timeout=%d sec\n", timeout); + return 0; +} +device_initcall(init_nmi_wdt); + +void touch_nmi_watchdog(void) +{ + atomic_set(&nmi_touched[smp_processor_id()], 1); +} + +/* Suspend/resume support */ +#ifdef CONFIG_PM +static int nmi_wdt_suspend(struct sys_device *dev, pm_message_t state) +{ + nmi_wdt_stop(); + return 0; +} + +static int nmi_wdt_resume(struct sys_device *dev) +{ + if (nmi_active) + nmi_wdt_start(); + return 0; +} + +static struct sysdev_class nmi_sysclass = { + .name = DRV_NAME, + .resume = nmi_wdt_resume, + .suspend = nmi_wdt_suspend, +}; + +static struct sys_device device_nmi_wdt = { + .id = 0, + .cls = &nmi_sysclass, +}; + +static int __init init_nmi_wdt_sysfs(void) +{ + int error; + + if (!nmi_active) + return 0; + + error = sysdev_class_register(&nmi_sysclass); + if (!error) + error = sysdev_register(&device_nmi_wdt); + return error; +} +late_initcall(init_nmi_wdt_sysfs); + +#endif /* CONFIG_PM */ + + +asmlinkage notrace void do_nmi(struct pt_regs *fp) +{ + unsigned int cpu = smp_processor_id(); + nmi_enter(); + + cpu_pda[cpu].__nmi_count += 1; + + if (cpu == nmi_wdt_cpu) { + /* CoreB goes here first */ + + /* reload the WDOG_STAT */ + nmi_wdt_keepalive(); + + /* clear nmi interrupt for CoreB */ + nmi_wdt_stop(); + nmi_wdt_clear(); + + /* trigger NMI interrupt of CoreA */ + send_corea_nmi(); + + /* waiting CoreB to enter NMI */ + wait_nmi_event(COREA_ENTER_NMI); + + /* recover WDOGA's settings */ + restore_corea_nmi(); + + save_corelock(); + + /* corelock is save/cleared, CoreA is dummping messages */ + + wait_nmi_event(COREA_EXIT_NMI); + } else { + /* OK, CoreA entered NMI */ + set_nmi_event(COREA_ENTER_NMI); + } + + pr_emerg("\nNMI Watchdog detected LOCKUP, dump for CPU %d\n", cpu); + dump_bfin_process(fp); + dump_bfin_mem(fp); + show_regs(fp); + dump_bfin_trace_buffer(); + show_stack(current, (unsigned long *)fp); + + if (cpu == nmi_wdt_cpu) { + pr_emerg("This fault is not recoverable, sorry!\n"); + + /* CoreA dump finished, restore the corelock */ + restore_corelock(); + + set_nmi_event(COREB_EXIT_NMI); + } else { + /* CoreB dump finished, notice the CoreA we are done */ + set_nmi_event(COREA_EXIT_NMI); + + /* synchronize with CoreA */ + wait_nmi_event(COREB_EXIT_NMI); + } + + nmi_exit(); +} diff --git a/arch/blackfin/kernel/time-ts.c b/arch/blackfin/kernel/time-ts.c index a351f97..41a9075 100644 --- a/arch/blackfin/kernel/time-ts.c +++ b/arch/blackfin/kernel/time-ts.c @@ -21,6 +21,7 @@ #include #include #include +#include /* Accelerators for sched_clock() * convert from cycles(64bits) => nanoseconds (64bits) @@ -309,6 +310,9 @@ irqreturn_t bfin_coretmr_interrupt(int irq, void *dev_id) smp_mb(); evt->event_handler(evt); + + touch_nmi_watchdog(); + return IRQ_HANDLED; } diff --git a/arch/blackfin/mach-common/interrupt.S b/arch/blackfin/mach-common/interrupt.S index 0a0c088..cee62cf 100644 --- a/arch/blackfin/mach-common/interrupt.S +++ b/arch/blackfin/mach-common/interrupt.S @@ -194,12 +194,28 @@ ENTRY(_evt_ivhw) ENDPROC(_evt_ivhw) /* Interrupt routine for evt2 (NMI). - * We don't actually use this, so just return. * For inner circle type details, please see: * http://docs.blackfin.uclinux.org/doku.php?id=linux-kernel:nmi */ ENTRY(_evt_nmi) +#ifndef CONFIG_NMI_WATCHDOG .weak _evt_nmi +#else + /* Not take account of CPLBs, this handler will not return */ + SAVE_ALL_SYS + r0 = sp; + r1 = retn; + [sp + PT_PC] = r1; + trace_buffer_save(p4,r5); + + ANOMALY_283_315_WORKAROUND(p4, r5) + + SP += -12; + call _do_nmi; + SP += 12; +1: + jump 1b; +#endif rtn; ENDPROC(_evt_nmi) -- cgit v0.10.2 From 6388d14eb2dd3af655cee28ca2a1c56881e63e56 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Thu, 21 Jan 2010 07:20:44 +0000 Subject: Blackfin: implement ndelay() Signed-off-by: Barry Song Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/delay.h b/arch/blackfin/include/asm/delay.h index c31f91c..171d8de 100644 --- a/arch/blackfin/include/asm/delay.h +++ b/arch/blackfin/include/asm/delay.h @@ -30,10 +30,22 @@ __asm__ __volatile__ ( #define HZSCALE (268435456 / (1000000/HZ)) -static inline void udelay(unsigned long usecs) +static inline unsigned long __to_delay(unsigned long scale) { extern unsigned long loops_per_jiffy; - __delay((((usecs * HZSCALE) >> 11) * (loops_per_jiffy >> 11)) >> 6); + return (((scale * HZSCALE) >> 11) * (loops_per_jiffy >> 11)) >> 6; +} + +static inline void udelay(unsigned long usecs) +{ + __delay(__to_delay(usecs)); } +static inline void ndelay(unsigned long nsecs) +{ + __delay(__to_delay(1) * nsecs / 1000); +} + +#define ndelay ndelay + #endif -- cgit v0.10.2 From aebfef03249819886a7f9c981940cbd48d82ea47 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 22 Jan 2010 07:35:20 -0500 Subject: Blackfin: implement ftrace mcount test Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index f46db59..3123aa4 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -25,6 +25,7 @@ config BLACKFIN def_bool y select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_TRACER + select HAVE_FUNCTION_TRACE_MCOUNT_TEST select HAVE_IDE select HAVE_KERNEL_GZIP if RAMKERNEL select HAVE_KERNEL_BZIP2 if RAMKERNEL diff --git a/arch/blackfin/kernel/ftrace-entry.S b/arch/blackfin/kernel/ftrace-entry.S index 76dd4fb..db3a51b 100644 --- a/arch/blackfin/kernel/ftrace-entry.S +++ b/arch/blackfin/kernel/ftrace-entry.S @@ -1,7 +1,7 @@ /* * mcount and friends -- ftrace stuff * - * Copyright (C) 2009 Analog Devices Inc. + * Copyright (C) 2009-2010 Analog Devices Inc. * Licensed under the GPL-2 or later. */ @@ -21,6 +21,15 @@ * function will be waiting there. mmmm pie. */ ENTRY(__mcount) +#ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST + /* optional micro optimization: return if stopped */ + p1.l = _function_trace_stop; + p1.h = _function_trace_stop; + r3 = [p1]; + cc = r3 == 0; + if ! cc jump _ftrace_stub (bp); +#endif + /* save third function arg early so we can do testing below */ [--sp] = r2; -- cgit v0.10.2 From b73faf74493fd1bc75a8938aa5d296facf50a650 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 22 Jan 2010 07:59:32 -0500 Subject: Blackfin: support new ftrace frame pointer semantics Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/kernel/ftrace-entry.S b/arch/blackfin/kernel/ftrace-entry.S index db3a51b..d66446b 100644 --- a/arch/blackfin/kernel/ftrace-entry.S +++ b/arch/blackfin/kernel/ftrace-entry.S @@ -115,9 +115,12 @@ ENTRY(_ftrace_graph_caller) [--sp] = r1; [--sp] = rets; - /* prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) */ - r0 = sp; - r1 = rets; + /* prepare_ftrace_return(parent, self_addr, frame_pointer) */ + r0 = sp; /* unsigned long *parent */ + r1 = rets; /* unsigned long self_addr */ +#ifdef CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST + r2 = fp; /* unsigned long frame_pointer */ +#endif r0 += 16; /* skip the 4 local regs on stack */ r1 += -MCOUNT_INSN_SIZE; call _prepare_ftrace_return; @@ -136,6 +139,9 @@ ENTRY(_return_to_handler) [--sp] = r1; /* get original return address */ +#ifdef CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST + r0 = fp; /* Blackfin is sane, so omit this */ +#endif call _ftrace_return_to_handler; rets = r0; diff --git a/arch/blackfin/kernel/ftrace.c b/arch/blackfin/kernel/ftrace.c index f2c85ac..a61d948 100644 --- a/arch/blackfin/kernel/ftrace.c +++ b/arch/blackfin/kernel/ftrace.c @@ -16,7 +16,8 @@ * Hook the return address and push it in the stack of return addrs * in current thread info. */ -void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) +void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, + unsigned long frame_pointer) { struct ftrace_graph_ent trace; unsigned long return_hooker = (unsigned long)&return_to_handler; @@ -24,7 +25,8 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) if (unlikely(atomic_read(¤t->tracing_graph_pause))) return; - if (ftrace_push_return_trace(*parent, self_addr, &trace.depth, 0) == -EBUSY) + if (ftrace_push_return_trace(*parent, self_addr, &trace.depth, + frame_pointer) == -EBUSY) return; trace.func = self_addr; -- cgit v0.10.2 From 3750411fb7ca96dd11ce8a63f213b60bfe4b5c29 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 22 Jan 2010 09:11:20 -0500 Subject: Blackfin: fix whitespace damage in thread_info.h Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/thread_info.h b/arch/blackfin/include/asm/thread_info.h index a40d936..0149c92 100644 --- a/arch/blackfin/include/asm/thread_info.h +++ b/arch/blackfin/include/asm/thread_info.h @@ -1,5 +1,5 @@ /* - * Copyright 2004-2009 Analog Devices Inc. + * Copyright 2004-2010 Analog Devices Inc. * * Licensed under the GPL-2 or later. */ @@ -17,7 +17,7 @@ /* Thread Align Mask to reach to the top of the stack * for any process */ -#define ALIGN_PAGE_MASK 0xffffe000 +#define ALIGN_PAGE_MASK 0xffffe000 /* * Size of kernel stack for each process. This must be a power of 2... @@ -57,7 +57,7 @@ struct thread_info { .exec_domain = &default_exec_domain, \ .flags = 0, \ .cpu = 0, \ - .preempt_count = INIT_PREEMPT_COUNT, \ + .preempt_count = INIT_PREEMPT_COUNT, \ .restart_block = { \ .fn = do_no_restart_syscall, \ }, \ @@ -73,8 +73,7 @@ __attribute_const__ static inline struct thread_info *current_thread_info(void) { struct thread_info *ti; - __asm__("%0 = sp;" : "=da"(ti) : - ); + __asm__("%0 = sp;" : "=da"(ti)); return (struct thread_info *)((long)ti & ~((long)THREAD_SIZE-1)); } @@ -99,21 +98,21 @@ static inline struct thread_info *current_thread_info(void) #define TIF_NEED_RESCHED 2 /* rescheduling necessary */ #define TIF_POLLING_NRFLAG 3 /* true if poll_idle() is polling TIF_NEED_RESCHED */ -#define TIF_MEMDIE 4 +#define TIF_MEMDIE 4 #define TIF_RESTORE_SIGMASK 5 /* restore signal mask in do_signal() */ -#define TIF_FREEZE 6 /* is freezing for suspend */ -#define TIF_IRQ_SYNC 7 /* sync pipeline stage */ -#define TIF_NOTIFY_RESUME 8 /* callback before returning to user */ +#define TIF_FREEZE 6 /* is freezing for suspend */ +#define TIF_IRQ_SYNC 7 /* sync pipeline stage */ +#define TIF_NOTIFY_RESUME 8 /* callback before returning to user */ /* as above, but as bit values */ #define _TIF_SYSCALL_TRACE (1< Date: Fri, 22 Jan 2010 10:07:30 +0000 Subject: Blackfin: add dma_disable_irq_nosync() API for irq handlers Some IRQ handlers need to disable a DMA channel without waiting. Signed-off-by: Barry Song Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/dma.h b/arch/blackfin/include/asm/dma.h index bd2e622..2c09b1d 100644 --- a/arch/blackfin/include/asm/dma.h +++ b/arch/blackfin/include/asm/dma.h @@ -262,6 +262,10 @@ static inline void dma_disable_irq(unsigned int channel) { disable_irq(dma_ch[channel].irq); } +static inline void dma_disable_irq_nosync(unsigned int channel) +{ + disable_irq_nosync(dma_ch[channel].irq); +} static inline void dma_enable_irq(unsigned int channel) { enable_irq(dma_ch[channel].irq); -- cgit v0.10.2 From 64b33a00dc39dceac04dbd7622ab14017e074712 Mon Sep 17 00:00:00 2001 From: Graf Yang Date: Mon, 25 Jan 2010 03:47:43 +0000 Subject: Blackfin: split watchdog definitions into a dedicated header file This allows things to be shared between the different watchdog sources. Signed-off-by: Graf Yang Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/bfin_watchdog.h b/arch/blackfin/include/asm/bfin_watchdog.h new file mode 100644 index 0000000..dce0982 --- /dev/null +++ b/arch/blackfin/include/asm/bfin_watchdog.h @@ -0,0 +1,30 @@ +/* + * bfin_watchdog.h - Blackfin watchdog definitions + * + * Copyright 2006-2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#ifndef _BFIN_WATCHDOG_H +#define _BFIN_WATCHDOG_H + +/* Bit in SWRST that indicates boot caused by watchdog */ +#define SWRST_RESET_WDOG 0x4000 + +/* Bit in WDOG_CTL that indicates watchdog has expired (WDR0) */ +#define WDOG_EXPIRED 0x8000 + +/* Masks for WDEV field in WDOG_CTL register */ +#define ICTL_RESET 0x0 +#define ICTL_NMI 0x2 +#define ICTL_GPI 0x4 +#define ICTL_NONE 0x6 +#define ICTL_MASK 0x6 + +/* Masks for WDEN field in WDOG_CTL register */ +#define WDEN_MASK 0x0FF0 +#define WDEN_ENABLE 0x0000 +#define WDEN_DISABLE 0x0AD0 + +#endif diff --git a/arch/blackfin/kernel/nmi.c b/arch/blackfin/kernel/nmi.c index 19093c1..0b5f72f 100644 --- a/arch/blackfin/kernel/nmi.c +++ b/arch/blackfin/kernel/nmi.c @@ -20,21 +20,7 @@ #include #include #include - -/* Bit in WDOG_CTL that indicates watchdog has expired (WDR0) */ -#define WDOG_EXPIRED 0x8000 - -/* Masks for WDEV field in WDOG_CTL register */ -#define ICTL_RESET 0x0 -#define ICTL_NMI 0x2 -#define ICTL_GPI 0x4 -#define ICTL_NONE 0x6 -#define ICTL_MASK 0x6 - -/* Masks for WDEN field in WDOG_CTL register */ -#define WDEN_MASK 0x0FF0 -#define WDEN_ENABLE 0x0000 -#define WDEN_DISABLE 0x0AD0 +#include #define DRV_NAME "nmi-wdt" -- cgit v0.10.2 From 652afdc3403cbccb93c7e6db582a1204a9e5e90a Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 25 Jan 2010 22:12:32 +0000 Subject: Blackfin: move KGDB selection to the way other arches do it Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index 3123aa4..ed339b8 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -23,6 +23,7 @@ config RWSEM_XCHGADD_ALGORITHM config BLACKFIN def_bool y + select HAVE_ARCH_KGDB select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_TRACE_MCOUNT_TEST diff --git a/arch/blackfin/Kconfig.debug b/arch/blackfin/Kconfig.debug index 1460d7b..aec89a5 100644 --- a/arch/blackfin/Kconfig.debug +++ b/arch/blackfin/Kconfig.debug @@ -18,9 +18,6 @@ config DEBUG_STACK_USAGE This option will slow down process creation somewhat. -config HAVE_ARCH_KGDB - def_bool y - config DEBUG_VERBOSE bool "Verbose fault messages" default y -- cgit v0.10.2 From 7136d9c5e874813ccbd1d438924c413b7305944c Mon Sep 17 00:00:00 2001 From: Yi Li Date: Tue, 26 Jan 2010 04:02:44 +0000 Subject: Blackfin: add CALLER_ADDR ftrace macros Since GCC doesn't support __builtin_frame_address(n) where n!=0, add our own function to walk the stack frame pointers. Signed-off-by: Yi Li Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/ftrace.h b/arch/blackfin/include/asm/ftrace.h index 90c9b40..4cfe2d9 100644 --- a/arch/blackfin/include/asm/ftrace.h +++ b/arch/blackfin/include/asm/ftrace.h @@ -10,4 +10,57 @@ #define MCOUNT_INSN_SIZE 6 /* sizeof "[++sp] = rets; call __mcount;" */ +#ifndef __ASSEMBLY__ + +#ifdef CONFIG_FRAME_POINTER +#include + +extern inline void *return_address(unsigned int level) +{ + unsigned long *endstack, *fp, *ret_addr; + unsigned int current_level = 0; + + if (level == 0) + return __builtin_return_address(0); + + fp = (unsigned long *)__builtin_frame_address(0); + endstack = (unsigned long *)PAGE_ALIGN((unsigned long)&level); + + while (((unsigned long)fp & 0x3) == 0 && fp && + (fp + 1) < endstack && current_level < level) { + fp = (unsigned long *)*fp; + current_level++; + } + + if (((unsigned long)fp & 0x3) == 0 && fp && + (fp + 1) < endstack) + ret_addr = (unsigned long *)*(fp + 1); + else + ret_addr = NULL; + + return ret_addr; +} + +#else + +extern inline void *return_address(unsigned int level) +{ + return NULL; +} + +#endif /* CONFIG_FRAME_POINTER */ + +#define HAVE_ARCH_CALLER_ADDR + +/* inline function or macro may lead to unexpected result */ +#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0)) +#define CALLER_ADDR1 ((unsigned long)return_address(1)) +#define CALLER_ADDR2 ((unsigned long)return_address(2)) +#define CALLER_ADDR3 ((unsigned long)return_address(3)) +#define CALLER_ADDR4 ((unsigned long)return_address(4)) +#define CALLER_ADDR5 ((unsigned long)return_address(5)) +#define CALLER_ADDR6 ((unsigned long)return_address(6)) + +#endif /* __ASSEMBLY__ */ + #endif -- cgit v0.10.2 From 3b82790c12f8122d3df07cc387d2d74355e54c75 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Wed, 27 Jan 2010 09:01:36 +0000 Subject: Blackfin: rename AD1938 to AD193X in board files The ASoC codec driver was generalized and renamed, so update the board resources accordingly. Signed-off-by: Barry Song Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 80b3b57..2e354b5 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -528,8 +528,8 @@ static struct bfin5xx_spi_chip ad1836_spi_chip_info = { }; #endif -#if defined(CONFIG_SND_BF5XX_SOC_AD1938) \ - || defined(CONFIG_SND_BF5XX_SOC_AD1938_MODULE) +#if defined(CONFIG_SND_BF5XX_SOC_AD193X) \ + || defined(CONFIG_SND_BF5XX_SOC_AD193X_MODULE) static struct bfin5xx_spi_chip ad1938_spi_chip_info = { .enable_dma = 0, .bits_per_word = 8, @@ -915,9 +915,9 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { }, #endif -#if defined(CONFIG_SND_BF5XX_SOC_AD1938) || defined(CONFIG_SND_BF5XX_SOC_AD1938_MODULE) +#if defined(CONFIG_SND_BF5XX_SOC_AD193X) || defined(CONFIG_SND_BF5XX_SOC_AD193X_MODULE) { - .modalias = "ad1938", + .modalias = "ad193x", .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ .bus_num = 0, .chip_select = 5, -- cgit v0.10.2 From 6c2b7072a7035837998da38809f98e4182e4c41c Mon Sep 17 00:00:00 2001 From: Graf Yang Date: Wed, 27 Jan 2010 11:16:32 +0000 Subject: Blackfin: add support for cpufreq on SMP systems Signed-off-by: Graf Yang Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index ed339b8..970df5b 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -1237,7 +1237,6 @@ config PM_BFIN_WAKE_GP endmenu menu "CPU Frequency scaling" - depends on !SMP source "drivers/cpufreq/Kconfig" diff --git a/arch/blackfin/include/asm/time.h b/arch/blackfin/include/asm/time.h index 767b938..9ca7db8 100644 --- a/arch/blackfin/include/asm/time.h +++ b/arch/blackfin/include/asm/time.h @@ -23,9 +23,7 @@ */ #ifndef CONFIG_CPU_FREQ -#define TIME_SCALE 1 -#define __bfin_cycles_off (0) -#define __bfin_cycles_mod (0) +# define TIME_SCALE 1 #else /* * Blackfin CPU frequency scaling supports max Core Clock 1, 1/2 and 1/4 . @@ -33,8 +31,11 @@ * adjust the Core Timer Presale Register. This way we don't lose time. */ #define TIME_SCALE 4 + +# ifdef CONFIG_CYCLES_CLOCKSOURCE extern unsigned long long __bfin_cycles_off; extern unsigned int __bfin_cycles_mod; +# endif #endif #if defined(CONFIG_TICKSOURCE_CORETMR) diff --git a/arch/blackfin/kernel/time-ts.c b/arch/blackfin/kernel/time-ts.c index 41a9075..cb7a01d 100644 --- a/arch/blackfin/kernel/time-ts.c +++ b/arch/blackfin/kernel/time-ts.c @@ -51,7 +51,11 @@ static notrace cycle_t bfin_read_cycles(struct clocksource *cs) { +#ifdef CONFIG_CPU_FREQ return __bfin_cycles_off + (get_cycles() << __bfin_cycles_mod); +#else + return get_cycles(); +#endif } static struct clocksource bfin_cs_cycles = { diff --git a/arch/blackfin/mach-common/cpufreq.c b/arch/blackfin/mach-common/cpufreq.c index 7775828..5d7f8ab 100644 --- a/arch/blackfin/mach-common/cpufreq.c +++ b/arch/blackfin/mach-common/cpufreq.c @@ -15,6 +15,8 @@ #include #include +#define CPUFREQ_CPU 0 + /* this is the table of CCLK frequencies, in Hz */ /* .index is the entry in the auxillary dpm_state_table[] */ static struct cpufreq_frequency_table bfin_freq_table[] = { @@ -41,64 +43,114 @@ static struct bfin_dpm_state { unsigned int tscale; /* change the divider on the core timer interrupt */ } dpm_state_table[3]; +#if defined(CONFIG_CYCLES_CLOCKSOURCE) /* - normalized to maximum frequncy offset for CYCLES, - used in time-ts cycles clock source, but could be used - somewhere also. + * normalized to maximum frequncy offset for CYCLES, + * used in time-ts cycles clock source, but could be used + * somewhere also. */ unsigned long long __bfin_cycles_off; unsigned int __bfin_cycles_mod; +#endif /**************************************************************************/ +static void __init bfin_init_tables(unsigned long cclk, unsigned long sclk) +{ -static unsigned int bfin_getfreq_khz(unsigned int cpu) + unsigned long csel, min_cclk; + int index; + + /* Anomaly 273 seems to still exist on non-BF54x w/dcache turned on */ +#if ANOMALY_05000273 || ANOMALY_05000274 || \ + (!defined(CONFIG_BF54x) && defined(CONFIG_BFIN_EXTMEM_DCACHEABLE)) + min_cclk = sclk * 2; +#else + min_cclk = sclk; +#endif + csel = ((bfin_read_PLL_DIV() & CSEL) >> 4); + + for (index = 0; (cclk >> index) >= min_cclk && csel <= 3; index++, csel++) { + bfin_freq_table[index].frequency = cclk >> index; + dpm_state_table[index].csel = csel << 4; /* Shift now into PLL_DIV bitpos */ + dpm_state_table[index].tscale = (TIME_SCALE / (1 << csel)) - 1; + + pr_debug("cpufreq: freq:%d csel:0x%x tscale:%d\n", + bfin_freq_table[index].frequency, + dpm_state_table[index].csel, + dpm_state_table[index].tscale); + } + return; +} + +static void bfin_adjust_core_timer(void *info) { - /* The driver only support single cpu */ - if (cpu != 0) - return -1; + unsigned int tscale; + unsigned int index = *(unsigned int *)info; + + /* we have to adjust the core timer, because it is using cclk */ + tscale = dpm_state_table[index].tscale; + bfin_write_TSCALE(tscale); + return; +} +static unsigned int bfin_getfreq_khz(unsigned int cpu) +{ + /* Both CoreA/B have the same core clock */ return get_cclk() / 1000; } -static int bfin_target(struct cpufreq_policy *policy, +static int bfin_target(struct cpufreq_policy *poli, unsigned int target_freq, unsigned int relation) { - unsigned int index, plldiv, tscale; + unsigned int index, plldiv, cpu; unsigned long flags, cclk_hz; struct cpufreq_freqs freqs; +#if defined(CONFIG_CYCLES_CLOCKSOURCE) cycles_t cycles; +#endif - if (cpufreq_frequency_table_target(policy, bfin_freq_table, - target_freq, relation, &index)) - return -EINVAL; - - cclk_hz = bfin_freq_table[index].frequency; - - freqs.old = bfin_getfreq_khz(0); - freqs.new = cclk_hz; - freqs.cpu = 0; - - pr_debug("cpufreq: changing cclk to %lu; target = %u, oldfreq = %u\n", - cclk_hz, target_freq, freqs.old); - - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - local_irq_save_hw(flags); - plldiv = (bfin_read_PLL_DIV() & SSEL) | dpm_state_table[index].csel; - tscale = dpm_state_table[index].tscale; - bfin_write_PLL_DIV(plldiv); - /* we have to adjust the core timer, because it is using cclk */ - bfin_write_TSCALE(tscale); - cycles = get_cycles(); - SSYNC(); - cycles += 10; /* ~10 cycles we lose after get_cycles() */ - __bfin_cycles_off += (cycles << __bfin_cycles_mod) - (cycles << index); - __bfin_cycles_mod = index; - local_irq_restore_hw(flags); - /* TODO: just test case for cycles clock source, remove later */ - pr_debug("cpufreq: done\n"); - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + for_each_online_cpu(cpu) { + struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); + + if (!policy) + continue; + + if (cpufreq_frequency_table_target(policy, bfin_freq_table, + target_freq, relation, &index)) + return -EINVAL; + + cclk_hz = bfin_freq_table[index].frequency; + + freqs.old = bfin_getfreq_khz(0); + freqs.new = cclk_hz; + freqs.cpu = cpu; + + pr_debug("cpufreq: changing cclk to %lu; target = %u, oldfreq = %u\n", + cclk_hz, target_freq, freqs.old); + + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + if (cpu == CPUFREQ_CPU) { + local_irq_save_hw(flags); + plldiv = (bfin_read_PLL_DIV() & SSEL) | + dpm_state_table[index].csel; + bfin_write_PLL_DIV(plldiv); + on_each_cpu(bfin_adjust_core_timer, &index, 1); +#if defined(CONFIG_CYCLES_CLOCKSOURCE) + cycles = get_cycles(); + SSYNC(); + cycles += 10; /* ~10 cycles we lose after get_cycles() */ + __bfin_cycles_off += + (cycles << __bfin_cycles_mod) - (cycles << index); + __bfin_cycles_mod = index; +#endif + local_irq_restore_hw(flags); + } + /* TODO: just test case for cycles clock source, remove later */ + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + } + pr_debug("cpufreq: done\n"); return 0; } @@ -110,37 +162,16 @@ static int bfin_verify_speed(struct cpufreq_policy *policy) static int __init __bfin_cpu_init(struct cpufreq_policy *policy) { - unsigned long cclk, sclk, csel, min_cclk; - int index; - - if (policy->cpu != 0) - return -EINVAL; + unsigned long cclk, sclk; cclk = get_cclk() / 1000; sclk = get_sclk() / 1000; -#if ANOMALY_05000273 || ANOMALY_05000274 || \ - (!defined(CONFIG_BF54x) && defined(CONFIG_BFIN_EXTMEM_DCACHEABLE)) - min_cclk = sclk * 2; -#else - min_cclk = sclk; -#endif - csel = ((bfin_read_PLL_DIV() & CSEL) >> 4); - - for (index = 0; (cclk >> index) >= min_cclk && csel <= 3; index++, csel++) { - bfin_freq_table[index].frequency = cclk >> index; - dpm_state_table[index].csel = csel << 4; /* Shift now into PLL_DIV bitpos */ - dpm_state_table[index].tscale = (TIME_SCALE / (1 << csel)) - 1; - - pr_debug("cpufreq: freq:%d csel:0x%x tscale:%d\n", - bfin_freq_table[index].frequency, - dpm_state_table[index].csel, - dpm_state_table[index].tscale); - } + if (policy->cpu == CPUFREQ_CPU) + bfin_init_tables(cclk, sclk); policy->cpuinfo.transition_latency = 50000; /* 50us assumed */ - /*Now ,only support one cpu */ policy->cur = cclk; cpufreq_frequency_table_get_attr(bfin_freq_table, policy->cpu); return cpufreq_frequency_table_cpuinfo(policy, bfin_freq_table); -- cgit v0.10.2 From 718340f62900ed44046d2b0f74d0dec7cf844194 Mon Sep 17 00:00:00 2001 From: Graf Yang Date: Mon, 1 Feb 2010 06:07:50 +0000 Subject: Blackfin: rewrite resync_core_{i,d}cache() SMP logic to avoid per_cpu data This functions are implicitly called by core functions like cpu_relax(), and since those functions may be called early on before common code has initialized the per-cpu data area, we need to tweak the stats gathering. Now the statistics are maintained in common bss which makes these funcs safe to use as soon as the C runtime env is setup. Signed-off-by: Graf Yang Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/cpu.h b/arch/blackfin/include/asm/cpu.h index b191dc6..16883e5 100644 --- a/arch/blackfin/include/asm/cpu.h +++ b/arch/blackfin/include/asm/cpu.h @@ -17,8 +17,6 @@ struct blackfin_cpudata { struct task_struct *idle; unsigned int imemctl; unsigned int dmemctl; - unsigned long dcache_invld_count; - unsigned long icache_invld_count; }; DECLARE_PER_CPU(struct blackfin_cpudata, cpu_data); diff --git a/arch/blackfin/include/asm/smp.h b/arch/blackfin/include/asm/smp.h index 7f26de0..f5b5379 100644 --- a/arch/blackfin/include/asm/smp.h +++ b/arch/blackfin/include/asm/smp.h @@ -24,6 +24,13 @@ struct corelock_slot { }; extern struct corelock_slot corelock; +#ifdef __ARCH_SYNC_CORE_ICACHE +extern unsigned long icache_invld_count[NR_CPUS]; +#endif +#ifdef __ARCH_SYNC_CORE_DCACHE +extern unsigned long dcache_invld_count[NR_CPUS]; +#endif + void smp_icache_flush_range_others(unsigned long start, unsigned long end); #ifdef CONFIG_HOTPLUG_CPU diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index b54ba45..8e2efce 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c @@ -1239,10 +1239,10 @@ static int show_cpuinfo(struct seq_file *m, void *v) dsup_banks, BFIN_DSUBBANKS, BFIN_DWAYS, BFIN_DLINES); #ifdef __ARCH_SYNC_CORE_DCACHE - seq_printf(m, "SMP Dcache Flushes\t: %lu\n\n", cpudata->dcache_invld_count); + seq_printf(m, "SMP Dcache Flushes\t: %lu\n\n", dcache_invld_count[cpu_num]); #endif #ifdef __ARCH_SYNC_CORE_ICACHE - seq_printf(m, "SMP Icache Flushes\t: %lu\n\n", cpudata->icache_invld_count); + seq_printf(m, "SMP Icache Flushes\t: %lu\n\n", icache_invld_count[cpu_num]); #endif if (cpu_num != num_possible_cpus() - 1) diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c index efc47ff..7803f22 100644 --- a/arch/blackfin/mach-common/smp.c +++ b/arch/blackfin/mach-common/smp.c @@ -474,24 +474,26 @@ void smp_icache_flush_range_others(unsigned long start, unsigned long end) EXPORT_SYMBOL_GPL(smp_icache_flush_range_others); #ifdef __ARCH_SYNC_CORE_ICACHE +unsigned long icache_invld_count[NR_CPUS]; void resync_core_icache(void) { unsigned int cpu = get_cpu(); blackfin_invalidate_entire_icache(); - ++per_cpu(cpu_data, cpu).icache_invld_count; + icache_invld_count[cpu]++; put_cpu(); } EXPORT_SYMBOL(resync_core_icache); #endif #ifdef __ARCH_SYNC_CORE_DCACHE +unsigned long dcache_invld_count[NR_CPUS]; unsigned long barrier_mask __attribute__ ((__section__(".l2.bss"))); void resync_core_dcache(void) { unsigned int cpu = get_cpu(); blackfin_invalidate_entire_dcache(); - ++per_cpu(cpu_data, cpu).dcache_invld_count; + dcache_invld_count[cpu]++; put_cpu(); } EXPORT_SYMBOL(resync_core_dcache); -- cgit v0.10.2 From ad6720c0b52ae1cde0bc567e57a71acde1a292aa Mon Sep 17 00:00:00 2001 From: Barry Song Date: Wed, 3 Feb 2010 09:15:31 +0000 Subject: Blackfin: bf537-stamp: add example AD715{0,2}/AD774{5,6,7} IIO resources Signed-off-by: Barry Song Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 2e354b5..9bc7bd3 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -1608,6 +1608,26 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { .platform_data = (void *)&ad7142_i2c_platform_data, }, #endif + +#if defined(CONFIG_AD7150) || defined(CONFIG_AD7150_MODULE) + { + I2C_BOARD_INFO("ad7150", 0x48), + .irq = IRQ_PG5, /* fixme: use real interrupt number */ + }, +#endif + +#if defined(CONFIG_AD7152) || defined(CONFIG_AD7152_MODULE) + { + I2C_BOARD_INFO("ad7152", 0x48), + }, +#endif + +#if defined(CONFIG_AD774X) || defined(CONFIG_AD774X_MODULE) + { + I2C_BOARD_INFO("ad774x", 0x48), + }, +#endif + #if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE) { I2C_BOARD_INFO("pcf8574_lcd", 0x22), -- cgit v0.10.2 From f5b99627a3065858ad5c678703ed7af5363dca39 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 3 Feb 2010 09:15:57 +0000 Subject: Blackfin: use generic ptrace_resume code Use the generic ptrace_resume code for PTRACE_SYSCALL, PTRACE_CONT, PTRACE_KILL and PTRACE_SINGLESTEP. This implies defining arch_has_single_step in and implementing the user_enable_single_step and user_disable_single_step functions, which also causes the breakpoint information to be cleared on fork, which could be considered a bug fix. Also the TIF_SYSCALL_TRACE thread flag is now cleared on PTRACE_KILL which it previously wasn't which is consistent with all architectures using the modern ptrace code. Signed-off-by: Christoph Hellwig Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c index 65567dc..895302d 100644 --- a/arch/blackfin/kernel/ptrace.c +++ b/arch/blackfin/kernel/ptrace.c @@ -354,50 +354,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ret = put_reg(child, addr, data); break; - case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ - case PTRACE_CONT: /* restart after signal. */ - pr_debug("ptrace: syscall/cont\n"); - - ret = -EIO; - if (!valid_signal(data)) - break; - if (request == PTRACE_SYSCALL) - set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); - else - clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); - child->exit_code = data; - ptrace_disable(child); - pr_debug("ptrace: before wake_up_process\n"); - wake_up_process(child); - ret = 0; - break; - - /* - * make the child exit. Best I can do is send it a sigkill. - * perhaps it should be put in the status that it wants to - * exit. - */ - case PTRACE_KILL: - ret = 0; - if (child->exit_state == EXIT_ZOMBIE) /* already dead */ - break; - child->exit_code = SIGKILL; - ptrace_disable(child); - wake_up_process(child); - break; - - case PTRACE_SINGLESTEP: /* set the trap flag. */ - pr_debug("ptrace: single step\n"); - ret = -EIO; - if (!valid_signal(data)) - break; - clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); - ptrace_enable(child); - child->exit_code = data; - wake_up_process(child); - ret = 0; - break; - case PTRACE_GETREGS: /* Get all gp regs from the child. */ ret = ptrace_getregs(child, datap); -- cgit v0.10.2 From 5f09c77d2ad69397498b6555f0d3cd697304253c Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sun, 14 Feb 2010 22:49:59 +0000 Subject: Blackfin: simplify SYSCFG code a bit and ignore attempts to change it We don't want to let user space modify the SYSCFG register arbitrarily as the settings are system wide (SNEN/CNEN) and can cause misbehavior. The only other bit here (SSSTEP) has proper controls via PTRACE_SINGLESTEP. Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c index 895302d..14118e4 100644 --- a/arch/blackfin/kernel/ptrace.c +++ b/arch/blackfin/kernel/ptrace.c @@ -31,12 +31,6 @@ * in exit.c or in signal.c. */ -/* determines which bits in the SYSCFG reg the user has access to. */ -/* 1 = access 0 = no access */ -#define SYSCFG_MASK 0x0007 /* SYSCFG reg */ -/* sets the trace bits. */ -#define TRACE_BITS 0x0001 - /* Find the stack offset for a register, relative to thread.esp0. */ #define PT_REG(reg) ((long)&((struct pt_regs *)0)->reg) @@ -162,9 +156,8 @@ static inline int is_user_addr_valid(struct task_struct *child, void ptrace_enable(struct task_struct *child) { - unsigned long tmp; - tmp = get_reg(child, PT_SYSCFG) | (TRACE_BITS); - put_reg(child, PT_SYSCFG, tmp); + struct pt_regs *regs = task_pt_regs(child); + regs->syscfg |= SYSCFG_SSSTEP; } /* @@ -174,10 +167,8 @@ void ptrace_enable(struct task_struct *child) */ void ptrace_disable(struct task_struct *child) { - unsigned long tmp; - /* make sure the single step bit is not set. */ - tmp = get_reg(child, PT_SYSCFG) & ~TRACE_BITS; - put_reg(child, PT_SYSCFG, tmp); + struct pt_regs *regs = task_pt_regs(child); + regs->syscfg &= ~SYSCFG_SSSTEP; } long arch_ptrace(struct task_struct *child, long request, long addr, long data) @@ -343,14 +334,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) break; } - if (addr >= (sizeof(struct pt_regs))) { + /* Ignore writes to SYSCFG and other pseudo regs */ + if (addr >= PT_SYSCFG) { ret = 0; break; } - if (addr == PT_SYSCFG) { - data &= SYSCFG_MASK; - data |= get_reg(child, PT_SYSCFG); - } ret = put_reg(child, addr, data); break; -- cgit v0.10.2 From f2ce48024a9a6d3e92a023ded0f7b1e99da1cd16 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sun, 14 Feb 2010 22:56:24 +0000 Subject: Blackfin: simplify PTRACE_{PEEK,POKE}USR in preperation for regset support Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/ptrace.h b/arch/blackfin/include/asm/ptrace.h index b33a448..c1aebdb 100644 --- a/arch/blackfin/include/asm/ptrace.h +++ b/arch/blackfin/include/asm/ptrace.h @@ -173,4 +173,6 @@ extern void show_regs(struct pt_regs *); #define PT_FDPIC_EXEC 232 #define PT_FDPIC_INTERP 236 +#define PT_LAST_PSEUDO PT_FDPIC_INTERP + #endif /* _BFIN_PTRACE_H */ diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c index 14118e4..9536c1e 100644 --- a/arch/blackfin/kernel/ptrace.c +++ b/arch/blackfin/kernel/ptrace.c @@ -25,7 +25,6 @@ #include #include -#define TEXT_OFFSET 0 /* * does not yet catch signals sent when the child dies. * in exit.c or in signal.c. @@ -43,7 +42,7 @@ * kernel stack will not be empty on entry to the kernel, so * ptracing these tasks will fail. */ -static inline struct pt_regs *get_user_regs(struct task_struct *task) +static inline struct pt_regs *task_pt_regs(struct task_struct *task) { return (struct pt_regs *) ((unsigned long)task_stack_page(task) + @@ -56,7 +55,7 @@ static inline struct pt_regs *get_user_regs(struct task_struct *task) static inline int ptrace_getregs(struct task_struct *tsk, void __user *uregs) { struct pt_regs regs; - memcpy(®s, get_user_regs(tsk), sizeof(regs)); + memcpy(®s, task_pt_regs(tsk), sizeof(regs)); regs.usp = tsk->thread.usp; return copy_to_user(uregs, ®s, sizeof(struct pt_regs)) ? -EFAULT : 0; } @@ -69,40 +68,49 @@ static inline int ptrace_getregs(struct task_struct *tsk, void __user *uregs) /* * Get contents of register REGNO in task TASK. */ -static inline long get_reg(struct task_struct *task, int regno) +static inline long +get_reg(struct task_struct *task, long regno, unsigned long __user *datap) { - unsigned char *reg_ptr; + long tmp; + struct pt_regs *regs = task_pt_regs(task); - struct pt_regs *regs = - (struct pt_regs *)((unsigned long)task_stack_page(task) + - (THREAD_SIZE - sizeof(struct pt_regs))); - reg_ptr = (char *)regs; + if (regno & 3 || regno > PT_LAST_PSEUDO || regno < 0) + return -EIO; switch (regno) { + case PT_TEXT_ADDR: + tmp = task->mm->start_code; + break; + case PT_TEXT_END_ADDR: + tmp = task->mm->end_code; + break; + case PT_DATA_ADDR: + tmp = task->mm->start_data; + break; case PT_USP: - return task->thread.usp; + tmp = task->thread.usp; + break; default: - if (regno <= 216) - return *(long *)(reg_ptr + regno); + if (regno < sizeof(*regs)) { + void *reg_ptr = regs; + tmp = *(long *)(reg_ptr + regno); + } else + return -EIO; } - /* slight mystery ... never seems to come here but kernel misbehaves without this code! */ - printk(KERN_WARNING "Request to get for unknown register %d\n", regno); - return 0; + return put_user(tmp, datap); } /* * Write contents of register REGNO in task TASK. */ static inline int -put_reg(struct task_struct *task, int regno, unsigned long data) +put_reg(struct task_struct *task, long regno, unsigned long data) { - char *reg_ptr; + struct pt_regs *regs = task_pt_regs(task); - struct pt_regs *regs = - (struct pt_regs *)((unsigned long)task_stack_page(task) + - (THREAD_SIZE - sizeof(struct pt_regs))); - reg_ptr = (char *)regs; + if (regno & 3 || regno > PT_LAST_PSEUDO || regno < 0) + return -EIO; switch (regno) { case PT_PC: @@ -119,10 +127,18 @@ put_reg(struct task_struct *task, int regno, unsigned long data) regs->usp = data; task->thread.usp = data; break; + case PT_SYSCFG: /* don't let userspace screw with this */ + if ((data & ~1) != 0x6) + pr_warning("ptrace: ignore syscfg write of %#lx\n", data); + break; /* regs->syscfg = data; break; */ default: - if (regno <= 216) - *(long *)(reg_ptr + regno) = data; + if (regno < sizeof(*regs)) { + void *reg_offset = regs; + *(long *)(reg_offset + regno) = data; + } + /* Ignore writes to pseudo registers */ } + return 0; } @@ -231,40 +247,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) break; } - /* read the word at location addr in the USER area. */ - case PTRACE_PEEKUSR: - { - unsigned long tmp; - ret = -EIO; - tmp = 0; - if ((addr & 3) || (addr > (sizeof(struct pt_regs) + 16))) { - printk(KERN_WARNING "ptrace error : PEEKUSR : temporarily returning " - "0 - %x sizeof(pt_regs) is %lx\n", - (int)addr, sizeof(struct pt_regs)); - break; - } - if (addr == sizeof(struct pt_regs)) { - /* PT_TEXT_ADDR */ - tmp = child->mm->start_code + TEXT_OFFSET; - } else if (addr == (sizeof(struct pt_regs) + 4)) { - /* PT_TEXT_END_ADDR */ - tmp = child->mm->end_code; - } else if (addr == (sizeof(struct pt_regs) + 8)) { - /* PT_DATA_ADDR */ - tmp = child->mm->start_data; -#ifdef CONFIG_BINFMT_ELF_FDPIC - } else if (addr == (sizeof(struct pt_regs) + 12)) { - goto case_PTRACE_GETFDPIC_EXEC; - } else if (addr == (sizeof(struct pt_regs) + 16)) { - goto case_PTRACE_GETFDPIC_INTERP; -#endif - } else { - tmp = get_reg(child, addr); - } - ret = put_user(tmp, datap); - break; - } - #ifdef CONFIG_BINFMT_ELF_FDPIC case PTRACE_GETFDPIC: { unsigned long tmp = 0; @@ -327,19 +309,21 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) break; } - case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ - ret = -EIO; - if ((addr & 3) || (addr > (sizeof(struct pt_regs) + 16))) { - printk(KERN_WARNING "ptrace error : POKEUSR: temporarily returning 0\n"); - break; + case PTRACE_PEEKUSR: + switch (addr) { +#ifdef CONFIG_BINFMT_ELF_FDPIC /* backwards compat */ + case PT_FDPIC_EXEC: goto case_PTRACE_GETFDPIC_EXEC; + case PT_FDPIC_INTERP: goto case_PTRACE_GETFDPIC_INTERP; +#endif + default: + ret = get_reg(child, addr, datap); } + pr_debug("ptrace: PEEKUSR reg %li with %#lx = %i\n", addr, data, ret); + break; - /* Ignore writes to SYSCFG and other pseudo regs */ - if (addr >= PT_SYSCFG) { - ret = 0; - break; - } + case PTRACE_POKEUSR: ret = put_reg(child, addr, data); + pr_debug("ptrace: POKEUSR reg %li with %li = %i\n", addr, data, ret); break; case PTRACE_GETREGS: -- cgit v0.10.2 From e50e2f25c5b90abd00a1e5871c45094cf5207afc Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sun, 14 Feb 2010 22:58:02 +0000 Subject: Blackfin: initial regset support We don't support core dumps (yet?), but this should make things easier. Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/elf.h b/arch/blackfin/include/asm/elf.h index 5b50f0e..117713a 100644 --- a/arch/blackfin/include/asm/elf.h +++ b/arch/blackfin/include/asm/elf.h @@ -22,12 +22,15 @@ #define EF_BFIN_CODE_IN_L2 0x00000040 /* --code-in-l2 */ #define EF_BFIN_DATA_IN_L2 0x00000080 /* --data-in-l2 */ +#if 1 /* core dumps not supported, but linux/elfcore.h needs these */ typedef unsigned long elf_greg_t; -#define ELF_NGREG 40 /* (sizeof(struct user_regs_struct) / sizeof(elf_greg_t)) */ +#define ELF_NGREG (sizeof(struct pt_regs) / sizeof(elf_greg_t)) typedef elf_greg_t elf_gregset_t[ELF_NGREG]; typedef struct { } elf_fpregset_t; +#endif + /* * This is used to ensure we don't load something for the wrong architecture. */ @@ -55,6 +58,9 @@ do { \ _regs->p2 = _dynamic_addr; \ } while(0) +#if 0 +#define CORE_DUMP_USE_REGSET +#endif #define ELF_FDPIC_CORE_EFLAGS EF_BFIN_FDPIC #define ELF_EXEC_PAGESIZE 4096 diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c index b56b0e4..29705ce 100644 --- a/arch/blackfin/kernel/process.c +++ b/arch/blackfin/kernel/process.c @@ -98,13 +98,6 @@ void cpu_idle(void) } } -/* Fill in the fpu structure for a core dump. */ - -int dump_fpu(struct pt_regs *regs, elf_fpregset_t * fpregs) -{ - return 1; -} - /* * This gets run with P1 containing the * function to call, and R1 containing diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c index 9536c1e..92b4ca0 100644 --- a/arch/blackfin/kernel/ptrace.c +++ b/arch/blackfin/kernel/ptrace.c @@ -9,9 +9,11 @@ #include #include #include +#include #include #include #include +#include #include #include @@ -50,22 +52,6 @@ static inline struct pt_regs *task_pt_regs(struct task_struct *task) } /* - * Get all user integer registers. - */ -static inline int ptrace_getregs(struct task_struct *tsk, void __user *uregs) -{ - struct pt_regs regs; - memcpy(®s, task_pt_regs(tsk), sizeof(regs)); - regs.usp = tsk->thread.usp; - return copy_to_user(uregs, ®s, sizeof(struct pt_regs)) ? -EFAULT : 0; -} - -/* Mapping from PT_xxx to the stack offset at which the register is - * saved. Notice that usp has no stack-slot and needs to be treated - * specially (see get_reg/put_reg below). - */ - -/* * Get contents of register REGNO in task TASK. */ static inline long @@ -170,6 +156,84 @@ static inline int is_user_addr_valid(struct task_struct *child, return -EIO; } +/* + * retrieve the contents of Blackfin userspace general registers + */ +static int genregs_get(struct task_struct *target, + const struct user_regset *regset, + unsigned int pos, unsigned int count, + void *kbuf, void __user *ubuf) +{ + struct pt_regs *regs = task_pt_regs(target); + int ret; + + /* This sucks ... */ + regs->usp = target->thread.usp; + + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, + regs, 0, sizeof(*regs)); + if (ret < 0) + return ret; + + return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, + sizeof(*regs), -1); +} + +/* + * update the contents of the Blackfin userspace general registers + */ +static int genregs_set(struct task_struct *target, + const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf) +{ + struct pt_regs *regs = task_pt_regs(target); + int ret; + + /* Don't let people set SYSCFG (it's at the end of pt_regs) */ + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + regs, 0, PT_SYSCFG); + if (ret < 0) + return ret; + + /* This sucks ... */ + target->thread.usp = regs->usp; + /* regs->retx = regs->pc; */ + + return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, + PT_SYSCFG, -1); +} + +/* + * Define the register sets available on the Blackfin under Linux + */ +enum bfin_regset { + REGSET_GENERAL, +}; + +static const struct user_regset bfin_regsets[] = { + [REGSET_GENERAL] = { + .core_note_type = NT_PRSTATUS, + .n = sizeof(struct pt_regs) / sizeof(long), + .size = sizeof(long), + .align = sizeof(long), + .get = genregs_get, + .set = genregs_set, + }, +}; + +static const struct user_regset_view user_bfin_native_view = { + .name = "Blackfin", + .e_machine = EM_BLACKFIN, + .regsets = bfin_regsets, + .n = ARRAY_SIZE(bfin_regsets), +}; + +const struct user_regset_view *task_user_regset_view(struct task_struct *task) +{ + return &user_bfin_native_view; +} + void ptrace_enable(struct task_struct *child) { struct pt_regs *regs = task_pt_regs(child); @@ -327,15 +391,18 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) break; case PTRACE_GETREGS: - /* Get all gp regs from the child. */ - ret = ptrace_getregs(child, datap); - break; + pr_debug("ptrace: PTRACE_GETREGS\n"); + return copy_regset_to_user(child, &user_bfin_native_view, + REGSET_GENERAL, + 0, sizeof(struct pt_regs), + (void __user *)data); case PTRACE_SETREGS: - printk(KERN_WARNING "ptrace: SETREGS: **** NOT IMPLEMENTED ***\n"); - /* Set all gp regs in the child. */ - ret = 0; - break; + pr_debug("ptrace: PTRACE_SETREGS\n"); + return copy_regset_from_user(child, &user_bfin_native_view, + REGSET_GENERAL, + 0, sizeof(struct pt_regs), + (const void __user *)data); default: ret = ptrace_request(child, request, addr, data); -- cgit v0.10.2 From e8f263dfd32a784a816fe68956e564f8ede4a9fc Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 26 Jan 2010 07:33:53 +0000 Subject: Blackfin: initial tracehook support Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index 970df5b..c078849 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -24,6 +24,7 @@ config RWSEM_XCHGADD_ALGORITHM config BLACKFIN def_bool y select HAVE_ARCH_KGDB + select HAVE_ARCH_TRACEHOOK select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_TRACE_MCOUNT_TEST diff --git a/arch/blackfin/include/asm/ptrace.h b/arch/blackfin/include/asm/ptrace.h index c1aebdb..aaa1c6c 100644 --- a/arch/blackfin/include/asm/ptrace.h +++ b/arch/blackfin/include/asm/ptrace.h @@ -24,6 +24,8 @@ #ifndef __ASSEMBLY__ +struct task_struct; + /* this struct defines the way the registers are stored on the stack during a system call. */ @@ -101,9 +103,30 @@ struct pt_regs { master interrupt enable. */ #define user_mode(regs) (!(((regs)->ipend & ~0x10) & (((regs)->ipend & ~0x10) - 1))) #define instruction_pointer(regs) ((regs)->pc) +#define user_stack_pointer(regs) ((regs)->usp) #define profile_pc(regs) instruction_pointer(regs) extern void show_regs(struct pt_regs *); +#define arch_has_single_step() (1) +extern void user_enable_single_step(struct task_struct *child); +extern void user_disable_single_step(struct task_struct *child); +/* common code demands this function */ +#define ptrace_disable(child) user_disable_single_step(child) + +/* + * Get the address of the live pt_regs for the specified task. + * These are saved onto the top kernel stack when the process + * is not running. + * + * Note: if a user thread is execve'd from kernel space, the + * kernel stack will not be empty on entry to the kernel, so + * ptracing these tasks will fail. + */ +#define task_pt_regs(task) \ + (struct pt_regs *) \ + ((unsigned long)task_stack_page(task) + \ + (THREAD_SIZE - sizeof(struct pt_regs))) + #endif /* __KERNEL__ */ #endif /* __ASSEMBLY__ */ diff --git a/arch/blackfin/include/asm/syscall.h b/arch/blackfin/include/asm/syscall.h new file mode 100644 index 0000000..4921a48 --- /dev/null +++ b/arch/blackfin/include/asm/syscall.h @@ -0,0 +1,96 @@ +/* + * Magic syscall break down functions + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#ifndef __ASM_BLACKFIN_SYSCALL_H__ +#define __ASM_BLACKFIN_SYSCALL_H__ + +/* + * Blackfin syscalls are simple: + * enter: + * p0: syscall number + * r{0,1,2,3,4,5}: syscall args 0,1,2,3,4,5 + * exit: + * r0: return/error value + */ + +#include +#include +#include + +static inline long +syscall_get_nr(struct task_struct *task, struct pt_regs *regs) +{ + return regs->p0; +} + +static inline void +syscall_rollback(struct task_struct *task, struct pt_regs *regs) +{ + regs->p0 = regs->orig_p0; +} + +static inline long +syscall_get_error(struct task_struct *task, struct pt_regs *regs) +{ + return IS_ERR_VALUE(regs->r0) ? regs->r0 : 0; +} + +static inline long +syscall_get_return_value(struct task_struct *task, struct pt_regs *regs) +{ + return regs->r0; +} + +static inline void +syscall_set_return_value(struct task_struct *task, struct pt_regs *regs, + int error, long val) +{ + regs->r0 = error ? -error : val; +} + +/** + * syscall_get_arguments() + * @task: unused + * @regs: the register layout to extract syscall arguments from + * @i: first syscall argument to extract + * @n: number of syscall arguments to extract + * @args: array to return the syscall arguments in + * + * args[0] gets i'th argument, args[n - 1] gets the i+n-1'th argument + */ +static inline void +syscall_get_arguments(struct task_struct *task, struct pt_regs *regs, + unsigned int i, unsigned int n, unsigned long *args) +{ + /* + * Assume the ptrace layout doesn't change -- r5 is first in memory, + * then r4, ..., then r0. So we simply reverse the ptrace register + * array in memory to store into the args array. + */ + long *aregs = ®s->r0 - i; + + BUG_ON(i > 5 || i + n > 6); + + while (n--) + *args++ = *aregs--; +} + +/* See syscall_get_arguments() comments */ +static inline void +syscall_set_arguments(struct task_struct *task, struct pt_regs *regs, + unsigned int i, unsigned int n, const unsigned long *args) +{ + long *aregs = ®s->r0 - i; + + BUG_ON(i > 5 || i + n > 6); + + while (n--) + *aregs-- = *args++; +} + +#endif diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c index 92b4ca0..0618b828 100644 --- a/arch/blackfin/kernel/ptrace.c +++ b/arch/blackfin/kernel/ptrace.c @@ -1,6 +1,6 @@ /* * linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds - * these modifications are Copyright 2004-2009 Analog Devices Inc. + * these modifications are Copyright 2004-2010 Analog Devices Inc. * * Licensed under the GPL-2 */ @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -32,25 +33,6 @@ * in exit.c or in signal.c. */ -/* Find the stack offset for a register, relative to thread.esp0. */ -#define PT_REG(reg) ((long)&((struct pt_regs *)0)->reg) - -/* - * Get the address of the live pt_regs for the specified task. - * These are saved onto the top kernel stack when the process - * is not running. - * - * Note: if a user thread is execve'd from kernel space, the - * kernel stack will not be empty on entry to the kernel, so - * ptracing these tasks will fail. - */ -static inline struct pt_regs *task_pt_regs(struct task_struct *task) -{ - return (struct pt_regs *) - ((unsigned long)task_stack_page(task) + - (THREAD_SIZE - sizeof(struct pt_regs))); -} - /* * Get contents of register REGNO in task TASK. */ @@ -234,18 +216,13 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task) return &user_bfin_native_view; } -void ptrace_enable(struct task_struct *child) +void user_enable_single_step(struct task_struct *child) { struct pt_regs *regs = task_pt_regs(child); regs->syscfg |= SYSCFG_SSSTEP; } -/* - * Called by kernel/ptrace.c when detaching.. - * - * Make sure the single step bit is not set. - */ -void ptrace_disable(struct task_struct *child) +void user_disable_single_step(struct task_struct *child) { struct pt_regs *regs = task_pt_regs(child); regs->syscfg &= ~SYSCFG_SSSTEP; @@ -412,27 +389,18 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) return ret; } -asmlinkage void syscall_trace(void) +asmlinkage int syscall_trace_enter(struct pt_regs *regs) { - if (!test_thread_flag(TIF_SYSCALL_TRACE)) - return; - - if (!(current->ptrace & PT_PTRACED)) - return; - - /* the 0x80 provides a way for the tracing parent to distinguish - * between a syscall stop and SIGTRAP delivery - */ - ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) - ? 0x80 : 0)); - - /* - * this isn't the same as continuing with a signal, but it will do - * for normal use. strace only continues with a signal if the - * stopping signal is not SIGTRAP. -brl - */ - if (current->exit_code) { - send_sig(current->exit_code, current, 1); - current->exit_code = 0; - } + int ret = 0; + + if (test_thread_flag(TIF_SYSCALL_TRACE)) + ret = tracehook_report_syscall_entry(regs); + + return ret; +} + +asmlinkage void syscall_trace_leave(struct pt_regs *regs) +{ + if (test_thread_flag(TIF_SYSCALL_TRACE)) + tracehook_report_syscall_exit(regs, 0); } diff --git a/arch/blackfin/kernel/signal.c b/arch/blackfin/kernel/signal.c index e0fd63e..e60990c 100644 --- a/arch/blackfin/kernel/signal.c +++ b/arch/blackfin/kernel/signal.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2009 Analog Devices Inc. + * Copyright 2004-2010 Analog Devices Inc. * * Licensed under the GPL-2 or later */ @@ -206,16 +206,6 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info, regs->r1 = (unsigned long)(&frame->info); regs->r2 = (unsigned long)(&frame->uc); - /* - * Clear the trace flag when entering the signal handler, but - * notify any tracer that was single-stepping it. The tracer - * may want to single-step inside the handler too. - */ - if (regs->syscfg & TRACE_BITS) { - regs->syscfg &= ~TRACE_BITS; - ptrace_notify(SIGTRAP); - } - return 0; give_sigsegv: @@ -315,6 +305,8 @@ asmlinkage void do_signal(struct pt_regs *regs) * clear the TIF_RESTORE_SIGMASK flag */ if (test_thread_flag(TIF_RESTORE_SIGMASK)) clear_thread_flag(TIF_RESTORE_SIGMASK); + + tracehook_signal_handler(signr, &info, &ka, regs, 1); } return; diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S index 1fa414f..0df5b83 100644 --- a/arch/blackfin/mach-common/entry.S +++ b/arch/blackfin/mach-common/entry.S @@ -736,7 +736,8 @@ ENDPROC(_system_call) * this symbol need not be global anyways, so ... */ _sys_trace: - pseudo_long_call _syscall_trace, p5; + r0 = sp; + pseudo_long_call _syscall_trace_enter, p5; /* Execute the appropriate system call */ @@ -760,7 +761,8 @@ _sys_trace: SP += 24; [sp + PT_R0] = r0; - pseudo_long_call _syscall_trace, p5; + r0 = sp; + pseudo_long_call _syscall_trace_leave, p5; jump .Lresume_userspace; ENDPROC(_sys_trace) -- cgit v0.10.2 From 600482c13d3d3612d71f39d8aaec47f63aafa801 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 17 Feb 2010 10:44:22 +0000 Subject: Blackfin: fix single stepping over system calls On Blackfin systems, the hardware single step exception triggers before the system call exception, so we need to save this info to process it later on. Otherwise, single stepping in userspace misses a few insns right after the system call. This is based a bit on the SuperH code added in commit 4b505db9c4c72dbd. Reported-by: Roland McGrath Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/thread_info.h b/arch/blackfin/include/asm/thread_info.h index 0149c92..e9a5614 100644 --- a/arch/blackfin/include/asm/thread_info.h +++ b/arch/blackfin/include/asm/thread_info.h @@ -103,6 +103,7 @@ static inline struct thread_info *current_thread_info(void) #define TIF_FREEZE 6 /* is freezing for suspend */ #define TIF_IRQ_SYNC 7 /* sync pipeline stage */ #define TIF_NOTIFY_RESUME 8 /* callback before returning to user */ +#define TIF_SINGLESTEP 9 /* as above, but as bit values */ #define _TIF_SYSCALL_TRACE (1<syscfg |= SYSCFG_SSSTEP; + + set_tsk_thread_flag(child, TIF_SINGLESTEP); } void user_disable_single_step(struct task_struct *child) { struct pt_regs *regs = task_pt_regs(child); regs->syscfg &= ~SYSCFG_SSSTEP; + + clear_tsk_thread_flag(child, TIF_SINGLESTEP); } long arch_ptrace(struct task_struct *child, long request, long addr, long data) @@ -401,6 +405,9 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs) asmlinkage void syscall_trace_leave(struct pt_regs *regs) { - if (test_thread_flag(TIF_SYSCALL_TRACE)) - tracehook_report_syscall_exit(regs, 0); + int step; + + step = test_thread_flag(TIF_SINGLESTEP); + if (step || test_thread_flag(TIF_SYSCALL_TRACE)) + tracehook_report_syscall_exit(regs, step); } diff --git a/arch/blackfin/kernel/signal.c b/arch/blackfin/kernel/signal.c index e60990c..28d6f28 100644 --- a/arch/blackfin/kernel/signal.c +++ b/arch/blackfin/kernel/signal.c @@ -306,7 +306,8 @@ asmlinkage void do_signal(struct pt_regs *regs) if (test_thread_flag(TIF_RESTORE_SIGMASK)) clear_thread_flag(TIF_RESTORE_SIGMASK); - tracehook_signal_handler(signr, &info, &ka, regs, 1); + tracehook_signal_handler(signr, &info, &ka, regs, + test_thread_flag(TIF_SINGLESTEP)); } return; diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S index 0df5b83..0a9e458 100644 --- a/arch/blackfin/mach-common/entry.S +++ b/arch/blackfin/mach-common/entry.S @@ -642,6 +642,8 @@ ENTRY(_system_call) r7 = [p2+TI_FLAGS]; CC = BITTST(r7,TIF_SYSCALL_TRACE); if CC JUMP _sys_trace; + CC = BITTST(r7,TIF_SINGLESTEP); + if CC JUMP _sys_trace; /* Execute the appropriate system call */ -- cgit v0.10.2 From 9e228ee9eae97b533d3b3133f76478c70dbd4294 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 12 Feb 2010 07:24:34 +0000 Subject: Blackfin: check for bad syscalls after tracing it We want to report all system calls (even invalid ones) to the tracing layers, so check the NR only after we've notified. Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S index 0a9e458..6c20044 100644 --- a/arch/blackfin/mach-common/entry.S +++ b/arch/blackfin/mach-common/entry.S @@ -626,13 +626,6 @@ ENTRY(_system_call) p0 = [sp + PT_ORIG_P0]; #endif /* CONFIG_IPIPE */ - /* Check the System Call */ - r7 = __NR_syscall; - /* System call number is passed in P0 */ - r6 = p0; - cc = r6 < r7; - if ! cc jump .Lbadsys; - /* are we tracing syscalls?*/ r7 = sp; r6.l = lo(ALIGN_PAGE_MASK); @@ -645,6 +638,12 @@ ENTRY(_system_call) CC = BITTST(r7,TIF_SINGLESTEP); if CC JUMP _sys_trace; + /* Make sure the system call # is valid */ + p4 = __NR_syscall; + /* System call number is passed in P0 */ + cc = p4 <= p0; + if cc jump .Lbadsys; + /* Execute the appropriate system call */ p4 = p0; @@ -741,9 +740,14 @@ _sys_trace: r0 = sp; pseudo_long_call _syscall_trace_enter, p5; - /* Execute the appropriate system call */ - + /* Make sure the system call # is valid */ p4 = [SP + PT_P0]; + p3 = __NR_syscall; + cc = p3 <= p4; + r0 = -ENOSYS; + if cc jump .Lsys_trace_badsys; + + /* Execute the appropriate system call */ p5.l = _sys_call_table; p5.h = _sys_call_table; p5 = p5 + (p4 << 2); @@ -761,6 +765,7 @@ _sys_trace: SP += -12; call (p5); SP += 24; +.Lsys_trace_badsys: [sp + PT_R0] = r0; r0 = sp; -- cgit v0.10.2 From ddaebcabbc18811ac4ac6e84fb9c327e8393a1dc Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 29 Jan 2010 01:33:54 +0000 Subject: Blackfin: add support for restart_syscall() Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/kernel/signal.c b/arch/blackfin/kernel/signal.c index 28d6f28..d536f35 100644 --- a/arch/blackfin/kernel/signal.c +++ b/arch/blackfin/kernel/signal.c @@ -17,6 +17,7 @@ #include #include #include +#include #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) @@ -50,6 +51,9 @@ rt_restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *p unsigned long usp = 0; int err = 0; + /* Always make any pending restarted system calls return -EINTR */ + current_thread_info()->restart_block.fn = do_no_restart_syscall; + #define RESTORE(x) err |= __get_user(regs->x, &sc->sc_##x) /* restore passed registers */ @@ -237,6 +241,11 @@ handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler) regs->r0 = regs->orig_r0; regs->pc -= 2; break; + + case -ERESTART_RESTARTBLOCK: + regs->p0 = __NR_restart_syscall; + regs->pc -= 2; + break; } } -- cgit v0.10.2 From fe5b25c09873faee44077ee6ff8f23eee61b0fa0 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Thu, 4 Feb 2010 14:41:39 +0000 Subject: Blackfin: bf537-stamp: add example ADS7846 touchscreen resources Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 9bc7bd3..7a1d645 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -825,6 +825,29 @@ static inline void adf702x_mac_init(void) static inline void adf702x_mac_init(void) {} #endif +#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) +#include +static struct bfin5xx_spi_chip ad7873_spi_chip_info = { + .bits_per_word = 8, +}; + +static int ads7873_get_pendown_state(void) +{ + return gpio_get_value(GPIO_PF6); +} + +static struct ads7846_platform_data __initdata ad7873_pdata = { + .model = 7873, /* AD7873 */ + .x_max = 0xfff, + .y_max = 0xfff, + .x_plate_ohms = 620, + .debounce_max = 1, + .debounce_rep = 0, + .debounce_tol = (~0), + .get_pendown_state = ads7873_get_pendown_state, +}; +#endif + #if defined(CONFIG_MTD_DATAFLASH) \ || defined(CONFIG_MTD_DATAFLASH_MODULE) @@ -1026,7 +1049,18 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { .mode = SPI_MODE_0, }, #endif - +#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) + { + .modalias = "ads7846", + .max_speed_hz = 2000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 0, + .irq = IRQ_PF6, + .chip_select = GPIO_PF10 + MAX_CTRL_CS, /* GPIO controlled SSEL */ + .controller_data = &ad7873_spi_chip_info, + .platform_data = &ad7873_pdata, + .mode = SPI_MODE_0, + }, +#endif }; #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) -- cgit v0.10.2 From 2bc4affe9c374983220c1a5d5566ce67c95384fc Mon Sep 17 00:00:00 2001 From: Frans Pop Date: Sat, 6 Feb 2010 18:47:18 +0100 Subject: Blackfin: remove trailing space in messages Signed-off-by: Frans Pop Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c index 924c002..26403d1 100644 --- a/arch/blackfin/kernel/bfin_dma_5xx.c +++ b/arch/blackfin/kernel/bfin_dma_5xx.c @@ -91,7 +91,7 @@ late_initcall(proc_dma_init); */ int request_dma(unsigned int channel, const char *device_id) { - pr_debug("request_dma() : BEGIN \n"); + pr_debug("request_dma() : BEGIN\n"); if (device_id == NULL) printk(KERN_WARNING "request_dma(%u): no device_id given\n", channel); @@ -107,7 +107,7 @@ int request_dma(unsigned int channel, const char *device_id) #endif if (atomic_cmpxchg(&dma_ch[channel].chan_status, 0, 1)) { - pr_debug("DMA CHANNEL IN USE \n"); + pr_debug("DMA CHANNEL IN USE\n"); return -EBUSY; } @@ -131,7 +131,7 @@ int request_dma(unsigned int channel, const char *device_id) * you have to request DMA, before doing any operations on * descriptor/channel */ - pr_debug("request_dma() : END \n"); + pr_debug("request_dma() : END\n"); return 0; } EXPORT_SYMBOL(request_dma); @@ -171,7 +171,7 @@ static void clear_dma_buffer(unsigned int channel) void free_dma(unsigned int channel) { - pr_debug("freedma() : BEGIN \n"); + pr_debug("freedma() : BEGIN\n"); BUG_ON(channel >= MAX_DMA_CHANNELS || !atomic_read(&dma_ch[channel].chan_status)); @@ -185,7 +185,7 @@ void free_dma(unsigned int channel) /* Clear the DMA Variable in the Channel */ atomic_set(&dma_ch[channel].chan_status, 0); - pr_debug("freedma() : END \n"); + pr_debug("freedma() : END\n"); } EXPORT_SYMBOL(free_dma); diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index 4eaca2d1..ba70c4b 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c @@ -1116,7 +1116,7 @@ void dump_bfin_mem(struct pt_regs *fp) /* And the last RETI points to the current userspace context */ if ((fp + 1)->pc >= current->mm->start_code && (fp + 1)->pc <= current->mm->end_code) { - verbose_printk(KERN_NOTICE "It might be better to look around here : \n"); + verbose_printk(KERN_NOTICE "It might be better to look around here :\n"); verbose_printk(KERN_NOTICE "-------------------------------------------\n"); show_regs(fp + 1); verbose_printk(KERN_NOTICE "-------------------------------------------\n"); -- cgit v0.10.2 From f32792d045e1bbd86c0af0a28a46ae87af1ae100 Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Tue, 9 Feb 2010 02:47:09 +0000 Subject: Blackfin: bf537-stamp: add example AD5398 power regulator resources Signed-off-by: Sonic Zhang Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 7a1d645..8456292 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -35,6 +35,11 @@ #include #include #include +#ifdef CONFIG_REGULATOR_AD5398 +#include +#endif +#include +#include /* * Name the Board for the /proc/cpuinfo @@ -1634,6 +1639,59 @@ static struct adp8870_backlight_platform_data adp8870_pdata = { }; #endif +#if defined(CONFIG_REGULATOR_AD5398) || defined(CONFIG_REGULATOR_AD5398_MODULE) +static struct regulator_consumer_supply ad5398_consumer = { + .supply = "current", +}; + +static struct regulator_init_data ad5398_regulator_data = { + .constraints = { + .name = "current range", + .max_uA = 120000, + .valid_ops_mask = REGULATOR_CHANGE_CURRENT | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &ad5398_consumer, +}; + +static struct ad5398_platform_data ad5398_i2c_platform_data = { + .current_bits = 10, + .current_offset = 4, + .regulator_data = &ad5398_regulator_data, +}; + +#if defined(CONFIG_REGULATOR_VIRTUAL_CONSUMER) || \ + defined(CONFIG_REGULATOR_VIRTUAL_CONSUMER_MODULE) +static struct platform_device ad5398_virt_consumer_device = { + .name = "reg-virt-consumer", + .id = 0, + .dev = { + .platform_data = "current", /* Passed to driver */ + }, +}; +#endif +#if defined(CONFIG_REGULATOR_USERSPACE_CONSUMER) || \ + defined(CONFIG_REGULATOR_USERSPACE_CONSUMER_MODULE) +static struct regulator_bulk_data ad5398_bulk_data = { + .supply = "current", +}; + +static struct regulator_userspace_consumer_data ad5398_userspace_comsumer_data = { + .name = "ad5398", + .num_supplies = 1, + .supplies = &ad5398_bulk_data, +}; + +static struct platform_device ad5398_userspace_consumer_device = { + .name = "reg-userspace-consumer", + .id = 0, + .dev = { + .platform_data = &ad5398_userspace_comsumer_data, + }, +}; +#endif +#endif + static struct i2c_board_info __initdata bfin_i2c_board_info[] = { #if defined(CONFIG_INPUT_AD714X_I2C) || defined(CONFIG_INPUT_AD714X_I2C_MODULE) { @@ -1743,6 +1801,12 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { I2C_BOARD_INFO("ssm2602", 0x1b), }, #endif +#if defined(CONFIG_REGULATOR_AD5398) || defined(CONFIG_REGULATOR_AD5398_MODULE) + { + I2C_BOARD_INFO("ad5398", 0xC), + .platform_data = (void *)&ad5398_i2c_platform_data, + }, +#endif }; #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) @@ -2047,6 +2111,16 @@ static struct platform_device *stamp_devices[] __initdata = { #if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE) &bfin_ac97, #endif +#if defined(CONFIG_REGULATOR_AD5398) || defined(CONFIG_REGULATOR_AD5398_MODULE) +#if defined(CONFIG_REGULATOR_VIRTUAL_CONSUMER) || \ + defined(CONFIG_REGULATOR_VIRTUAL_CONSUMER_MODULE) + &ad5398_virt_consumer_device, +#endif +#if defined(CONFIG_REGULATOR_USERSPACE_CONSUMER) || \ + defined(CONFIG_REGULATOR_USERSPACE_CONSUMER_MODULE) + &ad5398_userspace_consumer_device, +#endif +#endif }; static int __init stamp_init(void) -- cgit v0.10.2 From f5f9531c7e588ee62e3aeddb14613ea80e7c2ca2 Mon Sep 17 00:00:00 2001 From: Graf Yang Date: Wed, 10 Feb 2010 07:15:59 +0000 Subject: Blackfin: bf537-stamp: add example AD2S90 resources Signed-off-by: Graf Yang Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 8456292..4a09ce9 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -653,6 +653,13 @@ static struct ad714x_platform_data ad7142_i2c_platform_data = { }; #endif +#if defined(CONFIG_AD2S90) || defined(CONFIG_AD2S90_MODULE) +static struct bfin5xx_spi_chip ad2s90_spi_chip_info = { + .enable_dma = 0, + .bits_per_word = 16, +}; +#endif + #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) #define MMC_SPI_CARD_DETECT_INT IRQ_PF5 @@ -967,6 +974,16 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { }, #endif +#if defined(CONFIG_AD2S90) || defined(CONFIG_AD2S90_MODULE) + { + .modalias = "ad2s90", + .bus_num = 0, + .chip_select = 3, /* change it for your board */ + .platform_data = NULL, + .controller_data = &ad2s90_spi_chip_info, + }, +#endif + #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) { .modalias = "mmc_spi", -- cgit v0.10.2 From f8e6dbffa7a6cb3da3bcaf1fde3039896e1ac764 Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Wed, 10 Feb 2010 09:09:05 +0000 Subject: Blackfin: bf537-stamp: add example ADP122/ADP150 power regulator resources Signed-off-by: Sonic Zhang Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 4a09ce9..5f18951 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -35,6 +35,9 @@ #include #include #include +#ifdef CONFIG_REGULATOR_ADP_SWITCH +#include +#endif #ifdef CONFIG_REGULATOR_AD5398 #include #endif @@ -2008,6 +2011,93 @@ static struct platform_device bfin_ac97 = { }; #endif +#if defined(CONFIG_REGULATOR_ADP_SWITCH) || defined(CONFIG_REGULATOR_ADP_SWITCH_MODULE) +#define REGULATOR_ADP122 "adp122" +#define REGULATOR_ADP150 "adp150" + +static struct regulator_consumer_supply adp122_consumers = { + .supply = REGULATOR_ADP122, +}; + +static struct regulator_consumer_supply adp150_consumers = { + .supply = REGULATOR_ADP150, +}; + +static struct regulator_init_data adp_switch_regulator_data[] = { + { + .constraints = { + .name = REGULATOR_ADP122, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = 1, /* only 1 */ + .consumer_supplies = &adp122_consumers, + .driver_data = (void *)GPIO_PF2, /* gpio port only */ + }, + { + .constraints = { + .name = REGULATOR_ADP150, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = 1, /* only 1 */ + .consumer_supplies = &adp150_consumers, + .driver_data = (void *)GPIO_PF3, /* gpio port only */ + }, +}; + +static struct adp_switch_platform_data adp_switch_pdata = { + .regulator_num = ARRAY_SIZE(adp_switch_regulator_data), + .regulator_data = adp_switch_regulator_data, +}; + +static struct platform_device adp_switch_device = { + .name = "adp_switch", + .id = 0, + .dev = { + .platform_data = &adp_switch_pdata, + }, +}; + +#if defined(CONFIG_REGULATOR_USERSPACE_CONSUMER) || \ + defined(CONFIG_REGULATOR_USERSPACE_CONSUMER_MODULE) +static struct regulator_bulk_data adp122_bulk_data = { + .supply = REGULATOR_ADP122, +}; + +static struct regulator_userspace_consumer_data adp122_userspace_comsumer_data = { + .name = REGULATOR_ADP122, + .num_supplies = 1, + .supplies = &adp122_bulk_data, +}; + +static struct platform_device adp122_userspace_consumer_device = { + .name = "reg-userspace-consumer", + .id = 0, + .dev = { + .platform_data = &adp122_userspace_comsumer_data, + }, +}; + +static struct regulator_bulk_data adp150_bulk_data = { + .supply = REGULATOR_ADP150, +}; + +static struct regulator_userspace_consumer_data adp150_userspace_comsumer_data = { + .name = REGULATOR_ADP150, + .num_supplies = 1, + .supplies = &adp150_bulk_data, +}; + +static struct platform_device adp150_userspace_consumer_device = { + .name = "reg-userspace-consumer", + .id = 1, + .dev = { + .platform_data = &adp150_userspace_comsumer_data, + }, +}; +#endif +#endif + + static struct platform_device *stamp_devices[] __initdata = { &bfin_dpmc, @@ -2138,6 +2228,15 @@ static struct platform_device *stamp_devices[] __initdata = { &ad5398_userspace_consumer_device, #endif #endif + +#if defined(CONFIG_REGULATOR_ADP_SWITCH) || defined(CONFIG_REGULATOR_ADP_SWITCH_MODULE) + &adp_switch_device, +#if defined(CONFIG_REGULATOR_USERSPACE_CONSUMER) || \ + defined(CONFIG_REGULATOR_USERSPACE_CONSUMER_MODULE) + &adp122_userspace_consumer_device, + &adp150_userspace_consumer_device, +#endif +#endif }; static int __init stamp_init(void) -- cgit v0.10.2 From 7f4f69f991146fa976cbc914a50285b2afc0ad93 Mon Sep 17 00:00:00 2001 From: Joachim Eastwood Date: Wed, 10 Feb 2010 12:31:41 +0100 Subject: Blackfin: GPIO: implement to_irq handler This makes it possible to support IRQs coming from off-chip GPIO controllers. Signed-off-by: Joachim Eastwood Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/gpio.h b/arch/blackfin/include/asm/gpio.h index 539468a..91bd2d7 100644 --- a/arch/blackfin/include/asm/gpio.h +++ b/arch/blackfin/include/asm/gpio.h @@ -70,6 +70,8 @@ #ifndef __ASSEMBLY__ +#include + /*********************************************************** * * FUNCTIONS: Blackfin General Purpose Ports Access Functions @@ -223,6 +225,9 @@ int bfin_gpio_direction_output(unsigned gpio, int value); int bfin_gpio_get_value(unsigned gpio); void bfin_gpio_set_value(unsigned gpio, int value); +#include +#include + #ifdef CONFIG_GPIOLIB #include /* cansleep wrappers */ @@ -247,6 +252,11 @@ static inline int gpio_cansleep(unsigned int gpio) return __gpio_cansleep(gpio); } +static inline int gpio_to_irq(unsigned gpio) +{ + return __gpio_to_irq(gpio); +} + #else /* !CONFIG_GPIOLIB */ static inline int gpio_request(unsigned gpio, const char *label) @@ -279,10 +289,6 @@ static inline void gpio_set_value(unsigned gpio, int value) return bfin_gpio_set_value(gpio, value); } -#include /* cansleep wrappers */ -#endif /* !CONFIG_GPIOLIB */ -#include - static inline int gpio_to_irq(unsigned gpio) { if (likely(gpio < MAX_BLACKFIN_GPIOS)) @@ -291,6 +297,9 @@ static inline int gpio_to_irq(unsigned gpio) return -EINVAL; } +#include /* cansleep wrappers */ +#endif /* !CONFIG_GPIOLIB */ + static inline int irq_to_gpio(unsigned irq) { return (irq - GPIO_IRQ_BASE); diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c index 0dd9cf9..6dcb344 100644 --- a/arch/blackfin/kernel/bfin_gpio.c +++ b/arch/blackfin/kernel/bfin_gpio.c @@ -1319,6 +1319,11 @@ void bfin_gpiolib_gpio_free(struct gpio_chip *chip, unsigned gpio) return bfin_gpio_free(gpio); } +int bfin_gpiolib_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) +{ + return gpio + GPIO_IRQ_BASE; +} + static struct gpio_chip bfin_chip = { .label = "BFIN-GPIO", .direction_input = bfin_gpiolib_direction_input, @@ -1327,6 +1332,7 @@ static struct gpio_chip bfin_chip = { .set = bfin_gpiolib_set_value, .request = bfin_gpiolib_gpio_request, .free = bfin_gpiolib_gpio_free, + .to_irq = bfin_gpiolib_gpio_to_irq, .base = 0, .ngpio = MAX_BLACKFIN_GPIOS, }; -- cgit v0.10.2 From c48d767569ec6449277bf4248295b4c165b57159 Mon Sep 17 00:00:00 2001 From: Cliff Cai Date: Thu, 11 Feb 2010 09:27:18 +0000 Subject: Blackfin: bf537-stamp: add example ADAU1361 resources Signed-off-by: Cliff Cai Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 5f18951..8a138f0 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -1811,6 +1811,11 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { I2C_BOARD_INFO("adau1761", 0x38), }, #endif +#if defined(CONFIG_SND_SOC_ADAU1361) || defined(CONFIG_SND_SOC_ADAU1361_MODULE) + { + I2C_BOARD_INFO("adau1361", 0x38), + }, +#endif #if defined(CONFIG_AD525X_DPOT) || defined(CONFIG_AD525X_DPOT_MODULE) { I2C_BOARD_INFO("ad5258", 0x18), -- cgit v0.10.2 From f9c29e872b1c468d09c04ed452dc58961914c9d7 Mon Sep 17 00:00:00 2001 From: Joachim Eastwood Date: Thu, 11 Feb 2010 12:41:11 +0100 Subject: Blackfin: mark gpio lib functions static Signed-off-by: Joachim Eastwood Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c index 6dcb344..e35e20f 100644 --- a/arch/blackfin/kernel/bfin_gpio.c +++ b/arch/blackfin/kernel/bfin_gpio.c @@ -1289,37 +1289,37 @@ __initcall(gpio_register_proc); #endif #ifdef CONFIG_GPIOLIB -int bfin_gpiolib_direction_input(struct gpio_chip *chip, unsigned gpio) +static int bfin_gpiolib_direction_input(struct gpio_chip *chip, unsigned gpio) { return bfin_gpio_direction_input(gpio); } -int bfin_gpiolib_direction_output(struct gpio_chip *chip, unsigned gpio, int level) +static int bfin_gpiolib_direction_output(struct gpio_chip *chip, unsigned gpio, int level) { return bfin_gpio_direction_output(gpio, level); } -int bfin_gpiolib_get_value(struct gpio_chip *chip, unsigned gpio) +static int bfin_gpiolib_get_value(struct gpio_chip *chip, unsigned gpio) { return bfin_gpio_get_value(gpio); } -void bfin_gpiolib_set_value(struct gpio_chip *chip, unsigned gpio, int value) +static void bfin_gpiolib_set_value(struct gpio_chip *chip, unsigned gpio, int value) { return bfin_gpio_set_value(gpio, value); } -int bfin_gpiolib_gpio_request(struct gpio_chip *chip, unsigned gpio) +static int bfin_gpiolib_gpio_request(struct gpio_chip *chip, unsigned gpio) { return bfin_gpio_request(gpio, chip->label); } -void bfin_gpiolib_gpio_free(struct gpio_chip *chip, unsigned gpio) +static void bfin_gpiolib_gpio_free(struct gpio_chip *chip, unsigned gpio) { return bfin_gpio_free(gpio); } -int bfin_gpiolib_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) +static int bfin_gpiolib_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) { return gpio + GPIO_IRQ_BASE; } -- cgit v0.10.2 From b2740801457b2fbbe14812c0fda24bd689025886 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 16 Feb 2010 04:03:10 -0500 Subject: Blackfin: asm/page.h: pull in asm-generic headers Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/page.h b/arch/blackfin/include/asm/page.h index 1d04e40..d0ce975 100644 --- a/arch/blackfin/include/asm/page.h +++ b/arch/blackfin/include/asm/page.h @@ -15,4 +15,7 @@ ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) +#include +#include + #endif -- cgit v0.10.2 From aec59c911307639c77076bdc9d9b546a4a767a73 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Fri, 19 Feb 2010 15:09:10 +0000 Subject: Blackfin: add support for the on-chip MAC status interrupts This patch provides infrastructure for MAC Wake-On-Lan and PHYINT use in phylib. New Interrupts added: IRQ_MAC_PHYINT /* PHY_INT Interrupt */ IRQ_MAC_MMCINT /* MMC Counter Interrupt */ IRQ_MAC_RXFSINT /* RX Frame-Status Interrupt */ IRQ_MAC_TXFSINT /* TX Frame-Status Interrupt */ IRQ_MAC_WAKEDET /* Wake-Up Interrupt */ IRQ_MAC_RXDMAERR /* RX DMA Direction Error Interrupt */ IRQ_MAC_TXDMAERR /* TX DMA Direction Error Interrupt */ IRQ_MAC_STMDONE /* Station Mgt. Transfer Done Interrupt */ On BF537/6 the implementation is not straight forward since there are now two chained chained_handlers. A cleaner approach would have been to add latter IRQs to the demux of IRQ_GENERIC_ERROR. Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf518/include/mach/irq.h b/arch/blackfin/mach-bf518/include/mach/irq.h index 52edc84..435e76e 100644 --- a/arch/blackfin/mach-bf518/include/mach/irq.h +++ b/arch/blackfin/mach-bf518/include/mach/irq.h @@ -151,7 +151,16 @@ #define GPIO_IRQ_BASE IRQ_PF0 -#define NR_MACH_IRQS (IRQ_PH15 + 1) +#define IRQ_MAC_PHYINT 119 /* PHY_INT Interrupt */ +#define IRQ_MAC_MMCINT 120 /* MMC Counter Interrupt */ +#define IRQ_MAC_RXFSINT 121 /* RX Frame-Status Interrupt */ +#define IRQ_MAC_TXFSINT 122 /* TX Frame-Status Interrupt */ +#define IRQ_MAC_WAKEDET 123 /* Wake-Up Interrupt */ +#define IRQ_MAC_RXDMAERR 124 /* RX DMA Direction Error Interrupt */ +#define IRQ_MAC_TXDMAERR 125 /* TX DMA Direction Error Interrupt */ +#define IRQ_MAC_STMDONE 126 /* Station Mgt. Transfer Done Interrupt */ + +#define NR_MACH_IRQS (IRQ_MAC_STMDONE + 1) #define NR_IRQS (NR_MACH_IRQS + NR_SPARE_IRQS) #define IVG7 7 diff --git a/arch/blackfin/mach-bf527/include/mach/irq.h b/arch/blackfin/mach-bf527/include/mach/irq.h index 17604b4..704d925 100644 --- a/arch/blackfin/mach-bf527/include/mach/irq.h +++ b/arch/blackfin/mach-bf527/include/mach/irq.h @@ -151,7 +151,16 @@ #define GPIO_IRQ_BASE IRQ_PF0 -#define NR_MACH_IRQS (IRQ_PH15 + 1) +#define IRQ_MAC_PHYINT 119 /* PHY_INT Interrupt */ +#define IRQ_MAC_MMCINT 120 /* MMC Counter Interrupt */ +#define IRQ_MAC_RXFSINT 121 /* RX Frame-Status Interrupt */ +#define IRQ_MAC_TXFSINT 122 /* TX Frame-Status Interrupt */ +#define IRQ_MAC_WAKEDET 123 /* Wake-Up Interrupt */ +#define IRQ_MAC_RXDMAERR 124 /* RX DMA Direction Error Interrupt */ +#define IRQ_MAC_TXDMAERR 125 /* TX DMA Direction Error Interrupt */ +#define IRQ_MAC_STMDONE 126 /* Station Mgt. Transfer Done Interrupt */ + +#define NR_MACH_IRQS (IRQ_MAC_STMDONE + 1) #define NR_IRQS (NR_MACH_IRQS + NR_SPARE_IRQS) #define IVG7 7 diff --git a/arch/blackfin/mach-bf537/include/mach/irq.h b/arch/blackfin/mach-bf537/include/mach/irq.h index 9b2cbca..789a4f2 100644 --- a/arch/blackfin/mach-bf537/include/mach/irq.h +++ b/arch/blackfin/mach-bf537/include/mach/irq.h @@ -134,7 +134,16 @@ #define GPIO_IRQ_BASE IRQ_PF0 -#define NR_MACH_IRQS (IRQ_PH15 + 1) +#define IRQ_MAC_PHYINT 98 /* PHY_INT Interrupt */ +#define IRQ_MAC_MMCINT 99 /* MMC Counter Interrupt */ +#define IRQ_MAC_RXFSINT 100 /* RX Frame-Status Interrupt */ +#define IRQ_MAC_TXFSINT 101 /* TX Frame-Status Interrupt */ +#define IRQ_MAC_WAKEDET 102 /* Wake-Up Interrupt */ +#define IRQ_MAC_RXDMAERR 103 /* RX DMA Direction Error Interrupt */ +#define IRQ_MAC_TXDMAERR 104 /* TX DMA Direction Error Interrupt */ +#define IRQ_MAC_STMDONE 105 /* Station Mgt. Transfer Done Interrupt */ + +#define NR_MACH_IRQS (IRQ_MAC_STMDONE + 1) #define NR_IRQS (NR_MACH_IRQS + NR_SPARE_IRQS) #define IVG7 7 diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c index ebf8860..11c05f3 100644 --- a/arch/blackfin/mach-common/ints-priority.c +++ b/arch/blackfin/mach-common/ints-priority.c @@ -325,7 +325,6 @@ static int error_int_mask; static void bfin_generic_error_mask_irq(unsigned int irq) { error_int_mask &= ~(1L << (irq - IRQ_PPI_ERROR)); - if (!error_int_mask) bfin_internal_mask_irq(IRQ_GENERIC_ERROR); } @@ -416,6 +415,127 @@ static void bfin_demux_error_irq(unsigned int int_err_irq, } #endif /* BF537_GENERIC_ERROR_INT_DEMUX */ +#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) +static int mac_stat_int_mask; + +static void bfin_mac_status_ack_irq(unsigned int irq) +{ + switch (irq) { + case IRQ_MAC_MMCINT: + bfin_write_EMAC_MMC_TIRQS( + bfin_read_EMAC_MMC_TIRQE() & + bfin_read_EMAC_MMC_TIRQS()); + bfin_write_EMAC_MMC_RIRQS( + bfin_read_EMAC_MMC_RIRQE() & + bfin_read_EMAC_MMC_RIRQS()); + break; + case IRQ_MAC_RXFSINT: + bfin_write_EMAC_RX_STKY( + bfin_read_EMAC_RX_IRQE() & + bfin_read_EMAC_RX_STKY()); + break; + case IRQ_MAC_TXFSINT: + bfin_write_EMAC_TX_STKY( + bfin_read_EMAC_TX_IRQE() & + bfin_read_EMAC_TX_STKY()); + break; + case IRQ_MAC_WAKEDET: + bfin_write_EMAC_WKUP_CTL( + bfin_read_EMAC_WKUP_CTL() | MPKS | RWKS); + break; + default: + /* These bits are W1C */ + bfin_write_EMAC_SYSTAT(1L << (irq - IRQ_MAC_PHYINT)); + break; + } +} + +static void bfin_mac_status_mask_irq(unsigned int irq) +{ + mac_stat_int_mask &= ~(1L << (irq - IRQ_MAC_PHYINT)); +#ifdef BF537_GENERIC_ERROR_INT_DEMUX + switch (irq) { + case IRQ_MAC_PHYINT: + bfin_write_EMAC_SYSCTL(bfin_read_EMAC_SYSCTL() & ~PHYIE); + break; + default: + break; + } +#else + if (!mac_stat_int_mask) + bfin_internal_mask_irq(IRQ_MAC_ERROR); +#endif + bfin_mac_status_ack_irq(irq); +} + +static void bfin_mac_status_unmask_irq(unsigned int irq) +{ +#ifdef BF537_GENERIC_ERROR_INT_DEMUX + switch (irq) { + case IRQ_MAC_PHYINT: + bfin_write_EMAC_SYSCTL(bfin_read_EMAC_SYSCTL() | PHYIE); + break; + default: + break; + } +#else + if (!mac_stat_int_mask) + bfin_internal_unmask_irq(IRQ_MAC_ERROR); +#endif + mac_stat_int_mask |= 1L << (irq - IRQ_MAC_PHYINT); +} + +#ifdef CONFIG_PM +int bfin_mac_status_set_wake(unsigned int irq, unsigned int state) +{ +#ifdef BF537_GENERIC_ERROR_INT_DEMUX + return bfin_internal_set_wake(IRQ_GENERIC_ERROR, state); +#else + return bfin_internal_set_wake(IRQ_MAC_ERROR, state); +#endif +} +#endif + +static struct irq_chip bfin_mac_status_irqchip = { + .name = "MACST", + .ack = bfin_ack_noop, + .mask_ack = bfin_mac_status_mask_irq, + .mask = bfin_mac_status_mask_irq, + .unmask = bfin_mac_status_unmask_irq, +#ifdef CONFIG_PM + .set_wake = bfin_mac_status_set_wake, +#endif +}; + +static void bfin_demux_mac_status_irq(unsigned int int_err_irq, + struct irq_desc *inta_desc) +{ + int i, irq = 0; + u32 status = bfin_read_EMAC_SYSTAT(); + + for (i = 0; i < (IRQ_MAC_STMDONE - IRQ_MAC_PHYINT); i++) + if (status & (1L << i)) { + irq = IRQ_MAC_PHYINT + i; + break; + } + + if (irq) { + if (mac_stat_int_mask & (1L << (irq - IRQ_MAC_PHYINT))) { + bfin_handle_irq(irq); + } else { + bfin_mac_status_ack_irq(irq); + pr_debug("IRQ %d:" + " MASKED MAC ERROR INTERRUPT ASSERTED\n", + irq); + } + } else + printk(KERN_ERR + "%s : %s : LINE %d :\nIRQ ?: MAC ERROR" + " INTERRUPT ASSERTED BUT NO SOURCE FOUND\n", + __func__, __FILE__, __LINE__); +} +#endif + static inline void bfin_set_irq_handler(unsigned irq, irq_flow_handler_t handle) { #ifdef CONFIG_IPIPE @@ -1070,7 +1190,11 @@ int __init init_arch_irq(void) set_irq_chained_handler(irq, bfin_demux_error_irq); break; #endif - +#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) + case IRQ_MAC_ERROR: + set_irq_chained_handler(irq, bfin_demux_mac_status_irq); + break; +#endif #ifdef CONFIG_SMP case IRQ_SUPPLE_0: case IRQ_SUPPLE_1: @@ -1111,14 +1235,22 @@ int __init init_arch_irq(void) for (irq = IRQ_PPI_ERROR; irq <= IRQ_UART1_ERROR; irq++) set_irq_chip_and_handler(irq, &bfin_generic_error_irqchip, handle_level_irq); +#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) + set_irq_chained_handler(IRQ_MAC_ERROR, bfin_demux_mac_status_irq); +#endif #endif +#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) + for (irq = IRQ_MAC_PHYINT; irq <= IRQ_MAC_STMDONE; irq++) + set_irq_chip_and_handler(irq, &bfin_mac_status_irqchip, + handle_level_irq); +#endif /* if configured as edge, then will be changed to do_edge_IRQ */ - for (irq = GPIO_IRQ_BASE; irq < NR_MACH_IRQS; irq++) + for (irq = GPIO_IRQ_BASE; + irq < (GPIO_IRQ_BASE + MAX_BLACKFIN_GPIOS); irq++) set_irq_chip_and_handler(irq, &bfin_gpio_irqchip, handle_level_irq); - bfin_write_IMASK(0); CSYNC(); ilat = bfin_read_ILAT(); -- cgit v0.10.2 From df6a949b4666780969fd90a2f3ac3db3b62552d6 Mon Sep 17 00:00:00 2001 From: Graf Yang Date: Sun, 21 Feb 2010 10:23:07 +0000 Subject: Blackfin: bf537-stamp: add example AD2S120x resources Signed-off-by: Graf Yang Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 8a138f0..283cc66 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -663,6 +663,18 @@ static struct bfin5xx_spi_chip ad2s90_spi_chip_info = { }; #endif +#if defined(CONFIG_AD2S120X) || defined(CONFIG_AD2S120X_MODULE) +unsigned short ad2s120x_platform_data[] = { + /* used as SAMPLE and RDVEL */ + GPIO_PF5, GPIO_PF6, 0 +}; + +static struct bfin5xx_spi_chip ad2s120x_spi_chip_info = { + .enable_dma = 0, + .bits_per_word = 16, +}; +#endif + #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) #define MMC_SPI_CARD_DETECT_INT IRQ_PF5 @@ -987,6 +999,16 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { }, #endif +#if defined(CONFIG_AD2S120X) || defined(CONFIG_AD2S120X_MODULE) + { + .modalias = "ad2s120x", + .bus_num = 0, + .chip_select = 4, /* CS, change it for your board */ + .platform_data = ad2s120x_platform_data, + .controller_data = &ad2s120x_spi_chip_info, + }, +#endif + #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) { .modalias = "mmc_spi", -- cgit v0.10.2 From d40bd71f88e7be193ce4feb4b92572c70024b9c2 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Mon, 22 Feb 2010 10:31:06 +0000 Subject: Blackfin: rename AD1836 to AD183X in board files The ASoC codec driver was generalized and renamed, so update the board resources accordingly. Signed-off-by: Barry Song Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf527/boards/cm_bf527.c b/arch/blackfin/mach-bf527/boards/cm_bf527.c index d6efdfa..ebe76d1 100644 --- a/arch/blackfin/mach-bf527/boards/cm_bf527.c +++ b/arch/blackfin/mach-bf527/boards/cm_bf527.c @@ -339,8 +339,8 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = { }; #endif -#if defined(CONFIG_SND_BLACKFIN_AD1836) \ - || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) +#if defined(CONFIG_SND_BLACKFIN_AD183X) \ + || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE) static struct bfin5xx_spi_chip ad1836_spi_chip_info = { .enable_dma = 0, .bits_per_word = 16, @@ -417,8 +417,8 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { }, #endif -#if defined(CONFIG_SND_BLACKFIN_AD1836) \ - || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) +#if defined(CONFIG_SND_BLACKFIN_AD183X) \ + || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE) { .modalias = "ad1836", .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c index 3d32a35..9233833 100644 --- a/arch/blackfin/mach-bf527/boards/ezkit.c +++ b/arch/blackfin/mach-bf527/boards/ezkit.c @@ -428,8 +428,8 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = { }; #endif -#if defined(CONFIG_SND_BLACKFIN_AD1836) \ - || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) +#if defined(CONFIG_SND_BLACKFIN_AD183X) \ + || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE) static struct bfin5xx_spi_chip ad1836_spi_chip_info = { .enable_dma = 0, .bits_per_word = 16, @@ -544,8 +544,8 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { }, #endif -#if defined(CONFIG_SND_BLACKFIN_AD1836) \ - || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) +#if defined(CONFIG_SND_BLACKFIN_AD183X) \ + || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE) { .modalias = "ad1836", .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ diff --git a/arch/blackfin/mach-bf533/boards/H8606.c b/arch/blackfin/mach-bf533/boards/H8606.c index d10c8e8..175371a 100644 --- a/arch/blackfin/mach-bf533/boards/H8606.c +++ b/arch/blackfin/mach-bf533/boards/H8606.c @@ -171,7 +171,7 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = { }; #endif -#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) +#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE) static struct bfin5xx_spi_chip ad1836_spi_chip_info = { .enable_dma = 0, .bits_per_word = 16, @@ -206,7 +206,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { }, #endif -#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) +#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE) { .modalias = "ad1836", .max_speed_hz = 16, diff --git a/arch/blackfin/mach-bf533/boards/cm_bf533.c b/arch/blackfin/mach-bf533/boards/cm_bf533.c index 0592fe0..fdcde61 100644 --- a/arch/blackfin/mach-bf533/boards/cm_bf533.c +++ b/arch/blackfin/mach-bf533/boards/cm_bf533.c @@ -71,7 +71,7 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = { }; #endif -#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) +#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE) static struct bfin5xx_spi_chip ad1836_spi_chip_info = { .enable_dma = 0, .bits_per_word = 16, @@ -110,7 +110,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { }, #endif -#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) +#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE) { .modalias = "ad1836", .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ diff --git a/arch/blackfin/mach-bf533/boards/ezkit.c b/arch/blackfin/mach-bf533/boards/ezkit.c index 84efda1..739773c 100644 --- a/arch/blackfin/mach-bf533/boards/ezkit.c +++ b/arch/blackfin/mach-bf533/boards/ezkit.c @@ -222,7 +222,7 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = { }; #endif -#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) +#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE) static struct bfin5xx_spi_chip ad1836_spi_chip_info = { .enable_dma = 0, .bits_per_word = 16, @@ -261,7 +261,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { }, #endif -#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) +#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE) { .modalias = "ad1836", .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ diff --git a/arch/blackfin/mach-bf533/boards/stamp.c b/arch/blackfin/mach-bf533/boards/stamp.c index e997d7f..c457eaa 100644 --- a/arch/blackfin/mach-bf533/boards/stamp.c +++ b/arch/blackfin/mach-bf533/boards/stamp.c @@ -184,7 +184,7 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = { }; #endif -#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) +#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE) static struct bfin5xx_spi_chip ad1836_spi_chip_info = { .enable_dma = 0, .bits_per_word = 16, @@ -251,7 +251,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { }, #endif -#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) +#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE) { .modalias = "ad1836", .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537e.c b/arch/blackfin/mach-bf537/boards/cm_bf537e.c index c543312..d35fc5f 100644 --- a/arch/blackfin/mach-bf537/boards/cm_bf537e.c +++ b/arch/blackfin/mach-bf537/boards/cm_bf537e.c @@ -73,7 +73,7 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = { }; #endif -#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) +#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE) static struct bfin5xx_spi_chip ad1836_spi_chip_info = { .enable_dma = 0, .bits_per_word = 16, @@ -112,7 +112,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { }, #endif -#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) +#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE) { .modalias = "ad1836", .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537u.c b/arch/blackfin/mach-bf537/boards/cm_bf537u.c index 18daacb..d464ad5 100644 --- a/arch/blackfin/mach-bf537/boards/cm_bf537u.c +++ b/arch/blackfin/mach-bf537/boards/cm_bf537u.c @@ -74,7 +74,7 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = { }; #endif -#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) +#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE) static struct bfin5xx_spi_chip ad1836_spi_chip_info = { .enable_dma = 0, .bits_per_word = 16, @@ -113,7 +113,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { }, #endif -#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) +#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE) { .modalias = "ad1836", .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ diff --git a/arch/blackfin/mach-bf537/boards/pnav10.c b/arch/blackfin/mach-bf537/boards/pnav10.c index a0f64ff..812e8f9 100644 --- a/arch/blackfin/mach-bf537/boards/pnav10.c +++ b/arch/blackfin/mach-bf537/boards/pnav10.c @@ -175,8 +175,8 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = { }; #endif -#if defined(CONFIG_SND_BLACKFIN_AD1836) \ - || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) +#if defined(CONFIG_SND_BLACKFIN_AD183X) \ + || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE) static struct bfin5xx_spi_chip ad1836_spi_chip_info = { .enable_dma = 0, .bits_per_word = 16, @@ -238,8 +238,8 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { }, #endif -#if defined(CONFIG_SND_BLACKFIN_AD1836) \ - || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) +#if defined(CONFIG_SND_BLACKFIN_AD183X) \ + || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE) { .modalias = "ad1836", .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 283cc66..e0f5663 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -528,8 +528,8 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = { }; #endif -#if defined(CONFIG_SND_BF5XX_SOC_AD1836) \ - || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE) +#if defined(CONFIG_SND_BF5XX_SOC_AD183X) \ + || defined(CONFIG_SND_BF5XX_SOC_AD183X_MODULE) static struct bfin5xx_spi_chip ad1836_spi_chip_info = { .enable_dma = 0, .bits_per_word = 16, @@ -953,13 +953,14 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { }, #endif -#if defined(CONFIG_SND_BF5XX_SOC_AD1836) \ - || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE) +#if defined(CONFIG_SND_BF5XX_SOC_AD183X) \ + || defined(CONFIG_SND_BF5XX_SOC_AD183X_MODULE) { - .modalias = "ad1836", + .modalias = "ad183x", .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ .bus_num = 0, .chip_select = 4,/* CONFIG_SND_BLACKFIN_SPI_PFBIT */ + .platform_data = "ad1836", /* only includes chip name for the moment */ .controller_data = &ad1836_spi_chip_info, .mode = SPI_MODE_3, }, diff --git a/arch/blackfin/mach-bf537/boards/tcm_bf537.c b/arch/blackfin/mach-bf537/boards/tcm_bf537.c index 59951cd..4f0a2e7 100644 --- a/arch/blackfin/mach-bf537/boards/tcm_bf537.c +++ b/arch/blackfin/mach-bf537/boards/tcm_bf537.c @@ -74,7 +74,7 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = { }; #endif -#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) +#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE) static struct bfin5xx_spi_chip ad1836_spi_chip_info = { .enable_dma = 0, .bits_per_word = 16, @@ -113,7 +113,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { }, #endif -#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) +#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE) { .modalias = "ad1836", .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c index 5b39299..06919db 100644 --- a/arch/blackfin/mach-bf548/boards/ezkit.c +++ b/arch/blackfin/mach-bf548/boards/ezkit.c @@ -963,8 +963,8 @@ static struct bfin5xx_spi_chip spi_flash_chip_info = { }; #endif -#if defined(CONFIG_SND_BLACKFIN_AD1836) \ - || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) +#if defined(CONFIG_SND_BLACKFIN_AD183X) \ + || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE) static struct bfin5xx_spi_chip ad1836_spi_chip_info = { .enable_dma = 0, .bits_per_word = 16, @@ -1020,8 +1020,8 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { .mode = SPI_MODE_3, }, #endif -#if defined(CONFIG_SND_BLACKFIN_AD1836) \ - || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) +#if defined(CONFIG_SND_BLACKFIN_AD183X) \ + || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE) { .modalias = "ad1836", .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ diff --git a/arch/blackfin/mach-bf561/boards/cm_bf561.c b/arch/blackfin/mach-bf561/boards/cm_bf561.c index 37dd375..e127aed 100644 --- a/arch/blackfin/mach-bf561/boards/cm_bf561.c +++ b/arch/blackfin/mach-bf561/boards/cm_bf561.c @@ -72,7 +72,7 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = { }; #endif -#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) +#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE) static struct bfin5xx_spi_chip ad1836_spi_chip_info = { .enable_dma = 0, .bits_per_word = 16, @@ -111,7 +111,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { }, #endif -#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) +#if defined(CONFIG_SND_BLACKFIN_AD183X) || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE) { .modalias = "ad1836", .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ diff --git a/arch/blackfin/mach-bf561/boards/ezkit.c b/arch/blackfin/mach-bf561/boards/ezkit.c index c7a5db7..9b93e2f 100644 --- a/arch/blackfin/mach-bf561/boards/ezkit.c +++ b/arch/blackfin/mach-bf561/boards/ezkit.c @@ -274,8 +274,8 @@ static struct platform_device ezkit_flash_device = { }; #endif -#if defined(CONFIG_SND_BLACKFIN_AD1836) \ - || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) +#if defined(CONFIG_SND_BLACKFIN_AD183X) \ + || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE) static struct bfin5xx_spi_chip ad1836_spi_chip_info = { .enable_dma = 0, .bits_per_word = 16, @@ -328,8 +328,8 @@ static struct platform_device bfin_spi0_device = { #endif static struct spi_board_info bfin_spi_board_info[] __initdata = { -#if defined(CONFIG_SND_BLACKFIN_AD1836) \ - || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) +#if defined(CONFIG_SND_BLACKFIN_AD183X) \ + || defined(CONFIG_SND_BLACKFIN_AD183X_MODULE) { .modalias = "ad1836", .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ -- cgit v0.10.2 From 5f0225948ecc4bb21cc35839d3d447e22d40a71f Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Wed, 24 Feb 2010 07:32:50 +0000 Subject: Blackfin: bf537-stamp: add example AD7414 temp sensor resources Signed-off-by: Sonic Zhang Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index e0f5663..83489d8 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -1763,6 +1763,19 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { }, #endif +#if defined(CONFIG_AD7414) || defined(CONFIG_AD7414_MODULE) + { + I2C_BOARD_INFO("ad7414", 0x9), + .irq = IRQ_PG5, + /* + * platform_data pointer is borrwoed by the driver to + * store custimer defined IRQ ALART level mode. + * only IRQF_TRIGGER_HIGH and IRQF_TRIGGER_LOW are valid. + */ + .platform_data = (void *)IRQF_TRIGGER_LOW, + }, +#endif + #if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE) { I2C_BOARD_INFO("pcf8574_lcd", 0x22), @@ -2056,6 +2069,8 @@ static struct regulator_init_data adp_switch_regulator_data[] = { .constraints = { .name = REGULATOR_ADP122, .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .min_uA = 0, + .max_uA = 300000, }, .num_consumer_supplies = 1, /* only 1 */ .consumer_supplies = &adp122_consumers, @@ -2065,6 +2080,8 @@ static struct regulator_init_data adp_switch_regulator_data[] = { .constraints = { .name = REGULATOR_ADP150, .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .min_uA = 0, + .max_uA = 150000, }, .num_consumer_supplies = 1, /* only 1 */ .consumer_supplies = &adp150_consumers, -- cgit v0.10.2 From 72fa2e9204d5efe4732346f99465a01c380f5cd3 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Wed, 24 Feb 2010 21:05:35 +0000 Subject: Blackfin: bf537-stamp: add example ADP8860 backlight/led resources Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 83489d8..8f92953 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -1682,6 +1682,48 @@ static struct adp8870_backlight_platform_data adp8870_pdata = { }; #endif +#if defined(CONFIG_BACKLIGHT_ADP8860) || defined(CONFIG_BACKLIGHT_ADP8860_MODULE) +#include +static struct led_info adp8860_leds[] = { + { + .name = "adp8860-led7", + .default_trigger = "none", + .flags = ADP8860_LED_D7 | ADP8860_LED_OFFT_600ms, + }, +}; + +static struct adp8860_backlight_platform_data adp8860_pdata = { + .bl_led_assign = ADP8860_BL_D1 | ADP8860_BL_D2 | ADP8860_BL_D3 | + ADP8860_BL_D4 | ADP8860_BL_D5 | ADP8860_BL_D6, /* 1 = Backlight 0 = Individual LED */ + + .bl_fade_in = ADP8860_FADE_T_1200ms, /* Backlight Fade-In Timer */ + .bl_fade_out = ADP8860_FADE_T_1200ms, /* Backlight Fade-Out Timer */ + .bl_fade_law = ADP8860_FADE_LAW_CUBIC1, /* fade-on/fade-off transfer characteristic */ + + .en_ambl_sens = 1, /* 1 = enable ambient light sensor */ + .abml_filt = ADP8860_BL_AMBL_FILT_320ms, /* Light sensor filter time */ + + .l1_daylight_max = ADP8860_BL_CUR_mA(20), /* use BL_CUR_mA(I) 0 <= I <= 30 mA */ + .l1_daylight_dim = ADP8860_BL_CUR_mA(0), /* typ = 0, use BL_CUR_mA(I) 0 <= I <= 30 mA */ + .l2_office_max = ADP8860_BL_CUR_mA(6), /* use BL_CUR_mA(I) 0 <= I <= 30 mA */ + .l2_office_dim = ADP8860_BL_CUR_mA(0), /* typ = 0, use BL_CUR_mA(I) 0 <= I <= 30 mA */ + .l3_dark_max = ADP8860_BL_CUR_mA(2), /* use BL_CUR_mA(I) 0 <= I <= 30 mA */ + .l3_dark_dim = ADP8860_BL_CUR_mA(0), /* typ = 0, use BL_CUR_mA(I) 0 <= I <= 30 mA */ + + .l2_trip = ADP8860_L2_COMP_CURR_uA(710), /* use L2_COMP_CURR_uA(I) 0 <= I <= 1106 uA */ + .l2_hyst = ADP8860_L2_COMP_CURR_uA(73), /* use L2_COMP_CURR_uA(I) 0 <= I <= 1106 uA */ + .l3_trip = ADP8860_L3_COMP_CURR_uA(43), /* use L3_COMP_CURR_uA(I) 0 <= I <= 138 uA */ + .l3_hyst = ADP8860_L3_COMP_CURR_uA(11), /* use L3_COMP_CURR_uA(I) 0 <= I <= 138 uA */ + + .leds = adp8860_leds, + .num_leds = ARRAY_SIZE(adp8860_leds), + .led_fade_law = ADP8860_FADE_LAW_SQUARE, /* fade-on/fade-off transfer characteristic */ + .led_fade_in = ADP8860_FADE_T_600ms, + .led_fade_out = ADP8860_FADE_T_600ms, + .led_on_time = ADP8860_LED_ONT_200ms, +}; +#endif + #if defined(CONFIG_REGULATOR_AD5398) || defined(CONFIG_REGULATOR_AD5398_MODULE) static struct regulator_consumer_supply ad5398_consumer = { .supply = "current", @@ -1868,6 +1910,12 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { .platform_data = (void *)&ad5398_i2c_platform_data, }, #endif +#if defined(CONFIG_BACKLIGHT_ADP8860) || defined(CONFIG_BACKLIGHT_ADP8860_MODULE) + { + I2C_BOARD_INFO("adp8860", 0x2A), + .platform_data = (void *)&adp8860_pdata, + }, +#endif }; #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) -- cgit v0.10.2 From ef8873e06efdc023ee2e7f708787c79b78df3fcd Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Thu, 25 Feb 2010 10:27:48 +0000 Subject: Blackfin: bf537-stamp: add example AD7416 IIO resources Signed-off-by: Sonic Zhang Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 8f92953..4aec6c0 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -1818,6 +1818,19 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { }, #endif +#if defined(CONFIG_AD7416) || defined(CONFIG_AD7416_MODULE) + { + I2C_BOARD_INFO("ad7417", 0xb), + .irq = IRQ_PG5, + /* + * platform_data pointer is borrwoed by the driver to + * store custimer defined IRQ ALART level mode. + * only IRQF_TRIGGER_HIGH and IRQF_TRIGGER_LOW are valid. + */ + .platform_data = (void *)IRQF_TRIGGER_LOW, + }, +#endif + #if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE) { I2C_BOARD_INFO("pcf8574_lcd", 0x22), -- cgit v0.10.2 From ae4a8c1903e5d0ec19dcb257ec922b888941abba Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Thu, 25 Feb 2010 13:32:24 +0000 Subject: Blackfin: don't support keypad wakeup from hibernate The on-chip keypad peripheral requires different registers to be setup depending on the standby type (standby vs hibernation). However, since the power management framework doesn't differentiate between these types, the driver doesn't know which registers to program and subsequently it avoids doing so. Always enabling the keyboard wakeup source causes misbehavior when the pins are not assigned to the keypad. If they happen to drive a certain level, they'll trigger a wake up event which is not wanted. So until the aforementioned issue can be sorted out, drop support for the wakeup source completely. Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c index 11c05f3..7ad8878 100644 --- a/arch/blackfin/mach-common/ints-priority.c +++ b/arch/blackfin/mach-common/ints-priority.c @@ -252,11 +252,6 @@ int bfin_internal_set_wake(unsigned int irq, unsigned int state) wakeup |= USBWE; break; #endif -#ifdef IRQ_KEY - case IRQ_KEY: - wakeup |= KPADWE; - break; -#endif #ifdef CONFIG_BF54x case IRQ_CNT: wakeup |= ROTWE; -- cgit v0.10.2 From 848c51ccee5c4d51b1dc1a029508cfbb73f8c260 Mon Sep 17 00:00:00 2001 From: Graf Yang Date: Fri, 26 Feb 2010 11:49:52 +0000 Subject: Blackfin: bf537-stamp: add example AD2S1210 IIO resources Signed-off-by: Graf Yang Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 4aec6c0..772b7ba 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -675,6 +675,23 @@ static struct bfin5xx_spi_chip ad2s120x_spi_chip_info = { }; #endif +#if defined(CONFIG_AD2S1210) || defined(CONFIG_AD2S1210_MODULE) +unsigned short ad2s1210_platform_data[] = { + /* use as SAMPLE, A0, A1 */ + GPIO_PF7, GPIO_PF8, GPIO_PF9, +# if defined(CONFIG_AD2S1210_GPIO_INPUT) || defined(CONFIG_AD2S1210_GPIO_OUTPUT) + /* the RES0 and RES1 pins */ + GPIO_PF4, GPIO_PF5, +# endif + 0, +}; + +static struct bfin5xx_spi_chip ad2s1210_spi_chip_info = { + .enable_dma = 0, + .bits_per_word = 8, +}; +#endif + #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) #define MMC_SPI_CARD_DETECT_INT IRQ_PF5 @@ -1010,6 +1027,17 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { }, #endif +#if defined(CONFIG_AD2S1210) || defined(CONFIG_AD2S1210_MODULE) + { + .modalias = "ad2s1210", + .max_speed_hz = 8192000, + .bus_num = 0, + .chip_select = 4, /* CS, change it for your board */ + .platform_data = ad2s1210_platform_data, + .controller_data = &ad2s1210_spi_chip_info, + }, +#endif + #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) { .modalias = "mmc_spi", -- cgit v0.10.2 From 6ba255f4a8a0785ea8a2b052837a7b91eeac1bb4 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Tue, 8 Dec 2009 11:34:07 +0000 Subject: Blackfin: bf537-stamp: add example ADXL346 orientation resources Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 772b7ba..9eaf5b0 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -734,11 +734,11 @@ static const struct ad7877_platform_data bfin_ad7877_ts_info = { .y_plate_ohms = 486, .pressure_max = 1000, .pressure_min = 0, - .stopacq_polarity = 1, - .first_conversion_delay = 3, - .acquisition_time = 1, - .averaging = 1, - .pen_down_acc_interval = 1, + .stopacq_polarity = 1, + .first_conversion_delay = 3, + .acquisition_time = 1, + .averaging = 1, + .pen_down_acc_interval = 1, }; #endif @@ -749,11 +749,11 @@ static const struct ad7879_platform_data bfin_ad7879_ts_info = { .x_plate_ohms = 620, /* 620 Ohm from the touch datasheet */ .pressure_max = 10000, .pressure_min = 0, - .first_conversion_delay = 3, /* wait 512us before do a first conversion */ - .acquisition_time = 1, /* 4us acquisition time per sample */ + .first_conversion_delay = 3, /* wait 512us before do a first conversion */ + .acquisition_time = 1, /* 4us acquisition time per sample */ .median = 2, /* do 8 measurements */ - .averaging = 1, /* take the average of 4 middle samples */ - .pen_down_acc_interval = 255, /* 9.4 ms */ + .averaging = 1, /* take the average of 4 middle samples */ + .pen_down_acc_interval = 255, /* 9.4 ms */ .gpio_export = 1, /* Export GPIO to gpiolib */ .gpio_base = -1, /* Dynamic allocation */ }; @@ -790,6 +790,11 @@ static const struct adxl34x_platform_data adxl34x_info = { /* .ev_code_act_inactivity = KEY_A,*/ /* EV_KEY */ .power_mode = ADXL_AUTO_SLEEP | ADXL_LINK, .fifo_mode = ADXL_FIFO_STREAM, + .orientation_enable = ADXL_EN_ORIENTATION_3D, + .deadzone_angle = ADXL_DEADZONE_ANGLE_10p8, + .divisor_length = ADXL_LP_FILTER_DIVISOR_16, + /* EV_KEY {+Z, +Y, +X, -X, -Y, -Z} */ + .ev_codes_orient_3d = {BTN_Z, BTN_Y, BTN_X, BTN_A, BTN_B, BTN_C}, }; #endif -- cgit v0.10.2 From 2943bff69e3728cfd69841537120125f9373bb28 Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Thu, 25 Feb 2010 18:16:52 +0000 Subject: Blackfin: fix anomaly 283 handling with exact hardware error The exact hardware error handling code was added before the workaround for anomaly 283 which caused the anomaly to be triggered in some cases (an infinite core stall). So re-order the code to avoid this. Reported-by: Andrew Rook Signed-off-by: Robin Getz Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S index 6c20044..a5847f5 100644 --- a/arch/blackfin/mach-common/entry.S +++ b/arch/blackfin/mach-common/entry.S @@ -482,6 +482,8 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/ [--sp] = ASTAT; [--sp] = (R7:6,P5:4); + ANOMALY_283_315_WORKAROUND(p5, r7) + #ifdef CONFIG_EXACT_HWERR /* Make sure all pending read/writes complete. This will ensure any * accesses which could cause hardware errors completes, and signal @@ -492,8 +494,6 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/ ssync; #endif - ANOMALY_283_315_WORKAROUND(p5, r7) - #ifdef CONFIG_DEBUG_DOUBLEFAULT /* * Save these registers, as they are only valid in exception context -- cgit v0.10.2 From f2b0cd61cf635cbdc110472f6edc97328322cb8b Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 4 Mar 2010 07:35:30 -0500 Subject: Blackfin: eat spurious space in asm/dpmc.h Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/include/asm/dpmc.h b/arch/blackfin/include/asm/dpmc.h index 1597ae5..efcc3ae 100644 --- a/arch/blackfin/include/asm/dpmc.h +++ b/arch/blackfin/include/asm/dpmc.h @@ -75,7 +75,7 @@ #define VLEV 0x00F0 /* Internal Voltage Level */ #ifdef __ADSPBF52x__ -#define VLEV_085 0x0040 /* VLEV = 0.85 V (-5% - +10% Accuracy) */ +#define VLEV_085 0x0040 /* VLEV = 0.85 V (-5% - +10% Accuracy) */ #define VLEV_090 0x0050 /* VLEV = 0.90 V (-5% - +10% Accuracy) */ #define VLEV_095 0x0060 /* VLEV = 0.95 V (-5% - +10% Accuracy) */ #define VLEV_100 0x0070 /* VLEV = 1.00 V (-5% - +10% Accuracy) */ @@ -84,7 +84,7 @@ #define VLEV_115 0x00A0 /* VLEV = 1.15 V (-5% - +10% Accuracy) */ #define VLEV_120 0x00B0 /* VLEV = 1.20 V (-5% - +10% Accuracy) */ #else -#define VLEV_085 0x0060 /* VLEV = 0.85 V (-5% - +10% Accuracy) */ +#define VLEV_085 0x0060 /* VLEV = 0.85 V (-5% - +10% Accuracy) */ #define VLEV_090 0x0070 /* VLEV = 0.90 V (-5% - +10% Accuracy) */ #define VLEV_095 0x0080 /* VLEV = 0.95 V (-5% - +10% Accuracy) */ #define VLEV_100 0x0090 /* VLEV = 1.00 V (-5% - +10% Accuracy) */ -- cgit v0.10.2 From 7998a8787a8b35fede689c2bb716f65b231e7492 Mon Sep 17 00:00:00 2001 From: Graf Yang Date: Mon, 8 Mar 2010 03:01:35 +0000 Subject: Blackfin: scale calibration when cpu freq changes Need to make sure we update the loops_per_jiffy values when we start changing the core clock. Signed-off-by: Graf Yang Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/mach-common/cpufreq.c b/arch/blackfin/mach-common/cpufreq.c index 5d7f8ab..4391d03 100644 --- a/arch/blackfin/mach-common/cpufreq.c +++ b/arch/blackfin/mach-common/cpufreq.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -99,13 +100,15 @@ static unsigned int bfin_getfreq_khz(unsigned int cpu) return get_cclk() / 1000; } - static int bfin_target(struct cpufreq_policy *poli, unsigned int target_freq, unsigned int relation) { unsigned int index, plldiv, cpu; unsigned long flags, cclk_hz; struct cpufreq_freqs freqs; + static unsigned long lpj_ref; + static unsigned int lpj_ref_freq; + #if defined(CONFIG_CYCLES_CLOCKSOURCE) cycles_t cycles; #endif @@ -144,6 +147,14 @@ static int bfin_target(struct cpufreq_policy *poli, (cycles << __bfin_cycles_mod) - (cycles << index); __bfin_cycles_mod = index; #endif + if (!lpj_ref_freq) { + lpj_ref = loops_per_jiffy; + lpj_ref_freq = freqs.old; + } + if (freqs.new != freqs.old) { + loops_per_jiffy = cpufreq_scale(lpj_ref, + lpj_ref_freq, freqs.new); + } local_irq_restore_hw(flags); } /* TODO: just test case for cycles clock source, remove later */ -- cgit v0.10.2 From cfb581bcd4f8c158c6f2b48bf5e232bb9e6855c0 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 8 Mar 2010 15:20:50 +0100 Subject: MAINTAINERS: Add Arnaldo as tools/perf/ co-maintainer Acked-by: Peter Zijlstra Acked-by: Paul Mackerras Acked-by: Arnaldo Carvalho de Melo LKML-Reference: Signed-off-by: Ingo Molnar diff --git a/MAINTAINERS b/MAINTAINERS index 2533fc4..40ed22e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4221,6 +4221,7 @@ PERFORMANCE EVENTS SUBSYSTEM M: Peter Zijlstra M: Paul Mackerras M: Ingo Molnar +M: Arnaldo Carvalho de Melo S: Supported F: kernel/perf_event.c F: include/linux/perf_event.h -- cgit v0.10.2 From ec62e1c8dd2f9b2a833b48d4a2f58f0c5e07384c Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 8 Mar 2010 22:37:09 -0800 Subject: Input: i8042 - use platfrom_create_bundle() helper Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index b54aee7..fce8ab7 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c @@ -1386,6 +1386,8 @@ static int __init i8042_probe(struct platform_device *dev) { int error; + i8042_platform_device = dev; + error = i8042_controller_selftest(); if (error) return error; @@ -1421,6 +1423,7 @@ static int __init i8042_probe(struct platform_device *dev) i8042_free_aux_ports(); /* in case KBD failed but AUX not */ i8042_free_irqs(); i8042_controller_reset(); + i8042_platform_device = NULL; return error; } @@ -1430,6 +1433,7 @@ static int __devexit i8042_remove(struct platform_device *dev) i8042_unregister_ports(); i8042_free_irqs(); i8042_controller_reset(); + i8042_platform_device = NULL; return 0; } @@ -1448,6 +1452,7 @@ static struct platform_driver i8042_driver = { static int __init i8042_init(void) { + struct platform_device *pdev; int err; dbg_init(); @@ -1460,31 +1465,18 @@ static int __init i8042_init(void) if (err) goto err_platform_exit; - i8042_platform_device = platform_device_alloc("i8042", -1); - if (!i8042_platform_device) { - err = -ENOMEM; + pdev = platform_create_bundle(&i8042_driver, i8042_probe, NULL, 0, NULL, 0); + if (IS_ERR(pdev)) { + err = PTR_ERR(pdev); goto err_platform_exit; } - err = platform_device_add(i8042_platform_device); - if (err) - goto err_free_device; - - err = platform_driver_probe(&i8042_driver, i8042_probe); - if (err) - goto err_del_device; - panic_blink = i8042_panic_blink; return 0; - err_del_device: - platform_device_del(i8042_platform_device); - err_free_device: - platform_device_put(i8042_platform_device); err_platform_exit: i8042_platform_exit(); - return err; } -- cgit v0.10.2 From 58b939959d228681208ba997595411fddc860849 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 8 Mar 2010 22:37:10 -0800 Subject: Input: scancode in get/set_keycodes should be unsigned MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The HID layer has some scan codes of the form 0xffbc0000 for logitech devices which do not work if scancode is typed as signed int, so we need to switch to unsigned it instead. While at it keycode being signed does not make much sense either. Acked-by: Márton Németh Acked-by: Matthew Garrett Acked-by: Jiri Kosina Signed-off-by: Dmitry Torokhov diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 79d9edd..7a0d2e4 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -68,22 +68,25 @@ static const struct { #define map_key_clear(c) hid_map_usage_clear(hidinput, usage, &bit, \ &max, EV_KEY, (c)) -static inline int match_scancode(int code, int scancode) +static inline int match_scancode(unsigned int code, unsigned int scancode) { if (scancode == 0) return 1; - return ((code & (HID_USAGE_PAGE | HID_USAGE)) == scancode); + + return (code & (HID_USAGE_PAGE | HID_USAGE)) == scancode; } -static inline int match_keycode(int code, int keycode) +static inline int match_keycode(unsigned int code, unsigned int keycode) { if (keycode == 0) return 1; - return (code == keycode); + + return code == keycode; } static struct hid_usage *hidinput_find_key(struct hid_device *hid, - int scancode, int keycode) + unsigned int scancode, + unsigned int keycode) { int i, j, k; struct hid_report *report; @@ -105,8 +108,8 @@ static struct hid_usage *hidinput_find_key(struct hid_device *hid, return NULL; } -static int hidinput_getkeycode(struct input_dev *dev, int scancode, - int *keycode) +static int hidinput_getkeycode(struct input_dev *dev, + unsigned int scancode, unsigned int *keycode) { struct hid_device *hid = input_get_drvdata(dev); struct hid_usage *usage; @@ -119,16 +122,13 @@ static int hidinput_getkeycode(struct input_dev *dev, int scancode, return -EINVAL; } -static int hidinput_setkeycode(struct input_dev *dev, int scancode, - int keycode) +static int hidinput_setkeycode(struct input_dev *dev, + unsigned int scancode, unsigned int keycode) { struct hid_device *hid = input_get_drvdata(dev); struct hid_usage *usage; int old_keycode; - if (keycode < 0 || keycode > KEY_MAX) - return -EINVAL; - usage = hidinput_find_key(hid, scancode, 0); if (usage) { old_keycode = usage->code; diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 9f9816b..2ee6c7a 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -515,7 +515,7 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, struct input_absinfo abs; struct ff_effect effect; int __user *ip = (int __user *)p; - int i, t, u, v; + unsigned int i, t, u, v; int error; switch (cmd) { diff --git a/drivers/input/input.c b/drivers/input/input.c index 41168d5..e2dd885 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -582,7 +582,8 @@ static int input_fetch_keycode(struct input_dev *dev, int scancode) } static int input_default_getkeycode(struct input_dev *dev, - int scancode, int *keycode) + unsigned int scancode, + unsigned int *keycode) { if (!dev->keycodesize) return -EINVAL; @@ -596,7 +597,8 @@ static int input_default_getkeycode(struct input_dev *dev, } static int input_default_setkeycode(struct input_dev *dev, - int scancode, int keycode) + unsigned int scancode, + unsigned int keycode) { int old_keycode; int i; @@ -654,11 +656,9 @@ static int input_default_setkeycode(struct input_dev *dev, * This function should be called by anyone interested in retrieving current * keymap. Presently keyboard and evdev handlers use it. */ -int input_get_keycode(struct input_dev *dev, int scancode, int *keycode) +int input_get_keycode(struct input_dev *dev, + unsigned int scancode, unsigned int *keycode) { - if (scancode < 0) - return -EINVAL; - return dev->getkeycode(dev, scancode, keycode); } EXPORT_SYMBOL(input_get_keycode); @@ -672,16 +672,14 @@ EXPORT_SYMBOL(input_get_keycode); * This function should be called by anyone needing to update current * keymap. Presently keyboard and evdev handlers use it. */ -int input_set_keycode(struct input_dev *dev, int scancode, int keycode) +int input_set_keycode(struct input_dev *dev, + unsigned int scancode, unsigned int keycode) { unsigned long flags; int old_keycode; int retval; - if (scancode < 0) - return -EINVAL; - - if (keycode < 0 || keycode > KEY_MAX) + if (keycode > KEY_MAX) return -EINVAL; spin_lock_irqsave(&dev->event_lock, flags); diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c index 0501f0e..15be543 100644 --- a/drivers/input/misc/ati_remote2.c +++ b/drivers/input/misc/ati_remote2.c @@ -474,10 +474,11 @@ static void ati_remote2_complete_key(struct urb *urb) } static int ati_remote2_getkeycode(struct input_dev *idev, - int scancode, int *keycode) + unsigned int scancode, unsigned int *keycode) { struct ati_remote2 *ar2 = input_get_drvdata(idev); - int index, mode; + unsigned int mode; + int index; mode = scancode >> 8; if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask)) @@ -491,10 +492,12 @@ static int ati_remote2_getkeycode(struct input_dev *idev, return 0; } -static int ati_remote2_setkeycode(struct input_dev *idev, int scancode, int keycode) +static int ati_remote2_setkeycode(struct input_dev *idev, + unsigned int scancode, unsigned int keycode) { struct ati_remote2 *ar2 = input_get_drvdata(idev); - int index, mode, old_keycode; + unsigned int mode, old_keycode; + int index; mode = scancode >> 8; if (mode > ATI_REMOTE2_PC || !((1 << mode) & ar2->mode_mask)) @@ -504,9 +507,6 @@ static int ati_remote2_setkeycode(struct input_dev *idev, int scancode, int keyc if (index < 0) return -EINVAL; - if (keycode < KEY_RESERVED || keycode > KEY_MAX) - return -EINVAL; - old_keycode = ar2->keycode[mode][index]; ar2->keycode[mode][index] = keycode; __set_bit(keycode, idev->keybit); diff --git a/drivers/input/misc/winbond-cir.c b/drivers/input/misc/winbond-cir.c index cbec3df..9c155a4 100644 --- a/drivers/input/misc/winbond-cir.c +++ b/drivers/input/misc/winbond-cir.c @@ -385,26 +385,24 @@ wbcir_do_getkeycode(struct wbcir_data *data, u32 scancode) } static int -wbcir_getkeycode(struct input_dev *dev, int scancode, int *keycode) +wbcir_getkeycode(struct input_dev *dev, + unsigned int scancode, unsigned int *keycode) { struct wbcir_data *data = input_get_drvdata(dev); - *keycode = (int)wbcir_do_getkeycode(data, (u32)scancode); + *keycode = wbcir_do_getkeycode(data, scancode); return 0; } static int -wbcir_setkeycode(struct input_dev *dev, int sscancode, int keycode) +wbcir_setkeycode(struct input_dev *dev, + unsigned int scancode, unsigned int keycode) { struct wbcir_data *data = input_get_drvdata(dev); struct wbcir_keyentry *keyentry; struct wbcir_keyentry *new_keyentry; unsigned long flags; unsigned int old_keycode = KEY_RESERVED; - u32 scancode = (u32)sscancode; - - if (keycode < 0 || keycode > KEY_MAX) - return -EINVAL; new_keyentry = kmalloc(sizeof(*new_keyentry), GFP_KERNEL); if (!new_keyentry) diff --git a/drivers/input/sparse-keymap.c b/drivers/input/sparse-keymap.c index fbd3987..e6bde55 100644 --- a/drivers/input/sparse-keymap.c +++ b/drivers/input/sparse-keymap.c @@ -64,7 +64,8 @@ struct key_entry *sparse_keymap_entry_from_keycode(struct input_dev *dev, EXPORT_SYMBOL(sparse_keymap_entry_from_keycode); static int sparse_keymap_getkeycode(struct input_dev *dev, - int scancode, int *keycode) + unsigned int scancode, + unsigned int *keycode) { const struct key_entry *key = sparse_keymap_entry_from_scancode(dev, scancode); @@ -78,7 +79,8 @@ static int sparse_keymap_getkeycode(struct input_dev *dev, } static int sparse_keymap_setkeycode(struct input_dev *dev, - int scancode, int keycode) + unsigned int scancode, + unsigned int keycode) { struct key_entry *key; int old_keycode; diff --git a/drivers/media/IR/ir-keytable.c b/drivers/media/IR/ir-keytable.c index 0903f53..0a3b4ed 100644 --- a/drivers/media/IR/ir-keytable.c +++ b/drivers/media/IR/ir-keytable.c @@ -123,7 +123,7 @@ static int ir_copy_table(struct ir_scancode_table *destin, * If the key is not found, returns -EINVAL, otherwise, returns 0. */ static int ir_getkeycode(struct input_dev *dev, - int scancode, int *keycode) + unsigned int scancode, unsigned int *keycode) { int elem; struct ir_input_dev *ir_dev = input_get_drvdata(dev); @@ -291,7 +291,7 @@ static int ir_insert_key(struct ir_scancode_table *rc_tab, * If the key is not found, returns -EINVAL, otherwise, returns 0. */ static int ir_setkeycode(struct input_dev *dev, - int scancode, int keycode) + unsigned int scancode, unsigned int keycode) { int rc = 0; struct ir_input_dev *ir_dev = input_get_drvdata(dev); diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c index a03ef7e..852fe89 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c @@ -9,7 +9,7 @@ #include static int dvb_usb_getkeycode(struct input_dev *dev, - int scancode, int *keycode) + unsigned int scancode, unsigned int *keycode) { struct dvb_usb_device *d = input_get_drvdata(dev); @@ -39,7 +39,7 @@ static int dvb_usb_getkeycode(struct input_dev *dev, } static int dvb_usb_setkeycode(struct input_dev *dev, - int scancode, int keycode) + unsigned int scancode, unsigned int keycode) { struct dvb_usb_device *d = input_get_drvdata(dev); diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c index 1b1dddb..bed764e 100644 --- a/drivers/platform/x86/dell-wmi.c +++ b/drivers/platform/x86/dell-wmi.c @@ -142,7 +142,7 @@ static struct key_entry *dell_wmi_keymap = dell_legacy_wmi_keymap; static struct input_dev *dell_wmi_input_dev; -static struct key_entry *dell_wmi_get_entry_by_scancode(int code) +static struct key_entry *dell_wmi_get_entry_by_scancode(unsigned int code) { struct key_entry *key; @@ -153,7 +153,7 @@ static struct key_entry *dell_wmi_get_entry_by_scancode(int code) return NULL; } -static struct key_entry *dell_wmi_get_entry_by_keycode(int keycode) +static struct key_entry *dell_wmi_get_entry_by_keycode(unsigned int keycode) { struct key_entry *key; @@ -164,8 +164,8 @@ static struct key_entry *dell_wmi_get_entry_by_keycode(int keycode) return NULL; } -static int dell_wmi_getkeycode(struct input_dev *dev, int scancode, - int *keycode) +static int dell_wmi_getkeycode(struct input_dev *dev, + unsigned int scancode, unsigned int *keycode) { struct key_entry *key = dell_wmi_get_entry_by_scancode(scancode); @@ -177,13 +177,11 @@ static int dell_wmi_getkeycode(struct input_dev *dev, int scancode, return -EINVAL; } -static int dell_wmi_setkeycode(struct input_dev *dev, int scancode, int keycode) +static int dell_wmi_setkeycode(struct input_dev *dev, + unsigned int scancode, unsigned int keycode) { struct key_entry *key; - int old_keycode; - - if (keycode < 0 || keycode > KEY_MAX) - return -EINVAL; + unsigned int old_keycode; key = dell_wmi_get_entry_by_scancode(scancode); if (key && key->type == KE_KEY) { diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index 7ccf33c..5608636 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c @@ -278,7 +278,7 @@ static DEVICE_ATTR(als, S_IRUGO | S_IWUSR, show_als, set_als); static DEVICE_ATTR(dock, S_IRUGO, show_dock, NULL); static DEVICE_ATTR(tablet, S_IRUGO, show_tablet, NULL); -static struct key_entry *hp_wmi_get_entry_by_scancode(int code) +static struct key_entry *hp_wmi_get_entry_by_scancode(unsigned int code) { struct key_entry *key; @@ -289,7 +289,7 @@ static struct key_entry *hp_wmi_get_entry_by_scancode(int code) return NULL; } -static struct key_entry *hp_wmi_get_entry_by_keycode(int keycode) +static struct key_entry *hp_wmi_get_entry_by_keycode(unsigned int keycode) { struct key_entry *key; @@ -300,7 +300,8 @@ static struct key_entry *hp_wmi_get_entry_by_keycode(int keycode) return NULL; } -static int hp_wmi_getkeycode(struct input_dev *dev, int scancode, int *keycode) +static int hp_wmi_getkeycode(struct input_dev *dev, + unsigned int scancode, unsigned int *keycode) { struct key_entry *key = hp_wmi_get_entry_by_scancode(scancode); @@ -312,13 +313,11 @@ static int hp_wmi_getkeycode(struct input_dev *dev, int scancode, int *keycode) return -EINVAL; } -static int hp_wmi_setkeycode(struct input_dev *dev, int scancode, int keycode) +static int hp_wmi_setkeycode(struct input_dev *dev, + unsigned int scancode, unsigned int keycode) { struct key_entry *key; - int old_keycode; - - if (keycode < 0 || keycode > KEY_MAX) - return -EINVAL; + unsigned int old_keycode; key = hp_wmi_get_entry_by_scancode(scancode); if (key && key->type == KE_KEY) { diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c index fe7cf01..c9fc479 100644 --- a/drivers/platform/x86/panasonic-laptop.c +++ b/drivers/platform/x86/panasonic-laptop.c @@ -200,7 +200,7 @@ static struct acpi_driver acpi_pcc_driver = { }; #define KEYMAP_SIZE 11 -static const int initial_keymap[KEYMAP_SIZE] = { +static const unsigned int initial_keymap[KEYMAP_SIZE] = { /* 0 */ KEY_RESERVED, /* 1 */ KEY_BRIGHTNESSDOWN, /* 2 */ KEY_BRIGHTNESSUP, @@ -222,7 +222,7 @@ struct pcc_acpi { struct acpi_device *device; struct input_dev *input_dev; struct backlight_device *backlight; - int keymap[KEYMAP_SIZE]; + unsigned int keymap[KEYMAP_SIZE]; }; struct pcc_keyinput { @@ -445,7 +445,8 @@ static struct attribute_group pcc_attr_group = { /* hotkey input device driver */ -static int pcc_getkeycode(struct input_dev *dev, int scancode, int *keycode) +static int pcc_getkeycode(struct input_dev *dev, + unsigned int scancode, unsigned int *keycode) { struct pcc_acpi *pcc = input_get_drvdata(dev); @@ -457,7 +458,7 @@ static int pcc_getkeycode(struct input_dev *dev, int scancode, int *keycode) return 0; } -static int keymap_get_by_keycode(struct pcc_acpi *pcc, int keycode) +static int keymap_get_by_keycode(struct pcc_acpi *pcc, unsigned int keycode) { int i; @@ -469,7 +470,8 @@ static int keymap_get_by_keycode(struct pcc_acpi *pcc, int keycode) return 0; } -static int pcc_setkeycode(struct input_dev *dev, int scancode, int keycode) +static int pcc_setkeycode(struct input_dev *dev, + unsigned int scancode, unsigned int keycode) { struct pcc_acpi *pcc = input_get_drvdata(dev); int oldkeycode; @@ -477,9 +479,6 @@ static int pcc_setkeycode(struct input_dev *dev, int scancode, int keycode) if (scancode >= ARRAY_SIZE(pcc->keymap)) return -EINVAL; - if (keycode < 0 || keycode > KEY_MAX) - return -EINVAL; - oldkeycode = pcc->keymap[scancode]; pcc->keymap[scancode] = keycode; diff --git a/drivers/platform/x86/topstar-laptop.c b/drivers/platform/x86/topstar-laptop.c index 02f3d4e..4d6516f 100644 --- a/drivers/platform/x86/topstar-laptop.c +++ b/drivers/platform/x86/topstar-laptop.c @@ -46,7 +46,7 @@ static struct tps_key_entry topstar_keymap[] = { { } }; -static struct tps_key_entry *tps_get_key_by_scancode(int code) +static struct tps_key_entry *tps_get_key_by_scancode(unsigned int code) { struct tps_key_entry *key; @@ -57,7 +57,7 @@ static struct tps_key_entry *tps_get_key_by_scancode(int code) return NULL; } -static struct tps_key_entry *tps_get_key_by_keycode(int code) +static struct tps_key_entry *tps_get_key_by_keycode(unsigned int code) { struct tps_key_entry *key; @@ -126,7 +126,8 @@ static int acpi_topstar_fncx_switch(struct acpi_device *device, bool state) return 0; } -static int topstar_getkeycode(struct input_dev *dev, int scancode, int *keycode) +static int topstar_getkeycode(struct input_dev *dev, + unsigned int scancode, unsigned int *keycode) { struct tps_key_entry *key = tps_get_key_by_scancode(scancode); @@ -137,14 +138,12 @@ static int topstar_getkeycode(struct input_dev *dev, int scancode, int *keycode) return 0; } -static int topstar_setkeycode(struct input_dev *dev, int scancode, int keycode) +static int topstar_setkeycode(struct input_dev *dev, + unsigned int scancode, unsigned int keycode) { struct tps_key_entry *key; int old_keycode; - if (keycode < 0 || keycode > KEY_MAX) - return -EINVAL; - key = tps_get_key_by_scancode(scancode); if (!key) diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index 405b969..789240d 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -745,7 +745,7 @@ static struct backlight_ops toshiba_backlight_data = { .update_status = set_lcd_status, }; -static struct key_entry *toshiba_acpi_get_entry_by_scancode(int code) +static struct key_entry *toshiba_acpi_get_entry_by_scancode(unsigned int code) { struct key_entry *key; @@ -756,7 +756,7 @@ static struct key_entry *toshiba_acpi_get_entry_by_scancode(int code) return NULL; } -static struct key_entry *toshiba_acpi_get_entry_by_keycode(int code) +static struct key_entry *toshiba_acpi_get_entry_by_keycode(unsigned int code) { struct key_entry *key; @@ -767,8 +767,8 @@ static struct key_entry *toshiba_acpi_get_entry_by_keycode(int code) return NULL; } -static int toshiba_acpi_getkeycode(struct input_dev *dev, int scancode, - int *keycode) +static int toshiba_acpi_getkeycode(struct input_dev *dev, + unsigned int scancode, unsigned int *keycode) { struct key_entry *key = toshiba_acpi_get_entry_by_scancode(scancode); @@ -780,14 +780,11 @@ static int toshiba_acpi_getkeycode(struct input_dev *dev, int scancode, return -EINVAL; } -static int toshiba_acpi_setkeycode(struct input_dev *dev, int scancode, - int keycode) +static int toshiba_acpi_setkeycode(struct input_dev *dev, + unsigned int scancode, unsigned int keycode) { struct key_entry *key; - int old_keycode; - - if (keycode < 0 || keycode > KEY_MAX) - return -EINVAL; + unsigned int old_keycode; key = toshiba_acpi_get_entry_by_scancode(scancode); if (key && key->type == KE_KEY) { diff --git a/include/linux/input.h b/include/linux/input.h index dc24eff..7ed2251 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -58,10 +58,10 @@ struct input_absinfo { #define EVIOCGVERSION _IOR('E', 0x01, int) /* get driver version */ #define EVIOCGID _IOR('E', 0x02, struct input_id) /* get device ID */ -#define EVIOCGREP _IOR('E', 0x03, int[2]) /* get repeat settings */ -#define EVIOCSREP _IOW('E', 0x03, int[2]) /* set repeat settings */ -#define EVIOCGKEYCODE _IOR('E', 0x04, int[2]) /* get keycode */ -#define EVIOCSKEYCODE _IOW('E', 0x04, int[2]) /* set keycode */ +#define EVIOCGREP _IOR('E', 0x03, unsigned int[2]) /* get repeat settings */ +#define EVIOCSREP _IOW('E', 0x03, unsigned int[2]) /* set repeat settings */ +#define EVIOCGKEYCODE _IOR('E', 0x04, unsigned int[2]) /* get keycode */ +#define EVIOCSKEYCODE _IOW('E', 0x04, unsigned int[2]) /* set keycode */ #define EVIOCGNAME(len) _IOC(_IOC_READ, 'E', 0x06, len) /* get device name */ #define EVIOCGPHYS(len) _IOC(_IOC_READ, 'E', 0x07, len) /* get physical location */ @@ -1142,8 +1142,10 @@ struct input_dev { unsigned int keycodemax; unsigned int keycodesize; void *keycode; - int (*setkeycode)(struct input_dev *dev, int scancode, int keycode); - int (*getkeycode)(struct input_dev *dev, int scancode, int *keycode); + int (*setkeycode)(struct input_dev *dev, + unsigned int scancode, unsigned int keycode); + int (*getkeycode)(struct input_dev *dev, + unsigned int scancode, unsigned int *keycode); struct ff_device *ff; @@ -1415,8 +1417,10 @@ static inline void input_set_abs_params(struct input_dev *dev, int axis, int min dev->absbit[BIT_WORD(axis)] |= BIT_MASK(axis); } -int input_get_keycode(struct input_dev *dev, int scancode, int *keycode); -int input_set_keycode(struct input_dev *dev, int scancode, int keycode); +int input_get_keycode(struct input_dev *dev, + unsigned int scancode, unsigned int *keycode); +int input_set_keycode(struct input_dev *dev, + unsigned int scancode, unsigned int keycode); extern struct class input_class; -- cgit v0.10.2 From 881245dcff29df992d8431392a41fb81549129f9 Mon Sep 17 00:00:00 2001 From: William Cohen Date: Tue, 9 Mar 2010 09:26:04 +0100 Subject: Add DocBook documentation for the block tracepoints. This patch adds a simple description of the various block tracepoints available in the kernel. Signed-off-by: William Cohen Acked-by: Randy Dunlap Signed-off-by: Jens Axboe diff --git a/Documentation/DocBook/tracepoint.tmpl b/Documentation/DocBook/tracepoint.tmpl index 8bca1d5..e8473ea 100644 --- a/Documentation/DocBook/tracepoint.tmpl +++ b/Documentation/DocBook/tracepoint.tmpl @@ -16,6 +16,15 @@ + + William + Cohen + +
+ wcohen@redhat.com +
+
+
@@ -91,4 +100,8 @@ !Iinclude/trace/events/signal.h + + Block IO +!Iinclude/trace/events/block.h + diff --git a/include/trace/events/block.h b/include/trace/events/block.h index 5fb7273..d870a91 100644 --- a/include/trace/events/block.h +++ b/include/trace/events/block.h @@ -40,6 +40,16 @@ DECLARE_EVENT_CLASS(block_rq_with_error, __entry->nr_sector, __entry->errors) ); +/** + * block_rq_abort - abort block operation request + * @q: queue containing the block operation request + * @rq: block IO operation request + * + * Called immediately after pending block IO operation request @rq in + * queue @q is aborted. The fields in the operation request @rq + * can be examined to determine which device and sectors the pending + * operation would access. + */ DEFINE_EVENT(block_rq_with_error, block_rq_abort, TP_PROTO(struct request_queue *q, struct request *rq), @@ -47,6 +57,15 @@ DEFINE_EVENT(block_rq_with_error, block_rq_abort, TP_ARGS(q, rq) ); +/** + * block_rq_requeue - place block IO request back on a queue + * @q: queue holding operation + * @rq: block IO operation request + * + * The block operation request @rq is being placed back into queue + * @q. For some reason the request was not completed and needs to be + * put back in the queue. + */ DEFINE_EVENT(block_rq_with_error, block_rq_requeue, TP_PROTO(struct request_queue *q, struct request *rq), @@ -54,6 +73,17 @@ DEFINE_EVENT(block_rq_with_error, block_rq_requeue, TP_ARGS(q, rq) ); +/** + * block_rq_complete - block IO operation completed by device driver + * @q: queue containing the block operation request + * @rq: block operations request + * + * The block_rq_complete tracepoint event indicates that some portion + * of operation request has been completed by the device driver. If + * the @rq->bio is %NULL, then there is absolutely no additional work to + * do for the request. If @rq->bio is non-NULL then there is + * additional work required to complete the request. + */ DEFINE_EVENT(block_rq_with_error, block_rq_complete, TP_PROTO(struct request_queue *q, struct request *rq), @@ -95,6 +125,16 @@ DECLARE_EVENT_CLASS(block_rq, __entry->nr_sector, __entry->comm) ); +/** + * block_rq_insert - insert block operation request into queue + * @q: target queue + * @rq: block IO operation request + * + * Called immediately before block operation request @rq is inserted + * into queue @q. The fields in the operation request @rq struct can + * be examined to determine which device and sectors the pending + * operation would access. + */ DEFINE_EVENT(block_rq, block_rq_insert, TP_PROTO(struct request_queue *q, struct request *rq), @@ -102,6 +142,14 @@ DEFINE_EVENT(block_rq, block_rq_insert, TP_ARGS(q, rq) ); +/** + * block_rq_issue - issue pending block IO request operation to device driver + * @q: queue holding operation + * @rq: block IO operation operation request + * + * Called when block operation request @rq from queue @q is sent to a + * device driver for processing. + */ DEFINE_EVENT(block_rq, block_rq_issue, TP_PROTO(struct request_queue *q, struct request *rq), @@ -109,6 +157,17 @@ DEFINE_EVENT(block_rq, block_rq_issue, TP_ARGS(q, rq) ); +/** + * block_bio_bounce - used bounce buffer when processing block operation + * @q: queue holding the block operation + * @bio: block operation + * + * A bounce buffer was used to handle the block operation @bio in @q. + * This occurs when hardware limitations prevent a direct transfer of + * data between the @bio data memory area and the IO device. Use of a + * bounce buffer requires extra copying of data and decreases + * performance. + */ TRACE_EVENT(block_bio_bounce, TP_PROTO(struct request_queue *q, struct bio *bio), @@ -138,6 +197,14 @@ TRACE_EVENT(block_bio_bounce, __entry->nr_sector, __entry->comm) ); +/** + * block_bio_complete - completed all work on the block operation + * @q: queue holding the block operation + * @bio: block operation completed + * + * This tracepoint indicates there is no further work to do on this + * block IO operation @bio. + */ TRACE_EVENT(block_bio_complete, TP_PROTO(struct request_queue *q, struct bio *bio), @@ -193,6 +260,14 @@ DECLARE_EVENT_CLASS(block_bio, __entry->nr_sector, __entry->comm) ); +/** + * block_bio_backmerge - merging block operation to the end of an existing operation + * @q: queue holding operation + * @bio: new block operation to merge + * + * Merging block request @bio to the end of an existing block request + * in queue @q. + */ DEFINE_EVENT(block_bio, block_bio_backmerge, TP_PROTO(struct request_queue *q, struct bio *bio), @@ -200,6 +275,14 @@ DEFINE_EVENT(block_bio, block_bio_backmerge, TP_ARGS(q, bio) ); +/** + * block_bio_frontmerge - merging block operation to the beginning of an existing operation + * @q: queue holding operation + * @bio: new block operation to merge + * + * Merging block IO operation @bio to the beginning of an existing block + * operation in queue @q. + */ DEFINE_EVENT(block_bio, block_bio_frontmerge, TP_PROTO(struct request_queue *q, struct bio *bio), @@ -207,6 +290,13 @@ DEFINE_EVENT(block_bio, block_bio_frontmerge, TP_ARGS(q, bio) ); +/** + * block_bio_queue - putting new block IO operation in queue + * @q: queue holding operation + * @bio: new block operation + * + * About to place the block IO operation @bio into queue @q. + */ DEFINE_EVENT(block_bio, block_bio_queue, TP_PROTO(struct request_queue *q, struct bio *bio), @@ -243,6 +333,15 @@ DECLARE_EVENT_CLASS(block_get_rq, __entry->nr_sector, __entry->comm) ); +/** + * block_getrq - get a free request entry in queue for block IO operations + * @q: queue for operations + * @bio: pending block IO operation + * @rw: low bit indicates a read (%0) or a write (%1) + * + * A request struct for queue @q has been allocated to handle the + * block IO operation @bio. + */ DEFINE_EVENT(block_get_rq, block_getrq, TP_PROTO(struct request_queue *q, struct bio *bio, int rw), @@ -250,6 +349,17 @@ DEFINE_EVENT(block_get_rq, block_getrq, TP_ARGS(q, bio, rw) ); +/** + * block_sleeprq - waiting to get a free request entry in queue for block IO operation + * @q: queue for operation + * @bio: pending block IO operation + * @rw: low bit indicates a read (%0) or a write (%1) + * + * In the case where a request struct cannot be provided for queue @q + * the process needs to wait for an request struct to become + * available. This tracepoint event is generated each time the + * process goes to sleep waiting for request struct become available. + */ DEFINE_EVENT(block_get_rq, block_sleeprq, TP_PROTO(struct request_queue *q, struct bio *bio, int rw), @@ -257,6 +367,14 @@ DEFINE_EVENT(block_get_rq, block_sleeprq, TP_ARGS(q, bio, rw) ); +/** + * block_plug - keep operations requests in request queue + * @q: request queue to plug + * + * Plug the request queue @q. Do not allow block operation requests + * to be sent to the device driver. Instead, accumulate requests in + * the queue to improve throughput performance of the block device. + */ TRACE_EVENT(block_plug, TP_PROTO(struct request_queue *q), @@ -293,6 +411,13 @@ DECLARE_EVENT_CLASS(block_unplug, TP_printk("[%s] %d", __entry->comm, __entry->nr_rq) ); +/** + * block_unplug_timer - timed release of operations requests in queue to device driver + * @q: request queue to unplug + * + * Unplug the request queue @q because a timer expired and allow block + * operation requests to be sent to the device driver. + */ DEFINE_EVENT(block_unplug, block_unplug_timer, TP_PROTO(struct request_queue *q), @@ -300,6 +425,13 @@ DEFINE_EVENT(block_unplug, block_unplug_timer, TP_ARGS(q) ); +/** + * block_unplug_io - release of operations requests in request queue + * @q: request queue to unplug + * + * Unplug request queue @q because device driver is scheduled to work + * on elements in the request queue. + */ DEFINE_EVENT(block_unplug, block_unplug_io, TP_PROTO(struct request_queue *q), @@ -307,6 +439,17 @@ DEFINE_EVENT(block_unplug, block_unplug_io, TP_ARGS(q) ); +/** + * block_split - split a single bio struct into two bio structs + * @q: queue containing the bio + * @bio: block operation being split + * @new_sector: The starting sector for the new bio + * + * The bio request @bio in request queue @q needs to be split into two + * bio requests. The newly created @bio request starts at + * @new_sector. This split may be required due to hardware limitation + * such as operation crossing device boundaries in a RAID system. + */ TRACE_EVENT(block_split, TP_PROTO(struct request_queue *q, struct bio *bio, @@ -337,6 +480,16 @@ TRACE_EVENT(block_split, __entry->comm) ); +/** + * block_remap - map request for a partition to the raw device + * @q: queue holding the operation + * @bio: revised operation + * @dev: device for the operation + * @from: original sector for the operation + * + * An operation for a partition on a block device has been mapped to the + * raw block device. + */ TRACE_EVENT(block_remap, TP_PROTO(struct request_queue *q, struct bio *bio, dev_t dev, @@ -370,6 +523,17 @@ TRACE_EVENT(block_remap, (unsigned long long)__entry->old_sector) ); +/** + * block_rq_remap - map request for a block operation request + * @q: queue holding the operation + * @rq: block IO operation request + * @dev: device for the operation + * @from: original sector for the operation + * + * The block operation request @rq in @q has been remapped. The block + * operation request @rq holds the current information and @from hold + * the original sector. + */ TRACE_EVENT(block_rq_remap, TP_PROTO(struct request_queue *q, struct request *rq, dev_t dev, -- cgit v0.10.2 From 3e6e15a862a0bc20128497bbdc54254cdec21835 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 8 Mar 2010 23:42:46 -0800 Subject: Input: enable remote wakeup for PNP i8042 keyboard ports This patch (as1355) enables remote wakeup by default on PNP i8042 keyboard ports. Signed-off-by: Alan Stern Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 2a5982e..3696cab 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -624,6 +624,9 @@ static int i8042_pnp_kbd_probe(struct pnp_dev *dev, const struct pnp_device_id * strlcat(i8042_pnp_kbd_name, pnp_dev_name(dev), sizeof(i8042_pnp_kbd_name)); } + /* Keyboard ports are always supposed to be wakeup-enabled */ + device_set_wakeup_enable(&dev->dev, true); + i8042_pnp_kbd_devices++; return 0; } -- cgit v0.10.2 From 3dd1b39497b6820219581af16e6a8831a582bb3a Mon Sep 17 00:00:00 2001 From: Jari Vanhala Date: Tue, 9 Mar 2010 00:29:46 -0800 Subject: Input: add driver for TWL4030 vibrator device TWL4030 Vibrator implemented via Force Feedback interface. This uses MFD TWL4030 codec and own dynamic workqueue. Signed-off-by: Jari Vanhala Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 7097bfe..23140a3 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -214,6 +214,17 @@ config INPUT_TWL4030_PWRBUTTON To compile this driver as a module, choose M here. The module will be called twl4030_pwrbutton. +config INPUT_TWL4030_VIBRA + tristate "Support for TWL4030 Vibrator" + depends on TWL4030_CORE + select TWL4030_CODEC + select INPUT_FF_MEMLESS + help + This option enables support for TWL4030 Vibrator Driver. + + To compile this driver as a module, choose M here. The module will + be called twl4030_vibra. + config INPUT_UINPUT tristate "User level driver support" help diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index b611615..7e95a5d 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile @@ -26,6 +26,7 @@ obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER) += rotary_encoder.o obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON) += twl4030-pwrbutton.o +obj-$(CONFIG_INPUT_TWL4030_VIBRA) += twl4030-vibra.o obj-$(CONFIG_INPUT_UINPUT) += uinput.o obj-$(CONFIG_INPUT_WINBOND_CIR) += winbond-cir.o obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o diff --git a/drivers/input/misc/twl4030-vibra.c b/drivers/input/misc/twl4030-vibra.c new file mode 100644 index 0000000..2fb79e0 --- /dev/null +++ b/drivers/input/misc/twl4030-vibra.c @@ -0,0 +1,297 @@ +/* + * twl4030-vibra.c - TWL4030 Vibrator driver + * + * Copyright (C) 2008-2010 Nokia Corporation + * + * Written by Henrik Saari + * Updates by Felipe Balbi + * Input by Jari Vanhala + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include + +/* MODULE ID2 */ +#define LEDEN 0x00 + +/* ForceFeedback */ +#define EFFECT_DIR_180_DEG 0x8000 /* range is 0 - 0xFFFF */ + +struct vibra_info { + struct device *dev; + struct input_dev *input_dev; + + struct workqueue_struct *workqueue; + struct work_struct play_work; + + bool enabled; + int speed; + int direction; + + bool coexist; +}; + +static void vibra_disable_leds(void) +{ + u8 reg; + + /* Disable LEDA & LEDB, cannot be used with vibra (PWM) */ + twl_i2c_read_u8(TWL4030_MODULE_LED, ®, LEDEN); + reg &= ~0x03; + twl_i2c_write_u8(TWL4030_MODULE_LED, LEDEN, reg); +} + +/* Powers H-Bridge and enables audio clk */ +static void vibra_enable(struct vibra_info *info) +{ + u8 reg; + + twl4030_codec_enable_resource(TWL4030_CODEC_RES_POWER); + + /* turn H-Bridge on */ + twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, + ®, TWL4030_REG_VIBRA_CTL); + twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, + (reg | TWL4030_VIBRA_EN), TWL4030_REG_VIBRA_CTL); + + twl4030_codec_enable_resource(TWL4030_CODEC_RES_APLL); + + info->enabled = true; +} + +static void vibra_disable(struct vibra_info *info) +{ + u8 reg; + + /* Power down H-Bridge */ + twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, + ®, TWL4030_REG_VIBRA_CTL); + twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, + (reg & ~TWL4030_VIBRA_EN), TWL4030_REG_VIBRA_CTL); + + twl4030_codec_disable_resource(TWL4030_CODEC_RES_POWER); + twl4030_codec_disable_resource(TWL4030_CODEC_RES_APLL); + + info->enabled = false; +} + +static void vibra_play_work(struct work_struct *work) +{ + struct vibra_info *info = container_of(work, + struct vibra_info, play_work); + int dir; + int pwm; + u8 reg; + + dir = info->direction; + pwm = info->speed; + + twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, + ®, TWL4030_REG_VIBRA_CTL); + if (pwm && (!info->coexist || !(reg & TWL4030_VIBRA_SEL))) { + + if (!info->enabled) + vibra_enable(info); + + /* set vibra rotation direction */ + twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, + ®, TWL4030_REG_VIBRA_CTL); + reg = (dir) ? (reg | TWL4030_VIBRA_DIR) : + (reg & ~TWL4030_VIBRA_DIR); + twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, + reg, TWL4030_REG_VIBRA_CTL); + + /* set PWM, 1 = max, 255 = min */ + twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, + 256 - pwm, TWL4030_REG_VIBRA_SET); + } else { + if (info->enabled) + vibra_disable(info); + } +} + +/*** Input/ForceFeedback ***/ + +static int vibra_play(struct input_dev *input, void *data, + struct ff_effect *effect) +{ + struct vibra_info *info = input_get_drvdata(input); + + info->speed = effect->u.rumble.strong_magnitude >> 8; + if (!info->speed) + info->speed = effect->u.rumble.weak_magnitude >> 9; + info->direction = effect->direction < EFFECT_DIR_180_DEG ? 0 : 1; + queue_work(info->workqueue, &info->play_work); + return 0; +} + +static int twl4030_vibra_open(struct input_dev *input) +{ + struct vibra_info *info = input_get_drvdata(input); + + info->workqueue = create_singlethread_workqueue("vibra"); + if (info->workqueue == NULL) { + dev_err(&input->dev, "couldn't create workqueue\n"); + return -ENOMEM; + } + return 0; +} + +static void twl4030_vibra_close(struct input_dev *input) +{ + struct vibra_info *info = input_get_drvdata(input); + + cancel_work_sync(&info->play_work); + INIT_WORK(&info->play_work, vibra_play_work); /* cleanup */ + destroy_workqueue(info->workqueue); + info->workqueue = NULL; + + if (info->enabled) + vibra_disable(info); +} + +/*** Module ***/ +#if CONFIG_PM +static int twl4030_vibra_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct vibra_info *info = platform_get_drvdata(pdev); + + if (info->enabled) + vibra_disable(info); + + return 0; +} + +static int twl4030_vibra_resume(struct device *dev) +{ + vibra_disable_leds(); + return 0; +} + +static SIMPLE_DEV_PM_OPS(twl4030_vibra_pm_ops, + twl4030_vibra_suspend, twl4030_vibra_resume); +#endif + +static int __devinit twl4030_vibra_probe(struct platform_device *pdev) +{ + struct twl4030_codec_vibra_data *pdata = pdev->dev.platform_data; + struct vibra_info *info; + int ret; + + if (!pdata) { + dev_dbg(&pdev->dev, "platform_data not available\n"); + return -EINVAL; + } + + info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + info->dev = &pdev->dev; + info->coexist = pdata->coexist; + INIT_WORK(&info->play_work, vibra_play_work); + + info->input_dev = input_allocate_device(); + if (info->input_dev == NULL) { + dev_err(&pdev->dev, "couldn't allocate input device\n"); + ret = -ENOMEM; + goto err_kzalloc; + } + + input_set_drvdata(info->input_dev, info); + + info->input_dev->name = "twl4030:vibrator"; + info->input_dev->id.version = 1; + info->input_dev->dev.parent = pdev->dev.parent; + info->input_dev->open = twl4030_vibra_open; + info->input_dev->close = twl4030_vibra_close; + __set_bit(FF_RUMBLE, info->input_dev->ffbit); + + ret = input_ff_create_memless(info->input_dev, NULL, vibra_play); + if (ret < 0) { + dev_dbg(&pdev->dev, "couldn't register vibrator to FF\n"); + goto err_ialloc; + } + + ret = input_register_device(info->input_dev); + if (ret < 0) { + dev_dbg(&pdev->dev, "couldn't register input device\n"); + goto err_iff; + } + + vibra_disable_leds(); + + platform_set_drvdata(pdev, info); + return 0; + +err_iff: + input_ff_destroy(info->input_dev); +err_ialloc: + input_free_device(info->input_dev); +err_kzalloc: + kfree(info); + return ret; +} + +static int __devexit twl4030_vibra_remove(struct platform_device *pdev) +{ + struct vibra_info *info = platform_get_drvdata(pdev); + + /* this also free ff-memless and calls close if needed */ + input_unregister_device(info->input_dev); + kfree(info); + platform_set_drvdata(pdev, NULL); + + return 0; +} + +static struct platform_driver twl4030_vibra_driver = { + .probe = twl4030_vibra_probe, + .remove = __devexit_p(twl4030_vibra_remove), + .driver = { + .name = "twl4030_codec_vibra", + .owner = THIS_MODULE, +#ifdef CONFIG_PM + .pm = &twl4030_vibra_pm_ops, +#endif + }, +}; + +static int __init twl4030_vibra_init(void) +{ + return platform_driver_register(&twl4030_vibra_driver); +} +module_init(twl4030_vibra_init); + +static void __exit twl4030_vibra_exit(void) +{ + platform_driver_unregister(&twl4030_vibra_driver); +} +module_exit(twl4030_vibra_exit); + +MODULE_ALIAS("platform:twl4030_codec_vibra"); + +MODULE_DESCRIPTION("TWL4030 Vibra driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Nokia Corporation"); -- cgit v0.10.2 From e9edb1d8a345119c9baafa1b240eb1ec06a44662 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 3 Mar 2010 08:53:51 -0500 Subject: GFS2: do not select QUOTA gfs2 only needs the quotactl code, not the generic quota implementation. Signed-off-by: Christoph Hellwig Signed-off-by: Steven Whitehouse diff --git a/fs/gfs2/Kconfig b/fs/gfs2/Kconfig index 4dcddf8..a47b431 100644 --- a/fs/gfs2/Kconfig +++ b/fs/gfs2/Kconfig @@ -8,7 +8,6 @@ config GFS2_FS select FS_POSIX_ACL select CRC32 select SLOW_WORK - select QUOTA select QUOTACTL help A cluster filesystem. -- cgit v0.10.2 From 28918c211d86b6eeb70182c523800c7bc442960c Mon Sep 17 00:00:00 2001 From: Michael Poole Date: Tue, 9 Mar 2010 06:47:35 -0500 Subject: HID: magicmouse: fix oops after device removal Ask the HID core not to register an input device for the mouse. Fix an oops after removing the device, due to leaving the new input device registered. Signed-off-by: Michael Poole Signed-off-by: Jiri Kosina diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index 4a3a94f..c174b64 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c @@ -353,7 +353,7 @@ static int magicmouse_probe(struct hid_device *hdev, goto err_free; } - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); + ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_HIDINPUT); if (ret) { dev_err(&hdev->dev, "magicmouse hw start failed\n"); goto err_free; @@ -409,8 +409,11 @@ err_free: static void magicmouse_remove(struct hid_device *hdev) { + struct magicmouse_sc *msc = hid_get_drvdata(hdev); + hid_hw_stop(hdev); - kfree(hid_get_drvdata(hdev)); + input_unregister_device(msc->input); + kfree(msc); } static const struct hid_device_id magic_mice[] = { -- cgit v0.10.2 From eff7f270e9a05688066f40589d7b44e1dcf335dc Mon Sep 17 00:00:00 2001 From: Andrej Gelenberg Date: Tue, 9 Mar 2010 13:49:54 +0100 Subject: HID: add quirk for UC-Logik WP4030 tablet Add HID_QUIRK_MULTI_INPUT for UC-Logik tablet. $ lsusb ... Bus 004 Device 002: ID 5543:0003 UC-Logic Technology Corp. Genius MousePen 4x3 Tablet/Aquila L1 Tablet Signed-off-by: Andrej Gelenberg Signed-off-by: Jiri Kosina diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 72c05f9..797e064 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -445,6 +445,7 @@ #define USB_VENDOR_ID_UCLOGIC 0x5543 #define USB_DEVICE_ID_UCLOGIC_TABLET_PF1209 0x0042 +#define USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U 0x0003 #define USB_VENDOR_ID_VERNIER 0x08f7 #define USB_DEVICE_ID_VERNIER_LABPRO 0x0001 diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 7844280..928943c 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -63,6 +63,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET }, { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET }, { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209, HID_QUIRK_MULTI_INPUT }, + { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS }, { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, -- cgit v0.10.2 From eb63e5d15758d2b1e607ddd5fb861b5596629380 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 9 Mar 2010 08:41:12 -0500 Subject: Blackfin: stop cleaning include/asm/asm-offsets.h The file is no longer generated, so we don't want to clean it. Reported-by: Vivi Li Signed-off-by: Mike Frysinger diff --git a/arch/blackfin/Makefile b/arch/blackfin/Makefile index ba84206..5a97a31 100644 --- a/arch/blackfin/Makefile +++ b/arch/blackfin/Makefile @@ -133,7 +133,6 @@ KBUILD_CFLAGS += -Iarch/$(ARCH)/mach-$(MACHINE)/include KBUILD_CPPFLAGS += $(patsubst %,-I$(srctree)/%include,$(machdirs)) CLEAN_FILES += \ - arch/$(ARCH)/include/asm/asm-offsets.h \ arch/$(ARCH)/kernel/asm-offsets.s \ archclean: -- cgit v0.10.2 From ecd216260f87dd8c14b2580a16f055554644bbea Mon Sep 17 00:00:00 2001 From: Ralf Gerbig Date: Tue, 9 Mar 2010 18:25:47 +0100 Subject: ALSA: hda - Sound MSI fallout on a Asus mobo NVIDIA MCP55 without the following patch audio ssttuutteerrs on ASUS M2N32-SLI PREMIUM ACPI BIOS Revision 1304 the sound device is: 00:0e.1 Audio device: nVidia Corporation MCP55 High Definition Audio (rev a2) worked with 2.6.32 Signed-off-by: Ralf Gerbig Cc: Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index e37bffe..10bbb53 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2358,6 +2358,7 @@ static void __devinit check_probe_mask(struct azx *chip, int dev) static struct snd_pci_quirk msi_black_list[] __devinitdata = { SND_PCI_QUIRK(0x1043, 0x81f2, "ASUS", 0), /* Athlon64 X2 + nvidia */ SND_PCI_QUIRK(0x1043, 0x81f6, "ASUS", 0), /* nvidia */ + SND_PCI_QUIRK(0x1043, 0x822d, "ASUS", 0), /* Athlon64 X2 + nvidia MCP55 */ SND_PCI_QUIRK(0x1849, 0x0888, "ASRock", 0), /* Athlon64 X2 + nvidia */ {} }; -- cgit v0.10.2 From abab095d1fd25986b910d3c46289d8fa3582cdc5 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Fri, 12 Feb 2010 07:44:18 -0500 Subject: cifs: add cifs_revalidate_file ...to allow updating inode attributes on an existing inode by filehandle. Change mmap and llseek codepaths to use that instead of cifs_revalidate_dentry since they have a filehandle readily available. Signed-off-by: Jeff Layton Signed-off-by: Steve French diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index cf85a41..5183bc2 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -639,7 +639,7 @@ static loff_t cifs_llseek(struct file *file, loff_t offset, int origin) setting the revalidate time to zero */ CIFS_I(file->f_path.dentry->d_inode)->time = 0; - retval = cifs_revalidate_dentry(file->f_path.dentry); + retval = cifs_revalidate_file(file); if (retval < 0) return (loff_t)retval; } diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 2af995c..7aa57ec 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h @@ -61,6 +61,7 @@ extern int cifs_mkdir(struct inode *, struct dentry *, int); extern int cifs_rmdir(struct inode *, struct dentry *); extern int cifs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); +extern int cifs_revalidate_file(struct file *filp); extern int cifs_revalidate_dentry(struct dentry *); extern int cifs_getattr(struct vfsmount *, struct dentry *, struct kstat *); extern int cifs_setattr(struct dentry *, struct iattr *); diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index ce9199f..39e47f4 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -104,10 +104,12 @@ extern void cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr); extern struct inode *cifs_iget(struct super_block *sb, struct cifs_fattr *fattr); +extern int cifs_get_file_info(struct file *filp); extern int cifs_get_inode_info(struct inode **pinode, const unsigned char *search_path, FILE_ALL_INFO *pfile_info, struct super_block *sb, int xid, const __u16 *pfid); +extern int cifs_get_file_info_unix(struct file *filp); extern int cifs_get_inode_info_unix(struct inode **pinode, const unsigned char *search_path, struct super_block *sb, int xid); diff --git a/fs/cifs/file.c b/fs/cifs/file.c index b90f8f2..1389f6e 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -1890,11 +1890,10 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, int cifs_file_mmap(struct file *file, struct vm_area_struct *vma) { - struct dentry *dentry = file->f_path.dentry; int rc, xid; xid = GetXid(); - rc = cifs_revalidate_dentry(dentry); + rc = cifs_revalidate_file(file); if (rc) { cFYI(1, ("Validation prior to mmap failed, error=%d", rc)); FreeXid(xid); diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index f050dba..0d034a8 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -268,6 +268,31 @@ cifs_create_dfs_fattr(struct cifs_fattr *fattr, struct super_block *sb) fattr->cf_flags |= CIFS_FATTR_DFS_REFERRAL; } +int cifs_get_file_info_unix(struct file *filp) +{ + int rc; + int xid; + FILE_UNIX_BASIC_INFO find_data; + struct cifs_fattr fattr; + struct inode *inode = filp->f_path.dentry->d_inode; + struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); + struct cifsTconInfo *tcon = cifs_sb->tcon; + struct cifsFileInfo *cfile = (struct cifsFileInfo *) filp->private_data; + + xid = GetXid(); + rc = CIFSSMBUnixQFileInfo(xid, tcon, cfile->netfid, &find_data); + if (!rc) { + cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb); + } else if (rc == -EREMOTE) { + cifs_create_dfs_fattr(&fattr, inode->i_sb); + rc = 0; + } + + cifs_fattr_to_inode(inode, &fattr); + FreeXid(xid); + return rc; +} + int cifs_get_inode_info_unix(struct inode **pinode, const unsigned char *full_path, struct super_block *sb, int xid) @@ -469,6 +494,47 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info, fattr->cf_gid = cifs_sb->mnt_gid; } +int cifs_get_file_info(struct file *filp) +{ + int rc; + int xid; + FILE_ALL_INFO find_data; + struct cifs_fattr fattr; + struct inode *inode = filp->f_path.dentry->d_inode; + struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); + struct cifsTconInfo *tcon = cifs_sb->tcon; + struct cifsFileInfo *cfile = (struct cifsFileInfo *) filp->private_data; + + xid = GetXid(); + rc = CIFSSMBQFileInfo(xid, tcon, cfile->netfid, &find_data); + if (rc == -EOPNOTSUPP || rc == -EINVAL) { + /* + * FIXME: legacy server -- fall back to path-based call? + * for now, just skip revalidating and mark inode for + * immediate reval. + */ + rc = 0; + CIFS_I(inode)->time = 0; + goto cgfi_exit; + } else if (rc == -EREMOTE) { + cifs_create_dfs_fattr(&fattr, inode->i_sb); + rc = 0; + } else if (rc) + goto cgfi_exit; + + /* + * don't bother with SFU junk here -- just mark inode as needing + * revalidation. + */ + cifs_all_info_to_fattr(&fattr, &find_data, cifs_sb, false); + fattr.cf_uniqueid = CIFS_I(inode)->uniqueid; + fattr.cf_flags |= CIFS_FATTR_NEED_REVAL; + cifs_fattr_to_inode(inode, &fattr); +cgfi_exit: + FreeXid(xid); + return rc; +} + int cifs_get_inode_info(struct inode **pinode, const unsigned char *full_path, FILE_ALL_INFO *pfindData, struct super_block *sb, int xid, const __u16 *pfid) @@ -1465,6 +1531,26 @@ cifs_invalidate_mapping(struct inode *inode) invalidate_remote_inode(inode); } +int cifs_revalidate_file(struct file *filp) +{ + int rc = 0; + struct inode *inode = filp->f_path.dentry->d_inode; + + if (!cifs_inode_needs_reval(inode)) + goto check_inval; + + if (CIFS_SB(inode->i_sb)->tcon->unix_ext) + rc = cifs_get_file_info_unix(filp); + else + rc = cifs_get_file_info(filp); + +check_inval: + if (CIFS_I(inode)->invalid_mapping) + cifs_invalidate_mapping(inode); + + return rc; +} + /* revalidate a dentry's inode attributes */ int cifs_revalidate_dentry(struct dentry *dentry) { -- cgit v0.10.2 From ff215713eb33c56301cf6bfec0143ddc7f22c138 Mon Sep 17 00:00:00 2001 From: Steve French Date: Tue, 9 Mar 2010 20:30:42 +0000 Subject: [CIFS] checkpatch cleanup Signed-off-by: Steve French diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 1389f6e..ca2ba7a 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -219,8 +219,8 @@ static inline int cifs_open_inode_helper(struct inode *inode, struct file *file, cFYI(1, ("inode unchanged on server")); } else { if (file->f_path.dentry->d_inode->i_mapping) { - /* BB no need to lock inode until after invalidate - since namei code should already have it locked? */ + /* BB no need to lock inode until after invalidate + since namei code should already have it locked? */ rc = filemap_write_and_wait(file->f_path.dentry->d_inode->i_mapping); if (rc != 0) CIFS_I(file->f_path.dentry->d_inode)->write_behind_rc = rc; diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 0d034a8..723daac 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -510,9 +510,9 @@ int cifs_get_file_info(struct file *filp) if (rc == -EOPNOTSUPP || rc == -EINVAL) { /* * FIXME: legacy server -- fall back to path-based call? - * for now, just skip revalidating and mark inode for - * immediate reval. - */ + * for now, just skip revalidating and mark inode for + * immediate reval. + */ rc = 0; CIFS_I(inode)->time = 0; goto cgfi_exit; -- cgit v0.10.2 From 1d79e53c56afe0826a311c3bc1653ad938166c22 Mon Sep 17 00:00:00 2001 From: Reinette Chatre Date: Fri, 26 Feb 2010 11:01:36 -0800 Subject: iwl3945: fix memory corruption Recent patch "iwlwifi: move 3945 clip groups to 3945 data" exposed a memory corruption problem. When initializing the clip groups the code was mistakenly using the iwlagn rate count, not the 3945 rate count. This resulted in more memory being written than was allocated. "iwlwifi: move 3945 clip groups to 3945 data" moved the location where the clip groups are stored and the impact is now severe in that the number of configured TX queues is modified. Previously the "temperature" field was overwritten, which did not seem to affect the operation. Fix this one instance where wrong rate count was used. I also noticed one more location where the iwlagn rate count was used to index an iwl3945 array, fix this. I also modified one location that modified the iwlagn rate count to obtain the iwl3945 rate count ... just use the iwl3945 rate count directly. This fixes http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=2165 and http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=2168 Signed-off-by: Reinette Chatre diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 303cc81..e0678d9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -184,7 +184,7 @@ static int iwl3945_hwrate_to_plcp_idx(u8 plcp) { int idx; - for (idx = 0; idx < IWL_RATE_COUNT; idx++) + for (idx = 0; idx < IWL_RATE_COUNT_3945; idx++) if (iwl3945_rates[idx].plcp == plcp) return idx; return -1; @@ -805,7 +805,7 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, int sta_id, int tx_id) { u16 hw_value = ieee80211_get_tx_rate(priv->hw, info)->hw_value; - u16 rate_index = min(hw_value & 0xffff, IWL_RATE_COUNT - 1); + u16 rate_index = min(hw_value & 0xffff, IWL_RATE_COUNT_3945); u16 rate_mask; int rate; u8 rts_retry_limit; @@ -2146,7 +2146,7 @@ static void iwl3945_hw_reg_init_channel_groups(struct iwl_priv *priv) /* fill in channel group's nominal powers for each rate */ for (rate_index = 0; - rate_index < IWL_RATE_COUNT; rate_index++, clip_pwrs++) { + rate_index < IWL_RATE_COUNT_3945; rate_index++, clip_pwrs++) { switch (rate_index) { case IWL_RATE_36M_INDEX_TABLE: if (i == 0) /* B/G */ -- cgit v0.10.2 From 1382c71c764540880d35485b033a44ce104d8e2e Mon Sep 17 00:00:00 2001 From: Reinette Chatre Date: Thu, 25 Feb 2010 10:02:19 -0800 Subject: Revert "iwlwifi: Send broadcast probe request only when asked to" This reverts commit 21b2d8bd2f0d4e0f21ade147fd193c8b9c1fd2b9. As explained by Johannes: When we build a probe request frame in the buffer with the SSID, we could arrive over the limit of 200 bytes. When we build it in the buffer without the SSID (wildcard) we don't arrive over 200 bytes, but the ucode still allows direct probe in addition because it has an internal buffer that is larger when it inserts the SSID... Signed-off-by: Reinette Chatre diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 47b0214..818367b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2653,7 +2653,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv) */ hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; - hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX + 1; + hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX; /* we create the 802.11 header and a zero-length SSID element */ hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2; diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index dd9ff2e..bd2f7c4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -638,20 +638,9 @@ u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, if (left < 0) return 0; *pos++ = WLAN_EID_SSID; - if (!priv->is_internal_short_scan && - priv->scan_request->n_ssids) { - struct cfg80211_ssid *ssid = - priv->scan_request->ssids; - - /* Broadcast if ssid_len is 0 */ - *pos++ = ssid->ssid_len; - memcpy(pos, ssid->ssid, ssid->ssid_len); - pos += ssid->ssid_len; - len += 2 + ssid->ssid_len; - } else { - *pos++ = 0; - len += 2; - } + *pos++ = 0; + + len += 2; if (WARN_ON(left < ie_len)) return len; @@ -780,26 +769,20 @@ static void iwl_bg_request_scan(struct work_struct *data) if (priv->is_internal_short_scan) { IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n"); } else if (priv->scan_request->n_ssids) { + int i, p = 0; IWL_DEBUG_SCAN(priv, "Kicking off active scan\n"); - /* - * The first SSID to scan is stuffed into the probe request - * template and the remaining ones are handled through the - * direct_scan array. - */ - if (priv->scan_request->n_ssids > 1) { - int i, p = 0; - for (i = 1; i < priv->scan_request->n_ssids; i++) { - if (!priv->scan_request->ssids[i].ssid_len) - continue; - scan->direct_scan[p].id = WLAN_EID_SSID; - scan->direct_scan[p].len = - priv->scan_request->ssids[i].ssid_len; - memcpy(scan->direct_scan[p].ssid, - priv->scan_request->ssids[i].ssid, - priv->scan_request->ssids[i].ssid_len); - n_probes++; - p++; - } + for (i = 0; i < priv->scan_request->n_ssids; i++) { + /* always does wildcard anyway */ + if (!priv->scan_request->ssids[i].ssid_len) + continue; + scan->direct_scan[p].id = WLAN_EID_SSID; + scan->direct_scan[p].len = + priv->scan_request->ssids[i].ssid_len; + memcpy(scan->direct_scan[p].ssid, + priv->scan_request->ssids[i].ssid, + priv->scan_request->ssids[i].ssid_len); + n_probes++; + p++; } is_active = true; } else -- cgit v0.10.2 From d2197e1e6038bb01568367a220e4a4e040f8337d Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Tue, 9 Mar 2010 14:59:48 -0800 Subject: omap3: Fix compile for Touch Book early_param Commit 2b0d8c251b8876d530a6bf671eb5425838fa698a changed ARM to use the common early_param code. Fix compile for Touch Book accordingly. Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c index 3943d0f..2a5bf5c 100644 --- a/arch/arm/mach-omap2/board-omap3touchbook.c +++ b/arch/arm/mach-omap2/board-omap3touchbook.c @@ -518,14 +518,14 @@ static void omap3_touchbook_poweroff(void) gpio_direction_output(TB_KILL_POWER_GPIO, 0); } -static void __init early_touchbook_revision(char **p) +static int __init early_touchbook_revision(char *p) { - if (!*p) - return; + if (!p) + return 0; - strict_strtoul(*p, 10, &touchbook_revision); + return strict_strtoul(p, 10, &touchbook_revision); } -__early_param("tbr=", early_touchbook_revision); +early_param("tbr", early_touchbook_revision); static struct omap_musb_board_data musb_board_data = { .interface_type = MUSB_INTERFACE_ULPI, -- cgit v0.10.2 From 04e82ffb0f02e645f3dde5128ef39d425a8b3c6d Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Wed, 10 Mar 2010 11:55:05 +0900 Subject: serial: sh-sci: Fix build failure for non-sh architectures. This patch fixes a build failure for various arm based defconfigs [1][2][3] and maybe other architectures/configs. The build failure was introduced by the sh specific patch [4] "serial: sh-sci: Add DMA support" by Guennadi Liakhovetski Patch against linux-next of 20100309 References: [1] http://kisskb.ellerman.id.au/kisskb/buildresult/2248992/ [2] http://kisskb.ellerman.id.au/kisskb/buildresult/2248996/ [3] http://kisskb.ellerman.id.au/kisskb/buildresult/2248998/ [4] http://git.kernel.org/?p=linux/kernel/git/sfr/linux-next.git;a=commit;h=73a19e4c0301908ce6346715fd08a74308451f5a Signed-off-by: Peter Huewe Signed-off-by: Paul Mundt diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h index 1b177d2..193d4bf 100644 --- a/include/linux/serial_sci.h +++ b/include/linux/serial_sci.h @@ -2,7 +2,9 @@ #define __LINUX_SERIAL_SCI_H #include +#ifdef CONFIG_SERIAL_SH_SCI_DMA #include +#endif /* * Generic header for SuperH SCI(F) (used by sh/sh64/h8300 and related parts) @@ -30,8 +32,10 @@ struct plat_sci_port { upf_t flags; /* UPF_* flags */ char *clk; /* clock string */ struct device *dma_dev; +#ifdef CONFIG_SERIAL_SH_SCI_DMA enum sh_dmae_slave_chan_id dma_slave_tx; enum sh_dmae_slave_chan_id dma_slave_rx; +#endif }; #endif /* __LINUX_SERIAL_SCI_H */ -- cgit v0.10.2 From c90c6a885ac9827921e8f94f3ce4360ae11148f1 Mon Sep 17 00:00:00 2001 From: Thadeu Lima de Souza Cascardo Date: Tue, 9 Mar 2010 20:38:47 -0800 Subject: Input: mousedev - remove BKL There's no need for BKL in mousedev, relevan protection is provided by a private mutex. Signed-off-by: Thadeu Lima de Souza Cascardo Acked-by: Arnd Bergmann Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index a13d80f..f34b22b 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c @@ -15,7 +15,6 @@ #include #include -#include #include #include #include @@ -542,10 +541,8 @@ static int mousedev_open(struct inode *inode, struct file *file) if (i >= MOUSEDEV_MINORS) return -ENODEV; - lock_kernel(); error = mutex_lock_interruptible(&mousedev_table_mutex); if (error) { - unlock_kernel(); return error; } mousedev = mousedev_table[i]; @@ -554,7 +551,6 @@ static int mousedev_open(struct inode *inode, struct file *file) mutex_unlock(&mousedev_table_mutex); if (!mousedev) { - unlock_kernel(); return -ENODEV; } @@ -575,7 +571,6 @@ static int mousedev_open(struct inode *inode, struct file *file) goto err_free_client; file->private_data = client; - unlock_kernel(); return 0; err_free_client: @@ -583,7 +578,6 @@ static int mousedev_open(struct inode *inode, struct file *file) kfree(client); err_put_mousedev: put_device(&mousedev->dev); - unlock_kernel(); return error; } -- cgit v0.10.2 From 77554b4d1fac6a66d4e624a6e36c020a4f5b6b64 Mon Sep 17 00:00:00 2001 From: Thadeu Lima de Souza Cascardo Date: Tue, 9 Mar 2010 20:38:47 -0800 Subject: Input: serio_raw - remove BKL serio_raw open function already uses a mutex. Also change formatting a bit. Signed-off-by: Thadeu Lima de Souza Cascardo Acked-by: Arnd Bergmann Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c index 27fdaaf..9986648 100644 --- a/drivers/input/serio/serio_raw.c +++ b/drivers/input/serio/serio_raw.c @@ -81,12 +81,12 @@ static int serio_raw_open(struct inode *inode, struct file *file) struct serio_raw_list *list; int retval = 0; - lock_kernel(); retval = mutex_lock_interruptible(&serio_raw_mutex); if (retval) - goto out_bkl; + return retval; - if (!(serio_raw = serio_raw_locate(iminor(inode)))) { + serio_raw = serio_raw_locate(iminor(inode)); + if (!serio_raw) { retval = -ENODEV; goto out; } @@ -96,7 +96,8 @@ static int serio_raw_open(struct inode *inode, struct file *file) goto out; } - if (!(list = kzalloc(sizeof(struct serio_raw_list), GFP_KERNEL))) { + list = kzalloc(sizeof(struct serio_raw_list), GFP_KERNEL); + if (!list) { retval = -ENOMEM; goto out; } @@ -109,8 +110,6 @@ static int serio_raw_open(struct inode *inode, struct file *file) out: mutex_unlock(&serio_raw_mutex); -out_bkl: - unlock_kernel(); return retval; } -- cgit v0.10.2 From 2f2177c8dadbcb08c14f796ac983c5475eca1bd3 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 9 Mar 2010 20:38:48 -0800 Subject: Input: remove BKL, fix input_open_file() locking Holding the BKL in input_open_file seems pointless because it does not protect against updates of input_table, and all open functions from the underlying drivers have proper mutex locking. This makes input_open_file take the input_mutex when accessing the table and no lock when calling into the lower function. Signed-off-by: Arnd Bergmann Acked-by: Thadeu Lima de Souza Cascardo Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/input.c b/drivers/input/input.c index e2dd885..e2aad0a 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -1879,35 +1879,37 @@ static int input_open_file(struct inode *inode, struct file *file) const struct file_operations *old_fops, *new_fops = NULL; int err; - lock_kernel(); + err = mutex_lock_interruptible(&input_mutex); + if (err) + return err; + /* No load-on-demand here? */ handler = input_table[iminor(inode) >> 5]; - if (!handler || !(new_fops = fops_get(handler->fops))) { - err = -ENODEV; - goto out; - } + if (handler) + new_fops = fops_get(handler->fops); + + mutex_unlock(&input_mutex); /* * That's _really_ odd. Usually NULL ->open means "nothing special", * not "no device". Oh, well... */ - if (!new_fops->open) { + if (!new_fops || !new_fops->open) { fops_put(new_fops); err = -ENODEV; goto out; } + old_fops = file->f_op; file->f_op = new_fops; err = new_fops->open(inode, file); - if (err) { fops_put(file->f_op); file->f_op = fops_get(old_fops); } fops_put(old_fops); out: - unlock_kernel(); return err; } -- cgit v0.10.2 From eb8bff85c5bd5caef7c374ff32b86545029efb56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20B=C3=A4chler?= Date: Tue, 9 Mar 2010 20:38:48 -0800 Subject: Input: alps - add support for the touchpad on Toshiba Tecra A11-11L MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Bächler Cc: stable@kernel.org Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index f93c2c0..f6dad83 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -63,6 +63,8 @@ static const struct alps_model_info alps_model_data[] = { { { 0x62, 0x02, 0x14 }, 0xcf, 0xcf, ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, { { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FOUR_BUTTONS }, /* Dell Vostro 1400 */ + { { 0x52, 0x01, 0x14 }, 0xff, 0xff, + ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, /* Toshiba Tecra A11-11L */ }; /* -- cgit v0.10.2 From 37000d275721e25af6b49fbb2dbcd04022091276 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Ko=C5=9Bcielnicki?= Date: Thu, 25 Feb 2010 18:53:37 +0000 Subject: drm/nv50: Remove redundant/incorrect ctxvals initialisation. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 11c/004 offset corresponds to PGRAPH reg 0x400828, and is initialised earlier anyway by both our ctxprog generator and blob ctxvals. It's actually incorrect with the generator, since we use different layout on pre-NVA0. Signed-off-by: Marcin Kościelnicki Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c index 857a096..08d87b7 100644 --- a/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/drivers/gpu/drm/nouveau/nv50_graph.c @@ -229,10 +229,6 @@ nv50_graph_create_context(struct nouveau_channel *chan) nouveau_grctx_vals_load(dev, ctx); } nv_wo32(dev, ctx, 0x00000/4, chan->ramin->instance >> 12); - if ((dev_priv->chipset & 0xf0) == 0xa0) - nv_wo32(dev, ctx, 0x00004/4, 0x00000000); - else - nv_wo32(dev, ctx, 0x0011c/4, 0x00000000); dev_priv->engine.instmem.finish_access(dev); return 0; -- cgit v0.10.2 From c82b88d578847909797945824851a6a9a84f9c20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Ko=C5=9Bcielnicki?= Date: Sat, 27 Feb 2010 18:13:35 +0000 Subject: drm/nouveau: Fix fbcon corruption with font width not divisible by 8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NV50 is nice and has a switch that autoaligns stuff for us. Pre-NV50, we need to align input bitmap width manually. Signed-off-by: Marcin Kościelnicki Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nv04_fbcon.c b/drivers/gpu/drm/nouveau/nv04_fbcon.c index 3da90c2..813b25c 100644 --- a/drivers/gpu/drm/nouveau/nv04_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv04_fbcon.c @@ -118,8 +118,8 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) return; } - width = ALIGN(image->width, 32); - dsize = (width * image->height) >> 5; + width = ALIGN(image->width, 8); + dsize = ALIGN(width * image->height, 32) >> 5; if (info->fix.visual == FB_VISUAL_TRUECOLOR || info->fix.visual == FB_VISUAL_DIRECTCOLOR) { @@ -136,8 +136,8 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) ((image->dx + image->width) & 0xffff)); OUT_RING(chan, bg); OUT_RING(chan, fg); - OUT_RING(chan, (image->height << 16) | image->width); OUT_RING(chan, (image->height << 16) | width); + OUT_RING(chan, (image->height << 16) | image->width); OUT_RING(chan, (image->dy << 16) | (image->dx & 0xffff)); while (dsize) { diff --git a/drivers/gpu/drm/nouveau/nv50_fbcon.c b/drivers/gpu/drm/nouveau/nv50_fbcon.c index 993c712..25a3cd8 100644 --- a/drivers/gpu/drm/nouveau/nv50_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv50_fbcon.c @@ -233,7 +233,7 @@ nv50_fbcon_accel_init(struct fb_info *info) BEGIN_RING(chan, NvSub2D, 0x0808, 3); OUT_RING(chan, 0); OUT_RING(chan, 0); - OUT_RING(chan, 0); + OUT_RING(chan, 1); BEGIN_RING(chan, NvSub2D, 0x081c, 1); OUT_RING(chan, 1); BEGIN_RING(chan, NvSub2D, 0x0840, 4); -- cgit v0.10.2 From 3bf777bf0ab112527cea103c3681934a9f41c03d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Ko=C5=9Bcielnicki?= Date: Sun, 28 Feb 2010 23:45:38 +0000 Subject: drm/nv50: Make ctxprog wait until interrupt handler is done. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will fix races between generated ctxprogs and interrupt handler. Signed-off-by: Marcin Kościelnicki Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nv50_grctx.c b/drivers/gpu/drm/nouveau/nv50_grctx.c index d105fcd..9f909ab 100644 --- a/drivers/gpu/drm/nouveau/nv50_grctx.c +++ b/drivers/gpu/drm/nouveau/nv50_grctx.c @@ -64,6 +64,9 @@ #define CP_FLAG_ALWAYS ((2 * 32) + 13) #define CP_FLAG_ALWAYS_FALSE 0 #define CP_FLAG_ALWAYS_TRUE 1 +#define CP_FLAG_INTR ((2 * 32) + 15) +#define CP_FLAG_INTR_NOT_PENDING 0 +#define CP_FLAG_INTR_PENDING 1 #define CP_CTX 0x00100000 #define CP_CTX_COUNT 0x000f0000 @@ -214,6 +217,8 @@ nv50_grctx_init(struct nouveau_grctx *ctx) cp_name(ctx, cp_setup_save); cp_set (ctx, UNK1D, SET); cp_wait(ctx, STATUS, BUSY); + cp_wait(ctx, INTR, PENDING); + cp_bra (ctx, STATUS, BUSY, cp_setup_save); cp_set (ctx, UNK01, SET); cp_set (ctx, SWAP_DIRECTION, SAVE); -- cgit v0.10.2 From 304424e17dd904cef048ef8966d9f54618a915cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Ko=C5=9Bcielnicki?= Date: Mon, 1 Mar 2010 00:18:39 +0000 Subject: drm/nv50: Improve PGRAPH interrupt handling. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes nouveau recognise and report more kinds of PGRAPH errors, as well as prevent GPU lockups resulting from some of them. Lots of guesswork was involved and some part of this is probably incorrect. Some potential-lockuop situations are handled by just resetting a whole PGRAPH subunit, which doesn't sound like a "proper" solution, but seems to work just fine... for now. Signed-off-by: Marcin Kościelnicki Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile index 32db806..7f0d807 100644 --- a/drivers/gpu/drm/nouveau/Makefile +++ b/drivers/gpu/drm/nouveau/Makefile @@ -12,7 +12,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \ nouveau_dp.o nouveau_grctx.o \ nv04_timer.o \ nv04_mc.o nv40_mc.o nv50_mc.o \ - nv04_fb.o nv10_fb.o nv40_fb.o \ + nv04_fb.o nv10_fb.o nv40_fb.o nv50_fb.o \ nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o \ nv04_graph.o nv10_graph.o nv20_graph.o \ nv40_graph.o nv50_graph.o \ diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 2f8ce42..ad2d75d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -930,6 +930,10 @@ extern void nv40_fb_takedown(struct drm_device *); extern void nv40_fb_set_region_tiling(struct drm_device *, int, uint32_t, uint32_t, uint32_t); +/* nv50_fb.c */ +extern int nv50_fb_init(struct drm_device *); +extern void nv50_fb_takedown(struct drm_device *); + /* nv04_fifo.c */ extern int nv04_fifo_init(struct drm_device *); extern void nv04_fifo_disable(struct drm_device *); diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c index 95220dd..2bd59a9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_irq.c +++ b/drivers/gpu/drm/nouveau/nouveau_irq.c @@ -311,6 +311,31 @@ nouveau_print_bitfield_names_(uint32_t value, #define nouveau_print_bitfield_names(val, namelist) \ nouveau_print_bitfield_names_((val), (namelist), ARRAY_SIZE(namelist)) +struct nouveau_enum_names { + uint32_t value; + const char *name; +}; + +static void +nouveau_print_enum_names_(uint32_t value, + const struct nouveau_enum_names *namelist, + const int namelist_len) +{ + /* + * Caller must have already printed the KERN_* log level for us. + * Also the caller is responsible for adding the newline. + */ + int i; + for (i = 0; i < namelist_len; ++i) { + if (value == namelist[i].value) { + printk("%s", namelist[i].name); + return; + } + } + printk("unknown value 0x%08x", value); +} +#define nouveau_print_enum_names(val, namelist) \ + nouveau_print_enum_names_((val), (namelist), ARRAY_SIZE(namelist)) static int nouveau_graph_chid_from_grctx(struct drm_device *dev) @@ -427,14 +452,16 @@ nouveau_graph_dump_trap_info(struct drm_device *dev, const char *id, struct drm_nouveau_private *dev_priv = dev->dev_private; uint32_t nsource = trap->nsource, nstatus = trap->nstatus; - NV_INFO(dev, "%s - nSource:", id); - nouveau_print_bitfield_names(nsource, nsource_names); - printk(", nStatus:"); - if (dev_priv->card_type < NV_10) - nouveau_print_bitfield_names(nstatus, nstatus_names); - else - nouveau_print_bitfield_names(nstatus, nstatus_names_nv10); - printk("\n"); + if (dev_priv->card_type < NV_50) { + NV_INFO(dev, "%s - nSource:", id); + nouveau_print_bitfield_names(nsource, nsource_names); + printk(", nStatus:"); + if (dev_priv->card_type < NV_10) + nouveau_print_bitfield_names(nstatus, nstatus_names); + else + nouveau_print_bitfield_names(nstatus, nstatus_names_nv10); + printk("\n"); + } NV_INFO(dev, "%s - Ch %d/%d Class 0x%04x Mthd 0x%04x " "Data 0x%08x:0x%08x\n", @@ -578,27 +605,502 @@ nouveau_pgraph_irq_handler(struct drm_device *dev) } static void +nv50_pfb_vm_trap(struct drm_device *dev, int display, const char *name) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t trap[6]; + int i, ch; + uint32_t idx = nv_rd32(dev, 0x100c90); + if (idx & 0x80000000) { + idx &= 0xffffff; + if (display) { + for (i = 0; i < 6; i++) { + nv_wr32(dev, 0x100c90, idx | i << 24); + trap[i] = nv_rd32(dev, 0x100c94); + } + for (ch = 0; ch < dev_priv->engine.fifo.channels; ch++) { + struct nouveau_channel *chan = dev_priv->fifos[ch]; + + if (!chan || !chan->ramin) + continue; + + if (trap[1] == chan->ramin->instance >> 12) + break; + } + NV_INFO(dev, "%s - VM: Trapped %s at %02x%04x%04x status %08x %08x channel %d\n", + name, (trap[5]&0x100?"read":"write"), + trap[5]&0xff, trap[4]&0xffff, + trap[3]&0xffff, trap[0], trap[2], ch); + } + nv_wr32(dev, 0x100c90, idx | 0x80000000); + } else if (display) { + NV_INFO(dev, "%s - no VM fault?\n", name); + } +} + +static struct nouveau_enum_names nv50_mp_exec_error_names[] = +{ + { 3, "STACK_UNDERFLOW" }, + { 4, "QUADON_ACTIVE" }, + { 8, "TIMEOUT" }, + { 0x10, "INVALID_OPCODE" }, + { 0x40, "BREAKPOINT" }, +}; + +static void +nv50_pgraph_mp_trap(struct drm_device *dev, int tpid, int display) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t units = nv_rd32(dev, 0x1540); + uint32_t addr, mp10, status, pc, oplow, ophigh; + int i; + int mps = 0; + for (i = 0; i < 4; i++) { + if (!(units & 1 << (i+24))) + continue; + if (dev_priv->chipset < 0xa0) + addr = 0x408200 + (tpid << 12) + (i << 7); + else + addr = 0x408100 + (tpid << 11) + (i << 7); + mp10 = nv_rd32(dev, addr + 0x10); + status = nv_rd32(dev, addr + 0x14); + if (!status) + continue; + if (display) { + nv_rd32(dev, addr + 0x20); + pc = nv_rd32(dev, addr + 0x24); + oplow = nv_rd32(dev, addr + 0x70); + ophigh= nv_rd32(dev, addr + 0x74); + NV_INFO(dev, "PGRAPH_TRAP_MP_EXEC - " + "TP %d MP %d: ", tpid, i); + nouveau_print_enum_names(status, + nv50_mp_exec_error_names); + printk(" at %06x warp %d, opcode %08x %08x\n", + pc&0xffffff, pc >> 24, + oplow, ophigh); + } + nv_wr32(dev, addr + 0x10, mp10); + nv_wr32(dev, addr + 0x14, 0); + mps++; + } + if (!mps && display) + NV_INFO(dev, "PGRAPH_TRAP_MP_EXEC - TP %d: " + "No MPs claiming errors?\n", tpid); +} + +static void +nv50_pgraph_tp_trap(struct drm_device *dev, int type, uint32_t ustatus_old, + uint32_t ustatus_new, int display, const char *name) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + int tps = 0; + uint32_t units = nv_rd32(dev, 0x1540); + int i, r; + uint32_t ustatus_addr, ustatus; + for (i = 0; i < 16; i++) { + if (!(units & (1 << i))) + continue; + if (dev_priv->chipset < 0xa0) + ustatus_addr = ustatus_old + (i << 12); + else + ustatus_addr = ustatus_new + (i << 11); + ustatus = nv_rd32(dev, ustatus_addr) & 0x7fffffff; + if (!ustatus) + continue; + tps++; + switch (type) { + case 6: /* texture error... unknown for now */ + nv50_pfb_vm_trap(dev, display, name); + if (display) { + NV_ERROR(dev, "magic set %d:\n", i); + for (r = ustatus_addr + 4; r <= ustatus_addr + 0x10; r += 4) + NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, + nv_rd32(dev, r)); + } + break; + case 7: /* MP error */ + if (ustatus & 0x00010000) { + nv50_pgraph_mp_trap(dev, i, display); + ustatus &= ~0x00010000; + } + break; + case 8: /* TPDMA error */ + { + uint32_t e0c = nv_rd32(dev, ustatus_addr + 4); + uint32_t e10 = nv_rd32(dev, ustatus_addr + 8); + uint32_t e14 = nv_rd32(dev, ustatus_addr + 0xc); + uint32_t e18 = nv_rd32(dev, ustatus_addr + 0x10); + uint32_t e1c = nv_rd32(dev, ustatus_addr + 0x14); + uint32_t e20 = nv_rd32(dev, ustatus_addr + 0x18); + uint32_t e24 = nv_rd32(dev, ustatus_addr + 0x1c); + nv50_pfb_vm_trap(dev, display, name); + /* 2d engine destination */ + if (ustatus & 0x00000010) { + if (display) { + NV_INFO(dev, "PGRAPH_TRAP_TPDMA_2D - TP %d - Unknown fault at address %02x%08x\n", + i, e14, e10); + NV_INFO(dev, "PGRAPH_TRAP_TPDMA_2D - TP %d - e0c: %08x, e18: %08x, e1c: %08x, e20: %08x, e24: %08x\n", + i, e0c, e18, e1c, e20, e24); + } + ustatus &= ~0x00000010; + } + /* Render target */ + if (ustatus & 0x00000040) { + if (display) { + NV_INFO(dev, "PGRAPH_TRAP_TPDMA_RT - TP %d - Unknown fault at address %02x%08x\n", + i, e14, e10); + NV_INFO(dev, "PGRAPH_TRAP_TPDMA_RT - TP %d - e0c: %08x, e18: %08x, e1c: %08x, e20: %08x, e24: %08x\n", + i, e0c, e18, e1c, e20, e24); + } + ustatus &= ~0x00000040; + } + /* CUDA memory: l[], g[] or stack. */ + if (ustatus & 0x00000080) { + if (display) { + if (e18 & 0x80000000) { + /* g[] read fault? */ + NV_INFO(dev, "PGRAPH_TRAP_TPDMA - TP %d - Global read fault at address %02x%08x\n", + i, e14, e10 | ((e18 >> 24) & 0x1f)); + e18 &= ~0x1f000000; + } else if (e18 & 0xc) { + /* g[] write fault? */ + NV_INFO(dev, "PGRAPH_TRAP_TPDMA - TP %d - Global write fault at address %02x%08x\n", + i, e14, e10 | ((e18 >> 7) & 0x1f)); + e18 &= ~0x00000f80; + } else { + NV_INFO(dev, "PGRAPH_TRAP_TPDMA - TP %d - Unknown CUDA fault at address %02x%08x\n", + i, e14, e10); + } + NV_INFO(dev, "PGRAPH_TRAP_TPDMA - TP %d - e0c: %08x, e18: %08x, e1c: %08x, e20: %08x, e24: %08x\n", + i, e0c, e18, e1c, e20, e24); + } + ustatus &= ~0x00000080; + } + } + break; + } + if (ustatus) { + if (display) + NV_INFO(dev, "%s - TP%d: Unhandled ustatus 0x%08x\n", name, i, ustatus); + } + nv_wr32(dev, ustatus_addr, 0xc0000000); + } + + if (!tps && display) + NV_INFO(dev, "%s - No TPs claiming errors?\n", name); +} + +static void +nv50_pgraph_trap_handler(struct drm_device *dev) +{ + struct nouveau_pgraph_trap trap; + uint32_t status = nv_rd32(dev, 0x400108); + uint32_t ustatus; + int display = nouveau_ratelimit(); + + + if (!status && display) { + nouveau_graph_trap_info(dev, &trap); + nouveau_graph_dump_trap_info(dev, "PGRAPH_TRAP", &trap); + NV_INFO(dev, "PGRAPH_TRAP - no units reporting traps?\n"); + } + + /* DISPATCH: Relays commands to other units and handles NOTIFY, + * COND, QUERY. If you get a trap from it, the command is still stuck + * in DISPATCH and you need to do something about it. */ + if (status & 0x001) { + ustatus = nv_rd32(dev, 0x400804) & 0x7fffffff; + if (!ustatus && display) { + NV_INFO(dev, "PGRAPH_TRAP_DISPATCH - no ustatus?\n"); + } + + /* Known to be triggered by screwed up NOTIFY and COND... */ + if (ustatus & 0x00000001) { + nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_DISPATCH_FAULT"); + nv_wr32(dev, 0x400500, 0); + if (nv_rd32(dev, 0x400808) & 0x80000000) { + if (display) { + if (nouveau_graph_trapped_channel(dev, &trap.channel)) + trap.channel = -1; + trap.class = nv_rd32(dev, 0x400814); + trap.mthd = nv_rd32(dev, 0x400808) & 0x1ffc; + trap.subc = (nv_rd32(dev, 0x400808) >> 16) & 0x7; + trap.data = nv_rd32(dev, 0x40080c); + trap.data2 = nv_rd32(dev, 0x400810); + nouveau_graph_dump_trap_info(dev, + "PGRAPH_TRAP_DISPATCH_FAULT", &trap); + NV_INFO(dev, "PGRAPH_TRAP_DISPATCH_FAULT - 400808: %08x\n", nv_rd32(dev, 0x400808)); + NV_INFO(dev, "PGRAPH_TRAP_DISPATCH_FAULT - 400848: %08x\n", nv_rd32(dev, 0x400848)); + } + nv_wr32(dev, 0x400808, 0); + } else if (display) { + NV_INFO(dev, "PGRAPH_TRAP_DISPATCH_FAULT - No stuck command?\n"); + } + nv_wr32(dev, 0x4008e8, nv_rd32(dev, 0x4008e8) & 3); + nv_wr32(dev, 0x400848, 0); + ustatus &= ~0x00000001; + } + if (ustatus & 0x00000002) { + nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_DISPATCH_QUERY"); + nv_wr32(dev, 0x400500, 0); + if (nv_rd32(dev, 0x40084c) & 0x80000000) { + if (display) { + if (nouveau_graph_trapped_channel(dev, &trap.channel)) + trap.channel = -1; + trap.class = nv_rd32(dev, 0x400814); + trap.mthd = nv_rd32(dev, 0x40084c) & 0x1ffc; + trap.subc = (nv_rd32(dev, 0x40084c) >> 16) & 0x7; + trap.data = nv_rd32(dev, 0x40085c); + trap.data2 = 0; + nouveau_graph_dump_trap_info(dev, + "PGRAPH_TRAP_DISPATCH_QUERY", &trap); + NV_INFO(dev, "PGRAPH_TRAP_DISPATCH_QUERY - 40084c: %08x\n", nv_rd32(dev, 0x40084c)); + } + nv_wr32(dev, 0x40084c, 0); + } else if (display) { + NV_INFO(dev, "PGRAPH_TRAP_DISPATCH_QUERY - No stuck command?\n"); + } + ustatus &= ~0x00000002; + } + if (ustatus && display) + NV_INFO(dev, "PGRAPH_TRAP_DISPATCH - Unhandled ustatus 0x%08x\n", ustatus); + nv_wr32(dev, 0x400804, 0xc0000000); + nv_wr32(dev, 0x400108, 0x001); + status &= ~0x001; + } + + /* TRAPs other than dispatch use the "normal" trap regs. */ + if (status && display) { + nouveau_graph_trap_info(dev, &trap); + nouveau_graph_dump_trap_info(dev, + "PGRAPH_TRAP", &trap); + } + + /* M2MF: Memory to memory copy engine. */ + if (status & 0x002) { + ustatus = nv_rd32(dev, 0x406800) & 0x7fffffff; + if (!ustatus && display) { + NV_INFO(dev, "PGRAPH_TRAP_M2MF - no ustatus?\n"); + } + if (ustatus & 0x00000001) { + nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_M2MF_NOTIFY"); + ustatus &= ~0x00000001; + } + if (ustatus & 0x00000002) { + nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_M2MF_IN"); + ustatus &= ~0x00000002; + } + if (ustatus & 0x00000004) { + nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_M2MF_OUT"); + ustatus &= ~0x00000004; + } + NV_INFO (dev, "PGRAPH_TRAP_M2MF - %08x %08x %08x %08x\n", + nv_rd32(dev, 0x406804), + nv_rd32(dev, 0x406808), + nv_rd32(dev, 0x40680c), + nv_rd32(dev, 0x406810)); + if (ustatus && display) + NV_INFO(dev, "PGRAPH_TRAP_M2MF - Unhandled ustatus 0x%08x\n", ustatus); + /* No sane way found yet -- just reset the bugger. */ + nv_wr32(dev, 0x400040, 2); + nv_wr32(dev, 0x400040, 0); + nv_wr32(dev, 0x406800, 0xc0000000); + nv_wr32(dev, 0x400108, 0x002); + status &= ~0x002; + } + + /* VFETCH: Fetches data from vertex buffers. */ + if (status & 0x004) { + ustatus = nv_rd32(dev, 0x400c04) & 0x7fffffff; + if (!ustatus && display) { + NV_INFO(dev, "PGRAPH_TRAP_VFETCH - no ustatus?\n"); + } + if (ustatus & 0x00000001) { + nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_VFETCH_FAULT"); + NV_INFO (dev, "PGRAPH_TRAP_VFETCH_FAULT - %08x %08x %08x %08x\n", + nv_rd32(dev, 0x400c00), + nv_rd32(dev, 0x400c08), + nv_rd32(dev, 0x400c0c), + nv_rd32(dev, 0x400c10)); + ustatus &= ~0x00000001; + } + if (ustatus && display) + NV_INFO(dev, "PGRAPH_TRAP_VFETCH - Unhandled ustatus 0x%08x\n", ustatus); + nv_wr32(dev, 0x400c04, 0xc0000000); + nv_wr32(dev, 0x400108, 0x004); + status &= ~0x004; + } + + /* STRMOUT: DirectX streamout / OpenGL transform feedback. */ + if (status & 0x008) { + ustatus = nv_rd32(dev, 0x401800) & 0x7fffffff; + if (!ustatus && display) { + NV_INFO(dev, "PGRAPH_TRAP_STRMOUT - no ustatus?\n"); + } + if (ustatus & 0x00000001) { + nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_STRMOUT_FAULT"); + NV_INFO (dev, "PGRAPH_TRAP_STRMOUT_FAULT - %08x %08x %08x %08x\n", + nv_rd32(dev, 0x401804), + nv_rd32(dev, 0x401808), + nv_rd32(dev, 0x40180c), + nv_rd32(dev, 0x401810)); + ustatus &= ~0x00000001; + } + if (ustatus && display) + NV_INFO(dev, "PGRAPH_TRAP_STRMOUT - Unhandled ustatus 0x%08x\n", ustatus); + /* No sane way found yet -- just reset the bugger. */ + nv_wr32(dev, 0x400040, 0x80); + nv_wr32(dev, 0x400040, 0); + nv_wr32(dev, 0x401800, 0xc0000000); + nv_wr32(dev, 0x400108, 0x008); + status &= ~0x008; + } + + /* CCACHE: Handles code and c[] caches and fills them. */ + if (status & 0x010) { + ustatus = nv_rd32(dev, 0x405018) & 0x7fffffff; + if (!ustatus && display) { + NV_INFO(dev, "PGRAPH_TRAP_CCACHE - no ustatus?\n"); + } + if (ustatus & 0x00000001) { + nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_CCACHE_FAULT"); + NV_INFO (dev, "PGRAPH_TRAP_CCACHE_FAULT - %08x %08x %08x %08x %08x %08x %08x\n", + nv_rd32(dev, 0x405800), + nv_rd32(dev, 0x405804), + nv_rd32(dev, 0x405808), + nv_rd32(dev, 0x40580c), + nv_rd32(dev, 0x405810), + nv_rd32(dev, 0x405814), + nv_rd32(dev, 0x40581c)); + ustatus &= ~0x00000001; + } + if (ustatus && display) + NV_INFO(dev, "PGRAPH_TRAP_CCACHE - Unhandled ustatus 0x%08x\n", ustatus); + nv_wr32(dev, 0x405018, 0xc0000000); + nv_wr32(dev, 0x400108, 0x010); + status &= ~0x010; + } + + /* Unknown, not seen yet... 0x402000 is the only trap status reg + * remaining, so try to handle it anyway. Perhaps related to that + * unknown DMA slot on tesla? */ + if (status & 0x20) { + nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_UNKC04"); + ustatus = nv_rd32(dev, 0x402000) & 0x7fffffff; + if (display) + NV_INFO(dev, "PGRAPH_TRAP_UNKC04 - Unhandled ustatus 0x%08x\n", ustatus); + nv_wr32(dev, 0x402000, 0xc0000000); + /* no status modifiction on purpose */ + } + + /* TEXTURE: CUDA texturing units */ + if (status & 0x040) { + nv50_pgraph_tp_trap (dev, 6, 0x408900, 0x408600, display, + "PGRAPH_TRAP_TEXTURE"); + nv_wr32(dev, 0x400108, 0x040); + status &= ~0x040; + } + + /* MP: CUDA execution engines. */ + if (status & 0x080) { + nv50_pgraph_tp_trap (dev, 7, 0x408314, 0x40831c, display, + "PGRAPH_TRAP_MP"); + nv_wr32(dev, 0x400108, 0x080); + status &= ~0x080; + } + + /* TPDMA: Handles TP-initiated uncached memory accesses: + * l[], g[], stack, 2d surfaces, render targets. */ + if (status & 0x100) { + nv50_pgraph_tp_trap (dev, 8, 0x408e08, 0x408708, display, + "PGRAPH_TRAP_TPDMA"); + nv_wr32(dev, 0x400108, 0x100); + status &= ~0x100; + } + + if (status) { + if (display) + NV_INFO(dev, "PGRAPH_TRAP - Unknown trap 0x%08x\n", + status); + nv_wr32(dev, 0x400108, status); + } +} + +/* There must be a *lot* of these. Will take some time to gather them up. */ +static struct nouveau_enum_names nv50_data_error_names[] = +{ + { 4, "INVALID_VALUE" }, + { 5, "INVALID_ENUM" }, + { 8, "INVALID_OBJECT" }, + { 0xc, "INVALID_BITFIELD" }, + { 0x28, "MP_NO_REG_SPACE" }, + { 0x2b, "MP_BLOCK_SIZE_MISMATCH" }, +}; + +static void nv50_pgraph_irq_handler(struct drm_device *dev) { + struct nouveau_pgraph_trap trap; + int unhandled = 0; uint32_t status; while ((status = nv_rd32(dev, NV03_PGRAPH_INTR))) { - uint32_t nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE); - + /* NOTIFY: You've set a NOTIFY an a command and it's done. */ if (status & 0x00000001) { - nouveau_pgraph_intr_notify(dev, nsource); + nouveau_graph_trap_info(dev, &trap); + if (nouveau_ratelimit()) + nouveau_graph_dump_trap_info(dev, + "PGRAPH_NOTIFY", &trap); status &= ~0x00000001; nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000001); } - if (status & 0x00000010) { - nouveau_pgraph_intr_error(dev, nsource | - NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD); + /* COMPUTE_QUERY: Purpose and exact cause unknown, happens + * when you write 0x200 to 0x50c0 method 0x31c. */ + if (status & 0x00000002) { + nouveau_graph_trap_info(dev, &trap); + if (nouveau_ratelimit()) + nouveau_graph_dump_trap_info(dev, + "PGRAPH_COMPUTE_QUERY", &trap); + status &= ~0x00000002; + nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000002); + } + /* Unknown, never seen: 0x4 */ + + /* ILLEGAL_MTHD: You used a wrong method for this class. */ + if (status & 0x00000010) { + nouveau_graph_trap_info(dev, &trap); + if (nouveau_pgraph_intr_swmthd(dev, &trap)) + unhandled = 1; + if (unhandled && nouveau_ratelimit()) + nouveau_graph_dump_trap_info(dev, + "PGRAPH_ILLEGAL_MTHD", &trap); status &= ~0x00000010; nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000010); } + /* ILLEGAL_CLASS: You used a wrong class. */ + if (status & 0x00000020) { + nouveau_graph_trap_info(dev, &trap); + if (nouveau_ratelimit()) + nouveau_graph_dump_trap_info(dev, + "PGRAPH_ILLEGAL_CLASS", &trap); + status &= ~0x00000020; + nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000020); + } + + /* DOUBLE_NOTIFY: You tried to set a NOTIFY on another NOTIFY. */ + if (status & 0x00000040) { + nouveau_graph_trap_info(dev, &trap); + if (nouveau_ratelimit()) + nouveau_graph_dump_trap_info(dev, + "PGRAPH_DOUBLE_NOTIFY", &trap); + status &= ~0x00000040; + nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000040); + } + + /* CONTEXT_SWITCH: PGRAPH needs us to load a new context */ if (status & 0x00001000) { nv_wr32(dev, 0x400500, 0x00000000); nv_wr32(dev, NV03_PGRAPH_INTR, @@ -613,49 +1115,59 @@ nv50_pgraph_irq_handler(struct drm_device *dev) status &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH; } - if (status & 0x00100000) { - nouveau_pgraph_intr_error(dev, nsource | - NV03_PGRAPH_NSOURCE_DATA_ERROR); + /* BUFFER_NOTIFY: Your m2mf transfer finished */ + if (status & 0x00010000) { + nouveau_graph_trap_info(dev, &trap); + if (nouveau_ratelimit()) + nouveau_graph_dump_trap_info(dev, + "PGRAPH_BUFFER_NOTIFY", &trap); + status &= ~0x00010000; + nv_wr32(dev, NV03_PGRAPH_INTR, 0x00010000); + } + /* DATA_ERROR: Invalid value for this method, or invalid + * state in current PGRAPH context for this operation */ + if (status & 0x00100000) { + nouveau_graph_trap_info(dev, &trap); + if (nouveau_ratelimit()) { + nouveau_graph_dump_trap_info(dev, + "PGRAPH_DATA_ERROR", &trap); + NV_INFO (dev, "PGRAPH_DATA_ERROR - "); + nouveau_print_enum_names(nv_rd32(dev, 0x400110), + nv50_data_error_names); + printk("\n"); + } status &= ~0x00100000; nv_wr32(dev, NV03_PGRAPH_INTR, 0x00100000); } + /* TRAP: Something bad happened in the middle of command + * execution. Has a billion types, subtypes, and even + * subsubtypes. */ if (status & 0x00200000) { - int r; - - nouveau_pgraph_intr_error(dev, nsource | - NV03_PGRAPH_NSOURCE_PROTECTION_ERROR); - - NV_ERROR(dev, "magic set 1:\n"); - for (r = 0x408900; r <= 0x408910; r += 4) - NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, - nv_rd32(dev, r)); - nv_wr32(dev, 0x408900, - nv_rd32(dev, 0x408904) | 0xc0000000); - for (r = 0x408e08; r <= 0x408e24; r += 4) - NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, - nv_rd32(dev, r)); - nv_wr32(dev, 0x408e08, - nv_rd32(dev, 0x408e08) | 0xc0000000); - - NV_ERROR(dev, "magic set 2:\n"); - for (r = 0x409900; r <= 0x409910; r += 4) - NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, - nv_rd32(dev, r)); - nv_wr32(dev, 0x409900, - nv_rd32(dev, 0x409904) | 0xc0000000); - for (r = 0x409e08; r <= 0x409e24; r += 4) - NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, - nv_rd32(dev, r)); - nv_wr32(dev, 0x409e08, - nv_rd32(dev, 0x409e08) | 0xc0000000); - + nv50_pgraph_trap_handler(dev); status &= ~0x00200000; - nv_wr32(dev, NV03_PGRAPH_NSOURCE, nsource); nv_wr32(dev, NV03_PGRAPH_INTR, 0x00200000); } + /* Unknown, never seen: 0x00400000 */ + + /* SINGLE_STEP: Happens on every method if you turned on + * single stepping in 40008c */ + if (status & 0x01000000) { + nouveau_graph_trap_info(dev, &trap); + if (nouveau_ratelimit()) + nouveau_graph_dump_trap_info(dev, + "PGRAPH_SINGLE_STEP", &trap); + status &= ~0x01000000; + nv_wr32(dev, NV03_PGRAPH_INTR, 0x01000000); + } + + /* 0x02000000 happens when you pause a ctxprog... + * but the only way this can happen that I know is by + * poking the relevant MMIO register, and we don't + * do that. */ + if (status) { NV_INFO(dev, "Unhandled PGRAPH_INTR - 0x%08x\n", status); @@ -672,7 +1184,8 @@ nv50_pgraph_irq_handler(struct drm_device *dev) } nv_wr32(dev, NV03_PMC_INTR_0, NV_PMC_INTR_0_PGRAPH_PENDING); - nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) & ~(1 << 31)); + if (nv_rd32(dev, 0x400824) & (1 << 31)) + nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) & ~(1 << 31)); } static void diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 516a8d3..f4ea3e6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -34,7 +34,6 @@ #include "nouveau_drm.h" #include "nv50_display.h" -static int nouveau_stub_init(struct drm_device *dev) { return 0; } static void nouveau_stub_takedown(struct drm_device *dev) {} static int nouveau_init_engine_ptrs(struct drm_device *dev) @@ -276,8 +275,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->timer.init = nv04_timer_init; engine->timer.read = nv04_timer_read; engine->timer.takedown = nv04_timer_takedown; - engine->fb.init = nouveau_stub_init; - engine->fb.takedown = nouveau_stub_takedown; + engine->fb.init = nv50_fb_init; + engine->fb.takedown = nv50_fb_takedown; engine->graph.grclass = nv50_graph_grclass; engine->graph.init = nv50_graph_init; engine->graph.takedown = nv50_graph_takedown; diff --git a/drivers/gpu/drm/nouveau/nv50_fb.c b/drivers/gpu/drm/nouveau/nv50_fb.c new file mode 100644 index 0000000..a95e694 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nv50_fb.c @@ -0,0 +1,32 @@ +#include "drmP.h" +#include "drm.h" +#include "nouveau_drv.h" +#include "nouveau_drm.h" + +int +nv50_fb_init(struct drm_device *dev) +{ + /* This is needed to get meaningful information from 100c90 + * on traps. No idea what these values mean exactly. */ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + switch (dev_priv->chipset) { + case 0x50: + nv_wr32(dev, 0x100c90, 0x0707ff); + break; + case 0xa5: + case 0xa8: + nv_wr32(dev, 0x100c90, 0x0d0fff); + break; + default: + nv_wr32(dev, 0x100c90, 0x1d07ff); + break; + } + + return 0; +} + +void +nv50_fb_takedown(struct drm_device *dev) +{ +} diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c index 08d87b7..c62b33a 100644 --- a/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/drivers/gpu/drm/nouveau/nv50_graph.c @@ -56,6 +56,10 @@ nv50_graph_init_intr(struct drm_device *dev) static void nv50_graph_init_regs__nv(struct drm_device *dev) { + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t units = nv_rd32(dev, 0x1540); + int i; + NV_DEBUG(dev, "\n"); nv_wr32(dev, 0x400804, 0xc0000000); @@ -65,6 +69,20 @@ nv50_graph_init_regs__nv(struct drm_device *dev) nv_wr32(dev, 0x405018, 0xc0000000); nv_wr32(dev, 0x402000, 0xc0000000); + for (i = 0; i < 16; i++) { + if (units & 1 << i) { + if (dev_priv->chipset < 0xa0) { + nv_wr32(dev, 0x408900 + (i << 12), 0xc0000000); + nv_wr32(dev, 0x408e08 + (i << 12), 0xc0000000); + nv_wr32(dev, 0x408314 + (i << 12), 0xc0000000); + } else { + nv_wr32(dev, 0x408600 + (i << 11), 0xc0000000); + nv_wr32(dev, 0x408708 + (i << 11), 0xc0000000); + nv_wr32(dev, 0x40831c + (i << 11), 0xc0000000); + } + } + } + nv_wr32(dev, 0x400108, 0xffffffff); nv_wr32(dev, 0x400824, 0x00004000); diff --git a/drivers/gpu/drm/nouveau/nv50_grctx.c b/drivers/gpu/drm/nouveau/nv50_grctx.c index 9f909ab..546b319 100644 --- a/drivers/gpu/drm/nouveau/nv50_grctx.c +++ b/drivers/gpu/drm/nouveau/nv50_grctx.c @@ -274,7 +274,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx) int offset, base; uint32_t units = nv_rd32 (ctx->dev, 0x1540); - /* 0800 */ + /* 0800: DISPATCH */ cp_ctx(ctx, 0x400808, 7); gr_def(ctx, 0x400814, 0x00000030); cp_ctx(ctx, 0x400834, 0x32); @@ -305,7 +305,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx) gr_def(ctx, 0x400b20, 0x0001629d); } - /* 0C00 */ + /* 0C00: VFETCH */ cp_ctx(ctx, 0x400c08, 0x2); gr_def(ctx, 0x400c08, 0x0000fe0c); @@ -331,7 +331,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx) cp_ctx(ctx, 0x401540, 0x5); gr_def(ctx, 0x401550, 0x00001018); - /* 1800 */ + /* 1800: STREAMOUT */ cp_ctx(ctx, 0x401814, 0x1); gr_def(ctx, 0x401814, 0x000000ff); if (dev_priv->chipset == 0x50) { @@ -646,7 +646,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx) if (dev_priv->chipset == 0x50) cp_ctx(ctx, 0x4063e0, 0x1); - /* 6800 */ + /* 6800: M2MF */ if (dev_priv->chipset < 0x90) { cp_ctx(ctx, 0x406814, 0x2b); gr_def(ctx, 0x406818, 0x00000f80); -- cgit v0.10.2 From da647d5bf3c0a4b7ad150803910cb1d737ac522e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 4 Mar 2010 12:00:39 +1000 Subject: drm/nouveau: add option to allow override of dcb connector table types Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 71247da..75388f7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -5287,10 +5287,16 @@ parse_dcb_connector_table(struct nvbios *bios) break; default: cte->type = divine_connector_type(bios, cte->index); - NV_WARN(dev, "unknown type, using 0x%02x", cte->type); + NV_WARN(dev, "unknown type, using 0x%02x\n", cte->type); break; } + if (nouveau_override_conntype) { + int type = divine_connector_type(bios, cte->index); + if (type != cte->type) + NV_WARN(dev, " -> type 0x%02x\n", cte->type); + } + } } diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index 874adf5..f7f28f2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c @@ -83,6 +83,10 @@ MODULE_PARM_DESC(nofbaccel, "Disable fbcon acceleration"); int nouveau_nofbaccel = 0; module_param_named(nofbaccel, nouveau_nofbaccel, int, 0400); +MODULE_PARM_DESC(override_conntype, "Ignore DCB connector type"); +int nouveau_override_conntype = 0; +module_param_named(override_conntype, nouveau_override_conntype, int, 0400); + MODULE_PARM_DESC(tv_norm, "Default TV norm.\n" "\t\tSupported: PAL, PAL-M, PAL-N, PAL-Nc, NTSC-M, NTSC-J,\n" "\t\t\thd480i, hd480p, hd576i, hd576p, hd720p, hd1080i.\n" diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index ad2d75d..6238e25 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -689,6 +689,7 @@ extern int nouveau_ctxfw; extern int nouveau_ignorelid; extern int nouveau_nofbaccel; extern int nouveau_noaccel; +extern int nouveau_override_conntype; /* nouveau_state.c */ extern void nouveau_preclose(struct drm_device *dev, struct drm_file *); -- cgit v0.10.2 From 53c44c3a065ac48c4ccb38f811cf7c5d305c9d4e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 4 Mar 2010 12:12:22 +1000 Subject: drm/nouveau: Gigabyte NX85T connector table lies, it has DVI-I not HDMI Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 75388f7..e5f0ec2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -5211,6 +5211,21 @@ divine_connector_type(struct nvbios *bios, int index) } static void +apply_dcb_connector_quirks(struct nvbios *bios, int idx) +{ + struct dcb_connector_table_entry *cte = &bios->dcb.connector.entry[idx]; + struct drm_device *dev = bios->dev; + + /* Gigabyte NX85T */ + if ((dev->pdev->device == 0x0421) && + (dev->pdev->subsystem_vendor == 0x1458) && + (dev->pdev->subsystem_device == 0x344c)) { + if (cte->type == DCB_CONNECTOR_HDMI_1) + cte->type = DCB_CONNECTOR_DVI_I; + } +} + +static void parse_dcb_connector_table(struct nvbios *bios) { struct drm_device *dev = bios->dev; @@ -5266,6 +5281,8 @@ parse_dcb_connector_table(struct nvbios *bios) if (cte->type == 0xff) continue; + apply_dcb_connector_quirks(bios, i); + NV_INFO(dev, " %d: 0x%08x: type 0x%02x idx %d tag 0x%02x\n", i, cte->entry, cte->type, cte->index, cte->gpio_tag); -- cgit v0.10.2 From e5ec882cfc18007c6076236ac33a713bcc1d35aa Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Fri, 5 Mar 2010 15:15:39 +0100 Subject: drm/nv04-nv40: Fix up the programmed horizontal sync pulse delay. The calculated values were a little bit off (~16 clocks), the only effect it could have had is a slightly offset image with respect to the blob on analog outputs (bug 26790). Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/nv04_crtc.c index d2f143e..9986aba 100644 --- a/drivers/gpu/drm/nouveau/nv04_crtc.c +++ b/drivers/gpu/drm/nouveau/nv04_crtc.c @@ -230,9 +230,9 @@ nv_crtc_mode_set_vga(struct drm_crtc *crtc, struct drm_display_mode *mode) struct drm_framebuffer *fb = crtc->fb; /* Calculate our timings */ - int horizDisplay = (mode->crtc_hdisplay >> 3) - 1; - int horizStart = (mode->crtc_hsync_start >> 3) - 1; - int horizEnd = (mode->crtc_hsync_end >> 3) - 1; + int horizDisplay = (mode->crtc_hdisplay >> 3) - 1; + int horizStart = (mode->crtc_hsync_start >> 3) + 1; + int horizEnd = (mode->crtc_hsync_end >> 3) + 1; int horizTotal = (mode->crtc_htotal >> 3) - 5; int horizBlankStart = (mode->crtc_hdisplay >> 3) - 1; int horizBlankEnd = (mode->crtc_htotal >> 3) - 1; -- cgit v0.10.2 From 81441570c9cbf453891d90f5725adbbfe5a9cc69 Mon Sep 17 00:00:00 2001 From: Maarten Maathuis Date: Sun, 21 Feb 2010 13:28:35 +0100 Subject: drm/nouveau: print a message very early during suspend - In case of suspend lockups it's nice to know it happened in nouveau. Signed-off-by: Maarten Maathuis Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index f7f28f2..0f7e2d0 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c @@ -158,9 +158,11 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state) if (pm_state.event == PM_EVENT_PRETHAW) return 0; + NV_INFO(dev, "Disabling fbcon acceleration...\n"); fbdev_flags = dev_priv->fbdev_info->flags; dev_priv->fbdev_info->flags |= FBINFO_HWACCEL_DISABLED; + NV_INFO(dev, "Unpinning framebuffer(s)...\n"); list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { struct nouveau_framebuffer *nouveau_fb; -- cgit v0.10.2 From ce48fa93a6f5cadd4141a921dfb4129c8850374e Mon Sep 17 00:00:00 2001 From: Maarten Maathuis Date: Thu, 25 Feb 2010 20:00:38 +0100 Subject: drm/nv50: add a memory barrier to pushbuf submission - This is useful for vram pushbuffers that are write combined. - pre-nv50 has one too (in WRITE_PUT). Signed-off-by: Maarten Maathuis Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c index c8482a1..65c441a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.c +++ b/drivers/gpu/drm/nouveau/nouveau_dma.c @@ -190,6 +190,11 @@ nv50_dma_push(struct nouveau_channel *chan, struct nouveau_bo *bo, nouveau_bo_wr32(pb, ip++, upper_32_bits(offset) | length << 8); chan->dma.ib_put = (chan->dma.ib_put + 1) & chan->dma.ib_max; + + DRM_MEMORYBARRIER(); + /* Flush writes. */ + nouveau_bo_rd32(pb, 0); + nvchan_wr32(chan, 0x8c, chan->dma.ib_put); chan->dma.ib_free--; } -- cgit v0.10.2 From 9e49f6c1339a7972e23a335c4c71a289b4c6f65b Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 9 Mar 2010 20:38:45 -0800 Subject: Input: bf54x-keys - fix system hang when pressing a key We need to use the nosync version of disable_irq so that we don't hang in the IRQ handler as we don't ACK the interrupt until later. This used to work regardless, but at some point, the IRQ behavior changed. Not sure when exactly. Signed-off-by: Mike Frysinger Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/keyboard/bf54x-keys.c b/drivers/input/keyboard/bf54x-keys.c index fe376a2..593c052 100644 --- a/drivers/input/keyboard/bf54x-keys.c +++ b/drivers/input/keyboard/bf54x-keys.c @@ -162,7 +162,7 @@ static irqreturn_t bfin_kpad_isr(int irq, void *dev_id) input_sync(input); if (bfin_kpad_get_keypressed(bf54x_kpad)) { - disable_irq(bf54x_kpad->irq); + disable_irq_nosync(bf54x_kpad->irq); bf54x_kpad->lastkey = key; mod_timer(&bf54x_kpad->timer, jiffies + bf54x_kpad->keyup_test_jiffies); -- cgit v0.10.2 From d544d623c5ef3ca14407e8bc042fdf938a966b04 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 10 Mar 2010 15:52:43 +1000 Subject: drm/nv50: fix connector table parsing for some cards The connector table index in the DCB entry for each output type is an index into the connector table, and does *not* necessarily match up with what was previously called "index" in the connector table entries themselves. Not real sure what that index is exactly, renamed to "index2" as we still use it to prevent creating multiple TV connectors. Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index e5f0ec2..aed6068 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -5253,13 +5253,14 @@ parse_dcb_connector_table(struct nvbios *bios) entry = conntab + conntab[1]; cte = &ct->entry[0]; for (i = 0; i < conntab[2]; i++, entry += conntab[3], cte++) { + cte->index = i; if (conntab[3] == 2) cte->entry = ROM16(entry[0]); else cte->entry = ROM32(entry[0]); cte->type = (cte->entry & 0x000000ff) >> 0; - cte->index = (cte->entry & 0x00000f00) >> 8; + cte->index2 = (cte->entry & 0x00000f00) >> 8; switch (cte->entry & 0x00033000) { case 0x00001000: cte->gpio_tag = 0x07; diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h index 9f688aa..4f88e69 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.h +++ b/drivers/gpu/drm/nouveau/nouveau_bios.h @@ -72,9 +72,10 @@ enum dcb_connector_type { }; struct dcb_connector_table_entry { + uint8_t index; uint32_t entry; enum dcb_connector_type type; - uint8_t index; + uint8_t index2; uint8_t gpio_tag; }; diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 61a89f2..fac6c88 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -522,8 +522,8 @@ int nv50_display_create(struct drm_device *dev) } for (i = 0 ; i < dcb->connector.entries; i++) { - if (i != 0 && dcb->connector.entry[i].index == - dcb->connector.entry[i - 1].index) + if (i != 0 && dcb->connector.entry[i].index2 == + dcb->connector.entry[i - 1].index2) continue; nouveau_connector_create(dev, &dcb->connector.entry[i]); } -- cgit v0.10.2 From 06a09124b5ec65f81df66c56695d9a9ae04a0114 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Tue, 9 Mar 2010 20:38:45 -0800 Subject: Input: ads7846 - add support for AD7843 parts The AD7873 is almost identical to the ADS7846; the only difference is related to the Power Management bits PD0 and PD1. This results in a slightly different PENIRQ enable behavior. For the AD7873, VREF should be turned off during differential measurements. So, add the AD7873/43 to the list of driver supported devices, and prevent VREF usage during differential/ratiometric conversion modes. Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 7208654..8a8fa4d 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -24,17 +24,18 @@ config TOUCHSCREEN_88PM860X module will be called 88pm860x-ts. config TOUCHSCREEN_ADS7846 - tristate "ADS7846/TSC2046 and ADS7843 based touchscreens" + tristate "ADS7846/TSC2046/AD7873 and AD(S)7843 based touchscreens" depends on SPI_MASTER depends on HWMON = n || HWMON help Say Y here if you have a touchscreen interface using the - ADS7846/TSC2046 or ADS7843 controller, and your board-specific - setup code includes that in its table of SPI devices. + ADS7846/TSC2046/AD7873 or ADS7843/AD7843 controller, + and your board-specific setup code includes that in its + table of SPI devices. If HWMON is selected, and the driver is told the reference voltage on your board, you will also get hwmon interfaces for the voltage - (and on ads7846/tsc2046, temperature) sensors of this chip. + (and on ads7846/tsc2046/ad7873, temperature) sensors of this chip. If unsure, say N (but it's safe to say "Y"). diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 8b05d8e..d187be0 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -36,6 +36,7 @@ * TSC2046 is just newer ads7846 silicon. * Support for ads7843 tested on Atmel at91sam926x-EK. * Support for ads7845 has only been stubbed in. + * Support for Analog Devices AD7873 and AD7843 tested. * * IRQ handling needs a workaround because of a shortcoming in handling * edge triggered IRQs on some platforms like the OMAP1/2. These @@ -984,6 +985,15 @@ static int __devinit ads7846_probe(struct spi_device *spi) vref = pdata->keep_vref_on; + if (ts->model == 7873) { + /* The AD7873 is almost identical to the ADS7846 + * keep VREF off during differential/ratiometric + * conversion modes + */ + ts->model = 7846; + vref = 0; + } + /* set up the transfers to read touchscreen state; this assumes we * use formula #2 for pressure, not #3. */ diff --git a/include/linux/spi/ads7846.h b/include/linux/spi/ads7846.h index 51948eb..5710c15 100644 --- a/include/linux/spi/ads7846.h +++ b/include/linux/spi/ads7846.h @@ -12,7 +12,7 @@ enum ads7846_filter { }; struct ads7846_platform_data { - u16 model; /* 7843, 7845, 7846. */ + u16 model; /* 7843, 7845, 7846, 7873. */ u16 vref_delay_usecs; /* 0 for external vref; etc */ u16 vref_mv; /* external vref value, milliVolts */ bool keep_vref_on; /* set to keep vref on for differential -- cgit v0.10.2 From 4eb6f91b95e7618eae0103b6cba7c7f01f9d40f3 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Tue, 9 Mar 2010 20:38:47 -0800 Subject: Input: ad7877 - increase pen up imeout The time interval between consecutive interrupts depends on a number of tunables: first_conversion_delay, acquisition_time, averaging and foremost the pen_down_acc_interval. Since the mod_timer() action for the PEN UP event happens in the spi_async() callback function, latencies incurred by the spi bus drivers also need to be taken into account. So all in all, give the PEN UP event a bit more wiggle room and increase timeout to 100ms. Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/touchscreen/ad7877.c b/drivers/input/touchscreen/ad7877.c index eb83939c..e019d53 100644 --- a/drivers/input/touchscreen/ad7877.c +++ b/drivers/input/touchscreen/ad7877.c @@ -46,7 +46,7 @@ #include #include -#define TS_PEN_UP_TIMEOUT msecs_to_jiffies(50) +#define TS_PEN_UP_TIMEOUT msecs_to_jiffies(100) #define MAX_SPI_FREQ_HZ 20000000 #define MAX_12BIT ((1<<12)-1) -- cgit v0.10.2 From 089b43f9737f2e51c6ce354749f5a9f3f093601c Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 10 Mar 2010 16:29:48 +0900 Subject: sh: Fix up NUMA build for 29-bit. pmb_bolt_mapping() is undefined on 29-bit builds, so provide a stub. This fixes up the NUMA build on platforms lacking PMB support. Signed-off-by: Paul Mundt diff --git a/arch/sh/include/asm/mmu.h b/arch/sh/include/asm/mmu.h index 19fe845..56e4418 100644 --- a/arch/sh/include/asm/mmu.h +++ b/arch/sh/include/asm/mmu.h @@ -66,6 +66,13 @@ int pmb_unmap(void __iomem *addr); #else +static inline int +pmb_bolt_mapping(unsigned long virt, phys_addr_t phys, + unsigned long size, pgprot_t prot) +{ + return -EINVAL; +} + static inline void __iomem * pmb_remap_caller(phys_addr_t phys, unsigned long size, pgprot_t prot, void *caller) -- cgit v0.10.2 From 5b34d1ee1e51d61e779a25d28808e8ad824cea3d Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 10 Mar 2010 16:46:58 +0900 Subject: sh: Export uncached helper symbols. oprofile and others need to get at these, so provide symbol exports. Signed-off-by: Paul Mundt diff --git a/arch/sh/mm/uncached.c b/arch/sh/mm/uncached.c index 2ef57ef..8a4eca5 100644 --- a/arch/sh/mm/uncached.c +++ b/arch/sh/mm/uncached.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -16,11 +17,14 @@ unsigned long cached_to_uncached = SZ_512M; unsigned long uncached_size = SZ_512M; unsigned long uncached_start, uncached_end; +EXPORT_SYMBOL(uncached_start); +EXPORT_SYMBOL(uncached_end); int virt_addr_uncached(unsigned long kaddr) { return (kaddr >= uncached_start) && (kaddr < uncached_end); } +EXPORT_SYMBOL(virt_addr_uncached); void __init uncached_init(void) { -- cgit v0.10.2 From 5c1f96f4cffbdde9e194f3ae5373953f3fa12836 Mon Sep 17 00:00:00 2001 From: Thomas Weber Date: Wed, 3 Mar 2010 09:16:54 +0100 Subject: OMAP: DSS2: VRAM: Fix early_param for vram In commit 2b0d8c251b8876d530a6bf671eb5425838fa698a the __early_param is replaced with the generic early_param. This patch fixes the parameter passing for the vram. Signed-off-by: Thomas Weber [tomi.valkeinen@nokia.com: changed the commit prefix] Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/vram.c b/drivers/video/omap2/vram.c index 55a4de5..b266ffa 100644 --- a/drivers/video/omap2/vram.c +++ b/drivers/video/omap2/vram.c @@ -511,13 +511,14 @@ static u32 omap_vram_sdram_size __initdata; static u32 omap_vram_def_sdram_size __initdata; static u32 omap_vram_def_sdram_start __initdata; -static void __init omap_vram_early_vram(char **p) +static int __init omap_vram_early_vram(char *p) { - omap_vram_def_sdram_size = memparse(*p, p); - if (**p == ',') - omap_vram_def_sdram_start = simple_strtoul((*p) + 1, p, 16); + omap_vram_def_sdram_size = memparse(p, &p); + if (*p == ',') + omap_vram_def_sdram_start = simple_strtoul(p + 1, &p, 16); + return 0; } -__early_param("vram=", omap_vram_early_vram); +early_param("vram", omap_vram_early_vram); /* * Called from map_io. We need to call to this early enough so that we -- cgit v0.10.2 From dc1d628a67a8f042e711ea5accc0beedc3ef0092 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 3 Mar 2010 15:55:04 +0100 Subject: perf: Provide generic perf_sample_data initialization This makes it easier to extend perf_sample_data and fixes a bug on arm and sparc, which failed to set ->raw to NULL, which can cause crashes when combined with PERF_SAMPLE_RAW. It also optimizes PowerPC and tracepoint, because the struct initialization is forced to zero out the whole structure. Signed-off-by: Peter Zijlstra Acked-by: Jean Pihet Reviewed-by: Frederic Weisbecker Acked-by: David S. Miller Cc: Jamie Iles Cc: Paul Mackerras Cc: Stephane Eranian Cc: stable@kernel.org LKML-Reference: <20100304140100.315416040@chello.nl> Signed-off-by: Ingo Molnar diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index c54ceb3..3875d99 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c @@ -965,7 +965,7 @@ armv6pmu_handle_irq(int irq_num, */ armv6_pmcr_write(pmcr); - data.addr = 0; + perf_sample_data_init(&data, 0); cpuc = &__get_cpu_var(cpu_hw_events); for (idx = 0; idx <= armpmu->num_events; ++idx) { @@ -1945,7 +1945,7 @@ static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev) */ regs = get_irq_regs(); - data.addr = 0; + perf_sample_data_init(&data, 0); cpuc = &__get_cpu_var(cpu_hw_events); for (idx = 0; idx <= armpmu->num_events; ++idx) { diff --git a/arch/powerpc/kernel/perf_event.c b/arch/powerpc/kernel/perf_event.c index b6cf8f1..5120bd4 100644 --- a/arch/powerpc/kernel/perf_event.c +++ b/arch/powerpc/kernel/perf_event.c @@ -1164,10 +1164,10 @@ static void record_and_restart(struct perf_event *event, unsigned long val, * Finally record data if requested. */ if (record) { - struct perf_sample_data data = { - .addr = ~0ULL, - .period = event->hw.last_period, - }; + struct perf_sample_data data; + + perf_sample_data_init(&data, ~0ULL); + data.period = event->hw.last_period; if (event->attr.sample_type & PERF_SAMPLE_ADDR) perf_get_data_addr(regs, &data.addr); diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c index 9f2b2ba..6504208 100644 --- a/arch/sparc/kernel/perf_event.c +++ b/arch/sparc/kernel/perf_event.c @@ -1189,7 +1189,7 @@ static int __kprobes perf_event_nmi_handler(struct notifier_block *self, regs = args->regs; - data.addr = 0; + perf_sample_data_init(&data, 0); cpuc = &__get_cpu_var(cpu_hw_events); diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 97cddbf..42aafd1 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -1097,8 +1097,7 @@ static int x86_pmu_handle_irq(struct pt_regs *regs) int idx, handled = 0; u64 val; - data.addr = 0; - data.raw = NULL; + perf_sample_data_init(&data, 0); cpuc = &__get_cpu_var(cpu_hw_events); diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 73102df..44b60c8 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -590,10 +590,9 @@ static void intel_pmu_drain_bts_buffer(void) ds->bts_index = ds->bts_buffer_base; + perf_sample_data_init(&data, 0); data.period = event->hw.last_period; - data.addr = 0; - data.raw = NULL; regs.ip = 0; /* @@ -742,8 +741,7 @@ static int intel_pmu_handle_irq(struct pt_regs *regs) int bit, loops; u64 ack, status; - data.addr = 0; - data.raw = NULL; + perf_sample_data_init(&data, 0); cpuc = &__get_cpu_var(cpu_hw_events); diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 90e0521..6f8cd7d 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -801,6 +801,13 @@ struct perf_sample_data { struct perf_raw_record *raw; }; +static inline +void perf_sample_data_init(struct perf_sample_data *data, u64 addr) +{ + data->addr = addr; + data->raw = NULL; +} + extern void perf_output_sample(struct perf_output_handle *handle, struct perf_event_header *header, struct perf_sample_data *data, diff --git a/kernel/perf_event.c b/kernel/perf_event.c index e687450..4393b9e 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c @@ -4108,8 +4108,7 @@ void __perf_sw_event(u32 event_id, u64 nr, int nmi, if (rctx < 0) return; - data.addr = addr; - data.raw = NULL; + perf_sample_data_init(&data, addr); do_perf_sw_event(PERF_TYPE_SOFTWARE, event_id, nr, nmi, &data, regs); @@ -4154,11 +4153,10 @@ static enum hrtimer_restart perf_swevent_hrtimer(struct hrtimer *hrtimer) struct perf_event *event; u64 period; - event = container_of(hrtimer, struct perf_event, hw.hrtimer); + event = container_of(hrtimer, struct perf_event, hw.hrtimer); event->pmu->read(event); - data.addr = 0; - data.raw = NULL; + perf_sample_data_init(&data, 0); data.period = event->hw.last_period; regs = get_irq_regs(); /* @@ -4322,17 +4320,15 @@ static const struct pmu perf_ops_task_clock = { void perf_tp_event(int event_id, u64 addr, u64 count, void *record, int entry_size) { + struct pt_regs *regs = get_irq_regs(); + struct perf_sample_data data; struct perf_raw_record raw = { .size = entry_size, .data = record, }; - struct perf_sample_data data = { - .addr = addr, - .raw = &raw, - }; - - struct pt_regs *regs = get_irq_regs(); + perf_sample_data_init(&data, addr); + data.raw = &raw; if (!regs) regs = task_pt_regs(current); @@ -4448,8 +4444,7 @@ void perf_bp_event(struct perf_event *bp, void *data) struct perf_sample_data sample; struct pt_regs *regs = data; - sample.raw = NULL; - sample.addr = bp->attr.bp_addr; + perf_sample_data_init(&sample, bp->attr.bp_addr); if (!perf_exclude_event(bp, regs)) perf_swevent_add(bp, 1, 1, &sample, regs); -- cgit v0.10.2 From 3f6da3905398826d85731247e7fbcf53400c18bd Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Fri, 5 Mar 2010 13:01:18 +0100 Subject: perf: Rework and fix the arch CPU-hotplug hooks Remove the hw_perf_event_*() hotplug hooks in favour of per PMU hotplug notifiers. This has the advantage of reducing the static weak interface as well as exposing all hotplug actions to the PMU. Use this to fix x86 hotplug usage where we did things in ONLINE which should have been done in UP_PREPARE or STARTING. Signed-off-by: Peter Zijlstra Cc: Paul Mundt Cc: paulus@samba.org Cc: eranian@google.com Cc: robert.richter@amd.com Cc: fweisbec@gmail.com Cc: Arnaldo Carvalho de Melo LKML-Reference: <20100305154128.736225361@chello.nl> Signed-off-by: Ingo Molnar diff --git a/arch/powerpc/kernel/perf_event.c b/arch/powerpc/kernel/perf_event.c index 5120bd4..fbe101d 100644 --- a/arch/powerpc/kernel/perf_event.c +++ b/arch/powerpc/kernel/perf_event.c @@ -1287,7 +1287,7 @@ static void perf_event_interrupt(struct pt_regs *regs) irq_exit(); } -void hw_perf_event_setup(int cpu) +static void power_pmu_setup(int cpu) { struct cpu_hw_events *cpuhw = &per_cpu(cpu_hw_events, cpu); @@ -1297,6 +1297,23 @@ void hw_perf_event_setup(int cpu) cpuhw->mmcr[0] = MMCR0_FC; } +static int __cpuinit +power_pmu_notify(struct notifier_block *self, unsigned long action, void *hcpu) +{ + unsigned int cpu = (long)hcpu; + + switch (action & ~CPU_TASKS_FROZEN) { + case CPU_UP_PREPARE: + power_pmu_setup(cpu); + break; + + default: + break; + } + + return NOTIFY_OK; +} + int register_power_pmu(struct power_pmu *pmu) { if (ppmu) @@ -1314,5 +1331,7 @@ int register_power_pmu(struct power_pmu *pmu) freeze_events_kernel = MMCR0_FCHV; #endif /* CONFIG_PPC64 */ + perf_cpu_notifier(power_pmu_notifier); + return 0; } diff --git a/arch/sh/kernel/perf_event.c b/arch/sh/kernel/perf_event.c index 7ff0943..9f253e9 100644 --- a/arch/sh/kernel/perf_event.c +++ b/arch/sh/kernel/perf_event.c @@ -275,13 +275,30 @@ const struct pmu *hw_perf_event_init(struct perf_event *event) return &pmu; } -void hw_perf_event_setup(int cpu) +static void sh_pmu_setup(int cpu) { struct cpu_hw_events *cpuhw = &per_cpu(cpu_hw_events, cpu); memset(cpuhw, 0, sizeof(struct cpu_hw_events)); } +static int __cpuinit +sh_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu) +{ + unsigned int cpu = (long)hcpu; + + switch (action & ~CPU_TASKS_FROZEN) { + case CPU_UP_PREPARE: + sh_pmu_setup(cpu); + break; + + default: + break; + } + + return NOTIFY_OK; +} + void hw_perf_enable(void) { if (!sh_pmu_initialized()) @@ -308,5 +325,6 @@ int register_sh_pmu(struct sh_pmu *pmu) WARN_ON(pmu->num_events > MAX_HWEVENTS); + perf_cpu_notifier(sh_pmu_notifier); return 0; } diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 42aafd1..585d560 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -157,6 +157,11 @@ struct x86_pmu { void (*put_event_constraints)(struct cpu_hw_events *cpuc, struct perf_event *event); struct event_constraint *event_constraints; + + void (*cpu_prepare)(int cpu); + void (*cpu_starting)(int cpu); + void (*cpu_dying)(int cpu); + void (*cpu_dead)(int cpu); }; static struct x86_pmu x86_pmu __read_mostly; @@ -293,7 +298,7 @@ static inline bool bts_available(void) return x86_pmu.enable_bts != NULL; } -static inline void init_debug_store_on_cpu(int cpu) +static void init_debug_store_on_cpu(int cpu) { struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds; @@ -305,7 +310,7 @@ static inline void init_debug_store_on_cpu(int cpu) (u32)((u64)(unsigned long)ds >> 32)); } -static inline void fini_debug_store_on_cpu(int cpu) +static void fini_debug_store_on_cpu(int cpu) { if (!per_cpu(cpu_hw_events, cpu).ds) return; @@ -1337,6 +1342,39 @@ undo: #include "perf_event_p6.c" #include "perf_event_intel.c" +static int __cpuinit +x86_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu) +{ + unsigned int cpu = (long)hcpu; + + switch (action & ~CPU_TASKS_FROZEN) { + case CPU_UP_PREPARE: + if (x86_pmu.cpu_prepare) + x86_pmu.cpu_prepare(cpu); + break; + + case CPU_STARTING: + if (x86_pmu.cpu_starting) + x86_pmu.cpu_starting(cpu); + break; + + case CPU_DYING: + if (x86_pmu.cpu_dying) + x86_pmu.cpu_dying(cpu); + break; + + case CPU_DEAD: + if (x86_pmu.cpu_dead) + x86_pmu.cpu_dead(cpu); + break; + + default: + break; + } + + return NOTIFY_OK; +} + static void __init pmu_check_apic(void) { if (cpu_has_apic) @@ -1415,6 +1453,8 @@ void __init init_hw_perf_events(void) pr_info("... max period: %016Lx\n", x86_pmu.max_period); pr_info("... fixed-purpose events: %d\n", x86_pmu.num_events_fixed); pr_info("... event mask: %016Lx\n", perf_event_mask); + + perf_cpu_notifier(x86_pmu_notifier); } static inline void x86_pmu_read(struct perf_event *event) @@ -1674,29 +1714,3 @@ struct perf_callchain_entry *perf_callchain(struct pt_regs *regs) return entry; } - -void hw_perf_event_setup_online(int cpu) -{ - init_debug_store_on_cpu(cpu); - - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_AMD: - amd_pmu_cpu_online(cpu); - break; - default: - return; - } -} - -void hw_perf_event_setup_offline(int cpu) -{ - init_debug_store_on_cpu(cpu); - - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_AMD: - amd_pmu_cpu_offline(cpu); - break; - default: - return; - } -} diff --git a/arch/x86/kernel/cpu/perf_event_amd.c b/arch/x86/kernel/cpu/perf_event_amd.c index 8f3dbfd..014528b 100644 --- a/arch/x86/kernel/cpu/perf_event_amd.c +++ b/arch/x86/kernel/cpu/perf_event_amd.c @@ -271,28 +271,6 @@ done: return &emptyconstraint; } -static __initconst struct x86_pmu amd_pmu = { - .name = "AMD", - .handle_irq = x86_pmu_handle_irq, - .disable_all = x86_pmu_disable_all, - .enable_all = x86_pmu_enable_all, - .enable = x86_pmu_enable_event, - .disable = x86_pmu_disable_event, - .eventsel = MSR_K7_EVNTSEL0, - .perfctr = MSR_K7_PERFCTR0, - .event_map = amd_pmu_event_map, - .raw_event = amd_pmu_raw_event, - .max_events = ARRAY_SIZE(amd_perfmon_event_map), - .num_events = 4, - .event_bits = 48, - .event_mask = (1ULL << 48) - 1, - .apic = 1, - /* use highest bit to detect overflow */ - .max_period = (1ULL << 47) - 1, - .get_event_constraints = amd_get_event_constraints, - .put_event_constraints = amd_put_event_constraints -}; - static struct amd_nb *amd_alloc_nb(int cpu, int nb_id) { struct amd_nb *nb; @@ -378,6 +356,31 @@ static void amd_pmu_cpu_offline(int cpu) raw_spin_unlock(&amd_nb_lock); } +static __initconst struct x86_pmu amd_pmu = { + .name = "AMD", + .handle_irq = x86_pmu_handle_irq, + .disable_all = x86_pmu_disable_all, + .enable_all = x86_pmu_enable_all, + .enable = x86_pmu_enable_event, + .disable = x86_pmu_disable_event, + .eventsel = MSR_K7_EVNTSEL0, + .perfctr = MSR_K7_PERFCTR0, + .event_map = amd_pmu_event_map, + .raw_event = amd_pmu_raw_event, + .max_events = ARRAY_SIZE(amd_perfmon_event_map), + .num_events = 4, + .event_bits = 48, + .event_mask = (1ULL << 48) - 1, + .apic = 1, + /* use highest bit to detect overflow */ + .max_period = (1ULL << 47) - 1, + .get_event_constraints = amd_get_event_constraints, + .put_event_constraints = amd_put_event_constraints, + + .cpu_prepare = amd_pmu_cpu_online, + .cpu_dead = amd_pmu_cpu_offline, +}; + static __init int amd_pmu_init(void) { /* Performance-monitoring supported from K7 and later: */ @@ -390,11 +393,6 @@ static __init int amd_pmu_init(void) memcpy(hw_cache_event_ids, amd_hw_cache_event_ids, sizeof(hw_cache_event_ids)); - /* - * explicitly initialize the boot cpu, other cpus will get - * the cpu hotplug callbacks from smp_init() - */ - amd_pmu_cpu_online(smp_processor_id()); return 0; } @@ -405,12 +403,4 @@ static int amd_pmu_init(void) return 0; } -static void amd_pmu_cpu_online(int cpu) -{ -} - -static void amd_pmu_cpu_offline(int cpu) -{ -} - #endif diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 44b60c8..12e811a 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -870,7 +870,10 @@ static __initconst struct x86_pmu intel_pmu = { .max_period = (1ULL << 31) - 1, .enable_bts = intel_pmu_enable_bts, .disable_bts = intel_pmu_disable_bts, - .get_event_constraints = intel_get_event_constraints + .get_event_constraints = intel_get_event_constraints, + + .cpu_starting = init_debug_store_on_cpu, + .cpu_dying = fini_debug_store_on_cpu, }; static __init int intel_pmu_init(void) diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 6f8cd7d..80acbf3 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -936,5 +936,21 @@ static inline void perf_event_disable(struct perf_event *event) { } #define perf_output_put(handle, x) \ perf_output_copy((handle), &(x), sizeof(x)) +/* + * This has to have a higher priority than migration_notifier in sched.c. + */ +#define perf_cpu_notifier(fn) \ +do { \ + static struct notifier_block fn##_nb __cpuinitdata = \ + { .notifier_call = fn, .priority = 20 }; \ + fn(&fn##_nb, (unsigned long)CPU_UP_PREPARE, \ + (void *)(unsigned long)smp_processor_id()); \ + fn(&fn##_nb, (unsigned long)CPU_STARTING, \ + (void *)(unsigned long)smp_processor_id()); \ + fn(&fn##_nb, (unsigned long)CPU_ONLINE, \ + (void *)(unsigned long)smp_processor_id()); \ + register_cpu_notifier(&fn##_nb); \ +} while (0) + #endif /* __KERNEL__ */ #endif /* _LINUX_PERF_EVENT_H */ diff --git a/kernel/perf_event.c b/kernel/perf_event.c index 4393b9e..73329de 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c @@ -81,10 +81,6 @@ extern __weak const struct pmu *hw_perf_event_init(struct perf_event *event) void __weak hw_perf_disable(void) { barrier(); } void __weak hw_perf_enable(void) { barrier(); } -void __weak hw_perf_event_setup(int cpu) { barrier(); } -void __weak hw_perf_event_setup_online(int cpu) { barrier(); } -void __weak hw_perf_event_setup_offline(int cpu) { barrier(); } - int __weak hw_perf_group_sched_in(struct perf_event *group_leader, struct perf_cpu_context *cpuctx, @@ -5382,8 +5378,6 @@ static void __cpuinit perf_event_init_cpu(int cpu) spin_lock(&perf_resource_lock); cpuctx->max_pertask = perf_max_events - perf_reserved_percpu; spin_unlock(&perf_resource_lock); - - hw_perf_event_setup(cpu); } #ifdef CONFIG_HOTPLUG_CPU @@ -5423,20 +5417,11 @@ perf_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) perf_event_init_cpu(cpu); break; - case CPU_ONLINE: - case CPU_ONLINE_FROZEN: - hw_perf_event_setup_online(cpu); - break; - case CPU_DOWN_PREPARE: case CPU_DOWN_PREPARE_FROZEN: perf_event_exit_cpu(cpu); break; - case CPU_DEAD: - hw_perf_event_setup_offline(cpu); - break; - default: break; } -- cgit v0.10.2 From 32975a4f114be52286f9a5bf6c230dbb8c0e1903 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Sat, 6 Mar 2010 19:49:19 +0100 Subject: perf: Optimize perf_disable Currently we always call hw_perf_disable(), even if its already disabled, this seems superflous, esp. since it cannot be made NMI safe (see further patches). Signed-off-by: Peter Zijlstra Cc: paulus@samba.org Cc: eranian@google.com Cc: robert.richter@amd.com Cc: fweisbec@gmail.com Cc: Arnaldo Carvalho de Melo LKML-Reference: Signed-off-by: Ingo Molnar diff --git a/kernel/perf_event.c b/kernel/perf_event.c index 73329de..d810846 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c @@ -93,25 +93,15 @@ void __weak perf_event_print_debug(void) { } static DEFINE_PER_CPU(int, perf_disable_count); -void __perf_disable(void) -{ - __get_cpu_var(perf_disable_count)++; -} - -bool __perf_enable(void) -{ - return !--__get_cpu_var(perf_disable_count); -} - void perf_disable(void) { - __perf_disable(); - hw_perf_disable(); + if (!__get_cpu_var(perf_disable_count)++) + hw_perf_disable(); } void perf_enable(void) { - if (__perf_enable()) + if (!--__get_cpu_var(perf_disable_count)) hw_perf_enable(); } -- cgit v0.10.2 From 3fb2b8ddcc6a7aa62af6bd2cb939edfd4c460506 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 8 Mar 2010 13:51:01 +0100 Subject: perf, x86, Do not user perf_disable from NMI context Explicitly use intel_pmu_{disable,enable}_all() in intel_pmu_handle_irq() to avoid the NMI race conditions in perf_{disable,enable} Signed-off-by: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: paulus@samba.org Cc: eranian@google.com Cc: robert.richter@amd.com Cc: fweisbec@gmail.com LKML-Reference: Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 12e811a..c582449 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -745,11 +745,11 @@ static int intel_pmu_handle_irq(struct pt_regs *regs) cpuc = &__get_cpu_var(cpu_hw_events); - perf_disable(); + intel_pmu_disable_all(); intel_pmu_drain_bts_buffer(); status = intel_pmu_get_status(); if (!status) { - perf_enable(); + intel_pmu_enable_all(); return 0; } @@ -759,8 +759,7 @@ again: WARN_ONCE(1, "perfevents: irq loop stuck!\n"); perf_event_print_debug(); intel_pmu_reset(); - perf_enable(); - return 1; + goto done; } inc_irq_stat(apic_perf_irqs); @@ -790,8 +789,8 @@ again: if (status) goto again; - perf_enable(); - +done: + intel_pmu_enable_all(); return 1; } -- cgit v0.10.2 From 07088edb88164c2a2406cd2d9a7be19d8515214b Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 2 Mar 2010 20:16:01 +0100 Subject: perf, x86: Remove superfluous arguments to x86_perf_event_set_period() The second and third argument to x86_perf_event_set_period() are superfluous since they are simple expressions of the first argument. Hence remove them. Signed-off-by: Peter Zijlstra Cc: paulus@samba.org Cc: eranian@google.com Cc: robert.richter@amd.com Cc: fweisbec@gmail.com Cc: Arnaldo Carvalho de Melo LKML-Reference: <20100304140100.006500906@chello.nl> Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 585d560..fcf1788 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -170,8 +170,7 @@ static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { .enabled = 1, }; -static int x86_perf_event_set_period(struct perf_event *event, - struct hw_perf_event *hwc, int idx); +static int x86_perf_event_set_period(struct perf_event *event); /* * Generalized hw caching related hw_event table, filled @@ -835,7 +834,7 @@ void hw_perf_enable(void) if (hwc->idx == -1) { x86_assign_hw_event(event, cpuc, i); - x86_perf_event_set_period(event, hwc, hwc->idx); + x86_perf_event_set_period(event); } /* * need to mark as active because x86_pmu_disable() @@ -876,12 +875,12 @@ static DEFINE_PER_CPU(u64 [X86_PMC_IDX_MAX], pmc_prev_left); * To be called with the event disabled in hw: */ static int -x86_perf_event_set_period(struct perf_event *event, - struct hw_perf_event *hwc, int idx) +x86_perf_event_set_period(struct perf_event *event) { + struct hw_perf_event *hwc = &event->hw; s64 left = atomic64_read(&hwc->period_left); s64 period = hwc->sample_period; - int err, ret = 0; + int err, ret = 0, idx = hwc->idx; if (idx == X86_PMC_IDX_FIXED_BTS) return 0; @@ -979,7 +978,7 @@ static int x86_pmu_start(struct perf_event *event) if (hwc->idx == -1) return -EAGAIN; - x86_perf_event_set_period(event, hwc, hwc->idx); + x86_perf_event_set_period(event); x86_pmu.enable(hwc, hwc->idx); return 0; @@ -1123,7 +1122,7 @@ static int x86_pmu_handle_irq(struct pt_regs *regs) handled = 1; data.period = event->hw.last_period; - if (!x86_perf_event_set_period(event, hwc, idx)) + if (!x86_perf_event_set_period(event)) continue; if (perf_event_overflow(event, 1, &data, regs)) diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index c582449..6dbdf91 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -699,7 +699,7 @@ static int intel_pmu_save_and_restart(struct perf_event *event) int ret; x86_perf_event_update(event, hwc, idx); - ret = x86_perf_event_set_period(event, hwc, idx); + ret = x86_perf_event_set_period(event); return ret; } -- cgit v0.10.2 From cc2ad4ba8792b9d4ff893ae3b845d2c5a6206fc9 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 2 Mar 2010 20:18:39 +0100 Subject: perf, x86: Remove superfluous arguments to x86_perf_event_update() The second and third argument to x86_perf_event_update() are superfluous since they are simple expressions of the first argument. Hence remove them. Signed-off-by: Peter Zijlstra Cc: paulus@samba.org Cc: eranian@google.com Cc: robert.richter@amd.com Cc: fweisbec@gmail.com Cc: Arnaldo Carvalho de Melo LKML-Reference: <20100304140100.089468871@chello.nl> Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index fcf1788..086127b 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -193,11 +193,12 @@ static u64 __read_mostly hw_cache_event_ids * Returns the delta events processed. */ static u64 -x86_perf_event_update(struct perf_event *event, - struct hw_perf_event *hwc, int idx) +x86_perf_event_update(struct perf_event *event) { + struct hw_perf_event *hwc = &event->hw; int shift = 64 - x86_pmu.event_bits; u64 prev_raw_count, new_raw_count; + int idx = hwc->idx; s64 delta; if (idx == X86_PMC_IDX_FIXED_BTS) @@ -1064,7 +1065,7 @@ static void x86_pmu_stop(struct perf_event *event) * Drain the remaining delta count out of a event * that we are disabling: */ - x86_perf_event_update(event, hwc, idx); + x86_perf_event_update(event); cpuc->events[idx] = NULL; } @@ -1112,7 +1113,7 @@ static int x86_pmu_handle_irq(struct pt_regs *regs) event = cpuc->events[idx]; hwc = &event->hw; - val = x86_perf_event_update(event, hwc, idx); + val = x86_perf_event_update(event); if (val & (1ULL << (x86_pmu.event_bits - 1))) continue; @@ -1458,7 +1459,7 @@ void __init init_hw_perf_events(void) static inline void x86_pmu_read(struct perf_event *event) { - x86_perf_event_update(event, &event->hw, event->hw.idx); + x86_perf_event_update(event); } static const struct pmu pmu = { diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 6dbdf91..a4c9f16 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -694,14 +694,8 @@ static void intel_pmu_enable_event(struct hw_perf_event *hwc, int idx) */ static int intel_pmu_save_and_restart(struct perf_event *event) { - struct hw_perf_event *hwc = &event->hw; - int idx = hwc->idx; - int ret; - - x86_perf_event_update(event, hwc, idx); - ret = x86_perf_event_set_period(event); - - return ret; + x86_perf_event_update(event); + return x86_perf_event_set_period(event); } static void intel_pmu_reset(void) -- cgit v0.10.2 From aff3d91a913c9ae0c2f56b65b27cbd00c7d27ee3 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 2 Mar 2010 20:32:08 +0100 Subject: perf, x86: Change x86_pmu.{enable,disable} calling convention Pass the full perf_event into the x86_pmu functions so that those may make use of more than the hw_perf_event, and while doing this, remove the superfluous second argument. Signed-off-by: Peter Zijlstra Cc: paulus@samba.org Cc: eranian@google.com Cc: robert.richter@amd.com Cc: fweisbec@gmail.com Cc: Arnaldo Carvalho de Melo LKML-Reference: <20100304140100.165166129@chello.nl> Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 086127b..2dd704f 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -133,8 +133,8 @@ struct x86_pmu { int (*handle_irq)(struct pt_regs *); void (*disable_all)(void); void (*enable_all)(void); - void (*enable)(struct hw_perf_event *, int); - void (*disable)(struct hw_perf_event *, int); + void (*enable)(struct perf_event *); + void (*disable)(struct perf_event *); unsigned eventsel; unsigned perfctr; u64 (*event_map)(int); @@ -845,7 +845,7 @@ void hw_perf_enable(void) set_bit(hwc->idx, cpuc->active_mask); cpuc->events[hwc->idx] = event; - x86_pmu.enable(hwc, hwc->idx); + x86_pmu.enable(event); perf_event_update_userpage(event); } cpuc->n_added = 0; @@ -858,15 +858,16 @@ void hw_perf_enable(void) x86_pmu.enable_all(); } -static inline void __x86_pmu_enable_event(struct hw_perf_event *hwc, int idx) +static inline void __x86_pmu_enable_event(struct hw_perf_event *hwc) { - (void)checking_wrmsrl(hwc->config_base + idx, + (void)checking_wrmsrl(hwc->config_base + hwc->idx, hwc->config | ARCH_PERFMON_EVENTSEL_ENABLE); } -static inline void x86_pmu_disable_event(struct hw_perf_event *hwc, int idx) +static inline void x86_pmu_disable_event(struct perf_event *event) { - (void)checking_wrmsrl(hwc->config_base + idx, hwc->config); + struct hw_perf_event *hwc = &event->hw; + (void)checking_wrmsrl(hwc->config_base + hwc->idx, hwc->config); } static DEFINE_PER_CPU(u64 [X86_PMC_IDX_MAX], pmc_prev_left); @@ -927,11 +928,11 @@ x86_perf_event_set_period(struct perf_event *event) return ret; } -static void x86_pmu_enable_event(struct hw_perf_event *hwc, int idx) +static void x86_pmu_enable_event(struct perf_event *event) { struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); if (cpuc->enabled) - __x86_pmu_enable_event(hwc, idx); + __x86_pmu_enable_event(&event->hw); } /* @@ -974,13 +975,11 @@ static int x86_pmu_enable(struct perf_event *event) static int x86_pmu_start(struct perf_event *event) { - struct hw_perf_event *hwc = &event->hw; - - if (hwc->idx == -1) + if (event->hw.idx == -1) return -EAGAIN; x86_perf_event_set_period(event); - x86_pmu.enable(hwc, hwc->idx); + x86_pmu.enable(event); return 0; } @@ -994,7 +993,7 @@ static void x86_pmu_unthrottle(struct perf_event *event) cpuc->events[hwc->idx] != event)) return; - x86_pmu.enable(hwc, hwc->idx); + x86_pmu.enable(event); } void perf_event_print_debug(void) @@ -1059,7 +1058,7 @@ static void x86_pmu_stop(struct perf_event *event) * could reenable again: */ clear_bit(idx, cpuc->active_mask); - x86_pmu.disable(hwc, idx); + x86_pmu.disable(event); /* * Drain the remaining delta count out of a event @@ -1127,7 +1126,7 @@ static int x86_pmu_handle_irq(struct pt_regs *regs) continue; if (perf_event_overflow(event, 1, &data, regs)) - x86_pmu.disable(hwc, idx); + x86_pmu.disable(event); } if (handled) diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index a4c9f16..a840948 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -548,9 +548,9 @@ static inline void intel_pmu_ack_status(u64 ack) } static inline void -intel_pmu_disable_fixed(struct hw_perf_event *hwc, int __idx) +intel_pmu_disable_fixed(struct hw_perf_event *hwc) { - int idx = __idx - X86_PMC_IDX_FIXED; + int idx = hwc->idx - X86_PMC_IDX_FIXED; u64 ctrl_val, mask; mask = 0xfULL << (idx * 4); @@ -621,26 +621,28 @@ static void intel_pmu_drain_bts_buffer(void) } static inline void -intel_pmu_disable_event(struct hw_perf_event *hwc, int idx) +intel_pmu_disable_event(struct perf_event *event) { - if (unlikely(idx == X86_PMC_IDX_FIXED_BTS)) { + struct hw_perf_event *hwc = &event->hw; + + if (unlikely(hwc->idx == X86_PMC_IDX_FIXED_BTS)) { intel_pmu_disable_bts(); intel_pmu_drain_bts_buffer(); return; } if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) { - intel_pmu_disable_fixed(hwc, idx); + intel_pmu_disable_fixed(hwc); return; } - x86_pmu_disable_event(hwc, idx); + x86_pmu_disable_event(event); } static inline void -intel_pmu_enable_fixed(struct hw_perf_event *hwc, int __idx) +intel_pmu_enable_fixed(struct hw_perf_event *hwc) { - int idx = __idx - X86_PMC_IDX_FIXED; + int idx = hwc->idx - X86_PMC_IDX_FIXED; u64 ctrl_val, bits, mask; int err; @@ -670,9 +672,11 @@ intel_pmu_enable_fixed(struct hw_perf_event *hwc, int __idx) err = checking_wrmsrl(hwc->config_base, ctrl_val); } -static void intel_pmu_enable_event(struct hw_perf_event *hwc, int idx) +static void intel_pmu_enable_event(struct perf_event *event) { - if (unlikely(idx == X86_PMC_IDX_FIXED_BTS)) { + struct hw_perf_event *hwc = &event->hw; + + if (unlikely(hwc->idx == X86_PMC_IDX_FIXED_BTS)) { if (!__get_cpu_var(cpu_hw_events).enabled) return; @@ -681,11 +685,11 @@ static void intel_pmu_enable_event(struct hw_perf_event *hwc, int idx) } if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) { - intel_pmu_enable_fixed(hwc, idx); + intel_pmu_enable_fixed(hwc); return; } - __x86_pmu_enable_event(hwc, idx); + __x86_pmu_enable_event(hwc); } /* @@ -771,7 +775,7 @@ again: data.period = event->hw.last_period; if (perf_event_overflow(event, 1, &data, regs)) - intel_pmu_disable_event(&event->hw, bit); + intel_pmu_disable_event(event); } intel_pmu_ack_status(ack); diff --git a/arch/x86/kernel/cpu/perf_event_p6.c b/arch/x86/kernel/cpu/perf_event_p6.c index a4e67b9..a330485 100644 --- a/arch/x86/kernel/cpu/perf_event_p6.c +++ b/arch/x86/kernel/cpu/perf_event_p6.c @@ -77,27 +77,29 @@ static void p6_pmu_enable_all(void) } static inline void -p6_pmu_disable_event(struct hw_perf_event *hwc, int idx) +p6_pmu_disable_event(struct perf_event *event) { struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); + struct hw_perf_event *hwc = &event->hw; u64 val = P6_NOP_EVENT; if (cpuc->enabled) val |= ARCH_PERFMON_EVENTSEL_ENABLE; - (void)checking_wrmsrl(hwc->config_base + idx, val); + (void)checking_wrmsrl(hwc->config_base + hwc->idx, val); } -static void p6_pmu_enable_event(struct hw_perf_event *hwc, int idx) +static void p6_pmu_enable_event(struct perf_event *event) { struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); + struct hw_perf_event *hwc = &event->hw; u64 val; val = hwc->config; if (cpuc->enabled) val |= ARCH_PERFMON_EVENTSEL_ENABLE; - (void)checking_wrmsrl(hwc->config_base + idx, val); + (void)checking_wrmsrl(hwc->config_base + hwc->idx, val); } static __initconst struct x86_pmu p6_pmu = { -- cgit v0.10.2 From 34538ee77b39a12702e0f4c3ed9e8fa2dd5eb92c Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 2 Mar 2010 21:16:55 +0100 Subject: perf, x86: Use unlocked bitops There is no concurrency on these variables, so don't use LOCK'ed ops. As to the intel_pmu_handle_irq() status bit clean, nobody uses that so remove it all together. Signed-off-by: Peter Zijlstra Cc: paulus@samba.org Cc: eranian@google.com Cc: robert.richter@amd.com Cc: fweisbec@gmail.com Cc: Arnaldo Carvalho de Melo LKML-Reference: <20100304140100.240023029@chello.nl> Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 2dd704f..01b1667 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -643,7 +643,7 @@ static int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign) if (test_bit(hwc->idx, used_mask)) break; - set_bit(hwc->idx, used_mask); + __set_bit(hwc->idx, used_mask); if (assign) assign[i] = hwc->idx; } @@ -692,7 +692,7 @@ static int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign) if (j == X86_PMC_IDX_MAX) break; - set_bit(j, used_mask); + __set_bit(j, used_mask); if (assign) assign[i] = j; @@ -842,7 +842,7 @@ void hw_perf_enable(void) * clear active_mask and events[] yet it preserves * idx */ - set_bit(hwc->idx, cpuc->active_mask); + __set_bit(hwc->idx, cpuc->active_mask); cpuc->events[hwc->idx] = event; x86_pmu.enable(event); @@ -1057,7 +1057,7 @@ static void x86_pmu_stop(struct perf_event *event) * Must be done before we disable, otherwise the nmi handler * could reenable again: */ - clear_bit(idx, cpuc->active_mask); + __clear_bit(idx, cpuc->active_mask); x86_pmu.disable(event); /* diff --git a/arch/x86/kernel/cpu/perf_event_amd.c b/arch/x86/kernel/cpu/perf_event_amd.c index 014528b..573458f 100644 --- a/arch/x86/kernel/cpu/perf_event_amd.c +++ b/arch/x86/kernel/cpu/perf_event_amd.c @@ -287,7 +287,7 @@ static struct amd_nb *amd_alloc_nb(int cpu, int nb_id) * initialize all possible NB constraints */ for (i = 0; i < x86_pmu.num_events; i++) { - set_bit(i, nb->event_constraints[i].idxmsk); + __set_bit(i, nb->event_constraints[i].idxmsk); nb->event_constraints[i].weight = 1; } return nb; diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index a840948..d87421c 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -765,7 +765,6 @@ again: for_each_set_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) { struct perf_event *event = cpuc->events[bit]; - clear_bit(bit, (unsigned long *) &status); if (!test_bit(bit, cpuc->active_mask)) continue; -- cgit v0.10.2 From c08053e627d23490a03431285b78b7a5b617fbad Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Sat, 6 Mar 2010 13:19:24 +0100 Subject: perf, x86: Fix x86_pmu_start pmu::start should undo pmu::stop, make it so. Signed-off-by: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: paulus@samba.org Cc: eranian@google.com Cc: robert.richter@amd.com Cc: fweisbec@gmail.com LKML-Reference: Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 01b1667..9757b96 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -785,6 +785,7 @@ static inline int match_prev_assignment(struct hw_perf_event *hwc, hwc->last_tag == cpuc->tags[i]; } +static int x86_pmu_start(struct perf_event *event); static void x86_pmu_stop(struct perf_event *event); void hw_perf_enable(void) @@ -833,20 +834,10 @@ void hw_perf_enable(void) event = cpuc->event_list[i]; hwc = &event->hw; - if (hwc->idx == -1) { + if (hwc->idx == -1) x86_assign_hw_event(event, cpuc, i); - x86_perf_event_set_period(event); - } - /* - * need to mark as active because x86_pmu_disable() - * clear active_mask and events[] yet it preserves - * idx - */ - __set_bit(hwc->idx, cpuc->active_mask); - cpuc->events[hwc->idx] = event; - x86_pmu.enable(event); - perf_event_update_userpage(event); + x86_pmu_start(event); } cpuc->n_added = 0; perf_events_lapic_init(); @@ -975,11 +966,17 @@ static int x86_pmu_enable(struct perf_event *event) static int x86_pmu_start(struct perf_event *event) { - if (event->hw.idx == -1) + struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); + int idx = event->hw.idx; + + if (idx == -1) return -EAGAIN; x86_perf_event_set_period(event); + cpuc->events[idx] = event; + __set_bit(idx, cpuc->active_mask); x86_pmu.enable(event); + perf_event_update_userpage(event); return 0; } -- cgit v0.10.2 From 71e2d2828046133ed985696a02e2e1499ca0bfb8 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 8 Mar 2010 17:51:33 +0100 Subject: perf, x86: Avoid double disable on throttle vs ioctl(PERF_IOC_DISABLE) Calling ioctl(PERF_EVENT_IOC_DISABLE) on a thottled counter would result in a double disable, cure this by using x86_pmu_{start,stop} for throttle/unthrottle and teach x86_pmu_stop() to check ->active_mask. Signed-off-by: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: paulus@samba.org Cc: eranian@google.com Cc: robert.richter@amd.com Cc: fweisbec@gmail.com LKML-Reference: Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 9757b96..b68c4fb 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -983,14 +983,8 @@ static int x86_pmu_start(struct perf_event *event) static void x86_pmu_unthrottle(struct perf_event *event) { - struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); - struct hw_perf_event *hwc = &event->hw; - - if (WARN_ON_ONCE(hwc->idx >= X86_PMC_IDX_MAX || - cpuc->events[hwc->idx] != event)) - return; - - x86_pmu.enable(event); + int ret = x86_pmu_start(event); + WARN_ON_ONCE(ret); } void perf_event_print_debug(void) @@ -1050,11 +1044,9 @@ static void x86_pmu_stop(struct perf_event *event) struct hw_perf_event *hwc = &event->hw; int idx = hwc->idx; - /* - * Must be done before we disable, otherwise the nmi handler - * could reenable again: - */ - __clear_bit(idx, cpuc->active_mask); + if (!__test_and_clear_bit(idx, cpuc->active_mask)) + return; + x86_pmu.disable(event); /* @@ -1123,7 +1115,7 @@ static int x86_pmu_handle_irq(struct pt_regs *regs) continue; if (perf_event_overflow(event, 1, &data, regs)) - x86_pmu.disable(event); + x86_pmu_stop(event); } if (handled) diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index d87421c..84bfde6 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -774,7 +774,7 @@ again: data.period = event->hw.last_period; if (perf_event_overflow(event, 1, &data, regs)) - intel_pmu_disable_event(event); + x86_pmu_stop(event); } intel_pmu_ack_status(ack); -- cgit v0.10.2 From 356e1f2e0ace2d4b100c8eda9d49b709e8323da5 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Sat, 6 Mar 2010 13:49:56 +0100 Subject: perf, x86: Properly account n_added Make sure n_added is properly accounted so that we can rely on the value to reflect the number of added counters. This is needed if its going to be used for more than a boolean check. Signed-off-by: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: paulus@samba.org Cc: eranian@google.com Cc: robert.richter@amd.com Cc: fweisbec@gmail.com LKML-Reference: Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index b68c4fb..071c840 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -959,7 +959,7 @@ static int x86_pmu_enable(struct perf_event *event) memcpy(cpuc->assign, assign, n*sizeof(int)); cpuc->n_events = n; - cpuc->n_added = n - n0; + cpuc->n_added += n - n0; return 0; } @@ -1302,7 +1302,7 @@ int hw_perf_group_sched_in(struct perf_event *leader, memcpy(cpuc->assign, assign, n0*sizeof(int)); cpuc->n_events = n0; - cpuc->n_added = n1; + cpuc->n_added += n1; ctx->nr_active += n1; /* -- cgit v0.10.2 From 19925ce778f9fc371b9607625de3bff04c60121e Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Sat, 6 Mar 2010 13:20:40 +0100 Subject: perf, x86: Fix double disable calls hw_perf_enable() would disable events that were not yet enabled. This causes problems with code that assumes that ->enable/->disable calls are balanced (like the LBR code does). What happens is that we disable newly added counters that match their previous assignment, even though they are not yet programmed on the hardware. Avoid this by only doing the first pass over the existing events. Signed-off-by: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: paulus@samba.org Cc: eranian@google.com Cc: robert.richter@amd.com Cc: fweisbec@gmail.com LKML-Reference: Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 071c840..045cc0b 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -802,6 +802,7 @@ void hw_perf_enable(void) return; if (cpuc->n_added) { + int n_running = cpuc->n_events - cpuc->n_added; /* * apply assignment obtained either from * hw_perf_group_sched_in() or x86_pmu_enable() @@ -809,7 +810,7 @@ void hw_perf_enable(void) * step1: save events moving to new counters * step2: reprogram moved events into new counters */ - for (i = 0; i < cpuc->n_events; i++) { + for (i = 0; i < n_running; i++) { event = cpuc->event_list[i]; hwc = &event->hw; -- cgit v0.10.2 From f3d46b2e6fa57547f9884330798792afc83f4b04 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Sat, 6 Mar 2010 13:24:58 +0100 Subject: perf, x86: Fix double enable calls hw_perf_enable() would enable already enabled events. This causes problems with code that assumes that ->enable/->disable calls are balanced (like the LBR code does). What happens is that events that were already running and left in place would get enabled again. Avoid this by only enabling new events that match their previous assignment. Signed-off-by: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: paulus@samba.org Cc: eranian@google.com Cc: robert.richter@amd.com Cc: fweisbec@gmail.com LKML-Reference: Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 045cc0b..1d665a0b 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -835,6 +835,10 @@ void hw_perf_enable(void) event = cpuc->event_list[i]; hwc = &event->hw; + if (i < n_running && + match_prev_assignment(hwc, cpuc, i)) + continue; + if (hwc->idx == -1) x86_assign_hw_event(event, cpuc, i); -- cgit v0.10.2 From d4944a06666054707d23e11888e480af239e5abf Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 8 Mar 2010 13:51:20 +0100 Subject: perf: Provide better condition for event rotation Try to avoid useless rotation and PMU disables. [ Could be improved by keeping a nr_runnable count to better account for the < PERF_STAT_INACTIVE counters ] Signed-off-by: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: paulus@samba.org Cc: eranian@google.com Cc: robert.richter@amd.com Cc: fweisbec@gmail.com LKML-Reference: Signed-off-by: Ingo Molnar diff --git a/kernel/perf_event.c b/kernel/perf_event.c index d810846..52c69a3 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c @@ -1524,12 +1524,15 @@ static void perf_ctx_adjust_freq(struct perf_event_context *ctx) */ if (interrupts == MAX_INTERRUPTS) { perf_log_throttle(event, 1); + perf_disable(); event->pmu->unthrottle(event); + perf_enable(); } if (!event->attr.freq || !event->attr.sample_freq) continue; + perf_disable(); event->pmu->read(event); now = atomic64_read(&event->count); delta = now - hwc->freq_count_stamp; @@ -1537,6 +1540,7 @@ static void perf_ctx_adjust_freq(struct perf_event_context *ctx) if (delta > 0) perf_adjust_period(event, TICK_NSEC, delta); + perf_enable(); } raw_spin_unlock(&ctx->lock); } @@ -1546,9 +1550,6 @@ static void perf_ctx_adjust_freq(struct perf_event_context *ctx) */ static void rotate_ctx(struct perf_event_context *ctx) { - if (!ctx->nr_events) - return; - raw_spin_lock(&ctx->lock); /* Rotate the first entry last of non-pinned groups */ @@ -1561,19 +1562,28 @@ void perf_event_task_tick(struct task_struct *curr) { struct perf_cpu_context *cpuctx; struct perf_event_context *ctx; + int rotate = 0; if (!atomic_read(&nr_events)) return; cpuctx = &__get_cpu_var(perf_cpu_context); - ctx = curr->perf_event_ctxp; + if (cpuctx->ctx.nr_events && + cpuctx->ctx.nr_events != cpuctx->ctx.nr_active) + rotate = 1; - perf_disable(); + ctx = curr->perf_event_ctxp; + if (ctx && ctx->nr_events && ctx->nr_events != ctx->nr_active) + rotate = 1; perf_ctx_adjust_freq(&cpuctx->ctx); if (ctx) perf_ctx_adjust_freq(ctx); + if (!rotate) + return; + + perf_disable(); cpu_ctx_sched_out(cpuctx, EVENT_FLEXIBLE); if (ctx) task_ctx_sched_out(ctx, EVENT_FLEXIBLE); @@ -1585,7 +1595,6 @@ void perf_event_task_tick(struct task_struct *curr) cpu_ctx_sched_in(cpuctx, EVENT_FLEXIBLE); if (ctx) task_ctx_sched_in(curr, EVENT_FLEXIBLE); - perf_enable(); } -- cgit v0.10.2 From 1224550969e0bf18785786a1a9f801cd86d68586 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 5 Mar 2010 11:54:02 -0300 Subject: perf tools: Don't trow away old map slices not overlapped by new maps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Arnaldo Carvalho de Melo Cc: David S. Miller Cc: Frédéric Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Paul Mackerras LKML-Reference: <1267800842-22324-1-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index 21b9216..9024fa1 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -183,8 +183,8 @@ struct thread *perf_session__findnew(struct perf_session *self, pid_t pid) return th; } -static void map_groups__remove_overlappings(struct map_groups *self, - struct map *map) +static int map_groups__fixup_overlappings(struct map_groups *self, + struct map *map) { struct rb_root *root = &self->maps[map->type]; struct rb_node *next = rb_first(root); @@ -209,7 +209,36 @@ static void map_groups__remove_overlappings(struct map_groups *self, * list. */ list_add_tail(&pos->node, &self->removed_maps[map->type]); + /* + * Now check if we need to create new maps for areas not + * overlapped by the new map: + */ + if (map->start > pos->start) { + struct map *before = map__clone(pos); + + if (before == NULL) + return -ENOMEM; + + before->end = map->start - 1; + map_groups__insert(self, before); + if (verbose >= 2) + map__fprintf(before, stderr); + } + + if (map->end < pos->end) { + struct map *after = map__clone(pos); + + if (after == NULL) + return -ENOMEM; + + after->start = map->end + 1; + map_groups__insert(self, after); + if (verbose >= 2) + map__fprintf(after, stderr); + } } + + return 0; } void maps__insert(struct rb_root *maps, struct map *map) @@ -254,7 +283,7 @@ struct map *maps__find(struct rb_root *maps, u64 ip) void thread__insert_map(struct thread *self, struct map *map) { - map_groups__remove_overlappings(&self->mg, map); + map_groups__fixup_overlappings(&self->mg, map); map_groups__insert(&self->mg, map); } -- cgit v0.10.2 From accd3cc45a0e1d11090ea66888405987de77bdca Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 5 Mar 2010 12:51:04 -0300 Subject: perf probe: Add missing variable initialization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cc1: warnings being treated as errors util/probe-finder.c: In function 'find_line_range': util/probe-finder.c:172: warning: 'src' may be used uninitialized in this function make: *** [util/probe-finder.o] Error 1 Signed-off-by: Arnaldo Carvalho de Melo Acked-by: Masami Hiramatsu Cc: Frédéric Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Paul Mackerras LKML-Reference: <1267804269-22660-1-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index e77dc88..1e6c65e 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -169,7 +169,7 @@ static const char *cu_find_realpath(Dwarf_Die *cu_die, const char *fname) { Dwarf_Files *files; size_t nfiles, i; - const char *src; + const char *src = NULL; int ret; if (!fname) -- cgit v0.10.2 From 8907fd607b66e36636469a2de9833db643869db8 Mon Sep 17 00:00:00 2001 From: Eric B Munson Date: Fri, 5 Mar 2010 12:51:05 -0300 Subject: perf record: Add ID and to recorded event data when recording multiple events Currently perf record does not write the ID or the to disk for events. This doesn't allow report to tell if an event stream contains one or more types of events. This patch adds this entry to the list of data that record will write to disk if more than one event was requested. Signed-off-by: Eric B Munson Signed-off-by: Arnaldo Carvalho de Melo Cc: Peter Zijlstra Cc: Paul Mackerras LKML-Reference: <1267804269-22660-2-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 771533c..f573bbb 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -244,6 +244,9 @@ static void create_counter(int counter, int cpu, pid_t pid) attr->sample_type |= PERF_SAMPLE_IP | PERF_SAMPLE_TID; + if (nr_counters > 1) + attr->sample_type |= PERF_SAMPLE_ID; + if (freq) { attr->sample_type |= PERF_SAMPLE_PERIOD; attr->freq = 1; -- cgit v0.10.2 From d403d0acc9c5afa679a3f61e71489530d7fa0606 Mon Sep 17 00:00:00 2001 From: Eric B Munson Date: Fri, 5 Mar 2010 12:51:06 -0300 Subject: perf session: Change add_hist_entry to take the tree root instead of session In order to minimize the impact of storing multiple events in a report this function will now take the root of the histogram tree so that the logic for selecting the proper tree can be inserted before the call. Signed-off-by: Eric B Munson Signed-off-by: Arnaldo Carvalho de Melo Cc: Peter Zijlstra Cc: Paul Mackerras LKML-Reference: <1267804269-22660-3-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 5ec5de9..4b734c7 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -116,7 +116,7 @@ static int perf_session__add_hist_entry(struct perf_session *self, return 0; } - he = __perf_session__add_hist_entry(self, al, NULL, count, &hit); + he = __perf_session__add_hist_entry(&self->hists, al, NULL, count, &hit); if (he == NULL) return -ENOMEM; diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 18b3f50..20df735 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -26,7 +26,8 @@ static int perf_session__add_hist_entry(struct perf_session *self, struct addr_location *al, u64 count) { bool hit; - struct hist_entry *he = __perf_session__add_hist_entry(self, al, NULL, + struct hist_entry *he = __perf_session__add_hist_entry(&self->hists, + al, NULL, count, &hit); if (he == NULL) return -ENOMEM; diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index cfc655d..cd16e6a 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -56,7 +56,8 @@ static int perf_session__add_hist_entry(struct perf_session *self, if ((sort__has_parent || symbol_conf.use_callchain) && chain) syms = perf_session__resolve_callchain(self, al->thread, chain, &parent); - he = __perf_session__add_hist_entry(self, al, parent, count, &hit); + he = __perf_session__add_hist_entry(&self->hists, al, parent, + count, &hit); if (he == NULL) return -ENOMEM; diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index e8daf5c..55dd911 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -12,12 +12,12 @@ struct callchain_param callchain_param = { * histogram, sorted on item, collects counts */ -struct hist_entry *__perf_session__add_hist_entry(struct perf_session *self, +struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists, struct addr_location *al, struct symbol *sym_parent, u64 count, bool *hit) { - struct rb_node **p = &self->hists.rb_node; + struct rb_node **p = &hists->rb_node; struct rb_node *parent = NULL; struct hist_entry *he; struct hist_entry entry = { @@ -53,7 +53,7 @@ struct hist_entry *__perf_session__add_hist_entry(struct perf_session *self, return NULL; *he = entry; rb_link_node(&he->rb_node, parent, p); - rb_insert_color(&he->rb_node, &self->hists); + rb_insert_color(&he->rb_node, hists); *hit = false; return he; } diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index e5f99b2..7b48590 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -10,8 +10,9 @@ struct perf_session; struct hist_entry; struct addr_location; struct symbol; +struct rb_root; -struct hist_entry *__perf_session__add_hist_entry(struct perf_session *self, +struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists, struct addr_location *al, struct symbol *parent, u64 count, bool *hit); -- cgit v0.10.2 From cb8f09393646c5058056db771583c86e0ed1d92f Mon Sep 17 00:00:00 2001 From: Eric B Munson Date: Fri, 5 Mar 2010 12:51:07 -0300 Subject: perf session: Add storage for seperating event types in report This patch adds the structures necessary to count each event type independently in perf report. Signed-off-by: Eric B Munson Signed-off-by: Arnaldo Carvalho de Melo Cc: Peter Zijlstra Cc: Paul Mackerras LKML-Reference: <1267804269-22660-4-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 50a7132..a33b949 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -99,6 +99,15 @@ struct events_stats { u64 lost; }; +struct event_stat_id { + struct rb_node rb_node; + struct rb_root hists; + struct events_stats stats; + u64 config; + u64 event_stream; + u32 type; +}; + void event__print_totals(void); struct perf_session; diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 0de7258..eed1cb8 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -70,6 +70,7 @@ struct perf_session *perf_session__new(const char *filename, int mode, bool forc memcpy(self->filename, filename, len); self->threads = RB_ROOT; + self->stats_by_id = RB_ROOT; self->last_match = NULL; self->mmap_window = 32; self->cwd = NULL; diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 31950fc..5c33417 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -20,6 +20,7 @@ struct perf_session { struct thread *last_match; struct map *vmlinux_maps[MAP__NR_TYPES]; struct events_stats events_stats; + struct rb_root stats_by_id; unsigned long event_total[PERF_RECORD_MAX]; unsigned long unknown_events; struct rb_root hists; -- cgit v0.10.2 From eefc465cdd49cb89a742083fac2807c718ddad31 Mon Sep 17 00:00:00 2001 From: Eric B Munson Date: Fri, 5 Mar 2010 12:51:08 -0300 Subject: perf session: Change perf_session post processing functions to take histogram tree Now that report can store historgrams for multiple events we need to be able to do the post processing work for each histogram. This patch changes the post processing functions so that they can be called individually for each event's histogram. Signed-off-by: Eric B Munson [ Guarantee bisectabilty by fixing up builtin-report.c ] Signed-off-by: Arnaldo Carvalho de Melo Cc: Peter Zijlstra Cc: Paul Mackerras LKML-Reference: <1267804269-22660-5-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 4b734c7..6ad7148 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -564,8 +564,8 @@ static int __cmd_annotate(void) if (verbose > 2) dsos__fprintf(stdout); - perf_session__collapse_resort(session); - perf_session__output_resort(session, session->event_total[0]); + perf_session__collapse_resort(&session->hists); + perf_session__output_resort(&session->hists, session->event_total[0]); perf_session__find_annotations(session); out_delete: perf_session__delete(session); diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 20df735..1ea15d8 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -115,7 +115,7 @@ static void perf_session__resort_hist_entries(struct perf_session *self) static void perf_session__set_hist_entries_positions(struct perf_session *self) { - perf_session__output_resort(self, self->events_stats.total); + perf_session__output_resort(&self->hists, self->events_stats.total); perf_session__resort_hist_entries(self); } @@ -167,13 +167,15 @@ static int __cmd_diff(void) goto out_delete; } - perf_session__output_resort(session[1], session[1]->events_stats.total); + perf_session__output_resort(&session[1]->hists, + session[1]->events_stats.total); if (show_displacement) perf_session__set_hist_entries_positions(session[0]); perf_session__match_hists(session[0], session[1]); - perf_session__fprintf_hists(session[1], session[0], - show_displacement, stdout); + perf_session__fprintf_hists(&session[1]->hists, session[0], + show_displacement, stdout, + session[1]->events_stats.total); out_delete: for (i = 0; i < 2; ++i) perf_session__delete(session[i]); diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index cd16e6a..294b4cf 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -225,10 +225,12 @@ static int __cmd_report(void) if (verbose > 2) dsos__fprintf(stdout); - perf_session__collapse_resort(session); - perf_session__output_resort(session, session->events_stats.total); + perf_session__collapse_resort(&session->hists); + perf_session__output_resort(&session->hists, + session->events_stats.total); fprintf(stdout, "# Samples: %Ld\n#\n", session->events_stats.total); - perf_session__fprintf_hists(session, NULL, false, stdout); + perf_session__fprintf_hists(&session->hists, NULL, false, stdout, + session->events_stats.total); if (sort_order == default_sort_order && parent_pattern == default_parent_pattern) fprintf(stdout, "#\n# (For a higher level overview, try: perf report --sort comm,dso)\n#\n"); diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 55dd911..73ebb6f 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -130,7 +130,7 @@ static void collapse__insert_entry(struct rb_root *root, struct hist_entry *he) rb_insert_color(&he->rb_node, root); } -void perf_session__collapse_resort(struct perf_session *self) +void perf_session__collapse_resort(struct rb_root *hists) { struct rb_root tmp; struct rb_node *next; @@ -140,17 +140,17 @@ void perf_session__collapse_resort(struct perf_session *self) return; tmp = RB_ROOT; - next = rb_first(&self->hists); + next = rb_first(hists); while (next) { n = rb_entry(next, struct hist_entry, rb_node); next = rb_next(&n->rb_node); - rb_erase(&n->rb_node, &self->hists); + rb_erase(&n->rb_node, hists); collapse__insert_entry(&tmp, n); } - self->hists = tmp; + *hists = tmp; } /* @@ -183,7 +183,7 @@ static void perf_session__insert_output_hist_entry(struct rb_root *root, rb_insert_color(&he->rb_node, root); } -void perf_session__output_resort(struct perf_session *self, u64 total_samples) +void perf_session__output_resort(struct rb_root *hists, u64 total_samples) { struct rb_root tmp; struct rb_node *next; @@ -194,18 +194,18 @@ void perf_session__output_resort(struct perf_session *self, u64 total_samples) total_samples * (callchain_param.min_percent / 100); tmp = RB_ROOT; - next = rb_first(&self->hists); + next = rb_first(hists); while (next) { n = rb_entry(next, struct hist_entry, rb_node); next = rb_next(&n->rb_node); - rb_erase(&n->rb_node, &self->hists); + rb_erase(&n->rb_node, hists); perf_session__insert_output_hist_entry(&tmp, n, min_callchain_hits); } - self->hists = tmp; + *hists = tmp; } static size_t callchain__fprintf_left_margin(FILE *fp, int left_margin) @@ -456,10 +456,10 @@ static size_t hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self, } static size_t hist_entry__fprintf(struct hist_entry *self, - struct perf_session *session, struct perf_session *pair_session, bool show_displacement, - long displacement, FILE *fp) + long displacement, FILE *fp, + u64 session_total) { struct sort_entry *se; u64 count, total; @@ -474,7 +474,7 @@ static size_t hist_entry__fprintf(struct hist_entry *self, total = pair_session->events_stats.total; } else { count = self->count; - total = session->events_stats.total; + total = session_total; } if (total) @@ -496,8 +496,8 @@ static size_t hist_entry__fprintf(struct hist_entry *self, if (total > 0) old_percent = (count * 100.0) / total; - if (session->events_stats.total > 0) - new_percent = (self->count * 100.0) / session->events_stats.total; + if (session_total > 0) + new_percent = (self->count * 100.0) / session_total; diff = new_percent - old_percent; @@ -544,16 +544,17 @@ static size_t hist_entry__fprintf(struct hist_entry *self, left_margin -= thread__comm_len(self->thread); } - hist_entry_callchain__fprintf(fp, self, session->events_stats.total, + hist_entry_callchain__fprintf(fp, self, session_total, left_margin); } return ret; } -size_t perf_session__fprintf_hists(struct perf_session *self, +size_t perf_session__fprintf_hists(struct rb_root *hists, struct perf_session *pair, - bool show_displacement, FILE *fp) + bool show_displacement, FILE *fp, + u64 session_total) { struct sort_entry *se; struct rb_node *nd; @@ -641,7 +642,7 @@ size_t perf_session__fprintf_hists(struct perf_session *self, fprintf(fp, "\n#\n"); print_entries: - for (nd = rb_first(&self->hists); nd; nd = rb_next(nd)) { + for (nd = rb_first(hists); nd; nd = rb_next(nd)) { struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); if (show_displacement) { @@ -652,8 +653,8 @@ print_entries: displacement = 0; ++position; } - ret += hist_entry__fprintf(h, self, pair, show_displacement, - displacement, fp); + ret += hist_entry__fprintf(h, pair, show_displacement, + displacement, fp, session_total); } free(rem_sq_bracket); diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 7b48590..16f360c 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -20,9 +20,10 @@ extern int64_t hist_entry__cmp(struct hist_entry *, struct hist_entry *); extern int64_t hist_entry__collapse(struct hist_entry *, struct hist_entry *); void hist_entry__free(struct hist_entry *); -void perf_session__output_resort(struct perf_session *self, u64 total_samples); -void perf_session__collapse_resort(struct perf_session *self); -size_t perf_session__fprintf_hists(struct perf_session *self, +void perf_session__output_resort(struct rb_root *hists, u64 total_samples); +void perf_session__collapse_resort(struct rb_root *hists); +size_t perf_session__fprintf_hists(struct rb_root *hists, struct perf_session *pair, - bool show_displacement, FILE *fp); + bool show_displacement, FILE *fp, + u64 session_total); #endif /* __PERF_HIST_H */ -- cgit v0.10.2 From cbbc79a53278b83bf7f834127751459f9299e402 Mon Sep 17 00:00:00 2001 From: Eric B Munson Date: Fri, 5 Mar 2010 12:51:09 -0300 Subject: perf report: Add multiple event support Perf report does not handle multiple events being reported, even though perf record stores them properly on disk. This patch addresses that issue by adding the logic to perf report to use the event stream id that is saved by record and the new data structures to seperate the event streams and report them individually. Signed-off-by: Eric B Munson Signed-off-by: Arnaldo Carvalho de Melo Cc: Peter Zijlstra Cc: Paul Mackerras LKML-Reference: <1267804269-22660-6-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 294b4cf..f815de2 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -45,29 +45,71 @@ static char *pretty_printing_style = default_pretty_printing_style; static char callchain_default_opt[] = "fractal,0.5"; +static struct event_stat_id *get_stats(struct perf_session *self, + u64 event_stream, u32 type, u64 config) +{ + struct rb_node **p = &self->stats_by_id.rb_node; + struct rb_node *parent = NULL; + struct event_stat_id *iter, *new; + + while (*p != NULL) { + parent = *p; + iter = rb_entry(parent, struct event_stat_id, rb_node); + if (iter->config == config) + return iter; + + + if (config > iter->config) + p = &(*p)->rb_right; + else + p = &(*p)->rb_left; + } + + new = malloc(sizeof(struct event_stat_id)); + if (new == NULL) + return NULL; + memset(new, 0, sizeof(struct event_stat_id)); + new->event_stream = event_stream; + new->config = config; + new->type = type; + rb_link_node(&new->rb_node, parent, p); + rb_insert_color(&new->rb_node, &self->stats_by_id); + return new; +} + static int perf_session__add_hist_entry(struct perf_session *self, struct addr_location *al, - struct ip_callchain *chain, u64 count) + struct sample_data *data) { struct symbol **syms = NULL, *parent = NULL; bool hit; struct hist_entry *he; + struct event_stat_id *stats; + struct perf_event_attr *attr; - if ((sort__has_parent || symbol_conf.use_callchain) && chain) + if ((sort__has_parent || symbol_conf.use_callchain) && data->callchain) syms = perf_session__resolve_callchain(self, al->thread, - chain, &parent); - he = __perf_session__add_hist_entry(&self->hists, al, parent, - count, &hit); + data->callchain, &parent); + + attr = perf_header__find_attr(data->id, &self->header); + if (attr) + stats = get_stats(self, data->id, attr->type, attr->config); + else + stats = get_stats(self, data->id, 0, 0); + if (stats == NULL) + return -ENOMEM; + he = __perf_session__add_hist_entry(&stats->hists, al, parent, + data->period, &hit); if (he == NULL) return -ENOMEM; if (hit) - he->count += count; + he->count += data->period; if (symbol_conf.use_callchain) { if (!hit) callchain_init(&he->callchain); - append_chain(&he->callchain, chain, syms); + append_chain(&he->callchain, data->callchain, syms); free(syms); } @@ -87,10 +129,30 @@ static int validate_chain(struct ip_callchain *chain, event_t *event) return 0; } +static int add_event_total(struct perf_session *session, + struct sample_data *data, + struct perf_event_attr *attr) +{ + struct event_stat_id *stats; + + if (attr) + stats = get_stats(session, data->id, attr->type, attr->config); + else + stats = get_stats(session, data->id, 0, 0); + + if (!stats) + return -ENOMEM; + + stats->stats.total += data->period; + session->events_stats.total += data->period; + return 0; +} + static int process_sample_event(event_t *event, struct perf_session *session) { struct sample_data data = { .period = 1, }; struct addr_location al; + struct perf_event_attr *attr; event__parse_sample(event, session->sample_type, &data); @@ -124,12 +186,18 @@ static int process_sample_event(event_t *event, struct perf_session *session) if (al.filtered || (hide_unresolved && al.sym == NULL)) return 0; - if (perf_session__add_hist_entry(session, &al, data.callchain, data.period)) { + if (perf_session__add_hist_entry(session, &al, &data)) { pr_debug("problem incrementing symbol count, skipping event\n"); return -1; } - session->events_stats.total += data.period; + attr = perf_header__find_attr(data.id, &session->header); + + if (add_event_total(session, &data, attr)) { + pr_debug("problem adding event count\n"); + return -1; + } + return 0; } @@ -198,6 +266,7 @@ static int __cmd_report(void) { int ret = -EINVAL; struct perf_session *session; + struct rb_node *next; session = perf_session__new(input_name, O_RDONLY, force); if (session == NULL) @@ -225,12 +294,28 @@ static int __cmd_report(void) if (verbose > 2) dsos__fprintf(stdout); - perf_session__collapse_resort(&session->hists); - perf_session__output_resort(&session->hists, - session->events_stats.total); - fprintf(stdout, "# Samples: %Ld\n#\n", session->events_stats.total); - perf_session__fprintf_hists(&session->hists, NULL, false, stdout, - session->events_stats.total); + next = rb_first(&session->stats_by_id); + while (next) { + struct event_stat_id *stats; + + stats = rb_entry(next, struct event_stat_id, rb_node); + perf_session__collapse_resort(&stats->hists); + perf_session__output_resort(&stats->hists, stats->stats.total); + if (rb_first(&session->stats_by_id) == + rb_last(&session->stats_by_id)) + fprintf(stdout, "# Samples: %Ld\n#\n", + stats->stats.total); + else + fprintf(stdout, "# Samples: %Ld %s\n#\n", + stats->stats.total, + __event_name(stats->type, stats->config)); + + perf_session__fprintf_hists(&stats->hists, NULL, false, stdout, + stats->stats.total); + fprintf(stdout, "\n\n"); + next = rb_next(&stats->rb_node); + } + if (sort_order == default_sort_order && parent_pattern == default_parent_pattern) fprintf(stdout, "#\n# (For a higher level overview, try: perf report --sort comm,dso)\n#\n"); -- cgit v0.10.2 From 65f2ed2b2fa6034ef9890b60c8fd39fbe76b9d37 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 9 Mar 2010 15:58:17 -0300 Subject: perf report: Print the map table just after samples for which no map was found MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If -vv is used just the map table will be printed, -vvv will print the symbol table too, with it we can see that we have a bug where some samples are not being resolved to a map when we get them in the perf.data stream, but after we have it all processed, we can find the right map, some reordering probably is happening. Upcoming patches will provide ways to ask for most PERF_SAMPLE_ conditional samples to be taken for !PERF_RECORD_SAMPLE events too, then we'll be able to ask for PERF_SAMPLE_TIME and PERF_SAMPLE_CPU to help diagnose this. Signed-off-by: Arnaldo Carvalho de Melo Cc: Frédéric Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Paul Mackerras LKML-Reference: <1268161097-17761-1-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 73ebb6f..bdcfd61 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -655,6 +655,11 @@ print_entries: } ret += hist_entry__fprintf(h, pair, show_displacement, displacement, fp, session_total); + if (h->map == NULL && verbose > 1) { + __map_groups__fprintf_maps(&h->thread->mg, + MAP__FUNCTION, fp); + fprintf(fp, "%.10s end\n", graph_dotted_line); + } } free(rem_sq_bracket); diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index 9024fa1..fa96831 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -79,8 +79,8 @@ int thread__comm_len(struct thread *self) return self->comm_len; } -static size_t __map_groups__fprintf_maps(struct map_groups *self, - enum map_type type, FILE *fp) +size_t __map_groups__fprintf_maps(struct map_groups *self, + enum map_type type, FILE *fp) { size_t printed = fprintf(fp, "%s:\n", map_type__name[type]); struct rb_node *nd; @@ -89,7 +89,7 @@ static size_t __map_groups__fprintf_maps(struct map_groups *self, struct map *pos = rb_entry(nd, struct map, rb_node); printed += fprintf(fp, "Map:"); printed += map__fprintf(pos, fp); - if (verbose > 1) { + if (verbose > 2) { printed += dso__fprintf(pos->dso, type, fp); printed += fprintf(fp, "--\n"); } diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h index 0a28f39..dcf7030 100644 --- a/tools/perf/util/thread.h +++ b/tools/perf/util/thread.h @@ -10,6 +10,9 @@ struct map_groups { struct list_head removed_maps[MAP__NR_TYPES]; }; +size_t __map_groups__fprintf_maps(struct map_groups *self, + enum map_type type, FILE *fp); + struct thread { struct rb_node rb_node; struct map_groups mg; -- cgit v0.10.2 From db2c4c7791cd04512093d05afc693c3511a65fd7 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Tue, 2 Feb 2010 23:34:40 +0100 Subject: lockdep: Move lock events under lockdep recursion protection There are rcu locked read side areas in the path where we submit a trace event. And these rcu_read_(un)lock() trigger lock events, which create recursive events. One pair in do_perf_sw_event: __lock_acquire | |--96.11%-- lock_acquire | | | |--27.21%-- do_perf_sw_event | | perf_tp_event | | | | | |--49.62%-- ftrace_profile_lock_release | | | lock_release | | | | | | | |--33.85%-- _raw_spin_unlock Another pair in perf_output_begin/end: __lock_acquire |--23.40%-- perf_output_begin | | __perf_event_overflow | | perf_swevent_overflow | | perf_swevent_add | | perf_swevent_ctx_event | | do_perf_sw_event | | perf_tp_event | | | | | |--55.37%-- ftrace_profile_lock_acquire | | | lock_acquire | | | | | | | |--37.31%-- _raw_spin_lock The problem is not that much the trace recursion itself, as we have a recursion protection already (though it's always wasteful to recurse). But the trace events are outside the lockdep recursion protection, then each lockdep event triggers a lock trace, which will trigger two other lockdep events. Here the recursive lock trace event won't be taken because of the trace recursion, so the recursion stops there but lockdep will still analyse these new events: To sum up, for each lockdep events we have: lock_*() | trace lock_acquire | ----- rcu_read_lock() | | | lock_acquire() | | | trace_lock_acquire() (stopped) | | | lockdep analyze | ----- rcu_read_unlock() | lock_release | trace_lock_release() (stopped) | lockdep analyze And you can repeat the above two times as we have two rcu read side sections when we submit an event. This is fixed in this patch by moving the lock trace event under the lockdep recursion protection. Signed-off-by: Frederic Weisbecker Cc: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: Steven Rostedt Cc: Paul Mackerras Cc: Hitoshi Mitake Cc: Li Zefan Cc: Lai Jiangshan Cc: Masami Hiramatsu Cc: Jens Axboe diff --git a/kernel/lockdep.c b/kernel/lockdep.c index 0c30d04..65b5f5b 100644 --- a/kernel/lockdep.c +++ b/kernel/lockdep.c @@ -3211,8 +3211,6 @@ void lock_acquire(struct lockdep_map *lock, unsigned int subclass, { unsigned long flags; - trace_lock_acquire(lock, subclass, trylock, read, check, nest_lock, ip); - if (unlikely(current->lockdep_recursion)) return; @@ -3220,6 +3218,7 @@ void lock_acquire(struct lockdep_map *lock, unsigned int subclass, check_flags(flags); current->lockdep_recursion = 1; + trace_lock_acquire(lock, subclass, trylock, read, check, nest_lock, ip); __lock_acquire(lock, subclass, trylock, read, check, irqs_disabled_flags(flags), nest_lock, ip, 0); current->lockdep_recursion = 0; @@ -3232,14 +3231,13 @@ void lock_release(struct lockdep_map *lock, int nested, { unsigned long flags; - trace_lock_release(lock, nested, ip); - if (unlikely(current->lockdep_recursion)) return; raw_local_irq_save(flags); check_flags(flags); current->lockdep_recursion = 1; + trace_lock_release(lock, nested, ip); __lock_release(lock, nested, ip); current->lockdep_recursion = 0; raw_local_irq_restore(flags); @@ -3413,8 +3411,6 @@ void lock_contended(struct lockdep_map *lock, unsigned long ip) { unsigned long flags; - trace_lock_contended(lock, ip); - if (unlikely(!lock_stat)) return; @@ -3424,6 +3420,7 @@ void lock_contended(struct lockdep_map *lock, unsigned long ip) raw_local_irq_save(flags); check_flags(flags); current->lockdep_recursion = 1; + trace_lock_contended(lock, ip); __lock_contended(lock, ip); current->lockdep_recursion = 0; raw_local_irq_restore(flags); -- cgit v0.10.2 From 61e67fb9d3ed13e6a7f58652ae4979b9c872fa57 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Wed, 3 Mar 2010 07:38:37 +0100 Subject: perf/x86-64: Use frame pointer to walk on irq and process stacks We were using the frame pointer based stack walker on every contexts in x86-32, but not in x86-64 where we only use the seven-league boots on the exception stacks. Use it also on irq and process stacks. This utterly accelerate the captures. Signed-off-by: Frederic Weisbecker Cc: Ingo Molnar Cc: Peter Zijlstra Cc: Paul Mackerras Cc: Arnaldo Carvalho de Melo diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c index d5e2a2e..272c9f1 100644 --- a/arch/x86/kernel/dumpstack_64.c +++ b/arch/x86/kernel/dumpstack_64.c @@ -208,7 +208,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, if (in_irq_stack(stack, irq_stack, irq_stack_end)) { if (ops->stack(data, "IRQ") < 0) break; - bp = print_context_stack(tinfo, stack, bp, + bp = ops->walk_stack(tinfo, stack, bp, ops, data, irq_stack_end, &graph); /* * We link to the next stack (which would be @@ -229,7 +229,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, /* * This handles the process stack: */ - bp = print_context_stack(tinfo, stack, bp, ops, data, NULL, &graph); + bp = ops->walk_stack(tinfo, stack, bp, ops, data, NULL, &graph); put_cpu(); } EXPORT_SYMBOL(dump_trace); -- cgit v0.10.2 From 5331d7b84613b8325362dde53dc2bff2fb87d351 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Thu, 4 Mar 2010 21:15:56 +0100 Subject: perf: Introduce new perf_fetch_caller_regs() for hot regs snapshot Events that trigger overflows by interrupting a context can use get_irq_regs() or task_pt_regs() to retrieve the state when the event triggered. But this is not the case for some other class of events like trace events as tracepoints are executed in the same context than the code that triggered the event. It means we need a different api to capture the regs there, namely we need a hot snapshot to get the most important informations for perf: the instruction pointer to get the event origin, the frame pointer for the callchain, the code segment for user_mode() tests (we always use __KERNEL_CS as trace events always occur from the kernel) and the eflags for further purposes. v2: rename perf_save_regs to perf_fetch_caller_regs as per Masami's suggestion. Signed-off-by: Frederic Weisbecker Cc: Ingo Molnar Cc: Thomas Gleixner Cc: H. Peter Anvin Cc: Peter Zijlstra Cc: Paul Mackerras Cc: Steven Rostedt Cc: Arnaldo Carvalho de Melo Cc: Masami Hiramatsu Cc: Jason Baron Cc: Archs diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 1d665a0b..c6bde7d 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -1707,3 +1707,15 @@ struct perf_callchain_entry *perf_callchain(struct pt_regs *regs) return entry; } + +void perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int skip) +{ + regs->ip = ip; + /* + * perf_arch_fetch_caller_regs adds another call, we need to increment + * the skip level + */ + regs->bp = rewind_frame_pointer(skip + 1); + regs->cs = __KERNEL_CS; + local_save_flags(regs->flags); +} diff --git a/arch/x86/kernel/dumpstack.h b/arch/x86/kernel/dumpstack.h index 4fd1420..29e5f7c 100644 --- a/arch/x86/kernel/dumpstack.h +++ b/arch/x86/kernel/dumpstack.h @@ -29,4 +29,19 @@ struct stack_frame { struct stack_frame *next_frame; unsigned long return_address; }; + +static inline unsigned long rewind_frame_pointer(int n) +{ + struct stack_frame *frame; + + get_bp(frame); + +#ifdef CONFIG_FRAME_POINTER + while (n--) + frame = frame->next_frame; #endif + + return (unsigned long)frame; +} + +#endif /* DUMPSTACK_H */ diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 80acbf3..70cffd0 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -452,6 +452,7 @@ enum perf_callchain_context { #include #include #include +#include #include #define PERF_MAX_STACK_DEPTH 255 @@ -847,6 +848,44 @@ perf_sw_event(u32 event_id, u64 nr, int nmi, struct pt_regs *regs, u64 addr) __perf_sw_event(event_id, nr, nmi, regs, addr); } +extern void +perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int skip); + +/* + * Take a snapshot of the regs. Skip ip and frame pointer to + * the nth caller. We only need a few of the regs: + * - ip for PERF_SAMPLE_IP + * - cs for user_mode() tests + * - bp for callchains + * - eflags, for future purposes, just in case + */ +static inline void perf_fetch_caller_regs(struct pt_regs *regs, int skip) +{ + unsigned long ip; + + memset(regs, 0, sizeof(*regs)); + + switch (skip) { + case 1 : + ip = CALLER_ADDR0; + break; + case 2 : + ip = CALLER_ADDR1; + break; + case 3 : + ip = CALLER_ADDR2; + break; + case 4: + ip = CALLER_ADDR3; + break; + /* No need to support further for now */ + default: + ip = 0; + } + + return perf_arch_fetch_caller_regs(regs, ip, skip); +} + extern void __perf_event_mmap(struct vm_area_struct *vma); static inline void perf_event_mmap(struct vm_area_struct *vma) @@ -880,7 +919,8 @@ static inline bool perf_paranoid_kernel(void) } extern void perf_event_init(void); -extern void perf_tp_event(int event_id, u64 addr, u64 count, void *record, int entry_size); +extern void perf_tp_event(int event_id, u64 addr, u64 count, void *record, + int entry_size, struct pt_regs *regs); extern void perf_bp_event(struct perf_event *event, void *data); #ifndef perf_misc_flags diff --git a/kernel/perf_event.c b/kernel/perf_event.c index 52c69a3..359d7f6 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c @@ -2786,6 +2786,11 @@ __weak struct perf_callchain_entry *perf_callchain(struct pt_regs *regs) return NULL; } +__weak +void perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int skip) +{ +} + /* * Output */ -- cgit v0.10.2 From c530665c31c0140b74ca7689e7f836177796e5bd Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Wed, 3 Mar 2010 07:16:16 +0100 Subject: perf: Take a hot regs snapshot for trace events We are taking a wrong regs snapshot when a trace event triggers. Either we use get_irq_regs(), which gives us the interrupted registers if we are in an interrupt, or we use task_pt_regs() which gives us the state before we entered the kernel, assuming we are lucky enough to be no kernel thread, in which case task_pt_regs() returns the initial set of regs when the kernel thread was started. What we want is different. We need a hot snapshot of the regs, so that we can get the instruction pointer to record in the sample, the frame pointer for the callchain, and some other things. Let's use the new perf_fetch_caller_regs() for that. Comparison with perf record -e lock: -R -a -f -g Before: perf [kernel] [k] __do_softirq | --- __do_softirq | |--55.16%-- __open | --44.84%-- __write_nocancel After: perf [kernel] [k] perf_tp_event | --- perf_tp_event | |--41.07%-- lock_acquire | | | |--39.36%-- _raw_spin_lock | | | | | |--7.81%-- hrtimer_interrupt | | | smp_apic_timer_interrupt | | | apic_timer_interrupt The old case was producing unreliable callchains. Now having right frame and instruction pointers, we have the trace we want. Also syscalls and kprobe events already have the right regs, let's use them instead of wasting a retrieval. v2: Follow the rename perf_save_regs() -> perf_fetch_caller_regs() Signed-off-by: Frederic Weisbecker Cc: Ingo Molnar Cc: Thomas Gleixner Cc: H. Peter Anvin Cc: Peter Zijlstra Cc: Paul Mackerras Cc: Steven Rostedt Cc: Arnaldo Carvalho de Melo Cc: Masami Hiramatsu Cc: Jason Baron Cc: Archs diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index 6b7c444..ac424f1 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h @@ -187,6 +187,9 @@ do { \ #ifdef CONFIG_PERF_EVENTS struct perf_event; + +DECLARE_PER_CPU(struct pt_regs, perf_trace_regs); + extern int ftrace_profile_enable(int event_id); extern void ftrace_profile_disable(int event_id); extern int ftrace_profile_set_filter(struct perf_event *event, int event_id, @@ -198,11 +201,11 @@ ftrace_perf_buf_prepare(int size, unsigned short type, int *rctxp, static inline void ftrace_perf_buf_submit(void *raw_data, int size, int rctx, u64 addr, - u64 count, unsigned long irq_flags) + u64 count, unsigned long irq_flags, struct pt_regs *regs) { struct trace_entry *entry = raw_data; - perf_tp_event(entry->type, addr, count, raw_data, size); + perf_tp_event(entry->type, addr, count, raw_data, size, regs); perf_swevent_put_recursion_context(rctx); local_irq_restore(irq_flags); } diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h index 0804cd5..f31bb8b 100644 --- a/include/trace/ftrace.h +++ b/include/trace/ftrace.h @@ -764,6 +764,7 @@ ftrace_profile_templ_##call(struct ftrace_event_call *event_call, \ struct ftrace_raw_##call *entry; \ u64 __addr = 0, __count = 1; \ unsigned long irq_flags; \ + struct pt_regs *__regs; \ int __entry_size; \ int __data_size; \ int rctx; \ @@ -784,8 +785,11 @@ ftrace_profile_templ_##call(struct ftrace_event_call *event_call, \ \ { assign; } \ \ + __regs = &__get_cpu_var(perf_trace_regs); \ + perf_fetch_caller_regs(__regs, 2); \ + \ ftrace_perf_buf_submit(entry, __entry_size, rctx, __addr, \ - __count, irq_flags); \ + __count, irq_flags, __regs); \ } #undef DEFINE_EVENT diff --git a/kernel/perf_event.c b/kernel/perf_event.c index 359d7f6..45b4b6e 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c @@ -4318,9 +4318,8 @@ static const struct pmu perf_ops_task_clock = { #ifdef CONFIG_EVENT_TRACING void perf_tp_event(int event_id, u64 addr, u64 count, void *record, - int entry_size) + int entry_size, struct pt_regs *regs) { - struct pt_regs *regs = get_irq_regs(); struct perf_sample_data data; struct perf_raw_record raw = { .size = entry_size, @@ -4330,12 +4329,9 @@ void perf_tp_event(int event_id, u64 addr, u64 count, void *record, perf_sample_data_init(&data, addr); data.raw = &raw; - if (!regs) - regs = task_pt_regs(current); - /* Trace events already protected against recursion */ do_perf_sw_event(PERF_TYPE_TRACEPOINT, event_id, count, 1, - &data, regs); + &data, regs); } EXPORT_SYMBOL_GPL(perf_tp_event); diff --git a/kernel/trace/trace_event_profile.c b/kernel/trace/trace_event_profile.c index f0d6930..e66d21e 100644 --- a/kernel/trace/trace_event_profile.c +++ b/kernel/trace/trace_event_profile.c @@ -2,13 +2,14 @@ * trace event based perf counter profiling * * Copyright (C) 2009 Red Hat Inc, Peter Zijlstra - * + * Copyright (C) 2009-2010 Frederic Weisbecker */ #include #include #include "trace.h" +DEFINE_PER_CPU(struct pt_regs, perf_trace_regs); static char *perf_trace_buf; static char *perf_trace_buf_nmi; diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 505c922..f7a20a8 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -1240,7 +1240,7 @@ static __kprobes void kprobe_profile_func(struct kprobe *kp, for (i = 0; i < tp->nr_args; i++) entry->args[i] = call_fetch(&tp->args[i].fetch, regs); - ftrace_perf_buf_submit(entry, size, rctx, entry->ip, 1, irq_flags); + ftrace_perf_buf_submit(entry, size, rctx, entry->ip, 1, irq_flags, regs); } /* Kretprobe profile handler */ @@ -1271,7 +1271,8 @@ static __kprobes void kretprobe_profile_func(struct kretprobe_instance *ri, for (i = 0; i < tp->nr_args; i++) entry->args[i] = call_fetch(&tp->args[i].fetch, regs); - ftrace_perf_buf_submit(entry, size, rctx, entry->ret_ip, 1, irq_flags); + ftrace_perf_buf_submit(entry, size, rctx, entry->ret_ip, 1, + irq_flags, regs); } static int probe_profile_enable(struct ftrace_event_call *call) diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c index cba47d7..7e6e84f 100644 --- a/kernel/trace/trace_syscalls.c +++ b/kernel/trace/trace_syscalls.c @@ -467,7 +467,7 @@ static void prof_syscall_enter(struct pt_regs *regs, long id) rec->nr = syscall_nr; syscall_get_arguments(current, regs, 0, sys_data->nb_args, (unsigned long *)&rec->args); - ftrace_perf_buf_submit(rec, size, rctx, 0, 1, flags); + ftrace_perf_buf_submit(rec, size, rctx, 0, 1, flags, regs); } int prof_sysenter_enable(struct ftrace_event_call *call) @@ -542,7 +542,7 @@ static void prof_syscall_exit(struct pt_regs *regs, long ret) rec->nr = syscall_nr; rec->ret = syscall_get_return_value(current, regs); - ftrace_perf_buf_submit(rec, size, rctx, 0, 1, flags); + ftrace_perf_buf_submit(rec, size, rctx, 0, 1, flags, regs); } int prof_sysexit_enable(struct ftrace_event_call *call) -- cgit v0.10.2 From 97d5a22005f38057b4bc0d95f81cd26510268794 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Fri, 5 Mar 2010 05:35:37 +0100 Subject: perf: Drop the obsolete profile naming for trace events Drop the obsolete "profile" naming used by perf for trace events. Perf can now do more than simple events counting, so generalize the API naming. Signed-off-by: Frederic Weisbecker Cc: Ingo Molnar Cc: Peter Zijlstra Cc: Paul Mackerras Cc: Steven Rostedt Cc: Masami Hiramatsu Cc: Jason Baron diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index ac424f1..c0f4b36 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h @@ -131,12 +131,12 @@ struct ftrace_event_call { void *mod; void *data; - int profile_count; - int (*profile_enable)(struct ftrace_event_call *); - void (*profile_disable)(struct ftrace_event_call *); + int perf_refcount; + int (*perf_event_enable)(struct ftrace_event_call *); + void (*perf_event_disable)(struct ftrace_event_call *); }; -#define FTRACE_MAX_PROFILE_SIZE 2048 +#define PERF_MAX_TRACE_SIZE 2048 #define MAX_FILTER_PRED 32 #define MAX_FILTER_STR_VAL 256 /* Should handle KSYM_SYMBOL_LEN */ @@ -190,17 +190,17 @@ struct perf_event; DECLARE_PER_CPU(struct pt_regs, perf_trace_regs); -extern int ftrace_profile_enable(int event_id); -extern void ftrace_profile_disable(int event_id); +extern int perf_trace_enable(int event_id); +extern void perf_trace_disable(int event_id); extern int ftrace_profile_set_filter(struct perf_event *event, int event_id, char *filter_str); extern void ftrace_profile_free_filter(struct perf_event *event); extern void * -ftrace_perf_buf_prepare(int size, unsigned short type, int *rctxp, +perf_trace_buf_prepare(int size, unsigned short type, int *rctxp, unsigned long *irq_flags); static inline void -ftrace_perf_buf_submit(void *raw_data, int size, int rctx, u64 addr, +perf_trace_buf_submit(void *raw_data, int size, int rctx, u64 addr, u64 count, unsigned long irq_flags, struct pt_regs *regs) { struct trace_entry *entry = raw_data; diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 8126f23..51435bc 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -101,18 +101,18 @@ struct perf_event_attr; #ifdef CONFIG_PERF_EVENTS -#define TRACE_SYS_ENTER_PROFILE_INIT(sname) \ - .profile_enable = prof_sysenter_enable, \ - .profile_disable = prof_sysenter_disable, +#define TRACE_SYS_ENTER_PERF_INIT(sname) \ + .perf_event_enable = perf_sysenter_enable, \ + .perf_event_disable = perf_sysenter_disable, -#define TRACE_SYS_EXIT_PROFILE_INIT(sname) \ - .profile_enable = prof_sysexit_enable, \ - .profile_disable = prof_sysexit_disable, +#define TRACE_SYS_EXIT_PERF_INIT(sname) \ + .perf_event_enable = perf_sysexit_enable, \ + .perf_event_disable = perf_sysexit_disable, #else -#define TRACE_SYS_ENTER_PROFILE(sname) -#define TRACE_SYS_ENTER_PROFILE_INIT(sname) -#define TRACE_SYS_EXIT_PROFILE(sname) -#define TRACE_SYS_EXIT_PROFILE_INIT(sname) +#define TRACE_SYS_ENTER_PERF(sname) +#define TRACE_SYS_ENTER_PERF_INIT(sname) +#define TRACE_SYS_EXIT_PERF(sname) +#define TRACE_SYS_EXIT_PERF_INIT(sname) #endif /* CONFIG_PERF_EVENTS */ #ifdef CONFIG_FTRACE_SYSCALLS @@ -149,7 +149,7 @@ struct perf_event_attr; .regfunc = reg_event_syscall_enter, \ .unregfunc = unreg_event_syscall_enter, \ .data = (void *)&__syscall_meta_##sname,\ - TRACE_SYS_ENTER_PROFILE_INIT(sname) \ + TRACE_SYS_ENTER_PERF_INIT(sname) \ } #define SYSCALL_TRACE_EXIT_EVENT(sname) \ @@ -171,7 +171,7 @@ struct perf_event_attr; .regfunc = reg_event_syscall_exit, \ .unregfunc = unreg_event_syscall_exit, \ .data = (void *)&__syscall_meta_##sname,\ - TRACE_SYS_EXIT_PROFILE_INIT(sname) \ + TRACE_SYS_EXIT_PERF_INIT(sname) \ } #define SYSCALL_METADATA(sname, nb) \ diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h index f31bb8b..25ab56f 100644 --- a/include/trace/ftrace.h +++ b/include/trace/ftrace.h @@ -401,18 +401,18 @@ static inline notrace int ftrace_get_offsets_##call( \ #undef DEFINE_EVENT #define DEFINE_EVENT(template, name, proto, args) \ \ -static void ftrace_profile_##name(proto); \ +static void perf_trace_##name(proto); \ \ static notrace int \ -ftrace_profile_enable_##name(struct ftrace_event_call *unused) \ +perf_trace_enable_##name(struct ftrace_event_call *unused) \ { \ - return register_trace_##name(ftrace_profile_##name); \ + return register_trace_##name(perf_trace_##name); \ } \ \ static notrace void \ -ftrace_profile_disable_##name(struct ftrace_event_call *unused) \ +perf_trace_disable_##name(struct ftrace_event_call *unused) \ { \ - unregister_trace_##name(ftrace_profile_##name); \ + unregister_trace_##name(perf_trace_##name); \ } #undef DEFINE_EVENT_PRINT @@ -507,12 +507,12 @@ ftrace_profile_disable_##name(struct ftrace_event_call *unused) \ #ifdef CONFIG_PERF_EVENTS -#define _TRACE_PROFILE_INIT(call) \ - .profile_enable = ftrace_profile_enable_##call, \ - .profile_disable = ftrace_profile_disable_##call, +#define _TRACE_PERF_INIT(call) \ + .perf_event_enable = perf_trace_enable_##call, \ + .perf_event_disable = perf_trace_disable_##call, #else -#define _TRACE_PROFILE_INIT(call) +#define _TRACE_PERF_INIT(call) #endif /* CONFIG_PERF_EVENTS */ #undef __entry @@ -638,7 +638,7 @@ __attribute__((section("_ftrace_events"))) event_##call = { \ .unregfunc = ftrace_raw_unreg_event_##call, \ .print_fmt = print_fmt_##template, \ .define_fields = ftrace_define_fields_##template, \ - _TRACE_PROFILE_INIT(call) \ + _TRACE_PERF_INIT(call) \ } #undef DEFINE_EVENT_PRINT @@ -657,18 +657,18 @@ __attribute__((section("_ftrace_events"))) event_##call = { \ .unregfunc = ftrace_raw_unreg_event_##call, \ .print_fmt = print_fmt_##call, \ .define_fields = ftrace_define_fields_##template, \ - _TRACE_PROFILE_INIT(call) \ + _TRACE_PERF_INIT(call) \ } #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) /* - * Define the insertion callback to profile events + * Define the insertion callback to perf events * * The job is very similar to ftrace_raw_event_ except that we don't * insert in the ring buffer but in a perf counter. * - * static void ftrace_profile_(proto) + * static void ftrace_perf_(proto) * { * struct ftrace_data_offsets_ __maybe_unused __data_offsets; * struct ftrace_event_call *event_call = &event_; @@ -757,7 +757,7 @@ __attribute__((section("_ftrace_events"))) event_##call = { \ #undef DECLARE_EVENT_CLASS #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ static notrace void \ -ftrace_profile_templ_##call(struct ftrace_event_call *event_call, \ +perf_trace_templ_##call(struct ftrace_event_call *event_call, \ proto) \ { \ struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\ @@ -774,10 +774,10 @@ ftrace_profile_templ_##call(struct ftrace_event_call *event_call, \ sizeof(u64)); \ __entry_size -= sizeof(u32); \ \ - if (WARN_ONCE(__entry_size > FTRACE_MAX_PROFILE_SIZE, \ + if (WARN_ONCE(__entry_size > PERF_MAX_TRACE_SIZE, \ "profile buffer not large enough")) \ return; \ - entry = (struct ftrace_raw_##call *)ftrace_perf_buf_prepare( \ + entry = (struct ftrace_raw_##call *)perf_trace_buf_prepare( \ __entry_size, event_call->id, &rctx, &irq_flags); \ if (!entry) \ return; \ @@ -788,17 +788,17 @@ ftrace_profile_templ_##call(struct ftrace_event_call *event_call, \ __regs = &__get_cpu_var(perf_trace_regs); \ perf_fetch_caller_regs(__regs, 2); \ \ - ftrace_perf_buf_submit(entry, __entry_size, rctx, __addr, \ + perf_trace_buf_submit(entry, __entry_size, rctx, __addr, \ __count, irq_flags, __regs); \ } #undef DEFINE_EVENT #define DEFINE_EVENT(template, call, proto, args) \ -static notrace void ftrace_profile_##call(proto) \ +static notrace void perf_trace_##call(proto) \ { \ struct ftrace_event_call *event_call = &event_##call; \ \ - ftrace_profile_templ_##template(event_call, args); \ + perf_trace_templ_##template(event_call, args); \ } #undef DEFINE_EVENT_PRINT diff --git a/include/trace/syscall.h b/include/trace/syscall.h index 0387100..e5e5f48 100644 --- a/include/trace/syscall.h +++ b/include/trace/syscall.h @@ -47,10 +47,10 @@ enum print_line_t print_syscall_exit(struct trace_iterator *iter, int flags); #endif #ifdef CONFIG_PERF_EVENTS -int prof_sysenter_enable(struct ftrace_event_call *call); -void prof_sysenter_disable(struct ftrace_event_call *call); -int prof_sysexit_enable(struct ftrace_event_call *call); -void prof_sysexit_disable(struct ftrace_event_call *call); +int perf_sysenter_enable(struct ftrace_event_call *call); +void perf_sysenter_disable(struct ftrace_event_call *call); +int perf_sysexit_enable(struct ftrace_event_call *call); +void perf_sysexit_disable(struct ftrace_event_call *call); #endif #endif /* _TRACE_SYSCALL_H */ diff --git a/kernel/perf_event.c b/kernel/perf_event.c index 45b4b6e..c502b18 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c @@ -4347,7 +4347,7 @@ static int perf_tp_event_match(struct perf_event *event, static void tp_perf_event_destroy(struct perf_event *event) { - ftrace_profile_disable(event->attr.config); + perf_trace_disable(event->attr.config); } static const struct pmu *tp_perf_event_init(struct perf_event *event) @@ -4361,7 +4361,7 @@ static const struct pmu *tp_perf_event_init(struct perf_event *event) !capable(CAP_SYS_ADMIN)) return ERR_PTR(-EPERM); - if (ftrace_profile_enable(event->attr.config)) + if (perf_trace_enable(event->attr.config)) return NULL; event->destroy = tp_perf_event_destroy; diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile index d00c6fe..78edc64 100644 --- a/kernel/trace/Makefile +++ b/kernel/trace/Makefile @@ -52,7 +52,7 @@ obj-$(CONFIG_EVENT_TRACING) += trace_events.o obj-$(CONFIG_EVENT_TRACING) += trace_export.o obj-$(CONFIG_FTRACE_SYSCALLS) += trace_syscalls.o ifeq ($(CONFIG_PERF_EVENTS),y) -obj-$(CONFIG_EVENT_TRACING) += trace_event_profile.o +obj-$(CONFIG_EVENT_TRACING) += trace_event_perf.o endif obj-$(CONFIG_EVENT_TRACING) += trace_events_filter.o obj-$(CONFIG_KPROBE_EVENT) += trace_kprobe.o diff --git a/kernel/trace/trace_event_perf.c b/kernel/trace/trace_event_perf.c new file mode 100644 index 0000000..f315b12 --- /dev/null +++ b/kernel/trace/trace_event_perf.c @@ -0,0 +1,165 @@ +/* + * trace event based perf event profiling/tracing + * + * Copyright (C) 2009 Red Hat Inc, Peter Zijlstra + * Copyright (C) 2009-2010 Frederic Weisbecker + */ + +#include +#include +#include "trace.h" + +DEFINE_PER_CPU(struct pt_regs, perf_trace_regs); + +static char *perf_trace_buf; +static char *perf_trace_buf_nmi; + +typedef typeof(char [PERF_MAX_TRACE_SIZE]) perf_trace_t ; + +/* Count the events in use (per event id, not per instance) */ +static int total_ref_count; + +static int perf_trace_event_enable(struct ftrace_event_call *event) +{ + char *buf; + int ret = -ENOMEM; + + if (event->perf_refcount++ > 0) + return 0; + + if (!total_ref_count) { + buf = (char *)alloc_percpu(perf_trace_t); + if (!buf) + goto fail_buf; + + rcu_assign_pointer(perf_trace_buf, buf); + + buf = (char *)alloc_percpu(perf_trace_t); + if (!buf) + goto fail_buf_nmi; + + rcu_assign_pointer(perf_trace_buf_nmi, buf); + } + + ret = event->perf_event_enable(event); + if (!ret) { + total_ref_count++; + return 0; + } + +fail_buf_nmi: + if (!total_ref_count) { + free_percpu(perf_trace_buf_nmi); + free_percpu(perf_trace_buf); + perf_trace_buf_nmi = NULL; + perf_trace_buf = NULL; + } +fail_buf: + event->perf_refcount--; + + return ret; +} + +int perf_trace_enable(int event_id) +{ + struct ftrace_event_call *event; + int ret = -EINVAL; + + mutex_lock(&event_mutex); + list_for_each_entry(event, &ftrace_events, list) { + if (event->id == event_id && event->perf_event_enable && + try_module_get(event->mod)) { + ret = perf_trace_event_enable(event); + break; + } + } + mutex_unlock(&event_mutex); + + return ret; +} + +static void perf_trace_event_disable(struct ftrace_event_call *event) +{ + char *buf, *nmi_buf; + + if (--event->perf_refcount > 0) + return; + + event->perf_event_disable(event); + + if (!--total_ref_count) { + buf = perf_trace_buf; + rcu_assign_pointer(perf_trace_buf, NULL); + + nmi_buf = perf_trace_buf_nmi; + rcu_assign_pointer(perf_trace_buf_nmi, NULL); + + /* + * Ensure every events in profiling have finished before + * releasing the buffers + */ + synchronize_sched(); + + free_percpu(buf); + free_percpu(nmi_buf); + } +} + +void perf_trace_disable(int event_id) +{ + struct ftrace_event_call *event; + + mutex_lock(&event_mutex); + list_for_each_entry(event, &ftrace_events, list) { + if (event->id == event_id) { + perf_trace_event_disable(event); + module_put(event->mod); + break; + } + } + mutex_unlock(&event_mutex); +} + +__kprobes void *perf_trace_buf_prepare(int size, unsigned short type, + int *rctxp, unsigned long *irq_flags) +{ + struct trace_entry *entry; + char *trace_buf, *raw_data; + int pc, cpu; + + pc = preempt_count(); + + /* Protect the per cpu buffer, begin the rcu read side */ + local_irq_save(*irq_flags); + + *rctxp = perf_swevent_get_recursion_context(); + if (*rctxp < 0) + goto err_recursion; + + cpu = smp_processor_id(); + + if (in_nmi()) + trace_buf = rcu_dereference(perf_trace_buf_nmi); + else + trace_buf = rcu_dereference(perf_trace_buf); + + if (!trace_buf) + goto err; + + raw_data = per_cpu_ptr(trace_buf, cpu); + + /* zero the dead bytes from align to not leak stack to user */ + *(u64 *)(&raw_data[size - sizeof(u64)]) = 0ULL; + + entry = (struct trace_entry *)raw_data; + tracing_generic_entry_update(entry, *irq_flags, pc); + entry->type = type; + + return raw_data; +err: + perf_swevent_put_recursion_context(*rctxp); +err_recursion: + local_irq_restore(*irq_flags); + return NULL; +} +EXPORT_SYMBOL_GPL(perf_trace_buf_prepare); diff --git a/kernel/trace/trace_event_profile.c b/kernel/trace/trace_event_profile.c deleted file mode 100644 index e66d21e..0000000 --- a/kernel/trace/trace_event_profile.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * trace event based perf counter profiling - * - * Copyright (C) 2009 Red Hat Inc, Peter Zijlstra - * Copyright (C) 2009-2010 Frederic Weisbecker - */ - -#include -#include -#include "trace.h" - -DEFINE_PER_CPU(struct pt_regs, perf_trace_regs); - -static char *perf_trace_buf; -static char *perf_trace_buf_nmi; - -typedef typeof(char [FTRACE_MAX_PROFILE_SIZE]) perf_trace_t ; - -/* Count the events in use (per event id, not per instance) */ -static int total_profile_count; - -static int ftrace_profile_enable_event(struct ftrace_event_call *event) -{ - char *buf; - int ret = -ENOMEM; - - if (event->profile_count++ > 0) - return 0; - - if (!total_profile_count) { - buf = (char *)alloc_percpu(perf_trace_t); - if (!buf) - goto fail_buf; - - rcu_assign_pointer(perf_trace_buf, buf); - - buf = (char *)alloc_percpu(perf_trace_t); - if (!buf) - goto fail_buf_nmi; - - rcu_assign_pointer(perf_trace_buf_nmi, buf); - } - - ret = event->profile_enable(event); - if (!ret) { - total_profile_count++; - return 0; - } - -fail_buf_nmi: - if (!total_profile_count) { - free_percpu(perf_trace_buf_nmi); - free_percpu(perf_trace_buf); - perf_trace_buf_nmi = NULL; - perf_trace_buf = NULL; - } -fail_buf: - event->profile_count--; - - return ret; -} - -int ftrace_profile_enable(int event_id) -{ - struct ftrace_event_call *event; - int ret = -EINVAL; - - mutex_lock(&event_mutex); - list_for_each_entry(event, &ftrace_events, list) { - if (event->id == event_id && event->profile_enable && - try_module_get(event->mod)) { - ret = ftrace_profile_enable_event(event); - break; - } - } - mutex_unlock(&event_mutex); - - return ret; -} - -static void ftrace_profile_disable_event(struct ftrace_event_call *event) -{ - char *buf, *nmi_buf; - - if (--event->profile_count > 0) - return; - - event->profile_disable(event); - - if (!--total_profile_count) { - buf = perf_trace_buf; - rcu_assign_pointer(perf_trace_buf, NULL); - - nmi_buf = perf_trace_buf_nmi; - rcu_assign_pointer(perf_trace_buf_nmi, NULL); - - /* - * Ensure every events in profiling have finished before - * releasing the buffers - */ - synchronize_sched(); - - free_percpu(buf); - free_percpu(nmi_buf); - } -} - -void ftrace_profile_disable(int event_id) -{ - struct ftrace_event_call *event; - - mutex_lock(&event_mutex); - list_for_each_entry(event, &ftrace_events, list) { - if (event->id == event_id) { - ftrace_profile_disable_event(event); - module_put(event->mod); - break; - } - } - mutex_unlock(&event_mutex); -} - -__kprobes void *ftrace_perf_buf_prepare(int size, unsigned short type, - int *rctxp, unsigned long *irq_flags) -{ - struct trace_entry *entry; - char *trace_buf, *raw_data; - int pc, cpu; - - pc = preempt_count(); - - /* Protect the per cpu buffer, begin the rcu read side */ - local_irq_save(*irq_flags); - - *rctxp = perf_swevent_get_recursion_context(); - if (*rctxp < 0) - goto err_recursion; - - cpu = smp_processor_id(); - - if (in_nmi()) - trace_buf = rcu_dereference(perf_trace_buf_nmi); - else - trace_buf = rcu_dereference(perf_trace_buf); - - if (!trace_buf) - goto err; - - raw_data = per_cpu_ptr(trace_buf, cpu); - - /* zero the dead bytes from align to not leak stack to user */ - *(u64 *)(&raw_data[size - sizeof(u64)]) = 0ULL; - - entry = (struct trace_entry *)raw_data; - tracing_generic_entry_update(entry, *irq_flags, pc); - entry->type = type; - - return raw_data; -err: - perf_swevent_put_recursion_context(*rctxp); -err_recursion: - local_irq_restore(*irq_flags); - return NULL; -} -EXPORT_SYMBOL_GPL(ftrace_perf_buf_prepare); diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 3f972ad9..beab8bf 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -938,7 +938,7 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events, trace_create_file("enable", 0644, call->dir, call, enable); - if (call->id && call->profile_enable) + if (call->id && call->perf_event_enable) trace_create_file("id", 0444, call->dir, call, id); diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index f7a20a8..1251e36 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -1214,7 +1214,7 @@ static int set_print_fmt(struct trace_probe *tp) #ifdef CONFIG_PERF_EVENTS /* Kprobe profile handler */ -static __kprobes void kprobe_profile_func(struct kprobe *kp, +static __kprobes void kprobe_perf_func(struct kprobe *kp, struct pt_regs *regs) { struct trace_probe *tp = container_of(kp, struct trace_probe, rp.kp); @@ -1227,11 +1227,11 @@ static __kprobes void kprobe_profile_func(struct kprobe *kp, __size = SIZEOF_KPROBE_TRACE_ENTRY(tp->nr_args); size = ALIGN(__size + sizeof(u32), sizeof(u64)); size -= sizeof(u32); - if (WARN_ONCE(size > FTRACE_MAX_PROFILE_SIZE, + if (WARN_ONCE(size > PERF_MAX_TRACE_SIZE, "profile buffer not large enough")) return; - entry = ftrace_perf_buf_prepare(size, call->id, &rctx, &irq_flags); + entry = perf_trace_buf_prepare(size, call->id, &rctx, &irq_flags); if (!entry) return; @@ -1240,11 +1240,11 @@ static __kprobes void kprobe_profile_func(struct kprobe *kp, for (i = 0; i < tp->nr_args; i++) entry->args[i] = call_fetch(&tp->args[i].fetch, regs); - ftrace_perf_buf_submit(entry, size, rctx, entry->ip, 1, irq_flags, regs); + perf_trace_buf_submit(entry, size, rctx, entry->ip, 1, irq_flags, regs); } /* Kretprobe profile handler */ -static __kprobes void kretprobe_profile_func(struct kretprobe_instance *ri, +static __kprobes void kretprobe_perf_func(struct kretprobe_instance *ri, struct pt_regs *regs) { struct trace_probe *tp = container_of(ri->rp, struct trace_probe, rp); @@ -1257,11 +1257,11 @@ static __kprobes void kretprobe_profile_func(struct kretprobe_instance *ri, __size = SIZEOF_KRETPROBE_TRACE_ENTRY(tp->nr_args); size = ALIGN(__size + sizeof(u32), sizeof(u64)); size -= sizeof(u32); - if (WARN_ONCE(size > FTRACE_MAX_PROFILE_SIZE, + if (WARN_ONCE(size > PERF_MAX_TRACE_SIZE, "profile buffer not large enough")) return; - entry = ftrace_perf_buf_prepare(size, call->id, &rctx, &irq_flags); + entry = perf_trace_buf_prepare(size, call->id, &rctx, &irq_flags); if (!entry) return; @@ -1271,11 +1271,11 @@ static __kprobes void kretprobe_profile_func(struct kretprobe_instance *ri, for (i = 0; i < tp->nr_args; i++) entry->args[i] = call_fetch(&tp->args[i].fetch, regs); - ftrace_perf_buf_submit(entry, size, rctx, entry->ret_ip, 1, + perf_trace_buf_submit(entry, size, rctx, entry->ret_ip, 1, irq_flags, regs); } -static int probe_profile_enable(struct ftrace_event_call *call) +static int probe_perf_enable(struct ftrace_event_call *call) { struct trace_probe *tp = (struct trace_probe *)call->data; @@ -1287,7 +1287,7 @@ static int probe_profile_enable(struct ftrace_event_call *call) return enable_kprobe(&tp->rp.kp); } -static void probe_profile_disable(struct ftrace_event_call *call) +static void probe_perf_disable(struct ftrace_event_call *call) { struct trace_probe *tp = (struct trace_probe *)call->data; @@ -1312,7 +1312,7 @@ int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs) kprobe_trace_func(kp, regs); #ifdef CONFIG_PERF_EVENTS if (tp->flags & TP_FLAG_PROFILE) - kprobe_profile_func(kp, regs); + kprobe_perf_func(kp, regs); #endif return 0; /* We don't tweek kernel, so just return 0 */ } @@ -1326,7 +1326,7 @@ int kretprobe_dispatcher(struct kretprobe_instance *ri, struct pt_regs *regs) kretprobe_trace_func(ri, regs); #ifdef CONFIG_PERF_EVENTS if (tp->flags & TP_FLAG_PROFILE) - kretprobe_profile_func(ri, regs); + kretprobe_perf_func(ri, regs); #endif return 0; /* We don't tweek kernel, so just return 0 */ } @@ -1359,8 +1359,8 @@ static int register_probe_event(struct trace_probe *tp) call->unregfunc = probe_event_disable; #ifdef CONFIG_PERF_EVENTS - call->profile_enable = probe_profile_enable; - call->profile_disable = probe_profile_disable; + call->perf_event_enable = probe_perf_enable; + call->perf_event_disable = probe_perf_disable; #endif call->data = tp; ret = trace_add_event_call(call); diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c index 7e6e84f..33c2a5b 100644 --- a/kernel/trace/trace_syscalls.c +++ b/kernel/trace/trace_syscalls.c @@ -428,12 +428,12 @@ core_initcall(init_ftrace_syscalls); #ifdef CONFIG_PERF_EVENTS -static DECLARE_BITMAP(enabled_prof_enter_syscalls, NR_syscalls); -static DECLARE_BITMAP(enabled_prof_exit_syscalls, NR_syscalls); -static int sys_prof_refcount_enter; -static int sys_prof_refcount_exit; +static DECLARE_BITMAP(enabled_perf_enter_syscalls, NR_syscalls); +static DECLARE_BITMAP(enabled_perf_exit_syscalls, NR_syscalls); +static int sys_perf_refcount_enter; +static int sys_perf_refcount_exit; -static void prof_syscall_enter(struct pt_regs *regs, long id) +static void perf_syscall_enter(struct pt_regs *regs, long id) { struct syscall_metadata *sys_data; struct syscall_trace_enter *rec; @@ -443,7 +443,7 @@ static void prof_syscall_enter(struct pt_regs *regs, long id) int size; syscall_nr = syscall_get_nr(current, regs); - if (!test_bit(syscall_nr, enabled_prof_enter_syscalls)) + if (!test_bit(syscall_nr, enabled_perf_enter_syscalls)) return; sys_data = syscall_nr_to_meta(syscall_nr); @@ -455,11 +455,11 @@ static void prof_syscall_enter(struct pt_regs *regs, long id) size = ALIGN(size + sizeof(u32), sizeof(u64)); size -= sizeof(u32); - if (WARN_ONCE(size > FTRACE_MAX_PROFILE_SIZE, - "profile buffer not large enough")) + if (WARN_ONCE(size > PERF_MAX_TRACE_SIZE, + "perf buffer not large enough")) return; - rec = (struct syscall_trace_enter *)ftrace_perf_buf_prepare(size, + rec = (struct syscall_trace_enter *)perf_trace_buf_prepare(size, sys_data->enter_event->id, &rctx, &flags); if (!rec) return; @@ -467,10 +467,10 @@ static void prof_syscall_enter(struct pt_regs *regs, long id) rec->nr = syscall_nr; syscall_get_arguments(current, regs, 0, sys_data->nb_args, (unsigned long *)&rec->args); - ftrace_perf_buf_submit(rec, size, rctx, 0, 1, flags, regs); + perf_trace_buf_submit(rec, size, rctx, 0, 1, flags, regs); } -int prof_sysenter_enable(struct ftrace_event_call *call) +int perf_sysenter_enable(struct ftrace_event_call *call) { int ret = 0; int num; @@ -478,34 +478,34 @@ int prof_sysenter_enable(struct ftrace_event_call *call) num = ((struct syscall_metadata *)call->data)->syscall_nr; mutex_lock(&syscall_trace_lock); - if (!sys_prof_refcount_enter) - ret = register_trace_sys_enter(prof_syscall_enter); + if (!sys_perf_refcount_enter) + ret = register_trace_sys_enter(perf_syscall_enter); if (ret) { pr_info("event trace: Could not activate" "syscall entry trace point"); } else { - set_bit(num, enabled_prof_enter_syscalls); - sys_prof_refcount_enter++; + set_bit(num, enabled_perf_enter_syscalls); + sys_perf_refcount_enter++; } mutex_unlock(&syscall_trace_lock); return ret; } -void prof_sysenter_disable(struct ftrace_event_call *call) +void perf_sysenter_disable(struct ftrace_event_call *call) { int num; num = ((struct syscall_metadata *)call->data)->syscall_nr; mutex_lock(&syscall_trace_lock); - sys_prof_refcount_enter--; - clear_bit(num, enabled_prof_enter_syscalls); - if (!sys_prof_refcount_enter) - unregister_trace_sys_enter(prof_syscall_enter); + sys_perf_refcount_enter--; + clear_bit(num, enabled_perf_enter_syscalls); + if (!sys_perf_refcount_enter) + unregister_trace_sys_enter(perf_syscall_enter); mutex_unlock(&syscall_trace_lock); } -static void prof_syscall_exit(struct pt_regs *regs, long ret) +static void perf_syscall_exit(struct pt_regs *regs, long ret) { struct syscall_metadata *sys_data; struct syscall_trace_exit *rec; @@ -515,7 +515,7 @@ static void prof_syscall_exit(struct pt_regs *regs, long ret) int size; syscall_nr = syscall_get_nr(current, regs); - if (!test_bit(syscall_nr, enabled_prof_exit_syscalls)) + if (!test_bit(syscall_nr, enabled_perf_exit_syscalls)) return; sys_data = syscall_nr_to_meta(syscall_nr); @@ -530,11 +530,11 @@ static void prof_syscall_exit(struct pt_regs *regs, long ret) * Impossible, but be paranoid with the future * How to put this check outside runtime? */ - if (WARN_ONCE(size > FTRACE_MAX_PROFILE_SIZE, - "exit event has grown above profile buffer size")) + if (WARN_ONCE(size > PERF_MAX_TRACE_SIZE, + "exit event has grown above perf buffer size")) return; - rec = (struct syscall_trace_exit *)ftrace_perf_buf_prepare(size, + rec = (struct syscall_trace_exit *)perf_trace_buf_prepare(size, sys_data->exit_event->id, &rctx, &flags); if (!rec) return; @@ -542,10 +542,10 @@ static void prof_syscall_exit(struct pt_regs *regs, long ret) rec->nr = syscall_nr; rec->ret = syscall_get_return_value(current, regs); - ftrace_perf_buf_submit(rec, size, rctx, 0, 1, flags, regs); + perf_trace_buf_submit(rec, size, rctx, 0, 1, flags, regs); } -int prof_sysexit_enable(struct ftrace_event_call *call) +int perf_sysexit_enable(struct ftrace_event_call *call) { int ret = 0; int num; @@ -553,30 +553,30 @@ int prof_sysexit_enable(struct ftrace_event_call *call) num = ((struct syscall_metadata *)call->data)->syscall_nr; mutex_lock(&syscall_trace_lock); - if (!sys_prof_refcount_exit) - ret = register_trace_sys_exit(prof_syscall_exit); + if (!sys_perf_refcount_exit) + ret = register_trace_sys_exit(perf_syscall_exit); if (ret) { pr_info("event trace: Could not activate" "syscall exit trace point"); } else { - set_bit(num, enabled_prof_exit_syscalls); - sys_prof_refcount_exit++; + set_bit(num, enabled_perf_exit_syscalls); + sys_perf_refcount_exit++; } mutex_unlock(&syscall_trace_lock); return ret; } -void prof_sysexit_disable(struct ftrace_event_call *call) +void perf_sysexit_disable(struct ftrace_event_call *call) { int num; num = ((struct syscall_metadata *)call->data)->syscall_nr; mutex_lock(&syscall_trace_lock); - sys_prof_refcount_exit--; - clear_bit(num, enabled_prof_exit_syscalls); - if (!sys_prof_refcount_exit) - unregister_trace_sys_exit(prof_syscall_exit); + sys_perf_refcount_exit--; + clear_bit(num, enabled_perf_exit_syscalls); + if (!sys_perf_refcount_exit) + unregister_trace_sys_exit(perf_syscall_exit); mutex_unlock(&syscall_trace_lock); } -- cgit v0.10.2 From 2886539d5e649c22a6d2107eb431d3bee81e0e6d Mon Sep 17 00:00:00 2001 From: Rafi Rubin Date: Wed, 10 Mar 2010 16:10:28 +0100 Subject: HID: ntrig: fix touch events This reinstates the lost unpressing of BTN_TOUCH. To prevent undesireably touch toggles this also deals with tip switch events. Added a trap to prevent going out of bounds for hidinputs with empty reports. Clear bits of unused buttons which result in misidentification. Signed-off-by: Rafi Rubin Signed-off-by: Jiri Kosina diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c index 3234c72..edcc0c4 100644 --- a/drivers/hid/hid-ntrig.c +++ b/drivers/hid/hid-ntrig.c @@ -140,6 +140,9 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field, nd->reading_mt = 1; nd->first_contact_confidence = 0; break; + case HID_DG_TIPSWITCH: + /* Prevent emission of touch until validated */ + return 1; case HID_DG_CONFIDENCE: nd->confidence = value; break; @@ -259,6 +262,7 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field, BTN_TOOL_TRIPLETAP, 0); input_report_key(input, BTN_TOOL_QUADTAP, 0); + input_report_key(input, BTN_TOUCH, 0); } break; @@ -308,13 +312,20 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) list_for_each_entry(hidinput, &hdev->inputs, list) { + if (hidinput->report->maxfield < 1) + continue; + input = hidinput->input; switch (hidinput->report->field[0]->application) { case HID_DG_PEN: input->name = "N-Trig Pen"; break; case HID_DG_TOUCHSCREEN: + /* These keys are redundant for fingers, clear them + * to prevent incorrect identification */ __clear_bit(BTN_TOOL_PEN, input->keybit); + __clear_bit(BTN_TOOL_FINGER, input->keybit); + __clear_bit(BTN_0, input->keybit); /* * A little something special to enable * two and three finger taps. -- cgit v0.10.2 From fe7a26257a4191de6047f7e1d38832472eb22f85 Mon Sep 17 00:00:00 2001 From: Ursula Braun Date: Mon, 8 Mar 2010 20:36:53 +0000 Subject: qeth: enable kmsg hash processing in qeth_core_sys.c provide qeth kmsg definitions to enable hash string generation for kernel message created with dev_err(). Signed-off-by: Ursula Braun Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller diff --git a/drivers/s390/net/qeth_core_sys.c b/drivers/s390/net/qeth_core_sys.c index 88ae435..25dfd5a 100644 --- a/drivers/s390/net/qeth_core_sys.c +++ b/drivers/s390/net/qeth_core_sys.c @@ -8,6 +8,9 @@ * Frank Blaschka */ +#define KMSG_COMPONENT "qeth" +#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt + #include #include #include -- cgit v0.10.2 From 21fde749cbf71d03e8cf87a7a9a45349597e138a Mon Sep 17 00:00:00 2001 From: Frank Blaschka Date: Mon, 8 Mar 2010 20:36:54 +0000 Subject: qeth: l3 send dhcp in non pass thru mode dhcp frames are valid IPv4 packets so there is no need to send them in pass thru mode. This allows dhcp packets to pass HiperSockets. Also the dhcp release frame is send out correctly with this patch. Signed-off-by: Frank Blaschka Signed-off-by: Martin Schwidefsky Signed-off-by: David S. Miller diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index a3ac445..fcd005a 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -763,7 +763,8 @@ static inline int qeth_get_micros(void) static inline int qeth_get_ip_version(struct sk_buff *skb) { - switch (skb->protocol) { + struct ethhdr *ehdr = (struct ethhdr *)skb->data; + switch (ehdr->h_proto) { case ETH_P_IPV6: return 6; case ETH_P_IP: diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 5475834..42fe92c 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -2900,10 +2900,8 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) int data_offset = -1; int nr_frags; - if ((card->info.type == QETH_CARD_TYPE_IQD) && - (((skb->protocol != htons(ETH_P_IPV6)) && - (skb->protocol != htons(ETH_P_IP))) || - card->options.sniffer)) + if (((card->info.type == QETH_CARD_TYPE_IQD) && (!ipv)) || + card->options.sniffer) goto tx_drop; if ((card->state != CARD_STATE_UP) || !card->lan_online) { @@ -2949,14 +2947,14 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) if (data_offset < 0) skb_pull(new_skb, ETH_HLEN); } else { - if (new_skb->protocol == htons(ETH_P_IP)) { + if (ipv == 4) { if (card->dev->type == ARPHRD_IEEE802_TR) skb_pull(new_skb, TR_HLEN); else skb_pull(new_skb, ETH_HLEN); } - if (new_skb->protocol == ETH_P_IPV6 && card->vlangrp && + if (ipv == 6 && card->vlangrp && vlan_tx_tag_present(new_skb)) { skb_push(new_skb, VLAN_HLEN); skb_copy_to_linear_data(new_skb, new_skb->data + 4, 4); -- cgit v0.10.2 From a959189a978e0104e8aa7f1522f5eff42d891456 Mon Sep 17 00:00:00 2001 From: Ursula Braun Date: Mon, 8 Mar 2010 20:36:55 +0000 Subject: qeth: set promisc off after trace disabling failure If HiperSockets Network Traffic Analyzer is switched off, but trace disabling fails somehow, the qeth driver does not switch off its promisc mode status. A following sniffer reactivation fails, since qeth does not see a need to reenable tracing. At the same time the code analyzing results of trace commands is restructured. Signed-off-by: Ursula Braun Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 42fe92c..cd746da 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -1691,39 +1691,43 @@ qeth_diags_trace_cb(struct qeth_card *card, struct qeth_reply *reply, cmd = (struct qeth_ipa_cmd *)data; rc = cmd->hdr.return_code; - if (rc) { + if (rc) QETH_DBF_TEXT_(TRACE, 2, "dxter%x", rc); - if (cmd->data.diagass.action == QETH_DIAGS_CMD_TRACE_ENABLE) { - switch (rc) { - case IPA_RC_HARDWARE_AUTH_ERROR: - dev_warn(&card->gdev->dev, "The device is not " - "authorized to run as a HiperSockets " - "network traffic analyzer\n"); - break; - case IPA_RC_TRACE_ALREADY_ACTIVE: - dev_warn(&card->gdev->dev, "A HiperSockets " - "network traffic analyzer is already " - "active in the HiperSockets LAN\n"); - break; - default: - break; - } - } - return 0; - } - switch (cmd->data.diagass.action) { case QETH_DIAGS_CMD_TRACE_QUERY: break; case QETH_DIAGS_CMD_TRACE_DISABLE: - card->info.promisc_mode = SET_PROMISC_MODE_OFF; - dev_info(&card->gdev->dev, "The HiperSockets network traffic " - "analyzer is deactivated\n"); + switch (rc) { + case 0: + case IPA_RC_INVALID_SUBCMD: + card->info.promisc_mode = SET_PROMISC_MODE_OFF; + dev_info(&card->gdev->dev, "The HiperSockets network " + "traffic analyzer is deactivated\n"); + break; + default: + break; + } break; case QETH_DIAGS_CMD_TRACE_ENABLE: - card->info.promisc_mode = SET_PROMISC_MODE_ON; - dev_info(&card->gdev->dev, "The HiperSockets network traffic " - "analyzer is activated\n"); + switch (rc) { + case 0: + card->info.promisc_mode = SET_PROMISC_MODE_ON; + dev_info(&card->gdev->dev, "The HiperSockets network " + "traffic analyzer is activated\n"); + break; + case IPA_RC_HARDWARE_AUTH_ERROR: + dev_warn(&card->gdev->dev, "The device is not " + "authorized to run as a HiperSockets network " + "traffic analyzer\n"); + break; + case IPA_RC_TRACE_ALREADY_ACTIVE: + dev_warn(&card->gdev->dev, "A HiperSockets " + "network traffic analyzer is already " + "active in the HiperSockets LAN\n"); + break; + default: + break; + } break; default: QETH_DBF_MESSAGE(2, "Unknown sniffer action (0x%04x) on %s\n", -- cgit v0.10.2 From 869da90b9ae39f0d5b9b5aa3a84502684a6aa1f4 Mon Sep 17 00:00:00 2001 From: Ursula Braun Date: Mon, 8 Mar 2010 20:36:56 +0000 Subject: qeth: no recovery after layer mismatch (z/VM NICs) Depending on their definition in z/VM, virtual devices for z/VM VSWITCH or GuestLAN must be configured either in layer2 or in layer3 mode. If qeth detects a layer mismatch, device activation fails. Trying to recover from this error cannot help; thus scheduling a recovery should be avoided. In addition, since recovery is forbidden during online setting of a qeth device, existence of its network device is guaranteed for all dev_close() calls in qeth. The corresponding checks can be removed. Signed-off-by: Ursula Braun Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index fa8a519..834830a 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -537,7 +537,8 @@ static void qeth_send_control_data_cb(struct qeth_channel *channel, dev_err(&card->gdev->dev, "The qeth device is not configured " "for the OSI layer required by z/VM\n"); - qeth_schedule_recovery(card); + else + qeth_schedule_recovery(card); goto out; } diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 51fde6f..6f1e303 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -1071,11 +1071,9 @@ static int qeth_l2_recover(void *ptr) dev_info(&card->gdev->dev, "Device successfully recovered!\n"); else { - if (card->dev) { - rtnl_lock(); - dev_close(card->dev); - rtnl_unlock(); - } + rtnl_lock(); + dev_close(card->dev); + rtnl_unlock(); dev_warn(&card->gdev->dev, "The qeth device driver " "failed to recover an error on the device\n"); } @@ -1129,11 +1127,9 @@ static int qeth_l2_pm_resume(struct ccwgroup_device *gdev) if (card->state == CARD_STATE_RECOVER) { rc = __qeth_l2_set_online(card->gdev, 1); if (rc) { - if (card->dev) { - rtnl_lock(); - dev_close(card->dev); - rtnl_unlock(); - } + rtnl_lock(); + dev_close(card->dev); + rtnl_unlock(); } } else rc = __qeth_l2_set_online(card->gdev, 0); diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index cd746da..b3b6e87 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -2219,11 +2219,9 @@ static int qeth_l3_stop_card(struct qeth_card *card, int recovery_mode) if (recovery_mode) qeth_l3_stop(card->dev); else { - if (card->dev) { - rtnl_lock(); - dev_close(card->dev); - rtnl_unlock(); - } + rtnl_lock(); + dev_close(card->dev); + rtnl_unlock(); } if (!card->use_hard_stop) { rc = qeth_send_stoplan(card); @@ -3536,11 +3534,9 @@ static int qeth_l3_pm_resume(struct ccwgroup_device *gdev) if (card->state == CARD_STATE_RECOVER) { rc = __qeth_l3_set_online(card->gdev, 1); if (rc) { - if (card->dev) { - rtnl_lock(); - dev_close(card->dev); - rtnl_unlock(); - } + rtnl_lock(); + dev_close(card->dev); + rtnl_unlock(); } } else rc = __qeth_l3_set_online(card->gdev, 0); -- cgit v0.10.2 From 78cb27939ff4fd66d7f76cfe7c59c0fdf1b29ed8 Mon Sep 17 00:00:00 2001 From: Frank Blaschka Date: Mon, 8 Mar 2010 20:36:57 +0000 Subject: qeth: change checksumming default for HiperSockets Deactivate inbound checksumming on HiperSocket is a valid but dangerous optimization in case the frame is routed from an OSA network to an HiperSockets network. To go for sure we change the default to software checksumming. Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 834830a..c9f5af5 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -1114,8 +1114,6 @@ static int qeth_setup_card(struct qeth_card *card) card->ipato.enabled = 0; card->ipato.invert4 = 0; card->ipato.invert6 = 0; - if (card->info.type == QETH_CARD_TYPE_IQD) - card->options.checksum_type = NO_CHECKSUMMING; /* init QDIO stuff */ qeth_init_qdio_info(card); return 0; -- cgit v0.10.2 From fe234f0e5cbb880792d2d1ac0743cf8c07e9dde3 Mon Sep 17 00:00:00 2001 From: Louis Rilling Date: Tue, 9 Mar 2010 06:14:41 +0000 Subject: tg3: Fix tg3_poll_controller() passing wrong pointer to tg3_interrupt() Commit 09943a1819a240ff4a72f924d0038818fcdd0a90 Author: Matt Carlson Date: Fri Aug 28 14:01:57 2009 +0000 tg3: Convert ISR parameter to tnapi forgot to update tg3_poll_controller(), leading to intermittent crashes with netpoll. Fix this. Signed-off-by: Louis Rilling Cc: stable@kernel.org Signed-off-by: David S. Miller diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 0fa7688..c3b4fe7 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -5279,7 +5279,7 @@ static void tg3_poll_controller(struct net_device *dev) struct tg3 *tp = netdev_priv(dev); for (i = 0; i < tp->irq_cnt; i++) - tg3_interrupt(tp->napi[i].irq_vec, dev); + tg3_interrupt(tp->napi[i].irq_vec, &tp->napi[i]); } #endif -- cgit v0.10.2 From bb134d5d9580fc7b945e3bca3c4b263947022966 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 9 Mar 2010 05:55:56 +0000 Subject: tcp: Fix tcp_v4_rcv() Commit d218d111 (tcp: Generalized TTL Security Mechanism) added a bug for TIMEWAIT sockets. We should not test min_ttl for TW sockets. Reported-by: Tetsuo Handa Signed-off-by: Eric Dumazet Acked-by: Stephen Hemminger Signed-off-by: David S. Miller diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 8d51d39..70df409 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1651,15 +1651,15 @@ int tcp_v4_rcv(struct sk_buff *skb) if (!sk) goto no_tcp_socket; +process: + if (sk->sk_state == TCP_TIME_WAIT) + goto do_time_wait; + if (unlikely(iph->ttl < inet_sk(sk)->min_ttl)) { NET_INC_STATS_BH(net, LINUX_MIB_TCPMINTTLDROP); goto discard_and_relse; } -process: - if (sk->sk_state == TCP_TIME_WAIT) - goto do_time_wait; - if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb)) goto discard_and_relse; nf_reset(skb); -- cgit v0.10.2 From 0a141509ede48ac33ef756ac1640f4d3f46fa2db Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 9 Mar 2010 19:40:54 +0000 Subject: net: Annotates neigh_invalidate() Annotates neigh_invalidate() with __releases() and __acquires() for sparse sake. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller diff --git a/net/core/neighbour.c b/net/core/neighbour.c index d102f6d..6cee643 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -771,6 +771,8 @@ static __inline__ int neigh_max_probes(struct neighbour *n) } static void neigh_invalidate(struct neighbour *neigh) + __releases(neigh->lock) + __acquires(neigh->lock) { struct sk_buff *skb; -- cgit v0.10.2 From 3041f5170751e3522aa1bd6e8ca5d98e846720b0 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 9 Mar 2010 19:09:08 +0000 Subject: net: Fix dev_mc_add() Commit 6e17d45a (net: add addr len check to dev_mc_add) added a bug in dev_mc_add(), since it can now exit with a lock imbalance. Signed-off-by: Eric Dumazet CC: Jiri Pirko Signed-off-by: David S. Miller diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c index fd91569..3dc295b 100644 --- a/net/core/dev_mcast.c +++ b/net/core/dev_mcast.c @@ -97,8 +97,9 @@ int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl) netif_addr_lock_bh(dev); if (alen != dev->addr_len) - return -EINVAL; - err = __dev_addr_add(&dev->mc_list, &dev->mc_count, addr, alen, glbl); + err = -EINVAL; + else + err = __dev_addr_add(&dev->mc_list, &dev->mc_count, addr, alen, glbl); if (!err) __dev_set_rx_mode(dev); netif_addr_unlock_bh(dev); -- cgit v0.10.2 From 2b4c32972b9bcfee29d5e2c1b6f261dda5ef2a21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?YOSHIFUJI=20Hideaki=20/=20=E5=90=89=E8=97=A4=E8=8B=B1?= =?UTF-8?q?=E6=98=8E?= Date: Tue, 9 Mar 2010 16:47:52 +0000 Subject: ipv6 ip6_tunnel: eliminate unused recursion field from ip6_tnl{}. Commit a43912ab19... ("tunnel: eliminate recursion field") eliminated use of recursion field from tunnel structures, but its definition still exists in ip6_tnl{}. Let's remove that unused field. Signed-off-by: YOSHIFUJI Hideaki Acked-by: Eric Dumazet Signed-off-by: David S. Miller diff --git a/include/net/ip6_tunnel.h b/include/net/ip6_tunnel.h index 83b4e00..fbf9d1c 100644 --- a/include/net/ip6_tunnel.h +++ b/include/net/ip6_tunnel.h @@ -15,7 +15,6 @@ struct ip6_tnl { struct ip6_tnl *next; /* next tunnel in list */ struct net_device *dev; /* virtual device associated with tunnel */ - int recursion; /* depth of hard_start_xmit recursion */ struct ip6_tnl_parm parms; /* tunnel configuration parameters */ struct flowi fl; /* flowi template for xmit */ struct dst_entry *dst_cache; /* cached dst */ -- cgit v0.10.2 From 7f29a3baa825725d29db399663790d15c78cddcf Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Tue, 9 Mar 2010 12:24:38 +0000 Subject: asix: fix setting mac address for AX88772 Setting new MAC address only worked when device was set to promiscuous mode. Fix MAC address by writing new address to device using undocumented command AX_CMD_READ_NODE_ID+1. Patch is tested with AX88772 device. Signed-off-by: Jussi Kivilinna Acked-by: David Hollis Signed-off-by: David S. Miller diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 20e3460..9e05639 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -54,6 +54,7 @@ static const char driver_name [] = "asix"; #define AX_CMD_WRITE_IPG0 0x12 #define AX_CMD_WRITE_IPG1 0x13 #define AX_CMD_READ_NODE_ID 0x13 +#define AX_CMD_WRITE_NODE_ID 0x14 #define AX_CMD_WRITE_IPG2 0x14 #define AX_CMD_WRITE_MULTI_FILTER 0x16 #define AX88172_CMD_READ_NODE_ID 0x17 @@ -165,6 +166,7 @@ static const char driver_name [] = "asix"; /* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */ struct asix_data { u8 multi_filter[AX_MCAST_FILTER_SIZE]; + u8 mac_addr[ETH_ALEN]; u8 phymode; u8 ledmode; u8 eeprom_len; @@ -732,6 +734,30 @@ static int asix_ioctl (struct net_device *net, struct ifreq *rq, int cmd) return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); } +static int asix_set_mac_address(struct net_device *net, void *p) +{ + struct usbnet *dev = netdev_priv(net); + struct asix_data *data = (struct asix_data *)&dev->data; + struct sockaddr *addr = p; + + if (netif_running(net)) + return -EBUSY; + if (!is_valid_ether_addr(addr->sa_data)) + return -EADDRNOTAVAIL; + + memcpy(net->dev_addr, addr->sa_data, ETH_ALEN); + + /* We use the 20 byte dev->data + * for our 6 byte mac buffer + * to avoid allocating memory that + * is tricky to free later */ + memcpy(data->mac_addr, addr->sa_data, ETH_ALEN); + asix_write_cmd_async(dev, AX_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN, + data->mac_addr); + + return 0; +} + /* We need to override some ethtool_ops so we require our own structure so we don't interfere with other usbnet devices that may be connected at the same time. */ @@ -919,7 +945,7 @@ static const struct net_device_ops ax88772_netdev_ops = { .ndo_start_xmit = usbnet_start_xmit, .ndo_tx_timeout = usbnet_tx_timeout, .ndo_change_mtu = usbnet_change_mtu, - .ndo_set_mac_address = eth_mac_addr, + .ndo_set_mac_address = asix_set_mac_address, .ndo_validate_addr = eth_validate_addr, .ndo_do_ioctl = asix_ioctl, .ndo_set_multicast_list = asix_set_multicast, @@ -1213,7 +1239,7 @@ static const struct net_device_ops ax88178_netdev_ops = { .ndo_stop = usbnet_stop, .ndo_start_xmit = usbnet_start_xmit, .ndo_tx_timeout = usbnet_tx_timeout, - .ndo_set_mac_address = eth_mac_addr, + .ndo_set_mac_address = asix_set_mac_address, .ndo_validate_addr = eth_validate_addr, .ndo_set_multicast_list = asix_set_multicast, .ndo_do_ioctl = asix_ioctl, -- cgit v0.10.2 From 717ea4b3474852057b1ce2c639ce219f4f8d3a8d Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Wed, 10 Mar 2010 07:37:06 -0800 Subject: net: add ColdFire support to the smc91x driver Some embedded ColdFire based boards use the SMC 91x family of ethernet devices. (For example the Freescale M5249C3 and MoretonBay NETtel). Add IO access support to the SMC91x driver, and allow this driver to be configured for ColdFire platforms. Signed-off-by: Greg Ungerer Signed-off-by: David S. Miller diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 7029cd5..0ba5b8e 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -907,7 +907,7 @@ config SMC91X select CRC32 select MII depends on ARM || REDWOOD_5 || REDWOOD_6 || M32R || SUPERH || \ - MIPS || BLACKFIN || MN10300 + MIPS || BLACKFIN || MN10300 || COLDFIRE help This is a driver for SMC's 91x series of Ethernet chipsets, including the SMC91C94 and the SMC91C111. Say Y if you want it diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h index a6ee883..8d2772c 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h @@ -344,6 +344,34 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r, #define SMC_IRQ_FLAGS IRQF_TRIGGER_HIGH +#elif defined(CONFIG_COLDFIRE) + +#define SMC_CAN_USE_8BIT 0 +#define SMC_CAN_USE_16BIT 1 +#define SMC_CAN_USE_32BIT 0 +#define SMC_NOWAIT 1 + +static inline void mcf_insw(void *a, unsigned char *p, int l) +{ + u16 *wp = (u16 *) p; + while (l-- > 0) + *wp++ = readw(a); +} + +static inline void mcf_outsw(void *a, unsigned char *p, int l) +{ + u16 *wp = (u16 *) p; + while (l-- > 0) + writew(*wp++, a); +} + +#define SMC_inw(a, r) _swapw(readw((a) + (r))) +#define SMC_outw(v, a, r) writew(_swapw(v), (a) + (r)) +#define SMC_insw(a, r, p, l) mcf_insw(a + r, p, l) +#define SMC_outsw(a, r, p, l) mcf_outsw(a + r, p, l) + +#define SMC_IRQ_FLAGS (IRQF_DISABLED) + #else /* -- cgit v0.10.2 From 0b1adaa031a55e44f5dd942f234bf09d28e8a0d6 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 9 Mar 2010 19:45:54 +0100 Subject: genirq: Prevent oneshot irq thread race Lars-Peter pointed out that the oneshot threaded interrupt handler code has the following race: CPU0 CPU1 hande_level_irq(irq X) mask_ack_irq(irq X) handle_IRQ_event(irq X) wake_up(thread_handler) thread handler(irq X) runs finalize_oneshot(irq X) does not unmask due to !(desc->status & IRQ_MASKED) return from irq does not unmask due to (desc->status & IRQ_ONESHOT) This leaves the interrupt line masked forever. The reason for this is the inconsistent handling of the IRQ_MASKED flag. Instead of setting it in the mask function the oneshot support sets the flag after waking up the irq thread. The solution for this is to set/clear the IRQ_MASKED status whenever we mask/unmask an interrupt line. That's the easy part, but that cleanup opens another race: CPU0 CPU1 hande_level_irq(irq) mask_ack_irq(irq) handle_IRQ_event(irq) wake_up(thread_handler) thread handler(irq) runs finalize_oneshot_irq(irq) unmask(irq) irq triggers again handle_level_irq(irq) mask_ack_irq(irq) return from irq due to IRQ_INPROGRESS return from irq does not unmask due to (desc->status & IRQ_ONESHOT) This requires that we synchronize finalize_oneshot_irq() with the primary handler. If IRQ_INPROGESS is set we wait until the primary handler on the other CPU has returned before unmasking the interrupt line again. We probably have never seen that problem because it does not happen on UP and on SMP the irqbalancer protects us by pinning the primary handler and the thread to the same CPU. Reported-by: Lars-Peter Clausen Signed-off-by: Thomas Gleixner Cc: stable@kernel.org diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index d70394f..71eba24 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -359,6 +359,23 @@ static inline void mask_ack_irq(struct irq_desc *desc, int irq) if (desc->chip->ack) desc->chip->ack(irq); } + desc->status |= IRQ_MASKED; +} + +static inline void mask_irq(struct irq_desc *desc, int irq) +{ + if (desc->chip->mask) { + desc->chip->mask(irq); + desc->status |= IRQ_MASKED; + } +} + +static inline void unmask_irq(struct irq_desc *desc, int irq) +{ + if (desc->chip->unmask) { + desc->chip->unmask(irq); + desc->status &= ~IRQ_MASKED; + } } /* @@ -484,10 +501,8 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc) raw_spin_lock(&desc->lock); desc->status &= ~IRQ_INPROGRESS; - if (unlikely(desc->status & IRQ_ONESHOT)) - desc->status |= IRQ_MASKED; - else if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask) - desc->chip->unmask(irq); + if (!(desc->status & (IRQ_DISABLED | IRQ_ONESHOT))) + unmask_irq(desc, irq); out_unlock: raw_spin_unlock(&desc->lock); } @@ -524,8 +539,7 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc) action = desc->action; if (unlikely(!action || (desc->status & IRQ_DISABLED))) { desc->status |= IRQ_PENDING; - if (desc->chip->mask) - desc->chip->mask(irq); + mask_irq(desc, irq); goto out; } @@ -593,7 +607,7 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc) irqreturn_t action_ret; if (unlikely(!action)) { - desc->chip->mask(irq); + mask_irq(desc, irq); goto out_unlock; } @@ -605,8 +619,7 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc) if (unlikely((desc->status & (IRQ_PENDING | IRQ_MASKED | IRQ_DISABLED)) == (IRQ_PENDING | IRQ_MASKED))) { - desc->chip->unmask(irq); - desc->status &= ~IRQ_MASKED; + unmask_irq(desc, irq); } desc->status &= ~IRQ_PENDING; diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index eb6078c..69a3d7b 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -483,8 +483,26 @@ static int irq_wait_for_interrupt(struct irqaction *action) */ static void irq_finalize_oneshot(unsigned int irq, struct irq_desc *desc) { +again: chip_bus_lock(irq, desc); raw_spin_lock_irq(&desc->lock); + + /* + * Implausible though it may be we need to protect us against + * the following scenario: + * + * The thread is faster done than the hard interrupt handler + * on the other CPU. If we unmask the irq line then the + * interrupt can come in again and masks the line, leaves due + * to IRQ_INPROGRESS and the irq line is masked forever. + */ + if (unlikely(desc->status & IRQ_INPROGRESS)) { + raw_spin_unlock_irq(&desc->lock); + chip_bus_sync_unlock(irq, desc); + cpu_relax(); + goto again; + } + if (!(desc->status & IRQ_DISABLED) && (desc->status & IRQ_MASKED)) { desc->status &= ~IRQ_MASKED; desc->chip->unmask(irq); -- cgit v0.10.2 From b4d2314bb88b07e5a04e6c75b442a1dfcd60e340 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 10 Mar 2010 15:21:44 -0500 Subject: NFSv4: Don't ignore the NFS_INO_REVAL_FORCED flag in nfs_revalidate_inode() If the NFS_INO_REVAL_FORCED flag is set, that means that we don't yet have an up to date attribute cache. Even if we hold a delegation, we must put a GETATTR on the wire. Signed-off-by: Trond Myklebust Cc: stable@kernel.org diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h index 944b627..69e7b81 100644 --- a/fs/nfs/delegation.h +++ b/fs/nfs/delegation.h @@ -71,4 +71,10 @@ static inline int nfs_inode_return_delegation(struct inode *inode) } #endif +static inline int nfs_have_delegated_attributes(struct inode *inode) +{ + return nfs_have_delegation(inode, FMODE_READ) && + !(NFS_I(inode)->cache_validity & NFS_INO_REVAL_FORCED); +} + #endif diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index a1f6b44..c6f2750 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -1789,7 +1789,7 @@ static int nfs_access_get_cached(struct inode *inode, struct rpc_cred *cred, str cache = nfs_access_search_rbtree(inode, cred); if (cache == NULL) goto out; - if (!nfs_have_delegation(inode, FMODE_READ) && + if (!nfs_have_delegated_attributes(inode) && !time_in_range_open(jiffies, cache->jiffies, cache->jiffies + nfsi->attrtimeo)) goto out_stale; res->jiffies = cache->jiffies; diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 657201a..e358df7 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -729,7 +729,7 @@ int nfs_attribute_timeout(struct inode *inode) { struct nfs_inode *nfsi = NFS_I(inode); - if (nfs_have_delegation(inode, FMODE_READ)) + if (nfs_have_delegated_attributes(inode)) return 0; return !time_in_range_open(jiffies, nfsi->read_cache_jiffies, nfsi->read_cache_jiffies + nfsi->attrtimeo); } -- cgit v0.10.2 From 07081fd8587478849b69d7b41596e81ff5a7f532 Mon Sep 17 00:00:00 2001 From: David Miller Date: Wed, 10 Mar 2010 14:05:35 -0700 Subject: uartlite: Fix build on sparc. We can get this driver enabled via MFD_TIMBERDALE which only requires GPIO to be on. But the of_address_to_resource() function is only present on powerpc and microblaze, so we have to conditionalize the CONFIG_OF probing bits on that. Signed-off-by: David S. Miller Signed-off-by: Grant Likely diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c index ab2ab3c..f0a6c61 100644 --- a/drivers/serial/uartlite.c +++ b/drivers/serial/uartlite.c @@ -19,7 +19,7 @@ #include #include #include -#if defined(CONFIG_OF) +#if defined(CONFIG_OF) && (defined(CONFIG_PPC32) || defined(CONFIG_MICROBLAZE)) #include #include #include @@ -581,7 +581,7 @@ static struct platform_driver ulite_platform_driver = { /* --------------------------------------------------------------------- * OF bus bindings */ -#if defined(CONFIG_OF) +#if defined(CONFIG_OF) && (defined(CONFIG_PPC32) || defined(CONFIG_MICROBLAZE)) static int __devinit ulite_of_probe(struct of_device *op, const struct of_device_id *match) { @@ -631,11 +631,11 @@ static inline void __exit ulite_of_unregister(void) { of_unregister_platform_driver(&ulite_of_driver); } -#else /* CONFIG_OF */ -/* CONFIG_OF not enabled; do nothing helpers */ +#else /* CONFIG_OF && (CONFIG_PPC32 || CONFIG_MICROBLAZE) */ +/* Appropriate config not enabled; do nothing helpers */ static inline int __init ulite_of_register(void) { return 0; } static inline void __exit ulite_of_unregister(void) { } -#endif /* CONFIG_OF */ +#endif /* CONFIG_OF && (CONFIG_PPC32 || CONFIG_MICROBLAZE) */ /* --------------------------------------------------------------------- * Module setup/teardown -- cgit v0.10.2 From e5a9a35cb9c0d92d7c986cb3696fb794be100087 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Fri, 5 Mar 2010 17:44:22 +0100 Subject: rt2x00: remove KSEG1ADDR define from rt2x00soc.h Remove the KSEG1ADDR define from rt2x00soc.h as it redefines and covers the correct one from the arch/mips/include/asm/addrspace.h. Otherwise the driver oopses on the target platform (Ralink rt3050 board). Signed-off-by: Helmut Schaa Acked-by: Ivo van Doorn Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/rt2x00/rt2x00soc.h b/drivers/net/wireless/rt2x00/rt2x00soc.h index 4739edf..474cbfc 100644 --- a/drivers/net/wireless/rt2x00/rt2x00soc.h +++ b/drivers/net/wireless/rt2x00/rt2x00soc.h @@ -26,8 +26,6 @@ #ifndef RT2X00SOC_H #define RT2X00SOC_H -#define KSEG1ADDR(__ptr) __ptr - /* * SoC driver handlers. */ -- cgit v0.10.2 From 38a679a52be13d5a0c766597ab823e06688d6e8e Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sat, 6 Mar 2010 18:35:08 +0200 Subject: mac80211: Fix sta_mtx unlocking on insert STA failure path Commit 34e895075e21be3e21e71d6317440d1ee7969ad0 introduced sta_mtx locking into sta_info_insert() (now sta_info_insert_rcu), but forgot to unlock this mutex on one of the error paths. Fix this by adding the missing mutex_unlock() call for the case where STA insert fails due to an entry existing already. This may happen at least in AP mode when a STA roams between two BSSes (vifs). Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 211c475..56422d8 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -434,6 +434,7 @@ int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU) /* check if STA exists already */ if (sta_info_get_bss(sdata, sta->sta.addr)) { spin_unlock_irqrestore(&local->sta_lock, flags); + mutex_unlock(&local->sta_mtx); rcu_read_lock(); err = -EEXIST; goto out_free; -- cgit v0.10.2 From 8e59340e4fb65cfd748eaa1e23db057c52520f35 Mon Sep 17 00:00:00 2001 From: Zhu Yi Date: Mon, 8 Mar 2010 13:18:03 +0800 Subject: libipw: split ieee->networks into small pieces The ieee->networks consists of 128 struct libipw_network entries. If we allocate this chunk of memory altogether, it ends up with an order 4 page allocation. High order page allocation is likely to fail on system high load. This patch splits the big chunk memory allocation into small pieces, each is 344 bytes, allocates them with 128 times. The patch fixed bug http://bugzilla.kernel.org/show_bug.cgi?id=14989 Signed-off-by: Zhu Yi Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ipw2x00/libipw.h b/drivers/net/wireless/ipw2x00/libipw.h index bf45391..a6d5e42 100644 --- a/drivers/net/wireless/ipw2x00/libipw.h +++ b/drivers/net/wireless/ipw2x00/libipw.h @@ -797,7 +797,7 @@ struct libipw_device { /* Probe / Beacon management */ struct list_head network_free_list; struct list_head network_list; - struct libipw_network *networks; + struct libipw_network *networks[MAX_NETWORK_COUNT]; int scans; int scan_age; diff --git a/drivers/net/wireless/ipw2x00/libipw_module.c b/drivers/net/wireless/ipw2x00/libipw_module.c index 1ae0b2b..2fa5586 100644 --- a/drivers/net/wireless/ipw2x00/libipw_module.c +++ b/drivers/net/wireless/ipw2x00/libipw_module.c @@ -67,16 +67,17 @@ void *libipw_wiphy_privid = &libipw_wiphy_privid; static int libipw_networks_allocate(struct libipw_device *ieee) { - if (ieee->networks) - return 0; - - ieee->networks = - kzalloc(MAX_NETWORK_COUNT * sizeof(struct libipw_network), - GFP_KERNEL); - if (!ieee->networks) { - printk(KERN_WARNING "%s: Out of memory allocating beacons\n", - ieee->dev->name); - return -ENOMEM; + int i, j; + + for (i = 0; i < MAX_NETWORK_COUNT; i++) { + ieee->networks[i] = kzalloc(sizeof(struct libipw_network), + GFP_KERNEL); + if (!ieee->networks[i]) { + LIBIPW_ERROR("Out of memory allocating beacons\n"); + for (j = 0; j < i; j++) + kfree(ieee->networks[j]); + return -ENOMEM; + } } return 0; @@ -97,15 +98,11 @@ static inline void libipw_networks_free(struct libipw_device *ieee) { int i; - if (!ieee->networks) - return; - - for (i = 0; i < MAX_NETWORK_COUNT; i++) - if (ieee->networks[i].ibss_dfs) - kfree(ieee->networks[i].ibss_dfs); - - kfree(ieee->networks); - ieee->networks = NULL; + for (i = 0; i < MAX_NETWORK_COUNT; i++) { + if (ieee->networks[i]->ibss_dfs) + kfree(ieee->networks[i]->ibss_dfs); + kfree(ieee->networks[i]); + } } void libipw_networks_age(struct libipw_device *ieee, @@ -130,7 +127,7 @@ static void libipw_networks_initialize(struct libipw_device *ieee) INIT_LIST_HEAD(&ieee->network_free_list); INIT_LIST_HEAD(&ieee->network_list); for (i = 0; i < MAX_NETWORK_COUNT; i++) - list_add_tail(&ieee->networks[i].list, + list_add_tail(&ieee->networks[i]->list, &ieee->network_free_list); } -- cgit v0.10.2 From 8bd8beab49fec3f7d014c328641bd94de3df744b Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Tue, 9 Mar 2010 16:55:23 +0900 Subject: ath5k: use fixed antenna for tx descriptors when using a fixed antenna we should use the antenna number in all tx descriptors, otherwise the hardware will sometimes send the frame out on the other antenna. it seems like the hardware does not always respect the default antenna and diversity settings (esp. AR5K_STA_ID1_DEFAULT_ANTENNA). also i would like to note that antenna diversity does not always work correctly on 5414 (at least) when only one antenna is connected: for example all frames might be received on antenna A but still the HW tries to send on antenna B some times, causing packet loss. this is both verified with the antenna statistics output of the previous patch and a spectrum analyzer. Signed-off-by: Bruno Randolf Acked-by: Nick Kossifidis Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 72474c0..ffe253a 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -1873,7 +1873,7 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode) break; case AR5K_ANTMODE_FIXED_A: def_ant = 1; - tx_ant = 0; + tx_ant = 1; use_def_for_tx = true; update_def_on_tx = false; use_def_for_rts = true; @@ -1882,7 +1882,7 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode) break; case AR5K_ANTMODE_FIXED_B: def_ant = 2; - tx_ant = 0; + tx_ant = 2; use_def_for_tx = true; update_def_on_tx = false; use_def_for_rts = true; -- cgit v0.10.2 From a3b980fd1391e75068ae25f3817728b27bfdb04c Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Tue, 9 Mar 2010 16:55:33 +0900 Subject: ath5k: fix TSF reset to reset the TSF, AR5K_BEACON_RESET_TSF has to be 1, not 0. also we have a function for that so use it. Signed-off-by: Bruno Randolf Acked-by: Nick Kossifidis Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index a35a7db..c780b55 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c @@ -1379,11 +1379,10 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, ath5k_hw_set_sleep_clock(ah, true); /* - * Disable beacons and reset the register + * Disable beacons and reset the TSF */ - AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE | - AR5K_BEACON_RESET_TSF); - + AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE); + ath5k_hw_reset_tsf(ah); return 0; } -- cgit v0.10.2 From 86415d43efd4f7093979cfa8a80232114266f1a4 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Tue, 9 Mar 2010 16:56:05 +0900 Subject: ath5k: fix I/Q calibration (for real) I/Q calibration was completely broken, resulting in a high number of CRC errors on received packets. before i could see around 10% to 20% CRC errors, with this patch they are between 0% and 3%. 1.) the removal of the mask in commit "ath5k: Fix I/Q calibration (f1cf2dbd0f798b71b1590e7aca6647f2caef1649)" resulted in no mask beeing used when writing the I/Q values into the register. additional errors in the calculation of the values (see 2.) resulted too high numbers, exceeding the masks, so wrong values like 0xfffffffe were written. to be safe we should always use the bitmask when writing parts of a register. 2.) using a (s32) cast for q_coff is a wrong conversion to signed, since we convert to a signed value later by substracting 128. this resulted in too low numbers for Q many times, which were limited to -16 by the boundary check later on. 3.) checked everything against the HAL sources and took over comments and minor optimizations from there. 4.) we can't use ENABLE_BITS when we want to write a number (the number can contain zeros). also always write the correction values first and set ENABLE bit last, like the HAL does. Signed-off-by: Bruno Randolf Cc: stable@kernel.org Acked-by: Nick Kossifidis Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index ffe253a..eff3323 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -1386,38 +1386,39 @@ static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah, goto done; /* Calibration has finished, get the results and re-run */ + + /* work around empty results which can apparently happen on 5212 */ for (i = 0; i <= 10; i++) { iq_corr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_CORR); i_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_I); q_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_Q); + ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_CALIBRATE, + "iq_corr:%x i_pwr:%x q_pwr:%x", iq_corr, i_pwr, q_pwr); + if (i_pwr && q_pwr) + break; } i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7; q_coffd = q_pwr >> 7; - /* No correction */ - if (i_coffd == 0 || q_coffd == 0) + /* protect against divide by 0 and loss of sign bits */ + if (i_coffd == 0 || q_coffd < 2) goto done; - i_coff = ((-iq_corr) / i_coffd); + i_coff = (-iq_corr) / i_coffd; + i_coff = clamp(i_coff, -32, 31); /* signed 6 bit */ - /* Boundary check */ - if (i_coff > 31) - i_coff = 31; - if (i_coff < -32) - i_coff = -32; + q_coff = (i_pwr / q_coffd) - 128; + q_coff = clamp(q_coff, -16, 15); /* signed 5 bit */ - q_coff = (((s32)i_pwr / q_coffd) - 128); + ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_CALIBRATE, + "new I:%d Q:%d (i_coffd:%x q_coffd:%x)", + i_coff, q_coff, i_coffd, q_coffd); - /* Boundary check */ - if (q_coff > 15) - q_coff = 15; - if (q_coff < -16) - q_coff = -16; - - /* Commit new I/Q value */ - AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE | - ((u32)q_coff) | ((u32)i_coff << AR5K_PHY_IQ_CORR_Q_I_COFF_S)); + /* Commit new I/Q values (set enable bit last to match HAL sources) */ + AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_I_COFF, i_coff); + AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_Q_COFF, q_coff); + AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE); /* Re-enable calibration -if we don't we'll commit * the same values again and again */ diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h index 4cb9c5d..1464f89 100644 --- a/drivers/net/wireless/ath/ath5k/reg.h +++ b/drivers/net/wireless/ath/ath5k/reg.h @@ -2187,6 +2187,7 @@ */ #define AR5K_PHY_IQ 0x9920 /* Register Address */ #define AR5K_PHY_IQ_CORR_Q_Q_COFF 0x0000001f /* Mask for q correction info */ +#define AR5K_PHY_IQ_CORR_Q_Q_COFF_S 0 #define AR5K_PHY_IQ_CORR_Q_I_COFF 0x000007e0 /* Mask for i correction info */ #define AR5K_PHY_IQ_CORR_Q_I_COFF_S 5 #define AR5K_PHY_IQ_CORR_ENABLE 0x00000800 /* Enable i/q correction */ -- cgit v0.10.2 From 5f13bfac0718ce6f83ecba3755f224c3790e8d66 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Tue, 9 Mar 2010 16:56:10 +0900 Subject: ath5k: read eeprom IQ calibration values correctly for G mode we read the IQ correction values (i_cal and q_cal) for G mode from a wrong location (the same shifts as for A mode is applied which is incorrect). use correct locations, matching the docs and HAL sources. also we should write IQ correction only when we have that information in the EEPROM, starting from version 4. also write it in the same way as we do in the periodic recalibration (enable last), just to be sure. Signed-off-by: Bruno Randolf Acked-by: Nick Kossifidis Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index 6a3f4da..10b5226 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c @@ -429,8 +429,8 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset, ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f; AR5K_EEPROM_READ(o++, val); - ee->ee_i_cal[mode] = (val >> 8) & 0x3f; - ee->ee_q_cal[mode] = (val >> 3) & 0x1f; + ee->ee_i_cal[mode] = (val >> 5) & 0x3f; + ee->ee_q_cal[mode] = val & 0x1f; if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) { AR5K_EEPROM_READ(o++, val); diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index c780b55..cbf28e3 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c @@ -851,12 +851,15 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah, AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1, AR5K_INIT_CYCRSSI_THR1); - /* I/Q correction - * TODO: Per channel i/q infos ? */ - AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, - AR5K_PHY_IQ_CORR_ENABLE | - (ee->ee_i_cal[ee_mode] << AR5K_PHY_IQ_CORR_Q_I_COFF_S) | - ee->ee_q_cal[ee_mode]); + /* I/Q correction (set enable bit last to match HAL sources) */ + /* TODO: Per channel i/q infos ? */ + if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) { + AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_I_COFF, + ee->ee_i_cal[ee_mode]); + AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_Q_COFF, + ee->ee_q_cal[ee_mode]); + AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE); + } /* Heavy clipping -disable for now */ if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_1) -- cgit v0.10.2 From 5e7749436d576a525d7b2a4bcffb17b3364b9e00 Mon Sep 17 00:00:00 2001 From: Scott Ellis Date: Wed, 10 Mar 2010 14:22:45 -0700 Subject: spi/omap2_mcspi: fix NULL pointer dereference Check spi->controller_state before dereferencing. Shows up NULL here when using spi_alloc_device()/spi_add_device() and spi_add_device() fails before spi_setup(). Calling spi_dev_put() on the leftover spi_device results in the error. Signed-off-by: Scott Ellis Signed-off-by: Grant Likely diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c index 715c518..87d44ee 100644 --- a/drivers/spi/omap2_mcspi.c +++ b/drivers/spi/omap2_mcspi.c @@ -751,11 +751,13 @@ static void omap2_mcspi_cleanup(struct spi_device *spi) mcspi = spi_master_get_devdata(spi->master); mcspi_dma = &mcspi->dma_channels[spi->chip_select]; - /* Unlink controller state from context save list */ - cs = spi->controller_state; - list_del(&cs->node); + if (spi->controller_state) { + /* Unlink controller state from context save list */ + cs = spi->controller_state; + list_del(&cs->node); - kfree(spi->controller_state); + kfree(spi->controller_state); + } if (mcspi_dma->dma_rx_channel != -1) { omap_free_dma(mcspi_dma->dma_rx_channel); -- cgit v0.10.2 From 9bd4517ddc51c803784778ab52e6f0bc03b77a52 Mon Sep 17 00:00:00 2001 From: Scott Ellis Date: Wed, 10 Mar 2010 14:23:13 -0700 Subject: spi/omap2_mcspi: Use transaction speed if provided omap2_mcspi_transfer() gets called in omap2_mcspi_work() when the transaction speed_hz or bits_per_word fields are non-zero. omap2_mcspi_transfer() does not look at the speed_hz field so the override speed value is ignored. The code should probably change to one of these options. 1. Skip the call to omap2_mcsp_transfer() if the only reason was a non-zero speed_hz and it's not going to be used. 2. Use the new speed_hz value provided The patch below uses the speed_hz value. Signed-off-by: Scott Ellis Signed-off-by: Grant Likely diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c index 87d44ee..4dd786b 100644 --- a/drivers/spi/omap2_mcspi.c +++ b/drivers/spi/omap2_mcspi.c @@ -578,6 +578,7 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi, struct spi_master *spi_cntrl; u32 l = 0, div = 0; u8 word_len = spi->bits_per_word; + u32 speed_hz = spi->max_speed_hz; mcspi = spi_master_get_devdata(spi->master); spi_cntrl = mcspi->master; @@ -587,9 +588,12 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi, cs->word_len = word_len; - if (spi->max_speed_hz) { + if (t && t->speed_hz) + speed_hz = t->speed_hz; + + if (speed_hz) { while (div <= 15 && (OMAP2_MCSPI_MAX_FREQ / (1 << div)) - > spi->max_speed_hz) + > speed_hz) div++; } else div = 15; -- cgit v0.10.2 From 41093167ec6c1854903a4bc38a37b5740c028984 Mon Sep 17 00:00:00 2001 From: Zhu Yi Date: Tue, 9 Mar 2010 16:05:31 +0800 Subject: ipw2200: use kmalloc for large local variables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed below compiler warning: drivers/net/wireless/ipw2x00/ipw2200.c: In function ‘ipw_load_firmware’: drivers/net/wireless/ipw2x00/ipw2200.c:3260: warning: the frame size of 1168 bytes is larger than 1024 bytes Signed-off-by: Zhu Yi Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index 63c2a7a..5c7aa1b 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c @@ -3177,14 +3177,27 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len) int total_nr = 0; int i; struct pci_pool *pool; - u32 *virts[CB_NUMBER_OF_ELEMENTS_SMALL]; - dma_addr_t phys[CB_NUMBER_OF_ELEMENTS_SMALL]; + void **virts; + dma_addr_t *phys; IPW_DEBUG_TRACE("<< : \n"); + virts = kmalloc(sizeof(void *) * CB_NUMBER_OF_ELEMENTS_SMALL, + GFP_KERNEL); + if (!virts) + return -ENOMEM; + + phys = kmalloc(sizeof(dma_addr_t) * CB_NUMBER_OF_ELEMENTS_SMALL, + GFP_KERNEL); + if (!phys) { + kfree(virts); + return -ENOMEM; + } pool = pci_pool_create("ipw2200", priv->pci_dev, CB_MAX_LENGTH, 0, 0); if (!pool) { IPW_ERROR("pci_pool_create failed\n"); + kfree(phys); + kfree(virts); return -ENOMEM; } @@ -3254,6 +3267,8 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len) pci_pool_free(pool, virts[i], phys[i]); pci_pool_destroy(pool); + kfree(phys); + kfree(virts); return ret; } -- cgit v0.10.2 From 2a13052fe495948e572839e514e0e0cd236c50b0 Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Tue, 9 Mar 2010 14:25:02 +0200 Subject: mac80211: Fix (dynamic) power save entry Currently hardware with !IEEE80211_HW_PS_NULLFUNC_STACK and IEEE80211_HW_REPORTS_TX_ACK_STATUS will never enter PSM due to the conditions in the power save entry functions. Fix those conditions. Signed-off-by: Juuso Oikarinen Cc: stable@kernel.org Signed-off-by: John W. Linville diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 0ab284c..be5f723 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -436,10 +436,12 @@ static void ieee80211_enable_ps(struct ieee80211_local *local, if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) ieee80211_send_nullfunc(local, sdata, 1); - if (!(local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) { - conf->flags |= IEEE80211_CONF_PS; - ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); - } + if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) && + (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) + return; + + conf->flags |= IEEE80211_CONF_PS; + ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); } } @@ -558,7 +560,8 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work) (!(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED))) ieee80211_send_nullfunc(local, sdata, 1); - if (!(local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) || + if (!((local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) && + (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)) || (ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED)) { ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED; local->hw.conf.flags |= IEEE80211_CONF_PS; -- cgit v0.10.2 From 51f5f8ca446d4c59041b9b6995821e13208897ea Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 10 Mar 2010 17:13:36 +0100 Subject: mac80211: Fix memory leak in ieee80211_if_write() Fix memory leak and use kmalloc() instead of kzalloc() as we are going to overwrite the allocated buffer. Signed-off-by: Eric Dumazet Signed-off-by: John W. Linville diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index 9affe2c..b4ddb2f 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c @@ -48,20 +48,24 @@ static ssize_t ieee80211_if_write( ssize_t (*write)(struct ieee80211_sub_if_data *, const char *, int)) { u8 *buf; - ssize_t ret = -ENODEV; + ssize_t ret; - buf = kzalloc(count, GFP_KERNEL); + buf = kmalloc(count, GFP_KERNEL); if (!buf) return -ENOMEM; + ret = -EFAULT; if (copy_from_user(buf, userbuf, count)) - return -EFAULT; + goto freebuf; + ret = -ENODEV; rtnl_lock(); if (sdata->dev->reg_state == NETREG_REGISTERED) ret = (*write)(sdata, buf, count); rtnl_unlock(); +freebuf: + kfree(buf); return ret; } -- cgit v0.10.2 From acc6a0935e5958ad1a1b99a1c6f44a52264bedf0 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Wed, 10 Mar 2010 14:39:50 -0700 Subject: powerpc/52xx: update defconfigs Signed-off-by: Grant Likely diff --git a/arch/powerpc/configs/52xx/cm5200_defconfig b/arch/powerpc/configs/52xx/cm5200_defconfig index ff9bdb2..218d49b 100644 --- a/arch/powerpc/configs/52xx/cm5200_defconfig +++ b/arch/powerpc/configs/52xx/cm5200_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Wed Dec 30 14:45:07 2009 +# Linux kernel version: 2.6.34-rc1 +# Wed Mar 10 14:34:22 2010 # # CONFIG_PPC64 is not set @@ -94,11 +94,6 @@ CONFIG_RCU_FANOUT=32 # CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -109,6 +104,7 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -340,7 +336,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y CONFIG_XFRM_USER=y @@ -517,6 +512,8 @@ CONFIG_MTD_PHYSMAP_OF=y # UBI - Unsorted block images # # CONFIG_MTD_UBI is not set +CONFIG_OF_FLATTREE=y +CONFIG_OF_DYNAMIC=y CONFIG_OF_DEVICE=y CONFIG_OF_I2C=y CONFIG_OF_MDIO=y @@ -684,6 +681,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_SERIAL_MPC52xx=y CONFIG_SERIAL_MPC52xx_CONSOLE=y CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=57600 +# CONFIG_SERIAL_TIMBERDALE is not set # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set @@ -714,6 +712,7 @@ CONFIG_I2C_HELPER_AUTO=y CONFIG_I2C_MPC=y # CONFIG_I2C_OCORES is not set # CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set # # External I2C/SMBus adapter drivers @@ -754,6 +753,7 @@ CONFIG_WATCHDOG=y # Watchdog Device Drivers # # CONFIG_SOFT_WATCHDOG is not set +# CONFIG_MAX63XX_WATCHDOG is not set # CONFIG_MPC5200_WDT is not set # @@ -771,18 +771,20 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set # CONFIG_MFD_SM501 is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set # CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_AB3100_CORE is not set -# CONFIG_MFD_88PM8607 is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -813,7 +815,6 @@ CONFIG_USB=y CONFIG_USB_DEVICEFS=y # CONFIG_USB_DEVICE_CLASS is not set # CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_SUSPEND is not set # CONFIG_USB_OTG is not set # CONFIG_USB_OTG_WHITELIST is not set # CONFIG_USB_OTG_BLACKLIST_HUB is not set @@ -891,7 +892,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set @@ -903,7 +903,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_IOWARRIOR is not set # CONFIG_USB_TEST is not set # CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_VST is not set # CONFIG_USB_GADGET is not set # @@ -1009,6 +1008,7 @@ CONFIG_JFFS2_ZLIB=y # CONFIG_JFFS2_LZO is not set CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set +# CONFIG_LOGFS is not set CONFIG_CRAMFS=y # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set diff --git a/arch/powerpc/configs/52xx/lite5200b_defconfig b/arch/powerpc/configs/52xx/lite5200b_defconfig index 7b3f4d0..90492ff 100644 --- a/arch/powerpc/configs/52xx/lite5200b_defconfig +++ b/arch/powerpc/configs/52xx/lite5200b_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Wed Dec 30 14:45:09 2009 +# Linux kernel version: 2.6.34-rc1 +# Wed Mar 10 14:34:24 2010 # # CONFIG_PPC64 is not set @@ -95,11 +95,6 @@ CONFIG_RCU_FANOUT=32 # CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -CONFIG_GROUP_SCHED=y -# CONFIG_FAIR_GROUP_SCHED is not set -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -110,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -317,6 +313,7 @@ CONFIG_SUSPEND=y CONFIG_SUSPEND_FREEZER=y # CONFIG_HIBERNATION is not set # CONFIG_PM_RUNTIME is not set +CONFIG_PM_OPS=y CONFIG_SECCOMP=y CONFIG_ISA_DMA_API=y @@ -333,7 +330,6 @@ CONFIG_PCI_SYSCALL=y # CONFIG_PCIEPORTBUS is not set CONFIG_ARCH_SUPPORTS_MSI=y # CONFIG_PCI_MSI is not set -CONFIG_PCI_LEGACY=y # CONFIG_PCI_DEBUG is not set # CONFIG_PCI_STUB is not set # CONFIG_PCI_IOV is not set @@ -360,7 +356,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y CONFIG_XFRM_USER=m @@ -457,6 +452,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_SYS_HYPERVISOR is not set # CONFIG_CONNECTOR is not set # CONFIG_MTD is not set +CONFIG_OF_FLATTREE=y +CONFIG_OF_DYNAMIC=y CONFIG_OF_DEVICE=y CONFIG_OF_I2C=y CONFIG_OF_MDIO=y @@ -631,6 +628,7 @@ CONFIG_ATA_SFF=y # CONFIG_PATA_IT821X is not set # CONFIG_PATA_IT8213 is not set # CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_LEGACY is not set # CONFIG_PATA_TRIFLEX is not set # CONFIG_PATA_MARVELL is not set CONFIG_PATA_MPC52xx=y @@ -668,7 +666,7 @@ CONFIG_PATA_MPC52xx=y # # -# See the help texts for more information. +# The newer stack is recommended. # # CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set @@ -768,6 +766,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_MLX4_CORE is not set # CONFIG_TEHUTI is not set # CONFIG_BNX2X is not set +# CONFIG_QLCNIC is not set # CONFIG_QLGE is not set # CONFIG_SFC is not set # CONFIG_BE2NET is not set @@ -828,6 +827,7 @@ CONFIG_SERIAL_MPC52xx=y CONFIG_SERIAL_MPC52xx_CONSOLE=y CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200 # CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_TIMBERDALE is not set # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set @@ -879,6 +879,7 @@ CONFIG_I2C_HELPER_AUTO=y CONFIG_I2C_MPC=y # CONFIG_I2C_OCORES is not set # CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set # # External I2C/SMBus adapter drivers @@ -924,18 +925,21 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set # CONFIG_MFD_SM501 is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set # CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_AB3100_CORE is not set -# CONFIG_MFD_88PM8607 is not set +# CONFIG_LPC_SCH is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -944,6 +948,7 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_AGP is not set CONFIG_VGA_ARB=y +CONFIG_VGA_ARB_MAX_GPUS=16 # CONFIG_DRM is not set # CONFIG_VGASTATE is not set CONFIG_VIDEO_OUTPUT_CONTROL=m @@ -1062,6 +1067,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set +# CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set diff --git a/arch/powerpc/configs/52xx/motionpro_defconfig b/arch/powerpc/configs/52xx/motionpro_defconfig index eaae2d4..dffc8ca 100644 --- a/arch/powerpc/configs/52xx/motionpro_defconfig +++ b/arch/powerpc/configs/52xx/motionpro_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Wed Dec 30 14:45:08 2009 +# Linux kernel version: 2.6.34-rc1 +# Wed Mar 10 14:34:23 2010 # # CONFIG_PPC64 is not set @@ -94,11 +94,6 @@ CONFIG_RCU_FANOUT=32 # CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -109,6 +104,7 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -341,7 +337,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y CONFIG_XFRM_USER=y @@ -518,6 +513,8 @@ CONFIG_MTD_ROM=y # UBI - Unsorted block images # # CONFIG_MTD_UBI is not set +CONFIG_OF_FLATTREE=y +CONFIG_OF_DYNAMIC=y CONFIG_OF_DEVICE=y CONFIG_OF_I2C=y CONFIG_OF_MDIO=y @@ -699,6 +696,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_SERIAL_MPC52xx=y CONFIG_SERIAL_MPC52xx_CONSOLE=y CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200 +# CONFIG_SERIAL_TIMBERDALE is not set # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set @@ -728,6 +726,7 @@ CONFIG_I2C_HELPER_AUTO=y CONFIG_I2C_MPC=y # CONFIG_I2C_OCORES is not set # CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set # # External I2C/SMBus adapter drivers @@ -773,10 +772,11 @@ CONFIG_HWMON=y # CONFIG_SENSORS_ADM1029 is not set # CONFIG_SENSORS_ADM1031 is not set # CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ADT7411 is not set # CONFIG_SENSORS_ADT7462 is not set # CONFIG_SENSORS_ADT7470 is not set -# CONFIG_SENSORS_ADT7473 is not set # CONFIG_SENSORS_ADT7475 is not set +# CONFIG_SENSORS_ASC7621 is not set # CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS1621 is not set # CONFIG_SENSORS_F71805F is not set @@ -811,6 +811,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_SMSC47M192 is not set # CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_ADS7828 is not set +# CONFIG_SENSORS_AMC6821 is not set # CONFIG_SENSORS_THMC50 is not set # CONFIG_SENSORS_TMP401 is not set # CONFIG_SENSORS_TMP421 is not set @@ -831,6 +832,7 @@ CONFIG_WATCHDOG=y # Watchdog Device Drivers # # CONFIG_SOFT_WATCHDOG is not set +# CONFIG_MAX63XX_WATCHDOG is not set # CONFIG_MPC5200_WDT is not set CONFIG_SSB_POSSIBLE=y @@ -843,18 +845,20 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set # CONFIG_MFD_SM501 is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set # CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_AB3100_CORE is not set -# CONFIG_MFD_88PM8607 is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -1050,6 +1054,7 @@ CONFIG_JFFS2_ZLIB=y # CONFIG_JFFS2_LZO is not set CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set +# CONFIG_LOGFS is not set CONFIG_CRAMFS=y # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set diff --git a/arch/powerpc/configs/52xx/pcm030_defconfig b/arch/powerpc/configs/52xx/pcm030_defconfig index 1742c02..3cb2a52 100644 --- a/arch/powerpc/configs/52xx/pcm030_defconfig +++ b/arch/powerpc/configs/52xx/pcm030_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Wed Dec 30 14:45:10 2009 +# Linux kernel version: 2.6.34-rc1 +# Wed Mar 10 14:34:25 2010 # # CONFIG_PPC64 is not set @@ -97,11 +97,6 @@ CONFIG_RCU_FANOUT=32 CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -326,7 +321,6 @@ CONFIG_PCI_SYSCALL=y # CONFIG_PCIEPORTBUS is not set CONFIG_ARCH_SUPPORTS_MSI=y # CONFIG_PCI_MSI is not set -CONFIG_PCI_LEGACY=y # CONFIG_PCI_STUB is not set # CONFIG_PCI_IOV is not set # CONFIG_PCCARD is not set @@ -352,7 +346,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y @@ -525,6 +518,8 @@ CONFIG_MTD_PHYSMAP=y # UBI - Unsorted block images # # CONFIG_MTD_UBI is not set +CONFIG_OF_FLATTREE=y +CONFIG_OF_DYNAMIC=y CONFIG_OF_DEVICE=y CONFIG_OF_I2C=y CONFIG_OF_MDIO=y @@ -610,6 +605,7 @@ CONFIG_ATA_SFF=y # CONFIG_PATA_IT821X is not set # CONFIG_PATA_IT8213 is not set # CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_LEGACY is not set # CONFIG_PATA_TRIFLEX is not set # CONFIG_PATA_MARVELL is not set CONFIG_PATA_MPC52xx=m @@ -647,7 +643,7 @@ CONFIG_PATA_MPC52xx=m # # -# See the help texts for more information. +# The newer stack is recommended. # # CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set @@ -775,6 +771,7 @@ CONFIG_SERIAL_MPC52xx=y CONFIG_SERIAL_MPC52xx_CONSOLE=y CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=9600 # CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_TIMBERDALE is not set # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set @@ -824,6 +821,7 @@ CONFIG_I2C_HELPER_AUTO=y CONFIG_I2C_MPC=y # CONFIG_I2C_OCORES is not set # CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set # # External I2C/SMBus adapter drivers @@ -870,18 +868,21 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set # CONFIG_MFD_SM501 is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set # CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_AB3100_CORE is not set -# CONFIG_MFD_88PM8607 is not set +# CONFIG_LPC_SCH is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -890,6 +891,7 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_AGP is not set CONFIG_VGA_ARB=y +CONFIG_VGA_ARB_MAX_GPUS=16 # CONFIG_DRM is not set # CONFIG_VGASTATE is not set # CONFIG_VIDEO_OUTPUT_CONTROL is not set @@ -997,7 +999,6 @@ CONFIG_USB_STORAGE=m # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set @@ -1009,7 +1010,6 @@ CONFIG_USB_STORAGE=m # CONFIG_USB_IOWARRIOR is not set # CONFIG_USB_TEST is not set # CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_VST is not set # CONFIG_USB_GADGET is not set # @@ -1172,6 +1172,7 @@ CONFIG_JFFS2_ZLIB=y # CONFIG_JFFS2_LZO is not set CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set +# CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set diff --git a/arch/powerpc/configs/52xx/tqm5200_defconfig b/arch/powerpc/configs/52xx/tqm5200_defconfig index 3972438..96181c6 100644 --- a/arch/powerpc/configs/52xx/tqm5200_defconfig +++ b/arch/powerpc/configs/52xx/tqm5200_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Wed Dec 30 14:45:09 2009 +# Linux kernel version: 2.6.34-rc1 +# Wed Mar 10 14:34:24 2010 # # CONFIG_PPC64 is not set @@ -94,11 +94,6 @@ CONFIG_RCU_FANOUT=32 # CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y @@ -109,6 +104,7 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -346,7 +342,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y CONFIG_XFRM_USER=y @@ -524,6 +519,8 @@ CONFIG_MTD_PHYSMAP_OF=y # UBI - Unsorted block images # # CONFIG_MTD_UBI is not set +CONFIG_OF_FLATTREE=y +CONFIG_OF_DYNAMIC=y CONFIG_OF_DEVICE=y CONFIG_OF_I2C=y CONFIG_OF_MDIO=y @@ -704,6 +701,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_SERIAL_MPC52xx=y CONFIG_SERIAL_MPC52xx_CONSOLE=y CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200 +# CONFIG_SERIAL_TIMBERDALE is not set # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set @@ -733,6 +731,7 @@ CONFIG_I2C_HELPER_AUTO=y CONFIG_I2C_MPC=y # CONFIG_I2C_OCORES is not set # CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set # # External I2C/SMBus adapter drivers @@ -780,10 +779,11 @@ CONFIG_HWMON=y # CONFIG_SENSORS_ADM1029 is not set # CONFIG_SENSORS_ADM1031 is not set # CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ADT7411 is not set # CONFIG_SENSORS_ADT7462 is not set # CONFIG_SENSORS_ADT7470 is not set -# CONFIG_SENSORS_ADT7473 is not set # CONFIG_SENSORS_ADT7475 is not set +# CONFIG_SENSORS_ASC7621 is not set # CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS1621 is not set # CONFIG_SENSORS_F71805F is not set @@ -818,6 +818,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_SMSC47M192 is not set # CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_ADS7828 is not set +# CONFIG_SENSORS_AMC6821 is not set # CONFIG_SENSORS_THMC50 is not set # CONFIG_SENSORS_TMP401 is not set # CONFIG_SENSORS_TMP421 is not set @@ -838,6 +839,7 @@ CONFIG_WATCHDOG=y # Watchdog Device Drivers # # CONFIG_SOFT_WATCHDOG is not set +# CONFIG_MAX63XX_WATCHDOG is not set # CONFIG_MPC5200_WDT is not set # @@ -855,18 +857,20 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set # CONFIG_MFD_SM501 is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set # CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_AB3100_CORE is not set -# CONFIG_MFD_88PM8607 is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -897,7 +901,6 @@ CONFIG_USB=y CONFIG_USB_DEVICEFS=y # CONFIG_USB_DEVICE_CLASS is not set # CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_SUSPEND is not set # CONFIG_USB_OTG is not set # CONFIG_USB_OTG_WHITELIST is not set # CONFIG_USB_OTG_BLACKLIST_HUB is not set @@ -975,7 +978,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set @@ -987,7 +989,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_IOWARRIOR is not set # CONFIG_USB_TEST is not set # CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_VST is not set # CONFIG_USB_GADGET is not set # @@ -1151,6 +1152,7 @@ CONFIG_JFFS2_ZLIB=y # CONFIG_JFFS2_LZO is not set CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set +# CONFIG_LOGFS is not set CONFIG_CRAMFS=y # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set diff --git a/arch/powerpc/configs/mpc5200_defconfig b/arch/powerpc/configs/mpc5200_defconfig index 61cf73d..7012ac0 100644 --- a/arch/powerpc/configs/mpc5200_defconfig +++ b/arch/powerpc/configs/mpc5200_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Wed Dec 30 15:08:52 2009 +# Linux kernel version: 2.6.34-rc1 +# Wed Mar 10 14:38:54 2010 # # CONFIG_PPC64 is not set @@ -96,30 +96,37 @@ CONFIG_RCU_FANOUT=32 # CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y # CONFIG_RELAY is not set -# CONFIG_NAMESPACES is not set +CONFIG_NAMESPACES=y +# CONFIG_UTS_NS is not set +# CONFIG_IPC_NS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_NET_NS is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y -# CONFIG_RD_BZIP2 is not set -# CONFIG_RD_LZMA is not set +CONFIG_RD_BZIP2=y +CONFIG_RD_LZMA=y +CONFIG_RD_LZO=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_ANON_INODES=y -CONFIG_EMBEDDED=y -# CONFIG_SYSCTL_SYSCALL is not set -# CONFIG_KALLSYMS is not set +# CONFIG_EMBEDDED is not set +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y -# CONFIG_EPOLL is not set +CONFIG_EPOLL=y CONFIG_SIGNALFD=y CONFIG_TIMERFD=y CONFIG_EVENTFD=y @@ -141,6 +148,7 @@ CONFIG_SLUB=y # CONFIG_SLOB is not set # CONFIG_PROFILING is not set CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y @@ -320,6 +328,7 @@ CONFIG_SUSPEND=y CONFIG_SUSPEND_FREEZER=y # CONFIG_HIBERNATION is not set # CONFIG_PM_RUNTIME is not set +CONFIG_PM_OPS=y CONFIG_SECCOMP=y CONFIG_ISA_DMA_API=y @@ -336,7 +345,6 @@ CONFIG_PCI_SYSCALL=y # CONFIG_PCIEPORTBUS is not set CONFIG_ARCH_SUPPORTS_MSI=y # CONFIG_PCI_MSI is not set -CONFIG_PCI_LEGACY=y # CONFIG_PCI_DEBUG is not set # CONFIG_PCI_STUB is not set # CONFIG_PCI_IOV is not set @@ -363,7 +371,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y CONFIG_XFRM_USER=m @@ -454,7 +461,9 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_DEVTMPFS is not set CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_FW_LOADER is not set +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" # CONFIG_DEBUG_DRIVER is not set # CONFIG_DEBUG_DEVRES is not set # CONFIG_SYS_HYPERVISOR is not set @@ -554,6 +563,8 @@ CONFIG_MTD_UBI_BEB_RESERVE=1 # UBI debugging options # # CONFIG_MTD_UBI_DEBUG is not set +CONFIG_OF_FLATTREE=y +CONFIG_OF_DYNAMIC=y CONFIG_OF_DEVICE=y CONFIG_OF_GPIO=y CONFIG_OF_I2C=y @@ -732,6 +743,7 @@ CONFIG_ATA_SFF=y # CONFIG_PATA_IT821X is not set # CONFIG_PATA_IT8213 is not set # CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_LEGACY is not set # CONFIG_PATA_TRIFLEX is not set # CONFIG_PATA_MARVELL is not set CONFIG_PATA_MPC52xx=y @@ -770,7 +782,7 @@ CONFIG_PATA_PLATFORM=y # # -# See the help texts for more information. +# The newer stack is recommended. # # CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set @@ -929,6 +941,7 @@ CONFIG_SERIAL_MPC52xx=y CONFIG_SERIAL_MPC52xx_CONSOLE=y CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200 # CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_TIMBERDALE is not set # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set @@ -981,6 +994,7 @@ CONFIG_I2C_ALGOBIT=y CONFIG_I2C_MPC=y # CONFIG_I2C_OCORES is not set # CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set # # External I2C/SMBus adapter drivers @@ -1010,9 +1024,9 @@ CONFIG_SPI_MASTER=y # # SPI Master Controller Drivers # -# CONFIG_SPI_BITBANG is not set -# CONFIG_SPI_GPIO is not set -# CONFIG_SPI_MPC52xx is not set +CONFIG_SPI_BITBANG=m +CONFIG_SPI_GPIO=m +CONFIG_SPI_MPC52xx=m CONFIG_SPI_MPC52xx_PSC=m # CONFIG_SPI_XILINX is not set # CONFIG_SPI_DESIGNWARE is not set @@ -1036,14 +1050,18 @@ CONFIG_GPIOLIB=y # # Memory mapped GPIO expanders: # +# CONFIG_GPIO_IT8761E is not set # CONFIG_GPIO_XILINX is not set +# CONFIG_GPIO_SCH is not set # # I2C GPIO expanders: # +# CONFIG_GPIO_MAX7300 is not set # CONFIG_GPIO_MAX732X is not set # CONFIG_GPIO_PCA953X is not set # CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_ADP5588 is not set # # PCI GPIO expanders: @@ -1080,10 +1098,11 @@ CONFIG_HWMON=y # CONFIG_SENSORS_ADM1029 is not set # CONFIG_SENSORS_ADM1031 is not set # CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ADT7411 is not set # CONFIG_SENSORS_ADT7462 is not set # CONFIG_SENSORS_ADT7470 is not set -# CONFIG_SENSORS_ADT7473 is not set # CONFIG_SENSORS_ADT7475 is not set +# CONFIG_SENSORS_ASC7621 is not set # CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS1621 is not set # CONFIG_SENSORS_I5K_AMB is not set @@ -1123,6 +1142,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_SMSC47M192 is not set # CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_ADS7828 is not set +# CONFIG_SENSORS_AMC6821 is not set # CONFIG_SENSORS_THMC50 is not set # CONFIG_SENSORS_TMP401 is not set # CONFIG_SENSORS_TMP421 is not set @@ -1147,6 +1167,7 @@ CONFIG_WATCHDOG=y # Watchdog Device Drivers # # CONFIG_SOFT_WATCHDOG is not set +# CONFIG_MAX63XX_WATCHDOG is not set # CONFIG_ALIM7101_WDT is not set # CONFIG_MPC5200_WDT is not set # CONFIG_WATCHDOG_RTAS is not set @@ -1172,22 +1193,27 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set # CONFIG_MFD_SM501 is not set # CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set # CONFIG_TPS65010 is not set # CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set # CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_MFD_MC13783 is not set # CONFIG_AB3100_CORE is not set # CONFIG_EZX_PCAP is not set -# CONFIG_MFD_88PM8607 is not set # CONFIG_AB4500_CORE is not set +# CONFIG_MFD_TIMBERDALE is not set +# CONFIG_LPC_SCH is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set @@ -1196,6 +1222,7 @@ CONFIG_SSB_POSSIBLE=y # # CONFIG_AGP is not set CONFIG_VGA_ARB=y +CONFIG_VGA_ARB_MAX_GPUS=16 CONFIG_DRM=y # CONFIG_DRM_TDFX is not set # CONFIG_DRM_R128 is not set @@ -1309,32 +1336,46 @@ CONFIG_USB_HID=y # # Special HID drivers # +# CONFIG_HID_3M_PCT is not set CONFIG_HID_A4TECH=y -# CONFIG_HID_APPLE is not set +CONFIG_HID_APPLE=y CONFIG_HID_BELKIN=y CONFIG_HID_CHERRY=y -# CONFIG_HID_CHICONY is not set +CONFIG_HID_CHICONY=y CONFIG_HID_CYPRESS=y -# CONFIG_HID_DRAGONRISE is not set +CONFIG_HID_DRAGONRISE=y +# CONFIG_DRAGONRISE_FF is not set CONFIG_HID_EZKEY=y -# CONFIG_HID_KYE is not set -# CONFIG_HID_GYRATION is not set -# CONFIG_HID_TWINHAN is not set -# CONFIG_HID_KENSINGTON is not set -# CONFIG_HID_LOGITECH is not set -# CONFIG_HID_MICROSOFT is not set -# CONFIG_HID_MONTEREY is not set +CONFIG_HID_KYE=y +CONFIG_HID_GYRATION=y +CONFIG_HID_TWINHAN=y +CONFIG_HID_KENSINGTON=y +CONFIG_HID_LOGITECH=y +# CONFIG_LOGITECH_FF is not set +# CONFIG_LOGIRUMBLEPAD2_FF is not set +# CONFIG_LOGIG940_FF is not set +CONFIG_HID_MICROSOFT=y +# CONFIG_HID_MOSART is not set +CONFIG_HID_MONTEREY=y # CONFIG_HID_NTRIG is not set -# CONFIG_HID_PANTHERLORD is not set -# CONFIG_HID_PETALYNX is not set -# CONFIG_HID_SAMSUNG is not set -# CONFIG_HID_SONY is not set -# CONFIG_HID_SUNPLUS is not set -# CONFIG_HID_GREENASIA is not set -# CONFIG_HID_SMARTJOYPLUS is not set -# CONFIG_HID_TOPSEED is not set -# CONFIG_HID_THRUSTMASTER is not set -# CONFIG_HID_ZEROPLUS is not set +CONFIG_HID_ORTEK=y +CONFIG_HID_PANTHERLORD=y +# CONFIG_PANTHERLORD_FF is not set +CONFIG_HID_PETALYNX=y +# CONFIG_HID_QUANTA is not set +CONFIG_HID_SAMSUNG=y +CONFIG_HID_SONY=y +# CONFIG_HID_STANTUM is not set +CONFIG_HID_SUNPLUS=y +CONFIG_HID_GREENASIA=y +# CONFIG_GREENASIA_FF is not set +CONFIG_HID_SMARTJOYPLUS=y +# CONFIG_SMARTJOYPLUS_FF is not set +CONFIG_HID_TOPSEED=y +CONFIG_HID_THRUSTMASTER=y +# CONFIG_THRUSTMASTER_FF is not set +CONFIG_HID_ZEROPLUS=y +# CONFIG_ZEROPLUS_FF is not set CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y @@ -1349,10 +1390,7 @@ CONFIG_USB=y CONFIG_USB_DEVICEFS=y # CONFIG_USB_DEVICE_CLASS is not set # CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_SUSPEND is not set # CONFIG_USB_OTG is not set -# CONFIG_USB_OTG_WHITELIST is not set -# CONFIG_USB_OTG_BLACKLIST_HUB is not set CONFIG_USB_MON=y # CONFIG_USB_WUSB is not set # CONFIG_USB_WUSB_CBAF is not set @@ -1433,7 +1471,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set @@ -1445,7 +1482,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_IOWARRIOR is not set # CONFIG_USB_TEST is not set # CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_VST is not set # CONFIG_USB_GADGET is not set # @@ -1636,6 +1672,7 @@ CONFIG_UBIFS_FS=m CONFIG_UBIFS_FS_LZO=y CONFIG_UBIFS_FS_ZLIB=y # CONFIG_UBIFS_FS_DEBUG is not set +# CONFIG_LOGFS is not set CONFIG_CRAMFS=y # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -1730,8 +1767,11 @@ CONFIG_CRC32=y CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y CONFIG_LZO_COMPRESS=m -CONFIG_LZO_DECOMPRESS=m +CONFIG_LZO_DECOMPRESS=y CONFIG_DECOMPRESS_GZIP=y +CONFIG_DECOMPRESS_BZIP2=y +CONFIG_DECOMPRESS_LZMA=y +CONFIG_DECOMPRESS_LZO=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y @@ -1776,11 +1816,11 @@ CONFIG_SCHED_DEBUG=y # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set -# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_BUGVERBOSE=y CONFIG_DEBUG_INFO=y # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_WRITECOUNT is not set -# CONFIG_DEBUG_MEMORY_INIT is not set +CONFIG_DEBUG_MEMORY_INIT=y # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set # CONFIG_DEBUG_NOTIFIERS is not set -- cgit v0.10.2 From 04b4b88cca0ebe3813b4b6f014fb6a0db380b137 Mon Sep 17 00:00:00 2001 From: Vadim Zaliva Date: Wed, 10 Mar 2010 23:41:00 -0800 Subject: Input: appletouch - fix integer overflow issue When reading data from Geyser 2 touchpads used on post Oct 2005 Apple PowerBooks the driver was casting X and Y coordinates values to 'signed char'. Testing on one of such PowerBooks I have noticed that touchpad always generates positive values, but some of them are greater that 127, and thus, when cast to 'signed char' being interpreted as a negative. Such bigger values have been observed infrequently, closer to the edges of a touchpad, so the problem was not very visible. Nevertheless, the patch would potentially improve touchpad driver accuracy. Signed-off-by: Vadim Zaliva Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c index 908b5b4..53ec7dd 100644 --- a/drivers/input/mouse/appletouch.c +++ b/drivers/input/mouse/appletouch.c @@ -205,8 +205,8 @@ struct atp { bool overflow_warned; int x_old; /* last reported x/y, */ int y_old; /* used for smoothing */ - signed char xy_cur[ATP_XSENSORS + ATP_YSENSORS]; - signed char xy_old[ATP_XSENSORS + ATP_YSENSORS]; + u8 xy_cur[ATP_XSENSORS + ATP_YSENSORS]; + u8 xy_old[ATP_XSENSORS + ATP_YSENSORS]; int xy_acc[ATP_XSENSORS + ATP_YSENSORS]; int idlecount; /* number of empty packets */ struct work_struct work; @@ -531,7 +531,7 @@ static void atp_complete_geyser_1_2(struct urb *urb) for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++) { /* accumulate the change */ - signed char change = dev->xy_old[i] - dev->xy_cur[i]; + int change = dev->xy_old[i] - dev->xy_cur[i]; dev->xy_acc[i] -= change; /* prevent down drifting */ -- cgit v0.10.2 From fdba2bb1f2eed85085a0fe154e1acb82de3239f7 Mon Sep 17 00:00:00 2001 From: Ranjith Lohithakshan Date: Wed, 10 Mar 2010 23:41:22 -0800 Subject: Input: ads7846 - add wakeup support Add wakeup support to the ads7846 driver. Platforms can enable wakeup capability by setting the wakeup flag in ads7846_platform_data. With this patch the ads7846 driver can be used to wake the system from suspend. Signed-off-by: Ranjith Lohithakshan Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index d187be0..532279c 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -822,6 +822,9 @@ static int ads7846_suspend(struct spi_device *spi, pm_message_t message) spin_unlock_irq(&ts->lock); + if (device_may_wakeup(&ts->spi->dev)) + enable_irq_wake(ts->spi->irq); + return 0; } @@ -830,6 +833,9 @@ static int ads7846_resume(struct spi_device *spi) { struct ads7846 *ts = dev_get_drvdata(&spi->dev); + if (device_may_wakeup(&ts->spi->dev)) + disable_irq_wake(ts->spi->irq); + spin_lock_irq(&ts->lock); ts->is_suspended = 0; @@ -1201,6 +1207,8 @@ static int __devinit ads7846_probe(struct spi_device *spi) if (err) goto err_remove_attr_group; + device_init_wakeup(&spi->dev, pdata->wakeup); + return 0; err_remove_attr_group: @@ -1230,6 +1238,8 @@ static int __devexit ads7846_remove(struct spi_device *spi) { struct ads7846 *ts = dev_get_drvdata(&spi->dev); + device_init_wakeup(&spi->dev, false); + ads784x_hwmon_unregister(spi, ts); input_unregister_device(ts->input); diff --git a/include/linux/spi/ads7846.h b/include/linux/spi/ads7846.h index 5710c15..b4ae570 100644 --- a/include/linux/spi/ads7846.h +++ b/include/linux/spi/ads7846.h @@ -53,5 +53,6 @@ struct ads7846_platform_data { int (*filter) (void *filter_data, int data_idx, int *val); void (*filter_cleanup)(void *filter_data); void (*wait_for_sync)(void); + bool wakeup; }; -- cgit v0.10.2 From afadb8e08c48d08b75f3caf8404742b13e6b3624 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 10 Mar 2010 23:41:33 -0800 Subject: Input: wm831x-on - convert to use genirq Now that the WM831x core has been converted to use genirq for the interrupt controller there is no need for the client drivers to use a WM831x-specific API rather than just calling genirq directly. Also fixes a leak of the IRQ during init failure - the error path free_irq() was using NULL rather than the driver data as the data pointer so free_irq() wouldn't have matched. Signed-off-by: Mark Brown Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/misc/wm831x-on.c b/drivers/input/misc/wm831x-on.c index ba4f5dd..1e54bce 100644 --- a/drivers/input/misc/wm831x-on.c +++ b/drivers/input/misc/wm831x-on.c @@ -97,8 +97,9 @@ static int __devinit wm831x_on_probe(struct platform_device *pdev) wm831x_on->dev->phys = "wm831x_on/input0"; wm831x_on->dev->dev.parent = &pdev->dev; - ret = wm831x_request_irq(wm831x, irq, wm831x_on_irq, - IRQF_TRIGGER_RISING, "wm831x_on", wm831x_on); + ret = request_threaded_irq(irq, NULL, wm831x_on_irq, + IRQF_TRIGGER_RISING, "wm831x_on", + wm831x_on); if (ret < 0) { dev_err(&pdev->dev, "Unable to request IRQ: %d\n", ret); goto err_input_dev; @@ -114,7 +115,7 @@ static int __devinit wm831x_on_probe(struct platform_device *pdev) return 0; err_irq: - wm831x_free_irq(wm831x, irq, NULL); + free_irq(irq, wm831x_on); err_input_dev: input_free_device(wm831x_on->dev); err: @@ -127,7 +128,7 @@ static int __devexit wm831x_on_remove(struct platform_device *pdev) struct wm831x_on *wm831x_on = platform_get_drvdata(pdev); int irq = platform_get_irq(pdev, 0); - wm831x_free_irq(wm831x_on->wm831x, irq, wm831x_on); + free_irq(irq, wm831x_on); cancel_delayed_work_sync(&wm831x_on->work); input_unregister_device(wm831x_on->dev); kfree(wm831x_on); -- cgit v0.10.2 From 2e95e3f668c85276ce699993596d3b52b0fcf4c5 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Wed, 10 Mar 2010 18:10:19 -0600 Subject: GFS2: Allow the number of committed revokes to temporarily be negative GFS2 tracks the number of revokes and unrevokes that are part of committed transactions via sd_log_commited_revoke. It is possible for one process to add revokes during its transaction, while another process unrevokes them during its transaction. If the second process finishes its transaction first, sd_log_commited_revoke will be decremented by the number of unrevokes that the second process did, without first being incremented by the number of revokes the first process did. This is fine, since all started transactions must be completed before the journal can be flushed. However, sd_log_commited_revoke is an unsigned integer, and log_refund() causes an assertion failure if it would go negative at the end of a transaction. This patch makes sd_log_commited_revoke a signed integer and allows it to go negative. __gfs2_log_flush() still checks that it mataches the actual number of revokes. Signed-off-by: Benjamin Marzinski Signed-off-by: Steven Whitehouse diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index b8025e5..3aac46f 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h @@ -616,7 +616,7 @@ struct gfs2_sbd { unsigned int sd_log_blks_reserved; unsigned int sd_log_commited_buf; unsigned int sd_log_commited_databuf; - unsigned int sd_log_commited_revoke; + int sd_log_commited_revoke; unsigned int sd_log_num_buf; unsigned int sd_log_num_revoke; diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index 4511b08..e5bf4b5 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c @@ -417,7 +417,7 @@ static unsigned int calc_reserved(struct gfs2_sbd *sdp) databufhdrs_needed = (sdp->sd_log_commited_databuf + (dbuf_limit - 1)) / dbuf_limit; - if (sdp->sd_log_commited_revoke) + if (sdp->sd_log_commited_revoke > 0) revokes = gfs2_struct2blk(sdp, sdp->sd_log_commited_revoke, sizeof(u64)); @@ -790,7 +790,6 @@ static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr) gfs2_assert_withdraw(sdp, (((int)sdp->sd_log_commited_buf) >= 0) || (((int)sdp->sd_log_commited_databuf) >= 0)); sdp->sd_log_commited_revoke += tr->tr_num_revoke - tr->tr_num_revoke_rm; - gfs2_assert_withdraw(sdp, ((int)sdp->sd_log_commited_revoke) >= 0); reserved = calc_reserved(sdp); gfs2_assert_withdraw(sdp, sdp->sd_log_blks_reserved + tr->tr_reserved >= reserved); unused = sdp->sd_log_blks_reserved - reserved + tr->tr_reserved; -- cgit v0.10.2 From 220b140b52ab6cc133f674a7ffec8fa792054f25 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 10 Mar 2010 20:45:52 +1100 Subject: perf_event: Fix oops triggered by cpu offline/online Anton Blanchard found that he could reliably make the kernel hit a BUG_ON in the slab allocator by taking a cpu offline and then online while a system-wide perf record session was running. The reason is that when the cpu comes up, we completely reinitialize the ctx field of the struct perf_cpu_context for the cpu. If there is a system-wide perf record session running, then there will be a struct perf_event that has a reference to the context, so its refcount will be 2. (The perf_event has been removed from the context's group_entry and event_entry lists by perf_event_exit_cpu(), but that doesn't remove the perf_event's reference to the context and doesn't decrement the context's refcount.) When the cpu comes up, perf_event_init_cpu() gets called, and it calls __perf_event_init_context() on the cpu's context. That resets the refcount to 1. Then when the perf record session finishes and the perf_event is closed, the refcount gets decremented to 0 and the context gets kfreed after an RCU grace period. Since the context wasn't kmalloced -- it's part of a per-cpu variable -- bad things happen. In fact we don't need to completely reinitialize the context when the cpu comes up. It's sufficient to initialize the context once at boot, but we need to do it for all possible cpus. This moves the context initialization to happen at boot time. With this, we don't trash the refcount and the context never gets kfreed, and we don't hit the BUG_ON. Reported-by: Anton Blanchard Signed-off-by: Paul Mackerras Tested-by: Anton Blanchard Acked-by: Peter Zijlstra Cc: Signed-off-by: Ingo Molnar diff --git a/kernel/perf_event.c b/kernel/perf_event.c index c502b18..fb3031c 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c @@ -5368,12 +5368,22 @@ int perf_event_init_task(struct task_struct *child) return ret; } +static void __init perf_event_init_all_cpus(void) +{ + int cpu; + struct perf_cpu_context *cpuctx; + + for_each_possible_cpu(cpu) { + cpuctx = &per_cpu(perf_cpu_context, cpu); + __perf_event_init_context(&cpuctx->ctx, NULL); + } +} + static void __cpuinit perf_event_init_cpu(int cpu) { struct perf_cpu_context *cpuctx; cpuctx = &per_cpu(perf_cpu_context, cpu); - __perf_event_init_context(&cpuctx->ctx, NULL); spin_lock(&perf_resource_lock); cpuctx->max_pertask = perf_max_events - perf_reserved_percpu; @@ -5439,6 +5449,7 @@ static struct notifier_block __cpuinitdata perf_cpu_nb = { void __init perf_event_init(void) { + perf_event_init_all_cpus(); perf_cpu_notify(&perf_cpu_nb, (unsigned long)CPU_UP_PREPARE, (void *)(long)smp_processor_id()); perf_cpu_notify(&perf_cpu_nb, (unsigned long)CPU_ONLINE, -- cgit v0.10.2 From 8a03ae2a5baed3df09e5643615bdd853fc142a09 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Fri, 29 Jan 2010 20:39:07 +0000 Subject: block: drbd: Convert semaphore to mutex The bm_change semaphore is semantically a mutex. Convert it to a real mutex. Signed-off-by: Thomas Gleixner Signed-off-by: Philipp Reisner diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c index b61057e..f58e765 100644 --- a/drivers/block/drbd/drbd_bitmap.c +++ b/drivers/block/drbd/drbd_bitmap.c @@ -66,7 +66,7 @@ struct drbd_bitmap { size_t bm_words; size_t bm_number_of_pages; sector_t bm_dev_capacity; - struct semaphore bm_change; /* serializes resize operations */ + struct mutex bm_change; /* serializes resize operations */ atomic_t bm_async_io; wait_queue_head_t bm_io_wait; @@ -114,7 +114,7 @@ void drbd_bm_lock(struct drbd_conf *mdev, char *why) return; } - trylock_failed = down_trylock(&b->bm_change); + trylock_failed = !mutex_trylock(&b->bm_change); if (trylock_failed) { dev_warn(DEV, "%s going to '%s' but bitmap already locked for '%s' by %s\n", @@ -125,7 +125,7 @@ void drbd_bm_lock(struct drbd_conf *mdev, char *why) b->bm_task == mdev->receiver.task ? "receiver" : b->bm_task == mdev->asender.task ? "asender" : b->bm_task == mdev->worker.task ? "worker" : "?"); - down(&b->bm_change); + mutex_lock(&b->bm_change); } if (__test_and_set_bit(BM_LOCKED, &b->bm_flags)) dev_err(DEV, "FIXME bitmap already locked in bm_lock\n"); @@ -147,7 +147,7 @@ void drbd_bm_unlock(struct drbd_conf *mdev) b->bm_why = NULL; b->bm_task = NULL; - up(&b->bm_change); + mutex_unlock(&b->bm_change); } /* word offset to long pointer */ @@ -295,7 +295,7 @@ int drbd_bm_init(struct drbd_conf *mdev) if (!b) return -ENOMEM; spin_lock_init(&b->bm_lock); - init_MUTEX(&b->bm_change); + mutex_init(&b->bm_change); init_waitqueue_head(&b->bm_io_wait); mdev->bitmap = b; -- cgit v0.10.2 From a12b51c478899fe0b7e874a559b05ba35f1128ee Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 10 Mar 2010 20:36:09 +1100 Subject: perf tools: Fix sparse CPU numbering related bugs At present, the perf subcommands that do system-wide monitoring (perf stat, perf record and perf top) don't work properly unless the online cpus are numbered 0, 1, ..., N-1. These tools ask for the number of online cpus with sysconf(_SC_NPROCESSORS_ONLN) and then try to create events for cpus 0, 1, ..., N-1. This creates problems for systems where the online cpus are numbered sparsely. For example, a POWER6 system in single-threaded mode (i.e. only running 1 hardware thread per core) will have only even-numbered cpus online. This fixes the problem by reading the /sys/devices/system/cpu/online file to find out which cpus are online. The code that does that is in tools/perf/util/cpumap.[ch], and consists of a read_cpu_map() function that sets up a cpumap[] array and returns the number of online cpus. If /sys/devices/system/cpu/online can't be read or can't be parsed successfully, it falls back to using sysconf to ask how many cpus are online and sets up an identity map in cpumap[]. The perf record, perf stat and perf top code then calls read_cpu_map() in the system-wide monitoring case (instead of sysconf) and uses cpumap[] to get the cpu numbers to pass to perf_event_open. Signed-off-by: Paul Mackerras Cc: Anton Blanchard Cc: Peter Zijlstra Cc: Arnaldo Carvalho de Melo LKML-Reference: <20100310093609.GA3959@brick.ozlabs.ibm.com> Signed-off-by: Ingo Molnar diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 2d53738..5840499 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -387,6 +387,7 @@ LIB_H += util/thread.h LIB_H += util/trace-event.h LIB_H += util/probe-finder.h LIB_H += util/probe-event.h +LIB_H += util/cpumap.h LIB_OBJS += util/abspath.o LIB_OBJS += util/alias.o @@ -433,6 +434,7 @@ LIB_OBJS += util/sort.o LIB_OBJS += util/hist.o LIB_OBJS += util/probe-event.o LIB_OBJS += util/util.o +LIB_OBJS += util/cpumap.o BUILTIN_OBJS += builtin-annotate.o diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index f573bbb..b09d3b2 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -22,6 +22,7 @@ #include "util/debug.h" #include "util/session.h" #include "util/symbol.h" +#include "util/cpumap.h" #include #include @@ -421,9 +422,6 @@ static int __cmd_record(int argc, const char **argv) char buf; page_size = sysconf(_SC_PAGE_SIZE); - nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); - assert(nr_cpus <= MAX_NR_CPUS); - assert(nr_cpus >= 0); atexit(sig_atexit); signal(SIGCHLD, sig_handler); @@ -547,8 +545,9 @@ static int __cmd_record(int argc, const char **argv) if ((!system_wide && !inherit) || profile_cpu != -1) { open_counters(profile_cpu, target_pid); } else { + nr_cpus = read_cpu_map(); for (i = 0; i < nr_cpus; i++) - open_counters(i, target_pid); + open_counters(cpumap[i], target_pid); } if (file_new) { diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index e8c85d5..95db31c 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -45,6 +45,7 @@ #include "util/event.h" #include "util/debug.h" #include "util/header.h" +#include "util/cpumap.h" #include #include @@ -151,7 +152,7 @@ static void create_perf_stat_counter(int counter, int pid) unsigned int cpu; for (cpu = 0; cpu < nr_cpus; cpu++) { - fd[cpu][counter] = sys_perf_event_open(attr, -1, cpu, -1, 0); + fd[cpu][counter] = sys_perf_event_open(attr, -1, cpumap[cpu], -1, 0); if (fd[cpu][counter] < 0 && verbose) fprintf(stderr, ERR_PERF_OPEN, counter, fd[cpu][counter], strerror(errno)); @@ -519,9 +520,10 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used) nr_counters = ARRAY_SIZE(default_attrs); } - nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); - assert(nr_cpus <= MAX_NR_CPUS); - assert((int)nr_cpus >= 0); + if (system_wide) + nr_cpus = read_cpu_map(); + else + nr_cpus = 1; /* * We dont want to block the signals - that would cause diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 31f2e59..0b719e3 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -28,6 +28,7 @@ #include #include "util/parse-options.h" #include "util/parse-events.h" +#include "util/cpumap.h" #include "util/debug.h" @@ -1123,7 +1124,7 @@ static void start_counter(int i, int counter) cpu = profile_cpu; if (target_pid == -1 && profile_cpu == -1) - cpu = i; + cpu = cpumap[i]; attr = attrs + counter; @@ -1347,12 +1348,10 @@ int cmd_top(int argc, const char **argv, const char *prefix __used) attrs[counter].sample_period = default_interval; } - nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); - assert(nr_cpus <= MAX_NR_CPUS); - assert(nr_cpus >= 0); - if (target_pid != -1 || profile_cpu != -1) nr_cpus = 1; + else + nr_cpus = read_cpu_map(); get_term_dimensions(&winsize); if (print_entries == 0) { diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c new file mode 100644 index 0000000..4e01490 --- /dev/null +++ b/tools/perf/util/cpumap.c @@ -0,0 +1,59 @@ +#include "util.h" +#include "../perf.h" +#include "cpumap.h" +#include +#include + +int cpumap[MAX_NR_CPUS]; + +static int default_cpu_map(void) +{ + int nr_cpus, i; + + nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); + assert(nr_cpus <= MAX_NR_CPUS); + assert((int)nr_cpus >= 0); + + for (i = 0; i < nr_cpus; ++i) + cpumap[i] = i; + + return nr_cpus; +} + +int read_cpu_map(void) +{ + FILE *onlnf; + int nr_cpus = 0; + int n, cpu, prev; + char sep; + + onlnf = fopen("/sys/devices/system/cpu/online", "r"); + if (!onlnf) + return default_cpu_map(); + + sep = 0; + prev = -1; + for (;;) { + n = fscanf(onlnf, "%u%c", &cpu, &sep); + if (n <= 0) + break; + if (prev >= 0) { + assert(nr_cpus + cpu - prev - 1 < MAX_NR_CPUS); + while (++prev < cpu) + cpumap[nr_cpus++] = prev; + } + assert (nr_cpus < MAX_NR_CPUS); + cpumap[nr_cpus++] = cpu; + if (n == 2 && sep == '-') + prev = cpu; + else + prev = -1; + if (n == 1 || sep == '\n') + break; + } + fclose(onlnf); + if (nr_cpus > 0) + return nr_cpus; + + return default_cpu_map(); +} diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h new file mode 100644 index 0000000..86c78bb --- /dev/null +++ b/tools/perf/util/cpumap.h @@ -0,0 +1,7 @@ +#ifndef __PERF_CPUMAP_H +#define __PERF_CPUMAP_H + +extern int read_cpu_map(void); +extern int cpumap[]; + +#endif /* __PERF_CPUMAP_H */ -- cgit v0.10.2 From 3f379b03fbfddd20536389a85c6456f8233d1f8d Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Fri, 5 Mar 2010 15:03:25 -0800 Subject: ftrace: Replace read_barrier_depends() with rcu_dereference_raw() Replace the calls to read_barrier_depends() in ftrace_list_func() with rcu_dereference_raw() to improve readability. The reason that we use rcu_dereference_raw() here is that removed entries are never freed, instead they are simply leaked. This is one of a very few cases where use of rcu_dereference_raw() is the long-term right answer. And I don't yet know of any others. ;-) Signed-off-by: Paul E. McKenney Acked-by: Steven Rostedt Cc: Frederic Weisbecker Cc: laijs@cn.fujitsu.com Cc: dipankar@in.ibm.com Cc: mathieu.desnoyers@polymtl.ca Cc: josh@joshtriplett.org Cc: dvhltc@us.ibm.com Cc: niv@us.ibm.com Cc: peterz@infradead.org Cc: Valdis.Kletnieks@vt.edu Cc: dhowells@redhat.com LKML-Reference: <1267830207-9474-1-git-send-email-paulmck@linux.vnet.ibm.com> Signed-off-by: Ingo Molnar diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 8378357..8c5adc0 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -27,6 +27,7 @@ #include #include #include +#include #include @@ -88,18 +89,22 @@ ftrace_func_t ftrace_pid_function __read_mostly = ftrace_stub; static int ftrace_set_func(unsigned long *array, int *idx, char *buffer); #endif +/* + * Traverse the ftrace_list, invoking all entries. The reason that we + * can use rcu_dereference_raw() is that elements removed from this list + * are simply leaked, so there is no need to interact with a grace-period + * mechanism. The rcu_dereference_raw() calls are needed to handle + * concurrent insertions into the ftrace_list. + * + * Silly Alpha and silly pointer-speculation compiler optimizations! + */ static void ftrace_list_func(unsigned long ip, unsigned long parent_ip) { - struct ftrace_ops *op = ftrace_list; - - /* in case someone actually ports this to alpha! */ - read_barrier_depends(); + struct ftrace_ops *op = rcu_dereference_raw(ftrace_list); /*see above*/ while (op != &ftrace_list_end) { - /* silly alpha */ - read_barrier_depends(); op->func(ip, parent_ip); - op = op->next; + op = rcu_dereference_raw(op->next); /*see above*/ }; } @@ -154,8 +159,7 @@ static int __register_ftrace_function(struct ftrace_ops *ops) * the ops->next pointer is valid before another CPU sees * the ops pointer included into the ftrace_list. */ - smp_wmb(); - ftrace_list = ops; + rcu_assign_pointer(ftrace_list, ops); if (ftrace_enabled) { ftrace_func_t func; -- cgit v0.10.2 From 007b09243b099811124f69d492adeebe9e439f96 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Fri, 5 Mar 2010 15:03:26 -0800 Subject: rcu: Increase RCU CPU stall timeouts if PROVE_RCU CONFIG_PROVE_RCU imposes additional overhead on the kernel, so increase the RCU CPU stall timeouts in an attempt to allow for this effect. Signed-off-by: Paul E. McKenney Cc: laijs@cn.fujitsu.com Cc: dipankar@in.ibm.com Cc: mathieu.desnoyers@polymtl.ca Cc: josh@joshtriplett.org Cc: dvhltc@us.ibm.com Cc: niv@us.ibm.com Cc: peterz@infradead.org Cc: rostedt@goodmis.org Cc: Valdis.Kletnieks@vt.edu Cc: dhowells@redhat.com LKML-Reference: <1267830207-9474-2-git-send-email-paulmck@linux.vnet.ibm.com> Signed-off-by: Ingo Molnar diff --git a/kernel/rcutree.h b/kernel/rcutree.h index 1439eb5..4a525a3 100644 --- a/kernel/rcutree.h +++ b/kernel/rcutree.h @@ -246,12 +246,21 @@ struct rcu_data { #define RCU_JIFFIES_TILL_FORCE_QS 3 /* for rsp->jiffies_force_qs */ #ifdef CONFIG_RCU_CPU_STALL_DETECTOR -#define RCU_SECONDS_TILL_STALL_CHECK (10 * HZ) /* for rsp->jiffies_stall */ -#define RCU_SECONDS_TILL_STALL_RECHECK (30 * HZ) /* for rsp->jiffies_stall */ -#define RCU_STALL_RAT_DELAY 2 /* Allow other CPUs time */ - /* to take at least one */ - /* scheduling clock irq */ - /* before ratting on them. */ + +#ifdef CONFIG_PROVE_RCU +#define RCU_STALL_DELAY_DELTA (5 * HZ) +#else +#define RCU_STALL_DELAY_DELTA 0 +#endif + +#define RCU_SECONDS_TILL_STALL_CHECK (10 * HZ + RCU_STALL_DELAY_DELTA) + /* for rsp->jiffies_stall */ +#define RCU_SECONDS_TILL_STALL_RECHECK (30 * HZ + RCU_STALL_DELAY_DELTA) + /* for rsp->jiffies_stall */ +#define RCU_STALL_RAT_DELAY 2 /* Allow other CPUs time */ + /* to take at least one */ + /* scheduling clock irq */ + /* before ratting on them. */ #endif /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */ -- cgit v0.10.2 From f56e8a0765cc4374e02f4e3a79e2427b5096b075 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Fri, 5 Mar 2010 15:03:27 -0800 Subject: x86/mce: Fix RCU lockdep splats Create an rcu_dereference_check_mce() that checks for RCU-sched read side and mce_read_mutex being held on update side. Replace uses of rcu_dereference() in arch/x86/kernel/cpu/mcheck/mce.c with this new macro. Signed-off-by: Paul E. McKenney Cc: "H. Peter Anvin" Cc: x86@kernel.org Cc: laijs@cn.fujitsu.com Cc: dipankar@in.ibm.com Cc: mathieu.desnoyers@polymtl.ca Cc: josh@joshtriplett.org Cc: dvhltc@us.ibm.com Cc: niv@us.ibm.com Cc: peterz@infradead.org Cc: rostedt@goodmis.org Cc: Valdis.Kletnieks@vt.edu Cc: dhowells@redhat.com LKML-Reference: <1267830207-9474-3-git-send-email-paulmck@linux.vnet.ibm.com> Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index a8aacd4..4442e9e 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c @@ -46,6 +46,11 @@ #include "mce-internal.h" +#define rcu_dereference_check_mce(p) \ + rcu_dereference_check((p), \ + rcu_read_lock_sched_held() || \ + lockdep_is_held(&mce_read_mutex)) + #define CREATE_TRACE_POINTS #include @@ -158,7 +163,7 @@ void mce_log(struct mce *mce) mce->finished = 0; wmb(); for (;;) { - entry = rcu_dereference(mcelog.next); + entry = rcu_dereference_check_mce(mcelog.next); for (;;) { /* * When the buffer fills up discard new entries. @@ -1500,7 +1505,7 @@ static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize, return -ENOMEM; mutex_lock(&mce_read_mutex); - next = rcu_dereference(mcelog.next); + next = rcu_dereference_check_mce(mcelog.next); /* Only supports full reads right now */ if (*off != 0 || usize < MCE_LOG_LEN*sizeof(struct mce)) { @@ -1565,7 +1570,7 @@ timeout: static unsigned int mce_poll(struct file *file, poll_table *wait) { poll_wait(file, &mce_wait, wait); - if (rcu_dereference(mcelog.next)) + if (rcu_dereference_check_mce(mcelog.next)) return POLLIN | POLLRDNORM; return 0; } -- cgit v0.10.2 From ccfe27d7000668b02d10fc3e06aa49e3e3603162 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 14 Jan 2010 11:21:02 +0100 Subject: microblaze: Support DMA Add DMA support for Microblaze. There are some part of this new feature: 1. Basic DMA support 2. Enable DMA debug option 3. Setup notifier Ad 1. dma-mapping come from powerpc and x86 version and it is based on generic dma-mapping-common.h Ad 2. DMA support debug features which is used in generic file. For more information please look at Documentation/DMA-API.txt Ad 3. notifier is very important to setup dma_ops. Without this part for example ll_temac driver failed because there are no setup dma operations. Signed-off-by: Michal Simek diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index b008168..71ec041 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -14,6 +14,8 @@ config MICROBLAZE select USB_ARCH_HAS_EHCI select ARCH_WANT_OPTIONAL_GPIOLIB select HAVE_OPROFILE + select HAVE_DMA_ATTRS + select HAVE_DMA_API_DEBUG select TRACING_SUPPORT config SWAP @@ -76,9 +78,6 @@ config HAVE_LATENCYTOP_SUPPORT config PCI def_bool n -config NO_DMA - def_bool y - config DTC def_bool y diff --git a/arch/microblaze/include/asm/device.h b/arch/microblaze/include/asm/device.h index 78a0384..402b46e 100644 --- a/arch/microblaze/include/asm/device.h +++ b/arch/microblaze/include/asm/device.h @@ -14,6 +14,10 @@ struct device_node; struct dev_archdata { /* Optional pointer to an OF device node */ struct device_node *of_node; + + /* DMA operations on that device */ + struct dma_map_ops *dma_ops; + void *dma_data; }; struct pdev_archdata { diff --git a/arch/microblaze/include/asm/dma-mapping.h b/arch/microblaze/include/asm/dma-mapping.h index d00e400..096fa96 100644 --- a/arch/microblaze/include/asm/dma-mapping.h +++ b/arch/microblaze/include/asm/dma-mapping.h @@ -1 +1,154 @@ -#include +/* + * Implements the generic device dma API for microblaze and the pci + * + * Copyright (C) 2009-2010 Michal Simek + * Copyright (C) 2009-2010 PetaLogix + * + * This file is subject to the terms and conditions of the GNU General + * Public License. See the file COPYING in the main directory of this + * archive for more details. + * + * This file is base on powerpc and x86 dma-mapping.h versions + * Copyright (C) 2004 IBM + */ + +#ifndef _ASM_MICROBLAZE_DMA_MAPPING_H +#define _ASM_MICROBLAZE_DMA_MAPPING_H + +/* + * See Documentation/PCI/PCI-DMA-mapping.txt and + * Documentation/DMA-API.txt for documentation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define DMA_ERROR_CODE (~(dma_addr_t)0x0) + +#define __dma_alloc_coherent(dev, gfp, size, handle) NULL +#define __dma_free_coherent(size, addr) ((void)0) +#define __dma_sync(addr, size, rw) ((void)0) +#define __dma_sync_page(pg, off, sz, rw) ((void)0) + +static inline unsigned long device_to_mask(struct device *dev) +{ + if (dev->dma_mask && *dev->dma_mask) + return *dev->dma_mask; + /* Assume devices without mask can take 32 bit addresses */ + return 0xfffffffful; +} + +extern struct dma_map_ops *dma_ops; + +/* + * Available generic sets of operations + */ +extern struct dma_map_ops dma_direct_ops; + +static inline struct dma_map_ops *get_dma_ops(struct device *dev) +{ + /* We don't handle the NULL dev case for ISA for now. We could + * do it via an out of line call but it is not needed for now. The + * only ISA DMA device we support is the floppy and we have a hack + * in the floppy driver directly to get a device for us. + */ + if (unlikely(!dev) || !dev->archdata.dma_ops) + return NULL; + + return dev->archdata.dma_ops; +} + +static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops) +{ + dev->archdata.dma_ops = ops; +} + +static inline int dma_supported(struct device *dev, u64 mask) +{ + struct dma_map_ops *ops = get_dma_ops(dev); + + if (unlikely(!ops)) + return 0; + if (!ops->dma_supported) + return 1; + return ops->dma_supported(dev, mask); +} + +#ifdef CONFIG_PCI +/* We have our own implementation of pci_set_dma_mask() */ +#define HAVE_ARCH_PCI_SET_DMA_MASK + +#endif + +static inline int dma_set_mask(struct device *dev, u64 dma_mask) +{ + struct dma_map_ops *ops = get_dma_ops(dev); + + if (unlikely(ops == NULL)) + return -EIO; + if (ops->set_dma_mask) + return ops->set_dma_mask(dev, dma_mask); + if (!dev->dma_mask || !dma_supported(dev, dma_mask)) + return -EIO; + *dev->dma_mask = dma_mask; + return 0; +} + +#include + +static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +{ + struct dma_map_ops *ops = get_dma_ops(dev); + if (ops->mapping_error) + return ops->mapping_error(dev, dma_addr); + + return (dma_addr == DMA_ERROR_CODE); +} + +#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) +#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) +#define dma_is_consistent(d, h) (1) + +static inline void *dma_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t flag) +{ + struct dma_map_ops *ops = get_dma_ops(dev); + void *memory; + + BUG_ON(!ops); + + memory = ops->alloc_coherent(dev, size, dma_handle, flag); + + debug_dma_alloc_coherent(dev, size, *dma_handle, memory); + return memory; +} + +static inline void dma_free_coherent(struct device *dev, size_t size, + void *cpu_addr, dma_addr_t dma_handle) +{ + struct dma_map_ops *ops = get_dma_ops(dev); + + BUG_ON(!ops); + debug_dma_free_coherent(dev, size, cpu_addr, dma_handle); + ops->free_coherent(dev, size, cpu_addr, dma_handle); +} + +static inline int dma_get_cache_alignment(void) +{ + return L1_CACHE_BYTES; +} + +static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size, + enum dma_data_direction direction) +{ + BUG_ON(direction == DMA_NONE); + __dma_sync(vaddr, size, (int)direction); +} + +#endif /* _ASM_MICROBLAZE_DMA_MAPPING_H */ diff --git a/arch/microblaze/include/asm/io.h b/arch/microblaze/include/asm/io.h index 267c7c7..9ac409a 100644 --- a/arch/microblaze/include/asm/io.h +++ b/arch/microblaze/include/asm/io.h @@ -16,6 +16,7 @@ #include #include /* Get struct page {...} */ +#define PCI_DRAM_OFFSET 0 #define IO_SPACE_LIMIT (0xFFFFFFFF) diff --git a/arch/microblaze/kernel/Makefile b/arch/microblaze/kernel/Makefile index b07594e..e51bc15 100644 --- a/arch/microblaze/kernel/Makefile +++ b/arch/microblaze/kernel/Makefile @@ -14,7 +14,7 @@ endif extra-y := head.o vmlinux.lds -obj-y += exceptions.o \ +obj-y += dma.o exceptions.o \ hw_exception_handler.o init_task.o intc.o irq.o of_device.o \ of_platform.o process.o prom.o prom_parse.o ptrace.o \ setup.o signal.o sys_microblaze.o timer.o traps.o reset.o diff --git a/arch/microblaze/kernel/dma.c b/arch/microblaze/kernel/dma.c new file mode 100644 index 0000000..300fea4 --- /dev/null +++ b/arch/microblaze/kernel/dma.c @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2009-2010 PetaLogix + * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corporation + * + * Provide default implementations of the DMA mapping callbacks for + * directly mapped busses. + */ + +#include +#include +#include +#include + +/* + * Generic direct DMA implementation + * + * This implementation supports a per-device offset that can be applied if + * the address at which memory is visible to devices is not 0. Platform code + * can set archdata.dma_data to an unsigned long holding the offset. By + * default the offset is PCI_DRAM_OFFSET. + */ + +static unsigned long get_dma_direct_offset(struct device *dev) +{ + if (dev) + return (unsigned long)dev->archdata.dma_data; + + return PCI_DRAM_OFFSET; /* FIXME Not sure if is correct */ +} + +void *dma_direct_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t flag) +{ + void *ret; + struct page *page; + int node = dev_to_node(dev); + + /* ignore region specifiers */ + flag &= ~(__GFP_HIGHMEM); + + page = alloc_pages_node(node, flag, get_order(size)); + if (page == NULL) + return NULL; + ret = page_address(page); + memset(ret, 0, size); + *dma_handle = virt_to_phys(ret) + get_dma_direct_offset(dev); + + return ret; +} + +void dma_direct_free_coherent(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle) +{ + free_pages((unsigned long)vaddr, get_order(size)); +} + +static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl, + int nents, enum dma_data_direction direction, + struct dma_attrs *attrs) +{ + struct scatterlist *sg; + int i; + + for_each_sg(sgl, sg, nents, i) { + sg->dma_address = sg_phys(sg) + get_dma_direct_offset(dev); + sg->dma_length = sg->length; + __dma_sync_page(sg_page(sg), sg->offset, sg->length, direction); + } + + return nents; +} + +static void dma_direct_unmap_sg(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction direction, + struct dma_attrs *attrs) +{ +} + +static int dma_direct_dma_supported(struct device *dev, u64 mask) +{ + return 1; +} + +static inline dma_addr_t dma_direct_map_page(struct device *dev, + struct page *page, + unsigned long offset, + size_t size, + enum dma_data_direction dir, + struct dma_attrs *attrs) +{ + BUG_ON(dir == DMA_NONE); + __dma_sync_page(page, offset, size, dir); + return page_to_phys(page) + offset + get_dma_direct_offset(dev); +} + +static inline void dma_direct_unmap_page(struct device *dev, + dma_addr_t dma_address, + size_t size, + enum dma_data_direction direction, + struct dma_attrs *attrs) +{ +} + +struct dma_map_ops dma_direct_ops = { + .alloc_coherent = dma_direct_alloc_coherent, + .free_coherent = dma_direct_free_coherent, + .map_sg = dma_direct_map_sg, + .unmap_sg = dma_direct_unmap_sg, + .dma_supported = dma_direct_dma_supported, + .map_page = dma_direct_map_page, + .unmap_page = dma_direct_unmap_page, +}; +EXPORT_SYMBOL(dma_direct_ops); + +/* Number of entries preallocated for DMA-API debugging */ +#define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16) + +static int __init dma_init(void) +{ + dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES); + + return 0; +} +fs_initcall(dma_init); diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c index bb8c4b9..bc325ac 100644 --- a/arch/microblaze/kernel/setup.c +++ b/arch/microblaze/kernel/setup.c @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include #include #include @@ -188,3 +190,37 @@ static int microblaze_debugfs_init(void) } arch_initcall(microblaze_debugfs_init); #endif + +static int dflt_bus_notify(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct device *dev = data; + + /* We are only intereted in device addition */ + if (action != BUS_NOTIFY_ADD_DEVICE) + return 0; + + set_dma_ops(dev, &dma_direct_ops); + + return NOTIFY_DONE; +} + +static struct notifier_block dflt_plat_bus_notifier = { + .notifier_call = dflt_bus_notify, + .priority = INT_MAX, +}; + +static struct notifier_block dflt_of_bus_notifier = { + .notifier_call = dflt_bus_notify, + .priority = INT_MAX, +}; + +static int __init setup_bus_notifier(void) +{ + bus_register_notifier(&platform_bus_type, &dflt_plat_bus_notifier); + bus_register_notifier(&of_platform_bus_type, &dflt_of_bus_notifier); + + return 0; +} + +arch_initcall(setup_bus_notifier); -- cgit v0.10.2 From 2549edd353196d7de9c18e08146d7a8836f97235 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 20 Jan 2010 14:36:24 +0100 Subject: microblaze: Implement __dma_sync_page There is necessary to do some cache handling for dma operations. Signed-off-by: Michal Simek diff --git a/arch/microblaze/include/asm/dma-mapping.h b/arch/microblaze/include/asm/dma-mapping.h index 096fa96..18b3731 100644 --- a/arch/microblaze/include/asm/dma-mapping.h +++ b/arch/microblaze/include/asm/dma-mapping.h @@ -34,7 +34,6 @@ #define __dma_alloc_coherent(dev, gfp, size, handle) NULL #define __dma_free_coherent(size, addr) ((void)0) #define __dma_sync(addr, size, rw) ((void)0) -#define __dma_sync_page(pg, off, sz, rw) ((void)0) static inline unsigned long device_to_mask(struct device *dev) { diff --git a/arch/microblaze/kernel/dma.c b/arch/microblaze/kernel/dma.c index 300fea4..64bc39f 100644 --- a/arch/microblaze/kernel/dma.c +++ b/arch/microblaze/kernel/dma.c @@ -10,6 +10,7 @@ #include #include #include +#include /* * Generic direct DMA implementation @@ -20,6 +21,23 @@ * default the offset is PCI_DRAM_OFFSET. */ +static inline void __dma_sync_page(void *vaddr, unsigned long offset, + size_t size, enum dma_data_direction direction) +{ + unsigned long start = virt_to_phys(vaddr); + + switch (direction) { + case DMA_TO_DEVICE: + flush_dcache_range(start + offset, start + offset + size); + break; + case DMA_FROM_DEVICE: + invalidate_dcache_range(start + offset, start + offset + size); + break; + default: + BUG(); + } +} + static unsigned long get_dma_direct_offset(struct device *dev) { if (dev) @@ -85,11 +103,11 @@ static inline dma_addr_t dma_direct_map_page(struct device *dev, struct page *page, unsigned long offset, size_t size, - enum dma_data_direction dir, + enum dma_data_direction direction, struct dma_attrs *attrs) { - BUG_ON(dir == DMA_NONE); - __dma_sync_page(page, offset, size, dir); + BUG_ON(direction == DMA_NONE); + __dma_sync_page(page, offset, size, direction); return page_to_phys(page) + offset + get_dma_direct_offset(dev); } @@ -99,6 +117,8 @@ static inline void dma_direct_unmap_page(struct device *dev, enum dma_data_direction direction, struct dma_attrs *attrs) { +/* There is not necessary to do cache cleanup */ + /* __dma_sync_page(dma_address, 0 , size, direction); */ } struct dma_map_ops dma_direct_ops = { -- cgit v0.10.2 From a84642a339235020e6dccc022de27055f1fa9340 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 14 Jan 2010 17:03:49 +0100 Subject: microblaze: Add {z,}alloc_maybe_bootmem functions I will need {z,}alloc_maybe_bootmem functions for pci patches Signed-off-by: Michal Simek diff --git a/arch/microblaze/include/asm/system.h b/arch/microblaze/include/asm/system.h index 15797068..59efb3f 100644 --- a/arch/microblaze/include/asm/system.h +++ b/arch/microblaze/include/asm/system.h @@ -87,6 +87,9 @@ void free_initmem(void); extern char *klimit; extern void ret_from_fork(void); +extern void *alloc_maybe_bootmem(size_t size, gfp_t mask); +extern void *zalloc_maybe_bootmem(size_t size, gfp_t mask); + #ifdef CONFIG_DEBUG_FS extern struct dentry *of_debugfs_root; #endif diff --git a/arch/microblaze/mm/init.c b/arch/microblaze/mm/init.c index a57cedf..6eea554 100644 --- a/arch/microblaze/mm/init.c +++ b/arch/microblaze/mm/init.c @@ -349,4 +349,27 @@ void __init *early_get_page(void) } return p; } + +void * __init_refok alloc_maybe_bootmem(size_t size, gfp_t mask) +{ + if (mem_init_done) + return kmalloc(size, mask); + else + return alloc_bootmem(size); +} + +void * __init_refok zalloc_maybe_bootmem(size_t size, gfp_t mask) +{ + void *p; + + if (mem_init_done) + p = kzalloc(size, mask); + else { + p = alloc_bootmem(size); + if (p) + memset(p, 0, size); + } + return p; +} + #endif /* CONFIG_MMU */ -- cgit v0.10.2 From c6ba01a4c7806d134c8d483525997559071d0990 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 14 Jan 2010 15:16:31 +0100 Subject: microblaze: Add irq_create_{of_,}mapping functions Support function for PCI. We don't use any advance mapping mechanism that's why implementation is simple. Signed-off-by: Michal Simek diff --git a/arch/microblaze/include/asm/irq.h b/arch/microblaze/include/asm/irq.h index 90f0505..31a35c3 100644 --- a/arch/microblaze/include/asm/irq.h +++ b/arch/microblaze/include/asm/irq.h @@ -14,6 +14,12 @@ #include +/* This type is the placeholder for a hardware interrupt number. It has to + * be big enough to enclose whatever representation is used by a given + * platform. + */ +typedef unsigned long irq_hw_number_t; + extern unsigned int nr_irq; #define NO_IRQ (-1) @@ -21,7 +27,8 @@ extern unsigned int nr_irq; struct pt_regs; extern void do_IRQ(struct pt_regs *regs); -/* irq_of_parse_and_map - Parse and Map an interrupt into linux virq space +/** + * irq_of_parse_and_map - Parse and Map an interrupt into linux virq space * @device: Device node of the device whose interrupt is to be mapped * @index: Index of the interrupt to map * @@ -40,4 +47,32 @@ static inline void irq_dispose_mapping(unsigned int virq) return; } +struct irq_host; + +/** + * irq_create_mapping - Map a hardware interrupt into linux virq space + * @host: host owning this hardware interrupt or NULL for default host + * @hwirq: hardware irq number in that host space + * + * Only one mapping per hardware interrupt is permitted. Returns a linux + * virq number. + * If the sense/trigger is to be specified, set_irq_type() should be called + * on the number returned from that call. + */ +extern unsigned int irq_create_mapping(struct irq_host *host, + irq_hw_number_t hwirq); + +/** + * irq_create_of_mapping - Map a hardware interrupt into linux virq space + * @controller: Device node of the interrupt controller + * @inspec: Interrupt specifier from the device-tree + * @intsize: Size of the interrupt specifier from the device-tree + * + * This function is identical to irq_create_mapping except that it takes + * as input informations straight from the device-tree (typically the results + * of the of_irq_map_*() functions. + */ +extern unsigned int irq_create_of_mapping(struct device_node *controller, + u32 *intspec, unsigned int intsize); + #endif /* _ASM_MICROBLAZE_IRQ_H */ diff --git a/arch/microblaze/kernel/irq.c b/arch/microblaze/kernel/irq.c index 0f06034..6f39e2c 100644 --- a/arch/microblaze/kernel/irq.c +++ b/arch/microblaze/kernel/irq.c @@ -93,3 +93,18 @@ skip: } return 0; } + +/* MS: There is no any advance mapping mechanism. We are using simple 32bit + intc without any cascades or any connection that's why mapping is 1:1 */ +unsigned int irq_create_mapping(struct irq_host *host, irq_hw_number_t hwirq) +{ + return hwirq; +} +EXPORT_SYMBOL_GPL(irq_create_mapping); + +unsigned int irq_create_of_mapping(struct device_node *controller, + u32 *intspec, unsigned int intsize) +{ + return intspec[0]; +} +EXPORT_SYMBOL_GPL(irq_create_of_mapping); -- cgit v0.10.2 From ab3b3aa5dd01b3aaa6b15caee113b21b1b6520c4 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 6 Mar 2010 14:17:52 +0300 Subject: sched: Cleanup: remove unused variable in try_to_wake_up() We haven't used the "orig_rq" variable since 055a00865d "Fix/add missing update_rq_clock() calls" Signed-off-by: Dan Carpenter Cc: Peter Zijlstra Cc: Andreas Herrmann Cc: Gautham R Shenoy Cc: efault@gmx.de LKML-Reference: <20100306111752.GL4958@bicker> Signed-off-by: Ingo Molnar diff --git a/kernel/sched.c b/kernel/sched.c index 6a212c9..2c1db81 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2359,7 +2359,7 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state, { int cpu, orig_cpu, this_cpu, success = 0; unsigned long flags; - struct rq *rq, *orig_rq; + struct rq *rq; if (!sched_feat(SYNC_WAKEUPS)) wake_flags &= ~WF_SYNC; @@ -2367,7 +2367,7 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state, this_cpu = get_cpu(); smp_wmb(); - rq = orig_rq = task_rq_lock(p, &flags); + rq = task_rq_lock(p, &flags); update_rq_clock(rq); if (!(p->state & state)) goto out; -- cgit v0.10.2 From 2ddafeab6f159640299d17fb9b73b57f65011d85 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 14 Jan 2010 15:40:11 +0100 Subject: microblaze: io.h include asm-generic/iomap.h I need to use generic/iomap.h for PCI that's why is necessary to include it and fix ioport_{map,unmap} functions. Signed-off-by: Michal Simek diff --git a/arch/microblaze/include/asm/io.h b/arch/microblaze/include/asm/io.h index 9ac409a..f82df5d 100644 --- a/arch/microblaze/include/asm/io.h +++ b/arch/microblaze/include/asm/io.h @@ -15,6 +15,7 @@ #include #include #include /* Get struct page {...} */ +#include #define PCI_DRAM_OFFSET 0 @@ -228,15 +229,7 @@ static inline void __iomem *__ioremap(phys_addr_t address, unsigned long size, #define out_8(a, v) __raw_writeb((v), (a)) #define in_8(a) __raw_readb(a) -/* FIXME */ -static inline void __iomem *ioport_map(unsigned long port, unsigned int len) -{ - return (void __iomem *) (port); -} - -static inline void ioport_unmap(void __iomem *addr) -{ - /* Nothing to do */ -} +#define ioport_map(port, nr) ((void __iomem *)(port)) +#define ioport_unmap(addr) #endif /* _ASM_MICROBLAZE_IO_H */ -- cgit v0.10.2 From 830980a0a83e0b5af97c31f24dc7f1b57aa9ccea Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 18 Jan 2010 14:23:16 +0100 Subject: microblaze: Add pci.h Add pci.h for microblaze. It is based on powerpc pci.h Signed-off-by: Michal Simek diff --git a/arch/microblaze/include/asm/pci.h b/arch/microblaze/include/asm/pci.h index 9f0df5f..fecc044 100644 --- a/arch/microblaze/include/asm/pci.h +++ b/arch/microblaze/include/asm/pci.h @@ -1 +1,170 @@ -#include +/* + * 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. + * + * Based on powerpc version + */ + +#ifndef __ASM_MICROBLAZE_PCI_H +#define __ASM_MICROBLAZE_PCI_H +#ifdef __KERNEL__ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define PCIBIOS_MIN_IO 0x1000 +#define PCIBIOS_MIN_MEM 0x10000000 + +struct pci_dev; + +/* Values for the `which' argument to sys_pciconfig_iobase syscall. */ +#define IOBASE_BRIDGE_NUMBER 0 +#define IOBASE_MEMORY 1 +#define IOBASE_IO 2 +#define IOBASE_ISA_IO 3 +#define IOBASE_ISA_MEM 4 + +#define pcibios_scan_all_fns(a, b) 0 + +/* + * Set this to 1 if you want the kernel to re-assign all PCI + * bus numbers (don't do that on ppc64 yet !) + */ +#define pcibios_assign_all_busses() \ + (pci_has_flag(PCI_REASSIGN_ALL_BUS)) + +static inline void pcibios_set_master(struct pci_dev *dev) +{ + /* No special bus mastering setup handling */ +} + +static inline void pcibios_penalize_isa_irq(int irq, int active) +{ + /* We don't do dynamic PCI IRQ allocation */ +} + +#ifdef CONFIG_PCI +extern void set_pci_dma_ops(struct dma_map_ops *dma_ops); +extern struct dma_map_ops *get_pci_dma_ops(void); +#else /* CONFIG_PCI */ +#define set_pci_dma_ops(d) +#define get_pci_dma_ops() NULL +#endif + +#ifdef CONFIG_PCI +static inline void pci_dma_burst_advice(struct pci_dev *pdev, + enum pci_dma_burst_strategy *strat, + unsigned long *strategy_parameter) +{ + *strat = PCI_DMA_BURST_INFINITY; + *strategy_parameter = ~0UL; +} +#endif + +extern int pci_domain_nr(struct pci_bus *bus); + +/* Decide whether to display the domain number in /proc */ +extern int pci_proc_domain(struct pci_bus *bus); + +struct vm_area_struct; +/* Map a range of PCI memory or I/O space for a device into user space */ +int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma, + enum pci_mmap_state mmap_state, int write_combine); + +/* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */ +#define HAVE_PCI_MMAP 1 + +extern int pci_legacy_read(struct pci_bus *bus, loff_t port, u32 *val, + size_t count); +extern int pci_legacy_write(struct pci_bus *bus, loff_t port, u32 val, + size_t count); +extern int pci_mmap_legacy_page_range(struct pci_bus *bus, + struct vm_area_struct *vma, + enum pci_mmap_state mmap_state); + +#define HAVE_PCI_LEGACY 1 + +/* pci_unmap_{page,single} is a nop so... */ +#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) +#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) +#define pci_unmap_addr(PTR, ADDR_NAME) (0) +#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) do { } while (0) +#define pci_unmap_len(PTR, LEN_NAME) (0) +#define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0) + +/* The PCI address space does equal the physical memory + * address space (no IOMMU). The IDE and SCSI device layers use + * this boolean for bounce buffer decisions. + */ +#define PCI_DMA_BUS_IS_PHYS (1) + +extern void pcibios_resource_to_bus(struct pci_dev *dev, + struct pci_bus_region *region, + struct resource *res); + +extern void pcibios_bus_to_resource(struct pci_dev *dev, + struct resource *res, + struct pci_bus_region *region); + +static inline struct resource *pcibios_select_root(struct pci_dev *pdev, + struct resource *res) +{ + struct resource *root = NULL; + + if (res->flags & IORESOURCE_IO) + root = &ioport_resource; + if (res->flags & IORESOURCE_MEM) + root = &iomem_resource; + + return root; +} + +extern void pcibios_claim_one_bus(struct pci_bus *b); + +extern void pcibios_finish_adding_to_bus(struct pci_bus *bus); + +extern void pcibios_resource_survey(void); + +extern struct pci_controller *init_phb_dynamic(struct device_node *dn); +extern int remove_phb_dynamic(struct pci_controller *phb); + +extern struct pci_dev *of_create_pci_dev(struct device_node *node, + struct pci_bus *bus, int devfn); + +extern void of_scan_pci_bridge(struct device_node *node, + struct pci_dev *dev); + +extern void of_scan_bus(struct device_node *node, struct pci_bus *bus); +extern void of_rescan_bus(struct device_node *node, struct pci_bus *bus); + +extern int pci_read_irq_line(struct pci_dev *dev); + +extern int pci_bus_find_capability(struct pci_bus *bus, + unsigned int devfn, int cap); + +struct file; +extern pgprot_t pci_phys_mem_access_prot(struct file *file, + unsigned long pfn, + unsigned long size, + pgprot_t prot); + +#define HAVE_ARCH_PCI_RESOURCE_TO_USER +extern void pci_resource_to_user(const struct pci_dev *dev, int bar, + const struct resource *rsrc, + resource_size_t *start, resource_size_t *end); + +extern void pcibios_setup_bus_devices(struct pci_bus *bus); +extern void pcibios_setup_bus_self(struct pci_bus *bus); + +#endif /* __KERNEL__ */ +#endif /* __ASM_MICROBLAZE_PCI_H */ -- cgit v0.10.2 From 2ed975b43c1bf09652795a355c4e820e21c4ec44 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 18 Jan 2010 14:25:08 +0100 Subject: microblaze: Add pci-bridge.h Add pci-bridge.h for Microblaze. It is based on powerpc header file. My changes: I removed PPC_ prefix from constants Removed ppc64 specifis parts Signed-off-by: Michal Simek diff --git a/arch/microblaze/include/asm/pci-bridge.h b/arch/microblaze/include/asm/pci-bridge.h index 7ad28f6..0c77cda 100644 --- a/arch/microblaze/include/asm/pci-bridge.h +++ b/arch/microblaze/include/asm/pci-bridge.h @@ -1 +1,196 @@ +#ifndef _ASM_MICROBLAZE_PCI_BRIDGE_H +#define _ASM_MICROBLAZE_PCI_BRIDGE_H +#ifdef __KERNEL__ +/* + * 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. + */ #include +#include +#include + +struct device_node; + +enum { + /* Force re-assigning all resources (ignore firmware + * setup completely) + */ + PCI_REASSIGN_ALL_RSRC = 0x00000001, + + /* Re-assign all bus numbers */ + PCI_REASSIGN_ALL_BUS = 0x00000002, + + /* Do not try to assign, just use existing setup */ + PCI_PROBE_ONLY = 0x00000004, + + /* Don't bother with ISA alignment unless the bridge has + * ISA forwarding enabled + */ + PCI_CAN_SKIP_ISA_ALIGN = 0x00000008, + + /* Enable domain numbers in /proc */ + PCI_ENABLE_PROC_DOMAINS = 0x00000010, + /* ... except for domain 0 */ + PCI_COMPAT_DOMAIN_0 = 0x00000020, +}; + +/* + * Structure of a PCI controller (host bridge) + */ +struct pci_controller { + struct pci_bus *bus; + char is_dynamic; + struct device_node *dn; + struct list_head list_node; + struct device *parent; + + int first_busno; + int last_busno; + + int self_busno; + + void __iomem *io_base_virt; + resource_size_t io_base_phys; + + resource_size_t pci_io_size; + + /* Some machines (PReP) have a non 1:1 mapping of + * the PCI memory space in the CPU bus space + */ + resource_size_t pci_mem_offset; + + /* Some machines have a special region to forward the ISA + * "memory" cycles such as VGA memory regions. Left to 0 + * if unsupported + */ + resource_size_t isa_mem_phys; + resource_size_t isa_mem_size; + + struct pci_ops *ops; + unsigned int __iomem *cfg_addr; + void __iomem *cfg_data; + + /* + * Used for variants of PCI indirect handling and possible quirks: + * SET_CFG_TYPE - used on 4xx or any PHB that does explicit type0/1 + * EXT_REG - provides access to PCI-e extended registers + * SURPRESS_PRIMARY_BUS - we surpress the setting of PCI_PRIMARY_BUS + * on Freescale PCI-e controllers since they used the PCI_PRIMARY_BUS + * to determine which bus number to match on when generating type0 + * config cycles + * NO_PCIE_LINK - the Freescale PCI-e controllers have issues with + * hanging if we don't have link and try to do config cycles to + * anything but the PHB. Only allow talking to the PHB if this is + * set. + * BIG_ENDIAN - cfg_addr is a big endian register + * BROKEN_MRM - the 440EPx/GRx chips have an errata that causes hangs + * on the PLB4. Effectively disable MRM commands by setting this. + */ +#define INDIRECT_TYPE_SET_CFG_TYPE 0x00000001 +#define INDIRECT_TYPE_EXT_REG 0x00000002 +#define INDIRECT_TYPE_SURPRESS_PRIMARY_BUS 0x00000004 +#define INDIRECT_TYPE_NO_PCIE_LINK 0x00000008 +#define INDIRECT_TYPE_BIG_ENDIAN 0x00000010 +#define INDIRECT_TYPE_BROKEN_MRM 0x00000020 + u32 indirect_type; + + /* Currently, we limit ourselves to 1 IO range and 3 mem + * ranges since the common pci_bus structure can't handle more + */ + struct resource io_resource; + struct resource mem_resources[3]; + int global_number; /* PCI domain number */ +}; + +static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus) +{ + return bus->sysdata; +} + +static inline int isa_vaddr_is_ioport(void __iomem *address) +{ + /* No specific ISA handling on ppc32 at this stage, it + * all goes through PCI + */ + return 0; +} + +/* These are used for config access before all the PCI probing + has been done. */ +extern int early_read_config_byte(struct pci_controller *hose, int bus, + int dev_fn, int where, u8 *val); +extern int early_read_config_word(struct pci_controller *hose, int bus, + int dev_fn, int where, u16 *val); +extern int early_read_config_dword(struct pci_controller *hose, int bus, + int dev_fn, int where, u32 *val); +extern int early_write_config_byte(struct pci_controller *hose, int bus, + int dev_fn, int where, u8 val); +extern int early_write_config_word(struct pci_controller *hose, int bus, + int dev_fn, int where, u16 val); +extern int early_write_config_dword(struct pci_controller *hose, int bus, + int dev_fn, int where, u32 val); + +extern int early_find_capability(struct pci_controller *hose, int bus, + int dev_fn, int cap); + +extern void setup_indirect_pci(struct pci_controller *hose, + resource_size_t cfg_addr, + resource_size_t cfg_data, u32 flags); + +/* Get the PCI host controller for an OF device */ +extern struct pci_controller *pci_find_hose_for_OF_device( + struct device_node *node); + +/* Fill up host controller resources from the OF node */ +extern void pci_process_bridge_OF_ranges(struct pci_controller *hose, + struct device_node *dev, int primary); + +/* Allocate & free a PCI host bridge structure */ +extern struct pci_controller *pcibios_alloc_controller(struct device_node *dev); +extern void pcibios_free_controller(struct pci_controller *phb); +extern void pcibios_setup_phb_resources(struct pci_controller *hose); + +#ifdef CONFIG_PCI +extern unsigned int pci_flags; + +static inline void pci_set_flags(int flags) +{ + pci_flags = flags; +} + +static inline void pci_add_flags(int flags) +{ + pci_flags |= flags; +} + +static inline int pci_has_flag(int flag) +{ + return pci_flags & flag; +} + +extern struct list_head hose_list; + +extern unsigned long pci_address_to_pio(phys_addr_t address); +extern int pcibios_vaddr_is_ioport(void __iomem *address); +#else +static inline unsigned long pci_address_to_pio(phys_addr_t address) +{ + return (unsigned long)-1; +} +static inline int pcibios_vaddr_is_ioport(void __iomem *address) +{ + return 0; +} + +static inline void pci_set_flags(int flags) { } +static inline void pci_add_flags(int flags) { } +static inline int pci_has_flag(int flag) +{ + return 0; +} +#endif /* CONFIG_PCI */ + +#endif /* __KERNEL__ */ +#endif /* _ASM_MICROBLAZE_PCI_BRIDGE_H */ -- cgit v0.10.2 From d3afa58c20b65155af9f0d5eaa59fe2d367ac432 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 18 Jan 2010 14:42:34 +0100 Subject: microblaze: Add core PCI files Add pci-common.h and pci32.c. Files are based on PPC version. There are removed ppc specific parts and the code was completely clean. Signed-off-by: Michal Simek diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c new file mode 100644 index 0000000..f03f8be --- /dev/null +++ b/arch/microblaze/pci/pci-common.c @@ -0,0 +1,1640 @@ +/* + * Contains common pci routines for ALL ppc platform + * (based on pci_32.c and pci_64.c) + * + * Port for PPC64 David Engebretsen, IBM Corp. + * Contains common pci routines for ppc64 platform, pSeries and iSeries brands. + * + * Copyright (C) 2003 Anton Blanchard , IBM + * Rework, based on alpha PCI code. + * + * Common pmac/prep/chrp pci routines. -- Cort + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +static DEFINE_SPINLOCK(hose_spinlock); +LIST_HEAD(hose_list); + +/* XXX kill that some day ... */ +static int global_phb_number; /* Global phb counter */ + +/* ISA Memory physical address */ +resource_size_t isa_mem_base; + +/* Default PCI flags is 0 on ppc32, modified at boot on ppc64 */ +unsigned int pci_flags; + +static struct dma_map_ops *pci_dma_ops = &dma_direct_ops; + +void set_pci_dma_ops(struct dma_map_ops *dma_ops) +{ + pci_dma_ops = dma_ops; +} + +struct dma_map_ops *get_pci_dma_ops(void) +{ + return pci_dma_ops; +} +EXPORT_SYMBOL(get_pci_dma_ops); + +int pci_set_dma_mask(struct pci_dev *dev, u64 mask) +{ + return dma_set_mask(&dev->dev, mask); +} + +int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask) +{ + int rc; + + rc = dma_set_mask(&dev->dev, mask); + dev->dev.coherent_dma_mask = dev->dma_mask; + + return rc; +} + +struct pci_controller *pcibios_alloc_controller(struct device_node *dev) +{ + struct pci_controller *phb; + + phb = zalloc_maybe_bootmem(sizeof(struct pci_controller), GFP_KERNEL); + if (!phb) + return NULL; + spin_lock(&hose_spinlock); + phb->global_number = global_phb_number++; + list_add_tail(&phb->list_node, &hose_list); + spin_unlock(&hose_spinlock); + phb->dn = dev; + phb->is_dynamic = mem_init_done; + return phb; +} + +void pcibios_free_controller(struct pci_controller *phb) +{ + spin_lock(&hose_spinlock); + list_del(&phb->list_node); + spin_unlock(&hose_spinlock); + + if (phb->is_dynamic) + kfree(phb); +} + +static resource_size_t pcibios_io_size(const struct pci_controller *hose) +{ + return hose->io_resource.end - hose->io_resource.start + 1; +} + +int pcibios_vaddr_is_ioport(void __iomem *address) +{ + int ret = 0; + struct pci_controller *hose; + resource_size_t size; + + spin_lock(&hose_spinlock); + list_for_each_entry(hose, &hose_list, list_node) { + size = pcibios_io_size(hose); + if (address >= hose->io_base_virt && + address < (hose->io_base_virt + size)) { + ret = 1; + break; + } + } + spin_unlock(&hose_spinlock); + return ret; +} + +unsigned long pci_address_to_pio(phys_addr_t address) +{ + struct pci_controller *hose; + resource_size_t size; + unsigned long ret = ~0; + + spin_lock(&hose_spinlock); + list_for_each_entry(hose, &hose_list, list_node) { + size = pcibios_io_size(hose); + if (address >= hose->io_base_phys && + address < (hose->io_base_phys + size)) { + unsigned long base = + (unsigned long)hose->io_base_virt - _IO_BASE; + ret = base + (address - hose->io_base_phys); + break; + } + } + spin_unlock(&hose_spinlock); + + return ret; +} +EXPORT_SYMBOL_GPL(pci_address_to_pio); + +/* + * Return the domain number for this bus. + */ +int pci_domain_nr(struct pci_bus *bus) +{ + struct pci_controller *hose = pci_bus_to_host(bus); + + return hose->global_number; +} +EXPORT_SYMBOL(pci_domain_nr); + +/* This routine is meant to be used early during boot, when the + * PCI bus numbers have not yet been assigned, and you need to + * issue PCI config cycles to an OF device. + * It could also be used to "fix" RTAS config cycles if you want + * to set pci_assign_all_buses to 1 and still use RTAS for PCI + * config cycles. + */ +struct pci_controller *pci_find_hose_for_OF_device(struct device_node *node) +{ + while (node) { + struct pci_controller *hose, *tmp; + list_for_each_entry_safe(hose, tmp, &hose_list, list_node) + if (hose->dn == node) + return hose; + node = node->parent; + } + return NULL; +} + +static ssize_t pci_show_devspec(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct pci_dev *pdev; + struct device_node *np; + + pdev = to_pci_dev(dev); + np = pci_device_to_OF_node(pdev); + if (np == NULL || np->full_name == NULL) + return 0; + return sprintf(buf, "%s", np->full_name); +} +static DEVICE_ATTR(devspec, S_IRUGO, pci_show_devspec, NULL); + +/* Add sysfs properties */ +int pcibios_add_platform_entries(struct pci_dev *pdev) +{ + return device_create_file(&pdev->dev, &dev_attr_devspec); +} + +char __devinit *pcibios_setup(char *str) +{ + return str; +} + +/* + * Reads the interrupt pin to determine if interrupt is use by card. + * If the interrupt is used, then gets the interrupt line from the + * openfirmware and sets it in the pci_dev and pci_config line. + */ +int pci_read_irq_line(struct pci_dev *pci_dev) +{ + struct of_irq oirq; + unsigned int virq; + + /* The current device-tree that iSeries generates from the HV + * PCI informations doesn't contain proper interrupt routing, + * and all the fallback would do is print out crap, so we + * don't attempt to resolve the interrupts here at all, some + * iSeries specific fixup does it. + * + * In the long run, we will hopefully fix the generated device-tree + * instead. + */ + pr_debug("PCI: Try to map irq for %s...\n", pci_name(pci_dev)); + +#ifdef DEBUG + memset(&oirq, 0xff, sizeof(oirq)); +#endif + /* Try to get a mapping from the device-tree */ + if (of_irq_map_pci(pci_dev, &oirq)) { + u8 line, pin; + + /* If that fails, lets fallback to what is in the config + * space and map that through the default controller. We + * also set the type to level low since that's what PCI + * interrupts are. If your platform does differently, then + * either provide a proper interrupt tree or don't use this + * function. + */ + if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_PIN, &pin)) + return -1; + if (pin == 0) + return -1; + if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_LINE, &line) || + line == 0xff || line == 0) { + return -1; + } + pr_debug(" No map ! Using line %d (pin %d) from PCI config\n", + line, pin); + + virq = irq_create_mapping(NULL, line); + if (virq != NO_IRQ) + set_irq_type(virq, IRQ_TYPE_LEVEL_LOW); + } else { + pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %s\n", + oirq.size, oirq.specifier[0], oirq.specifier[1], + oirq.controller ? oirq.controller->full_name : + ""); + + virq = irq_create_of_mapping(oirq.controller, oirq.specifier, + oirq.size); + } + if (virq == NO_IRQ) { + pr_debug(" Failed to map !\n"); + return -1; + } + + pr_debug(" Mapped to linux irq %d\n", virq); + + pci_dev->irq = virq; + + return 0; +} +EXPORT_SYMBOL(pci_read_irq_line); + +/* + * Platform support for /proc/bus/pci/X/Y mmap()s, + * modelled on the sparc64 implementation by Dave Miller. + * -- paulus. + */ + +/* + * Adjust vm_pgoff of VMA such that it is the physical page offset + * corresponding to the 32-bit pci bus offset for DEV requested by the user. + * + * Basically, the user finds the base address for his device which he wishes + * to mmap. They read the 32-bit value from the config space base register, + * add whatever PAGE_SIZE multiple offset they wish, and feed this into the + * offset parameter of mmap on /proc/bus/pci/XXX for that device. + * + * Returns negative error code on failure, zero on success. + */ +static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, + resource_size_t *offset, + enum pci_mmap_state mmap_state) +{ + struct pci_controller *hose = pci_bus_to_host(dev->bus); + unsigned long io_offset = 0; + int i, res_bit; + + if (hose == 0) + return NULL; /* should never happen */ + + /* If memory, add on the PCI bridge address offset */ + if (mmap_state == pci_mmap_mem) { +#if 0 /* See comment in pci_resource_to_user() for why this is disabled */ + *offset += hose->pci_mem_offset; +#endif + res_bit = IORESOURCE_MEM; + } else { + io_offset = (unsigned long)hose->io_base_virt - _IO_BASE; + *offset += io_offset; + res_bit = IORESOURCE_IO; + } + + /* + * Check that the offset requested corresponds to one of the + * resources of the device. + */ + for (i = 0; i <= PCI_ROM_RESOURCE; i++) { + struct resource *rp = &dev->resource[i]; + int flags = rp->flags; + + /* treat ROM as memory (should be already) */ + if (i == PCI_ROM_RESOURCE) + flags |= IORESOURCE_MEM; + + /* Active and same type? */ + if ((flags & res_bit) == 0) + continue; + + /* In the range of this resource? */ + if (*offset < (rp->start & PAGE_MASK) || *offset > rp->end) + continue; + + /* found it! construct the final physical address */ + if (mmap_state == pci_mmap_io) + *offset += hose->io_base_phys - io_offset; + return rp; + } + + return NULL; +} + +/* + * Set vm_page_prot of VMA, as appropriate for this architecture, for a pci + * device mapping. + */ +static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp, + pgprot_t protection, + enum pci_mmap_state mmap_state, + int write_combine) +{ + pgprot_t prot = protection; + + /* Write combine is always 0 on non-memory space mappings. On + * memory space, if the user didn't pass 1, we check for a + * "prefetchable" resource. This is a bit hackish, but we use + * this to workaround the inability of /sysfs to provide a write + * combine bit + */ + if (mmap_state != pci_mmap_mem) + write_combine = 0; + else if (write_combine == 0) { + if (rp->flags & IORESOURCE_PREFETCH) + write_combine = 1; + } + + return pgprot_noncached(prot); +} + +/* + * This one is used by /dev/mem and fbdev who have no clue about the + * PCI device, it tries to find the PCI device first and calls the + * above routine + */ +pgprot_t pci_phys_mem_access_prot(struct file *file, + unsigned long pfn, + unsigned long size, + pgprot_t prot) +{ + struct pci_dev *pdev = NULL; + struct resource *found = NULL; + resource_size_t offset = ((resource_size_t)pfn) << PAGE_SHIFT; + int i; + + if (page_is_ram(pfn)) + return prot; + + prot = pgprot_noncached(prot); + for_each_pci_dev(pdev) { + for (i = 0; i <= PCI_ROM_RESOURCE; i++) { + struct resource *rp = &pdev->resource[i]; + int flags = rp->flags; + + /* Active and same type? */ + if ((flags & IORESOURCE_MEM) == 0) + continue; + /* In the range of this resource? */ + if (offset < (rp->start & PAGE_MASK) || + offset > rp->end) + continue; + found = rp; + break; + } + if (found) + break; + } + if (found) { + if (found->flags & IORESOURCE_PREFETCH) + prot = pgprot_noncached_wc(prot); + pci_dev_put(pdev); + } + + pr_debug("PCI: Non-PCI map for %llx, prot: %lx\n", + (unsigned long long)offset, pgprot_val(prot)); + + return prot; +} + +/* + * Perform the actual remap of the pages for a PCI device mapping, as + * appropriate for this architecture. The region in the process to map + * is described by vm_start and vm_end members of VMA, the base physical + * address is found in vm_pgoff. + * The pci device structure is provided so that architectures may make mapping + * decisions on a per-device or per-bus basis. + * + * Returns a negative error code on failure, zero on success. + */ +int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, + enum pci_mmap_state mmap_state, int write_combine) +{ + resource_size_t offset = + ((resource_size_t)vma->vm_pgoff) << PAGE_SHIFT; + struct resource *rp; + int ret; + + rp = __pci_mmap_make_offset(dev, &offset, mmap_state); + if (rp == NULL) + return -EINVAL; + + vma->vm_pgoff = offset >> PAGE_SHIFT; + vma->vm_page_prot = __pci_mmap_set_pgprot(dev, rp, + vma->vm_page_prot, + mmap_state, write_combine); + + ret = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, + vma->vm_end - vma->vm_start, vma->vm_page_prot); + + return ret; +} + +/* This provides legacy IO read access on a bus */ +int pci_legacy_read(struct pci_bus *bus, loff_t port, u32 *val, size_t size) +{ + unsigned long offset; + struct pci_controller *hose = pci_bus_to_host(bus); + struct resource *rp = &hose->io_resource; + void __iomem *addr; + + /* Check if port can be supported by that bus. We only check + * the ranges of the PHB though, not the bus itself as the rules + * for forwarding legacy cycles down bridges are not our problem + * here. So if the host bridge supports it, we do it. + */ + offset = (unsigned long)hose->io_base_virt - _IO_BASE; + offset += port; + + if (!(rp->flags & IORESOURCE_IO)) + return -ENXIO; + if (offset < rp->start || (offset + size) > rp->end) + return -ENXIO; + addr = hose->io_base_virt + port; + + switch (size) { + case 1: + *((u8 *)val) = in_8(addr); + return 1; + case 2: + if (port & 1) + return -EINVAL; + *((u16 *)val) = in_le16(addr); + return 2; + case 4: + if (port & 3) + return -EINVAL; + *((u32 *)val) = in_le32(addr); + return 4; + } + return -EINVAL; +} + +/* This provides legacy IO write access on a bus */ +int pci_legacy_write(struct pci_bus *bus, loff_t port, u32 val, size_t size) +{ + unsigned long offset; + struct pci_controller *hose = pci_bus_to_host(bus); + struct resource *rp = &hose->io_resource; + void __iomem *addr; + + /* Check if port can be supported by that bus. We only check + * the ranges of the PHB though, not the bus itself as the rules + * for forwarding legacy cycles down bridges are not our problem + * here. So if the host bridge supports it, we do it. + */ + offset = (unsigned long)hose->io_base_virt - _IO_BASE; + offset += port; + + if (!(rp->flags & IORESOURCE_IO)) + return -ENXIO; + if (offset < rp->start || (offset + size) > rp->end) + return -ENXIO; + addr = hose->io_base_virt + port; + + /* WARNING: The generic code is idiotic. It gets passed a pointer + * to what can be a 1, 2 or 4 byte quantity and always reads that + * as a u32, which means that we have to correct the location of + * the data read within those 32 bits for size 1 and 2 + */ + switch (size) { + case 1: + out_8(addr, val >> 24); + return 1; + case 2: + if (port & 1) + return -EINVAL; + out_le16(addr, val >> 16); + return 2; + case 4: + if (port & 3) + return -EINVAL; + out_le32(addr, val); + return 4; + } + return -EINVAL; +} + +/* This provides legacy IO or memory mmap access on a bus */ +int pci_mmap_legacy_page_range(struct pci_bus *bus, + struct vm_area_struct *vma, + enum pci_mmap_state mmap_state) +{ + struct pci_controller *hose = pci_bus_to_host(bus); + resource_size_t offset = + ((resource_size_t)vma->vm_pgoff) << PAGE_SHIFT; + resource_size_t size = vma->vm_end - vma->vm_start; + struct resource *rp; + + pr_debug("pci_mmap_legacy_page_range(%04x:%02x, %s @%llx..%llx)\n", + pci_domain_nr(bus), bus->number, + mmap_state == pci_mmap_mem ? "MEM" : "IO", + (unsigned long long)offset, + (unsigned long long)(offset + size - 1)); + + if (mmap_state == pci_mmap_mem) { + /* Hack alert ! + * + * Because X is lame and can fail starting if it gets an error + * trying to mmap legacy_mem (instead of just moving on without + * legacy memory access) we fake it here by giving it anonymous + * memory, effectively behaving just like /dev/zero + */ + if ((offset + size) > hose->isa_mem_size) { + printk(KERN_DEBUG + "Process %s (pid:%d) mapped non-existing PCI" + "legacy memory for 0%04x:%02x\n", + current->comm, current->pid, pci_domain_nr(bus), + bus->number); + if (vma->vm_flags & VM_SHARED) + return shmem_zero_setup(vma); + return 0; + } + offset += hose->isa_mem_phys; + } else { + unsigned long io_offset = (unsigned long)hose->io_base_virt - \ + _IO_BASE; + unsigned long roffset = offset + io_offset; + rp = &hose->io_resource; + if (!(rp->flags & IORESOURCE_IO)) + return -ENXIO; + if (roffset < rp->start || (roffset + size) > rp->end) + return -ENXIO; + offset += hose->io_base_phys; + } + pr_debug(" -> mapping phys %llx\n", (unsigned long long)offset); + + vma->vm_pgoff = offset >> PAGE_SHIFT; + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, + vma->vm_end - vma->vm_start, + vma->vm_page_prot); +} + +void pci_resource_to_user(const struct pci_dev *dev, int bar, + const struct resource *rsrc, + resource_size_t *start, resource_size_t *end) +{ + struct pci_controller *hose = pci_bus_to_host(dev->bus); + resource_size_t offset = 0; + + if (hose == NULL) + return; + + if (rsrc->flags & IORESOURCE_IO) + offset = (unsigned long)hose->io_base_virt - _IO_BASE; + + /* We pass a fully fixed up address to userland for MMIO instead of + * a BAR value because X is lame and expects to be able to use that + * to pass to /dev/mem ! + * + * That means that we'll have potentially 64 bits values where some + * userland apps only expect 32 (like X itself since it thinks only + * Sparc has 64 bits MMIO) but if we don't do that, we break it on + * 32 bits CHRPs :-( + * + * Hopefully, the sysfs insterface is immune to that gunk. Once X + * has been fixed (and the fix spread enough), we can re-enable the + * 2 lines below and pass down a BAR value to userland. In that case + * we'll also have to re-enable the matching code in + * __pci_mmap_make_offset(). + * + * BenH. + */ +#if 0 + else if (rsrc->flags & IORESOURCE_MEM) + offset = hose->pci_mem_offset; +#endif + + *start = rsrc->start - offset; + *end = rsrc->end - offset; +} + +/** + * pci_process_bridge_OF_ranges - Parse PCI bridge resources from device tree + * @hose: newly allocated pci_controller to be setup + * @dev: device node of the host bridge + * @primary: set if primary bus (32 bits only, soon to be deprecated) + * + * This function will parse the "ranges" property of a PCI host bridge device + * node and setup the resource mapping of a pci controller based on its + * content. + * + * Life would be boring if it wasn't for a few issues that we have to deal + * with here: + * + * - We can only cope with one IO space range and up to 3 Memory space + * ranges. However, some machines (thanks Apple !) tend to split their + * space into lots of small contiguous ranges. So we have to coalesce. + * + * - We can only cope with all memory ranges having the same offset + * between CPU addresses and PCI addresses. Unfortunately, some bridges + * are setup for a large 1:1 mapping along with a small "window" which + * maps PCI address 0 to some arbitrary high address of the CPU space in + * order to give access to the ISA memory hole. + * The way out of here that I've chosen for now is to always set the + * offset based on the first resource found, then override it if we + * have a different offset and the previous was set by an ISA hole. + * + * - Some busses have IO space not starting at 0, which causes trouble with + * the way we do our IO resource renumbering. The code somewhat deals with + * it for 64 bits but I would expect problems on 32 bits. + * + * - Some 32 bits platforms such as 4xx can have physical space larger than + * 32 bits so we need to use 64 bits values for the parsing + */ +void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose, + struct device_node *dev, + int primary) +{ + const u32 *ranges; + int rlen; + int pna = of_n_addr_cells(dev); + int np = pna + 5; + int memno = 0, isa_hole = -1; + u32 pci_space; + unsigned long long pci_addr, cpu_addr, pci_next, cpu_next, size; + unsigned long long isa_mb = 0; + struct resource *res; + + printk(KERN_INFO "PCI host bridge %s %s ranges:\n", + dev->full_name, primary ? "(primary)" : ""); + + /* Get ranges property */ + ranges = of_get_property(dev, "ranges", &rlen); + if (ranges == NULL) + return; + + /* Parse it */ + pr_debug("Parsing ranges property...\n"); + while ((rlen -= np * 4) >= 0) { + /* Read next ranges element */ + pci_space = ranges[0]; + pci_addr = of_read_number(ranges + 1, 2); + cpu_addr = of_translate_address(dev, ranges + 3); + size = of_read_number(ranges + pna + 3, 2); + + pr_debug("pci_space: 0x%08x pci_addr:0x%016llx " + "cpu_addr:0x%016llx size:0x%016llx\n", + pci_space, pci_addr, cpu_addr, size); + + ranges += np; + + /* If we failed translation or got a zero-sized region + * (some FW try to feed us with non sensical zero sized regions + * such as power3 which look like some kind of attempt + * at exposing the VGA memory hole) + */ + if (cpu_addr == OF_BAD_ADDR || size == 0) + continue; + + /* Now consume following elements while they are contiguous */ + for (; rlen >= np * sizeof(u32); + ranges += np, rlen -= np * 4) { + if (ranges[0] != pci_space) + break; + pci_next = of_read_number(ranges + 1, 2); + cpu_next = of_translate_address(dev, ranges + 3); + if (pci_next != pci_addr + size || + cpu_next != cpu_addr + size) + break; + size += of_read_number(ranges + pna + 3, 2); + } + + /* Act based on address space type */ + res = NULL; + switch ((pci_space >> 24) & 0x3) { + case 1: /* PCI IO space */ + printk(KERN_INFO + " IO 0x%016llx..0x%016llx -> 0x%016llx\n", + cpu_addr, cpu_addr + size - 1, pci_addr); + + /* We support only one IO range */ + if (hose->pci_io_size) { + printk(KERN_INFO + " \\--> Skipped (too many) !\n"); + continue; + } + /* On 32 bits, limit I/O space to 16MB */ + if (size > 0x01000000) + size = 0x01000000; + + /* 32 bits needs to map IOs here */ + hose->io_base_virt = ioremap(cpu_addr, size); + + /* Expect trouble if pci_addr is not 0 */ + if (primary) + isa_io_base = + (unsigned long)hose->io_base_virt; + /* pci_io_size and io_base_phys always represent IO + * space starting at 0 so we factor in pci_addr + */ + hose->pci_io_size = pci_addr + size; + hose->io_base_phys = cpu_addr - pci_addr; + + /* Build resource */ + res = &hose->io_resource; + res->flags = IORESOURCE_IO; + res->start = pci_addr; + break; + case 2: /* PCI Memory space */ + case 3: /* PCI 64 bits Memory space */ + printk(KERN_INFO + " MEM 0x%016llx..0x%016llx -> 0x%016llx %s\n", + cpu_addr, cpu_addr + size - 1, pci_addr, + (pci_space & 0x40000000) ? "Prefetch" : ""); + + /* We support only 3 memory ranges */ + if (memno >= 3) { + printk(KERN_INFO + " \\--> Skipped (too many) !\n"); + continue; + } + /* Handles ISA memory hole space here */ + if (pci_addr == 0) { + isa_mb = cpu_addr; + isa_hole = memno; + if (primary || isa_mem_base == 0) + isa_mem_base = cpu_addr; + hose->isa_mem_phys = cpu_addr; + hose->isa_mem_size = size; + } + + /* We get the PCI/Mem offset from the first range or + * the, current one if the offset came from an ISA + * hole. If they don't match, bugger. + */ + if (memno == 0 || + (isa_hole >= 0 && pci_addr != 0 && + hose->pci_mem_offset == isa_mb)) + hose->pci_mem_offset = cpu_addr - pci_addr; + else if (pci_addr != 0 && + hose->pci_mem_offset != cpu_addr - pci_addr) { + printk(KERN_INFO + " \\--> Skipped (offset mismatch) !\n"); + continue; + } + + /* Build resource */ + res = &hose->mem_resources[memno++]; + res->flags = IORESOURCE_MEM; + if (pci_space & 0x40000000) + res->flags |= IORESOURCE_PREFETCH; + res->start = cpu_addr; + break; + } + if (res != NULL) { + res->name = dev->full_name; + res->end = res->start + size - 1; + res->parent = NULL; + res->sibling = NULL; + res->child = NULL; + } + } + + /* If there's an ISA hole and the pci_mem_offset is -not- matching + * the ISA hole offset, then we need to remove the ISA hole from + * the resource list for that brige + */ + if (isa_hole >= 0 && hose->pci_mem_offset != isa_mb) { + unsigned int next = isa_hole + 1; + printk(KERN_INFO " Removing ISA hole at 0x%016llx\n", isa_mb); + if (next < memno) + memmove(&hose->mem_resources[isa_hole], + &hose->mem_resources[next], + sizeof(struct resource) * (memno - next)); + hose->mem_resources[--memno].flags = 0; + } +} + +/* Decide whether to display the domain number in /proc */ +int pci_proc_domain(struct pci_bus *bus) +{ + struct pci_controller *hose = pci_bus_to_host(bus); + + if (!(pci_flags & PCI_ENABLE_PROC_DOMAINS)) + return 0; + if (pci_flags & PCI_COMPAT_DOMAIN_0) + return hose->global_number != 0; + return 1; +} + +void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, + struct resource *res) +{ + resource_size_t offset = 0, mask = (resource_size_t)-1; + struct pci_controller *hose = pci_bus_to_host(dev->bus); + + if (!hose) + return; + if (res->flags & IORESOURCE_IO) { + offset = (unsigned long)hose->io_base_virt - _IO_BASE; + mask = 0xffffffffu; + } else if (res->flags & IORESOURCE_MEM) + offset = hose->pci_mem_offset; + + region->start = (res->start - offset) & mask; + region->end = (res->end - offset) & mask; +} +EXPORT_SYMBOL(pcibios_resource_to_bus); + +void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, + struct pci_bus_region *region) +{ + resource_size_t offset = 0, mask = (resource_size_t)-1; + struct pci_controller *hose = pci_bus_to_host(dev->bus); + + if (!hose) + return; + if (res->flags & IORESOURCE_IO) { + offset = (unsigned long)hose->io_base_virt - _IO_BASE; + mask = 0xffffffffu; + } else if (res->flags & IORESOURCE_MEM) + offset = hose->pci_mem_offset; + res->start = (region->start + offset) & mask; + res->end = (region->end + offset) & mask; +} +EXPORT_SYMBOL(pcibios_bus_to_resource); + +/* Fixup a bus resource into a linux resource */ +static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev) +{ + struct pci_controller *hose = pci_bus_to_host(dev->bus); + resource_size_t offset = 0, mask = (resource_size_t)-1; + + if (res->flags & IORESOURCE_IO) { + offset = (unsigned long)hose->io_base_virt - _IO_BASE; + mask = 0xffffffffu; + } else if (res->flags & IORESOURCE_MEM) + offset = hose->pci_mem_offset; + + res->start = (res->start + offset) & mask; + res->end = (res->end + offset) & mask; +} + +/* This header fixup will do the resource fixup for all devices as they are + * probed, but not for bridge ranges + */ +static void __devinit pcibios_fixup_resources(struct pci_dev *dev) +{ + struct pci_controller *hose = pci_bus_to_host(dev->bus); + int i; + + if (!hose) { + printk(KERN_ERR "No host bridge for PCI dev %s !\n", + pci_name(dev)); + return; + } + for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { + struct resource *res = dev->resource + i; + if (!res->flags) + continue; + /* On platforms that have PCI_PROBE_ONLY set, we don't + * consider 0 as an unassigned BAR value. It's technically + * a valid value, but linux doesn't like it... so when we can + * re-assign things, we do so, but if we can't, we keep it + * around and hope for the best... + */ + if (res->start == 0 && !(pci_flags & PCI_PROBE_ONLY)) { + pr_debug("PCI:%s Resource %d %016llx-%016llx [%x]" \ + "is unassigned\n", + pci_name(dev), i, + (unsigned long long)res->start, + (unsigned long long)res->end, + (unsigned int)res->flags); + res->end -= res->start; + res->start = 0; + res->flags |= IORESOURCE_UNSET; + continue; + } + + pr_debug("PCI:%s Resource %d %016llx-%016llx [%x] fixup...\n", + pci_name(dev), i, + (unsigned long long)res->start,\ + (unsigned long long)res->end, + (unsigned int)res->flags); + + fixup_resource(res, dev); + + pr_debug("PCI:%s %016llx-%016llx\n", + pci_name(dev), + (unsigned long long)res->start, + (unsigned long long)res->end); + } +} +DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources); + +/* This function tries to figure out if a bridge resource has been initialized + * by the firmware or not. It doesn't have to be absolutely bullet proof, but + * things go more smoothly when it gets it right. It should covers cases such + * as Apple "closed" bridge resources and bare-metal pSeries unassigned bridges + */ +static int __devinit pcibios_uninitialized_bridge_resource(struct pci_bus *bus, + struct resource *res) +{ + struct pci_controller *hose = pci_bus_to_host(bus); + struct pci_dev *dev = bus->self; + resource_size_t offset; + u16 command; + int i; + + /* We don't do anything if PCI_PROBE_ONLY is set */ + if (pci_flags & PCI_PROBE_ONLY) + return 0; + + /* Job is a bit different between memory and IO */ + if (res->flags & IORESOURCE_MEM) { + /* If the BAR is non-0 (res != pci_mem_offset) then it's + * probably been initialized by somebody + */ + if (res->start != hose->pci_mem_offset) + return 0; + + /* The BAR is 0, let's check if memory decoding is enabled on + * the bridge. If not, we consider it unassigned + */ + pci_read_config_word(dev, PCI_COMMAND, &command); + if ((command & PCI_COMMAND_MEMORY) == 0) + return 1; + + /* Memory decoding is enabled and the BAR is 0. If any of + * the bridge resources covers that starting address (0 then + * it's good enough for us for memory + */ + for (i = 0; i < 3; i++) { + if ((hose->mem_resources[i].flags & IORESOURCE_MEM) && + hose->mem_resources[i].start == hose->pci_mem_offset) + return 0; + } + + /* Well, it starts at 0 and we know it will collide so we may as + * well consider it as unassigned. That covers the Apple case. + */ + return 1; + } else { + /* If the BAR is non-0, then we consider it assigned */ + offset = (unsigned long)hose->io_base_virt - _IO_BASE; + if (((res->start - offset) & 0xfffffffful) != 0) + return 0; + + /* Here, we are a bit different than memory as typically IO + * space starting at low addresses -is- valid. What we do + * instead if that we consider as unassigned anything that + * doesn't have IO enabled in the PCI command register, + * and that's it. + */ + pci_read_config_word(dev, PCI_COMMAND, &command); + if (command & PCI_COMMAND_IO) + return 0; + + /* It's starting at 0 and IO is disabled in the bridge, consider + * it unassigned + */ + return 1; + } +} + +/* Fixup resources of a PCI<->PCI bridge */ +static void __devinit pcibios_fixup_bridge(struct pci_bus *bus) +{ + struct resource *res; + int i; + + struct pci_dev *dev = bus->self; + + for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) { + res = bus->resource[i]; + if (!res) + continue; + if (!res->flags) + continue; + if (i >= 3 && bus->self->transparent) + continue; + + pr_debug("PCI:%s Bus rsrc %d %016llx-%016llx [%x] fixup...\n", + pci_name(dev), i, + (unsigned long long)res->start,\ + (unsigned long long)res->end, + (unsigned int)res->flags); + + /* Perform fixup */ + fixup_resource(res, dev); + + /* Try to detect uninitialized P2P bridge resources, + * and clear them out so they get re-assigned later + */ + if (pcibios_uninitialized_bridge_resource(bus, res)) { + res->flags = 0; + pr_debug("PCI:%s (unassigned)\n", + pci_name(dev)); + } else { + pr_debug("PCI:%s %016llx-%016llx\n", + pci_name(dev), + (unsigned long long)res->start, + (unsigned long long)res->end); + } + } +} + +void __devinit pcibios_setup_bus_self(struct pci_bus *bus) +{ + /* Fix up the bus resources for P2P bridges */ + if (bus->self != NULL) + pcibios_fixup_bridge(bus); +} + +void __devinit pcibios_setup_bus_devices(struct pci_bus *bus) +{ + struct pci_dev *dev; + + pr_debug("PCI: Fixup bus devices %d (%s)\n", + bus->number, bus->self ? pci_name(bus->self) : "PHB"); + + list_for_each_entry(dev, &bus->devices, bus_list) { + struct dev_archdata *sd = &dev->dev.archdata; + + /* Setup OF node pointer in archdata */ + sd->of_node = pci_device_to_OF_node(dev); + + /* Fixup NUMA node as it may not be setup yet by the generic + * code and is needed by the DMA init + */ + set_dev_node(&dev->dev, pcibus_to_node(dev->bus)); + + /* Hook up default DMA ops */ + sd->dma_ops = pci_dma_ops; + sd->dma_data = (void *)PCI_DRAM_OFFSET; + + /* Read default IRQs and fixup if necessary */ + pci_read_irq_line(dev); + } +} + +void __devinit pcibios_fixup_bus(struct pci_bus *bus) +{ + /* When called from the generic PCI probe, read PCI<->PCI bridge + * bases. This is -not- called when generating the PCI tree from + * the OF device-tree. + */ + if (bus->self != NULL) + pci_read_bridge_bases(bus); + + /* Now fixup the bus bus */ + pcibios_setup_bus_self(bus); + + /* Now fixup devices on that bus */ + pcibios_setup_bus_devices(bus); +} +EXPORT_SYMBOL(pcibios_fixup_bus); + +static int skip_isa_ioresource_align(struct pci_dev *dev) +{ + if ((pci_flags & PCI_CAN_SKIP_ISA_ALIGN) && + !(dev->bus->bridge_ctl & PCI_BRIDGE_CTL_ISA)) + return 1; + return 0; +} + +/* + * We need to avoid collisions with `mirrored' VGA ports + * and other strange ISA hardware, so we always want the + * addresses to be allocated in the 0x000-0x0ff region + * modulo 0x400. + * + * Why? Because some silly external IO cards only decode + * the low 10 bits of the IO address. The 0x00-0xff region + * is reserved for motherboard devices that decode all 16 + * bits, so it's ok to allocate at, say, 0x2800-0x28ff, + * but we want to try to avoid allocating at 0x2900-0x2bff + * which might have be mirrored at 0x0100-0x03ff.. + */ +void pcibios_align_resource(void *data, struct resource *res, + resource_size_t size, resource_size_t align) +{ + struct pci_dev *dev = data; + + if (res->flags & IORESOURCE_IO) { + resource_size_t start = res->start; + + if (skip_isa_ioresource_align(dev)) + return; + if (start & 0x300) { + start = (start + 0x3ff) & ~0x3ff; + res->start = start; + } + } +} +EXPORT_SYMBOL(pcibios_align_resource); + +/* + * Reparent resource children of pr that conflict with res + * under res, and make res replace those children. + */ +static int __init reparent_resources(struct resource *parent, + struct resource *res) +{ + struct resource *p, **pp; + struct resource **firstpp = NULL; + + for (pp = &parent->child; (p = *pp) != NULL; pp = &p->sibling) { + if (p->end < res->start) + continue; + if (res->end < p->start) + break; + if (p->start < res->start || p->end > res->end) + return -1; /* not completely contained */ + if (firstpp == NULL) + firstpp = pp; + } + if (firstpp == NULL) + return -1; /* didn't find any conflicting entries? */ + res->parent = parent; + res->child = *firstpp; + res->sibling = *pp; + *firstpp = res; + *pp = NULL; + for (p = res->child; p != NULL; p = p->sibling) { + p->parent = res; + pr_debug("PCI: Reparented %s [%llx..%llx] under %s\n", + p->name, + (unsigned long long)p->start, + (unsigned long long)p->end, res->name); + } + return 0; +} + +/* + * Handle resources of PCI devices. If the world were perfect, we could + * just allocate all the resource regions and do nothing more. It isn't. + * On the other hand, we cannot just re-allocate all devices, as it would + * require us to know lots of host bridge internals. So we attempt to + * keep as much of the original configuration as possible, but tweak it + * when it's found to be wrong. + * + * Known BIOS problems we have to work around: + * - I/O or memory regions not configured + * - regions configured, but not enabled in the command register + * - bogus I/O addresses above 64K used + * - expansion ROMs left enabled (this may sound harmless, but given + * the fact the PCI specs explicitly allow address decoders to be + * shared between expansion ROMs and other resource regions, it's + * at least dangerous) + * + * Our solution: + * (1) Allocate resources for all buses behind PCI-to-PCI bridges. + * This gives us fixed barriers on where we can allocate. + * (2) Allocate resources for all enabled devices. If there is + * a collision, just mark the resource as unallocated. Also + * disable expansion ROMs during this step. + * (3) Try to allocate resources for disabled devices. If the + * resources were assigned correctly, everything goes well, + * if they weren't, they won't disturb allocation of other + * resources. + * (4) Assign new addresses to resources which were either + * not configured at all or misconfigured. If explicitly + * requested by the user, configure expansion ROM address + * as well. + */ + +void pcibios_allocate_bus_resources(struct pci_bus *bus) +{ + struct pci_bus *b; + int i; + struct resource *res, *pr; + + pr_debug("PCI: Allocating bus resources for %04x:%02x...\n", + pci_domain_nr(bus), bus->number); + + for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) { + res = bus->resource[i]; + if (!res || !res->flags + || res->start > res->end || res->parent) + continue; + if (bus->parent == NULL) + pr = (res->flags & IORESOURCE_IO) ? + &ioport_resource : &iomem_resource; + else { + /* Don't bother with non-root busses when + * re-assigning all resources. We clear the + * resource flags as if they were colliding + * and as such ensure proper re-allocation + * later. + */ + if (pci_flags & PCI_REASSIGN_ALL_RSRC) + goto clear_resource; + pr = pci_find_parent_resource(bus->self, res); + if (pr == res) { + /* this happens when the generic PCI + * code (wrongly) decides that this + * bridge is transparent -- paulus + */ + continue; + } + } + + pr_debug("PCI: %s (bus %d) bridge rsrc %d: %016llx-%016llx " + "[0x%x], parent %p (%s)\n", + bus->self ? pci_name(bus->self) : "PHB", + bus->number, i, + (unsigned long long)res->start, + (unsigned long long)res->end, + (unsigned int)res->flags, + pr, (pr && pr->name) ? pr->name : "nil"); + + if (pr && !(pr->flags & IORESOURCE_UNSET)) { + if (request_resource(pr, res) == 0) + continue; + /* + * Must be a conflict with an existing entry. + * Move that entry (or entries) under the + * bridge resource and try again. + */ + if (reparent_resources(pr, res) == 0) + continue; + } + printk(KERN_WARNING "PCI: Cannot allocate resource region " + "%d of PCI bridge %d, will remap\n", i, bus->number); +clear_resource: + res->flags = 0; + } + + list_for_each_entry(b, &bus->children, node) + pcibios_allocate_bus_resources(b); +} + +static inline void __devinit alloc_resource(struct pci_dev *dev, int idx) +{ + struct resource *pr, *r = &dev->resource[idx]; + + pr_debug("PCI: Allocating %s: Resource %d: %016llx..%016llx [%x]\n", + pci_name(dev), idx, + (unsigned long long)r->start, + (unsigned long long)r->end, + (unsigned int)r->flags); + + pr = pci_find_parent_resource(dev, r); + if (!pr || (pr->flags & IORESOURCE_UNSET) || + request_resource(pr, r) < 0) { + printk(KERN_WARNING "PCI: Cannot allocate resource region %d" + " of device %s, will remap\n", idx, pci_name(dev)); + if (pr) + pr_debug("PCI: parent is %p: %016llx-%016llx [%x]\n", + pr, + (unsigned long long)pr->start, + (unsigned long long)pr->end, + (unsigned int)pr->flags); + /* We'll assign a new address later */ + r->flags |= IORESOURCE_UNSET; + r->end -= r->start; + r->start = 0; + } +} + +static void __init pcibios_allocate_resources(int pass) +{ + struct pci_dev *dev = NULL; + int idx, disabled; + u16 command; + struct resource *r; + + for_each_pci_dev(dev) { + pci_read_config_word(dev, PCI_COMMAND, &command); + for (idx = 0; idx <= PCI_ROM_RESOURCE; idx++) { + r = &dev->resource[idx]; + if (r->parent) /* Already allocated */ + continue; + if (!r->flags || (r->flags & IORESOURCE_UNSET)) + continue; /* Not assigned at all */ + /* We only allocate ROMs on pass 1 just in case they + * have been screwed up by firmware + */ + if (idx == PCI_ROM_RESOURCE) + disabled = 1; + if (r->flags & IORESOURCE_IO) + disabled = !(command & PCI_COMMAND_IO); + else + disabled = !(command & PCI_COMMAND_MEMORY); + if (pass == disabled) + alloc_resource(dev, idx); + } + if (pass) + continue; + r = &dev->resource[PCI_ROM_RESOURCE]; + if (r->flags) { + /* Turn the ROM off, leave the resource region, + * but keep it unregistered. + */ + u32 reg; + pci_read_config_dword(dev, dev->rom_base_reg, ®); + if (reg & PCI_ROM_ADDRESS_ENABLE) { + pr_debug("PCI: Switching off ROM of %s\n", + pci_name(dev)); + r->flags &= ~IORESOURCE_ROM_ENABLE; + pci_write_config_dword(dev, dev->rom_base_reg, + reg & ~PCI_ROM_ADDRESS_ENABLE); + } + } + } +} + +static void __init pcibios_reserve_legacy_regions(struct pci_bus *bus) +{ + struct pci_controller *hose = pci_bus_to_host(bus); + resource_size_t offset; + struct resource *res, *pres; + int i; + + pr_debug("Reserving legacy ranges for domain %04x\n", + pci_domain_nr(bus)); + + /* Check for IO */ + if (!(hose->io_resource.flags & IORESOURCE_IO)) + goto no_io; + offset = (unsigned long)hose->io_base_virt - _IO_BASE; + res = kzalloc(sizeof(struct resource), GFP_KERNEL); + BUG_ON(res == NULL); + res->name = "Legacy IO"; + res->flags = IORESOURCE_IO; + res->start = offset; + res->end = (offset + 0xfff) & 0xfffffffful; + pr_debug("Candidate legacy IO: %pR\n", res); + if (request_resource(&hose->io_resource, res)) { + printk(KERN_DEBUG + "PCI %04x:%02x Cannot reserve Legacy IO %pR\n", + pci_domain_nr(bus), bus->number, res); + kfree(res); + } + + no_io: + /* Check for memory */ + offset = hose->pci_mem_offset; + pr_debug("hose mem offset: %016llx\n", (unsigned long long)offset); + for (i = 0; i < 3; i++) { + pres = &hose->mem_resources[i]; + if (!(pres->flags & IORESOURCE_MEM)) + continue; + pr_debug("hose mem res: %pR\n", pres); + if ((pres->start - offset) <= 0xa0000 && + (pres->end - offset) >= 0xbffff) + break; + } + if (i >= 3) + return; + res = kzalloc(sizeof(struct resource), GFP_KERNEL); + BUG_ON(res == NULL); + res->name = "Legacy VGA memory"; + res->flags = IORESOURCE_MEM; + res->start = 0xa0000 + offset; + res->end = 0xbffff + offset; + pr_debug("Candidate VGA memory: %pR\n", res); + if (request_resource(pres, res)) { + printk(KERN_DEBUG + "PCI %04x:%02x Cannot reserve VGA memory %pR\n", + pci_domain_nr(bus), bus->number, res); + kfree(res); + } +} + +void __init pcibios_resource_survey(void) +{ + struct pci_bus *b; + + /* Allocate and assign resources. If we re-assign everything, then + * we skip the allocate phase + */ + list_for_each_entry(b, &pci_root_buses, node) + pcibios_allocate_bus_resources(b); + + if (!(pci_flags & PCI_REASSIGN_ALL_RSRC)) { + pcibios_allocate_resources(0); + pcibios_allocate_resources(1); + } + + /* Before we start assigning unassigned resource, we try to reserve + * the low IO area and the VGA memory area if they intersect the + * bus available resources to avoid allocating things on top of them + */ + if (!(pci_flags & PCI_PROBE_ONLY)) { + list_for_each_entry(b, &pci_root_buses, node) + pcibios_reserve_legacy_regions(b); + } + + /* Now, if the platform didn't decide to blindly trust the firmware, + * we proceed to assigning things that were left unassigned + */ + if (!(pci_flags & PCI_PROBE_ONLY)) { + pr_debug("PCI: Assigning unassigned resources...\n"); + pci_assign_unassigned_resources(); + } +} + +#ifdef CONFIG_HOTPLUG + +/* This is used by the PCI hotplug driver to allocate resource + * of newly plugged busses. We can try to consolidate with the + * rest of the code later, for now, keep it as-is as our main + * resource allocation function doesn't deal with sub-trees yet. + */ +void __devinit pcibios_claim_one_bus(struct pci_bus *bus) +{ + struct pci_dev *dev; + struct pci_bus *child_bus; + + list_for_each_entry(dev, &bus->devices, bus_list) { + int i; + + for (i = 0; i < PCI_NUM_RESOURCES; i++) { + struct resource *r = &dev->resource[i]; + + if (r->parent || !r->start || !r->flags) + continue; + + pr_debug("PCI: Claiming %s: " + "Resource %d: %016llx..%016llx [%x]\n", + pci_name(dev), i, + (unsigned long long)r->start, + (unsigned long long)r->end, + (unsigned int)r->flags); + + pci_claim_resource(dev, i); + } + } + + list_for_each_entry(child_bus, &bus->children, node) + pcibios_claim_one_bus(child_bus); +} +EXPORT_SYMBOL_GPL(pcibios_claim_one_bus); + + +/* pcibios_finish_adding_to_bus + * + * This is to be called by the hotplug code after devices have been + * added to a bus, this include calling it for a PHB that is just + * being added + */ +void pcibios_finish_adding_to_bus(struct pci_bus *bus) +{ + pr_debug("PCI: Finishing adding to hotplug bus %04x:%02x\n", + pci_domain_nr(bus), bus->number); + + /* Allocate bus and devices resources */ + pcibios_allocate_bus_resources(bus); + pcibios_claim_one_bus(bus); + + /* Add new devices to global lists. Register in proc, sysfs. */ + pci_bus_add_devices(bus); + + /* Fixup EEH */ + eeh_add_device_tree_late(bus); +} +EXPORT_SYMBOL_GPL(pcibios_finish_adding_to_bus); + +#endif /* CONFIG_HOTPLUG */ + +int pcibios_enable_device(struct pci_dev *dev, int mask) +{ + return pci_enable_resources(dev, mask); +} + +void __devinit pcibios_setup_phb_resources(struct pci_controller *hose) +{ + struct pci_bus *bus = hose->bus; + struct resource *res; + int i; + + /* Hookup PHB IO resource */ + bus->resource[0] = res = &hose->io_resource; + + if (!res->flags) { + printk(KERN_WARNING "PCI: I/O resource not set for host" + " bridge %s (domain %d)\n", + hose->dn->full_name, hose->global_number); + /* Workaround for lack of IO resource only on 32-bit */ + res->start = (unsigned long)hose->io_base_virt - isa_io_base; + res->end = res->start + IO_SPACE_LIMIT; + res->flags = IORESOURCE_IO; + } + + pr_debug("PCI: PHB IO resource = %016llx-%016llx [%lx]\n", + (unsigned long long)res->start, + (unsigned long long)res->end, + (unsigned long)res->flags); + + /* Hookup PHB Memory resources */ + for (i = 0; i < 3; ++i) { + res = &hose->mem_resources[i]; + if (!res->flags) { + if (i > 0) + continue; + printk(KERN_ERR "PCI: Memory resource 0 not set for " + "host bridge %s (domain %d)\n", + hose->dn->full_name, hose->global_number); + + /* Workaround for lack of MEM resource only on 32-bit */ + res->start = hose->pci_mem_offset; + res->end = (resource_size_t)-1LL; + res->flags = IORESOURCE_MEM; + + } + bus->resource[i+1] = res; + + pr_debug("PCI: PHB MEM resource %d = %016llx-%016llx [%lx]\n", + i, (unsigned long long)res->start, + (unsigned long long)res->end, + (unsigned long)res->flags); + } + + pr_debug("PCI: PHB MEM offset = %016llx\n", + (unsigned long long)hose->pci_mem_offset); + pr_debug("PCI: PHB IO offset = %08lx\n", + (unsigned long)hose->io_base_virt - _IO_BASE); +} + +/* + * Null PCI config access functions, for the case when we can't + * find a hose. + */ +#define NULL_PCI_OP(rw, size, type) \ +static int \ +null_##rw##_config_##size(struct pci_dev *dev, int offset, type val) \ +{ \ + return PCIBIOS_DEVICE_NOT_FOUND; \ +} + +static int +null_read_config(struct pci_bus *bus, unsigned int devfn, int offset, + int len, u32 *val) +{ + return PCIBIOS_DEVICE_NOT_FOUND; +} + +static int +null_write_config(struct pci_bus *bus, unsigned int devfn, int offset, + int len, u32 val) +{ + return PCIBIOS_DEVICE_NOT_FOUND; +} + +static struct pci_ops null_pci_ops = { + .read = null_read_config, + .write = null_write_config, +}; + +/* + * These functions are used early on before PCI scanning is done + * and all of the pci_dev and pci_bus structures have been created. + */ +static struct pci_bus * +fake_pci_bus(struct pci_controller *hose, int busnr) +{ + static struct pci_bus bus; + + if (!hose) + printk(KERN_ERR "Can't find hose for PCI bus %d!\n", busnr); + + bus.number = busnr; + bus.sysdata = hose; + bus.ops = hose ? hose->ops : &null_pci_ops; + return &bus; +} + +#define EARLY_PCI_OP(rw, size, type) \ +int early_##rw##_config_##size(struct pci_controller *hose, int bus, \ + int devfn, int offset, type value) \ +{ \ + return pci_bus_##rw##_config_##size(fake_pci_bus(hose, bus), \ + devfn, offset, value); \ +} + +EARLY_PCI_OP(read, byte, u8 *) +EARLY_PCI_OP(read, word, u16 *) +EARLY_PCI_OP(read, dword, u32 *) +EARLY_PCI_OP(write, byte, u8) +EARLY_PCI_OP(write, word, u16) +EARLY_PCI_OP(write, dword, u32) + +int early_find_capability(struct pci_controller *hose, int bus, int devfn, + int cap) +{ + return pci_bus_find_capability(fake_pci_bus(hose, bus), devfn, cap); +} diff --git a/arch/microblaze/pci/pci_32.c b/arch/microblaze/pci/pci_32.c new file mode 100644 index 0000000..7e0c94f --- /dev/null +++ b/arch/microblaze/pci/pci_32.c @@ -0,0 +1,430 @@ +/* + * Common pmac/prep/chrp pci routines. -- Cort + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#undef DEBUG + +unsigned long isa_io_base; +unsigned long pci_dram_offset; +int pcibios_assign_bus_offset = 1; + +static u8 *pci_to_OF_bus_map; + +/* By default, we don't re-assign bus numbers. We do this only on + * some pmacs + */ +static int pci_assign_all_buses; + +static int pci_bus_count; + +/* + * Functions below are used on OpenFirmware machines. + */ +static void +make_one_node_map(struct device_node *node, u8 pci_bus) +{ + const int *bus_range; + int len; + + if (pci_bus >= pci_bus_count) + return; + bus_range = of_get_property(node, "bus-range", &len); + if (bus_range == NULL || len < 2 * sizeof(int)) { + printk(KERN_WARNING "Can't get bus-range for %s, " + "assuming it starts at 0\n", node->full_name); + pci_to_OF_bus_map[pci_bus] = 0; + } else + pci_to_OF_bus_map[pci_bus] = bus_range[0]; + + for_each_child_of_node(node, node) { + struct pci_dev *dev; + const unsigned int *class_code, *reg; + + class_code = of_get_property(node, "class-code", NULL); + if (!class_code || + ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && + (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) + continue; + reg = of_get_property(node, "reg", NULL); + if (!reg) + continue; + dev = pci_get_bus_and_slot(pci_bus, ((reg[0] >> 8) & 0xff)); + if (!dev || !dev->subordinate) { + pci_dev_put(dev); + continue; + } + make_one_node_map(node, dev->subordinate->number); + pci_dev_put(dev); + } +} + +void +pcibios_make_OF_bus_map(void) +{ + int i; + struct pci_controller *hose, *tmp; + struct property *map_prop; + struct device_node *dn; + + pci_to_OF_bus_map = kmalloc(pci_bus_count, GFP_KERNEL); + if (!pci_to_OF_bus_map) { + printk(KERN_ERR "Can't allocate OF bus map !\n"); + return; + } + + /* We fill the bus map with invalid values, that helps + * debugging. + */ + for (i = 0; i < pci_bus_count; i++) + pci_to_OF_bus_map[i] = 0xff; + + /* For each hose, we begin searching bridges */ + list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { + struct device_node *node = hose->dn; + + if (!node) + continue; + make_one_node_map(node, hose->first_busno); + } + dn = of_find_node_by_path("/"); + map_prop = of_find_property(dn, "pci-OF-bus-map", NULL); + if (map_prop) { + BUG_ON(pci_bus_count > map_prop->length); + memcpy(map_prop->value, pci_to_OF_bus_map, pci_bus_count); + } + of_node_put(dn); +#ifdef DEBUG + printk(KERN_INFO "PCI->OF bus map:\n"); + for (i = 0; i < pci_bus_count; i++) { + if (pci_to_OF_bus_map[i] == 0xff) + continue; + printk(KERN_INFO "%d -> %d\n", i, pci_to_OF_bus_map[i]); + } +#endif +} + +typedef int (*pci_OF_scan_iterator)(struct device_node *node, void *data); + +static struct device_node *scan_OF_pci_childs(struct device_node *parent, + pci_OF_scan_iterator filter, void *data) +{ + struct device_node *node; + struct device_node *sub_node; + + for_each_child_of_node(parent, node) { + const unsigned int *class_code; + + if (filter(node, data)) { + of_node_put(node); + return node; + } + + /* For PCI<->PCI bridges or CardBus bridges, we go down + * Note: some OFs create a parent node "multifunc-device" as + * a fake root for all functions of a multi-function device, + * we go down them as well. + */ + class_code = of_get_property(node, "class-code", NULL); + if ((!class_code || + ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && + (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) && + strcmp(node->name, "multifunc-device")) + continue; + sub_node = scan_OF_pci_childs(node, filter, data); + if (sub_node) { + of_node_put(node); + return sub_node; + } + } + return NULL; +} + +static struct device_node *scan_OF_for_pci_dev(struct device_node *parent, + unsigned int devfn) +{ + struct device_node *np, *cnp; + const u32 *reg; + unsigned int psize; + + for_each_child_of_node(parent, np) { + reg = of_get_property(np, "reg", &psize); + if (reg && psize >= 4 && ((reg[0] >> 8) & 0xff) == devfn) + return np; + + /* Note: some OFs create a parent node "multifunc-device" as + * a fake root for all functions of a multi-function device, + * we go down them as well. */ + if (!strcmp(np->name, "multifunc-device")) { + cnp = scan_OF_for_pci_dev(np, devfn); + if (cnp) + return cnp; + } + } + return NULL; +} + + +static struct device_node *scan_OF_for_pci_bus(struct pci_bus *bus) +{ + struct device_node *parent, *np; + + /* Are we a root bus ? */ + if (bus->self == NULL || bus->parent == NULL) { + struct pci_controller *hose = pci_bus_to_host(bus); + if (hose == NULL) + return NULL; + return of_node_get(hose->dn); + } + + /* not a root bus, we need to get our parent */ + parent = scan_OF_for_pci_bus(bus->parent); + if (parent == NULL) + return NULL; + + /* now iterate for children for a match */ + np = scan_OF_for_pci_dev(parent, bus->self->devfn); + of_node_put(parent); + + return np; +} + +/* + * Scans the OF tree for a device node matching a PCI device + */ +struct device_node * +pci_busdev_to_OF_node(struct pci_bus *bus, int devfn) +{ + struct device_node *parent, *np; + + pr_debug("pci_busdev_to_OF_node(%d,0x%x)\n", bus->number, devfn); + parent = scan_OF_for_pci_bus(bus); + if (parent == NULL) + return NULL; + pr_debug(" parent is %s\n", parent ? parent->full_name : ""); + np = scan_OF_for_pci_dev(parent, devfn); + of_node_put(parent); + pr_debug(" result is %s\n", np ? np->full_name : ""); + + /* XXX most callers don't release the returned node + * mostly because ppc64 doesn't increase the refcount, + * we need to fix that. + */ + return np; +} +EXPORT_SYMBOL(pci_busdev_to_OF_node); + +struct device_node* +pci_device_to_OF_node(struct pci_dev *dev) +{ + return pci_busdev_to_OF_node(dev->bus, dev->devfn); +} +EXPORT_SYMBOL(pci_device_to_OF_node); + +static int +find_OF_pci_device_filter(struct device_node *node, void *data) +{ + return ((void *)node == data); +} + +/* + * Returns the PCI device matching a given OF node + */ +int +pci_device_from_OF_node(struct device_node *node, u8 *bus, u8 *devfn) +{ + const unsigned int *reg; + struct pci_controller *hose; + struct pci_dev *dev = NULL; + + /* Make sure it's really a PCI device */ + hose = pci_find_hose_for_OF_device(node); + if (!hose || !hose->dn) + return -ENODEV; + if (!scan_OF_pci_childs(hose->dn, + find_OF_pci_device_filter, (void *)node)) + return -ENODEV; + reg = of_get_property(node, "reg", NULL); + if (!reg) + return -ENODEV; + *bus = (reg[0] >> 16) & 0xff; + *devfn = ((reg[0] >> 8) & 0xff); + + /* Ok, here we need some tweak. If we have already renumbered + * all busses, we can't rely on the OF bus number any more. + * the pci_to_OF_bus_map is not enough as several PCI busses + * may match the same OF bus number. + */ + if (!pci_to_OF_bus_map) + return 0; + + for_each_pci_dev(dev) + if (pci_to_OF_bus_map[dev->bus->number] == *bus && + dev->devfn == *devfn) { + *bus = dev->bus->number; + pci_dev_put(dev); + return 0; + } + + return -ENODEV; +} +EXPORT_SYMBOL(pci_device_from_OF_node); + +/* We create the "pci-OF-bus-map" property now so it appears in the + * /proc device tree + */ +void __init +pci_create_OF_bus_map(void) +{ + struct property *of_prop; + struct device_node *dn; + + of_prop = (struct property *) alloc_bootmem(sizeof(struct property) + \ + 256); + if (!of_prop) + return; + dn = of_find_node_by_path("/"); + if (dn) { + memset(of_prop, -1, sizeof(struct property) + 256); + of_prop->name = "pci-OF-bus-map"; + of_prop->length = 256; + of_prop->value = &of_prop[1]; + prom_add_property(dn, of_prop); + of_node_put(dn); + } +} + +static void __devinit pcibios_scan_phb(struct pci_controller *hose) +{ + struct pci_bus *bus; + struct device_node *node = hose->dn; + unsigned long io_offset; + struct resource *res = &hose->io_resource; + + pr_debug("PCI: Scanning PHB %s\n", + node ? node->full_name : ""); + + /* Create an empty bus for the toplevel */ + bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, hose); + if (bus == NULL) { + printk(KERN_ERR "Failed to create bus for PCI domain %04x\n", + hose->global_number); + return; + } + bus->secondary = hose->first_busno; + hose->bus = bus; + + /* Fixup IO space offset */ + io_offset = (unsigned long)hose->io_base_virt - isa_io_base; + res->start = (res->start + io_offset) & 0xffffffffu; + res->end = (res->end + io_offset) & 0xffffffffu; + + /* Wire up PHB bus resources */ + pcibios_setup_phb_resources(hose); + + /* Scan children */ + hose->last_busno = bus->subordinate = pci_scan_child_bus(bus); +} + +static int __init pcibios_init(void) +{ + struct pci_controller *hose, *tmp; + int next_busno = 0; + + printk(KERN_INFO "PCI: Probing PCI hardware\n"); + + if (pci_flags & PCI_REASSIGN_ALL_BUS) { + printk(KERN_INFO "setting pci_asign_all_busses\n"); + pci_assign_all_buses = 1; + } + + /* Scan all of the recorded PCI controllers. */ + list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { + if (pci_assign_all_buses) + hose->first_busno = next_busno; + hose->last_busno = 0xff; + pcibios_scan_phb(hose); + printk(KERN_INFO "calling pci_bus_add_devices()\n"); + pci_bus_add_devices(hose->bus); + if (pci_assign_all_buses || next_busno <= hose->last_busno) + next_busno = hose->last_busno + \ + pcibios_assign_bus_offset; + } + pci_bus_count = next_busno; + + /* OpenFirmware based machines need a map of OF bus + * numbers vs. kernel bus numbers since we may have to + * remap them. + */ + if (pci_assign_all_buses) + pcibios_make_OF_bus_map(); + + /* Call common code to handle resource allocation */ + pcibios_resource_survey(); + + return 0; +} + +subsys_initcall(pcibios_init); + +static struct pci_controller* +pci_bus_to_hose(int bus) +{ + struct pci_controller *hose, *tmp; + + list_for_each_entry_safe(hose, tmp, &hose_list, list_node) + if (bus >= hose->first_busno && bus <= hose->last_busno) + return hose; + return NULL; +} + +/* Provide information on locations of various I/O regions in physical + * memory. Do this on a per-card basis so that we choose the right + * root bridge. + * Note that the returned IO or memory base is a physical address + */ + +long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn) +{ + struct pci_controller *hose; + long result = -EOPNOTSUPP; + + hose = pci_bus_to_hose(bus); + if (!hose) + return -ENODEV; + + switch (which) { + case IOBASE_BRIDGE_NUMBER: + return (long)hose->first_busno; + case IOBASE_MEMORY: + return (long)hose->pci_mem_offset; + case IOBASE_IO: + return (long)hose->io_base_phys; + case IOBASE_ISA_IO: + return (long)isa_io_base; + case IOBASE_ISA_MEM: + return (long)isa_mem_base; + } + + return result; +} -- cgit v0.10.2 From a6475c132278c1be158a13872c233aeab8a00176 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 18 Jan 2010 15:27:10 +0100 Subject: microblaze: Enable PCI, missing files There are two parts of changes. The first is just enable PCI in Makefiles and in Kconfig. The second is the rest of missing files. I didn't want to add it with previous patch because that patch is too big. Current Microblaze toolchain has problem with weak symbols that's why is necessary to apply this changes to be possible to compile pci support. Xilinx knows about this problem. Signed-off-by: Michal Simek diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index 71ec041..e1fa084 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -256,6 +256,21 @@ source "fs/Kconfig.binfmt" endmenu +menu "Bus Options" + +config PCI + bool "PCI support" + +config PCI_DOMAINS + def_bool PCI + +config PCI_SYSCALL + def_bool PCI + +source "drivers/pci/Kconfig" + +endmenu + source "net/Kconfig" source "drivers/Kconfig" diff --git a/arch/microblaze/Makefile b/arch/microblaze/Makefile index d2d6cfc..836832d 100644 --- a/arch/microblaze/Makefile +++ b/arch/microblaze/Makefile @@ -50,6 +50,7 @@ libs-y += $(LIBGCC) core-y += arch/microblaze/kernel/ core-y += arch/microblaze/mm/ core-y += arch/microblaze/platform/ +core-$(CONFIG_PCI) += arch/microblaze/pci/ drivers-$(CONFIG_OPROFILE) += arch/microblaze/oprofile/ diff --git a/arch/microblaze/include/asm/io.h b/arch/microblaze/include/asm/io.h index f82df5d..06d804b 100644 --- a/arch/microblaze/include/asm/io.h +++ b/arch/microblaze/include/asm/io.h @@ -17,7 +17,21 @@ #include /* Get struct page {...} */ #include -#define PCI_DRAM_OFFSET 0 +#ifndef CONFIG_PCI +#define _IO_BASE 0 +#define _ISA_MEM_BASE 0 +#define PCI_DRAM_OFFSET 0 +#else +#define _IO_BASE isa_io_base +#define _ISA_MEM_BASE isa_mem_base +#define PCI_DRAM_OFFSET pci_dram_offset +#endif + +extern unsigned long isa_io_base; +extern unsigned long pci_io_base; +extern unsigned long pci_dram_offset; + +extern resource_size_t isa_mem_base; #define IO_SPACE_LIMIT (0xFFFFFFFF) diff --git a/arch/microblaze/include/asm/pgtable.h b/arch/microblaze/include/asm/pgtable.h index cc3a4df..1c47f6f 100644 --- a/arch/microblaze/include/asm/pgtable.h +++ b/arch/microblaze/include/asm/pgtable.h @@ -90,6 +90,21 @@ static inline pte_t pte_mkspecial(pte_t pte) { return pte; } #endif /* __ASSEMBLY__ */ /* + * Macro to mark a page protection value as "uncacheable". + */ + +#define _PAGE_CACHE_CTL (_PAGE_GUARDED | _PAGE_NO_CACHE | \ + _PAGE_WRITETHRU) + +#define pgprot_noncached(prot) \ + (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \ + _PAGE_NO_CACHE | _PAGE_GUARDED)) + +#define pgprot_noncached_wc(prot) \ + (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \ + _PAGE_NO_CACHE)) + +/* * The MicroBlaze MMU is identical to the PPC-40x MMU, and uses a hash * table containing PTEs, together with a set of 16 segment registers, to * define the virtual to physical address mapping. diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h index 03f45a9..e7d67a3 100644 --- a/arch/microblaze/include/asm/prom.h +++ b/arch/microblaze/include/asm/prom.h @@ -31,6 +31,21 @@ /* Other Prototypes */ extern int early_uartlite_console(void); +#ifdef CONFIG_PCI +/* + * PCI <-> OF matching functions + * (XXX should these be here?) + */ +struct pci_bus; +struct pci_dev; +extern int pci_device_from_OF_node(struct device_node *node, + u8 *bus, u8 *devfn); +extern struct device_node *pci_busdev_to_OF_node(struct pci_bus *bus, + int devfn); +extern struct device_node *pci_device_to_OF_node(struct pci_dev *dev); +extern void pci_create_OF_bus_map(void); +#endif + /* * OF address retreival & translation */ diff --git a/arch/microblaze/pci/Makefile b/arch/microblaze/pci/Makefile new file mode 100644 index 0000000..2b89018 --- /dev/null +++ b/arch/microblaze/pci/Makefile @@ -0,0 +1,5 @@ +# +# Makefile +# + +obj-$(CONFIG_PCI) += pci_32.o pci-common.o indirect_pci.o iomap.o diff --git a/arch/microblaze/pci/indirect_pci.c b/arch/microblaze/pci/indirect_pci.c new file mode 100644 index 0000000..25f18f0 --- /dev/null +++ b/arch/microblaze/pci/indirect_pci.c @@ -0,0 +1,163 @@ +/* + * Support for indirect PCI bridges. + * + * Copyright (C) 1998 Gabriel Paubert. + * + * 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. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +static int +indirect_read_config(struct pci_bus *bus, unsigned int devfn, int offset, + int len, u32 *val) +{ + struct pci_controller *hose = pci_bus_to_host(bus); + volatile void __iomem *cfg_data; + u8 cfg_type = 0; + u32 bus_no, reg; + + if (hose->indirect_type & INDIRECT_TYPE_NO_PCIE_LINK) { + if (bus->number != hose->first_busno) + return PCIBIOS_DEVICE_NOT_FOUND; + if (devfn != 0) + return PCIBIOS_DEVICE_NOT_FOUND; + } + + if (hose->indirect_type & INDIRECT_TYPE_SET_CFG_TYPE) + if (bus->number != hose->first_busno) + cfg_type = 1; + + bus_no = (bus->number == hose->first_busno) ? + hose->self_busno : bus->number; + + if (hose->indirect_type & INDIRECT_TYPE_EXT_REG) + reg = ((offset & 0xf00) << 16) | (offset & 0xfc); + else + reg = offset & 0xfc; /* Only 3 bits for function */ + + if (hose->indirect_type & INDIRECT_TYPE_BIG_ENDIAN) + out_be32(hose->cfg_addr, (0x80000000 | (bus_no << 16) | + (devfn << 8) | reg | cfg_type)); + else + out_le32(hose->cfg_addr, (0x80000000 | (bus_no << 16) | + (devfn << 8) | reg | cfg_type)); + + /* + * Note: the caller has already checked that offset is + * suitably aligned and that len is 1, 2 or 4. + */ + cfg_data = hose->cfg_data + (offset & 3); /* Only 3 bits for function */ + switch (len) { + case 1: + *val = in_8(cfg_data); + break; + case 2: + *val = in_le16(cfg_data); + break; + default: + *val = in_le32(cfg_data); + break; + } + return PCIBIOS_SUCCESSFUL; +} + +static int +indirect_write_config(struct pci_bus *bus, unsigned int devfn, int offset, + int len, u32 val) +{ + struct pci_controller *hose = pci_bus_to_host(bus); + volatile void __iomem *cfg_data; + u8 cfg_type = 0; + u32 bus_no, reg; + + if (hose->indirect_type & INDIRECT_TYPE_NO_PCIE_LINK) { + if (bus->number != hose->first_busno) + return PCIBIOS_DEVICE_NOT_FOUND; + if (devfn != 0) + return PCIBIOS_DEVICE_NOT_FOUND; + } + + if (hose->indirect_type & INDIRECT_TYPE_SET_CFG_TYPE) + if (bus->number != hose->first_busno) + cfg_type = 1; + + bus_no = (bus->number == hose->first_busno) ? + hose->self_busno : bus->number; + + if (hose->indirect_type & INDIRECT_TYPE_EXT_REG) + reg = ((offset & 0xf00) << 16) | (offset & 0xfc); + else + reg = offset & 0xfc; + + if (hose->indirect_type & INDIRECT_TYPE_BIG_ENDIAN) + out_be32(hose->cfg_addr, (0x80000000 | (bus_no << 16) | + (devfn << 8) | reg | cfg_type)); + else + out_le32(hose->cfg_addr, (0x80000000 | (bus_no << 16) | + (devfn << 8) | reg | cfg_type)); + + /* surpress setting of PCI_PRIMARY_BUS */ + if (hose->indirect_type & INDIRECT_TYPE_SURPRESS_PRIMARY_BUS) + if ((offset == PCI_PRIMARY_BUS) && + (bus->number == hose->first_busno)) + val &= 0xffffff00; + + /* Workaround for PCI_28 Errata in 440EPx/GRx */ + if ((hose->indirect_type & INDIRECT_TYPE_BROKEN_MRM) && + offset == PCI_CACHE_LINE_SIZE) { + val = 0; + } + + /* + * Note: the caller has already checked that offset is + * suitably aligned and that len is 1, 2 or 4. + */ + cfg_data = hose->cfg_data + (offset & 3); + switch (len) { + case 1: + out_8(cfg_data, val); + break; + case 2: + out_le16(cfg_data, val); + break; + default: + out_le32(cfg_data, val); + break; + } + + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops indirect_pci_ops = { + .read = indirect_read_config, + .write = indirect_write_config, +}; + +void __init +setup_indirect_pci(struct pci_controller *hose, + resource_size_t cfg_addr, + resource_size_t cfg_data, u32 flags) +{ + resource_size_t base = cfg_addr & PAGE_MASK; + void __iomem *mbase; + + mbase = ioremap(base, PAGE_SIZE); + hose->cfg_addr = mbase + (cfg_addr & ~PAGE_MASK); + if ((cfg_data & PAGE_MASK) != base) + mbase = ioremap(cfg_data & PAGE_MASK, PAGE_SIZE); + hose->cfg_data = mbase + (cfg_data & ~PAGE_MASK); + hose->ops = &indirect_pci_ops; + hose->indirect_type = flags; +} diff --git a/arch/microblaze/pci/iomap.c b/arch/microblaze/pci/iomap.c new file mode 100644 index 0000000..3fbf16f --- /dev/null +++ b/arch/microblaze/pci/iomap.c @@ -0,0 +1,39 @@ +/* + * ppc64 "iomap" interface implementation. + * + * (C) Copyright 2004 Linus Torvalds + */ +#include +#include +#include +#include +#include + +void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max) +{ + resource_size_t start = pci_resource_start(dev, bar); + resource_size_t len = pci_resource_len(dev, bar); + unsigned long flags = pci_resource_flags(dev, bar); + + if (!len) + return NULL; + if (max && len > max) + len = max; + if (flags & IORESOURCE_IO) + return ioport_map(start, len); + if (flags & IORESOURCE_MEM) + return ioremap(start, len); + /* What? */ + return NULL; +} +EXPORT_SYMBOL(pci_iomap); + +void pci_iounmap(struct pci_dev *dev, void __iomem *addr) +{ + if (isa_vaddr_is_ioport(addr)) + return; + if (pcibios_vaddr_is_ioport(addr)) + return; + iounmap(addr); +} +EXPORT_SYMBOL(pci_iounmap); diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 3d102dd..0b51857 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -48,6 +48,7 @@ obj-$(CONFIG_PPC) += setup-bus.o obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o obj-$(CONFIG_X86_VISWS) += setup-irq.o obj-$(CONFIG_MN10300) += setup-bus.o +obj-$(CONFIG_MICROBLAZE) += setup-bus.o # # ACPI Related PCI FW Functions -- cgit v0.10.2 From 733cc2183116b216abb52e709709bb0e626c9a75 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 18 Jan 2010 15:27:11 +0100 Subject: microblaze: Add support for Xilinx PCI host bridge This patch is based on powerpc patch 64f16502475ddf663169369fffff6da9b10ea9fb We did some cleanups and removed powerpc parts. There is one new debug early listing function too. Exclude function is only in Debug options. We tested in on custom board. Signed-off-by: Michal Simek diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index e1fa084..c1e731b 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -267,6 +267,10 @@ config PCI_DOMAINS config PCI_SYSCALL def_bool PCI +config PCI_XILINX + bool "Xilinx PCI host bridge support" + depends on PCI + source "drivers/pci/Kconfig" endmenu diff --git a/arch/microblaze/include/asm/pci.h b/arch/microblaze/include/asm/pci.h index fecc044..bdd65aa 100644 --- a/arch/microblaze/include/asm/pci.h +++ b/arch/microblaze/include/asm/pci.h @@ -166,5 +166,12 @@ extern void pci_resource_to_user(const struct pci_dev *dev, int bar, extern void pcibios_setup_bus_devices(struct pci_bus *bus); extern void pcibios_setup_bus_self(struct pci_bus *bus); +/* This part of code was originaly in xilinx-pci.h */ +#ifdef CONFIG_PCI_XILINX +extern void __init xilinx_pci_init(void); +#else +static inline void __init xilinx_pci_init(void) { return; } +#endif + #endif /* __KERNEL__ */ #endif /* __ASM_MICROBLAZE_PCI_H */ diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c index bc325ac..cd68e98 100644 --- a/arch/microblaze/kernel/setup.c +++ b/arch/microblaze/kernel/setup.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -64,6 +65,8 @@ void __init setup_arch(char **cmdline_p) setup_memory(); + xilinx_pci_init(); + #if defined(CONFIG_SELFMOD_INTC) || defined(CONFIG_SELFMOD_TIMER) printk(KERN_NOTICE "Self modified code enable\n"); #endif diff --git a/arch/microblaze/pci/Makefile b/arch/microblaze/pci/Makefile index 2b89018..9889cc2 100644 --- a/arch/microblaze/pci/Makefile +++ b/arch/microblaze/pci/Makefile @@ -3,3 +3,4 @@ # obj-$(CONFIG_PCI) += pci_32.o pci-common.o indirect_pci.o iomap.o +obj-$(CONFIG_PCI_XILINX) += xilinx_pci.o diff --git a/arch/microblaze/pci/xilinx_pci.c b/arch/microblaze/pci/xilinx_pci.c new file mode 100644 index 0000000..7869a41 --- /dev/null +++ b/arch/microblaze/pci/xilinx_pci.c @@ -0,0 +1,168 @@ +/* + * PCI support for Xilinx plbv46_pci soft-core which can be used on + * Xilinx Virtex ML410 / ML510 boards. + * + * Copyright 2009 Roderick Colenbrander + * Copyright 2009 Secret Lab Technologies Ltd. + * + * The pci bridge fixup code was copied from ppc4xx_pci.c and was written + * by Benjamin Herrenschmidt. + * Copyright 2007 Ben. Herrenschmidt , IBM Corp. + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#include +#include +#include +#include + +#define XPLB_PCI_ADDR 0x10c +#define XPLB_PCI_DATA 0x110 +#define XPLB_PCI_BUS 0x114 + +#define PCI_HOST_ENABLE_CMD (PCI_COMMAND_SERR | PCI_COMMAND_PARITY | \ + PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY) + +static struct of_device_id xilinx_pci_match[] = { + { .compatible = "xlnx,plbv46-pci-1.03.a", }, + {} +}; + +/** + * xilinx_pci_fixup_bridge - Block Xilinx PHB configuration. + */ +static void xilinx_pci_fixup_bridge(struct pci_dev *dev) +{ + struct pci_controller *hose; + int i; + + if (dev->devfn || dev->bus->self) + return; + + hose = pci_bus_to_host(dev->bus); + if (!hose) + return; + + if (!of_match_node(xilinx_pci_match, hose->dn)) + return; + + /* Hide the PCI host BARs from the kernel as their content doesn't + * fit well in the resource management + */ + for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { + dev->resource[i].start = 0; + dev->resource[i].end = 0; + dev->resource[i].flags = 0; + } + + dev_info(&dev->dev, "Hiding Xilinx plb-pci host bridge resources %s\n", + pci_name(dev)); +} +DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, xilinx_pci_fixup_bridge); + +#ifdef DEBUG +/** + * xilinx_pci_exclude_device - Don't do config access for non-root bus + * + * This is a hack. Config access to any bus other than bus 0 does not + * currently work on the ML510 so we prevent it here. + */ +static int +xilinx_pci_exclude_device(struct pci_controller *hose, u_char bus, u8 devfn) +{ + return (bus != 0); +} + +/** + * xilinx_early_pci_scan - List pci config space for available devices + * + * List pci devices in very early phase. + */ +void __init xilinx_early_pci_scan(struct pci_controller *hose) +{ + u32 bus = 0; + u32 val, dev, func, offset; + + /* Currently we have only 2 device connected - up-to 32 devices */ + for (dev = 0; dev < 2; dev++) { + /* List only first function number - up-to 8 functions */ + for (func = 0; func < 1; func++) { + printk(KERN_INFO "%02x:%02x:%02x", bus, dev, func); + /* read the first 64 standardized bytes */ + /* Up-to 192 bytes can be list of capabilities */ + for (offset = 0; offset < 64; offset += 4) { + early_read_config_dword(hose, bus, + PCI_DEVFN(dev, func), offset, &val); + if (offset == 0 && val == 0xFFFFFFFF) { + printk(KERN_CONT "\nABSENT"); + break; + } + if (!(offset % 0x10)) + printk(KERN_CONT "\n%04x: ", offset); + + printk(KERN_CONT "%08x ", val); + } + printk(KERN_INFO "\n"); + } + } +} +#else +void __init xilinx_early_pci_scan(struct pci_controller *hose) +{ +} +#endif + +/** + * xilinx_pci_init - Find and register a Xilinx PCI host bridge + */ +void __init xilinx_pci_init(void) +{ + struct pci_controller *hose; + struct resource r; + void __iomem *pci_reg; + struct device_node *pci_node; + + pci_node = of_find_matching_node(NULL, xilinx_pci_match); + if (!pci_node) + return; + + if (of_address_to_resource(pci_node, 0, &r)) { + pr_err("xilinx-pci: cannot resolve base address\n"); + return; + } + + hose = pcibios_alloc_controller(pci_node); + if (!hose) { + pr_err("xilinx-pci: pcibios_alloc_controller() failed\n"); + return; + } + + /* Setup config space */ + setup_indirect_pci(hose, r.start + XPLB_PCI_ADDR, + r.start + XPLB_PCI_DATA, + INDIRECT_TYPE_SET_CFG_TYPE); + + /* According to the xilinx plbv46_pci documentation the soft-core starts + * a self-init when the bus master enable bit is set. Without this bit + * set the pci bus can't be scanned. + */ + early_write_config_word(hose, 0, 0, PCI_COMMAND, PCI_HOST_ENABLE_CMD); + + /* Set the max latency timer to 255 */ + early_write_config_byte(hose, 0, 0, PCI_LATENCY_TIMER, 0xff); + + /* Set the max bus number to 255, and bus/subbus no's to 0 */ + pci_reg = of_iomap(pci_node, 0); + out_be32(pci_reg + XPLB_PCI_BUS, 0x000000ff); + iounmap(pci_reg); + + /* Register the host bridge with the linux kernel! */ + pci_process_bridge_OF_ranges(hose, pci_node, + INDIRECT_TYPE_SET_CFG_TYPE); + + pr_info("xilinx-pci: Registered PCI host bridge\n"); + xilinx_early_pci_scan(hose); +} -- cgit v0.10.2 From 83ff56f46a8532488ee364bb93a9cb2a59490d33 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Tue, 9 Mar 2010 10:22:19 -0500 Subject: kprobes: Calculate the index correctly when freeing the out-of-line execution slot From : Ananth N Mavinakayanahalli When freeing the instruction slot, the arithmetic to calculate the index of the slot in the page needs to account for the total size of the instruction on the various architectures. Calculate the index correctly when freeing the out-of-line execution slot. Reported-by: Sachin Sant Reported-by: Heiko Carstens Signed-off-by: Ananth N Mavinakayanahalli Signed-off-by: Masami Hiramatsu LKML-Reference: <4B9667AB.9050507@redhat.com> Signed-off-by: Ingo Molnar diff --git a/kernel/kprobes.c b/kernel/kprobes.c index fa034d2..0ed46f3 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c @@ -259,7 +259,8 @@ static void __kprobes __free_insn_slot(struct kprobe_insn_cache *c, struct kprobe_insn_page *kip; list_for_each_entry(kip, &c->pages, list) { - long idx = ((long)slot - (long)kip->insns) / c->insn_size; + long idx = ((long)slot - (long)kip->insns) / + (c->insn_size * sizeof(kprobe_opcode_t)); if (idx >= 0 && idx < slots_per_page(c)) { WARN_ON(kip->slot_used[idx] != SLOT_USED); if (dirty) { -- cgit v0.10.2 From 777537905744c28b02c283692e7f75f5445c1afa Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 12 Jan 2010 09:55:10 +0100 Subject: microblaze: Add support from PREEMPT This patch add core PREEMPT support for Microblaze. I tried to trace it via tracers and I was able to see any output. I also added low level debug functions to see if that code is called. Signed-off-by: Michal Simek diff --git a/arch/microblaze/include/asm/tlbflush.h b/arch/microblaze/include/asm/tlbflush.h index 10ec70c..bcb8b41 100644 --- a/arch/microblaze/include/asm/tlbflush.h +++ b/arch/microblaze/include/asm/tlbflush.h @@ -23,7 +23,7 @@ extern void _tlbie(unsigned long address); extern void _tlbia(void); -#define __tlbia() _tlbia() +#define __tlbia() { preempt_disable(); _tlbia(); preempt_enable(); } static inline void local_flush_tlb_all(void) { __tlbia(); } diff --git a/arch/microblaze/kernel/asm-offsets.c b/arch/microblaze/kernel/asm-offsets.c index 7bc7b68..0071260 100644 --- a/arch/microblaze/kernel/asm-offsets.c +++ b/arch/microblaze/kernel/asm-offsets.c @@ -90,6 +90,7 @@ int main(int argc, char *argv[]) DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); DEFINE(TI_ADDR_LIMIT, offsetof(struct thread_info, addr_limit)); DEFINE(TI_CPU_CONTEXT, offsetof(struct thread_info, cpu_context)); + DEFINE(TI_PREEMPT_COUNT, offsetof(struct thread_info, preempt_count)); BLANK(); /* struct cpu_context */ diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S index 3bad4ff..1a6729d 100644 --- a/arch/microblaze/kernel/entry.S +++ b/arch/microblaze/kernel/entry.S @@ -853,7 +853,30 @@ no_intr_resched: lwi r1, r1, PT_R1 - PT_SIZE; bri 6f; /* MS: Return to kernel state. */ -2: VM_OFF /* MS: turn off MMU */ +2: +#ifdef CONFIG_PREEMPT + add r11, r0, CURRENT_TASK; + lwi r11, r11, TS_THREAD_INFO; + /* MS: get preempt_count from thread info */ + lwi r5, r11, TI_PREEMPT_COUNT; + bgti r5, restore; + + lwi r5, r11, TI_FLAGS; /* get flags in thread info */ + andi r5, r5, _TIF_NEED_RESCHED; + beqi r5, restore /* if zero jump over */ + +preempt: + /* interrupts are off that's why I am calling preempt_chedule_irq */ + bralid r15, preempt_schedule_irq + nop + add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */ + lwi r11, r11, TS_THREAD_INFO; /* get thread info */ + lwi r5, r11, TI_FLAGS; /* get flags in thread info */ + andi r5, r5, _TIF_NEED_RESCHED; + bnei r5, preempt /* if non zero jump to resched */ +restore: +#endif + VM_OFF /* MS: turn off MMU */ tophys(r1,r1) lwi r3, r1, PTO + PT_R3; /* MS: restore saved r3, r4 registers */ lwi r4, r1, PTO + PT_R4; -- cgit v0.10.2 From 407c1da07d5afa001ed0fdb8f379c00bbd09990a Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 12 Jan 2010 14:51:04 +0100 Subject: microblaze: Move cache function to cache.c It is better to have init cache handling on one place. Signed-off-by: Michal Simek diff --git a/arch/microblaze/kernel/cpu/cache.c b/arch/microblaze/kernel/cpu/cache.c index 2a56bcc..5425f89 100644 --- a/arch/microblaze/kernel/cpu/cache.c +++ b/arch/microblaze/kernel/cpu/cache.c @@ -532,4 +532,9 @@ void microblaze_cache_init(void) } } } + invalidate_dcache(); + enable_dcache(); + + invalidate_icache(); + enable_icache(); } diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c index cd68e98..f974ec7 100644 --- a/arch/microblaze/kernel/setup.c +++ b/arch/microblaze/kernel/setup.c @@ -57,12 +57,6 @@ void __init setup_arch(char **cmdline_p) microblaze_cache_init(); - invalidate_dcache(); - enable_dcache(); - - invalidate_icache(); - enable_icache(); - setup_memory(); xilinx_pci_init(); -- cgit v0.10.2 From 7ae5f21361fea11f58c398701da635f778635d13 Mon Sep 17 00:00:00 2001 From: John Kacur Date: Thu, 11 Mar 2010 13:57:00 +0100 Subject: perf: Make the install relative to DESTDIR if specified Without this change, the install path is relative to prefix/DESTDIR where prefix is automatically set to $HOME. This can produce unexpected results. For example: make -C tools/perf DESTDIR=/home/jkacur/tmp install-man creates the directory: /home/jkacur/home/jkacur/tmp/share/... instead of the expected: /home/jkacur/tmp/share/... Signed-off-by: John Kacur Cc: Peter Zijlstra Cc: Paul Mackerras Cc: Arnaldo Carvalho de Melo Cc: Frederic Weisbecker Cc: Tom Zanussi Cc: Kyle McMartin Cc: LKML-Reference: <1268312220-12880-1-git-send-email-jkacur@redhat.com> Signed-off-by: Ingo Molnar diff --git a/tools/perf/Documentation/Makefile b/tools/perf/Documentation/Makefile index bdd3b7e..bd498d4 100644 --- a/tools/perf/Documentation/Makefile +++ b/tools/perf/Documentation/Makefile @@ -24,7 +24,10 @@ DOC_MAN1=$(patsubst %.txt,%.1,$(MAN1_TXT)) DOC_MAN5=$(patsubst %.txt,%.5,$(MAN5_TXT)) DOC_MAN7=$(patsubst %.txt,%.7,$(MAN7_TXT)) +# Make the path relative to DESTDIR, not prefix +ifndef DESTDIR prefix?=$(HOME) +endif bindir?=$(prefix)/bin htmldir?=$(prefix)/share/doc/perf-doc pdfdir?=$(prefix)/share/doc/perf-doc @@ -32,7 +35,6 @@ mandir?=$(prefix)/share/man man1dir=$(mandir)/man1 man5dir=$(mandir)/man5 man7dir=$(mandir)/man7 -# DESTDIR= ASCIIDOC=asciidoc ASCIIDOC_EXTRA = --unsafe diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 5840499..8a8f52d 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -216,7 +216,10 @@ STRIP ?= strip # runtime figures out where they are based on the path to the executable. # This can help installing the suite in a relocatable way. +# Make the path relative to DESTDIR, not to prefix +ifndef DESTDIR prefix = $(HOME) +endif bindir_relative = bin bindir = $(prefix)/$(bindir_relative) mandir = share/man @@ -233,7 +236,6 @@ sysconfdir = $(prefix)/etc ETC_PERFCONFIG = etc/perfconfig endif lib = lib -# DESTDIR= export prefix bindir sharedir sysconfdir -- cgit v0.10.2 From d79f3b06a9e40b382bd5d5ae8dea9b3210eda9ce Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 8 Feb 2010 12:13:10 +0100 Subject: microblaze: Preliminary support for dma drivers I found several problems for ll_temac driver and on system with WB. This early fix should fix it. I will clean this patch before I will add it to mainline Signed-off-by: Michal Simek diff --git a/arch/microblaze/include/asm/io.h b/arch/microblaze/include/asm/io.h index 06d804b..32d621a 100644 --- a/arch/microblaze/include/asm/io.h +++ b/arch/microblaze/include/asm/io.h @@ -140,9 +140,6 @@ static inline void writel(unsigned int v, volatile void __iomem *addr) #define virt_to_phys(addr) ((unsigned long)__virt_to_phys(addr)) #define virt_to_bus(addr) ((unsigned long)__virt_to_phys(addr)) -#define __page_address(page) \ - (PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT)) -#define page_to_phys(page) virt_to_phys((void *)__page_address(page)) #define page_to_bus(page) (page_to_phys(page)) #define bus_to_virt(addr) (phys_to_virt(addr)) diff --git a/arch/microblaze/include/asm/page.h b/arch/microblaze/include/asm/page.h index 9b66c0f..2dd1d04 100644 --- a/arch/microblaze/include/asm/page.h +++ b/arch/microblaze/include/asm/page.h @@ -62,12 +62,6 @@ extern unsigned int __page_offset; #define PAGE_OFFSET CONFIG_KERNEL_START /* - * MAP_NR -- given an address, calculate the index of the page struct which - * points to the address's page. - */ -#define MAP_NR(addr) (((unsigned long)(addr) - PAGE_OFFSET) >> PAGE_SHIFT) - -/* * The basic type of a PTE - 32 bit physical addressing. */ typedef unsigned long pte_basic_t; @@ -154,7 +148,11 @@ extern int page_is_ram(unsigned long pfn); # define pfn_to_virt(pfn) __va(pfn_to_phys((pfn))) # ifdef CONFIG_MMU -# define virt_to_page(kaddr) (mem_map + MAP_NR(kaddr)) + +# define virt_to_page(kaddr) (pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)) +# define page_to_virt(page) __va(page_to_pfn(page) << PAGE_SHIFT) +# define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) + # else /* CONFIG_MMU */ # define virt_to_page(vaddr) (pfn_to_page(virt_to_pfn(vaddr))) # define page_to_virt(page) (pfn_to_virt(page_to_pfn(page))) diff --git a/arch/microblaze/kernel/dma.c b/arch/microblaze/kernel/dma.c index 64bc39f..f230a8d 100644 --- a/arch/microblaze/kernel/dma.c +++ b/arch/microblaze/kernel/dma.c @@ -21,10 +21,10 @@ * default the offset is PCI_DRAM_OFFSET. */ -static inline void __dma_sync_page(void *vaddr, unsigned long offset, +static inline void __dma_sync_page(void *paddr, unsigned long offset, size_t size, enum dma_data_direction direction) { - unsigned long start = virt_to_phys(vaddr); + unsigned long start = (unsigned long)paddr; switch (direction) { case DMA_TO_DEVICE: @@ -79,10 +79,12 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl, struct scatterlist *sg; int i; + /* FIXME this part of code is untested */ for_each_sg(sgl, sg, nents, i) { sg->dma_address = sg_phys(sg) + get_dma_direct_offset(dev); sg->dma_length = sg->length; - __dma_sync_page(sg_page(sg), sg->offset, sg->length, direction); + __dma_sync_page(page_to_phys(sg_page(sg)), sg->offset, + sg->length, direction); } return nents; @@ -107,7 +109,7 @@ static inline dma_addr_t dma_direct_map_page(struct device *dev, struct dma_attrs *attrs) { BUG_ON(direction == DMA_NONE); - __dma_sync_page(page, offset, size, direction); + __dma_sync_page(page_to_phys(page), offset, size, direction); return page_to_phys(page) + offset + get_dma_direct_offset(dev); } @@ -117,8 +119,12 @@ static inline void dma_direct_unmap_page(struct device *dev, enum dma_data_direction direction, struct dma_attrs *attrs) { -/* There is not necessary to do cache cleanup */ - /* __dma_sync_page(dma_address, 0 , size, direction); */ +/* There is not necessary to do cache cleanup + * + * phys_to_virt is here because in __dma_sync_page is __virt_to_phys and + * dma_address is physical address + */ + __dma_sync_page((void *)dma_address, 0 , size, direction); } struct dma_map_ops dma_direct_ops = { -- cgit v0.10.2 From 137d0795a72786fa33e6900cb2ac2eae81f4b6ee Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 4 Feb 2010 11:42:24 +0100 Subject: microblaze: Change temp register for cmdline For copy was used r7 register when CONFIG_CMDLINE_BOOL option is enabled. But r7 stores pointer to fdt that's why machine_early_init not detect compiled-in DTB. I also moved kernel PID setup to have TLB init in one block Signed-off-by: Michal Simek diff --git a/arch/microblaze/kernel/head.S b/arch/microblaze/kernel/head.S index 3091619..cb7815c 100644 --- a/arch/microblaze/kernel/head.S +++ b/arch/microblaze/kernel/head.S @@ -99,8 +99,8 @@ no_fdt_arg: tophys(r4,r4) /* convert to phys address */ ori r3, r0, COMMAND_LINE_SIZE - 1 /* number of loops */ _copy_command_line: - lbu r7, r5, r6 /* r7=r5+r6 - r5 contain pointer to command line */ - sb r7, r4, r6 /* addr[r4+r6]= r7*/ + lbu r2, r5, r6 /* r7=r5+r6 - r5 contain pointer to command line */ + sb r2, r4, r6 /* addr[r4+r6]= r7*/ addik r6, r6, 1 /* increment counting */ bgtid r3, _copy_command_line /* loop for all entries */ addik r3, r3, -1 /* descrement loop */ @@ -136,6 +136,11 @@ _invalidate: addik r3, r3, -1 /* sync */ + /* Setup the kernel PID */ + mts rpid,r0 /* Load the kernel PID */ + nop + bri 4 + /* * We should still be executing code at physical address area * RAM_BASEADDR at this point. However, kernel code is at @@ -146,10 +151,6 @@ _invalidate: addik r3,r0, CONFIG_KERNEL_START /* Load the kernel virtual address */ tophys(r4,r3) /* Load the kernel physical address */ - mts rpid,r0 /* Load the kernel PID */ - nop - bri 4 - /* * Configure and load two entries into TLB slots 0 and 1. * In case we are pinning TLBs, these are reserved in by the -- cgit v0.10.2 From e786c6ad2ba7f1f9b9cc9d75d5e7ba7d9cdc550a Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 8 Feb 2010 14:48:16 +0100 Subject: microblaze: Use generic show_mem() Remove arch-specific show_mem() in favor of the generic version. It is based on powerpc patch. bda2fa535564ace56a395d5b65c6dc81305401fa Signed-off-by: Michal Simek diff --git a/arch/microblaze/mm/init.c b/arch/microblaze/mm/init.c index 6eea554..aa6e163 100644 --- a/arch/microblaze/mm/init.c +++ b/arch/microblaze/mm/init.c @@ -193,12 +193,6 @@ void free_initmem(void) (unsigned long)(&__init_end)); } -/* FIXME from arch/powerpc/mm/mem.c*/ -void show_mem(void) -{ - printk(KERN_NOTICE "%s\n", __func__); -} - void __init mem_init(void) { high_memory = (void *)__va(memory_end); -- cgit v0.10.2 From 4c912c1a33abb67aefecb5ed8bd73d91887c4977 Mon Sep 17 00:00:00 2001 From: Frans Pop Date: Sat, 6 Feb 2010 18:47:12 +0100 Subject: microblaze: remove trailing space in messages Signed-off-by: Frans Pop Cc: microblaze-uclinux@itee.uq.edu.au Cc: Michal Simek Signed-off-by: Michal Simek diff --git a/arch/microblaze/kernel/cpu/cache.c b/arch/microblaze/kernel/cpu/cache.c index 5425f89..13f0c1d 100644 --- a/arch/microblaze/kernel/cpu/cache.c +++ b/arch/microblaze/kernel/cpu/cache.c @@ -493,7 +493,7 @@ const struct scache wt_nomsr_noirq = { #define CPUVER_7_20_A 0x0c #define CPUVER_7_20_D 0x0f -#define INFO(s) printk(KERN_INFO "cache: " s " \n"); +#define INFO(s) printk(KERN_INFO "cache: " s "\n"); void microblaze_cache_init(void) { -- cgit v0.10.2 From dcbae4be907488df5e1cc8a89b7df1a0565c257c Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 9 Feb 2010 09:25:08 +0100 Subject: microblaze: Preliminary support for dma drivers I found several problems for ll_temac driver and on system with WB. This early fix should fix it. I will clean this patch before I will add it to mainline Signed-off-by: Michal Simek diff --git a/arch/microblaze/kernel/dma.c b/arch/microblaze/kernel/dma.c index f230a8d..fbe1e81 100644 --- a/arch/microblaze/kernel/dma.c +++ b/arch/microblaze/kernel/dma.c @@ -20,18 +20,15 @@ * can set archdata.dma_data to an unsigned long holding the offset. By * default the offset is PCI_DRAM_OFFSET. */ - -static inline void __dma_sync_page(void *paddr, unsigned long offset, +static inline void __dma_sync_page(unsigned long paddr, unsigned long offset, size_t size, enum dma_data_direction direction) { - unsigned long start = (unsigned long)paddr; - switch (direction) { case DMA_TO_DEVICE: - flush_dcache_range(start + offset, start + offset + size); + flush_dcache_range(paddr + offset, paddr + offset + size); break; case DMA_FROM_DEVICE: - invalidate_dcache_range(start + offset, start + offset + size); + invalidate_dcache_range(paddr + offset, paddr + offset + size); break; default: BUG(); -- cgit v0.10.2 From 22607a28213068af113b46862eafa785f00a482e Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 15 Feb 2010 16:41:40 +0100 Subject: microblaze: Add define for ASM_LOOP It is default option but both options must be measured. Signed-off-by: Michal Simek diff --git a/arch/microblaze/kernel/cpu/cache.c b/arch/microblaze/kernel/cpu/cache.c index 13f0c1d..f04d8a8 100644 --- a/arch/microblaze/kernel/cpu/cache.c +++ b/arch/microblaze/kernel/cpu/cache.c @@ -15,25 +15,6 @@ #include #include -static inline void __invalidate_flush_icache(unsigned int addr) -{ - __asm__ __volatile__ ("wic %0, r0;" \ - : : "r" (addr)); -} - -static inline void __flush_dcache(unsigned int addr) -{ - __asm__ __volatile__ ("wdc.flush %0, r0;" \ - : : "r" (addr)); -} - -static inline void __invalidate_dcache(unsigned int baseaddr, - unsigned int offset) -{ - __asm__ __volatile__ ("wdc.clear %0, %1;" \ - : : "r" (baseaddr), "r" (offset)); -} - static inline void __enable_icache_msr(void) { __asm__ __volatile__ (" msrset r0, %0; \ @@ -148,9 +129,9 @@ do { \ int step = -line_length; \ BUG_ON(step >= 0); \ \ - __asm__ __volatile__ (" 1: " #op " r0, %0; \ - bgtid %0, 1b; \ - addk %0, %0, %1; \ + __asm__ __volatile__ (" 1: " #op " r0, %0; \ + bgtid %0, 1b; \ + addk %0, %0, %1; \ " : : "r" (len), "r" (step) \ : "memory"); \ } while (0); @@ -162,9 +143,9 @@ do { \ int count = end - start; \ BUG_ON(count <= 0); \ \ - __asm__ __volatile__ (" 1: " #op " %0, %1; \ - bgtid %1, 1b; \ - addk %1, %1, %2; \ + __asm__ __volatile__ (" 1: " #op " %0, %1; \ + bgtid %1, 1b; \ + addk %1, %1, %2; \ " : : "r" (start), "r" (count), \ "r" (step) : "memory"); \ } while (0); @@ -175,7 +156,7 @@ do { \ int volatile temp; \ BUG_ON(end - start <= 0); \ \ - __asm__ __volatile__ (" 1: " #op " %1, r0; \ + __asm__ __volatile__ (" 1: " #op " %1, r0; \ cmpu %0, %1, %2; \ bgtid %0, 1b; \ addk %1, %1, %3; \ @@ -183,10 +164,14 @@ do { \ "r" (line_length) : "memory"); \ } while (0); +#define ASM_LOOP + static void __flush_icache_range_msr_irq(unsigned long start, unsigned long end) { unsigned long flags; - +#ifndef ASM_LOOP + int i; +#endif pr_debug("%s: start 0x%x, end 0x%x\n", __func__, (unsigned int)start, (unsigned int) end); @@ -196,8 +181,13 @@ static void __flush_icache_range_msr_irq(unsigned long start, unsigned long end) local_irq_save(flags); __disable_icache_msr(); +#ifdef ASM_LOOP CACHE_RANGE_LOOP_1(start, end, cpuinfo.icache_line_length, wic); - +#else + for (i = start; i < end; i += cpuinfo.icache_line_length) + __asm__ __volatile__ ("wic %0, r0;" \ + : : "r" (i)); +#endif __enable_icache_msr(); local_irq_restore(flags); } @@ -206,7 +196,9 @@ static void __flush_icache_range_nomsr_irq(unsigned long start, unsigned long end) { unsigned long flags; - +#ifndef ASM_LOOP + int i; +#endif pr_debug("%s: start 0x%x, end 0x%x\n", __func__, (unsigned int)start, (unsigned int) end); @@ -216,7 +208,13 @@ static void __flush_icache_range_nomsr_irq(unsigned long start, local_irq_save(flags); __disable_icache_nomsr(); +#ifdef ASM_LOOP CACHE_RANGE_LOOP_1(start, end, cpuinfo.icache_line_length, wic); +#else + for (i = start; i < end; i += cpuinfo.icache_line_length) + __asm__ __volatile__ ("wic %0, r0;" \ + : : "r" (i)); +#endif __enable_icache_nomsr(); local_irq_restore(flags); @@ -225,25 +223,41 @@ static void __flush_icache_range_nomsr_irq(unsigned long start, static void __flush_icache_range_noirq(unsigned long start, unsigned long end) { +#ifndef ASM_LOOP + int i; +#endif pr_debug("%s: start 0x%x, end 0x%x\n", __func__, (unsigned int)start, (unsigned int) end); CACHE_LOOP_LIMITS(start, end, cpuinfo.icache_line_length, cpuinfo.icache_size); +#ifdef ASM_LOOP CACHE_RANGE_LOOP_1(start, end, cpuinfo.icache_line_length, wic); +#else + for (i = start; i < end; i += cpuinfo.icache_line_length) + __asm__ __volatile__ ("wic %0, r0;" \ + : : "r" (i)); +#endif } static void __flush_icache_all_msr_irq(void) { unsigned long flags; - +#ifndef ASM_LOOP + int i; +#endif pr_debug("%s\n", __func__); local_irq_save(flags); __disable_icache_msr(); - +#ifdef ASM_LOOP CACHE_ALL_LOOP(cpuinfo.icache_size, cpuinfo.icache_line_length, wic); - +#else + for (i = 0; i < cpuinfo.icache_size; + i += cpuinfo.icache_line_length) + __asm__ __volatile__ ("wic %0, r0;" \ + : : "r" (i)); +#endif __enable_icache_msr(); local_irq_restore(flags); } @@ -251,35 +265,59 @@ static void __flush_icache_all_msr_irq(void) static void __flush_icache_all_nomsr_irq(void) { unsigned long flags; - +#ifndef ASM_LOOP + int i; +#endif pr_debug("%s\n", __func__); local_irq_save(flags); __disable_icache_nomsr(); - +#ifdef ASM_LOOP CACHE_ALL_LOOP(cpuinfo.icache_size, cpuinfo.icache_line_length, wic); - +#else + for (i = 0; i < cpuinfo.icache_size; + i += cpuinfo.icache_line_length) + __asm__ __volatile__ ("wic %0, r0;" \ + : : "r" (i)); +#endif __enable_icache_nomsr(); local_irq_restore(flags); } static void __flush_icache_all_noirq(void) { +#ifndef ASM_LOOP + int i; +#endif pr_debug("%s\n", __func__); +#ifdef ASM_LOOP CACHE_ALL_LOOP(cpuinfo.icache_size, cpuinfo.icache_line_length, wic); +#else + for (i = 0; i < cpuinfo.icache_size; + i += cpuinfo.icache_line_length) + __asm__ __volatile__ ("wic %0, r0;" \ + : : "r" (i)); +#endif } static void __invalidate_dcache_all_msr_irq(void) { unsigned long flags; - +#ifndef ASM_LOOP + int i; +#endif pr_debug("%s\n", __func__); local_irq_save(flags); __disable_dcache_msr(); - +#ifdef ASM_LOOP CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length, wdc); - +#else + for (i = 0; i < cpuinfo.dcache_size; + i += cpuinfo.dcache_line_length) + __asm__ __volatile__ ("wdc %0, r0;" \ + : : "r" (i)); +#endif __enable_dcache_msr(); local_irq_restore(flags); } @@ -287,60 +325,107 @@ static void __invalidate_dcache_all_msr_irq(void) static void __invalidate_dcache_all_nomsr_irq(void) { unsigned long flags; - +#ifndef ASM_LOOP + int i; +#endif pr_debug("%s\n", __func__); local_irq_save(flags); __disable_dcache_nomsr(); - +#ifdef ASM_LOOP CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length, wdc); - +#else + for (i = 0; i < cpuinfo.dcache_size; + i += cpuinfo.dcache_line_length) + __asm__ __volatile__ ("wdc %0, r0;" \ + : : "r" (i)); +#endif __enable_dcache_nomsr(); local_irq_restore(flags); } static void __invalidate_dcache_all_noirq_wt(void) { +#ifndef ASM_LOOP + int i; +#endif pr_debug("%s\n", __func__); +#ifdef ASM_LOOP CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length, wdc) +#else + for (i = 0; i < cpuinfo.dcache_size; + i += cpuinfo.dcache_line_length) + __asm__ __volatile__ ("wdc %0, r0;" \ + : : "r" (i)); +#endif } /* FIXME this is weird - should be only wdc but not work * MS: I am getting bus errors and other weird things */ static void __invalidate_dcache_all_wb(void) { +#ifndef ASM_LOOP + int i; +#endif pr_debug("%s\n", __func__); +#ifdef ASM_LOOP CACHE_ALL_LOOP2(cpuinfo.dcache_size, cpuinfo.dcache_line_length, wdc.clear) +#else + for (i = 0; i < cpuinfo.dcache_size; + i += cpuinfo.dcache_line_length) + __asm__ __volatile__ ("wdc.clear %0, r0;" \ + : : "r" (i)); +#endif } static void __invalidate_dcache_range_wb(unsigned long start, unsigned long end) { +#ifndef ASM_LOOP + int i; +#endif pr_debug("%s: start 0x%x, end 0x%x\n", __func__, (unsigned int)start, (unsigned int) end); CACHE_LOOP_LIMITS(start, end, cpuinfo.dcache_line_length, cpuinfo.dcache_size); +#ifdef ASM_LOOP CACHE_RANGE_LOOP_2(start, end, cpuinfo.dcache_line_length, wdc.clear); +#else + for (i = start; i < end; i += cpuinfo.icache_line_length) + __asm__ __volatile__ ("wdc.clear %0, r0;" \ + : : "r" (i)); +#endif } static void __invalidate_dcache_range_nomsr_wt(unsigned long start, unsigned long end) { +#ifndef ASM_LOOP + int i; +#endif pr_debug("%s: start 0x%x, end 0x%x\n", __func__, (unsigned int)start, (unsigned int) end); CACHE_LOOP_LIMITS(start, end, cpuinfo.dcache_line_length, cpuinfo.dcache_size); +#ifdef ASM_LOOP CACHE_RANGE_LOOP_1(start, end, cpuinfo.dcache_line_length, wdc); +#else + for (i = start; i < end; i += cpuinfo.icache_line_length) + __asm__ __volatile__ ("wdc %0, r0;" \ + : : "r" (i)); +#endif } static void __invalidate_dcache_range_msr_irq_wt(unsigned long start, unsigned long end) { unsigned long flags; - +#ifndef ASM_LOOP + int i; +#endif pr_debug("%s: start 0x%x, end 0x%x\n", __func__, (unsigned int)start, (unsigned int) end); CACHE_LOOP_LIMITS(start, end, @@ -349,7 +434,13 @@ static void __invalidate_dcache_range_msr_irq_wt(unsigned long start, local_irq_save(flags); __disable_dcache_msr(); +#ifdef ASM_LOOP CACHE_RANGE_LOOP_1(start, end, cpuinfo.dcache_line_length, wdc); +#else + for (i = start; i < end; i += cpuinfo.icache_line_length) + __asm__ __volatile__ ("wdc %0, r0;" \ + : : "r" (i)); +#endif __enable_dcache_msr(); local_irq_restore(flags); @@ -359,7 +450,9 @@ static void __invalidate_dcache_range_nomsr_irq(unsigned long start, unsigned long end) { unsigned long flags; - +#ifndef ASM_LOOP + int i; +#endif pr_debug("%s: start 0x%x, end 0x%x\n", __func__, (unsigned int)start, (unsigned int) end); @@ -369,7 +462,13 @@ static void __invalidate_dcache_range_nomsr_irq(unsigned long start, local_irq_save(flags); __disable_dcache_nomsr(); +#ifdef ASM_LOOP CACHE_RANGE_LOOP_1(start, end, cpuinfo.dcache_line_length, wdc); +#else + for (i = start; i < end; i += cpuinfo.icache_line_length) + __asm__ __volatile__ ("wdc %0, r0;" \ + : : "r" (i)); +#endif __enable_dcache_nomsr(); local_irq_restore(flags); @@ -377,19 +476,38 @@ static void __invalidate_dcache_range_nomsr_irq(unsigned long start, static void __flush_dcache_all_wb(void) { +#ifndef ASM_LOOP + int i; +#endif pr_debug("%s\n", __func__); +#ifdef ASM_LOOP CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length, wdc.flush); +#else + for (i = 0; i < cpuinfo.dcache_size; + i += cpuinfo.dcache_line_length) + __asm__ __volatile__ ("wdc.flush %0, r0;" \ + : : "r" (i)); +#endif } static void __flush_dcache_range_wb(unsigned long start, unsigned long end) { +#ifndef ASM_LOOP + int i; +#endif pr_debug("%s: start 0x%x, end 0x%x\n", __func__, (unsigned int)start, (unsigned int) end); CACHE_LOOP_LIMITS(start, end, cpuinfo.dcache_line_length, cpuinfo.dcache_size); +#ifdef ASM_LOOP CACHE_RANGE_LOOP_2(start, end, cpuinfo.dcache_line_length, wdc.flush); +#else + for (i = start; i < end; i += cpuinfo.icache_line_length) + __asm__ __volatile__ ("wdc.flush %0, r0;" \ + : : "r" (i)); +#endif } /* struct for wb caches and for wt caches */ -- cgit v0.10.2 From cca5613f0278fb0ae0aba285a496add55d0cabab Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 22 Feb 2010 11:27:27 +0100 Subject: microblaze: Remove VMALLOC_VMADDR Signed-off-by: Michal Simek diff --git a/arch/microblaze/include/asm/pgtable.h b/arch/microblaze/include/asm/pgtable.h index 1c47f6f..e8d25fb 100644 --- a/arch/microblaze/include/asm/pgtable.h +++ b/arch/microblaze/include/asm/pgtable.h @@ -85,7 +85,6 @@ static inline pte_t pte_mkspecial(pte_t pte) { return pte; } #define VMALLOC_START (CONFIG_KERNEL_START + \ max(32 * 1024 * 1024UL, memory_size)) #define VMALLOC_END ioremap_bot -#define VMALLOC_VMADDR(x) ((unsigned long)(x)) #endif /* __ASSEMBLY__ */ diff --git a/arch/microblaze/mm/pgtable.c b/arch/microblaze/mm/pgtable.c index 2820081..63a6fd0 100644 --- a/arch/microblaze/mm/pgtable.c +++ b/arch/microblaze/mm/pgtable.c @@ -103,7 +103,7 @@ static void __iomem *__ioremap(phys_addr_t addr, unsigned long size, area = get_vm_area(size, VM_IOREMAP); if (area == NULL) return NULL; - v = VMALLOC_VMADDR(area->addr); + v = (unsigned long) area->addr; } else { v = (ioremap_bot -= size); } -- cgit v0.10.2 From b8a84059b5c3a3b9ba3973dcdab1e1d9cc4975e0 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 22 Feb 2010 11:33:07 +0100 Subject: microblaze: Remove ancient Kconfig option for consistent mapping We don't use CONSISTENT option from Kconfig that's why I am removing them. Signed-off-by: Michal Simek diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index c1e731b..e451c08 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -145,7 +145,6 @@ menu "Advanced setup" config ADVANCED_OPTIONS bool "Prompt for advanced kernel configuration options" - depends on MMU help This option will enable prompting for a variety of advanced kernel configuration options. These options can cause the kernel to not @@ -174,7 +173,7 @@ config HIGHMEM_START config LOWMEM_SIZE_BOOL bool "Set maximum low memory" - depends on ADVANCED_OPTIONS + depends on ADVANCED_OPTIONS && MMU help This option allows you to set the maximum amount of memory which will be used as "low memory", that is, memory which the kernel can @@ -186,7 +185,6 @@ config LOWMEM_SIZE_BOOL config LOWMEM_SIZE hex "Maximum low memory size (in bytes)" if LOWMEM_SIZE_BOOL - depends on MMU default "0x30000000" config KERNEL_START_BOOL @@ -207,7 +205,7 @@ config KERNEL_START config TASK_SIZE_BOOL bool "Set custom user task size" - depends on ADVANCED_OPTIONS + depends on ADVANCED_OPTIONS && MMU help This option allows you to set the amount of virtual address space allocated to user tasks. This can be useful in optimizing the @@ -217,35 +215,8 @@ config TASK_SIZE_BOOL config TASK_SIZE hex "Size of user task space" if TASK_SIZE_BOOL - depends on MMU default "0x80000000" -config CONSISTENT_START_BOOL - bool "Set custom consistent memory pool address" - depends on ADVANCED_OPTIONS && NOT_COHERENT_CACHE - help - This option allows you to set the base virtual address - of the the consistent memory pool. This pool of virtual - memory is used to make consistent memory allocations. - -config CONSISTENT_START - hex "Base virtual address of consistent memory pool" if CONSISTENT_START_BOOL - depends on MMU - default "0xff100000" if NOT_COHERENT_CACHE - -config CONSISTENT_SIZE_BOOL - bool "Set custom consistent memory pool size" - depends on ADVANCED_OPTIONS && NOT_COHERENT_CACHE - help - This option allows you to set the size of the the - consistent memory pool. This pool of virtual memory - is used to make consistent memory allocations. - -config CONSISTENT_SIZE - hex "Size of consistent memory pool" if CONSISTENT_SIZE_BOOL - depends on MMU - default "0x00200000" if NOT_COHERENT_CACHE - endmenu source "mm/Kconfig" -- cgit v0.10.2 From ae8ee1505162f47f8b8cf7a44c26ea6b172e1445 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 22 Feb 2010 12:09:02 +0100 Subject: microblaze: pgtable.h: move consistent functions Consistent functions will be used for noMMU and MMU kernels. Signed-off-by: Michal Simek diff --git a/arch/microblaze/include/asm/pgtable.h b/arch/microblaze/include/asm/pgtable.h index e8d25fb..adcc332 100644 --- a/arch/microblaze/include/asm/pgtable.h +++ b/arch/microblaze/include/asm/pgtable.h @@ -68,7 +68,6 @@ static inline int pte_file(pte_t pte) { return 0; } extern unsigned long va_to_phys(unsigned long address); extern pte_t *va_to_pte(unsigned long address); -extern unsigned long ioremap_bot, ioremap_base; /* * The following only work if pte_present() is true. @@ -411,7 +410,7 @@ static inline unsigned long pte_update(pte_t *p, unsigned long clr, mts rmsr, %2\n\ nop" : "=&r" (old), "=&r" (tmp), "=&r" (msr), "=m" (*p) - : "r" ((unsigned long)(p+1) - 4), "r" (clr), "r" (set), "m" (*p) + : "r" ((unsigned long)(p + 1) - 4), "r" (clr), "r" (set), "m" (*p) : "cc"); return old; @@ -580,18 +579,11 @@ void mapin_ram(void); int map_page(unsigned long va, phys_addr_t pa, int flags); extern int mem_init_done; -extern unsigned long ioremap_base; -extern unsigned long ioremap_bot; asmlinkage void __init mmu_init(void); void __init *early_get_page(void); -void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle); -void consistent_free(void *vaddr); -void consistent_sync(void *vaddr, size_t size, int direction); -void consistent_sync_page(struct page *page, unsigned long offset, - size_t size, int direction); #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ @@ -600,6 +592,14 @@ void consistent_sync_page(struct page *page, unsigned long offset, #ifndef __ASSEMBLY__ #include +extern unsigned long ioremap_bot, ioremap_base; + +void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle); +void consistent_free(void *vaddr); +void consistent_sync(void *vaddr, size_t size, int direction); +void consistent_sync_page(struct page *page, unsigned long offset, + size_t size, int direction); + void setup_memory(void); #endif /* __ASSEMBLY__ */ -- cgit v0.10.2 From 3a0d7a4dd5b3a6545e5764735b48ab84e64af723 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 22 Feb 2010 12:16:08 +0100 Subject: microblaze: Add consistent code Remove ancient Kconfig option for consistent code. MMU uses cache inhibit pages. noMMU uses UNCACHE SHADOW feature where is used double ram size. For example: Physical ram is 256MB and cache are setup to cover the same size. But if you setup in HW that size is 512MB and cache covers 256MB than you can use adresses from 256-512MB without caches and correspond with 0-256MB with cache. That's why I am using dcache base/high addresses to find out uncache area. Signed-off-by: Michal Simek diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index e451c08..203ec61 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -156,6 +156,15 @@ config ADVANCED_OPTIONS comment "Default settings for advanced configuration options are used" depends on !ADVANCED_OPTIONS +config XILINX_UNCACHED_SHADOW + bool "Are you using uncached shadow for RAM ?" + depends on ADVANCED_OPTIONS && !MMU + default n + help + This is needed to be able to allocate uncachable memory regions. + The feature requires the design to define the RAM memory controller + window to be twice as large as the actual physical memory. + config HIGHMEM_START_BOOL bool "Set high memory pool address" depends on ADVANCED_OPTIONS && HIGHMEM diff --git a/arch/microblaze/mm/Makefile b/arch/microblaze/mm/Makefile index 6c8a924..09c49ed 100644 --- a/arch/microblaze/mm/Makefile +++ b/arch/microblaze/mm/Makefile @@ -2,6 +2,6 @@ # Makefile # -obj-y := init.o +obj-y := consistent.o init.o obj-$(CONFIG_MMU) += pgtable.o mmu_context.o fault.o diff --git a/arch/microblaze/mm/consistent.c b/arch/microblaze/mm/consistent.c new file mode 100644 index 0000000..a9b443e --- /dev/null +++ b/arch/microblaze/mm/consistent.c @@ -0,0 +1,246 @@ +/* + * Microblaze support for cache consistent memory. + * Copyright (C) 2010 Michal Simek + * Copyright (C) 2010 PetaLogix + * Copyright (C) 2005 John Williams + * + * Based on PowerPC version derived from arch/arm/mm/consistent.c + * Copyright (C) 2001 Dan Malek (dmalek@jlc.net) + * Copyright (C) 2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef CONFIG_MMU + +/* I have to use dcache values because I can't relate on ram size */ +#define UNCACHED_SHADOW_MASK (cpuinfo.dcache_high - cpuinfo.dcache_base + 1) + +/* + * Consistent memory allocators. Used for DMA devices that want to + * share uncached memory with the processor core. + * My crufty no-MMU approach is simple. In the HW platform we can optionally + * mirror the DDR up above the processor cacheable region. So, memory accessed + * in this mirror region will not be cached. It's alloced from the same + * pool as normal memory, but the handle we return is shifted up into the + * uncached region. This will no doubt cause big problems if memory allocated + * here is not also freed properly. -- JW + */ +void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle) +{ + struct page *page, *end, *free; + unsigned long order; + void *ret, *virt; + + if (in_interrupt()) + BUG(); + + size = PAGE_ALIGN(size); + order = get_order(size); + + page = alloc_pages(gfp, order); + if (!page) + goto no_page; + + /* We could do with a page_to_phys and page_to_bus here. */ + virt = page_address(page); + ret = ioremap(virt_to_phys(virt), size); + if (!ret) + goto no_remap; + + /* + * Here's the magic! Note if the uncached shadow is not implemented, + * it's up to the calling code to also test that condition and make + * other arranegments, such as manually flushing the cache and so on. + */ +#ifdef CONFIG_XILINX_UNCACHED_SHADOW + ret = (void *)((unsigned) ret | UNCACHED_SHADOW_MASK); +#endif + /* dma_handle is same as physical (shadowed) address */ + *dma_handle = (dma_addr_t)ret; + + /* + * free wasted pages. We skip the first page since we know + * that it will have count = 1 and won't require freeing. + * We also mark the pages in use as reserved so that + * remap_page_range works. + */ + page = virt_to_page(virt); + free = page + (size >> PAGE_SHIFT); + end = page + (1 << order); + + for (; page < end; page++) { + init_page_count(page); + if (page >= free) + __free_page(page); + else + SetPageReserved(page); + } + + return ret; +no_remap: + __free_pages(page, order); +no_page: + return NULL; +} + +#else + +void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle) +{ + int order, err, i; + unsigned long page, va, flags; + phys_addr_t pa; + struct vm_struct *area; + void *ret; + + if (in_interrupt()) + BUG(); + + /* Only allocate page size areas. */ + size = PAGE_ALIGN(size); + order = get_order(size); + + page = __get_free_pages(gfp, order); + if (!page) { + BUG(); + return NULL; + } + + /* + * we need to ensure that there are no cachelines in use, + * or worse dirty in this area. + */ + flush_dcache_range(virt_to_phys(page), virt_to_phys(page) + size); + + /* Allocate some common virtual space to map the new pages. */ + area = get_vm_area(size, VM_ALLOC); + if (area == NULL) { + free_pages(page, order); + return NULL; + } + va = (unsigned long) area->addr; + ret = (void *)va; + + /* This gives us the real physical address of the first page. */ + *dma_handle = pa = virt_to_bus((void *)page); + + /* MS: This is the whole magic - use cache inhibit pages */ + flags = _PAGE_KERNEL | _PAGE_NO_CACHE; + + /* + * Set refcount=1 on all pages in an order>0 + * allocation so that vfree() will actually + * free all pages that were allocated. + */ + if (order > 0) { + struct page *rpage = virt_to_page(page); + for (i = 1; i < (1 << order); i++) + init_page_count(rpage+i); + } + + err = 0; + for (i = 0; i < size && err == 0; i += PAGE_SIZE) + err = map_page(va+i, pa+i, flags); + + if (err) { + vfree((void *)va); + return NULL; + } + + return ret; +} +#endif /* CONFIG_MMU */ +EXPORT_SYMBOL(consistent_alloc); + +/* + * free page(s) as defined by the above mapping. + */ +void consistent_free(void *vaddr) +{ + if (in_interrupt()) + BUG(); + + /* Clear SHADOW_MASK bit in address, and free as per usual */ +#ifdef CONFIG_XILINX_UNCACHED_SHADOW + vaddr = (void *)((unsigned)vaddr & ~UNCACHED_SHADOW_MASK); +#endif + vfree(vaddr); +} +EXPORT_SYMBOL(consistent_free); + +/* + * make an area consistent. + */ +void consistent_sync(void *vaddr, size_t size, int direction) +{ + unsigned long start; + unsigned long end; + + start = (unsigned long)vaddr; + + /* Convert start address back down to unshadowed memory region */ +#ifdef CONFIG_XILINX_UNCACHED_SHADOW + start &= ~UNCACHED_SHADOW_MASK; +#endif + end = start + size; + + switch (direction) { + case PCI_DMA_NONE: + BUG(); + case PCI_DMA_FROMDEVICE: /* invalidate only */ + flush_dcache_range(start, end); + break; + case PCI_DMA_TODEVICE: /* writeback only */ + flush_dcache_range(start, end); + break; + case PCI_DMA_BIDIRECTIONAL: /* writeback and invalidate */ + flush_dcache_range(start, end); + break; + } +} +EXPORT_SYMBOL(consistent_sync); + +/* + * consistent_sync_page makes memory consistent. identical + * to consistent_sync, but takes a struct page instead of a + * virtual address + */ +void consistent_sync_page(struct page *page, unsigned long offset, + size_t size, int direction) +{ + unsigned long start = (unsigned long)page_address(page) + offset; + consistent_sync((void *)start, size, direction); +} +EXPORT_SYMBOL(consistent_sync_page); -- cgit v0.10.2 From 1be53e084a5bd8f59850348e1066d25aa0200031 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 11 Mar 2010 14:15:48 +0100 Subject: microblaze: Fix dma alloc and free coherent dma functions We have to use consistent code to be able to do coherent dma function. In consistent code is used cache inhibit page mapping. Xilinx reported that there is bug in Microblaze for WB and d-cache_always use option. Microblaze 7.30.a should be first version where is this bug removed. Signed-off-by: Michal Simek diff --git a/arch/microblaze/kernel/dma.c b/arch/microblaze/kernel/dma.c index fbe1e81..b108497 100644 --- a/arch/microblaze/kernel/dma.c +++ b/arch/microblaze/kernel/dma.c @@ -43,9 +43,14 @@ static unsigned long get_dma_direct_offset(struct device *dev) return PCI_DRAM_OFFSET; /* FIXME Not sure if is correct */ } -void *dma_direct_alloc_coherent(struct device *dev, size_t size, +#define NOT_COHERENT_CACHE + +static void *dma_direct_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag) { +#ifdef NOT_COHERENT_CACHE + return consistent_alloc(flag, size, dma_handle); +#else void *ret; struct page *page; int node = dev_to_node(dev); @@ -61,12 +66,17 @@ void *dma_direct_alloc_coherent(struct device *dev, size_t size, *dma_handle = virt_to_phys(ret) + get_dma_direct_offset(dev); return ret; +#endif } -void dma_direct_free_coherent(struct device *dev, size_t size, +static void dma_direct_free_coherent(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle) { +#ifdef NOT_COHERENT_CACHE + consistent_free(vaddr); +#else free_pages((unsigned long)vaddr, get_order(size)); +#endif } static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl, @@ -105,7 +115,6 @@ static inline dma_addr_t dma_direct_map_page(struct device *dev, enum dma_data_direction direction, struct dma_attrs *attrs) { - BUG_ON(direction == DMA_NONE); __dma_sync_page(page_to_phys(page), offset, size, direction); return page_to_phys(page) + offset + get_dma_direct_offset(dev); } @@ -121,7 +130,7 @@ static inline void dma_direct_unmap_page(struct device *dev, * phys_to_virt is here because in __dma_sync_page is __virt_to_phys and * dma_address is physical address */ - __dma_sync_page((void *)dma_address, 0 , size, direction); + __dma_sync_page(dma_address, 0 , size, direction); } struct dma_map_ops dma_direct_ops = { -- cgit v0.10.2 From 79bf3a137617e6deeac411c39f1660b7e91d6348 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 20 Jan 2010 15:17:08 +0100 Subject: microblaze: PCI early support for noMMU system Signed-off-by: Michal Simek diff --git a/arch/microblaze/include/asm/pgalloc.h b/arch/microblaze/include/asm/pgalloc.h index 7547f50..f44b0d6 100644 --- a/arch/microblaze/include/asm/pgalloc.h +++ b/arch/microblaze/include/asm/pgalloc.h @@ -19,6 +19,7 @@ #include #include #include +#include #define PGDIR_ORDER 0 @@ -111,7 +112,6 @@ static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) { pte_t *pte; - extern int mem_init_done; extern void *early_get_page(void); if (mem_init_done) { pte = (pte_t *)__get_free_page(GFP_KERNEL | diff --git a/arch/microblaze/include/asm/pgtable.h b/arch/microblaze/include/asm/pgtable.h index adcc332..dd2bb60 100644 --- a/arch/microblaze/include/asm/pgtable.h +++ b/arch/microblaze/include/asm/pgtable.h @@ -16,6 +16,10 @@ #define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ remap_pfn_range(vma, vaddr, pfn, size, prot) +#ifndef __ASSEMBLY__ +extern int mem_init_done; +#endif + #ifndef CONFIG_MMU #define pgd_present(pgd) (1) /* pages are always present on non MMU */ @@ -51,6 +55,8 @@ static inline int pte_file(pte_t pte) { return 0; } #define arch_enter_lazy_cpu_mode() do {} while (0) +#define pgprot_noncached_wc(prot) prot + #else /* CONFIG_MMU */ #include diff --git a/arch/microblaze/mm/init.c b/arch/microblaze/mm/init.c index aa6e163..1608e2e 100644 --- a/arch/microblaze/mm/init.c +++ b/arch/microblaze/mm/init.c @@ -23,6 +23,9 @@ #include #include +/* Use for MMU and noMMU because of PCI generic code */ +int mem_init_done; + #ifndef CONFIG_MMU unsigned int __page_offset; EXPORT_SYMBOL(__page_offset); @@ -30,7 +33,6 @@ EXPORT_SYMBOL(__page_offset); #else DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); -int mem_init_done; static int init_bootmem_done; #endif /* CONFIG_MMU */ @@ -202,9 +204,7 @@ void __init mem_init(void) printk(KERN_INFO "Memory: %luk/%luk available\n", nr_free_pages() << (PAGE_SHIFT-10), num_physpages << (PAGE_SHIFT-10)); -#ifdef CONFIG_MMU mem_init_done = 1; -#endif } #ifndef CONFIG_MMU @@ -216,6 +216,10 @@ int ___range_ok(unsigned long addr, unsigned long size) } EXPORT_SYMBOL(___range_ok); +int page_is_ram(unsigned long pfn) +{ + return __range_ok(pfn, 0); +} #else int page_is_ram(unsigned long pfn) { @@ -344,6 +348,8 @@ void __init *early_get_page(void) return p; } +#endif /* CONFIG_MMU */ + void * __init_refok alloc_maybe_bootmem(size_t size, gfp_t mask) { if (mem_init_done) @@ -365,5 +371,3 @@ void * __init_refok zalloc_maybe_bootmem(size_t size, gfp_t mask) } return p; } - -#endif /* CONFIG_MMU */ diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c index f03f8be..0be3435 100644 --- a/arch/microblaze/pci/pci-common.c +++ b/arch/microblaze/pci/pci-common.c @@ -561,11 +561,13 @@ int pci_mmap_legacy_page_range(struct pci_bus *bus, * memory, effectively behaving just like /dev/zero */ if ((offset + size) > hose->isa_mem_size) { +#ifdef CONFIG_MMU printk(KERN_DEBUG "Process %s (pid:%d) mapped non-existing PCI" "legacy memory for 0%04x:%02x\n", current->comm, current->pid, pci_domain_nr(bus), bus->number); +#endif if (vma->vm_flags & VM_SHARED) return shmem_zero_setup(vma); return 0; -- cgit v0.10.2 From b1d70c62fff3e8b6224699801c610c244882685a Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 22 Jan 2010 10:24:06 +0100 Subject: microblaze: Simplify entry.S - save/restore r3/r4 - ret_from_trap There is possible to save r3/r4 at the beggining of user part before calling handlers and at the end restore it. Signed-off-by: Michal Simek diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S index 1a6729d..772fe74 100644 --- a/arch/microblaze/kernel/entry.S +++ b/arch/microblaze/kernel/entry.S @@ -305,7 +305,7 @@ C_ENTRY(_user_exception): swi r11, r1, PTO+PT_R1; /* Store user SP. */ addi r11, r0, 1; swi r11, r0, TOPHYS(PER_CPU(KM)); /* Now we're in kernel-mode. */ -2: lwi r31, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */ +2: lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* Save away the syscall number. */ swi r12, r1, PTO+PT_R0; tovirt(r1,r1) @@ -322,8 +322,7 @@ C_ENTRY(_user_exception): rtid r11, 0 nop 3: - add r11, r0, CURRENT_TASK /* Get current task ptr into r11 */ - lwi r11, r11, TS_THREAD_INFO /* get thread info */ + lwi r11, CURRENT_TASK, TS_THREAD_INFO /* get thread info */ lwi r11, r11, TI_FLAGS /* get flags in thread info */ andi r11, r11, _TIF_WORK_SYSCALL_MASK beqi r11, 4f @@ -382,58 +381,50 @@ C_ENTRY(ret_from_trap): /* See if returning to kernel mode, if so, skip resched &c. */ bnei r11, 2f; + swi r3, r1, PTO + PT_R3 + swi r4, r1, PTO + PT_R4 + /* We're returning to user mode, so check for various conditions that * trigger rescheduling. */ - # FIXME: Restructure all these flag checks. - add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */ - lwi r11, r11, TS_THREAD_INFO; /* get thread info */ + /* FIXME: Restructure all these flag checks. */ + lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */ lwi r11, r11, TI_FLAGS; /* get flags in thread info */ andi r11, r11, _TIF_WORK_SYSCALL_MASK beqi r11, 1f - swi r3, r1, PTO + PT_R3 - swi r4, r1, PTO + PT_R4 brlid r15, do_syscall_trace_leave addik r5, r1, PTO + PT_R0 - lwi r3, r1, PTO + PT_R3 - lwi r4, r1, PTO + PT_R4 1: - /* We're returning to user mode, so check for various conditions that * trigger rescheduling. */ - /* Get current task ptr into r11 */ - add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */ - lwi r11, r11, TS_THREAD_INFO; /* get thread info */ + /* get thread info from current task */ + lwi r11, CURRENT_TASK, TS_THREAD_INFO; lwi r11, r11, TI_FLAGS; /* get flags in thread info */ andi r11, r11, _TIF_NEED_RESCHED; beqi r11, 5f; - swi r3, r1, PTO + PT_R3; /* store syscall result */ - swi r4, r1, PTO + PT_R4; bralid r15, schedule; /* Call scheduler */ nop; /* delay slot */ - lwi r3, r1, PTO + PT_R3; /* restore syscall result */ - lwi r4, r1, PTO + PT_R4; /* Maybe handle a signal */ -5: add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */ - lwi r11, r11, TS_THREAD_INFO; /* get thread info */ +5: /* get thread info from current task*/ + lwi r11, CURRENT_TASK, TS_THREAD_INFO; lwi r11, r11, TI_FLAGS; /* get flags in thread info */ andi r11, r11, _TIF_SIGPENDING; beqi r11, 1f; /* Signals to handle, handle them */ - swi r3, r1, PTO + PT_R3; /* store syscall result */ - swi r4, r1, PTO + PT_R4; la r5, r1, PTO; /* Arg 1: struct pt_regs *regs */ add r6, r0, r0; /* Arg 2: sigset_t *oldset */ addi r7, r0, 1; /* Arg 3: int in_syscall */ bralid r15, do_signal; /* Handle any signals */ nop; + +/* Finally, return to user state. */ +1: lwi r3, r1, PTO + PT_R3; /* restore syscall result */ lwi r4, r1, PTO + PT_R4; -/* Finally, return to user state. */ -1: swi r0, r0, PER_CPU(KM); /* Now officially in user state. */ + swi r0, r0, PER_CPU(KM); /* Now officially in user state. */ add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */ swi r11, r0, PER_CPU(CURRENT_SAVE); /* save current */ VM_OFF; @@ -565,7 +556,7 @@ C_ENTRY(sys_rt_sigreturn_wrapper): swi r11, r1, PTO+PT_R1; /* Store user SP. */ \ addi r11, r0, 1; \ swi r11, r0, TOPHYS(PER_CPU(KM)); /* Now we're in kernel-mode.*/\ -2: lwi r31, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */\ +2: lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); \ /* Save away the syscall number. */ \ swi r0, r1, PTO+PT_R0; \ tovirt(r1,r1) @@ -673,9 +664,7 @@ C_ENTRY(ret_from_exc): /* We're returning to user mode, so check for various conditions that trigger rescheduling. */ - /* Get current task ptr into r11 */ - add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */ - lwi r11, r11, TS_THREAD_INFO; /* get thread info */ + lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */ lwi r11, r11, TI_FLAGS; /* get flags in thread info */ andi r11, r11, _TIF_NEED_RESCHED; beqi r11, 5f; @@ -685,8 +674,7 @@ C_ENTRY(ret_from_exc): nop; /* delay slot */ /* Maybe handle a signal */ -5: add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */ - lwi r11, r11, TS_THREAD_INFO; /* get thread info */ +5: lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */ lwi r11, r11, TI_FLAGS; /* get flags in thread info */ andi r11, r11, _TIF_SIGPENDING; beqi r11, 1f; /* Signals to handle, handle them */ @@ -802,7 +790,7 @@ C_ENTRY(_interrupt): swi r11, r0, TOPHYS(PER_CPU(KM)); 2: - lwi r31, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); + lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); swi r0, r1, PTO + PT_R0; tovirt(r1,r1) la r5, r1, PTO; @@ -817,8 +805,7 @@ ret_from_irq: lwi r11, r1, PTO + PT_MODE; bnei r11, 2f; - add r11, r0, CURRENT_TASK; - lwi r11, r11, TS_THREAD_INFO; + lwi r11, CURRENT_TASK, TS_THREAD_INFO; lwi r11, r11, TI_FLAGS; /* MS: get flags from thread info */ andi r11, r11, _TIF_NEED_RESCHED; beqi r11, 5f @@ -826,8 +813,7 @@ ret_from_irq: nop; /* delay slot */ /* Maybe handle a signal */ -5: add r11, r0, CURRENT_TASK; - lwi r11, r11, TS_THREAD_INFO; /* MS: get thread info */ +5: lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* MS: get thread info */ lwi r11, r11, TI_FLAGS; /* get flags in thread info */ andi r11, r11, _TIF_SIGPENDING; beqid r11, no_intr_resched @@ -855,8 +841,7 @@ no_intr_resched: /* MS: Return to kernel state. */ 2: #ifdef CONFIG_PREEMPT - add r11, r0, CURRENT_TASK; - lwi r11, r11, TS_THREAD_INFO; + lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* MS: get preempt_count from thread info */ lwi r5, r11, TI_PREEMPT_COUNT; bgti r5, restore; @@ -869,8 +854,7 @@ preempt: /* interrupts are off that's why I am calling preempt_chedule_irq */ bralid r15, preempt_schedule_irq nop - add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */ - lwi r11, r11, TS_THREAD_INFO; /* get thread info */ + lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */ lwi r5, r11, TI_FLAGS; /* get flags in thread info */ andi r5, r5, _TIF_NEED_RESCHED; bnei r5, preempt /* if non zero jump to resched */ @@ -938,7 +922,7 @@ C_ENTRY(_debug_exception): swi r11, r1, PTO+PT_R1; /* Store user SP. */ addi r11, r0, 1; swi r11, r0, TOPHYS(PER_CPU(KM)); /* Now we're in kernel-mode. */ -2: lwi r31, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */ +2: lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* Save away the syscall number. */ swi r0, r1, PTO+PT_R0; tovirt(r1,r1) @@ -958,8 +942,7 @@ dbtrap_call: rtbd r11, 0; bnei r11, 2f; /* Get current task ptr into r11 */ - add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */ - lwi r11, r11, TS_THREAD_INFO; /* get thread info */ + lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */ lwi r11, r11, TI_FLAGS; /* get flags in thread info */ andi r11, r11, _TIF_NEED_RESCHED; beqi r11, 5f; @@ -972,8 +955,7 @@ dbtrap_call: rtbd r11, 0; /* XXX m68knommu also checks TASK_STATE & TASK_COUNTER here. */ /* Maybe handle a signal */ -5: add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */ - lwi r11, r11, TS_THREAD_INFO; /* get thread info */ +5: lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */ lwi r11, r11, TI_FLAGS; /* get flags in thread info */ andi r11, r11, _TIF_SIGPENDING; beqi r11, 1f; /* Signals to handle, handle them */ @@ -1030,7 +1012,7 @@ DBTRAP_return: /* Make global symbol for debugging */ ENTRY(_switch_to) /* prepare return value */ - addk r3, r0, r31 + addk r3, r0, CURRENT_TASK /* save registers in cpu_context */ /* use r11 and r12, volatile registers, as temp register */ @@ -1074,10 +1056,10 @@ ENTRY(_switch_to) nop swi r12, r11, CC_FSR - /* update r31, the current */ - lwi r31, r6, TI_TASK/* give me pointer to task which will be next */ + /* update r31, the current-give me pointer to task which will be next */ + lwi CURRENT_TASK, r6, TI_TASK /* stored it to current_save too */ - swi r31, r0, PER_CPU(CURRENT_SAVE) + swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE) /* get new process' cpu context and restore */ /* give me start where start context of next task */ -- cgit v0.10.2 From 8633bebc63ba5752254925f8b49a19102df1a0ff Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 22 Feb 2010 13:24:43 +0100 Subject: microblaze: Save current task directly Signed-off-by: Michal Simek diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S index 772fe74..cc9885d 100644 --- a/arch/microblaze/kernel/entry.S +++ b/arch/microblaze/kernel/entry.S @@ -425,8 +425,7 @@ C_ENTRY(ret_from_trap): lwi r4, r1, PTO + PT_R4; swi r0, r0, PER_CPU(KM); /* Now officially in user state. */ - add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */ - swi r11, r0, PER_CPU(CURRENT_SAVE); /* save current */ + swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); /* save current */ VM_OFF; tophys(r1,r1); RESTORE_REGS; @@ -700,8 +699,7 @@ C_ENTRY(ret_from_exc): /* Finally, return to user state. */ 1: swi r0, r0, PER_CPU(KM); /* Now officially in user state. */ - add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */ - swi r11, r0, PER_CPU(CURRENT_SAVE); /* save current */ + swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); /* save current */ VM_OFF; tophys(r1,r1); @@ -828,8 +826,7 @@ no_intr_resched: /* Disable interrupts, we are now committed to the state restore */ disable_irq swi r0, r0, PER_CPU(KM); /* MS: Now officially in user state. */ - add r11, r0, CURRENT_TASK; - swi r11, r0, PER_CPU(CURRENT_SAVE); + swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); VM_OFF; tophys(r1,r1); lwi r3, r1, PTO + PT_R3; /* MS: restore saved r3, r4 registers */ @@ -979,8 +976,7 @@ dbtrap_call: rtbd r11, 0; /* Finally, return to user state. */ 1: swi r0, r0, PER_CPU(KM); /* Now officially in user state. */ - add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */ - swi r11, r0, PER_CPU(CURRENT_SAVE); /* save current */ + swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); /* save current */ VM_OFF; tophys(r1,r1); -- cgit v0.10.2 From 841d6e8c4e969b2cdd80f7216af34d932c41b1a6 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 22 Jan 2010 14:28:36 +0100 Subject: microblaze: entry.S use delay slot for return handlers Signed-off-by: Michal Simek diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S index cc9885d..c0ede25 100644 --- a/arch/microblaze/kernel/entry.S +++ b/arch/microblaze/kernel/entry.S @@ -414,10 +414,9 @@ C_ENTRY(ret_from_trap): beqi r11, 1f; /* Signals to handle, handle them */ la r5, r1, PTO; /* Arg 1: struct pt_regs *regs */ - add r6, r0, r0; /* Arg 2: sigset_t *oldset */ addi r7, r0, 1; /* Arg 3: int in_syscall */ bralid r15, do_signal; /* Handle any signals */ - nop; + add r6, r0, r0; /* Arg 2: sigset_t *oldset */ /* Finally, return to user state. */ 1: @@ -692,10 +691,9 @@ C_ENTRY(ret_from_exc): * store return registers separately because this macros is use * for others exceptions */ la r5, r1, PTO; /* Arg 1: struct pt_regs *regs */ - add r6, r0, r0; /* Arg 2: sigset_t *oldset */ addi r7, r0, 0; /* Arg 3: int in_syscall */ bralid r15, do_signal; /* Handle any signals */ - nop; + add r6, r0, r0; /* Arg 2: sigset_t *oldset */ /* Finally, return to user state. */ 1: swi r0, r0, PER_CPU(KM); /* Now officially in user state. */ @@ -968,10 +966,9 @@ dbtrap_call: rtbd r11, 0; (in a possibly modified form) after do_signal returns. */ la r5, r1, PTO; /* Arg 1: struct pt_regs *regs */ - add r6, r0, r0; /* Arg 2: sigset_t *oldset */ addi r7, r0, 0; /* Arg 3: int in_syscall */ bralid r15, do_signal; /* Handle any signals */ - nop; + add r6, r0, r0; /* Arg 2: sigset_t *oldset */ /* Finally, return to user state. */ -- cgit v0.10.2 From 10fb7f1f2d311b4d2e5d881fe2d83f1c281100f9 Mon Sep 17 00:00:00 2001 From: Mike Travis Date: Fri, 5 Mar 2010 13:10:36 -0600 Subject: x86: Reduce per cpu MCA boot up messages Don't write per cpu MCA boot up messages. Signed-of-by: Mike Travis Cc: Hidetoshi Seto Cc: x86@kernel.org Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/cpu/mcheck/mce_intel.c b/arch/x86/kernel/cpu/mcheck/mce_intel.c index 7c78563..d15df6e 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_intel.c +++ b/arch/x86/kernel/cpu/mcheck/mce_intel.c @@ -95,7 +95,7 @@ static void cmci_discover(int banks, int boot) /* Already owned by someone else? */ if (val & CMCI_EN) { - if (test_and_clear_bit(i, owned) || boot) + if (test_and_clear_bit(i, owned) && !boot) print_update("SHD", &hdr, i); __clear_bit(i, __get_cpu_var(mce_poll_banks)); continue; @@ -107,7 +107,7 @@ static void cmci_discover(int banks, int boot) /* Did the enable bit stick? -- the bank supports CMCI */ if (val & CMCI_EN) { - if (!test_and_set_bit(i, owned) || boot) + if (!test_and_set_bit(i, owned) && !boot) print_update("CMCI", &hdr, i); __clear_bit(i, __get_cpu_var(mce_poll_banks)); } else { -- cgit v0.10.2 From d6dd692168c049196f54edc2e8227c60702bb1d2 Mon Sep 17 00:00:00 2001 From: Mike Travis Date: Fri, 5 Mar 2010 13:10:38 -0600 Subject: x86: Reduce per cpu warning boot up messages Reduce warning message output to one line only instead of per cpu. Signed-of-by: Mike Travis Cc: Rusty Russell Cc: Frederic Weisbecker Cc: Brian Gerst Cc: x86@kernel.org Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index c9b3522..4e8cb4e 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -600,7 +600,7 @@ void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) { #ifdef CONFIG_SMP if (pm_idle == poll_idle && smp_num_siblings > 1) { - printk(KERN_WARNING "WARNING: polling idle and HT enabled," + printk_once(KERN_WARNING "WARNING: polling idle and HT enabled," " performance may degrade.\n"); } #endif -- cgit v0.10.2 From bb6fbc4548b9ae7ebbd06ef72f00229df259d217 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 11 Mar 2010 09:19:35 -0500 Subject: NFS: Avoid a deadlock in nfs_release_page J.R. Okajima reports the following deadlock: INFO: task kswapd0:305 blocked for more than 120 seconds. "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. kswapd0 D 0000000000000001 0 305 2 0x00000000 ffff88001f21d4f0 0000000000000046 ffff88001fdea680 ffff88001f21c000 ffff88001f21dfd8 ffff88001f21c000 ffff88001f21dfd8 ffff88001f21dfd8 ffff88001fdea040 0000000000014c00 0000000000000001 ffff88001fdea040 Call Trace: [] io_schedule+0x4d/0x70 [] sync_page+0x65/0xa0 [] __wait_on_bit_lock+0x52/0xb0 [] ? sync_page+0x0/0xa0 [] __lock_page+0x64/0x70 [] ? wake_bit_function+0x0/0x40 [] truncate_inode_pages_range+0x344/0x4a0 [] truncate_inode_pages+0x10/0x20 [] generic_delete_inode+0x15e/0x190 [] generic_drop_inode+0x5d/0x80 [] iput+0x78/0x80 [] nfs_dentry_iput+0x38/0x50 [] dentry_iput+0x84/0x110 [] d_kill+0x2e/0x60 [] dput+0x7a/0x170 [] path_put+0x15/0x40 [] __put_nfs_open_context+0xa4/0xb0 [] ? nfs_free_request+0x0/0x50 [] put_nfs_open_context+0xb/0x10 [] nfs_free_request+0x29/0x50 [] kref_put+0x8e/0xe0 [] nfs_release_request+0x14/0x20 [] nfs_find_and_lock_request+0x89/0xa0 [] nfs_wb_page+0x80/0x110 [] nfs_release_page+0x70/0x90 [] try_to_release_page+0x5e/0x80 [] shrink_page_list+0x638/0x860 [] shrink_zone+0x63e/0xc40 We can fix this by making the call to put_nfs_open_context() happen when we actually remove the write request from the inode (which is done by the nfsiod thread in this case). Signed-off-by: Trond Myklebust Cc: stable@kernel.org diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index a12c45b..29d9d36 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c @@ -112,12 +112,10 @@ void nfs_unlock_request(struct nfs_page *req) */ int nfs_set_page_tag_locked(struct nfs_page *req) { - struct nfs_inode *nfsi = NFS_I(req->wb_context->path.dentry->d_inode); - if (!nfs_lock_request_dontget(req)) return 0; if (req->wb_page != NULL) - radix_tree_tag_set(&nfsi->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_LOCKED); + radix_tree_tag_set(&NFS_I(req->wb_context->path.dentry->d_inode)->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_LOCKED); return 1; } @@ -126,10 +124,10 @@ int nfs_set_page_tag_locked(struct nfs_page *req) */ void nfs_clear_page_tag_locked(struct nfs_page *req) { - struct inode *inode = req->wb_context->path.dentry->d_inode; - struct nfs_inode *nfsi = NFS_I(inode); - if (req->wb_page != NULL) { + struct inode *inode = req->wb_context->path.dentry->d_inode; + struct nfs_inode *nfsi = NFS_I(inode); + spin_lock(&inode->i_lock); radix_tree_tag_clear(&nfsi->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_LOCKED); nfs_unlock_request(req); @@ -142,16 +140,22 @@ void nfs_clear_page_tag_locked(struct nfs_page *req) * nfs_clear_request - Free up all resources allocated to the request * @req: * - * Release page resources associated with a write request after it - * has completed. + * Release page and open context resources associated with a read/write + * request after it has completed. */ void nfs_clear_request(struct nfs_page *req) { struct page *page = req->wb_page; + struct nfs_open_context *ctx = req->wb_context; + if (page != NULL) { page_cache_release(page); req->wb_page = NULL; } + if (ctx != NULL) { + put_nfs_open_context(ctx); + req->wb_context = NULL; + } } @@ -165,9 +169,8 @@ static void nfs_free_request(struct kref *kref) { struct nfs_page *req = container_of(kref, struct nfs_page, wb_kref); - /* Release struct file or cached credential */ + /* Release struct file and open context */ nfs_clear_request(req); - put_nfs_open_context(req->wb_context); nfs_page_free(req); } -- cgit v0.10.2 From 85cfabbcd10f8d112feee6e2ec64ee78033b6d3c Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 11 Mar 2010 13:06:56 +0100 Subject: perf, ppc: Fix compile error due to new cpu notifiers Fix: arch/powerpc/kernel/perf_event.c:1334: error: 'power_pmu_notifier' undeclared (first use in this function) arch/powerpc/kernel/perf_event.c:1334: error: (Each undeclared identifier is reported only once arch/powerpc/kernel/perf_event.c:1334: error: for each function it appears in.) arch/powerpc/kernel/perf_event.c:1334: error: implicit declaration of function 'power_pmu_notifier' arch/powerpc/kernel/perf_event.c:1334: error: implicit declaration of function 'register_cpu_notifier' Due to commit 3f6da390 (perf: Rework and fix the arch CPU-hotplug hooks). Signed-off-by: Peter Zijlstra LKML-Reference: Signed-off-by: Ingo Molnar diff --git a/arch/powerpc/kernel/perf_event.c b/arch/powerpc/kernel/perf_event.c index fbe101d..08460a2 100644 --- a/arch/powerpc/kernel/perf_event.c +++ b/arch/powerpc/kernel/perf_event.c @@ -1298,7 +1298,7 @@ static void power_pmu_setup(int cpu) } static int __cpuinit -power_pmu_notify(struct notifier_block *self, unsigned long action, void *hcpu) +power_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu) { unsigned int cpu = (long)hcpu; diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 70cffd0..9547703 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -453,6 +453,7 @@ enum perf_callchain_context { #include #include #include +#include #include #define PERF_MAX_STACK_DEPTH 255 -- cgit v0.10.2 From 45e16a6834b6af098702e5ea6c9a40de42ff77d8 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 11 Mar 2010 13:40:30 +0100 Subject: perf, x86: Fix hw_perf_enable() event assignment What happens is that we schedule badly like: <...>-1987 [019] 280.252808: x86_pmu_start: event-46/1300c0: idx: 0 <...>-1987 [019] 280.252811: x86_pmu_start: event-47/1300c0: idx: 1 <...>-1987 [019] 280.252812: x86_pmu_start: event-48/1300c0: idx: 2 <...>-1987 [019] 280.252813: x86_pmu_start: event-49/1300c0: idx: 3 <...>-1987 [019] 280.252814: x86_pmu_start: event-50/1300c0: idx: 32 <...>-1987 [019] 280.252825: x86_pmu_stop: event-46/1300c0: idx: 0 <...>-1987 [019] 280.252826: x86_pmu_stop: event-47/1300c0: idx: 1 <...>-1987 [019] 280.252827: x86_pmu_stop: event-48/1300c0: idx: 2 <...>-1987 [019] 280.252828: x86_pmu_stop: event-49/1300c0: idx: 3 <...>-1987 [019] 280.252829: x86_pmu_stop: event-50/1300c0: idx: 32 <...>-1987 [019] 280.252834: x86_pmu_start: event-47/1300c0: idx: 1 <...>-1987 [019] 280.252834: x86_pmu_start: event-48/1300c0: idx: 2 <...>-1987 [019] 280.252835: x86_pmu_start: event-49/1300c0: idx: 3 <...>-1987 [019] 280.252836: x86_pmu_start: event-50/1300c0: idx: 32 <...>-1987 [019] 280.252837: x86_pmu_start: event-51/1300c0: idx: 32 *FAIL* This happens because we only iterate the n_running events in the first pass, and reset their index to -1 if they don't match to force a re-assignment. Now, in our RR example, n_running == 0 because we fully unscheduled, so event-50 will retain its idx==32, even though in scheduling it will have gotten idx=0, and we don't trigger the re-assign path. The easiest way to fix this is the below patch, which simply validates the full assignment in the second pass. Reported-by: Stephane Eranian Signed-off-by: Peter Zijlstra LKML-Reference: <1268311069.5037.31.camel@laptop> Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index c6bde7d..5fb490c 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -811,7 +811,6 @@ void hw_perf_enable(void) * step2: reprogram moved events into new counters */ for (i = 0; i < n_running; i++) { - event = cpuc->event_list[i]; hwc = &event->hw; @@ -826,21 +825,16 @@ void hw_perf_enable(void) continue; x86_pmu_stop(event); - - hwc->idx = -1; } for (i = 0; i < cpuc->n_events; i++) { - event = cpuc->event_list[i]; hwc = &event->hw; - if (i < n_running && - match_prev_assignment(hwc, cpuc, i)) - continue; - - if (hwc->idx == -1) + if (!match_prev_assignment(hwc, cpuc, i)) x86_assign_hw_event(event, cpuc, i); + else if (i < n_running) + continue; x86_pmu_start(event); } -- cgit v0.10.2 From 639fe4b12f92b54c9c3b38c82cdafaa38cfd3e63 Mon Sep 17 00:00:00 2001 From: Xiao Guangrong Date: Thu, 11 Mar 2010 15:30:35 +0800 Subject: perf: export perf_trace_regs and perf_arch_fetch_caller_regs Export perf_trace_regs and perf_arch_fetch_caller_regs since module will use these. Signed-off-by: Xiao Guangrong [ use EXPORT_PER_CPU_SYMBOL_GPL() ] Signed-off-by: Peter Zijlstra LKML-Reference: <4B989C1B.2090407@cn.fujitsu.com> Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 5fb490c..7645fae 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -1713,3 +1713,4 @@ void perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int ski regs->cs = __KERNEL_CS; local_save_flags(regs->flags); } +EXPORT_SYMBOL_GPL(perf_arch_fetch_caller_regs); diff --git a/kernel/trace/trace_event_perf.c b/kernel/trace/trace_event_perf.c index f315b12..0709e4f 100644 --- a/kernel/trace/trace_event_perf.c +++ b/kernel/trace/trace_event_perf.c @@ -10,6 +10,7 @@ #include "trace.h" DEFINE_PER_CPU(struct pt_regs, perf_trace_regs); +EXPORT_PER_CPU_SYMBOL_GPL(perf_trace_regs); static char *perf_trace_buf; static char *perf_trace_buf_nmi; -- cgit v0.10.2 From 3d07467b7aa91623b31d7b5888a123a2c8c8e9cc Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 10 Mar 2010 17:07:24 +0100 Subject: sched: Fix pick_next_highest_task_rt() for cgroups Since pick_next_highest_task_rt() already iterates all the cgroups and is really only interested in tasks, skip over the !task entries. Reported-by: Dhaval Giani Signed-off-by: Peter Zijlstra Tested-by: Dhaval Giani LKML-Reference: Signed-off-by: Ingo Molnar diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c index bf3e38f..c4fb42a 100644 --- a/kernel/sched_rt.c +++ b/kernel/sched_rt.c @@ -1146,7 +1146,12 @@ static struct task_struct *pick_next_highest_task_rt(struct rq *rq, int cpu) if (next && next->prio < idx) continue; list_for_each_entry(rt_se, array->queue + idx, run_list) { - struct task_struct *p = rt_task_of(rt_se); + struct task_struct *p; + + if (!rt_entity_is_task(rt_se)) + continue; + + p = rt_task_of(rt_se); if (pick_rt_task(rq, p, cpu)) { next = p; break; -- cgit v0.10.2 From cf14c2e987ba0a09a7b09be2ecd55af0bc9c17b4 Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Tue, 2 Feb 2010 21:03:50 +0100 Subject: drbd: --dry-run option for drbdsetup net ( drbdadm -- --dry-run connect ) Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 2bf3a6e..1aae724 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -443,13 +443,18 @@ struct p_rs_param_89 { char csums_alg[SHARED_SECRET_MAX]; } __packed; +enum drbd_conn_flags { + CF_WANT_LOSE = 1, + CF_DRY_RUN = 2, +}; + struct p_protocol { struct p_header head; u32 protocol; u32 after_sb_0p; u32 after_sb_1p; u32 after_sb_2p; - u32 want_lose; + u32 conn_flags; u32 two_primaries; /* Since protocol version 87 and higher. */ @@ -791,6 +796,7 @@ enum { * while this is set. */ RESIZE_PENDING, /* Size change detected locally, waiting for the response from * the peer, if it changed there as well. */ + CONN_DRY_RUN, /* Expect disconnect after resync handshake. */ }; struct drbd_bitmap; /* opaque for drbd_conf */ diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index ab871e0..b2d347d 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -1668,7 +1668,7 @@ int drbd_send_sync_param(struct drbd_conf *mdev, struct syncer_conf *sc) int drbd_send_protocol(struct drbd_conf *mdev) { struct p_protocol *p; - int size, rv; + int size, cf, rv; size = sizeof(struct p_protocol); @@ -1685,9 +1685,21 @@ int drbd_send_protocol(struct drbd_conf *mdev) p->after_sb_0p = cpu_to_be32(mdev->net_conf->after_sb_0p); p->after_sb_1p = cpu_to_be32(mdev->net_conf->after_sb_1p); p->after_sb_2p = cpu_to_be32(mdev->net_conf->after_sb_2p); - p->want_lose = cpu_to_be32(mdev->net_conf->want_lose); p->two_primaries = cpu_to_be32(mdev->net_conf->two_primaries); + cf = 0; + if (mdev->net_conf->want_lose) + cf |= CF_WANT_LOSE; + if (mdev->net_conf->dry_run) { + if (mdev->agreed_pro_version >= 92) + cf |= CF_DRY_RUN; + else { + dev_err(DEV, "--dry-run is not supported by peer"); + return 0; + } + } + p->conn_flags = cpu_to_be32(cf); + if (mdev->agreed_pro_version >= 87) strcpy(p->integrity_alg, mdev->net_conf->integrity_alg); diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index d065c64..8bcde4a 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -2538,6 +2538,16 @@ static enum drbd_conns drbd_sync_handshake(struct drbd_conf *mdev, enum drbd_rol } } + if (mdev->net_conf->dry_run || test_bit(CONN_DRY_RUN, &mdev->flags)) { + if (hg == 0) + dev_info(DEV, "dry-run connect: No resync, would become Connected immediately.\n"); + else + dev_info(DEV, "dry-run connect: Would become %s, doing a %s resync.", + drbd_conn_str(hg > 0 ? C_SYNC_SOURCE : C_SYNC_TARGET), + abs(hg) >= 2 ? "full" : "bit-map based"); + return C_MASK; + } + if (abs(hg) >= 2) { dev_info(DEV, "Writing the whole bitmap, full sync required after drbd_sync_handshake.\n"); if (drbd_bitmap_io(mdev, &drbd_bmio_set_n_write, "set_n_write from sync_handshake")) @@ -2585,7 +2595,7 @@ static int receive_protocol(struct drbd_conf *mdev, struct p_header *h) struct p_protocol *p = (struct p_protocol *)h; int header_size, data_size; int p_proto, p_after_sb_0p, p_after_sb_1p, p_after_sb_2p; - int p_want_lose, p_two_primaries; + int p_want_lose, p_two_primaries, cf; char p_integrity_alg[SHARED_SECRET_MAX] = ""; header_size = sizeof(*p) - sizeof(*h); @@ -2598,8 +2608,14 @@ static int receive_protocol(struct drbd_conf *mdev, struct p_header *h) p_after_sb_0p = be32_to_cpu(p->after_sb_0p); p_after_sb_1p = be32_to_cpu(p->after_sb_1p); p_after_sb_2p = be32_to_cpu(p->after_sb_2p); - p_want_lose = be32_to_cpu(p->want_lose); p_two_primaries = be32_to_cpu(p->two_primaries); + cf = be32_to_cpu(p->conn_flags); + p_want_lose = cf & CF_WANT_LOSE; + + clear_bit(CONN_DRY_RUN, &mdev->flags); + + if (cf & CF_DRY_RUN) + set_bit(CONN_DRY_RUN, &mdev->flags); if (p_proto != mdev->net_conf->wire_protocol) { dev_err(DEV, "incompatible communication protocols\n"); @@ -3125,6 +3141,8 @@ static int receive_state(struct drbd_conf *mdev, struct p_header *h) dev_err(DEV, "Disk attach process on the peer node was aborted.\n"); peer_state.disk = D_DISKLESS; } else { + if (test_and_clear_bit(CONN_DRY_RUN, &mdev->flags)) + return FALSE; D_ASSERT(oconn == C_WF_REPORT_PARAMS); drbd_force_state(mdev, NS(conn, C_DISCONNECTING)); return FALSE; diff --git a/include/linux/drbd.h b/include/linux/drbd.h index 7896227..4341b1a 100644 --- a/include/linux/drbd.h +++ b/include/linux/drbd.h @@ -56,7 +56,7 @@ extern const char *drbd_buildtag(void); #define REL_VERSION "8.3.7" #define API_VERSION 88 #define PRO_VERSION_MIN 86 -#define PRO_VERSION_MAX 91 +#define PRO_VERSION_MAX 92 enum drbd_io_error_p { diff --git a/include/linux/drbd_nl.h b/include/linux/drbd_nl.h index a4d82f8..b41050e 100644 --- a/include/linux/drbd_nl.h +++ b/include/linux/drbd_nl.h @@ -63,6 +63,7 @@ NL_PACKET(net_conf, 5, NL_BIT( 41, T_MAY_IGNORE, always_asbp) NL_BIT( 61, T_MAY_IGNORE, no_cork) NL_BIT( 62, T_MANDATORY, auto_sndbuf_size) + NL_BIT( 70, T_MANDATORY, dry_run) ) NL_PACKET(disconnect, 6, ) -- cgit v0.10.2 From 4aa83b7bf122106669346eef40632289f540653f Mon Sep 17 00:00:00 2001 From: Lars Ellenberg Date: Fri, 26 Feb 2010 16:53:24 +0100 Subject: drbd: fix NULL pointer dereference on 4k hard sect size we still don't support 4k 'physical' sectors 'natively', but use a read-modify-write workaround. And we even tried to use the extra page before we allocated it :( Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 4df3b40..d53d36c 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -941,6 +941,25 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp drbd_md_set_sector_offsets(mdev, nbc); + /* allocate a second IO page if logical_block_size != 512 */ + logical_block_size = bdev_logical_block_size(nbc->md_bdev); + if (logical_block_size == 0) + logical_block_size = MD_SECTOR_SIZE; + + if (logical_block_size != MD_SECTOR_SIZE) { + if (!mdev->md_io_tmpp) { + struct page *page = alloc_page(GFP_NOIO); + if (!page) + goto force_diskless_dec; + + dev_warn(DEV, "Meta data's bdev logical_block_size = %d != %d\n", + logical_block_size, MD_SECTOR_SIZE); + dev_warn(DEV, "Workaround engaged (has performance impact).\n"); + + mdev->md_io_tmpp = page; + } + } + if (!mdev->bitmap) { if (drbd_bm_init(mdev)) { retcode = ERR_NOMEM; @@ -980,25 +999,6 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp goto force_diskless_dec; } - /* allocate a second IO page if logical_block_size != 512 */ - logical_block_size = bdev_logical_block_size(nbc->md_bdev); - if (logical_block_size == 0) - logical_block_size = MD_SECTOR_SIZE; - - if (logical_block_size != MD_SECTOR_SIZE) { - if (!mdev->md_io_tmpp) { - struct page *page = alloc_page(GFP_NOIO); - if (!page) - goto force_diskless_dec; - - dev_warn(DEV, "Meta data's bdev logical_block_size = %d != %d\n", - logical_block_size, MD_SECTOR_SIZE); - dev_warn(DEV, "Workaround engaged (has performance impact).\n"); - - mdev->md_io_tmpp = page; - } - } - /* Reset the "barriers don't work" bits here, then force meta data to * be written, to ensure we determine if barriers are supported. */ if (nbc->dc.no_md_flush) -- cgit v0.10.2 From 580b9767dbdf2c049c4d05330c70ea786ef01016 Mon Sep 17 00:00:00 2001 From: Lars Ellenberg Date: Fri, 26 Feb 2010 23:15:23 +0100 Subject: drbd: fix broken state change after split-brain attach while connected Situation: we have diverging data sets, i.e. we had a split brain somewhen, but currently are connected, one node diskless. Then we try to attach that disk, figure it is consistent, but has a diverging data set, we refuse to attach. This led to strange state changes: 22:18:35 bb drbd1: peer( Unknown -> Primary ) conn( WFReportParams -> Connected) pdsk( DUnknown -> UpToDate ) 22:19:30 bb drbd1: disk( Diskless -> Attaching ) 22:19:30 bb drbd1: disk( Attaching -> Negotiating ) 22:19:30 bb drbd1: drbd_sync_handshake: 22:19:30 bb drbd1: self 97BF25798B9D5222:F33D1F62ADE698DD:4269796F9D027C83:AC45D8B5C3C1BF93 bits:19449 flags:0 22:19:30 bb drbd1: peer 280DFB6E125465D3:F33D1F62ADE698DC:4269796F9D027C82:AC45D8B5C3C1BF93 bits:2575806 flags:0 22:19:30 bb drbd1: uuid_compare()=100 by rule 90 22:19:30 bb drbd1: Split-Brain detected, dropping connection! 22:19:30 bb drbd1: disk( Negotiating -> Diskless ) while the other side says: 22:19:30 aa drbd1: Split-Brain detected, dropping connection! 22:19:30 aa drbd1: Disk attach process on the peer node was aborted. 22:19:30 aa drbd1: conn( Connected -> TOO_LARGE ) pdsk( Diskless -> Consistent ) This should be fixed now. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 8bcde4a..41f36a9 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -2513,6 +2513,10 @@ static enum drbd_conns drbd_sync_handshake(struct drbd_conf *mdev, enum drbd_rol } if (hg == -100) { + /* FIXME this log message is not correct if we end up here + * after an attempted attach on a diskless node. + * We just refuse to attach -- well, we drop the "connection" + * to that disk, in a way... */ dev_alert(DEV, "Split-Brain detected, dropping connection!\n"); drbd_khelper(mdev, "split-brain"); return C_MASK; @@ -3134,12 +3138,13 @@ static int receive_state(struct drbd_conf *mdev, struct p_header *h) put_ldev(mdev); if (nconn == C_MASK) { + nconn = C_CONNECTED; if (mdev->state.disk == D_NEGOTIATING) { drbd_force_state(mdev, NS(disk, D_DISKLESS)); - nconn = C_CONNECTED; } else if (peer_state.disk == D_NEGOTIATING) { dev_err(DEV, "Disk attach process on the peer node was aborted.\n"); peer_state.disk = D_DISKLESS; + real_peer_disk = D_DISKLESS; } else { if (test_and_clear_bit(CONN_DRY_RUN, &mdev->flags)) return FALSE; -- cgit v0.10.2 From 676396d545350a70d922605ec23c2ed26124334a Mon Sep 17 00:00:00 2001 From: Lars Ellenberg Date: Wed, 3 Mar 2010 02:08:22 +0100 Subject: fix unit of rs_same_csums accounting Depending on resync request size, we need to account for more than one bit. Impact: cosmetic If SyncTarget reported correctly 100% equal checksums, the SyncSource usually reported 12% equal checksums instead, because it only counted requests, we typically do 32k resync requests, and the bitmap granularity is still 4k. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c index b453c2b..d97a811 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c @@ -938,7 +938,8 @@ int w_e_end_csum_rs_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel) if (eq) { drbd_set_in_sync(mdev, e->sector, e->size); - mdev->rs_same_csum++; + /* rs_same_csums unit is BM_BLOCK_SIZE */ + mdev->rs_same_csum += e->size >> BM_BLOCK_SHIFT; ok = drbd_send_ack(mdev, P_RS_IS_IN_SYNC, e); } else { inc_rs_pending(mdev); -- cgit v0.10.2 From 4589d7f829951c1713ef5a4ad1a9bb563da329b5 Mon Sep 17 00:00:00 2001 From: Lars Ellenberg Date: Wed, 3 Mar 2010 02:25:33 +0100 Subject: drbd_disconnect: grab meta.socket mutex as well Fixes a race and potential kernel panic if e.g. the worker was just about to send a few P_RS_IS_IN_SYNC via the meta socket for checksum based resync, while the receiver destroys the sockets in drbd_disconnect. To make sure no-one is using the meta socket, it is not enough to stop the asender... Grab the meta socket mutex before destroying it. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index b2d347d..67e0fc5 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -3173,14 +3173,18 @@ void drbd_free_bc(struct drbd_backing_dev *ldev) void drbd_free_sock(struct drbd_conf *mdev) { if (mdev->data.socket) { + mutex_lock(&mdev->data.mutex); kernel_sock_shutdown(mdev->data.socket, SHUT_RDWR); sock_release(mdev->data.socket); mdev->data.socket = NULL; + mutex_unlock(&mdev->data.mutex); } if (mdev->meta.socket) { + mutex_lock(&mdev->meta.mutex); kernel_sock_shutdown(mdev->meta.socket, SHUT_RDWR); sock_release(mdev->meta.socket); mdev->meta.socket = NULL; + mutex_unlock(&mdev->meta.mutex); } } diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 41f36a9..d803e6c 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -3617,10 +3617,7 @@ static void drbd_disconnect(struct drbd_conf *mdev) /* asender does not clean up anything. it must not interfere, either */ drbd_thread_stop(&mdev->asender); - - mutex_lock(&mdev->data.mutex); drbd_free_sock(mdev); - mutex_unlock(&mdev->data.mutex); spin_lock_irq(&mdev->req_lock); _drbd_wait_ee_list_empty(mdev, &mdev->active_ee); -- cgit v0.10.2 From c42b6cf4b38c9726d4b46c48d04197c9ca74d773 Mon Sep 17 00:00:00 2001 From: Lars Ellenberg Date: Wed, 3 Mar 2010 02:44:11 +0100 Subject: drbd: add missing drbd command names to avoid in error messages cmdname() should map command number to its human readable representation. The string table was incomplete, though. Maybe rather do a switch() block, and let the compiler help us to keep it complete? Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 1aae724..844206c 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -261,6 +261,9 @@ static inline const char *cmdname(enum drbd_packets cmd) [P_OV_REQUEST] = "OVRequest", [P_OV_REPLY] = "OVReply", [P_OV_RESULT] = "OVResult", + [P_CSUM_RS_REQUEST] = "CsumRSRequest", + [P_RS_IS_IN_SYNC] = "CsumRSIsInSync", + [P_COMPRESSED_BITMAP] = "CBitmap", [P_MAX_CMD] = NULL, }; -- cgit v0.10.2 From 309d1608cce32903d67d47e7545e232c400b6aa0 Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Tue, 2 Mar 2010 15:03:44 +0100 Subject: drbd: Reduce the time an empty resync takes usually This mitigates changes introduced with commit: http://git.drbd.org/?p=drbd-8.3.git;a=commit;h=4b6803a3276652da3737 Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 844206c..2d5cebb 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -800,6 +800,7 @@ enum { RESIZE_PENDING, /* Size change detected locally, waiting for the response from * the peer, if it changed there as well. */ CONN_DRY_RUN, /* Expect disconnect after resync handshake. */ + GOT_PING_ACK, /* set when we receive a ping_ack packet, misc wait gets woken */ }; struct drbd_bitmap; /* opaque for drbd_conf */ diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index d803e6c..ed9f1de 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -4074,6 +4074,8 @@ static int got_PingAck(struct drbd_conf *mdev, struct p_header *h) { /* restore idle timeout */ mdev->meta.socket->sk->sk_rcvtimeo = mdev->net_conf->ping_int*HZ; + if (!test_and_set_bit(GOT_PING_ACK, &mdev->flags)) + wake_up(&mdev->misc_wait); return TRUE; } diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c index d97a811..4672f2f 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c @@ -1289,6 +1289,14 @@ int drbd_alter_sa(struct drbd_conf *mdev, int na) return retcode; } +static void ping_peer(struct drbd_conf *mdev) +{ + clear_bit(GOT_PING_ACK, &mdev->flags); + request_ping(mdev); + wait_event(mdev->misc_wait, + test_bit(GOT_PING_ACK, &mdev->flags) || mdev->state.conn < C_CONNECTED); +} + /** * drbd_start_resync() - Start the resync process * @mdev: DRBD device. @@ -1383,9 +1391,7 @@ void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side) if (mdev->rs_total == 0) { /* Peer still reachable? Beware of failing before-resync-target handlers! */ - request_ping(mdev); - __set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(mdev->net_conf->ping_timeo*HZ/9); /* 9 instead 10 */ + ping_peer(mdev); drbd_resync_finished(mdev); return; } -- cgit v0.10.2 From d0c3f60f3611ceac9b1e4fdffd1497337568e7cb Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Tue, 2 Mar 2010 15:06:45 +0100 Subject: drbd: Make sure we do not send state updates during an empty resync [Bugz 271] This is a race condition that existed for ages. The previous commit reduces the window, this one closes it. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c index 4672f2f..44bf6d1 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c @@ -1380,7 +1380,6 @@ void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side) _drbd_pause_after(mdev); } write_unlock_irq(&global_state_lock); - drbd_state_unlock(mdev); put_ldev(mdev); if (r == SS_SUCCESS) { @@ -1393,7 +1392,6 @@ void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side) /* Peer still reachable? Beware of failing before-resync-target handlers! */ ping_peer(mdev); drbd_resync_finished(mdev); - return; } /* ns.conn may already be != mdev->state.conn, @@ -1405,6 +1403,7 @@ void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side) drbd_md_sync(mdev); } + drbd_state_unlock(mdev); } int drbd_worker(struct drbd_thread *thi) -- cgit v0.10.2 From d10a33c68b8526d95ef6ee72b371c392d48df4d3 Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Thu, 4 Mar 2010 15:11:39 +0100 Subject: drbd: Forcing primary should also work for Consistent disks [Bugz 266] Up to now this only worked for Outdated and Inconsistent disks, that it did not worked for Consistent disks was an inconsistent omission. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index d53d36c..6492e32 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -285,8 +285,8 @@ int drbd_set_role(struct drbd_conf *mdev, enum drbd_role new_role, int force) } if (r == SS_NO_UP_TO_DATE_DISK && force && - (mdev->state.disk == D_INCONSISTENT || - mdev->state.disk == D_OUTDATED)) { + (mdev->state.disk < D_UP_TO_DATE && + mdev->state.disk >= D_INCONSISTENT)) { mask.disk = D_MASK; val.disk = D_UP_TO_DATE; forced = 1; -- cgit v0.10.2 From 1f55243024087b56aef0b1e6d9c0ea89c76f0a6b Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Thu, 4 Mar 2010 15:51:01 +0100 Subject: drbd: Renamed overwrite_peer to primary_force Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 6492e32..6429d2b 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -407,7 +407,7 @@ static int drbd_nl_primary(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, } reply->ret_code = - drbd_set_role(mdev, R_PRIMARY, primary_args.overwrite_peer); + drbd_set_role(mdev, R_PRIMARY, primary_args.primary_force); return 0; } diff --git a/include/linux/drbd_nl.h b/include/linux/drbd_nl.h index b41050e..f7431a4 100644 --- a/include/linux/drbd_nl.h +++ b/include/linux/drbd_nl.h @@ -12,7 +12,7 @@ #endif NL_PACKET(primary, 1, - NL_BIT( 1, T_MAY_IGNORE, overwrite_peer) + NL_BIT( 1, T_MAY_IGNORE, primary_force) ) NL_PACKET(secondary, 2, ) -- cgit v0.10.2 From 39ad2bbb5900d1bc9ae8f06cebb4cb2529d9e42e Mon Sep 17 00:00:00 2001 From: Lars Ellenberg Date: Thu, 4 Mar 2010 15:52:30 +0100 Subject: drbd: fix al-to-on-disk-bitmap for 4k logical_block_size Up to now, applying the in-core activity-log to the on-disk bitmap did not care for logical_block_size. On logical_block_size != 512 byte, this very likely results in misalligned block access and spurious "io errors". We now simply always submit aligned whole 4k blocks, fixing this for logical block sizes of 512, 1024, 2048 and 4096. For even larger logical block sizes, this won't work. But I'm not aware of devices with such properties being available. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c index 17956ff..43e57f3 100644 --- a/drivers/block/drbd/drbd_actlog.c +++ b/drivers/block/drbd/drbd_actlog.c @@ -536,7 +536,9 @@ static void atodb_endio(struct bio *bio, int error) put_ldev(mdev); } +/* sector to word */ #define S2W(s) ((s)<<(BM_EXT_SHIFT-BM_BLOCK_SHIFT-LN2_BPL)) + /* activity log to on disk bitmap -- prepare bio unless that sector * is already covered by previously prepared bios */ static int atodb_prepare_unless_covered(struct drbd_conf *mdev, @@ -546,13 +548,20 @@ static int atodb_prepare_unless_covered(struct drbd_conf *mdev, { struct bio *bio; struct page *page; - sector_t on_disk_sector = enr + mdev->ldev->md.md_offset - + mdev->ldev->md.bm_offset; + sector_t on_disk_sector; unsigned int page_offset = PAGE_SIZE; int offset; int i = 0; int err = -ENOMEM; + /* We always write aligned, full 4k blocks, + * so we can ignore the logical_block_size (for now) */ + enr &= ~7U; + on_disk_sector = enr + mdev->ldev->md.md_offset + + mdev->ldev->md.bm_offset; + + D_ASSERT(!(on_disk_sector & 7U)); + /* Check if that enr is already covered by an already created bio. * Caution, bios[] is not NULL terminated, * but only initialized to all NULL. @@ -588,7 +597,7 @@ static int atodb_prepare_unless_covered(struct drbd_conf *mdev, offset = S2W(enr); drbd_bm_get_lel(mdev, offset, - min_t(size_t, S2W(1), drbd_bm_words(mdev) - offset), + min_t(size_t, S2W(8), drbd_bm_words(mdev) - offset), kmap(page) + page_offset); kunmap(page); @@ -597,7 +606,7 @@ static int atodb_prepare_unless_covered(struct drbd_conf *mdev, bio->bi_bdev = mdev->ldev->md_bdev; bio->bi_sector = on_disk_sector; - if (bio_add_page(bio, page, MD_SECTOR_SIZE, page_offset) != MD_SECTOR_SIZE) + if (bio_add_page(bio, page, 4096, page_offset) != 4096) goto out_put_page; atomic_inc(&wc->count); -- cgit v0.10.2 From 720e7749279bde0d08684b1bb4e7a2eedeec6394 Mon Sep 17 00:00:00 2001 From: Sachin Prabhu Date: Thu, 11 Mar 2010 12:24:45 -0500 Subject: GFS2: Skip check for mandatory locks when unlocking gfs2_lock() will skip locks on file which have mode set to 02666. This is a problem in cases where the mode of the file is changed after a process has obtained a lock on the file. Such a lock will be skipped and will result in a BUG in locks_remove_flock(). gfs2_lock() should skip the check for mandatory locks when unlocking a file. Signed-off-by: Sachin Prabhu Signed-off-by: Steven Whitehouse diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index a6abbae8..e6dd2ae 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -640,7 +640,7 @@ static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl) if (!(fl->fl_flags & FL_POSIX)) return -ENOLCK; - if (__mandatory_lock(&ip->i_inode)) + if (__mandatory_lock(&ip->i_inode) && fl->fl_type != F_UNLCK) return -ENOLCK; if (cmd == F_CANCELLK) { -- cgit v0.10.2 From 6f69a1815a93722b360a1439934856e766509002 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 4 Mar 2010 09:45:53 +0200 Subject: omap2/3/4: ehci: avoid compiler error with touchbook the early_param() call in board-omap3touchbook.c expands to: static const char __setup_str_early_touchbook_revision[] __section(.init.rodata) _aligned(1) = tbr; [...] and we have a non-const variable being added to the same section: static struct ehci_hcd_omap_platform_data ehci_pdata __section(.init.rodata); because of that, gcc generates a section type conflict which can (and actually should) be avoided by marking const every variable marked with __initconst. This patch fixes that for the ehci_hdc_omap_platform_data. Signed-off-by: Felipe Balbi Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c index a101029..5822bcf 100644 --- a/arch/arm/mach-omap2/board-3430sdp.c +++ b/arch/arm/mach-omap2/board-3430sdp.c @@ -648,7 +648,7 @@ static void enable_board_wakeup_source(void) OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP); } -static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { +static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY, .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY, diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c index 4386d2b..a0a2a11 100755 --- a/arch/arm/mach-omap2/board-3630sdp.c +++ b/arch/arm/mach-omap2/board-3630sdp.c @@ -54,7 +54,7 @@ static void enable_board_wakeup_source(void) OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP); } -static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { +static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY, .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY, diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c index 70c1861..6ae8805 100644 --- a/arch/arm/mach-omap2/board-am3517evm.c +++ b/arch/arm/mach-omap2/board-am3517evm.c @@ -273,7 +273,7 @@ static void __init am3517_evm_init_irq(void) omap_gpio_init(); } -static struct ehci_hcd_omap_platform_data ehci_pdata __initdata = { +static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY, .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY, .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN, diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c index afa77ca..2de4f79 100644 --- a/arch/arm/mach-omap2/board-cm-t35.c +++ b/arch/arm/mach-omap2/board-cm-t35.c @@ -612,7 +612,7 @@ static struct omap2_hsmmc_info mmc[] = { {} /* Terminator */ }; -static struct ehci_hcd_omap_platform_data ehci_pdata = { +static struct ehci_hcd_omap_platform_data ehci_pdata __initdata = { .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY, .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY, .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN, diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c index 3710190..5bfc13b 100644 --- a/arch/arm/mach-omap2/board-devkit8000.c +++ b/arch/arm/mach-omap2/board-devkit8000.c @@ -636,7 +636,7 @@ static struct omap_musb_board_data musb_board_data = { .power = 100, }; -static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { +static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY, .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY, diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c index 9958987..4f1accf 100644 --- a/arch/arm/mach-omap2/board-igep0020.c +++ b/arch/arm/mach-omap2/board-igep0020.c @@ -442,7 +442,7 @@ static struct omap_musb_board_data musb_board_data = { .power = 100, }; -static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { +static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { .port_mode[0] = EHCI_HCD_OMAP_MODE_UNKNOWN, .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY, .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN, diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index 6eb77e1..962d377 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c @@ -410,7 +410,7 @@ static void __init omap3beagle_flash_init(void) } } -static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { +static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY, .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY, diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c index d6bc88c..017bb2f 100644 --- a/arch/arm/mach-omap2/board-omap3evm.c +++ b/arch/arm/mach-omap2/board-omap3evm.c @@ -635,7 +635,7 @@ static struct platform_device *omap3_evm_devices[] __initdata = { &omap3_evm_dss_device, }; -static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { +static struct ehci_hcd_omap_platform_data ehci_pdata __initdata = { .port_mode[0] = EHCI_HCD_OMAP_MODE_UNKNOWN, .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY, diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c index 4827f46..51a5315 100644 --- a/arch/arm/mach-omap2/board-omap3pandora.c +++ b/arch/arm/mach-omap2/board-omap3pandora.c @@ -537,7 +537,7 @@ static struct platform_device *omap3pandora_devices[] __initdata = { &pandora_dss_device, }; -static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { +static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY, .port_mode[1] = EHCI_HCD_OMAP_MODE_UNKNOWN, diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c index 2a5bf5c..2504d41 100644 --- a/arch/arm/mach-omap2/board-omap3touchbook.c +++ b/arch/arm/mach-omap2/board-omap3touchbook.c @@ -493,7 +493,7 @@ static void __init omap3touchbook_flash_init(void) } } -static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { +static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY, .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY, diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c index 50872a4..8848c7c 100644 --- a/arch/arm/mach-omap2/board-overo.c +++ b/arch/arm/mach-omap2/board-overo.c @@ -394,7 +394,7 @@ static struct platform_device *overo_devices[] __initdata = { &overo_lcd_device, }; -static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { +static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { .port_mode[0] = EHCI_HCD_OMAP_MODE_UNKNOWN, .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY, .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN, diff --git a/arch/arm/mach-omap2/board-zoom3.c b/arch/arm/mach-omap2/board-zoom3.c index d3e3cd5..cd3e40c 100644 --- a/arch/arm/mach-omap2/board-zoom3.c +++ b/arch/arm/mach-omap2/board-zoom3.c @@ -52,7 +52,7 @@ static struct omap_board_mux board_mux[] __initdata = { #define board_mux NULL #endif -static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { +static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { .port_mode[0] = EHCI_HCD_OMAP_MODE_UNKNOWN, .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY, .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN, diff --git a/arch/arm/mach-omap2/usb-ehci.c b/arch/arm/mach-omap2/usb-ehci.c index f1df873..ee9f548 100644 --- a/arch/arm/mach-omap2/usb-ehci.c +++ b/arch/arm/mach-omap2/usb-ehci.c @@ -70,7 +70,7 @@ static struct platform_device ehci_device = { /* * setup_ehci_io_mux - initialize IO pad mux for USBHOST */ -static void setup_ehci_io_mux(enum ehci_hcd_omap_mode *port_mode) +static void setup_ehci_io_mux(const enum ehci_hcd_omap_mode *port_mode) { switch (port_mode[0]) { case EHCI_HCD_OMAP_MODE_PHY: @@ -213,7 +213,7 @@ static void setup_ehci_io_mux(enum ehci_hcd_omap_mode *port_mode) return; } -void __init usb_ehci_init(struct ehci_hcd_omap_platform_data *pdata) +void __init usb_ehci_init(const struct ehci_hcd_omap_platform_data *pdata) { platform_device_add_data(&ehci_device, pdata, sizeof(*pdata)); @@ -229,7 +229,7 @@ void __init usb_ehci_init(struct ehci_hcd_omap_platform_data *pdata) #else -void __init usb_ehci_init(struct ehci_hcd_omap_platform_data *pdata) +void __init usb_ehci_init(const struct ehci_hcd_omap_platform_data *pdata) { } diff --git a/arch/arm/plat-omap/include/plat/usb.h b/arch/arm/plat-omap/include/plat/usb.h index 288e29e..568578d 100644 --- a/arch/arm/plat-omap/include/plat/usb.h +++ b/arch/arm/plat-omap/include/plat/usb.h @@ -53,7 +53,7 @@ enum musb_interface {MUSB_INTERFACE_ULPI, MUSB_INTERFACE_UTMI}; extern void usb_musb_init(struct omap_musb_board_data *board_data); -extern void usb_ehci_init(struct ehci_hcd_omap_platform_data *pdata); +extern void usb_ehci_init(const struct ehci_hcd_omap_platform_data *pdata); #endif -- cgit v0.10.2 From d660f9a26ef81c3bbced92514ffbe82e1b882ee1 Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Thu, 11 Mar 2010 07:33:46 +0000 Subject: omap4: Fix build break by moving omap_smc1 into a separate .S This patch moves omap_smc1 function to a seperate omap44xx-smc.S file and sets compile flags as -Wa,-march=armv7-a. This fix was suggested by Tony Lindgren Signed-off-by: Santosh Shilimkar [tony@atomide.com: otherwise multi-omap build with V6 and V7 breaks] Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 2069fb3..4b9fc57 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -22,6 +22,9 @@ obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o # SMP support ONLY available for OMAP4 obj-$(CONFIG_SMP) += omap-smp.o omap-headsmp.o obj-$(CONFIG_LOCAL_TIMERS) += timer-mpu.o +obj-$(CONFIG_ARCH_OMAP4) += omap44xx-smc.o + +AFLAGS_omap44xx-smc.o :=-Wa,-march=armv7-a # Functions loaded to SRAM obj-$(CONFIG_ARCH_OMAP2420) += sram242x.o diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index 180ac11..b88f28c 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -50,33 +50,9 @@ static struct omap_board_config_kernel sdp4430_config[] __initdata = { }; #ifdef CONFIG_CACHE_L2X0 -noinline void omap_smc1(u32 fn, u32 arg) -{ - register u32 r12 asm("r12") = fn; - register u32 r0 asm("r0") = arg; - - /* This is common routine cache secure monitor API used to - * modify the PL310 secure registers. - * r0 contains the value to be modified and "r12" contains - * the monitor API number. It uses few CPU registers - * internally and hence they need be backed up including - * link register "lr". - * Explicitly save r11 and r12 the compiler generated code - * won't save it. - */ - asm volatile( - "stmfd r13!, {r11,r12}\n" - "dsb\n" - "smc\n" - "ldmfd r13!, {r11,r12}\n" - : "+r" (r0), "+r" (r12) - : - : "r4", "r5", "r10", "lr", "cc"); -} -EXPORT_SYMBOL(omap_smc1); - static int __init omap_l2_cache_init(void) { + extern void omap_smc1(u32 fn, u32 arg); void __iomem *l2cache_base; /* To avoid code running on other OMAPs in diff --git a/arch/arm/mach-omap2/omap44xx-smc.S b/arch/arm/mach-omap2/omap44xx-smc.S new file mode 100644 index 0000000..89bb2b1 --- /dev/null +++ b/arch/arm/mach-omap2/omap44xx-smc.S @@ -0,0 +1,32 @@ +/* + * OMAP44xx secure APIs file. + * + * Copyright (C) 2010 Texas Instruments, Inc. + * Written by Santosh Shilimkar + * + * + * This program is free software,you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include + +/* + * This is common routine to manage secure monitor API + * used to modify the PL310 secure registers. + * 'r0' contains the value to be modified and 'r12' contains + * the monitor API number. It uses few CPU registers + * internally and hence they need be backed up including + * link register "lr". + * Function signature : void omap_smc1(u32 fn, u32 arg) + */ + +ENTRY(omap_smc1) + stmfd sp!, {r2-r12, lr} + mov r12, r0 + mov r0, r1 + dsb + smc + ldmfd sp!, {r2-r12, pc} +END(omap_smc1) -- cgit v0.10.2 From 97b9ad1633ed3724e0563d250850763d20275da7 Mon Sep 17 00:00:00 2001 From: Francisco Alecrim Date: Wed, 10 Mar 2010 18:52:24 -0800 Subject: omap2: add USB initialization for tusb6010 Based on Kalle's and Tony's patches. Some variables re-organized and unused code removed. Signed-off-by: Kalle Valo Signed-off-by: Francisco Alecrim [tony@atomide.com: this is needed to fix the related tusb6010 DMA API changes] Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c index 4cab052..da9bcb8 100644 --- a/arch/arm/mach-omap2/board-n8x0.c +++ b/arch/arm/mach-omap2/board-n8x0.c @@ -37,6 +37,103 @@ static int slot1_cover_open; static int slot2_cover_open; static struct device *mmc_device; +#define TUSB6010_ASYNC_CS 1 +#define TUSB6010_SYNC_CS 4 +#define TUSB6010_GPIO_INT 58 +#define TUSB6010_GPIO_ENABLE 0 +#define TUSB6010_DMACHAN 0x3f + +#if defined(CONFIG_USB_TUSB6010) || \ + defined(CONFIG_USB_TUSB6010_MODULE) +/* + * Enable or disable power to TUSB6010. When enabling, turn on 3.3 V and + * 1.5 V voltage regulators of PM companion chip. Companion chip will then + * provide then PGOOD signal to TUSB6010 which will release it from reset. + */ +static int tusb_set_power(int state) +{ + int i, retval = 0; + + if (state) { + gpio_set_value(TUSB6010_GPIO_ENABLE, 1); + msleep(1); + + /* Wait until TUSB6010 pulls INT pin down */ + i = 100; + while (i && gpio_get_value(TUSB6010_GPIO_INT)) { + msleep(1); + i--; + } + + if (!i) { + printk(KERN_ERR "tusb: powerup failed\n"); + retval = -ENODEV; + } + } else { + gpio_set_value(TUSB6010_GPIO_ENABLE, 0); + msleep(10); + } + + return retval; +} + +static struct musb_hdrc_config musb_config = { + .multipoint = 1, + .dyn_fifo = 1, + .num_eps = 16, + .ram_bits = 12, +}; + +static struct musb_hdrc_platform_data tusb_data = { +#if defined(CONFIG_USB_MUSB_OTG) + .mode = MUSB_OTG, +#elif defined(CONFIG_USB_MUSB_PERIPHERAL) + .mode = MUSB_PERIPHERAL, +#else /* defined(CONFIG_USB_MUSB_HOST) */ + .mode = MUSB_HOST, +#endif + .set_power = tusb_set_power, + .min_power = 25, /* x2 = 50 mA drawn from VBUS as peripheral */ + .power = 100, /* Max 100 mA VBUS for host mode */ + .config = &musb_config, +}; + +static void __init n8x0_usb_init(void) +{ + int ret = 0; + static char announce[] __initdata = KERN_INFO "TUSB 6010\n"; + + /* PM companion chip power control pin */ + ret = gpio_request(TUSB6010_GPIO_ENABLE, "TUSB6010 enable"); + if (ret != 0) { + printk(KERN_ERR "Could not get TUSB power GPIO%i\n", + TUSB6010_GPIO_ENABLE); + return; + } + gpio_direction_output(TUSB6010_GPIO_ENABLE, 0); + + tusb_set_power(0); + + ret = tusb6010_setup_interface(&tusb_data, TUSB6010_REFCLK_19, 2, + TUSB6010_ASYNC_CS, TUSB6010_SYNC_CS, + TUSB6010_GPIO_INT, TUSB6010_DMACHAN); + if (ret != 0) + goto err; + + printk(announce); + + return; + +err: + gpio_free(TUSB6010_GPIO_ENABLE); +} +#else + +static void __init n8x0_usb_init(void) {} + +#endif /*CONFIG_USB_TUSB6010 */ + + static struct omap2_mcspi_device_config p54spi_mcspi_config = { .turbo_mode = 0, .single_channel = 1, @@ -562,6 +659,7 @@ static void __init n8x0_init_machine(void) n8x0_menelaus_init(); n8x0_onenand_init(); n8x0_mmc_init(); + n8x0_usb_init(); } MACHINE_START(NOKIA_N800, "Nokia N800") diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c index f12af95..d932b14 100644 --- a/arch/arm/mach-omap2/clock2420_data.c +++ b/arch/arm/mach-omap2/clock2420_data.c @@ -1841,6 +1841,7 @@ static struct omap_clk omap2420_clks[] = { CLK(NULL, "aes_ick", &aes_ick, CK_242X), CLK(NULL, "pka_ick", &pka_ick, CK_242X), CLK(NULL, "usb_fck", &usb_fck, CK_242X), + CLK("musb_hdrc", "fck", &osc_ck, CK_242X), }; /* -- cgit v0.10.2 From 79cf5bff25bc30c31fd7e4782c36947ec4bace7f Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 10 Mar 2010 18:55:31 -0800 Subject: omap2: Update n8x0 defconfig to test multi-omap and DMA api changes Recent DMA API changes broke compile for tusb6010. While testing the fixes for tusb6010, I had to update the n8x0 defconfig quite a bit. Might as well merge it while at it to make it more usable as we're using this to test the multi-omap booting between V6 and V7 ARMs. Also, anybody using n8x0 with a current kernel will most likely want to mount root on the MMC instead of the onenand to keep the Maemo install intact. Enable I2C, REGULATOR, MMC, MFD, PM, and USB. Also change the root to /dev/mmcblk0p2 instead of the onenand. Signed-off-by: Tony Lindgren diff --git a/arch/arm/configs/n8x0_defconfig b/arch/arm/configs/n8x0_defconfig index e6f667c..216ad00 100644 --- a/arch/arm/configs/n8x0_defconfig +++ b/arch/arm/configs/n8x0_defconfig @@ -191,6 +191,7 @@ CONFIG_ARCH_OMAP=y # CONFIG_ARCH_OMAP_OTG=y # CONFIG_ARCH_OMAP1 is not set +CONFIG_ARCH_OMAP2PLUS=y CONFIG_ARCH_OMAP2=y # CONFIG_ARCH_OMAP3 is not set # CONFIG_ARCH_OMAP4 is not set @@ -198,8 +199,6 @@ CONFIG_ARCH_OMAP2=y # # OMAP Feature Selections # -# CONFIG_OMAP_DEBUG_POWERDOMAIN is not set -# CONFIG_OMAP_DEBUG_CLOCKDOMAIN is not set CONFIG_OMAP_RESET_CLOCKS=y # CONFIG_OMAP_MUX is not set # CONFIG_OMAP_MCBSP is not set @@ -208,15 +207,13 @@ CONFIG_OMAP_MBOX_FWK=y CONFIG_OMAP_32K_TIMER=y CONFIG_OMAP_32K_TIMER_HZ=128 CONFIG_OMAP_DM_TIMER=y -# CONFIG_OMAP_LL_DEBUG_UART1 is not set -# CONFIG_OMAP_LL_DEBUG_UART2 is not set -CONFIG_OMAP_LL_DEBUG_UART3=y +# CONFIG_OMAP_PM_NONE is not set +CONFIG_OMAP_PM_NOOP=y # CONFIG_MACH_OMAP_GENERIC is not set # # OMAP Core Type # -CONFIG_ARCH_OMAP24XX=y CONFIG_ARCH_OMAP2420=y # CONFIG_ARCH_OMAP2430 is not set @@ -227,6 +224,9 @@ CONFIG_MACH_OMAP2_TUSB6010=y # CONFIG_MACH_OMAP_H4 is not set # CONFIG_MACH_OMAP_APOLLON is not set # CONFIG_MACH_OMAP_2430SDP is not set +CONFIG_MACH_NOKIA_N800=y +CONFIG_MACH_NOKIA_N810=y +CONFIG_MACH_NOKIA_N810_WIMAX=y CONFIG_MACH_NOKIA_N8X0=y # @@ -303,7 +303,7 @@ CONFIG_ALIGNMENT_TRAP=y CONFIG_ZBOOT_ROM_TEXT=0x10C08000 CONFIG_ZBOOT_ROM_BSS=0x10200000 # CONFIG_ZBOOT_ROM is not set -CONFIG_CMDLINE="root=1f03 rootfstype=jffs2 console=ttyS2,115200n8" +CONFIG_CMDLINE="root=/dev/mmcblk0p2 console=ttyS2,115200n8 debug earlyprintk rootwait" # CONFIG_XIP_KERNEL is not set # CONFIG_KEXEC is not set @@ -337,7 +337,14 @@ CONFIG_HAVE_AOUT=y # # Power management options # -# CONFIG_PM is not set +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +# CONFIG_APM_EMULATION is not set +CONFIG_PM_RUNTIME=y +CONFIG_PM_OPS=y CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_NET=y @@ -617,7 +624,55 @@ CONFIG_UNIX98_PTYS=y # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set # CONFIG_TCG_TPM is not set -# CONFIG_I2C is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +# CONFIG_I2C_COMPAT is not set +# CONFIG_I2C_CHARDEV is not set +# CONFIG_I2C_HELPER_AUTO is not set +# CONFIG_I2C_SMBUS is not set + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_DESIGNWARE is not set +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_OCORES is not set +CONFIG_I2C_OMAP=y +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_STUB is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set CONFIG_SPI=y # CONFIG_SPI_DEBUG is not set CONFIG_SPI_MASTER=y @@ -673,15 +728,44 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_CORE is not set +# CONFIG_MFD_88PM860X is not set # CONFIG_MFD_SM501 is not set # CONFIG_MFD_ASIC3 is not set # CONFIG_HTC_EGPIO is not set # CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_TPS65010 is not set +CONFIG_MENELAUS=y +# CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set # CONFIG_MFD_T7L66XB is not set # CONFIG_MFD_TC6387XB is not set # CONFIG_MFD_TC6393XB is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13783 is not set +# CONFIG_AB3100_CORE is not set # CONFIG_EZX_PCAP is not set +# CONFIG_AB4500_CORE is not set +CONFIG_REGULATOR=y +# CONFIG_REGULATOR_DEBUG is not set +# CONFIG_REGULATOR_DUMMY is not set +# CONFIG_REGULATOR_FIXED_VOLTAGE is not set +# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set +# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set +# CONFIG_REGULATOR_BQ24022 is not set +# CONFIG_REGULATOR_MAX1586 is not set +# CONFIG_REGULATOR_MAX8649 is not set +# CONFIG_REGULATOR_MAX8660 is not set +# CONFIG_REGULATOR_LP3971 is not set +# CONFIG_REGULATOR_TPS65023 is not set +# CONFIG_REGULATOR_TPS6507X is not set # CONFIG_MEDIA_SUPPORT is not set # @@ -718,7 +802,10 @@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y CONFIG_USB_DEVICEFS=y CONFIG_USB_DEVICE_CLASS=y # CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_OTG is not set +CONFIG_USB_SUSPEND=y +CONFIG_USB_OTG=y +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set # CONFIG_USB_MON is not set # CONFIG_USB_WUSB is not set # CONFIG_USB_WUSB_CBAF is not set @@ -737,9 +824,10 @@ CONFIG_USB_DEVICE_CLASS=y CONFIG_USB_MUSB_HDRC=y CONFIG_USB_TUSB6010=y # CONFIG_USB_MUSB_HOST is not set -CONFIG_USB_MUSB_PERIPHERAL=y -# CONFIG_USB_MUSB_OTG is not set +# CONFIG_USB_MUSB_PERIPHERAL is not set +CONFIG_USB_MUSB_OTG=y CONFIG_USB_GADGET_MUSB_HDRC=y +CONFIG_USB_MUSB_HDRC_HCD=y # CONFIG_MUSB_PIO_ONLY is not set # CONFIG_USB_INVENTRA_DMA is not set # CONFIG_USB_TI_CPPI_DMA is not set @@ -824,44 +912,77 @@ CONFIG_USB_GADGET_DUALSPEED=y # CONFIG_USB_ZERO is not set # CONFIG_USB_AUDIO is not set CONFIG_USB_ETH=y -# CONFIG_USB_ETH_RNDIS is not set +CONFIG_USB_ETH_RNDIS=y +CONFIG_USB_ETH_EEM=y # CONFIG_USB_GADGETFS is not set # CONFIG_USB_FILE_STORAGE is not set +# CONFIG_USB_MASS_STORAGE is not set # CONFIG_USB_G_SERIAL is not set # CONFIG_USB_MIDI_GADGET is not set # CONFIG_USB_G_PRINTER is not set # CONFIG_USB_CDC_COMPOSITE is not set +# CONFIG_USB_G_NOKIA is not set +# CONFIG_USB_G_MULTI is not set # # OTG and related infrastructure # CONFIG_USB_OTG_UTILS=y # CONFIG_USB_GPIO_VBUS is not set +# CONFIG_ISP1301_OMAP is not set +# CONFIG_USB_ULPI is not set CONFIG_NOP_USB_XCEIV=y -# CONFIG_MMC is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_SDHCI is not set +CONFIG_MMC_OMAP=y +# CONFIG_MMC_SPI is not set # CONFIG_MEMSTICK is not set -# CONFIG_ACCESSIBILITY is not set # CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set CONFIG_RTC_LIB=y # CONFIG_RTC_CLASS is not set # CONFIG_DMADEVICES is not set # CONFIG_AUXDISPLAY is not set -# CONFIG_REGULATOR is not set # CONFIG_UIO is not set + +# +# TI VLYNQ +# # CONFIG_STAGING is not set # # File systems # # CONFIG_EXT2_FS is not set -# CONFIG_EXT3_FS is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set # CONFIG_EXT4_FS is not set +CONFIG_JBD=y +CONFIG_FS_MBCACHE=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set # CONFIG_OCFS2_FS is not set # CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_FILE_LOCKING=y CONFIG_FSNOTIFY=y CONFIG_DNOTIFY=y @@ -886,8 +1007,11 @@ CONFIG_INOTIFY_USER=y # # DOS/FAT/NT Filesystems # +CONFIG_FAT_FS=y # CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" # CONFIG_NTFS_FS is not set # -- cgit v0.10.2 From 9f591fd76afdc0e5192e9ed00a36f8efc0b4dfe6 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 11 Mar 2010 15:53:11 -0300 Subject: perf record: Don't try to find buildids in a zero sized file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixing this symptom: [acme@mica linux-2.6-tip]$ perf record -a -f Fatal: Permission error - are you root? Bus error [acme@mica linux-2.6-tip]$ I.e. if for some reason no data is collected, in this case a non root user trying to do systemwide profiling, no data will be collected, and then we end up trying to mmap a zero sized file and access the file header, b00m. Reported-by: Ingo Molnar Signed-off-by: Arnaldo Carvalho de Melo Cc: Frédéric Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Paul Mackerras Cc: LKML-Reference: <1268333592-30872-1-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index b09d3b2..3b8b638 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -395,6 +395,9 @@ static int process_buildids(void) { u64 size = lseek(output, 0, SEEK_CUR); + if (size == 0) + return 0; + session->fd = output; return __perf_session__process_events(session, post_processing_offset, size - post_processing_offset, -- cgit v0.10.2 From 9e542f37ce20428170010baa36a0ecbfcc0b29bb Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 11 Mar 2010 11:06:56 -0800 Subject: omap: Enable PM_RUNTIME in defconfigs to avoid USB compile errors While waiting for the related USB patch, fix compile by enabling it in the defconfigs. As discussed at: http://thread.gmane.org/gmane.linux.usb.general/27432/focus=4460 Otherwise we'll get errors like: drivers/usb/core/hcd.c:1892: error: 'pm_wq' undeclared (first use in this function) drivers/usb/core/hcd.c:1892: error: (Each undeclared identifier is reported only once drivers/usb/core/hcd.c:1892: error: for each function it appears in.) Signed-off-by: Tony Lindgren diff --git a/arch/arm/configs/cm_t35_defconfig b/arch/arm/configs/cm_t35_defconfig index 893cd26..032b49ba 100644 --- a/arch/arm/configs/cm_t35_defconfig +++ b/arch/arm/configs/cm_t35_defconfig @@ -358,7 +358,7 @@ CONFIG_PM_SLEEP=y CONFIG_SUSPEND=y CONFIG_SUSPEND_FREEZER=y # CONFIG_APM_EMULATION is not set -# CONFIG_PM_RUNTIME is not set +CONFIG_PM_RUNTIME=y CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_NET=y diff --git a/arch/arm/configs/n770_defconfig b/arch/arm/configs/n770_defconfig index 75cae18..de0c28a 100644 --- a/arch/arm/configs/n770_defconfig +++ b/arch/arm/configs/n770_defconfig @@ -308,6 +308,7 @@ CONFIG_PM_SLEEP=y CONFIG_SUSPEND_UP_POSSIBLE=y CONFIG_SUSPEND=y # CONFIG_APM_EMULATION is not set +CONFIG_PM_RUNTIME=y # # Networking diff --git a/arch/arm/configs/omap3_beagle_defconfig b/arch/arm/configs/omap3_beagle_defconfig index c7999f5..5a9e95f 100644 --- a/arch/arm/configs/omap3_beagle_defconfig +++ b/arch/arm/configs/omap3_beagle_defconfig @@ -324,6 +324,7 @@ CONFIG_PM_SLEEP=y CONFIG_SUSPEND=y CONFIG_SUSPEND_FREEZER=y # CONFIG_APM_EMULATION is not set +CONFIG_PM_RUNTIME=y CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_NET=y diff --git a/arch/arm/configs/omap3_defconfig b/arch/arm/configs/omap3_defconfig index 714835e..d6ad921 100644 --- a/arch/arm/configs/omap3_defconfig +++ b/arch/arm/configs/omap3_defconfig @@ -450,7 +450,7 @@ CONFIG_SUSPEND=y # CONFIG_PM_TEST_SUSPEND is not set CONFIG_SUSPEND_FREEZER=y # CONFIG_APM_EMULATION is not set -# CONFIG_PM_RUNTIME is not set +CONFIG_PM_RUNTIME=y CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_NET=y diff --git a/arch/arm/configs/omap3_evm_defconfig b/arch/arm/configs/omap3_evm_defconfig index e2ad859..a6dd6d1 100644 --- a/arch/arm/configs/omap3_evm_defconfig +++ b/arch/arm/configs/omap3_evm_defconfig @@ -340,6 +340,7 @@ CONFIG_PM_SLEEP=y CONFIG_SUSPEND=y CONFIG_SUSPEND_FREEZER=y # CONFIG_APM_EMULATION is not set +CONFIG_PM_RUNTIME=y CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_NET=y diff --git a/arch/arm/configs/omap3_touchbook_defconfig b/arch/arm/configs/omap3_touchbook_defconfig index 74fe6be..968fbaa 100644 --- a/arch/arm/configs/omap3_touchbook_defconfig +++ b/arch/arm/configs/omap3_touchbook_defconfig @@ -368,7 +368,7 @@ CONFIG_SUSPEND=y # CONFIG_PM_TEST_SUSPEND is not set CONFIG_SUSPEND_FREEZER=y # CONFIG_APM_EMULATION is not set -# CONFIG_PM_RUNTIME is not set +CONFIG_PM_RUNTIME=y CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_NET=y diff --git a/arch/arm/configs/omap_3430sdp_defconfig b/arch/arm/configs/omap_3430sdp_defconfig index bb2917e..ddde429 100644 --- a/arch/arm/configs/omap_3430sdp_defconfig +++ b/arch/arm/configs/omap_3430sdp_defconfig @@ -363,6 +363,7 @@ CONFIG_PM_SLEEP=y CONFIG_SUSPEND=y CONFIG_SUSPEND_FREEZER=y # CONFIG_APM_EMULATION is not set +CONFIG_PM_RUNTIME=y CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_NET=y diff --git a/arch/arm/configs/omap_3630sdp_defconfig b/arch/arm/configs/omap_3630sdp_defconfig index d25c3d4..609f348 100644 --- a/arch/arm/configs/omap_3630sdp_defconfig +++ b/arch/arm/configs/omap_3630sdp_defconfig @@ -361,7 +361,7 @@ CONFIG_SUSPEND=y # CONFIG_PM_TEST_SUSPEND is not set CONFIG_SUSPEND_FREEZER=y # CONFIG_APM_EMULATION is not set -# CONFIG_PM_RUNTIME is not set +CONFIG_PM_RUNTIME=y CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_NET=y diff --git a/arch/arm/configs/omap_h2_1610_defconfig b/arch/arm/configs/omap_h2_1610_defconfig index 5231895..91ef2ed 100644 --- a/arch/arm/configs/omap_h2_1610_defconfig +++ b/arch/arm/configs/omap_h2_1610_defconfig @@ -331,6 +331,7 @@ CONFIG_PM_SLEEP=y CONFIG_SUSPEND=y CONFIG_SUSPEND_FREEZER=y # CONFIG_APM_EMULATION is not set +CONFIG_PM_RUNTIME=y CONFIG_ARCH_SUSPEND_POSSIBLE=y # diff --git a/arch/arm/configs/omap_zoom2_defconfig b/arch/arm/configs/omap_zoom2_defconfig index a82e813..f5c6e11 100644 --- a/arch/arm/configs/omap_zoom2_defconfig +++ b/arch/arm/configs/omap_zoom2_defconfig @@ -343,6 +343,7 @@ CONFIG_SUSPEND=y # CONFIG_PM_TEST_SUSPEND is not set CONFIG_SUSPEND_FREEZER=y # CONFIG_APM_EMULATION is not set +CONFIG_PM_RUNTIME=y CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_NET=y diff --git a/arch/arm/configs/omap_zoom3_defconfig b/arch/arm/configs/omap_zoom3_defconfig index ff8ac3d..ea9a501 100644 --- a/arch/arm/configs/omap_zoom3_defconfig +++ b/arch/arm/configs/omap_zoom3_defconfig @@ -361,7 +361,7 @@ CONFIG_SUSPEND=y # CONFIG_PM_TEST_SUSPEND is not set CONFIG_SUSPEND_FREEZER=y # CONFIG_APM_EMULATION is not set -# CONFIG_PM_RUNTIME is not set +CONFIG_PM_RUNTIME=y CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_NET=y diff --git a/arch/arm/configs/rx51_defconfig b/arch/arm/configs/rx51_defconfig index 193bd33..45135ff 100644 --- a/arch/arm/configs/rx51_defconfig +++ b/arch/arm/configs/rx51_defconfig @@ -322,6 +322,7 @@ CONFIG_PM_SLEEP=y CONFIG_SUSPEND=y CONFIG_SUSPEND_FREEZER=y # CONFIG_APM_EMULATION is not set +CONFIG_PM_RUNTIME=y CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_NET=y -- cgit v0.10.2 From f0dc117abdfa9a0e96c3d013d836460ef3cd08c7 Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Wed, 3 Mar 2010 12:27:52 +0000 Subject: IPoIB: Fix TX queue lockup with mixed UD/CM traffic The IPoIB UD QP reports send completions to priv->send_cq, which is usually left unarmed; it only gets armed when the number of outstanding send requests reaches the size of the TX queue. This arming is done only in the send path for the UD QP. However, when sending CM packets, the net queue may be stopped for the same reasons but no measures are taken to recover the UD path from a lockup. Consider this scenario: a host sends high rate of both CM and UD packets, with a TX queue length of N. If at some time the number of outstanding UD packets is more than N/2 and the overall outstanding packets is N-1, and CM sends a packet (making the number of outstanding sends equal N), the TX queue will be stopped. When all the CM packets complete, the number of outstanding packets will still be higher than N/2 so the TX queue will not be restarted. Fix this by calling ib_req_notify_cq() when the queue is stopped in the CM path. Signed-off-by: Eli Cohen Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 83a7751..6e3cc86 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c @@ -752,6 +752,8 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_ if (++priv->tx_outstanding == ipoib_sendq_size) { ipoib_dbg(priv, "TX ring 0x%x full, stopping kernel net queue\n", tx->qp->qp_num); + if (ib_req_notify_cq(priv->send_cq, IB_CQ_NEXT_COMP)) + ipoib_warn(priv, "request notify on send CQ failed\n"); netif_stop_queue(dev); } } -- cgit v0.10.2 From a48f509b26cec53338f4b0abd52ecea35e3974b8 Mon Sep 17 00:00:00 2001 From: Or Gerlitz Date: Thu, 4 Mar 2010 13:17:37 +0000 Subject: IPoIB: Include return code in trace message for ib_post_send() failures Print the return code of ib_post_send() if it fails to make these debugging messages more useful. Signed-off-by: Or Gerlitz Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 6e3cc86..bc65837 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c @@ -708,6 +708,7 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_ struct ipoib_dev_priv *priv = netdev_priv(dev); struct ipoib_cm_tx_buf *tx_req; u64 addr; + int rc; if (unlikely(skb->len > tx->mtu)) { ipoib_warn(priv, "packet len %d (> %d) too long to send, dropping\n", @@ -739,9 +740,10 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_ tx_req->mapping = addr; - if (unlikely(post_send(priv, tx, tx->tx_head & (ipoib_sendq_size - 1), - addr, skb->len))) { - ipoib_warn(priv, "post_send failed\n"); + rc = post_send(priv, tx, tx->tx_head & (ipoib_sendq_size - 1), + addr, skb->len); + if (unlikely(rc)) { + ipoib_warn(priv, "post_send failed, error %d\n", rc); ++dev->stats.tx_errors; ib_dma_unmap_single(priv->ca, addr, skb->len, DMA_TO_DEVICE); dev_kfree_skb_any(skb); diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index 8c91d9f..5df40b1 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c @@ -529,7 +529,7 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb, { struct ipoib_dev_priv *priv = netdev_priv(dev); struct ipoib_tx_buf *tx_req; - int hlen; + int hlen, rc; void *phead; if (skb_is_gso(skb)) { @@ -585,9 +585,10 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb, netif_stop_queue(dev); } - if (unlikely(post_send(priv, priv->tx_head & (ipoib_sendq_size - 1), - address->ah, qpn, tx_req, phead, hlen))) { - ipoib_warn(priv, "post_send failed\n"); + rc = post_send(priv, priv->tx_head & (ipoib_sendq_size - 1), + address->ah, qpn, tx_req, phead, hlen); + if (unlikely(rc)) { + ipoib_warn(priv, "post_send failed, error %d\n", rc); ++dev->stats.tx_errors; --priv->tx_outstanding; ipoib_dma_unmap_tx(priv->ca, tx_req); -- cgit v0.10.2 From 070e140c4c536df33a9870318791b2ca8f7dbfcf Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Thu, 4 Mar 2010 18:18:18 +0000 Subject: IB/mad: Ignore iWARP devices on device removal When an iWARP device is unloaded, the ib_mad module logs errors. It should be ignoring iWARP devices on device removal just like it does on device add. Signed-off-by: Steve Wise Acked-by: Sean Hefty Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index 58463da..e351b15 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c @@ -2953,6 +2953,9 @@ static void ib_mad_remove_device(struct ib_device *device) { int i, num_ports, cur_port; + if (rdma_node_get_transport(device->node_type) != RDMA_TRANSPORT_IB) + return; + if (device->node_type == RDMA_NODE_IB_SWITCH) { num_ports = 1; cur_port = 0; -- cgit v0.10.2 From 69960a275efc9d82797bbbe2460a2d6c9cace314 Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Wed, 3 Mar 2010 15:06:34 +0000 Subject: RDMA/cxgb3: Wait at least one schedule cycle during device removal During a hot-plug LLD removal event or an EEH error event, iw_cxgb3 must ensure that any/all threads that might be in a cxgb3 exported function must return from the function before iw_cxgb3 returns from its event processing. Do this by calling synchronize_net(). Signed-off-by: Steve Wise Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/cxgb3/iwch.c b/drivers/infiniband/hw/cxgb3/iwch.c index ee1d8b4..63f975f 100644 --- a/drivers/infiniband/hw/cxgb3/iwch.c +++ b/drivers/infiniband/hw/cxgb3/iwch.c @@ -189,6 +189,7 @@ static void close_rnic_dev(struct t3cdev *tdev) list_for_each_entry_safe(dev, tmp, &dev_list, entry) { if (dev->rdev.t3cdev_p == tdev) { dev->rdev.flags = CXIO_ERROR_FATAL; + synchronize_net(); cancel_delayed_work_sync(&dev->db_drop_task); list_del(&dev->entry); iwch_unregister_device(dev); @@ -217,6 +218,7 @@ static void iwch_event_handler(struct t3cdev *tdev, u32 evt, u32 port_id) switch (evt) { case OFFLOAD_STATUS_DOWN: { rdev->flags = CXIO_ERROR_FATAL; + synchronize_net(); event.event = IB_EVENT_DEVICE_FATAL; dispatch = 1; break; -- cgit v0.10.2 From 21b90340207d324f92111e25ead1752533eeb9ca Mon Sep 17 00:00:00 2001 From: Thomas Weber Date: Thu, 25 Feb 2010 09:40:19 +0000 Subject: OMAP2: serial.c: Fix number of uarts in early_init The omap_serial_early_init prints the following errors: Could not get uart4_ick Could not get uart4_fck because all the uarts available in omap_uart[] will be initialized. Only omap4430 and omap3630 have 4 uarts at the moment. This patch reduces the number of uarts when cpu is not omap4430 or omap3630. Signed-off-by: Thomas Weber Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index b79bc89..da77930 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -644,16 +644,21 @@ static void serial_out_override(struct uart_port *up, int offset, int value) } void __init omap_serial_early_init(void) { - int i; + int i, nr_ports; char name[16]; + if (!(cpu_is_omap3630() || cpu_is_omap4430())) + nr_ports = 3; + else + nr_ports = ARRAY_SIZE(omap_uart); + /* * Make sure the serial ports are muxed on at this point. * You have to mux them off in device drivers later on * if not needed. */ - for (i = 0; i < ARRAY_SIZE(omap_uart); i++) { + for (i = 0; i < nr_ports; i++) { struct omap_uart_state *uart = &omap_uart[i]; struct platform_device *pdev = &uart->pdev; struct device *dev = &pdev->dev; @@ -669,17 +674,17 @@ void __init omap_serial_early_init(void) continue; } - sprintf(name, "uart%d_ick", i+1); + sprintf(name, "uart%d_ick", i + 1); uart->ick = clk_get(NULL, name); if (IS_ERR(uart->ick)) { - printk(KERN_ERR "Could not get uart%d_ick\n", i+1); + printk(KERN_ERR "Could not get uart%d_ick\n", i + 1); uart->ick = NULL; } sprintf(name, "uart%d_fck", i+1); uart->fck = clk_get(NULL, name); if (IS_ERR(uart->fck)) { - printk(KERN_ERR "Could not get uart%d_fck\n", i+1); + printk(KERN_ERR "Could not get uart%d_fck\n", i + 1); uart->fck = NULL; } -- cgit v0.10.2 From 26e4248359c6bf2da4a07767f6e12f1df426ab0a Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Mon, 25 Jan 2010 18:27:21 -0600 Subject: omap2/3/4: mailbox: remove compiler warning Remove a compiler warning in device-specific mailbox module. Signed-off-by: Suman Anna Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/mailbox.c b/arch/arm/mach-omap2/mailbox.c index 52a981c..318f363 100644 --- a/arch/arm/mach-omap2/mailbox.c +++ b/arch/arm/mach-omap2/mailbox.c @@ -430,19 +430,19 @@ static int __devinit omap2_mbox_probe(struct platform_device *pdev) if (unlikely(!res)) { dev_err(&pdev->dev, "invalid irq resource\n"); ret = -ENODEV; - goto err_iva1; + omap_mbox_unregister(&mbox_dsp_info); + goto err_dsp; } mbox_iva_info.irq = res->start; ret = omap_mbox_register(&pdev->dev, &mbox_iva_info); - if (ret) - goto err_iva1; + if (ret) { + omap_mbox_unregister(&mbox_dsp_info); + goto err_dsp; + } } #endif return 0; -err_iva1: - omap_mbox_unregister(&mbox_dsp_info); - err_dsp: iounmap(mbox_base); return ret; -- cgit v0.10.2 From 29b9a218d0be8e207ddeacdc68eb1e4b7f54b85a Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Fri, 26 Feb 2010 10:25:28 +0000 Subject: omap: pass the reboot command to the boot loader This patch follows the commit be093beb608edf821b45fe00a8a080fb5c6ed4af by Russell King: OMAP wishes to pass state to the boot loader upon reboot in order to instruct it whether to wait for USB-based reflashing or not. There is already a facility to do this via the reboot() syscall, except we ignore the string passed to machine_restart(). The patch adds the missing parameter to omap1_arch_reset() and omap_prcm_arch_reset(), and modifies the latter to pass the reboot command parameter to the boot loader instead of reboot mode (which is for kernel internal use only and cannot be modified by the userspace). Signed-off-by: Aaro Koskinen Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c index 81872aa..9537f6f 100644 --- a/arch/arm/mach-omap2/prcm.c +++ b/arch/arm/mach-omap2/prcm.c @@ -133,7 +133,7 @@ u32 omap_prcm_get_reset_sources(void) EXPORT_SYMBOL(omap_prcm_get_reset_sources); /* Resets clock rates and reboots the system. Only called from system.h */ -void omap_prcm_arch_reset(char mode) +void omap_prcm_arch_reset(char mode, const char *cmd) { s16 prcm_offs = 0; @@ -145,7 +145,7 @@ void omap_prcm_arch_reset(char mode) u32 l; prcm_offs = OMAP3430_GR_MOD; - l = ('B' << 24) | ('M' << 16) | mode; + l = ('B' << 24) | ('M' << 16) | (cmd ? (u8)*cmd : 0); /* Reserve the first word in scratchpad for communicating * with the boot ROM. A pointer to a data structure * describing the boot process can be stored there, diff --git a/arch/arm/plat-omap/include/plat/prcm.h b/arch/arm/plat-omap/include/plat/prcm.h index d6a0e27..9fbd914 100644 --- a/arch/arm/plat-omap/include/plat/prcm.h +++ b/arch/arm/plat-omap/include/plat/prcm.h @@ -24,7 +24,7 @@ #define __ASM_ARM_ARCH_OMAP_PRCM_H u32 omap_prcm_get_reset_sources(void); -void omap_prcm_arch_reset(char mode); +void omap_prcm_arch_reset(char mode, const char *cmd); int omap2_cm_wait_idlest(void __iomem *reg, u32 mask, u8 idlest, const char *name); diff --git a/arch/arm/plat-omap/include/plat/system.h b/arch/arm/plat-omap/include/plat/system.h index c58a4ef..d0a119f 100644 --- a/arch/arm/plat-omap/include/plat/system.h +++ b/arch/arm/plat-omap/include/plat/system.h @@ -22,7 +22,7 @@ static inline void arch_idle(void) cpu_do_idle(); } -static inline void omap1_arch_reset(char mode) +static inline void omap1_arch_reset(char mode, const char *cmd) { /* * Workaround for 5912/1611b bug mentioned in sprz209d.pdf p. 28 @@ -43,9 +43,9 @@ static inline void omap1_arch_reset(char mode) static inline void arch_reset(char mode, const char *cmd) { if (!cpu_class_is_omap2()) - omap1_arch_reset(mode); + omap1_arch_reset(mode, cmd); else - omap_prcm_arch_reset(mode); + omap_prcm_arch_reset(mode, cmd); } #endif -- cgit v0.10.2 From 00df9384ccfa02c062449e381c051bcfe97cdf6f Mon Sep 17 00:00:00 2001 From: Andrea Gelmini Date: Sat, 27 Feb 2010 16:51:38 +0000 Subject: omap: Checkpatch cleanup for blizzard.h arch/arm/plat-omap/include/plat/blizzard.h:9: ERROR: spaces prohibited around that ':' (ctx:WxW) Signed-off-by: Andrea Gelmini Signed-off-by: Tony Lindgren diff --git a/arch/arm/plat-omap/include/plat/blizzard.h b/arch/arm/plat-omap/include/plat/blizzard.h index 8d160f1..56e7f2e 100644 --- a/arch/arm/plat-omap/include/plat/blizzard.h +++ b/arch/arm/plat-omap/include/plat/blizzard.h @@ -6,7 +6,7 @@ struct blizzard_platform_data { void (*power_down)(struct device *dev); unsigned long (*get_clock_rate)(struct device *dev); - unsigned te_connected : 1; + unsigned te_connected:1; }; #endif -- cgit v0.10.2 From 228893f9d2b70a7416267050ce03bfd9eb624713 Mon Sep 17 00:00:00 2001 From: Enric Balletbo i Serra Date: Mon, 1 Mar 2010 11:18:08 +0000 Subject: omap3: Fix support for the LEDs connected to GPIO outputs on IGEP v2board Select CONFIG_LEDS_GPIO to enable IGEP v2 LED support and control of supported LEDs from userspace. Otherwise GPIO LEDs are exported as GPIO 26, 27 and 28 using the gpiolib framework. Signed-off-by: Enric Balletbo i Serra Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c index 4f1accf..3c7789d 100644 --- a/arch/arm/mach-omap2/board-igep0020.c +++ b/arch/arm/mach-omap2/board-igep0020.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include @@ -39,8 +38,8 @@ #define IGEP2_SMSC911X_CS 5 #define IGEP2_SMSC911X_GPIO 176 #define IGEP2_GPIO_USBH_NRESET 24 -#define IGEP2_GPIO_LED0_RED 26 -#define IGEP2_GPIO_LED0_GREEN 27 +#define IGEP2_GPIO_LED0_GREEN 26 +#define IGEP2_GPIO_LED0_RED 27 #define IGEP2_GPIO_LED1_RED 28 #define IGEP2_GPIO_DVI_PUP 170 #define IGEP2_GPIO_WIFI_NPD 94 @@ -355,34 +354,50 @@ static void __init igep2_display_init(void) gpio_direction_output(IGEP2_GPIO_DVI_PUP, 1)) pr_err("IGEP v2: Could not obtain gpio GPIO_DVI_PUP\n"); } -#ifdef CONFIG_LEDS_TRIGGERS -static struct gpio_led gpio_leds[] = { + +#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) +#include + +static struct gpio_led igep2_gpio_leds[] = { { - .name = "GPIO_LED1_RED", + .name = "led0:red", + .gpio = IGEP2_GPIO_LED0_RED, + }, + { + .name = "led0:green", .default_trigger = "heartbeat", + .gpio = IGEP2_GPIO_LED0_GREEN, + }, + { + .name = "led1:red", .gpio = IGEP2_GPIO_LED1_RED, }, }; -static struct gpio_led_platform_data gpio_leds_info = { - .leds = gpio_leds, - .num_leds = ARRAY_SIZE(gpio_leds), +static struct gpio_led_platform_data igep2_led_pdata = { + .leds = igep2_gpio_leds, + .num_leds = ARRAY_SIZE(igep2_gpio_leds), }; -static struct platform_device leds_gpio = { +static struct platform_device igep2_led_device = { .name = "leds-gpio", .id = -1, .dev = { - .platform_data = &gpio_leds_info, + .platform_data = &igep2_led_pdata, }, }; + +static void __init igep2_init_led(void) +{ + platform_device_register(&igep2_led_device); +} + +#else +static inline void igep2_init_led(void) {} #endif static struct platform_device *igep2_devices[] __initdata = { &igep2_dss_device, -#ifdef CONFIG_LEDS_TRIGGERS - &leds_gpio, -#endif }; static void __init igep2_init_irq(void) @@ -471,31 +486,34 @@ static void __init igep2_init(void) usb_ehci_init(&ehci_pdata); igep2_flash_init(); + igep2_init_led(); igep2_display_init(); igep2_init_smsc911x(); /* GPIO userspace leds */ - if ((gpio_request(IGEP2_GPIO_LED0_RED, "GPIO_LED0_RED") == 0) && +#if !defined(CONFIG_LEDS_GPIO) && !defined(CONFIG_LEDS_GPIO_MODULE) + if ((gpio_request(IGEP2_GPIO_LED0_RED, "led0:red") == 0) && (gpio_direction_output(IGEP2_GPIO_LED0_RED, 1) == 0)) { gpio_export(IGEP2_GPIO_LED0_RED, 0); gpio_set_value(IGEP2_GPIO_LED0_RED, 0); } else pr_warning("IGEP v2: Could not obtain gpio GPIO_LED0_RED\n"); - if ((gpio_request(IGEP2_GPIO_LED0_GREEN, "GPIO_LED0_GREEN") == 0) && + if ((gpio_request(IGEP2_GPIO_LED0_GREEN, "led0:green") == 0) && (gpio_direction_output(IGEP2_GPIO_LED0_GREEN, 1) == 0)) { gpio_export(IGEP2_GPIO_LED0_GREEN, 0); gpio_set_value(IGEP2_GPIO_LED0_GREEN, 0); } else pr_warning("IGEP v2: Could not obtain gpio GPIO_LED0_GREEN\n"); -#ifndef CONFIG_LEDS_TRIGGERS - if ((gpio_request(IGEP2_GPIO_LED1_RED, "GPIO_LED1_RED") == 0) && + + if ((gpio_request(IGEP2_GPIO_LED1_RED, "led1:red") == 0) && (gpio_direction_output(IGEP2_GPIO_LED1_RED, 1) == 0)) { gpio_export(IGEP2_GPIO_LED1_RED, 0); gpio_set_value(IGEP2_GPIO_LED1_RED, 0); } else pr_warning("IGEP v2: Could not obtain gpio GPIO_LED1_RED\n"); #endif + /* GPIO W-LAN + Bluetooth combo module */ if ((gpio_request(IGEP2_GPIO_WIFI_NPD, "GPIO_WIFI_NPD") == 0) && (gpio_direction_output(IGEP2_GPIO_WIFI_NPD, 1) == 0)) { -- cgit v0.10.2 From f00d649703fbedbdeb33d63c4c4731656e11297c Mon Sep 17 00:00:00 2001 From: Sergio Aguirre Date: Wed, 3 Mar 2010 16:21:08 +0000 Subject: omap: Fix gpio_resume_after_retention For omap4 case, this was wrongly writing GPIO_LEVELDETECTx registers with OMAP24XX_ offset and OMAP4_ offset. Bug introduced in commit: commit 3f1686a9bfe74979c6ad538c78039730f665f77e Author: Tony Lindgren Date: Mon Feb 15 09:27:25 2010 -0800 omap: Fix gpio.c for multi-omap for omap4 Signed-off-by: Sergio Aguirre Signed-off-by: Tony Lindgren diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 337199e..76a347b 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -2140,18 +2140,18 @@ void omap2_gpio_resume_after_retention(void) if (gen) { u32 old0, old1; - if (cpu_is_omap24xx() || cpu_is_omap44xx()) { + if (cpu_is_omap24xx() || cpu_is_omap34xx()) { old0 = __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0); old1 = __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1); - __raw_writel(old0 | gen, bank->base + + __raw_writel(old0 | gen, bank->base + OMAP24XX_GPIO_LEVELDETECT0); - __raw_writel(old1 | gen, bank->base + + __raw_writel(old1 | gen, bank->base + OMAP24XX_GPIO_LEVELDETECT1); - __raw_writel(old0, bank->base + + __raw_writel(old0, bank->base + OMAP24XX_GPIO_LEVELDETECT0); - __raw_writel(old1, bank->base + + __raw_writel(old1, bank->base + OMAP24XX_GPIO_LEVELDETECT1); } -- cgit v0.10.2 From 883c699241f48667ff59277d8c20790868fd4829 Mon Sep 17 00:00:00 2001 From: Faisal Latif Date: Tue, 2 Mar 2010 17:22:51 -0600 Subject: RDMA/nes: Set assume_aligned_header bit Set assume_aligned_header bit in QP context as requested by hardware group. Signed-off-by: Faisal Latif Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index 815725f..6992829 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c @@ -1323,6 +1323,7 @@ static struct ib_qp *nes_create_qp(struct ib_pd *ibpd, nesqp->nesqp_context->aeq_token_low = cpu_to_le32((u32)((unsigned long)(nesqp))); nesqp->nesqp_context->aeq_token_high = cpu_to_le32((u32)(upper_32_bits((unsigned long)(nesqp)))); nesqp->nesqp_context->ird_ord_sizes = cpu_to_le32(NES_QPCONTEXT_ORDIRD_ALSMM | + NES_QPCONTEXT_ORDIRD_AAH | ((((u32)nesadapter->max_irrq_wr) << NES_QPCONTEXT_ORDIRD_IRDSIZE_SHIFT) & NES_QPCONTEXT_ORDIRD_IRDSIZE_MASK)); if (disable_mpa_crc) { -- cgit v0.10.2 From 9f29006ae8c85746e5a52d557f689359149a0793 Mon Sep 17 00:00:00 2001 From: Chien Tung Date: Wed, 3 Mar 2010 19:13:28 +0000 Subject: RDMA/nes: Clear stall bit before destroying NIC QP Clear the stall bit to drop any incoming packets while destroying NIC QP. This will prevent a chip resource leak. Signed-off-by: Chien Tung Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c index ce7f538..9250755 100644 --- a/drivers/infiniband/hw/nes/nes_hw.c +++ b/drivers/infiniband/hw/nes/nes_hw.c @@ -1899,9 +1899,14 @@ void nes_destroy_nic_qp(struct nes_vnic *nesvnic) u16 wqe_fragment_index; u64 wqe_frag; u32 cqp_head; + u32 wqm_cfg0; unsigned long flags; int ret; + /* clear wqe stall before destroying NIC QP */ + wqm_cfg0 = nes_read_indexed(nesdev, NES_IDX_WQM_CONFIG0); + nes_write_indexed(nesdev, NES_IDX_WQM_CONFIG0, wqm_cfg0 & 0xFFFF7FFF); + /* Free remaining NIC receive buffers */ while (nesvnic->nic.rq_head != nesvnic->nic.rq_tail) { nic_rqe = &nesvnic->nic.rq_vbase[nesvnic->nic.rq_tail]; @@ -2020,6 +2025,9 @@ void nes_destroy_nic_qp(struct nes_vnic *nesvnic) pci_free_consistent(nesdev->pcidev, nesvnic->nic_mem_size, nesvnic->nic_vbase, nesvnic->nic_pbase); + + /* restore old wqm_cfg0 value */ + nes_write_indexed(nesdev, NES_IDX_WQM_CONFIG0, wqm_cfg0); } /** diff --git a/drivers/infiniband/hw/nes/nes_hw.h b/drivers/infiniband/hw/nes/nes_hw.h index 9b1e7f8..bbbfe9f 100644 --- a/drivers/infiniband/hw/nes/nes_hw.h +++ b/drivers/infiniband/hw/nes/nes_hw.h @@ -160,6 +160,7 @@ enum indexed_regs { NES_IDX_ENDNODE0_NSTAT_TX_OCTETS_HI = 0x7004, NES_IDX_ENDNODE0_NSTAT_TX_FRAMES_LO = 0x7008, NES_IDX_ENDNODE0_NSTAT_TX_FRAMES_HI = 0x700c, + NES_IDX_WQM_CONFIG0 = 0x5000, NES_IDX_WQM_CONFIG1 = 0x5004, NES_IDX_CM_CONFIG = 0x5100, NES_IDX_NIC_LOGPORT_TO_PHYPORT = 0x6000, -- cgit v0.10.2 From 8185e468446e1e2b383bd61210702fffaed3ddc0 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Wed, 3 Mar 2010 16:24:53 +0000 Subject: omap: mach-omap2/io.c: fix function declarations Get rid of the following warnings: warning: non-ANSI function declaration of function [...] Signed-off-by: Aaro Koskinen Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 402e8f0..ae89d55 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -237,7 +237,7 @@ static void __init _omap2_map_common_io(void) } #ifdef CONFIG_ARCH_OMAP2420 -void __init omap242x_map_common_io() +void __init omap242x_map_common_io(void) { iotable_init(omap24xx_io_desc, ARRAY_SIZE(omap24xx_io_desc)); iotable_init(omap242x_io_desc, ARRAY_SIZE(omap242x_io_desc)); @@ -246,7 +246,7 @@ void __init omap242x_map_common_io() #endif #ifdef CONFIG_ARCH_OMAP2430 -void __init omap243x_map_common_io() +void __init omap243x_map_common_io(void) { iotable_init(omap24xx_io_desc, ARRAY_SIZE(omap24xx_io_desc)); iotable_init(omap243x_io_desc, ARRAY_SIZE(omap243x_io_desc)); @@ -255,7 +255,7 @@ void __init omap243x_map_common_io() #endif #ifdef CONFIG_ARCH_OMAP3 -void __init omap34xx_map_common_io() +void __init omap34xx_map_common_io(void) { iotable_init(omap34xx_io_desc, ARRAY_SIZE(omap34xx_io_desc)); _omap2_map_common_io(); @@ -263,7 +263,7 @@ void __init omap34xx_map_common_io() #endif #ifdef CONFIG_ARCH_OMAP4 -void __init omap44xx_map_common_io() +void __init omap44xx_map_common_io(void) { iotable_init(omap44xx_io_desc, ARRAY_SIZE(omap44xx_io_desc)); _omap2_map_common_io(); -- cgit v0.10.2 From 03d5671dde04a186471969d73cfc89ee02664c2c Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Wed, 10 Mar 2010 11:13:53 +0000 Subject: omap3: pandora: add missing i2c3 board_info This will allow BQ27500 fuel gauge to function. Signed-off-by: Grazvydas Ignotas Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c index 51a5315..395d049 100644 --- a/arch/arm/mach-omap2/board-omap3pandora.c +++ b/arch/arm/mach-omap2/board-omap3pandora.c @@ -459,12 +459,20 @@ static struct i2c_board_info __initdata omap3pandora_i2c_boardinfo[] = { }, }; +static struct i2c_board_info __initdata omap3pandora_i2c3_boardinfo[] = { + { + I2C_BOARD_INFO("bq27500", 0x55), + .flags = I2C_CLIENT_WAKE, + }, +}; + static int __init omap3pandora_i2c_init(void) { omap_register_i2c_bus(1, 2600, omap3pandora_i2c_boardinfo, ARRAY_SIZE(omap3pandora_i2c_boardinfo)); /* i2c2 pins are not connected */ - omap_register_i2c_bus(3, 100, NULL, 0); + omap_register_i2c_bus(3, 100, omap3pandora_i2c3_boardinfo, + ARRAY_SIZE(omap3pandora_i2c3_boardinfo)); return 0; } -- cgit v0.10.2 From 54c44fb7df4774280a2deb4ba191cbab84602413 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Wed, 10 Mar 2010 17:16:30 +0000 Subject: OMAP2: cpu_is_omap2*: fix compile-time removal of unused code Currently if omap2420 is defined but not omap2430, cpu_is_omap2430() is still defined as a macro, instead of #define'd to zero. This results in conditional cpu_is_omap2430() code still being compiled, and leads to possible compile/link errors. In particular for hwmod init. To fix, add extra #ifdefs to CPU check macros to ensure that the is_omap* macros are zero for each OMAP2 if they are not configured into the kernel. Tested-by: Santosh Shilimkar Signed-off-by: Kevin Hilman Signed-off-by: Tony Lindgren diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h index ed8786c..7514174 100644 --- a/arch/arm/plat-omap/include/plat/cpu.h +++ b/arch/arm/plat-omap/include/plat/cpu.h @@ -167,10 +167,14 @@ IS_OMAP_SUBCLASS(443x, 0x443) #if defined(MULTI_OMAP2) # if defined(CONFIG_ARCH_OMAP2) # undef cpu_is_omap24xx -# undef cpu_is_omap242x -# undef cpu_is_omap243x # define cpu_is_omap24xx() is_omap24xx() +# endif +# if defined (CONFIG_ARCH_OMAP2420) +# undef cpu_is_omap242x # define cpu_is_omap242x() is_omap242x() +# endif +# if defined (CONFIG_ARCH_OMAP2430) +# undef cpu_is_omap243x # define cpu_is_omap243x() is_omap243x() # endif # if defined(CONFIG_ARCH_OMAP3) -- cgit v0.10.2 From aa4b1f6e83aaf20997edc4c10e03baf834343e5a Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Wed, 10 Mar 2010 17:16:31 +0000 Subject: OMAP4: fix temporary hacks that break multi-omap PM When building for multi-omap, and OMAP4 is enabled, CONFIG_ARCH_OMAP4 will be true and prevent included code from building/running for OMAP2/3 as well. This problem exists in io.c where some hwmod/PM/SDRC init code is prevented from running even on OMAP2/3 when OMAP4 is included in a multi-OMAP build. A quick glance suggests that this #ifndef is no longer needed in most of the cases. In the remaining cases, the function is wrapped with "if (cpu_is_omap24xx() || cpu_is_omap34xx())" which will be optimized out for OMAP4-only builds. Note that this is only a short-term fix. Longer-term, OMAP4 needs to create init functions for SDRC and hwmod late-init. Tested-by: Santosh Shilimkar Signed-off-by: Kevin Hilman Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index ae89d55..87f676a 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -309,7 +309,6 @@ void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0, { pwrdm_init(powerdomains_omap); clkdm_init(clockdomains_omap, clkdm_autodeps); -#ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once the clkdev is ready */ if (cpu_is_omap242x()) omap2420_hwmod_init(); else if (cpu_is_omap243x()) @@ -319,7 +318,6 @@ void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0, omap2_mux_init(); /* The OPP tables have to be registered before a clk init */ omap_pm_if_early_init(mpu_opps, dsp_opps, l3_opps); -#endif if (cpu_is_omap2420()) omap2420_clk_init(); @@ -333,11 +331,12 @@ void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0, pr_err("Could not init clock framework - unknown CPU\n"); omap_serial_early_init(); -#ifndef CONFIG_ARCH_OMAP4 - omap_hwmod_late_init(); + if (cpu_is_omap24xx() || cpu_is_omap34xx()) /* FIXME: OMAP4 */ + omap_hwmod_late_init(); omap_pm_if_init(); - omap2_sdrc_init(sdrc_cs0, sdrc_cs1); - _omap2_init_reprogram_sdrc(); -#endif + if (cpu_is_omap24xx() || cpu_is_omap34xx()) { + omap2_sdrc_init(sdrc_cs0, sdrc_cs1); + _omap2_init_reprogram_sdrc(); + } gpmc_init(); } -- cgit v0.10.2 From 964ad81cbd933e5fa310faeec1e923c14651284b Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 12 Mar 2010 00:00:17 -0800 Subject: ipconfig: Handle devices which take some time to come up. Some network devices, particularly USB ones, take several seconds to fully init and appear in the device list. If the user turned ipconfig on, they are using it for NFS root or some other early booting purpose. So it makes no sense to just flat out fail immediately if the device isn't found. It also doesn't make sense to just jack up the initial wait to something crazy like 10 seconds. Instead, poll immediately, and then periodically once a second, waiting for a usable device to appear. Fail after 12 seconds. Signed-off-by: David S. Miller Tested-by: Christian Pellegrin diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index 10a6a60..6789092 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c @@ -187,6 +187,16 @@ struct ic_device { static struct ic_device *ic_first_dev __initdata = NULL;/* List of open device */ static struct net_device *ic_dev __initdata = NULL; /* Selected device */ +static bool __init ic_device_match(struct net_device *dev) +{ + if (user_dev_name[0] ? !strcmp(dev->name, user_dev_name) : + (!(dev->flags & IFF_LOOPBACK) && + (dev->flags & (IFF_POINTOPOINT|IFF_BROADCAST)) && + strncmp(dev->name, "dummy", 5))) + return true; + return false; +} + static int __init ic_open_devs(void) { struct ic_device *d, **last; @@ -207,10 +217,7 @@ static int __init ic_open_devs(void) for_each_netdev(&init_net, dev) { if (dev->flags & IFF_LOOPBACK) continue; - if (user_dev_name[0] ? !strcmp(dev->name, user_dev_name) : - (!(dev->flags & IFF_LOOPBACK) && - (dev->flags & (IFF_POINTOPOINT|IFF_BROADCAST)) && - strncmp(dev->name, "dummy", 5))) { + if (ic_device_match(dev)) { int able = 0; if (dev->mtu >= 364) able |= IC_BOOTP; @@ -228,7 +235,7 @@ static int __init ic_open_devs(void) } if (!(d = kmalloc(sizeof(struct ic_device), GFP_KERNEL))) { rtnl_unlock(); - return -1; + return -ENOMEM; } d->dev = dev; *last = d; @@ -253,7 +260,7 @@ static int __init ic_open_devs(void) printk(KERN_ERR "IP-Config: Device `%s' not found.\n", user_dev_name); else printk(KERN_ERR "IP-Config: No network devices available.\n"); - return -1; + return -ENODEV; } return 0; } @@ -1303,6 +1310,32 @@ __be32 __init root_nfs_parse_addr(char *name) return addr; } +#define DEVICE_WAIT_MAX 12 /* 12 seconds */ + +static int __init wait_for_devices(void) +{ + int i; + + msleep(CONF_PRE_OPEN); + for (i = 0; i < DEVICE_WAIT_MAX; i++) { + struct net_device *dev; + int found = 0; + + rtnl_lock(); + for_each_netdev(&init_net, dev) { + if (ic_device_match(dev)) { + found = 1; + break; + } + } + rtnl_unlock(); + if (found) + return 0; + ssleep(1); + } + return -ENODEV; +} + /* * IP Autoconfig dispatcher. */ @@ -1313,6 +1346,7 @@ static int __init ip_auto_config(void) #ifdef IPCONFIG_DYNAMIC int retries = CONF_OPEN_RETRIES; #endif + int err; #ifdef CONFIG_PROC_FS proc_net_fops_create(&init_net, "pnp", S_IRUGO, &pnp_seq_fops); @@ -1325,12 +1359,15 @@ static int __init ip_auto_config(void) #ifdef IPCONFIG_DYNAMIC try_try_again: #endif - /* Give hardware a chance to settle */ - msleep(CONF_PRE_OPEN); + /* Wait for devices to appear */ + err = wait_for_devices(); + if (err) + return err; /* Setup all network devices */ - if (ic_open_devs() < 0) - return -1; + err = ic_open_devs(); + if (err) + return err; /* Give drivers a chance to settle */ ssleep(CONF_POST_OPEN); -- cgit v0.10.2 From c12ec0a2d94001003dfb929ce14c287fca0522b0 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Thu, 11 Mar 2010 14:09:47 -0800 Subject: paride: fix off-by-one test With `while (j++ < PX_SPIN)' j reaches PX_SPIN + 1 after the loop. This is probably unlikely to produce a problem. Signed-off-by: Roel Kluin Cc: Jens Axboe Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c index 8866ca3..71acf4e 100644 --- a/drivers/block/paride/pcd.c +++ b/drivers/block/paride/pcd.c @@ -341,11 +341,11 @@ static int pcd_wait(struct pcd_unit *cd, int go, int stop, char *fun, char *msg) && (j++ < PCD_SPIN)) udelay(PCD_DELAY); - if ((r & (IDE_ERR & stop)) || (j >= PCD_SPIN)) { + if ((r & (IDE_ERR & stop)) || (j > PCD_SPIN)) { s = read_reg(cd, 7); e = read_reg(cd, 1); p = read_reg(cd, 2); - if (j >= PCD_SPIN) + if (j > PCD_SPIN) e |= 0x100; if (fun) printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x" diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c index ddb4f9a..c059aab 100644 --- a/drivers/block/paride/pf.c +++ b/drivers/block/paride/pf.c @@ -391,11 +391,11 @@ static int pf_wait(struct pf_unit *pf, int go, int stop, char *fun, char *msg) && (j++ < PF_SPIN)) udelay(PF_SPIN_DEL); - if ((r & (STAT_ERR & stop)) || (j >= PF_SPIN)) { + if ((r & (STAT_ERR & stop)) || (j > PF_SPIN)) { s = read_reg(pf, 7); e = read_reg(pf, 1); p = read_reg(pf, 2); - if (j >= PF_SPIN) + if (j > PF_SPIN) e |= 0x100; if (fun) printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x" diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c index 1e4006e..bc5825f 100644 --- a/drivers/block/paride/pt.c +++ b/drivers/block/paride/pt.c @@ -274,11 +274,11 @@ static int pt_wait(struct pt_unit *tape, int go, int stop, char *fun, char *msg) && (j++ < PT_SPIN)) udelay(PT_SPIN_DEL); - if ((r & (STAT_ERR & stop)) || (j >= PT_SPIN)) { + if ((r & (STAT_ERR & stop)) || (j > PT_SPIN)) { s = read_reg(pi, 7); e = read_reg(pi, 1); p = read_reg(pi, 2); - if (j >= PT_SPIN) + if (j > PT_SPIN) e |= 0x100; if (fun) printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x" -- cgit v0.10.2 From f11c9c5c259cb2c3d698548dc3936f773ab1f5b9 Mon Sep 17 00:00:00 2001 From: Edward Shishkin Date: Thu, 11 Mar 2010 14:09:47 -0800 Subject: vfs: improve writeback_inodes_wb() Do not pin/unpin superblock for every inode in writeback_inodes_wb(), pin it for the whole group of inodes which belong to the same superblock and call writeback_sb_inodes() handler for them. Signed-off-by: Edward Shishkin Cc: Jens Axboe Cc: Wu Fengguang Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 76fc4d5..6841eff 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -553,108 +553,85 @@ select_queue: return ret; } -static void unpin_sb_for_writeback(struct super_block **psb) +static void unpin_sb_for_writeback(struct super_block *sb) { - struct super_block *sb = *psb; - - if (sb) { - up_read(&sb->s_umount); - put_super(sb); - *psb = NULL; - } + up_read(&sb->s_umount); + put_super(sb); } +enum sb_pin_state { + SB_PINNED, + SB_NOT_PINNED, + SB_PIN_FAILED +}; + /* * For WB_SYNC_NONE writeback, the caller does not have the sb pinned * before calling writeback. So make sure that we do pin it, so it doesn't * go away while we are writing inodes from it. - * - * Returns 0 if the super was successfully pinned (or pinning wasn't needed), - * 1 if we failed. */ -static int pin_sb_for_writeback(struct writeback_control *wbc, - struct inode *inode, struct super_block **psb) +static enum sb_pin_state pin_sb_for_writeback(struct writeback_control *wbc, + struct super_block *sb) { - struct super_block *sb = inode->i_sb; - - /* - * If this sb is already pinned, nothing more to do. If not and - * *psb is non-NULL, unpin the old one first - */ - if (sb == *psb) - return 0; - else if (*psb) - unpin_sb_for_writeback(psb); - /* * Caller must already hold the ref for this */ if (wbc->sync_mode == WB_SYNC_ALL) { WARN_ON(!rwsem_is_locked(&sb->s_umount)); - return 0; + return SB_NOT_PINNED; } - spin_lock(&sb_lock); sb->s_count++; if (down_read_trylock(&sb->s_umount)) { if (sb->s_root) { spin_unlock(&sb_lock); - goto pinned; + return SB_PINNED; } /* * umounted, drop rwsem again and fall through to failure */ up_read(&sb->s_umount); } - sb->s_count--; spin_unlock(&sb_lock); - return 1; -pinned: - *psb = sb; - return 0; + return SB_PIN_FAILED; } -static void writeback_inodes_wb(struct bdi_writeback *wb, - struct writeback_control *wbc) +/* + * Write a portion of b_io inodes which belong to @sb. + * If @wbc->sb != NULL, then find and write all such + * inodes. Otherwise write only ones which go sequentially + * in reverse order. + * Return 1, if the caller writeback routine should be + * interrupted. Otherwise return 0. + */ +static int writeback_sb_inodes(struct super_block *sb, + struct bdi_writeback *wb, + struct writeback_control *wbc) { - struct super_block *sb = wbc->sb, *pin_sb = NULL; - const unsigned long start = jiffies; /* livelock avoidance */ - - spin_lock(&inode_lock); - - if (!wbc->for_kupdate || list_empty(&wb->b_io)) - queue_io(wb, wbc->older_than_this); - while (!list_empty(&wb->b_io)) { - struct inode *inode = list_entry(wb->b_io.prev, - struct inode, i_list); long pages_skipped; - - /* - * super block given and doesn't match, skip this inode - */ - if (sb && sb != inode->i_sb) { + struct inode *inode = list_entry(wb->b_io.prev, + struct inode, i_list); + if (wbc->sb && sb != inode->i_sb) { + /* super block given and doesn't + match, skip this inode */ redirty_tail(inode); continue; } - + if (sb != inode->i_sb) + /* finish with this superblock */ + return 0; if (inode->i_state & (I_NEW | I_WILL_FREE)) { requeue_io(inode); continue; } - /* * Was this inode dirtied after sync_sb_inodes was called? * This keeps sync from extra jobs and livelock. */ - if (inode_dirtied_after(inode, start)) - break; - - if (pin_sb_for_writeback(wbc, inode, &pin_sb)) { - requeue_io(inode); - continue; - } + if (inode_dirtied_after(inode, wbc->wb_start)) + return 1; BUG_ON(inode->i_state & (I_FREEING | I_CLEAR)); __iget(inode); @@ -673,14 +650,50 @@ static void writeback_inodes_wb(struct bdi_writeback *wb, spin_lock(&inode_lock); if (wbc->nr_to_write <= 0) { wbc->more_io = 1; - break; + return 1; } if (!list_empty(&wb->b_more_io)) wbc->more_io = 1; } + /* b_io is empty */ + return 1; +} + +static void writeback_inodes_wb(struct bdi_writeback *wb, + struct writeback_control *wbc) +{ + int ret = 0; - unpin_sb_for_writeback(&pin_sb); + wbc->wb_start = jiffies; /* livelock avoidance */ + spin_lock(&inode_lock); + if (!wbc->for_kupdate || list_empty(&wb->b_io)) + queue_io(wb, wbc->older_than_this); + + while (!list_empty(&wb->b_io)) { + struct inode *inode = list_entry(wb->b_io.prev, + struct inode, i_list); + struct super_block *sb = inode->i_sb; + enum sb_pin_state state; + + if (wbc->sb && sb != wbc->sb) { + /* super block given and doesn't + match, skip this inode */ + redirty_tail(inode); + continue; + } + state = pin_sb_for_writeback(wbc, sb); + + if (state == SB_PIN_FAILED) { + requeue_io(inode); + continue; + } + ret = writeback_sb_inodes(sb, wb, wbc); + if (state == SB_PINNED) + unpin_sb_for_writeback(sb); + if (ret) + break; + } spin_unlock(&inode_lock); /* Leave any unwritten inodes on b_io */ } diff --git a/include/linux/writeback.h b/include/linux/writeback.h index 76e8903..36520de 100644 --- a/include/linux/writeback.h +++ b/include/linux/writeback.h @@ -34,6 +34,9 @@ struct writeback_control { enum writeback_sync_modes sync_mode; unsigned long *older_than_this; /* If !NULL, only write back inodes older than this */ + unsigned long wb_start; /* Time writeback_inodes_wb was + called. This is needed to avoid + extra jobs and livelock */ long nr_to_write; /* Write this many pages, and decrement this for each page written */ long pages_skipped; /* Pages which were not written */ -- cgit v0.10.2 From 8447b360a3897bdfb0677107564d1dd9ab6e63be Mon Sep 17 00:00:00 2001 From: Jack Steiner Date: Thu, 11 Mar 2010 12:43:29 -0600 Subject: x86, UV: Fix target_cpus() in x2apic_uv_x.c target_cpu() should initially target all cpus, not just cpu 0. Otherwise systems with lots of disks can exhaust the interrupt vectors on cpu 0 if a large number of disks are discovered before the irq balancer is running. Note: UV code only... Signed-off-by: Jack Steiner LKML-Reference: <20100311184328.GA21433@sgi.com> Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index 21db3cb..af0ca80 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c @@ -114,11 +114,9 @@ EXPORT_SYMBOL_GPL(uv_possible_blades); unsigned long sn_rtc_cycles_per_second; EXPORT_SYMBOL(sn_rtc_cycles_per_second); -/* Start with all IRQs pointing to boot CPU. IRQ balancing will shift them. */ - static const struct cpumask *uv_target_cpus(void) { - return cpumask_of(0); + return cpu_online_mask; } static void uv_vector_allocation_domain(int cpu, struct cpumask *retmask) -- cgit v0.10.2 From 0841cb826859a4f14c472cc75a782811310f010e Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Tue, 23 Feb 2010 15:50:38 +0000 Subject: omap: McBSP: Drop unnecessary status/error bit clearing on reg_cacheretrieved register values The MsBSP register cache will never have any error/status flags set, since these flags are never written to the reg_cache. So it is kind of not necessary to clear these flags, which are actually always 0. In other words, clearing the status/error flags are not necessary, since the reg_cache will never got these bits set. We can just write back the register content from the cache as it is when clearing an error condition. Tested on Amstrad Delta. Reported-by: Peter Ujfalusi Signed-off-by: Janusz Krzysztofik Acked-by: Jarkko Nikula Signed-off-by: Tony Lindgren diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index e47686e..52dfcc8 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c @@ -133,8 +133,7 @@ static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id) dev_err(mcbsp_tx->dev, "TX Frame Sync Error! : 0x%x\n", irqst_spcr2); /* Writing zero to XSYNC_ERR clears the IRQ */ - MCBSP_WRITE(mcbsp_tx, SPCR2, - MCBSP_READ_CACHE(mcbsp_tx, SPCR2) & ~(XSYNC_ERR)); + MCBSP_WRITE(mcbsp_tx, SPCR2, MCBSP_READ_CACHE(mcbsp_tx, SPCR2)); } else { complete(&mcbsp_tx->tx_irq_completion); } @@ -154,8 +153,7 @@ static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id) dev_err(mcbsp_rx->dev, "RX Frame Sync Error! : 0x%x\n", irqst_spcr1); /* Writing zero to RSYNC_ERR clears the IRQ */ - MCBSP_WRITE(mcbsp_rx, SPCR1, - MCBSP_READ_CACHE(mcbsp_rx, SPCR1) & ~(RSYNC_ERR)); + MCBSP_WRITE(mcbsp_rx, SPCR1, MCBSP_READ_CACHE(mcbsp_rx, SPCR1)); } else { complete(&mcbsp_rx->tx_irq_completion); } @@ -934,8 +932,7 @@ int omap_mcbsp_pollwrite(unsigned int id, u16 buf) /* if frame sync error - clear the error */ if (MCBSP_READ(mcbsp, SPCR2) & XSYNC_ERR) { /* clear error */ - MCBSP_WRITE(mcbsp, SPCR2, - MCBSP_READ_CACHE(mcbsp, SPCR2) & (~XSYNC_ERR)); + MCBSP_WRITE(mcbsp, SPCR2, MCBSP_READ_CACHE(mcbsp, SPCR2)); /* resend */ return -1; } else { @@ -975,8 +972,7 @@ int omap_mcbsp_pollread(unsigned int id, u16 *buf) /* if frame sync error - clear the error */ if (MCBSP_READ(mcbsp, SPCR1) & RSYNC_ERR) { /* clear error */ - MCBSP_WRITE(mcbsp, SPCR1, - MCBSP_READ_CACHE(mcbsp, SPCR1) & (~RSYNC_ERR)); + MCBSP_WRITE(mcbsp, SPCR1, MCBSP_READ_CACHE(mcbsp, SPCR1)); /* resend */ return -1; } else { -- cgit v0.10.2 From 29b2ee5af5f3a02846bd38a1e2121d62ee5f6aca Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Sat, 6 Mar 2010 00:14:46 +0000 Subject: ARM/OMAP: Remove the +x bit from a couple of source files Remove the +x bit from a couple of source files Signed-off-by: Andrew Clayton Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c old mode 100755 new mode 100644 diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c old mode 100755 new mode 100644 -- cgit v0.10.2 From 80a05b9ffa7dc13f6693902dd8999a2b61a3a0d7 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Fri, 12 Mar 2010 17:34:14 +0100 Subject: clockevents: Sanitize min_delta_ns adjustment and prevent overflows The current logic which handles clock events programming failures can increase min_delta_ns unlimited and even can cause overflows. Sanitize it by: - prevent zero increase when min_delta_ns == 1 - limiting min_delta_ns to a jiffie - bail out if the jiffie limit is hit - add retries stats for /proc/timer_list so we can gather data Reported-by: Uwe Kleine-Koenig Signed-off-by: Thomas Gleixner diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h index 0cf725b..fc53492 100644 --- a/include/linux/clockchips.h +++ b/include/linux/clockchips.h @@ -73,6 +73,7 @@ enum clock_event_nofitiers { * @list: list head for the management code * @mode: operating mode assigned by the management code * @next_event: local storage for the next event in oneshot mode + * @retries: number of forced programming retries */ struct clock_event_device { const char *name; @@ -93,6 +94,7 @@ struct clock_event_device { struct list_head list; enum clock_event_mode mode; ktime_t next_event; + unsigned long retries; }; /* diff --git a/kernel/time/tick-oneshot.c b/kernel/time/tick-oneshot.c index 0a8a213..aada0e5 100644 --- a/kernel/time/tick-oneshot.c +++ b/kernel/time/tick-oneshot.c @@ -22,6 +22,29 @@ #include "tick-internal.h" +/* Limit min_delta to a jiffie */ +#define MIN_DELTA_LIMIT (NSEC_PER_SEC / HZ) + +static int tick_increase_min_delta(struct clock_event_device *dev) +{ + /* Nothing to do if we already reached the limit */ + if (dev->min_delta_ns >= MIN_DELTA_LIMIT) + return -ETIME; + + if (dev->min_delta_ns < 5000) + dev->min_delta_ns = 5000; + else + dev->min_delta_ns += dev->min_delta_ns >> 1; + + if (dev->min_delta_ns > MIN_DELTA_LIMIT) + dev->min_delta_ns = MIN_DELTA_LIMIT; + + printk(KERN_WARNING "CE: %s increased min_delta_ns to %llu nsec\n", + dev->name ? dev->name : "?", + (unsigned long long) dev->min_delta_ns); + return 0; +} + /** * tick_program_event internal worker function */ @@ -37,23 +60,28 @@ int tick_dev_program_event(struct clock_event_device *dev, ktime_t expires, if (!ret || !force) return ret; + dev->retries++; /* - * We tried 2 times to program the device with the given - * min_delta_ns. If that's not working then we double it + * We tried 3 times to program the device with the given + * min_delta_ns. If that's not working then we increase it * and emit a warning. */ if (++i > 2) { /* Increase the min. delta and try again */ - if (!dev->min_delta_ns) - dev->min_delta_ns = 5000; - else - dev->min_delta_ns += dev->min_delta_ns >> 1; - - printk(KERN_WARNING - "CE: %s increasing min_delta_ns to %llu nsec\n", - dev->name ? dev->name : "?", - (unsigned long long) dev->min_delta_ns << 1); - + if (tick_increase_min_delta(dev)) { + /* + * Get out of the loop if min_delta_ns + * hit the limit already. That's + * better than staying here forever. + * + * We clear next_event so we have a + * chance that the box survives. + */ + printk(KERN_WARNING + "CE: Reprogramming failure. Giving up\n"); + dev->next_event.tv64 = KTIME_MAX; + return -ETIME; + } i = 0; } diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c index bdfb8dd..1a4a7dd 100644 --- a/kernel/time/timer_list.c +++ b/kernel/time/timer_list.c @@ -228,6 +228,7 @@ print_tickdevice(struct seq_file *m, struct tick_device *td, int cpu) SEQ_printf(m, " event_handler: "); print_name_offset(m, dev->event_handler); SEQ_printf(m, "\n"); + SEQ_printf(m, " retries: %lu\n", dev->retries); } static void timer_list_show_tickdevices(struct seq_file *m) @@ -257,7 +258,7 @@ static int timer_list_show(struct seq_file *m, void *v) u64 now = ktime_to_ns(ktime_get()); int cpu; - SEQ_printf(m, "Timer List Version: v0.5\n"); + SEQ_printf(m, "Timer List Version: v0.6\n"); SEQ_printf(m, "HRTIMER_MAX_CLOCK_BASES: %d\n", HRTIMER_MAX_CLOCK_BASES); SEQ_printf(m, "now at %Ld nsecs\n", (unsigned long long)now); -- cgit v0.10.2 From 829b6c1ef488856c6a46a2f705f5068062d5f34c Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 11 Mar 2010 14:04:30 -0800 Subject: timer stats: Fix del_timer_sync() and try_to_del_timer_sync() These functions forgot to run timer_stats_timer_clear_start_info(). It's unobvious what effect this has and whether it matters much - we won't be printing it out anyway if the timer's detached. Untested, just an Ingo trollpatch. [ Nevertheless correct - tglx ] Signed-off-by: Andrew Morton Cc: Ingo Molnar Cc: johnstul@us.ibm.com Signed-off-by: Thomas Gleixner diff --git a/kernel/timer.c b/kernel/timer.c index c61a794..fc965ea 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -880,6 +880,7 @@ int try_to_del_timer_sync(struct timer_list *timer) if (base->running_timer == timer) goto out; + timer_stats_timer_clear_start_info(timer); ret = 0; if (timer_pending(timer)) { detach_timer(timer, 1); -- cgit v0.10.2 From 15365c108ea27598e265f8c13e7051d99ca5b0b9 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Thu, 11 Mar 2010 14:04:31 -0800 Subject: posix-cpu-timers: Reset expire cache when no timer is running When a process deletes cpu timer or a timer expires we do not clear the expiration cache sig->cputimer_expires. As a result the fastpath_timer_check() which prevents us to loop over all threads in case no timer is active is not working and we run the slow path needlessly on every tick. Zero sig->cputimer_expires in stop_process_timers(). Signed-off-by: Stanislaw Gruszka Cc: Ingo Molnar Cc: Oleg Nesterov Cc: Peter Zijlstra Cc: Hidetoshi Seto Cc: Spencer Candland Signed-off-by: Andrew Morton Signed-off-by: Thomas Gleixner diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c index 438ff45..edec25a 100644 --- a/kernel/posix-cpu-timers.c +++ b/kernel/posix-cpu-timers.c @@ -1060,9 +1060,9 @@ static void check_thread_timers(struct task_struct *tsk, } } -static void stop_process_timers(struct task_struct *tsk) +static void stop_process_timers(struct signal_struct *sig) { - struct thread_group_cputimer *cputimer = &tsk->signal->cputimer; + struct thread_group_cputimer *cputimer = &sig->cputimer; unsigned long flags; if (!cputimer->running) @@ -1071,6 +1071,10 @@ static void stop_process_timers(struct task_struct *tsk) spin_lock_irqsave(&cputimer->lock, flags); cputimer->running = 0; spin_unlock_irqrestore(&cputimer->lock, flags); + + sig->cputime_expires.prof_exp = cputime_zero; + sig->cputime_expires.virt_exp = cputime_zero; + sig->cputime_expires.sched_exp = 0; } static u32 onecputick; @@ -1131,7 +1135,7 @@ static void check_process_timers(struct task_struct *tsk, list_empty(&timers[CPUCLOCK_VIRT]) && cputime_eq(sig->it[CPUCLOCK_VIRT].expires, cputime_zero) && list_empty(&timers[CPUCLOCK_SCHED])) { - stop_process_timers(tsk); + stop_process_timers(sig); return; } -- cgit v0.10.2 From a72042c08a8ba3b685dc9cba62c57c48188ef2c8 Mon Sep 17 00:00:00 2001 From: Chien Tung Date: Wed, 3 Mar 2010 19:13:26 +0000 Subject: RDMA/nes: Fix CX4 link problem in back-to-back configuration Commit 09124e19 ("RDMA/nes: Add support for KR device id 0x0110") took out too much code and broke CX4 link detection in back-to-back configuration. Put back the code that does the link check. Signed-off-by: Chien Tung Signed-off-by: Roland Dreier diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c index a1d79b6..91fdde3 100644 --- a/drivers/infiniband/hw/nes/nes_nic.c +++ b/drivers/infiniband/hw/nes/nes_nic.c @@ -1595,7 +1595,6 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev, struct nes_vnic *nesvnic; struct net_device *netdev; struct nic_qp_map *curr_qp_map; - u32 u32temp; u8 phy_type = nesdev->nesadapter->phy_type[nesdev->mac_index]; netdev = alloc_etherdev(sizeof(struct nes_vnic)); @@ -1707,6 +1706,10 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev, ((phy_type == NES_PHY_TYPE_PUMA_1G) && (((PCI_FUNC(nesdev->pcidev->devfn) == 1) && (nesdev->mac_index == 2)) || ((PCI_FUNC(nesdev->pcidev->devfn) == 2) && (nesdev->mac_index == 1)))))) { + u32 u32temp; + u32 link_mask; + u32 link_val; + u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + (0x200 * (nesdev->mac_index & 1))); if (phy_type != NES_PHY_TYPE_PUMA_1G) { @@ -1715,13 +1718,36 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev, (0x200 * (nesdev->mac_index & 1)), u32temp); } + /* Check and set linkup here. This is for back to back */ + /* configuration where second port won't get link interrupt */ + switch (phy_type) { + case NES_PHY_TYPE_PUMA_1G: + if (nesdev->mac_index < 2) { + link_mask = 0x01010000; + link_val = 0x01010000; + } else { + link_mask = 0x02020000; + link_val = 0x02020000; + } + break; + default: + link_mask = 0x0f1f0000; + link_val = 0x0f0f0000; + break; + } + + u32temp = nes_read_indexed(nesdev, + NES_IDX_PHY_PCS_CONTROL_STATUS0 + + (0x200 * (nesdev->mac_index & 1))); + if ((u32temp & link_mask) == link_val) + nesvnic->linkup = 1; + /* clear the MAC interrupt status, assumes direct logical to physical mapping */ u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index)); nes_debug(NES_DBG_INIT, "Phy interrupt status = 0x%X.\n", u32temp); nes_write_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index), u32temp); nes_init_phy(nesdev); - } return netdev; -- cgit v0.10.2 From b97c4bc16734a2e597dac7f91ee9eb78f4aeef9a Mon Sep 17 00:00:00 2001 From: Luca Barbieri Date: Thu, 11 Mar 2010 14:08:45 -0800 Subject: locking: Make sparse work with inline spinlocks and rwlocks Currently sparse does not work with inline spinlock and rwlock functions. The problem is that they do not use the __acquires/__releases out-of-line functions, but use inline functions with no sparse annotations. This patch adds the appropriate annotations to make it work properly. Signed-off-by: Luca Barbieri Cc: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Thomas Gleixner diff --git a/include/linux/rwlock.h b/include/linux/rwlock.h index 71e0b00..bc2994e 100644 --- a/include/linux/rwlock.h +++ b/include/linux/rwlock.h @@ -29,25 +29,25 @@ do { \ #endif #ifdef CONFIG_DEBUG_SPINLOCK - extern void do_raw_read_lock(rwlock_t *lock); + extern void do_raw_read_lock(rwlock_t *lock) __acquires(lock); #define do_raw_read_lock_flags(lock, flags) do_raw_read_lock(lock) extern int do_raw_read_trylock(rwlock_t *lock); - extern void do_raw_read_unlock(rwlock_t *lock); - extern void do_raw_write_lock(rwlock_t *lock); + extern void do_raw_read_unlock(rwlock_t *lock) __releases(lock); + extern void do_raw_write_lock(rwlock_t *lock) __acquires(lock); #define do_raw_write_lock_flags(lock, flags) do_raw_write_lock(lock) extern int do_raw_write_trylock(rwlock_t *lock); - extern void do_raw_write_unlock(rwlock_t *lock); + extern void do_raw_write_unlock(rwlock_t *lock) __releases(lock); #else -# define do_raw_read_lock(rwlock) arch_read_lock(&(rwlock)->raw_lock) +# define do_raw_read_lock(rwlock) do {__acquire(lock); arch_read_lock(&(rwlock)->raw_lock); } while (0) # define do_raw_read_lock_flags(lock, flags) \ - arch_read_lock_flags(&(lock)->raw_lock, *(flags)) + do {__acquire(lock); arch_read_lock_flags(&(lock)->raw_lock, *(flags)); } while (0) # define do_raw_read_trylock(rwlock) arch_read_trylock(&(rwlock)->raw_lock) -# define do_raw_read_unlock(rwlock) arch_read_unlock(&(rwlock)->raw_lock) -# define do_raw_write_lock(rwlock) arch_write_lock(&(rwlock)->raw_lock) +# define do_raw_read_unlock(rwlock) do {arch_read_unlock(&(rwlock)->raw_lock); __release(lock); } while (0) +# define do_raw_write_lock(rwlock) do {__acquire(lock); arch_write_lock(&(rwlock)->raw_lock); } while (0) # define do_raw_write_lock_flags(lock, flags) \ - arch_write_lock_flags(&(lock)->raw_lock, *(flags)) + do {__acquire(lock); arch_write_lock_flags(&(lock)->raw_lock, *(flags)); } while (0) # define do_raw_write_trylock(rwlock) arch_write_trylock(&(rwlock)->raw_lock) -# define do_raw_write_unlock(rwlock) arch_write_unlock(&(rwlock)->raw_lock) +# define do_raw_write_unlock(rwlock) do {arch_write_unlock(&(rwlock)->raw_lock); __release(lock); } while (0) #endif #define read_can_lock(rwlock) arch_read_can_lock(&(rwlock)->raw_lock) diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h index 8608821..89fac6a 100644 --- a/include/linux/spinlock.h +++ b/include/linux/spinlock.h @@ -128,19 +128,21 @@ static inline void smp_mb__after_lock(void) { smp_mb(); } #define raw_spin_unlock_wait(lock) arch_spin_unlock_wait(&(lock)->raw_lock) #ifdef CONFIG_DEBUG_SPINLOCK - extern void do_raw_spin_lock(raw_spinlock_t *lock); + extern void do_raw_spin_lock(raw_spinlock_t *lock) __acquires(lock); #define do_raw_spin_lock_flags(lock, flags) do_raw_spin_lock(lock) extern int do_raw_spin_trylock(raw_spinlock_t *lock); - extern void do_raw_spin_unlock(raw_spinlock_t *lock); + extern void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock); #else -static inline void do_raw_spin_lock(raw_spinlock_t *lock) +static inline void do_raw_spin_lock(raw_spinlock_t *lock) __acquires(lock) { + __acquire(lock); arch_spin_lock(&lock->raw_lock); } static inline void -do_raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long *flags) +do_raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long *flags) __acquires(lock) { + __acquire(lock); arch_spin_lock_flags(&lock->raw_lock, *flags); } @@ -149,9 +151,10 @@ static inline int do_raw_spin_trylock(raw_spinlock_t *lock) return arch_spin_trylock(&(lock)->raw_lock); } -static inline void do_raw_spin_unlock(raw_spinlock_t *lock) +static inline void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock) { arch_spin_unlock(&lock->raw_lock); + __release(lock); } #endif -- cgit v0.10.2 From 52fbe9cde7fdb5c6fac196d7ebd2d92d05ef3cd4 Mon Sep 17 00:00:00 2001 From: Lai Jiangshan Date: Mon, 8 Mar 2010 14:50:43 +0800 Subject: ring-buffer: Move disabled check into preempt disable section The ring buffer resizing and resetting relies on a schedule RCU action. The buffers are disabled, a synchronize_sched() is called and then the resize or reset takes place. But this only works if the disabling of the buffers are within the preempt disabled section, otherwise a window exists that the buffers can be written to while a reset or resize takes place. Cc: stable@kernel.org Reported-by: Li Zefan Signed-off-by: Lai Jiangshan LKML-Reference: <4B949E43.2010906@cn.fujitsu.com> Signed-off-by: Steven Rostedt diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 8c1b2d2..54191d6 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -2232,12 +2232,12 @@ ring_buffer_lock_reserve(struct ring_buffer *buffer, unsigned long length) if (ring_buffer_flags != RB_BUFFERS_ON) return NULL; - if (atomic_read(&buffer->record_disabled)) - return NULL; - /* If we are tracing schedule, we don't want to recurse */ resched = ftrace_preempt_disable(); + if (atomic_read(&buffer->record_disabled)) + goto out_nocheck; + if (trace_recursive_lock()) goto out_nocheck; @@ -2469,11 +2469,11 @@ int ring_buffer_write(struct ring_buffer *buffer, if (ring_buffer_flags != RB_BUFFERS_ON) return -EBUSY; - if (atomic_read(&buffer->record_disabled)) - return -EBUSY; - resched = ftrace_preempt_disable(); + if (atomic_read(&buffer->record_disabled)) + goto out; + cpu = raw_smp_processor_id(); if (!cpumask_test_cpu(cpu, buffer->cpumask)) -- cgit v0.10.2 From ea14eb714041d40fcc5180b5a586034503650149 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 12 Mar 2010 19:41:23 -0500 Subject: function-graph: Init curr_ret_stack with ret_stack If the graph tracer is active, and a task is forked but the allocating of the processes graph stack fails, it can cause crash later on. This is due to the temporary stack being NULL, but the curr_ret_stack variable is copied from the parent. If it is not -1, then in ftrace_graph_probe_sched_switch() the following: for (index = next->curr_ret_stack; index >= 0; index--) next->ret_stack[index].calltime += timestamp; Will cause a kernel OOPS. Found with Li Zefan's ftrace_stress_test. Cc: stable@kernel.org Signed-off-by: Steven Rostedt diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index d4d1238..bb53edb 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -3349,6 +3349,7 @@ void ftrace_graph_init_task(struct task_struct *t) { /* Make sure we do not use the parent ret_stack */ t->ret_stack = NULL; + t->curr_ret_stack = -1; if (ftrace_graph_active) { struct ftrace_ret_stack *ret_stack; @@ -3358,7 +3359,6 @@ void ftrace_graph_init_task(struct task_struct *t) GFP_KERNEL); if (!ret_stack) return; - t->curr_ret_stack = -1; atomic_set(&t->tracing_graph_pause, 0); atomic_set(&t->trace_overrun, 0); t->ftrace_timestamp = 0; -- cgit v0.10.2 From 283740c619d211e34572cc93c8cdba92ccbdb9cc Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 12 Mar 2010 19:48:41 -0500 Subject: tracing: Use same local variable when resetting the ring buffer In the ftrace code that resets the ring buffer it references the buffer with a local variable, but then uses the tr->buffer as the parameter to reset. If the wakeup tracer is running, which can switch the tr->buffer with the max saved buffer, this can break the requirement of disabling the buffer before the reset. buffer = tr->buffer; ring_buffer_record_disable(buffer); synchronize_sched(); __tracing_reset(tr->buffer, cpu); If the tr->buffer is swapped, then the reset is not happening to the buffer that was disabled. This will cause the ring buffer to fail. Found with Li Zefan's ftrace_stress_test. Cc: stable@kernel.org Reported-by: Lai Jiangshan Signed-off-by: Steven Rostedt diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 6af8d7b..60de37b 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -840,10 +840,10 @@ out: mutex_unlock(&trace_types_lock); } -static void __tracing_reset(struct trace_array *tr, int cpu) +static void __tracing_reset(struct ring_buffer *buffer, int cpu) { ftrace_disable_cpu(); - ring_buffer_reset_cpu(tr->buffer, cpu); + ring_buffer_reset_cpu(buffer, cpu); ftrace_enable_cpu(); } @@ -855,7 +855,7 @@ void tracing_reset(struct trace_array *tr, int cpu) /* Make sure all commits have finished */ synchronize_sched(); - __tracing_reset(tr, cpu); + __tracing_reset(buffer, cpu); ring_buffer_record_enable(buffer); } @@ -873,7 +873,7 @@ void tracing_reset_online_cpus(struct trace_array *tr) tr->time_start = ftrace_now(tr->cpu); for_each_online_cpu(cpu) - __tracing_reset(tr, cpu); + __tracing_reset(buffer, cpu); ring_buffer_record_enable(buffer); } -- cgit v0.10.2 From a2f8071428ed9a0f06865f417c962421c9a6b488 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 12 Mar 2010 19:56:00 -0500 Subject: tracing: Disable buffer switching when starting or stopping trace When the trace iterator is read, tracing_start() and tracing_stop() is called to stop tracing while the iterator is processing the trace output. These functions disable both the standard buffer and the max latency buffer. But if the wakeup tracer is running, it can switch these buffers between the two disables: buffer = global_trace.buffer; if (buffer) ring_buffer_record_disable(buffer); <<<--------- swap happens here buffer = max_tr.buffer; if (buffer) ring_buffer_record_disable(buffer); What happens is that we disabled the same buffer twice. On tracing_start() we can enable the same buffer twice. All ring_buffer_record_disable() must be matched with a ring_buffer_record_enable() or the buffer can be disable permanently, or enable prematurely, and cause a bug where a reset happens while a trace is commiting. This patch protects these two by taking the ftrace_max_lock to prevent a switch from occurring. Found with Li Zefan's ftrace_stress_test. Cc: stable@kernel.org Reported-by: Lai Jiangshan Signed-off-by: Steven Rostedt diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 60de37b..484337d 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -950,6 +950,8 @@ void tracing_start(void) goto out; } + /* Prevent the buffers from switching */ + arch_spin_lock(&ftrace_max_lock); buffer = global_trace.buffer; if (buffer) @@ -959,6 +961,8 @@ void tracing_start(void) if (buffer) ring_buffer_record_enable(buffer); + arch_spin_unlock(&ftrace_max_lock); + ftrace_start(); out: spin_unlock_irqrestore(&tracing_start_lock, flags); @@ -980,6 +984,9 @@ void tracing_stop(void) if (trace_stop_count++) goto out; + /* Prevent the buffers from switching */ + arch_spin_lock(&ftrace_max_lock); + buffer = global_trace.buffer; if (buffer) ring_buffer_record_disable(buffer); @@ -988,6 +995,8 @@ void tracing_stop(void) if (buffer) ring_buffer_record_disable(buffer); + arch_spin_unlock(&ftrace_max_lock); + out: spin_unlock_irqrestore(&tracing_start_lock, flags); } -- cgit v0.10.2 From b6345879ccbd9b92864fbd7eb8ac48acdb4d6b15 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 12 Mar 2010 20:03:30 -0500 Subject: tracing: Do not record user stack trace from NMI context A bug was found with Li Zefan's ftrace_stress_test that caused applications to segfault during the test. Placing a tracing_off() in the segfault code, and examining several traces, I found that the following was always the case. The lock tracer was enabled (lockdep being required) and userstack was enabled. Testing this out, I just enabled the two, but that was not good enough. I needed to run something else that could trigger it. Running a load like hackbench did not work, but executing a new program would. The following would trigger the segfault within seconds: # echo 1 > /debug/tracing/options/userstacktrace # echo 1 > /debug/tracing/events/lock/enable # while :; do ls > /dev/null ; done Enabling the function graph tracer and looking at what was happening I finally noticed that all cashes happened just after an NMI. 1) | copy_user_handle_tail() { 1) | bad_area_nosemaphore() { 1) | __bad_area_nosemaphore() { 1) | no_context() { 1) | fixup_exception() { 1) 0.319 us | search_exception_tables(); 1) 0.873 us | } [...] 1) 0.314 us | __rcu_read_unlock(); 1) 0.325 us | native_apic_mem_write(); 1) 0.943 us | } 1) 0.304 us | rcu_nmi_exit(); [...] 1) 0.479 us | find_vma(); 1) | bad_area() { 1) | __bad_area() { After capturing several traces of failures, all of them happened after an NMI. Curious about this, I added a trace_printk() to the NMI handler to read the regs->ip to see where the NMI happened. In which I found out it was here: ffffffff8135b660 : ffffffff8135b660: 48 83 ec 78 sub $0x78,%rsp ffffffff8135b664: e8 97 01 00 00 callq ffffffff8135b800 What was happening is that the NMI would happen at the place that a page fault occurred. It would call rcu_read_lock() which was traced by the lock events, and the user_stack_trace would run. This would trigger a page fault inside the NMI. I do not see where the CR2 register is saved or restored in NMI handling. This means that it would corrupt the page fault handling that the NMI interrupted. The reason the while loop of ls helped trigger the bug, was that each execution of ls would cause lots of pages to be faulted in, and increase the chances of the race happening. The simple solution is to not allow user stack traces in NMI context. After this patch, I ran the above "ls" test for a couple of hours without any issues. Without this patch, the bug would trigger in less than a minute. Cc: stable@kernel.org Reported-by: Li Zefan Signed-off-by: Steven Rostedt diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 484337d..e52683f 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1284,6 +1284,13 @@ ftrace_trace_userstack(struct ring_buffer *buffer, unsigned long flags, int pc) if (!(trace_flags & TRACE_ITER_USERSTACKTRACE)) return; + /* + * NMIs can not handle page faults, even with fix ups. + * The save user stack can (and often does) fault. + */ + if (unlikely(in_nmi())) + return; + event = trace_buffer_lock_reserve(buffer, TRACE_USER_STACK, sizeof(*entry), flags, pc); if (!event) -- cgit v0.10.2 From 594087a04eea544356f9c52e83c1a9bc380ce80f Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Fri, 12 Mar 2010 18:22:17 -0500 Subject: perf probe: Fix probe_point buffer overrun Fix probe_point array-size overrun problem. In some cases (e.g. inline function), one user-specified probe-point can be translated to many probe address, and it overruns pre-defined array-size. This also removes redundant MAX_PROBES macro definition. Signed-off-by: Masami Hiramatsu Cc: systemtap Cc: DLE Cc: LKML-Reference: <20100312232217.2017.45017.stgit@localhost6.localdomain6> [ Note that only root can create new probes. Eventually we should remove the MAX_PROBES limit, but that is a larger patch not eligible to perf/urgent treatment. ] Signed-off-by: Ingo Molnar diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c index c30a335..152d6c9 100644 --- a/tools/perf/builtin-probe.c +++ b/tools/perf/builtin-probe.c @@ -47,7 +47,6 @@ #include "util/probe-event.h" #define MAX_PATH_LEN 256 -#define MAX_PROBES 128 /* Session management structure */ static struct { diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 1e6c65e..f9cbbf1 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -455,6 +455,9 @@ static void show_probe_point(Dwarf_Die *sp_die, struct probe_finder *pf) /* *pf->fb_ops will be cached in libdw. Don't free it. */ pf->fb_ops = NULL; + if (pp->found == MAX_PROBES) + die("Too many( > %d) probe point found.\n", MAX_PROBES); + pp->probes[pp->found] = strdup(tmp); pp->found++; } -- cgit v0.10.2 From fc6ceea045031658d0b59af562369eae980b4370 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Fri, 12 Mar 2010 18:22:24 -0500 Subject: perf probe: Fix need_dwarf flag if lazy matching is used Set need_dwarf if lazy matching pattern is specified, because lazy matching requires real source path for which we must use debuginfo. Signed-off-by: Masami Hiramatsu Cc: systemtap Cc: DLE LKML-Reference: <20100312232224.2017.54550.stgit@localhost6.localdomain6> Signed-off-by: Ingo Molnar diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 53181db..7c004b6 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -242,7 +242,7 @@ void parse_perf_probe_event(const char *str, struct probe_point *pp, /* Parse probe point */ parse_perf_probe_probepoint(argv[0], pp); - if (pp->file || pp->line) + if (pp->file || pp->line || pp->lazy_line) *need_dwarf = true; /* Copy arguments and ensure return probe has no C argument */ -- cgit v0.10.2 From 0e152cd7c16832bd5cadee0c2e41d9959bc9b6f9 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Fri, 12 Mar 2010 15:43:03 +0100 Subject: x86, k8 nb: Fix boot crash: enable k8_northbridges unconditionally on AMD systems de957628ce7c84764ff41331111036b3ae5bad0f changed setting of the x86_init.iommu.iommu_init function ptr only when GART IOMMU is found. One side effect of it is that num_k8_northbridges is not initialized anymore if not explicitly called. This resulted in uninitialized pointers in , for example, which uses the num_k8_northbridges thing through node_to_k8_nb_misc(). Fix that through an initcall that runs right after the PCI subsystem and does all the scanning. Then, remove initialization in gart_iommu_init() which is a rootfs_initcall and we're running before that. What is more, since num_k8_northbridges is being used in other places beside GART IOMMU, include it whenever we add AMD CPU support. The previous dependency chain in kconfig contained K8_NB depends on AGP_AMD64|GART_IOMMU which was clearly incorrect. The more natural way in terms of hardware dependency should be AGP_AMD64|GART_IOMMU depends on K8_NB depends on CPU_SUP_AMD && PCI. Make it so Number One! Signed-off-by: Borislav Petkov Cc: FUJITA Tomonori Cc: Joerg Roedel LKML-Reference: <20100312144303.GA29262@aftab> Signed-off-by: Ingo Molnar Tested-by: Joerg Roedel diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index eb40925..ddb52b8 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -627,7 +627,7 @@ config GART_IOMMU bool "GART IOMMU support" if EMBEDDED default y select SWIOTLB - depends on X86_64 && PCI + depends on X86_64 && PCI && K8_NB ---help--- Support for full DMA access of devices with 32bit memory access only on systems with more than 3GB. This is usually needed for USB, @@ -2026,7 +2026,7 @@ endif # X86_32 config K8_NB def_bool y - depends on AGP_AMD64 || (X86_64 && (GART_IOMMU || (PCI && NUMA))) + depends on CPU_SUP_AMD && PCI source "drivers/pcmcia/Kconfig" diff --git a/arch/x86/kernel/k8.c b/arch/x86/kernel/k8.c index cbc4332..9b89546 100644 --- a/arch/x86/kernel/k8.c +++ b/arch/x86/kernel/k8.c @@ -121,3 +121,17 @@ void k8_flush_garts(void) } EXPORT_SYMBOL_GPL(k8_flush_garts); +static __init int init_k8_nbs(void) +{ + int err = 0; + + err = cache_k8_northbridges(); + + if (err < 0) + printk(KERN_NOTICE "K8 NB: Cannot enumerate AMD northbridges.\n"); + + return err; +} + +/* This has to go after the PCI subsystem */ +fs_initcall(init_k8_nbs); diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c index 34de53b..f3af115 100644 --- a/arch/x86/kernel/pci-gart_64.c +++ b/arch/x86/kernel/pci-gart_64.c @@ -735,7 +735,7 @@ int __init gart_iommu_init(void) unsigned long scratch; long i; - if (cache_k8_northbridges() < 0 || num_k8_northbridges == 0) + if (num_k8_northbridges == 0) return 0; #ifndef CONFIG_AGP_AMD64 diff --git a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig index 2fb3a48..4b66c69 100644 --- a/drivers/char/agp/Kconfig +++ b/drivers/char/agp/Kconfig @@ -57,7 +57,7 @@ config AGP_AMD config AGP_AMD64 tristate "AMD Opteron/Athlon64 on-CPU GART support" - depends on AGP && X86 + depends on AGP && X86 && K8_NB help This option gives you AGP support for the GLX component of X using the on-CPU northbridge of the AMD Athlon64/Opteron CPUs. -- cgit v0.10.2 From a2302b45d8ab41a55e84c39a6c6f813586ad8493 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 10 Mar 2010 19:10:28 +0100 Subject: ARM: 5985/2: ARM: Fix Samsung build after "ARM: Eliminate decompressor -Dstatic= PIC hack" Commit 5de813b6 (ARM: Eliminate decompressor -Dstatic= PIC hack) among other things changed the declared type of the error() function to an extern, conflicting with the forward declartion in the Samsung plat/uncompress.h which appears to have been relying on the static being defined away, causing build failures since error() ends up with a GOT relocation but the linker script discards all GOT relocated data and functions: arch/arm/boot/compressed/decompress.o: In function `gunzip': /home/broonie/git/linux-2.6/arch/arm/boot/compressed/../../../../lib/decompress_ +inflate.c:68: undefined reference to `error' and so on. Fix this by moving the declaration into uncompress/misc.c where it is shared with the rest of the code, correcting the definition as we go. Signed-off-by: Mark Brown Signed-off-by: Russell King diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c index d32bc71..d2b2ef4 100644 --- a/arch/arm/boot/compressed/misc.c +++ b/arch/arm/boot/compressed/misc.c @@ -33,6 +33,7 @@ unsigned int __machine_arch_type; #else static void putstr(const char *ptr); +extern void error(char *x); #include diff --git a/arch/arm/plat-samsung/include/plat/uncompress.h b/arch/arm/plat-samsung/include/plat/uncompress.h index e87ce8f..7d6ed72 100644 --- a/arch/arm/plat-samsung/include/plat/uncompress.h +++ b/arch/arm/plat-samsung/include/plat/uncompress.h @@ -140,8 +140,6 @@ static void arch_decomp_error(const char *x) #define arch_error arch_decomp_error #endif -static void error(char *err); - #ifdef CONFIG_S3C_BOOT_UART_FORCE_FIFO static inline void arch_enable_uart_fifo(void) { -- cgit v0.10.2 From 438ff39d7813515d3aac20f53b5b95aaa58b38f9 Mon Sep 17 00:00:00 2001 From: Rob Alley Date: Thu, 11 Mar 2010 02:15:04 +0100 Subject: ARM: 5986/1: at91sam9g20-ek: Correct braces in I2C registration code The change introduced in patch 5596/1 used incorrect bracing which resulted in the AT24 EEPROM no longer being registered. This patch corrects the bracing and allows both the WM8731 audio device and AT24 EEPROM device to be registered. Signed-off-by: Rob Alley Signed-off-by: Russell King diff --git a/arch/arm/mach-at91/board-sam9g20ek.c b/arch/arm/mach-at91/board-sam9g20ek.c index 29cf831..c11fd47 100644 --- a/arch/arm/mach-at91/board-sam9g20ek.c +++ b/arch/arm/mach-at91/board-sam9g20ek.c @@ -271,10 +271,12 @@ static void __init ek_add_device_buttons(void) {} static struct i2c_board_info __initdata ek_i2c_devices[] = { - { - I2C_BOARD_INFO("24c512", 0x50), - I2C_BOARD_INFO("wm8731", 0x1b), - }, + { + I2C_BOARD_INFO("24c512", 0x50) + }, + { + I2C_BOARD_INFO("wm8731", 0x1b) + }, }; -- cgit v0.10.2 From bb35579b45bcb0b74167a2165d3ea973f640bf00 Mon Sep 17 00:00:00 2001 From: Mikael Pettersson Date: Thu, 11 Mar 2010 12:28:31 +0100 Subject: ARM: 5987/1: fix warning in kernel/elfcore.c from ARM's elf.h 2.6.34-rc1 added kernel/elfcore.c which includes . On ARM, this results in: In file included from include/linux/elf.h:7, from kernel/elfcore.c:1: /tmp/linux-2.6.34-rc1/arch/arm/include/asm/elf.h:101: warning: 'struct task_struct' declared inside parameter list /tmp/linux-2.6.34-rc1/arch/arm/include/asm/elf.h:101: warning: its scope is only this definition or declaration, which is probably not what you want Including seems a bit heavyweight, so this patch just adds a tentative declaration of struct task_struct in . Signed-off-by: Mikael Pettersson Signed-off-by: Russell King diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h index a399bb5..bff0564 100644 --- a/arch/arm/include/asm/elf.h +++ b/arch/arm/include/asm/elf.h @@ -98,6 +98,7 @@ extern int elf_check_arch(const struct elf32_hdr *); extern int arm_elf_read_implies_exec(const struct elf32_hdr *, int); #define elf_read_implies_exec(ex,stk) arm_elf_read_implies_exec(&(ex), stk) +struct task_struct; int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs); #define ELF_CORE_COPY_TASK_REGS dump_task_regs -- cgit v0.10.2 From a91ed072d6135926c296a42b0b46de35e6347845 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Fri, 12 Mar 2010 06:19:25 +0100 Subject: ARM: 5988/1: pgprot_dmacoherent() for non-mmu builds Commit 26a26d329688ab018e068b412b03d43d7c299f0a ("dma-mapping: switch ARMv7 DMA mappings to retain 'memory' attribute") added a new macro, pgprot_dmacoherent(), to correctly map DMA memory. The non-mmu pgtable support code also needs to implement this macro, otherwise when compiling you get: CC arch/arm/mm/dma-mapping.o arch/arm/mm/dma-mapping.c: In function 'dma_alloc_coherent': arch/arm/mm/dma-mapping.c:320: error: implicit declaration of function 'pgprot_dmacoherent' arch/arm/mm/dma-mapping.c:320: error: 'pgprot_kernel' undeclared (first use in this function) arch/arm/mm/dma-mapping.c:320: error: (Each undeclared identifier is reported only once arch/arm/mm/dma-mapping.c:320: error: for each function it appears in.) Signed-off-by: Greg Ungerer Signed-off-by: Russell King diff --git a/arch/arm/include/asm/pgtable-nommu.h b/arch/arm/include/asm/pgtable-nommu.h index 013cfcd..ffc0e857 100644 --- a/arch/arm/include/asm/pgtable-nommu.h +++ b/arch/arm/include/asm/pgtable-nommu.h @@ -67,6 +67,7 @@ static inline int pte_file(pte_t pte) { return 0; } */ #define pgprot_noncached(prot) __pgprot(0) #define pgprot_writecombine(prot) __pgprot(0) +#define pgprot_dmacoherent(prot) __pgprot(0) /* -- cgit v0.10.2 From ddee87f208b6229d2910dd5930c87089dc56c87e Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Thu, 25 Feb 2010 15:04:14 +0100 Subject: ARM: 5959/1: ARM: perf-events: request PMU interrupts with IRQF_NOBALANCING If IRQ balancing is used on a multicore ARM system, PMU interrupt lines may be relocated onto CPUs other than the one causing the counter overflow. This can result in misattribution of events to the wrong core and, in the case that the CPU handling the interrupt has not experience counter overflow, the interrupt can be disabled because the handler returns IRQ_NONE. This patch adds the IRQF_NOBALANCING flag to the request_irq call in perf_events.c. Acked-by: Jamie Iles Signed-off-by: Will Deacon Signed-off-by: Russell King diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index c54ceb3..b44d159 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c @@ -332,7 +332,8 @@ armpmu_reserve_hardware(void) for (i = 0; i < pmu_irqs->num_irqs; ++i) { err = request_irq(pmu_irqs->irqs[i], armpmu->handle_irq, - IRQF_DISABLED, "armpmu", NULL); + IRQF_DISABLED | IRQF_NOBALANCING, + "armpmu", NULL); if (err) { pr_warning("unable to request IRQ%d for ARM " "perf counters\n", pmu_irqs->irqs[i]); -- cgit v0.10.2 From d10fca9f39238b07cc670b441d2b423de30359d2 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 26 Feb 2010 10:46:15 +0100 Subject: ARM: 5960/1: ARM: perf-events: fix v7 event selection mask The event selection mask for ARMv7 cores [ARMV7_EVTSEL_MASK] is incorrectly set to 0x7f. This means that the top bit of an event ID is ignored, so counting branch misses (id=0x10) and ISBs (id=0x90) give the same results. This patch sets the event selection mask to the correct value of 0xff. Signed-off-by: Jean Pihet Signed-off-by: Will Deacon Signed-off-by: Russell King diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index b44d159..c45a155 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c @@ -1625,7 +1625,7 @@ enum armv7_counters { /* * EVTSEL: Event selection reg */ -#define ARMV7_EVTSEL_MASK 0x7f /* Mask for writable bits */ +#define ARMV7_EVTSEL_MASK 0xff /* Mask for writable bits */ /* * SELECT: Counter selection reg -- cgit v0.10.2 From 97ee9b0257402f4731b55dfea42f24d26d793ddf Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Sat, 6 Mar 2010 04:44:14 +0000 Subject: net/9p: Use the tag name in the config space for identifying mount point This patch use the tag name in the config space to identify the mount device. The the virtio device name depend on the enumeration order of the device and may not remain the same across multiple boots So we use the tag name which is set via qemu option to uniquely identify the mount device Signed-off-by: Aneesh Kumar K.V Signed-off-by: Eric Van Hensbergen diff --git a/include/linux/virtio_9p.h b/include/linux/virtio_9p.h index 3322750..5cf1176 100644 --- a/include/linux/virtio_9p.h +++ b/include/linux/virtio_9p.h @@ -5,4 +5,16 @@ #include #include +/* The feature bitmap for virtio 9P */ + +/* The mount point is specified in a config variable */ +#define VIRTIO_9P_MOUNT_TAG 0 + +struct virtio_9p_config { + /* length of the tag name */ + __u16 tag_len; + /* non-NULL terminated tag name */ + __u8 tag[0]; +} __attribute__((packed)); + #endif /* _LINUX_VIRTIO_9P_H */ diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c index 0aaed48..026775a 100644 --- a/net/9p/trans_virtio.c +++ b/net/9p/trans_virtio.c @@ -78,6 +78,12 @@ struct virtio_chan { /* Scatterlist: can be too big for stack. */ struct scatterlist sg[VIRTQUEUE_NUM]; + int tag_len; + /* + * tag name to identify a mount Non-null terminated + */ + char *tag; + struct list_head chan_list; }; @@ -224,6 +230,8 @@ p9_virtio_request(struct p9_client *client, struct p9_req_t *req) static int p9_virtio_probe(struct virtio_device *vdev) { + __u16 tag_len; + char *tag; int err; struct virtio_chan *chan; @@ -248,6 +256,23 @@ static int p9_virtio_probe(struct virtio_device *vdev) sg_init_table(chan->sg, VIRTQUEUE_NUM); chan->inuse = false; + if (virtio_has_feature(vdev, VIRTIO_9P_MOUNT_TAG)) { + vdev->config->get(vdev, + offsetof(struct virtio_9p_config, tag_len), + &tag_len, sizeof(tag_len)); + } else { + err = -EINVAL; + goto out_free_vq; + } + tag = kmalloc(tag_len, GFP_KERNEL); + if (!tag) { + err = -ENOMEM; + goto out_free_vq; + } + vdev->config->get(vdev, offsetof(struct virtio_9p_config, tag), + tag, tag_len); + chan->tag = tag; + chan->tag_len = tag_len; mutex_lock(&virtio_9p_lock); list_add_tail(&chan->chan_list, &virtio_chan_list); mutex_unlock(&virtio_9p_lock); @@ -284,7 +309,7 @@ p9_virtio_create(struct p9_client *client, const char *devname, char *args) mutex_lock(&virtio_9p_lock); list_for_each_entry(chan, &virtio_chan_list, chan_list) { - if (!strcmp(devname, dev_name(&chan->vdev->dev))) { + if (!strncmp(devname, chan->tag, chan->tag_len)) { if (!chan->inuse) { chan->inuse = true; found = 1; @@ -323,6 +348,7 @@ static void p9_virtio_remove(struct virtio_device *vdev) mutex_lock(&virtio_9p_lock); list_del(&chan->chan_list); mutex_unlock(&virtio_9p_lock); + kfree(chan->tag); kfree(chan); } @@ -332,13 +358,19 @@ static struct virtio_device_id id_table[] = { { 0 }, }; +static unsigned int features[] = { + VIRTIO_9P_MOUNT_TAG, +}; + /* The standard "struct lguest_driver": */ static struct virtio_driver p9_virtio_drv = { - .driver.name = KBUILD_MODNAME, - .driver.owner = THIS_MODULE, - .id_table = id_table, - .probe = p9_virtio_probe, - .remove = p9_virtio_remove, + .feature_table = features, + .feature_table_size = ARRAY_SIZE(features), + .driver.name = KBUILD_MODNAME, + .driver.owner = THIS_MODULE, + .id_table = id_table, + .probe = p9_virtio_probe, + .remove = p9_virtio_remove, }; static struct p9_trans_module p9_virtio_trans = { -- cgit v0.10.2 From 86c8437383acd85c05ec7c9a004f59fe7ac9821a Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Sat, 6 Mar 2010 04:44:15 +0000 Subject: net/9p: Add sysfs mount_tag file for virtio 9P device This adds a new file for virtio 9P device. The file contain details of the mount device name that should be used to mount the 9P file system. Ex: /sys/devices/virtio-pci/virtio1/mount_tag file now contian the tag name to be used to mount the 9P file system. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Eric Van Hensbergen diff --git a/include/linux/virtio.h b/include/linux/virtio.h index f508c65..40d1709 100644 --- a/include/linux/virtio.h +++ b/include/linux/virtio.h @@ -98,6 +98,7 @@ struct virtio_device { void *priv; }; +#define dev_to_virtio(dev) container_of(dev, struct virtio_device, dev) int register_virtio_device(struct virtio_device *dev); void unregister_virtio_device(struct virtio_device *dev); diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c index 026775a..afde1a8 100644 --- a/net/9p/trans_virtio.c +++ b/net/9p/trans_virtio.c @@ -220,6 +220,20 @@ p9_virtio_request(struct p9_client *client, struct p9_req_t *req) return 0; } +static ssize_t p9_mount_tag_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct virtio_chan *chan; + struct virtio_device *vdev; + + vdev = dev_to_virtio(dev); + chan = vdev->priv; + + return snprintf(buf, chan->tag_len + 1, "%s", chan->tag); +} + +static DEVICE_ATTR(mount_tag, 0444, p9_mount_tag_show, NULL); + /** * p9_virtio_probe - probe for existence of 9P virtio channels * @vdev: virtio device to probe @@ -273,6 +287,11 @@ static int p9_virtio_probe(struct virtio_device *vdev) tag, tag_len); chan->tag = tag; chan->tag_len = tag_len; + err = sysfs_create_file(&(vdev->dev.kobj), &dev_attr_mount_tag.attr); + if (err) { + kfree(tag); + goto out_free_vq; + } mutex_lock(&virtio_9p_lock); list_add_tail(&chan->chan_list, &virtio_chan_list); mutex_unlock(&virtio_9p_lock); @@ -348,6 +367,7 @@ static void p9_virtio_remove(struct virtio_device *vdev) mutex_lock(&virtio_9p_lock); list_del(&chan->chan_list); mutex_unlock(&virtio_9p_lock); + sysfs_remove_file(&(vdev->dev.kobj), &dev_attr_mount_tag.attr); kfree(chan->tag); kfree(chan); -- cgit v0.10.2 From fae4528b2341f2ab0c86c191e24d9cdd93624c60 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Sat, 6 Mar 2010 04:44:16 +0000 Subject: fs/9p: re-init the wstat in readdir loop This ensure that on failure when we free the stat buf we don't end up freeing an already freed pointer in the earlier loop Signed-off-by: Aneesh Kumar K.V Signed-off-by: Sripathi Kodi Signed-off-by: Eric Van Hensbergen diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c index 6580aa4..d8a3afe 100644 --- a/fs/9p/vfs_dir.c +++ b/fs/9p/vfs_dir.c @@ -76,6 +76,15 @@ static inline int dt_type(struct p9_wstat *mistat) return rettype; } +static void p9stat_init(struct p9_wstat *stbuf) +{ + stbuf->name = NULL; + stbuf->uid = NULL; + stbuf->gid = NULL; + stbuf->muid = NULL; + stbuf->extension = NULL; +} + /** * v9fs_dir_readdir - read a directory * @filp: opened file structure @@ -131,8 +140,8 @@ static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir) rdir->head = 0; rdir->tail = err; } - while (rdir->head < rdir->tail) { + p9stat_init(&st); err = p9stat_read(rdir->buf + rdir->head, buflen - rdir->head, &st, fid->clnt->proto_version); -- cgit v0.10.2 From 45bc21edb52fa71dbb1324c6f573aa880e95519d Mon Sep 17 00:00:00 2001 From: Sripathi Kodi Date: Mon, 8 Mar 2010 17:33:04 +0000 Subject: 9p: Change the name of new protocol from 9p2010.L to 9p2000.L This patch changes the name of the new 9P protocol from 9p2010.L to 9p2000.u. This is because we learnt that the name 9p2010 is already being used by others. Signed-off-by: Sripathi Kodi Signed-off-by: Eric Van Hensbergen diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h index 79000bf..6b801d1 100644 --- a/fs/9p/v9fs.h +++ b/fs/9p/v9fs.h @@ -24,7 +24,7 @@ /** * enum p9_session_flags - option flags for each 9P session * @V9FS_PROTO_2000U: whether or not to use 9P2000.u extensions - * @V9FS_PROTO_2010L: whether or not to use 9P2010.l extensions + * @V9FS_PROTO_2000L: whether or not to use 9P2000.l extensions * @V9FS_ACCESS_SINGLE: only the mounting user can access the hierarchy * @V9FS_ACCESS_USER: a new attach will be issued for every user (default) * @V9FS_ACCESS_ANY: use a single attach for all users @@ -34,7 +34,7 @@ */ enum p9_session_flags { V9FS_PROTO_2000U = 0x01, - V9FS_PROTO_2010L = 0x02, + V9FS_PROTO_2000L = 0x02, V9FS_ACCESS_SINGLE = 0x04, V9FS_ACCESS_USER = 0x08, V9FS_ACCESS_ANY = 0x0C, @@ -130,5 +130,5 @@ static inline int v9fs_proto_dotu(struct v9fs_session_info *v9ses) static inline int v9fs_proto_dotl(struct v9fs_session_info *v9ses) { - return v9ses->flags & V9FS_PROTO_2010L; + return v9ses->flags & V9FS_PROTO_2000L; } diff --git a/include/net/9p/client.h b/include/net/9p/client.h index 52e1fff..f076dfa 100644 --- a/include/net/9p/client.h +++ b/include/net/9p/client.h @@ -32,13 +32,13 @@ /** enum p9_proto_versions - 9P protocol versions * @p9_proto_legacy: 9P Legacy mode, pre-9P2000.u * @p9_proto_2000u: 9P2000.u extension - * @p9_proto_2010L: 9P2010.L extension + * @p9_proto_2000L: 9P2000.L extension */ enum p9_proto_versions{ p9_proto_legacy = 0, p9_proto_2000u = 1, - p9_proto_2010L = 2, + p9_proto_2000L = 2, }; diff --git a/net/9p/client.c b/net/9p/client.c index bde9f3d..e3e5bf4 100644 --- a/net/9p/client.c +++ b/net/9p/client.c @@ -60,7 +60,7 @@ static const match_table_t tokens = { inline int p9_is_proto_dotl(struct p9_client *clnt) { - return (clnt->proto_version == p9_proto_2010L); + return (clnt->proto_version == p9_proto_2000L); } EXPORT_SYMBOL(p9_is_proto_dotl); @@ -80,9 +80,9 @@ static unsigned char get_protocol_version(const substring_t *name) } else if (!strncmp("9p2000.u", name->from, name->to-name->from)) { version = p9_proto_2000u; P9_DPRINTK(P9_DEBUG_9P, "Protocol version: 9P2000.u\n"); - } else if (!strncmp("9p2010.L", name->from, name->to-name->from)) { - version = p9_proto_2010L; - P9_DPRINTK(P9_DEBUG_9P, "Protocol version: 9P2010.L\n"); + } else if (!strncmp("9p2000.L", name->from, name->to-name->from)) { + version = p9_proto_2000L; + P9_DPRINTK(P9_DEBUG_9P, "Protocol version: 9P2000.L\n"); } else { P9_DPRINTK(P9_DEBUG_ERROR, "Unknown protocol version %s. ", name->from); @@ -672,9 +672,9 @@ int p9_client_version(struct p9_client *c) c->msize, c->proto_version); switch (c->proto_version) { - case p9_proto_2010L: + case p9_proto_2000L: req = p9_client_rpc(c, P9_TVERSION, "ds", - c->msize, "9P2010.L"); + c->msize, "9P2000.L"); break; case p9_proto_2000u: req = p9_client_rpc(c, P9_TVERSION, "ds", @@ -700,8 +700,8 @@ int p9_client_version(struct p9_client *c) } P9_DPRINTK(P9_DEBUG_9P, "<<< RVERSION msize %d %s\n", msize, version); - if (!strncmp(version, "9P2010.L", 8)) - c->proto_version = p9_proto_2010L; + if (!strncmp(version, "9P2000.L", 8)) + c->proto_version = p9_proto_2000L; else if (!strncmp(version, "9P2000.u", 8)) c->proto_version = p9_proto_2000u; else if (!strncmp(version, "9P2000", 6)) -- cgit v0.10.2 From fc0f296126433e61600539325975b6c30681c07e Mon Sep 17 00:00:00 2001 From: jvrao Date: Mon, 8 Mar 2010 22:07:02 +0000 Subject: 9p: Fixes a simple bug enabling writes beyond 2GB. Fixes a simple bug so that large files beyond 2GB can be created. Signed-off-by: Venkateswararao Jujjuri Signed-off-by: Badari Pulavarty Signed-off-by: Eric Van Hensbergen diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index 3612268..019f1cd 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c @@ -215,7 +215,7 @@ v9fs_file_write(struct file *filp, const char __user * data, struct p9_fid *fid; struct p9_client *clnt; struct inode *inode = filp->f_path.dentry->d_inode; - int origin = *offset; + loff_t origin = *offset; unsigned long pg_start, pg_end; P9_DPRINTK(P9_DEBUG_VFS, "data %p count %d offset %x\n", data, -- cgit v0.10.2 From f78233dd44a110c574fe760ad6f9c1e8741a0d00 Mon Sep 17 00:00:00 2001 From: Sachin Prabhu Date: Sat, 13 Mar 2010 09:03:55 -0600 Subject: 9p: Skip check for mandatory locks when unlocking While investigating a bug, I came across a possible bug in v9fs. The problem is similar to the one reported for NFS by ASANO Masahiro in http://lkml.org/lkml/2005/12/21/334. v9fs_file_lock() will skip locks on file which has mode set to 02666. This is a problem in cases where the mode of the file is changed after a process has obtained a lock on the file. Such a lock will be skipped during unlock and the machine will end up with a BUG in locks_remove_flock(). v9fs_file_lock() should skip the check for mandatory locks when unlocking a file. Signed-off-by: Sachin Prabhu Signed-off-by: Eric Van Hensbergen diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index 019f1cd..df52d48 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c @@ -114,7 +114,7 @@ static int v9fs_file_lock(struct file *filp, int cmd, struct file_lock *fl) P9_DPRINTK(P9_DEBUG_VFS, "filp: %p lock: %p\n", filp, fl); /* No mandatory locks */ - if (__mandatory_lock(inode)) + if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK) return -ENOLCK; if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) { -- cgit v0.10.2 From f635a1e74bd6001f06fe1df53d32daf2b28bf04b Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 1 Mar 2010 16:04:45 +1100 Subject: i2c-smbus: Use device_lock/device_unlock Use the new device locking/unlocking API. Signed-off-by: Stephen Rothwell Signed-off-by: Jean Delvare diff --git a/drivers/i2c/i2c-smbus.c b/drivers/i2c/i2c-smbus.c index 4212782..7a8201e 100644 --- a/drivers/i2c/i2c-smbus.c +++ b/drivers/i2c/i2c-smbus.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -55,7 +54,7 @@ static int smbus_do_alert(struct device *dev, void *addrp) * Drivers should either disable alerts, or provide at least * a minimal handler. Lock so client->driver won't change. */ - down(&dev->sem); + device_lock(dev); if (client->driver) { if (client->driver->alert) client->driver->alert(client, data->flag); @@ -63,7 +62,7 @@ static int smbus_do_alert(struct device *dev, void *addrp) dev_warn(&client->dev, "no driver alert()!\n"); } else dev_dbg(&client->dev, "alert with no driver\n"); - up(&dev->sem); + device_unlock(dev); /* Stop iterating after we find the device */ return -EBUSY; -- cgit v0.10.2 From 8e4b980c28c91cfe9d0ce0431bc0af56e146b49e Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 13 Mar 2010 20:56:52 +0100 Subject: i2c-powermac: Be less verbose in the absence of real errors. Be less verbose in the absence of real errors. We don't have to report failed probes to the users, it's only confusing them. Signed-off-by: Jean Delvare Tested-by: Andrey Gusev Cc: Benjamin Herrenschmidt Cc: stable@kernel.org diff --git a/drivers/i2c/busses/i2c-powermac.c b/drivers/i2c/busses/i2c-powermac.c index 1c440a7..b289ec9 100644 --- a/drivers/i2c/busses/i2c-powermac.c +++ b/drivers/i2c/busses/i2c-powermac.c @@ -122,9 +122,14 @@ static s32 i2c_powermac_smbus_xfer( struct i2c_adapter* adap, rc = pmac_i2c_xfer(bus, addrdir, subsize, subaddr, buf, len); if (rc) { - dev_err(&adap->dev, - "I2C transfer at 0x%02x failed, size %d, err %d\n", - addrdir >> 1, size, rc); + if (rc == -ENXIO) + dev_dbg(&adap->dev, + "I2C transfer at 0x%02x failed, size %d, " + "err %d\n", addrdir >> 1, size, rc); + else + dev_err(&adap->dev, + "I2C transfer at 0x%02x failed, size %d, " + "err %d\n", addrdir >> 1, size, rc); goto bail; } @@ -175,10 +180,16 @@ static int i2c_powermac_master_xfer( struct i2c_adapter *adap, goto bail; } rc = pmac_i2c_xfer(bus, addrdir, 0, 0, msgs->buf, msgs->len); - if (rc < 0) - dev_err(&adap->dev, "I2C %s 0x%02x failed, err %d\n", - addrdir & 1 ? "read from" : "write to", addrdir >> 1, - rc); + if (rc < 0) { + if (rc == -ENXIO) + dev_dbg(&adap->dev, "I2C %s 0x%02x failed, err %d\n", + addrdir & 1 ? "read from" : "write to", + addrdir >> 1, rc); + else + dev_err(&adap->dev, "I2C %s 0x%02x failed, err %d\n", + addrdir & 1 ? "read from" : "write to", + addrdir >> 1, rc); + } bail: pmac_i2c_close(bus); return rc < 0 ? rc : 1; -- cgit v0.10.2 From c074c39d62306efa5ba7c69c1a1531bc7333d252 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 13 Mar 2010 20:56:53 +0100 Subject: i2c-i801: Don't use the block buffer for I2C block writes Experience has shown that the block buffer can only be used for SMBus (not I2C) block transactions, even though the datasheet doesn't mention this limitation. Reported-by: Felix Rubinstein Signed-off-by: Jean Delvare Cc: Oleg Ryjkov Cc: stable@kernel.org diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 9da5b05..299b918 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -416,9 +416,11 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write, data->block[0] = 32; /* max for SMBus block reads */ } + /* Experience has shown that the block buffer can only be used for + SMBus (not I2C) block transactions, even though the datasheet + doesn't mention this limitation. */ if ((i801_features & FEATURE_BLOCK_BUFFER) - && !(command == I2C_SMBUS_I2C_BLOCK_DATA - && read_write == I2C_SMBUS_READ) + && command != I2C_SMBUS_I2C_BLOCK_DATA && i801_set_block_buffer_mode() == 0) result = i801_block_transaction_by_block(data, read_write, hwpec); -- cgit v0.10.2 From 6a9bcced518b98a7e52b9e8e96af228b171e0498 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 13 Mar 2010 20:56:54 +0100 Subject: tsl2550: Move from i2c/chips to misc Move the last remaining driver from i2c/chips to misc. Good ridance! Signed-off-by: Jean Delvare Acked-by: Wolfram Sang Acked-by: Jonathan Cameron diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index 02ce9cf..7bcde5d 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -73,7 +73,6 @@ config I2C_SMBUS source drivers/i2c/algos/Kconfig source drivers/i2c/busses/Kconfig -source drivers/i2c/chips/Kconfig config I2C_DEBUG_CORE bool "I2C Core debugging messages" diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index acd0250..a7d9b4b 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -6,7 +6,7 @@ obj-$(CONFIG_I2C_BOARDINFO) += i2c-boardinfo.o obj-$(CONFIG_I2C) += i2c-core.o obj-$(CONFIG_I2C_SMBUS) += i2c-smbus.o obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o -obj-y += busses/ chips/ algos/ +obj-y += algos/ busses/ ifeq ($(CONFIG_I2C_DEBUG_CORE),y) EXTRA_CFLAGS += -DDEBUG diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig deleted file mode 100644 index ae4539d..0000000 --- a/drivers/i2c/chips/Kconfig +++ /dev/null @@ -1,19 +0,0 @@ -# -# Miscellaneous I2C chip drivers configuration -# -# *** DEPRECATED! Do not add new entries! See Makefile *** -# - -menu "Miscellaneous I2C Chip support" - -config SENSORS_TSL2550 - tristate "Taos TSL2550 ambient light sensor" - depends on EXPERIMENTAL - help - If you say yes here you get support for the Taos TSL2550 - ambient light sensor. - - This driver can also be built as a module. If so, the module - will be called tsl2550. - -endmenu diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile deleted file mode 100644 index fe0af0f..0000000 --- a/drivers/i2c/chips/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -# -# Makefile for miscellaneous I2C chip drivers. -# -# Do not add new drivers to this directory! It is DEPRECATED. -# -# Device drivers are better grouped according to the functionality they -# implement rather than to the bus they are connected to. In particular: -# * Hardware monitoring chip drivers go to drivers/hwmon -# * RTC chip drivers go to drivers/rtc -# * I/O expander drivers go to drivers/gpio -# - -obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o - -ifeq ($(CONFIG_I2C_DEBUG_CHIP),y) -EXTRA_CFLAGS += -DDEBUG -endif - diff --git a/drivers/i2c/chips/tsl2550.c b/drivers/i2c/chips/tsl2550.c deleted file mode 100644 index a0702f3..0000000 --- a/drivers/i2c/chips/tsl2550.c +++ /dev/null @@ -1,473 +0,0 @@ -/* - * tsl2550.c - Linux kernel modules for ambient light sensor - * - * Copyright (C) 2007 Rodolfo Giometti - * Copyright (C) 2007 Eurotech S.p.A. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include - -#define TSL2550_DRV_NAME "tsl2550" -#define DRIVER_VERSION "1.2" - -/* - * Defines - */ - -#define TSL2550_POWER_DOWN 0x00 -#define TSL2550_POWER_UP 0x03 -#define TSL2550_STANDARD_RANGE 0x18 -#define TSL2550_EXTENDED_RANGE 0x1d -#define TSL2550_READ_ADC0 0x43 -#define TSL2550_READ_ADC1 0x83 - -/* - * Structs - */ - -struct tsl2550_data { - struct i2c_client *client; - struct mutex update_lock; - - unsigned int power_state : 1; - unsigned int operating_mode : 1; -}; - -/* - * Global data - */ - -static const u8 TSL2550_MODE_RANGE[2] = { - TSL2550_STANDARD_RANGE, TSL2550_EXTENDED_RANGE, -}; - -/* - * Management functions - */ - -static int tsl2550_set_operating_mode(struct i2c_client *client, int mode) -{ - struct tsl2550_data *data = i2c_get_clientdata(client); - - int ret = i2c_smbus_write_byte(client, TSL2550_MODE_RANGE[mode]); - - data->operating_mode = mode; - - return ret; -} - -static int tsl2550_set_power_state(struct i2c_client *client, int state) -{ - struct tsl2550_data *data = i2c_get_clientdata(client); - int ret; - - if (state == 0) - ret = i2c_smbus_write_byte(client, TSL2550_POWER_DOWN); - else { - ret = i2c_smbus_write_byte(client, TSL2550_POWER_UP); - - /* On power up we should reset operating mode also... */ - tsl2550_set_operating_mode(client, data->operating_mode); - } - - data->power_state = state; - - return ret; -} - -static int tsl2550_get_adc_value(struct i2c_client *client, u8 cmd) -{ - int ret; - - ret = i2c_smbus_read_byte_data(client, cmd); - if (ret < 0) - return ret; - if (!(ret & 0x80)) - return -EAGAIN; - return ret & 0x7f; /* remove the "valid" bit */ -} - -/* - * LUX calculation - */ - -#define TSL2550_MAX_LUX 1846 - -static const u8 ratio_lut[] = { - 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 100, 100, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 98, 98, 98, 98, 98, - 98, 98, 97, 97, 97, 97, 97, 96, - 96, 96, 96, 95, 95, 95, 94, 94, - 93, 93, 93, 92, 92, 91, 91, 90, - 89, 89, 88, 87, 87, 86, 85, 84, - 83, 82, 81, 80, 79, 78, 77, 75, - 74, 73, 71, 69, 68, 66, 64, 62, - 60, 58, 56, 54, 52, 49, 47, 44, - 42, 41, 40, 40, 39, 39, 38, 38, - 37, 37, 37, 36, 36, 36, 35, 35, - 35, 35, 34, 34, 34, 34, 33, 33, - 33, 33, 32, 32, 32, 32, 32, 31, - 31, 31, 31, 31, 30, 30, 30, 30, - 30, -}; - -static const u16 count_lut[] = { - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 18, 20, 22, 24, 26, 28, 30, - 32, 34, 36, 38, 40, 42, 44, 46, - 49, 53, 57, 61, 65, 69, 73, 77, - 81, 85, 89, 93, 97, 101, 105, 109, - 115, 123, 131, 139, 147, 155, 163, 171, - 179, 187, 195, 203, 211, 219, 227, 235, - 247, 263, 279, 295, 311, 327, 343, 359, - 375, 391, 407, 423, 439, 455, 471, 487, - 511, 543, 575, 607, 639, 671, 703, 735, - 767, 799, 831, 863, 895, 927, 959, 991, - 1039, 1103, 1167, 1231, 1295, 1359, 1423, 1487, - 1551, 1615, 1679, 1743, 1807, 1871, 1935, 1999, - 2095, 2223, 2351, 2479, 2607, 2735, 2863, 2991, - 3119, 3247, 3375, 3503, 3631, 3759, 3887, 4015, -}; - -/* - * This function is described into Taos TSL2550 Designer's Notebook - * pages 2, 3. - */ -static int tsl2550_calculate_lux(u8 ch0, u8 ch1) -{ - unsigned int lux; - - /* Look up count from channel values */ - u16 c0 = count_lut[ch0]; - u16 c1 = count_lut[ch1]; - - /* - * Calculate ratio. - * Note: the "128" is a scaling factor - */ - u8 r = 128; - - /* Avoid division by 0 and count 1 cannot be greater than count 0 */ - if (c1 <= c0) - if (c0) { - r = c1 * 128 / c0; - - /* Calculate LUX */ - lux = ((c0 - c1) * ratio_lut[r]) / 256; - } else - lux = 0; - else - return -EAGAIN; - - /* LUX range check */ - return lux > TSL2550_MAX_LUX ? TSL2550_MAX_LUX : lux; -} - -/* - * SysFS support - */ - -static ssize_t tsl2550_show_power_state(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct tsl2550_data *data = i2c_get_clientdata(to_i2c_client(dev)); - - return sprintf(buf, "%u\n", data->power_state); -} - -static ssize_t tsl2550_store_power_state(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - struct tsl2550_data *data = i2c_get_clientdata(client); - unsigned long val = simple_strtoul(buf, NULL, 10); - int ret; - - if (val < 0 || val > 1) - return -EINVAL; - - mutex_lock(&data->update_lock); - ret = tsl2550_set_power_state(client, val); - mutex_unlock(&data->update_lock); - - if (ret < 0) - return ret; - - return count; -} - -static DEVICE_ATTR(power_state, S_IWUSR | S_IRUGO, - tsl2550_show_power_state, tsl2550_store_power_state); - -static ssize_t tsl2550_show_operating_mode(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct tsl2550_data *data = i2c_get_clientdata(to_i2c_client(dev)); - - return sprintf(buf, "%u\n", data->operating_mode); -} - -static ssize_t tsl2550_store_operating_mode(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - struct tsl2550_data *data = i2c_get_clientdata(client); - unsigned long val = simple_strtoul(buf, NULL, 10); - int ret; - - if (val < 0 || val > 1) - return -EINVAL; - - if (data->power_state == 0) - return -EBUSY; - - mutex_lock(&data->update_lock); - ret = tsl2550_set_operating_mode(client, val); - mutex_unlock(&data->update_lock); - - if (ret < 0) - return ret; - - return count; -} - -static DEVICE_ATTR(operating_mode, S_IWUSR | S_IRUGO, - tsl2550_show_operating_mode, tsl2550_store_operating_mode); - -static ssize_t __tsl2550_show_lux(struct i2c_client *client, char *buf) -{ - struct tsl2550_data *data = i2c_get_clientdata(client); - u8 ch0, ch1; - int ret; - - ret = tsl2550_get_adc_value(client, TSL2550_READ_ADC0); - if (ret < 0) - return ret; - ch0 = ret; - - ret = tsl2550_get_adc_value(client, TSL2550_READ_ADC1); - if (ret < 0) - return ret; - ch1 = ret; - - /* Do the job */ - ret = tsl2550_calculate_lux(ch0, ch1); - if (ret < 0) - return ret; - if (data->operating_mode == 1) - ret *= 5; - - return sprintf(buf, "%d\n", ret); -} - -static ssize_t tsl2550_show_lux1_input(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - struct tsl2550_data *data = i2c_get_clientdata(client); - int ret; - - /* No LUX data if not operational */ - if (!data->power_state) - return -EBUSY; - - mutex_lock(&data->update_lock); - ret = __tsl2550_show_lux(client, buf); - mutex_unlock(&data->update_lock); - - return ret; -} - -static DEVICE_ATTR(lux1_input, S_IRUGO, - tsl2550_show_lux1_input, NULL); - -static struct attribute *tsl2550_attributes[] = { - &dev_attr_power_state.attr, - &dev_attr_operating_mode.attr, - &dev_attr_lux1_input.attr, - NULL -}; - -static const struct attribute_group tsl2550_attr_group = { - .attrs = tsl2550_attributes, -}; - -/* - * Initialization function - */ - -static int tsl2550_init_client(struct i2c_client *client) -{ - struct tsl2550_data *data = i2c_get_clientdata(client); - int err; - - /* - * Probe the chip. To do so we try to power up the device and then to - * read back the 0x03 code - */ - err = i2c_smbus_read_byte_data(client, TSL2550_POWER_UP); - if (err < 0) - return err; - if (err != TSL2550_POWER_UP) - return -ENODEV; - data->power_state = 1; - - /* Set the default operating mode */ - err = i2c_smbus_write_byte(client, - TSL2550_MODE_RANGE[data->operating_mode]); - if (err < 0) - return err; - - return 0; -} - -/* - * I2C init/probing/exit functions - */ - -static struct i2c_driver tsl2550_driver; -static int __devinit tsl2550_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); - struct tsl2550_data *data; - int *opmode, err = 0; - - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE - | I2C_FUNC_SMBUS_READ_BYTE_DATA)) { - err = -EIO; - goto exit; - } - - data = kzalloc(sizeof(struct tsl2550_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } - data->client = client; - i2c_set_clientdata(client, data); - - /* Check platform data */ - opmode = client->dev.platform_data; - if (opmode) { - if (*opmode < 0 || *opmode > 1) { - dev_err(&client->dev, "invalid operating_mode (%d)\n", - *opmode); - err = -EINVAL; - goto exit_kfree; - } - data->operating_mode = *opmode; - } else - data->operating_mode = 0; /* default mode is standard */ - dev_info(&client->dev, "%s operating mode\n", - data->operating_mode ? "extended" : "standard"); - - mutex_init(&data->update_lock); - - /* Initialize the TSL2550 chip */ - err = tsl2550_init_client(client); - if (err) - goto exit_kfree; - - /* Register sysfs hooks */ - err = sysfs_create_group(&client->dev.kobj, &tsl2550_attr_group); - if (err) - goto exit_kfree; - - dev_info(&client->dev, "support ver. %s enabled\n", DRIVER_VERSION); - - return 0; - -exit_kfree: - kfree(data); -exit: - return err; -} - -static int __devexit tsl2550_remove(struct i2c_client *client) -{ - sysfs_remove_group(&client->dev.kobj, &tsl2550_attr_group); - - /* Power down the device */ - tsl2550_set_power_state(client, 0); - - kfree(i2c_get_clientdata(client)); - - return 0; -} - -#ifdef CONFIG_PM - -static int tsl2550_suspend(struct i2c_client *client, pm_message_t mesg) -{ - return tsl2550_set_power_state(client, 0); -} - -static int tsl2550_resume(struct i2c_client *client) -{ - return tsl2550_set_power_state(client, 1); -} - -#else - -#define tsl2550_suspend NULL -#define tsl2550_resume NULL - -#endif /* CONFIG_PM */ - -static const struct i2c_device_id tsl2550_id[] = { - { "tsl2550", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, tsl2550_id); - -static struct i2c_driver tsl2550_driver = { - .driver = { - .name = TSL2550_DRV_NAME, - .owner = THIS_MODULE, - }, - .suspend = tsl2550_suspend, - .resume = tsl2550_resume, - .probe = tsl2550_probe, - .remove = __devexit_p(tsl2550_remove), - .id_table = tsl2550_id, -}; - -static int __init tsl2550_init(void) -{ - return i2c_add_driver(&tsl2550_driver); -} - -static void __exit tsl2550_exit(void) -{ - i2c_del_driver(&tsl2550_driver); -} - -MODULE_AUTHOR("Rodolfo Giometti "); -MODULE_DESCRIPTION("TSL2550 ambient light sensor driver"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(DRIVER_VERSION); - -module_init(tsl2550_init); -module_exit(tsl2550_exit); diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index d16af6a..2191c8d 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -268,6 +268,16 @@ config ISL29003 This driver can also be built as a module. If so, the module will be called isl29003. +config SENSORS_TSL2550 + tristate "Taos TSL2550 ambient light sensor" + depends on I2C && SYSFS + help + If you say yes here you get support for the Taos TSL2550 + ambient light sensor. + + This driver can also be built as a module. If so, the module + will be called tsl2550. + config EP93XX_PWM tristate "EP93xx PWM support" depends on ARCH_EP93XX diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 049ff24..27c4843 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -21,6 +21,7 @@ obj-$(CONFIG_SGI_GRU) += sgi-gru/ obj-$(CONFIG_CS5535_MFGPT) += cs5535-mfgpt.o obj-$(CONFIG_HP_ILO) += hpilo.o obj-$(CONFIG_ISL29003) += isl29003.o +obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o obj-$(CONFIG_EP93XX_PWM) += ep93xx_pwm.o obj-$(CONFIG_DS1682) += ds1682.o obj-$(CONFIG_TI_DAC7512) += ti_dac7512.o diff --git a/drivers/misc/tsl2550.c b/drivers/misc/tsl2550.c new file mode 100644 index 0000000..483ae5f --- /dev/null +++ b/drivers/misc/tsl2550.c @@ -0,0 +1,473 @@ +/* + * tsl2550.c - Linux kernel modules for ambient light sensor + * + * Copyright (C) 2007 Rodolfo Giometti + * Copyright (C) 2007 Eurotech S.p.A. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include + +#define TSL2550_DRV_NAME "tsl2550" +#define DRIVER_VERSION "1.2" + +/* + * Defines + */ + +#define TSL2550_POWER_DOWN 0x00 +#define TSL2550_POWER_UP 0x03 +#define TSL2550_STANDARD_RANGE 0x18 +#define TSL2550_EXTENDED_RANGE 0x1d +#define TSL2550_READ_ADC0 0x43 +#define TSL2550_READ_ADC1 0x83 + +/* + * Structs + */ + +struct tsl2550_data { + struct i2c_client *client; + struct mutex update_lock; + + unsigned int power_state:1; + unsigned int operating_mode:1; +}; + +/* + * Global data + */ + +static const u8 TSL2550_MODE_RANGE[2] = { + TSL2550_STANDARD_RANGE, TSL2550_EXTENDED_RANGE, +}; + +/* + * Management functions + */ + +static int tsl2550_set_operating_mode(struct i2c_client *client, int mode) +{ + struct tsl2550_data *data = i2c_get_clientdata(client); + + int ret = i2c_smbus_write_byte(client, TSL2550_MODE_RANGE[mode]); + + data->operating_mode = mode; + + return ret; +} + +static int tsl2550_set_power_state(struct i2c_client *client, int state) +{ + struct tsl2550_data *data = i2c_get_clientdata(client); + int ret; + + if (state == 0) + ret = i2c_smbus_write_byte(client, TSL2550_POWER_DOWN); + else { + ret = i2c_smbus_write_byte(client, TSL2550_POWER_UP); + + /* On power up we should reset operating mode also... */ + tsl2550_set_operating_mode(client, data->operating_mode); + } + + data->power_state = state; + + return ret; +} + +static int tsl2550_get_adc_value(struct i2c_client *client, u8 cmd) +{ + int ret; + + ret = i2c_smbus_read_byte_data(client, cmd); + if (ret < 0) + return ret; + if (!(ret & 0x80)) + return -EAGAIN; + return ret & 0x7f; /* remove the "valid" bit */ +} + +/* + * LUX calculation + */ + +#define TSL2550_MAX_LUX 1846 + +static const u8 ratio_lut[] = { + 100, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 100, 100, 100, 100, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 98, 98, 98, 98, 98, + 98, 98, 97, 97, 97, 97, 97, 96, + 96, 96, 96, 95, 95, 95, 94, 94, + 93, 93, 93, 92, 92, 91, 91, 90, + 89, 89, 88, 87, 87, 86, 85, 84, + 83, 82, 81, 80, 79, 78, 77, 75, + 74, 73, 71, 69, 68, 66, 64, 62, + 60, 58, 56, 54, 52, 49, 47, 44, + 42, 41, 40, 40, 39, 39, 38, 38, + 37, 37, 37, 36, 36, 36, 35, 35, + 35, 35, 34, 34, 34, 34, 33, 33, + 33, 33, 32, 32, 32, 32, 32, 31, + 31, 31, 31, 31, 30, 30, 30, 30, + 30, +}; + +static const u16 count_lut[] = { + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 18, 20, 22, 24, 26, 28, 30, + 32, 34, 36, 38, 40, 42, 44, 46, + 49, 53, 57, 61, 65, 69, 73, 77, + 81, 85, 89, 93, 97, 101, 105, 109, + 115, 123, 131, 139, 147, 155, 163, 171, + 179, 187, 195, 203, 211, 219, 227, 235, + 247, 263, 279, 295, 311, 327, 343, 359, + 375, 391, 407, 423, 439, 455, 471, 487, + 511, 543, 575, 607, 639, 671, 703, 735, + 767, 799, 831, 863, 895, 927, 959, 991, + 1039, 1103, 1167, 1231, 1295, 1359, 1423, 1487, + 1551, 1615, 1679, 1743, 1807, 1871, 1935, 1999, + 2095, 2223, 2351, 2479, 2607, 2735, 2863, 2991, + 3119, 3247, 3375, 3503, 3631, 3759, 3887, 4015, +}; + +/* + * This function is described into Taos TSL2550 Designer's Notebook + * pages 2, 3. + */ +static int tsl2550_calculate_lux(u8 ch0, u8 ch1) +{ + unsigned int lux; + + /* Look up count from channel values */ + u16 c0 = count_lut[ch0]; + u16 c1 = count_lut[ch1]; + + /* + * Calculate ratio. + * Note: the "128" is a scaling factor + */ + u8 r = 128; + + /* Avoid division by 0 and count 1 cannot be greater than count 0 */ + if (c1 <= c0) + if (c0) { + r = c1 * 128 / c0; + + /* Calculate LUX */ + lux = ((c0 - c1) * ratio_lut[r]) / 256; + } else + lux = 0; + else + return -EAGAIN; + + /* LUX range check */ + return lux > TSL2550_MAX_LUX ? TSL2550_MAX_LUX : lux; +} + +/* + * SysFS support + */ + +static ssize_t tsl2550_show_power_state(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tsl2550_data *data = i2c_get_clientdata(to_i2c_client(dev)); + + return sprintf(buf, "%u\n", data->power_state); +} + +static ssize_t tsl2550_store_power_state(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct tsl2550_data *data = i2c_get_clientdata(client); + unsigned long val = simple_strtoul(buf, NULL, 10); + int ret; + + if (val < 0 || val > 1) + return -EINVAL; + + mutex_lock(&data->update_lock); + ret = tsl2550_set_power_state(client, val); + mutex_unlock(&data->update_lock); + + if (ret < 0) + return ret; + + return count; +} + +static DEVICE_ATTR(power_state, S_IWUSR | S_IRUGO, + tsl2550_show_power_state, tsl2550_store_power_state); + +static ssize_t tsl2550_show_operating_mode(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tsl2550_data *data = i2c_get_clientdata(to_i2c_client(dev)); + + return sprintf(buf, "%u\n", data->operating_mode); +} + +static ssize_t tsl2550_store_operating_mode(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct tsl2550_data *data = i2c_get_clientdata(client); + unsigned long val = simple_strtoul(buf, NULL, 10); + int ret; + + if (val < 0 || val > 1) + return -EINVAL; + + if (data->power_state == 0) + return -EBUSY; + + mutex_lock(&data->update_lock); + ret = tsl2550_set_operating_mode(client, val); + mutex_unlock(&data->update_lock); + + if (ret < 0) + return ret; + + return count; +} + +static DEVICE_ATTR(operating_mode, S_IWUSR | S_IRUGO, + tsl2550_show_operating_mode, tsl2550_store_operating_mode); + +static ssize_t __tsl2550_show_lux(struct i2c_client *client, char *buf) +{ + struct tsl2550_data *data = i2c_get_clientdata(client); + u8 ch0, ch1; + int ret; + + ret = tsl2550_get_adc_value(client, TSL2550_READ_ADC0); + if (ret < 0) + return ret; + ch0 = ret; + + ret = tsl2550_get_adc_value(client, TSL2550_READ_ADC1); + if (ret < 0) + return ret; + ch1 = ret; + + /* Do the job */ + ret = tsl2550_calculate_lux(ch0, ch1); + if (ret < 0) + return ret; + if (data->operating_mode == 1) + ret *= 5; + + return sprintf(buf, "%d\n", ret); +} + +static ssize_t tsl2550_show_lux1_input(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct tsl2550_data *data = i2c_get_clientdata(client); + int ret; + + /* No LUX data if not operational */ + if (!data->power_state) + return -EBUSY; + + mutex_lock(&data->update_lock); + ret = __tsl2550_show_lux(client, buf); + mutex_unlock(&data->update_lock); + + return ret; +} + +static DEVICE_ATTR(lux1_input, S_IRUGO, + tsl2550_show_lux1_input, NULL); + +static struct attribute *tsl2550_attributes[] = { + &dev_attr_power_state.attr, + &dev_attr_operating_mode.attr, + &dev_attr_lux1_input.attr, + NULL +}; + +static const struct attribute_group tsl2550_attr_group = { + .attrs = tsl2550_attributes, +}; + +/* + * Initialization function + */ + +static int tsl2550_init_client(struct i2c_client *client) +{ + struct tsl2550_data *data = i2c_get_clientdata(client); + int err; + + /* + * Probe the chip. To do so we try to power up the device and then to + * read back the 0x03 code + */ + err = i2c_smbus_read_byte_data(client, TSL2550_POWER_UP); + if (err < 0) + return err; + if (err != TSL2550_POWER_UP) + return -ENODEV; + data->power_state = 1; + + /* Set the default operating mode */ + err = i2c_smbus_write_byte(client, + TSL2550_MODE_RANGE[data->operating_mode]); + if (err < 0) + return err; + + return 0; +} + +/* + * I2C init/probing/exit functions + */ + +static struct i2c_driver tsl2550_driver; +static int __devinit tsl2550_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); + struct tsl2550_data *data; + int *opmode, err = 0; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE + | I2C_FUNC_SMBUS_READ_BYTE_DATA)) { + err = -EIO; + goto exit; + } + + data = kzalloc(sizeof(struct tsl2550_data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto exit; + } + data->client = client; + i2c_set_clientdata(client, data); + + /* Check platform data */ + opmode = client->dev.platform_data; + if (opmode) { + if (*opmode < 0 || *opmode > 1) { + dev_err(&client->dev, "invalid operating_mode (%d)\n", + *opmode); + err = -EINVAL; + goto exit_kfree; + } + data->operating_mode = *opmode; + } else + data->operating_mode = 0; /* default mode is standard */ + dev_info(&client->dev, "%s operating mode\n", + data->operating_mode ? "extended" : "standard"); + + mutex_init(&data->update_lock); + + /* Initialize the TSL2550 chip */ + err = tsl2550_init_client(client); + if (err) + goto exit_kfree; + + /* Register sysfs hooks */ + err = sysfs_create_group(&client->dev.kobj, &tsl2550_attr_group); + if (err) + goto exit_kfree; + + dev_info(&client->dev, "support ver. %s enabled\n", DRIVER_VERSION); + + return 0; + +exit_kfree: + kfree(data); +exit: + return err; +} + +static int __devexit tsl2550_remove(struct i2c_client *client) +{ + sysfs_remove_group(&client->dev.kobj, &tsl2550_attr_group); + + /* Power down the device */ + tsl2550_set_power_state(client, 0); + + kfree(i2c_get_clientdata(client)); + + return 0; +} + +#ifdef CONFIG_PM + +static int tsl2550_suspend(struct i2c_client *client, pm_message_t mesg) +{ + return tsl2550_set_power_state(client, 0); +} + +static int tsl2550_resume(struct i2c_client *client) +{ + return tsl2550_set_power_state(client, 1); +} + +#else + +#define tsl2550_suspend NULL +#define tsl2550_resume NULL + +#endif /* CONFIG_PM */ + +static const struct i2c_device_id tsl2550_id[] = { + { "tsl2550", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, tsl2550_id); + +static struct i2c_driver tsl2550_driver = { + .driver = { + .name = TSL2550_DRV_NAME, + .owner = THIS_MODULE, + }, + .suspend = tsl2550_suspend, + .resume = tsl2550_resume, + .probe = tsl2550_probe, + .remove = __devexit_p(tsl2550_remove), + .id_table = tsl2550_id, +}; + +static int __init tsl2550_init(void) +{ + return i2c_add_driver(&tsl2550_driver); +} + +static void __exit tsl2550_exit(void) +{ + i2c_del_driver(&tsl2550_driver); +} + +MODULE_AUTHOR("Rodolfo Giometti "); +MODULE_DESCRIPTION("TSL2550 ambient light sensor driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(DRIVER_VERSION); + +module_init(tsl2550_init); +module_exit(tsl2550_exit); -- cgit v0.10.2 From e77482d735efa2606c1f2afeebd53e1119d0e5c6 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 13 Mar 2010 20:56:55 +0100 Subject: i2c: Drop configure option I2C_DEBUG_CHIP Now that directory drivers/i2c/chips is gone, configuration option I2C_DEBUG_CHIP no longer has any effect, so we can drop it. Signed-off-by: Jean Delvare Acked-by: Wolfram Sang diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index 7bcde5d..d06083f 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -97,12 +97,4 @@ config I2C_DEBUG_BUS a problem with I2C support and want to see more of what is going on. -config I2C_DEBUG_CHIP - bool "I2C Chip debugging messages" - help - Say Y here if you want the I2C chip drivers to produce a bunch of - debug messages to the system log. Select this if you are having - a problem with I2C support and want to see more of what is going - on. - endif # I2C -- cgit v0.10.2 From d07b56b3098b9f32ae6dedeacbc594bd01dcfcd1 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Sat, 13 Mar 2010 20:56:55 +0100 Subject: at24: Init dynamic bin_attribute structures Commit 6992f5334995af474c2b58d010d08bc597f0f2fe introduced this requirement. Reported-by: Albrecht Dress Signed-off-by: Wolfram Sang Signed-off-by: Eric W. Biederman Signed-off-by: Jean Delvare diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c index 2cb2736..db7d0f2 100644 --- a/drivers/misc/eeprom/at24.c +++ b/drivers/misc/eeprom/at24.c @@ -505,6 +505,7 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) * Export the EEPROM bytes through sysfs, since that's convenient. * By default, only root should see the data (maybe passwords etc) */ + sysfs_bin_attr_init(&at24->bin); at24->bin.attr.name = "eeprom"; at24->bin.attr.mode = chip.flags & AT24_FLAG_IRUGO ? S_IRUGO : S_IRUSR; at24->bin.read = at24_bin_read; -- cgit v0.10.2 From 0a9c14751377a1407f5e35791e13651d2fc7801c Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 13 Mar 2010 20:56:56 +0100 Subject: i2c-algo-bit: Add pre- and post-xfer hooks Drivers might have to do random things before and/or after I2C transfers. Add hooks to the i2c-algo-bit implementation to let them do so. Signed-off-by: Jean Delvare Cc: Alex Deucher diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c index e25e139..e8d568c 100644 --- a/drivers/i2c/algos/i2c-algo-bit.c +++ b/drivers/i2c/algos/i2c-algo-bit.c @@ -522,6 +522,12 @@ static int bit_xfer(struct i2c_adapter *i2c_adap, int i, ret; unsigned short nak_ok; + if (adap->pre_xfer) { + ret = adap->pre_xfer(i2c_adap); + if (ret < 0) + return ret; + } + bit_dbg(3, &i2c_adap->dev, "emitting start condition\n"); i2c_start(adap); for (i = 0; i < num; i++) { @@ -570,6 +576,9 @@ static int bit_xfer(struct i2c_adapter *i2c_adap, bailout: bit_dbg(3, &i2c_adap->dev, "emitting stop condition\n"); i2c_stop(adap); + + if (adap->post_xfer) + adap->post_xfer(i2c_adap); return ret; } diff --git a/include/linux/i2c-algo-bit.h b/include/linux/i2c-algo-bit.h index 111334f..4f98148 100644 --- a/include/linux/i2c-algo-bit.h +++ b/include/linux/i2c-algo-bit.h @@ -36,6 +36,8 @@ struct i2c_algo_bit_data { void (*setscl) (void *data, int state); int (*getsda) (void *data); int (*getscl) (void *data); + int (*pre_xfer) (struct i2c_adapter *); + void (*post_xfer) (struct i2c_adapter *); /* local settings */ int udelay; /* half clock cycle time in us, -- cgit v0.10.2 From 3f07d1295191cfa41125e4e61ee2064790070071 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 13 Mar 2010 12:22:16 -0800 Subject: drivers/net/tg3.c: change the field used with the TG3_FLAG_10_100_ONLY constant The constant TG3_FLAG_10_100_ONLY should be used with the tg3_flags field, not the tg3_flags2 field, as done elsewhere in the same file. Signed-off-by: Julia Lawall Signed-off-by: David S. Miller diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index c3b4fe7..22cf1c4 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -9776,7 +9776,7 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) ADVERTISED_Pause | ADVERTISED_Asym_Pause; - if (!(tp->tg3_flags2 & TG3_FLAG_10_100_ONLY)) + if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) mask |= ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full; -- cgit v0.10.2 From e2577a065832f2c6d108de2e027891bdb2d78924 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sat, 13 Mar 2010 12:23:29 -0800 Subject: ipv6: Send netlink notification when DAD fails If we are managing IPv6 addresses using DHCP, it would be nice for user-space to be notified if an address configured through DHCP fails DAD. Otherwise user-space would have to poll to see whether DAD succeeds. This patch uses the existing notification mechanism and simply hooks it into the DAD failure code path. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 6cf3ee1..3381b43 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -1380,6 +1380,8 @@ static void addrconf_dad_stop(struct inet6_ifaddr *ifp, int dad_failed) if (dad_failed) ifp->flags |= IFA_F_DADFAILED; spin_unlock_bh(&ifp->lock); + if (dad_failed) + ipv6_ifa_notify(0, ifp); in6_ifa_put(ifp); #ifdef CONFIG_IPV6_PRIVACY } else if (ifp->flags&IFA_F_TEMPORARY) { -- cgit v0.10.2 From 2a40018984c5c9647df1c18489449a3a227d9136 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Sat, 13 Mar 2010 12:24:18 -0800 Subject: sky2: Avoid rtnl_unlock without rtnl_lock Make sure we always call rtnl_lock before going down the error path in sky2_resume, which unlocks the rtnl lock. Signed-off-by: Mike McCormack Signed-off-by: David S. Miller diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 653bdd7..d8ec4c1 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -4863,6 +4863,7 @@ static int sky2_resume(struct pci_dev *pdev) if (!hw) return 0; + rtnl_lock(); err = pci_set_power_state(pdev, PCI_D0); if (err) goto out; @@ -4884,7 +4885,6 @@ static int sky2_resume(struct pci_dev *pdev) sky2_write32(hw, B0_IMSK, Y2_IS_BASE); napi_enable(&hw->napi); - rtnl_lock(); for (i = 0; i < hw->ports; i++) { err = sky2_reattach(hw->dev[i]); if (err) -- cgit v0.10.2 From c251c7f738cd94eb3a1febda318078c661eccb4d Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 13 Mar 2010 12:26:15 -0800 Subject: drivers/net/tulip/eeprom.c: fix bogus "(null)" in tulip init messages On Wed, 2010-03-10 at 08:41 -0800, David Miller wrote: > From: Mikael Pettersson > Date: Wed, 10 Mar 2010 16:33:28 +0100 > > Booting 2.6.34-rc1 on a machine with a tulip nic I see > > a number of kernel messages that include "(null)" where > > previous kernels included the string "tulip0": > CC:'ing the guilty party :-) It's one of the following > commits: Thanks Mikael. Anonymity has some good attributes. Blame avoidance is one of them. I've broad shoulders. It's me, then Dwight Howard... There might be another few of these where ->name or ->dev was used before struct device or net_device was registered. I'll go back and check. tulip_core has: if (tp->flags & HAS_MEDIA_TABLE) { sprintf(dev->name, DRV_NAME "%d", board_idx); /* hack */ tulip_parse_eeprom(dev); strcpy(dev->name, "eth%d"); /* un-hack */ } So I don't feel _too_ bad. tulip_parse_eeprom is done before register_netdev so the logging there can not use netdev_ or dev_(&dev->dev Signed-off-by: Joe Perches Tested-by: Mikael Pettersson Signed-off-by: David S. Miller diff --git a/drivers/net/tulip/eeprom.c b/drivers/net/tulip/eeprom.c index 93f4e83..49f05d1 100644 --- a/drivers/net/tulip/eeprom.c +++ b/drivers/net/tulip/eeprom.c @@ -143,6 +143,12 @@ static void __devinit tulip_build_fake_mediatable(struct tulip_private *tp) void __devinit tulip_parse_eeprom(struct net_device *dev) { + /* + dev is not registered at this point, so logging messages can't + use dev_ or netdev_ but dev->name is good via a + hack in the caller + */ + /* The last media info list parsed, for multiport boards. */ static struct mediatable *last_mediatable; static unsigned char *last_ee_data; @@ -161,15 +167,14 @@ void __devinit tulip_parse_eeprom(struct net_device *dev) if (ee_data[0] == 0xff) { if (last_mediatable) { controller_index++; - dev_info(&dev->dev, - "Controller %d of multiport board\n", - controller_index); + pr_info("%s: Controller %d of multiport board\n", + dev->name, controller_index); tp->mtable = last_mediatable; ee_data = last_ee_data; goto subsequent_board; } else - dev_info(&dev->dev, - "Missing EEPROM, this interface may not work correctly!\n"); + pr_info("%s: Missing EEPROM, this interface may not work correctly!\n", + dev->name); return; } /* Do a fix-up based on the vendor half of the station address prefix. */ @@ -181,15 +186,14 @@ void __devinit tulip_parse_eeprom(struct net_device *dev) i++; /* An Accton EN1207, not an outlaw Maxtech. */ memcpy(ee_data + 26, eeprom_fixups[i].newtable, sizeof(eeprom_fixups[i].newtable)); - dev_info(&dev->dev, - "Old format EEPROM on '%s' board. Using substitute media control info\n", - eeprom_fixups[i].name); + pr_info("%s: Old format EEPROM on '%s' board. Using substitute media control info\n", + dev->name, eeprom_fixups[i].name); break; } } if (eeprom_fixups[i].name == NULL) { /* No fixup found. */ - dev_info(&dev->dev, - "Old style EEPROM with no media selection information\n"); + pr_info("%s: Old style EEPROM with no media selection information\n", + dev->name); return; } } @@ -217,8 +221,8 @@ subsequent_board: /* there is no phy information, don't even try to build mtable */ if (count == 0) { if (tulip_debug > 0) - dev_warn(&dev->dev, - "no phy info, aborting mtable build\n"); + pr_warning("%s: no phy info, aborting mtable build\n", + dev->name); return; } @@ -234,8 +238,10 @@ subsequent_board: mtable->has_nonmii = mtable->has_mii = mtable->has_reset = 0; mtable->csr15dir = mtable->csr15val = 0; - dev_info(&dev->dev, "EEPROM default media type %s\n", - media & 0x0800 ? "Autosense" : medianame[media & MEDIA_MASK]); + pr_info("%s: EEPROM default media type %s\n", + dev->name, + media & 0x0800 ? "Autosense" + : medianame[media & MEDIA_MASK]); for (i = 0; i < count; i++) { struct medialeaf *leaf = &mtable->mleaf[i]; @@ -298,17 +304,17 @@ subsequent_board: } if (tulip_debug > 1 && leaf->media == 11) { unsigned char *bp = leaf->leafdata; - dev_info(&dev->dev, - "MII interface PHY %d, setup/reset sequences %d/%d long, capabilities %02x %02x\n", - bp[0], bp[1], bp[2 + bp[1]*2], - bp[5 + bp[2 + bp[1]*2]*2], - bp[4 + bp[2 + bp[1]*2]*2]); + pr_info("%s: MII interface PHY %d, setup/reset sequences %d/%d long, capabilities %02x %02x\n", + dev->name, + bp[0], bp[1], bp[2 + bp[1]*2], + bp[5 + bp[2 + bp[1]*2]*2], + bp[4 + bp[2 + bp[1]*2]*2]); } - dev_info(&dev->dev, - "Index #%d - Media %s (#%d) described by a %s (%d) block\n", - i, medianame[leaf->media & 15], leaf->media, - leaf->type < ARRAY_SIZE(block_name) ? block_name[leaf->type] : "", - leaf->type); + pr_info("%s: Index #%d - Media %s (#%d) described by a %s (%d) block\n", + dev->name, + i, medianame[leaf->media & 15], leaf->media, + leaf->type < ARRAY_SIZE(block_name) ? block_name[leaf->type] : "", + leaf->type); } if (new_advertise) tp->sym_advertise = new_advertise; -- cgit v0.10.2 From bec68ff1637ca00bb1585a03a7be8a13380084de Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Sat, 13 Mar 2010 12:27:21 -0800 Subject: bridge: ensure to unlock in error path in br_multicast_query(). Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: David S. Miller diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 12ce1ea..fd96a8d 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -823,6 +823,7 @@ static int br_multicast_query(struct net_bridge *br, unsigned long max_delay; unsigned long now = jiffies; __be32 group; + int err = 0; spin_lock(&br->multicast_lock); if (!netif_running(br->dev) || @@ -841,12 +842,14 @@ static int br_multicast_query(struct net_bridge *br, group = 0; } } else { - if (!pskb_may_pull(skb, sizeof(struct igmpv3_query))) - return -EINVAL; + if (!pskb_may_pull(skb, sizeof(struct igmpv3_query))) { + err = -EINVAL; + goto out; + } ih3 = igmpv3_query_hdr(skb); if (ih3->nsrcs) - return 0; + goto out; max_delay = ih3->code ? 1 : IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE); @@ -876,7 +879,7 @@ static int br_multicast_query(struct net_bridge *br, out: spin_unlock(&br->multicast_lock); - return 0; + return err; } static void br_multicast_leave_group(struct net_bridge *br, -- cgit v0.10.2 From 3ee8f0a2b1c81f0472b25d40aa5c1c7c6a0edc2a Mon Sep 17 00:00:00 2001 From: Markus Rathgeb Date: Sat, 13 Mar 2010 17:29:43 +0100 Subject: HID: Add RGT Clutch Wheel clutch device id This patch enables force feedback for the "RGT Force Feedback CLUTCH Racing Wheel". It only modifies hid-core.c (hid_blacklist) and hid-tmff.c to add the new USB IDs. Signed-off-by: Markus Rathgeb Signed-off-by: Jiri Kosina diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 368fbb0..2e2aa75 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1357,6 +1357,7 @@ static const struct hid_device_id hid_blacklist[] = { { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb323) }, { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb324) }, { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) }, + { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb653) }, { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) }, { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) }, { HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) }, diff --git a/drivers/hid/hid-tmff.c b/drivers/hid/hid-tmff.c index 167ea74..c32f32c 100644 --- a/drivers/hid/hid-tmff.c +++ b/drivers/hid/hid-tmff.c @@ -251,6 +251,8 @@ static const struct hid_device_id tm_devices[] = { .driver_data = (unsigned long)ff_rumble }, { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651), /* FGT Rumble Force Wheel */ .driver_data = (unsigned long)ff_rumble }, + { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb653), /* RGT Force Feedback CLUTCH Raging Wheel */ + .driver_data = (unsigned long)ff_joystick }, { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654), /* FGT Force Feedback Wheel */ .driver_data = (unsigned long)ff_joystick }, { } -- cgit v0.10.2 From 2d378b9179881b46a0faf11430efb421fe03ddd8 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 13 Mar 2010 16:25:03 -0800 Subject: sparc64: Add very basic XVR-1000 framebuffer driver. Signed-off-by: David S. Miller Acked-by: Frans van Berckel diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 5a5c303..a5755b8 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -909,6 +909,18 @@ config FB_XVR2500 mostly initialized the card already. It is treated as a completely dumb framebuffer device. +config FB_XVR1000 + bool "Sun XVR-1000 support" + depends on SPARC64 + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the framebuffer device for the Sun XVR-1000 and similar + graphics cards. The driver only works on sparc64 systems where + the system firmware has mostly initialized the card already. It + is treated as a completely dumb framebuffer device. + config FB_PVR2 tristate "NEC PowerVR 2 display support" depends on FB && SH_DREAMCAST diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 4ecb30c..8c9a357 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -79,6 +79,7 @@ obj-$(CONFIG_FB_N411) += n411.o obj-$(CONFIG_FB_HGA) += hgafb.o obj-$(CONFIG_FB_XVR500) += sunxvr500.o obj-$(CONFIG_FB_XVR2500) += sunxvr2500.o +obj-$(CONFIG_FB_XVR1000) += sunxvr1000.o obj-$(CONFIG_FB_IGA) += igafb.o obj-$(CONFIG_FB_APOLLO) += dnfb.o obj-$(CONFIG_FB_Q40) += q40fb.o diff --git a/drivers/video/sunxvr1000.c b/drivers/video/sunxvr1000.c new file mode 100644 index 0000000..a8248c0 --- /dev/null +++ b/drivers/video/sunxvr1000.c @@ -0,0 +1,228 @@ +/* sunxvr1000.c: Sun XVR-1000 driver for sparc64 systems + * + * Copyright (C) 2010 David S. Miller (davem@davemloft.net) + */ + +#include +#include +#include +#include +#include +#include + +struct gfb_info { + struct fb_info *info; + + char __iomem *fb_base; + unsigned long fb_base_phys; + + struct device_node *of_node; + + unsigned int width; + unsigned int height; + unsigned int depth; + unsigned int fb_size; + + u32 pseudo_palette[16]; +}; + +static int __devinit gfb_get_props(struct gfb_info *gp) +{ + gp->width = of_getintprop_default(gp->of_node, "width", 0); + gp->height = of_getintprop_default(gp->of_node, "height", 0); + gp->depth = of_getintprop_default(gp->of_node, "depth", 32); + + if (!gp->width || !gp->height) { + printk(KERN_ERR "gfb: Critical properties missing for %s\n", + gp->of_node->full_name); + return -EINVAL; + } + + return 0; +} + +static int gfb_setcolreg(unsigned regno, + unsigned red, unsigned green, unsigned blue, + unsigned transp, struct fb_info *info) +{ + u32 value; + + if (regno < 16) { + red >>= 8; + green >>= 8; + blue >>= 8; + + value = (blue << 16) | (green << 8) | red; + ((u32 *)info->pseudo_palette)[regno] = value; + } + + return 0; +} + +static struct fb_ops gfb_ops = { + .owner = THIS_MODULE, + .fb_setcolreg = gfb_setcolreg, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, +}; + +static int __devinit gfb_set_fbinfo(struct gfb_info *gp) +{ + struct fb_info *info = gp->info; + struct fb_var_screeninfo *var = &info->var; + + info->flags = FBINFO_DEFAULT; + info->fbops = &gfb_ops; + info->screen_base = gp->fb_base; + info->screen_size = gp->fb_size; + + info->pseudo_palette = gp->pseudo_palette; + + /* Fill fix common fields */ + strlcpy(info->fix.id, "gfb", sizeof(info->fix.id)); + info->fix.smem_start = gp->fb_base_phys; + info->fix.smem_len = gp->fb_size; + info->fix.type = FB_TYPE_PACKED_PIXELS; + if (gp->depth == 32 || gp->depth == 24) + info->fix.visual = FB_VISUAL_TRUECOLOR; + else + info->fix.visual = FB_VISUAL_PSEUDOCOLOR; + + var->xres = gp->width; + var->yres = gp->height; + var->xres_virtual = var->xres; + var->yres_virtual = var->yres; + var->bits_per_pixel = gp->depth; + + var->red.offset = 0; + var->red.length = 8; + var->green.offset = 8; + var->green.length = 8; + var->blue.offset = 16; + var->blue.length = 8; + var->transp.offset = 0; + var->transp.length = 0; + + if (fb_alloc_cmap(&info->cmap, 256, 0)) { + printk(KERN_ERR "gfb: Cannot allocate color map.\n"); + return -ENOMEM; + } + + return 0; +} + +static int __devinit gfb_probe(struct of_device *op, + const struct of_device_id *match) +{ + struct device_node *dp = op->node; + struct fb_info *info; + struct gfb_info *gp; + int err; + + info = framebuffer_alloc(sizeof(struct gfb_info), &op->dev); + if (!info) { + printk(KERN_ERR "gfb: Cannot allocate fb_info\n"); + err = -ENOMEM; + goto err_out; + } + + gp = info->par; + gp->info = info; + gp->of_node = dp; + + gp->fb_base_phys = op->resource[6].start; + + err = gfb_get_props(gp); + if (err) + goto err_release_fb; + + /* Framebuffer length is the same regardless of resolution. */ + info->fix.line_length = 16384; + gp->fb_size = info->fix.line_length * gp->height; + + gp->fb_base = of_ioremap(&op->resource[6], 0, + gp->fb_size, "gfb fb"); + if (!gp->fb_base) + goto err_release_fb; + + err = gfb_set_fbinfo(gp); + if (err) + goto err_unmap_fb; + + printk("gfb: Found device at %s\n", dp->full_name); + + err = register_framebuffer(info); + if (err < 0) { + printk(KERN_ERR "gfb: Could not register framebuffer %s\n", + dp->full_name); + goto err_unmap_fb; + } + + dev_set_drvdata(&op->dev, info); + + return 0; + +err_unmap_fb: + of_iounmap(&op->resource[6], gp->fb_base, gp->fb_size); + +err_release_fb: + framebuffer_release(info); + +err_out: + return err; +} + +static int __devexit gfb_remove(struct of_device *op) +{ + struct fb_info *info = dev_get_drvdata(&op->dev); + struct gfb_info *gp = info->par; + + unregister_framebuffer(info); + + iounmap(gp->fb_base); + + of_iounmap(&op->resource[6], gp->fb_base, gp->fb_size); + + framebuffer_release(info); + + dev_set_drvdata(&op->dev, NULL); + + return 0; +} + +static const struct of_device_id gfb_match[] = { + { + .name = "SUNW,gfb", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, ffb_match); + +static struct of_platform_driver gfb_driver = { + .name = "gfb", + .match_table = gfb_match, + .probe = gfb_probe, + .remove = __devexit_p(gfb_remove), +}; + +static int __init gfb_init(void) +{ + if (fb_get_options("gfb", NULL)) + return -ENODEV; + + return of_register_driver(&gfb_driver, &of_bus_type); +} + +static void __exit gfb_exit(void) +{ + of_unregister_driver(&gfb_driver); +} + +module_init(gfb_init); +module_exit(gfb_exit); + +MODULE_DESCRIPTION("framebuffer driver for Sun XVR-1000 graphics"); +MODULE_AUTHOR("David S. Miller "); +MODULE_VERSION("1.0"); +MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 6c477d44a7dad43a2783b4dea7f4ca3882d77126 Mon Sep 17 00:00:00 2001 From: Ryusuke Konishi Date: Sun, 14 Mar 2010 02:01:51 +0900 Subject: nilfs2: fix discrepancy in use of static specifier Two segbuf functions, nilfs_segbuf_write and nilfs_segbuf_wait, are declared with the static storage class specifier, but their implementations are not. This fixes the discrepancy. Signed-off-by: Ryusuke Konishi diff --git a/fs/nilfs2/segbuf.c b/fs/nilfs2/segbuf.c index ab56fe4..68b08f2 100644 --- a/fs/nilfs2/segbuf.c +++ b/fs/nilfs2/segbuf.c @@ -470,8 +470,8 @@ static int nilfs_segbuf_submit_bh(struct nilfs_segment_buffer *segbuf, * * %-ENOMEM - Insufficient memory available. */ -int nilfs_segbuf_write(struct nilfs_segment_buffer *segbuf, - struct the_nilfs *nilfs) +static int nilfs_segbuf_write(struct nilfs_segment_buffer *segbuf, + struct the_nilfs *nilfs) { struct nilfs_write_info wi; struct buffer_head *bh; @@ -514,7 +514,7 @@ int nilfs_segbuf_write(struct nilfs_segment_buffer *segbuf, * * %-EIO - I/O error */ -int nilfs_segbuf_wait(struct nilfs_segment_buffer *segbuf) +static int nilfs_segbuf_wait(struct nilfs_segment_buffer *segbuf) { int err = 0; -- cgit v0.10.2 From 9ccf56c13831c5fe0edecd8c1184c9a6fe805d23 Mon Sep 17 00:00:00 2001 From: Ryusuke Konishi Date: Sun, 14 Mar 2010 03:01:03 +0900 Subject: nilfs2: fix function name typos in docbook comments Fixes the following typos in docbook comments: nilfs_detroy_transaction_cache -> nilfs_destroy_transaction_cache nilfs_secgtor_start_timer -> nilfs_segctor_start_timer Signed-off-by: Ryusuke Konishi diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index ada2f1b..3265bfc 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c @@ -141,7 +141,7 @@ int nilfs_init_transaction_cache(void) } /** - * nilfs_detroy_transaction_cache - destroy the cache for transaction info + * nilfs_destroy_transaction_cache - destroy the cache for transaction info * * nilfs_destroy_transaction_cache() frees the slab cache for the struct * nilfs_transaction_info. @@ -2214,7 +2214,7 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode) } /** - * nilfs_secgtor_start_timer - set timer of background write + * nilfs_segctor_start_timer - set timer of background write * @sci: nilfs_sc_info * * If the timer has already been set, it ignores the new request. -- cgit v0.10.2 From 1621562b6ac55aa69239895d90276577547a5f62 Mon Sep 17 00:00:00 2001 From: Ryusuke Konishi Date: Sun, 14 Mar 2010 03:17:45 +0900 Subject: nilfs2: fix typo "cout" -> "count" in error message Signed-off-by: Ryusuke Konishi diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c index 0092840..85c89df 100644 --- a/fs/nilfs2/dir.c +++ b/fs/nilfs2/dir.c @@ -396,7 +396,7 @@ nilfs_find_entry(struct inode *dir, const struct qstr *qstr, /* next page is past the blocks we've got */ if (unlikely(n > (dir->i_blocks >> (PAGE_CACHE_SHIFT - 9)))) { nilfs_error(dir->i_sb, __func__, - "dir %lu size %lld exceeds block cout %llu", + "dir %lu size %lld exceeds block count %llu", dir->i_ino, dir->i_size, (unsigned long long)dir->i_blocks); goto out; -- cgit v0.10.2 From 7a65004bbaa6a21a0438aac9c64814e46084dc3f Mon Sep 17 00:00:00 2001 From: Ryusuke Konishi Date: Sun, 14 Mar 2010 03:32:40 +0900 Subject: nilfs2: fix various typos in comments This fixes various typos I found in comments of nilfs2. Signed-off-by: Ryusuke Konishi diff --git a/fs/nilfs2/alloc.h b/fs/nilfs2/alloc.h index f4543ac..5cccf87 100644 --- a/fs/nilfs2/alloc.h +++ b/fs/nilfs2/alloc.h @@ -42,7 +42,7 @@ void *nilfs_palloc_block_get_entry(const struct inode *, __u64, const struct buffer_head *, void *); /** - * nilfs_palloc_req - persistent alloctor request and reply + * nilfs_palloc_req - persistent allocator request and reply * @pr_entry_nr: entry number (vblocknr or inode number) * @pr_desc_bh: buffer head of the buffer containing block group descriptors * @pr_bitmap_bh: buffer head of the buffer containing a block group bitmap diff --git a/fs/nilfs2/dat.c b/fs/nilfs2/dat.c index 9d1e5de..0131467 100644 --- a/fs/nilfs2/dat.c +++ b/fs/nilfs2/dat.c @@ -288,7 +288,7 @@ int nilfs_dat_mark_dirty(struct inode *dat, __u64 vblocknr) * @vblocknrs and @nitems. * * Return Value: On success, 0 is returned. On error, one of the following - * nagative error codes is returned. + * negative error codes is returned. * * %-EIO - I/O error. * diff --git a/fs/nilfs2/gcinode.c b/fs/nilfs2/gcinode.c index e16a666..8880a9e 100644 --- a/fs/nilfs2/gcinode.c +++ b/fs/nilfs2/gcinode.c @@ -28,10 +28,10 @@ * gcinodes), and this file provides lookup function of the dummy * inodes and their buffer read function. * - * Since NILFS2 keeps up multiple checkpoints/snapshots accross GC, it + * Since NILFS2 keeps up multiple checkpoints/snapshots across GC, it * has to treat blocks that belong to a same file but have different * checkpoint numbers. To avoid interference among generations, dummy - * inodes are managed separatly from actual inodes, and their lookup + * inodes are managed separately from actual inodes, and their lookup * function (nilfs_gc_iget) is designed to be specified with a * checkpoint number argument as well as an inode number. * diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c index a2692bb..fc246db 100644 --- a/fs/nilfs2/page.c +++ b/fs/nilfs2/page.c @@ -292,7 +292,7 @@ void nilfs_free_private_page(struct page *page) * @src: source page * @copy_dirty: flag whether to copy dirty states on the page's buffer heads. * - * This fuction is for both data pages and btnode pages. The dirty flag + * This function is for both data pages and btnode pages. The dirty flag * should be treated by caller. The page must not be under i/o. * Both src and dst page must be locked */ @@ -388,7 +388,7 @@ repeat: } /** - * nilfs_copy_back_pages -- copy back pages to orignal cache from shadow cache + * nilfs_copy_back_pages -- copy back pages to original cache from shadow cache * @dmap: destination page cache * @smap: source page cache * diff --git a/fs/nilfs2/segbuf.c b/fs/nilfs2/segbuf.c index 68b08f2..e3f67c6 100644 --- a/fs/nilfs2/segbuf.c +++ b/fs/nilfs2/segbuf.c @@ -174,7 +174,7 @@ int nilfs_segbuf_reset(struct nilfs_segment_buffer *segbuf, unsigned flags, } /* - * Setup segument summary + * Setup segment summary */ void nilfs_segbuf_fill_in_segsum(struct nilfs_segment_buffer *segbuf) { diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index 3265bfc..69576a9 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c @@ -201,7 +201,7 @@ static int nilfs_prepare_segment_lock(struct nilfs_transaction_info *ti) * This function allocates a nilfs_transaction_info struct to keep context * information on it. It is initialized and hooked onto the current task in * the outermost call. If a pre-allocated struct is given to @ti, it is used - * instead; othewise a new struct is assigned from a slab. + * instead; otherwise a new struct is assigned from a slab. * * When @vacancy_check flag is set, this function will check the amount of * free space, and will wait for the GC to reclaim disk space if low capacity. @@ -2854,7 +2854,7 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci) * @sbi: nilfs_sb_info * * nilfs_attach_segment_constructor() allocates a struct nilfs_sc_info, - * initilizes it, and starts the segment constructor. + * initializes it, and starts the segment constructor. * * Return Value: On success, 0 is returned. On error, one of the following * negative error code is returned. diff --git a/fs/nilfs2/segment.h b/fs/nilfs2/segment.h index 3155e0c..2a79456 100644 --- a/fs/nilfs2/segment.h +++ b/fs/nilfs2/segment.h @@ -30,7 +30,7 @@ #include "sb.h" /** - * struct nilfs_recovery_info - Recovery infomation + * struct nilfs_recovery_info - Recovery information * @ri_need_recovery: Recovery status * @ri_super_root: Block number of the last super root * @ri_ri_cno: Number of the last checkpoint diff --git a/fs/nilfs2/sufile.c b/fs/nilfs2/sufile.c index b6c36d0..3c6cc60 100644 --- a/fs/nilfs2/sufile.c +++ b/fs/nilfs2/sufile.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Written by Koji Sato . - * Rivised by Ryusuke Konishi . + * Revised by Ryusuke Konishi . */ #include diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 92579cc..896b463 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c @@ -436,7 +436,7 @@ static int nilfs_statfs(struct dentry *dentry, struct kstatfs *buf) /* * Compute the overhead * - * When distributing meta data blocks outside semgent structure, + * When distributing meta data blocks outside segment structure, * We must count them as the overhead. */ overhead = 0; -- cgit v0.10.2 From 55480a06e9ee8d05d0e580bf46611df489653c76 Mon Sep 17 00:00:00 2001 From: Ryusuke Konishi Date: Sun, 14 Mar 2010 03:55:56 +0900 Subject: nilfs2: remove spaces before tabs This kills the following checkpatch warnings: WARNING: please, no space before tabs #74: FILE: segment.h:74: +^Iunsigned ^I^Iflags;$ WARNING: please, no space before tabs #35: FILE: segbuf.c:35: +^Iint ^I^I^Istart, end; /* The region to be submitted */$ Signed-off-by: Ryusuke Konishi diff --git a/fs/nilfs2/segbuf.c b/fs/nilfs2/segbuf.c index e3f67c6..636eaaf 100644 --- a/fs/nilfs2/segbuf.c +++ b/fs/nilfs2/segbuf.c @@ -32,7 +32,7 @@ struct nilfs_write_info { struct the_nilfs *nilfs; struct bio *bio; - int start, end; /* The region to be submitted */ + int start, end; /* The region to be submitted */ int rest_blocks; int max_pages; int nr_vecs; diff --git a/fs/nilfs2/segment.h b/fs/nilfs2/segment.h index 2a79456..82dfd6a 100644 --- a/fs/nilfs2/segment.h +++ b/fs/nilfs2/segment.h @@ -71,7 +71,7 @@ struct nilfs_recovery_info { */ struct nilfs_cstage { int scnt; - unsigned flags; + unsigned flags; struct nilfs_inode_info *dirty_file_ptr; struct nilfs_inode_info *gc_inode_ptr; }; -- cgit v0.10.2 From c91cea11dfec65968ff9d1b4239c1eab63bf72fd Mon Sep 17 00:00:00 2001 From: Ryusuke Konishi Date: Sun, 14 Mar 2010 04:01:27 +0900 Subject: nilfs2: remove whitespaces before quoted newlines This kills the following checkpatch warnings: WARNING: unnecessary whitespace before a quoted newline #869: FILE: super.c:869: + "remount to a different snapshot. \n", WARNING: unnecessary whitespace before a quoted newline #389: FILE: the_nilfs.c:389: + printk(KERN_ERR "NILFS: too short segment. \n"); Signed-off-by: Ryusuke Konishi diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 896b463..0cdbc5e 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c @@ -866,7 +866,7 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data) if ((*flags & MS_RDONLY) && sbi->s_snapshot_cno != old_opts.snapshot_cno) { printk(KERN_WARNING "NILFS (device %s): couldn't " - "remount to a different snapshot. \n", + "remount to a different snapshot.\n", sb->s_id); err = -EINVAL; goto restore_opts; diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c index 92733d5..33871f7 100644 --- a/fs/nilfs2/the_nilfs.c +++ b/fs/nilfs2/the_nilfs.c @@ -386,7 +386,7 @@ static int nilfs_store_disk_layout(struct the_nilfs *nilfs, nilfs->ns_blocks_per_segment = le32_to_cpu(sbp->s_blocks_per_segment); if (nilfs->ns_blocks_per_segment < NILFS_SEG_MIN_BLOCKS) { - printk(KERN_ERR "NILFS: too short segment. \n"); + printk(KERN_ERR "NILFS: too short segment.\n"); return -EINVAL; } -- cgit v0.10.2 From c91ed059a080c6f9a7ba525e5027c65d19115d15 Mon Sep 17 00:00:00 2001 From: Martin Buck Date: Sat, 13 Mar 2010 22:23:58 -0800 Subject: Input: ALPS - fix stuck buttons on some touchpads Enable button release event redirection to the device that got the button press not only for touchpads with interleaved protocols, but unconditionally for all Alps touchpads. This is required at least for the touchpads in Dell Inspiron 8200 and Latitude d630. Signed-off-by: Martin Buck Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index f6dad83..7490f1d 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -120,40 +120,27 @@ static void alps_report_buttons(struct psmouse *psmouse, struct input_dev *dev1, struct input_dev *dev2, int left, int right, int middle) { - struct alps_data *priv = psmouse->private; - const struct alps_model_info *model = priv->i; - - if (model->flags & ALPS_PS2_INTERLEAVED) { - struct input_dev *dev; + struct input_dev *dev; - /* - * If shared button has already been reported on the - * other device (dev2) then this event should be also - * sent through that device. - */ - dev = test_bit(BTN_LEFT, dev2->key) ? dev2 : dev1; - input_report_key(dev, BTN_LEFT, left); + /* + * If shared button has already been reported on the + * other device (dev2) then this event should be also + * sent through that device. + */ + dev = test_bit(BTN_LEFT, dev2->key) ? dev2 : dev1; + input_report_key(dev, BTN_LEFT, left); - dev = test_bit(BTN_RIGHT, dev2->key) ? dev2 : dev1; - input_report_key(dev, BTN_RIGHT, right); + dev = test_bit(BTN_RIGHT, dev2->key) ? dev2 : dev1; + input_report_key(dev, BTN_RIGHT, right); - dev = test_bit(BTN_MIDDLE, dev2->key) ? dev2 : dev1; - input_report_key(dev, BTN_MIDDLE, middle); + dev = test_bit(BTN_MIDDLE, dev2->key) ? dev2 : dev1; + input_report_key(dev, BTN_MIDDLE, middle); - /* - * Sync the _other_ device now, we'll do the first - * device later once we report the rest of the events. - */ - input_sync(dev2); - } else { - /* - * For devices with non-interleaved packets we know what - * device buttons belong to so we can simply report them. - */ - input_report_key(dev1, BTN_LEFT, left); - input_report_key(dev1, BTN_RIGHT, right); - input_report_key(dev1, BTN_MIDDLE, middle); - } + /* + * Sync the _other_ device now, we'll do the first + * device later once we report the rest of the events. + */ + input_sync(dev2); } static void alps_process_packet(struct psmouse *psmouse) -- cgit v0.10.2 From 31968ecf584330b51a25b7bf881c2b632a02a3fb Mon Sep 17 00:00:00 2001 From: Christoph Fritz Date: Sat, 13 Mar 2010 22:26:23 -0800 Subject: Input: i8042 - add ALDI/MEDION netbook E1222 to qurik reset table ALDI/MEDION netbook E1222 needs to be in the reset quirk list for its touchpad's proper function. Reported-by: Michael Fischer Signed-off-by: Christoph Fritz Cc: stable@kernel.org Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 3696cab..ead0494 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -442,6 +442,13 @@ static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = { }, }, { + /* Medion Akoya E1222 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "MEDION"), + DMI_MATCH(DMI_PRODUCT_NAME, "E122X"), + }, + }, + { /* Mivvy M310 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "VIOOO"), -- cgit v0.10.2 From 2aa2b50dd62b5d0675bd7453fbeb5732dc2d7866 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sun, 14 Mar 2010 08:57:03 +0100 Subject: x86/mce: Fix build bug with CONFIG_PROVE_LOCKING=y && CONFIG_X86_MCE_INTEL=y Commit f56e8a076 "x86/mce: Fix RCU lockdep splats" introduced the following build bug: arch/x86/kernel/cpu/mcheck/mce.c: In function 'mce_log': arch/x86/kernel/cpu/mcheck/mce.c:166: error: 'mce_read_mutex' undeclared (first use in this function) arch/x86/kernel/cpu/mcheck/mce.c:166: error: (Each undeclared identifier is reported only once arch/x86/kernel/cpu/mcheck/mce.c:166: error: for each function it appears in.) Move the in-the-middle-of-file lock variable up to the variable definition section, the top of the .c file. Cc: Paul E. McKenney Cc: "H. Peter Anvin" Cc: x86@kernel.org Cc: laijs@cn.fujitsu.com Cc: dipankar@in.ibm.com Cc: mathieu.desnoyers@polymtl.ca Cc: josh@joshtriplett.org Cc: dvhltc@us.ibm.com Cc: niv@us.ibm.com Cc: peterz@infradead.org Cc: rostedt@goodmis.org Cc: Valdis.Kletnieks@vt.edu Cc: dhowells@redhat.com LKML-Reference: <1267830207-9474-3-git-send-email-paulmck@linux.vnet.ibm.com> Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index bd58de4..3ab9c88 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c @@ -46,6 +46,8 @@ #include "mce-internal.h" +static DEFINE_MUTEX(mce_read_mutex); + #define rcu_dereference_check_mce(p) \ rcu_dereference_check((p), \ rcu_read_lock_sched_held() || \ @@ -1490,8 +1492,6 @@ static void collect_tscs(void *data) rdtscll(cpu_tsc[smp_processor_id()]); } -static DEFINE_MUTEX(mce_read_mutex); - static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize, loff_t *off) { -- cgit v0.10.2 From 3f995f317f7070e81e8e38bb11357d6671ab6969 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Richard=20R=C3=B6jfors?= Date: Tue, 9 Mar 2010 09:17:36 +0100 Subject: Add the platform data include for the Xilinx XPS IIC Bus Interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This file was missed in the original patch that went into Linus' tree. Cc: "Ben Dooks (embedded platforms)" Cc: linux-i2c@vger.kernel.org Signed-off-by: Richard Röjfors Signed-off-by: Stephen Rothwell Signed-off-by: Linus Torvalds diff --git a/include/linux/i2c-xiic.h b/include/linux/i2c-xiic.h new file mode 100644 index 0000000..4f9f225 --- /dev/null +++ b/include/linux/i2c-xiic.h @@ -0,0 +1,43 @@ +/* + * i2c-xiic.h + * Copyright (c) 2009 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* Supports: + * Xilinx IIC + */ + +#ifndef _LINUX_I2C_XIIC_H +#define _LINUX_I2C_XIIC_H + +/** + * struct xiic_i2c_platform_data - Platform data of the Xilinx I2C driver + * @num_devices: Number of devices that shall be added when the driver + * is probed. + * @devices: The actuall devices to add. + * + * This purpose of this platform data struct is to be able to provide a number + * of devices that should be added to the I2C bus. The reason is that sometimes + * the I2C board info is not enough, a new PCI board can for instance be + * plugged into a standard PC, and the bus number might be unknown at + * early init time. + */ +struct xiic_i2c_platform_data { + u8 num_devices; + struct i2c_board_info const *devices; +}; + +#endif /* _LINUX_I2C_XIIC_H */ -- cgit v0.10.2 From 02ca6c407e0d43e6de5d646d26d87fc2eaa7a98b Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 4 Feb 2010 12:11:09 -0800 Subject: Add include to i2c-xii.c to fix build error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/i2c/busses/i2c-xiic.c:493: error: implicit declaration of function 'mdelay' Signed-off-by: Randy Dunlap Cc: "Richard Röjfors" Cc: "Ben Dooks (embedded platforms)" Cc: linux-i2c@vger.kernel.org Signed-off-by: Stephen Rothwell Signed-off-by: Linus Torvalds diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c index eece39a..f0ef8da 100644 --- a/drivers/i2c/busses/i2c-xiic.c +++ b/drivers/i2c/busses/i2c-xiic.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include -- cgit v0.10.2 From 1027247f6eb727db6c600b9eb02796f0766ae704 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 12 Feb 2010 14:36:24 +0000 Subject: ARM: Add L2 cache handling to smp boot support The page table and secondary data which we're asking the secondary CPU to make use of has to hit RAM to ensure that the secondary CPU can see it since it may not be taking part in coherency or cache searches at this point. Acked-by: Santosh Shilimkar Signed-off-by: Russell King diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 57162af..577543f 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -99,6 +99,7 @@ int __cpuinit __cpu_up(unsigned int cpu) *pmd = __pmd((PHYS_OFFSET & PGDIR_MASK) | PMD_TYPE_SECT | PMD_SECT_AP_WRITE); flush_pmd_entry(pmd); + outer_clean_range(__pa(pmd), __pa(pmd + 1)); /* * We need to tell the secondary core where to find @@ -106,7 +107,8 @@ int __cpuinit __cpu_up(unsigned int cpu) */ secondary_data.stack = task_stack_page(idle) + THREAD_START_SP; secondary_data.pgdir = virt_to_phys(pgd); - wmb(); + __cpuc_flush_dcache_area(&secondary_data, sizeof(secondary_data)); + outer_clean_range(__pa(&secondary_data), __pa(&secondary_data + 1)); /* * Now bring the CPU into our world. -- cgit v0.10.2 From 3f17522ce461a31e7ced6311b28fcf5b8a763316 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 12 Feb 2010 14:32:01 +0000 Subject: Video: ARM CLCD: Better fix for swapped IENB and CNTL registers On PL111, as found on Realview and other platforms, these registers are always arranged as CNTL then IENB. On PL110, these registers are IENB then CNTL, except on Versatile platforms. Re-arrange the handling of these register swaps so that PL111 always gets it right without resorting to ifdefs, leaving the only case needing special handling being PL110 on Versatile. Fill out amba/clcd.h with the PL110/PL111 register definition differences in case someone tries to use the PL110 specific definitions on PL111. Signed-off-by: Russell King diff --git a/drivers/video/amba-clcd.c b/drivers/video/amba-clcd.c index a21efcd..afe21e6 100644 --- a/drivers/video/amba-clcd.c +++ b/drivers/video/amba-clcd.c @@ -65,16 +65,16 @@ static void clcdfb_disable(struct clcd_fb *fb) if (fb->board->disable) fb->board->disable(fb); - val = readl(fb->regs + CLCD_CNTL); + val = readl(fb->regs + fb->off_cntl); if (val & CNTL_LCDPWR) { val &= ~CNTL_LCDPWR; - writel(val, fb->regs + CLCD_CNTL); + writel(val, fb->regs + fb->off_cntl); clcdfb_sleep(20); } if (val & CNTL_LCDEN) { val &= ~CNTL_LCDEN; - writel(val, fb->regs + CLCD_CNTL); + writel(val, fb->regs + fb->off_cntl); } /* @@ -94,7 +94,7 @@ static void clcdfb_enable(struct clcd_fb *fb, u32 cntl) * Bring up by first enabling.. */ cntl |= CNTL_LCDEN; - writel(cntl, fb->regs + CLCD_CNTL); + writel(cntl, fb->regs + fb->off_cntl); clcdfb_sleep(20); @@ -102,7 +102,7 @@ static void clcdfb_enable(struct clcd_fb *fb, u32 cntl) * and now apply power. */ cntl |= CNTL_LCDPWR; - writel(cntl, fb->regs + CLCD_CNTL); + writel(cntl, fb->regs + fb->off_cntl); /* * finally, enable the interface. @@ -233,7 +233,7 @@ static int clcdfb_set_par(struct fb_info *info) readl(fb->regs + CLCD_TIM0), readl(fb->regs + CLCD_TIM1), readl(fb->regs + CLCD_TIM2), readl(fb->regs + CLCD_TIM3), readl(fb->regs + CLCD_UBAS), readl(fb->regs + CLCD_LBAS), - readl(fb->regs + CLCD_IENB), readl(fb->regs + CLCD_CNTL)); + readl(fb->regs + fb->off_ienb), readl(fb->regs + fb->off_cntl)); #endif return 0; @@ -345,6 +345,23 @@ static int clcdfb_register(struct clcd_fb *fb) { int ret; + /* + * ARM PL111 always has IENB at 0x1c; it's only PL110 + * which is reversed on some platforms. + */ + if (amba_manf(fb->dev) == 0x41 && amba_part(fb->dev) == 0x111) { + fb->off_ienb = CLCD_PL111_IENB; + fb->off_cntl = CLCD_PL111_CNTL; + } else { +#ifdef CONFIG_ARCH_VERSATILE + fb->off_ienb = CLCD_PL111_IENB; + fb->off_cntl = CLCD_PL111_CNTL; +#else + fb->off_ienb = CLCD_PL110_IENB; + fb->off_cntl = CLCD_PL110_CNTL; +#endif + } + fb->clk = clk_get(&fb->dev->dev, NULL); if (IS_ERR(fb->clk)) { ret = PTR_ERR(fb->clk); @@ -416,7 +433,7 @@ static int clcdfb_register(struct clcd_fb *fb) /* * Ensure interrupts are disabled. */ - writel(0, fb->regs + CLCD_IENB); + writel(0, fb->regs + fb->off_ienb); fb_set_var(&fb->fb, &fb->fb.var); diff --git a/include/linux/amba/clcd.h b/include/linux/amba/clcd.h index 29c0448..ca16c38 100644 --- a/include/linux/amba/clcd.h +++ b/include/linux/amba/clcd.h @@ -21,22 +21,21 @@ #define CLCD_UBAS 0x00000010 #define CLCD_LBAS 0x00000014 -#if !defined(CONFIG_ARCH_VERSATILE) && !defined(CONFIG_ARCH_REALVIEW) -#define CLCD_IENB 0x00000018 -#define CLCD_CNTL 0x0000001c -#else -/* - * Someone rearranged these two registers on the Versatile - * platform... - */ -#define CLCD_IENB 0x0000001c -#define CLCD_CNTL 0x00000018 -#endif - -#define CLCD_STAT 0x00000020 -#define CLCD_INTR 0x00000024 -#define CLCD_UCUR 0x00000028 -#define CLCD_LCUR 0x0000002C +#define CLCD_PL110_IENB 0x00000018 +#define CLCD_PL110_CNTL 0x0000001c +#define CLCD_PL110_STAT 0x00000020 +#define CLCD_PL110_INTR 0x00000024 +#define CLCD_PL110_UCUR 0x00000028 +#define CLCD_PL110_LCUR 0x0000002C + +#define CLCD_PL111_CNTL 0x00000018 +#define CLCD_PL111_IENB 0x0000001c +#define CLCD_PL111_RIS 0x00000020 +#define CLCD_PL111_MIS 0x00000024 +#define CLCD_PL111_ICR 0x00000028 +#define CLCD_PL111_UCUR 0x0000002c +#define CLCD_PL111_LCUR 0x00000030 + #define CLCD_PALL 0x00000200 #define CLCD_PALETTE 0x00000200 @@ -147,6 +146,8 @@ struct clcd_fb { struct clcd_board *board; void *board_data; void __iomem *regs; + u16 off_ienb; + u16 off_cntl; u32 clcd_cntl; u32 cmap[16]; }; -- cgit v0.10.2 From 70287db87cfc968fe78bf82a489833cc77b84352 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Tue, 16 Feb 2010 16:53:50 -0500 Subject: ACPI video: Be more liberal in validating _BQC behaviour Right now, if _BQC returns a value we don't understand we immediately invalidate it. Change this behaviour so we only invalidate it if it continues to give an invalid answer after we've already set a brightness. Signed-off-by: Matthew Garrett Acked-by: Zhang Rui Signed-off-by: Len Brown diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index b765790..ea314a2 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -327,7 +327,7 @@ static int acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level); static int acpi_video_device_lcd_get_level_current( struct acpi_video_device *device, - unsigned long long *level); + unsigned long long *level, int init); static int acpi_video_get_next_level(struct acpi_video_device *device, u32 level_current, u32 event); static int acpi_video_switch_brightness(struct acpi_video_device *device, @@ -345,7 +345,7 @@ static int acpi_video_get_brightness(struct backlight_device *bd) struct acpi_video_device *vd = (struct acpi_video_device *)bl_get_data(bd); - if (acpi_video_device_lcd_get_level_current(vd, &cur_level)) + if (acpi_video_device_lcd_get_level_current(vd, &cur_level, 0)) return -EINVAL; for (i = 2; i < vd->brightness->count; i++) { if (vd->brightness->levels[i] == cur_level) @@ -414,7 +414,7 @@ static int video_get_cur_state(struct thermal_cooling_device *cooling_dev, unsig unsigned long long level; int offset; - if (acpi_video_device_lcd_get_level_current(video, &level)) + if (acpi_video_device_lcd_get_level_current(video, &level, 0)) return -EINVAL; for (offset = 2; offset < video->brightness->count; offset++) if (level == video->brightness->levels[offset]) { @@ -609,7 +609,7 @@ static struct dmi_system_id video_dmi_table[] __initdata = { static int acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, - unsigned long long *level) + unsigned long long *level, int init) { acpi_status status = AE_OK; int i; @@ -633,10 +633,16 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, device->brightness->curr = *level; return 0; } - /* BQC returned an invalid level. Stop using it. */ - ACPI_WARNING((AE_INFO, "%s returned an invalid level", - buf)); - device->cap._BQC = device->cap._BCQ = 0; + if (!init) { + /* + * BQC returned an invalid level. + * Stop using it. + */ + ACPI_WARNING((AE_INFO, + "%s returned an invalid level", + buf)); + device->cap._BQC = device->cap._BCQ = 0; + } } else { /* Fixme: * should we return an error or ignore this failure? @@ -892,7 +898,7 @@ acpi_video_init_brightness(struct acpi_video_device *device) if (!device->cap._BQC) goto set_level; - result = acpi_video_device_lcd_get_level_current(device, &level_old); + result = acpi_video_device_lcd_get_level_current(device, &level_old, 1); if (result) goto out_free_levels; @@ -903,7 +909,7 @@ acpi_video_init_brightness(struct acpi_video_device *device) if (result) goto out_free_levels; - result = acpi_video_device_lcd_get_level_current(device, &level); + result = acpi_video_device_lcd_get_level_current(device, &level, 0); if (result) goto out_free_levels; @@ -1996,7 +2002,7 @@ acpi_video_switch_brightness(struct acpi_video_device *device, int event) goto out; result = acpi_video_device_lcd_get_level_current(device, - &level_current); + &level_current, 0); if (result) goto out; -- cgit v0.10.2 From d06070509147c948a06056da619c9dc2ed349805 Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Thu, 25 Feb 2010 10:59:34 +0800 Subject: acpiphp: Execute ACPI _REG method for hotadded devices Per ACPI spec, _ERG method should be executed before device driver gets control for hotpluged device. Firmware might do some configuration there. See http://bugzilla.kernel.org/show_bug.cgi?id=10805. In this machine, _REG method of docked device will configure cardbus bridge. Signed-off-by: Shaohua Li Tested-by: Paul Martin Signed-off-by: Len Brown diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index cb2fd01..b5dad9f3 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -749,6 +749,24 @@ static int acpiphp_bus_trim(acpi_handle handle) return retval; } +static void acpiphp_set_acpi_region(struct acpiphp_slot *slot) +{ + struct acpiphp_func *func; + union acpi_object params[2]; + struct acpi_object_list arg_list; + + list_for_each_entry(func, &slot->funcs, sibling) { + arg_list.count = 2; + arg_list.pointer = params; + params[0].type = ACPI_TYPE_INTEGER; + params[0].integer.value = ACPI_ADR_SPACE_PCI_CONFIG; + params[1].type = ACPI_TYPE_INTEGER; + params[1].integer.value = 1; + /* _REG is optional, we don't care about if there is failure */ + acpi_evaluate_object(func->handle, "_REG", &arg_list, NULL); + } +} + /** * enable_device - enable, configure a slot * @slot: slot to be enabled @@ -805,6 +823,7 @@ static int __ref enable_device(struct acpiphp_slot *slot) pci_bus_assign_resources(bus); acpiphp_sanitize_bus(bus); acpiphp_set_hpp_values(bus); + acpiphp_set_acpi_region(slot); pci_enable_bridges(bus); pci_bus_add_devices(bus); -- cgit v0.10.2 From 181427a7e01beab76c789414334375839f026128 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 13 Mar 2010 14:14:22 +0300 Subject: tomoyo: fix potential use after free The original code returns a freed pointer. This function is expected to return NULL on errors. Signed-off-by: Dan Carpenter Acked-by: Tetsuo Handa Signed-off-by: James Morris diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c index ff51f10..ef89947 100644 --- a/security/tomoyo/common.c +++ b/security/tomoyo/common.c @@ -886,6 +886,7 @@ static struct tomoyo_profile *tomoyo_find_or_assign_new_profile(const unsigned ptr = kmalloc(sizeof(*ptr), GFP_KERNEL); if (!tomoyo_memory_ok(ptr)) { kfree(ptr); + ptr = NULL; goto ok; } for (i = 0; i < TOMOYO_MAX_CONTROL_INDEX; i++) -- cgit v0.10.2 From d330a5befb88875a9b3d2db62f9b74dadf660b13 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Sun, 14 Mar 2010 18:17:54 -0400 Subject: ext4: Fix estimate of # of blocks needed to write indirect-mapped files http://bugzilla.kernel.org/show_bug.cgi?id=15420 Signed-off-by: Jan Kara Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 986120f..11119e0 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -1035,7 +1035,7 @@ static int ext4_indirect_calc_metadata_amount(struct inode *inode, sector_t lblock) { struct ext4_inode_info *ei = EXT4_I(inode); - int dind_mask = EXT4_ADDR_PER_BLOCK(inode->i_sb) - 1; + sector_t dind_mask = ~((sector_t)EXT4_ADDR_PER_BLOCK(inode->i_sb) - 1); int blk_bits; if (lblock < EXT4_NDIR_BLOCKS) @@ -1050,7 +1050,7 @@ static int ext4_indirect_calc_metadata_amount(struct inode *inode, } ei->i_da_metadata_calc_last_lblock = lblock & dind_mask; ei->i_da_metadata_calc_len = 1; - blk_bits = roundup_pow_of_two(lblock + 1); + blk_bits = order_base_2(lblock); return (blk_bits / EXT4_ADDR_PER_BLOCK_BITS(inode->i_sb)) + 1; } -- cgit v0.10.2 From 338e2b1d571e4873908b199c90d6a31f65137fe3 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 3 Mar 2010 13:39:13 -0500 Subject: drm/radeon: add new RS880 pci id This should go to 2.6.33 stable as well. Signed-off-by: Alex Deucher Cc: stable@kernel.org Signed-off-by: Dave Airlie diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h index 676104b..04a6ebc 100644 --- a/include/drm/drm_pciids.h +++ b/include/drm/drm_pciids.h @@ -410,6 +410,7 @@ {0x1002, 0x9712, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS880|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ {0x1002, 0x9713, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS880|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ {0x1002, 0x9714, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS880|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x9715, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS880|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ {0, 0, 0} #define r128_PCI_IDS \ -- cgit v0.10.2 From c21b0fe6de3912f53087b4f3991942529f03eef6 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Tue, 2 Mar 2010 20:37:52 +0100 Subject: drm/radeon/kms: catch atombios infinite loop and break out of it In somecase the atombios code might lead to infinite loop because the GPU is in broken state, this patch track the jump history and will abort atombios execution if we are stuck executing the same jump for more than 1sec. Note that otherwise in some case we might enter an infinite loop in the kernel context which is bad. Signed-off-by: Jerome Glisse Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index d75788f..b7fe660 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c @@ -52,15 +52,17 @@ typedef struct { struct atom_context *ctx; - uint32_t *ps, *ws; int ps_shift; uint16_t start; + unsigned last_jump; + unsigned long last_jump_jiffies; + bool abort; } atom_exec_context; int atom_debug = 0; -static void atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params); -void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params); +static int atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params); +int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params); static uint32_t atom_arg_mask[8] = { 0xFFFFFFFF, 0xFFFF, 0xFFFF00, 0xFFFF0000, 0xFF, 0xFF00, 0xFF0000, @@ -604,12 +606,17 @@ static void atom_op_beep(atom_exec_context *ctx, int *ptr, int arg) static void atom_op_calltable(atom_exec_context *ctx, int *ptr, int arg) { int idx = U8((*ptr)++); + int r = 0; + if (idx < ATOM_TABLE_NAMES_CNT) SDEBUG(" table: %d (%s)\n", idx, atom_table_names[idx]); else SDEBUG(" table: %d\n", idx); if (U16(ctx->ctx->cmd_table + 4 + 2 * idx)) - atom_execute_table_locked(ctx->ctx, idx, ctx->ps + ctx->ps_shift); + r = atom_execute_table_locked(ctx->ctx, idx, ctx->ps + ctx->ps_shift); + if (r) { + ctx->abort = true; + } } static void atom_op_clear(atom_exec_context *ctx, int *ptr, int arg) @@ -673,6 +680,8 @@ static void atom_op_eot(atom_exec_context *ctx, int *ptr, int arg) static void atom_op_jump(atom_exec_context *ctx, int *ptr, int arg) { int execute = 0, target = U16(*ptr); + unsigned long cjiffies; + (*ptr) += 2; switch (arg) { case ATOM_COND_ABOVE: @@ -700,8 +709,25 @@ static void atom_op_jump(atom_exec_context *ctx, int *ptr, int arg) if (arg != ATOM_COND_ALWAYS) SDEBUG(" taken: %s\n", execute ? "yes" : "no"); SDEBUG(" target: 0x%04X\n", target); - if (execute) + if (execute) { + if (ctx->last_jump == (ctx->start + target)) { + cjiffies = jiffies; + if (time_after(cjiffies, ctx->last_jump_jiffies)) { + cjiffies -= ctx->last_jump_jiffies; + if ((jiffies_to_msecs(cjiffies) > 1000)) { + DRM_ERROR("atombios stuck in loop for more than 1sec aborting\n"); + ctx->abort = true; + } + } else { + /* jiffies wrap around we will just wait a little longer */ + ctx->last_jump_jiffies = jiffies; + } + } else { + ctx->last_jump = ctx->start + target; + ctx->last_jump_jiffies = jiffies; + } *ptr = ctx->start + target; + } } static void atom_op_mask(atom_exec_context *ctx, int *ptr, int arg) @@ -1104,7 +1130,7 @@ static struct { atom_op_shr, ATOM_ARG_MC}, { atom_op_debug, 0},}; -static void atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params) +static int atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params) { int base = CU16(ctx->cmd_table + 4 + 2 * index); int len, ws, ps, ptr; @@ -1112,7 +1138,7 @@ static void atom_execute_table_locked(struct atom_context *ctx, int index, uint3 atom_exec_context ectx; if (!base) - return; + return -EINVAL; len = CU16(base + ATOM_CT_SIZE_PTR); ws = CU8(base + ATOM_CT_WS_PTR); @@ -1125,6 +1151,8 @@ static void atom_execute_table_locked(struct atom_context *ctx, int index, uint3 ectx.ps_shift = ps / 4; ectx.start = base; ectx.ps = params; + ectx.abort = false; + ectx.last_jump = 0; if (ws) ectx.ws = kzalloc(4 * ws, GFP_KERNEL); else @@ -1137,6 +1165,11 @@ static void atom_execute_table_locked(struct atom_context *ctx, int index, uint3 SDEBUG("%s @ 0x%04X\n", atom_op_names[op], ptr - 1); else SDEBUG("[%d] @ 0x%04X\n", op, ptr - 1); + if (ectx.abort) { + DRM_ERROR("atombios stuck executing %04X (len %d, WS %d, PS %d) @ 0x%04X\n", + base, len, ws, ps, ptr - 1); + return -EINVAL; + } if (op < ATOM_OP_CNT && op > 0) opcode_table[op].func(&ectx, &ptr, @@ -1152,10 +1185,13 @@ static void atom_execute_table_locked(struct atom_context *ctx, int index, uint3 if (ws) kfree(ectx.ws); + return 0; } -void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params) +int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params) { + int r; + mutex_lock(&ctx->mutex); /* reset reg block */ ctx->reg_block = 0; @@ -1163,8 +1199,9 @@ void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params) ctx->fb_base = 0; /* reset io mode */ ctx->io_mode = ATOM_IO_MM; - atom_execute_table_locked(ctx, index, params); + r = atom_execute_table_locked(ctx, index, params); mutex_unlock(&ctx->mutex); + return r; } static int atom_iio_len[] = { 1, 2, 3, 3, 3, 3, 4, 4, 4, 3 }; @@ -1248,9 +1285,7 @@ int atom_asic_init(struct atom_context *ctx) if (!CU16(ctx->cmd_table + 4 + 2 * ATOM_CMD_INIT)) return 1; - atom_execute_table(ctx, ATOM_CMD_INIT, ps); - - return 0; + return atom_execute_table(ctx, ATOM_CMD_INIT, ps); } void atom_destroy(struct atom_context *ctx) diff --git a/drivers/gpu/drm/radeon/atom.h b/drivers/gpu/drm/radeon/atom.h index bc73781..1b26263 100644 --- a/drivers/gpu/drm/radeon/atom.h +++ b/drivers/gpu/drm/radeon/atom.h @@ -140,7 +140,7 @@ struct atom_context { extern int atom_debug; struct atom_context *atom_parse(struct card_info *, void *); -void atom_execute_table(struct atom_context *, int, uint32_t *); +int atom_execute_table(struct atom_context *, int, uint32_t *); int atom_asic_init(struct atom_context *); void atom_destroy(struct atom_context *); void atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size, uint8_t *frev, uint8_t *crev, uint16_t *data_start); -- cgit v0.10.2 From 965cf68e8797932e9cd49238a6dd39423ac9b256 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sat, 6 Mar 2010 13:42:45 +0100 Subject: drm/nouveau: Never evict VRAM buffers to system. VRAM->system is a synchronous operation: it involves scheduling a VRAM->TT DMA transfer and stalling the CPU until it's finished so that we can unbind the new memory from the translation tables. VRAM->TT can always be performed asynchronously, even if TT is already full and we have to move something out of it. Additionally, allowing VRAM->system behaves badly under heavy memory pressure because once we run out of TT, stuff starts to be moved back and forth between VRAM and system, and the TT contents are hardly renewed. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 028719f..0266124 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -439,8 +439,7 @@ nouveau_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl) switch (bo->mem.mem_type) { case TTM_PL_VRAM: - nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_TT | - TTM_PL_FLAG_SYSTEM); + nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_TT); break; default: nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_SYSTEM); -- cgit v0.10.2 From f4053509669f904aec70c51e2ff75563ba7ae823 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 15 Mar 2010 09:43:51 +1000 Subject: drm/nouveau: add module option to disable TV detection Intended to be used as a workaround in cases where we falsely detect that a TV is connected when it's not. Signed-off-by: Ben Skeggs diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 24327f4..14afe1e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -302,7 +302,7 @@ nouveau_connector_detect(struct drm_connector *connector) detect_analog: nv_encoder = find_encoder_by_type(connector, OUTPUT_ANALOG); - if (!nv_encoder) + if (!nv_encoder && !nouveau_tv_disable) nv_encoder = find_encoder_by_type(connector, OUTPUT_TV); if (nv_encoder) { struct drm_encoder *encoder = to_drm_encoder(nv_encoder); diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index 0f7e2d0..60a709c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c @@ -87,6 +87,10 @@ MODULE_PARM_DESC(override_conntype, "Ignore DCB connector type"); int nouveau_override_conntype = 0; module_param_named(override_conntype, nouveau_override_conntype, int, 0400); +MODULE_PARM_DESC(tv_disable, "Disable TV-out detection\n"); +int nouveau_tv_disable = 0; +module_param_named(tv_disable, nouveau_tv_disable, int, 0400); + MODULE_PARM_DESC(tv_norm, "Default TV norm.\n" "\t\tSupported: PAL, PAL-M, PAL-N, PAL-Nc, NTSC-M, NTSC-J,\n" "\t\t\thd480i, hd480p, hd576i, hd576p, hd720p, hd1080i.\n" diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 6238e25..3b6bbd0 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -682,6 +682,7 @@ extern int nouveau_uscript_tmds; extern int nouveau_vram_pushbuf; extern int nouveau_vram_notify; extern int nouveau_fbpercrtc; +extern int nouveau_tv_disable; extern char *nouveau_tv_norm; extern int nouveau_reg_debug; extern char *nouveau_vbios; -- cgit v0.10.2 From b792210e7d1f9fb102061e2016da96cf2ad5cdbd Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Sat, 6 Mar 2010 10:57:30 -0500 Subject: drm/radeon/kms/atom: spread spectrum fix The atom spread spectrum table does not always disable ss. Explicitly disable it and then use the atom table to enable later if needed (currently only used for LVDS). Fixes display issues on some systems. Signed-off-by: Alex Deucher Cc: stable@kernel.org Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index dd9fdf5..0c67669 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -353,12 +353,55 @@ static void atombios_crtc_set_timing(struct drm_crtc *crtc, atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); } +static void atombios_disable_ss(struct drm_crtc *crtc) +{ + struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); + struct drm_device *dev = crtc->dev; + struct radeon_device *rdev = dev->dev_private; + u32 ss_cntl; + + if (ASIC_IS_DCE4(rdev)) { + switch (radeon_crtc->pll_id) { + case ATOM_PPLL1: + ss_cntl = RREG32(EVERGREEN_P1PLL_SS_CNTL); + ss_cntl &= ~EVERGREEN_PxPLL_SS_EN; + WREG32(EVERGREEN_P1PLL_SS_CNTL, ss_cntl); + break; + case ATOM_PPLL2: + ss_cntl = RREG32(EVERGREEN_P2PLL_SS_CNTL); + ss_cntl &= ~EVERGREEN_PxPLL_SS_EN; + WREG32(EVERGREEN_P2PLL_SS_CNTL, ss_cntl); + break; + case ATOM_DCPLL: + case ATOM_PPLL_INVALID: + return; + } + } else if (ASIC_IS_AVIVO(rdev)) { + switch (radeon_crtc->pll_id) { + case ATOM_PPLL1: + ss_cntl = RREG32(AVIVO_P1PLL_INT_SS_CNTL); + ss_cntl &= ~1; + WREG32(AVIVO_P1PLL_INT_SS_CNTL, ss_cntl); + break; + case ATOM_PPLL2: + ss_cntl = RREG32(AVIVO_P2PLL_INT_SS_CNTL); + ss_cntl &= ~1; + WREG32(AVIVO_P2PLL_INT_SS_CNTL, ss_cntl); + break; + case ATOM_DCPLL: + case ATOM_PPLL_INVALID: + return; + } + } +} + + union atom_enable_ss { ENABLE_LVDS_SS_PARAMETERS legacy; ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION v1; }; -static void atombios_set_ss(struct drm_crtc *crtc, int enable) +static void atombios_enable_ss(struct drm_crtc *crtc) { struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); struct drm_device *dev = crtc->dev; @@ -387,9 +430,9 @@ static void atombios_set_ss(struct drm_crtc *crtc, int enable) step = dig->ss->step; delay = dig->ss->delay; range = dig->ss->range; - } else if (enable) + } else return; - } else if (enable) + } else return; break; } @@ -406,13 +449,13 @@ static void atombios_set_ss(struct drm_crtc *crtc, int enable) args.v1.ucSpreadSpectrumDelay = delay; args.v1.ucSpreadSpectrumRange = range; args.v1.ucPpll = radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; - args.v1.ucEnable = enable; + args.v1.ucEnable = ATOM_ENABLE; } else { args.legacy.usSpreadSpectrumPercentage = cpu_to_le16(percentage); args.legacy.ucSpreadSpectrumType = type; args.legacy.ucSpreadSpectrumStepSize_Delay = (step & 3) << 2; args.legacy.ucSpreadSpectrumStepSize_Delay |= (delay & 7) << 4; - args.legacy.ucEnable = enable; + args.legacy.ucEnable = ATOM_ENABLE; } atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); } @@ -1086,12 +1129,12 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc, /* pick pll */ radeon_crtc->pll_id = radeon_atom_pick_pll(crtc); - atombios_set_ss(crtc, 0); + atombios_disable_ss(crtc); /* always set DCPLL */ if (ASIC_IS_DCE4(rdev)) atombios_crtc_set_dcpll(crtc); atombios_crtc_set_pll(crtc, adjusted_mode); - atombios_set_ss(crtc, 1); + atombios_enable_ss(crtc); if (ASIC_IS_DCE4(rdev)) atombios_set_crtc_dtd_timing(crtc, adjusted_mode); -- cgit v0.10.2 From 86cb2bbfda2cf402aee46779ee90bbb7d915482b Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 8 Mar 2010 12:55:16 -0500 Subject: drm/radeon/kms: use lcd pll limits when available The bios has alternate pll output limits for LCD panels. If available, use these for pll divider calculations. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 0c67669..a8cd637 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -525,6 +525,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) { struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; pll->algo = dig->pll_algo; + pll->flags |= RADEON_PLL_IS_LCD; } } else { if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 93783b1..e4540b2 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -887,6 +887,20 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) p1pll->pll_out_max = le32_to_cpu(firmware_info->info.ulMaxPixelClockPLL_Output); + if (crev >= 4) { + p1pll->lcd_pll_out_min = + le16_to_cpu(firmware_info->info_14.usLcdMinPixelClockPLL_Output) * 100; + if (p1pll->lcd_pll_out_min == 0) + p1pll->lcd_pll_out_min = p1pll->pll_out_min; + p1pll->lcd_pll_out_max = + le16_to_cpu(firmware_info->info_14.usLcdMaxPixelClockPLL_Output) * 100; + if (p1pll->lcd_pll_out_max == 0) + p1pll->lcd_pll_out_max = p1pll->pll_out_max; + } else { + p1pll->lcd_pll_out_min = p1pll->pll_out_min; + p1pll->lcd_pll_out_max = p1pll->pll_out_max; + } + if (p1pll->pll_out_min == 0) { if (ASIC_IS_AVIVO(rdev)) p1pll->pll_out_min = 64800; diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 69af81d..30a84ae 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -633,6 +633,8 @@ bool radeon_combios_get_clock_info(struct drm_device *dev) p1pll->reference_div = RBIOS16(pll_info + 0x10); p1pll->pll_out_min = RBIOS32(pll_info + 0x12); p1pll->pll_out_max = RBIOS32(pll_info + 0x16); + p1pll->lcd_pll_out_min = p1pll->pll_out_min; + p1pll->lcd_pll_out_max = p1pll->pll_out_max; if (rev > 9) { p1pll->pll_in_min = RBIOS32(pll_info + 0x36); diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index ba8d806..ff5f099 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -469,10 +469,19 @@ static void radeon_compute_pll_legacy(struct radeon_pll *pll, uint32_t best_error = 0xffffffff; uint32_t best_vco_diff = 1; uint32_t post_div; + u32 pll_out_min, pll_out_max; DRM_DEBUG("PLL freq %llu %u %u\n", freq, pll->min_ref_div, pll->max_ref_div); freq = freq * 1000; + if (pll->flags & RADEON_PLL_IS_LCD) { + pll_out_min = pll->lcd_pll_out_min; + pll_out_max = pll->lcd_pll_out_max; + } else { + pll_out_min = pll->pll_out_min; + pll_out_max = pll->pll_out_max; + } + if (pll->flags & RADEON_PLL_USE_REF_DIV) min_ref_div = max_ref_div = pll->reference_div; else { @@ -536,10 +545,10 @@ static void radeon_compute_pll_legacy(struct radeon_pll *pll, tmp = (uint64_t)pll->reference_freq * feedback_div; vco = radeon_div(tmp, ref_div); - if (vco < pll->pll_out_min) { + if (vco < pll_out_min) { min_feed_div = feedback_div + 1; continue; - } else if (vco > pll->pll_out_max) { + } else if (vco > pll_out_max) { max_feed_div = feedback_div; continue; } @@ -675,6 +684,15 @@ calc_fb_ref_div(struct radeon_pll *pll, { fixed20_12 ffreq, max_error, error, pll_out, a; u32 vco; + u32 pll_out_min, pll_out_max; + + if (pll->flags & RADEON_PLL_IS_LCD) { + pll_out_min = pll->lcd_pll_out_min; + pll_out_max = pll->lcd_pll_out_max; + } else { + pll_out_min = pll->pll_out_min; + pll_out_max = pll->pll_out_max; + } ffreq.full = rfixed_const(freq); /* max_error = ffreq * 0.0025; */ @@ -686,7 +704,7 @@ calc_fb_ref_div(struct radeon_pll *pll, vco = pll->reference_freq * (((*fb_div) * 10) + (*fb_div_frac)); vco = vco / ((*ref_div) * 10); - if ((vco < pll->pll_out_min) || (vco > pll->pll_out_max)) + if ((vco < pll_out_min) || (vco > pll_out_max)) continue; /* pll_out = vco / post_div; */ @@ -714,6 +732,15 @@ static void radeon_compute_pll_new(struct radeon_pll *pll, { u32 fb_div = 0, fb_div_frac = 0, post_div = 0, ref_div = 0; u32 best_freq = 0, vco_frequency; + u32 pll_out_min, pll_out_max; + + if (pll->flags & RADEON_PLL_IS_LCD) { + pll_out_min = pll->lcd_pll_out_min; + pll_out_max = pll->lcd_pll_out_max; + } else { + pll_out_min = pll->pll_out_min; + pll_out_max = pll->pll_out_max; + } /* freq = freq / 10; */ do_div(freq, 10); @@ -724,7 +751,7 @@ static void radeon_compute_pll_new(struct radeon_pll *pll, goto done; vco_frequency = freq * post_div; - if ((vco_frequency < pll->pll_out_min) || (vco_frequency > pll->pll_out_max)) + if ((vco_frequency < pll_out_min) || (vco_frequency > pll_out_max)) goto done; if (pll->flags & RADEON_PLL_USE_REF_DIV) { @@ -749,7 +776,7 @@ static void radeon_compute_pll_new(struct radeon_pll *pll, continue; vco_frequency = freq * post_div; - if ((vco_frequency < pll->pll_out_min) || (vco_frequency > pll->pll_out_max)) + if ((vco_frequency < pll_out_min) || (vco_frequency > pll_out_max)) continue; if (pll->flags & RADEON_PLL_USE_REF_DIV) { ref_div = pll->reference_div; diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 1702b82..b868ffa 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -129,6 +129,7 @@ struct radeon_tmds_pll { #define RADEON_PLL_USE_FRAC_FB_DIV (1 << 10) #define RADEON_PLL_PREFER_CLOSEST_LOWER (1 << 11) #define RADEON_PLL_USE_POST_DIV (1 << 12) +#define RADEON_PLL_IS_LCD (1 << 13) /* pll algo */ enum radeon_pll_algo { @@ -149,6 +150,8 @@ struct radeon_pll { uint32_t pll_in_max; uint32_t pll_out_min; uint32_t pll_out_max; + uint32_t lcd_pll_out_min; + uint32_t lcd_pll_out_max; uint32_t best_vco; /* divider limits */ -- cgit v0.10.2 From 267364ac17f6474c69b03034340f769b22f46105 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 8 Mar 2010 17:10:41 -0500 Subject: drm/radeon/kms: further spread spectrum fixes Adjust modeset ordering to fix spread spectrum. The spread spectrum command table relies on the crtc routing to already be set in order to work properly on some asics. Should fix fdo bug 25741. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index a8cd637..7c30e2e 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -1127,9 +1127,6 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc, /* TODO color tiling */ - /* pick pll */ - radeon_crtc->pll_id = radeon_atom_pick_pll(crtc); - atombios_disable_ss(crtc); /* always set DCPLL */ if (ASIC_IS_DCE4(rdev)) @@ -1164,6 +1161,11 @@ static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc, static void atombios_crtc_prepare(struct drm_crtc *crtc) { + struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); + + /* pick pll */ + radeon_crtc->pll_id = radeon_atom_pick_pll(crtc); + atombios_lock_crtc(crtc, ATOM_ENABLE); atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); } diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index bc926ea..4eae30c 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c @@ -1216,6 +1216,9 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder) } atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); + + /* update scratch regs with new routing */ + radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); } static void @@ -1326,19 +1329,9 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, struct drm_device *dev = encoder->dev; struct radeon_device *rdev = dev->dev_private; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); - if (radeon_encoder->active_device & - (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) { - struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; - if (dig) - dig->dig_encoder = radeon_atom_pick_dig_encoder(encoder); - } radeon_encoder->pixel_clock = adjusted_mode->clock; - radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); - atombios_set_encoder_crtc_source(encoder); - if (ASIC_IS_AVIVO(rdev)) { if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT)) atombios_yuv_setup(encoder, true); @@ -1492,8 +1485,20 @@ radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connec static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) { + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + + if (radeon_encoder->active_device & + (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) { + struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; + if (dig) + dig->dig_encoder = radeon_atom_pick_dig_encoder(encoder); + } + radeon_atom_output_lock(encoder, true); radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); + + /* this is needed for the pll/ss setup to work correctly in some cases */ + atombios_set_encoder_crtc_source(encoder); } static void radeon_atom_encoder_commit(struct drm_encoder *encoder) -- cgit v0.10.2 From 15f7207761cfcf8f53fb6e5cacffe060478782c3 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 10 Mar 2010 18:33:03 -0500 Subject: drm/radeon/kms: fix pal tv-out support on legacy IGP chips Based on ddx patch by Andrzej Hajda. Signed-off-by: Alex Deucher Cc: stable@kernel.org Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/radeon_legacy_tv.c b/drivers/gpu/drm/radeon/radeon_legacy_tv.c index 417684d..f2ed27c 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_tv.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_tv.c @@ -57,6 +57,10 @@ #define NTSC_TV_PLL_N_14 693 #define NTSC_TV_PLL_P_14 7 +#define PAL_TV_PLL_M_14 19 +#define PAL_TV_PLL_N_14 353 +#define PAL_TV_PLL_P_14 5 + #define VERT_LEAD_IN_LINES 2 #define FRAC_BITS 0xe #define FRAC_MASK 0x3fff @@ -205,9 +209,24 @@ static const struct radeon_tv_mode_constants available_tv_modes[] = { 630627, /* defRestart */ 347, /* crtcPLL_N */ 14, /* crtcPLL_M */ - 8, /* crtcPLL_postDiv */ + 8, /* crtcPLL_postDiv */ 1022, /* pixToTV */ }, + { /* PAL timing for 14 Mhz ref clk */ + 800, /* horResolution */ + 600, /* verResolution */ + TV_STD_PAL, /* standard */ + 1131, /* horTotal */ + 742, /* verTotal */ + 813, /* horStart */ + 840, /* horSyncStart */ + 633, /* verSyncStart */ + 708369, /* defRestart */ + 211, /* crtcPLL_N */ + 9, /* crtcPLL_M */ + 8, /* crtcPLL_postDiv */ + 759, /* pixToTV */ + }, }; #define N_AVAILABLE_MODES ARRAY_SIZE(available_tv_modes) @@ -242,7 +261,7 @@ static const struct radeon_tv_mode_constants *radeon_legacy_tv_get_std_mode(stru if (pll->reference_freq == 2700) const_ptr = &available_tv_modes[1]; else - const_ptr = &available_tv_modes[1]; /* FIX ME */ + const_ptr = &available_tv_modes[3]; } return const_ptr; } @@ -685,9 +704,9 @@ void radeon_legacy_tv_mode_set(struct drm_encoder *encoder, n = PAL_TV_PLL_N_27; p = PAL_TV_PLL_P_27; } else { - m = PAL_TV_PLL_M_27; - n = PAL_TV_PLL_N_27; - p = PAL_TV_PLL_P_27; + m = PAL_TV_PLL_M_14; + n = PAL_TV_PLL_N_14; + p = PAL_TV_PLL_P_14; } } -- cgit v0.10.2 From ae08819c2a4729444676f1bb55e5e28263f6f5a1 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 11 Mar 2010 13:28:14 -0500 Subject: drm/radeon/kms: fix for hw i2c use the i2c pads to drive SDA Possible fix for fdo bug 26430 Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index 4ae50c1..5d93418 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c @@ -291,6 +291,7 @@ static int r100_hw_i2c_xfer(struct i2c_adapter *i2c_adap, prescale = radeon_get_i2c_prescale(rdev); reg = ((prescale << RADEON_I2C_PRESCALE_SHIFT) | + RADEON_I2C_DRIVE_EN | RADEON_I2C_START | RADEON_I2C_STOP | RADEON_I2C_GO); -- cgit v0.10.2 From 96a4c8d50de20da865296a380b996f73204d6b34 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 12 Mar 2010 12:55:34 -0500 Subject: drm/radeon/kms: fix i2c prescale calc on older radeons Should fix fdo bug 26430 Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index 5d93418..f007fcb 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c @@ -183,11 +183,10 @@ static void set_data(void *i2c_priv, int data) static u32 radeon_get_i2c_prescale(struct radeon_device *rdev) { - struct radeon_pll *spll = &rdev->clock.spll; u32 sclk = radeon_get_engine_clock(rdev); u32 prescale = 0; - u32 n, m; - u8 loop; + u32 nm; + u8 n, m, loop; int i2c_clock; switch (rdev->family) { @@ -203,13 +202,15 @@ static u32 radeon_get_i2c_prescale(struct radeon_device *rdev) case CHIP_R300: case CHIP_R350: case CHIP_RV350: - n = (spll->reference_freq) / (4 * 6); + i2c_clock = 60; + nm = (sclk * 10) / (i2c_clock * 4); for (loop = 1; loop < 255; loop++) { - if ((loop * (loop - 1)) > n) + if ((nm / loop) < loop) break; } - m = loop - 1; - prescale = m | (loop << 8); + n = loop - 1; + m = loop - 2; + prescale = m | (n << 8); break; case CHIP_RV380: case CHIP_RS400: @@ -217,7 +218,6 @@ static u32 radeon_get_i2c_prescale(struct radeon_device *rdev) case CHIP_R420: case CHIP_R423: case CHIP_RV410: - sclk = radeon_get_engine_clock(rdev); prescale = (((sclk * 10)/(4 * 128 * 100) + 1) << 8) + 128; break; case CHIP_RS600: @@ -232,7 +232,6 @@ static u32 radeon_get_i2c_prescale(struct radeon_device *rdev) case CHIP_RV570: case CHIP_R580: i2c_clock = 50; - sclk = radeon_get_engine_clock(rdev); if (rdev->family == CHIP_R520) prescale = (127 << 8) + ((sclk * 10) / (4 * 127 * i2c_clock)); else -- cgit v0.10.2 From b28ea41164dc36110dafcdc63783e9b7fb865784 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 12 Mar 2010 13:30:49 -0500 Subject: drm/radeon/kms/r1xx: enable hw i2c fixing the i2c prescale in the last patch gets it working on r1xx. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 30a84ae..6d87e70 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -531,10 +531,7 @@ static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rde case CHIP_RS300: switch (ddc_line) { case RADEON_GPIO_DVI_DDC: - /* in theory this should be hw capable, - * but it doesn't seem to work - */ - i2c.hw_capable = false; + i2c.hw_capable = true; break; default: i2c.hw_capable = false; -- cgit v0.10.2 From d805f50aa1d9eef63fec356b2be557e2da3cd643 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 11 Mar 2010 10:38:07 -0500 Subject: drm/radeon/kms/rs4xx: make sure crtcs are enabled when setting timing based on ddx patch from Matthias Hopf. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index df23d6a..88865e3 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c @@ -603,6 +603,10 @@ static bool radeon_set_crtc_timing(struct drm_crtc *crtc, struct drm_display_mod ? RADEON_CRTC2_INTERLACE_EN : 0)); + /* rs4xx chips seem to like to have the crtc enabled when the timing is set */ + if ((rdev->family == CHIP_RS400) || (rdev->family == CHIP_RS480)) + crtc2_gen_cntl |= RADEON_CRTC2_EN; + disp2_merge_cntl = RREG32(RADEON_DISP2_MERGE_CNTL); disp2_merge_cntl &= ~RADEON_DISP2_RGB_OFFSET_EN; @@ -630,6 +634,10 @@ static bool radeon_set_crtc_timing(struct drm_crtc *crtc, struct drm_display_mod ? RADEON_CRTC_INTERLACE_EN : 0)); + /* rs4xx chips seem to like to have the crtc enabled when the timing is set */ + if ((rdev->family == CHIP_RS400) || (rdev->family == CHIP_RS480)) + crtc_gen_cntl |= RADEON_CRTC_EN; + crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL); crtc_ext_cntl |= (RADEON_XCRT_CNT_EN | RADEON_CRTC_VSYNC_DIS | -- cgit v0.10.2 From 808032ee296ee7b37a6df090be40a330e09ae30e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sat, 6 Mar 2010 13:03:33 +0000 Subject: drm/radeon/kms: clean HDMI definitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We already know same offsets are used for different encoders/transmitters, so just numeric them instead naming incorrectly. Additionaly we found additional registers needed for RV770+ Signed-off-by: Rafał Miłecki Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index fcc949d..4d09973 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c @@ -470,27 +470,27 @@ void r600_hdmi_init(struct drm_encoder *encoder) case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: - radeon_encoder->hdmi_offset = R600_HDMI_TMDS1; + radeon_encoder->hdmi_offset = R600_HDMI_BLOCK1; break; case ENCODER_OBJECT_ID_INTERNAL_LVTM1: switch (r600_audio_tmds_index(encoder)) { case 0: - radeon_encoder->hdmi_offset = R600_HDMI_TMDS1; + radeon_encoder->hdmi_offset = R600_HDMI_BLOCK1; break; case 1: - radeon_encoder->hdmi_offset = R600_HDMI_TMDS2; + radeon_encoder->hdmi_offset = R600_HDMI_BLOCK2; break; default: radeon_encoder->hdmi_offset = 0; break; } case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: - radeon_encoder->hdmi_offset = R600_HDMI_TMDS2; + radeon_encoder->hdmi_offset = R600_HDMI_BLOCK2; break; case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: - radeon_encoder->hdmi_offset = R600_HDMI_DIG; + radeon_encoder->hdmi_offset = R600_HDMI_BLOCK3; break; default: diff --git a/drivers/gpu/drm/radeon/r600_reg.h b/drivers/gpu/drm/radeon/r600_reg.h index d0e28ff..7b1d223 100644 --- a/drivers/gpu/drm/radeon/r600_reg.h +++ b/drivers/gpu/drm/radeon/r600_reg.h @@ -152,9 +152,9 @@ #define R600_AUDIO_STATUS_BITS 0x73d8 /* HDMI base register addresses */ -#define R600_HDMI_TMDS1 0x7400 -#define R600_HDMI_TMDS2 0x7700 -#define R600_HDMI_DIG 0x7800 +#define R600_HDMI_BLOCK1 0x7400 +#define R600_HDMI_BLOCK2 0x7700 +#define R600_HDMI_BLOCK3 0x7800 /* HDMI registers */ #define R600_HDMI_ENABLE 0x00 @@ -185,4 +185,8 @@ #define R600_HDMI_AUDIO_DEBUG_2 0xe8 #define R600_HDMI_AUDIO_DEBUG_3 0xec +/* HDMI additional config base register addresses */ +#define R600_HDMI_CONFIG1 0x7600 +#define R600_HDMI_CONFIG2 0x7a00 + #endif diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index b868ffa..55a4175 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -345,6 +345,7 @@ struct radeon_encoder { struct drm_display_mode native_mode; void *enc_priv; int hdmi_offset; + int hdmi_config_offset; int hdmi_audio_workaround; int hdmi_buffer_status; }; -- cgit v0.10.2 From 2cd6218cb8043ef4360b561e726cd081f8a380cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Mon, 8 Mar 2010 22:14:01 +0000 Subject: drm/radeon/kms: clean assigning HDMI blocks to encoders MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We almost always used first HDMI block for first encoder and second for sencod. Exception was KLDSCP_LVTMA. Analyzing code picking DIG encoder shows the same behaviour. It shows HDMI block are related to DIGs, which relation we now use. Signed-off-by: Rafał Miłecki Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/r600_audio.c b/drivers/gpu/drm/radeon/r600_audio.c index db92801..baf222f 100644 --- a/drivers/gpu/drm/radeon/r600_audio.c +++ b/drivers/gpu/drm/radeon/r600_audio.c @@ -224,6 +224,7 @@ void r600_audio_set_clock(struct drm_encoder *encoder, int clock) struct drm_device *dev = encoder->dev; struct radeon_device *rdev = dev->dev_private; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; int base_rate = 48000; switch (radeon_encoder->encoder_id) { @@ -245,7 +246,7 @@ void r600_audio_set_clock(struct drm_encoder *encoder, int clock) return; } - switch (r600_audio_tmds_index(encoder)) { + switch (dig->dig_encoder) { case 0: WREG32(R600_AUDIO_PLL1_MUL, base_rate*50); WREG32(R600_AUDIO_PLL1_DIV, clock*100); @@ -257,6 +258,10 @@ void r600_audio_set_clock(struct drm_encoder *encoder, int clock) WREG32(R600_AUDIO_PLL2_DIV, clock*100); WREG32(R600_AUDIO_CLK_SRCSEL, 1); break; + default: + dev_err(rdev->dev, "Unsupported DIG on encoder 0x%02X\n", + radeon_encoder->encoder_id); + return; } } diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index 4d09973..5275a81 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c @@ -417,90 +417,74 @@ void r600_hdmi_update_audio_settings(struct drm_encoder *encoder, WREG32_P(offset+R600_HDMI_CNTL, 0x04000000, ~0x04000000); } -/* - * enable/disable the HDMI engine - */ -void r600_hdmi_enable(struct drm_encoder *encoder, int enable) +static void r600_hdmi_assign_block(struct drm_encoder *encoder) { struct drm_device *dev = encoder->dev; struct radeon_device *rdev = dev->dev_private; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset; + struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; - if (!offset) + if (!dig) { + dev_err(rdev->dev, "Enabling HDMI on non-dig encoder\n"); return; + } - DRM_DEBUG("%s HDMI interface @ 0x%04X\n", enable ? "Enabling" : "Disabling", offset); - - /* some version of atombios ignore the enable HDMI flag - * so enabling/disabling HDMI was moved here for TMDS1+2 */ - switch (radeon_encoder->encoder_id) { - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: - WREG32_P(AVIVO_TMDSA_CNTL, enable ? 0x4 : 0x0, ~0x4); - WREG32(offset+R600_HDMI_ENABLE, enable ? 0x101 : 0x0); - break; - - case ENCODER_OBJECT_ID_INTERNAL_LVTM1: - WREG32_P(AVIVO_LVTMA_CNTL, enable ? 0x4 : 0x0, ~0x4); - WREG32(offset+R600_HDMI_ENABLE, enable ? 0x105 : 0x0); - break; - - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: - /* This part is doubtfull in my opinion */ - WREG32(offset+R600_HDMI_ENABLE, enable ? 0x110 : 0x0); - break; - - default: - DRM_ERROR("unknown HDMI output type\n"); - break; + if (ASIC_IS_DCE4(rdev)) { + /* TODO */ + } else if (ASIC_IS_DCE3(rdev)) { + radeon_encoder->hdmi_offset = dig->dig_encoder ? + R600_HDMI_BLOCK3 : R600_HDMI_BLOCK1; + if (ASIC_IS_DCE32(rdev)) + radeon_encoder->hdmi_config_offset = dig->dig_encoder ? + R600_HDMI_CONFIG2 : R600_HDMI_CONFIG1; } } /* - * determin at which register offset the HDMI encoder is + * enable the HDMI engine */ -void r600_hdmi_init(struct drm_encoder *encoder) +void r600_hdmi_enable(struct drm_encoder *encoder) { + struct drm_device *dev = encoder->dev; + struct radeon_device *rdev = dev->dev_private; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - switch (radeon_encoder->encoder_id) { - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: - radeon_encoder->hdmi_offset = R600_HDMI_BLOCK1; - break; - - case ENCODER_OBJECT_ID_INTERNAL_LVTM1: - switch (r600_audio_tmds_index(encoder)) { - case 0: - radeon_encoder->hdmi_offset = R600_HDMI_BLOCK1; - break; - case 1: - radeon_encoder->hdmi_offset = R600_HDMI_BLOCK2; - break; - default: - radeon_encoder->hdmi_offset = 0; - break; + if (!radeon_encoder->hdmi_offset) { + r600_hdmi_assign_block(encoder); + if (!radeon_encoder->hdmi_offset) { + dev_warn(rdev->dev, "Could not find HDMI block for " + "0x%x encoder\n", radeon_encoder->encoder_id); + return; } - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: - radeon_encoder->hdmi_offset = R600_HDMI_BLOCK2; - break; + } - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: - radeon_encoder->hdmi_offset = R600_HDMI_BLOCK3; - break; + if (ASIC_IS_DCE32(rdev) && !ASIC_IS_DCE4(rdev)) + WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0x1, ~0x1); + + DRM_DEBUG("Enabling HDMI interface @ 0x%04X for encoder 0x%x\n", + radeon_encoder->hdmi_offset, radeon_encoder->encoder_id); +} - default: - radeon_encoder->hdmi_offset = 0; - break; +/* + * disable the HDMI engine + */ +void r600_hdmi_disable(struct drm_encoder *encoder) +{ + struct drm_device *dev = encoder->dev; + struct radeon_device *rdev = dev->dev_private; + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + + if (!radeon_encoder->hdmi_offset) { + dev_err(rdev->dev, "Disabling not enabled HDMI\n"); + return; } - DRM_DEBUG("using HDMI engine at offset 0x%04X for encoder 0x%x\n", - radeon_encoder->hdmi_offset, radeon_encoder->encoder_id); + DRM_DEBUG("Disabling HDMI interface @ 0x%04X for encoder 0x%x\n", + radeon_encoder->hdmi_offset, radeon_encoder->encoder_id); + + if (ASIC_IS_DCE32(rdev) && !ASIC_IS_DCE4(rdev)) + WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0, ~0x1); - /* TODO: make this configureable */ - radeon_encoder->hdmi_audio_workaround = 0; + radeon_encoder->hdmi_offset = 0; + radeon_encoder->hdmi_config_offset = 0; } diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 829e26e..ba93e5a 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1322,7 +1322,8 @@ extern int r600_audio_tmds_index(struct drm_encoder *encoder); extern void r600_audio_set_clock(struct drm_encoder *encoder, int clock); extern void r600_audio_fini(struct radeon_device *rdev); extern void r600_hdmi_init(struct drm_encoder *encoder); -extern void r600_hdmi_enable(struct drm_encoder *encoder, int enable); +extern void r600_hdmi_enable(struct drm_encoder *encoder); +extern void r600_hdmi_disable(struct drm_encoder *encoder); extern void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode); extern int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder); extern void r600_hdmi_update_audio_settings(struct drm_encoder *encoder, diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 4eae30c..a236c75 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c @@ -593,7 +593,6 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) } atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); - r600_hdmi_enable(encoder, hdmi_detected); } int @@ -1389,9 +1388,10 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, } atombios_apply_encoder_quirks(encoder, adjusted_mode); - /* XXX */ - if (!ASIC_IS_DCE4(rdev)) + if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) { + r600_hdmi_enable(encoder); r600_hdmi_setmode(encoder, adjusted_mode); + } } static bool @@ -1514,6 +1514,8 @@ static void radeon_atom_encoder_disable(struct drm_encoder *encoder) radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); if (radeon_encoder_is_digital(encoder)) { + if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) + r600_hdmi_disable(encoder); dig = radeon_encoder->enc_priv; dig->dig_encoder = -1; } @@ -1664,6 +1666,4 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs); break; } - - r600_hdmi_init(encoder); } -- cgit v0.10.2 From 5715f67cecee3617c7a6ff84ee44da46d525559e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sat, 6 Mar 2010 13:03:35 +0000 Subject: drm/radeon/kms: add HDMI code for pre-DCE3 R6xx GPUs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Older GPUs are little different, HDMI blocks are not hard-wired, but routable. We should just find some free HDMI block and route it to choosen encoder. In case of RS6x0 there is only one HDMI block, we don't enable HDMI on RS6x00 yet however. Signed-off-by: Rafał Miłecki Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index 5275a81..8fbfc73 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c @@ -417,6 +417,39 @@ void r600_hdmi_update_audio_settings(struct drm_encoder *encoder, WREG32_P(offset+R600_HDMI_CNTL, 0x04000000, ~0x04000000); } +static int r600_hdmi_find_free_block(struct drm_device *dev) +{ + struct radeon_device *rdev = dev->dev_private; + struct drm_encoder *encoder; + struct radeon_encoder *radeon_encoder; + bool free_blocks[3] = { true, true, true }; + + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { + radeon_encoder = to_radeon_encoder(encoder); + switch (radeon_encoder->hdmi_offset) { + case R600_HDMI_BLOCK1: + free_blocks[0] = false; + break; + case R600_HDMI_BLOCK2: + free_blocks[1] = false; + break; + case R600_HDMI_BLOCK3: + free_blocks[2] = false; + break; + } + } + + if (rdev->family == CHIP_RS600 || rdev->family == CHIP_RS690) { + return free_blocks[0] ? R600_HDMI_BLOCK1 : 0; + } else if (rdev->family >= CHIP_R600) { + if (free_blocks[0]) + return R600_HDMI_BLOCK1; + else if (free_blocks[1]) + return R600_HDMI_BLOCK2; + } + return 0; +} + static void r600_hdmi_assign_block(struct drm_encoder *encoder) { struct drm_device *dev = encoder->dev; @@ -437,6 +470,8 @@ static void r600_hdmi_assign_block(struct drm_encoder *encoder) if (ASIC_IS_DCE32(rdev)) radeon_encoder->hdmi_config_offset = dig->dig_encoder ? R600_HDMI_CONFIG2 : R600_HDMI_CONFIG1; + } else if (rdev->family >= CHIP_R600) { + radeon_encoder->hdmi_offset = r600_hdmi_find_free_block(dev); } } @@ -458,8 +493,24 @@ void r600_hdmi_enable(struct drm_encoder *encoder) } } - if (ASIC_IS_DCE32(rdev) && !ASIC_IS_DCE4(rdev)) + if (ASIC_IS_DCE32(rdev) && !ASIC_IS_DCE4(rdev)) { WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0x1, ~0x1); + } else if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) { + int offset = radeon_encoder->hdmi_offset; + switch (radeon_encoder->encoder_id) { + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: + WREG32_P(AVIVO_TMDSA_CNTL, 0x4, ~0x4); + WREG32(offset + R600_HDMI_ENABLE, 0x101); + break; + case ENCODER_OBJECT_ID_INTERNAL_LVTM1: + WREG32_P(AVIVO_LVTMA_CNTL, 0x4, ~0x4); + WREG32(offset + R600_HDMI_ENABLE, 0x105); + break; + default: + dev_err(rdev->dev, "Unknown HDMI output type\n"); + break; + } + } DRM_DEBUG("Enabling HDMI interface @ 0x%04X for encoder 0x%x\n", radeon_encoder->hdmi_offset, radeon_encoder->encoder_id); @@ -482,8 +533,24 @@ void r600_hdmi_disable(struct drm_encoder *encoder) DRM_DEBUG("Disabling HDMI interface @ 0x%04X for encoder 0x%x\n", radeon_encoder->hdmi_offset, radeon_encoder->encoder_id); - if (ASIC_IS_DCE32(rdev) && !ASIC_IS_DCE4(rdev)) + if (ASIC_IS_DCE32(rdev) && !ASIC_IS_DCE4(rdev)) { WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0, ~0x1); + } else if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) { + int offset = radeon_encoder->hdmi_offset; + switch (radeon_encoder->encoder_id) { + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: + WREG32_P(AVIVO_TMDSA_CNTL, 0, ~0x4); + WREG32(offset + R600_HDMI_ENABLE, 0); + break; + case ENCODER_OBJECT_ID_INTERNAL_LVTM1: + WREG32_P(AVIVO_LVTMA_CNTL, 0, ~0x4); + WREG32(offset + R600_HDMI_ENABLE, 0); + break; + default: + dev_err(rdev->dev, "Unknown HDMI output type\n"); + break; + } + } radeon_encoder->hdmi_offset = 0; radeon_encoder->hdmi_config_offset = 0; -- cgit v0.10.2 From 8a8c6e7cfb63cc5e04d5c247ab8d6253200fd425 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sat, 6 Mar 2010 13:03:36 +0000 Subject: drm/radeon/kms: enable audio engine on DCE32 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 37887de..8f0c925 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -1013,6 +1013,13 @@ int rv770_resume(struct radeon_device *rdev) DRM_ERROR("radeon: failled testing IB (%d).\n", r); return r; } + + r = r600_audio_init(rdev); + if (r) { + dev_err(rdev->dev, "radeon: audio init failed\n"); + return r; + } + return r; } @@ -1021,6 +1028,7 @@ int rv770_suspend(struct radeon_device *rdev) { int r; + r600_audio_fini(rdev); /* FIXME: we should wait for ring to be empty */ r700_cp_stop(rdev); rdev->cp.ready = false; @@ -1144,6 +1152,13 @@ int rv770_init(struct radeon_device *rdev) } } } + + r = r600_audio_init(rdev); + if (r) { + dev_err(rdev->dev, "radeon: audio init failed\n"); + return r; + } + return 0; } -- cgit v0.10.2 From 0a7d934e6022a12e3f428b2adcb4b531e86170dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sat, 6 Mar 2010 13:03:37 +0000 Subject: drm/radeon/kms: remove dead audio/HDMI code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/r600_audio.c b/drivers/gpu/drm/radeon/r600_audio.c index baf222f..dddb9e5 100644 --- a/drivers/gpu/drm/radeon/r600_audio.c +++ b/drivers/gpu/drm/radeon/r600_audio.c @@ -182,41 +182,6 @@ int r600_audio_init(struct radeon_device *rdev) } /* - * determin how the encoders and audio interface is wired together - */ -int r600_audio_tmds_index(struct drm_encoder *encoder) -{ - struct drm_device *dev = encoder->dev; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct drm_encoder *other; - - switch (radeon_encoder->encoder_id) { - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: - return 0; - - case ENCODER_OBJECT_ID_INTERNAL_LVTM1: - /* special case check if an TMDS1 is present */ - list_for_each_entry(other, &dev->mode_config.encoder_list, head) { - if (to_radeon_encoder(other)->encoder_id == - ENCODER_OBJECT_ID_INTERNAL_TMDS1) - return 1; - } - return 0; - - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: - return 1; - - default: - DRM_ERROR("Unsupported encoder type 0x%02X\n", - radeon_encoder->encoder_id); - return -1; - } -} - -/* * atach the audio codec to the clock source of the encoder */ void r600_audio_set_clock(struct drm_encoder *encoder, int clock) -- cgit v0.10.2 From 3fe373d98cdb35c494517b0954b76f8094f4c59d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sat, 6 Mar 2010 13:03:38 +0000 Subject: drm/radeon/kms: improve coding style a little MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We still have many magic numbers in HDMI/audio to define Signed-off-by: Rafał Miłecki Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/r600_audio.c b/drivers/gpu/drm/radeon/r600_audio.c index dddb9e5..dac7042 100644 --- a/drivers/gpu/drm/radeon/r600_audio.c +++ b/drivers/gpu/drm/radeon/r600_audio.c @@ -197,14 +197,12 @@ void r600_audio_set_clock(struct drm_encoder *encoder, int clock) case ENCODER_OBJECT_ID_INTERNAL_LVTM1: WREG32_P(R600_AUDIO_TIMING, 0, ~0x301); break; - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: WREG32_P(R600_AUDIO_TIMING, 0x100, ~0x301); break; - default: DRM_ERROR("Unsupported encoder type 0x%02X\n", radeon_encoder->encoder_id); @@ -213,14 +211,14 @@ void r600_audio_set_clock(struct drm_encoder *encoder, int clock) switch (dig->dig_encoder) { case 0: - WREG32(R600_AUDIO_PLL1_MUL, base_rate*50); - WREG32(R600_AUDIO_PLL1_DIV, clock*100); + WREG32(R600_AUDIO_PLL1_MUL, base_rate * 50); + WREG32(R600_AUDIO_PLL1_DIV, clock * 100); WREG32(R600_AUDIO_CLK_SRCSEL, 0); break; case 1: - WREG32(R600_AUDIO_PLL2_MUL, base_rate*50); - WREG32(R600_AUDIO_PLL2_DIV, clock*100); + WREG32(R600_AUDIO_PLL2_MUL, base_rate * 50); + WREG32(R600_AUDIO_PLL2_DIV, clock * 100); WREG32(R600_AUDIO_CLK_SRCSEL, 1); break; default: diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index 8fbfc73..029fa14 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c @@ -42,13 +42,13 @@ enum r600_hdmi_color_format { */ enum r600_hdmi_iec_status_bits { AUDIO_STATUS_DIG_ENABLE = 0x01, - AUDIO_STATUS_V = 0x02, - AUDIO_STATUS_VCFG = 0x04, + AUDIO_STATUS_V = 0x02, + AUDIO_STATUS_VCFG = 0x04, AUDIO_STATUS_EMPHASIS = 0x08, AUDIO_STATUS_COPYRIGHT = 0x10, AUDIO_STATUS_NONAUDIO = 0x20, AUDIO_STATUS_PROFESSIONAL = 0x40, - AUDIO_STATUS_LEVEL = 0x80 + AUDIO_STATUS_LEVEL = 0x80 }; struct { @@ -85,7 +85,7 @@ struct { static void r600_hdmi_calc_CTS(uint32_t clock, int *CTS, int N, int freq) { if (*CTS == 0) - *CTS = clock*N/(128*freq)*1000; + *CTS = clock * N / (128 * freq) * 1000; DRM_DEBUG("Using ACR timing N=%d CTS=%d for frequency %d\n", N, *CTS, freq); } @@ -131,11 +131,11 @@ static void r600_hdmi_infoframe_checksum(uint8_t packetType, uint8_t length, uint8_t *frame) { - int i; - frame[0] = packetType + versionNumber + length; - for (i = 1; i <= length; i++) - frame[0] += frame[i]; - frame[0] = 0x100 - frame[0]; + int i; + frame[0] = packetType + versionNumber + length; + for (i = 1; i <= length; i++) + frame[0] += frame[i]; + frame[0] = 0x100 - frame[0]; } /* -- cgit v0.10.2 From 65388342d66a63a29c76058e94a00d7bc0c6423b Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 5 Mar 2010 19:22:24 -0500 Subject: drm/radeon/r600: add missing license and comments to r600_blit_shaders.c R6xx+ cards need to use the 3D engine to blit data which requires quite a bit of hw state setup. Rather than pull the whole 3D driver (which normally generates the 3D state) into the DRM, we opt to use statically generated state tables. The regsiter state and shaders were hand generated to support blitting functionality. See the 3D driver or documentation for descriptions of the registers and shader instructions. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/r600_blit_shaders.c b/drivers/gpu/drm/radeon/r600_blit_shaders.c index a112c59..0271b53 100644 --- a/drivers/gpu/drm/radeon/r600_blit_shaders.c +++ b/drivers/gpu/drm/radeon/r600_blit_shaders.c @@ -1,7 +1,42 @@ +/* + * Copyright 2009 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Alex Deucher + */ #include #include +/* + * R6xx+ cards need to use the 3D engine to blit data which requires + * quite a bit of hw state setup. Rather than pull the whole 3D driver + * (which normally generates the 3D state) into the DRM, we opt to use + * statically generated state tables. The regsiter state and shaders + * were hand generated to support blitting functionality. See the 3D + * driver or documentation for descriptions of the registers and + * shader instructions. + */ + const u32 r6xx_default_state[] = { 0xc0002400, -- cgit v0.10.2 From cd7e9fcd1f7c9c397f747cf506c66f7dca11d1c6 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 5 Mar 2010 10:47:26 -0700 Subject: resource: expand IORESOURCE_TYPE_BITS to make room for bus resource type No functional change; this just makes room for another resource type. Signed-off-by: Bjorn Helgaas Signed-off-by: Len Brown diff --git a/include/linux/ioport.h b/include/linux/ioport.h index dda9841..b126209 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h @@ -34,20 +34,20 @@ struct resource_list { */ #define IORESOURCE_BITS 0x000000ff /* Bus-specific bits */ -#define IORESOURCE_TYPE_BITS 0x00000f00 /* Resource type */ +#define IORESOURCE_TYPE_BITS 0x00001f00 /* Resource type */ #define IORESOURCE_IO 0x00000100 #define IORESOURCE_MEM 0x00000200 #define IORESOURCE_IRQ 0x00000400 #define IORESOURCE_DMA 0x00000800 -#define IORESOURCE_PREFETCH 0x00001000 /* No side effects */ -#define IORESOURCE_READONLY 0x00002000 -#define IORESOURCE_CACHEABLE 0x00004000 -#define IORESOURCE_RANGELENGTH 0x00008000 -#define IORESOURCE_SHADOWABLE 0x00010000 +#define IORESOURCE_PREFETCH 0x00002000 /* No side effects */ +#define IORESOURCE_READONLY 0x00004000 +#define IORESOURCE_CACHEABLE 0x00008000 +#define IORESOURCE_RANGELENGTH 0x00010000 +#define IORESOURCE_SHADOWABLE 0x00020000 -#define IORESOURCE_SIZEALIGN 0x00020000 /* size indicates alignment */ -#define IORESOURCE_STARTALIGN 0x00040000 /* start field is alignment */ +#define IORESOURCE_SIZEALIGN 0x00040000 /* size indicates alignment */ +#define IORESOURCE_STARTALIGN 0x00080000 /* start field is alignment */ #define IORESOURCE_MEM_64 0x00100000 -- cgit v0.10.2 From 0f4050c7d3ba0275e5f39513c0670a717d43048c Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 5 Mar 2010 10:47:42 -0700 Subject: resource: add bus number support Add support for bus number resources. This is for bridges with a range of bus numbers behind them. Signed-off-by: Bjorn Helgaas Signed-off-by: Len Brown diff --git a/include/linux/ioport.h b/include/linux/ioport.h index b126209..510e4ac 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h @@ -39,6 +39,7 @@ struct resource_list { #define IORESOURCE_MEM 0x00000200 #define IORESOURCE_IRQ 0x00000400 #define IORESOURCE_DMA 0x00000800 +#define IORESOURCE_BUS 0x00001000 #define IORESOURCE_PREFETCH 0x00002000 /* No side effects */ #define IORESOURCE_READONLY 0x00004000 diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 0d461c7..ebbecf9 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -609,6 +609,12 @@ static char *resource_string(char *buf, char *end, struct resource *res, .precision = -1, .flags = SPECIAL | SMALL | ZEROPAD, }; + static const struct printf_spec bus_spec = { + .base = 16, + .field_width = 2, + .precision = -1, + .flags = SMALL | ZEROPAD, + }; static const struct printf_spec dec_spec = { .base = 10, .precision = -1, @@ -651,6 +657,9 @@ static char *resource_string(char *buf, char *end, struct resource *res, } else if (res->flags & IORESOURCE_DMA) { p = string(p, pend, "dma ", str_spec); specp = &dec_spec; + } else if (res->flags & IORESOURCE_BUS) { + p = string(p, pend, "bus ", str_spec); + specp = &bus_spec; } else { p = string(p, pend, "??? ", str_spec); specp = &mem_spec; -- cgit v0.10.2 From 9d7cca04211d4eb104eaaa424b98f650bc29c730 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 5 Mar 2010 10:47:47 -0700 Subject: resource: add window support Add support for resource windows. This is for bridge resources, i.e., regions where a bridge forwards transactions from the primary to the secondary side. Signed-off-by: Bjorn Helgaas Signed-off-by: Len Brown diff --git a/include/linux/ioport.h b/include/linux/ioport.h index 510e4ac..71ab79d 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h @@ -51,6 +51,7 @@ struct resource_list { #define IORESOURCE_STARTALIGN 0x00080000 /* start field is alignment */ #define IORESOURCE_MEM_64 0x00100000 +#define IORESOURCE_WINDOW 0x00200000 /* forwarded by bridge */ #define IORESOURCE_EXCLUSIVE 0x08000000 /* Userland may not map this resource */ #define IORESOURCE_DISABLED 0x10000000 diff --git a/lib/vsprintf.c b/lib/vsprintf.c index ebbecf9..24112e5 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -635,7 +635,7 @@ static char *resource_string(char *buf, char *end, struct resource *res, * 64-bit res (sizeof==8): 20 chars in dec, 18 in hex ("0x" + 16) */ #define RSRC_BUF_SIZE ((2 * sizeof(resource_size_t)) + 4) #define FLAG_BUF_SIZE (2 * sizeof(res->flags)) -#define DECODED_BUF_SIZE sizeof("[mem - 64bit pref disabled]") +#define DECODED_BUF_SIZE sizeof("[mem - 64bit pref window disabled]") #define RAW_BUF_SIZE sizeof("[mem - flags 0x]") char sym[max(2*RSRC_BUF_SIZE + DECODED_BUF_SIZE, 2*RSRC_BUF_SIZE + FLAG_BUF_SIZE + RAW_BUF_SIZE)]; @@ -675,6 +675,8 @@ static char *resource_string(char *buf, char *end, struct resource *res, p = string(p, pend, " 64bit", str_spec); if (res->flags & IORESOURCE_PREFETCH) p = string(p, pend, " pref", str_spec); + if (res->flags & IORESOURCE_WINDOW) + p = string(p, pend, " window", str_spec); if (res->flags & IORESOURCE_DISABLED) p = string(p, pend, " disabled", str_spec); } else { -- cgit v0.10.2 From fa35b49260b615d634bfa1f767aa315fa323c2e9 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 5 Mar 2010 10:47:52 -0700 Subject: PNPACPI: add window support Add support for resource windows. This is for bridge resources, i.e., regions where a bridge forwards transactions from the primary to the secondary side. This does not add support for *setting* windows via the /proc interface. Signed-off-by: Bjorn Helgaas Signed-off-by: Len Brown diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c index 68b0c04..ba437b7 100644 --- a/drivers/pnp/interface.c +++ b/drivers/pnp/interface.c @@ -278,9 +278,11 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, switch (pnp_resource_type(res)) { case IORESOURCE_IO: case IORESOURCE_MEM: - pnp_printf(buffer, " %#llx-%#llx\n", + pnp_printf(buffer, " %#llx-%#llx%s\n", (unsigned long long) res->start, - (unsigned long long) res->end); + (unsigned long long) res->end, + res->flags & IORESOURCE_WINDOW ? + " window" : ""); break; case IORESOURCE_IRQ: case IORESOURCE_DMA: diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 5702b2c..0d7d61d 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c @@ -177,7 +177,8 @@ static int dma_flags(struct pnp_dev *dev, int type, int bus_master, } static void pnpacpi_parse_allocated_ioresource(struct pnp_dev *dev, u64 start, - u64 len, int io_decode) + u64 len, int io_decode, + int window) { int flags = 0; u64 end = start + len - 1; @@ -186,6 +187,8 @@ static void pnpacpi_parse_allocated_ioresource(struct pnp_dev *dev, u64 start, flags |= IORESOURCE_IO_16BIT_ADDR; if (len == 0 || end >= 0x10003) flags |= IORESOURCE_DISABLED; + if (window) + flags |= IORESOURCE_WINDOW; pnp_add_io_resource(dev, start, end, flags); } @@ -247,7 +250,7 @@ static void pnpacpi_parse_allocated_vendor(struct pnp_dev *dev, static void pnpacpi_parse_allocated_memresource(struct pnp_dev *dev, u64 start, u64 len, - int write_protect) + int write_protect, int window) { int flags = 0; u64 end = start + len - 1; @@ -256,6 +259,8 @@ static void pnpacpi_parse_allocated_memresource(struct pnp_dev *dev, flags |= IORESOURCE_DISABLED; if (write_protect == ACPI_READ_WRITE_MEMORY) flags |= IORESOURCE_MEM_WRITEABLE; + if (window) + flags |= IORESOURCE_WINDOW; pnp_add_mem_resource(dev, start, end, flags); } @@ -265,6 +270,7 @@ static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev, { struct acpi_resource_address64 addr, *p = &addr; acpi_status status; + int window; status = acpi_resource_to_address64(res, p); if (!ACPI_SUCCESS(status)) { @@ -273,37 +279,36 @@ static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev, return; } - if (p->producer_consumer == ACPI_PRODUCER) - return; + window = (p->producer_consumer == ACPI_PRODUCER) ? 1 : 0; if (p->resource_type == ACPI_MEMORY_RANGE) pnpacpi_parse_allocated_memresource(dev, p->minimum, p->address_length, - p->info.mem.write_protect); + p->info.mem.write_protect, window); else if (p->resource_type == ACPI_IO_RANGE) pnpacpi_parse_allocated_ioresource(dev, p->minimum, p->address_length, p->granularity == 0xfff ? ACPI_DECODE_10 : - ACPI_DECODE_16); + ACPI_DECODE_16, window); } static void pnpacpi_parse_allocated_ext_address_space(struct pnp_dev *dev, struct acpi_resource *res) { struct acpi_resource_extended_address64 *p = &res->data.ext_address64; + int window; - if (p->producer_consumer == ACPI_PRODUCER) - return; + window = (p->producer_consumer == ACPI_PRODUCER) ? 1 : 0; if (p->resource_type == ACPI_MEMORY_RANGE) pnpacpi_parse_allocated_memresource(dev, p->minimum, p->address_length, - p->info.mem.write_protect); + p->info.mem.write_protect, window); else if (p->resource_type == ACPI_IO_RANGE) pnpacpi_parse_allocated_ioresource(dev, p->minimum, p->address_length, p->granularity == 0xfff ? ACPI_DECODE_10 : - ACPI_DECODE_16); + ACPI_DECODE_16, window); } static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, @@ -368,7 +373,7 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, pnpacpi_parse_allocated_ioresource(dev, io->minimum, io->address_length, - io->io_decode); + io->io_decode, 0); break; case ACPI_RESOURCE_TYPE_START_DEPENDENT: @@ -380,7 +385,7 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, pnpacpi_parse_allocated_ioresource(dev, fixed_io->address, fixed_io->address_length, - ACPI_DECODE_10); + ACPI_DECODE_10, 0); break; case ACPI_RESOURCE_TYPE_VENDOR: @@ -396,21 +401,21 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, pnpacpi_parse_allocated_memresource(dev, memory24->minimum, memory24->address_length, - memory24->write_protect); + memory24->write_protect, 0); break; case ACPI_RESOURCE_TYPE_MEMORY32: memory32 = &res->data.memory32; pnpacpi_parse_allocated_memresource(dev, memory32->minimum, memory32->address_length, - memory32->write_protect); + memory32->write_protect, 0); break; case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: fixed_memory32 = &res->data.fixed_memory32; pnpacpi_parse_allocated_memresource(dev, fixed_memory32->address, fixed_memory32->address_length, - fixed_memory32->write_protect); + fixed_memory32->write_protect, 0); break; case ACPI_RESOURCE_TYPE_ADDRESS16: case ACPI_RESOURCE_TYPE_ADDRESS32: -- cgit v0.10.2 From 7e0e9c042790d4ea44c6a00ddaad8b8bbcc3f17f Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 5 Mar 2010 10:47:57 -0700 Subject: PNPACPI: add bus number support Add support for bus number resources. This is for bridges with a range of bus numbers behind them. Previously, PNP ignored bus number resources. Signed-off-by: Bjorn Helgaas Signed-off-by: Len Brown diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h index 0b8d140..0bab84e 100644 --- a/drivers/pnp/base.h +++ b/drivers/pnp/base.h @@ -166,6 +166,9 @@ struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev, struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev, resource_size_t start, resource_size_t end, int flags); +struct pnp_resource *pnp_add_bus_resource(struct pnp_dev *dev, + resource_size_t start, + resource_size_t end); extern int pnp_debug; diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c index ba437b7..cfaf5b7 100644 --- a/drivers/pnp/interface.c +++ b/drivers/pnp/interface.c @@ -278,6 +278,7 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, switch (pnp_resource_type(res)) { case IORESOURCE_IO: case IORESOURCE_MEM: + case IORESOURCE_BUS: pnp_printf(buffer, " %#llx-%#llx%s\n", (unsigned long long) res->start, (unsigned long long) res->end, diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 0d7d61d..54514aa 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c @@ -265,6 +265,14 @@ static void pnpacpi_parse_allocated_memresource(struct pnp_dev *dev, pnp_add_mem_resource(dev, start, end, flags); } +static void pnpacpi_parse_allocated_busresource(struct pnp_dev *dev, + u64 start, u64 len) +{ + u64 end = start + len - 1; + + pnp_add_bus_resource(dev, start, end); +} + static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev, struct acpi_resource *res) { @@ -290,6 +298,9 @@ static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev, p->minimum, p->address_length, p->granularity == 0xfff ? ACPI_DECODE_10 : ACPI_DECODE_16, window); + else if (p->resource_type == ACPI_BUS_NUMBER_RANGE) + pnpacpi_parse_allocated_busresource(dev, p->minimum, + p->address_length); } static void pnpacpi_parse_allocated_ext_address_space(struct pnp_dev *dev, @@ -309,6 +320,9 @@ static void pnpacpi_parse_allocated_ext_address_space(struct pnp_dev *dev, p->minimum, p->address_length, p->granularity == 0xfff ? ACPI_DECODE_10 : ACPI_DECODE_16, window); + else if (p->resource_type == ACPI_BUS_NUMBER_RANGE) + pnpacpi_parse_allocated_busresource(dev, p->minimum, + p->address_length); } static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c index 64d0596..5b277db 100644 --- a/drivers/pnp/resource.c +++ b/drivers/pnp/resource.c @@ -470,7 +470,8 @@ int pnp_check_dma(struct pnp_dev *dev, struct resource *res) unsigned long pnp_resource_type(struct resource *res) { return res->flags & (IORESOURCE_IO | IORESOURCE_MEM | - IORESOURCE_IRQ | IORESOURCE_DMA); + IORESOURCE_IRQ | IORESOURCE_DMA | + IORESOURCE_BUS); } struct resource *pnp_get_resource(struct pnp_dev *dev, @@ -590,6 +591,30 @@ struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev, return pnp_res; } +struct pnp_resource *pnp_add_bus_resource(struct pnp_dev *dev, + resource_size_t start, + resource_size_t end) +{ + struct pnp_resource *pnp_res; + struct resource *res; + + pnp_res = pnp_new_resource(dev); + if (!pnp_res) { + dev_err(&dev->dev, "can't add resource for BUS %#llx-%#llx\n", + (unsigned long long) start, + (unsigned long long) end); + return NULL; + } + + res = &pnp_res->res; + res->flags = IORESOURCE_BUS; + res->start = start; + res->end = end; + + pnp_dbg(&dev->dev, " add %pr\n", res); + return pnp_res; +} + /* * Determine whether the specified resource is a possible configuration * for this device. diff --git a/drivers/pnp/support.c b/drivers/pnp/support.c index 9585c1c..f5beb24 100644 --- a/drivers/pnp/support.c +++ b/drivers/pnp/support.c @@ -69,8 +69,10 @@ char *pnp_resource_type_name(struct resource *res) return "irq"; case IORESOURCE_DMA: return "dma"; + case IORESOURCE_BUS: + return "bus"; } - return NULL; + return "unknown"; } void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc) -- cgit v0.10.2 From 839461d3b0e3082eb382f17a3e3899372f28649a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Tue, 2 Mar 2010 22:06:51 +0100 Subject: drm/radeon/kms: switch to condition waiting for reclocking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We tried to implement interruptible waiting with timeout (it was broken anyway) which was not a good idea as explained by Andrew. It's possible to avoid using additional variable but actually it inroduces using more complex in-kernel tools. So simply add one variable for condition. Signed-off-by: Rafał Miłecki Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 91eb762..73f9a79 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -312,10 +312,12 @@ int r100_irq_process(struct radeon_device *rdev) /* Vertical blank interrupts */ if (status & RADEON_CRTC_VBLANK_STAT) { drm_handle_vblank(rdev->ddev, 0); + rdev->pm.vblank_sync = true; wake_up(&rdev->irq.vblank_queue); } if (status & RADEON_CRTC2_VBLANK_STAT) { drm_handle_vblank(rdev->ddev, 1); + rdev->pm.vblank_sync = true; wake_up(&rdev->irq.vblank_queue); } if (status & RADEON_FP_DETECT_STAT) { diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index c522901..5b56a1b 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -2765,6 +2765,7 @@ restart_ih: case 0: /* D1 vblank */ if (disp_int & LB_D1_VBLANK_INTERRUPT) { drm_handle_vblank(rdev->ddev, 0); + rdev->pm.vblank_sync = true; wake_up(&rdev->irq.vblank_queue); disp_int &= ~LB_D1_VBLANK_INTERRUPT; DRM_DEBUG("IH: D1 vblank\n"); @@ -2786,6 +2787,7 @@ restart_ih: case 0: /* D2 vblank */ if (disp_int & LB_D2_VBLANK_INTERRUPT) { drm_handle_vblank(rdev->ddev, 1); + rdev->pm.vblank_sync = true; wake_up(&rdev->irq.vblank_queue); disp_int &= ~LB_D2_VBLANK_INTERRUPT; DRM_DEBUG("IH: D2 vblank\n"); diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index ba93e5a..b54d4f3 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -687,6 +687,7 @@ struct radeon_pm { bool downclocked; int active_crtcs; int req_vblank; + bool vblank_sync; fixed20_12 max_bandwidth; fixed20_12 igp_sideport_mclk; fixed20_12 igp_system_mclk; diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index d4d1c39..d800b86 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -353,10 +353,12 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev) rdev->pm.req_vblank |= (1 << 1); drm_vblank_get(rdev->ddev, 1); } - if (rdev->pm.active_crtcs) - wait_event_interruptible_timeout( - rdev->irq.vblank_queue, 0, + if (rdev->pm.active_crtcs) { + rdev->pm.vblank_sync = false; + wait_event_timeout( + rdev->irq.vblank_queue, rdev->pm.vblank_sync, msecs_to_jiffies(RADEON_WAIT_VBLANK_TIMEOUT)); + } if (rdev->pm.req_vblank & (1 << 0)) { rdev->pm.req_vblank &= ~(1 << 0); drm_vblank_put(rdev->ddev, 0); diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 47f046b..ac7c27a 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -392,10 +392,12 @@ int rs600_irq_process(struct radeon_device *rdev) /* Vertical blank interrupts */ if (G_007EDC_LB_D1_VBLANK_INTERRUPT(r500_disp_int)) { drm_handle_vblank(rdev->ddev, 0); + rdev->pm.vblank_sync = true; wake_up(&rdev->irq.vblank_queue); } if (G_007EDC_LB_D2_VBLANK_INTERRUPT(r500_disp_int)) { drm_handle_vblank(rdev->ddev, 1); + rdev->pm.vblank_sync = true; wake_up(&rdev->irq.vblank_queue); } if (G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(r500_disp_int)) { -- cgit v0.10.2 From d0d6cb81e7eb34d83461070ca3e919fba1db437c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Tue, 2 Mar 2010 22:06:52 +0100 Subject: drm/radeon/kms: prepare for more reclocking operations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index d800b86..4f37b52 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -28,6 +28,7 @@ #define RADEON_RECLOCK_DELAY_MS 200 #define RADEON_WAIT_VBLANK_TIMEOUT 200 +static bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish); static void radeon_pm_set_clocks_locked(struct radeon_device *rdev); static void radeon_pm_set_clocks(struct radeon_device *rdev); static void radeon_pm_idle_work_handler(struct work_struct *work); @@ -179,6 +180,16 @@ static void radeon_get_power_state(struct radeon_device *rdev, rdev->pm.requested_power_state->non_clock_info.pcie_lanes); } +static inline void radeon_sync_with_vblank(struct radeon_device *rdev) +{ + if (rdev->pm.active_crtcs) { + rdev->pm.vblank_sync = false; + wait_event_timeout( + rdev->irq.vblank_queue, rdev->pm.vblank_sync, + msecs_to_jiffies(RADEON_WAIT_VBLANK_TIMEOUT)); + } +} + static void radeon_set_power_state(struct radeon_device *rdev) { /* if *_clock_mode are the same, *_power_state are as well */ @@ -189,11 +200,28 @@ static void radeon_set_power_state(struct radeon_device *rdev) rdev->pm.requested_clock_mode->sclk, rdev->pm.requested_clock_mode->mclk, rdev->pm.requested_power_state->non_clock_info.pcie_lanes); + /* set pcie lanes */ + /* TODO */ + /* set voltage */ + /* TODO */ + /* set engine clock */ + radeon_sync_with_vblank(rdev); + radeon_pm_debug_check_in_vbl(rdev, false); radeon_set_engine_clock(rdev, rdev->pm.requested_clock_mode->sclk); + radeon_pm_debug_check_in_vbl(rdev, true); + +#if 0 /* set memory clock */ + if (rdev->asic->set_memory_clock) { + radeon_sync_with_vblank(rdev); + radeon_pm_debug_check_in_vbl(rdev, false); + radeon_set_memory_clock(rdev, rdev->pm.requested_clock_mode->mclk); + radeon_pm_debug_check_in_vbl(rdev, true); + } +#endif rdev->pm.current_power_state = rdev->pm.requested_power_state; rdev->pm.current_clock_mode = rdev->pm.requested_clock_mode; @@ -333,10 +361,7 @@ static void radeon_pm_set_clocks_locked(struct radeon_device *rdev) break; } - /* check if we are in vblank */ - radeon_pm_debug_check_in_vbl(rdev, false); radeon_set_power_state(rdev); - radeon_pm_debug_check_in_vbl(rdev, true); rdev->pm.planned_action = PM_ACTION_NONE; } @@ -353,12 +378,7 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev) rdev->pm.req_vblank |= (1 << 1); drm_vblank_get(rdev->ddev, 1); } - if (rdev->pm.active_crtcs) { - rdev->pm.vblank_sync = false; - wait_event_timeout( - rdev->irq.vblank_queue, rdev->pm.vblank_sync, - msecs_to_jiffies(RADEON_WAIT_VBLANK_TIMEOUT)); - } + radeon_pm_set_clocks_locked(rdev); if (rdev->pm.req_vblank & (1 << 0)) { rdev->pm.req_vblank &= ~(1 << 0); drm_vblank_put(rdev->ddev, 0); @@ -368,7 +388,6 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev) drm_vblank_put(rdev->ddev, 1); } - radeon_pm_set_clocks_locked(rdev); mutex_unlock(&rdev->cp.mutex); } -- cgit v0.10.2 From 72e942dd846f98e2d35aad5436d77a878ef05c5e Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 9 Mar 2010 06:33:26 +0000 Subject: drm/ttm: use drm calloc large and free large Now that the drm core can do this, lets just use it, split the code out so TTM doesn't have to drag all of drmP.h in. Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c index a759170..bab6cd8 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c @@ -28,13 +28,13 @@ * Authors: Thomas Hellstrom */ -#include #include #include #include #include #include #include "drm_cache.h" +#include "drm_mem_util.h" #include "ttm/ttm_module.h" #include "ttm/ttm_bo_driver.h" #include "ttm/ttm_placement.h" @@ -43,32 +43,15 @@ static int ttm_tt_swapin(struct ttm_tt *ttm); /** * Allocates storage for pointers to the pages that back the ttm. - * - * Uses kmalloc if possible. Otherwise falls back to vmalloc. */ static void ttm_tt_alloc_page_directory(struct ttm_tt *ttm) { - unsigned long size = ttm->num_pages * sizeof(*ttm->pages); - ttm->pages = NULL; - - if (size <= PAGE_SIZE) - ttm->pages = kzalloc(size, GFP_KERNEL); - - if (!ttm->pages) { - ttm->pages = vmalloc_user(size); - if (ttm->pages) - ttm->page_flags |= TTM_PAGE_FLAG_VMALLOC; - } + ttm->pages = drm_calloc_large(ttm->num_pages, sizeof(*ttm->pages)); } static void ttm_tt_free_page_directory(struct ttm_tt *ttm) { - if (ttm->page_flags & TTM_PAGE_FLAG_VMALLOC) { - vfree(ttm->pages); - ttm->page_flags &= ~TTM_PAGE_FLAG_VMALLOC; - } else { - kfree(ttm->pages); - } + drm_free_large(ttm->pages); ttm->pages = NULL; } diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 4a3c4e4..de2f82e 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -1545,39 +1545,7 @@ static __inline__ void drm_core_dropmap(struct drm_local_map *map) { } - -static __inline__ void *drm_calloc_large(size_t nmemb, size_t size) -{ - if (size != 0 && nmemb > ULONG_MAX / size) - return NULL; - - if (size * nmemb <= PAGE_SIZE) - return kcalloc(nmemb, size, GFP_KERNEL); - - return __vmalloc(size * nmemb, - GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL); -} - -/* Modeled after cairo's malloc_ab, it's like calloc but without the zeroing. */ -static __inline__ void *drm_malloc_ab(size_t nmemb, size_t size) -{ - if (size != 0 && nmemb > ULONG_MAX / size) - return NULL; - - if (size * nmemb <= PAGE_SIZE) - return kmalloc(nmemb * size, GFP_KERNEL); - - return __vmalloc(size * nmemb, - GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL); -} - -static __inline void drm_free_large(void *ptr) -{ - if (!is_vmalloc_addr(ptr)) - return kfree(ptr); - - vfree(ptr); -} +#include "drm_mem_util.h" /*@}*/ #endif /* __KERNEL__ */ diff --git a/include/drm/drm_mem_util.h b/include/drm/drm_mem_util.h new file mode 100644 index 0000000..6bd325f --- /dev/null +++ b/include/drm/drm_mem_util.h @@ -0,0 +1,65 @@ +/* + * Copyright © 2008 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Jesse Barnes + * + */ +#ifndef _DRM_MEM_UTIL_H_ +#define _DRM_MEM_UTIL_H_ + +#include + +static __inline__ void *drm_calloc_large(size_t nmemb, size_t size) +{ + if (size != 0 && nmemb > ULONG_MAX / size) + return NULL; + + if (size * nmemb <= PAGE_SIZE) + return kcalloc(nmemb, size, GFP_KERNEL); + + return __vmalloc(size * nmemb, + GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL); +} + +/* Modeled after cairo's malloc_ab, it's like calloc but without the zeroing. */ +static __inline__ void *drm_malloc_ab(size_t nmemb, size_t size) +{ + if (size != 0 && nmemb > ULONG_MAX / size) + return NULL; + + if (size * nmemb <= PAGE_SIZE) + return kmalloc(nmemb * size, GFP_KERNEL); + + return __vmalloc(size * nmemb, + GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL); +} + +static __inline void drm_free_large(void *ptr) +{ + if (!is_vmalloc_addr(ptr)) + return kfree(ptr); + + vfree(ptr); +} + +#endif diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h index e3f1b4a..e929c27 100644 --- a/include/drm/ttm/ttm_bo_driver.h +++ b/include/drm/ttm/ttm_bo_driver.h @@ -115,7 +115,6 @@ struct ttm_backend { struct ttm_backend_func *func; }; -#define TTM_PAGE_FLAG_VMALLOC (1 << 0) #define TTM_PAGE_FLAG_USER (1 << 1) #define TTM_PAGE_FLAG_USER_DIRTY (1 << 2) #define TTM_PAGE_FLAG_WRITE (1 << 3) -- cgit v0.10.2 From b642ed06f2fccf62534f5269358776e0cba28f3c Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Sat, 13 Mar 2010 10:36:32 +0000 Subject: drm: "kobject_init/kobject_add" -> "kobject_init_and_add". Replace sequential calls to kobject_init() and kobject_add() with the combo wrapper kobject_init_and_add(), which provides the same semantics. Signed-off-by: Robert P. J. Day Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index c7320ce..9db02bb 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -1425,8 +1425,8 @@ int ttm_bo_global_init(struct ttm_global_reference *ref) atomic_set(&glob->bo_count, 0); - kobject_init(&glob->kobj, &ttm_bo_glob_kobj_type); - ret = kobject_add(&glob->kobj, ttm_get_kobj(), "buffer_objects"); + ret = kobject_init_and_add( + &glob->kobj, &ttm_bo_glob_kobj_type, ttm_get_kobj(), "buffer_objects"); if (unlikely(ret != 0)) kobject_put(&glob->kobj); return ret; diff --git a/drivers/gpu/drm/ttm/ttm_memory.c b/drivers/gpu/drm/ttm/ttm_memory.c index f5245c0..f9d6b35 100644 --- a/drivers/gpu/drm/ttm/ttm_memory.c +++ b/drivers/gpu/drm/ttm/ttm_memory.c @@ -260,8 +260,8 @@ static int ttm_mem_init_kernel_zone(struct ttm_mem_global *glob, zone->used_mem = 0; zone->glob = glob; glob->zone_kernel = zone; - kobject_init(&zone->kobj, &ttm_mem_zone_kobj_type); - ret = kobject_add(&zone->kobj, &glob->kobj, zone->name); + ret = kobject_init_and_add( + &zone->kobj, &ttm_mem_zone_kobj_type, &glob->kobj, zone->name); if (unlikely(ret != 0)) { kobject_put(&zone->kobj); return ret; @@ -296,8 +296,8 @@ static int ttm_mem_init_highmem_zone(struct ttm_mem_global *glob, zone->used_mem = 0; zone->glob = glob; glob->zone_highmem = zone; - kobject_init(&zone->kobj, &ttm_mem_zone_kobj_type); - ret = kobject_add(&zone->kobj, &glob->kobj, zone->name); + ret = kobject_init_and_add( + &zone->kobj, &ttm_mem_zone_kobj_type, &glob->kobj, zone->name); if (unlikely(ret != 0)) { kobject_put(&zone->kobj); return ret; @@ -343,8 +343,8 @@ static int ttm_mem_init_dma32_zone(struct ttm_mem_global *glob, zone->used_mem = 0; zone->glob = glob; glob->zone_dma32 = zone; - kobject_init(&zone->kobj, &ttm_mem_zone_kobj_type); - ret = kobject_add(&zone->kobj, &glob->kobj, zone->name); + ret = kobject_init_and_add( + &zone->kobj, &ttm_mem_zone_kobj_type, &glob->kobj, zone->name); if (unlikely(ret != 0)) { kobject_put(&zone->kobj); return ret; @@ -365,10 +365,8 @@ int ttm_mem_global_init(struct ttm_mem_global *glob) glob->swap_queue = create_singlethread_workqueue("ttm_swap"); INIT_WORK(&glob->work, ttm_shrink_work); init_waitqueue_head(&glob->queue); - kobject_init(&glob->kobj, &ttm_mem_glob_kobj_type); - ret = kobject_add(&glob->kobj, - ttm_get_kobj(), - "memory_accounting"); + ret = kobject_init_and_add( + &glob->kobj, &ttm_mem_glob_kobj_type, ttm_get_kobj(), "memory_accounting"); if (unlikely(ret != 0)) { kobject_put(&glob->kobj); return ret; -- cgit v0.10.2 From ae6445ac7475ff0526b019560793e50bad9cf78d Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 11 Mar 2010 22:01:39 +0000 Subject: drm/vmwgfx: depends on FB vmwfgx uses framebuffer interfaces, so it should depend on FB. Otherwise it has these build errors (e.g., when CONFIG_FB=m): drivers/built-in.o: In function `vmw_fb_close': (.text+0x97713): undefined reference to `unregister_framebuffer' drivers/built-in.o: In function `vmw_fb_close': (.text+0x97754): undefined reference to `framebuffer_release' drivers/built-in.o: In function `vmw_fb_init': (.text+0x97e1c): undefined reference to `framebuffer_alloc' drivers/built-in.o: In function `vmw_fb_init': (.text+0x9838d): undefined reference to `register_framebuffer' drivers/built-in.o: In function `vmw_fb_init': (.text+0x9842a): undefined reference to `framebuffer_release' Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Acked-by: Jakob Bornecrantz Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/vmwgfx/Kconfig b/drivers/gpu/drm/vmwgfx/Kconfig index f20b8bc..30ad133 100644 --- a/drivers/gpu/drm/vmwgfx/Kconfig +++ b/drivers/gpu/drm/vmwgfx/Kconfig @@ -1,6 +1,6 @@ config DRM_VMWGFX tristate "DRM driver for VMware Virtual GPU" - depends on DRM && PCI + depends on DRM && PCI && FB select FB_DEFERRED_IO select FB_CFB_FILLRECT select FB_CFB_COPYAREA -- cgit v0.10.2 From 725398322d05486109375fbb85c3404108881e17 Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Thu, 4 Mar 2010 08:25:55 +0000 Subject: drm: remove the EDID blob stored in the EDID property when it is disconnected Now the EDID property will be updated when the corresponding EDID can be obtained from the external display device. But after the external device is plugged-out, the EDID property is not updated. In such case we still get the corresponding EDID property although it is already detected as disconnected. https://bugs.freedesktop.org/show_bug.cgi?id=26743 Signed-off-by: Zhao Yakui Signed-off-by: Zhenyu Wang Cc: stable@kernel.org Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index f2aaf39..51103aa 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -104,6 +104,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, if (connector->status == connector_status_disconnected) { DRM_DEBUG_KMS("%s is disconnected\n", drm_get_connector_name(connector)); + drm_mode_connector_update_edid_property(connector, NULL); goto prune; } -- cgit v0.10.2 From 8144c880397d502d12af4ef721f3eac50163fa39 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Thu, 18 Feb 2010 23:42:47 -0500 Subject: ACPI: remove "acpi=ht" DMI blacklist SuSE added these entries when deploying ACPI in Linux-2.4. I pulled them into Linux-2.6 on 2003-08-09. Over the last 6+ years, several entries have proven to be unnecessary and deleted, while no new entries have been added. Matthew suggests that they now have negative value, and I agree. Based-on-patch-by: Matthew Garrett Signed-off-by: Len Brown diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index a54d714..df586bb 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -1293,23 +1293,6 @@ static int __init dmi_disable_acpi(const struct dmi_system_id *d) } /* - * Limit ACPI to CPU enumeration for HT - */ -static int __init force_acpi_ht(const struct dmi_system_id *d) -{ - if (!acpi_force) { - printk(KERN_NOTICE "%s detected: force use of acpi=ht\n", - d->ident); - disable_acpi(); - acpi_ht = 1; - } else { - printk(KERN_NOTICE - "Warning: acpi=force overrules DMI blacklist: acpi=ht\n"); - } - return 0; -} - -/* * Force ignoring BIOS IRQ0 pin2 override */ static int __init dmi_ignore_irq0_timer_override(const struct dmi_system_id *d) @@ -1345,82 +1328,6 @@ static struct dmi_system_id __initdata acpi_dmi_table[] = { }, /* - * Boxes that need acpi=ht - */ - { - .callback = force_acpi_ht, - .ident = "FSC Primergy T850", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), - DMI_MATCH(DMI_PRODUCT_NAME, "PRIMERGY T850"), - }, - }, - { - .callback = force_acpi_ht, - .ident = "HP VISUALIZE NT Workstation", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP VISUALIZE NT Workstation"), - }, - }, - { - .callback = force_acpi_ht, - .ident = "Compaq Workstation W8000", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), - DMI_MATCH(DMI_PRODUCT_NAME, "Workstation W8000"), - }, - }, - { - .callback = force_acpi_ht, - .ident = "ASUS CUR-DLS", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), - DMI_MATCH(DMI_BOARD_NAME, "CUR-DLS"), - }, - }, - { - .callback = force_acpi_ht, - .ident = "ABIT i440BX-W83977", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "ABIT "), - DMI_MATCH(DMI_BOARD_NAME, "i440BX-W83977 (BP6)"), - }, - }, - { - .callback = force_acpi_ht, - .ident = "IBM Bladecenter", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), - DMI_MATCH(DMI_BOARD_NAME, "IBM eServer BladeCenter HS20"), - }, - }, - { - .callback = force_acpi_ht, - .ident = "IBM eServer xSeries 360", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), - DMI_MATCH(DMI_BOARD_NAME, "eServer xSeries 360"), - }, - }, - { - .callback = force_acpi_ht, - .ident = "IBM eserver xSeries 330", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), - DMI_MATCH(DMI_BOARD_NAME, "eserver xSeries 330"), - }, - }, - { - .callback = force_acpi_ht, - .ident = "IBM eserver xSeries 440", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), - DMI_MATCH(DMI_PRODUCT_NAME, "eserver xSeries 440"), - }, - }, - - /* * Boxes that need ACPI PCI IRQ routing disabled */ { -- cgit v0.10.2 From 44fef22416886a04d432043f741a6faf2c6ffefd Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 18 Feb 2010 09:12:09 +1000 Subject: drm/edid: allow certain bogus edids to hit a fixup path rather than fail Signed-off-by: Ben Skeggs Cc: stable@kernel.org Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index f97e7c4..7e608f4 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -707,15 +707,6 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, mode->vsync_end = mode->vsync_start + vsync_pulse_width; mode->vtotal = mode->vdisplay + vblank; - /* perform the basic check for the detailed timing */ - if (mode->hsync_end > mode->htotal || - mode->vsync_end > mode->vtotal) { - drm_mode_destroy(dev, mode); - DRM_DEBUG_KMS("Incorrect detailed timing. " - "Sync is beyond the blank.\n"); - return NULL; - } - /* Some EDIDs have bogus h/vtotal values */ if (mode->hsync_end > mode->htotal) mode->htotal = mode->hsync_end + 1; -- cgit v0.10.2 From 4c81ba4900ab4eb24c7d2ba1aca594c644b6ce4c Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sun, 14 Mar 2010 16:28:46 -0400 Subject: ACPI: plan to delete "acpi=ht" boot option Signed-off-by: Len Brown diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index a5cc0db..ed511af 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -582,3 +582,10 @@ Why: The paravirt mmu host support is slower than non-paravirt mmu, both Who: Avi Kivity ---------------------------- + +What: "acpi=ht" boot option +When: 2.6.35 +Why: Useful in 2003, implementation is a hack. + Generally invoked by accident today. + Seen as doing more harm than good. +Who: Len Brown diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index df586bb..7914ab0 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -1559,8 +1559,10 @@ static int __init parse_acpi(char *arg) } /* Limit ACPI just to boot-time to enable HT */ else if (strcmp(arg, "ht") == 0) { - if (!acpi_force) + if (!acpi_force) { + printk(KERN_WARNING "acpi=ht will be removed in Linux-2.6.35\n"); disable_acpi(); + } acpi_ht = 1; } /* acpi=rsdt use RSDT instead of XSDT */ -- cgit v0.10.2 From 0131aa3dd7dcf41c66784b96ff351f63ee3ef348 Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Mon, 22 Feb 2010 12:11:08 -0700 Subject: ACPI: processor: mv processor_core.c processor_driver.c The ACPI processor driver can be built as a module. But it has pieces of code that should always be built statically into the kernel. The plan is for processor_core.c to contain the static bits while processor_driver.c contains the module-like bits. Since the bulk of the code in the current processor_core.c is module-like, first step is to rename the file to processor_driver.c Next step will re-create processor_core.c and cherry-pick out the static bits. Acked-by: Venkatesh Pallipadi Signed-off-by: Alex Chiang Signed-off-by: Len Brown diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 66cc3f3..6b363a5 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -61,7 +61,7 @@ obj-$(CONFIG_ACPI_SBS) += sbs.o obj-$(CONFIG_ACPI_POWER_METER) += power_meter.o # processor has its own "processor." module_param namespace -processor-y := processor_core.o processor_throttling.o +processor-y := processor_driver.o processor_throttling.o processor-y += processor_idle.o processor_thermal.o processor-$(CONFIG_CPU_FREQ) += processor_perflib.o diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c deleted file mode 100644 index e9b7b40..0000000 --- a/drivers/acpi/processor_core.c +++ /dev/null @@ -1,1142 +0,0 @@ -/* - * acpi_processor.c - ACPI Processor Driver ($Revision: 71 $) - * - * Copyright (C) 2001, 2002 Andy Grover - * Copyright (C) 2001, 2002 Paul Diefenbaugh - * Copyright (C) 2004 Dominik Brodowski - * Copyright (C) 2004 Anil S Keshavamurthy - * - Added processor hotplug support - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * 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. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * TBD: - * 1. Make # power states dynamic. - * 2. Support duty_cycle values that span bit 4. - * 3. Optimize by having scheduler determine business instead of - * having us try to calculate it here. - * 4. Need C1 timing -- must modify kernel (IRQ handler) to get this. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#define PREFIX "ACPI: " - -#define ACPI_PROCESSOR_CLASS "processor" -#define ACPI_PROCESSOR_DEVICE_NAME "Processor" -#define ACPI_PROCESSOR_FILE_INFO "info" -#define ACPI_PROCESSOR_FILE_THROTTLING "throttling" -#define ACPI_PROCESSOR_FILE_LIMIT "limit" -#define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80 -#define ACPI_PROCESSOR_NOTIFY_POWER 0x81 -#define ACPI_PROCESSOR_NOTIFY_THROTTLING 0x82 - -#define ACPI_PROCESSOR_LIMIT_USER 0 -#define ACPI_PROCESSOR_LIMIT_THERMAL 1 - -#define _COMPONENT ACPI_PROCESSOR_COMPONENT -ACPI_MODULE_NAME("processor_core"); - -MODULE_AUTHOR("Paul Diefenbaugh"); -MODULE_DESCRIPTION("ACPI Processor Driver"); -MODULE_LICENSE("GPL"); - -static int acpi_processor_add(struct acpi_device *device); -static int acpi_processor_remove(struct acpi_device *device, int type); -#ifdef CONFIG_ACPI_PROCFS -static int acpi_processor_info_open_fs(struct inode *inode, struct file *file); -#endif -static void acpi_processor_notify(struct acpi_device *device, u32 event); -static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu); -static int acpi_processor_handle_eject(struct acpi_processor *pr); - - -static const struct acpi_device_id processor_device_ids[] = { - {ACPI_PROCESSOR_OBJECT_HID, 0}, - {"ACPI0007", 0}, - {"", 0}, -}; -MODULE_DEVICE_TABLE(acpi, processor_device_ids); - -static struct acpi_driver acpi_processor_driver = { - .name = "processor", - .class = ACPI_PROCESSOR_CLASS, - .ids = processor_device_ids, - .ops = { - .add = acpi_processor_add, - .remove = acpi_processor_remove, - .suspend = acpi_processor_suspend, - .resume = acpi_processor_resume, - .notify = acpi_processor_notify, - }, -}; - -#define INSTALL_NOTIFY_HANDLER 1 -#define UNINSTALL_NOTIFY_HANDLER 2 -#ifdef CONFIG_ACPI_PROCFS -static const struct file_operations acpi_processor_info_fops = { - .owner = THIS_MODULE, - .open = acpi_processor_info_open_fs, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; -#endif - -DEFINE_PER_CPU(struct acpi_processor *, processors); -EXPORT_PER_CPU_SYMBOL(processors); - -struct acpi_processor_errata errata __read_mostly; - -/* -------------------------------------------------------------------------- - Errata Handling - -------------------------------------------------------------------------- */ - -static int acpi_processor_errata_piix4(struct pci_dev *dev) -{ - u8 value1 = 0; - u8 value2 = 0; - - - if (!dev) - return -EINVAL; - - /* - * Note that 'dev' references the PIIX4 ACPI Controller. - */ - - switch (dev->revision) { - case 0: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 A-step\n")); - break; - case 1: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 B-step\n")); - break; - case 2: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4E\n")); - break; - case 3: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4M\n")); - break; - default: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found unknown PIIX4\n")); - break; - } - - switch (dev->revision) { - - case 0: /* PIIX4 A-step */ - case 1: /* PIIX4 B-step */ - /* - * See specification changes #13 ("Manual Throttle Duty Cycle") - * and #14 ("Enabling and Disabling Manual Throttle"), plus - * erratum #5 ("STPCLK# Deassertion Time") from the January - * 2002 PIIX4 specification update. Applies to only older - * PIIX4 models. - */ - errata.piix4.throttle = 1; - - case 2: /* PIIX4E */ - case 3: /* PIIX4M */ - /* - * See erratum #18 ("C3 Power State/BMIDE and Type-F DMA - * Livelock") from the January 2002 PIIX4 specification update. - * Applies to all PIIX4 models. - */ - - /* - * BM-IDE - * ------ - * Find the PIIX4 IDE Controller and get the Bus Master IDE - * Status register address. We'll use this later to read - * each IDE controller's DMA status to make sure we catch all - * DMA activity. - */ - dev = pci_get_subsys(PCI_VENDOR_ID_INTEL, - PCI_DEVICE_ID_INTEL_82371AB, - PCI_ANY_ID, PCI_ANY_ID, NULL); - if (dev) { - errata.piix4.bmisx = pci_resource_start(dev, 4); - pci_dev_put(dev); - } - - /* - * Type-F DMA - * ---------- - * Find the PIIX4 ISA Controller and read the Motherboard - * DMA controller's status to see if Type-F (Fast) DMA mode - * is enabled (bit 7) on either channel. Note that we'll - * disable C3 support if this is enabled, as some legacy - * devices won't operate well if fast DMA is disabled. - */ - dev = pci_get_subsys(PCI_VENDOR_ID_INTEL, - PCI_DEVICE_ID_INTEL_82371AB_0, - PCI_ANY_ID, PCI_ANY_ID, NULL); - if (dev) { - pci_read_config_byte(dev, 0x76, &value1); - pci_read_config_byte(dev, 0x77, &value2); - if ((value1 & 0x80) || (value2 & 0x80)) - errata.piix4.fdma = 1; - pci_dev_put(dev); - } - - break; - } - - if (errata.piix4.bmisx) - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Bus master activity detection (BM-IDE) erratum enabled\n")); - if (errata.piix4.fdma) - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Type-F DMA livelock erratum (C3 disabled)\n")); - - return 0; -} - -static int acpi_processor_errata(struct acpi_processor *pr) -{ - int result = 0; - struct pci_dev *dev = NULL; - - - if (!pr) - return -EINVAL; - - /* - * PIIX4 - */ - dev = pci_get_subsys(PCI_VENDOR_ID_INTEL, - PCI_DEVICE_ID_INTEL_82371AB_3, PCI_ANY_ID, - PCI_ANY_ID, NULL); - if (dev) { - result = acpi_processor_errata_piix4(dev); - pci_dev_put(dev); - } - - return result; -} - -/* -------------------------------------------------------------------------- - FS Interface (/proc) - -------------------------------------------------------------------------- */ - -#ifdef CONFIG_ACPI_PROCFS -static struct proc_dir_entry *acpi_processor_dir = NULL; - -static int acpi_processor_info_seq_show(struct seq_file *seq, void *offset) -{ - struct acpi_processor *pr = seq->private; - - - if (!pr) - goto end; - - seq_printf(seq, "processor id: %d\n" - "acpi id: %d\n" - "bus mastering control: %s\n" - "power management: %s\n" - "throttling control: %s\n" - "limit interface: %s\n", - pr->id, - pr->acpi_id, - pr->flags.bm_control ? "yes" : "no", - pr->flags.power ? "yes" : "no", - pr->flags.throttling ? "yes" : "no", - pr->flags.limit ? "yes" : "no"); - - end: - return 0; -} - -static int acpi_processor_info_open_fs(struct inode *inode, struct file *file) -{ - return single_open(file, acpi_processor_info_seq_show, - PDE(inode)->data); -} - -static int __cpuinit acpi_processor_add_fs(struct acpi_device *device) -{ - struct proc_dir_entry *entry = NULL; - - - if (!acpi_device_dir(device)) { - acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), - acpi_processor_dir); - if (!acpi_device_dir(device)) - return -ENODEV; - } - - /* 'info' [R] */ - entry = proc_create_data(ACPI_PROCESSOR_FILE_INFO, - S_IRUGO, acpi_device_dir(device), - &acpi_processor_info_fops, - acpi_driver_data(device)); - if (!entry) - return -EIO; - - /* 'throttling' [R/W] */ - entry = proc_create_data(ACPI_PROCESSOR_FILE_THROTTLING, - S_IFREG | S_IRUGO | S_IWUSR, - acpi_device_dir(device), - &acpi_processor_throttling_fops, - acpi_driver_data(device)); - if (!entry) - return -EIO; - - /* 'limit' [R/W] */ - entry = proc_create_data(ACPI_PROCESSOR_FILE_LIMIT, - S_IFREG | S_IRUGO | S_IWUSR, - acpi_device_dir(device), - &acpi_processor_limit_fops, - acpi_driver_data(device)); - if (!entry) - return -EIO; - return 0; -} -static int acpi_processor_remove_fs(struct acpi_device *device) -{ - - if (acpi_device_dir(device)) { - remove_proc_entry(ACPI_PROCESSOR_FILE_INFO, - acpi_device_dir(device)); - remove_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING, - acpi_device_dir(device)); - remove_proc_entry(ACPI_PROCESSOR_FILE_LIMIT, - acpi_device_dir(device)); - remove_proc_entry(acpi_device_bid(device), acpi_processor_dir); - acpi_device_dir(device) = NULL; - } - - return 0; -} -#else -static inline int acpi_processor_add_fs(struct acpi_device *device) -{ - return 0; -} -static inline int acpi_processor_remove_fs(struct acpi_device *device) -{ - return 0; -} -#endif - -/* Use the acpiid in MADT to map cpus in case of SMP */ - -#ifndef CONFIG_SMP -static int get_cpu_id(acpi_handle handle, int type, u32 acpi_id) { return -1; } -#else - -static struct acpi_table_madt *madt; - -static int map_lapic_id(struct acpi_subtable_header *entry, - u32 acpi_id, int *apic_id) -{ - struct acpi_madt_local_apic *lapic = - (struct acpi_madt_local_apic *)entry; - if ((lapic->lapic_flags & ACPI_MADT_ENABLED) && - lapic->processor_id == acpi_id) { - *apic_id = lapic->id; - return 1; - } - return 0; -} - -static int map_x2apic_id(struct acpi_subtable_header *entry, - int device_declaration, u32 acpi_id, int *apic_id) -{ - struct acpi_madt_local_x2apic *apic = - (struct acpi_madt_local_x2apic *)entry; - u32 tmp = apic->local_apic_id; - - /* Only check enabled APICs*/ - if (!(apic->lapic_flags & ACPI_MADT_ENABLED)) - return 0; - - /* Device statement declaration type */ - if (device_declaration) { - if (apic->uid == acpi_id) - goto found; - } - - return 0; -found: - *apic_id = tmp; - return 1; -} - -static int map_lsapic_id(struct acpi_subtable_header *entry, - int device_declaration, u32 acpi_id, int *apic_id) -{ - struct acpi_madt_local_sapic *lsapic = - (struct acpi_madt_local_sapic *)entry; - u32 tmp = (lsapic->id << 8) | lsapic->eid; - - /* Only check enabled APICs*/ - if (!(lsapic->lapic_flags & ACPI_MADT_ENABLED)) - return 0; - - /* Device statement declaration type */ - if (device_declaration) { - if (entry->length < 16) - printk(KERN_ERR PREFIX - "Invalid LSAPIC with Device type processor (SAPIC ID %#x)\n", - tmp); - else if (lsapic->uid == acpi_id) - goto found; - /* Processor statement declaration type */ - } else if (lsapic->processor_id == acpi_id) - goto found; - - return 0; -found: - *apic_id = tmp; - return 1; -} - -static int map_madt_entry(int type, u32 acpi_id) -{ - unsigned long madt_end, entry; - int apic_id = -1; - - if (!madt) - return apic_id; - - entry = (unsigned long)madt; - madt_end = entry + madt->header.length; - - /* Parse all entries looking for a match. */ - - entry += sizeof(struct acpi_table_madt); - while (entry + sizeof(struct acpi_subtable_header) < madt_end) { - struct acpi_subtable_header *header = - (struct acpi_subtable_header *)entry; - if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) { - if (map_lapic_id(header, acpi_id, &apic_id)) - break; - } else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) { - if (map_x2apic_id(header, type, acpi_id, &apic_id)) - break; - } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { - if (map_lsapic_id(header, type, acpi_id, &apic_id)) - break; - } - entry += header->length; - } - return apic_id; -} - -static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id) -{ - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - union acpi_object *obj; - struct acpi_subtable_header *header; - int apic_id = -1; - - if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer))) - goto exit; - - if (!buffer.length || !buffer.pointer) - goto exit; - - obj = buffer.pointer; - if (obj->type != ACPI_TYPE_BUFFER || - obj->buffer.length < sizeof(struct acpi_subtable_header)) { - goto exit; - } - - header = (struct acpi_subtable_header *)obj->buffer.pointer; - if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) { - map_lapic_id(header, acpi_id, &apic_id); - } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { - map_lsapic_id(header, type, acpi_id, &apic_id); - } - -exit: - if (buffer.pointer) - kfree(buffer.pointer); - return apic_id; -} - -static int get_cpu_id(acpi_handle handle, int type, u32 acpi_id) -{ - int i; - int apic_id = -1; - - apic_id = map_mat_entry(handle, type, acpi_id); - if (apic_id == -1) - apic_id = map_madt_entry(type, acpi_id); - if (apic_id == -1) - return apic_id; - - for_each_possible_cpu(i) { - if (cpu_physical_id(i) == apic_id) - return i; - } - return -1; -} -#endif - -/* -------------------------------------------------------------------------- - Driver Interface - -------------------------------------------------------------------------- */ - -static int acpi_processor_get_info(struct acpi_device *device) -{ - acpi_status status = 0; - union acpi_object object = { 0 }; - struct acpi_buffer buffer = { sizeof(union acpi_object), &object }; - struct acpi_processor *pr; - int cpu_index, device_declaration = 0; - static int cpu0_initialized; - - pr = acpi_driver_data(device); - if (!pr) - return -EINVAL; - - if (num_online_cpus() > 1) - errata.smp = TRUE; - - acpi_processor_errata(pr); - - /* - * Check to see if we have bus mastering arbitration control. This - * is required for proper C3 usage (to maintain cache coherency). - */ - if (acpi_gbl_FADT.pm2_control_block && acpi_gbl_FADT.pm2_control_length) { - pr->flags.bm_control = 1; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Bus mastering arbitration control present\n")); - } else - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "No bus mastering arbitration control\n")); - - if (!strcmp(acpi_device_hid(device), ACPI_PROCESSOR_OBJECT_HID)) { - /* Declared with "Processor" statement; match ProcessorID */ - status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer); - if (ACPI_FAILURE(status)) { - printk(KERN_ERR PREFIX "Evaluating processor object\n"); - return -ENODEV; - } - - /* - * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP. - * >>> 'acpi_get_processor_id(acpi_id, &id)' in - * arch/xxx/acpi.c - */ - pr->acpi_id = object.processor.proc_id; - } else { - /* - * Declared with "Device" statement; match _UID. - * Note that we don't handle string _UIDs yet. - */ - unsigned long long value; - status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID, - NULL, &value); - if (ACPI_FAILURE(status)) { - printk(KERN_ERR PREFIX - "Evaluating processor _UID [%#x]\n", status); - return -ENODEV; - } - device_declaration = 1; - pr->acpi_id = value; - } - cpu_index = get_cpu_id(pr->handle, device_declaration, pr->acpi_id); - - /* Handle UP system running SMP kernel, with no LAPIC in MADT */ - if (!cpu0_initialized && (cpu_index == -1) && - (num_online_cpus() == 1)) { - cpu_index = 0; - } - - cpu0_initialized = 1; - - pr->id = cpu_index; - - /* - * Extra Processor objects may be enumerated on MP systems with - * less than the max # of CPUs. They should be ignored _iff - * they are physically not present. - */ - if (pr->id == -1) { - if (ACPI_FAILURE - (acpi_processor_hotadd_init(pr->handle, &pr->id))) { - return -ENODEV; - } - } - /* - * On some boxes several processors use the same processor bus id. - * But they are located in different scope. For example: - * \_SB.SCK0.CPU0 - * \_SB.SCK1.CPU0 - * Rename the processor device bus id. And the new bus id will be - * generated as the following format: - * CPU+CPU ID. - */ - sprintf(acpi_device_bid(device), "CPU%X", pr->id); - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d:%d]\n", pr->id, - pr->acpi_id)); - - if (!object.processor.pblk_address) - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No PBLK (NULL address)\n")); - else if (object.processor.pblk_length != 6) - printk(KERN_ERR PREFIX "Invalid PBLK length [%d]\n", - object.processor.pblk_length); - else { - pr->throttling.address = object.processor.pblk_address; - pr->throttling.duty_offset = acpi_gbl_FADT.duty_offset; - pr->throttling.duty_width = acpi_gbl_FADT.duty_width; - - pr->pblk = object.processor.pblk_address; - - /* - * We don't care about error returns - we just try to mark - * these reserved so that nobody else is confused into thinking - * that this region might be unused.. - * - * (In particular, allocating the IO range for Cardbus) - */ - request_region(pr->throttling.address, 6, "ACPI CPU throttle"); - } - - /* - * If ACPI describes a slot number for this CPU, we can use it - * ensure we get the right value in the "physical id" field - * of /proc/cpuinfo - */ - status = acpi_evaluate_object(pr->handle, "_SUN", NULL, &buffer); - if (ACPI_SUCCESS(status)) - arch_fix_phys_package_id(pr->id, object.integer.value); - - return 0; -} - -static DEFINE_PER_CPU(void *, processor_device_array); - -static void acpi_processor_notify(struct acpi_device *device, u32 event) -{ - struct acpi_processor *pr = acpi_driver_data(device); - int saved; - - if (!pr) - return; - - switch (event) { - case ACPI_PROCESSOR_NOTIFY_PERFORMANCE: - saved = pr->performance_platform_limit; - acpi_processor_ppc_has_changed(pr, 1); - if (saved == pr->performance_platform_limit) - break; - acpi_bus_generate_proc_event(device, event, - pr->performance_platform_limit); - acpi_bus_generate_netlink_event(device->pnp.device_class, - dev_name(&device->dev), event, - pr->performance_platform_limit); - break; - case ACPI_PROCESSOR_NOTIFY_POWER: - acpi_processor_cst_has_changed(pr); - acpi_bus_generate_proc_event(device, event, 0); - acpi_bus_generate_netlink_event(device->pnp.device_class, - dev_name(&device->dev), event, 0); - break; - case ACPI_PROCESSOR_NOTIFY_THROTTLING: - acpi_processor_tstate_has_changed(pr); - acpi_bus_generate_proc_event(device, event, 0); - acpi_bus_generate_netlink_event(device->pnp.device_class, - dev_name(&device->dev), event, 0); - default: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Unsupported event [0x%x]\n", event)); - break; - } - - return; -} - -static int acpi_cpu_soft_notify(struct notifier_block *nfb, - unsigned long action, void *hcpu) -{ - unsigned int cpu = (unsigned long)hcpu; - struct acpi_processor *pr = per_cpu(processors, cpu); - - if (action == CPU_ONLINE && pr) { - acpi_processor_ppc_has_changed(pr, 0); - acpi_processor_cst_has_changed(pr); - acpi_processor_tstate_has_changed(pr); - } - return NOTIFY_OK; -} - -static struct notifier_block acpi_cpu_notifier = -{ - .notifier_call = acpi_cpu_soft_notify, -}; - -static int __cpuinit acpi_processor_add(struct acpi_device *device) -{ - struct acpi_processor *pr = NULL; - int result = 0; - struct sys_device *sysdev; - - pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL); - if (!pr) - return -ENOMEM; - - if (!zalloc_cpumask_var(&pr->throttling.shared_cpu_map, GFP_KERNEL)) { - kfree(pr); - return -ENOMEM; - } - - pr->handle = device->handle; - strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME); - strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS); - device->driver_data = pr; - - result = acpi_processor_get_info(device); - if (result) { - /* Processor is physically not present */ - return 0; - } - - BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0)); - - /* - * Buggy BIOS check - * ACPI id of processors can be reported wrongly by the BIOS. - * Don't trust it blindly - */ - if (per_cpu(processor_device_array, pr->id) != NULL && - per_cpu(processor_device_array, pr->id) != device) { - printk(KERN_WARNING "BIOS reported wrong ACPI id " - "for the processor\n"); - result = -ENODEV; - goto err_free_cpumask; - } - per_cpu(processor_device_array, pr->id) = device; - - per_cpu(processors, pr->id) = pr; - - result = acpi_processor_add_fs(device); - if (result) - goto err_free_cpumask; - - sysdev = get_cpu_sysdev(pr->id); - if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev")) { - result = -EFAULT; - goto err_remove_fs; - } - - /* _PDC call should be done before doing anything else (if reqd.). */ - acpi_processor_set_pdc(pr->handle); - -#ifdef CONFIG_CPU_FREQ - acpi_processor_ppc_has_changed(pr, 0); -#endif - acpi_processor_get_throttling_info(pr); - acpi_processor_get_limit_info(pr); - - - acpi_processor_power_init(pr, device); - - pr->cdev = thermal_cooling_device_register("Processor", device, - &processor_cooling_ops); - if (IS_ERR(pr->cdev)) { - result = PTR_ERR(pr->cdev); - goto err_power_exit; - } - - dev_dbg(&device->dev, "registered as cooling_device%d\n", - pr->cdev->id); - - result = sysfs_create_link(&device->dev.kobj, - &pr->cdev->device.kobj, - "thermal_cooling"); - if (result) { - printk(KERN_ERR PREFIX "Create sysfs link\n"); - goto err_thermal_unregister; - } - result = sysfs_create_link(&pr->cdev->device.kobj, - &device->dev.kobj, - "device"); - if (result) { - printk(KERN_ERR PREFIX "Create sysfs link\n"); - goto err_remove_sysfs; - } - - return 0; - -err_remove_sysfs: - sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); -err_thermal_unregister: - thermal_cooling_device_unregister(pr->cdev); -err_power_exit: - acpi_processor_power_exit(pr, device); -err_remove_fs: - acpi_processor_remove_fs(device); -err_free_cpumask: - free_cpumask_var(pr->throttling.shared_cpu_map); - - return result; -} - -static int acpi_processor_remove(struct acpi_device *device, int type) -{ - struct acpi_processor *pr = NULL; - - - if (!device || !acpi_driver_data(device)) - return -EINVAL; - - pr = acpi_driver_data(device); - - if (pr->id >= nr_cpu_ids) - goto free; - - if (type == ACPI_BUS_REMOVAL_EJECT) { - if (acpi_processor_handle_eject(pr)) - return -EINVAL; - } - - acpi_processor_power_exit(pr, device); - - sysfs_remove_link(&device->dev.kobj, "sysdev"); - - acpi_processor_remove_fs(device); - - if (pr->cdev) { - sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); - sysfs_remove_link(&pr->cdev->device.kobj, "device"); - thermal_cooling_device_unregister(pr->cdev); - pr->cdev = NULL; - } - - per_cpu(processors, pr->id) = NULL; - per_cpu(processor_device_array, pr->id) = NULL; - -free: - free_cpumask_var(pr->throttling.shared_cpu_map); - kfree(pr); - - return 0; -} - -#ifdef CONFIG_ACPI_HOTPLUG_CPU -/**************************************************************************** - * Acpi processor hotplug support * - ****************************************************************************/ - -static int is_processor_present(acpi_handle handle) -{ - acpi_status status; - unsigned long long sta = 0; - - - status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); - - if (ACPI_SUCCESS(status) && (sta & ACPI_STA_DEVICE_PRESENT)) - return 1; - - /* - * _STA is mandatory for a processor that supports hot plug - */ - if (status == AE_NOT_FOUND) - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Processor does not support hot plug\n")); - else - ACPI_EXCEPTION((AE_INFO, status, - "Processor Device is not present")); - return 0; -} - -static -int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device) -{ - acpi_handle phandle; - struct acpi_device *pdev; - - - if (acpi_get_parent(handle, &phandle)) { - return -ENODEV; - } - - if (acpi_bus_get_device(phandle, &pdev)) { - return -ENODEV; - } - - if (acpi_bus_add(device, pdev, handle, ACPI_BUS_TYPE_PROCESSOR)) { - return -ENODEV; - } - - return 0; -} - -static void __ref acpi_processor_hotplug_notify(acpi_handle handle, - u32 event, void *data) -{ - struct acpi_processor *pr; - struct acpi_device *device = NULL; - int result; - - - switch (event) { - case ACPI_NOTIFY_BUS_CHECK: - case ACPI_NOTIFY_DEVICE_CHECK: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Processor driver received %s event\n", - (event == ACPI_NOTIFY_BUS_CHECK) ? - "ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK")); - - if (!is_processor_present(handle)) - break; - - if (acpi_bus_get_device(handle, &device)) { - result = acpi_processor_device_add(handle, &device); - if (result) - printk(KERN_ERR PREFIX - "Unable to add the device\n"); - break; - } - break; - case ACPI_NOTIFY_EJECT_REQUEST: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "received ACPI_NOTIFY_EJECT_REQUEST\n")); - - if (acpi_bus_get_device(handle, &device)) { - printk(KERN_ERR PREFIX - "Device don't exist, dropping EJECT\n"); - break; - } - pr = acpi_driver_data(device); - if (!pr) { - printk(KERN_ERR PREFIX - "Driver data is NULL, dropping EJECT\n"); - return; - } - break; - default: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Unsupported event [0x%x]\n", event)); - break; - } - - return; -} - -static acpi_status -processor_walk_namespace_cb(acpi_handle handle, - u32 lvl, void *context, void **rv) -{ - acpi_status status; - int *action = context; - acpi_object_type type = 0; - - status = acpi_get_type(handle, &type); - if (ACPI_FAILURE(status)) - return (AE_OK); - - if (type != ACPI_TYPE_PROCESSOR) - return (AE_OK); - - switch (*action) { - case INSTALL_NOTIFY_HANDLER: - acpi_install_notify_handler(handle, - ACPI_SYSTEM_NOTIFY, - acpi_processor_hotplug_notify, - NULL); - break; - case UNINSTALL_NOTIFY_HANDLER: - acpi_remove_notify_handler(handle, - ACPI_SYSTEM_NOTIFY, - acpi_processor_hotplug_notify); - break; - default: - break; - } - - return (AE_OK); -} - -static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu) -{ - - if (!is_processor_present(handle)) { - return AE_ERROR; - } - - if (acpi_map_lsapic(handle, p_cpu)) - return AE_ERROR; - - if (arch_register_cpu(*p_cpu)) { - acpi_unmap_lsapic(*p_cpu); - return AE_ERROR; - } - - return AE_OK; -} - -static int acpi_processor_handle_eject(struct acpi_processor *pr) -{ - if (cpu_online(pr->id)) - cpu_down(pr->id); - - arch_unregister_cpu(pr->id); - acpi_unmap_lsapic(pr->id); - return (0); -} -#else -static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu) -{ - return AE_ERROR; -} -static int acpi_processor_handle_eject(struct acpi_processor *pr) -{ - return (-EINVAL); -} -#endif - -static -void acpi_processor_install_hotplug_notify(void) -{ -#ifdef CONFIG_ACPI_HOTPLUG_CPU - int action = INSTALL_NOTIFY_HANDLER; - acpi_walk_namespace(ACPI_TYPE_PROCESSOR, - ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, - processor_walk_namespace_cb, NULL, &action, NULL); -#endif - register_hotcpu_notifier(&acpi_cpu_notifier); -} - -static -void acpi_processor_uninstall_hotplug_notify(void) -{ -#ifdef CONFIG_ACPI_HOTPLUG_CPU - int action = UNINSTALL_NOTIFY_HANDLER; - acpi_walk_namespace(ACPI_TYPE_PROCESSOR, - ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, - processor_walk_namespace_cb, NULL, &action, NULL); -#endif - unregister_hotcpu_notifier(&acpi_cpu_notifier); -} - -/* - * We keep the driver loaded even when ACPI is not running. - * This is needed for the powernow-k8 driver, that works even without - * ACPI, but needs symbols from this driver - */ - -static int __init acpi_processor_init(void) -{ - int result = 0; - - if (acpi_disabled) - return 0; - - memset(&errata, 0, sizeof(errata)); - -#ifdef CONFIG_SMP - if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_MADT, 0, - (struct acpi_table_header **)&madt))) - madt = NULL; -#endif -#ifdef CONFIG_ACPI_PROCFS - acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir); - if (!acpi_processor_dir) - return -ENOMEM; -#endif - result = cpuidle_register_driver(&acpi_idle_driver); - if (result < 0) - goto out_proc; - - result = acpi_bus_register_driver(&acpi_processor_driver); - if (result < 0) - goto out_cpuidle; - - acpi_processor_install_hotplug_notify(); - - acpi_thermal_cpufreq_init(); - - acpi_processor_ppc_init(); - - acpi_processor_throttling_init(); - - return 0; - -out_cpuidle: - cpuidle_unregister_driver(&acpi_idle_driver); - -out_proc: -#ifdef CONFIG_ACPI_PROCFS - remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); -#endif - - return result; -} - -static void __exit acpi_processor_exit(void) -{ - if (acpi_disabled) - return; - - acpi_processor_ppc_exit(); - - acpi_thermal_cpufreq_exit(); - - acpi_processor_uninstall_hotplug_notify(); - - acpi_bus_unregister_driver(&acpi_processor_driver); - - cpuidle_unregister_driver(&acpi_idle_driver); - -#ifdef CONFIG_ACPI_PROCFS - remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); -#endif - - return; -} - -module_init(acpi_processor_init); -module_exit(acpi_processor_exit); - -EXPORT_SYMBOL(acpi_processor_set_thermal_limit); - -MODULE_ALIAS("processor"); diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c new file mode 100644 index 0000000..7b0f4c2 --- /dev/null +++ b/drivers/acpi/processor_driver.c @@ -0,0 +1,1142 @@ +/* + * acpi_processor.c - ACPI Processor Driver ($Revision: 71 $) + * + * Copyright (C) 2001, 2002 Andy Grover + * Copyright (C) 2001, 2002 Paul Diefenbaugh + * Copyright (C) 2004 Dominik Brodowski + * Copyright (C) 2004 Anil S Keshavamurthy + * - Added processor hotplug support + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * 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. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * TBD: + * 1. Make # power states dynamic. + * 2. Support duty_cycle values that span bit 4. + * 3. Optimize by having scheduler determine business instead of + * having us try to calculate it here. + * 4. Need C1 timing -- must modify kernel (IRQ handler) to get this. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define PREFIX "ACPI: " + +#define ACPI_PROCESSOR_CLASS "processor" +#define ACPI_PROCESSOR_DEVICE_NAME "Processor" +#define ACPI_PROCESSOR_FILE_INFO "info" +#define ACPI_PROCESSOR_FILE_THROTTLING "throttling" +#define ACPI_PROCESSOR_FILE_LIMIT "limit" +#define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80 +#define ACPI_PROCESSOR_NOTIFY_POWER 0x81 +#define ACPI_PROCESSOR_NOTIFY_THROTTLING 0x82 + +#define ACPI_PROCESSOR_LIMIT_USER 0 +#define ACPI_PROCESSOR_LIMIT_THERMAL 1 + +#define _COMPONENT ACPI_PROCESSOR_COMPONENT +ACPI_MODULE_NAME("processor_driver"); + +MODULE_AUTHOR("Paul Diefenbaugh"); +MODULE_DESCRIPTION("ACPI Processor Driver"); +MODULE_LICENSE("GPL"); + +static int acpi_processor_add(struct acpi_device *device); +static int acpi_processor_remove(struct acpi_device *device, int type); +#ifdef CONFIG_ACPI_PROCFS +static int acpi_processor_info_open_fs(struct inode *inode, struct file *file); +#endif +static void acpi_processor_notify(struct acpi_device *device, u32 event); +static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu); +static int acpi_processor_handle_eject(struct acpi_processor *pr); + + +static const struct acpi_device_id processor_device_ids[] = { + {ACPI_PROCESSOR_OBJECT_HID, 0}, + {"ACPI0007", 0}, + {"", 0}, +}; +MODULE_DEVICE_TABLE(acpi, processor_device_ids); + +static struct acpi_driver acpi_processor_driver = { + .name = "processor", + .class = ACPI_PROCESSOR_CLASS, + .ids = processor_device_ids, + .ops = { + .add = acpi_processor_add, + .remove = acpi_processor_remove, + .suspend = acpi_processor_suspend, + .resume = acpi_processor_resume, + .notify = acpi_processor_notify, + }, +}; + +#define INSTALL_NOTIFY_HANDLER 1 +#define UNINSTALL_NOTIFY_HANDLER 2 +#ifdef CONFIG_ACPI_PROCFS +static const struct file_operations acpi_processor_info_fops = { + .owner = THIS_MODULE, + .open = acpi_processor_info_open_fs, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; +#endif + +DEFINE_PER_CPU(struct acpi_processor *, processors); +EXPORT_PER_CPU_SYMBOL(processors); + +struct acpi_processor_errata errata __read_mostly; + +/* -------------------------------------------------------------------------- + Errata Handling + -------------------------------------------------------------------------- */ + +static int acpi_processor_errata_piix4(struct pci_dev *dev) +{ + u8 value1 = 0; + u8 value2 = 0; + + + if (!dev) + return -EINVAL; + + /* + * Note that 'dev' references the PIIX4 ACPI Controller. + */ + + switch (dev->revision) { + case 0: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 A-step\n")); + break; + case 1: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 B-step\n")); + break; + case 2: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4E\n")); + break; + case 3: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4M\n")); + break; + default: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found unknown PIIX4\n")); + break; + } + + switch (dev->revision) { + + case 0: /* PIIX4 A-step */ + case 1: /* PIIX4 B-step */ + /* + * See specification changes #13 ("Manual Throttle Duty Cycle") + * and #14 ("Enabling and Disabling Manual Throttle"), plus + * erratum #5 ("STPCLK# Deassertion Time") from the January + * 2002 PIIX4 specification update. Applies to only older + * PIIX4 models. + */ + errata.piix4.throttle = 1; + + case 2: /* PIIX4E */ + case 3: /* PIIX4M */ + /* + * See erratum #18 ("C3 Power State/BMIDE and Type-F DMA + * Livelock") from the January 2002 PIIX4 specification update. + * Applies to all PIIX4 models. + */ + + /* + * BM-IDE + * ------ + * Find the PIIX4 IDE Controller and get the Bus Master IDE + * Status register address. We'll use this later to read + * each IDE controller's DMA status to make sure we catch all + * DMA activity. + */ + dev = pci_get_subsys(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_82371AB, + PCI_ANY_ID, PCI_ANY_ID, NULL); + if (dev) { + errata.piix4.bmisx = pci_resource_start(dev, 4); + pci_dev_put(dev); + } + + /* + * Type-F DMA + * ---------- + * Find the PIIX4 ISA Controller and read the Motherboard + * DMA controller's status to see if Type-F (Fast) DMA mode + * is enabled (bit 7) on either channel. Note that we'll + * disable C3 support if this is enabled, as some legacy + * devices won't operate well if fast DMA is disabled. + */ + dev = pci_get_subsys(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_82371AB_0, + PCI_ANY_ID, PCI_ANY_ID, NULL); + if (dev) { + pci_read_config_byte(dev, 0x76, &value1); + pci_read_config_byte(dev, 0x77, &value2); + if ((value1 & 0x80) || (value2 & 0x80)) + errata.piix4.fdma = 1; + pci_dev_put(dev); + } + + break; + } + + if (errata.piix4.bmisx) + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Bus master activity detection (BM-IDE) erratum enabled\n")); + if (errata.piix4.fdma) + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Type-F DMA livelock erratum (C3 disabled)\n")); + + return 0; +} + +static int acpi_processor_errata(struct acpi_processor *pr) +{ + int result = 0; + struct pci_dev *dev = NULL; + + + if (!pr) + return -EINVAL; + + /* + * PIIX4 + */ + dev = pci_get_subsys(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_82371AB_3, PCI_ANY_ID, + PCI_ANY_ID, NULL); + if (dev) { + result = acpi_processor_errata_piix4(dev); + pci_dev_put(dev); + } + + return result; +} + +/* -------------------------------------------------------------------------- + FS Interface (/proc) + -------------------------------------------------------------------------- */ + +#ifdef CONFIG_ACPI_PROCFS +static struct proc_dir_entry *acpi_processor_dir = NULL; + +static int acpi_processor_info_seq_show(struct seq_file *seq, void *offset) +{ + struct acpi_processor *pr = seq->private; + + + if (!pr) + goto end; + + seq_printf(seq, "processor id: %d\n" + "acpi id: %d\n" + "bus mastering control: %s\n" + "power management: %s\n" + "throttling control: %s\n" + "limit interface: %s\n", + pr->id, + pr->acpi_id, + pr->flags.bm_control ? "yes" : "no", + pr->flags.power ? "yes" : "no", + pr->flags.throttling ? "yes" : "no", + pr->flags.limit ? "yes" : "no"); + + end: + return 0; +} + +static int acpi_processor_info_open_fs(struct inode *inode, struct file *file) +{ + return single_open(file, acpi_processor_info_seq_show, + PDE(inode)->data); +} + +static int __cpuinit acpi_processor_add_fs(struct acpi_device *device) +{ + struct proc_dir_entry *entry = NULL; + + + if (!acpi_device_dir(device)) { + acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), + acpi_processor_dir); + if (!acpi_device_dir(device)) + return -ENODEV; + } + + /* 'info' [R] */ + entry = proc_create_data(ACPI_PROCESSOR_FILE_INFO, + S_IRUGO, acpi_device_dir(device), + &acpi_processor_info_fops, + acpi_driver_data(device)); + if (!entry) + return -EIO; + + /* 'throttling' [R/W] */ + entry = proc_create_data(ACPI_PROCESSOR_FILE_THROTTLING, + S_IFREG | S_IRUGO | S_IWUSR, + acpi_device_dir(device), + &acpi_processor_throttling_fops, + acpi_driver_data(device)); + if (!entry) + return -EIO; + + /* 'limit' [R/W] */ + entry = proc_create_data(ACPI_PROCESSOR_FILE_LIMIT, + S_IFREG | S_IRUGO | S_IWUSR, + acpi_device_dir(device), + &acpi_processor_limit_fops, + acpi_driver_data(device)); + if (!entry) + return -EIO; + return 0; +} +static int acpi_processor_remove_fs(struct acpi_device *device) +{ + + if (acpi_device_dir(device)) { + remove_proc_entry(ACPI_PROCESSOR_FILE_INFO, + acpi_device_dir(device)); + remove_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING, + acpi_device_dir(device)); + remove_proc_entry(ACPI_PROCESSOR_FILE_LIMIT, + acpi_device_dir(device)); + remove_proc_entry(acpi_device_bid(device), acpi_processor_dir); + acpi_device_dir(device) = NULL; + } + + return 0; +} +#else +static inline int acpi_processor_add_fs(struct acpi_device *device) +{ + return 0; +} +static inline int acpi_processor_remove_fs(struct acpi_device *device) +{ + return 0; +} +#endif + +/* Use the acpiid in MADT to map cpus in case of SMP */ + +#ifndef CONFIG_SMP +static int get_cpu_id(acpi_handle handle, int type, u32 acpi_id) { return -1; } +#else + +static struct acpi_table_madt *madt; + +static int map_lapic_id(struct acpi_subtable_header *entry, + u32 acpi_id, int *apic_id) +{ + struct acpi_madt_local_apic *lapic = + (struct acpi_madt_local_apic *)entry; + if ((lapic->lapic_flags & ACPI_MADT_ENABLED) && + lapic->processor_id == acpi_id) { + *apic_id = lapic->id; + return 1; + } + return 0; +} + +static int map_x2apic_id(struct acpi_subtable_header *entry, + int device_declaration, u32 acpi_id, int *apic_id) +{ + struct acpi_madt_local_x2apic *apic = + (struct acpi_madt_local_x2apic *)entry; + u32 tmp = apic->local_apic_id; + + /* Only check enabled APICs*/ + if (!(apic->lapic_flags & ACPI_MADT_ENABLED)) + return 0; + + /* Device statement declaration type */ + if (device_declaration) { + if (apic->uid == acpi_id) + goto found; + } + + return 0; +found: + *apic_id = tmp; + return 1; +} + +static int map_lsapic_id(struct acpi_subtable_header *entry, + int device_declaration, u32 acpi_id, int *apic_id) +{ + struct acpi_madt_local_sapic *lsapic = + (struct acpi_madt_local_sapic *)entry; + u32 tmp = (lsapic->id << 8) | lsapic->eid; + + /* Only check enabled APICs*/ + if (!(lsapic->lapic_flags & ACPI_MADT_ENABLED)) + return 0; + + /* Device statement declaration type */ + if (device_declaration) { + if (entry->length < 16) + printk(KERN_ERR PREFIX + "Invalid LSAPIC with Device type processor (SAPIC ID %#x)\n", + tmp); + else if (lsapic->uid == acpi_id) + goto found; + /* Processor statement declaration type */ + } else if (lsapic->processor_id == acpi_id) + goto found; + + return 0; +found: + *apic_id = tmp; + return 1; +} + +static int map_madt_entry(int type, u32 acpi_id) +{ + unsigned long madt_end, entry; + int apic_id = -1; + + if (!madt) + return apic_id; + + entry = (unsigned long)madt; + madt_end = entry + madt->header.length; + + /* Parse all entries looking for a match. */ + + entry += sizeof(struct acpi_table_madt); + while (entry + sizeof(struct acpi_subtable_header) < madt_end) { + struct acpi_subtable_header *header = + (struct acpi_subtable_header *)entry; + if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) { + if (map_lapic_id(header, acpi_id, &apic_id)) + break; + } else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) { + if (map_x2apic_id(header, type, acpi_id, &apic_id)) + break; + } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { + if (map_lsapic_id(header, type, acpi_id, &apic_id)) + break; + } + entry += header->length; + } + return apic_id; +} + +static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id) +{ + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + union acpi_object *obj; + struct acpi_subtable_header *header; + int apic_id = -1; + + if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer))) + goto exit; + + if (!buffer.length || !buffer.pointer) + goto exit; + + obj = buffer.pointer; + if (obj->type != ACPI_TYPE_BUFFER || + obj->buffer.length < sizeof(struct acpi_subtable_header)) { + goto exit; + } + + header = (struct acpi_subtable_header *)obj->buffer.pointer; + if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) { + map_lapic_id(header, acpi_id, &apic_id); + } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { + map_lsapic_id(header, type, acpi_id, &apic_id); + } + +exit: + if (buffer.pointer) + kfree(buffer.pointer); + return apic_id; +} + +static int get_cpu_id(acpi_handle handle, int type, u32 acpi_id) +{ + int i; + int apic_id = -1; + + apic_id = map_mat_entry(handle, type, acpi_id); + if (apic_id == -1) + apic_id = map_madt_entry(type, acpi_id); + if (apic_id == -1) + return apic_id; + + for_each_possible_cpu(i) { + if (cpu_physical_id(i) == apic_id) + return i; + } + return -1; +} +#endif + +/* -------------------------------------------------------------------------- + Driver Interface + -------------------------------------------------------------------------- */ + +static int acpi_processor_get_info(struct acpi_device *device) +{ + acpi_status status = 0; + union acpi_object object = { 0 }; + struct acpi_buffer buffer = { sizeof(union acpi_object), &object }; + struct acpi_processor *pr; + int cpu_index, device_declaration = 0; + static int cpu0_initialized; + + pr = acpi_driver_data(device); + if (!pr) + return -EINVAL; + + if (num_online_cpus() > 1) + errata.smp = TRUE; + + acpi_processor_errata(pr); + + /* + * Check to see if we have bus mastering arbitration control. This + * is required for proper C3 usage (to maintain cache coherency). + */ + if (acpi_gbl_FADT.pm2_control_block && acpi_gbl_FADT.pm2_control_length) { + pr->flags.bm_control = 1; + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Bus mastering arbitration control present\n")); + } else + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "No bus mastering arbitration control\n")); + + if (!strcmp(acpi_device_hid(device), ACPI_PROCESSOR_OBJECT_HID)) { + /* Declared with "Processor" statement; match ProcessorID */ + status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer); + if (ACPI_FAILURE(status)) { + printk(KERN_ERR PREFIX "Evaluating processor object\n"); + return -ENODEV; + } + + /* + * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP. + * >>> 'acpi_get_processor_id(acpi_id, &id)' in + * arch/xxx/acpi.c + */ + pr->acpi_id = object.processor.proc_id; + } else { + /* + * Declared with "Device" statement; match _UID. + * Note that we don't handle string _UIDs yet. + */ + unsigned long long value; + status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID, + NULL, &value); + if (ACPI_FAILURE(status)) { + printk(KERN_ERR PREFIX + "Evaluating processor _UID [%#x]\n", status); + return -ENODEV; + } + device_declaration = 1; + pr->acpi_id = value; + } + cpu_index = get_cpu_id(pr->handle, device_declaration, pr->acpi_id); + + /* Handle UP system running SMP kernel, with no LAPIC in MADT */ + if (!cpu0_initialized && (cpu_index == -1) && + (num_online_cpus() == 1)) { + cpu_index = 0; + } + + cpu0_initialized = 1; + + pr->id = cpu_index; + + /* + * Extra Processor objects may be enumerated on MP systems with + * less than the max # of CPUs. They should be ignored _iff + * they are physically not present. + */ + if (pr->id == -1) { + if (ACPI_FAILURE + (acpi_processor_hotadd_init(pr->handle, &pr->id))) { + return -ENODEV; + } + } + /* + * On some boxes several processors use the same processor bus id. + * But they are located in different scope. For example: + * \_SB.SCK0.CPU0 + * \_SB.SCK1.CPU0 + * Rename the processor device bus id. And the new bus id will be + * generated as the following format: + * CPU+CPU ID. + */ + sprintf(acpi_device_bid(device), "CPU%X", pr->id); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d:%d]\n", pr->id, + pr->acpi_id)); + + if (!object.processor.pblk_address) + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No PBLK (NULL address)\n")); + else if (object.processor.pblk_length != 6) + printk(KERN_ERR PREFIX "Invalid PBLK length [%d]\n", + object.processor.pblk_length); + else { + pr->throttling.address = object.processor.pblk_address; + pr->throttling.duty_offset = acpi_gbl_FADT.duty_offset; + pr->throttling.duty_width = acpi_gbl_FADT.duty_width; + + pr->pblk = object.processor.pblk_address; + + /* + * We don't care about error returns - we just try to mark + * these reserved so that nobody else is confused into thinking + * that this region might be unused.. + * + * (In particular, allocating the IO range for Cardbus) + */ + request_region(pr->throttling.address, 6, "ACPI CPU throttle"); + } + + /* + * If ACPI describes a slot number for this CPU, we can use it + * ensure we get the right value in the "physical id" field + * of /proc/cpuinfo + */ + status = acpi_evaluate_object(pr->handle, "_SUN", NULL, &buffer); + if (ACPI_SUCCESS(status)) + arch_fix_phys_package_id(pr->id, object.integer.value); + + return 0; +} + +static DEFINE_PER_CPU(void *, processor_device_array); + +static void acpi_processor_notify(struct acpi_device *device, u32 event) +{ + struct acpi_processor *pr = acpi_driver_data(device); + int saved; + + if (!pr) + return; + + switch (event) { + case ACPI_PROCESSOR_NOTIFY_PERFORMANCE: + saved = pr->performance_platform_limit; + acpi_processor_ppc_has_changed(pr, 1); + if (saved == pr->performance_platform_limit) + break; + acpi_bus_generate_proc_event(device, event, + pr->performance_platform_limit); + acpi_bus_generate_netlink_event(device->pnp.device_class, + dev_name(&device->dev), event, + pr->performance_platform_limit); + break; + case ACPI_PROCESSOR_NOTIFY_POWER: + acpi_processor_cst_has_changed(pr); + acpi_bus_generate_proc_event(device, event, 0); + acpi_bus_generate_netlink_event(device->pnp.device_class, + dev_name(&device->dev), event, 0); + break; + case ACPI_PROCESSOR_NOTIFY_THROTTLING: + acpi_processor_tstate_has_changed(pr); + acpi_bus_generate_proc_event(device, event, 0); + acpi_bus_generate_netlink_event(device->pnp.device_class, + dev_name(&device->dev), event, 0); + default: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Unsupported event [0x%x]\n", event)); + break; + } + + return; +} + +static int acpi_cpu_soft_notify(struct notifier_block *nfb, + unsigned long action, void *hcpu) +{ + unsigned int cpu = (unsigned long)hcpu; + struct acpi_processor *pr = per_cpu(processors, cpu); + + if (action == CPU_ONLINE && pr) { + acpi_processor_ppc_has_changed(pr, 0); + acpi_processor_cst_has_changed(pr); + acpi_processor_tstate_has_changed(pr); + } + return NOTIFY_OK; +} + +static struct notifier_block acpi_cpu_notifier = +{ + .notifier_call = acpi_cpu_soft_notify, +}; + +static int __cpuinit acpi_processor_add(struct acpi_device *device) +{ + struct acpi_processor *pr = NULL; + int result = 0; + struct sys_device *sysdev; + + pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL); + if (!pr) + return -ENOMEM; + + if (!zalloc_cpumask_var(&pr->throttling.shared_cpu_map, GFP_KERNEL)) { + kfree(pr); + return -ENOMEM; + } + + pr->handle = device->handle; + strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME); + strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS); + device->driver_data = pr; + + result = acpi_processor_get_info(device); + if (result) { + /* Processor is physically not present */ + return 0; + } + + BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0)); + + /* + * Buggy BIOS check + * ACPI id of processors can be reported wrongly by the BIOS. + * Don't trust it blindly + */ + if (per_cpu(processor_device_array, pr->id) != NULL && + per_cpu(processor_device_array, pr->id) != device) { + printk(KERN_WARNING "BIOS reported wrong ACPI id " + "for the processor\n"); + result = -ENODEV; + goto err_free_cpumask; + } + per_cpu(processor_device_array, pr->id) = device; + + per_cpu(processors, pr->id) = pr; + + result = acpi_processor_add_fs(device); + if (result) + goto err_free_cpumask; + + sysdev = get_cpu_sysdev(pr->id); + if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev")) { + result = -EFAULT; + goto err_remove_fs; + } + + /* _PDC call should be done before doing anything else (if reqd.). */ + acpi_processor_set_pdc(pr->handle); + +#ifdef CONFIG_CPU_FREQ + acpi_processor_ppc_has_changed(pr, 0); +#endif + acpi_processor_get_throttling_info(pr); + acpi_processor_get_limit_info(pr); + + + acpi_processor_power_init(pr, device); + + pr->cdev = thermal_cooling_device_register("Processor", device, + &processor_cooling_ops); + if (IS_ERR(pr->cdev)) { + result = PTR_ERR(pr->cdev); + goto err_power_exit; + } + + dev_dbg(&device->dev, "registered as cooling_device%d\n", + pr->cdev->id); + + result = sysfs_create_link(&device->dev.kobj, + &pr->cdev->device.kobj, + "thermal_cooling"); + if (result) { + printk(KERN_ERR PREFIX "Create sysfs link\n"); + goto err_thermal_unregister; + } + result = sysfs_create_link(&pr->cdev->device.kobj, + &device->dev.kobj, + "device"); + if (result) { + printk(KERN_ERR PREFIX "Create sysfs link\n"); + goto err_remove_sysfs; + } + + return 0; + +err_remove_sysfs: + sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); +err_thermal_unregister: + thermal_cooling_device_unregister(pr->cdev); +err_power_exit: + acpi_processor_power_exit(pr, device); +err_remove_fs: + acpi_processor_remove_fs(device); +err_free_cpumask: + free_cpumask_var(pr->throttling.shared_cpu_map); + + return result; +} + +static int acpi_processor_remove(struct acpi_device *device, int type) +{ + struct acpi_processor *pr = NULL; + + + if (!device || !acpi_driver_data(device)) + return -EINVAL; + + pr = acpi_driver_data(device); + + if (pr->id >= nr_cpu_ids) + goto free; + + if (type == ACPI_BUS_REMOVAL_EJECT) { + if (acpi_processor_handle_eject(pr)) + return -EINVAL; + } + + acpi_processor_power_exit(pr, device); + + sysfs_remove_link(&device->dev.kobj, "sysdev"); + + acpi_processor_remove_fs(device); + + if (pr->cdev) { + sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); + sysfs_remove_link(&pr->cdev->device.kobj, "device"); + thermal_cooling_device_unregister(pr->cdev); + pr->cdev = NULL; + } + + per_cpu(processors, pr->id) = NULL; + per_cpu(processor_device_array, pr->id) = NULL; + +free: + free_cpumask_var(pr->throttling.shared_cpu_map); + kfree(pr); + + return 0; +} + +#ifdef CONFIG_ACPI_HOTPLUG_CPU +/**************************************************************************** + * Acpi processor hotplug support * + ****************************************************************************/ + +static int is_processor_present(acpi_handle handle) +{ + acpi_status status; + unsigned long long sta = 0; + + + status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); + + if (ACPI_SUCCESS(status) && (sta & ACPI_STA_DEVICE_PRESENT)) + return 1; + + /* + * _STA is mandatory for a processor that supports hot plug + */ + if (status == AE_NOT_FOUND) + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Processor does not support hot plug\n")); + else + ACPI_EXCEPTION((AE_INFO, status, + "Processor Device is not present")); + return 0; +} + +static +int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device) +{ + acpi_handle phandle; + struct acpi_device *pdev; + + + if (acpi_get_parent(handle, &phandle)) { + return -ENODEV; + } + + if (acpi_bus_get_device(phandle, &pdev)) { + return -ENODEV; + } + + if (acpi_bus_add(device, pdev, handle, ACPI_BUS_TYPE_PROCESSOR)) { + return -ENODEV; + } + + return 0; +} + +static void __ref acpi_processor_hotplug_notify(acpi_handle handle, + u32 event, void *data) +{ + struct acpi_processor *pr; + struct acpi_device *device = NULL; + int result; + + + switch (event) { + case ACPI_NOTIFY_BUS_CHECK: + case ACPI_NOTIFY_DEVICE_CHECK: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Processor driver received %s event\n", + (event == ACPI_NOTIFY_BUS_CHECK) ? + "ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK")); + + if (!is_processor_present(handle)) + break; + + if (acpi_bus_get_device(handle, &device)) { + result = acpi_processor_device_add(handle, &device); + if (result) + printk(KERN_ERR PREFIX + "Unable to add the device\n"); + break; + } + break; + case ACPI_NOTIFY_EJECT_REQUEST: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "received ACPI_NOTIFY_EJECT_REQUEST\n")); + + if (acpi_bus_get_device(handle, &device)) { + printk(KERN_ERR PREFIX + "Device don't exist, dropping EJECT\n"); + break; + } + pr = acpi_driver_data(device); + if (!pr) { + printk(KERN_ERR PREFIX + "Driver data is NULL, dropping EJECT\n"); + return; + } + break; + default: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Unsupported event [0x%x]\n", event)); + break; + } + + return; +} + +static acpi_status +processor_walk_namespace_cb(acpi_handle handle, + u32 lvl, void *context, void **rv) +{ + acpi_status status; + int *action = context; + acpi_object_type type = 0; + + status = acpi_get_type(handle, &type); + if (ACPI_FAILURE(status)) + return (AE_OK); + + if (type != ACPI_TYPE_PROCESSOR) + return (AE_OK); + + switch (*action) { + case INSTALL_NOTIFY_HANDLER: + acpi_install_notify_handler(handle, + ACPI_SYSTEM_NOTIFY, + acpi_processor_hotplug_notify, + NULL); + break; + case UNINSTALL_NOTIFY_HANDLER: + acpi_remove_notify_handler(handle, + ACPI_SYSTEM_NOTIFY, + acpi_processor_hotplug_notify); + break; + default: + break; + } + + return (AE_OK); +} + +static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu) +{ + + if (!is_processor_present(handle)) { + return AE_ERROR; + } + + if (acpi_map_lsapic(handle, p_cpu)) + return AE_ERROR; + + if (arch_register_cpu(*p_cpu)) { + acpi_unmap_lsapic(*p_cpu); + return AE_ERROR; + } + + return AE_OK; +} + +static int acpi_processor_handle_eject(struct acpi_processor *pr) +{ + if (cpu_online(pr->id)) + cpu_down(pr->id); + + arch_unregister_cpu(pr->id); + acpi_unmap_lsapic(pr->id); + return (0); +} +#else +static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu) +{ + return AE_ERROR; +} +static int acpi_processor_handle_eject(struct acpi_processor *pr) +{ + return (-EINVAL); +} +#endif + +static +void acpi_processor_install_hotplug_notify(void) +{ +#ifdef CONFIG_ACPI_HOTPLUG_CPU + int action = INSTALL_NOTIFY_HANDLER; + acpi_walk_namespace(ACPI_TYPE_PROCESSOR, + ACPI_ROOT_OBJECT, + ACPI_UINT32_MAX, + processor_walk_namespace_cb, NULL, &action, NULL); +#endif + register_hotcpu_notifier(&acpi_cpu_notifier); +} + +static +void acpi_processor_uninstall_hotplug_notify(void) +{ +#ifdef CONFIG_ACPI_HOTPLUG_CPU + int action = UNINSTALL_NOTIFY_HANDLER; + acpi_walk_namespace(ACPI_TYPE_PROCESSOR, + ACPI_ROOT_OBJECT, + ACPI_UINT32_MAX, + processor_walk_namespace_cb, NULL, &action, NULL); +#endif + unregister_hotcpu_notifier(&acpi_cpu_notifier); +} + +/* + * We keep the driver loaded even when ACPI is not running. + * This is needed for the powernow-k8 driver, that works even without + * ACPI, but needs symbols from this driver + */ + +static int __init acpi_processor_init(void) +{ + int result = 0; + + if (acpi_disabled) + return 0; + + memset(&errata, 0, sizeof(errata)); + +#ifdef CONFIG_SMP + if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_MADT, 0, + (struct acpi_table_header **)&madt))) + madt = NULL; +#endif +#ifdef CONFIG_ACPI_PROCFS + acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir); + if (!acpi_processor_dir) + return -ENOMEM; +#endif + result = cpuidle_register_driver(&acpi_idle_driver); + if (result < 0) + goto out_proc; + + result = acpi_bus_register_driver(&acpi_processor_driver); + if (result < 0) + goto out_cpuidle; + + acpi_processor_install_hotplug_notify(); + + acpi_thermal_cpufreq_init(); + + acpi_processor_ppc_init(); + + acpi_processor_throttling_init(); + + return 0; + +out_cpuidle: + cpuidle_unregister_driver(&acpi_idle_driver); + +out_proc: +#ifdef CONFIG_ACPI_PROCFS + remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); +#endif + + return result; +} + +static void __exit acpi_processor_exit(void) +{ + if (acpi_disabled) + return; + + acpi_processor_ppc_exit(); + + acpi_thermal_cpufreq_exit(); + + acpi_processor_uninstall_hotplug_notify(); + + acpi_bus_unregister_driver(&acpi_processor_driver); + + cpuidle_unregister_driver(&acpi_idle_driver); + +#ifdef CONFIG_ACPI_PROCFS + remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); +#endif + + return; +} + +module_init(acpi_processor_init); +module_exit(acpi_processor_exit); + +EXPORT_SYMBOL(acpi_processor_set_thermal_limit); + +MODULE_ALIAS("processor"); -- cgit v0.10.2 From 4d5d4cd88c542ff56cf7feacd29cc907f2abbfbb Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Mon, 22 Feb 2010 12:11:14 -0700 Subject: ACPI: processor: mv processor_pdc.c processor_core.c We've renamed the old processor_core.c to processor_driver.c, to convey the idea that it can be built modular and has driver-like bits. Now let's re-create a processor_core.c for the bits needed statically by the rest of the kernel. The contents of processor_pdc.c are a good starting spot, so let's just rename that file and complete our three card monte. Acked-by: Venkatesh Pallipadi Signed-off-by: Alex Chiang Signed-off-by: Len Brown diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 6b363a5..a8d8998 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -32,7 +32,7 @@ acpi-$(CONFIG_ACPI_SLEEP) += proc.o # acpi-y += bus.o glue.o acpi-y += scan.o -acpi-y += processor_pdc.o +acpi-y += processor_core.o acpi-y += ec.o acpi-$(CONFIG_ACPI_DOCK) += dock.o acpi-y += pci_root.o pci_link.o pci_irq.o pci_bind.o diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c new file mode 100644 index 0000000..6f376bf --- /dev/null +++ b/drivers/acpi/processor_core.c @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2005 Intel Corporation + * Copyright (C) 2009 Hewlett-Packard Development Company, L.P. + * + * Alex Chiang + * - Unified x86/ia64 implementations + * Venkatesh Pallipadi + * - Added _PDC for platforms with Intel CPUs + */ +#include + +#include +#include + +#include "internal.h" + +#define PREFIX "ACPI: " +#define _COMPONENT ACPI_PROCESSOR_COMPONENT +ACPI_MODULE_NAME("processor_core"); + +static int set_no_mwait(const struct dmi_system_id *id) +{ + printk(KERN_NOTICE PREFIX "%s detected - " + "disabling mwait for CPU C-states\n", id->ident); + idle_nomwait = 1; + return 0; +} + +static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = { + { + set_no_mwait, "IFL91 board", { + DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"), + DMI_MATCH(DMI_SYS_VENDOR, "ZEPTO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "3215W"), + DMI_MATCH(DMI_BOARD_NAME, "IFL91") }, NULL}, + { + set_no_mwait, "Extensa 5220", { + DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_VERSION, "0100"), + DMI_MATCH(DMI_BOARD_NAME, "Columbia") }, NULL}, + {}, +}; + +static void acpi_set_pdc_bits(u32 *buf) +{ + buf[0] = ACPI_PDC_REVISION_ID; + buf[1] = 1; + + /* Enable coordination with firmware's _TSD info */ + buf[2] = ACPI_PDC_SMP_T_SWCOORD; + + /* Twiddle arch-specific bits needed for _PDC */ + arch_acpi_set_pdc_bits(buf); +} + +static struct acpi_object_list *acpi_processor_alloc_pdc(void) +{ + struct acpi_object_list *obj_list; + union acpi_object *obj; + u32 *buf; + + /* allocate and initialize pdc. It will be used later. */ + obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL); + if (!obj_list) { + printk(KERN_ERR "Memory allocation error\n"); + return NULL; + } + + obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL); + if (!obj) { + printk(KERN_ERR "Memory allocation error\n"); + kfree(obj_list); + return NULL; + } + + buf = kmalloc(12, GFP_KERNEL); + if (!buf) { + printk(KERN_ERR "Memory allocation error\n"); + kfree(obj); + kfree(obj_list); + return NULL; + } + + acpi_set_pdc_bits(buf); + + obj->type = ACPI_TYPE_BUFFER; + obj->buffer.length = 12; + obj->buffer.pointer = (u8 *) buf; + obj_list->count = 1; + obj_list->pointer = obj; + + return obj_list; +} + +/* + * _PDC is required for a BIOS-OS handshake for most of the newer + * ACPI processor features. + */ +static int +acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in) +{ + acpi_status status = AE_OK; + + if (idle_nomwait) { + /* + * If mwait is disabled for CPU C-states, the C2C3_FFH access + * mode will be disabled in the parameter of _PDC object. + * Of course C1_FFH access mode will also be disabled. + */ + union acpi_object *obj; + u32 *buffer = NULL; + + obj = pdc_in->pointer; + buffer = (u32 *)(obj->buffer.pointer); + buffer[2] &= ~(ACPI_PDC_C_C2C3_FFH | ACPI_PDC_C_C1_FFH); + + } + status = acpi_evaluate_object(handle, "_PDC", pdc_in, NULL); + + if (ACPI_FAILURE(status)) + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Could not evaluate _PDC, using legacy perf. control.\n")); + + return status; +} + +static int early_pdc_done; + +void acpi_processor_set_pdc(acpi_handle handle) +{ + struct acpi_object_list *obj_list; + + if (arch_has_acpi_pdc() == false) + return; + + if (early_pdc_done) + return; + + obj_list = acpi_processor_alloc_pdc(); + if (!obj_list) + return; + + acpi_processor_eval_pdc(handle, obj_list); + + kfree(obj_list->pointer->buffer.pointer); + kfree(obj_list->pointer); + kfree(obj_list); +} +EXPORT_SYMBOL_GPL(acpi_processor_set_pdc); + +static int early_pdc_optin; +static int set_early_pdc_optin(const struct dmi_system_id *id) +{ + early_pdc_optin = 1; + return 0; +} + +static int param_early_pdc_optin(char *s) +{ + early_pdc_optin = 1; + return 1; +} +__setup("acpi_early_pdc_eval", param_early_pdc_optin); + +static struct dmi_system_id __cpuinitdata early_pdc_optin_table[] = { + { + set_early_pdc_optin, "HP Envy", { + DMI_MATCH(DMI_BIOS_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Envy") }, NULL}, + { + set_early_pdc_optin, "HP Pavilion dv6", { + DMI_MATCH(DMI_BIOS_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv6") }, NULL}, + { + set_early_pdc_optin, "HP Pavilion dv7", { + DMI_MATCH(DMI_BIOS_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv7") }, NULL}, + {}, +}; + +static acpi_status +early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv) +{ + acpi_processor_set_pdc(handle); + return AE_OK; +} + +void __init acpi_early_processor_set_pdc(void) +{ + /* + * Check whether the system is DMI table. If yes, OSPM + * should not use mwait for CPU-states. + */ + dmi_check_system(processor_idle_dmi_table); + + /* + * Allow systems to opt-in to early _PDC evaluation. + */ + dmi_check_system(early_pdc_optin_table); + if (!early_pdc_optin) + return; + + acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, + ACPI_UINT32_MAX, + early_init_pdc, NULL, NULL, NULL); + + early_pdc_done = 1; +} diff --git a/drivers/acpi/processor_pdc.c b/drivers/acpi/processor_pdc.c deleted file mode 100644 index e306ba9..0000000 --- a/drivers/acpi/processor_pdc.c +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Copyright (C) 2005 Intel Corporation - * Copyright (C) 2009 Hewlett-Packard Development Company, L.P. - * - * Alex Chiang - * - Unified x86/ia64 implementations - * Venkatesh Pallipadi - * - Added _PDC for platforms with Intel CPUs - */ -#include - -#include -#include - -#include "internal.h" - -#define PREFIX "ACPI: " -#define _COMPONENT ACPI_PROCESSOR_COMPONENT -ACPI_MODULE_NAME("processor_pdc"); - -static int set_no_mwait(const struct dmi_system_id *id) -{ - printk(KERN_NOTICE PREFIX "%s detected - " - "disabling mwait for CPU C-states\n", id->ident); - idle_nomwait = 1; - return 0; -} - -static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = { - { - set_no_mwait, "IFL91 board", { - DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"), - DMI_MATCH(DMI_SYS_VENDOR, "ZEPTO"), - DMI_MATCH(DMI_PRODUCT_VERSION, "3215W"), - DMI_MATCH(DMI_BOARD_NAME, "IFL91") }, NULL}, - { - set_no_mwait, "Extensa 5220", { - DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_VERSION, "0100"), - DMI_MATCH(DMI_BOARD_NAME, "Columbia") }, NULL}, - {}, -}; - -static void acpi_set_pdc_bits(u32 *buf) -{ - buf[0] = ACPI_PDC_REVISION_ID; - buf[1] = 1; - - /* Enable coordination with firmware's _TSD info */ - buf[2] = ACPI_PDC_SMP_T_SWCOORD; - - /* Twiddle arch-specific bits needed for _PDC */ - arch_acpi_set_pdc_bits(buf); -} - -static struct acpi_object_list *acpi_processor_alloc_pdc(void) -{ - struct acpi_object_list *obj_list; - union acpi_object *obj; - u32 *buf; - - /* allocate and initialize pdc. It will be used later. */ - obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL); - if (!obj_list) { - printk(KERN_ERR "Memory allocation error\n"); - return NULL; - } - - obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL); - if (!obj) { - printk(KERN_ERR "Memory allocation error\n"); - kfree(obj_list); - return NULL; - } - - buf = kmalloc(12, GFP_KERNEL); - if (!buf) { - printk(KERN_ERR "Memory allocation error\n"); - kfree(obj); - kfree(obj_list); - return NULL; - } - - acpi_set_pdc_bits(buf); - - obj->type = ACPI_TYPE_BUFFER; - obj->buffer.length = 12; - obj->buffer.pointer = (u8 *) buf; - obj_list->count = 1; - obj_list->pointer = obj; - - return obj_list; -} - -/* - * _PDC is required for a BIOS-OS handshake for most of the newer - * ACPI processor features. - */ -static int -acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in) -{ - acpi_status status = AE_OK; - - if (idle_nomwait) { - /* - * If mwait is disabled for CPU C-states, the C2C3_FFH access - * mode will be disabled in the parameter of _PDC object. - * Of course C1_FFH access mode will also be disabled. - */ - union acpi_object *obj; - u32 *buffer = NULL; - - obj = pdc_in->pointer; - buffer = (u32 *)(obj->buffer.pointer); - buffer[2] &= ~(ACPI_PDC_C_C2C3_FFH | ACPI_PDC_C_C1_FFH); - - } - status = acpi_evaluate_object(handle, "_PDC", pdc_in, NULL); - - if (ACPI_FAILURE(status)) - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Could not evaluate _PDC, using legacy perf. control.\n")); - - return status; -} - -static int early_pdc_done; - -void acpi_processor_set_pdc(acpi_handle handle) -{ - struct acpi_object_list *obj_list; - - if (arch_has_acpi_pdc() == false) - return; - - if (early_pdc_done) - return; - - obj_list = acpi_processor_alloc_pdc(); - if (!obj_list) - return; - - acpi_processor_eval_pdc(handle, obj_list); - - kfree(obj_list->pointer->buffer.pointer); - kfree(obj_list->pointer); - kfree(obj_list); -} -EXPORT_SYMBOL_GPL(acpi_processor_set_pdc); - -static int early_pdc_optin; -static int set_early_pdc_optin(const struct dmi_system_id *id) -{ - early_pdc_optin = 1; - return 0; -} - -static int param_early_pdc_optin(char *s) -{ - early_pdc_optin = 1; - return 1; -} -__setup("acpi_early_pdc_eval", param_early_pdc_optin); - -static struct dmi_system_id __cpuinitdata early_pdc_optin_table[] = { - { - set_early_pdc_optin, "HP Envy", { - DMI_MATCH(DMI_BIOS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP Envy") }, NULL}, - { - set_early_pdc_optin, "HP Pavilion dv6", { - DMI_MATCH(DMI_BIOS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv6") }, NULL}, - { - set_early_pdc_optin, "HP Pavilion dv7", { - DMI_MATCH(DMI_BIOS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv7") }, NULL}, - {}, -}; - -static acpi_status -early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv) -{ - acpi_processor_set_pdc(handle); - return AE_OK; -} - -void __init acpi_early_processor_set_pdc(void) -{ - /* - * Check whether the system is DMI table. If yes, OSPM - * should not use mwait for CPU-states. - */ - dmi_check_system(processor_idle_dmi_table); - - /* - * Allow systems to opt-in to early _PDC evaluation. - */ - dmi_check_system(early_pdc_optin_table); - if (!early_pdc_optin) - return; - - acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, - early_init_pdc, NULL, NULL, NULL); - - early_pdc_done = 1; -} diff --git a/include/acpi/processor.h b/include/acpi/processor.h index 1172c27..7bb0b8b 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h @@ -320,7 +320,7 @@ static inline int acpi_processor_get_bios_limit(int cpu, unsigned int *limit) #endif /* CONFIG_CPU_FREQ */ -/* in processor_pdc.c */ +/* in processor_core.c */ void acpi_processor_set_pdc(acpi_handle handle); /* in processor_throttling.c */ -- cgit v0.10.2 From 2e9d5e4efa0beeca03ad550bda28027826e83e42 Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Mon, 22 Feb 2010 12:11:19 -0700 Subject: ACPI: processor: export acpi_get_cpuid() Rename static get_cpu_id() to acpi_get_cpuid() and export it. This change also gives us an opportunity to remove the #ifndef CONFIG_SMP from processor_driver.c and into a header file where it properly belongs. Acked-by: Venkatesh Pallipadi Signed-off-by: Alex Chiang Signed-off-by: Len Brown diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 7b0f4c2..9835825 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -361,10 +361,7 @@ static inline int acpi_processor_remove_fs(struct acpi_device *device) /* Use the acpiid in MADT to map cpus in case of SMP */ -#ifndef CONFIG_SMP -static int get_cpu_id(acpi_handle handle, int type, u32 acpi_id) { return -1; } -#else - +#ifdef CONFIG_SMP static struct acpi_table_madt *madt; static int map_lapic_id(struct acpi_subtable_header *entry, @@ -496,7 +493,7 @@ exit: return apic_id; } -static int get_cpu_id(acpi_handle handle, int type, u32 acpi_id) +int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id) { int i; int apic_id = -1; @@ -513,6 +510,7 @@ static int get_cpu_id(acpi_handle handle, int type, u32 acpi_id) } return -1; } +EXPORT_SYMBOL_GPL(acpi_get_cpuid); #endif /* -------------------------------------------------------------------------- @@ -579,7 +577,7 @@ static int acpi_processor_get_info(struct acpi_device *device) device_declaration = 1; pr->acpi_id = value; } - cpu_index = get_cpu_id(pr->handle, device_declaration, pr->acpi_id); + cpu_index = acpi_get_cpuid(pr->handle, device_declaration, pr->acpi_id); /* Handle UP system running SMP kernel, with no LAPIC in MADT */ if (!cpu0_initialized && (cpu_index == -1) && diff --git a/include/acpi/processor.h b/include/acpi/processor.h index 7bb0b8b..86825dd 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h @@ -322,6 +322,14 @@ static inline int acpi_processor_get_bios_limit(int cpu, unsigned int *limit) /* in processor_core.c */ void acpi_processor_set_pdc(acpi_handle handle); +#ifdef CONFIG_SMP +int acpi_get_cpuid(acpi_handle, int type, u32 acpi_id); +#else +static inline int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id) +{ + return -1; +} +#endif /* in processor_throttling.c */ int acpi_processor_tstate_has_changed(struct acpi_processor *pr); -- cgit v0.10.2 From 78ed8bd2944b6400f742306e5fe9d1b9b6bf18ba Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Mon, 22 Feb 2010 12:11:24 -0700 Subject: ACPI: processor: move acpi_get_cpuid into processor_core.c Enumerating processors (via MADT/_MAT) belongs in the processor core, which is always built-in, rather than living in the processor driver which may not be built. Acked-by: Venkatesh Pallipadi Signed-off-by: Alex Chiang Signed-off-by: Len Brown diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 6f376bf..9ae5cc2 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -42,6 +42,159 @@ static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = { {}, }; +#ifdef CONFIG_SMP +static struct acpi_table_madt *madt; + +static int map_lapic_id(struct acpi_subtable_header *entry, + u32 acpi_id, int *apic_id) +{ + struct acpi_madt_local_apic *lapic = + (struct acpi_madt_local_apic *)entry; + if ((lapic->lapic_flags & ACPI_MADT_ENABLED) && + lapic->processor_id == acpi_id) { + *apic_id = lapic->id; + return 1; + } + return 0; +} + +static int map_x2apic_id(struct acpi_subtable_header *entry, + int device_declaration, u32 acpi_id, int *apic_id) +{ + struct acpi_madt_local_x2apic *apic = + (struct acpi_madt_local_x2apic *)entry; + u32 tmp = apic->local_apic_id; + + /* Only check enabled APICs*/ + if (!(apic->lapic_flags & ACPI_MADT_ENABLED)) + return 0; + + /* Device statement declaration type */ + if (device_declaration) { + if (apic->uid == acpi_id) + goto found; + } + + return 0; +found: + *apic_id = tmp; + return 1; +} + +static int map_lsapic_id(struct acpi_subtable_header *entry, + int device_declaration, u32 acpi_id, int *apic_id) +{ + struct acpi_madt_local_sapic *lsapic = + (struct acpi_madt_local_sapic *)entry; + u32 tmp = (lsapic->id << 8) | lsapic->eid; + + /* Only check enabled APICs*/ + if (!(lsapic->lapic_flags & ACPI_MADT_ENABLED)) + return 0; + + /* Device statement declaration type */ + if (device_declaration) { + if (entry->length < 16) + printk(KERN_ERR PREFIX + "Invalid LSAPIC with Device type processor (SAPIC ID %#x)\n", + tmp); + else if (lsapic->uid == acpi_id) + goto found; + /* Processor statement declaration type */ + } else if (lsapic->processor_id == acpi_id) + goto found; + + return 0; +found: + *apic_id = tmp; + return 1; +} + +static int map_madt_entry(int type, u32 acpi_id) +{ + unsigned long madt_end, entry; + int apic_id = -1; + + if (!madt) + return apic_id; + + entry = (unsigned long)madt; + madt_end = entry + madt->header.length; + + /* Parse all entries looking for a match. */ + + entry += sizeof(struct acpi_table_madt); + while (entry + sizeof(struct acpi_subtable_header) < madt_end) { + struct acpi_subtable_header *header = + (struct acpi_subtable_header *)entry; + if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) { + if (map_lapic_id(header, acpi_id, &apic_id)) + break; + } else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) { + if (map_x2apic_id(header, type, acpi_id, &apic_id)) + break; + } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { + if (map_lsapic_id(header, type, acpi_id, &apic_id)) + break; + } + entry += header->length; + } + return apic_id; +} + +static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id) +{ + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + union acpi_object *obj; + struct acpi_subtable_header *header; + int apic_id = -1; + + if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer))) + goto exit; + + if (!buffer.length || !buffer.pointer) + goto exit; + + obj = buffer.pointer; + if (obj->type != ACPI_TYPE_BUFFER || + obj->buffer.length < sizeof(struct acpi_subtable_header)) { + goto exit; + } + + header = (struct acpi_subtable_header *)obj->buffer.pointer; + if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) { + map_lapic_id(header, acpi_id, &apic_id); + } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { + map_lsapic_id(header, type, acpi_id, &apic_id); + } + +exit: + if (buffer.pointer) + kfree(buffer.pointer); + return apic_id; +} + +int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id) +{ + int i; + int apic_id = -1; + + apic_id = map_mat_entry(handle, type, acpi_id); + if (apic_id == -1) + apic_id = map_madt_entry(type, acpi_id); + if (apic_id == -1) + return apic_id; + + for_each_possible_cpu(i) { + if (cpu_physical_id(i) == apic_id) + return i; + } + return -1; +} +EXPORT_SYMBOL_GPL(acpi_get_cpuid); +#endif + + static void acpi_set_pdc_bits(u32 *buf) { buf[0] = ACPI_PDC_REVISION_ID; @@ -188,6 +341,13 @@ early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv) void __init acpi_early_processor_set_pdc(void) { + +#ifdef CONFIG_SMP + if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_MADT, 0, + (struct acpi_table_header **)&madt))) + madt = NULL; +#endif + /* * Check whether the system is DMI table. If yes, OSPM * should not use mwait for CPU-states. diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 9835825..7eedf74 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -359,160 +359,6 @@ static inline int acpi_processor_remove_fs(struct acpi_device *device) } #endif -/* Use the acpiid in MADT to map cpus in case of SMP */ - -#ifdef CONFIG_SMP -static struct acpi_table_madt *madt; - -static int map_lapic_id(struct acpi_subtable_header *entry, - u32 acpi_id, int *apic_id) -{ - struct acpi_madt_local_apic *lapic = - (struct acpi_madt_local_apic *)entry; - if ((lapic->lapic_flags & ACPI_MADT_ENABLED) && - lapic->processor_id == acpi_id) { - *apic_id = lapic->id; - return 1; - } - return 0; -} - -static int map_x2apic_id(struct acpi_subtable_header *entry, - int device_declaration, u32 acpi_id, int *apic_id) -{ - struct acpi_madt_local_x2apic *apic = - (struct acpi_madt_local_x2apic *)entry; - u32 tmp = apic->local_apic_id; - - /* Only check enabled APICs*/ - if (!(apic->lapic_flags & ACPI_MADT_ENABLED)) - return 0; - - /* Device statement declaration type */ - if (device_declaration) { - if (apic->uid == acpi_id) - goto found; - } - - return 0; -found: - *apic_id = tmp; - return 1; -} - -static int map_lsapic_id(struct acpi_subtable_header *entry, - int device_declaration, u32 acpi_id, int *apic_id) -{ - struct acpi_madt_local_sapic *lsapic = - (struct acpi_madt_local_sapic *)entry; - u32 tmp = (lsapic->id << 8) | lsapic->eid; - - /* Only check enabled APICs*/ - if (!(lsapic->lapic_flags & ACPI_MADT_ENABLED)) - return 0; - - /* Device statement declaration type */ - if (device_declaration) { - if (entry->length < 16) - printk(KERN_ERR PREFIX - "Invalid LSAPIC with Device type processor (SAPIC ID %#x)\n", - tmp); - else if (lsapic->uid == acpi_id) - goto found; - /* Processor statement declaration type */ - } else if (lsapic->processor_id == acpi_id) - goto found; - - return 0; -found: - *apic_id = tmp; - return 1; -} - -static int map_madt_entry(int type, u32 acpi_id) -{ - unsigned long madt_end, entry; - int apic_id = -1; - - if (!madt) - return apic_id; - - entry = (unsigned long)madt; - madt_end = entry + madt->header.length; - - /* Parse all entries looking for a match. */ - - entry += sizeof(struct acpi_table_madt); - while (entry + sizeof(struct acpi_subtable_header) < madt_end) { - struct acpi_subtable_header *header = - (struct acpi_subtable_header *)entry; - if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) { - if (map_lapic_id(header, acpi_id, &apic_id)) - break; - } else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) { - if (map_x2apic_id(header, type, acpi_id, &apic_id)) - break; - } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { - if (map_lsapic_id(header, type, acpi_id, &apic_id)) - break; - } - entry += header->length; - } - return apic_id; -} - -static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id) -{ - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - union acpi_object *obj; - struct acpi_subtable_header *header; - int apic_id = -1; - - if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer))) - goto exit; - - if (!buffer.length || !buffer.pointer) - goto exit; - - obj = buffer.pointer; - if (obj->type != ACPI_TYPE_BUFFER || - obj->buffer.length < sizeof(struct acpi_subtable_header)) { - goto exit; - } - - header = (struct acpi_subtable_header *)obj->buffer.pointer; - if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) { - map_lapic_id(header, acpi_id, &apic_id); - } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { - map_lsapic_id(header, type, acpi_id, &apic_id); - } - -exit: - if (buffer.pointer) - kfree(buffer.pointer); - return apic_id; -} - -int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id) -{ - int i; - int apic_id = -1; - - apic_id = map_mat_entry(handle, type, acpi_id); - if (apic_id == -1) - apic_id = map_madt_entry(type, acpi_id); - if (apic_id == -1) - return apic_id; - - for_each_possible_cpu(i) { - if (cpu_physical_id(i) == apic_id) - return i; - } - return -1; -} -EXPORT_SYMBOL_GPL(acpi_get_cpuid); -#endif - /* -------------------------------------------------------------------------- Driver Interface -------------------------------------------------------------------------- */ @@ -1071,11 +917,6 @@ static int __init acpi_processor_init(void) memset(&errata, 0, sizeof(errata)); -#ifdef CONFIG_SMP - if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_MADT, 0, - (struct acpi_table_header **)&madt))) - madt = NULL; -#endif #ifdef CONFIG_ACPI_PROCFS acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir); if (!acpi_processor_dir) -- cgit v0.10.2 From 5d554a7bb0643a6151a84319bfeba8270bf5269e Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Mon, 22 Feb 2010 12:11:29 -0700 Subject: ACPI: processor: add internal processor_physically_present() Detect if a processor is physically present before evaluating _PDC. We want this because some BIOS will provide a _PDC even for processors that are not present. These bogus _PDC methods then attempt to load non-existent tables, which causes problems. Avoid those bogus landmines. Acked-by: Venkatesh Pallipadi Signed-off-by: Alex Chiang Signed-off-by: Len Brown diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 9ae5cc2..f0c68c1 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -194,6 +194,45 @@ int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id) EXPORT_SYMBOL_GPL(acpi_get_cpuid); #endif +static bool processor_physically_present(acpi_handle handle) +{ + int cpuid, type; + u32 acpi_id; + acpi_status status; + acpi_object_type acpi_type; + unsigned long long tmp; + union acpi_object object = { 0 }; + struct acpi_buffer buffer = { sizeof(union acpi_object), &object }; + + status = acpi_get_type(handle, &acpi_type); + if (ACPI_FAILURE(status)) + return false; + + switch (acpi_type) { + case ACPI_TYPE_PROCESSOR: + status = acpi_evaluate_object(handle, NULL, NULL, &buffer); + if (ACPI_FAILURE(status)) + return false; + acpi_id = object.processor.proc_id; + break; + case ACPI_TYPE_DEVICE: + status = acpi_evaluate_integer(handle, "_UID", NULL, &tmp); + if (ACPI_FAILURE(status)) + return false; + acpi_id = tmp; + break; + default: + return false; + } + + type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0; + cpuid = acpi_get_cpuid(handle, type, acpi_id); + + if (cpuid == -1) + return false; + + return true; +} static void acpi_set_pdc_bits(u32 *buf) { @@ -335,6 +374,9 @@ static struct dmi_system_id __cpuinitdata early_pdc_optin_table[] = { static acpi_status early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv) { + if (processor_physically_present(handle) == false) + return AE_OK; + acpi_processor_set_pdc(handle); return AE_OK; } -- cgit v0.10.2 From 3b1da4c5d1032ebc29fec8bd8f592ba6589be8ed Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Mon, 22 Feb 2010 12:11:34 -0700 Subject: ACPI: processor: remove early _PDC optin quirks Now that we check for physically present processors before blindly evaluating _PDC, we no longer need to maintain a DMI opt-in table nor a kernel param. Acked-by: Venkatesh Pallipadi Signed-off-by: Alex Chiang Signed-off-by: Len Brown diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 3bc48b0..e4cbca5 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -200,10 +200,6 @@ and is between 256 and 4096 characters. It is defined in the file acpi_display_output=video See above. - acpi_early_pdc_eval [HW,ACPI] Evaluate processor _PDC methods - early. Needed on some platforms to properly - initialize the EC. - acpi_irq_balance [HW,ACPI] ACPI will balance active IRQs default in APIC mode diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index f0c68c1..ef34faa 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -341,36 +341,6 @@ void acpi_processor_set_pdc(acpi_handle handle) } EXPORT_SYMBOL_GPL(acpi_processor_set_pdc); -static int early_pdc_optin; -static int set_early_pdc_optin(const struct dmi_system_id *id) -{ - early_pdc_optin = 1; - return 0; -} - -static int param_early_pdc_optin(char *s) -{ - early_pdc_optin = 1; - return 1; -} -__setup("acpi_early_pdc_eval", param_early_pdc_optin); - -static struct dmi_system_id __cpuinitdata early_pdc_optin_table[] = { - { - set_early_pdc_optin, "HP Envy", { - DMI_MATCH(DMI_BIOS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP Envy") }, NULL}, - { - set_early_pdc_optin, "HP Pavilion dv6", { - DMI_MATCH(DMI_BIOS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv6") }, NULL}, - { - set_early_pdc_optin, "HP Pavilion dv7", { - DMI_MATCH(DMI_BIOS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv7") }, NULL}, - {}, -}; - static acpi_status early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv) { @@ -396,13 +366,6 @@ void __init acpi_early_processor_set_pdc(void) */ dmi_check_system(processor_idle_dmi_table); - /* - * Allow systems to opt-in to early _PDC evaluation. - */ - dmi_check_system(early_pdc_optin_table); - if (!early_pdc_optin) - return; - acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, early_init_pdc, NULL, NULL, NULL); -- cgit v0.10.2 From d8191fa4a33fdc817277da4f2b7f771ff605a41c Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Mon, 22 Feb 2010 12:11:39 -0700 Subject: ACPI: processor: driver doesn't need to evaluate _PDC Now that the early _PDC evaluation path knows how to correctly evaluate _PDC on only physically present processors, there's no need for the processor driver to evaluate it later when it loads. To cover the hotplug case, push _PDC evaluation down into the hotplug paths. Cc: x86@kernel.org Cc: Tony Luck Acked-by: Venkatesh Pallipadi Signed-off-by: Alex Chiang Signed-off-by: Len Brown diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index a7ca07f..f1c9f70 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -907,6 +908,8 @@ int acpi_map_lsapic(acpi_handle handle, int *pcpu) cpu_set(cpu, cpu_present_map); ia64_cpu_to_sapicid[cpu] = physid; + acpi_processor_set_pdc(handle); + *pcpu = cpu; return (0); } diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index a54d714..d635a93 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -490,6 +490,7 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity) * ACPI based hotplug support for CPU */ #ifdef CONFIG_ACPI_HOTPLUG_CPU +#include static void acpi_map_cpu2node(acpi_handle handle, int cpu, int physid) { @@ -567,6 +568,8 @@ static int __cpuinit _acpi_map_lsapic(acpi_handle handle, int *pcpu) goto free_new_map; } + acpi_processor_set_pdc(handle); + cpu = cpumask_first(new_map); acpi_map_cpu2node(handle, cpu, physid); diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index ef34faa..626c754 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -317,8 +317,6 @@ acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in) return status; } -static int early_pdc_done; - void acpi_processor_set_pdc(acpi_handle handle) { struct acpi_object_list *obj_list; @@ -326,9 +324,6 @@ void acpi_processor_set_pdc(acpi_handle handle) if (arch_has_acpi_pdc() == false) return; - if (early_pdc_done) - return; - obj_list = acpi_processor_alloc_pdc(); if (!obj_list) return; @@ -369,6 +364,4 @@ void __init acpi_early_processor_set_pdc(void) acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, early_init_pdc, NULL, NULL, NULL); - - early_pdc_done = 1; } diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 7eedf74..b5658cd 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -608,9 +608,6 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device) goto err_remove_fs; } - /* _PDC call should be done before doing anything else (if reqd.). */ - acpi_processor_set_pdc(pr->handle); - #ifdef CONFIG_CPU_FREQ acpi_processor_ppc_has_changed(pr, 0); #endif -- cgit v0.10.2 From 11130736c99c37e253f45b2d3fd30b07313f83c6 Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Mon, 22 Feb 2010 12:11:44 -0700 Subject: ACPI: processor: refactor internal map_lapic_id() Untangle the if() statement a little for readability. Acked-by: Venkatesh Pallipadi Signed-off-by: Alex Chiang Signed-off-by: Len Brown diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 626c754..9eeda9e 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -50,12 +50,15 @@ static int map_lapic_id(struct acpi_subtable_header *entry, { struct acpi_madt_local_apic *lapic = (struct acpi_madt_local_apic *)entry; - if ((lapic->lapic_flags & ACPI_MADT_ENABLED) && - lapic->processor_id == acpi_id) { - *apic_id = lapic->id; - return 1; - } - return 0; + + if (!(lapic->lapic_flags & ACPI_MADT_ENABLED)) + return 0; + + if (lapic->processor_id != acpi_id) + return 0; + + *apic_id = lapic->id; + return 1; } static int map_x2apic_id(struct acpi_subtable_header *entry, -- cgit v0.10.2 From d67420956b7b1dcffb894b2f1f81b9408fca1b4c Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Mon, 22 Feb 2010 12:11:50 -0700 Subject: ACPI: processor: refactor internal map_x2apic_id() Untangle the nested if conditions to make this function look more similar to the other map_*apic_id() functions. Acked-by: Venkatesh Pallipadi Signed-off-by: Alex Chiang Signed-off-by: Len Brown diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 9eeda9e..18fa633 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -66,22 +66,16 @@ static int map_x2apic_id(struct acpi_subtable_header *entry, { struct acpi_madt_local_x2apic *apic = (struct acpi_madt_local_x2apic *)entry; - u32 tmp = apic->local_apic_id; - /* Only check enabled APICs*/ if (!(apic->lapic_flags & ACPI_MADT_ENABLED)) return 0; - /* Device statement declaration type */ - if (device_declaration) { - if (apic->uid == acpi_id) - goto found; + if (device_declaration && (apic->uid == acpi_id)) { + *apic_id = apic->local_apic_id; + return 1; } return 0; -found: - *apic_id = tmp; - return 1; } static int map_lsapic_id(struct acpi_subtable_header *entry, -- cgit v0.10.2 From eae701ceadf5aa3fc3b334029ef71f6885ef1cde Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Mon, 22 Feb 2010 12:11:55 -0700 Subject: ACPI: processor: refactor internal map_lsapic_id() Un-nest the if statements for readability. Remove comments that re-state the obvious. Change the control flow so that we no longer need a temp variable. Acked-by: Venkatesh Pallipadi Signed-off-by: Alex Chiang Signed-off-by: Len Brown diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 18fa633..ee9bce1 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -83,27 +83,17 @@ static int map_lsapic_id(struct acpi_subtable_header *entry, { struct acpi_madt_local_sapic *lsapic = (struct acpi_madt_local_sapic *)entry; - u32 tmp = (lsapic->id << 8) | lsapic->eid; - /* Only check enabled APICs*/ if (!(lsapic->lapic_flags & ACPI_MADT_ENABLED)) return 0; - /* Device statement declaration type */ if (device_declaration) { - if (entry->length < 16) - printk(KERN_ERR PREFIX - "Invalid LSAPIC with Device type processor (SAPIC ID %#x)\n", - tmp); - else if (lsapic->uid == acpi_id) - goto found; - /* Processor statement declaration type */ - } else if (lsapic->processor_id == acpi_id) - goto found; + if ((entry->length < 16) || (lsapic->uid != acpi_id)) + return 0; + } else if (lsapic->processor_id != acpi_id) + return 0; - return 0; -found: - *apic_id = tmp; + *apic_id = (lsapic->id << 8) | lsapic->eid; return 1; } -- cgit v0.10.2 From 149fe9c293f76803206648270ca24fc2604d5f01 Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Mon, 22 Feb 2010 12:12:00 -0700 Subject: ACPI: processor: push file static MADT pointer into internal map_madt_entry() There's no real need for a pointer to the MADT to be global. The only function who uses it is map_madt_entry. This allows us to remove some more ugly #ifdefs. Acked-by: Venkatesh Pallipadi Signed-off-by: Alex Chiang Signed-off-by: Len Brown diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index ee9bce1..791ac7b 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -43,8 +43,6 @@ static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = { }; #ifdef CONFIG_SMP -static struct acpi_table_madt *madt; - static int map_lapic_id(struct acpi_subtable_header *entry, u32 acpi_id, int *apic_id) { @@ -100,8 +98,17 @@ static int map_lsapic_id(struct acpi_subtable_header *entry, static int map_madt_entry(int type, u32 acpi_id) { unsigned long madt_end, entry; + static struct acpi_table_madt *madt; + static int read_madt; int apic_id = -1; + if (!read_madt) { + if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_MADT, 0, + (struct acpi_table_header **)&madt))) + madt = NULL; + read_madt++; + } + if (!madt) return apic_id; @@ -335,13 +342,6 @@ early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv) void __init acpi_early_processor_set_pdc(void) { - -#ifdef CONFIG_SMP - if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_MADT, 0, - (struct acpi_table_header **)&madt))) - madt = NULL; -#endif - /* * Check whether the system is DMI table. If yes, OSPM * should not use mwait for CPU-states. -- cgit v0.10.2 From 0a10c85129c2d53cfd6db81677628e2fe58b5928 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 11 Mar 2010 21:19:14 +0000 Subject: drm/radeon: create radeon_asic.c And move asic init plus a few related functions from radeon_device.c to it. This file will hold all the asic structures in the future, but atm they're still stuck in radeon_asic.h. Signed-off-by: Daniel Vetter Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile index ed38262..3c91312 100644 --- a/drivers/gpu/drm/radeon/Makefile +++ b/drivers/gpu/drm/radeon/Makefile @@ -50,7 +50,7 @@ $(obj)/r600_cs.o: $(obj)/r600_reg_safe.h radeon-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o \ radeon_irq.o r300_cmdbuf.o r600_cp.o # add KMS driver -radeon-y += radeon_device.o radeon_kms.o \ +radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \ radeon_atombios.o radeon_agp.o atombios_crtc.o radeon_combios.o \ atom.o radeon_fence.o radeon_ttm.o radeon_object.o radeon_gart.o \ radeon_legacy_crtc.o radeon_legacy_encoders.o radeon_connectors.o \ diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index b54d4f3..67f3c57 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -863,6 +863,12 @@ union radeon_asic_config { struct rv770_asic rv770; }; +/* + * asic initizalization from radeon_asic.c + */ +void radeon_agp_disable(struct radeon_device *rdev); +int radeon_asic_init(struct radeon_device *rdev); + /* * IOCTL. diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c new file mode 100644 index 0000000..9dffaed --- /dev/null +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -0,0 +1,236 @@ +/* + * Copyright 2008 Advanced Micro Devices, Inc. + * Copyright 2008 Red Hat Inc. + * Copyright 2009 Jerome Glisse. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Dave Airlie + * Alex Deucher + * Jerome Glisse + */ + +#include +#include +#include +#include +#include +#include +#include "radeon_reg.h" +#include "radeon.h" +#include "radeon_asic.h" +#include "atom.h" + +/* + * Registers accessors functions. + */ +static uint32_t radeon_invalid_rreg(struct radeon_device *rdev, uint32_t reg) +{ + DRM_ERROR("Invalid callback to read register 0x%04X\n", reg); + BUG_ON(1); + return 0; +} + +static void radeon_invalid_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) +{ + DRM_ERROR("Invalid callback to write register 0x%04X with 0x%08X\n", + reg, v); + BUG_ON(1); +} + +static void radeon_register_accessor_init(struct radeon_device *rdev) +{ + rdev->mc_rreg = &radeon_invalid_rreg; + rdev->mc_wreg = &radeon_invalid_wreg; + rdev->pll_rreg = &radeon_invalid_rreg; + rdev->pll_wreg = &radeon_invalid_wreg; + rdev->pciep_rreg = &radeon_invalid_rreg; + rdev->pciep_wreg = &radeon_invalid_wreg; + + /* Don't change order as we are overridding accessor. */ + if (rdev->family < CHIP_RV515) { + rdev->pcie_reg_mask = 0xff; + } else { + rdev->pcie_reg_mask = 0x7ff; + } + /* FIXME: not sure here */ + if (rdev->family <= CHIP_R580) { + rdev->pll_rreg = &r100_pll_rreg; + rdev->pll_wreg = &r100_pll_wreg; + } + if (rdev->family >= CHIP_R420) { + rdev->mc_rreg = &r420_mc_rreg; + rdev->mc_wreg = &r420_mc_wreg; + } + if (rdev->family >= CHIP_RV515) { + rdev->mc_rreg = &rv515_mc_rreg; + rdev->mc_wreg = &rv515_mc_wreg; + } + if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480) { + rdev->mc_rreg = &rs400_mc_rreg; + rdev->mc_wreg = &rs400_mc_wreg; + } + if (rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) { + rdev->mc_rreg = &rs690_mc_rreg; + rdev->mc_wreg = &rs690_mc_wreg; + } + if (rdev->family == CHIP_RS600) { + rdev->mc_rreg = &rs600_mc_rreg; + rdev->mc_wreg = &rs600_mc_wreg; + } + if ((rdev->family >= CHIP_R600) && (rdev->family <= CHIP_RV740)) { + rdev->pciep_rreg = &r600_pciep_rreg; + rdev->pciep_wreg = &r600_pciep_wreg; + } +} + + +/* helper to disable agp */ +void radeon_agp_disable(struct radeon_device *rdev) +{ + rdev->flags &= ~RADEON_IS_AGP; + if (rdev->family >= CHIP_R600) { + DRM_INFO("Forcing AGP to PCIE mode\n"); + rdev->flags |= RADEON_IS_PCIE; + } else if (rdev->family >= CHIP_RV515 || + rdev->family == CHIP_RV380 || + rdev->family == CHIP_RV410 || + rdev->family == CHIP_R423) { + DRM_INFO("Forcing AGP to PCIE mode\n"); + rdev->flags |= RADEON_IS_PCIE; + rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush; + rdev->asic->gart_set_page = &rv370_pcie_gart_set_page; + } else { + DRM_INFO("Forcing AGP to PCI mode\n"); + rdev->flags |= RADEON_IS_PCI; + rdev->asic->gart_tlb_flush = &r100_pci_gart_tlb_flush; + rdev->asic->gart_set_page = &r100_pci_gart_set_page; + } + rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; +} + +/* + * ASIC + */ +int radeon_asic_init(struct radeon_device *rdev) +{ + radeon_register_accessor_init(rdev); + switch (rdev->family) { + case CHIP_R100: + case CHIP_RV100: + case CHIP_RS100: + case CHIP_RV200: + case CHIP_RS200: + rdev->asic = &r100_asic; + break; + case CHIP_R200: + case CHIP_RV250: + case CHIP_RS300: + case CHIP_RV280: + rdev->asic = &r200_asic; + break; + case CHIP_R300: + case CHIP_R350: + case CHIP_RV350: + case CHIP_RV380: + if (rdev->flags & RADEON_IS_PCIE) + rdev->asic = &r300_asic_pcie; + else + rdev->asic = &r300_asic; + break; + case CHIP_R420: + case CHIP_R423: + case CHIP_RV410: + rdev->asic = &r420_asic; + break; + case CHIP_RS400: + case CHIP_RS480: + rdev->asic = &rs400_asic; + break; + case CHIP_RS600: + rdev->asic = &rs600_asic; + break; + case CHIP_RS690: + case CHIP_RS740: + rdev->asic = &rs690_asic; + break; + case CHIP_RV515: + rdev->asic = &rv515_asic; + break; + case CHIP_R520: + case CHIP_RV530: + case CHIP_RV560: + case CHIP_RV570: + case CHIP_R580: + rdev->asic = &r520_asic; + break; + case CHIP_R600: + case CHIP_RV610: + case CHIP_RV630: + case CHIP_RV620: + case CHIP_RV635: + case CHIP_RV670: + case CHIP_RS780: + case CHIP_RS880: + rdev->asic = &r600_asic; + break; + case CHIP_RV770: + case CHIP_RV730: + case CHIP_RV710: + case CHIP_RV740: + rdev->asic = &rv770_asic; + break; + case CHIP_CEDAR: + case CHIP_REDWOOD: + case CHIP_JUNIPER: + case CHIP_CYPRESS: + case CHIP_HEMLOCK: + rdev->asic = &evergreen_asic; + break; + default: + /* FIXME: not supported yet */ + return -EINVAL; + } + + if (rdev->flags & RADEON_IS_IGP) { + rdev->asic->get_memory_clock = NULL; + rdev->asic->set_memory_clock = NULL; + } + + return 0; +} + +/* + * Wrapper around modesetting bits. Move to radeon_clocks.c? + */ +int radeon_clocks_init(struct radeon_device *rdev) +{ + int r; + + r = radeon_static_clocks_init(rdev->ddev); + if (r) { + return r; + } + DRM_INFO("Clocks initialized !\n"); + return 0; +} + +void radeon_clocks_fini(struct radeon_device *rdev) +{ +} diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index e28e4ed..581b75a 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -33,7 +33,6 @@ #include #include "radeon_reg.h" #include "radeon.h" -#include "radeon_asic.h" #include "atom.h" /* @@ -288,181 +287,6 @@ void radeon_dummy_page_fini(struct radeon_device *rdev) } -/* - * Registers accessors functions. - */ -uint32_t radeon_invalid_rreg(struct radeon_device *rdev, uint32_t reg) -{ - DRM_ERROR("Invalid callback to read register 0x%04X\n", reg); - BUG_ON(1); - return 0; -} - -void radeon_invalid_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) -{ - DRM_ERROR("Invalid callback to write register 0x%04X with 0x%08X\n", - reg, v); - BUG_ON(1); -} - -void radeon_register_accessor_init(struct radeon_device *rdev) -{ - rdev->mc_rreg = &radeon_invalid_rreg; - rdev->mc_wreg = &radeon_invalid_wreg; - rdev->pll_rreg = &radeon_invalid_rreg; - rdev->pll_wreg = &radeon_invalid_wreg; - rdev->pciep_rreg = &radeon_invalid_rreg; - rdev->pciep_wreg = &radeon_invalid_wreg; - - /* Don't change order as we are overridding accessor. */ - if (rdev->family < CHIP_RV515) { - rdev->pcie_reg_mask = 0xff; - } else { - rdev->pcie_reg_mask = 0x7ff; - } - /* FIXME: not sure here */ - if (rdev->family <= CHIP_R580) { - rdev->pll_rreg = &r100_pll_rreg; - rdev->pll_wreg = &r100_pll_wreg; - } - if (rdev->family >= CHIP_R420) { - rdev->mc_rreg = &r420_mc_rreg; - rdev->mc_wreg = &r420_mc_wreg; - } - if (rdev->family >= CHIP_RV515) { - rdev->mc_rreg = &rv515_mc_rreg; - rdev->mc_wreg = &rv515_mc_wreg; - } - if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480) { - rdev->mc_rreg = &rs400_mc_rreg; - rdev->mc_wreg = &rs400_mc_wreg; - } - if (rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) { - rdev->mc_rreg = &rs690_mc_rreg; - rdev->mc_wreg = &rs690_mc_wreg; - } - if (rdev->family == CHIP_RS600) { - rdev->mc_rreg = &rs600_mc_rreg; - rdev->mc_wreg = &rs600_mc_wreg; - } - if ((rdev->family >= CHIP_R600) && (rdev->family <= CHIP_RV740)) { - rdev->pciep_rreg = &r600_pciep_rreg; - rdev->pciep_wreg = &r600_pciep_wreg; - } -} - - -/* - * ASIC - */ -int radeon_asic_init(struct radeon_device *rdev) -{ - radeon_register_accessor_init(rdev); - switch (rdev->family) { - case CHIP_R100: - case CHIP_RV100: - case CHIP_RS100: - case CHIP_RV200: - case CHIP_RS200: - rdev->asic = &r100_asic; - break; - case CHIP_R200: - case CHIP_RV250: - case CHIP_RS300: - case CHIP_RV280: - rdev->asic = &r200_asic; - break; - case CHIP_R300: - case CHIP_R350: - case CHIP_RV350: - case CHIP_RV380: - if (rdev->flags & RADEON_IS_PCIE) - rdev->asic = &r300_asic_pcie; - else - rdev->asic = &r300_asic; - break; - case CHIP_R420: - case CHIP_R423: - case CHIP_RV410: - rdev->asic = &r420_asic; - break; - case CHIP_RS400: - case CHIP_RS480: - rdev->asic = &rs400_asic; - break; - case CHIP_RS600: - rdev->asic = &rs600_asic; - break; - case CHIP_RS690: - case CHIP_RS740: - rdev->asic = &rs690_asic; - break; - case CHIP_RV515: - rdev->asic = &rv515_asic; - break; - case CHIP_R520: - case CHIP_RV530: - case CHIP_RV560: - case CHIP_RV570: - case CHIP_R580: - rdev->asic = &r520_asic; - break; - case CHIP_R600: - case CHIP_RV610: - case CHIP_RV630: - case CHIP_RV620: - case CHIP_RV635: - case CHIP_RV670: - case CHIP_RS780: - case CHIP_RS880: - rdev->asic = &r600_asic; - break; - case CHIP_RV770: - case CHIP_RV730: - case CHIP_RV710: - case CHIP_RV740: - rdev->asic = &rv770_asic; - break; - case CHIP_CEDAR: - case CHIP_REDWOOD: - case CHIP_JUNIPER: - case CHIP_CYPRESS: - case CHIP_HEMLOCK: - rdev->asic = &evergreen_asic; - break; - default: - /* FIXME: not supported yet */ - return -EINVAL; - } - - if (rdev->flags & RADEON_IS_IGP) { - rdev->asic->get_memory_clock = NULL; - rdev->asic->set_memory_clock = NULL; - } - - return 0; -} - - -/* - * Wrapper around modesetting bits. - */ -int radeon_clocks_init(struct radeon_device *rdev) -{ - int r; - - r = radeon_static_clocks_init(rdev->ddev); - if (r) { - return r; - } - DRM_INFO("Clocks initialized !\n"); - return 0; -} - -void radeon_clocks_fini(struct radeon_device *rdev) -{ -} - /* ATOM accessor methods */ static uint32_t cail_pll_read(struct card_info *info, uint32_t reg) { @@ -567,29 +391,6 @@ static unsigned int radeon_vga_set_decode(void *cookie, bool state) return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; } -void radeon_agp_disable(struct radeon_device *rdev) -{ - rdev->flags &= ~RADEON_IS_AGP; - if (rdev->family >= CHIP_R600) { - DRM_INFO("Forcing AGP to PCIE mode\n"); - rdev->flags |= RADEON_IS_PCIE; - } else if (rdev->family >= CHIP_RV515 || - rdev->family == CHIP_RV380 || - rdev->family == CHIP_RV410 || - rdev->family == CHIP_R423) { - DRM_INFO("Forcing AGP to PCIE mode\n"); - rdev->flags |= RADEON_IS_PCIE; - rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush; - rdev->asic->gart_set_page = &rv370_pcie_gart_set_page; - } else { - DRM_INFO("Forcing AGP to PCI mode\n"); - rdev->flags |= RADEON_IS_PCI; - rdev->asic->gart_tlb_flush = &r100_pci_gart_tlb_flush; - rdev->asic->gart_set_page = &r100_pci_gart_set_page; - } - rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; -} - void radeon_check_arguments(struct radeon_device *rdev) { /* vramlimit must be a power of two */ -- cgit v0.10.2 From 48e7a5f19fe0c10ebb35be7acf383366d139ee0a Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 11 Mar 2010 21:19:15 +0000 Subject: drm/radeon: move asic structs to radeon_asic.c With these static structs gone, radeon_asic.h is a real header file and can be used as such. Signed-off-by: Daniel Vetter Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 9dffaed..6d2a5457 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -128,6 +128,493 @@ void radeon_agp_disable(struct radeon_device *rdev) /* * ASIC */ +static struct radeon_asic r100_asic = { + .init = &r100_init, + .fini = &r100_fini, + .suspend = &r100_suspend, + .resume = &r100_resume, + .vga_set_state = &r100_vga_set_state, + .gpu_reset = &r100_gpu_reset, + .gart_tlb_flush = &r100_pci_gart_tlb_flush, + .gart_set_page = &r100_pci_gart_set_page, + .cp_commit = &r100_cp_commit, + .ring_start = &r100_ring_start, + .ring_test = &r100_ring_test, + .ring_ib_execute = &r100_ring_ib_execute, + .irq_set = &r100_irq_set, + .irq_process = &r100_irq_process, + .get_vblank_counter = &r100_get_vblank_counter, + .fence_ring_emit = &r100_fence_ring_emit, + .cs_parse = &r100_cs_parse, + .copy_blit = &r100_copy_blit, + .copy_dma = NULL, + .copy = &r100_copy_blit, + .get_engine_clock = &radeon_legacy_get_engine_clock, + .set_engine_clock = &radeon_legacy_set_engine_clock, + .get_memory_clock = &radeon_legacy_get_memory_clock, + .set_memory_clock = NULL, + .get_pcie_lanes = NULL, + .set_pcie_lanes = NULL, + .set_clock_gating = &radeon_legacy_set_clock_gating, + .set_surface_reg = r100_set_surface_reg, + .clear_surface_reg = r100_clear_surface_reg, + .bandwidth_update = &r100_bandwidth_update, + .hpd_init = &r100_hpd_init, + .hpd_fini = &r100_hpd_fini, + .hpd_sense = &r100_hpd_sense, + .hpd_set_polarity = &r100_hpd_set_polarity, + .ioctl_wait_idle = NULL, +}; + +static struct radeon_asic r200_asic = { + .init = &r100_init, + .fini = &r100_fini, + .suspend = &r100_suspend, + .resume = &r100_resume, + .vga_set_state = &r100_vga_set_state, + .gpu_reset = &r100_gpu_reset, + .gart_tlb_flush = &r100_pci_gart_tlb_flush, + .gart_set_page = &r100_pci_gart_set_page, + .cp_commit = &r100_cp_commit, + .ring_start = &r100_ring_start, + .ring_test = &r100_ring_test, + .ring_ib_execute = &r100_ring_ib_execute, + .irq_set = &r100_irq_set, + .irq_process = &r100_irq_process, + .get_vblank_counter = &r100_get_vblank_counter, + .fence_ring_emit = &r100_fence_ring_emit, + .cs_parse = &r100_cs_parse, + .copy_blit = &r100_copy_blit, + .copy_dma = &r200_copy_dma, + .copy = &r100_copy_blit, + .get_engine_clock = &radeon_legacy_get_engine_clock, + .set_engine_clock = &radeon_legacy_set_engine_clock, + .get_memory_clock = &radeon_legacy_get_memory_clock, + .set_memory_clock = NULL, + .set_pcie_lanes = NULL, + .set_clock_gating = &radeon_legacy_set_clock_gating, + .set_surface_reg = r100_set_surface_reg, + .clear_surface_reg = r100_clear_surface_reg, + .bandwidth_update = &r100_bandwidth_update, + .hpd_init = &r100_hpd_init, + .hpd_fini = &r100_hpd_fini, + .hpd_sense = &r100_hpd_sense, + .hpd_set_polarity = &r100_hpd_set_polarity, + .ioctl_wait_idle = NULL, +}; + +static struct radeon_asic r300_asic = { + .init = &r300_init, + .fini = &r300_fini, + .suspend = &r300_suspend, + .resume = &r300_resume, + .vga_set_state = &r100_vga_set_state, + .gpu_reset = &r300_gpu_reset, + .gart_tlb_flush = &r100_pci_gart_tlb_flush, + .gart_set_page = &r100_pci_gart_set_page, + .cp_commit = &r100_cp_commit, + .ring_start = &r300_ring_start, + .ring_test = &r100_ring_test, + .ring_ib_execute = &r100_ring_ib_execute, + .irq_set = &r100_irq_set, + .irq_process = &r100_irq_process, + .get_vblank_counter = &r100_get_vblank_counter, + .fence_ring_emit = &r300_fence_ring_emit, + .cs_parse = &r300_cs_parse, + .copy_blit = &r100_copy_blit, + .copy_dma = &r200_copy_dma, + .copy = &r100_copy_blit, + .get_engine_clock = &radeon_legacy_get_engine_clock, + .set_engine_clock = &radeon_legacy_set_engine_clock, + .get_memory_clock = &radeon_legacy_get_memory_clock, + .set_memory_clock = NULL, + .get_pcie_lanes = &rv370_get_pcie_lanes, + .set_pcie_lanes = &rv370_set_pcie_lanes, + .set_clock_gating = &radeon_legacy_set_clock_gating, + .set_surface_reg = r100_set_surface_reg, + .clear_surface_reg = r100_clear_surface_reg, + .bandwidth_update = &r100_bandwidth_update, + .hpd_init = &r100_hpd_init, + .hpd_fini = &r100_hpd_fini, + .hpd_sense = &r100_hpd_sense, + .hpd_set_polarity = &r100_hpd_set_polarity, + .ioctl_wait_idle = NULL, +}; + +static struct radeon_asic r300_asic_pcie = { + .init = &r300_init, + .fini = &r300_fini, + .suspend = &r300_suspend, + .resume = &r300_resume, + .vga_set_state = &r100_vga_set_state, + .gpu_reset = &r300_gpu_reset, + .gart_tlb_flush = &rv370_pcie_gart_tlb_flush, + .gart_set_page = &rv370_pcie_gart_set_page, + .cp_commit = &r100_cp_commit, + .ring_start = &r300_ring_start, + .ring_test = &r100_ring_test, + .ring_ib_execute = &r100_ring_ib_execute, + .irq_set = &r100_irq_set, + .irq_process = &r100_irq_process, + .get_vblank_counter = &r100_get_vblank_counter, + .fence_ring_emit = &r300_fence_ring_emit, + .cs_parse = &r300_cs_parse, + .copy_blit = &r100_copy_blit, + .copy_dma = &r200_copy_dma, + .copy = &r100_copy_blit, + .get_engine_clock = &radeon_legacy_get_engine_clock, + .set_engine_clock = &radeon_legacy_set_engine_clock, + .get_memory_clock = &radeon_legacy_get_memory_clock, + .set_memory_clock = NULL, + .set_pcie_lanes = &rv370_set_pcie_lanes, + .set_clock_gating = &radeon_legacy_set_clock_gating, + .set_surface_reg = r100_set_surface_reg, + .clear_surface_reg = r100_clear_surface_reg, + .bandwidth_update = &r100_bandwidth_update, + .hpd_init = &r100_hpd_init, + .hpd_fini = &r100_hpd_fini, + .hpd_sense = &r100_hpd_sense, + .hpd_set_polarity = &r100_hpd_set_polarity, + .ioctl_wait_idle = NULL, +}; + +static struct radeon_asic r420_asic = { + .init = &r420_init, + .fini = &r420_fini, + .suspend = &r420_suspend, + .resume = &r420_resume, + .vga_set_state = &r100_vga_set_state, + .gpu_reset = &r300_gpu_reset, + .gart_tlb_flush = &rv370_pcie_gart_tlb_flush, + .gart_set_page = &rv370_pcie_gart_set_page, + .cp_commit = &r100_cp_commit, + .ring_start = &r300_ring_start, + .ring_test = &r100_ring_test, + .ring_ib_execute = &r100_ring_ib_execute, + .irq_set = &r100_irq_set, + .irq_process = &r100_irq_process, + .get_vblank_counter = &r100_get_vblank_counter, + .fence_ring_emit = &r300_fence_ring_emit, + .cs_parse = &r300_cs_parse, + .copy_blit = &r100_copy_blit, + .copy_dma = &r200_copy_dma, + .copy = &r100_copy_blit, + .get_engine_clock = &radeon_atom_get_engine_clock, + .set_engine_clock = &radeon_atom_set_engine_clock, + .get_memory_clock = &radeon_atom_get_memory_clock, + .set_memory_clock = &radeon_atom_set_memory_clock, + .get_pcie_lanes = &rv370_get_pcie_lanes, + .set_pcie_lanes = &rv370_set_pcie_lanes, + .set_clock_gating = &radeon_atom_set_clock_gating, + .set_surface_reg = r100_set_surface_reg, + .clear_surface_reg = r100_clear_surface_reg, + .bandwidth_update = &r100_bandwidth_update, + .hpd_init = &r100_hpd_init, + .hpd_fini = &r100_hpd_fini, + .hpd_sense = &r100_hpd_sense, + .hpd_set_polarity = &r100_hpd_set_polarity, + .ioctl_wait_idle = NULL, +}; + +static struct radeon_asic rs400_asic = { + .init = &rs400_init, + .fini = &rs400_fini, + .suspend = &rs400_suspend, + .resume = &rs400_resume, + .vga_set_state = &r100_vga_set_state, + .gpu_reset = &r300_gpu_reset, + .gart_tlb_flush = &rs400_gart_tlb_flush, + .gart_set_page = &rs400_gart_set_page, + .cp_commit = &r100_cp_commit, + .ring_start = &r300_ring_start, + .ring_test = &r100_ring_test, + .ring_ib_execute = &r100_ring_ib_execute, + .irq_set = &r100_irq_set, + .irq_process = &r100_irq_process, + .get_vblank_counter = &r100_get_vblank_counter, + .fence_ring_emit = &r300_fence_ring_emit, + .cs_parse = &r300_cs_parse, + .copy_blit = &r100_copy_blit, + .copy_dma = &r200_copy_dma, + .copy = &r100_copy_blit, + .get_engine_clock = &radeon_legacy_get_engine_clock, + .set_engine_clock = &radeon_legacy_set_engine_clock, + .get_memory_clock = &radeon_legacy_get_memory_clock, + .set_memory_clock = NULL, + .get_pcie_lanes = NULL, + .set_pcie_lanes = NULL, + .set_clock_gating = &radeon_legacy_set_clock_gating, + .set_surface_reg = r100_set_surface_reg, + .clear_surface_reg = r100_clear_surface_reg, + .bandwidth_update = &r100_bandwidth_update, + .hpd_init = &r100_hpd_init, + .hpd_fini = &r100_hpd_fini, + .hpd_sense = &r100_hpd_sense, + .hpd_set_polarity = &r100_hpd_set_polarity, + .ioctl_wait_idle = NULL, +}; + +static struct radeon_asic rs600_asic = { + .init = &rs600_init, + .fini = &rs600_fini, + .suspend = &rs600_suspend, + .resume = &rs600_resume, + .vga_set_state = &r100_vga_set_state, + .gpu_reset = &r300_gpu_reset, + .gart_tlb_flush = &rs600_gart_tlb_flush, + .gart_set_page = &rs600_gart_set_page, + .cp_commit = &r100_cp_commit, + .ring_start = &r300_ring_start, + .ring_test = &r100_ring_test, + .ring_ib_execute = &r100_ring_ib_execute, + .irq_set = &rs600_irq_set, + .irq_process = &rs600_irq_process, + .get_vblank_counter = &rs600_get_vblank_counter, + .fence_ring_emit = &r300_fence_ring_emit, + .cs_parse = &r300_cs_parse, + .copy_blit = &r100_copy_blit, + .copy_dma = &r200_copy_dma, + .copy = &r100_copy_blit, + .get_engine_clock = &radeon_atom_get_engine_clock, + .set_engine_clock = &radeon_atom_set_engine_clock, + .get_memory_clock = &radeon_atom_get_memory_clock, + .set_memory_clock = &radeon_atom_set_memory_clock, + .get_pcie_lanes = NULL, + .set_pcie_lanes = NULL, + .set_clock_gating = &radeon_atom_set_clock_gating, + .set_surface_reg = r100_set_surface_reg, + .clear_surface_reg = r100_clear_surface_reg, + .bandwidth_update = &rs600_bandwidth_update, + .hpd_init = &rs600_hpd_init, + .hpd_fini = &rs600_hpd_fini, + .hpd_sense = &rs600_hpd_sense, + .hpd_set_polarity = &rs600_hpd_set_polarity, + .ioctl_wait_idle = NULL, +}; + +static struct radeon_asic rs690_asic = { + .init = &rs690_init, + .fini = &rs690_fini, + .suspend = &rs690_suspend, + .resume = &rs690_resume, + .vga_set_state = &r100_vga_set_state, + .gpu_reset = &r300_gpu_reset, + .gart_tlb_flush = &rs400_gart_tlb_flush, + .gart_set_page = &rs400_gart_set_page, + .cp_commit = &r100_cp_commit, + .ring_start = &r300_ring_start, + .ring_test = &r100_ring_test, + .ring_ib_execute = &r100_ring_ib_execute, + .irq_set = &rs600_irq_set, + .irq_process = &rs600_irq_process, + .get_vblank_counter = &rs600_get_vblank_counter, + .fence_ring_emit = &r300_fence_ring_emit, + .cs_parse = &r300_cs_parse, + .copy_blit = &r100_copy_blit, + .copy_dma = &r200_copy_dma, + .copy = &r200_copy_dma, + .get_engine_clock = &radeon_atom_get_engine_clock, + .set_engine_clock = &radeon_atom_set_engine_clock, + .get_memory_clock = &radeon_atom_get_memory_clock, + .set_memory_clock = &radeon_atom_set_memory_clock, + .get_pcie_lanes = NULL, + .set_pcie_lanes = NULL, + .set_clock_gating = &radeon_atom_set_clock_gating, + .set_surface_reg = r100_set_surface_reg, + .clear_surface_reg = r100_clear_surface_reg, + .bandwidth_update = &rs690_bandwidth_update, + .hpd_init = &rs600_hpd_init, + .hpd_fini = &rs600_hpd_fini, + .hpd_sense = &rs600_hpd_sense, + .hpd_set_polarity = &rs600_hpd_set_polarity, + .ioctl_wait_idle = NULL, +}; + +static struct radeon_asic rv515_asic = { + .init = &rv515_init, + .fini = &rv515_fini, + .suspend = &rv515_suspend, + .resume = &rv515_resume, + .vga_set_state = &r100_vga_set_state, + .gpu_reset = &rv515_gpu_reset, + .gart_tlb_flush = &rv370_pcie_gart_tlb_flush, + .gart_set_page = &rv370_pcie_gart_set_page, + .cp_commit = &r100_cp_commit, + .ring_start = &rv515_ring_start, + .ring_test = &r100_ring_test, + .ring_ib_execute = &r100_ring_ib_execute, + .irq_set = &rs600_irq_set, + .irq_process = &rs600_irq_process, + .get_vblank_counter = &rs600_get_vblank_counter, + .fence_ring_emit = &r300_fence_ring_emit, + .cs_parse = &r300_cs_parse, + .copy_blit = &r100_copy_blit, + .copy_dma = &r200_copy_dma, + .copy = &r100_copy_blit, + .get_engine_clock = &radeon_atom_get_engine_clock, + .set_engine_clock = &radeon_atom_set_engine_clock, + .get_memory_clock = &radeon_atom_get_memory_clock, + .set_memory_clock = &radeon_atom_set_memory_clock, + .get_pcie_lanes = &rv370_get_pcie_lanes, + .set_pcie_lanes = &rv370_set_pcie_lanes, + .set_clock_gating = &radeon_atom_set_clock_gating, + .set_surface_reg = r100_set_surface_reg, + .clear_surface_reg = r100_clear_surface_reg, + .bandwidth_update = &rv515_bandwidth_update, + .hpd_init = &rs600_hpd_init, + .hpd_fini = &rs600_hpd_fini, + .hpd_sense = &rs600_hpd_sense, + .hpd_set_polarity = &rs600_hpd_set_polarity, + .ioctl_wait_idle = NULL, +}; + +static struct radeon_asic r520_asic = { + .init = &r520_init, + .fini = &rv515_fini, + .suspend = &rv515_suspend, + .resume = &r520_resume, + .vga_set_state = &r100_vga_set_state, + .gpu_reset = &rv515_gpu_reset, + .gart_tlb_flush = &rv370_pcie_gart_tlb_flush, + .gart_set_page = &rv370_pcie_gart_set_page, + .cp_commit = &r100_cp_commit, + .ring_start = &rv515_ring_start, + .ring_test = &r100_ring_test, + .ring_ib_execute = &r100_ring_ib_execute, + .irq_set = &rs600_irq_set, + .irq_process = &rs600_irq_process, + .get_vblank_counter = &rs600_get_vblank_counter, + .fence_ring_emit = &r300_fence_ring_emit, + .cs_parse = &r300_cs_parse, + .copy_blit = &r100_copy_blit, + .copy_dma = &r200_copy_dma, + .copy = &r100_copy_blit, + .get_engine_clock = &radeon_atom_get_engine_clock, + .set_engine_clock = &radeon_atom_set_engine_clock, + .get_memory_clock = &radeon_atom_get_memory_clock, + .set_memory_clock = &radeon_atom_set_memory_clock, + .get_pcie_lanes = &rv370_get_pcie_lanes, + .set_pcie_lanes = &rv370_set_pcie_lanes, + .set_clock_gating = &radeon_atom_set_clock_gating, + .set_surface_reg = r100_set_surface_reg, + .clear_surface_reg = r100_clear_surface_reg, + .bandwidth_update = &rv515_bandwidth_update, + .hpd_init = &rs600_hpd_init, + .hpd_fini = &rs600_hpd_fini, + .hpd_sense = &rs600_hpd_sense, + .hpd_set_polarity = &rs600_hpd_set_polarity, + .ioctl_wait_idle = NULL, +}; + +static struct radeon_asic r600_asic = { + .init = &r600_init, + .fini = &r600_fini, + .suspend = &r600_suspend, + .resume = &r600_resume, + .cp_commit = &r600_cp_commit, + .vga_set_state = &r600_vga_set_state, + .gpu_reset = &r600_gpu_reset, + .gart_tlb_flush = &r600_pcie_gart_tlb_flush, + .gart_set_page = &rs600_gart_set_page, + .ring_test = &r600_ring_test, + .ring_ib_execute = &r600_ring_ib_execute, + .irq_set = &r600_irq_set, + .irq_process = &r600_irq_process, + .get_vblank_counter = &rs600_get_vblank_counter, + .fence_ring_emit = &r600_fence_ring_emit, + .cs_parse = &r600_cs_parse, + .copy_blit = &r600_copy_blit, + .copy_dma = &r600_copy_blit, + .copy = &r600_copy_blit, + .get_engine_clock = &radeon_atom_get_engine_clock, + .set_engine_clock = &radeon_atom_set_engine_clock, + .get_memory_clock = &radeon_atom_get_memory_clock, + .set_memory_clock = &radeon_atom_set_memory_clock, + .get_pcie_lanes = &rv370_get_pcie_lanes, + .set_pcie_lanes = NULL, + .set_clock_gating = NULL, + .set_surface_reg = r600_set_surface_reg, + .clear_surface_reg = r600_clear_surface_reg, + .bandwidth_update = &rv515_bandwidth_update, + .hpd_init = &r600_hpd_init, + .hpd_fini = &r600_hpd_fini, + .hpd_sense = &r600_hpd_sense, + .hpd_set_polarity = &r600_hpd_set_polarity, + .ioctl_wait_idle = r600_ioctl_wait_idle, +}; + +static struct radeon_asic rv770_asic = { + .init = &rv770_init, + .fini = &rv770_fini, + .suspend = &rv770_suspend, + .resume = &rv770_resume, + .cp_commit = &r600_cp_commit, + .gpu_reset = &rv770_gpu_reset, + .vga_set_state = &r600_vga_set_state, + .gart_tlb_flush = &r600_pcie_gart_tlb_flush, + .gart_set_page = &rs600_gart_set_page, + .ring_test = &r600_ring_test, + .ring_ib_execute = &r600_ring_ib_execute, + .irq_set = &r600_irq_set, + .irq_process = &r600_irq_process, + .get_vblank_counter = &rs600_get_vblank_counter, + .fence_ring_emit = &r600_fence_ring_emit, + .cs_parse = &r600_cs_parse, + .copy_blit = &r600_copy_blit, + .copy_dma = &r600_copy_blit, + .copy = &r600_copy_blit, + .get_engine_clock = &radeon_atom_get_engine_clock, + .set_engine_clock = &radeon_atom_set_engine_clock, + .get_memory_clock = &radeon_atom_get_memory_clock, + .set_memory_clock = &radeon_atom_set_memory_clock, + .get_pcie_lanes = &rv370_get_pcie_lanes, + .set_pcie_lanes = NULL, + .set_clock_gating = &radeon_atom_set_clock_gating, + .set_surface_reg = r600_set_surface_reg, + .clear_surface_reg = r600_clear_surface_reg, + .bandwidth_update = &rv515_bandwidth_update, + .hpd_init = &r600_hpd_init, + .hpd_fini = &r600_hpd_fini, + .hpd_sense = &r600_hpd_sense, + .hpd_set_polarity = &r600_hpd_set_polarity, + .ioctl_wait_idle = r600_ioctl_wait_idle, +}; + +static struct radeon_asic evergreen_asic = { + .init = &evergreen_init, + .fini = &evergreen_fini, + .suspend = &evergreen_suspend, + .resume = &evergreen_resume, + .cp_commit = NULL, + .gpu_reset = &evergreen_gpu_reset, + .vga_set_state = &r600_vga_set_state, + .gart_tlb_flush = &r600_pcie_gart_tlb_flush, + .gart_set_page = &rs600_gart_set_page, + .ring_test = NULL, + .ring_ib_execute = NULL, + .irq_set = NULL, + .irq_process = NULL, + .get_vblank_counter = NULL, + .fence_ring_emit = NULL, + .cs_parse = NULL, + .copy_blit = NULL, + .copy_dma = NULL, + .copy = NULL, + .get_engine_clock = &radeon_atom_get_engine_clock, + .set_engine_clock = &radeon_atom_set_engine_clock, + .get_memory_clock = &radeon_atom_get_memory_clock, + .set_memory_clock = &radeon_atom_set_memory_clock, + .set_pcie_lanes = NULL, + .set_clock_gating = NULL, + .set_surface_reg = r600_set_surface_reg, + .clear_surface_reg = r600_clear_surface_reg, + .bandwidth_update = &evergreen_bandwidth_update, + .hpd_init = &evergreen_hpd_init, + .hpd_fini = &evergreen_hpd_fini, + .hpd_sense = &evergreen_hpd_sense, + .hpd_set_polarity = &evergreen_hpd_set_polarity, +}; + int radeon_asic_init(struct radeon_device *rdev) { radeon_register_accessor_init(rdev); diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index d3a157b..2bc2623 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -83,44 +83,6 @@ bool r100_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); void r100_hpd_set_polarity(struct radeon_device *rdev, enum radeon_hpd_id hpd); -static struct radeon_asic r100_asic = { - .init = &r100_init, - .fini = &r100_fini, - .suspend = &r100_suspend, - .resume = &r100_resume, - .vga_set_state = &r100_vga_set_state, - .gpu_reset = &r100_gpu_reset, - .gart_tlb_flush = &r100_pci_gart_tlb_flush, - .gart_set_page = &r100_pci_gart_set_page, - .cp_commit = &r100_cp_commit, - .ring_start = &r100_ring_start, - .ring_test = &r100_ring_test, - .ring_ib_execute = &r100_ring_ib_execute, - .irq_set = &r100_irq_set, - .irq_process = &r100_irq_process, - .get_vblank_counter = &r100_get_vblank_counter, - .fence_ring_emit = &r100_fence_ring_emit, - .cs_parse = &r100_cs_parse, - .copy_blit = &r100_copy_blit, - .copy_dma = NULL, - .copy = &r100_copy_blit, - .get_engine_clock = &radeon_legacy_get_engine_clock, - .set_engine_clock = &radeon_legacy_set_engine_clock, - .get_memory_clock = &radeon_legacy_get_memory_clock, - .set_memory_clock = NULL, - .get_pcie_lanes = NULL, - .set_pcie_lanes = NULL, - .set_clock_gating = &radeon_legacy_set_clock_gating, - .set_surface_reg = r100_set_surface_reg, - .clear_surface_reg = r100_clear_surface_reg, - .bandwidth_update = &r100_bandwidth_update, - .hpd_init = &r100_hpd_init, - .hpd_fini = &r100_hpd_fini, - .hpd_sense = &r100_hpd_sense, - .hpd_set_polarity = &r100_hpd_set_polarity, - .ioctl_wait_idle = NULL, -}; - /* * r200,rv250,rs300,rv280 */ @@ -129,43 +91,6 @@ extern int r200_copy_dma(struct radeon_device *rdev, uint64_t dst_offset, unsigned num_pages, struct radeon_fence *fence); -static struct radeon_asic r200_asic = { - .init = &r100_init, - .fini = &r100_fini, - .suspend = &r100_suspend, - .resume = &r100_resume, - .vga_set_state = &r100_vga_set_state, - .gpu_reset = &r100_gpu_reset, - .gart_tlb_flush = &r100_pci_gart_tlb_flush, - .gart_set_page = &r100_pci_gart_set_page, - .cp_commit = &r100_cp_commit, - .ring_start = &r100_ring_start, - .ring_test = &r100_ring_test, - .ring_ib_execute = &r100_ring_ib_execute, - .irq_set = &r100_irq_set, - .irq_process = &r100_irq_process, - .get_vblank_counter = &r100_get_vblank_counter, - .fence_ring_emit = &r100_fence_ring_emit, - .cs_parse = &r100_cs_parse, - .copy_blit = &r100_copy_blit, - .copy_dma = &r200_copy_dma, - .copy = &r100_copy_blit, - .get_engine_clock = &radeon_legacy_get_engine_clock, - .set_engine_clock = &radeon_legacy_set_engine_clock, - .get_memory_clock = &radeon_legacy_get_memory_clock, - .set_memory_clock = NULL, - .set_pcie_lanes = NULL, - .set_clock_gating = &radeon_legacy_set_clock_gating, - .set_surface_reg = r100_set_surface_reg, - .clear_surface_reg = r100_clear_surface_reg, - .bandwidth_update = &r100_bandwidth_update, - .hpd_init = &r100_hpd_init, - .hpd_fini = &r100_hpd_fini, - .hpd_sense = &r100_hpd_sense, - .hpd_set_polarity = &r100_hpd_set_polarity, - .ioctl_wait_idle = NULL, -}; - /* * r300,r350,rv350,rv380 @@ -186,82 +111,6 @@ extern void rv370_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v extern void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes); extern int rv370_get_pcie_lanes(struct radeon_device *rdev); -static struct radeon_asic r300_asic = { - .init = &r300_init, - .fini = &r300_fini, - .suspend = &r300_suspend, - .resume = &r300_resume, - .vga_set_state = &r100_vga_set_state, - .gpu_reset = &r300_gpu_reset, - .gart_tlb_flush = &r100_pci_gart_tlb_flush, - .gart_set_page = &r100_pci_gart_set_page, - .cp_commit = &r100_cp_commit, - .ring_start = &r300_ring_start, - .ring_test = &r100_ring_test, - .ring_ib_execute = &r100_ring_ib_execute, - .irq_set = &r100_irq_set, - .irq_process = &r100_irq_process, - .get_vblank_counter = &r100_get_vblank_counter, - .fence_ring_emit = &r300_fence_ring_emit, - .cs_parse = &r300_cs_parse, - .copy_blit = &r100_copy_blit, - .copy_dma = &r200_copy_dma, - .copy = &r100_copy_blit, - .get_engine_clock = &radeon_legacy_get_engine_clock, - .set_engine_clock = &radeon_legacy_set_engine_clock, - .get_memory_clock = &radeon_legacy_get_memory_clock, - .set_memory_clock = NULL, - .get_pcie_lanes = &rv370_get_pcie_lanes, - .set_pcie_lanes = &rv370_set_pcie_lanes, - .set_clock_gating = &radeon_legacy_set_clock_gating, - .set_surface_reg = r100_set_surface_reg, - .clear_surface_reg = r100_clear_surface_reg, - .bandwidth_update = &r100_bandwidth_update, - .hpd_init = &r100_hpd_init, - .hpd_fini = &r100_hpd_fini, - .hpd_sense = &r100_hpd_sense, - .hpd_set_polarity = &r100_hpd_set_polarity, - .ioctl_wait_idle = NULL, -}; - - -static struct radeon_asic r300_asic_pcie = { - .init = &r300_init, - .fini = &r300_fini, - .suspend = &r300_suspend, - .resume = &r300_resume, - .vga_set_state = &r100_vga_set_state, - .gpu_reset = &r300_gpu_reset, - .gart_tlb_flush = &rv370_pcie_gart_tlb_flush, - .gart_set_page = &rv370_pcie_gart_set_page, - .cp_commit = &r100_cp_commit, - .ring_start = &r300_ring_start, - .ring_test = &r100_ring_test, - .ring_ib_execute = &r100_ring_ib_execute, - .irq_set = &r100_irq_set, - .irq_process = &r100_irq_process, - .get_vblank_counter = &r100_get_vblank_counter, - .fence_ring_emit = &r300_fence_ring_emit, - .cs_parse = &r300_cs_parse, - .copy_blit = &r100_copy_blit, - .copy_dma = &r200_copy_dma, - .copy = &r100_copy_blit, - .get_engine_clock = &radeon_legacy_get_engine_clock, - .set_engine_clock = &radeon_legacy_set_engine_clock, - .get_memory_clock = &radeon_legacy_get_memory_clock, - .set_memory_clock = NULL, - .set_pcie_lanes = &rv370_set_pcie_lanes, - .set_clock_gating = &radeon_legacy_set_clock_gating, - .set_surface_reg = r100_set_surface_reg, - .clear_surface_reg = r100_clear_surface_reg, - .bandwidth_update = &r100_bandwidth_update, - .hpd_init = &r100_hpd_init, - .hpd_fini = &r100_hpd_fini, - .hpd_sense = &r100_hpd_sense, - .hpd_set_polarity = &r100_hpd_set_polarity, - .ioctl_wait_idle = NULL, -}; - /* * r420,r423,rv410 */ @@ -269,44 +118,6 @@ extern int r420_init(struct radeon_device *rdev); extern void r420_fini(struct radeon_device *rdev); extern int r420_suspend(struct radeon_device *rdev); extern int r420_resume(struct radeon_device *rdev); -static struct radeon_asic r420_asic = { - .init = &r420_init, - .fini = &r420_fini, - .suspend = &r420_suspend, - .resume = &r420_resume, - .vga_set_state = &r100_vga_set_state, - .gpu_reset = &r300_gpu_reset, - .gart_tlb_flush = &rv370_pcie_gart_tlb_flush, - .gart_set_page = &rv370_pcie_gart_set_page, - .cp_commit = &r100_cp_commit, - .ring_start = &r300_ring_start, - .ring_test = &r100_ring_test, - .ring_ib_execute = &r100_ring_ib_execute, - .irq_set = &r100_irq_set, - .irq_process = &r100_irq_process, - .get_vblank_counter = &r100_get_vblank_counter, - .fence_ring_emit = &r300_fence_ring_emit, - .cs_parse = &r300_cs_parse, - .copy_blit = &r100_copy_blit, - .copy_dma = &r200_copy_dma, - .copy = &r100_copy_blit, - .get_engine_clock = &radeon_atom_get_engine_clock, - .set_engine_clock = &radeon_atom_set_engine_clock, - .get_memory_clock = &radeon_atom_get_memory_clock, - .set_memory_clock = &radeon_atom_set_memory_clock, - .get_pcie_lanes = &rv370_get_pcie_lanes, - .set_pcie_lanes = &rv370_set_pcie_lanes, - .set_clock_gating = &radeon_atom_set_clock_gating, - .set_surface_reg = r100_set_surface_reg, - .clear_surface_reg = r100_clear_surface_reg, - .bandwidth_update = &r100_bandwidth_update, - .hpd_init = &r100_hpd_init, - .hpd_fini = &r100_hpd_fini, - .hpd_sense = &r100_hpd_sense, - .hpd_set_polarity = &r100_hpd_set_polarity, - .ioctl_wait_idle = NULL, -}; - /* * rs400,rs480 @@ -319,44 +130,6 @@ void rs400_gart_tlb_flush(struct radeon_device *rdev); int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr); uint32_t rs400_mc_rreg(struct radeon_device *rdev, uint32_t reg); void rs400_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); -static struct radeon_asic rs400_asic = { - .init = &rs400_init, - .fini = &rs400_fini, - .suspend = &rs400_suspend, - .resume = &rs400_resume, - .vga_set_state = &r100_vga_set_state, - .gpu_reset = &r300_gpu_reset, - .gart_tlb_flush = &rs400_gart_tlb_flush, - .gart_set_page = &rs400_gart_set_page, - .cp_commit = &r100_cp_commit, - .ring_start = &r300_ring_start, - .ring_test = &r100_ring_test, - .ring_ib_execute = &r100_ring_ib_execute, - .irq_set = &r100_irq_set, - .irq_process = &r100_irq_process, - .get_vblank_counter = &r100_get_vblank_counter, - .fence_ring_emit = &r300_fence_ring_emit, - .cs_parse = &r300_cs_parse, - .copy_blit = &r100_copy_blit, - .copy_dma = &r200_copy_dma, - .copy = &r100_copy_blit, - .get_engine_clock = &radeon_legacy_get_engine_clock, - .set_engine_clock = &radeon_legacy_set_engine_clock, - .get_memory_clock = &radeon_legacy_get_memory_clock, - .set_memory_clock = NULL, - .get_pcie_lanes = NULL, - .set_pcie_lanes = NULL, - .set_clock_gating = &radeon_legacy_set_clock_gating, - .set_surface_reg = r100_set_surface_reg, - .clear_surface_reg = r100_clear_surface_reg, - .bandwidth_update = &r100_bandwidth_update, - .hpd_init = &r100_hpd_init, - .hpd_fini = &r100_hpd_fini, - .hpd_sense = &r100_hpd_sense, - .hpd_set_polarity = &r100_hpd_set_polarity, - .ioctl_wait_idle = NULL, -}; - /* * rs600. @@ -379,45 +152,6 @@ bool rs600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); void rs600_hpd_set_polarity(struct radeon_device *rdev, enum radeon_hpd_id hpd); -static struct radeon_asic rs600_asic = { - .init = &rs600_init, - .fini = &rs600_fini, - .suspend = &rs600_suspend, - .resume = &rs600_resume, - .vga_set_state = &r100_vga_set_state, - .gpu_reset = &r300_gpu_reset, - .gart_tlb_flush = &rs600_gart_tlb_flush, - .gart_set_page = &rs600_gart_set_page, - .cp_commit = &r100_cp_commit, - .ring_start = &r300_ring_start, - .ring_test = &r100_ring_test, - .ring_ib_execute = &r100_ring_ib_execute, - .irq_set = &rs600_irq_set, - .irq_process = &rs600_irq_process, - .get_vblank_counter = &rs600_get_vblank_counter, - .fence_ring_emit = &r300_fence_ring_emit, - .cs_parse = &r300_cs_parse, - .copy_blit = &r100_copy_blit, - .copy_dma = &r200_copy_dma, - .copy = &r100_copy_blit, - .get_engine_clock = &radeon_atom_get_engine_clock, - .set_engine_clock = &radeon_atom_set_engine_clock, - .get_memory_clock = &radeon_atom_get_memory_clock, - .set_memory_clock = &radeon_atom_set_memory_clock, - .get_pcie_lanes = NULL, - .set_pcie_lanes = NULL, - .set_clock_gating = &radeon_atom_set_clock_gating, - .set_surface_reg = r100_set_surface_reg, - .clear_surface_reg = r100_clear_surface_reg, - .bandwidth_update = &rs600_bandwidth_update, - .hpd_init = &rs600_hpd_init, - .hpd_fini = &rs600_hpd_fini, - .hpd_sense = &rs600_hpd_sense, - .hpd_set_polarity = &rs600_hpd_set_polarity, - .ioctl_wait_idle = NULL, -}; - - /* * rs690,rs740 */ @@ -428,44 +162,6 @@ int rs690_suspend(struct radeon_device *rdev); uint32_t rs690_mc_rreg(struct radeon_device *rdev, uint32_t reg); void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); void rs690_bandwidth_update(struct radeon_device *rdev); -static struct radeon_asic rs690_asic = { - .init = &rs690_init, - .fini = &rs690_fini, - .suspend = &rs690_suspend, - .resume = &rs690_resume, - .vga_set_state = &r100_vga_set_state, - .gpu_reset = &r300_gpu_reset, - .gart_tlb_flush = &rs400_gart_tlb_flush, - .gart_set_page = &rs400_gart_set_page, - .cp_commit = &r100_cp_commit, - .ring_start = &r300_ring_start, - .ring_test = &r100_ring_test, - .ring_ib_execute = &r100_ring_ib_execute, - .irq_set = &rs600_irq_set, - .irq_process = &rs600_irq_process, - .get_vblank_counter = &rs600_get_vblank_counter, - .fence_ring_emit = &r300_fence_ring_emit, - .cs_parse = &r300_cs_parse, - .copy_blit = &r100_copy_blit, - .copy_dma = &r200_copy_dma, - .copy = &r200_copy_dma, - .get_engine_clock = &radeon_atom_get_engine_clock, - .set_engine_clock = &radeon_atom_set_engine_clock, - .get_memory_clock = &radeon_atom_get_memory_clock, - .set_memory_clock = &radeon_atom_set_memory_clock, - .get_pcie_lanes = NULL, - .set_pcie_lanes = NULL, - .set_clock_gating = &radeon_atom_set_clock_gating, - .set_surface_reg = r100_set_surface_reg, - .clear_surface_reg = r100_clear_surface_reg, - .bandwidth_update = &rs690_bandwidth_update, - .hpd_init = &rs600_hpd_init, - .hpd_fini = &rs600_hpd_fini, - .hpd_sense = &rs600_hpd_sense, - .hpd_set_polarity = &rs600_hpd_set_polarity, - .ioctl_wait_idle = NULL, -}; - /* * rv515 @@ -481,87 +177,12 @@ void rv515_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); void rv515_bandwidth_update(struct radeon_device *rdev); int rv515_resume(struct radeon_device *rdev); int rv515_suspend(struct radeon_device *rdev); -static struct radeon_asic rv515_asic = { - .init = &rv515_init, - .fini = &rv515_fini, - .suspend = &rv515_suspend, - .resume = &rv515_resume, - .vga_set_state = &r100_vga_set_state, - .gpu_reset = &rv515_gpu_reset, - .gart_tlb_flush = &rv370_pcie_gart_tlb_flush, - .gart_set_page = &rv370_pcie_gart_set_page, - .cp_commit = &r100_cp_commit, - .ring_start = &rv515_ring_start, - .ring_test = &r100_ring_test, - .ring_ib_execute = &r100_ring_ib_execute, - .irq_set = &rs600_irq_set, - .irq_process = &rs600_irq_process, - .get_vblank_counter = &rs600_get_vblank_counter, - .fence_ring_emit = &r300_fence_ring_emit, - .cs_parse = &r300_cs_parse, - .copy_blit = &r100_copy_blit, - .copy_dma = &r200_copy_dma, - .copy = &r100_copy_blit, - .get_engine_clock = &radeon_atom_get_engine_clock, - .set_engine_clock = &radeon_atom_set_engine_clock, - .get_memory_clock = &radeon_atom_get_memory_clock, - .set_memory_clock = &radeon_atom_set_memory_clock, - .get_pcie_lanes = &rv370_get_pcie_lanes, - .set_pcie_lanes = &rv370_set_pcie_lanes, - .set_clock_gating = &radeon_atom_set_clock_gating, - .set_surface_reg = r100_set_surface_reg, - .clear_surface_reg = r100_clear_surface_reg, - .bandwidth_update = &rv515_bandwidth_update, - .hpd_init = &rs600_hpd_init, - .hpd_fini = &rs600_hpd_fini, - .hpd_sense = &rs600_hpd_sense, - .hpd_set_polarity = &rs600_hpd_set_polarity, - .ioctl_wait_idle = NULL, -}; - /* * r520,rv530,rv560,rv570,r580 */ int r520_init(struct radeon_device *rdev); int r520_resume(struct radeon_device *rdev); -static struct radeon_asic r520_asic = { - .init = &r520_init, - .fini = &rv515_fini, - .suspend = &rv515_suspend, - .resume = &r520_resume, - .vga_set_state = &r100_vga_set_state, - .gpu_reset = &rv515_gpu_reset, - .gart_tlb_flush = &rv370_pcie_gart_tlb_flush, - .gart_set_page = &rv370_pcie_gart_set_page, - .cp_commit = &r100_cp_commit, - .ring_start = &rv515_ring_start, - .ring_test = &r100_ring_test, - .ring_ib_execute = &r100_ring_ib_execute, - .irq_set = &rs600_irq_set, - .irq_process = &rs600_irq_process, - .get_vblank_counter = &rs600_get_vblank_counter, - .fence_ring_emit = &r300_fence_ring_emit, - .cs_parse = &r300_cs_parse, - .copy_blit = &r100_copy_blit, - .copy_dma = &r200_copy_dma, - .copy = &r100_copy_blit, - .get_engine_clock = &radeon_atom_get_engine_clock, - .set_engine_clock = &radeon_atom_set_engine_clock, - .get_memory_clock = &radeon_atom_get_memory_clock, - .set_memory_clock = &radeon_atom_set_memory_clock, - .get_pcie_lanes = &rv370_get_pcie_lanes, - .set_pcie_lanes = &rv370_set_pcie_lanes, - .set_clock_gating = &radeon_atom_set_clock_gating, - .set_surface_reg = r100_set_surface_reg, - .clear_surface_reg = r100_clear_surface_reg, - .bandwidth_update = &rv515_bandwidth_update, - .hpd_init = &rs600_hpd_init, - .hpd_fini = &rs600_hpd_fini, - .hpd_sense = &rs600_hpd_sense, - .hpd_set_polarity = &rs600_hpd_set_polarity, - .ioctl_wait_idle = NULL, -}; /* * r600,rv610,rv630,rv620,rv635,rv670,rs780,rs880 @@ -604,43 +225,6 @@ void r600_hpd_set_polarity(struct radeon_device *rdev, enum radeon_hpd_id hpd); extern void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo); -static struct radeon_asic r600_asic = { - .init = &r600_init, - .fini = &r600_fini, - .suspend = &r600_suspend, - .resume = &r600_resume, - .cp_commit = &r600_cp_commit, - .vga_set_state = &r600_vga_set_state, - .gpu_reset = &r600_gpu_reset, - .gart_tlb_flush = &r600_pcie_gart_tlb_flush, - .gart_set_page = &rs600_gart_set_page, - .ring_test = &r600_ring_test, - .ring_ib_execute = &r600_ring_ib_execute, - .irq_set = &r600_irq_set, - .irq_process = &r600_irq_process, - .get_vblank_counter = &rs600_get_vblank_counter, - .fence_ring_emit = &r600_fence_ring_emit, - .cs_parse = &r600_cs_parse, - .copy_blit = &r600_copy_blit, - .copy_dma = &r600_copy_blit, - .copy = &r600_copy_blit, - .get_engine_clock = &radeon_atom_get_engine_clock, - .set_engine_clock = &radeon_atom_set_engine_clock, - .get_memory_clock = &radeon_atom_get_memory_clock, - .set_memory_clock = &radeon_atom_set_memory_clock, - .get_pcie_lanes = &rv370_get_pcie_lanes, - .set_pcie_lanes = NULL, - .set_clock_gating = NULL, - .set_surface_reg = r600_set_surface_reg, - .clear_surface_reg = r600_clear_surface_reg, - .bandwidth_update = &rv515_bandwidth_update, - .hpd_init = &r600_hpd_init, - .hpd_fini = &r600_hpd_fini, - .hpd_sense = &r600_hpd_sense, - .hpd_set_polarity = &r600_hpd_set_polarity, - .ioctl_wait_idle = r600_ioctl_wait_idle, -}; - /* * rv770,rv730,rv710,rv740 */ @@ -650,43 +234,6 @@ int rv770_suspend(struct radeon_device *rdev); int rv770_resume(struct radeon_device *rdev); int rv770_gpu_reset(struct radeon_device *rdev); -static struct radeon_asic rv770_asic = { - .init = &rv770_init, - .fini = &rv770_fini, - .suspend = &rv770_suspend, - .resume = &rv770_resume, - .cp_commit = &r600_cp_commit, - .gpu_reset = &rv770_gpu_reset, - .vga_set_state = &r600_vga_set_state, - .gart_tlb_flush = &r600_pcie_gart_tlb_flush, - .gart_set_page = &rs600_gart_set_page, - .ring_test = &r600_ring_test, - .ring_ib_execute = &r600_ring_ib_execute, - .irq_set = &r600_irq_set, - .irq_process = &r600_irq_process, - .get_vblank_counter = &rs600_get_vblank_counter, - .fence_ring_emit = &r600_fence_ring_emit, - .cs_parse = &r600_cs_parse, - .copy_blit = &r600_copy_blit, - .copy_dma = &r600_copy_blit, - .copy = &r600_copy_blit, - .get_engine_clock = &radeon_atom_get_engine_clock, - .set_engine_clock = &radeon_atom_set_engine_clock, - .get_memory_clock = &radeon_atom_get_memory_clock, - .set_memory_clock = &radeon_atom_set_memory_clock, - .get_pcie_lanes = &rv370_get_pcie_lanes, - .set_pcie_lanes = NULL, - .set_clock_gating = &radeon_atom_set_clock_gating, - .set_surface_reg = r600_set_surface_reg, - .clear_surface_reg = r600_clear_surface_reg, - .bandwidth_update = &rv515_bandwidth_update, - .hpd_init = &r600_hpd_init, - .hpd_fini = &r600_hpd_fini, - .hpd_sense = &r600_hpd_sense, - .hpd_set_polarity = &r600_hpd_set_polarity, - .ioctl_wait_idle = r600_ioctl_wait_idle, -}; - /* * evergreen */ @@ -701,40 +248,4 @@ void evergreen_hpd_fini(struct radeon_device *rdev); bool evergreen_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); void evergreen_hpd_set_polarity(struct radeon_device *rdev, enum radeon_hpd_id hpd); - -static struct radeon_asic evergreen_asic = { - .init = &evergreen_init, - .fini = &evergreen_fini, - .suspend = &evergreen_suspend, - .resume = &evergreen_resume, - .cp_commit = NULL, - .gpu_reset = &evergreen_gpu_reset, - .vga_set_state = &r600_vga_set_state, - .gart_tlb_flush = &r600_pcie_gart_tlb_flush, - .gart_set_page = &rs600_gart_set_page, - .ring_test = NULL, - .ring_ib_execute = NULL, - .irq_set = NULL, - .irq_process = NULL, - .get_vblank_counter = NULL, - .fence_ring_emit = NULL, - .cs_parse = NULL, - .copy_blit = NULL, - .copy_dma = NULL, - .copy = NULL, - .get_engine_clock = &radeon_atom_get_engine_clock, - .set_engine_clock = &radeon_atom_set_engine_clock, - .get_memory_clock = &radeon_atom_get_memory_clock, - .set_memory_clock = &radeon_atom_set_memory_clock, - .set_pcie_lanes = NULL, - .set_clock_gating = NULL, - .set_surface_reg = r600_set_surface_reg, - .clear_surface_reg = r600_clear_surface_reg, - .bandwidth_update = &evergreen_bandwidth_update, - .hpd_init = &evergreen_hpd_init, - .hpd_fini = &evergreen_hpd_fini, - .hpd_sense = &evergreen_hpd_sense, - .hpd_set_polarity = &evergreen_hpd_set_polarity, -}; - #endif -- cgit v0.10.2 From 9479c54f0dfa63dad1ecfca897f51693c7c2fa65 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 11 Mar 2010 21:19:16 +0000 Subject: drm/radeon: unconfuse return value of radeon_asic->clear_surface_reg No one cares about it, so set it to void. Signed-off-by: Daniel Vetter Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 67f3c57..a8552ee 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -783,7 +783,7 @@ struct radeon_asic { int (*set_surface_reg)(struct radeon_device *rdev, int reg, uint32_t tiling_flags, uint32_t pitch, uint32_t offset, uint32_t obj_size); - int (*clear_surface_reg)(struct radeon_device *rdev, int reg); + void (*clear_surface_reg)(struct radeon_device *rdev, int reg); void (*bandwidth_update)(struct radeon_device *rdev); void (*hpd_init)(struct radeon_device *rdev); void (*hpd_fini)(struct radeon_device *rdev); diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 2bc2623..4c0d3da 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -73,7 +73,7 @@ int r100_copy_blit(struct radeon_device *rdev, int r100_set_surface_reg(struct radeon_device *rdev, int reg, uint32_t tiling_flags, uint32_t pitch, uint32_t offset, uint32_t obj_size); -int r100_clear_surface_reg(struct radeon_device *rdev, int reg); +void r100_clear_surface_reg(struct radeon_device *rdev, int reg); void r100_bandwidth_update(struct radeon_device *rdev); void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); int r100_ring_test(struct radeon_device *rdev); @@ -212,7 +212,7 @@ int r600_gpu_reset(struct radeon_device *rdev); int r600_set_surface_reg(struct radeon_device *rdev, int reg, uint32_t tiling_flags, uint32_t pitch, uint32_t offset, uint32_t obj_size); -int r600_clear_surface_reg(struct radeon_device *rdev, int reg); +void r600_clear_surface_reg(struct radeon_device *rdev, int reg); void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); int r600_ring_test(struct radeon_device *rdev); int r600_copy_blit(struct radeon_device *rdev, -- cgit v0.10.2 From e6990375ef4ec449994991034238f1ffab8a3a1a Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 11 Mar 2010 21:19:17 +0000 Subject: drm/radeon: include radeon_asic.h in the asic specific files In essence this creates a home for all asic specific declarations in radeon_asic.h Signed-off-by: Daniel Vetter Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index bd2e7aa..9d6283e 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -25,6 +25,7 @@ #include #include "drmP.h" #include "radeon.h" +#include "radeon_asic.h" #include "radeon_drm.h" #include "rv770d.h" #include "atom.h" diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 73f9a79..ea5ebfe 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -31,6 +31,7 @@ #include "radeon_drm.h" #include "radeon_reg.h" #include "radeon.h" +#include "radeon_asic.h" #include "r100d.h" #include "rs100d.h" #include "rv200d.h" diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c index 1146c99..85617c3 100644 --- a/drivers/gpu/drm/radeon/r200.c +++ b/drivers/gpu/drm/radeon/r200.c @@ -30,6 +30,7 @@ #include "radeon_drm.h" #include "radeon_reg.h" #include "radeon.h" +#include "radeon_asic.h" #include "r100d.h" #include "r200_reg_safe.h" diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 4cef90c..1042cea 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -30,6 +30,7 @@ #include "drm.h" #include "radeon_reg.h" #include "radeon.h" +#include "radeon_asic.h" #include "radeon_drm.h" #include "r100_track.h" #include "r300d.h" diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c index c7593b8..2ab35ff 100644 --- a/drivers/gpu/drm/radeon/r420.c +++ b/drivers/gpu/drm/radeon/r420.c @@ -29,6 +29,7 @@ #include "drmP.h" #include "radeon_reg.h" #include "radeon.h" +#include "radeon_asic.h" #include "atom.h" #include "r100d.h" #include "r420d.h" diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c index 2b8a5dd..f6d8541 100644 --- a/drivers/gpu/drm/radeon/r520.c +++ b/drivers/gpu/drm/radeon/r520.c @@ -27,6 +27,7 @@ */ #include "drmP.h" #include "radeon.h" +#include "radeon_asic.h" #include "atom.h" #include "r520d.h" diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 5b56a1b..5b00d5e 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -31,6 +31,7 @@ #include "drmP.h" #include "radeon_drm.h" #include "radeon.h" +#include "radeon_asic.h" #include "radeon_mode.h" #include "r600d.h" #include "atom.h" diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c index 626d518..1240e7d 100644 --- a/drivers/gpu/drm/radeon/rs400.c +++ b/drivers/gpu/drm/radeon/rs400.c @@ -28,6 +28,7 @@ #include #include #include "radeon.h" +#include "radeon_asic.h" #include "rs400d.h" /* This files gather functions specifics to : rs400,rs480 */ diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index ac7c27a..e3410c9 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -37,6 +37,7 @@ */ #include "drmP.h" #include "radeon.h" +#include "radeon_asic.h" #include "atom.h" #include "rs600d.h" diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index 83b9174..c39cb50 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c @@ -27,6 +27,7 @@ */ #include "drmP.h" #include "radeon.h" +#include "radeon_asic.h" #include "atom.h" #include "rs690d.h" diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index bea747d..26108b4 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c @@ -29,6 +29,7 @@ #include "drmP.h" #include "rv515d.h" #include "radeon.h" +#include "radeon_asic.h" #include "atom.h" #include "rv515_reg_safe.h" diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 8f0c925..1484d06 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -29,6 +29,7 @@ #include #include "drmP.h" #include "radeon.h" +#include "radeon_asic.h" #include "radeon_drm.h" #include "rv770d.h" #include "atom.h" -- cgit v0.10.2 From 2b497502b7cef167288a08737403a5a6cec697f0 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 11 Mar 2010 21:19:18 +0000 Subject: drm/radeon: collect r100 asic related declarations in radeon_asic.h This just an example to show what radeon_asic.h might be good for. Before Jerome kills it ;) Signed-off-by: Daniel Vetter Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index a8552ee..bd63f53 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -730,8 +730,6 @@ int radeon_debugfs_add_files(struct radeon_device *rdev, struct drm_info_list *files, unsigned nfiles); int radeon_debugfs_fence_init(struct radeon_device *rdev); -int r100_debugfs_rbbm_init(struct radeon_device *rdev); -int r100_debugfs_cp_init(struct radeon_device *rdev); /* @@ -1195,51 +1193,6 @@ extern int radeon_resume_kms(struct drm_device *dev); extern int radeon_suspend_kms(struct drm_device *dev, pm_message_t state); /* r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 */ -struct r100_mc_save { - u32 GENMO_WT; - u32 CRTC_EXT_CNTL; - u32 CRTC_GEN_CNTL; - u32 CRTC2_GEN_CNTL; - u32 CUR_OFFSET; - u32 CUR2_OFFSET; -}; -extern void r100_cp_disable(struct radeon_device *rdev); -extern int r100_cp_init(struct radeon_device *rdev, unsigned ring_size); -extern void r100_cp_fini(struct radeon_device *rdev); -extern void r100_pci_gart_tlb_flush(struct radeon_device *rdev); -extern int r100_pci_gart_init(struct radeon_device *rdev); -extern void r100_pci_gart_fini(struct radeon_device *rdev); -extern int r100_pci_gart_enable(struct radeon_device *rdev); -extern void r100_pci_gart_disable(struct radeon_device *rdev); -extern int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr); -extern int r100_debugfs_mc_info_init(struct radeon_device *rdev); -extern int r100_gui_wait_for_idle(struct radeon_device *rdev); -extern void r100_ib_fini(struct radeon_device *rdev); -extern int r100_ib_init(struct radeon_device *rdev); -extern void r100_irq_disable(struct radeon_device *rdev); -extern int r100_irq_set(struct radeon_device *rdev); -extern void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save); -extern void r100_mc_resume(struct radeon_device *rdev, struct r100_mc_save *save); -extern void r100_vram_init_sizes(struct radeon_device *rdev); -extern void r100_wb_disable(struct radeon_device *rdev); -extern void r100_wb_fini(struct radeon_device *rdev); -extern int r100_wb_init(struct radeon_device *rdev); -extern void r100_hdp_reset(struct radeon_device *rdev); -extern int r100_rb2d_reset(struct radeon_device *rdev); -extern int r100_cp_reset(struct radeon_device *rdev); -extern void r100_vga_render_disable(struct radeon_device *rdev); -extern int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt, - struct radeon_bo *robj); -extern int r100_cs_parse_packet0(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt, - const unsigned *auth, unsigned n, - radeon_packet0_check_t check); -extern int r100_cs_packet_parse(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt, - unsigned idx); -extern void r100_enable_bm(struct radeon_device *rdev); -extern void r100_set_common_regs(struct radeon_device *rdev); /* rv200,rv250,rv280 */ extern void r200_set_safe_registers(struct radeon_device *rdev); diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 4c0d3da..a0b8280 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -45,10 +45,18 @@ void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable); /* * r100,rv100,rs100,rv200,rs200 */ -extern int r100_init(struct radeon_device *rdev); -extern void r100_fini(struct radeon_device *rdev); -extern int r100_suspend(struct radeon_device *rdev); -extern int r100_resume(struct radeon_device *rdev); +struct r100_mc_save { + u32 GENMO_WT; + u32 CRTC_EXT_CNTL; + u32 CRTC_GEN_CNTL; + u32 CRTC2_GEN_CNTL; + u32 CUR_OFFSET; + u32 CUR2_OFFSET; +}; +int r100_init(struct radeon_device *rdev); +void r100_fini(struct radeon_device *rdev); +int r100_suspend(struct radeon_device *rdev); +int r100_resume(struct radeon_device *rdev); uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg); void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); void r100_vga_set_state(struct radeon_device *rdev, bool state); @@ -82,6 +90,42 @@ void r100_hpd_fini(struct radeon_device *rdev); bool r100_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); void r100_hpd_set_polarity(struct radeon_device *rdev, enum radeon_hpd_id hpd); +int r100_debugfs_rbbm_init(struct radeon_device *rdev); +int r100_debugfs_cp_init(struct radeon_device *rdev); +void r100_cp_disable(struct radeon_device *rdev); +int r100_cp_init(struct radeon_device *rdev, unsigned ring_size); +void r100_cp_fini(struct radeon_device *rdev); +int r100_pci_gart_init(struct radeon_device *rdev); +void r100_pci_gart_fini(struct radeon_device *rdev); +int r100_pci_gart_enable(struct radeon_device *rdev); +void r100_pci_gart_disable(struct radeon_device *rdev); +int r100_debugfs_mc_info_init(struct radeon_device *rdev); +int r100_gui_wait_for_idle(struct radeon_device *rdev); +void r100_ib_fini(struct radeon_device *rdev); +int r100_ib_init(struct radeon_device *rdev); +void r100_irq_disable(struct radeon_device *rdev); +void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save); +void r100_mc_resume(struct radeon_device *rdev, struct r100_mc_save *save); +void r100_vram_init_sizes(struct radeon_device *rdev); +void r100_wb_disable(struct radeon_device *rdev); +void r100_wb_fini(struct radeon_device *rdev); +int r100_wb_init(struct radeon_device *rdev); +void r100_hdp_reset(struct radeon_device *rdev); +int r100_rb2d_reset(struct radeon_device *rdev); +int r100_cp_reset(struct radeon_device *rdev); +void r100_vga_render_disable(struct radeon_device *rdev); +int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p, + struct radeon_cs_packet *pkt, + struct radeon_bo *robj); +int r100_cs_parse_packet0(struct radeon_cs_parser *p, + struct radeon_cs_packet *pkt, + const unsigned *auth, unsigned n, + radeon_packet0_check_t check); +int r100_cs_packet_parse(struct radeon_cs_parser *p, + struct radeon_cs_packet *pkt, + unsigned idx); +void r100_enable_bm(struct radeon_device *rdev); +void r100_set_common_regs(struct radeon_device *rdev); /* * r200,rv250,rs300,rv280 -- cgit v0.10.2 From 03fb256df9c960b10c0e01b7e92d2f31433675fe Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 16 Feb 2010 10:48:15 +0000 Subject: ARM: mach-shmobile: G3EVM KEYSC platform data This patch adds KEYSC platform data for the G3EVM board. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt diff --git a/arch/arm/mach-shmobile/board-g3evm.c b/arch/arm/mach-shmobile/board-g3evm.c index f36c9a9..9d32689 100644 --- a/arch/arm/mach-shmobile/board-g3evm.c +++ b/arch/arm/mach-shmobile/board-g3evm.c @@ -29,6 +29,8 @@ #include #include #include +#include +#include #include #include #include @@ -127,9 +129,47 @@ static struct platform_device usb_host_device = { .resource = usb_host_resources, }; +/* KEYSC */ +static struct sh_keysc_info keysc_info = { + .mode = SH_KEYSC_MODE_5, + .scan_timing = 3, + .delay = 100, + .keycodes = { + KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G, + KEY_H, KEY_I, KEY_J, KEY_K, KEY_L, KEY_M, KEY_N, + KEY_O, KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U, + KEY_V, KEY_W, KEY_X, KEY_Y, KEY_Z, KEY_HOME, KEY_SLEEP, + KEY_WAKEUP, KEY_COFFEE, KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, + KEY_5, KEY_6, KEY_7, KEY_8, KEY_9, KEY_STOP, KEY_COMPUTER, + }, +}; + +static struct resource keysc_resources[] = { + [0] = { + .name = "KEYSC", + .start = 0xe61b0000, + .end = 0xe61b000f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 79, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device keysc_device = { + .name = "sh_keysc", + .num_resources = ARRAY_SIZE(keysc_resources), + .resource = keysc_resources, + .dev = { + .platform_data = &keysc_info, + }, +}; + static struct platform_device *g3evm_devices[] __initdata = { &nor_flash_device, &usb_host_device, + &keysc_device, }; static struct map_desc g3evm_io_desc[] __initdata = { @@ -196,6 +236,21 @@ static void __init g3evm_init(void) __raw_writew(0x6010, 0xe60581c6); /* CGPOSR */ __raw_writew(0x8a0a, 0xe605810c); /* USBCR2 */ + /* KEYSC @ CN7 */ + gpio_request(GPIO_FN_PORT42_KEYOUT0, NULL); + gpio_request(GPIO_FN_PORT43_KEYOUT1, NULL); + gpio_request(GPIO_FN_PORT44_KEYOUT2, NULL); + gpio_request(GPIO_FN_PORT45_KEYOUT3, NULL); + gpio_request(GPIO_FN_PORT46_KEYOUT4, NULL); + gpio_request(GPIO_FN_PORT47_KEYOUT5, NULL); + gpio_request(GPIO_FN_PORT48_KEYIN0_PU, NULL); + gpio_request(GPIO_FN_PORT49_KEYIN1_PU, NULL); + gpio_request(GPIO_FN_PORT50_KEYIN2_PU, NULL); + gpio_request(GPIO_FN_PORT55_KEYIN3_PU, NULL); + gpio_request(GPIO_FN_PORT56_KEYIN4_PU, NULL); + gpio_request(GPIO_FN_PORT57_KEYIN5_PU, NULL); + gpio_request(GPIO_FN_PORT58_KEYIN6_PU, NULL); + sh7367_add_standard_devices(); platform_add_devices(g3evm_devices, ARRAY_SIZE(g3evm_devices)); diff --git a/arch/arm/mach-shmobile/clock-sh7367.c b/arch/arm/mach-shmobile/clock-sh7367.c index 58bd54e..bb940c6 100644 --- a/arch/arm/mach-shmobile/clock-sh7367.c +++ b/arch/arm/mach-shmobile/clock-sh7367.c @@ -75,6 +75,11 @@ static struct clk usb0_clk = { .name = "usb0", }; +/* a static keysc0 clk for now - enough to get sh_keysc working */ +static struct clk keysc0_clk = { + .name = "keysc0", +}; + static struct clk_lookup lookups[] = { { .clk = &peripheral_clk, @@ -82,6 +87,8 @@ static struct clk_lookup lookups[] = { .clk = &r_clk, }, { .clk = &usb0_clk, + }, { + .clk = &keysc0_clk, } }; -- cgit v0.10.2 From 143f3b833f98271341379d813cb72deb1657a380 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 19 Feb 2010 09:54:06 +0000 Subject: ARM: mach-shmobile: G3EVM FLCTL platform data This patch adds FLCTL platform data for the G3EVM board. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt diff --git a/arch/arm/mach-shmobile/board-g3evm.c b/arch/arm/mach-shmobile/board-g3evm.c index 9d32689..9247503 100644 --- a/arch/arm/mach-shmobile/board-g3evm.c +++ b/arch/arm/mach-shmobile/board-g3evm.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -166,10 +167,53 @@ static struct platform_device keysc_device = { }, }; +static struct mtd_partition nand_partition_info[] = { + { + .name = "system", + .offset = 0, + .size = 64 * 1024 * 1024, + }, + { + .name = "userdata", + .offset = MTDPART_OFS_APPEND, + .size = 128 * 1024 * 1024, + }, + { + .name = "cache", + .offset = MTDPART_OFS_APPEND, + .size = 64 * 1024 * 1024, + }, +}; + +static struct resource nand_flash_resources[] = { + [0] = { + .start = 0xe6a30000, + .end = 0xe6a3009b, + .flags = IORESOURCE_MEM, + } +}; + +static struct sh_flctl_platform_data nand_flash_data = { + .parts = nand_partition_info, + .nr_parts = ARRAY_SIZE(nand_partition_info), + .flcmncr_val = QTSEL_E | FCKSEL_E | TYPESEL_SET | NANWF_E + | SHBUSSEL | SEL_16BIT, +}; + +static struct platform_device nand_flash_device = { + .name = "sh_flctl", + .resource = nand_flash_resources, + .num_resources = ARRAY_SIZE(nand_flash_resources), + .dev = { + .platform_data = &nand_flash_data, + }, +}; + static struct platform_device *g3evm_devices[] __initdata = { &nor_flash_device, &usb_host_device, &keysc_device, + &nand_flash_device, }; static struct map_desc g3evm_io_desc[] __initdata = { @@ -251,6 +295,29 @@ static void __init g3evm_init(void) gpio_request(GPIO_FN_PORT57_KEYIN5_PU, NULL); gpio_request(GPIO_FN_PORT58_KEYIN6_PU, NULL); + /* FLCTL */ + gpio_request(GPIO_FN_FCE0, NULL); + gpio_request(GPIO_FN_D0_ED0_NAF0, NULL); + gpio_request(GPIO_FN_D1_ED1_NAF1, NULL); + gpio_request(GPIO_FN_D2_ED2_NAF2, NULL); + gpio_request(GPIO_FN_D3_ED3_NAF3, NULL); + gpio_request(GPIO_FN_D4_ED4_NAF4, NULL); + gpio_request(GPIO_FN_D5_ED5_NAF5, NULL); + gpio_request(GPIO_FN_D6_ED6_NAF6, NULL); + gpio_request(GPIO_FN_D7_ED7_NAF7, NULL); + gpio_request(GPIO_FN_D8_ED8_NAF8, NULL); + gpio_request(GPIO_FN_D9_ED9_NAF9, NULL); + gpio_request(GPIO_FN_D10_ED10_NAF10, NULL); + gpio_request(GPIO_FN_D11_ED11_NAF11, NULL); + gpio_request(GPIO_FN_D12_ED12_NAF12, NULL); + gpio_request(GPIO_FN_D13_ED13_NAF13, NULL); + gpio_request(GPIO_FN_D14_ED14_NAF14, NULL); + gpio_request(GPIO_FN_D15_ED15_NAF15, NULL); + gpio_request(GPIO_FN_WE0_XWR0_FWE, NULL); + gpio_request(GPIO_FN_FRB, NULL); + /* FOE, FCDE, FSC on dedicated pins */ + __raw_writel(__raw_readl(0xe6158048) & ~(1 << 15), 0xe6158048); + sh7367_add_standard_devices(); platform_add_devices(g3evm_devices, ARRAY_SIZE(g3evm_devices)); -- cgit v0.10.2 From 3e862c05ca1bf5bd4cb703bc257d180a4583bc41 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 19 Feb 2010 10:01:22 +0000 Subject: mtd: enable sh_flctl on SH-Mobile ARM Update the Kconfig entry for the sh_flctl driver to enable build on SH-Mobile ARM platforms. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 1157d56..42e5ea49 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -457,7 +457,7 @@ config MTD_NAND_NOMADIK config MTD_NAND_SH_FLCTL tristate "Support for NAND on Renesas SuperH FLCTL" - depends on MTD_NAND && SUPERH + depends on MTD_NAND && (SUPERH || ARCH_SHMOBILE) help Several Renesas SuperH CPU has FLCTL. This option enables support for NAND Flash using FLCTL. -- cgit v0.10.2 From 6676a1701b0b135dacbb7cfeef48004315300df0 Mon Sep 17 00:00:00 2001 From: NISHIMOTO Hiroki Date: Tue, 23 Feb 2010 10:55:10 +0000 Subject: ARM: mach-shmobile: G4EVM KEYSC platform data This patch adds KEYSC platform data for the G4EVM board. Signed-off-by: NISHIMOTO Hiroki Signed-off-by: Paul Mundt diff --git a/arch/arm/mach-shmobile/board-g4evm.c b/arch/arm/mach-shmobile/board-g4evm.c index 5acd623..10673a9 100644 --- a/arch/arm/mach-shmobile/board-g4evm.c +++ b/arch/arm/mach-shmobile/board-g4evm.c @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include #include #include @@ -128,9 +130,49 @@ static struct platform_device usb_host_device = { .resource = usb_host_resources, }; +/* KEYSC */ +static struct sh_keysc_info keysc_info = { + .mode = SH_KEYSC_MODE_5, + .scan_timing = 3, + .delay = 100, + .keycodes = { + KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, + KEY_G, KEY_H, KEY_I, KEY_J, KEY_K, KEY_L, + KEY_M, KEY_N, KEY_U, KEY_P, KEY_Q, KEY_R, + KEY_S, KEY_T, KEY_U, KEY_V, KEY_W, KEY_X, + KEY_Y, KEY_Z, KEY_HOME, KEY_SLEEP, KEY_WAKEUP, KEY_COFFEE, + KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, + KEY_6, KEY_7, KEY_8, KEY_9, KEY_STOP, KEY_COMPUTER, + }, +}; + +static struct resource keysc_resources[] = { + [0] = { + .name = "KEYSC", + .start = 0xe61b0000, + .end = 0xe61b000f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 79, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device keysc_device = { + .name = "sh_keysc", + .id = 0, /* keysc0 clock */ + .num_resources = ARRAY_SIZE(keysc_resources), + .resource = keysc_resources, + .dev = { + .platform_data = &keysc_info, + }, +}; + static struct platform_device *g4evm_devices[] __initdata = { &nor_flash_device, &usb_host_device, + &keysc_device, }; static struct map_desc g4evm_io_desc[] __initdata = { @@ -196,6 +238,21 @@ static void __init g4evm_init(void) __raw_writew(0x6010, 0xe60581c6); /* CGPOSR */ __raw_writew(0x8a0a, 0xe605810c); /* USBCR2 */ + /* KEYSC @ CN31 */ + gpio_request(GPIO_FN_PORT60_KEYOUT5, NULL); + gpio_request(GPIO_FN_PORT61_KEYOUT4, NULL); + gpio_request(GPIO_FN_PORT62_KEYOUT3, NULL); + gpio_request(GPIO_FN_PORT63_KEYOUT2, NULL); + gpio_request(GPIO_FN_PORT64_KEYOUT1, NULL); + gpio_request(GPIO_FN_PORT65_KEYOUT0, NULL); + gpio_request(GPIO_FN_PORT66_KEYIN0_PU, NULL); + gpio_request(GPIO_FN_PORT67_KEYIN1_PU, NULL); + gpio_request(GPIO_FN_PORT68_KEYIN2_PU, NULL); + gpio_request(GPIO_FN_PORT69_KEYIN3_PU, NULL); + gpio_request(GPIO_FN_PORT70_KEYIN4_PU, NULL); + gpio_request(GPIO_FN_PORT71_KEYIN5_PU, NULL); + gpio_request(GPIO_FN_PORT72_KEYIN6_PU, NULL); + sh7377_add_standard_devices(); platform_add_devices(g4evm_devices, ARRAY_SIZE(g4evm_devices)); -- cgit v0.10.2 From 9615b37c5c8fed963811c100053d495c412880fb Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 10 Mar 2010 05:13:12 +0000 Subject: ARM: mach-shmobile: sh7367 SDHI vector merge Merge the SDHI vectors for sh7367 using the recently merged INTC force_enable/disable feature. With this in place SDHI hotplug is supported using the drivers sh_mobile_sdhi and tmio_mmc. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt diff --git a/arch/arm/mach-shmobile/intc-sh7367.c b/arch/arm/mach-shmobile/intc-sh7367.c index 6a547b4..5ff70cad 100644 --- a/arch/arm/mach-shmobile/intc-sh7367.c +++ b/arch/arm/mach-shmobile/intc-sh7367.c @@ -27,6 +27,8 @@ enum { UNUSED_INTCA = 0, + ENABLED, + DISABLED, /* interrupt sources INTCA */ IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A, @@ -46,8 +48,8 @@ enum { MSIOF2, MSIOF1, SCIFA4, SCIFA5, SCIFB, FLCTL_FLSTEI, FLCTL_FLTENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I, - SDHI0_SDHI0I0, SDHI0_SDHI0I1, SDHI0_SDHI0I2, SDHI0_SDHI0I3, - SDHI1_SDHI1I0, SDHI1_SDHI1I1, SDHI1_SDHI1I2, SDHI1_SDHI1I3, + SDHI0, + SDHI1, MSU_MSU, MSU_MSU2, IREM, SIU, @@ -59,7 +61,7 @@ enum { TTI20, MISTY, DDM, - SDHI2_SDHI2I0, SDHI2_SDHI2I1, SDHI2_SDHI2I2, SDHI2_SDHI2I3, + SDHI2, RWDT0, RWDT1, DMAC_1_DEI0, DMAC_1_DEI1, DMAC_1_DEI2, DMAC_1_DEI3, DMAC_2_DEI4, DMAC_2_DEI5, DMAC_2_DADERR, @@ -70,7 +72,7 @@ enum { /* interrupt groups INTCA */ DMAC_1, DMAC_2, DMAC2_1, DMAC2_2, DMAC3_1, DMAC3_2, - ETM11, ARM11, USBHS, FLCTL, IIC1, SDHI0, SDHI1, SDHI2, + ETM11, ARM11, USBHS, FLCTL, IIC1 }; static struct intc_vect intca_vectors[] = { @@ -105,10 +107,10 @@ static struct intc_vect intca_vectors[] = { INTC_VECT(SCIFB, 0x0d60), INTC_VECT(FLCTL_FLSTEI, 0x0d80), INTC_VECT(FLCTL_FLTENDI, 0x0da0), INTC_VECT(FLCTL_FLTREQ0I, 0x0dc0), INTC_VECT(FLCTL_FLTREQ1I, 0x0de0), - INTC_VECT(SDHI0_SDHI0I0, 0x0e00), INTC_VECT(SDHI0_SDHI0I1, 0x0e20), - INTC_VECT(SDHI0_SDHI0I2, 0x0e40), INTC_VECT(SDHI0_SDHI0I3, 0x0e60), - INTC_VECT(SDHI1_SDHI1I0, 0x0e80), INTC_VECT(SDHI1_SDHI1I1, 0x0ea0), - INTC_VECT(SDHI1_SDHI1I2, 0x0ec0), INTC_VECT(SDHI1_SDHI1I3, 0x0ee0), + INTC_VECT(SDHI0, 0x0e00), INTC_VECT(SDHI0, 0x0e20), + INTC_VECT(SDHI0, 0x0e40), INTC_VECT(SDHI0, 0x0e60), + INTC_VECT(SDHI1, 0x0e80), INTC_VECT(SDHI1, 0x0ea0), + INTC_VECT(SDHI1, 0x0ec0), INTC_VECT(SDHI1, 0x0ee0), INTC_VECT(MSU_MSU, 0x0f20), INTC_VECT(MSU_MSU2, 0x0f40), INTC_VECT(IREM, 0x0f60), INTC_VECT(SIU, 0x0fa0), @@ -122,8 +124,8 @@ static struct intc_vect intca_vectors[] = { INTC_VECT(TTI20, 0x1100), INTC_VECT(MISTY, 0x1120), INTC_VECT(DDM, 0x1140), - INTC_VECT(SDHI2_SDHI2I0, 0x1200), INTC_VECT(SDHI2_SDHI2I1, 0x1220), - INTC_VECT(SDHI2_SDHI2I2, 0x1240), INTC_VECT(SDHI2_SDHI2I3, 0x1260), + INTC_VECT(SDHI2, 0x1200), INTC_VECT(SDHI2, 0x1220), + INTC_VECT(SDHI2, 0x1240), INTC_VECT(SDHI2, 0x1260), INTC_VECT(RWDT0, 0x1280), INTC_VECT(RWDT1, 0x12a0), INTC_VECT(DMAC_1_DEI0, 0x2000), INTC_VECT(DMAC_1_DEI1, 0x2020), INTC_VECT(DMAC_1_DEI2, 0x2040), INTC_VECT(DMAC_1_DEI3, 0x2060), @@ -158,12 +160,6 @@ static struct intc_group intca_groups[] __initdata = { INTC_GROUP(FLCTL, FLCTL_FLSTEI, FLCTL_FLTENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I), INTC_GROUP(IIC1, IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1), - INTC_GROUP(SDHI0, SDHI0_SDHI0I0, SDHI0_SDHI0I1, - SDHI0_SDHI0I2, SDHI0_SDHI0I3), - INTC_GROUP(SDHI1, SDHI1_SDHI1I0, SDHI1_SDHI1I1, - SDHI1_SDHI1I2, SDHI1_SDHI1I3), - INTC_GROUP(SDHI2, SDHI2_SDHI2I0, SDHI2_SDHI2I1, - SDHI2_SDHI2I2, SDHI2_SDHI2I3), }; static struct intc_mask_reg intca_mask_registers[] = { @@ -193,10 +189,10 @@ static struct intc_mask_reg intca_mask_registers[] = { { SCIFB, SCIFA5, SCIFA4, MSIOF1, 0, 0, MSIOF2, 0 } }, { 0xe694009c, 0xe69400dc, 8, /* IMR7A / IMCR7A */ - { SDHI0_SDHI0I3, SDHI0_SDHI0I2, SDHI0_SDHI0I1, SDHI0_SDHI0I0, + { DISABLED, DISABLED, ENABLED, ENABLED, FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLTENDI, FLCTL_FLSTEI } }, { 0xe69400a0, 0xe69400e0, 8, /* IMR8A / IMCR8A */ - { SDHI1_SDHI1I3, SDHI1_SDHI1I2, SDHI1_SDHI1I1, SDHI1_SDHI1I0, + { DISABLED, DISABLED, ENABLED, ENABLED, TTI20, USBDMAC_USHDMI, SPU, SIU } }, { 0xe69400a4, 0xe69400e4, 8, /* IMR9A / IMCR9A */ { CMT1_CMT13, CMT1_CMT12, CMT1_CMT11, CMT1_CMT10, @@ -211,7 +207,7 @@ static struct intc_mask_reg intca_mask_registers[] = { { 0, 0, TPU0, TPU1, TPU2, TPU3, TPU4, 0 } }, { 0xe69400b4, 0xe69400f4, 8, /* IMR13A / IMCR13A */ - { SDHI2_SDHI2I3, SDHI2_SDHI2I2, SDHI2_SDHI2I1, SDHI2_SDHI2I0, + { DISABLED, DISABLED, ENABLED, ENABLED, MISTY, CMT3, RWDT1, RWDT0 } }, }; @@ -258,10 +254,14 @@ static struct intc_mask_reg intca_ack_registers[] __initdata = { { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } }, }; -static DECLARE_INTC_DESC_ACK(intca_desc, "sh7367-intca", - intca_vectors, intca_groups, - intca_mask_registers, intca_prio_registers, - intca_sense_registers, intca_ack_registers); +static struct intc_desc intca_desc __initdata = { + .name = "sh7367-intca", + .force_enable = ENABLED, + .force_disable = DISABLED, + .hw = INTC_HW_DESC(intca_vectors, intca_groups, + intca_mask_registers, intca_prio_registers, + intca_sense_registers, intca_ack_registers), +}; void __init sh7367_init_irq(void) { -- cgit v0.10.2 From c148abfc2d807b2734e7ecd0e00c71ef7d4b7f42 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 10 Mar 2010 05:15:16 +0000 Subject: ARM: mach-shmobile: sh7377 SDHI vector merge Merge the SDHI vectors for sh7377 using the recently merged INTC force_enable/disable feature. With this in place SDHI hotplug is supported using the drivers sh_mobile_sdhi and tmio_mmc. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt diff --git a/arch/arm/mach-shmobile/intc-sh7377.c b/arch/arm/mach-shmobile/intc-sh7377.c index 125021c..5c781e2d1 100644 --- a/arch/arm/mach-shmobile/intc-sh7377.c +++ b/arch/arm/mach-shmobile/intc-sh7377.c @@ -27,6 +27,8 @@ enum { UNUSED_INTCA = 0, + ENABLED, + DISABLED, /* interrupt sources INTCA */ IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A, @@ -49,8 +51,8 @@ enum { MSIOF2, MSIOF1, SCIFA4, SCIFA5, SCIFB, FLCTL_FLSTEI, FLCTL_FLTENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I, - SDHI0_SDHI0I0, SDHI0_SDHI0I1, SDHI0_SDHI0I2, SDHI0_SDHI0I3, - SDHI1_SDHI1I0, SDHI1_SDHI1I1, SDHI1_SDHI1I2, SDHI1_SDHI1I3, + SDHI0, + SDHI1, MSU_MSU, MSU_MSU2, IRREM, MSUG, @@ -84,7 +86,7 @@ enum { /* interrupt groups INTCA */ DMAC_1, DMAC_2, DMAC2_1, DMAC2_2, DMAC3_1, DMAC3_2, SHWYSTAT, - AP_ARM1, AP_ARM2, USBHS, SPU2, FLCTL, IIC1, SDHI0, SDHI1, + AP_ARM1, AP_ARM2, USBHS, SPU2, FLCTL, IIC1, ICUSB, ICUDMC }; @@ -128,10 +130,10 @@ static struct intc_vect intca_vectors[] = { INTC_VECT(SCIFB, 0x0d60), INTC_VECT(FLCTL_FLSTEI, 0x0d80), INTC_VECT(FLCTL_FLTENDI, 0x0da0), INTC_VECT(FLCTL_FLTREQ0I, 0x0dc0), INTC_VECT(FLCTL_FLTREQ1I, 0x0de0), - INTC_VECT(SDHI0_SDHI0I0, 0x0e00), INTC_VECT(SDHI0_SDHI0I1, 0x0e20), - INTC_VECT(SDHI0_SDHI0I2, 0x0e40), INTC_VECT(SDHI0_SDHI0I3, 0x0e60), - INTC_VECT(SDHI1_SDHI1I0, 0x0e80), INTC_VECT(SDHI1_SDHI1I1, 0x0ea0), - INTC_VECT(SDHI1_SDHI1I2, 0x0ec0), INTC_VECT(SDHI1_SDHI1I3, 0x0ee0), + INTC_VECT(SDHI0, 0x0e00), INTC_VECT(SDHI0, 0x0e20), + INTC_VECT(SDHI0, 0x0e40), INTC_VECT(SDHI0, 0x0e60), + INTC_VECT(SDHI1, 0x0e80), INTC_VECT(SDHI1, 0x0ea0), + INTC_VECT(SDHI1, 0x0ec0), INTC_VECT(SDHI1, 0x0ee0), INTC_VECT(MSU_MSU, 0x0f20), INTC_VECT(MSU_MSU2, 0x0f40), INTC_VECT(IRREM, 0x0f60), INTC_VECT(MSUG, 0x0fa0), @@ -195,10 +197,6 @@ static struct intc_group intca_groups[] __initdata = { INTC_GROUP(FLCTL, FLCTL_FLSTEI, FLCTL_FLTENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I), INTC_GROUP(IIC1, IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1), - INTC_GROUP(SDHI0, SDHI0_SDHI0I0, SDHI0_SDHI0I1, - SDHI0_SDHI0I2, SDHI0_SDHI0I3), - INTC_GROUP(SDHI1, SDHI1_SDHI1I0, SDHI1_SDHI1I1, - SDHI1_SDHI1I2, SDHI1_SDHI1I3), INTC_GROUP(SHWYSTAT, SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM), INTC_GROUP(ICUSB, ICUSB_ICUSB0, ICUSB_ICUSB1), INTC_GROUP(ICUDMC, ICUDMC_ICUDMC1, ICUDMC_ICUDMC2), @@ -236,10 +234,10 @@ static struct intc_mask_reg intca_mask_registers[] = { { SCIFB, SCIFA5, SCIFA4, MSIOF1, 0, 0, MSIOF2, 0 } }, { 0xe694009c, 0xe69400dc, 8, /* IMR7A / IMCR7A */ - { SDHI0_SDHI0I3, SDHI0_SDHI0I2, SDHI0_SDHI0I1, SDHI0_SDHI0I0, + { DISABLED, DISABLED, ENABLED, ENABLED, FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLTENDI, FLCTL_FLSTEI } }, { 0xe69400a0, 0xe69400e0, 8, /* IMR8A / IMCR8A */ - { SDHI1_SDHI1I3, SDHI1_SDHI1I2, SDHI1_SDHI1I1, SDHI1_SDHI1I0, + { DISABLED, DISABLED, ENABLED, ENABLED, TTI20, USBDMAC_USHDMI, 0, MSUG } }, { 0xe69400a4, 0xe69400e4, 8, /* IMR9A / IMCR9A */ { CMT1_CMT13, CMT1_CMT12, CMT1_CMT11, CMT1_CMT10, @@ -339,10 +337,14 @@ static struct intc_mask_reg intca_ack_registers[] __initdata = { { IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A } }, }; -static DECLARE_INTC_DESC_ACK(intca_desc, "sh7377-intca", - intca_vectors, intca_groups, - intca_mask_registers, intca_prio_registers, - intca_sense_registers, intca_ack_registers); +static struct intc_desc intca_desc __initdata = { + .name = "sh7377-intca", + .force_enable = ENABLED, + .force_disable = DISABLED, + .hw = INTC_HW_DESC(intca_vectors, intca_groups, + intca_mask_registers, intca_prio_registers, + intca_sense_registers, intca_ack_registers), +}; void __init sh7377_init_irq(void) { -- cgit v0.10.2 From c57a31abf0b469b9cab6810f4e1895bb7ef1c482 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 10 Mar 2010 05:17:24 +0000 Subject: ARM: mach-shmobile: sh7372 SDHI vector merge Merge the SDHI vectors for sh7372 using the recently merged INTC force_enable/disable feature. With this in place SDHI hotplug is supported using the drivers sh_mobile_sdhi and tmio_mmc. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt diff --git a/arch/arm/mach-shmobile/intc-sh7372.c b/arch/arm/mach-shmobile/intc-sh7372.c index c57a923..3ce9d9b 100644 --- a/arch/arm/mach-shmobile/intc-sh7372.c +++ b/arch/arm/mach-shmobile/intc-sh7372.c @@ -27,6 +27,8 @@ enum { UNUSED_INTCA = 0, + ENABLED, + DISABLED, /* interrupt sources INTCA */ IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A, @@ -47,14 +49,14 @@ enum { MSIOF2, MSIOF1, SCIFA4, SCIFA5, SCIFB, FLCTL_FLSTEI, FLCTL_FLTENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I, - SDHI0_SDHI0I0, SDHI0_SDHI0I1, SDHI0_SDHI0I2, SDHI0_SDHI0I3, - SDHI1_SDHI1I0, SDHI1_SDHI1I1, SDHI1_SDHI1I2, + SDHI0, + SDHI1, IRREM, IRDA, TPU0, TTI20, DDM, - SDHI2_SDHI2I0, SDHI2_SDHI2I1, SDHI2_SDHI2I2, SDHI2_SDHI2I3, + SDHI2, RWDT0, DMAC1_1_DEI0, DMAC1_1_DEI1, DMAC1_1_DEI2, DMAC1_1_DEI3, DMAC1_2_DEI4, DMAC1_2_DEI5, DMAC1_2_DADERR, @@ -82,7 +84,7 @@ enum { /* interrupt groups INTCA */ DMAC1_1, DMAC1_2, DMAC2_1, DMAC2_2, DMAC3_1, DMAC3_2, SHWYSTAT, - AP_ARM1, AP_ARM2, SPU2, FLCTL, IIC1, SDHI0, SDHI1, SDHI2 + AP_ARM1, AP_ARM2, SPU2, FLCTL, IIC1 }; static struct intc_vect intca_vectors[] __initdata = { @@ -123,17 +125,17 @@ static struct intc_vect intca_vectors[] __initdata = { INTC_VECT(SCIFB, 0x0d60), INTC_VECT(FLCTL_FLSTEI, 0x0d80), INTC_VECT(FLCTL_FLTENDI, 0x0da0), INTC_VECT(FLCTL_FLTREQ0I, 0x0dc0), INTC_VECT(FLCTL_FLTREQ1I, 0x0de0), - INTC_VECT(SDHI0_SDHI0I0, 0x0e00), INTC_VECT(SDHI0_SDHI0I1, 0x0e20), - INTC_VECT(SDHI0_SDHI0I2, 0x0e40), INTC_VECT(SDHI0_SDHI0I3, 0x0e60), - INTC_VECT(SDHI1_SDHI1I0, 0x0e80), INTC_VECT(SDHI1_SDHI1I1, 0x0ea0), - INTC_VECT(SDHI1_SDHI1I2, 0x0ec0), + INTC_VECT(SDHI0, 0x0e00), INTC_VECT(SDHI0, 0x0e20), + INTC_VECT(SDHI0, 0x0e40), INTC_VECT(SDHI0, 0x0e60), + INTC_VECT(SDHI1, 0x0e80), INTC_VECT(SDHI1, 0x0ea0), + INTC_VECT(SDHI1, 0x0ec0), INTC_VECT(IRREM, 0x0f60), INTC_VECT(IRDA, 0x0480), INTC_VECT(TPU0, 0x04a0), INTC_VECT(TTI20, 0x1100), INTC_VECT(DDM, 0x1140), - INTC_VECT(SDHI2_SDHI2I0, 0x1200), INTC_VECT(SDHI2_SDHI2I1, 0x1220), - INTC_VECT(SDHI2_SDHI2I2, 0x1240), INTC_VECT(SDHI2_SDHI2I3, 0x1260), + INTC_VECT(SDHI2, 0x1200), INTC_VECT(SDHI2, 0x1220), + INTC_VECT(SDHI2, 0x1240), INTC_VECT(SDHI2, 0x1260), INTC_VECT(RWDT0, 0x1280), INTC_VECT(DMAC1_1_DEI0, 0x2000), INTC_VECT(DMAC1_1_DEI1, 0x2020), INTC_VECT(DMAC1_1_DEI2, 0x2040), INTC_VECT(DMAC1_1_DEI3, 0x2060), @@ -193,12 +195,6 @@ static struct intc_group intca_groups[] __initdata = { INTC_GROUP(FLCTL, FLCTL_FLSTEI, FLCTL_FLTENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I), INTC_GROUP(IIC1, IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1), - INTC_GROUP(SDHI0, SDHI0_SDHI0I0, SDHI0_SDHI0I1, - SDHI0_SDHI0I2, SDHI0_SDHI0I3), - INTC_GROUP(SDHI1, SDHI1_SDHI1I0, SDHI1_SDHI1I1, - SDHI1_SDHI1I2), - INTC_GROUP(SDHI2, SDHI2_SDHI2I0, SDHI2_SDHI2I1, - SDHI2_SDHI2I2, SDHI2_SDHI2I3), INTC_GROUP(SHWYSTAT, SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM), }; @@ -234,10 +230,10 @@ static struct intc_mask_reg intca_mask_registers[] __initdata = { { SCIFB, SCIFA5, SCIFA4, MSIOF1, 0, 0, MSIOF2, 0 } }, { 0xe694009c, 0xe69400dc, 8, /* IMR7A / IMCR7A */ - { SDHI0_SDHI0I3, SDHI0_SDHI0I2, SDHI0_SDHI0I1, SDHI0_SDHI0I0, + { DISABLED, DISABLED, ENABLED, ENABLED, FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLTENDI, FLCTL_FLSTEI } }, { 0xe69400a0, 0xe69400e0, 8, /* IMR8A / IMCR8A */ - { 0, SDHI1_SDHI1I2, SDHI1_SDHI1I1, SDHI1_SDHI1I0, + { 0, DISABLED, ENABLED, ENABLED, TTI20, USBHSDMAC0_USHDMI, 0, 0 } }, { 0xe69400a4, 0xe69400e4, 8, /* IMR9A / IMCR9A */ { CMT1_CMT13, CMT1_CMT12, CMT1_CMT11, CMT1_CMT10, @@ -252,7 +248,7 @@ static struct intc_mask_reg intca_mask_registers[] __initdata = { { 0, 0, TPU0, 0, 0, 0, 0, 0 } }, { 0xe69400b4, 0xe69400f4, 8, /* IMR13A / IMCR13A */ - { SDHI2_SDHI2I3, SDHI2_SDHI2I2, SDHI2_SDHI2I1, SDHI2_SDHI2I0, + { DISABLED, DISABLED, ENABLED, ENABLED, 0, CMT3, 0, RWDT0 } }, { 0xe6950080, 0xe69500c0, 8, /* IMR0A3 / IMCR0A3 */ { SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM, 0, @@ -358,10 +354,14 @@ static struct intc_mask_reg intca_ack_registers[] __initdata = { { IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A } }, }; -static DECLARE_INTC_DESC_ACK(intca_desc, "sh7372-intca", - intca_vectors, intca_groups, - intca_mask_registers, intca_prio_registers, - intca_sense_registers, intca_ack_registers); +static struct intc_desc intca_desc __initdata = { + .name = "sh7372-intca", + .force_enable = ENABLED, + .force_disable = DISABLED, + .hw = INTC_HW_DESC(intca_vectors, intca_groups, + intca_mask_registers, intca_prio_registers, + intca_sense_registers, intca_ack_registers), +}; void __init sh7372_init_irq(void) { -- cgit v0.10.2 From 3a14d0397732b6aaa541348b5a8e8f639ecd02b7 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 10 Mar 2010 09:26:44 +0000 Subject: ARM: mach-shmobile: ap4evb SDHI0 platform data V2 Add SDHI0 platform data for the AP4EVB board V2. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index a0463d9..1c2ec96 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c @@ -206,10 +206,32 @@ static struct platform_device keysc_device = { }, }; +/* SDHI0 */ +static struct resource sdhi0_resources[] = { + [0] = { + .name = "SDHI0", + .start = 0xe6850000, + .end = 0xe68501ff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 96, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device sdhi0_device = { + .name = "sh_mobile_sdhi", + .num_resources = ARRAY_SIZE(sdhi0_resources), + .resource = sdhi0_resources, + .id = 0, +}; + static struct platform_device *ap4evb_devices[] __initdata = { &nor_flash_device, &smc911x_device, &keysc_device, + &sdhi0_device, }; static struct map_desc ap4evb_io_desc[] __initdata = { @@ -286,6 +308,16 @@ static void __init ap4evb_init(void) gpio_request(GPIO_FN_KEYIN3_133, NULL); gpio_request(GPIO_FN_KEYIN4, NULL); + /* SDHI0 */ + gpio_request(GPIO_FN_SDHICD0, NULL); + gpio_request(GPIO_FN_SDHIWP0, NULL); + gpio_request(GPIO_FN_SDHICMD0, NULL); + gpio_request(GPIO_FN_SDHICLK0, NULL); + gpio_request(GPIO_FN_SDHID0_3, NULL); + gpio_request(GPIO_FN_SDHID0_2, NULL); + gpio_request(GPIO_FN_SDHID0_1, NULL); + gpio_request(GPIO_FN_SDHID0_0, NULL); + sh7372_add_standard_devices(); platform_add_devices(ap4evb_devices, ARRAY_SIZE(ap4evb_devices)); -- cgit v0.10.2 From 7278a22143b003e9af7b9ca1b5f1c40ae4b55d98 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 10 Mar 2010 11:33:10 +0000 Subject: video: enable sh_mobile_lcdc on SH-Mobile ARM This patch enables the sh_mobile_lcdc driver on SH-Mobile ARM. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index dabe804..4be9b48 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -1881,7 +1881,7 @@ config FB_W100 config FB_SH_MOBILE_LCDC tristate "SuperH Mobile LCDC framebuffer support" - depends on FB && SUPERH && HAVE_CLK + depends on FB && (SUPERH || ARCH_SHMOBILE) && HAVE_CLK select FB_SYS_FILLRECT select FB_SYS_COPYAREA select FB_SYS_IMAGEBLIT -- cgit v0.10.2 From 3f7581d66ece6b7ff643c8c817bfbd72cdbe9077 Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Fri, 12 Mar 2010 13:05:06 +0000 Subject: serial: sh-sci: remove duplicated #include Remove duplicated #include('s) in drivers/serial/sh-sci.c Signed-off-by: Huang Weiyi Signed-off-by: Paul Mundt diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 980f394..f7b9aff 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -50,7 +50,6 @@ #include #include #include -#include #ifdef CONFIG_SUPERH #include -- cgit v0.10.2 From f937331b3f92cb2f67bc81baa1b8cc5198c439e5 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 15 Mar 2010 01:29:41 +0100 Subject: init dynamic bin_attribute structures Commit 6992f5334995af474c2b58d010d08bc597f0f2fe ("sysfs: Use one lockdep class per sysfs attribute.") introduced this requirement. First, at25 was fixed manually. Then, other occurences were found with coccinelle and the following semantic patch. Results were reviewed and fixed up: @ init @ identifier struct_name, bin; @@ struct struct_name { ... struct bin_attribute bin; ... }; @ main extends init @ expression E; statement S; identifier name, err; @@ ( struct struct_name *name; | - struct struct_name *name = NULL; + struct struct_name *name; ) ... ( sysfs_bin_attr_init(&name->bin); | + sysfs_bin_attr_init(&name->bin); if (sysfs_create_bin_file(E, &name->bin)) S | + sysfs_bin_attr_init(&name->bin); err = sysfs_create_bin_file(E, &name->bin); ) Signed-off-by: Wolfram Sang Cc: Eric W. Biederman Signed-off-by: Linus Torvalds diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c index 7174d83..95184a0 100644 --- a/arch/mips/txx9/generic/setup.c +++ b/arch/mips/txx9/generic/setup.c @@ -956,6 +956,7 @@ void __init txx9_sramc_init(struct resource *r) if (!dev->base) goto exit; dev->dev.cls = &txx9_sramc_sysdev_class; + sysfs_bin_attr_init(&dev->bindata_attr); dev->bindata_attr.attr.name = "bindata"; dev->bindata_attr.attr.mode = S_IRUSR | S_IWUSR; dev->bindata_attr.read = txx9_sram_read; diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c index d902d81..d194212 100644 --- a/drivers/misc/eeprom/at25.c +++ b/drivers/misc/eeprom/at25.c @@ -347,6 +347,7 @@ static int at25_probe(struct spi_device *spi) * that's sensitive for read and/or write, like ethernet addresses, * security codes, board-specific manufacturing calibrations, etc. */ + sysfs_bin_attr_init(&at25->bin); at25->bin.attr.name = "eeprom"; at25->bin.attr.mode = S_IRUSR; at25->bin.read = at25_bin_read; diff --git a/drivers/rtc/rtc-ds1742.c b/drivers/rtc/rtc-ds1742.c index a127336..cad9ceb 100644 --- a/drivers/rtc/rtc-ds1742.c +++ b/drivers/rtc/rtc-ds1742.c @@ -184,6 +184,7 @@ static int __devinit ds1742_rtc_probe(struct platform_device *pdev) pdata->size_nvram = pdata->size - RTC_SIZE; pdata->ioaddr_rtc = ioaddr + pdata->size_nvram; + sysfs_bin_attr_init(&pdata->nvram_attr); pdata->nvram_attr.attr.name = "nvram"; pdata->nvram_attr.attr.mode = S_IRUGO | S_IWUSR; pdata->nvram_attr.read = ds1742_nvram_read; -- cgit v0.10.2 From cd3d8031eb4311e516329aee03c79a08333141f1 Mon Sep 17 00:00:00 2001 From: KOSAKI Motohiro Date: Fri, 12 Mar 2010 16:15:36 +0900 Subject: sched: sched_getaffinity(): Allow less than NR_CPUS length [ Note, this commit changes the syscall ABI for > 1024 CPUs systems. ] Recently, some distro decided to use NR_CPUS=4096 for mysterious reasons. Unfortunately, glibc sched interface has the following definition: # define __CPU_SETSIZE 1024 # define __NCPUBITS (8 * sizeof (__cpu_mask)) typedef unsigned long int __cpu_mask; typedef struct { __cpu_mask __bits[__CPU_SETSIZE / __NCPUBITS]; } cpu_set_t; It mean, if NR_CPUS is bigger than 1024, cpu_set_t makes an ABI issue ... More recently, Sharyathi Nagesh reported following test program makes misterious syscall failure: ----------------------------------------------------------------------- #define _GNU_SOURCE #include #include #include int main() { cpu_set_t set; if (sched_getaffinity(0, sizeof(cpu_set_t), &set) < 0) printf("\n Call is failing with:%d", errno); } ----------------------------------------------------------------------- Because the kernel assumes len argument of sched_getaffinity() is bigger than NR_CPUS. But now it is not correct. Now we are faced with the following annoying dilemma, due to the limitations of the glibc interface built in years ago: (1) if we change glibc's __CPU_SETSIZE definition, we lost binary compatibility of _all_ application. (2) if we don't change it, we also lost binary compatibility of Sharyathi's use case. Then, I would propse to change the rule of the len argument of sched_getaffinity(). Old: len should be bigger than NR_CPUS New: len should be bigger than maximum possible cpu id This creates the following behavior: (A) In the real 4096 cpus machine, the above test program still return -EINVAL. (B) NR_CPUS=4096 but the machine have less than 1024 cpus (almost all machines in the world), the above can run successfully. Fortunatelly, BIG SGI machine is mainly used for HPC use case. It means they can rebuild their programs. IOW we hope they are not annoyed by this issue ... Reported-by: Sharyathi Nagesh Signed-off-by: KOSAKI Motohiro Acked-by: Ulrich Drepper Acked-by: Peter Zijlstra Cc: Linus Torvalds Cc: Andrew Morton Cc: Jack Steiner Cc: Russ Anderson Cc: Mike Travis LKML-Reference: <20100312161316.9520.A69D9226@jp.fujitsu.com> Signed-off-by: Ingo Molnar diff --git a/kernel/sched.c b/kernel/sched.c index 9ab3cd7..6eaef3d 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -4902,7 +4902,9 @@ SYSCALL_DEFINE3(sched_getaffinity, pid_t, pid, unsigned int, len, int ret; cpumask_var_t mask; - if (len < cpumask_size()) + if (len < nr_cpu_ids) + return -EINVAL; + if (len & (sizeof(unsigned long)-1)) return -EINVAL; if (!alloc_cpumask_var(&mask, GFP_KERNEL)) @@ -4910,10 +4912,12 @@ SYSCALL_DEFINE3(sched_getaffinity, pid_t, pid, unsigned int, len, ret = sched_getaffinity(pid, mask); if (ret == 0) { - if (copy_to_user(user_mask_ptr, mask, cpumask_size())) + int retlen = min(len, cpumask_size()); + + if (copy_to_user(user_mask_ptr, mask, retlen)) ret = -EFAULT; else - ret = cpumask_size(); + ret = retlen; } free_cpumask_var(mask); -- cgit v0.10.2 From c602c8ad45d6ee6ad91fc544513cc96f70790983 Mon Sep 17 00:00:00 2001 From: Vitaliy Kulikov Date: Mon, 15 Mar 2010 09:01:26 +0100 Subject: ALSA: hda - New Intel HDA controller Added a PCI controller id on new Dell laptops. Signed-off-by: Vitaliy Kulikov Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 10bbb53..9268152 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2706,6 +2706,7 @@ static struct pci_device_id azx_ids[] = { { PCI_DEVICE(0x8086, 0x3a6e), .driver_data = AZX_DRIVER_ICH }, /* PCH */ { PCI_DEVICE(0x8086, 0x3b56), .driver_data = AZX_DRIVER_ICH }, + { PCI_DEVICE(0x8086, 0x3b57), .driver_data = AZX_DRIVER_ICH }, /* CPT */ { PCI_DEVICE(0x8086, 0x1c20), .driver_data = AZX_DRIVER_PCH }, /* SCH */ -- cgit v0.10.2 From 28d1a85e136985982448b2f9b1342bae85ad1c98 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 15 Mar 2010 09:05:46 +0100 Subject: ALSA: hda - Add an error message for invalid mapping NID Add an error message to snd_hda_add_nid() for invalid mapping NID to make easier to hunt the buggy code. Also added a missing space to the error message in snd_hda_build_controls() Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 5bd7cf4..0e76ac2 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -1806,6 +1806,8 @@ int snd_hda_add_nid(struct hda_codec *codec, struct snd_kcontrol *kctl, item->nid = nid; return 0; } + printk(KERN_ERR "hda-codec: no NID for mapping control %s:%d:%d\n", + kctl->id.name, kctl->id.index, index); return -EINVAL; } EXPORT_SYMBOL_HDA(snd_hda_add_nid); @@ -2884,7 +2886,7 @@ int /*__devinit*/ snd_hda_build_controls(struct hda_bus *bus) list_for_each_entry(codec, &bus->codec_list, list) { int err = snd_hda_codec_build_controls(codec); if (err < 0) { - printk(KERN_ERR "hda_codec: cannot build controls" + printk(KERN_ERR "hda_codec: cannot build controls " "for #%d (error %d)\n", codec->addr, err); err = snd_hda_codec_reset(codec); if (err < 0) { -- cgit v0.10.2 From 9c4cc0bdede1c39bde60a0d5d9251aac71fbe719 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 15 Mar 2010 09:07:52 +0100 Subject: ALSA: hda - Fix secondary ADC of ALC260 basic model Fix adc_nids[] for ALC260 basic model to match with num_adc_nids. Otherwise you get an invalid NID in the secondary "Input Source" mixer element. Signed-off-by: Takashi Iwai Cc: diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 3a83719..ba45868 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6477,7 +6477,7 @@ static struct alc_config_preset alc260_presets[] = { .num_dacs = ARRAY_SIZE(alc260_dac_nids), .dac_nids = alc260_dac_nids, .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), - .adc_nids = alc260_adc_nids, + .adc_nids = alc260_dual_adc_nids, .num_channel_mode = ARRAY_SIZE(alc260_modes), .channel_mode = alc260_modes, .input_mux = &alc260_capture_source, -- cgit v0.10.2 From b43f6e5e258d67acae5961896d10bbe38c271070 Mon Sep 17 00:00:00 2001 From: Anisse Astier Date: Wed, 10 Mar 2010 19:17:46 +0100 Subject: ALSA: hda - Add PCI quirks for MSI NetOn AP1900 and Wind Top AE2220 This should make the speakers and jack detection work on MSI all-in-one computers NetOn AP1900 and Wind Top AE2220. Signed-off-by: Anisse Astier Cc: Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index ba45868..07637c4 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -9195,6 +9195,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = { SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG), SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG), SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG), + SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG), SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG), SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG), SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG), @@ -9204,6 +9205,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = { SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG), SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG), SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG), + SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG), SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG), SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG), -- cgit v0.10.2 From ce619e1fb86d68f125e0e6d10a5484f67a6d97b3 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 12 Mar 2010 12:46:05 +0200 Subject: OMAP: DSS2: initialize dss clk sources properly Clk sources were not initialized, leading to kernel crash, or possibly to strange behaviour if DSI was compiled in. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index 8254a42..5434418 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -590,6 +590,9 @@ int dss_init(bool skip_init) } } + dss.dsi_clk_source = DSS_SRC_DSS1_ALWON_FCLK; + dss.dispc_clk_source = DSS_SRC_DSS1_ALWON_FCLK; + dss_save_context(); rev = dss_read_reg(DSS_REVISION); -- cgit v0.10.2 From 8871d54b5e1558bd59baad02eb7a80f86d49f4a1 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 4 Mar 2010 17:52:43 +0200 Subject: OMAP: DSS2: panel-generic: re-implement mode changing Mode changing code was left out with the DSS driver remodeling. Add the code back. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/displays/panel-generic.c b/drivers/video/omap2/displays/panel-generic.c index c59e4ba..300eff5 100644 --- a/drivers/video/omap2/displays/panel-generic.c +++ b/drivers/video/omap2/displays/panel-generic.c @@ -116,6 +116,24 @@ static int generic_panel_resume(struct omap_dss_device *dssdev) return 0; } +static void generic_panel_set_timings(struct omap_dss_device *dssdev, + struct omap_video_timings *timings) +{ + dpi_set_timings(dssdev, timings); +} + +static void generic_panel_get_timings(struct omap_dss_device *dssdev, + struct omap_video_timings *timings) +{ + *timings = dssdev->panel.timings; +} + +static int generic_panel_check_timings(struct omap_dss_device *dssdev, + struct omap_video_timings *timings) +{ + return dpi_check_timings(dssdev, timings); +} + static struct omap_dss_driver generic_driver = { .probe = generic_panel_probe, .remove = generic_panel_remove, @@ -125,6 +143,10 @@ static struct omap_dss_driver generic_driver = { .suspend = generic_panel_suspend, .resume = generic_panel_resume, + .set_timings = generic_panel_set_timings, + .get_timings = generic_panel_get_timings, + .check_timings = generic_panel_check_timings, + .driver = { .name = "generic_panel", .owner = THIS_MODULE, -- cgit v0.10.2 From 2cda2728aa1c8c006418a24f867b25e5eb7a32e2 Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Mon, 15 Mar 2010 12:46:51 +0100 Subject: block: Fix overrun in lcm() and move it to lib lcm() was defined to take integer-sized arguments. The supplied arguments are multiplied, however, causing us to overflow given sufficiently large input. That in turn led to incorrect optimal I/O size reporting in some cases (RAID over RAID). Switch lcm() over to unsigned long similar to gcd() and move the function from blk-settings.c to lib. Signed-off-by: Martin K. Petersen Signed-off-by: Jens Axboe diff --git a/block/blk-settings.c b/block/blk-settings.c index 31e7a93..4c4700d 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c @@ -8,6 +8,7 @@ #include #include /* for max_pfn/max_low_pfn */ #include +#include #include #include "blk.h" @@ -461,16 +462,6 @@ void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b) } EXPORT_SYMBOL(blk_queue_stack_limits); -static unsigned int lcm(unsigned int a, unsigned int b) -{ - if (a && b) - return (a * b) / gcd(a, b); - else if (b) - return b; - - return a; -} - /** * blk_stack_limits - adjust queue_limits for stacked devices * @t: the stacking driver limits (top device) diff --git a/include/linux/lcm.h b/include/linux/lcm.h new file mode 100644 index 0000000..7bf01d7 --- /dev/null +++ b/include/linux/lcm.h @@ -0,0 +1,8 @@ +#ifndef _LCM_H +#define _LCM_H + +#include + +unsigned long lcm(unsigned long a, unsigned long b) __attribute_const__; + +#endif /* _LCM_H */ diff --git a/lib/Makefile b/lib/Makefile index 2e152ae..0d40152 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -21,7 +21,7 @@ lib-y += kobject.o kref.o klist.o obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \ bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \ - string_helpers.o gcd.o list_sort.o + string_helpers.o gcd.o lcm.o list_sort.o ifeq ($(CONFIG_DEBUG_KOBJECT),y) CFLAGS_kobject.o += -DDEBUG diff --git a/lib/lcm.c b/lib/lcm.c new file mode 100644 index 0000000..157cd88 --- /dev/null +++ b/lib/lcm.c @@ -0,0 +1,15 @@ +#include +#include +#include + +/* Lowest common multiple */ +unsigned long lcm(unsigned long a, unsigned long b) +{ + if (a && b) + return (a * b) / gcd(a, b); + else if (b) + return b; + + return a; +} +EXPORT_SYMBOL_GPL(lcm); -- cgit v0.10.2 From ee714f2dd33e726346e34f5cda12543162f4753e Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Wed, 10 Mar 2010 00:48:32 -0500 Subject: block: Finalize conversion of block limits functions Remove compatibility wrappers and update remaining drivers. Signed-off-by: Martin K. Petersen Signed-off-by: Jens Axboe diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index 459f1bc..c5f22bb 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c @@ -2533,7 +2533,6 @@ static bool DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller) Controller->RequestQueue[n] = RequestQueue; blk_queue_bounce_limit(RequestQueue, Controller->BounceBufferLimit); RequestQueue->queuedata = Controller; - blk_queue_max_hw_segments(RequestQueue, Controller->DriverScatterGatherLimit); blk_queue_max_segments(RequestQueue, Controller->DriverScatterGatherLimit); blk_queue_max_hw_sectors(RequestQueue, Controller->MaxBlocksPerCommand); disk->queue = RequestQueue; diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 3c64af0..653817c 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -347,14 +347,13 @@ static int __devinit virtblk_probe(struct virtio_device *vdev) set_capacity(vblk->disk, cap); /* We can handle whatever the host told us to handle. */ - blk_queue_max_phys_segments(q, vblk->sg_elems-2); - blk_queue_max_hw_segments(q, vblk->sg_elems-2); + blk_queue_max_segments(q, vblk->sg_elems-2); /* No need to bounce any requests */ blk_queue_bounce_limit(q, BLK_BOUNCE_ANY); /* No real sector limit. */ - blk_queue_max_sectors(q, -1U); + blk_queue_max_hw_sectors(q, -1U); /* Host can optionally specify maximum segment size and number of * segments. */ diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index ebd22db..41551c9 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -921,26 +921,7 @@ extern void blk_cleanup_queue(struct request_queue *); extern void blk_queue_make_request(struct request_queue *, make_request_fn *); extern void blk_queue_bounce_limit(struct request_queue *, u64); extern void blk_queue_max_hw_sectors(struct request_queue *, unsigned int); - -/* Temporary compatibility wrapper */ -static inline void blk_queue_max_sectors(struct request_queue *q, unsigned int max) -{ - blk_queue_max_hw_sectors(q, max); -} - extern void blk_queue_max_segments(struct request_queue *, unsigned short); - -static inline void blk_queue_max_phys_segments(struct request_queue *q, unsigned short max) -{ - blk_queue_max_segments(q, max); -} - -static inline void blk_queue_max_hw_segments(struct request_queue *q, unsigned short max) -{ - blk_queue_max_segments(q, max); -} - - extern void blk_queue_max_segment_size(struct request_queue *, unsigned int); extern void blk_queue_max_discard_sectors(struct request_queue *q, unsigned int max_discard_sectors); @@ -1030,11 +1011,6 @@ static inline int sb_issue_discard(struct super_block *sb, extern int blk_verify_command(unsigned char *cmd, fmode_t has_write_perm); -#define MAX_PHYS_SEGMENTS 128 -#define MAX_HW_SEGMENTS 128 -#define SAFE_MAX_SECTORS 255 -#define MAX_SEGMENT_SIZE 65536 - enum blk_default_limits { BLK_MAX_SEGMENTS = 128, BLK_SAFE_MAX_SECTORS = 255, -- cgit v0.10.2 From c77a5710b7e23847bfdb81fcaa10b585f65c960a Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Wed, 10 Mar 2010 00:48:33 -0500 Subject: block: Export max number of segments and max segment size in sysfs These two values are useful when debugging issues surrounding maximum I/O size. Put them in sysfs with the rest of the queue limits. Signed-off-by: Martin K. Petersen Signed-off-by: Jens Axboe diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index e854424..fad8655 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c @@ -106,6 +106,19 @@ static ssize_t queue_max_sectors_show(struct request_queue *q, char *page) return queue_var_show(max_sectors_kb, (page)); } +static ssize_t queue_max_segments_show(struct request_queue *q, char *page) +{ + return queue_var_show(queue_max_segments(q), (page)); +} + +static ssize_t queue_max_segment_size_show(struct request_queue *q, char *page) +{ + if (test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags)) + return queue_var_show(queue_max_segment_size(q), (page)); + + return queue_var_show(PAGE_CACHE_SIZE, (page)); +} + static ssize_t queue_logical_block_size_show(struct request_queue *q, char *page) { return queue_var_show(queue_logical_block_size(q), page); @@ -280,6 +293,16 @@ static struct queue_sysfs_entry queue_max_hw_sectors_entry = { .show = queue_max_hw_sectors_show, }; +static struct queue_sysfs_entry queue_max_segments_entry = { + .attr = {.name = "max_segments", .mode = S_IRUGO }, + .show = queue_max_segments_show, +}; + +static struct queue_sysfs_entry queue_max_segment_size_entry = { + .attr = {.name = "max_segment_size", .mode = S_IRUGO }, + .show = queue_max_segment_size_show, +}; + static struct queue_sysfs_entry queue_iosched_entry = { .attr = {.name = "scheduler", .mode = S_IRUGO | S_IWUSR }, .show = elv_iosched_show, @@ -355,6 +378,8 @@ static struct attribute *default_attrs[] = { &queue_ra_entry.attr, &queue_max_hw_sectors_entry.attr, &queue_max_sectors_entry.attr, + &queue_max_segments_entry.attr, + &queue_max_segment_size_entry.attr, &queue_iosched_entry.attr, &queue_hw_sector_size_entry.attr, &queue_logical_block_size_entry.attr, -- cgit v0.10.2 From cf36df6bfb49fd265a39f676bfc9718029fef160 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 15 Mar 2010 13:20:32 +0100 Subject: firewire: core: fw_iso_resource_manage: fix error handling If the bandwidth allocation fails, the error must be returned in *channel regardless of whether the channel allocation succeeded. Checking for c >= 0 is not correct if no channel allocation was requested, in which case this part of the code is reached with c == -EINVAL. Signed-off-by: Clemens Ladisch Signed-off-by: Stefan Richter diff --git a/drivers/firewire/core-iso.c b/drivers/firewire/core-iso.c index 1c0b504..99c20f1 100644 --- a/drivers/firewire/core-iso.c +++ b/drivers/firewire/core-iso.c @@ -331,8 +331,9 @@ void fw_iso_resource_manage(struct fw_card *card, int generation, if (ret < 0) *bandwidth = 0; - if (allocate && ret < 0 && c >= 0) { - deallocate_channel(card, irm_id, generation, c, buffer); + if (allocate && ret < 0) { + if (c >= 0) + deallocate_channel(card, irm_id, generation, c, buffer); *channel = ret; } } -- cgit v0.10.2 From 7a410e8d4d97457c8c381e2de9cdc7bd3306badc Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Wed, 10 Mar 2010 15:57:56 +0900 Subject: pcmcia/vrc4171: use local spinlock for device local lock. struct pcmcia_socket lock had been used before. Signed-off-by: Yoichi Yuasa Signed-off-by: Dominik Brodowski diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c index c9fcbdc..aaccdb9 100644 --- a/drivers/pcmcia/vrc4171_card.c +++ b/drivers/pcmcia/vrc4171_card.c @@ -105,6 +105,7 @@ typedef struct vrc4171_socket { char name[24]; int csc_irq; int io_irq; + spinlock_t lock; } vrc4171_socket_t; static vrc4171_socket_t vrc4171_sockets[CARD_MAX_SLOTS]; @@ -327,7 +328,7 @@ static int pccard_set_socket(struct pcmcia_socket *sock, socket_state_t *state) slot = sock->sock; socket = &vrc4171_sockets[slot]; - spin_lock_irq(&sock->lock); + spin_lock_irq(&socket->lock); voltage = set_Vcc_value(state->Vcc); exca_write_byte(slot, CARD_VOLTAGE_SELECT, voltage); @@ -370,7 +371,7 @@ static int pccard_set_socket(struct pcmcia_socket *sock, socket_state_t *state) cscint |= I365_CSC_DETECT; exca_write_byte(slot, I365_CSCINT, cscint); - spin_unlock_irq(&sock->lock); + spin_unlock_irq(&socket->lock); return 0; } -- cgit v0.10.2 From 7a96e87d6e58a07235a2bc3eff9b093af4937a72 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sat, 13 Mar 2010 17:42:39 +0100 Subject: pcmcia: pd6729, i82092: use parent (PCI) resources A newly added parent resource entry for the root PCI bus, such as 40000000-ffffffff : PCI Bus #00 means that the pd6729 and i82092 drivers cannot allocate iomem as freely as before, unless they do so as PCI devices. Therefore, set socket->cb_dev so that rsrc_nonstatic.c does the right thing. Reported-by: Komuro Signed-off-by: Dominik Brodowski diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c index a04f21c..f5da626 100644 --- a/drivers/pcmcia/i82092.c +++ b/drivers/pcmcia/i82092.c @@ -133,6 +133,7 @@ static int __devinit i82092aa_pci_probe(struct pci_dev *dev, const struct pci_de sockets[i].socket.map_size = 0x1000; sockets[i].socket.irq_mask = 0; sockets[i].socket.pci_irq = dev->irq; + sockets[i].socket.cb_dev = dev; sockets[i].socket.owner = THIS_MODULE; sockets[i].number = i; diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c index 7c20491..7ba57a5 100644 --- a/drivers/pcmcia/pd6729.c +++ b/drivers/pcmcia/pd6729.c @@ -671,6 +671,7 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev, socket[i].socket.map_size = 0x1000; socket[i].socket.irq_mask = mask; socket[i].socket.pci_irq = dev->irq; + socket[i].socket.cb_dev = dev; socket[i].socket.owner = THIS_MODULE; socket[i].number = i; -- cgit v0.10.2 From b416cd8efb6ce2661f8f98f603972f0b8f796ee4 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 9 Mar 2010 17:17:36 +0100 Subject: pcmcia: revert "irq probe can be done without risking an IRQ storm" This reverts commit 635416ef393e8cec5a89fc6c1de710ee9596a51e. The argument passed to request_irq() only affects action->flags (IRQF_*), but IRQ_NOAUTOEN relates to desc->status. Reported-by: Jan Beulich CC: Alan Cox Signed-off-by: Dominik Brodowski diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index b2df041..ef782c0 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c @@ -752,14 +752,6 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) #ifdef CONFIG_PCMCIA_PROBE -#ifdef IRQ_NOAUTOEN - /* if the underlying IRQ infrastructure allows for it, only allocate - * the IRQ, but do not enable it - */ - if (!(req->Handler)) - type |= IRQ_NOAUTOEN; -#endif /* IRQ_NOAUTOEN */ - if (s->irq.AssignedIRQ != 0) { /* If the interrupt is already assigned, it must be the same */ irq = s->irq.AssignedIRQ; -- cgit v0.10.2 From 28ca8dd71fc170090edca62cb8129625d01b7760 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20K=C3=BCnzer?= Date: Sat, 6 Mar 2010 07:46:16 +0100 Subject: pcmcia: honor saved flags in yenta_socket's I365_CSCINT register Instead of overwriting the I365_CSCINT register, save the old value and merely change the bits we care about. Part 1 of a series to allow the ISA irq to be used for Cardbus devices if the socket's PCI irq is unusable. [linux@dominikbrodowski.net: split up the original patch, commit message] Signed-off-by: Jens Kuenzer Signed-off-by: Dominik Brodowski diff --git a/drivers/pcmcia/i82365.h b/drivers/pcmcia/i82365.h index 849ef1b..3f84d7a 100644 --- a/drivers/pcmcia/i82365.h +++ b/drivers/pcmcia/i82365.h @@ -95,6 +95,7 @@ #define I365_CSC_DETECT 0x08 #define I365_CSC_ANY 0x0F #define I365_CSC_GPI 0x10 +#define I365_CSC_IRQ_MASK 0xF0 /* Flags for I365_ADDRWIN */ #define I365_ENA_IO(map) (0x40 << (map)) diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index 967c766..42f6763 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c @@ -356,7 +356,9 @@ static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state) exca_writeb(socket, I365_POWER, reg); /* CSC interrupt: no ISA irq for CSC */ - reg = I365_CSC_DETECT; + reg = exca_readb(socket, I365_CSCINT); + reg &= I365_CSC_IRQ_MASK; + reg |= I365_CSC_DETECT; if (state->flags & SS_IOCARD) { if (state->csc_mask & SS_STSCHG) reg |= I365_CSC_STSCHG; @@ -912,6 +914,7 @@ static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mas int i; unsigned long val; u32 mask; + u8 reg; /* * Probe for usable interrupts using the force @@ -919,6 +922,7 @@ static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mas */ cb_writel(socket, CB_SOCKET_EVENT, -1); cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK); + reg = exca_readb(socket, I365_CSCINT); exca_writeb(socket, I365_CSCINT, 0); val = probe_irq_on() & isa_irq_mask; for (i = 1; i < 16; i++) { @@ -930,7 +934,7 @@ static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mas cb_writel(socket, CB_SOCKET_EVENT, -1); } cb_writel(socket, CB_SOCKET_MASK, 0); - exca_writeb(socket, I365_CSCINT, 0); + exca_writeb(socket, I365_CSCINT, reg); mask = probe_irq_mask(val) & 0xffff; @@ -967,6 +971,8 @@ static irqreturn_t yenta_probe_handler(int irq, void *dev_id) /* probes the PCI interrupt, use only on override functions */ static int yenta_probe_cb_irq(struct yenta_socket *socket) { + u8 reg; + if (!socket->cb_irq) return -1; @@ -979,7 +985,8 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket) } /* generate interrupt, wait */ - exca_writeb(socket, I365_CSCINT, I365_CSC_STSCHG); + reg = exca_readb(socket, I365_CSCINT); + exca_writeb(socket, I365_CSCINT, reg | I365_CSC_STSCHG); cb_writel(socket, CB_SOCKET_EVENT, -1); cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK); cb_writel(socket, CB_SOCKET_FORCE, CB_FCARDSTS); @@ -988,7 +995,7 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket) /* disable interrupts */ cb_writel(socket, CB_SOCKET_MASK, 0); - exca_writeb(socket, I365_CSCINT, 0); + exca_writeb(socket, I365_CSCINT, reg); cb_writel(socket, CB_SOCKET_EVENT, -1); exca_readb(socket, I365_CSC); -- cgit v0.10.2 From ba8819e991ac507fcbfa080eacdff3e7eea4dc03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20K=C3=BCnzer?= Date: Sat, 6 Mar 2010 08:02:24 +0100 Subject: pcmcia: allow for cb_irq to differ from pci_dev's irq in yenta_socket cb_irq is presumed to be the same as the pci_dev's irq. This won't be true any more as soon as we allow the ISA irq to be used for Cardbus devices. Therefore, use the pci_dev's irq explicitely whenever we care about it. Part 2 of a series to allow the ISA irq to be used for Cardbus devices if the socket's PCI irq is unusable. [linux@dominikbrodowski.net: split up the original patch, commit message] Signed-off-by: Jens Kuenzer Signed-off-by: Dominik Brodowski diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index 42f6763..51ee68d 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c @@ -329,8 +329,8 @@ static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state) /* ISA interrupt control? */ intr = exca_readb(socket, I365_INTCTL); intr = (intr & ~0xf); - if (!socket->cb_irq) { - intr |= state->io_irq; + if (!socket->dev->irq) { + intr |= socket->cb_irq ? socket->cb_irq : state->io_irq; bridge |= CB_BRIDGE_INTR; } exca_writeb(socket, I365_INTCTL, intr); @@ -340,7 +340,7 @@ static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state) reg = exca_readb(socket, I365_INTCTL) & (I365_RING_ENA | I365_INTR_ENA); reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET; reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0; - if (state->io_irq != socket->cb_irq) { + if (state->io_irq != socket->dev->irq) { reg |= state->io_irq; bridge |= CB_BRIDGE_INTR; } -- cgit v0.10.2 From 0d3a940de51c47a3d6322537c8dce925db755477 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20K=C3=BCnzer?= Date: Sat, 6 Mar 2010 08:27:22 +0100 Subject: pcmcia: re-route Cardbus IRQ to ISA on ti1130 bridges if necessary As the PCI irq pin of the ti1130 pcmcia bridge is not connected (at least on some old IBM Thinkpad 760ED notebooks), the Cardbus IRQ has to be routed to an ISA irq. Part 3 of a series to allow the ISA irq to be used for Cardbus devices if the socket's PCI irq is unusable. [linux@dominikbrodowski.net: split up the original patch, commit message, cleanup] Signed-off-by: Jens Kuenzer Signed-off-by: Dominik Brodowski diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h index aaa7022..9ffa97d 100644 --- a/drivers/pcmcia/ti113x.h +++ b/drivers/pcmcia/ti113x.h @@ -296,7 +296,7 @@ static int ti_init(struct yenta_socket *socket) u8 new, reg = exca_readb(socket, I365_INTCTL); new = reg & ~I365_INTR_ENA; - if (socket->cb_irq) + if (socket->dev->irq) new |= I365_INTR_ENA; if (new != reg) exca_writeb(socket, I365_INTCTL, new); @@ -316,14 +316,47 @@ static int ti_override(struct yenta_socket *socket) return 0; } +static void ti113x_use_isa_irq(struct yenta_socket *socket) +{ + int isa_irq = -1; + u8 intctl; + u32 isa_irq_mask = 0; + + if (!isa_probe) + return; + + /* get a free isa int */ + isa_irq_mask = yenta_probe_irq(socket, isa_interrupts); + if (!isa_irq_mask) + return; /* no useable isa irq found */ + + /* choose highest available */ + for (; isa_irq_mask; isa_irq++) + isa_irq_mask >>= 1; + socket->cb_irq = isa_irq; + + exca_writeb(socket, I365_CSCINT, (isa_irq << 4)); + + intctl = exca_readb(socket, I365_INTCTL); + intctl &= ~(I365_INTR_ENA | I365_IRQ_MASK); /* CSC Enable */ + exca_writeb(socket, I365_INTCTL, intctl); + + dev_info(&socket->dev->dev, + "Yenta TI113x: using isa irq %d for CardBus\n", isa_irq); +} + + static int ti113x_override(struct yenta_socket *socket) { u8 cardctl; cardctl = config_readb(socket, TI113X_CARD_CONTROL); cardctl &= ~(TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_IREQ | TI113X_CCR_PCI_CSC); - if (socket->cb_irq) + if (socket->dev->irq) cardctl |= TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_CSC | TI113X_CCR_PCI_IREQ; + else + ti113x_use_isa_irq(socket); + config_writeb(socket, TI113X_CARD_CONTROL, cardctl); return ti_override(socket); diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index 51ee68d..418988a 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c @@ -42,6 +42,18 @@ module_param_string(o2_speedup, o2_speedup, sizeof(o2_speedup), 0444); MODULE_PARM_DESC(o2_speedup, "Use prefetch/burst for O2-bridges: 'on', 'off' " "or 'default' (uses recommended behaviour for the detected bridge)"); +/* + * Only probe "regular" interrupts, don't + * touch dangerous spots like the mouse irq, + * because there are mice that apparently + * get really confused if they get fondled + * too intimately. + * + * Default to 11, 10, 9, 7, 6, 5, 4, 3. + */ +static u32 isa_interrupts = 0x0ef8; + + #define debug(x, s, args...) dev_dbg(&s->dev->dev, x, ##args) /* Don't ask.. */ @@ -54,6 +66,8 @@ MODULE_PARM_DESC(o2_speedup, "Use prefetch/burst for O2-bridges: 'on', 'off' " */ #ifdef CONFIG_YENTA_TI static int yenta_probe_cb_irq(struct yenta_socket *socket); +static unsigned int yenta_probe_irq(struct yenta_socket *socket, + u32 isa_irq_mask); #endif @@ -898,17 +912,6 @@ static struct cardbus_type cardbus_type[] = { }; -/* - * Only probe "regular" interrupts, don't - * touch dangerous spots like the mouse irq, - * because there are mice that apparently - * get really confused if they get fondled - * too intimately. - * - * Default to 11, 10, 9, 7, 6, 5, 4, 3. - */ -static u32 isa_interrupts = 0x0ef8; - static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mask) { int i; -- cgit v0.10.2 From e794c01b7de40d180417eacbd910e8f31f2fafeb Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 15 Mar 2010 11:25:10 +0300 Subject: pcmcia: add important if statement There was a problem introduced in Jul 2008 by: 0e6f9d270840 pcmcia: use pcmcia_loop_config in scsi pcmcia drivers Signed-off-by: Dan Carpenter Signed-off-by: Dominik Brodowski diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c index c2341af..0212464 100644 --- a/drivers/scsi/pcmcia/nsp_cs.c +++ b/drivers/scsi/pcmcia/nsp_cs.c @@ -1717,6 +1717,7 @@ static int nsp_cs_config(struct pcmcia_device *link) cfg_mem->data = data; ret = pcmcia_loop_config(link, nsp_cs_config_check, cfg_mem); + if (ret) goto cs_failed; if (link->conf.Attributes & CONF_ENABLE_IRQ) { -- cgit v0.10.2 From b89ebadc3421f8ff85030768ec14144794984877 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 15 Mar 2010 14:29:22 +0000 Subject: ARM: Add final piece to fix XIP decompressor in read-only memory This defines STATIC_RW_DATA, which prevents the read/write malloc management data being declared with a static attribute. Signed-off-by: Russell King diff --git a/arch/arm/boot/compressed/decompress.c b/arch/arm/boot/compressed/decompress.c index 0da382f..9c09707 100644 --- a/arch/arm/boot/compressed/decompress.c +++ b/arch/arm/boot/compressed/decompress.c @@ -11,6 +11,7 @@ extern unsigned long free_mem_end_ptr; extern void error(char *); #define STATIC static +#define STATIC_RW_DATA /* non-static please */ #define ARCH_HAS_DECOMP_WDOG -- cgit v0.10.2 From 75216859d96f66856a0ee78c2de5b02115ff65f3 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 15 Mar 2010 15:14:50 +0100 Subject: ARM: 5990/1: ARM: use __armv5tej_mmu_cache_flush for V5TEJ instead of __armv4_mmu_cache_flush This got broken with commit 0e056f20 Signed-off-by: Sascha Hauer Signed-off-by: Russell King diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 535a91d..0f23009 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -742,7 +742,7 @@ proc_types: .word 0x000f0000 W(b) __armv4_mmu_cache_on W(b) __armv4_mmu_cache_off - W(b) __armv4_mmu_cache_flush + W(b) __armv5tej_mmu_cache_flush .word 0x0007b000 @ ARMv6 .word 0x000ff000 -- cgit v0.10.2 From 5d8614cc5d6c5c02b7995ed97303481d4e3a8cc7 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 12 Mar 2010 11:03:58 +0100 Subject: ARM: 5989/1: ARM: KGDB: add support for SMP platforms To support SMP platforms, KGDB requires the architecture backend to implement the kgdb_roundup_cpus function. This patch, taken against 2.6.33, implements the function for ARM based on the MIPS port. Cc: Jason Wessel Cc: Jean-Michel Hautbois Cc: KGDB Mailing List Signed-off-by: Will Deacon Signed-off-by: Russell King diff --git a/arch/arm/kernel/kgdb.c b/arch/arm/kernel/kgdb.c index ba8ccfe..a5b846b 100644 --- a/arch/arm/kernel/kgdb.c +++ b/arch/arm/kernel/kgdb.c @@ -9,6 +9,7 @@ * Authors: George Davis * Deepak Saxena */ +#include #include #include @@ -158,6 +159,18 @@ static struct undef_hook kgdb_compiled_brkpt_hook = { .fn = kgdb_compiled_brk_fn }; +static void kgdb_call_nmi_hook(void *ignored) +{ + kgdb_nmicallback(raw_smp_processor_id(), get_irq_regs()); +} + +void kgdb_roundup_cpus(unsigned long flags) +{ + local_irq_enable(); + smp_call_function(kgdb_call_nmi_hook, NULL, 0); + local_irq_disable(); +} + /** * kgdb_arch_init - Perform any architecture specific initalization. * -- cgit v0.10.2 From 80c43ed724797627d8f86855248c497a6161a214 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 15 Mar 2010 15:51:53 +0100 Subject: ALSA: hda - Disable MSI for Nvidia controller Judging from the member of enable_msi white-list, Nvidia controller seems to cause troubles with MSI enabled, e.g. boot hang up or other serious issue may come up. It's safer to disable MSI as default for Nvidia controllers again for now. Signed-off-by: Takashi Iwai Cc: diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 9268152..027d3f4 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2378,6 +2378,13 @@ static void __devinit check_msi(struct azx *chip) "hda_intel: msi for device %04x:%04x set to %d\n", q->subvendor, q->subdevice, q->value); chip->msi = q->value; + return; + } + + /* NVidia chipsets seem to cause troubles with MSI */ + if (chip->driver_type == AZX_DRIVER_NVIDIA) { + printk(KERN_INFO "hda_intel: Disable MSI for Nvidia chipset\n"); + chip->msi = 0; } } -- cgit v0.10.2 From 98d377a0894e6bcca44eafd4d2eee74e8af4db83 Mon Sep 17 00:00:00 2001 From: TARUISI Hiroaki Date: Wed, 18 Nov 2009 05:42:14 +0000 Subject: Btrfs: add a function to lookup a directory path by following backrefs This will be used by the inode lookup ioctl. Signed-off-by: TARUISI Hiroaki Signed-off-by: Chris Mason diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 645a179..ac2a28f4 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -48,6 +48,7 @@ #include "print-tree.h" #include "volumes.h" #include "locking.h" +#include "ctree.h" /* Mask out flags that are inappropriate for the given type of inode. */ static inline __u32 btrfs_mask_flags(umode_t mode, __u32 flags) @@ -743,6 +744,97 @@ out: return ret; } +/* + Search INODE_REFs to identify path name of 'dirid' directory + in a 'tree_id' tree. and sets path name to 'name'. +*/ +static noinline int btrfs_search_path_in_tree(struct btrfs_fs_info *info, + u64 tree_id, u64 dirid, char *name) +{ + struct btrfs_root *root; + struct btrfs_key key; + char *name_stack, *ptr; + int ret = -1; + int slot; + int len; + int total_len = 0; + struct btrfs_inode_ref *iref; + struct extent_buffer *l; + struct btrfs_path *path; + + if (dirid == BTRFS_FIRST_FREE_OBJECTID) { + name[0]='\0'; + return 0; + } + + path = btrfs_alloc_path(); + if (!path) + return -ENOMEM; + + name_stack = kzalloc(BTRFS_PATH_NAME_MAX+1, GFP_NOFS); + if (!name_stack) { + btrfs_free_path(path); + return -ENOMEM; + } + + ptr = &name_stack[BTRFS_PATH_NAME_MAX]; + + key.objectid = tree_id; + key.type = BTRFS_ROOT_ITEM_KEY; + key.offset = (u64)-1; + root = btrfs_read_fs_root_no_name(info, &key); + if (IS_ERR(root)) { + printk(KERN_ERR "could not find root %llu\n", tree_id); + return -ENOENT; + } + + key.objectid = dirid; + key.type = BTRFS_INODE_REF_KEY; + key.offset = 0; + + while(1) { + ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); + if (ret < 0) + goto out; + + l = path->nodes[0]; + slot = path->slots[0]; + btrfs_item_key_to_cpu(l, &key, slot); + + if (ret > 0 && (key.objectid != dirid || + key.type != BTRFS_INODE_REF_KEY)) + goto out; + + iref = btrfs_item_ptr(l, slot, struct btrfs_inode_ref); + len = btrfs_inode_ref_name_len(l, iref); + ptr -= len + 1; + total_len += len + 1; + if (ptr < name_stack) + goto out; + + *(ptr + len) = '/'; + read_extent_buffer(l, ptr,(unsigned long)(iref + 1), len); + + if (key.offset == BTRFS_FIRST_FREE_OBJECTID) + break; + + btrfs_release_path(root, path); + key.objectid = key.offset; + key.offset = 0; + dirid = key.objectid; + + } + if (ptr < name_stack) + goto out; + strncpy(name, ptr, total_len); + name[total_len]='\0'; + ret = 0; +out: + btrfs_free_path(path); + kfree(name_stack); + return ret; +} + static noinline int btrfs_ioctl_snap_destroy(struct file *file, void __user *arg) { -- cgit v0.10.2 From ac8e9819d71f907a0532b01b22c26b56bbbcbd21 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Sun, 28 Feb 2010 15:39:26 -0500 Subject: Btrfs: add search and inode lookup ioctls The search ioctl is a generic tool for doing btree searches from userland applications. The first user of the search ioctl is a subvolume listing feature, but we'll also use it to find new files in a subvolume. The search ioctl allows you to specify min and max keys to search for, along with min and max transid. It returns the items along with a header that includes the item key. Signed-off-by: Chris Mason diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index ac2a28f4..c604473 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -744,16 +744,206 @@ out: return ret; } +static noinline int key_in_sk(struct btrfs_key *key, + struct btrfs_ioctl_search_key *sk) +{ + if (key->objectid < sk->min_objectid) + return 0; + if (key->offset < sk->min_offset) + return 0; + if (key->type < sk->min_type) + return 0; + if (key->objectid > sk->max_objectid) + return 0; + if (key->type > sk->max_type) + return 0; + if (key->offset > sk->max_offset) + return 0; + return 1; +} + +static noinline int copy_to_sk(struct btrfs_root *root, + struct btrfs_path *path, + struct btrfs_key *key, + struct btrfs_ioctl_search_key *sk, + char *buf, + unsigned long *sk_offset, + int *num_found) +{ + u64 found_transid; + struct extent_buffer *leaf; + struct btrfs_ioctl_search_header sh; + unsigned long item_off; + unsigned long item_len; + int nritems; + int i; + int slot; + int found = 0; + int ret = 0; + + leaf = path->nodes[0]; + slot = path->slots[0]; + nritems = btrfs_header_nritems(leaf); + + if (btrfs_header_generation(leaf) > sk->max_transid) { + i = nritems; + goto advance_key; + } + found_transid = btrfs_header_generation(leaf); + + for (i = slot; i < nritems; i++) { + item_off = btrfs_item_ptr_offset(leaf, i); + item_len = btrfs_item_size_nr(leaf, i); + + if (item_len > BTRFS_SEARCH_ARGS_BUFSIZE) + item_len = 0; + + if (sizeof(sh) + item_len + *sk_offset > + BTRFS_SEARCH_ARGS_BUFSIZE) { + ret = 1; + goto overflow; + } + + btrfs_item_key_to_cpu(leaf, key, i); + if (!key_in_sk(key, sk)) + continue; + + sh.objectid = key->objectid; + sh.offset = key->offset; + sh.type = key->type; + sh.len = item_len; + sh.transid = found_transid; + + /* copy search result header */ + memcpy(buf + *sk_offset, &sh, sizeof(sh)); + *sk_offset += sizeof(sh); + + if (item_len) { + char *p = buf + *sk_offset; + /* copy the item */ + read_extent_buffer(leaf, p, + item_off, item_len); + *sk_offset += item_len; + found++; + } + + if (*num_found >= sk->nr_items) + break; + } +advance_key: + if (key->offset < (u64)-1) + key->offset++; + else if (key->type < (u64)-1) + key->type++; + else if (key->objectid < (u64)-1) + key->objectid++; + ret = 0; +overflow: + *num_found += found; + return ret; +} + +static noinline int search_ioctl(struct inode *inode, + struct btrfs_ioctl_search_args *args) +{ + struct btrfs_root *root; + struct btrfs_key key; + struct btrfs_key max_key; + struct btrfs_path *path; + struct btrfs_ioctl_search_key *sk = &args->key; + struct btrfs_fs_info *info = BTRFS_I(inode)->root->fs_info; + int ret; + int num_found = 0; + unsigned long sk_offset = 0; + + path = btrfs_alloc_path(); + if (!path) + return -ENOMEM; + + if (sk->tree_id == 0) { + /* search the root of the inode that was passed */ + root = BTRFS_I(inode)->root; + } else { + key.objectid = sk->tree_id; + key.type = BTRFS_ROOT_ITEM_KEY; + key.offset = (u64)-1; + root = btrfs_read_fs_root_no_name(info, &key); + if (IS_ERR(root)) { + printk(KERN_ERR "could not find root %llu\n", + sk->tree_id); + btrfs_free_path(path); + return -ENOENT; + } + } + + key.objectid = sk->min_objectid; + key.type = sk->min_type; + key.offset = sk->min_offset; + + max_key.objectid = sk->max_objectid; + max_key.type = sk->max_type; + max_key.offset = sk->max_offset; + + path->keep_locks = 1; + + while(1) { + ret = btrfs_search_forward(root, &key, &max_key, path, 0, + sk->min_transid); + if (ret != 0) { + if (ret > 0) + ret = 0; + goto err; + } + ret = copy_to_sk(root, path, &key, sk, args->buf, + &sk_offset, &num_found); + btrfs_release_path(root, path); + if (ret || num_found >= sk->nr_items) + break; + + } + ret = 0; +err: + sk->nr_items = num_found; + btrfs_free_path(path); + return ret; +} + +static noinline int btrfs_ioctl_tree_search(struct file *file, + void __user *argp) +{ + struct btrfs_ioctl_search_args *args; + struct inode *inode; + int ret; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + args = kmalloc(sizeof(*args), GFP_KERNEL); + if (!args) + return -ENOMEM; + + if (copy_from_user(args, argp, sizeof(*args))) { + kfree(args); + return -EFAULT; + } + inode = fdentry(file)->d_inode; + ret = search_ioctl(inode, args); + if (ret == 0 && copy_to_user(argp, args, sizeof(*args))) + ret = -EFAULT; + kfree(args); + return ret; +} + /* - Search INODE_REFs to identify path name of 'dirid' directory - in a 'tree_id' tree. and sets path name to 'name'. -*/ + * Search INODE_REFs to identify path name of 'dirid' directory + * in a 'tree_id' tree. and sets path name to 'name'. + */ static noinline int btrfs_search_path_in_tree(struct btrfs_fs_info *info, u64 tree_id, u64 dirid, char *name) { struct btrfs_root *root; struct btrfs_key key; - char *name_stack, *ptr; + char *ptr; int ret = -1; int slot; int len; @@ -771,13 +961,7 @@ static noinline int btrfs_search_path_in_tree(struct btrfs_fs_info *info, if (!path) return -ENOMEM; - name_stack = kzalloc(BTRFS_PATH_NAME_MAX+1, GFP_NOFS); - if (!name_stack) { - btrfs_free_path(path); - return -ENOMEM; - } - - ptr = &name_stack[BTRFS_PATH_NAME_MAX]; + ptr = &name[BTRFS_INO_LOOKUP_PATH_MAX]; key.objectid = tree_id; key.type = BTRFS_ROOT_ITEM_KEY; @@ -802,14 +986,16 @@ static noinline int btrfs_search_path_in_tree(struct btrfs_fs_info *info, btrfs_item_key_to_cpu(l, &key, slot); if (ret > 0 && (key.objectid != dirid || - key.type != BTRFS_INODE_REF_KEY)) + key.type != BTRFS_INODE_REF_KEY)) { + ret = -ENOENT; goto out; + } iref = btrfs_item_ptr(l, slot, struct btrfs_inode_ref); len = btrfs_inode_ref_name_len(l, iref); ptr -= len + 1; total_len += len + 1; - if (ptr < name_stack) + if (ptr < name) goto out; *(ptr + len) = '/'; @@ -824,14 +1010,41 @@ static noinline int btrfs_search_path_in_tree(struct btrfs_fs_info *info, dirid = key.objectid; } - if (ptr < name_stack) + if (ptr < name) goto out; - strncpy(name, ptr, total_len); + memcpy(name, ptr, total_len); name[total_len]='\0'; ret = 0; out: btrfs_free_path(path); - kfree(name_stack); + return ret; +} + +static noinline int btrfs_ioctl_ino_lookup(struct file *file, + void __user *argp) +{ + struct btrfs_ioctl_ino_lookup_args *args; + struct inode *inode; + int ret; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + args = kmalloc(sizeof(*args), GFP_KERNEL); + if (copy_from_user(args, argp, sizeof(*args))) { + kfree(args); + return -EFAULT; + } + inode = fdentry(file)->d_inode; + + ret = btrfs_search_path_in_tree(BTRFS_I(inode)->root->fs_info, + args->treeid, args->objectid, + args->name); + + if (ret == 0 && copy_to_user(argp, args, sizeof(*args))) + ret = -EFAULT; + + kfree(args); return ret; } @@ -1430,6 +1643,10 @@ long btrfs_ioctl(struct file *file, unsigned int return btrfs_ioctl_trans_start(file); case BTRFS_IOC_TRANS_END: return btrfs_ioctl_trans_end(file); + case BTRFS_IOC_TREE_SEARCH: + return btrfs_ioctl_tree_search(file, argp); + case BTRFS_IOC_INO_LOOKUP: + return btrfs_ioctl_ino_lookup(file, argp); case BTRFS_IOC_SYNC: btrfs_sync_fs(file->f_dentry->d_sb, 1); return 0; diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h index bc49914..79c07b1 100644 --- a/fs/btrfs/ioctl.h +++ b/fs/btrfs/ioctl.h @@ -30,6 +30,68 @@ struct btrfs_ioctl_vol_args { char name[BTRFS_PATH_NAME_MAX + 1]; }; +#define BTRFS_INO_LOOKUP_PATH_MAX 4080 +struct btrfs_ioctl_ino_lookup_args { + __u64 treeid; + __u64 objectid; + char name[BTRFS_INO_LOOKUP_PATH_MAX]; +}; + +struct btrfs_ioctl_search_key { + /* which root are we searching. 0 is the tree of tree roots */ + __u64 tree_id; + + /* keys returned will be >= min and <= max */ + __u64 min_objectid; + __u64 max_objectid; + + /* keys returned will be >= min and <= max */ + __u64 min_offset; + __u64 max_offset; + + /* max and min transids to search for */ + __u64 min_transid; + __u64 max_transid; + + /* keys returned will be >= min and <= max */ + __u32 min_type; + __u32 max_type; + + /* + * how many items did userland ask for, and how many are we + * returning + */ + __u32 nr_items; + + /* align to 64 bits */ + __u32 unused; + + /* some extra for later */ + __u64 unused1; + __u64 unused2; + __u64 unused3; + __u64 unused4; +}; + +struct btrfs_ioctl_search_header { + __u64 transid; + __u64 objectid; + __u64 offset; + __u32 type; + __u32 len; +}; + +#define BTRFS_SEARCH_ARGS_BUFSIZE (4096 - sizeof(struct btrfs_ioctl_search_key)) +/* + * the buf is an array of search headers where + * each header is followed by the actual item + * the type field is expanded to 32 bits for alignment + */ +struct btrfs_ioctl_search_args { + struct btrfs_ioctl_search_key key; + char buf[BTRFS_SEARCH_ARGS_BUFSIZE]; +}; + struct btrfs_ioctl_clone_range_args { __s64 src_fd; __u64 src_offset, src_length; @@ -67,4 +129,8 @@ struct btrfs_ioctl_clone_range_args { struct btrfs_ioctl_vol_args) #define BTRFS_IOC_SNAP_DESTROY _IOW(BTRFS_IOCTL_MAGIC, 15, \ struct btrfs_ioctl_vol_args) +#define BTRFS_IOC_TREE_SEARCH _IOWR(BTRFS_IOCTL_MAGIC, 17, \ + struct btrfs_ioctl_search_args) +#define BTRFS_IOC_INO_LOOKUP _IOWR(BTRFS_IOCTL_MAGIC, 18, \ + struct btrfs_ioctl_ino_lookup_args) #endif -- cgit v0.10.2 From 12534832cb7b0abc7369298246e8b7af03b863ca Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Thu, 17 Dec 2009 21:32:27 +0000 Subject: Btrfs: make set/get functions for the super compat_ro flags use compat_ro Our set/get functions for compat_ro_flags actually look at compat_flags. This will mess any attempt to use compat flags up. The fix is obvious. Thanks, Signed-off-by: Josef Bacik Signed-off-by: Chris Mason diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 2aa8ec6..abbce4d 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -1842,7 +1842,7 @@ BTRFS_SETGET_STACK_FUNCS(super_num_devices, struct btrfs_super_block, BTRFS_SETGET_STACK_FUNCS(super_compat_flags, struct btrfs_super_block, compat_flags, 64); BTRFS_SETGET_STACK_FUNCS(super_compat_ro_flags, struct btrfs_super_block, - compat_flags, 64); + compat_ro_flags, 64); BTRFS_SETGET_STACK_FUNCS(super_incompat_flags, struct btrfs_super_block, incompat_flags, 64); BTRFS_SETGET_STACK_FUNCS(super_csum_type, struct btrfs_super_block, -- cgit v0.10.2 From 73f73415caddbc01d9f10c03e0a677d5b3d11569 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Fri, 4 Dec 2009 17:38:27 +0000 Subject: Btrfs: change how we mount subvolumes This work is in preperation for being able to set a different root as the default mounting root. There is currently a problem with how we mount subvolumes. We cannot currently mount a subvolume of a subvolume, you can only mount subvolumes/snapshots of the default subvolume. So say you take a snapshot of the default subvolume and call it snap1, and then take a snapshot of snap1 and call it snap2, so now you have / /snap1 /snap1/snap2 as your available volumes. Currently you can only mount / and /snap1, you cannot mount /snap1/snap2. To fix this problem instead of passing subvolid= you must pass in subvolid=, where is the tree id that gets spit out via the subvolume listing you get from the subvolume listing patches (btrfs filesystem list). This allows us to mount /, /snap1 and /snap1/snap2 as the root volume. In addition to the above, we also now read the default dir item in the tree root to get the root key that it points to. For now this just points at what has always been the default subvolme, but later on I plan to change it to point at whatever root you want to be the new default root, so you can just set the default mount and not have to mount with -o subvolid=. I tested this out with the above scenario and it worked perfectly. Thanks, mount -o subvol operates inside the selected subvolid. For example: mount -o subvol=snap1,subvolid=256 /dev/xxx /mnt /mnt will have the snap1 directory for the subvolume with id 256. mount -o subvol=snap /dev/xxx /mnt /mnt will be the snap directory of whatever the default subvolume is. Signed-off-by: Josef Bacik Signed-off-by: Chris Mason diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index abbce4d..07d9569 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -2335,7 +2335,7 @@ int btrfs_init_cachep(void); void btrfs_destroy_cachep(void); long btrfs_ioctl_trans_end(struct file *file); struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location, - struct btrfs_root *root); + struct btrfs_root *root, int *was_new); int btrfs_commit_write(struct file *file, struct page *page, unsigned from, unsigned to); struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page, diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c index ba5c3fd..951ef09 100644 --- a/fs/btrfs/export.c +++ b/fs/btrfs/export.c @@ -95,7 +95,7 @@ static struct dentry *btrfs_get_dentry(struct super_block *sb, u64 objectid, btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); key.offset = 0; - inode = btrfs_iget(sb, &key, root); + inode = btrfs_iget(sb, &key, root, NULL); if (IS_ERR(inode)) { err = PTR_ERR(inode); goto fail; @@ -223,7 +223,7 @@ static struct dentry *btrfs_get_parent(struct dentry *child) key.type = BTRFS_INODE_ITEM_KEY; key.offset = 0; - dentry = d_obtain_alias(btrfs_iget(root->fs_info->sb, &key, root)); + dentry = d_obtain_alias(btrfs_iget(root->fs_info->sb, &key, root, NULL)); if (!IS_ERR(dentry)) dentry->d_op = &btrfs_dentry_operations; return dentry; diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 4deb280..7d10d1c 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -2153,7 +2153,7 @@ void btrfs_orphan_cleanup(struct btrfs_root *root) found_key.objectid = found_key.offset; found_key.type = BTRFS_INODE_ITEM_KEY; found_key.offset = 0; - inode = btrfs_iget(root->fs_info->sb, &found_key, root); + inode = btrfs_iget(root->fs_info->sb, &found_key, root, NULL); if (IS_ERR(inode)) break; @@ -3687,7 +3687,7 @@ static struct inode *btrfs_iget_locked(struct super_block *s, * Returns in *is_new if the inode was read from disk */ struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location, - struct btrfs_root *root) + struct btrfs_root *root, int *new) { struct inode *inode; @@ -3702,6 +3702,8 @@ struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location, inode_tree_add(inode); unlock_new_inode(inode); + if (new) + *new = 1; } return inode; @@ -3754,7 +3756,7 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry) return NULL; if (location.type == BTRFS_INODE_ITEM_KEY) { - inode = btrfs_iget(dir->i_sb, &location, root); + inode = btrfs_iget(dir->i_sb, &location, root, NULL); return inode; } @@ -3769,7 +3771,7 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry) else inode = new_simple_dir(dir->i_sb, &location, sub_root); } else { - inode = btrfs_iget(dir->i_sb, &location, sub_root); + inode = btrfs_iget(dir->i_sb, &location, sub_root, NULL); } srcu_read_unlock(&root->fs_info->subvol_srcu, index); diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 0109e56..d52759d 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -3487,7 +3487,7 @@ static struct inode *create_reloc_inode(struct btrfs_fs_info *fs_info, key.objectid = objectid; key.type = BTRFS_INODE_ITEM_KEY; key.offset = 0; - inode = btrfs_iget(root->fs_info->sb, &key, root); + inode = btrfs_iget(root->fs_info->sb, &key, root, NULL); BUG_ON(IS_ERR(inode) || is_bad_inode(inode)); BTRFS_I(inode)->index_cnt = group->key.objectid; diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index f8b4521..f878337 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -63,10 +63,10 @@ static void btrfs_put_super(struct super_block *sb) } enum { - Opt_degraded, Opt_subvol, Opt_device, Opt_nodatasum, Opt_nodatacow, - Opt_max_extent, Opt_max_inline, Opt_alloc_start, Opt_nobarrier, - Opt_ssd, Opt_nossd, Opt_ssd_spread, Opt_thread_pool, Opt_noacl, - Opt_compress, Opt_compress_force, Opt_notreelog, Opt_ratio, + Opt_degraded, Opt_subvol, Opt_subvolid, Opt_device, Opt_nodatasum, + Opt_nodatacow, Opt_max_extent, Opt_max_inline, Opt_alloc_start, + Opt_nobarrier, Opt_ssd, Opt_nossd, Opt_ssd_spread, Opt_thread_pool, + Opt_noacl, Opt_compress, Opt_compress_force, Opt_notreelog, Opt_ratio, Opt_flushoncommit, Opt_discard, Opt_err, }; @@ -74,6 +74,7 @@ enum { static match_table_t tokens = { {Opt_degraded, "degraded"}, {Opt_subvol, "subvol=%s"}, + {Opt_subvolid, "subvolid=%d"}, {Opt_device, "device=%s"}, {Opt_nodatasum, "nodatasum"}, {Opt_nodatacow, "nodatacow"}, @@ -157,6 +158,7 @@ int btrfs_parse_options(struct btrfs_root *root, char *options) btrfs_set_opt(info->mount_opt, DEGRADED); break; case Opt_subvol: + case Opt_subvolid: case Opt_device: /* * These are parsed by btrfs_parse_early_options @@ -292,12 +294,13 @@ out: * only when we need to allocate a new super block. */ static int btrfs_parse_early_options(const char *options, fmode_t flags, - void *holder, char **subvol_name, + void *holder, char **subvol_name, u64 *subvol_objectid, struct btrfs_fs_devices **fs_devices) { substring_t args[MAX_OPT_ARGS]; char *opts, *p; int error = 0; + int intarg; if (!options) goto out; @@ -320,6 +323,12 @@ static int btrfs_parse_early_options(const char *options, fmode_t flags, case Opt_subvol: *subvol_name = match_strdup(&args[0]); break; + case Opt_subvolid: + intarg = 0; + match_int(&args[0], &intarg); + if (intarg) + *subvol_objectid = intarg; + break; case Opt_device: error = btrfs_scan_one_device(match_strdup(&args[0]), flags, holder, fs_devices); @@ -347,6 +356,110 @@ static int btrfs_parse_early_options(const char *options, fmode_t flags, return error; } +static struct dentry *get_default_root(struct super_block *sb, + u64 subvol_objectid) +{ + struct btrfs_root *root = sb->s_fs_info; + struct btrfs_root *new_root; + struct btrfs_dir_item *di; + struct btrfs_path *path; + struct btrfs_key location; + struct inode *inode; + struct dentry *dentry; + u64 dir_id; + int new = 0; + + /* + * We have a specific subvol we want to mount, just setup location and + * go look up the root. + */ + if (subvol_objectid) { + location.objectid = subvol_objectid; + location.type = BTRFS_ROOT_ITEM_KEY; + location.offset = (u64)-1; + goto find_root; + } + + path = btrfs_alloc_path(); + if (!path) + return ERR_PTR(-ENOMEM); + path->leave_spinning = 1; + + /* + * Find the "default" dir item which points to the root item that we + * will mount by default if we haven't been given a specific subvolume + * to mount. + */ + dir_id = btrfs_super_root_dir(&root->fs_info->super_copy); + di = btrfs_lookup_dir_item(NULL, root, path, dir_id, "default", 7, 0); + if (!di) { + /* + * Ok the default dir item isn't there. This is weird since + * it's always been there, but don't freak out, just try and + * mount to root most subvolume. + */ + btrfs_free_path(path); + dir_id = BTRFS_FIRST_FREE_OBJECTID; + new_root = root->fs_info->fs_root; + goto setup_root; + } + + btrfs_dir_item_key_to_cpu(path->nodes[0], di, &location); + btrfs_free_path(path); + +find_root: + new_root = btrfs_read_fs_root_no_name(root->fs_info, &location); + if (IS_ERR(new_root)) + return ERR_PTR(PTR_ERR(new_root)); + + if (btrfs_root_refs(&new_root->root_item) == 0) + return ERR_PTR(-ENOENT); + + dir_id = btrfs_root_dirid(&new_root->root_item); +setup_root: + location.objectid = dir_id; + location.type = BTRFS_INODE_ITEM_KEY; + location.offset = 0; + + inode = btrfs_iget(sb, &location, new_root, &new); + if (!inode) + return ERR_PTR(-ENOMEM); + + /* + * If we're just mounting the root most subvol put the inode and return + * a reference to the dentry. We will have already gotten a reference + * to the inode in btrfs_fill_super so we're good to go. + */ + if (!new && sb->s_root->d_inode == inode) { + iput(inode); + return dget(sb->s_root); + } + + if (new) { + const struct qstr name = { .name = "/", .len = 1 }; + + /* + * New inode, we need to make the dentry a sibling of s_root so + * everything gets cleaned up properly on unmount. + */ + dentry = d_alloc(sb->s_root, &name); + if (!dentry) { + iput(inode); + return ERR_PTR(-ENOMEM); + } + d_splice_alias(inode, dentry); + } else { + /* + * We found the inode in cache, just find a dentry for it and + * put the reference to the inode we just got. + */ + dentry = d_find_alias(inode); + iput(inode); + } + + return dentry; +} + static int btrfs_fill_super(struct super_block *sb, struct btrfs_fs_devices *fs_devices, void *data, int silent) @@ -380,7 +493,7 @@ static int btrfs_fill_super(struct super_block *sb, key.objectid = BTRFS_FIRST_FREE_OBJECTID; key.type = BTRFS_INODE_ITEM_KEY; key.offset = 0; - inode = btrfs_iget(sb, &key, tree_root->fs_info->fs_root); + inode = btrfs_iget(sb, &key, tree_root->fs_info->fs_root, NULL); if (IS_ERR(inode)) { err = PTR_ERR(inode); goto fail_close; @@ -392,12 +505,6 @@ static int btrfs_fill_super(struct super_block *sb, err = -ENOMEM; goto fail_close; } -#if 0 - /* this does the super kobj at the same time */ - err = btrfs_sysfs_add_super(tree_root->fs_info); - if (err) - goto fail_close; -#endif sb->s_root = root_dentry; @@ -489,19 +596,22 @@ static int btrfs_test_super(struct super_block *s, void *data) static int btrfs_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data, struct vfsmount *mnt) { - char *subvol_name = NULL; struct block_device *bdev = NULL; struct super_block *s; struct dentry *root; struct btrfs_fs_devices *fs_devices = NULL; fmode_t mode = FMODE_READ; + char *subvol_name = NULL; + u64 subvol_objectid = 0; int error = 0; + int found = 0; if (!(flags & MS_RDONLY)) mode |= FMODE_WRITE; error = btrfs_parse_early_options(data, mode, fs_type, - &subvol_name, &fs_devices); + &subvol_name, &subvol_objectid, + &fs_devices); if (error) return error; @@ -530,6 +640,7 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags, goto error_close_devices; } + found = 1; btrfs_close_devices(fs_devices); } else { char b[BDEVNAME_SIZE]; @@ -547,25 +658,35 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags, s->s_flags |= MS_ACTIVE; } - if (!strcmp(subvol_name, ".")) - root = dget(s->s_root); - else { - mutex_lock(&s->s_root->d_inode->i_mutex); - root = lookup_one_len(subvol_name, s->s_root, + root = get_default_root(s, subvol_objectid); + if (IS_ERR(root)) { + error = PTR_ERR(root); + deactivate_locked_super(s); + goto error; + } + /* if they gave us a subvolume name bind mount into that */ + if (strcmp(subvol_name, ".")) { + struct dentry *new_root; + mutex_lock(&root->d_inode->i_mutex); + new_root = lookup_one_len(subvol_name, root, strlen(subvol_name)); - mutex_unlock(&s->s_root->d_inode->i_mutex); + mutex_unlock(&root->d_inode->i_mutex); - if (IS_ERR(root)) { + if (IS_ERR(new_root)) { deactivate_locked_super(s); - error = PTR_ERR(root); - goto error_free_subvol_name; + error = PTR_ERR(new_root); + dput(root); + goto error_close_devices; } - if (!root->d_inode) { + if (!new_root->d_inode) { dput(root); + dput(new_root); deactivate_locked_super(s); error = -ENXIO; - goto error_free_subvol_name; + goto error_close_devices; } + dput(root); + root = new_root; } mnt->mnt_sb = s; @@ -580,6 +701,7 @@ error_close_devices: btrfs_close_devices(fs_devices); error_free_subvol_name: kfree(subvol_name); +error: return error; } diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 4a9434b..1255fcc 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -445,7 +445,7 @@ static noinline struct inode *read_one_inode(struct btrfs_root *root, key.objectid = objectid; key.type = BTRFS_INODE_ITEM_KEY; key.offset = 0; - inode = btrfs_iget(root->fs_info->sb, &key, root); + inode = btrfs_iget(root->fs_info->sb, &key, root, NULL); if (IS_ERR(inode)) { inode = NULL; } else if (is_bad_inode(inode)) { -- cgit v0.10.2 From 6ef5ed0d386be5c43ec66d6f2999919c0893558b Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Fri, 11 Dec 2009 21:11:29 +0000 Subject: Btrfs: add ioctl and incompat flag to set the default mount subvol This patch needs to go along with my previous patch. This lets us set the default dir item's location to whatever root we want to use as our default mounting subvol. With this we don't have to use mount -o subvol= anymore to mount a different subvol, we can just set the new one and it will just magically work. I've done some moderate testing with this, mostly just switching the default mount around, mounting subvols and the default mount at the same time and such, everything seems to work. Thanks, Older kernels would generally be able to still mount the filesystem with the default subvolume set, but it would result in a different volume being mounted, which could be an even more unpleasant suprise for users. So if you set your default subvolume, you can't go back to older kernels. Thanks, Signed-off-by: Josef Bacik Signed-off-by: Chris Mason diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 07d9569..1166b15 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -373,11 +373,13 @@ struct btrfs_super_block { * ones specified below then we will fail to mount */ #define BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF (1ULL << 0) +#define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL (2ULL << 0) #define BTRFS_FEATURE_COMPAT_SUPP 0ULL #define BTRFS_FEATURE_COMPAT_RO_SUPP 0ULL #define BTRFS_FEATURE_INCOMPAT_SUPP \ - BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF + (BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF | \ + BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL) /* * A leaf is full of items. offset and size tell us where to find diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index c604473..7875a75 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -1579,6 +1579,79 @@ out: return ret; } +static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp) +{ + struct inode *inode = fdentry(file)->d_inode; + struct btrfs_root *root = BTRFS_I(inode)->root; + struct btrfs_root *new_root; + struct btrfs_dir_item *di; + struct btrfs_trans_handle *trans; + struct btrfs_path *path; + struct btrfs_key location; + struct btrfs_disk_key disk_key; + struct btrfs_super_block *disk_super; + u64 features; + u64 objectid = 0; + u64 dir_id; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + if (copy_from_user(&objectid, argp, sizeof(objectid))) + return -EFAULT; + + if (!objectid) + objectid = root->root_key.objectid; + + location.objectid = objectid; + location.type = BTRFS_ROOT_ITEM_KEY; + location.offset = (u64)-1; + + new_root = btrfs_read_fs_root_no_name(root->fs_info, &location); + if (IS_ERR(new_root)) + return PTR_ERR(new_root); + + if (btrfs_root_refs(&new_root->root_item) == 0) + return -ENOENT; + + path = btrfs_alloc_path(); + if (!path) + return -ENOMEM; + path->leave_spinning = 1; + + trans = btrfs_start_transaction(root, 1); + if (!trans) { + btrfs_free_path(path); + return -ENOMEM; + } + + dir_id = btrfs_super_root_dir(&root->fs_info->super_copy); + di = btrfs_lookup_dir_item(trans, root->fs_info->tree_root, path, + dir_id, "default", 7, 1); + if (!di) { + btrfs_free_path(path); + btrfs_end_transaction(trans, root); + printk(KERN_ERR "Umm, you don't have the default dir item, " + "this isn't going to work\n"); + return -ENOENT; + } + + btrfs_cpu_key_to_disk(&disk_key, &new_root->root_key); + btrfs_set_dir_item_key(path->nodes[0], di, &disk_key); + btrfs_mark_buffer_dirty(path->nodes[0]); + btrfs_free_path(path); + + disk_super = &root->fs_info->super_copy; + features = btrfs_super_incompat_flags(disk_super); + if (!(features & BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL)) { + features |= BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL; + btrfs_set_super_incompat_flags(disk_super, features); + } + btrfs_end_transaction(trans, root); + + return 0; +} + /* * there are many ways the trans_start and trans_end ioctls can lead * to deadlocks. They should only be used by applications that @@ -1625,6 +1698,8 @@ long btrfs_ioctl(struct file *file, unsigned int return btrfs_ioctl_snap_create(file, argp, 1); case BTRFS_IOC_SNAP_DESTROY: return btrfs_ioctl_snap_destroy(file, argp); + case BTRFS_IOC_DEFAULT_SUBVOL: + return btrfs_ioctl_default_subvol(file, argp); case BTRFS_IOC_DEFRAG: return btrfs_ioctl_defrag(file); case BTRFS_IOC_RESIZE: diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h index 79c07b1..f1923e0 100644 --- a/fs/btrfs/ioctl.h +++ b/fs/btrfs/ioctl.h @@ -1,3 +1,4 @@ + /* * Copyright (C) 2007 Oracle. All rights reserved. * @@ -133,4 +134,5 @@ struct btrfs_ioctl_clone_range_args { struct btrfs_ioctl_search_args) #define BTRFS_IOC_INO_LOOKUP _IOWR(BTRFS_IOCTL_MAGIC, 18, \ struct btrfs_ioctl_ino_lookup_args) +#define BTRFS_IOC_DEFAULT_SUBVOL _IOW(BTRFS_IOCTL_MAGIC, 19, u64) #endif -- cgit v0.10.2 From 4849f01d153be0f52b8191ee1be0ce492aa96811 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Mon, 14 Dec 2009 19:18:38 +0000 Subject: Btrfs: make subvolid=0 mount the original default root Since theres not a good way to make sure the user sees the original default root tree id, and not to mention it's 5 so is way different than any other volume, just make subvol=0 mount the original default root. This makes it a bit easier for users to handle in the long run. Thanks, Signed-off-by: Josef Bacik Signed-off-by: Chris Mason diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index f878337..9771eb8 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -325,9 +325,15 @@ static int btrfs_parse_early_options(const char *options, fmode_t flags, break; case Opt_subvolid: intarg = 0; - match_int(&args[0], &intarg); - if (intarg) - *subvol_objectid = intarg; + error = match_int(&args[0], &intarg); + if (!error) { + /* we want the original fs_tree */ + if (!intarg) + *subvol_objectid = + BTRFS_FS_TREE_OBJECTID; + else + *subvol_objectid = intarg; + } break; case Opt_device: error = btrfs_scan_one_device(match_strdup(&args[0]), -- cgit v0.10.2 From 51684082b11c304829ea22193d4d96a5b1663b97 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Wed, 10 Mar 2010 15:33:32 -0500 Subject: Btrfs: run the backing dev more often in the submit_bio helper The submit_bio helper thread can decide to loop back around to service more bios. This commit forces it to unplug first, which helps reduce the latency seen by submitters. Signed-off-by: Chris Mason diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 41ecbb2..ace2e8d 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -325,16 +325,6 @@ loop_lock: num_sync_run = 0; blk_run_backing_dev(bdi, NULL); } - - cond_resched(); - if (again) - goto loop; - - spin_lock(&device->io_lock); - if (device->pending_bios.head || device->pending_sync_bios.head) - goto loop_lock; - spin_unlock(&device->io_lock); - /* * IO has already been through a long path to get here. Checksumming, * async helper threads, perhaps compression. We've done a pretty @@ -346,6 +336,16 @@ loop_lock: * cared about found its way down here. */ blk_run_backing_dev(bdi, NULL); + + cond_resched(); + if (again) + goto loop; + + spin_lock(&device->io_lock); + if (device->pending_bios.head || device->pending_sync_bios.head) + goto loop_lock; + spin_unlock(&device->io_lock); + done: return 0; } -- cgit v0.10.2 From 940100a4a7b78b27e60a3e72340fb9b5397dcdb2 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Wed, 10 Mar 2010 10:52:59 -0500 Subject: Btrfs: be more selective in the defrag ioctl The btrfs defrag ioctl had some bugs around delalloc accounting, and it wasn't properly skipping pages that were not in the mapping. It wasn't properly clearing the page checked flag, which could make the writeback code ignore the page forever while pinning it as dirty. This commit fixes those problems and makes defrag a little smarter. It skips holes and it doesn't waste time defragging large extents. If a tiny extent comes before a very large extent, it will defrag both of them to make sure the tiny extent ends up next to something big. Signed-off-by: Chris Mason diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 7875a75..3a89cd7 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -475,6 +475,73 @@ out_unlock: return error; } +static int should_defrag_range(struct inode *inode, u64 start, u64 len, + u64 *last_len, u64 *skip, u64 *defrag_end) +{ + struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; + struct extent_map *em = NULL; + struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; + int ret = 1; + + /* + * make sure that once we start defragging and extent, we keep on + * defragging it + */ + if (start < *defrag_end) + return 1; + + *skip = 0; + + /* + * hopefully we have this extent in the tree already, try without + * the full extent lock + */ + read_lock(&em_tree->lock); + em = lookup_extent_mapping(em_tree, start, len); + read_unlock(&em_tree->lock); + + if (!em) { + /* get the big lock and read metadata off disk */ + lock_extent(io_tree, start, start + len - 1, GFP_NOFS); + em = btrfs_get_extent(inode, NULL, 0, start, len, 0); + unlock_extent(io_tree, start, start + len - 1, GFP_NOFS); + + if (!em) + return 0; + } + + /* this will cover holes, and inline extents */ + if (em->block_start >= EXTENT_MAP_LAST_BYTE) + ret = 0; + + /* + * we hit a real extent, if it is big don't bother defragging it again + */ + if ((*last_len == 0 || *last_len >= 256 * 1024) && + em->len >= 256 * 1024) + ret = 0; + + /* + * last_len ends up being a counter of how many bytes we've defragged. + * every time we choose not to defrag an extent, we reset *last_len + * so that the next tiny extent will force a defrag. + * + * The end result of this is that tiny extents before a single big + * extent will force at least part of that big extent to be defragged. + */ + if (ret) { + *last_len += len; + *defrag_end = extent_map_end(em); + } else { + *last_len = 0; + *skip = extent_map_end(em); + *defrag_end = 0; + } + + free_extent_map(em); + return ret; +} + static int btrfs_defrag_file(struct file *file) { struct inode *inode = fdentry(file)->d_inode; @@ -487,37 +554,86 @@ static int btrfs_defrag_file(struct file *file) unsigned long total_read = 0; u64 page_start; u64 page_end; + u64 last_len = 0; + u64 skip = 0; + u64 defrag_end = 0; unsigned long i; int ret; - ret = btrfs_check_data_free_space(root, inode, inode->i_size); - if (ret) - return -ENOSPC; + if (inode->i_size == 0) + return 0; + + last_index = (inode->i_size - 1) >> PAGE_CACHE_SHIFT; + i = 0; + while (i <= last_index) { + if (!should_defrag_range(inode, (u64)i << PAGE_CACHE_SHIFT, + PAGE_CACHE_SIZE, &last_len, &skip, + &defrag_end)) { + unsigned long next; + /* + * the should_defrag function tells us how much to skip + * bump our counter by the suggested amount + */ + next = (skip + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; + i = max(i + 1, next); + continue; + } - mutex_lock(&inode->i_mutex); - last_index = inode->i_size >> PAGE_CACHE_SHIFT; - for (i = 0; i <= last_index; i++) { if (total_read % ra_pages == 0) { btrfs_force_ra(inode->i_mapping, &file->f_ra, file, i, min(last_index, i + ra_pages - 1)); } total_read++; + mutex_lock(&inode->i_mutex); + + ret = btrfs_check_data_free_space(root, inode, PAGE_CACHE_SIZE); + if (ret) { + ret = -ENOSPC; + break; + } + + ret = btrfs_reserve_metadata_for_delalloc(root, inode, 1); + if (ret) { + btrfs_free_reserved_data_space(root, inode, + PAGE_CACHE_SIZE); + ret = -ENOSPC; + break; + } again: + if (inode->i_size == 0 || + i > ((inode->i_size - 1) >> PAGE_CACHE_SHIFT)) { + ret = 0; + goto err_reservations; + } + page = grab_cache_page(inode->i_mapping, i); if (!page) - goto out_unlock; + goto err_reservations; + if (!PageUptodate(page)) { btrfs_readpage(NULL, page); lock_page(page); if (!PageUptodate(page)) { unlock_page(page); page_cache_release(page); - goto out_unlock; + goto err_reservations; } } + if (page->mapping != inode->i_mapping) { + unlock_page(page); + page_cache_release(page); + goto again; + } + wait_on_page_writeback(page); + if (PageDirty(page)) { + btrfs_free_reserved_data_space(root, inode, + PAGE_CACHE_SIZE); + goto loop_unlock; + } + page_start = (u64)page->index << PAGE_CACHE_SHIFT; page_end = page_start + PAGE_CACHE_SIZE - 1; lock_extent(io_tree, page_start, page_end, GFP_NOFS); @@ -538,18 +654,32 @@ again: * page if it is dirtied again later */ clear_page_dirty_for_io(page); + clear_extent_bits(&BTRFS_I(inode)->io_tree, page_start, + page_end, EXTENT_DIRTY | EXTENT_DELALLOC | + EXTENT_DO_ACCOUNTING, GFP_NOFS); btrfs_set_extent_delalloc(inode, page_start, page_end); + ClearPageChecked(page); set_page_dirty(page); unlock_extent(io_tree, page_start, page_end, GFP_NOFS); + +loop_unlock: unlock_page(page); page_cache_release(page); + mutex_unlock(&inode->i_mutex); + + btrfs_unreserve_metadata_for_delalloc(root, inode, 1); balance_dirty_pages_ratelimited_nr(inode->i_mapping, 1); + i++; } -out_unlock: - mutex_unlock(&inode->i_mutex); return 0; + +err_reservations: + mutex_unlock(&inode->i_mutex); + btrfs_free_reserved_data_space(root, inode, PAGE_CACHE_SIZE); + btrfs_unreserve_metadata_for_delalloc(root, inode, 1); + return ret; } static noinline int btrfs_ioctl_resize(struct btrfs_root *root, -- cgit v0.10.2 From 1e701a3292e25a6c4939cad9f24951dc6b6ad853 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Thu, 11 Mar 2010 09:42:04 -0500 Subject: Btrfs: add new defrag-range ioctl. The btrfs defrag ioctl was limited to doing the entire file. This commit adds a new interface that can defrag a specific range inside the file. It can also force compression on the file, allowing you to selectively compress individual files after they were created, even when mount -o compress isn't turned on. Signed-off-by: Chris Mason diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h index 3f1f50d..7a4dee1 100644 --- a/fs/btrfs/btrfs_inode.h +++ b/fs/btrfs/btrfs_inode.h @@ -153,6 +153,11 @@ struct btrfs_inode { unsigned ordered_data_close:1; unsigned dummy_inode:1; + /* + * always compress this one file + */ + unsigned force_compress:1; + struct inode vfs_inode; }; diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 1166b15..3a36b1f 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -1184,7 +1184,6 @@ struct btrfs_root { #define BTRFS_INODE_NOATIME (1 << 9) #define BTRFS_INODE_DIRSYNC (1 << 10) - /* some macros to generate set/get funcs for the struct fields. This * assumes there is a lefoo_to_cpu for every type, so lets make a simple * one for u8: diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 7d10d1c..3657925 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -379,7 +379,8 @@ again: * change at any time if we discover bad compression ratios. */ if (!(BTRFS_I(inode)->flags & BTRFS_INODE_NOCOMPRESS) && - btrfs_test_opt(root, COMPRESS)) { + (btrfs_test_opt(root, COMPRESS) || + (BTRFS_I(inode)->force_compress))) { WARN_ON(pages); pages = kzalloc(sizeof(struct page *) * nr_pages, GFP_NOFS); @@ -483,8 +484,10 @@ again: nr_pages_ret = 0; /* flag the file so we don't compress in the future */ - if (!btrfs_test_opt(root, FORCE_COMPRESS)) + if (!btrfs_test_opt(root, FORCE_COMPRESS) && + !(BTRFS_I(inode)->force_compress)) { BTRFS_I(inode)->flags |= BTRFS_INODE_NOCOMPRESS; + } } if (will_compress) { *num_added += 1; @@ -1211,7 +1214,8 @@ static int run_delalloc_range(struct inode *inode, struct page *locked_page, else if (BTRFS_I(inode)->flags & BTRFS_INODE_PREALLOC) ret = run_delalloc_nocow(inode, locked_page, start, end, page_started, 0, nr_written); - else if (!btrfs_test_opt(root, COMPRESS)) + else if (!btrfs_test_opt(root, COMPRESS) && + !(BTRFS_I(inode)->force_compress)) ret = cow_file_range(inode, locked_page, start, end, page_started, nr_written, 1); else @@ -3639,6 +3643,7 @@ static noinline void init_btrfs_i(struct inode *inode) bi->index_cnt = (u64)-1; bi->last_unlink_trans = 0; bi->ordered_data_close = 0; + bi->force_compress = 0; extent_map_tree_init(&BTRFS_I(inode)->extent_tree, GFP_NOFS); extent_io_tree_init(&BTRFS_I(inode)->io_tree, inode->i_mapping, GFP_NOFS); diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 3a89cd7..d866b46 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -476,13 +476,18 @@ out_unlock: } static int should_defrag_range(struct inode *inode, u64 start, u64 len, - u64 *last_len, u64 *skip, u64 *defrag_end) + int thresh, u64 *last_len, u64 *skip, + u64 *defrag_end) { struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; struct extent_map *em = NULL; struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; int ret = 1; + + if (thresh == 0) + thresh = 256 * 1024; + /* * make sure that once we start defragging and extent, we keep on * defragging it @@ -517,8 +522,7 @@ static int should_defrag_range(struct inode *inode, u64 start, u64 len, /* * we hit a real extent, if it is big don't bother defragging it again */ - if ((*last_len == 0 || *last_len >= 256 * 1024) && - em->len >= 256 * 1024) + if ((*last_len == 0 || *last_len >= thresh) && em->len >= thresh) ret = 0; /* @@ -542,7 +546,8 @@ static int should_defrag_range(struct inode *inode, u64 start, u64 len, return ret; } -static int btrfs_defrag_file(struct file *file) +static int btrfs_defrag_file(struct file *file, + struct btrfs_ioctl_defrag_range_args *range) { struct inode *inode = fdentry(file)->d_inode; struct btrfs_root *root = BTRFS_I(inode)->root; @@ -563,11 +568,19 @@ static int btrfs_defrag_file(struct file *file) if (inode->i_size == 0) return 0; - last_index = (inode->i_size - 1) >> PAGE_CACHE_SHIFT; - i = 0; + if (range->start + range->len > range->start) { + last_index = min_t(u64, inode->i_size - 1, + range->start + range->len - 1) >> PAGE_CACHE_SHIFT; + } else { + last_index = (inode->i_size - 1) >> PAGE_CACHE_SHIFT; + } + + i = range->start >> PAGE_CACHE_SHIFT; while (i <= last_index) { if (!should_defrag_range(inode, (u64)i << PAGE_CACHE_SHIFT, - PAGE_CACHE_SIZE, &last_len, &skip, + PAGE_CACHE_SIZE, + range->extent_thresh, + &last_len, &skip, &defrag_end)) { unsigned long next; /* @@ -585,6 +598,8 @@ static int btrfs_defrag_file(struct file *file) } total_read++; mutex_lock(&inode->i_mutex); + if (range->flags & BTRFS_DEFRAG_RANGE_COMPRESS) + BTRFS_I(inode)->force_compress = 1; ret = btrfs_check_data_free_space(root, inode, PAGE_CACHE_SIZE); if (ret) { @@ -673,6 +688,28 @@ loop_unlock: i++; } + if ((range->flags & BTRFS_DEFRAG_RANGE_START_IO)) + filemap_flush(inode->i_mapping); + + if ((range->flags & BTRFS_DEFRAG_RANGE_COMPRESS)) { + /* the filemap_flush will queue IO into the worker threads, but + * we have to make sure the IO is actually started and that + * ordered extents get created before we return + */ + atomic_inc(&root->fs_info->async_submit_draining); + while (atomic_read(&root->fs_info->nr_async_submits) || + atomic_read(&root->fs_info->async_delalloc_pages)) { + wait_event(root->fs_info->async_submit_wait, + (atomic_read(&root->fs_info->nr_async_submits) == 0 && + atomic_read(&root->fs_info->async_delalloc_pages) == 0)); + } + atomic_dec(&root->fs_info->async_submit_draining); + + mutex_lock(&inode->i_mutex); + BTRFS_I(inode)->force_compress = 0; + mutex_unlock(&inode->i_mutex); + } + return 0; err_reservations: @@ -1284,10 +1321,11 @@ out: return err; } -static int btrfs_ioctl_defrag(struct file *file) +static int btrfs_ioctl_defrag(struct file *file, void __user *argp) { struct inode *inode = fdentry(file)->d_inode; struct btrfs_root *root = BTRFS_I(inode)->root; + struct btrfs_ioctl_defrag_range_args *range; int ret; ret = mnt_want_write(file->f_path.mnt); @@ -1308,7 +1346,30 @@ static int btrfs_ioctl_defrag(struct file *file) ret = -EINVAL; goto out; } - btrfs_defrag_file(file); + + range = kzalloc(sizeof(*range), GFP_KERNEL); + if (!range) { + ret = -ENOMEM; + goto out; + } + + if (argp) { + if (copy_from_user(range, argp, + sizeof(*range))) { + ret = -EFAULT; + kfree(range); + } + /* compression requires us to start the IO */ + if ((range->flags & BTRFS_DEFRAG_RANGE_COMPRESS)) { + range->flags |= BTRFS_DEFRAG_RANGE_START_IO; + range->extent_thresh = (u32)-1; + } + } else { + /* the rest are all set to zero by kzalloc */ + range->len = (u64)-1; + } + btrfs_defrag_file(file, range); + kfree(range); break; } out: @@ -1831,7 +1892,9 @@ long btrfs_ioctl(struct file *file, unsigned int case BTRFS_IOC_DEFAULT_SUBVOL: return btrfs_ioctl_default_subvol(file, argp); case BTRFS_IOC_DEFRAG: - return btrfs_ioctl_defrag(file); + return btrfs_ioctl_defrag(file, NULL); + case BTRFS_IOC_DEFRAG_RANGE: + return btrfs_ioctl_defrag(file, argp); case BTRFS_IOC_RESIZE: return btrfs_ioctl_resize(root, argp); case BTRFS_IOC_ADD_DEV: diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h index f1923e0..2d64a65 100644 --- a/fs/btrfs/ioctl.h +++ b/fs/btrfs/ioctl.h @@ -99,6 +99,35 @@ struct btrfs_ioctl_clone_range_args { __u64 dest_offset; }; +/* flags for the defrag range ioctl */ +#define BTRFS_DEFRAG_RANGE_COMPRESS 1 +#define BTRFS_DEFRAG_RANGE_START_IO 2 + +struct btrfs_ioctl_defrag_range_args { + /* start of the defrag operation */ + __u64 start; + + /* number of bytes to defrag, use (u64)-1 to say all */ + __u64 len; + + /* + * flags for the operation, which can include turning + * on compression for this one defrag + */ + __u64 flags; + + /* + * any extent bigger than this will be considered + * already defragged. Use 0 to take the kernel default + * Use 1 to say every single extent must be rewritten + */ + __u32 extent_thresh; + + /* spare for later */ + __u32 unused[5]; +}; + + #define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \ struct btrfs_ioctl_vol_args) #define BTRFS_IOC_DEFRAG _IOW(BTRFS_IOCTL_MAGIC, 2, \ @@ -130,6 +159,8 @@ struct btrfs_ioctl_clone_range_args { struct btrfs_ioctl_vol_args) #define BTRFS_IOC_SNAP_DESTROY _IOW(BTRFS_IOCTL_MAGIC, 15, \ struct btrfs_ioctl_vol_args) +#define BTRFS_IOC_DEFRAG_RANGE _IOW(BTRFS_IOCTL_MAGIC, 16, \ + struct btrfs_ioctl_defrag_range_args) #define BTRFS_IOC_TREE_SEARCH _IOWR(BTRFS_IOCTL_MAGIC, 17, \ struct btrfs_ioctl_search_args) #define BTRFS_IOC_INO_LOOKUP _IOWR(BTRFS_IOCTL_MAGIC, 18, \ -- cgit v0.10.2 From 3a0524dc054791688177544fe510d2868ee20d9f Mon Sep 17 00:00:00 2001 From: TARUISI Hiroaki Date: Tue, 9 Feb 2010 06:36:45 +0000 Subject: btrfs: Update existing btrfs_device for renaming device When we scan devices in a multi-device filesystem, we memorize the original name. If the device gets a new name, later scans don't update the in-kernel structures related to it, and we're not able to mount the filesystem. This patch updates device name during scaning. Signed-off-by: TARUISI Hiroaki Signed-off-by: Chris Mason diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index ace2e8d..eb89e13 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -365,6 +365,7 @@ static noinline int device_list_add(const char *path, struct btrfs_device *device; struct btrfs_fs_devices *fs_devices; u64 found_transid = btrfs_super_generation(disk_super); + char *name; fs_devices = find_fsid(disk_super->fsid); if (!fs_devices) { @@ -411,6 +412,12 @@ static noinline int device_list_add(const char *path, device->fs_devices = fs_devices; fs_devices->num_devices++; + } else if (strcmp(device->name, path)) { + name = kstrdup(path, GFP_NOFS); + if (!name) + return -ENOMEM; + kfree(device->name); + device->name = name; } if (found_transid > fs_devices->latest_trans) { -- cgit v0.10.2 From bd4d10888990f7e3f8029205d27eb155202d6969 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Fri, 5 Mar 2010 21:59:21 +0000 Subject: Btrfs: make df be a little bit more understandable The way we report df usage is way confusing for everybody, including some other utilities (bacula for one). So this patch makes df a little bit more understandable. First we make used actually count the total amount of used space in all space info's. This will give us a real view of how much disk space is in use. Second, for blocks available, only count data space. This makes things like bacula work because it says 0 when you can no longer write anymore data to the disk. I think this is a nice compromise, since you will end up with something like the following [root@alpha ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/VolGroup-lv_root 148G 30G 111G 21% / /dev/sda1 194M 116M 68M 64% /boot tmpfs 985M 12K 985M 1% /dev/shm /dev/mapper/VolGroup-LogVol02 145G 140G 0 100% /mnt/btrfs-test Compare this with btrfsctl -i output [root@alpha btrfs-progs-unstable]# ./btrfsctl -i /mnt/btrfs-test/ Metadata, DUP: total=4.62GB, used=2.46GB System, DUP: total=8.00MB, used=24.00KB Data: total=134.80GB, used=134.80GB Metadata: total=8.00MB, used=0.00 System: total=4.00MB, used=0.00 operation complete This way we show that there is no more data space to be used, but we have another 5GB of space left for metadata. Thanks, Signed-off-by: Josef Bacik Signed-off-by: Chris Mason diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 9771eb8..ff3dd55 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -752,14 +752,37 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) { struct btrfs_root *root = btrfs_sb(dentry->d_sb); struct btrfs_super_block *disk_super = &root->fs_info->super_copy; + struct list_head *head = &root->fs_info->space_info; + struct btrfs_space_info *found; + u64 total_used = 0; + u64 data_used = 0; int bits = dentry->d_sb->s_blocksize_bits; __be32 *fsid = (__be32 *)root->fs_info->fsid; + rcu_read_lock(); + list_for_each_entry_rcu(found, head, list) { + if (found->flags & (BTRFS_BLOCK_GROUP_DUP| + BTRFS_BLOCK_GROUP_RAID10| + BTRFS_BLOCK_GROUP_RAID1)) { + total_used += found->bytes_used; + if (found->flags & BTRFS_BLOCK_GROUP_DATA) + data_used += found->bytes_used; + else + data_used += found->total_bytes; + } + + total_used += found->bytes_used; + if (found->flags & BTRFS_BLOCK_GROUP_DATA) + data_used += found->bytes_used; + else + data_used += found->total_bytes; + } + rcu_read_unlock(); + buf->f_namelen = BTRFS_NAME_LEN; buf->f_blocks = btrfs_super_total_bytes(disk_super) >> bits; - buf->f_bfree = buf->f_blocks - - (btrfs_super_bytes_used(disk_super) >> bits); - buf->f_bavail = buf->f_bfree; + buf->f_bfree = buf->f_blocks - (total_used >> bits); + buf->f_bavail = buf->f_blocks - (data_used >> bits); buf->f_bsize = dentry->d_sb->s_blocksize; buf->f_type = BTRFS_SUPER_MAGIC; -- cgit v0.10.2 From 0bdb1db297ab36865a63ee722d35ff0a1f0ae522 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 19 Feb 2010 14:13:50 -0800 Subject: Btrfs: flush data on snapshot creation Flush any delalloc extents when we create a snapshot, so that recently written file data is always included in the snapshot. A later commit will add the ability to snapshot without the flush, but most people expect flushing. Signed-off-by: Sage Weil Signed-off-by: Chris Mason diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 2a36e23..2d654c1 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -997,13 +997,10 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, mutex_unlock(&root->fs_info->trans_mutex); - if (flush_on_commit) { + if (flush_on_commit || snap_pending) { btrfs_start_delalloc_inodes(root, 1); ret = btrfs_wait_ordered_extents(root, 0, 1); BUG_ON(ret); - } else if (snap_pending) { - ret = btrfs_wait_ordered_extents(root, 0, 1); - BUG_ON(ret); } /* -- cgit v0.10.2 From 0be2e98173f8badd5ccc7c2e994891746ba1caf4 Mon Sep 17 00:00:00 2001 From: Miao Xie Date: Thu, 11 Feb 2010 08:06:58 +0000 Subject: btrfs: fix btrfs_mkdir goto for no free objectids btrfs_mkdir() must jump to the place of ending transaction after btrfs_find_free_objectid() failed. Or this transaction can't end. Signed-off-by: Miao Xie Signed-off-by: Chris Mason diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 3657925..50ce884 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -4508,7 +4508,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) err = btrfs_find_free_objectid(trans, root, dir->i_ino, &objectid); if (err) { err = -ENOSPC; - goto out_unlock; + goto out_fail; } inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name, -- cgit v0.10.2 From 4125bf761cd0786e1163e024c7c809ce2cc625bc Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Wed, 3 Feb 2010 18:18:45 +0000 Subject: Btrfs: finish read pages in the order they are submitted The endio is done at reverse order of bio vectors. That means for a sequential read, the page first submitted will finish last in a bio. Considering we will do checksum (making cache hot) for every page, this does introduce delay (and chance to squeeze cache used soon) for pages submitted at the begining. I don't observe obvious performance difference with below patch at my simple test, but seems more natural to finish read in the order they are submitted. Signed-off-by: Shaohua Li Signed-off-by: Chris Mason diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 7073cbb..355a973 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -1750,7 +1750,8 @@ static void end_bio_extent_writepage(struct bio *bio, int err) static void end_bio_extent_readpage(struct bio *bio, int err) { int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); - struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1; + struct bio_vec *bvec_end = bio->bi_io_vec + bio->bi_vcnt - 1; + struct bio_vec *bvec = bio->bi_io_vec; struct extent_io_tree *tree; u64 start; u64 end; @@ -1773,7 +1774,7 @@ static void end_bio_extent_readpage(struct bio *bio, int err) else whole_page = 0; - if (--bvec >= bio->bi_io_vec) + if (++bvec <= bvec_end) prefetchw(&bvec->bv_page->flags); if (uptodate && tree->ops && tree->ops->readpage_end_io_hook) { @@ -1818,7 +1819,7 @@ static void end_bio_extent_readpage(struct bio *bio, int err) } check_page_locked(tree, page); } - } while (bvec >= bio->bi_io_vec); + } while (bvec <= bvec_end); bio_put(bio); } -- cgit v0.10.2 From 49958fd7dbb83cd4d65179d025940e01fe1fbacd Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Tue, 2 Feb 2010 21:48:28 +0000 Subject: Btrfs: change the ordered tree to use a spinlock instead of a mutex The ordered tree used to need a mutex, but currently all we use it for is to protect the rb_tree, and a spin_lock is just fine for that. Using a spin_lock instead makes dbench run a little faster, 58 mb/s instead of 51 mb/s, and have less latency, 3445.138 ms instead of 3820.633 ms. Signed-off-by: Josef Bacik Signed-off-by: Chris Mason diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index 5c2a9e7..d56f732 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c @@ -174,7 +174,6 @@ int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset, if (!entry) return -ENOMEM; - mutex_lock(&tree->mutex); entry->file_offset = file_offset; entry->start = start; entry->len = len; @@ -190,16 +189,17 @@ int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset, INIT_LIST_HEAD(&entry->list); INIT_LIST_HEAD(&entry->root_extent_list); + spin_lock(&tree->lock); node = tree_insert(&tree->tree, file_offset, &entry->rb_node); BUG_ON(node); + spin_unlock(&tree->lock); spin_lock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock); list_add_tail(&entry->root_extent_list, &BTRFS_I(inode)->root->fs_info->ordered_extents); spin_unlock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock); - mutex_unlock(&tree->mutex); BUG_ON(node); return 0; } @@ -216,9 +216,9 @@ int btrfs_add_ordered_sum(struct inode *inode, struct btrfs_ordered_inode_tree *tree; tree = &BTRFS_I(inode)->ordered_tree; - mutex_lock(&tree->mutex); + spin_lock(&tree->lock); list_add_tail(&sum->list, &entry->list); - mutex_unlock(&tree->mutex); + spin_unlock(&tree->lock); return 0; } @@ -240,7 +240,7 @@ int btrfs_dec_test_ordered_pending(struct inode *inode, int ret; tree = &BTRFS_I(inode)->ordered_tree; - mutex_lock(&tree->mutex); + spin_lock(&tree->lock); node = tree_search(tree, file_offset); if (!node) { ret = 1; @@ -264,7 +264,7 @@ int btrfs_dec_test_ordered_pending(struct inode *inode, else ret = 1; out: - mutex_unlock(&tree->mutex); + spin_unlock(&tree->lock); return ret == 0; } @@ -291,7 +291,7 @@ int btrfs_put_ordered_extent(struct btrfs_ordered_extent *entry) /* * remove an ordered extent from the tree. No references are dropped - * and you must wake_up entry->wait. You must hold the tree mutex + * and you must wake_up entry->wait. You must hold the tree lock * while you call this function. */ static int __btrfs_remove_ordered_extent(struct inode *inode, @@ -340,9 +340,9 @@ int btrfs_remove_ordered_extent(struct inode *inode, int ret; tree = &BTRFS_I(inode)->ordered_tree; - mutex_lock(&tree->mutex); + spin_lock(&tree->lock); ret = __btrfs_remove_ordered_extent(inode, entry); - mutex_unlock(&tree->mutex); + spin_unlock(&tree->lock); wake_up(&entry->wait); return ret; @@ -567,7 +567,7 @@ struct btrfs_ordered_extent *btrfs_lookup_ordered_extent(struct inode *inode, struct btrfs_ordered_extent *entry = NULL; tree = &BTRFS_I(inode)->ordered_tree; - mutex_lock(&tree->mutex); + spin_lock(&tree->lock); node = tree_search(tree, file_offset); if (!node) goto out; @@ -578,7 +578,7 @@ struct btrfs_ordered_extent *btrfs_lookup_ordered_extent(struct inode *inode, if (entry) atomic_inc(&entry->refs); out: - mutex_unlock(&tree->mutex); + spin_unlock(&tree->lock); return entry; } @@ -594,7 +594,7 @@ btrfs_lookup_first_ordered_extent(struct inode *inode, u64 file_offset) struct btrfs_ordered_extent *entry = NULL; tree = &BTRFS_I(inode)->ordered_tree; - mutex_lock(&tree->mutex); + spin_lock(&tree->lock); node = tree_search(tree, file_offset); if (!node) goto out; @@ -602,7 +602,7 @@ btrfs_lookup_first_ordered_extent(struct inode *inode, u64 file_offset) entry = rb_entry(node, struct btrfs_ordered_extent, rb_node); atomic_inc(&entry->refs); out: - mutex_unlock(&tree->mutex); + spin_unlock(&tree->lock); return entry; } @@ -629,7 +629,7 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset, else offset = ALIGN(offset, BTRFS_I(inode)->root->sectorsize); - mutex_lock(&tree->mutex); + spin_lock(&tree->lock); disk_i_size = BTRFS_I(inode)->disk_i_size; /* truncate file */ @@ -735,7 +735,7 @@ out: */ if (ordered) __btrfs_remove_ordered_extent(inode, ordered); - mutex_unlock(&tree->mutex); + spin_unlock(&tree->lock); if (ordered) wake_up(&ordered->wait); return ret; @@ -762,7 +762,7 @@ int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr, if (!ordered) return 1; - mutex_lock(&tree->mutex); + spin_lock(&tree->lock); list_for_each_entry_reverse(ordered_sum, &ordered->list, list) { if (disk_bytenr >= ordered_sum->bytenr) { num_sectors = ordered_sum->len / sectorsize; @@ -777,7 +777,7 @@ int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr, } } out: - mutex_unlock(&tree->mutex); + spin_unlock(&tree->lock); btrfs_put_ordered_extent(ordered); return ret; } diff --git a/fs/btrfs/ordered-data.h b/fs/btrfs/ordered-data.h index 9116c6d..bfbcebb 100644 --- a/fs/btrfs/ordered-data.h +++ b/fs/btrfs/ordered-data.h @@ -21,7 +21,7 @@ /* one of these per inode */ struct btrfs_ordered_inode_tree { - struct mutex mutex; + spinlock_t lock; struct rb_root tree; struct rb_node *last; }; @@ -128,7 +128,7 @@ static inline int btrfs_ordered_sum_size(struct btrfs_root *root, static inline void btrfs_ordered_inode_tree_init(struct btrfs_ordered_inode_tree *t) { - mutex_init(&t->mutex); + spin_lock_init(&t->lock); t->tree = RB_ROOT; t->last = NULL; } -- cgit v0.10.2 From c2a128d28a2e78e159e17e8c9274d0a9d9492555 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Tue, 2 Feb 2010 21:19:11 +0000 Subject: Btrfs: cache extent state in find_delalloc_range This patch makes us cache the extent state we find in find_delalloc_range since we'll have to lock the extent later on in the function. This will keep us from re-searching for the rang when we try to lock the extent. Signed-off-by: Josef Bacik Signed-off-by: Chris Mason diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 355a973..3c17c9e 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -1171,7 +1171,8 @@ out: * 1 is returned if we find something, 0 if nothing was in the tree */ static noinline u64 find_delalloc_range(struct extent_io_tree *tree, - u64 *start, u64 *end, u64 max_bytes) + u64 *start, u64 *end, u64 max_bytes, + struct extent_state **cached_state) { struct rb_node *node; struct extent_state *state; @@ -1203,8 +1204,11 @@ static noinline u64 find_delalloc_range(struct extent_io_tree *tree, *end = state->end; goto out; } - if (!found) + if (!found) { *start = state->start; + *cached_state = state; + atomic_inc(&state->refs); + } found++; *end = state->end; cur_start = state->end + 1; @@ -1336,10 +1340,11 @@ again: delalloc_start = *start; delalloc_end = 0; found = find_delalloc_range(tree, &delalloc_start, &delalloc_end, - max_bytes); + max_bytes, &cached_state); if (!found || delalloc_end <= *start) { *start = delalloc_start; *end = delalloc_end; + free_extent_state(cached_state); return found; } -- cgit v0.10.2 From 5a1a3df1f6c86926cfe8657e6f9b4b4c2f467d60 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Tue, 2 Feb 2010 20:51:14 +0000 Subject: Btrfs: cache ordered extent when completing io When finishing io we run btrfs_dec_test_ordered_pending, and then immediately run btrfs_lookup_ordered_extent, but btrfs_dec_test_ordered_pending does that already, so we're searching twice when we don't have to. This patch lets us pass a btrfs_ordered_extent in to btrfs_dec_test_ordered_pending so if we do complete io on that ordered extent we can just use the one we found then instead of having to do another btrfs_lookup_ordered_extent. This made my fio job with the other patch go from 24 mb/s to 29 mb/s. Signed-off-by: Josef Bacik Signed-off-by: Chris Mason diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 50ce884..1824dda 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -1698,11 +1698,10 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) int compressed = 0; int ret; - ret = btrfs_dec_test_ordered_pending(inode, start, end - start + 1); + ret = btrfs_dec_test_ordered_pending(inode, &ordered_extent, start, + end - start + 1); if (!ret) return 0; - - ordered_extent = btrfs_lookup_ordered_extent(inode, start); BUG_ON(!ordered_extent); if (test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags)) { diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index d56f732..a8ffecd 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c @@ -232,11 +232,12 @@ int btrfs_add_ordered_sum(struct inode *inode, * to make sure this function only returns 1 once for a given ordered extent. */ int btrfs_dec_test_ordered_pending(struct inode *inode, + struct btrfs_ordered_extent **cached, u64 file_offset, u64 io_size) { struct btrfs_ordered_inode_tree *tree; struct rb_node *node; - struct btrfs_ordered_extent *entry; + struct btrfs_ordered_extent *entry = NULL; int ret; tree = &BTRFS_I(inode)->ordered_tree; @@ -264,6 +265,10 @@ int btrfs_dec_test_ordered_pending(struct inode *inode, else ret = 1; out: + if (!ret && cached && entry) { + *cached = entry; + atomic_inc(&entry->refs); + } spin_unlock(&tree->lock); return ret == 0; } diff --git a/fs/btrfs/ordered-data.h b/fs/btrfs/ordered-data.h index bfbcebb..c82f76a 100644 --- a/fs/btrfs/ordered-data.h +++ b/fs/btrfs/ordered-data.h @@ -137,7 +137,8 @@ int btrfs_put_ordered_extent(struct btrfs_ordered_extent *entry); int btrfs_remove_ordered_extent(struct inode *inode, struct btrfs_ordered_extent *entry); int btrfs_dec_test_ordered_pending(struct inode *inode, - u64 file_offset, u64 io_size); + struct btrfs_ordered_extent **cached, + u64 file_offset, u64 io_size); int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset, u64 start, u64 len, u64 disk_len, int tyep); int btrfs_add_ordered_sum(struct inode *inode, -- cgit v0.10.2 From 2ac55d41b5d6bf49e76bc85db5431240617e2f8f Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Wed, 3 Feb 2010 19:33:23 +0000 Subject: Btrfs: cache the extent state everywhere we possibly can V2 This patch just goes through and fixes everybody that does lock_extent() blah unlock_extent() to use lock_extent_bits() blah unlock_extent_cached() and pass around a extent_state so we only have to do the searches once per function. This gives me about a 3 mb/s boots on my random write test. I have not converted some things, like the relocation and ioctl's, since they aren't heavily used and the relocation stuff is in the middle of being re-written. I also changed the clear_extent_bit() to only unset the cached state if we are clearing EXTENT_LOCKED and related stuff, so we can do things like this lock_extent_bits() clear delalloc bits unlock_extent_cached() without losing our cached state. I tested this thoroughly and turned on LEAK_DEBUG to make sure we weren't leaking extent states, everything worked out fine. Signed-off-by: Josef Bacik Signed-off-by: Chris Mason diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 3a36b1f..3f704a8 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -2311,7 +2311,8 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, u32 min_type); int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput); -int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end); +int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end, + struct extent_state **cached_state); int btrfs_writepages(struct address_space *mapping, struct writeback_control *wbc); int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 0427183..11d0ad3 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -263,13 +263,15 @@ static int csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf, static int verify_parent_transid(struct extent_io_tree *io_tree, struct extent_buffer *eb, u64 parent_transid) { + struct extent_state *cached_state = NULL; int ret; if (!parent_transid || btrfs_header_generation(eb) == parent_transid) return 0; - lock_extent(io_tree, eb->start, eb->start + eb->len - 1, GFP_NOFS); - if (extent_buffer_uptodate(io_tree, eb) && + lock_extent_bits(io_tree, eb->start, eb->start + eb->len - 1, + 0, &cached_state, GFP_NOFS); + if (extent_buffer_uptodate(io_tree, eb, cached_state) && btrfs_header_generation(eb) == parent_transid) { ret = 0; goto out; @@ -282,10 +284,10 @@ static int verify_parent_transid(struct extent_io_tree *io_tree, (unsigned long long)btrfs_header_generation(eb)); } ret = 1; - clear_extent_buffer_uptodate(io_tree, eb); + clear_extent_buffer_uptodate(io_tree, eb, &cached_state); out: - unlock_extent(io_tree, eb->start, eb->start + eb->len - 1, - GFP_NOFS); + unlock_extent_cached(io_tree, eb->start, eb->start + eb->len - 1, + &cached_state, GFP_NOFS); return ret; } @@ -2497,7 +2499,8 @@ int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid) int ret; struct inode *btree_inode = buf->first_page->mapping->host; - ret = extent_buffer_uptodate(&BTRFS_I(btree_inode)->io_tree, buf); + ret = extent_buffer_uptodate(&BTRFS_I(btree_inode)->io_tree, buf, + NULL); if (!ret) return ret; diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 559f724..1727b26 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -6561,6 +6561,7 @@ static noinline int invalidate_extent_cache(struct btrfs_root *root, struct btrfs_key key; struct inode *inode = NULL; struct btrfs_file_extent_item *fi; + struct extent_state *cached_state = NULL; u64 num_bytes; u64 skip_objectid = 0; u32 nritems; @@ -6589,12 +6590,14 @@ static noinline int invalidate_extent_cache(struct btrfs_root *root, } num_bytes = btrfs_file_extent_num_bytes(leaf, fi); - lock_extent(&BTRFS_I(inode)->io_tree, key.offset, - key.offset + num_bytes - 1, GFP_NOFS); + lock_extent_bits(&BTRFS_I(inode)->io_tree, key.offset, + key.offset + num_bytes - 1, 0, &cached_state, + GFP_NOFS); btrfs_drop_extent_cache(inode, key.offset, key.offset + num_bytes - 1, 1); - unlock_extent(&BTRFS_I(inode)->io_tree, key.offset, - key.offset + num_bytes - 1, GFP_NOFS); + unlock_extent_cached(&BTRFS_I(inode)->io_tree, key.offset, + key.offset + num_bytes - 1, &cached_state, + GFP_NOFS); cond_resched(); } iput(inode); diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 3c17c9e..c99121a 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -513,7 +513,10 @@ int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, u64 last_end; int err; int set = 0; + int clear = 0; + if (bits & (EXTENT_IOBITS | EXTENT_BOUNDARY)) + clear = 1; again: if (!prealloc && (mask & __GFP_WAIT)) { prealloc = alloc_extent_state(mask); @@ -524,14 +527,20 @@ again: spin_lock(&tree->lock); if (cached_state) { cached = *cached_state; - *cached_state = NULL; - cached_state = NULL; + + if (clear) { + *cached_state = NULL; + cached_state = NULL; + } + if (cached && cached->tree && cached->start == start) { - atomic_dec(&cached->refs); + if (clear) + atomic_dec(&cached->refs); state = cached; goto hit_next; } - free_extent_state(cached); + if (clear) + free_extent_state(cached); } /* * this search will find the extents that end after @@ -946,11 +955,11 @@ int clear_extent_bits(struct extent_io_tree *tree, u64 start, u64 end, } int set_extent_delalloc(struct extent_io_tree *tree, u64 start, u64 end, - gfp_t mask) + struct extent_state **cached_state, gfp_t mask) { return set_extent_bit(tree, start, end, EXTENT_DELALLOC | EXTENT_DIRTY | EXTENT_UPTODATE, - 0, NULL, NULL, mask); + 0, NULL, cached_state, mask); } int clear_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end, @@ -984,10 +993,11 @@ int set_extent_uptodate(struct extent_io_tree *tree, u64 start, u64 end, } static int clear_extent_uptodate(struct extent_io_tree *tree, u64 start, - u64 end, gfp_t mask) + u64 end, struct extent_state **cached_state, + gfp_t mask) { return clear_extent_bit(tree, start, end, EXTENT_UPTODATE, 0, 0, - NULL, mask); + cached_state, mask); } int wait_on_extent_writeback(struct extent_io_tree *tree, u64 start, u64 end) @@ -1727,7 +1737,7 @@ static void end_bio_extent_writepage(struct bio *bio, int err) } if (!uptodate) { - clear_extent_uptodate(tree, start, end, GFP_NOFS); + clear_extent_uptodate(tree, start, end, NULL, GFP_NOFS); ClearPageUptodate(page); SetPageError(page); } @@ -2710,6 +2720,7 @@ int extent_readpages(struct extent_io_tree *tree, int extent_invalidatepage(struct extent_io_tree *tree, struct page *page, unsigned long offset) { + struct extent_state *cached_state = NULL; u64 start = ((u64)page->index << PAGE_CACHE_SHIFT); u64 end = start + PAGE_CACHE_SIZE - 1; size_t blocksize = page->mapping->host->i_sb->s_blocksize; @@ -2718,12 +2729,12 @@ int extent_invalidatepage(struct extent_io_tree *tree, if (start > end) return 0; - lock_extent(tree, start, end, GFP_NOFS); + lock_extent_bits(tree, start, end, 0, &cached_state, GFP_NOFS); wait_on_page_writeback(page); clear_extent_bit(tree, start, end, EXTENT_LOCKED | EXTENT_DIRTY | EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING, - 1, 1, NULL, GFP_NOFS); + 1, 1, &cached_state, GFP_NOFS); return 0; } @@ -2926,16 +2937,17 @@ sector_t extent_bmap(struct address_space *mapping, sector_t iblock, get_extent_t *get_extent) { struct inode *inode = mapping->host; + struct extent_state *cached_state = NULL; u64 start = iblock << inode->i_blkbits; sector_t sector = 0; size_t blksize = (1 << inode->i_blkbits); struct extent_map *em; - lock_extent(&BTRFS_I(inode)->io_tree, start, start + blksize - 1, - GFP_NOFS); + lock_extent_bits(&BTRFS_I(inode)->io_tree, start, start + blksize - 1, + 0, &cached_state, GFP_NOFS); em = get_extent(inode, NULL, 0, start, blksize, 0); - unlock_extent(&BTRFS_I(inode)->io_tree, start, start + blksize - 1, - GFP_NOFS); + unlock_extent_cached(&BTRFS_I(inode)->io_tree, start, + start + blksize - 1, &cached_state, GFP_NOFS); if (!em || IS_ERR(em)) return 0; @@ -2957,6 +2969,7 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, u32 flags = 0; u64 disko = 0; struct extent_map *em = NULL; + struct extent_state *cached_state = NULL; int end = 0; u64 em_start = 0, em_len = 0; unsigned long emflags; @@ -2965,8 +2978,8 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, if (len == 0) return -EINVAL; - lock_extent(&BTRFS_I(inode)->io_tree, start, start + len, - GFP_NOFS); + lock_extent_bits(&BTRFS_I(inode)->io_tree, start, start + len, 0, + &cached_state, GFP_NOFS); em = get_extent(inode, NULL, 0, off, max - off, 0); if (!em) goto out; @@ -3029,8 +3042,8 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, out_free: free_extent_map(em); out: - unlock_extent(&BTRFS_I(inode)->io_tree, start, start + len, - GFP_NOFS); + unlock_extent_cached(&BTRFS_I(inode)->io_tree, start, start + len, + &cached_state, GFP_NOFS); return ret; } @@ -3270,7 +3283,8 @@ int set_extent_buffer_dirty(struct extent_io_tree *tree, } int clear_extent_buffer_uptodate(struct extent_io_tree *tree, - struct extent_buffer *eb) + struct extent_buffer *eb, + struct extent_state **cached_state) { unsigned long i; struct page *page; @@ -3280,7 +3294,7 @@ int clear_extent_buffer_uptodate(struct extent_io_tree *tree, clear_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags); clear_extent_uptodate(tree, eb->start, eb->start + eb->len - 1, - GFP_NOFS); + cached_state, GFP_NOFS); for (i = 0; i < num_pages; i++) { page = extent_buffer_page(eb, i); if (page) @@ -3340,7 +3354,8 @@ int extent_range_uptodate(struct extent_io_tree *tree, } int extent_buffer_uptodate(struct extent_io_tree *tree, - struct extent_buffer *eb) + struct extent_buffer *eb, + struct extent_state *cached_state) { int ret = 0; unsigned long num_pages; @@ -3352,7 +3367,7 @@ int extent_buffer_uptodate(struct extent_io_tree *tree, return 1; ret = test_range_bit(tree, eb->start, eb->start + eb->len - 1, - EXTENT_UPTODATE, 1, NULL); + EXTENT_UPTODATE, 1, cached_state); if (ret) return ret; diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index 36de250..bbab481 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h @@ -163,6 +163,8 @@ int lock_extent(struct extent_io_tree *tree, u64 start, u64 end, gfp_t mask); int lock_extent_bits(struct extent_io_tree *tree, u64 start, u64 end, int bits, struct extent_state **cached, gfp_t mask); int unlock_extent(struct extent_io_tree *tree, u64 start, u64 end, gfp_t mask); +int unlock_extent_cached(struct extent_io_tree *tree, u64 start, u64 end, + struct extent_state **cached, gfp_t mask); int try_lock_extent(struct extent_io_tree *tree, u64 start, u64 end, gfp_t mask); int extent_read_full_page(struct extent_io_tree *tree, struct page *page, @@ -196,7 +198,7 @@ int clear_extent_ordered(struct extent_io_tree *tree, u64 start, u64 end, int clear_extent_ordered_metadata(struct extent_io_tree *tree, u64 start, u64 end, gfp_t mask); int set_extent_delalloc(struct extent_io_tree *tree, u64 start, u64 end, - gfp_t mask); + struct extent_state **cached_state, gfp_t mask); int set_extent_ordered(struct extent_io_tree *tree, u64 start, u64 end, gfp_t mask); int find_first_extent_bit(struct extent_io_tree *tree, u64 start, @@ -281,9 +283,11 @@ int test_extent_buffer_dirty(struct extent_io_tree *tree, int set_extent_buffer_uptodate(struct extent_io_tree *tree, struct extent_buffer *eb); int clear_extent_buffer_uptodate(struct extent_io_tree *tree, - struct extent_buffer *eb); + struct extent_buffer *eb, + struct extent_state **cached_state); int extent_buffer_uptodate(struct extent_io_tree *tree, - struct extent_buffer *eb); + struct extent_buffer *eb, + struct extent_state *cached_state); int map_extent_buffer(struct extent_buffer *eb, unsigned long offset, unsigned long min_len, char **token, char **map, unsigned long *map_start, diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index a7fd9f3..d146dde 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -123,7 +123,8 @@ static noinline int dirty_and_release_pages(struct btrfs_trans_handle *trans, root->sectorsize - 1) & ~((u64)root->sectorsize - 1); end_of_last_block = start_pos + num_bytes - 1; - err = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block); + err = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block, + NULL); if (err) return err; @@ -753,6 +754,7 @@ static noinline int prepare_pages(struct btrfs_root *root, struct file *file, loff_t pos, unsigned long first_index, unsigned long last_index, size_t write_bytes) { + struct extent_state *cached_state = NULL; int i; unsigned long index = pos >> PAGE_CACHE_SHIFT; struct inode *inode = fdentry(file)->d_inode; @@ -781,16 +783,18 @@ again: } if (start_pos < inode->i_size) { struct btrfs_ordered_extent *ordered; - lock_extent(&BTRFS_I(inode)->io_tree, - start_pos, last_pos - 1, GFP_NOFS); + lock_extent_bits(&BTRFS_I(inode)->io_tree, + start_pos, last_pos - 1, 0, &cached_state, + GFP_NOFS); ordered = btrfs_lookup_first_ordered_extent(inode, last_pos - 1); if (ordered && ordered->file_offset + ordered->len > start_pos && ordered->file_offset < last_pos) { btrfs_put_ordered_extent(ordered); - unlock_extent(&BTRFS_I(inode)->io_tree, - start_pos, last_pos - 1, GFP_NOFS); + unlock_extent_cached(&BTRFS_I(inode)->io_tree, + start_pos, last_pos - 1, + &cached_state, GFP_NOFS); for (i = 0; i < num_pages; i++) { unlock_page(pages[i]); page_cache_release(pages[i]); @@ -802,12 +806,13 @@ again: if (ordered) btrfs_put_ordered_extent(ordered); - clear_extent_bits(&BTRFS_I(inode)->io_tree, start_pos, + clear_extent_bit(&BTRFS_I(inode)->io_tree, start_pos, last_pos - 1, EXTENT_DIRTY | EXTENT_DELALLOC | - EXTENT_DO_ACCOUNTING, + EXTENT_DO_ACCOUNTING, 0, 0, &cached_state, GFP_NOFS); - unlock_extent(&BTRFS_I(inode)->io_tree, - start_pos, last_pos - 1, GFP_NOFS); + unlock_extent_cached(&BTRFS_I(inode)->io_tree, + start_pos, last_pos - 1, &cached_state, + GFP_NOFS); } for (i = 0; i < num_pages; i++) { clear_page_dirty_for_io(pages[i]); diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 1824dda..2a337a0 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -573,8 +573,8 @@ retry: unsigned long nr_written = 0; lock_extent(io_tree, async_extent->start, - async_extent->start + - async_extent->ram_size - 1, GFP_NOFS); + async_extent->start + + async_extent->ram_size - 1, GFP_NOFS); /* allocate blocks */ ret = cow_file_range(inode, async_cow->locked_page, @@ -1512,12 +1512,13 @@ static noinline int add_pending_csums(struct btrfs_trans_handle *trans, return 0; } -int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end) +int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end, + struct extent_state **cached_state) { if ((end & (PAGE_CACHE_SIZE - 1)) == 0) WARN_ON(1); return set_extent_delalloc(&BTRFS_I(inode)->io_tree, start, end, - GFP_NOFS); + cached_state, GFP_NOFS); } /* see btrfs_writepage_start_hook for details on why this is required */ @@ -1530,6 +1531,7 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work) { struct btrfs_writepage_fixup *fixup; struct btrfs_ordered_extent *ordered; + struct extent_state *cached_state = NULL; struct page *page; struct inode *inode; u64 page_start; @@ -1548,7 +1550,8 @@ again: page_start = page_offset(page); page_end = page_offset(page) + PAGE_CACHE_SIZE - 1; - lock_extent(&BTRFS_I(inode)->io_tree, page_start, page_end, GFP_NOFS); + lock_extent_bits(&BTRFS_I(inode)->io_tree, page_start, page_end, 0, + &cached_state, GFP_NOFS); /* already ordered? We're done */ if (PagePrivate2(page)) @@ -1556,17 +1559,18 @@ again: ordered = btrfs_lookup_ordered_extent(inode, page_start); if (ordered) { - unlock_extent(&BTRFS_I(inode)->io_tree, page_start, - page_end, GFP_NOFS); + unlock_extent_cached(&BTRFS_I(inode)->io_tree, page_start, + page_end, &cached_state, GFP_NOFS); unlock_page(page); btrfs_start_ordered_extent(inode, ordered, 1); goto again; } - btrfs_set_extent_delalloc(inode, page_start, page_end); + btrfs_set_extent_delalloc(inode, page_start, page_end, &cached_state); ClearPageChecked(page); out: - unlock_extent(&BTRFS_I(inode)->io_tree, page_start, page_end, GFP_NOFS); + unlock_extent_cached(&BTRFS_I(inode)->io_tree, page_start, page_end, + &cached_state, GFP_NOFS); out_page: unlock_page(page); page_cache_release(page); @@ -1695,6 +1699,7 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) struct btrfs_trans_handle *trans; struct btrfs_ordered_extent *ordered_extent = NULL; struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; + struct extent_state *cached_state = NULL; int compressed = 0; int ret; @@ -1716,9 +1721,9 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) goto out; } - lock_extent(io_tree, ordered_extent->file_offset, - ordered_extent->file_offset + ordered_extent->len - 1, - GFP_NOFS); + lock_extent_bits(io_tree, ordered_extent->file_offset, + ordered_extent->file_offset + ordered_extent->len - 1, + 0, &cached_state, GFP_NOFS); trans = btrfs_join_transaction(root, 1); @@ -1745,9 +1750,10 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) ordered_extent->len); BUG_ON(ret); } - unlock_extent(io_tree, ordered_extent->file_offset, - ordered_extent->file_offset + ordered_extent->len - 1, - GFP_NOFS); + unlock_extent_cached(io_tree, ordered_extent->file_offset, + ordered_extent->file_offset + + ordered_extent->len - 1, &cached_state, GFP_NOFS); + add_pending_csums(trans, inode, ordered_extent->file_offset, &ordered_extent->list); @@ -3084,6 +3090,7 @@ static int btrfs_truncate_page(struct address_space *mapping, loff_t from) struct btrfs_root *root = BTRFS_I(inode)->root; struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; struct btrfs_ordered_extent *ordered; + struct extent_state *cached_state = NULL; char *kaddr; u32 blocksize = root->sectorsize; pgoff_t index = from >> PAGE_CACHE_SHIFT; @@ -3130,12 +3137,14 @@ again: } wait_on_page_writeback(page); - lock_extent(io_tree, page_start, page_end, GFP_NOFS); + lock_extent_bits(io_tree, page_start, page_end, 0, &cached_state, + GFP_NOFS); set_page_extent_mapped(page); ordered = btrfs_lookup_ordered_extent(inode, page_start); if (ordered) { - unlock_extent(io_tree, page_start, page_end, GFP_NOFS); + unlock_extent_cached(io_tree, page_start, page_end, + &cached_state, GFP_NOFS); unlock_page(page); page_cache_release(page); btrfs_start_ordered_extent(inode, ordered, 1); @@ -3143,13 +3152,15 @@ again: goto again; } - clear_extent_bits(&BTRFS_I(inode)->io_tree, page_start, page_end, + clear_extent_bit(&BTRFS_I(inode)->io_tree, page_start, page_end, EXTENT_DIRTY | EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING, - GFP_NOFS); + 0, 0, &cached_state, GFP_NOFS); - ret = btrfs_set_extent_delalloc(inode, page_start, page_end); + ret = btrfs_set_extent_delalloc(inode, page_start, page_end, + &cached_state); if (ret) { - unlock_extent(io_tree, page_start, page_end, GFP_NOFS); + unlock_extent_cached(io_tree, page_start, page_end, + &cached_state, GFP_NOFS); goto out_unlock; } @@ -3162,7 +3173,8 @@ again: } ClearPageChecked(page); set_page_dirty(page); - unlock_extent(io_tree, page_start, page_end, GFP_NOFS); + unlock_extent_cached(io_tree, page_start, page_end, &cached_state, + GFP_NOFS); out_unlock: if (ret) @@ -3180,6 +3192,7 @@ int btrfs_cont_expand(struct inode *inode, loff_t size) struct btrfs_root *root = BTRFS_I(inode)->root; struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; struct extent_map *em; + struct extent_state *cached_state = NULL; u64 mask = root->sectorsize - 1; u64 hole_start = (inode->i_size + mask) & ~mask; u64 block_end = (size + mask) & ~mask; @@ -3195,11 +3208,13 @@ int btrfs_cont_expand(struct inode *inode, loff_t size) struct btrfs_ordered_extent *ordered; btrfs_wait_ordered_range(inode, hole_start, block_end - hole_start); - lock_extent(io_tree, hole_start, block_end - 1, GFP_NOFS); + lock_extent_bits(io_tree, hole_start, block_end - 1, 0, + &cached_state, GFP_NOFS); ordered = btrfs_lookup_ordered_extent(inode, hole_start); if (!ordered) break; - unlock_extent(io_tree, hole_start, block_end - 1, GFP_NOFS); + unlock_extent_cached(io_tree, hole_start, block_end - 1, + &cached_state, GFP_NOFS); btrfs_put_ordered_extent(ordered); } @@ -3244,7 +3259,8 @@ int btrfs_cont_expand(struct inode *inode, loff_t size) break; } - unlock_extent(io_tree, hole_start, block_end - 1, GFP_NOFS); + unlock_extent_cached(io_tree, hole_start, block_end - 1, &cached_state, + GFP_NOFS); return err; } @@ -4985,6 +5001,7 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset) { struct extent_io_tree *tree; struct btrfs_ordered_extent *ordered; + struct extent_state *cached_state = NULL; u64 page_start = page_offset(page); u64 page_end = page_start + PAGE_CACHE_SIZE - 1; @@ -5003,7 +5020,8 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset) btrfs_releasepage(page, GFP_NOFS); return; } - lock_extent(tree, page_start, page_end, GFP_NOFS); + lock_extent_bits(tree, page_start, page_end, 0, &cached_state, + GFP_NOFS); ordered = btrfs_lookup_ordered_extent(page->mapping->host, page_offset(page)); if (ordered) { @@ -5014,7 +5032,7 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset) clear_extent_bit(tree, page_start, page_end, EXTENT_DIRTY | EXTENT_DELALLOC | EXTENT_LOCKED | EXTENT_DO_ACCOUNTING, 1, 0, - NULL, GFP_NOFS); + &cached_state, GFP_NOFS); /* * whoever cleared the private bit is responsible * for the finish_ordered_io @@ -5024,11 +5042,13 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset) page_start, page_end); } btrfs_put_ordered_extent(ordered); - lock_extent(tree, page_start, page_end, GFP_NOFS); + cached_state = NULL; + lock_extent_bits(tree, page_start, page_end, 0, &cached_state, + GFP_NOFS); } clear_extent_bit(tree, page_start, page_end, EXTENT_LOCKED | EXTENT_DIRTY | EXTENT_DELALLOC | - EXTENT_DO_ACCOUNTING, 1, 1, NULL, GFP_NOFS); + EXTENT_DO_ACCOUNTING, 1, 1, &cached_state, GFP_NOFS); __btrfs_releasepage(page, GFP_NOFS); ClearPageChecked(page); @@ -5061,6 +5081,7 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) struct btrfs_root *root = BTRFS_I(inode)->root; struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; struct btrfs_ordered_extent *ordered; + struct extent_state *cached_state = NULL; char *kaddr; unsigned long zero_start; loff_t size; @@ -5099,7 +5120,8 @@ again: } wait_on_page_writeback(page); - lock_extent(io_tree, page_start, page_end, GFP_NOFS); + lock_extent_bits(io_tree, page_start, page_end, 0, &cached_state, + GFP_NOFS); set_page_extent_mapped(page); /* @@ -5108,7 +5130,8 @@ again: */ ordered = btrfs_lookup_ordered_extent(inode, page_start); if (ordered) { - unlock_extent(io_tree, page_start, page_end, GFP_NOFS); + unlock_extent_cached(io_tree, page_start, page_end, + &cached_state, GFP_NOFS); unlock_page(page); btrfs_start_ordered_extent(inode, ordered, 1); btrfs_put_ordered_extent(ordered); @@ -5122,13 +5145,15 @@ again: * is probably a better way to do this, but for now keep consistent with * prepare_pages in the normal write path. */ - clear_extent_bits(&BTRFS_I(inode)->io_tree, page_start, page_end, + clear_extent_bit(&BTRFS_I(inode)->io_tree, page_start, page_end, EXTENT_DIRTY | EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING, - GFP_NOFS); + 0, 0, &cached_state, GFP_NOFS); - ret = btrfs_set_extent_delalloc(inode, page_start, page_end); + ret = btrfs_set_extent_delalloc(inode, page_start, page_end, + &cached_state); if (ret) { - unlock_extent(io_tree, page_start, page_end, GFP_NOFS); + unlock_extent_cached(io_tree, page_start, page_end, + &cached_state, GFP_NOFS); ret = VM_FAULT_SIGBUS; btrfs_free_reserved_data_space(root, inode, PAGE_CACHE_SIZE); goto out_unlock; @@ -5154,7 +5179,7 @@ again: BTRFS_I(inode)->last_trans = root->fs_info->generation; BTRFS_I(inode)->last_sub_trans = BTRFS_I(inode)->root->log_transid; - unlock_extent(io_tree, page_start, page_end, GFP_NOFS); + unlock_extent_cached(io_tree, page_start, page_end, &cached_state, GFP_NOFS); out_unlock: btrfs_unreserve_metadata_for_delalloc(root, inode, 1); @@ -5833,6 +5858,7 @@ stop_trans: static long btrfs_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len) { + struct extent_state *cached_state = NULL; u64 cur_offset; u64 last_byte; u64 alloc_start; @@ -5871,16 +5897,17 @@ static long btrfs_fallocate(struct inode *inode, int mode, /* the extent lock is ordered inside the running * transaction */ - lock_extent(&BTRFS_I(inode)->io_tree, alloc_start, locked_end, - GFP_NOFS); + lock_extent_bits(&BTRFS_I(inode)->io_tree, alloc_start, + locked_end, 0, &cached_state, GFP_NOFS); ordered = btrfs_lookup_first_ordered_extent(inode, alloc_end - 1); if (ordered && ordered->file_offset + ordered->len > alloc_start && ordered->file_offset < alloc_end) { btrfs_put_ordered_extent(ordered); - unlock_extent(&BTRFS_I(inode)->io_tree, - alloc_start, locked_end, GFP_NOFS); + unlock_extent_cached(&BTRFS_I(inode)->io_tree, + alloc_start, locked_end, + &cached_state, GFP_NOFS); /* * we can't wait on the range with the transaction * running or with the extent lock held @@ -5922,8 +5949,8 @@ static long btrfs_fallocate(struct inode *inode, int mode, break; } } - unlock_extent(&BTRFS_I(inode)->io_tree, alloc_start, locked_end, - GFP_NOFS); + unlock_extent_cached(&BTRFS_I(inode)->io_tree, alloc_start, locked_end, + &cached_state, GFP_NOFS); btrfs_free_reserved_data_space(BTRFS_I(inode)->root, inode, alloc_end - alloc_start); diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index d866b46..9aaba6e 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -673,7 +673,7 @@ again: page_end, EXTENT_DIRTY | EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING, GFP_NOFS); - btrfs_set_extent_delalloc(inode, page_start, page_end); + btrfs_set_extent_delalloc(inode, page_start, page_end, NULL); ClearPageChecked(page); set_page_dirty(page); unlock_extent(io_tree, page_start, page_end, GFP_NOFS); diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index d52759d..0b23942 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -2659,7 +2659,7 @@ static int relocate_file_extent_cluster(struct inode *inode, EXTENT_BOUNDARY, GFP_NOFS); nr++; } - btrfs_set_extent_delalloc(inode, page_start, page_end); + btrfs_set_extent_delalloc(inode, page_start, page_end, NULL); set_page_dirty(page); dirty_page++; -- cgit v0.10.2 From 1406e4327be3a533a2b18582f715ce2cfbcf6804 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Wed, 13 Jan 2010 18:19:06 +0000 Subject: Btrfs: add a "df" ioctl for btrfs df is a very loaded question in btrfs. This gives us a way to get the per-space usage information so we can tell exactly what is in use where. This will help us figure out ENOSPC problems, and help users better understand where their disk space is going. Signed-off-by: Josef Bacik Signed-off-by: Chris Mason diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 9aaba6e..9213d39 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -1843,6 +1843,49 @@ static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp) return 0; } +long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg) +{ + struct btrfs_ioctl_space_args space_args; + struct btrfs_ioctl_space_info space; + struct btrfs_ioctl_space_info *dest; + struct btrfs_space_info *info; + int ret = 0; + + if (copy_from_user(&space_args, + (struct btrfs_ioctl_space_args __user *)arg, + sizeof(space_args))) + return -EFAULT; + + space_args.total_spaces = 0; + dest = (struct btrfs_ioctl_space_info *) + (arg + sizeof(struct btrfs_ioctl_space_args)); + + rcu_read_lock(); + list_for_each_entry_rcu(info, &root->fs_info->space_info, list) { + if (!space_args.space_slots) { + space_args.total_spaces++; + continue; + } + if (space_args.total_spaces >= space_args.space_slots) + break; + space.flags = info->flags; + space.total_bytes = info->total_bytes; + space.used_bytes = info->bytes_used; + if (copy_to_user(dest, &space, sizeof(space))) { + ret = -EFAULT; + break; + } + dest++; + space_args.total_spaces++; + } + rcu_read_unlock(); + + if (copy_to_user(arg, &space_args, sizeof(space_args))) + ret = -EFAULT; + + return ret; +} + /* * there are many ways the trans_start and trans_end ioctls can lead * to deadlocks. They should only be used by applications that @@ -1915,6 +1958,8 @@ long btrfs_ioctl(struct file *file, unsigned int return btrfs_ioctl_tree_search(file, argp); case BTRFS_IOC_INO_LOOKUP: return btrfs_ioctl_ino_lookup(file, argp); + case BTRFS_IOC_SPACE_INFO: + return btrfs_ioctl_space_info(root, argp); case BTRFS_IOC_SYNC: btrfs_sync_fs(file->f_dentry->d_sb, 1); return 0; diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h index 2d64a65..81eac0a 100644 --- a/fs/btrfs/ioctl.h +++ b/fs/btrfs/ioctl.h @@ -1,4 +1,3 @@ - /* * Copyright (C) 2007 Oracle. All rights reserved. * @@ -127,6 +126,17 @@ struct btrfs_ioctl_defrag_range_args { __u32 unused[5]; }; +struct btrfs_ioctl_space_info { + u64 flags; + u64 total_bytes; + u64 used_bytes; +}; + +struct btrfs_ioctl_space_args { + u64 space_slots; + u64 total_spaces; + struct btrfs_ioctl_space_info spaces[0]; +}; #define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \ struct btrfs_ioctl_vol_args) @@ -166,4 +176,6 @@ struct btrfs_ioctl_defrag_range_args { #define BTRFS_IOC_INO_LOOKUP _IOWR(BTRFS_IOCTL_MAGIC, 18, \ struct btrfs_ioctl_ino_lookup_args) #define BTRFS_IOC_DEFAULT_SUBVOL _IOW(BTRFS_IOCTL_MAGIC, 19, u64) +#define BTRFS_IOC_SPACE_INFO _IOWR(BTRFS_IOCTL_MAGIC, 20, \ + struct btrfs_ioctl_space_args) #endif -- cgit v0.10.2 From 91748467a5c5884e44ad5cf58630c0c28474f1f6 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Sun, 28 Feb 2010 10:59:11 +0000 Subject: btrfs: use memparse Use memparse() instead of its own private implementation. Signed-off-by: Akinobu Mita Cc: Chris Mason Cc: linux-btrfs@vger.kernel.org Signed-off-by: Chris Mason diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 3f704a8..1111584 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -2388,7 +2388,6 @@ void btrfs_sysfs_del_super(struct btrfs_fs_info *root); ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size); /* super.c */ -u64 btrfs_parse_size(char *str); int btrfs_parse_options(struct btrfs_root *root, char *options); int btrfs_sync_fs(struct super_block *sb, int wait); diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 9213d39..363e209 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -776,7 +776,7 @@ static noinline int btrfs_ioctl_resize(struct btrfs_root *root, mod = 1; sizestr++; } - new_size = btrfs_parse_size(sizestr); + new_size = memparse(sizestr, NULL); if (new_size == 0) { ret = -EINVAL; goto out_unlock; diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index ff3dd55..9ac612e 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -96,31 +96,6 @@ static match_table_t tokens = { {Opt_err, NULL}, }; -u64 btrfs_parse_size(char *str) -{ - u64 res; - int mult = 1; - char *end; - char last; - - res = simple_strtoul(str, &end, 10); - - last = end[0]; - if (isalpha(last)) { - last = tolower(last); - switch (last) { - case 'g': - mult *= 1024; - case 'm': - mult *= 1024; - case 'k': - mult *= 1024; - } - res = res * mult; - } - return res; -} - /* * Regular mount options parser. Everything that is needed only when * reading in a new superblock is parsed here. @@ -216,7 +191,7 @@ int btrfs_parse_options(struct btrfs_root *root, char *options) case Opt_max_extent: num = match_strdup(&args[0]); if (num) { - info->max_extent = btrfs_parse_size(num); + info->max_extent = memparse(num, NULL); kfree(num); info->max_extent = max_t(u64, @@ -228,7 +203,7 @@ int btrfs_parse_options(struct btrfs_root *root, char *options) case Opt_max_inline: num = match_strdup(&args[0]); if (num) { - info->max_inline = btrfs_parse_size(num); + info->max_inline = memparse(num, NULL); kfree(num); if (info->max_inline) { @@ -243,7 +218,7 @@ int btrfs_parse_options(struct btrfs_root *root, char *options) case Opt_alloc_start: num = match_strdup(&args[0]); if (num) { - info->alloc_start = btrfs_parse_size(num); + info->alloc_start = memparse(num, NULL); kfree(num); printk(KERN_INFO "btrfs: allocations start at %llu\n", -- cgit v0.10.2 From a343832f1a55c74791a8a37053fc02ad80640710 Mon Sep 17 00:00:00 2001 From: Xiao Guangrong Date: Wed, 6 Jan 2010 11:48:18 +0000 Subject: btrfs: using btrfs_stack_device_id() get devid We can use btrfs_stack_device_id() to get dev_item->devid Signed-off-by: Xiao Guangrong Signed-off-by: Chris Mason diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index eb89e13..4053fc4 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -599,7 +599,7 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices, goto error_close; disk_super = (struct btrfs_super_block *)bh->b_data; - devid = le64_to_cpu(disk_super->dev_item.devid); + devid = btrfs_stack_device_id(&disk_super->dev_item); if (devid != device->devid) goto error_brelse; @@ -701,7 +701,7 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder, goto error_close; } disk_super = (struct btrfs_super_block *)bh->b_data; - devid = le64_to_cpu(disk_super->dev_item.devid); + devid = btrfs_stack_device_id(&disk_super->dev_item); transid = btrfs_super_generation(disk_super); if (disk_super->label[0]) printk(KERN_INFO "device label %s ", disk_super->label); @@ -1194,7 +1194,7 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path) goto error_close; } disk_super = (struct btrfs_super_block *)bh->b_data; - devid = le64_to_cpu(disk_super->dev_item.devid); + devid = btrfs_stack_device_id(&disk_super->dev_item); dev_uuid = disk_super->dev_item.uuid; device = btrfs_find_device(root, devid, dev_uuid, disk_super->fsid); -- cgit v0.10.2 From 5ff7ba3a797a8ffd5299b8477df2dca3c3ebd34e Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Mon, 15 Mar 2010 10:21:30 -0400 Subject: Btrfs: don't look at bio flags after submit_bio After callling submit_bio, the bio can be freed at any time. The btrfs submission thread helper was checking the bio flags too late, which might not give the correct answer. When CONFIG_DEBUG_PAGE_ALLOC is turned on, it can lead to oopsen. Signed-off-by: Chris Mason diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 4053fc4..9df8e3f 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -256,13 +256,13 @@ loop_lock: wake_up(&fs_info->async_submit_wait); BUG_ON(atomic_read(&cur->bi_cnt) == 0); - submit_bio(cur->bi_rw, cur); - num_run++; - batch_run++; if (bio_rw_flagged(cur, BIO_RW_SYNCIO)) num_sync_run++; + submit_bio(cur->bi_rw, cur); + num_run++; + batch_run++; if (need_resched()) { if (num_sync_run) { blk_run_backing_dev(bdi, NULL); -- cgit v0.10.2 From ef5780c018ed169a77b623f87c4ba52faa8ad0fe Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Mon, 15 Mar 2010 11:05:29 -0400 Subject: Btrfs: fix gfp flags masking in the compression code GFP_FS must be masked out, NOFS can't be or'd in. Signed-off-by: Chris Mason diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index a11a320..28b92a7 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c @@ -478,7 +478,7 @@ static noinline int add_ra_bio_pages(struct inode *inode, goto next; } - page = alloc_page(mapping_gfp_mask(mapping) | GFP_NOFS); + page = alloc_page(mapping_gfp_mask(mapping) & ~__GFP_FS); if (!page) break; -- cgit v0.10.2 From 8212cf7583a5ba5d213d9c9180be808222a2813f Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 15 Mar 2010 11:22:26 +0300 Subject: cifs: trivial white space I fixed the indent level. Signed-off-by: Dan Carpenter Signed-off-by: Steve French diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 903d538..20959be 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -500,7 +500,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) } else if (pSMBr->hdr.WordCount == 13) { cERROR(1, ("mount failed, cifs module not built " "with CIFS_WEAK_PW_HASH support")); - rc = -EOPNOTSUPP; + rc = -EOPNOTSUPP; #endif /* WEAK_PW_HASH */ goto neg_err_exit; } else if (pSMBr->hdr.WordCount != 17) { -- cgit v0.10.2 From 8e4971f2fb2380ce66196136e113d04196b80fcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Grafstr=C3=B6m?= Date: Mon, 15 Mar 2010 16:04:14 +0100 Subject: ARM: 5991/1: Fix regression in restore_user_regs macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ARMv5T and earlier require that a ldm {}^ instruction is not followed by an instruction that accesses banked registers. This patch restores the nop that was lost in commit b86040a59feb255a8193173caa4d5199464433d5. Signed-off-by: Anders Grafström Signed-off-by: Russell King diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S index 7e9ed1e..d93f976 100644 --- a/arch/arm/kernel/entry-header.S +++ b/arch/arm/kernel/entry-header.S @@ -102,6 +102,8 @@ .else ldmdb sp, {r0 - lr}^ @ get calling r0 - lr .endif + mov r0, r0 @ ARMv5T and earlier require a nop + @ after ldm {}^ add sp, sp, #S_FRAME_SIZE - S_PC movs pc, lr @ return & move spsr_svc into cpsr .endm -- cgit v0.10.2 From ccf50e2341c4174d5579315e184ea312081acec6 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 15 Mar 2010 19:03:06 +0000 Subject: ARM: Fix sorting of platform group config options and includes ... and document the sorting criteria to help future additions. Signed-off-by: Russell King diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index cadfe2e..c5408bf 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -218,6 +218,10 @@ config MMU Select if you want MMU-based virtualised addressing space support by paged memory management. If unsure, say 'Y'. +# +# The "ARM system type" choice list is ordered alphabetically by option +# text. Please add new entries in the option alphabetic order. +# choice prompt "ARM system type" default ARCH_VERSATILE @@ -274,6 +278,18 @@ config ARCH_AT91 This enables support for systems based on the Atmel AT91RM9200, AT91SAM9 and AT91CAP9 processors. +config ARCH_BCMRING + bool "Broadcom BCMRING" + depends on MMU + select CPU_V6 + select ARM_AMBA + select COMMON_CLKDEV + select GENERIC_TIME + select GENERIC_CLOCKEVENTS + select ARCH_WANT_OPTIONAL_GPIOLIB + help + Support for Broadcom's BCMRing platform. + config ARCH_CLPS711X bool "Cirrus Logic CLPS711x/EP721x-based" select CPU_ARM720T @@ -359,20 +375,6 @@ config ARCH_H720X help This enables support for systems based on the Hynix HMS720x -config ARCH_NOMADIK - bool "STMicroelectronics Nomadik" - select ARM_AMBA - select ARM_VIC - select CPU_ARM926T - select HAVE_CLK - select COMMON_CLKDEV - select GENERIC_TIME - select GENERIC_CLOCKEVENTS - select GENERIC_GPIO - select ARCH_REQUIRE_GPIOLIB - help - Support for the Nomadik platform by ST-Ericsson - config ARCH_IOP13XX bool "IOP13xx-based" depends on MMU @@ -747,6 +749,30 @@ config ARCH_U300 help Support for ST-Ericsson U300 series mobile platforms. +config ARCH_U8500 + bool "ST-Ericsson U8500 Series" + select CPU_V7 + select ARM_AMBA + select GENERIC_TIME + select GENERIC_CLOCKEVENTS + select COMMON_CLKDEV + help + Support for ST-Ericsson's Ux500 architecture + +config ARCH_NOMADIK + bool "STMicroelectronics Nomadik" + select ARM_AMBA + select ARM_VIC + select CPU_ARM926T + select HAVE_CLK + select COMMON_CLKDEV + select GENERIC_TIME + select GENERIC_CLOCKEVENTS + select GENERIC_GPIO + select ARCH_REQUIRE_GPIOLIB + help + Support for the Nomadik platform by ST-Ericsson + config ARCH_DAVINCI bool "TI DaVinci" select CPU_ARM926T @@ -775,30 +801,13 @@ config ARCH_OMAP help Support for TI's OMAP platform (OMAP1 and OMAP2). -config ARCH_BCMRING - bool "Broadcom BCMRING" - depends on MMU - select CPU_V6 - select ARM_AMBA - select COMMON_CLKDEV - select GENERIC_TIME - select GENERIC_CLOCKEVENTS - select ARCH_WANT_OPTIONAL_GPIOLIB - help - Support for Broadcom's BCMRing platform. - -config ARCH_U8500 - bool "ST-Ericsson U8500 Series" - select CPU_V7 - select ARM_AMBA - select GENERIC_TIME - select GENERIC_CLOCKEVENTS - select COMMON_CLKDEV - help - Support for ST-Ericsson's Ux500 architecture - endchoice +# +# This is sorted alphabetically by mach-* pathname. However, plat-* +# Kconfigs may be included either alphabetically (according to the +# plat- suffix) or along side the corresponding mach-* source. +# source "arch/arm/mach-aaec2000/Kconfig" source "arch/arm/mach-at91/Kconfig" -- cgit v0.10.2 From cfbc0683af235106e7dabe92003870b82ad6f0ba Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 11 Mar 2010 11:20:17 +1100 Subject: NFS: ensure bdi_unregister is called on mount failure. bdi_unregister is called by nfs_put_super which is only called by generic_shutdown_super if ->s_root is not NULL. So if we error out in a circumstance where we called nfs_bdi_register (i.e. server != NULL) but have not set s_root, then we need to call bdi_unregister explicitly in nfs_get_sb and various other *_get_sb() functions. Signed-off-by: NeilBrown Signed-off-by: Trond Myklebust diff --git a/fs/nfs/super.c b/fs/nfs/super.c index f1afee4..6baf9a3 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -2214,7 +2214,7 @@ static int nfs_get_sb(struct file_system_type *fs_type, } else { error = nfs_bdi_register(server); if (error) - goto error_splat_super; + goto error_splat_bdi; } if (!s->s_root) { @@ -2256,6 +2256,9 @@ out_err_nosb: error_splat_root: dput(mntroot); error_splat_super: + if (server && !s->s_root) + bdi_unregister(&server->backing_dev_info); +error_splat_bdi: deactivate_locked_super(s); goto out; } @@ -2326,7 +2329,7 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags, } else { error = nfs_bdi_register(server); if (error) - goto error_splat_super; + goto error_splat_bdi; } if (!s->s_root) { @@ -2363,6 +2366,9 @@ out_err_noserver: return error; error_splat_super: + if (server && !s->s_root) + bdi_unregister(&server->backing_dev_info); +error_splat_bdi: deactivate_locked_super(s); dprintk("<-- nfs_xdev_get_sb() = %d [splat]\n", error); return error; @@ -2578,7 +2584,7 @@ static int nfs4_remote_get_sb(struct file_system_type *fs_type, } else { error = nfs_bdi_register(server); if (error) - goto error_splat_super; + goto error_splat_bdi; } if (!s->s_root) { @@ -2616,6 +2622,9 @@ out_free: error_splat_root: dput(mntroot); error_splat_super: + if (server && !s->s_root) + bdi_unregister(&server->backing_dev_info); +error_splat_bdi: deactivate_locked_super(s); goto out; } @@ -2811,7 +2820,7 @@ static int nfs4_xdev_get_sb(struct file_system_type *fs_type, int flags, } else { error = nfs_bdi_register(server); if (error) - goto error_splat_super; + goto error_splat_bdi; } if (!s->s_root) { @@ -2847,6 +2856,9 @@ out_err_noserver: return error; error_splat_super: + if (server && !s->s_root) + bdi_unregister(&server->backing_dev_info); +error_splat_bdi: deactivate_locked_super(s); dprintk("<-- nfs4_xdev_get_sb() = %d [splat]\n", error); return error; @@ -2893,7 +2905,7 @@ static int nfs4_remote_referral_get_sb(struct file_system_type *fs_type, } else { error = nfs_bdi_register(server); if (error) - goto error_splat_super; + goto error_splat_bdi; } if (!s->s_root) { @@ -2929,6 +2941,9 @@ out_err_noserver: return error; error_splat_super: + if (server && !s->s_root) + bdi_unregister(&server->backing_dev_info); +error_splat_bdi: deactivate_locked_super(s); dprintk("<-- nfs4_referral_get_sb() = %d [splat]\n", error); return error; -- cgit v0.10.2 From 0d5e6f7ae8609b944c08e8a2f63f7d169c548134 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 15 Mar 2010 22:04:24 +0000 Subject: ARM: Fix RiscPC decompressor build errors arch/arm/boot/compressed/decompress.o: In function `do_decompress': decompress.c:(.text+0x26e8): undefined reference to `error' decompress.c:(.text+0x2760): undefined reference to `error' decompress.c:(.text+0x27d8): undefined reference to `error' decompress.c:(.text+0x2824): undefined reference to `error' decompress.c:(.text+0x28f0): undefined reference to `error' Signed-off-by: Russell King diff --git a/arch/arm/mach-rpc/include/mach/uncompress.h b/arch/arm/mach-rpc/include/mach/uncompress.h index d586236..8c9e2c7 100644 --- a/arch/arm/mach-rpc/include/mach/uncompress.h +++ b/arch/arm/mach-rpc/include/mach/uncompress.h @@ -109,8 +109,6 @@ static inline void flush(void) { } -static void error(char *x); - /* * Setup for decompression */ -- cgit v0.10.2 From 211a0d941b1924e667483f822a55e2cc694cd212 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 15 Mar 2010 15:23:30 -0700 Subject: e100: Fix ring parameter change handling regression. When the PCI pool changes were added to fix resume failures: commit 98468efddb101f8a29af974101c17ba513b07be1 e100: Use pci pool to work around GFP_ATOMIC order 5 memory allocation failu and commit 70abc8cb90e679d8519721e2761d8366a18212a6 e100: Fix broken cbs accounting due to missing memset. This introduced a problem that can happen if the TX ring size is increased. We need to size the PCI pool using cbs->max instead of the default cbs->count value. Signed-off-by: David S. Miller diff --git a/drivers/net/e100.c b/drivers/net/e100.c index a26ccab..b997e57 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -2858,7 +2858,7 @@ static int __devinit e100_probe(struct pci_dev *pdev, } nic->cbs_pool = pci_pool_create(netdev->name, nic->pdev, - nic->params.cbs.count * sizeof(struct cb), + nic->params.cbs.max * sizeof(struct cb), sizeof(u32), 0); DPRINTK(PROBE, INFO, "addr 0x%llx, irq %d, MAC addr %pM\n", -- cgit v0.10.2 From 664e87e47e086962a832f9a613a8fd4042a02ac1 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Sun, 14 Mar 2010 16:32:28 +0200 Subject: ARM: S3C2440: Fix s3c2440 cpufreq compilation post move. Fix compilation issue by moving s3c2440-cpufreq.c into mach-s3c2440 directory Signed-off-by: Vasily Khoruzhick Signed-off-by: Ben Dooks diff --git a/arch/arm/mach-s3c2440/s3c2440-cpufreq.c b/arch/arm/mach-s3c2440/s3c2440-cpufreq.c new file mode 100644 index 0000000..976002f --- /dev/null +++ b/arch/arm/mach-s3c2440/s3c2440-cpufreq.c @@ -0,0 +1,311 @@ +/* linux/arch/arm/plat-s3c24xx/s3c2440-cpufreq.c + * + * Copyright (c) 2006-2009 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * Vincent Sanders + * + * S3C2440/S3C2442 CPU Frequency scaling + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include + +#include +#include +#include + +static struct clk *xtal; +static struct clk *fclk; +static struct clk *hclk; +static struct clk *armclk; + +/* HDIV: 1, 2, 3, 4, 6, 8 */ + +static inline int within_khz(unsigned long a, unsigned long b) +{ + long diff = a - b; + + return (diff >= -1000 && diff <= 1000); +} + +/** + * s3c2440_cpufreq_calcdivs - calculate divider settings + * @cfg: The cpu frequency settings. + * + * Calcualte the divider values for the given frequency settings + * specified in @cfg. The values are stored in @cfg for later use + * by the relevant set routine if the request settings can be reached. + */ +int s3c2440_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg) +{ + unsigned int hdiv, pdiv; + unsigned long hclk, fclk, armclk; + unsigned long hclk_max; + + fclk = cfg->freq.fclk; + armclk = cfg->freq.armclk; + hclk_max = cfg->max.hclk; + + s3c_freq_dbg("%s: fclk is %lu, armclk %lu, max hclk %lu\n", + __func__, fclk, armclk, hclk_max); + + if (armclk > fclk) { + printk(KERN_WARNING "%s: armclk > fclk\n", __func__); + armclk = fclk; + } + + /* if we are in DVS, we need HCLK to be <= ARMCLK */ + if (armclk < fclk && armclk < hclk_max) + hclk_max = armclk; + + for (hdiv = 1; hdiv < 9; hdiv++) { + if (hdiv == 5 || hdiv == 7) + hdiv++; + + hclk = (fclk / hdiv); + if (hclk <= hclk_max || within_khz(hclk, hclk_max)) + break; + } + + s3c_freq_dbg("%s: hclk %lu, div %d\n", __func__, hclk, hdiv); + + if (hdiv > 8) + goto invalid; + + pdiv = (hclk > cfg->max.pclk) ? 2 : 1; + + if ((hclk / pdiv) > cfg->max.pclk) + pdiv++; + + s3c_freq_dbg("%s: pdiv %d\n", __func__, pdiv); + + if (pdiv > 2) + goto invalid; + + pdiv *= hdiv; + + /* calculate a valid armclk */ + + if (armclk < hclk) + armclk = hclk; + + /* if we're running armclk lower than fclk, this really means + * that the system should go into dvs mode, which means that + * armclk is connected to hclk. */ + if (armclk < fclk) { + cfg->divs.dvs = 1; + armclk = hclk; + } else + cfg->divs.dvs = 0; + + cfg->freq.armclk = armclk; + + /* store the result, and then return */ + + cfg->divs.h_divisor = hdiv; + cfg->divs.p_divisor = pdiv; + + return 0; + + invalid: + return -EINVAL; +} + +#define CAMDIVN_HCLK_HALF (S3C2440_CAMDIVN_HCLK3_HALF | \ + S3C2440_CAMDIVN_HCLK4_HALF) + +/** + * s3c2440_cpufreq_setdivs - set the cpu frequency divider settings + * @cfg: The cpu frequency settings. + * + * Set the divisors from the settings in @cfg, which where generated + * during the calculation phase by s3c2440_cpufreq_calcdivs(). + */ +static void s3c2440_cpufreq_setdivs(struct s3c_cpufreq_config *cfg) +{ + unsigned long clkdiv, camdiv; + + s3c_freq_dbg("%s: divsiors: h=%d, p=%d\n", __func__, + cfg->divs.h_divisor, cfg->divs.p_divisor); + + clkdiv = __raw_readl(S3C2410_CLKDIVN); + camdiv = __raw_readl(S3C2440_CAMDIVN); + + clkdiv &= ~(S3C2440_CLKDIVN_HDIVN_MASK | S3C2440_CLKDIVN_PDIVN); + camdiv &= ~CAMDIVN_HCLK_HALF; + + switch (cfg->divs.h_divisor) { + case 1: + clkdiv |= S3C2440_CLKDIVN_HDIVN_1; + break; + + case 2: + clkdiv |= S3C2440_CLKDIVN_HDIVN_2; + break; + + case 6: + camdiv |= S3C2440_CAMDIVN_HCLK3_HALF; + case 3: + clkdiv |= S3C2440_CLKDIVN_HDIVN_3_6; + break; + + case 8: + camdiv |= S3C2440_CAMDIVN_HCLK4_HALF; + case 4: + clkdiv |= S3C2440_CLKDIVN_HDIVN_4_8; + break; + + default: + BUG(); /* we don't expect to get here. */ + } + + if (cfg->divs.p_divisor != cfg->divs.h_divisor) + clkdiv |= S3C2440_CLKDIVN_PDIVN; + + /* todo - set pclk. */ + + /* Write the divisors first with hclk intentionally halved so that + * when we write clkdiv we will under-frequency instead of over. We + * then make a short delay and remove the hclk halving if necessary. + */ + + __raw_writel(camdiv | CAMDIVN_HCLK_HALF, S3C2440_CAMDIVN); + __raw_writel(clkdiv, S3C2410_CLKDIVN); + + ndelay(20); + __raw_writel(camdiv, S3C2440_CAMDIVN); + + clk_set_parent(armclk, cfg->divs.dvs ? hclk : fclk); +} + +static int run_freq_for(unsigned long max_hclk, unsigned long fclk, + int *divs, + struct cpufreq_frequency_table *table, + size_t table_size) +{ + unsigned long freq; + int index = 0; + int div; + + for (div = *divs; div > 0; div = *divs++) { + freq = fclk / div; + + if (freq > max_hclk && div != 1) + continue; + + freq /= 1000; /* table is in kHz */ + index = s3c_cpufreq_addfreq(table, index, table_size, freq); + if (index < 0) + break; + } + + return index; +} + +static int hclk_divs[] = { 1, 2, 3, 4, 6, 8, -1 }; + +static int s3c2440_cpufreq_calctable(struct s3c_cpufreq_config *cfg, + struct cpufreq_frequency_table *table, + size_t table_size) +{ + int ret; + + WARN_ON(cfg->info == NULL); + WARN_ON(cfg->board == NULL); + + ret = run_freq_for(cfg->info->max.hclk, + cfg->info->max.fclk, + hclk_divs, + table, table_size); + + s3c_freq_dbg("%s: returning %d\n", __func__, ret); + + return ret; +} + +struct s3c_cpufreq_info s3c2440_cpufreq_info = { + .max = { + .fclk = 400000000, + .hclk = 133333333, + .pclk = 66666666, + }, + + .locktime_m = 300, + .locktime_u = 300, + .locktime_bits = 16, + + .name = "s3c244x", + .calc_iotiming = s3c2410_iotiming_calc, + .set_iotiming = s3c2410_iotiming_set, + .get_iotiming = s3c2410_iotiming_get, + .set_fvco = s3c2410_set_fvco, + + .set_refresh = s3c2410_cpufreq_setrefresh, + .set_divs = s3c2440_cpufreq_setdivs, + .calc_divs = s3c2440_cpufreq_calcdivs, + .calc_freqtable = s3c2440_cpufreq_calctable, + + .resume_clocks = s3c244x_setup_clocks, + + .debug_io_show = s3c_cpufreq_debugfs_call(s3c2410_iotiming_debugfs), +}; + +static int s3c2440_cpufreq_add(struct sys_device *sysdev) +{ + xtal = s3c_cpufreq_clk_get(NULL, "xtal"); + hclk = s3c_cpufreq_clk_get(NULL, "hclk"); + fclk = s3c_cpufreq_clk_get(NULL, "fclk"); + armclk = s3c_cpufreq_clk_get(NULL, "armclk"); + + if (IS_ERR(xtal) || IS_ERR(hclk) || IS_ERR(fclk) || IS_ERR(armclk)) { + printk(KERN_ERR "%s: failed to get clocks\n", __func__); + return -ENOENT; + } + + return s3c_cpufreq_register(&s3c2440_cpufreq_info); +} + +static struct sysdev_driver s3c2440_cpufreq_driver = { + .add = s3c2440_cpufreq_add, +}; + +static int s3c2440_cpufreq_init(void) +{ + return sysdev_driver_register(&s3c2440_sysclass, + &s3c2440_cpufreq_driver); +} + +/* arch_initcall adds the clocks we need, so use subsys_initcall. */ +subsys_initcall(s3c2440_cpufreq_init); + +static struct sysdev_driver s3c2442_cpufreq_driver = { + .add = s3c2440_cpufreq_add, +}; + +static int s3c2442_cpufreq_init(void) +{ + return sysdev_driver_register(&s3c2442_sysclass, + &s3c2442_cpufreq_driver); +} + +subsys_initcall(s3c2442_cpufreq_init); diff --git a/arch/arm/plat-s3c24xx/s3c2440-cpufreq.c b/arch/arm/plat-s3c24xx/s3c2440-cpufreq.c deleted file mode 100644 index 976002f..0000000 --- a/arch/arm/plat-s3c24xx/s3c2440-cpufreq.c +++ /dev/null @@ -1,311 +0,0 @@ -/* linux/arch/arm/plat-s3c24xx/s3c2440-cpufreq.c - * - * Copyright (c) 2006-2009 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * Ben Dooks - * Vincent Sanders - * - * S3C2440/S3C2442 CPU Frequency scaling - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include - -#include -#include -#include - -static struct clk *xtal; -static struct clk *fclk; -static struct clk *hclk; -static struct clk *armclk; - -/* HDIV: 1, 2, 3, 4, 6, 8 */ - -static inline int within_khz(unsigned long a, unsigned long b) -{ - long diff = a - b; - - return (diff >= -1000 && diff <= 1000); -} - -/** - * s3c2440_cpufreq_calcdivs - calculate divider settings - * @cfg: The cpu frequency settings. - * - * Calcualte the divider values for the given frequency settings - * specified in @cfg. The values are stored in @cfg for later use - * by the relevant set routine if the request settings can be reached. - */ -int s3c2440_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg) -{ - unsigned int hdiv, pdiv; - unsigned long hclk, fclk, armclk; - unsigned long hclk_max; - - fclk = cfg->freq.fclk; - armclk = cfg->freq.armclk; - hclk_max = cfg->max.hclk; - - s3c_freq_dbg("%s: fclk is %lu, armclk %lu, max hclk %lu\n", - __func__, fclk, armclk, hclk_max); - - if (armclk > fclk) { - printk(KERN_WARNING "%s: armclk > fclk\n", __func__); - armclk = fclk; - } - - /* if we are in DVS, we need HCLK to be <= ARMCLK */ - if (armclk < fclk && armclk < hclk_max) - hclk_max = armclk; - - for (hdiv = 1; hdiv < 9; hdiv++) { - if (hdiv == 5 || hdiv == 7) - hdiv++; - - hclk = (fclk / hdiv); - if (hclk <= hclk_max || within_khz(hclk, hclk_max)) - break; - } - - s3c_freq_dbg("%s: hclk %lu, div %d\n", __func__, hclk, hdiv); - - if (hdiv > 8) - goto invalid; - - pdiv = (hclk > cfg->max.pclk) ? 2 : 1; - - if ((hclk / pdiv) > cfg->max.pclk) - pdiv++; - - s3c_freq_dbg("%s: pdiv %d\n", __func__, pdiv); - - if (pdiv > 2) - goto invalid; - - pdiv *= hdiv; - - /* calculate a valid armclk */ - - if (armclk < hclk) - armclk = hclk; - - /* if we're running armclk lower than fclk, this really means - * that the system should go into dvs mode, which means that - * armclk is connected to hclk. */ - if (armclk < fclk) { - cfg->divs.dvs = 1; - armclk = hclk; - } else - cfg->divs.dvs = 0; - - cfg->freq.armclk = armclk; - - /* store the result, and then return */ - - cfg->divs.h_divisor = hdiv; - cfg->divs.p_divisor = pdiv; - - return 0; - - invalid: - return -EINVAL; -} - -#define CAMDIVN_HCLK_HALF (S3C2440_CAMDIVN_HCLK3_HALF | \ - S3C2440_CAMDIVN_HCLK4_HALF) - -/** - * s3c2440_cpufreq_setdivs - set the cpu frequency divider settings - * @cfg: The cpu frequency settings. - * - * Set the divisors from the settings in @cfg, which where generated - * during the calculation phase by s3c2440_cpufreq_calcdivs(). - */ -static void s3c2440_cpufreq_setdivs(struct s3c_cpufreq_config *cfg) -{ - unsigned long clkdiv, camdiv; - - s3c_freq_dbg("%s: divsiors: h=%d, p=%d\n", __func__, - cfg->divs.h_divisor, cfg->divs.p_divisor); - - clkdiv = __raw_readl(S3C2410_CLKDIVN); - camdiv = __raw_readl(S3C2440_CAMDIVN); - - clkdiv &= ~(S3C2440_CLKDIVN_HDIVN_MASK | S3C2440_CLKDIVN_PDIVN); - camdiv &= ~CAMDIVN_HCLK_HALF; - - switch (cfg->divs.h_divisor) { - case 1: - clkdiv |= S3C2440_CLKDIVN_HDIVN_1; - break; - - case 2: - clkdiv |= S3C2440_CLKDIVN_HDIVN_2; - break; - - case 6: - camdiv |= S3C2440_CAMDIVN_HCLK3_HALF; - case 3: - clkdiv |= S3C2440_CLKDIVN_HDIVN_3_6; - break; - - case 8: - camdiv |= S3C2440_CAMDIVN_HCLK4_HALF; - case 4: - clkdiv |= S3C2440_CLKDIVN_HDIVN_4_8; - break; - - default: - BUG(); /* we don't expect to get here. */ - } - - if (cfg->divs.p_divisor != cfg->divs.h_divisor) - clkdiv |= S3C2440_CLKDIVN_PDIVN; - - /* todo - set pclk. */ - - /* Write the divisors first with hclk intentionally halved so that - * when we write clkdiv we will under-frequency instead of over. We - * then make a short delay and remove the hclk halving if necessary. - */ - - __raw_writel(camdiv | CAMDIVN_HCLK_HALF, S3C2440_CAMDIVN); - __raw_writel(clkdiv, S3C2410_CLKDIVN); - - ndelay(20); - __raw_writel(camdiv, S3C2440_CAMDIVN); - - clk_set_parent(armclk, cfg->divs.dvs ? hclk : fclk); -} - -static int run_freq_for(unsigned long max_hclk, unsigned long fclk, - int *divs, - struct cpufreq_frequency_table *table, - size_t table_size) -{ - unsigned long freq; - int index = 0; - int div; - - for (div = *divs; div > 0; div = *divs++) { - freq = fclk / div; - - if (freq > max_hclk && div != 1) - continue; - - freq /= 1000; /* table is in kHz */ - index = s3c_cpufreq_addfreq(table, index, table_size, freq); - if (index < 0) - break; - } - - return index; -} - -static int hclk_divs[] = { 1, 2, 3, 4, 6, 8, -1 }; - -static int s3c2440_cpufreq_calctable(struct s3c_cpufreq_config *cfg, - struct cpufreq_frequency_table *table, - size_t table_size) -{ - int ret; - - WARN_ON(cfg->info == NULL); - WARN_ON(cfg->board == NULL); - - ret = run_freq_for(cfg->info->max.hclk, - cfg->info->max.fclk, - hclk_divs, - table, table_size); - - s3c_freq_dbg("%s: returning %d\n", __func__, ret); - - return ret; -} - -struct s3c_cpufreq_info s3c2440_cpufreq_info = { - .max = { - .fclk = 400000000, - .hclk = 133333333, - .pclk = 66666666, - }, - - .locktime_m = 300, - .locktime_u = 300, - .locktime_bits = 16, - - .name = "s3c244x", - .calc_iotiming = s3c2410_iotiming_calc, - .set_iotiming = s3c2410_iotiming_set, - .get_iotiming = s3c2410_iotiming_get, - .set_fvco = s3c2410_set_fvco, - - .set_refresh = s3c2410_cpufreq_setrefresh, - .set_divs = s3c2440_cpufreq_setdivs, - .calc_divs = s3c2440_cpufreq_calcdivs, - .calc_freqtable = s3c2440_cpufreq_calctable, - - .resume_clocks = s3c244x_setup_clocks, - - .debug_io_show = s3c_cpufreq_debugfs_call(s3c2410_iotiming_debugfs), -}; - -static int s3c2440_cpufreq_add(struct sys_device *sysdev) -{ - xtal = s3c_cpufreq_clk_get(NULL, "xtal"); - hclk = s3c_cpufreq_clk_get(NULL, "hclk"); - fclk = s3c_cpufreq_clk_get(NULL, "fclk"); - armclk = s3c_cpufreq_clk_get(NULL, "armclk"); - - if (IS_ERR(xtal) || IS_ERR(hclk) || IS_ERR(fclk) || IS_ERR(armclk)) { - printk(KERN_ERR "%s: failed to get clocks\n", __func__); - return -ENOENT; - } - - return s3c_cpufreq_register(&s3c2440_cpufreq_info); -} - -static struct sysdev_driver s3c2440_cpufreq_driver = { - .add = s3c2440_cpufreq_add, -}; - -static int s3c2440_cpufreq_init(void) -{ - return sysdev_driver_register(&s3c2440_sysclass, - &s3c2440_cpufreq_driver); -} - -/* arch_initcall adds the clocks we need, so use subsys_initcall. */ -subsys_initcall(s3c2440_cpufreq_init); - -static struct sysdev_driver s3c2442_cpufreq_driver = { - .add = s3c2440_cpufreq_add, -}; - -static int s3c2442_cpufreq_init(void) -{ - return sysdev_driver_register(&s3c2442_sysclass, - &s3c2442_cpufreq_driver); -} - -subsys_initcall(s3c2442_cpufreq_init); -- cgit v0.10.2 From e79032aa75af76a14e2cdd973b199855e7761881 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Mon, 15 Mar 2010 16:27:08 +0200 Subject: ARM: SAMSUNG: Add suspend/resume support for S3C PWM driver Reset period_ns and duty_ns values in suspend handler to avoid skip of configuration if same values passed to pwm_config; Restore invertion bit in resume handler. Without this patch PWM works incorrectly after resume from suspend. Signed-off-by: Vasily Khoruzhick Signed-off-by: Ben Dooks diff --git a/arch/arm/plat-samsung/pwm.c b/arch/arm/plat-samsung/pwm.c index ef019f2..f2d1139 100644 --- a/arch/arm/plat-samsung/pwm.c +++ b/arch/arm/plat-samsung/pwm.c @@ -379,6 +379,39 @@ static int __devexit s3c_pwm_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM +static int s3c_pwm_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct pwm_device *pwm = platform_get_drvdata(pdev); + + /* No one preserve these values during suspend so reset them + * Otherwise driver leaves PWM unconfigured if same values + * passed to pwm_config + */ + pwm->period_ns = 0; + pwm->duty_ns = 0; + + return 0; +} + +static int s3c_pwm_resume(struct platform_device *pdev) +{ + struct pwm_device *pwm = platform_get_drvdata(pdev); + unsigned long tcon; + + /* Restore invertion */ + tcon = __raw_readl(S3C2410_TCON); + tcon |= pwm_tcon_invert(pwm); + __raw_writel(tcon, S3C2410_TCON); + + return 0; +} + +#else +#define s3c_pwm_suspend NULL +#define s3c_pwm_resume NULL +#endif + static struct platform_driver s3c_pwm_driver = { .driver = { .name = "s3c24xx-pwm", @@ -386,6 +419,8 @@ static struct platform_driver s3c_pwm_driver = { }, .probe = s3c_pwm_probe, .remove = __devexit_p(s3c_pwm_remove), + .suspend = s3c_pwm_suspend, + .resume = s3c_pwm_resume, }; static int __init pwm_init(void) -- cgit v0.10.2 From be5bce2bf5cfe021bc6bdff4d49fa18776bc293d Mon Sep 17 00:00:00 2001 From: Sekhar Nori Date: Tue, 9 Mar 2010 01:20:37 +0000 Subject: net: davinci emac: use dma_{map, unmap}_single API for cache coherency The davinci emac driver uses some ARM specific DMA APIs for cache coherency which have been removed from kernel with the 2.6.34 merge. Modify the driver to use the dma_{map, unmap}_single() APIs defined in dma-mapping.h Without this fix, the driver fails to compile on Linus's tree. Tested on DM365 and OMAP-L138 EVMs. Signed-off-by: Sekhar Nori Acked-by: Kevin Hilman Signed-off-by: David S. Miller diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index 32960b9..491e64c 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c @@ -29,10 +29,6 @@ * PHY layer usage */ -/** Pending Items in this driver: - * 1. Use Linux cache infrastcture for DMA'ed memory (dma_xxx functions) - */ - #include #include #include @@ -504,12 +500,6 @@ static unsigned long mdio_max_freq; /* Cache macros - Packet buffers would be from skb pool which is cached */ #define EMAC_VIRT_NOCACHE(addr) (addr) -#define EMAC_CACHE_INVALIDATE(addr, size) \ - dma_cache_maint((void *)addr, size, DMA_FROM_DEVICE) -#define EMAC_CACHE_WRITEBACK(addr, size) \ - dma_cache_maint((void *)addr, size, DMA_TO_DEVICE) -#define EMAC_CACHE_WRITEBACK_INVALIDATE(addr, size) \ - dma_cache_maint((void *)addr, size, DMA_BIDIRECTIONAL) /* DM644x does not have BD's in cached memory - so no cache functions */ #define BD_CACHE_INVALIDATE(addr, size) @@ -1235,6 +1225,10 @@ static void emac_txch_teardown(struct emac_priv *priv, u32 ch) if (1 == txch->queue_active) { curr_bd = txch->active_queue_head; while (curr_bd != NULL) { + dma_unmap_single(emac_dev, curr_bd->buff_ptr, + curr_bd->off_b_len & EMAC_RX_BD_BUF_SIZE, + DMA_TO_DEVICE); + emac_net_tx_complete(priv, (void __force *) &curr_bd->buf_token, 1, ch); if (curr_bd != txch->active_queue_tail) @@ -1327,6 +1321,11 @@ static int emac_tx_bdproc(struct emac_priv *priv, u32 ch, u32 budget) txch->queue_active = 0; /* end of queue */ } } + + dma_unmap_single(emac_dev, curr_bd->buff_ptr, + curr_bd->off_b_len & EMAC_RX_BD_BUF_SIZE, + DMA_TO_DEVICE); + *tx_complete_ptr = (u32) curr_bd->buf_token; ++tx_complete_ptr; ++tx_complete_cnt; @@ -1387,8 +1386,8 @@ static int emac_send(struct emac_priv *priv, struct emac_netpktobj *pkt, u32 ch) txch->bd_pool_head = curr_bd->next; curr_bd->buf_token = buf_list->buf_token; - /* FIXME buff_ptr = dma_map_single(... data_ptr ...) */ - curr_bd->buff_ptr = virt_to_phys(buf_list->data_ptr); + curr_bd->buff_ptr = dma_map_single(&priv->ndev->dev, buf_list->data_ptr, + buf_list->length, DMA_TO_DEVICE); curr_bd->off_b_len = buf_list->length; curr_bd->h_next = 0; curr_bd->next = NULL; @@ -1468,7 +1467,6 @@ static int emac_dev_xmit(struct sk_buff *skb, struct net_device *ndev) tx_buf.length = skb->len; tx_buf.buf_token = (void *)skb; tx_buf.data_ptr = skb->data; - EMAC_CACHE_WRITEBACK((unsigned long)skb->data, skb->len); ndev->trans_start = jiffies; ret_code = emac_send(priv, &tx_packet, EMAC_DEF_TX_CH); if (unlikely(ret_code != 0)) { @@ -1543,7 +1541,6 @@ static void *emac_net_alloc_rx_buf(struct emac_priv *priv, int buf_size, p_skb->dev = ndev; skb_reserve(p_skb, NET_IP_ALIGN); *data_token = (void *) p_skb; - EMAC_CACHE_WRITEBACK_INVALIDATE((unsigned long)p_skb->data, buf_size); return p_skb->data; } @@ -1612,8 +1609,8 @@ static int emac_init_rxch(struct emac_priv *priv, u32 ch, char *param) /* populate the hardware descriptor */ curr_bd->h_next = emac_virt_to_phys(rxch->active_queue_head, priv); - /* FIXME buff_ptr = dma_map_single(... data_ptr ...) */ - curr_bd->buff_ptr = virt_to_phys(curr_bd->data_ptr); + curr_bd->buff_ptr = dma_map_single(emac_dev, curr_bd->data_ptr, + rxch->buf_size, DMA_FROM_DEVICE); curr_bd->off_b_len = rxch->buf_size; curr_bd->mode = EMAC_CPPI_OWNERSHIP_BIT; @@ -1697,6 +1694,12 @@ static void emac_cleanup_rxch(struct emac_priv *priv, u32 ch) curr_bd = rxch->active_queue_head; while (curr_bd) { if (curr_bd->buf_token) { + dma_unmap_single(&priv->ndev->dev, + curr_bd->buff_ptr, + curr_bd->off_b_len + & EMAC_RX_BD_BUF_SIZE, + DMA_FROM_DEVICE); + dev_kfree_skb_any((struct sk_buff *)\ curr_bd->buf_token); } @@ -1871,8 +1874,8 @@ static void emac_addbd_to_rx_queue(struct emac_priv *priv, u32 ch, /* populate the hardware descriptor */ curr_bd->h_next = 0; - /* FIXME buff_ptr = dma_map_single(... buffer ...) */ - curr_bd->buff_ptr = virt_to_phys(buffer); + curr_bd->buff_ptr = dma_map_single(&priv->ndev->dev, buffer, + rxch->buf_size, DMA_FROM_DEVICE); curr_bd->off_b_len = rxch->buf_size; curr_bd->mode = EMAC_CPPI_OWNERSHIP_BIT; curr_bd->next = NULL; @@ -1927,7 +1930,6 @@ static int emac_net_rx_cb(struct emac_priv *priv, p_skb = (struct sk_buff *)net_pkt_list->pkt_token; /* set length of packet */ skb_put(p_skb, net_pkt_list->pkt_length); - EMAC_CACHE_INVALIDATE((unsigned long)p_skb->data, p_skb->len); p_skb->protocol = eth_type_trans(p_skb, priv->ndev); netif_receive_skb(p_skb); priv->net_dev_stats.rx_bytes += net_pkt_list->pkt_length; @@ -1990,6 +1992,11 @@ static int emac_rx_bdproc(struct emac_priv *priv, u32 ch, u32 budget) rx_buf_obj->data_ptr = (char *)curr_bd->data_ptr; rx_buf_obj->length = curr_bd->off_b_len & EMAC_RX_BD_BUF_SIZE; rx_buf_obj->buf_token = curr_bd->buf_token; + + dma_unmap_single(&priv->ndev->dev, curr_bd->buff_ptr, + curr_bd->off_b_len & EMAC_RX_BD_BUF_SIZE, + DMA_FROM_DEVICE); + curr_pkt->pkt_token = curr_pkt->buf_list->buf_token; curr_pkt->num_bufs = 1; curr_pkt->pkt_length = -- cgit v0.10.2 From d4fdcd923daf9d03d2e1b956d66f05c3f2ca4c43 Mon Sep 17 00:00:00 2001 From: "chaithrika@ti.com" Date: Wed, 10 Mar 2010 22:37:56 +0000 Subject: TI DaVinci EMAC: Convert to dev_pm_ops Migrate from the legacy PM hooks to use dev_pm_ops structure. Signed-off-by: Chaithrika U S Acked-by: Kevin Hilman Signed-off-by: David S. Miller diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index 491e64c..5c4f5b1 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c @@ -2827,31 +2827,37 @@ static int __devexit davinci_emac_remove(struct platform_device *pdev) return 0; } -static -int davinci_emac_suspend(struct platform_device *pdev, pm_message_t state) +static int davinci_emac_suspend(struct device *dev) { - struct net_device *dev = platform_get_drvdata(pdev); + struct platform_device *pdev = to_platform_device(dev); + struct net_device *ndev = platform_get_drvdata(pdev); - if (netif_running(dev)) - emac_dev_stop(dev); + if (netif_running(ndev)) + emac_dev_stop(ndev); clk_disable(emac_clk); return 0; } -static int davinci_emac_resume(struct platform_device *pdev) +static int davinci_emac_resume(struct device *dev) { - struct net_device *dev = platform_get_drvdata(pdev); + struct platform_device *pdev = to_platform_device(dev); + struct net_device *ndev = platform_get_drvdata(pdev); clk_enable(emac_clk); - if (netif_running(dev)) - emac_dev_open(dev); + if (netif_running(ndev)) + emac_dev_open(ndev); return 0; } +static const struct dev_pm_ops davinci_emac_pm_ops = { + .suspend = davinci_emac_suspend, + .resume = davinci_emac_resume, +}; + /** * davinci_emac_driver: EMAC platform driver structure */ @@ -2859,11 +2865,10 @@ static struct platform_driver davinci_emac_driver = { .driver = { .name = "davinci_emac", .owner = THIS_MODULE, + .pm = &davinci_emac_pm_ops, }, .probe = davinci_emac_probe, .remove = __devexit_p(davinci_emac_remove), - .suspend = davinci_emac_suspend, - .resume = davinci_emac_resume, }; /** -- cgit v0.10.2 From d4a2ac3e802d9f598453a7854d0fdf67371ac2dd Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Thu, 11 Mar 2010 01:35:59 +0000 Subject: be2net: fix mccq create for big endian architectures The request to create an mccq was being dispatched without doing a byte swap of num_pages. This byte swap is necessary for Big Endian systems like PPC. Not having this fix leads mccq create to fail on BE ASICs running newer version of firmware, thereby causing driver initialization failure. Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index c592153..50e6259 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -673,7 +673,7 @@ int be_cmd_mccq_create(struct be_adapter *adapter, be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, OPCODE_COMMON_MCC_CREATE, sizeof(*req)); - req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size); + req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size)); AMAP_SET_BITS(struct amap_mcc_context, valid, ctxt, 1); AMAP_SET_BITS(struct amap_mcc_context, ring_size, ctxt, -- cgit v0.10.2 From 2d99cf16f42b1979a2c498bb6d09498dbd689978 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 9 Mar 2010 06:55:00 +0000 Subject: bnx2x: use smp_mb() to keep ordering of read write operations Since we want to keep ordering of write to fp->bd_tx_cons and netif_tx_queue_stopped(txq), what is read of txq->state, we have to use general memory barrier. Signed-off-by: Stanislaw Gruszka Signed-off-by: David S. Miller diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index ed785a3..9fc0f6a 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -963,7 +963,7 @@ static int bnx2x_tx_int(struct bnx2x_fastpath *fp) * start_xmit() will miss it and cause the queue to be stopped * forever. */ - smp_wmb(); + smp_mb(); /* TBD need a thresh? */ if (unlikely(netif_tx_queue_stopped(txq))) { -- cgit v0.10.2 From 0efc22f3afa5d8f070a33fea06162d7d9d518e38 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 9 Mar 2010 06:55:01 +0000 Subject: bnx2x: remove not necessary compiler barrier Access to fp->tx_bd_prod is protected by __netif_tx_lock, so we do not need any barrier for that. Update of fp->tx_bd_cons in bnx2x_tx_int() is not protected by lock, but barrier() nor smb_mb() in bnx2x_tx_avail() not guarantee we will see values that is written on other cpu. Ordering issues between netif_tx_stop_queue(), netif_tx_queue_stopped(), fp->tx_bd_cons = bd_cons and bnx2x_tx_avail() are already handled by smp_mb() in bnx2x_tx_int() and bnx2x_start_xmit(). Signed-off-by: Stanislaw Gruszka Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 9fc0f6a..ae62b67 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -893,7 +893,6 @@ static inline u16 bnx2x_tx_avail(struct bnx2x_fastpath *fp) u16 prod; u16 cons; - barrier(); /* Tell compiler that prod and cons can change */ prod = fp->tx_bd_prod; cons = fp->tx_bd_cons; -- cgit v0.10.2 From 9baddeb8c6c7faa7da8706ad629f09ca221850c1 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 9 Mar 2010 06:55:02 +0000 Subject: bnx2x: change smp_mb() comment to conform the true Access to fp->tx_bp_prod is protected by __netif_tx_lock, smp_mb() is not needed for that. Signed-off-by: Stanislaw Gruszka Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index ae62b67..6c042a7 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -11428,9 +11428,12 @@ static netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) if (unlikely(bnx2x_tx_avail(fp) < MAX_SKB_FRAGS + 3)) { netif_tx_stop_queue(txq); - /* We want bnx2x_tx_int to "see" the updated tx_bd_prod - if we put Tx into XOFF state. */ + + /* paired memory barrier is in bnx2x_tx_int(), we have to keep + * ordering of set_bit() in netif_tx_stop_queue() and read of + * fp->bd_tx_cons */ smp_mb(); + fp->eth_q_stats.driver_xoff++; if (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3) netif_tx_wake_queue(txq); -- cgit v0.10.2 From dec9951b8ad86c591af7b452966bf48b307a4010 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Thu, 11 Mar 2010 12:07:22 +0000 Subject: isdn: misplaced parenthesis in pof_handle_data() The parenthesis was misplaced. Signed-off-by: Roel Kluin Cc: Karsten Keil Signed-off-by: Andrew Morton Signed-off-by: David S. Miller diff --git a/drivers/isdn/hysdn/hysdn_boot.c b/drivers/isdn/hysdn/hysdn_boot.c index be787e1..4f541ef 100644 --- a/drivers/isdn/hysdn/hysdn_boot.c +++ b/drivers/isdn/hysdn/hysdn_boot.c @@ -143,7 +143,7 @@ pof_handle_data(hysdn_card * card, int datlen) (boot->pof_recid == TAG_CABSDATA) ? "CABSDATA" : "ABSDATA", datlen, boot->pof_recoffset); - if ((boot->last_error = card->writebootseq(card, boot->buf.BootBuf, datlen) < 0)) + if ((boot->last_error = card->writebootseq(card, boot->buf.BootBuf, datlen)) < 0) return (boot->last_error); /* error writing data */ if (boot->pof_recoffset + datlen >= boot->pof_reclen) -- cgit v0.10.2 From 8b4017d8c191822f1c93744e7876c9020e6209aa Mon Sep 17 00:00:00 2001 From: Ian Munsie Date: Thu, 11 Mar 2010 12:07:24 +0000 Subject: i4l: silence compiler warnings for array access in Eicon DIVA ISDN driver When compiling this driver, the compiler throws the following warnings: drivers/isdn/hardware/eicon/message.c:8426: warning: array subscript is above array bounds drivers/isdn/hardware/eicon/message.c:8427: warning: array subscript is above array bounds drivers/isdn/hardware/eicon/message.c:8434: warning: array subscript is above array bounds drivers/isdn/hardware/eicon/message.c:8435: warning: array subscript is above array bounds drivers/isdn/hardware/eicon/message.c:8436: warning: array subscript is above array bounds drivers/isdn/hardware/eicon/message.c:8447: warning: array subscript is above array bounds This arises from the particular semantics the driver is using to write to the nlc array (static byte[256]). The array has a length in byte 0 followed by a T30_INFO struct starting at byte 1. The T30_INFO struct has a number of variable length strings after the station_id entry, which cannot be explicitly defined in the struct and the driver accesses them with an array index to station_id beyond the length of station_id. This patch merely changes the semantics that the driver uses to access the entries after the station_id entry to use the original 256 byte nlc array taking the offset and length of the station_id entry to calculate where to write in the array, thereby silencing the warning. Signed-off-by: Ian Munsie Cc: Armin Schindler Cc: Karsten Keil Cc: Stoyan Gaydarov Signed-off-by: Andrew Morton Signed-off-by: David S. Miller diff --git a/drivers/isdn/hardware/eicon/message.c b/drivers/isdn/hardware/eicon/message.c index ae89fb8..4bd469b 100644 --- a/drivers/isdn/hardware/eicon/message.c +++ b/drivers/isdn/hardware/eicon/message.c @@ -8423,17 +8423,17 @@ static word add_b23(PLCI *plci, API_PARSE *bp) pos = 0; else { - ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ' '; - ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ' '; + nlc[1 + offsetof(T30_INFO, station_id) + 20 + pos++] = ' '; + nlc[1 + offsetof(T30_INFO, station_id) + 20 + pos++] = ' '; len = (byte)b3_config_parms[2].length; if (len > 20) len = 20; if (CAPI_MAX_DATE_TIME_LENGTH + 2 + len + 2 + b3_config_parms[3].length <= CAPI_MAX_HEAD_LINE_SPACE) { for (i = 0; i < len; i++) - ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ((byte *)b3_config_parms[2].info)[1+i]; - ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ' '; - ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ' '; + nlc[1 + offsetof(T30_INFO, station_id) + 20 + pos++] = ((byte *)b3_config_parms[2].info)[1+i]; + nlc[1 + offsetof(T30_INFO, station_id) + 20 + pos++] = ' '; + nlc[1 + offsetof(T30_INFO, station_id) + 20 + pos++] = ' '; } } } @@ -8444,9 +8444,8 @@ static word add_b23(PLCI *plci, API_PARSE *bp) ((T30_INFO *)&nlc[1])->head_line_len = (byte)(pos + len); nlc[0] += (byte)(pos + len); for (i = 0; i < len; i++) - ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ((byte *)b3_config_parms[3].info)[1+i]; - } - else + nlc[1 + offsetof(T30_INFO, station_id) + 20 + pos++] = ((byte *)b3_config_parms[3].info)[1+i]; + } else ((T30_INFO *)&nlc[1])->head_line_len = 0; plci->nsf_control_bits = 0; -- cgit v0.10.2 From 255f5c327ec3a1d77fe54ef5773ef5eaf7c35a3e Mon Sep 17 00:00:00 2001 From: Ian Munsie Date: Thu, 11 Mar 2010 12:07:25 +0000 Subject: i4l: change magic numbers in Eicon DIVA ISDN driver to symbolic names Replace references to the '20' magic number found throughout the Eicon ISDN driver for the length of the station_id field in the T30_INFO struct with the T30_MAX_STATION_ID_LENGTH symbolic constant. Signed-off-by: Ian Munsie Cc: Armin Schindler Cc: Karsten Keil Cc: Stoyan Gaydarov Signed-off-by: Andrew Morton Signed-off-by: David S. Miller diff --git a/drivers/isdn/hardware/eicon/message.c b/drivers/isdn/hardware/eicon/message.c index 4bd469b..341ef17 100644 --- a/drivers/isdn/hardware/eicon/message.c +++ b/drivers/isdn/hardware/eicon/message.c @@ -2754,7 +2754,7 @@ static byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a, for (i = 0; i < w; i++) ((T30_INFO *)(plci->fax_connect_info_buffer))->station_id[i] = fax_parms[4].info[1+i]; ((T30_INFO *)(plci->fax_connect_info_buffer))->head_line_len = 0; - len = offsetof(T30_INFO, station_id) + 20; + len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH; w = fax_parms[5].length; if (w > 20) w = 20; @@ -2892,7 +2892,7 @@ static byte connect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a, && (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_ENABLE_NSF) && (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_NEGOTIATE_RESP)) { - len = offsetof(T30_INFO, station_id) + 20; + len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH; if (plci->fax_connect_info_length < len) { ((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = 0; @@ -3802,7 +3802,7 @@ static byte manufacturer_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a, break; } ncpi = &m_parms[1]; - len = offsetof(T30_INFO, station_id) + 20; + len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH; if (plci->fax_connect_info_length < len) { ((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = 0; @@ -6830,7 +6830,7 @@ static void nl_ind(PLCI *plci) if(((T30_INFO *)plci->NL.RBuffer->P)->station_id_len) { plci->ncpi_buffer[len] = 20; - for (i = 0; i < 20; i++) + for (i = 0; i < T30_MAX_STATION_ID_LENGTH; i++) plci->ncpi_buffer[++len] = ((T30_INFO *)plci->NL.RBuffer->P)->station_id[i]; } if (((plci->NL.Ind & 0x0f) == N_DISC) || ((plci->NL.Ind & 0x0f) == N_DISC_ACK)) @@ -6844,7 +6844,7 @@ static void nl_ind(PLCI *plci) if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[plci->appl->Id-1]) & ((1L << PRIVATE_FAX_SUB_SEP_PWD) | (1L << PRIVATE_FAX_NONSTANDARD))) { - i = offsetof(T30_INFO, station_id) + 20 + ((T30_INFO *)plci->NL.RBuffer->P)->head_line_len; + i = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + ((T30_INFO *)plci->NL.RBuffer->P)->head_line_len; while (i < plci->NL.RBuffer->length) plci->ncpi_buffer[++len] = plci->NL.RBuffer->P[i++]; } @@ -8400,7 +8400,7 @@ static word add_b23(PLCI *plci, API_PARSE *bp) } } /* copy station id to NLC */ - for(i=0; i<20; i++) + for(i=0; i < T30_MAX_STATION_ID_LENGTH; i++) { if(istation_id[i] = ' '; } } - ((T30_INFO *)&nlc[1])->station_id_len = 20; + ((T30_INFO *)&nlc[1])->station_id_len = T30_MAX_STATION_ID_LENGTH; /* copy head line to NLC */ if(b3_config_parms[3].length) { - pos = (byte)(fax_head_line_time (&(((T30_INFO *)&nlc[1])->station_id[20]))); + pos = (byte)(fax_head_line_time (&(((T30_INFO *)&nlc[1])->station_id[T30_MAX_STATION_ID_LENGTH]))); if (pos != 0) { if (CAPI_MAX_DATE_TIME_LENGTH + 2 + b3_config_parms[3].length > CAPI_MAX_HEAD_LINE_SPACE) pos = 0; else { - nlc[1 + offsetof(T30_INFO, station_id) + 20 + pos++] = ' '; - nlc[1 + offsetof(T30_INFO, station_id) + 20 + pos++] = ' '; + nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' '; + nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' '; len = (byte)b3_config_parms[2].length; if (len > 20) len = 20; if (CAPI_MAX_DATE_TIME_LENGTH + 2 + len + 2 + b3_config_parms[3].length <= CAPI_MAX_HEAD_LINE_SPACE) { for (i = 0; i < len; i++) - nlc[1 + offsetof(T30_INFO, station_id) + 20 + pos++] = ((byte *)b3_config_parms[2].info)[1+i]; - nlc[1 + offsetof(T30_INFO, station_id) + 20 + pos++] = ' '; - nlc[1 + offsetof(T30_INFO, station_id) + 20 + pos++] = ' '; + nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ((byte *)b3_config_parms[2].info)[1+i]; + nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' '; + nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' '; } } } @@ -8444,7 +8444,7 @@ static word add_b23(PLCI *plci, API_PARSE *bp) ((T30_INFO *)&nlc[1])->head_line_len = (byte)(pos + len); nlc[0] += (byte)(pos + len); for (i = 0; i < len; i++) - nlc[1 + offsetof(T30_INFO, station_id) + 20 + pos++] = ((byte *)b3_config_parms[3].info)[1+i]; + nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ((byte *)b3_config_parms[3].info)[1+i]; } else ((T30_INFO *)&nlc[1])->head_line_len = 0; @@ -8472,7 +8472,7 @@ static word add_b23(PLCI *plci, API_PARSE *bp) fax_control_bits |= T30_CONTROL_BIT_ACCEPT_SEL_POLLING; } len = nlc[0]; - pos = offsetof(T30_INFO, station_id) + 20; + pos = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH; if (pos < plci->fax_connect_info_length) { for (i = 1 + plci->fax_connect_info_buffer[pos]; i != 0; i--) @@ -8524,7 +8524,7 @@ static word add_b23(PLCI *plci, API_PARSE *bp) } PUT_WORD(&(((T30_INFO *)&nlc[1])->control_bits_low), fax_control_bits); - len = offsetof(T30_INFO, station_id) + 20; + len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH; for (i = 0; i < len; i++) plci->fax_connect_info_buffer[i] = nlc[1+i]; ((T30_INFO *) plci->fax_connect_info_buffer)->head_line_len = 0; -- cgit v0.10.2 From 876e956f207373f974f2808c36aabcd4e32c9ee4 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 9 Mar 2010 11:14:11 +0000 Subject: drivers/net: drop redundant memset The region set by the call to memset is immediately overwritten by the subsequent call to memcpy. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ expression e1,e2,e3,e4; @@ - memset(e1,e2,e3); memcpy(e1,e4,e3); // Signed-off-by: Julia Lawall Signed-off-by: David S. Miller diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index df70657..2eb7f8a 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -5819,10 +5819,8 @@ static void s2io_vpd_read(struct s2io_nic *nic) } } - if ((!fail) && (vpd_data[1] < VPD_STRING_LEN)) { - memset(nic->product_name, 0, vpd_data[1]); + if ((!fail) && (vpd_data[1] < VPD_STRING_LEN)) memcpy(nic->product_name, &vpd_data[3], vpd_data[1]); - } kfree(vpd_data); swstats->mem_freed += 256; } -- cgit v0.10.2 From 65e543f12cb7f98cb041a759a21685569eec8695 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 15 Mar 2010 22:57:18 +0000 Subject: ARM: SAMSUNG: Fix build error from stale define in The decleration of error() as static in the platform specific uncompress code in arch/arm/plat-samsung/include/plat/uncomopress.h causes the build of the uncompressor to break. Remove it, as it is no longer needed. arch/arm/boot/compressed/decompress.o: In function `gunzip': /var/tmp/kernel-orig/arch/arm/boot/compressed/../../../../lib/decompress_inflate.c:67: undefined reference to `error' /var/tmp/kernel-orig/arch/arm/boot/compressed/../../../../lib/decompress_inflate.c:73: undefined reference to `error' /var/tmp/kernel-orig/arch/arm/boot/compressed/../../../../lib/decompress_inflate.c:80: undefined reference to `error' /var/tmp/kernel-orig/arch/arm/boot/compressed/../../../../lib/decompress_inflate.c:95: undefined reference to `error' /var/tmp/kernel-orig/arch/arm/boot/compressed/../../../../lib/decompress_inflate.c:152: undefined reference to `error' Signed-off-by: Ben Dooks diff --git a/arch/arm/plat-samsung/include/plat/uncompress.h b/arch/arm/plat-samsung/include/plat/uncompress.h index e87ce8f..7d6ed72 100644 --- a/arch/arm/plat-samsung/include/plat/uncompress.h +++ b/arch/arm/plat-samsung/include/plat/uncompress.h @@ -140,8 +140,6 @@ static void arch_decomp_error(const char *x) #define arch_error arch_decomp_error #endif -static void error(char *err); - #ifdef CONFIG_S3C_BOOT_UART_FORCE_FIFO static inline void arch_enable_uart_fifo(void) { -- cgit v0.10.2 From f28f9e43b3d81d1e69da0ebf77c8a6780cb5e0c8 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 12 Mar 2010 19:23:27 +0000 Subject: timestamping: fix example build Fix Makefiles so that Documentation/networking/timestamping/timestamping.c will build when using the CONFIG_BUILD_DOCSRC kconfig option. (timestamping.c does not build currently with its simple Makefile.) Also fix printf format warnings. Signed-off-by: Randy Dunlap Cc: Patrick Ohly Signed-off-by: David S. Miller diff --git a/Documentation/networking/Makefile b/Documentation/networking/Makefile index 6d8af1a..5aba7a3 100644 --- a/Documentation/networking/Makefile +++ b/Documentation/networking/Makefile @@ -6,3 +6,5 @@ hostprogs-y := ifenslave # Tell kbuild to always build the programs always := $(hostprogs-y) + +obj-m := timestamping/ diff --git a/Documentation/networking/timestamping/Makefile b/Documentation/networking/timestamping/Makefile index 2a1489f..e799734 100644 --- a/Documentation/networking/timestamping/Makefile +++ b/Documentation/networking/timestamping/Makefile @@ -1,6 +1,13 @@ -CPPFLAGS = -I../../../include +# kbuild trick to avoid linker error. Can be omitted if a module is built. +obj- := dummy.o -timestamping: timestamping.c +# List of programs to build +hostprogs-y := timestamping + +# Tell kbuild to always build the programs +always := $(hostprogs-y) + +HOSTCFLAGS_timestamping.o += -I$(objtree)/usr/include clean: rm -f timestamping diff --git a/Documentation/networking/timestamping/timestamping.c b/Documentation/networking/timestamping/timestamping.c index a7936fe..7b81d16 100644 --- a/Documentation/networking/timestamping/timestamping.c +++ b/Documentation/networking/timestamping/timestamping.c @@ -41,9 +41,9 @@ #include #include -#include "asm/types.h" -#include "linux/net_tstamp.h" -#include "linux/errqueue.h" +#include +#include +#include #ifndef SO_TIMESTAMPING # define SO_TIMESTAMPING 37 @@ -164,7 +164,7 @@ static void printpacket(struct msghdr *msg, int res, gettimeofday(&now, 0); - printf("%ld.%06ld: received %s data, %d bytes from %s, %d bytes control messages\n", + printf("%ld.%06ld: received %s data, %d bytes from %s, %zu bytes control messages\n", (long)now.tv_sec, (long)now.tv_usec, (recvmsg_flags & MSG_ERRQUEUE) ? "error" : "regular", res, @@ -173,7 +173,7 @@ static void printpacket(struct msghdr *msg, int res, for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) { - printf(" cmsg len %d: ", cmsg->cmsg_len); + printf(" cmsg len %zu: ", cmsg->cmsg_len); switch (cmsg->cmsg_level) { case SOL_SOCKET: printf("SOL_SOCKET "); -- cgit v0.10.2 From a1ca14ac54675d3bf48d442b5a7b9eba133f1888 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Thu, 11 Mar 2010 12:07:49 +0000 Subject: phonet: use for_each_set_bit() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace open-coded loop with for_each_set_bit(). Signed-off-by: Akinobu Mita Cc: "David S. Miller" Signed-off-by: Andrew Morton Acked-by: Rémi Denis-Courmont Signed-off-by: David S. Miller diff --git a/net/phonet/pn_dev.c b/net/phonet/pn_dev.c index c597cc5..5c6ae0c 100644 --- a/net/phonet/pn_dev.c +++ b/net/phonet/pn_dev.c @@ -107,8 +107,7 @@ static void phonet_device_destroy(struct net_device *dev) if (pnd) { u8 addr; - for (addr = find_first_bit(pnd->addrs, 64); addr < 64; - addr = find_next_bit(pnd->addrs, 64, 1+addr)) + for_each_set_bit(addr, pnd->addrs, 64) phonet_address_notify(RTM_DELADDR, dev, addr); kfree(pnd); } diff --git a/net/phonet/pn_netlink.c b/net/phonet/pn_netlink.c index 2e6c7eb..fe2e708 100644 --- a/net/phonet/pn_netlink.c +++ b/net/phonet/pn_netlink.c @@ -141,8 +141,7 @@ static int getaddr_dumpit(struct sk_buff *skb, struct netlink_callback *cb) continue; addr_idx = 0; - for (addr = find_first_bit(pnd->addrs, 64); addr < 64; - addr = find_next_bit(pnd->addrs, 64, 1+addr)) { + for_each_set_bit(addr, pnd->addrs, 64) { if (addr_idx++ < addr_start_idx) continue; -- cgit v0.10.2 From d287d66ee460b8d90b9ac840dd37f524a289bf97 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Thu, 11 Mar 2010 12:07:50 +0000 Subject: atm: use for_each_set_bit() Replace open-coded loop with for_each_set_bit(). Signed-off-by: Akinobu Mita Cc: Chas Williams Signed-off-by: Andrew Morton Signed-off-by: David S. Miller diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c index 7fe7c32..23d9505 100644 --- a/drivers/atm/lanai.c +++ b/drivers/atm/lanai.c @@ -306,11 +306,10 @@ static void vci_bitfield_iterate(struct lanai_dev *lanai, const unsigned long *lp, void (*func)(struct lanai_dev *,vci_t vci)) { - vci_t vci = find_first_bit(lp, NUM_VCI); - while (vci < NUM_VCI) { + vci_t vci; + + for_each_set_bit(vci, lp, NUM_VCI) func(lanai, vci); - vci = find_next_bit(lp, NUM_VCI, vci + 1); - } } /* -------------------- BUFFER UTILITIES: */ -- cgit v0.10.2 From 6329da5f258ae752d1f33b549bae4f8a20b6871a Mon Sep 17 00:00:00 2001 From: Christoph Egger Date: Thu, 11 Mar 2010 12:07:52 +0000 Subject: obsolete config in kernel source: USE_INTERNAL_TIMER CONFIG_USE_INTERNAL_TIMER seems to be the remainings of some experiment. It is explicitely #undef-ed as not working, only referenced from one source file and rather aged. Hereby cleaning it from the kernel tree. Signed-off-by: Christoph Egger Acked-by: Roel Kluin Cc: "David S. Miller" Signed-off-by: Andrew Morton Signed-off-by: David S. Miller diff --git a/drivers/net/irda/w83977af_ir.c b/drivers/net/irda/w83977af_ir.c index 551810f..980625f 100644 --- a/drivers/net/irda/w83977af_ir.c +++ b/drivers/net/irda/w83977af_ir.c @@ -65,7 +65,6 @@ #undef CONFIG_NETWINDER_TX_DMA_PROBLEMS /* Not needed */ #define CONFIG_NETWINDER_RX_DMA_PROBLEMS /* Must have this one! */ #endif -#undef CONFIG_USE_INTERNAL_TIMER /* Just cannot make that timer work */ #define CONFIG_USE_W977_PNP /* Currently needed */ #define PIO_MAX_SPEED 115200 @@ -533,25 +532,6 @@ static netdev_tx_t w83977af_hard_xmit(struct sk_buff *skb, self->tx_buff.len = skb->len; mtt = irda_get_mtt(skb); -#ifdef CONFIG_USE_INTERNAL_TIMER - if (mtt > 50) { - /* Adjust for timer resolution */ - mtt /= 1000+1; - - /* Setup timer */ - switch_bank(iobase, SET4); - outb(mtt & 0xff, iobase+TMRL); - outb((mtt >> 8) & 0x0f, iobase+TMRH); - - /* Start timer */ - outb(IR_MSL_EN_TMR, iobase+IR_MSL); - self->io.direction = IO_XMIT; - - /* Enable timer interrupt */ - switch_bank(iobase, SET0); - outb(ICR_ETMRI, iobase+ICR); - } else { -#endif IRDA_DEBUG(4, "%s(%ld), mtt=%d\n", __func__ , jiffies, mtt); if (mtt) udelay(mtt); @@ -560,9 +540,6 @@ static netdev_tx_t w83977af_hard_xmit(struct sk_buff *skb, switch_bank(iobase, SET0); outb(ICR_EDMAI, iobase+ICR); w83977af_dma_write(self, iobase); -#ifdef CONFIG_USE_INTERNAL_TIMER - } -#endif } else { self->tx_buff.data = self->tx_buff.head; self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data, @@ -876,20 +853,7 @@ static int w83977af_dma_receive_complete(struct w83977af_ir *self) /* Check if we have transferred all data to memory */ switch_bank(iobase, SET0); if (inb(iobase+USR) & USR_RDR) { -#ifdef CONFIG_USE_INTERNAL_TIMER - /* Put this entry back in fifo */ - st_fifo->head--; - st_fifo->len++; - st_fifo->entries[st_fifo->head].status = status; - st_fifo->entries[st_fifo->head].len = len; - - /* Restore set register */ - outb(set, iobase+SSR); - - return FALSE; /* I'll be back! */ -#else udelay(80); /* Should be enough!? */ -#endif } skb = dev_alloc_skb(len+1); -- cgit v0.10.2 From 4d823be98c5b24d94c7f41a384a4bb60d7848ad5 Mon Sep 17 00:00:00 2001 From: Christoph Egger Date: Thu, 11 Mar 2010 12:07:54 +0000 Subject: obsolete config in kernel source: HSO_AUTOPM CONFIG_HSO_AUTOPM is set by KConfig / set in the Kernel source, makefiles and won't be ever set this way, therefor simply removing the protected code. Signed-off-by: Christoph Egger Cc: "David S. Miller" Signed-off-by: Andrew Morton Signed-off-by: David S. Miller diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 6895f15..be0cc99 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -1155,9 +1155,6 @@ static void _hso_serial_set_termios(struct tty_struct *tty, static void hso_resubmit_rx_bulk_urb(struct hso_serial *serial, struct urb *urb) { int result; -#ifdef CONFIG_HSO_AUTOPM - usb_mark_last_busy(urb->dev); -#endif /* We are done with this URB, resubmit it. Prep the USB to wait for * another frame */ usb_fill_bulk_urb(urb, serial->parent->usb, -- cgit v0.10.2 From bc35b4e347c047fb1c665bb761ddb22482539f7f Mon Sep 17 00:00:00 2001 From: Tilman Schmidt Date: Sun, 14 Mar 2010 12:58:05 +0000 Subject: gigaset: avoid registering CAPI driver more than once Registering/unregistering the Gigaset CAPI driver when a device is connected/disconnected causes an Oops when disconnecting two Gigaset devices in a row, because the same capi_driver structure gets unregistered twice. Fix by making driver registration/unregistration a separate operation (empty in the ISDN4Linux case) called when the main module is loaded/unloaded. Impact: bugfix Signed-off-by: Tilman Schmidt Acked-by: Karsten Keil CC: stable@kernel.org Signed-off-by: David S. Miller diff --git a/drivers/isdn/gigaset/capi.c b/drivers/isdn/gigaset/capi.c index 6643d65..4a31962 100644 --- a/drivers/isdn/gigaset/capi.c +++ b/drivers/isdn/gigaset/capi.c @@ -2191,36 +2191,24 @@ static const struct file_operations gigaset_proc_fops = { .release = single_release, }; -static struct capi_driver capi_driver_gigaset = { - .name = "gigaset", - .revision = "1.0", -}; - /** - * gigaset_isdn_register() - register to LL + * gigaset_isdn_regdev() - register device to LL * @cs: device descriptor structure. * @isdnid: device name. * - * Called by main module to register the device with the LL. - * * Return value: 1 for success, 0 for failure */ -int gigaset_isdn_register(struct cardstate *cs, const char *isdnid) +int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid) { struct gigaset_capi_ctr *iif; int rc; - pr_info("Kernel CAPI interface\n"); - iif = kmalloc(sizeof(*iif), GFP_KERNEL); if (!iif) { pr_err("%s: out of memory\n", __func__); return 0; } - /* register driver with CAPI (ToDo: what for?) */ - register_capi_driver(&capi_driver_gigaset); - /* prepare controller structure */ iif->ctr.owner = THIS_MODULE; iif->ctr.driverdata = cs; @@ -2241,7 +2229,6 @@ int gigaset_isdn_register(struct cardstate *cs, const char *isdnid) rc = attach_capi_ctr(&iif->ctr); if (rc) { pr_err("attach_capi_ctr failed (%d)\n", rc); - unregister_capi_driver(&capi_driver_gigaset); kfree(iif); return 0; } @@ -2252,17 +2239,36 @@ int gigaset_isdn_register(struct cardstate *cs, const char *isdnid) } /** - * gigaset_isdn_unregister() - unregister from LL + * gigaset_isdn_unregdev() - unregister device from LL * @cs: device descriptor structure. - * - * Called by main module to unregister the device from the LL. */ -void gigaset_isdn_unregister(struct cardstate *cs) +void gigaset_isdn_unregdev(struct cardstate *cs) { struct gigaset_capi_ctr *iif = cs->iif; detach_capi_ctr(&iif->ctr); kfree(iif); cs->iif = NULL; +} + +static struct capi_driver capi_driver_gigaset = { + .name = "gigaset", + .revision = "1.0", +}; + +/** + * gigaset_isdn_regdrv() - register driver to LL + */ +void gigaset_isdn_regdrv(void) +{ + pr_info("Kernel CAPI interface\n"); + register_capi_driver(&capi_driver_gigaset); +} + +/** + * gigaset_isdn_unregdrv() - unregister driver from LL + */ +void gigaset_isdn_unregdrv(void) +{ unregister_capi_driver(&capi_driver_gigaset); } diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c index 85de339..bdc01cb 100644 --- a/drivers/isdn/gigaset/common.c +++ b/drivers/isdn/gigaset/common.c @@ -507,7 +507,7 @@ void gigaset_freecs(struct cardstate *cs) case 2: /* error in initcshw */ /* Deregister from LL */ make_invalid(cs, VALID_ID); - gigaset_isdn_unregister(cs); + gigaset_isdn_unregdev(cs); /* fall through */ case 1: /* error when registering to LL */ @@ -769,7 +769,7 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, cs->cmdbytes = 0; gig_dbg(DEBUG_INIT, "setting up iif"); - if (!gigaset_isdn_register(cs, modulename)) { + if (!gigaset_isdn_regdev(cs, modulename)) { pr_err("error registering ISDN device\n"); goto error; } @@ -1205,11 +1205,13 @@ static int __init gigaset_init_module(void) gigaset_debuglevel = DEBUG_DEFAULT; pr_info(DRIVER_DESC DRIVER_DESC_DEBUG "\n"); + gigaset_isdn_regdrv(); return 0; } static void __exit gigaset_exit_module(void) { + gigaset_isdn_unregdrv(); } module_init(gigaset_init_module); diff --git a/drivers/isdn/gigaset/gigaset.h b/drivers/isdn/gigaset/gigaset.h index 1875ab8..cdd144e 100644 --- a/drivers/isdn/gigaset/gigaset.h +++ b/drivers/isdn/gigaset/gigaset.h @@ -675,8 +675,10 @@ int gigaset_isowbuf_getbytes(struct isowbuf_t *iwb, int size); */ /* Called from common.c for setting up/shutting down with the ISDN subsystem */ -int gigaset_isdn_register(struct cardstate *cs, const char *isdnid); -void gigaset_isdn_unregister(struct cardstate *cs); +void gigaset_isdn_regdrv(void); +void gigaset_isdn_unregdrv(void); +int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid); +void gigaset_isdn_unregdev(struct cardstate *cs); /* Called from hardware module to indicate completion of an skb */ void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb); diff --git a/drivers/isdn/gigaset/i4l.c b/drivers/isdn/gigaset/i4l.c index f0acb9d..c22e5ac 100644 --- a/drivers/isdn/gigaset/i4l.c +++ b/drivers/isdn/gigaset/i4l.c @@ -592,15 +592,13 @@ void gigaset_isdn_stop(struct cardstate *cs) } /** - * gigaset_isdn_register() - register to LL + * gigaset_isdn_regdev() - register to LL * @cs: device descriptor structure. * @isdnid: device name. * - * Called by main module to register the device with the LL. - * * Return value: 1 for success, 0 for failure */ -int gigaset_isdn_register(struct cardstate *cs, const char *isdnid) +int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid) { isdn_if *iif; @@ -650,15 +648,29 @@ int gigaset_isdn_register(struct cardstate *cs, const char *isdnid) } /** - * gigaset_isdn_unregister() - unregister from LL + * gigaset_isdn_unregdev() - unregister device from LL * @cs: device descriptor structure. - * - * Called by main module to unregister the device from the LL. */ -void gigaset_isdn_unregister(struct cardstate *cs) +void gigaset_isdn_unregdev(struct cardstate *cs) { gig_dbg(DEBUG_CMD, "sending UNLOAD"); gigaset_i4l_cmd(cs, ISDN_STAT_UNLOAD); kfree(cs->iif); cs->iif = NULL; } + +/** + * gigaset_isdn_regdrv() - register driver to LL + */ +void gigaset_isdn_regdrv(void) +{ + /* nothing to do */ +} + +/** + * gigaset_isdn_unregdrv() - unregister driver from LL + */ +void gigaset_isdn_unregdrv(void) +{ + /* nothing to do */ +} -- cgit v0.10.2 From 3a0a3a6b92edf181f849ebd8417122392ba73a96 Mon Sep 17 00:00:00 2001 From: Tilman Schmidt Date: Sun, 14 Mar 2010 12:58:05 +0000 Subject: gigaset: correct clearing of at_state strings on RING In RING handling, clear the table of received parameter strings in a loop like everywhere else, instead of by enumeration which had already gotten out of sync. Impact: minor bugfix Signed-off-by: Tilman Schmidt Acked-by: Karsten Keil CC: stable@kernel.org Signed-off-by: David S. Miller diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c index c8f89b7..206c380 100644 --- a/drivers/isdn/gigaset/ev-layer.c +++ b/drivers/isdn/gigaset/ev-layer.c @@ -1258,14 +1258,10 @@ static void do_action(int action, struct cardstate *cs, * note that bcs may be NULL if no B channel is free */ at_state2->ConState = 700; - kfree(at_state2->str_var[STR_NMBR]); - at_state2->str_var[STR_NMBR] = NULL; - kfree(at_state2->str_var[STR_ZCPN]); - at_state2->str_var[STR_ZCPN] = NULL; - kfree(at_state2->str_var[STR_ZBC]); - at_state2->str_var[STR_ZBC] = NULL; - kfree(at_state2->str_var[STR_ZHLC]); - at_state2->str_var[STR_ZHLC] = NULL; + for (i = 0; i < STR_NUM; ++i) { + kfree(at_state2->str_var[i]); + at_state2->str_var[i] = NULL; + } at_state2->int_var[VAR_ZCTP] = -1; spin_lock_irqsave(&cs->lock, flags); -- cgit v0.10.2 From 873a69a358a6b393fd8d9d92e193ec8895cac4d7 Mon Sep 17 00:00:00 2001 From: Tilman Schmidt Date: Sun, 14 Mar 2010 12:58:05 +0000 Subject: gigaset: prune use of tty_buffer_request_room Calling tty_buffer_request_room() before tty_insert_flip_string() is unnecessary, costs CPU and for big buffers can mess up the multi-page allocation avoidance. Signed-off-by: Tilman Schmidt Acked-by: Karsten Keil CC: Alan Cox , stable@kernel.org Signed-off-by: David S. Miller diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c index a1bcbc2..f0dc6c9 100644 --- a/drivers/isdn/gigaset/interface.c +++ b/drivers/isdn/gigaset/interface.c @@ -628,7 +628,6 @@ void gigaset_if_receive(struct cardstate *cs, if (tty == NULL) gig_dbg(DEBUG_IF, "receive on closed device"); else { - tty_buffer_request_room(tty, len); tty_insert_flip_string(tty, buffer, len); tty_flip_buffer_push(tty); } -- cgit v0.10.2 From b8d689743106bab5c49dda87080e76aa78db8a56 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sun, 14 Mar 2010 22:24:08 +0000 Subject: myri: remove dead code We can never reach the return statement. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 676c513..e84dd3e 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -3687,7 +3687,6 @@ static void myri10ge_probe_slices(struct myri10ge_priv *mgp) if (status != 0) { dev_err(&mgp->pdev->dev, "failed reset\n"); goto abort_with_fw; - return; } mgp->max_intr_slots = cmd.data0 / sizeof(struct mcp_slot); -- cgit v0.10.2 From d14a0ebda7d3daede1a99c01527affb9ceaa4c22 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Sun, 14 Mar 2010 20:13:19 +0000 Subject: net-2.6 [Bug-Fix][dccp]: fix oops caused after failed initialisation dccp: fix panic caused by failed initialisation This fixes a kernel panic reported thanks to Andre Noll: if DCCP is compiled into the kernel and any out of the initialisation steps in net/dccp/proto.c:dccp_init() fail, a subsequent attempt to create a SOCK_DCCP socket will panic, since inet{,6}_create() are not prevented from creating DCCP sockets. This patch fixes the problem by propagating a failure in dccp_init() to dccp_v{4,6}_init_net(), and from there to dccp_v{4,6}_init(), so that the DCCP protocol is not made available if its initialisation fails. Signed-off-by: Gerrit Renker Signed-off-by: David S. Miller diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index b195c4f..4071eaf 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c @@ -998,11 +998,11 @@ static struct inet_protosw dccp_v4_protosw = { static int __net_init dccp_v4_init_net(struct net *net) { - int err; + if (dccp_hashinfo.bhash == NULL) + return -ESOCKTNOSUPPORT; - err = inet_ctl_sock_create(&net->dccp.v4_ctl_sk, PF_INET, - SOCK_DCCP, IPPROTO_DCCP, net); - return err; + return inet_ctl_sock_create(&net->dccp.v4_ctl_sk, PF_INET, + SOCK_DCCP, IPPROTO_DCCP, net); } static void __net_exit dccp_v4_exit_net(struct net *net) diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index 1aec634..af3394d 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c @@ -1191,11 +1191,11 @@ static struct inet_protosw dccp_v6_protosw = { static int __net_init dccp_v6_init_net(struct net *net) { - int err; + if (dccp_hashinfo.bhash == NULL) + return -ESOCKTNOSUPPORT; - err = inet_ctl_sock_create(&net->dccp.v6_ctl_sk, PF_INET6, - SOCK_DCCP, IPPROTO_DCCP, net); - return err; + return inet_ctl_sock_create(&net->dccp.v6_ctl_sk, PF_INET6, + SOCK_DCCP, IPPROTO_DCCP, net); } static void __net_exit dccp_v6_exit_net(struct net *net) diff --git a/net/dccp/proto.c b/net/dccp/proto.c index 0ef7061..aa4cef3 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c @@ -1036,7 +1036,7 @@ static int __init dccp_init(void) FIELD_SIZEOF(struct sk_buff, cb)); rc = percpu_counter_init(&dccp_orphan_count, 0); if (rc) - goto out; + goto out_fail; rc = -ENOBUFS; inet_hashinfo_init(&dccp_hashinfo); dccp_hashinfo.bind_bucket_cachep = @@ -1125,8 +1125,9 @@ static int __init dccp_init(void) goto out_sysctl_exit; dccp_timestamping_init(); -out: - return rc; + + return 0; + out_sysctl_exit: dccp_sysctl_exit(); out_ackvec_exit: @@ -1135,18 +1136,19 @@ out_free_dccp_mib: dccp_mib_exit(); out_free_dccp_bhash: free_pages((unsigned long)dccp_hashinfo.bhash, bhash_order); - dccp_hashinfo.bhash = NULL; out_free_dccp_locks: inet_ehash_locks_free(&dccp_hashinfo); out_free_dccp_ehash: free_pages((unsigned long)dccp_hashinfo.ehash, ehash_order); - dccp_hashinfo.ehash = NULL; out_free_bind_bucket_cachep: kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep); - dccp_hashinfo.bind_bucket_cachep = NULL; out_free_percpu: percpu_counter_destroy(&dccp_orphan_count); - goto out; +out_fail: + dccp_hashinfo.bhash = NULL; + dccp_hashinfo.ehash = NULL; + dccp_hashinfo.bind_bucket_cachep = NULL; + return rc; } static void __exit dccp_fini(void) -- cgit v0.10.2 From 0e17226f7cd289504724466f4298abc9bdfca3fe Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 15 Mar 2010 23:08:03 +0000 Subject: ARM: SAMSUNG: Fixup commit 4e6d488af37980d224cbf298224db6173673f362 Commit 4e6d488af37980d224cbf298224db6173673f362 either missed out the following machine files or somehow managed to clash between merges. Fixup the three files missing the second parameter to addruart macro to allow them to build. Fixes the following warnings in arch/arm/kernel/debug.c: arch/arm/kernel/debug.S: Assembler messages: arch/arm/kernel/debug.S:167: Error: too many positional arguments arch/arm/kernel/debug.S:183: Error: too many positional arguments Signed-off-by: Ben Dooks diff --git a/arch/arm/mach-s3c64xx/include/mach/debug-macro.S b/arch/arm/mach-s3c64xx/include/mach/debug-macro.S index b18ac52..f9ab5d2 100644 --- a/arch/arm/mach-s3c64xx/include/mach/debug-macro.S +++ b/arch/arm/mach-s3c64xx/include/mach/debug-macro.S @@ -21,7 +21,7 @@ * aligned and add in the offset when we load the value here. */ - .macro addruart, rx + .macro addruart, rx, rtmp mrc p15, 0, \rx, c1, c0 tst \rx, #1 ldreq \rx, = S3C_PA_UART diff --git a/arch/arm/mach-s5p6440/include/mach/debug-macro.S b/arch/arm/mach-s5p6440/include/mach/debug-macro.S index 48cdb0d..1347d7f 100644 --- a/arch/arm/mach-s5p6440/include/mach/debug-macro.S +++ b/arch/arm/mach-s5p6440/include/mach/debug-macro.S @@ -19,7 +19,7 @@ * aligned and add in the offset when we load the value here. */ - .macro addruart, rx + .macro addruart, rx, rtmp mrc p15, 0, \rx, c1, c0 tst \rx, #1 ldreq \rx, = S3C_PA_UART diff --git a/arch/arm/mach-s5p6442/include/mach/debug-macro.S b/arch/arm/mach-s5p6442/include/mach/debug-macro.S index 1aae691..bb65361 100644 --- a/arch/arm/mach-s5p6442/include/mach/debug-macro.S +++ b/arch/arm/mach-s5p6442/include/mach/debug-macro.S @@ -15,7 +15,7 @@ #include #include - .macro addruart, rx + .macro addruart, rx, rtmp mrc p15, 0, \rx, c1, c0 tst \rx, #1 ldreq \rx, = S3C_PA_UART -- cgit v0.10.2 From d00561a2f64b381aefb41f4a140ff5dc373b52e7 Mon Sep 17 00:00:00 2001 From: Lars Ellenberg Date: Mon, 15 Mar 2010 19:09:28 -0700 Subject: ISDN: Add PCI ID for HFC-2S/4S Beronet Card PCIe A few subdevice IDs seem to have been dropped when hfc_multi was included upstream, just compare the list at http://www.openvox.cn/viewvc/misdn/trunk/hfc_multi.c?revision=75&view=annotate#l175 with the IDs in drivers/isdn/hardware/mISDN/hfcmulti.c Added PCIe 2 Port card and LED settings (same as PCI) Do not use /KKe Signed-off-by: Lars Ellenberg Signed-off-by: Karsten Keil Signed-off-by: David S. Miller diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c index ad36df9..8affba3 100644 --- a/drivers/isdn/hardware/mISDN/hfcmulti.c +++ b/drivers/isdn/hardware/mISDN/hfcmulti.c @@ -5265,6 +5265,8 @@ static const struct hm_map hfcm_map[] = { /*31*/ {VENDOR_CCD, "XHFC-4S Speech Design", 5, 4, 0, 0, 0, 0, HFC_IO_MODE_EMBSD, XHFC_IRQ}, /*32*/ {VENDOR_JH, "HFC-8S (junghanns)", 8, 8, 1, 0, 0, 0, 0, 0}, +/*33*/ {VENDOR_BN, "HFC-2S Beronet Card PCIe", 4, 2, 1, 3, 0, DIP_4S, 0, 0}, +/*34*/ {VENDOR_BN, "HFC-4S Beronet Card PCIe", 4, 4, 1, 2, 0, DIP_4S, 0, 0}, }; #undef H @@ -5300,6 +5302,10 @@ static struct pci_device_id hfmultipci_ids[] __devinitdata = { PCI_SUBDEVICE_ID_CCD_OV4S, 0, 0, H(28)}, /* OpenVox 4 */ { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD, PCI_SUBDEVICE_ID_CCD_OV2S, 0, 0, H(29)}, /* OpenVox 2 */ + { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD, + 0xb761, 0, 0, H(33)}, /* BN2S PCIe */ + { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD, + 0xb762, 0, 0, H(34)}, /* BN4S PCIe */ /* Cards with HFC-8S Chip */ { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD, -- cgit v0.10.2 From 0821ec55bb1382dd3b9476dc15d5dbbb19f0c3fd Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Mon, 15 Mar 2010 20:38:25 -0700 Subject: bridge: Move NULL mdb check into br_mdb_ip_get Since all callers of br_mdb_ip_get need to check whether the hash table is NULL, this patch moves the check into the function. This fixes the two callers (query/leave handler) that didn't check it. Reported-by: Michael Braun Signed-off-by: Herbert Xu Signed-off-by: David S. Miller diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index fd96a8d..398221e 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -49,22 +49,23 @@ static struct net_bridge_mdb_entry *__br_mdb_ip_get( static struct net_bridge_mdb_entry *br_mdb_ip_get( struct net_bridge_mdb_htable *mdb, __be32 dst) { + if (!mdb) + return NULL; + return __br_mdb_ip_get(mdb, dst, br_ip_hash(mdb, dst)); } struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br, struct sk_buff *skb) { - struct net_bridge_mdb_htable *mdb = br->mdb; - - if (!mdb || br->multicast_disabled) + if (br->multicast_disabled) return NULL; switch (skb->protocol) { case htons(ETH_P_IP): if (BR_INPUT_SKB_CB(skb)->igmp) break; - return br_mdb_ip_get(mdb, ip_hdr(skb)->daddr); + return br_mdb_ip_get(br->mdb, ip_hdr(skb)->daddr); } return NULL; -- cgit v0.10.2 From 36e9e1eab777e077f7484d309ff676d0568e27d1 Mon Sep 17 00:00:00 2001 From: Suresh Siddha Date: Mon, 15 Mar 2010 14:33:06 -0800 Subject: x86: Handle legacy PIC interrupts on all the cpu's Ingo Molnar reported that with the recent changes of not statically blocking IRQ0_VECTOR..IRQ15_VECTOR's on all the cpu's, broke an AMD platform (with Nvidia chipset) boot when "noapic" boot option is used. On this platform, legacy PIC interrupts are getting delivered to all the cpu's instead of just the boot cpu. Thus not initializing the vector to irq mapping for the legacy irq's resulted in not handling certain interrupts causing boot hang. Fix this by initializing the vector to irq mapping on all the logical cpu's, if the legacy IRQ is handled by the legacy PIC. Reported-by: Ingo Molnar Signed-off-by: Suresh Siddha [ -v2: io-apic-enabled improvement ] Acked-by: Yinghai Lu Cc: Eric W. Biederman LKML-Reference: <1268692386.3296.43.camel@sbs-t61.sc.intel.com> Signed-off-by: Ingo Molnar diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h index a929c9e..46c0fe0 100644 --- a/arch/x86/include/asm/hw_irq.h +++ b/arch/x86/include/asm/hw_irq.h @@ -133,6 +133,7 @@ extern void (*__initconst interrupt[NR_VECTORS-FIRST_EXTERNAL_VECTOR])(void); typedef int vector_irq_t[NR_VECTORS]; DECLARE_PER_CPU(vector_irq_t, vector_irq); +extern void setup_vector_irq(int cpu); #ifdef CONFIG_X86_IO_APIC extern void lock_vector_lock(void); diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index e4e0ddc..463de9a 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -1268,6 +1268,14 @@ void __setup_vector_irq(int cpu) /* Mark the inuse vectors */ for_each_irq_desc(irq, desc) { cfg = desc->chip_data; + + /* + * If it is a legacy IRQ handled by the legacy PIC, this cpu + * will be part of the irq_cfg's domain. + */ + if (irq < legacy_pic->nr_legacy_irqs && !IO_APIC_IRQ(irq)) + cpumask_set_cpu(cpu, cfg->domain); + if (!cpumask_test_cpu(cpu, cfg->domain)) continue; vector = cfg->vector; diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c index ef257fc..f01d390 100644 --- a/arch/x86/kernel/irqinit.c +++ b/arch/x86/kernel/irqinit.c @@ -141,6 +141,28 @@ void __init init_IRQ(void) x86_init.irqs.intr_init(); } +/* + * Setup the vector to irq mappings. + */ +void setup_vector_irq(int cpu) +{ +#ifndef CONFIG_X86_IO_APIC + int irq; + + /* + * On most of the platforms, legacy PIC delivers the interrupts on the + * boot cpu. But there are certain platforms where PIC interrupts are + * delivered to multiple cpu's. If the legacy IRQ is handled by the + * legacy PIC, for the new cpu that is coming online, setup the static + * legacy vector to irq mapping: + */ + for (irq = 0; irq < legacy_pic->nr_legacy_irqs; irq++) + per_cpu(vector_irq, cpu)[IRQ0_VECTOR + irq] = irq; +#endif + + __setup_vector_irq(cpu); +} + static void __init smp_intr_init(void) { #ifdef CONFIG_SMP diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index a02e80c..06d98ae 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -247,7 +247,7 @@ static void __cpuinit smp_callin(void) /* * Need to setup vector mappings before we enable interrupts. */ - __setup_vector_irq(smp_processor_id()); + setup_vector_irq(smp_processor_id()); /* * Get our bogomips. * -- cgit v0.10.2 From 627a2d3c29427637f4c5d31ccc7fcbd8d312cd71 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 8 Mar 2010 16:44:38 +1100 Subject: md: deal with merge_bvec_fn in component devices better. If a component device has a merge_bvec_fn then as we never call it we must ensure we never need to. Currently this is done by setting max_sector to 1 PAGE, however this does not stop a bio being created with several sub-page iovecs that would violate the merge_bvec_fn. So instead set max_segments to 1 and set the segment boundary to the same as a page boundary to ensure there is only ever one single-page segment of IO requested at a time. This can particularly be an issue when 'xen' is used as it is known to submit multiple small buffers in a single bio. Signed-off-by: NeilBrown Cc: stable@kernel.org diff --git a/drivers/md/linear.c b/drivers/md/linear.c index af2d39d..bb2a231 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c @@ -172,12 +172,14 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) disk_stack_limits(mddev->gendisk, rdev->bdev, rdev->data_offset << 9); /* as we don't honour merge_bvec_fn, we must never risk - * violating it, so limit ->max_sector to one PAGE, as - * a one page request is never in violation. + * violating it, so limit max_segments to 1 lying within + * a single page. */ - if (rdev->bdev->bd_disk->queue->merge_bvec_fn && - queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9)) - blk_queue_max_hw_sectors(mddev->queue, PAGE_SIZE>>9); + if (rdev->bdev->bd_disk->queue->merge_bvec_fn) { + blk_queue_max_segments(mddev->queue, 1); + blk_queue_segment_boundary(mddev->queue, + PAGE_CACHE_SIZE - 1); + } conf->array_sectors += rdev->sectors; cnt++; diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index 4b323f4..5558ebc 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c @@ -301,14 +301,16 @@ static int multipath_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) rdev->data_offset << 9); /* as we don't honour merge_bvec_fn, we must never risk - * violating it, so limit ->max_sector to one PAGE, as - * a one page request is never in violation. + * violating it, so limit ->max_segments to one, lying + * within a single page. * (Note: it is very unlikely that a device with * merge_bvec_fn will be involved in multipath.) */ - if (q->merge_bvec_fn && - queue_max_sectors(q) > (PAGE_SIZE>>9)) - blk_queue_max_hw_sectors(mddev->queue, PAGE_SIZE>>9); + if (q->merge_bvec_fn) { + blk_queue_max_segments(mddev->queue, 1); + blk_queue_segment_boundary(mddev->queue, + PAGE_CACHE_SIZE - 1); + } conf->working_disks++; mddev->degraded--; @@ -476,9 +478,11 @@ static int multipath_run (mddev_t *mddev) /* as we don't honour merge_bvec_fn, we must never risk * violating it, not that we ever expect a device with * a merge_bvec_fn to be involved in multipath */ - if (rdev->bdev->bd_disk->queue->merge_bvec_fn && - queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9)) - blk_queue_max_hw_sectors(mddev->queue, PAGE_SIZE>>9); + if (rdev->bdev->bd_disk->queue->merge_bvec_fn) { + blk_queue_max_segments(mddev->queue, 1); + blk_queue_segment_boundary(mddev->queue, + PAGE_CACHE_SIZE - 1); + } if (!test_bit(Faulty, &rdev->flags)) conf->working_disks++; diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index a1f7147..377cf2a 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -176,14 +176,15 @@ static int create_strip_zones(mddev_t *mddev) disk_stack_limits(mddev->gendisk, rdev1->bdev, rdev1->data_offset << 9); /* as we don't honour merge_bvec_fn, we must never risk - * violating it, so limit ->max_sector to one PAGE, as - * a one page request is never in violation. + * violating it, so limit ->max_segments to 1, lying within + * a single page. */ - if (rdev1->bdev->bd_disk->queue->merge_bvec_fn && - queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9)) - blk_queue_max_hw_sectors(mddev->queue, PAGE_SIZE>>9); - + if (rdev1->bdev->bd_disk->queue->merge_bvec_fn) { + blk_queue_max_segments(mddev->queue, 1); + blk_queue_segment_boundary(mddev->queue, + PAGE_CACHE_SIZE - 1); + } if (!smallest || (rdev1->sectors < smallest->sectors)) smallest = rdev1; cnt++; diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 5a06122..f741f77 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1152,13 +1152,17 @@ static int raid1_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) disk_stack_limits(mddev->gendisk, rdev->bdev, rdev->data_offset << 9); - /* as we don't honour merge_bvec_fn, we must never risk - * violating it, so limit ->max_sector to one PAGE, as - * a one page request is never in violation. + /* as we don't honour merge_bvec_fn, we must + * never risk violating it, so limit + * ->max_segments to one lying with a single + * page, as a one page request is never in + * violation. */ - if (rdev->bdev->bd_disk->queue->merge_bvec_fn && - queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9)) - blk_queue_max_hw_sectors(mddev->queue, PAGE_SIZE>>9); + if (rdev->bdev->bd_disk->queue->merge_bvec_fn) { + blk_queue_max_segments(mddev->queue, 1); + blk_queue_segment_boundary(mddev->queue, + PAGE_CACHE_SIZE - 1); + } p->head_position = 0; rdev->raid_disk = mirror; @@ -2098,12 +2102,14 @@ static int run(mddev_t *mddev) disk_stack_limits(mddev->gendisk, rdev->bdev, rdev->data_offset << 9); /* as we don't honour merge_bvec_fn, we must never risk - * violating it, so limit ->max_sector to one PAGE, as - * a one page request is never in violation. + * violating it, so limit ->max_segments to 1 lying within + * a single page, as a one page request is never in violation. */ - if (rdev->bdev->bd_disk->queue->merge_bvec_fn && - queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9)) - blk_queue_max_hw_sectors(mddev->queue, PAGE_SIZE>>9); + if (rdev->bdev->bd_disk->queue->merge_bvec_fn) { + blk_queue_max_segments(mddev->queue, 1); + blk_queue_segment_boundary(mddev->queue, + PAGE_CACHE_SIZE - 1); + } } mddev->degraded = 0; diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 7584f9a..b4ba41e 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -1155,13 +1155,17 @@ static int raid10_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) disk_stack_limits(mddev->gendisk, rdev->bdev, rdev->data_offset << 9); - /* as we don't honour merge_bvec_fn, we must never risk - * violating it, so limit ->max_sector to one PAGE, as - * a one page request is never in violation. + /* as we don't honour merge_bvec_fn, we must + * never risk violating it, so limit + * ->max_segments to one lying with a single + * page, as a one page request is never in + * violation. */ - if (rdev->bdev->bd_disk->queue->merge_bvec_fn && - queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9)) - blk_queue_max_hw_sectors(mddev->queue, PAGE_SIZE>>9); + if (rdev->bdev->bd_disk->queue->merge_bvec_fn) { + blk_queue_max_segments(mddev->queue, 1); + blk_queue_segment_boundary(mddev->queue, + PAGE_CACHE_SIZE - 1); + } p->head_position = 0; rdev->raid_disk = mirror; @@ -2255,12 +2259,14 @@ static int run(mddev_t *mddev) disk_stack_limits(mddev->gendisk, rdev->bdev, rdev->data_offset << 9); /* as we don't honour merge_bvec_fn, we must never risk - * violating it, so limit ->max_sector to one PAGE, as - * a one page request is never in violation. + * violating it, so limit max_segments to 1 lying + * within a single page. */ - if (rdev->bdev->bd_disk->queue->merge_bvec_fn && - queue_max_sectors(mddev->queue) > (PAGE_SIZE>>9)) - blk_queue_max_hw_sectors(mddev->queue, PAGE_SIZE>>9); + if (rdev->bdev->bd_disk->queue->merge_bvec_fn) { + blk_queue_max_segments(mddev->queue, 1); + blk_queue_segment_boundary(mddev->queue, + PAGE_CACHE_SIZE - 1); + } disk->head_position = 0; } -- cgit v0.10.2 From 572c0e3c73341755f3e7dfaaef6b26df12bd709c Mon Sep 17 00:00:00 2001 From: Daniel T Chen Date: Sun, 14 Mar 2010 23:44:03 -0400 Subject: ALSA: hda: Use LPIB and 6stack-dig for eMachines T5212 BugLink: https://bugs.launchpad.net/bugs/538895 The OR has verified that both position_fix=1 and model=6stack-dig are necessary to have capture function properly. (The existing 3stack-6ch model quirk seems to be incorrect.) Reported-by: Reuben Bailey Tested-by: Reuben Bailey Cc: Signed-off-by: Daniel T Chen Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 027d3f4..1766ad2 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2271,6 +2271,7 @@ static struct snd_pci_quirk position_fix_list[] __devinitdata = { SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB), SND_PCI_QUIRK(0x1565, 0x820f, "Biostar Microtech", POS_FIX_LPIB), + SND_PCI_QUIRK(0x8086, 0xd601, "eMachines T5212", POS_FIX_LPIB), {} }; diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 07637c4..4ec5763 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -9237,7 +9237,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = { SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL), SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL), SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL), - SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch), + SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG), {} }; -- cgit v0.10.2 From fb40b496ad8bbe60a60c25eb2fce20f3cc114679 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 16 Mar 2010 09:46:23 +0300 Subject: sound: sequencer: clean up remove bogus check A few lines earlier bend is limited to 2399. So semitones is always less than 24 here. Signed-off-by: Dan Carpenter Signed-off-by: Takashi Iwai diff --git a/sound/oss/sequencer.c b/sound/oss/sequencer.c index c798746..e85789e 100644 --- a/sound/oss/sequencer.c +++ b/sound/oss/sequencer.c @@ -1631,8 +1631,6 @@ unsigned long compute_finetune(unsigned long base_freq, int bend, int range, } semitones = bend / 100; - if (semitones > 99) - semitones = 99; cents = bend % 100; amount = (int) (semitone_tuning[semitones] * multiplier * cent_tuning[cents]) / 10000; -- cgit v0.10.2 From 7f7708f0055e49e331f267700aa8b2ee879f004c Mon Sep 17 00:00:00 2001 From: Michael Braun Date: Tue, 16 Mar 2010 00:26:22 -0700 Subject: bridge: Fix br_forward crash in promiscuous mode From: Michael Braun bridge: Fix br_forward crash in promiscuous mode It's a linux-next kernel from 2010-03-12 on an x86 system and it OOPs in the bridge module in br_pass_frame_up (called by br_handle_frame_finish) because brdev cannot be dereferenced (its set to a non-null value). Adding some BUG_ON statements revealed that BR_INPUT_SKB_CB(skb)->brdev == br-dev (as set in br_handle_frame_finish first) only holds until br_forward is called. The next call to br_pass_frame_up then fails. Digging deeper it seems that br_forward either frees the skb or passes it to NF_HOOK which will in turn take care of freeing the skb. The same is holds for br_pass_frame_ip. So it seems as if two independent skb allocations are required. As far as I can see, commit b33084be192ee1e347d98bb5c9e38a53d98d35e2 ("bridge: Avoid unnecessary clone on forward path") removed skb duplication and so likely causes this crash. This crash does not happen on 2.6.33. I've therefore modified br_forward the same way br_flood has been modified so that the skb is not freed if skb0 is going to be used and I can confirm that the attached patch resolves the issue for me. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c index d61e6f7..8347916 100644 --- a/net/bridge/br_forward.c +++ b/net/bridge/br_forward.c @@ -19,6 +19,10 @@ #include #include "br_private.h" +static int deliver_clone(struct net_bridge_port *prev, struct sk_buff *skb, + void (*__packet_hook)(const struct net_bridge_port *p, + struct sk_buff *skb)); + /* Don't forward packets to originating port or forwarding diasabled */ static inline int should_deliver(const struct net_bridge_port *p, const struct sk_buff *skb) @@ -94,14 +98,18 @@ void br_deliver(const struct net_bridge_port *to, struct sk_buff *skb) } /* called with rcu_read_lock */ -void br_forward(const struct net_bridge_port *to, struct sk_buff *skb) +void br_forward(const struct net_bridge_port *to, struct sk_buff *skb, struct sk_buff *skb0) { if (should_deliver(to, skb)) { - __br_forward(to, skb); + if (skb0) + deliver_clone(to, skb, __br_forward); + else + __br_forward(to, skb); return; } - kfree_skb(skb); + if (!skb0) + kfree_skb(skb); } static int deliver_clone(struct net_bridge_port *prev, struct sk_buff *skb, diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 53b3985..08a72e6 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c @@ -90,7 +90,7 @@ int br_handle_frame_finish(struct sk_buff *skb) if (skb) { if (dst) - br_forward(dst->dst, skb); + br_forward(dst->dst, skb, skb2); else br_flood_forward(br, skb, skb2); } diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index fef0384..bfb8feb 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -252,7 +252,7 @@ extern void br_deliver(const struct net_bridge_port *to, struct sk_buff *skb); extern int br_dev_queue_push_xmit(struct sk_buff *skb); extern void br_forward(const struct net_bridge_port *to, - struct sk_buff *skb); + struct sk_buff *skb, struct sk_buff *skb0); extern int br_forward_finish(struct sk_buff *skb); extern void br_flood_deliver(struct net_bridge *br, struct sk_buff *skb); extern void br_flood_forward(struct net_bridge *br, struct sk_buff *skb, -- cgit v0.10.2 From 935050daad4c0ce687f7111995ed7791796deff9 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 16 Mar 2010 00:33:37 -0700 Subject: drivers/serial/sunsab.c: adjust the constant used to initialize the interrupt_mask0 fields From: Julia Lawall SAB82532_ISR0_TCD is declared in drivers/serial/subsab.h as relating to a status register, while SAB82532_IMR0_TCD is declared in the same file as relating to a mask register. The latter seems more appropriate for the interrupt_mask0 field, and follows the strategy for initializing this field elsewhere in the same file. Both SAB82532_ISR0_TCD and SAB82532_IMR0_TCD have the same value. Signed-off-by: Julia Lawall Signed-off-by: David S. Miller diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c index d514e28..d2e0321 100644 --- a/drivers/serial/sunsab.c +++ b/drivers/serial/sunsab.c @@ -474,7 +474,7 @@ static void sunsab_stop_rx(struct uart_port *port) { struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; - up->interrupt_mask0 |= SAB82532_ISR0_TCD; + up->interrupt_mask0 |= SAB82532_IMR0_TCD; writeb(up->interrupt_mask1, &up->regs->w.imr0); } -- cgit v0.10.2 From 97fedbbe1046b3118f49df249840ca21041eefe4 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 16 Mar 2010 08:55:32 +0100 Subject: Remove GENHD_FL_DRIVERFS This flag is not used, so best discarded. Signed-off-by: NeilBrown -- Hi Jens, I came across this recently - these are the only two occurances of "GENHD_FL_DRIVERFS" in the kernel, so it cannot be needed. NeilBrown Signed-off-by: Jens Axboe diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 1dd4d84..466fae8 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -2185,7 +2185,7 @@ static void sd_probe_async(void *data, async_cookie_t cookie) blk_queue_prep_rq(sdp->request_queue, sd_prep_fn); gd->driverfs_dev = &sdp->sdev_gendev; - gd->flags = GENHD_FL_EXT_DEVT | GENHD_FL_DRIVERFS; + gd->flags = GENHD_FL_EXT_DEVT; if (sdp->removable) gd->flags |= GENHD_FL_REMOVABLE; diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 56b5051..5f2f4c4 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -109,7 +109,7 @@ struct hd_struct { }; #define GENHD_FL_REMOVABLE 1 -#define GENHD_FL_DRIVERFS 2 +/* 2 is unused */ #define GENHD_FL_MEDIA_CHANGE_NOTIFY 4 #define GENHD_FL_CD 8 #define GENHD_FL_UP 16 -- cgit v0.10.2 From 910ac735bad53ce54741a72a5b19ab69794ae069 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Tue, 16 Mar 2010 08:57:15 +0100 Subject: block: make CONFIG_BLK_CGROUP visible Make the config visible, so we can choose from CONFIG_BLK_CGROUP=y and CONFIG_BLK_CGROUP=m when CONFIG_IOSCHED_CFQ=m. Signed-off-by: Li Zefan Signed-off-by: Jens Axboe diff --git a/block/Kconfig b/block/Kconfig index e20fbde..f9e89f4 100644 --- a/block/Kconfig +++ b/block/Kconfig @@ -78,8 +78,9 @@ config BLK_DEV_INTEGRITY Protection. If in doubt, say N. config BLK_CGROUP - bool + tristate "Block cgroup support" depends on CGROUPS + depends on CFQ_GROUP_IOSCHED default n ---help--- Generic block IO controller cgroup interface. This is the common -- cgit v0.10.2 From 6404fccafa3bfdc0602130a87f4d93baf928bea4 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 16 Mar 2010 01:00:17 -0700 Subject: MAINTAINERS: Add entry for sparc serial drivers. Signed-off-by: David S. Miller diff --git a/MAINTAINERS b/MAINTAINERS index 34f52a1..a1cb1e6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5136,6 +5136,21 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next-2.6.git S: Maintained F: arch/sparc/ +SPARC SERIAL DRIVERS +M: "David S. Miller" +L: sparclinux@vger.kernel.org +T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next-2.6.git +S: Maintained +F: drivers/serial/suncore.c +F: drivers/serial/suncore.h +F: drivers/serial/sunhv.c +F: drivers/serial/sunsab.c +F: drivers/serial/sunsab.h +F: drivers/serial/sunsu.c +F: drivers/serial/sunzilog.c +F: drivers/serial/sunzilog.h + SPECIALIX IO8+ MULTIPORT SERIAL CARD DRIVER M: Roger Wolff S: Supported -- cgit v0.10.2 From b63be8d7beda7fe5879559be6f70f8e1c93109e4 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 15 Mar 2010 15:03:50 -0300 Subject: perf top: Improve the autosizing of column lenghts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When profiling C++ workloads the symbol name length can be really big, so cap it before it garbles the result. This builds upon the autosizing already present where we choose to use the short, basename of DSOs instead of its long, full pathname. Reported-by: Pavel Krauz Signed-off-by: Arnaldo Carvalho de Melo Cc: Frédéric Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Paul Mackerras LKML-Reference: <1268676230-9261-1-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 0b719e3..8364c8a 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -455,7 +455,7 @@ static void print_sym_table(void) struct sym_entry *syme, *n; struct rb_root tmp = RB_ROOT; struct rb_node *nd; - int sym_width = 0, dso_width = 0, max_dso_width; + int sym_width = 0, dso_width = 0, dso_short_width; const int win_width = winsize.ws_col - 1; samples = userspace_samples = 0; @@ -545,15 +545,20 @@ static void print_sym_table(void) if (syme->map->dso->long_name_len > dso_width) dso_width = syme->map->dso->long_name_len; + if (syme->map->dso->short_name_len > dso_short_width) + dso_short_width = syme->map->dso->short_name_len; + if (syme->name_len > sym_width) sym_width = syme->name_len; } printed = 0; - max_dso_width = winsize.ws_col - sym_width - 29; - if (dso_width > max_dso_width) - dso_width = max_dso_width; + if (sym_width + dso_width > winsize.ws_col - 29) { + dso_width = dso_short_width; + if (sym_width + dso_width > winsize.ws_col - 29) + sym_width = winsize.ws_col - dso_width - 29; + } putchar('\n'); if (nr_counters == 1) printf(" samples pcnt"); diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 323c0ae..c458c4a 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -163,9 +163,17 @@ void dso__set_long_name(struct dso *self, char *name) self->long_name_len = strlen(name); } +static void dso__set_short_name(struct dso *self, const char *name) +{ + if (name == NULL) + return; + self->short_name = name; + self->short_name_len = strlen(name); +} + static void dso__set_basename(struct dso *self) { - self->short_name = basename(self->long_name); + dso__set_short_name(self, basename(self->long_name)); } struct dso *dso__new(const char *name) @@ -176,7 +184,7 @@ struct dso *dso__new(const char *name) int i; strcpy(self->name, name); dso__set_long_name(self, self->name); - self->short_name = self->name; + dso__set_short_name(self, self->name); for (i = 0; i < MAP__NR_TYPES; ++i) self->symbols[i] = self->symbol_names[i] = RB_ROOT; self->slen_calculated = 0; @@ -897,7 +905,6 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name, struct kmap *kmap = self->kernel ? map__kmap(map) : NULL; struct map *curr_map = map; struct dso *curr_dso = self; - size_t dso_name_len = strlen(self->short_name); Elf_Data *symstrs, *secstrs; uint32_t nr_syms; int err = -1; @@ -987,7 +994,8 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name, char dso_name[PATH_MAX]; if (strcmp(section_name, - curr_dso->short_name + dso_name_len) == 0) + (curr_dso->short_name + + self->short_name_len)) == 0) goto new_symbol; if (strcmp(section_name, ".text") == 0) { @@ -1782,7 +1790,7 @@ struct dso *dso__new_kernel(const char *name) struct dso *self = dso__new(name ?: "[kernel.kallsyms]"); if (self != NULL) { - self->short_name = "[kernel]"; + dso__set_short_name(self, "[kernel]"); self->kernel = 1; } diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 280dadd..f30a374 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -110,9 +110,10 @@ struct dso { u8 sorted_by_name; u8 loaded; u8 build_id[BUILD_ID_SIZE]; - u16 long_name_len; const char *short_name; char *long_name; + u16 long_name_len; + u16 short_name_len; char name[0]; }; -- cgit v0.10.2 From e3818b8dce2a934cd1521dbc4827e5238d8f45d8 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Mon, 15 Mar 2010 17:03:43 -0700 Subject: rcu: Make rcu_read_lock_bh_held() allow for disabled BH Disabling BH can stand in for rcu_read_lock_bh(), and this patch updates rcu_read_lock_bh_held() to allow for this. In order to avoid include-file hell, this function is moved out of line to kernel/rcupdate.c. This fixes a false positive RCU warning. Reported-by: Arnd Bergmann Reported-by: Eric Dumazet Signed-off-by: Paul E. McKenney Acked-by: Lai Jiangshan Cc: dipankar@in.ibm.com Cc: mathieu.desnoyers@polymtl.ca Cc: josh@joshtriplett.org Cc: dvhltc@us.ibm.com Cc: niv@us.ibm.com Cc: peterz@infradead.org Cc: rostedt@goodmis.org Cc: Valdis.Kletnieks@vt.edu Cc: dhowells@redhat.com LKML-Reference: <20100316000343.GA25857@linux.vnet.ibm.com> Signed-off-by: Ingo Molnar diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 3024050..e1bdc4b 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -123,22 +123,11 @@ static inline int rcu_read_lock_held(void) return lock_is_held(&rcu_lock_map); } -/** - * rcu_read_lock_bh_held - might we be in RCU-bh read-side critical section? - * - * If CONFIG_PROVE_LOCKING is selected and enabled, returns nonzero iff in - * an RCU-bh read-side critical section. In absence of CONFIG_PROVE_LOCKING, - * this assumes we are in an RCU-bh read-side critical section unless it can - * prove otherwise. - * - * Check rcu_scheduler_active to prevent false positives during boot. +/* + * rcu_read_lock_bh_held() is defined out of line to avoid #include-file + * hell. */ -static inline int rcu_read_lock_bh_held(void) -{ - if (!debug_lockdep_rcu_enabled()) - return 1; - return lock_is_held(&rcu_bh_lock_map); -} +extern int rcu_read_lock_bh_held(void); /** * rcu_read_lock_sched_held - might we be in RCU-sched read-side critical section? diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index f1125c1..63fe254 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c @@ -45,6 +45,7 @@ #include #include #include +#include #ifdef CONFIG_DEBUG_LOCK_ALLOC static struct lock_class_key rcu_lock_key; @@ -66,6 +67,28 @@ EXPORT_SYMBOL_GPL(rcu_sched_lock_map); int rcu_scheduler_active __read_mostly; EXPORT_SYMBOL_GPL(rcu_scheduler_active); +#ifdef CONFIG_DEBUG_LOCK_ALLOC + +/** + * rcu_read_lock_bh_held - might we be in RCU-bh read-side critical section? + * + * Check for bottom half being disabled, which covers both the + * CONFIG_PROVE_RCU and not cases. Note that if someone uses + * rcu_read_lock_bh(), but then later enables BH, lockdep (if enabled) + * will show the situation. + * + * Check debug_lockdep_rcu_enabled() to prevent false positives during boot. + */ +int rcu_read_lock_bh_held(void) +{ + if (!debug_lockdep_rcu_enabled()) + return 1; + return in_softirq(); +} +EXPORT_SYMBOL_GPL(rcu_read_lock_bh_held); + +#endif /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */ + /* * This function is invoked towards the end of the scheduler's initialization * process. Before this is called, the idle task might contain -- cgit v0.10.2 From 67c7ff7c56f38a8ab338fbbfe366621ce6303ba1 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Mon, 15 Mar 2010 13:02:28 -0400 Subject: perf probe: Fix offset to allow signed value Fix dereference offset to intmax_t from uintmax_t, because it can have negative values (for example local variable's offset from frame pointer). Signed-off-by: Masami Hiramatsu Cc: systemtap Cc: DLE LKML-Reference: <20100315170228.31852.71946.stgit@localhost6.localdomain6> Signed-off-by: Ingo Molnar diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index f9cbbf1..0e8c8f1 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -333,8 +333,8 @@ static void show_location(Dwarf_Op *op, struct probe_finder *pf) die("%u exceeds max register number.", regn); if (deref) - ret = snprintf(pf->buf, pf->len, " %s=+%ju(%s)", - pf->var, (uintmax_t)offs, regs); + ret = snprintf(pf->buf, pf->len, " %s=%+jd(%s)", + pf->var, (intmax_t)offs, regs); else ret = snprintf(pf->buf, pf->len, " %s=%s", pf->var, regs); DIE_IF(ret < 0); -- cgit v0.10.2 From d0cb4260f899d07462d49fc67e29f2438dbaca2f Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Mon, 15 Mar 2010 13:02:35 -0400 Subject: perf probe: Use original address instead of CU-based address Use original address for looking up the location of variables for dwarf_getlocation_addr() instead of CU-based address. Signed-off-by: Masami Hiramatsu Cc: systemtap Cc: DLE LKML-Reference: <20100315170235.31852.91195.stgit@localhost6.localdomain6> Signed-off-by: Ingo Molnar diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 0e8c8f1..c171a24 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -352,8 +352,7 @@ static void show_variable(Dwarf_Die *vr_die, struct probe_finder *pf) if (dwarf_attr(vr_die, DW_AT_location, &attr) == NULL) goto error; /* TODO: handle more than 1 exprs */ - ret = dwarf_getlocation_addr(&attr, (pf->addr - pf->cu_base), - &expr, &nexpr, 1); + ret = dwarf_getlocation_addr(&attr, pf->addr, &expr, &nexpr, 1); if (ret <= 0 || nexpr == 0) goto error; @@ -437,8 +436,7 @@ static void show_probe_point(Dwarf_Die *sp_die, struct probe_finder *pf) /* Get the frame base attribute/ops */ dwarf_attr(sp_die, DW_AT_frame_base, &fb_attr); - ret = dwarf_getlocation_addr(&fb_attr, (pf->addr - pf->cu_base), - &pf->fb_ops, &nops, 1); + ret = dwarf_getlocation_addr(&fb_attr, pf->addr, &pf->fb_ops, &nops, 1); if (ret <= 0 || nops == 0) pf->fb_ops = NULL; @@ -644,7 +642,6 @@ static void find_probe_point_by_func(struct probe_finder *pf) int find_probe_point(int fd, struct probe_point *pp) { struct probe_finder pf = {.pp = pp}; - int ret; Dwarf_Off off, noff; size_t cuhl; Dwarf_Die *diep; @@ -671,10 +668,6 @@ int find_probe_point(int fd, struct probe_point *pp) pf.fname = NULL; if (!pp->file || pf.fname) { - /* Save CU base address (for frame_base) */ - ret = dwarf_lowpc(&pf.cu_die, &pf.cu_base); - if (ret != 0) - pf.cu_base = 0; if (pp->function) find_probe_point_by_func(&pf); else if (pp->lazy_line) diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h index d1a6517..21f7354 100644 --- a/tools/perf/util/probe-finder.h +++ b/tools/perf/util/probe-finder.h @@ -71,7 +71,6 @@ struct probe_finder { /* For variable searching */ Dwarf_Op *fb_ops; /* Frame base attribute */ - Dwarf_Addr cu_base; /* Current CU base address */ const char *var; /* Current variable name */ char *buf; /* Current output buffer */ int len; /* Length of output buffer */ -- cgit v0.10.2 From 7f5b774275df8c76a959eae7488128b637fcbfc8 Mon Sep 17 00:00:00 2001 From: Lai Jiangshan Date: Tue, 16 Mar 2010 17:00:29 +0800 Subject: rcu: Fix tracepoints & lockdep false positive tracepoint.h uses rcu_dereference(), which triggers this warning: [ 0.701161] =================================================== [ 0.702211] [ INFO: suspicious rcu_dereference_check() usage. ] [ 0.702716] --------------------------------------------------- [ 0.703203] include/trace/events/workqueue.h:68 invoked rcu_dereference_check() without protection! [ 0.703971] [ 0.703990] other info that might help us debug this: [ 0.703993] [ 0.705590] [ 0.705604] rcu_scheduler_active = 1, debug_locks = 0 [ 0.706712] 1 lock held by swapper/1: [ 0.707229] #0: (cpu_add_remove_lock){+.+.+.}, at: [] cpu_maps_update_begin+0x14/0x20 [ 0.710097] [ 0.710106] stack backtrace: [ 0.712602] Pid: 1, comm: swapper Not tainted 2.6.34-rc1-tip-01613-g72662bb #168 [ 0.713231] Call Trace: [ 0.713997] [] lockdep_rcu_dereference+0x9d/0xb0 [ 0.714746] [] create_workqueue_thread+0x107/0x110 [ 0.715353] [] ? worker_thread+0x0/0x340 [ 0.715845] [] __create_workqueue_key+0x138/0x240 [ 0.716427] [] ? cpu_maps_update_done+0x12/0x20 [ 0.717012] [] init_workqueues+0x6f/0x80 [ 0.717530] [] kernel_init+0x102/0x1f0 [ 0.717570] [] ? kernel_init+0x0/0x1f0 [ 0.718944] [] kernel_thread_helper+0x6/0x10 Signed-off-by: Lai Jiangshan Cc: Paul E. McKenney Cc: Mathieu Desnoyers Cc: Steven Rostedt Cc: Frederic Weisbecker LKML-Reference: <4B9F48AD.4000404@cn.fujitsu.com> Signed-off-by: Ingo Molnar diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index f59604e..78b4bd3 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h @@ -49,7 +49,7 @@ struct tracepoint { void **it_func; \ \ rcu_read_lock_sched_notrace(); \ - it_func = rcu_dereference((tp)->funcs); \ + it_func = rcu_dereference_sched((tp)->funcs); \ if (it_func) { \ do { \ ((void(*)(proto))(*it_func))(args); \ -- cgit v0.10.2 From c890692bf37671b5b78a1870d55d6d87e1c8a509 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 11 Mar 2010 14:08:43 -0800 Subject: kernel/sched.c: Suppress unused var warning On UP: kernel/sched.c: In function 'wake_up_new_task': kernel/sched.c:2631: warning: unused variable 'cpu' Signed-off-by: Andrew Morton Cc: Peter Zijlstra Signed-off-by: Ingo Molnar diff --git a/kernel/sched.c b/kernel/sched.c index 6eaef3d..82975b5 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2650,7 +2650,7 @@ void wake_up_new_task(struct task_struct *p, unsigned long clone_flags) { unsigned long flags; struct rq *rq; - int cpu = get_cpu(); + int cpu __maybe_unused = get_cpu(); #ifdef CONFIG_SMP /* -- cgit v0.10.2 From ff30a0543e9a6cd732582063e7cae951cdb7acf2 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Mon, 15 Mar 2010 10:11:15 +0000 Subject: x86: Fix placement of FIX_OHCI1394_BASE Ever for 32-bit with sufficiently high NR_CPUS, and starting with commit 789d03f584484af85dbdc64935270c8e45f36ef7 also for 64-bit, the statically allocated early fixmap page tables were not covering FIX_OHCI1394_BASE, leading to a boot time crash when "ohci1394_dma=early" was used. Despite this entry not being a permanently used one, it needs to be moved into the permanent range since it has to be close to FIX_DBGP_BASE and FIX_EARLYCON_MEM_BASE. Reported-bisected-and-tested-by: Justin P. Mattock Fixes-bug: http://bugzilla.kernel.org/show_bug.cgi?id=14487 Signed-off-by: Jan Beulich Cc: # [as far back as long as it still applies] LKML-Reference: <4B9E15D30200007800034D23@vpn.id2.novell.com> Signed-off-by: Ingo Molnar diff --git a/arch/x86/include/asm/fixmap.h b/arch/x86/include/asm/fixmap.h index 635f03b..d07b44f 100644 --- a/arch/x86/include/asm/fixmap.h +++ b/arch/x86/include/asm/fixmap.h @@ -82,6 +82,9 @@ enum fixed_addresses { #endif FIX_DBGP_BASE, FIX_EARLYCON_MEM_BASE, +#ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT + FIX_OHCI1394_BASE, +#endif #ifdef CONFIG_X86_LOCAL_APIC FIX_APIC_BASE, /* local (CPU) APIC) -- required for SMP or not */ #endif @@ -132,9 +135,6 @@ enum fixed_addresses { (__end_of_permanent_fixed_addresses & (TOTAL_FIX_BTMAPS - 1)) : __end_of_permanent_fixed_addresses, FIX_BTMAP_BEGIN = FIX_BTMAP_END + TOTAL_FIX_BTMAPS - 1, -#ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT - FIX_OHCI1394_BASE, -#endif #ifdef CONFIG_X86_32 FIX_WP_TEST, #endif -- cgit v0.10.2 From e639ba481b76e445df354acd6e29d859a9b1657f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bruno=20Pr=C3=A9mont?= Date: Mon, 15 Mar 2010 19:00:27 +0100 Subject: HID: avoid '\0' in hid debugfs events file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When dumping /sys/kernel/debug/hid/$device/events '\0' characters show up (invisible if cat to console but shown by less or while looking at a dump file). These are due to hid_debug_event() adding strlen()+1 bytes to the ring buffer (e.g. including the trailing '\0'). Any roll-over causes a '\0' as well as hid_debug_event() handles the ring buffers with HID_DEBUG_BUFSIZE-1 size while hid_debug_events_read() handles it with full HID_DEBUG_BUFSIZE size. Signed-off-by: Bruno Prémont Signed-off-by: Jiri Kosina diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c index cd4ece6..0c4e755 100644 --- a/drivers/hid/hid-debug.c +++ b/drivers/hid/hid-debug.c @@ -564,10 +564,10 @@ void hid_debug_event(struct hid_device *hdev, char *buf) struct hid_debug_list *list; list_for_each_entry(list, &hdev->debug_list, node) { - for (i = 0; i <= strlen(buf); i++) - list->hid_debug_buf[(list->tail + i) % (HID_DEBUG_BUFSIZE - 1)] = + for (i = 0; i < strlen(buf); i++) + list->hid_debug_buf[(list->tail + i) % HID_DEBUG_BUFSIZE] = buf[i]; - list->tail = (list->tail + i) % (HID_DEBUG_BUFSIZE - 1); + list->tail = (list->tail + i) % HID_DEBUG_BUFSIZE; } } EXPORT_SYMBOL_GPL(hid_debug_event); -- cgit v0.10.2 From 4e06e240dcbb803433ee31bfe89a3e785a77cd3b Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 16 Mar 2010 15:57:44 +0100 Subject: PCMCIA: resource, fix lock imbalance Stanse found that one error path (when alloc_skb fails) in netdev_tx omits to unlock hw_priv->hwlock. Fix that by moving away from unlock in each fail path. Unlock at one place instead. Introduced in 94a819f80297e1f635a7cde4ed5317612e512ba7 (pcmcia: assert locking to struct pcmcia_device) Signed-off-by: Jiri Slaby Signed-off-by: Dominik Brodowski diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index ef782c0..c4612c5 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c @@ -256,6 +256,7 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev, { struct pcmcia_socket *s; config_t *c; + int ret; s = p_dev->socket; @@ -264,13 +265,13 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev, if (!(s->state & SOCKET_PRESENT)) { dev_dbg(&s->dev, "No card present\n"); - mutex_unlock(&s->ops_mutex); - return -ENODEV; + ret = -ENODEV; + goto unlock; } if (!(c->state & CONFIG_LOCKED)) { dev_dbg(&s->dev, "Configuration isnt't locked\n"); - mutex_unlock(&s->ops_mutex); - return -EACCES; + ret = -EACCES; + goto unlock; } if (mod->Attributes & CONF_IRQ_CHANGE_VALID) { @@ -286,7 +287,8 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev, if (mod->Attributes & CONF_VCC_CHANGE_VALID) { dev_dbg(&s->dev, "changing Vcc is not allowed at this time\n"); - return -EINVAL; + ret = -EINVAL; + goto unlock; } /* We only allow changing Vpp1 and Vpp2 to the same value */ @@ -294,21 +296,21 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev, (mod->Attributes & CONF_VPP2_CHANGE_VALID)) { if (mod->Vpp1 != mod->Vpp2) { dev_dbg(&s->dev, "Vpp1 and Vpp2 must be the same\n"); - mutex_unlock(&s->ops_mutex); - return -EINVAL; + ret = -EINVAL; + goto unlock; } s->socket.Vpp = mod->Vpp1; if (s->ops->set_socket(s, &s->socket)) { - mutex_unlock(&s->ops_mutex); dev_printk(KERN_WARNING, &s->dev, "Unable to set VPP\n"); - return -EIO; + ret = -EIO; + goto unlock; } } else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) || (mod->Attributes & CONF_VPP2_CHANGE_VALID)) { dev_dbg(&s->dev, "changing Vcc is not allowed at this time\n"); - mutex_unlock(&s->ops_mutex); - return -EINVAL; + ret = -EINVAL; + goto unlock; } if (mod->Attributes & CONF_IO_CHANGE_WIDTH) { @@ -332,9 +334,11 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev, s->ops->set_io_map(s, &io_on); } } + ret = 0; +unlock: mutex_unlock(&s->ops_mutex); - return 0; + return ret; } /* modify_configuration */ EXPORT_SYMBOL(pcmcia_modify_configuration); -- cgit v0.10.2 From 854d2c3531e6d32e76b94ca5e096ea54c7497e40 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 16 Mar 2010 00:02:25 +0000 Subject: Btrfs: fix search_ioctl key advance key->type is u8, not u64. fs/btrfs/ioctl.c: In function 'copy_to_sk': fs/btrfs/ioctl.c:1024: warning: comparison is always true due to limited range of data type Signed-off-by: Sage Weil Signed-off-by: Chris Mason diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 363e209..38a6886 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -1000,7 +1000,7 @@ static noinline int copy_to_sk(struct btrfs_root *root, advance_key: if (key->offset < (u64)-1) key->offset++; - else if (key->type < (u64)-1) + else if (key->type < (u8)-1) key->type++; else if (key->objectid < (u64)-1) key->objectid++; -- cgit v0.10.2 From ce769a2904bf5a9110ef534a7702397e38e2b3e9 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 16 Mar 2010 00:02:26 +0000 Subject: Btrfs: use __u64 types in ioctl.h Signed-off-by: Sage Weil Signed-off-by: Chris Mason diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h index 81eac0a..424694a 100644 --- a/fs/btrfs/ioctl.h +++ b/fs/btrfs/ioctl.h @@ -127,14 +127,14 @@ struct btrfs_ioctl_defrag_range_args { }; struct btrfs_ioctl_space_info { - u64 flags; - u64 total_bytes; - u64 used_bytes; + __u64 flags; + __u64 total_bytes; + __u64 used_bytes; }; struct btrfs_ioctl_space_args { - u64 space_slots; - u64 total_spaces; + __u64 space_slots; + __u64 total_spaces; struct btrfs_ioctl_space_info spaces[0]; }; -- cgit v0.10.2 From 3f60ebc9d6291863652d564bacc430629271e6a9 Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Thu, 11 Mar 2010 17:45:26 +0200 Subject: wl1251: fix potential crash In case debugfs does not init for some reason (or is disabled on older kernels) driver does not allocate stats.fw_stats structure, but tries to clear it later and trips on a NULL pointer: Unable to handle kernel NULL pointer dereference at virtual address 00000000 PC is at __memzero+0x24/0x80 Backtrace: [] (wl1251_debugfs_reset+0x0/0x30 [wl1251]) [] (wl1251_op_stop+0x0/0x12c [wl1251]) [] (ieee80211_stop_device+0x0/0x74 [mac80211]) [] (ieee80211_stop+0x0/0x4ac [mac80211]) [] (dev_close+0x0/0xb4) [] (dev_change_flags+0x0/0x184) [] (devinet_ioctl+0x0/0x704) [] (inet_ioctl+0x0/0x100) Add a NULL pointer check to fix this. Signed-off-by: Grazvydas Ignotas Acked-by: Kalle Valo Cc: stable@kernel.org Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/wl12xx/wl1251_debugfs.c b/drivers/net/wireless/wl12xx/wl1251_debugfs.c index 0ccba57..05e4d68 100644 --- a/drivers/net/wireless/wl12xx/wl1251_debugfs.c +++ b/drivers/net/wireless/wl12xx/wl1251_debugfs.c @@ -466,7 +466,8 @@ out: void wl1251_debugfs_reset(struct wl1251 *wl) { - memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats)); + if (wl->stats.fw_stats != NULL) + memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats)); wl->stats.retry_count = 0; wl->stats.excessive_retries = 0; } -- cgit v0.10.2 From 4fdec031b9169b3c17938b9c4168f099f457169c Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 12 Mar 2010 04:02:43 +0100 Subject: ath9k: fix BUG_ON triggered by PAE frames When I initially stumbled upon sequence number problems with PAE frames in ath9k, I submitted a patch to remove all special cases for PAE frames and let them go through the normal transmit path. Out of concern about crypto incompatibility issues, this change was merged instead: commit 6c8afef551fef87a3bf24f8a74c69a7f2f72fc82 Author: Sujith Date: Tue Feb 9 10:07:00 2010 +0530 ath9k: Fix sequence numbers for PAE frames After a lot of testing, I'm able to reliably trigger a driver crash on rekeying with current versions with this change in place. It seems that the driver does not support sending out regular MPDUs with the same TID while an A-MPDU session is active. This leads to duplicate entries in the TID Tx buffer, which hits the following BUG_ON in ath_tx_addto_baw(): index = ATH_BA_INDEX(tid->seq_start, bf->bf_seqno); cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1); BUG_ON(tid->tx_buf[cindex] != NULL); I believe until we actually have a reproducible case of an incompatibility with another AP using no PAE special cases, we should simply get rid of this mess. This patch completely fixes my crash issues in STA mode and makes it stay connected without throughput drops or connectivity issues even when the AP is configured to a very short group rekey interval. Signed-off-by: Felix Fietkau Cc: stable@kernel.org Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index b2c8207..294b486 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1353,25 +1353,6 @@ static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb) return htype; } -static bool is_pae(struct sk_buff *skb) -{ - struct ieee80211_hdr *hdr; - __le16 fc; - - hdr = (struct ieee80211_hdr *)skb->data; - fc = hdr->frame_control; - - if (ieee80211_is_data(fc)) { - if (ieee80211_is_nullfunc(fc) || - /* Port Access Entity (IEEE 802.1X) */ - (skb->protocol == cpu_to_be16(ETH_P_PAE))) { - return true; - } - } - - return false; -} - static int get_hw_crypto_keytype(struct sk_buff *skb) { struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); @@ -1696,7 +1677,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, goto tx_done; } - if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && !is_pae(skb)) { + if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { /* * Try aggregation if it's a unicast data frame * and the destination is HT capable. -- cgit v0.10.2 From c8406ea8fa1adde8dc5400127281d497bbcdb84a Mon Sep 17 00:00:00 2001 From: Adel Gadllah Date: Sun, 14 Mar 2010 19:16:25 +0100 Subject: iwlwifi: Silence tfds_in_queue message Commit a239a8b47cc0e5e6d7416a89f340beac06d5edaa introduced a noisy message, that fills up the log very fast. The error seems not to be fatal (the connection is stable and performance is ok), so make it IWL_DEBUG_TX rather than IWL_ERR. Signed-off-by: Adel Gadllah Cc: stable@kernel.org Acked-by: Reinette Chatre Signed-off-by: John W. Linville diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 1ed5206..8c12311 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -124,7 +124,7 @@ void iwl_free_tfds_in_queue(struct iwl_priv *priv, if (priv->stations[sta_id].tid[tid].tfds_in_queue >= freed) priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; else { - IWL_ERR(priv, "free more than tfds_in_queue (%u:%d)\n", + IWL_DEBUG_TX(priv, "free more than tfds_in_queue (%u:%d)\n", priv->stations[sta_id].tid[tid].tfds_in_queue, freed); priv->stations[sta_id].tid[tid].tfds_in_queue = 0; -- cgit v0.10.2 From 7fde62bffb576d384ea49a3aed3403d5609ee5bc Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Tue, 16 Mar 2010 15:40:10 -0400 Subject: Btrfs: buffer results in the space_info ioctl The space_info ioctl was using copy_to_user inside rcu_read_lock. This commit changes things to copy into a buffer first and then dump the result down to userland. Signed-off-by: Chris Mason diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 38a6886..4329610 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -1848,39 +1848,74 @@ long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg) struct btrfs_ioctl_space_args space_args; struct btrfs_ioctl_space_info space; struct btrfs_ioctl_space_info *dest; + struct btrfs_ioctl_space_info *dest_orig; + struct btrfs_ioctl_space_info *user_dest; struct btrfs_space_info *info; + int alloc_size; int ret = 0; + int slot_count = 0; if (copy_from_user(&space_args, (struct btrfs_ioctl_space_args __user *)arg, sizeof(space_args))) return -EFAULT; + /* first we count slots */ + rcu_read_lock(); + list_for_each_entry_rcu(info, &root->fs_info->space_info, list) + slot_count++; + rcu_read_unlock(); + + /* space_slots == 0 means they are asking for a count */ + if (space_args.space_slots == 0) { + space_args.total_spaces = slot_count; + goto out; + } + alloc_size = sizeof(*dest) * slot_count; + /* we generally have at most 6 or so space infos, one for each raid + * level. So, a whole page should be more than enough for everyone + */ + if (alloc_size > PAGE_CACHE_SIZE) + return -ENOMEM; + space_args.total_spaces = 0; - dest = (struct btrfs_ioctl_space_info *) - (arg + sizeof(struct btrfs_ioctl_space_args)); + dest = kmalloc(alloc_size, GFP_NOFS); + if (!dest) + return -ENOMEM; + dest_orig = dest; + /* now we have a buffer to copy into */ rcu_read_lock(); list_for_each_entry_rcu(info, &root->fs_info->space_info, list) { - if (!space_args.space_slots) { - space_args.total_spaces++; - continue; - } + /* make sure we don't copy more than we allocated + * in our buffer + */ + if (slot_count == 0) + break; + slot_count--; + + /* make sure userland has enough room in their buffer */ if (space_args.total_spaces >= space_args.space_slots) break; + space.flags = info->flags; space.total_bytes = info->total_bytes; space.used_bytes = info->bytes_used; - if (copy_to_user(dest, &space, sizeof(space))) { - ret = -EFAULT; - break; - } + memcpy(dest, &space, sizeof(space)); dest++; space_args.total_spaces++; } rcu_read_unlock(); - if (copy_to_user(arg, &space_args, sizeof(space_args))) + user_dest = (struct btrfs_ioctl_space_info *) + (arg + sizeof(struct btrfs_ioctl_space_args)); + + if (copy_to_user(user_dest, dest_orig, alloc_size)) + ret = -EFAULT; + + kfree(dest_orig); +out: + if (ret == 0 && copy_to_user(arg, &space_args, sizeof(space_args))) ret = -EFAULT; return ret; -- cgit v0.10.2 From e7fb9c4ad351a8da7c09e182bd2e7ccd043daf08 Mon Sep 17 00:00:00 2001 From: Alberto Panizzo Date: Fri, 18 Dec 2009 16:42:11 +0100 Subject: backlight: Add Epson L4F00242T03 LCD driver The Epson LCD L4F00242T03 is mounted on the Freescale i.MX31 PDK board. Based upon Marek Vasut work in l4f00242t03.c, this driver provides basic init and power on/off functionality for this device through the sysfs lcd interface. Unfortunately Datasheet for this device are not available and all the control sequences sent to the display were copied from the freescale driver that in the i.MX31 Linux BSP. As in the i.MX31PDK board the core and io suppliers are voltage regulators, that functionality is embedded here, but not strict. Signed-off-by: Alberto Panizzo Signed-off-by: Richard Purdie diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index 0c77fc6..c025c84 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -31,6 +31,13 @@ config LCD_CORGI Say y here to support the LCD panels usually found on SHARP corgi (C7x0) and spitz (Cxx00) models. +config LCD_L4F00242T03 + tristate "Epson L4F00242T03 LCD" + depends on LCD_CLASS_DEVICE && SPI_MASTER && GENERIC_GPIO + help + SPI driver for Epson L4F00242T03. This provides basic support + for init and powering the LCD up/down through a sysfs interface. + config LCD_LMS283GF05 tristate "Samsung LMS283GF05 LCD" depends on LCD_CLASS_DEVICE && SPI_MASTER && GENERIC_GPIO diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index 6c704d4..09d1f14 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile @@ -3,6 +3,7 @@ obj-$(CONFIG_LCD_CLASS_DEVICE) += lcd.o obj-$(CONFIG_LCD_CORGI) += corgi_lcd.o obj-$(CONFIG_LCD_HP700) += jornada720_lcd.o +obj-$(CONFIG_LCD_L4F00242T03) += l4f00242t03.o obj-$(CONFIG_LCD_LMS283GF05) += lms283gf05.o obj-$(CONFIG_LCD_LTV350QV) += ltv350qv.o obj-$(CONFIG_LCD_ILI9320) += ili9320.o diff --git a/drivers/video/backlight/l4f00242t03.c b/drivers/video/backlight/l4f00242t03.c new file mode 100644 index 0000000..42d061e --- /dev/null +++ b/drivers/video/backlight/l4f00242t03.c @@ -0,0 +1,256 @@ +/* + * l4f00242t03.c -- support for Epson L4F00242T03 LCD + * + * Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved. + * + * Copyright (c) 2009 Alberto Panizzo + * Inspired by Marek Vasut work in l4f00242t03.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +struct l4f00242t03_priv { + struct spi_device *spi; + struct lcd_device *ld; + int lcd_on:1; + struct regulator *io_reg; + struct regulator *core_reg; +}; + + +static void l4f00242t03_reset(unsigned int gpio) +{ + pr_debug("l4f00242t03_reset.\n"); + gpio_set_value(gpio, 1); + mdelay(100); + gpio_set_value(gpio, 0); + mdelay(10); /* tRES >= 100us */ + gpio_set_value(gpio, 1); + mdelay(20); +} + +#define param(x) ((x) | 0x100) + +static void l4f00242t03_lcd_init(struct spi_device *spi) +{ + struct l4f00242t03_pdata *pdata = spi->dev.platform_data; + struct l4f00242t03_priv *priv = dev_get_drvdata(&spi->dev); + const u16 cmd[] = { 0x36, param(0), 0x3A, param(0x60) }; + + dev_dbg(&spi->dev, "initializing LCD\n"); + + if (priv->io_reg) { + regulator_set_voltage(priv->io_reg, 1800000, 1800000); + regulator_enable(priv->io_reg); + } + + if (priv->core_reg) { + regulator_set_voltage(priv->core_reg, 2800000, 2800000); + regulator_enable(priv->core_reg); + } + + gpio_set_value(pdata->data_enable_gpio, 1); + msleep(60); + spi_write(spi, (const u8 *)cmd, ARRAY_SIZE(cmd) * sizeof(u16)); +} + +static int l4f00242t03_lcd_power_set(struct lcd_device *ld, int power) +{ + struct l4f00242t03_priv *priv = lcd_get_data(ld); + struct spi_device *spi = priv->spi; + + const u16 slpout = 0x11; + const u16 dison = 0x29; + + const u16 slpin = 0x10; + const u16 disoff = 0x28; + + if (power) { + if (priv->lcd_on) + return 0; + + dev_dbg(&spi->dev, "turning on LCD\n"); + + spi_write(spi, (const u8 *)&slpout, sizeof(u16)); + msleep(60); + spi_write(spi, (const u8 *)&dison, sizeof(u16)); + + priv->lcd_on = 1; + } else { + if (!priv->lcd_on) + return 0; + + dev_dbg(&spi->dev, "turning off LCD\n"); + + spi_write(spi, (const u8 *)&disoff, sizeof(u16)); + msleep(60); + spi_write(spi, (const u8 *)&slpin, sizeof(u16)); + + priv->lcd_on = 0; + } + + return 0; +} + +static struct lcd_ops l4f_ops = { + .set_power = l4f00242t03_lcd_power_set, + .get_power = NULL, +}; + +static int __devinit l4f00242t03_probe(struct spi_device *spi) +{ + struct l4f00242t03_priv *priv; + struct l4f00242t03_pdata *pdata = spi->dev.platform_data; + int ret; + + if (pdata == NULL) { + dev_err(&spi->dev, "Uninitialized platform data.\n"); + return -EINVAL; + } + + priv = kzalloc(sizeof(struct l4f00242t03_priv), GFP_KERNEL); + + if (priv == NULL) { + dev_err(&spi->dev, "No memory for this device.\n"); + ret = -ENOMEM; + goto err; + } + + dev_set_drvdata(&spi->dev, priv); + spi->bits_per_word = 9; + spi_setup(spi); + + priv->spi = spi; + + ret = gpio_request(pdata->reset_gpio, "lcd l4f00242t03 reset"); + if (ret) { + dev_err(&spi->dev, + "Unable to get the lcd l4f00242t03 reset gpio.\n"); + return ret; + } + + ret = gpio_direction_output(pdata->reset_gpio, 1); + if (ret) + goto err2; + + ret = gpio_request(pdata->data_enable_gpio, + "lcd l4f00242t03 data enable"); + if (ret) { + dev_err(&spi->dev, + "Unable to get the lcd l4f00242t03 data en gpio.\n"); + return ret; + } + + ret = gpio_direction_output(pdata->data_enable_gpio, 0); + if (ret) + goto err3; + + if (pdata->io_supply) { + priv->io_reg = regulator_get(NULL, pdata->io_supply); + + if (IS_ERR(priv->io_reg)) { + pr_err("%s: Unable to get the IO regulator\n", + __func__); + goto err3; + } + } + + if (pdata->core_supply) { + priv->core_reg = regulator_get(NULL, pdata->core_supply); + + if (IS_ERR(priv->core_reg)) { + pr_err("%s: Unable to get the core regulator\n", + __func__); + goto err4; + } + } + + priv->ld = lcd_device_register("l4f00242t03", + &spi->dev, priv, &l4f_ops); + if (IS_ERR(priv->ld)) { + ret = PTR_ERR(priv->ld); + goto err5; + } + + /* Init the LCD */ + l4f00242t03_reset(pdata->reset_gpio); + l4f00242t03_lcd_init(spi); + l4f00242t03_lcd_power_set(priv->ld, 1); + + dev_info(&spi->dev, "Epson l4f00242t03 lcd probed.\n"); + + return 0; + +err5: + if (priv->core_reg) + regulator_put(priv->core_reg); +err4: + if (priv->io_reg) + regulator_put(priv->io_reg); +err3: + gpio_free(pdata->data_enable_gpio); +err2: + gpio_free(pdata->reset_gpio); +err: + kfree(priv); + + return ret; +} + +static int __devexit l4f00242t03_remove(struct spi_device *spi) +{ + struct l4f00242t03_priv *priv = dev_get_drvdata(&spi->dev); + struct l4f00242t03_pdata *pdata = priv->spi->dev.platform_data; + + l4f00242t03_lcd_power_set(priv->ld, 0); + lcd_device_unregister(priv->ld); + + gpio_free(pdata->data_enable_gpio); + gpio_free(pdata->reset_gpio); + + if (priv->io_reg) + regulator_put(priv->core_reg); + if (priv->core_reg) + regulator_put(priv->io_reg); + + kfree(priv); + + return 0; +} + +static struct spi_driver l4f00242t03_driver = { + .driver = { + .name = "l4f00242t03", + .owner = THIS_MODULE, + }, + .probe = l4f00242t03_probe, + .remove = __devexit_p(l4f00242t03_remove), +}; + +static __init int l4f00242t03_init(void) +{ + return spi_register_driver(&l4f00242t03_driver); +} + +static __exit void l4f00242t03_exit(void) +{ + spi_unregister_driver(&l4f00242t03_driver); +} + +module_init(l4f00242t03_init); +module_exit(l4f00242t03_exit); + +MODULE_AUTHOR("Alberto Panizzo "); +MODULE_DESCRIPTION("EPSON L4F00242T03 LCD"); diff --git a/include/linux/spi/l4f00242t03.h b/include/linux/spi/l4f00242t03.h new file mode 100644 index 0000000..aee1dbd --- /dev/null +++ b/include/linux/spi/l4f00242t03.h @@ -0,0 +1,31 @@ +/* + * l4f00242t03.h -- Platform glue for Epson L4F00242T03 LCD + * + * Copyright (c) 2009 Alberto Panizzo + * Based on Marek Vasut work in lms283gf05.h + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _INCLUDE_LINUX_SPI_L4F00242T03_H_ +#define _INCLUDE_LINUX_SPI_L4F00242T03_H_ + +struct l4f00242t03_pdata { + unsigned int reset_gpio; + unsigned int data_enable_gpio; + const char *io_supply; /* will be set to 1.8 V */ + const char *core_supply; /* will be set to 2.8 V */ +}; + +#endif /* _INCLUDE_LINUX_SPI_L4F00242T03_H_ */ -- cgit v0.10.2 From b4144e4f6e3b448d322095ca08af393682a69e33 Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Mon, 18 Jan 2010 14:16:07 +0000 Subject: backlight: Revert some const qualifiers 9905a43b2d563e6f89e4c63c4278ada03f2ebb14 went a little to far with const qualifiers as there are legitiment cases where the function pointers can change (machine specific setup code for example). Signed-off-by: Richard Purdie diff --git a/include/linux/backlight.h b/include/linux/backlight.h index 8c4f884..ee377d7 100644 --- a/include/linux/backlight.h +++ b/include/linux/backlight.h @@ -36,18 +36,18 @@ struct backlight_device; struct fb_info; struct backlight_ops { - const unsigned int options; + unsigned int options; #define BL_CORE_SUSPENDRESUME (1 << 0) /* Notify the backlight driver some property has changed */ - int (* const update_status)(struct backlight_device *); + int (*update_status)(struct backlight_device *); /* Return the current backlight brightness (accounting for power, fb_blank etc.) */ - int (* const get_brightness)(struct backlight_device *); + int (*get_brightness)(struct backlight_device *); /* Check if given framebuffer device is the one bound to this backlight; return 0 if not, !=0 if it is. If NULL, backlight always matches the fb. */ - int (* const check_fb)(struct fb_info *); + int (*check_fb)(struct fb_info *); }; /* This structure defines all the properties of a backlight */ -- cgit v0.10.2 From c3cf2e44d3bbc694eccef33b0f2fe8e2d89baae7 Mon Sep 17 00:00:00 2001 From: Alberto Panizzo Date: Tue, 19 Jan 2010 09:30:50 +0100 Subject: backlight: l4f00242t03: Fix module licence absence. Signed-off-by: Alberto Panizzo Signed-off-by: Richard Purdie diff --git a/drivers/video/backlight/l4f00242t03.c b/drivers/video/backlight/l4f00242t03.c index 42d061e..74abd69 100644 --- a/drivers/video/backlight/l4f00242t03.c +++ b/drivers/video/backlight/l4f00242t03.c @@ -254,3 +254,4 @@ module_exit(l4f00242t03_exit); MODULE_AUTHOR("Alberto Panizzo "); MODULE_DESCRIPTION("EPSON L4F00242T03 LCD"); +MODULE_LICENSE("GPL v2"); -- cgit v0.10.2 From a4ebb780e194e8751dc22deeabcddd3fdc8f18f0 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 2 Feb 2010 14:44:50 -0800 Subject: video: backlight/progear, fix pci device refcounting Stanse found an ommitted pci_dev_puts on error path in progearbl_probe. pmu_dev and sb_dev are gotten, but never put when backlight_device_register fails. So unify fail paths and put the devs when the failure occurs. Signed-off-by: Jiri Slaby Signed-off-by: Andrew Morton Signed-off-by: Richard Purdie diff --git a/drivers/video/backlight/progear_bl.c b/drivers/video/backlight/progear_bl.c index 075786e..2ec16de 100644 --- a/drivers/video/backlight/progear_bl.c +++ b/drivers/video/backlight/progear_bl.c @@ -63,6 +63,7 @@ static int progearbl_probe(struct platform_device *pdev) { u8 temp; struct backlight_device *progear_backlight_device; + int ret; pmu_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, NULL); if (!pmu_dev) { @@ -73,8 +74,8 @@ static int progearbl_probe(struct platform_device *pdev) sb_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL); if (!sb_dev) { printk("ALI 1533 SB not found.\n"); - pci_dev_put(pmu_dev); - return -ENODEV; + ret = -ENODEV; + goto put_pmu; } /* Set SB_MPS1 to enable brightness control. */ @@ -84,8 +85,10 @@ static int progearbl_probe(struct platform_device *pdev) progear_backlight_device = backlight_device_register("progear-bl", &pdev->dev, NULL, &progearbl_ops); - if (IS_ERR(progear_backlight_device)) - return PTR_ERR(progear_backlight_device); + if (IS_ERR(progear_backlight_device)) { + ret = PTR_ERR(progear_backlight_device); + goto put_sb; + } platform_set_drvdata(pdev, progear_backlight_device); @@ -95,6 +98,11 @@ static int progearbl_probe(struct platform_device *pdev) progearbl_set_intensity(progear_backlight_device); return 0; +put_sb: + pci_dev_put(sb_dev); +put_pmu: + pci_dev_put(pmu_dev); + return ret; } static int progearbl_remove(struct platform_device *pdev) -- cgit v0.10.2 From 57e148b6a975980944f4466ccb669b1d02dfc6a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bruno=20Pr=C3=A9mont?= Date: Sun, 21 Feb 2010 00:20:01 +0100 Subject: backlight: Add backlight_device parameter to check_fb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit check_fb from backlight_ops lacks a reference to the backlight_device that's being referred to. Add this parameter so a backlight_device can be mapped to a single framebuffer, especially if the same driver handles multiple devices on a single system. Signed-off-by: Bruno Prémont Signed-off-by: Richard Purdie diff --git a/drivers/video/backlight/adx_bl.c b/drivers/video/backlight/adx_bl.c index d769b0b..a683dd1 100644 --- a/drivers/video/backlight/adx_bl.c +++ b/drivers/video/backlight/adx_bl.c @@ -56,7 +56,7 @@ static int adx_backlight_get_brightness(struct backlight_device *bldev) return brightness & 0xff; } -static int adx_backlight_check_fb(struct fb_info *fb) +static int adx_backlight_check_fb(struct backlight_device *bldev, struct fb_info *fb) { return 1; } diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index 18829cf..b800cd4 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c @@ -38,7 +38,7 @@ static int fb_notifier_callback(struct notifier_block *self, mutex_lock(&bd->ops_lock); if (bd->ops) if (!bd->ops->check_fb || - bd->ops->check_fb(evdata->info)) { + bd->ops->check_fb(bd, evdata->info)) { bd->props.fb_blank = *(int *)evdata->data; if (bd->props.fb_blank == FB_BLANK_UNBLANK) bd->props.state &= ~BL_CORE_FBBLANK; diff --git a/include/linux/backlight.h b/include/linux/backlight.h index ee377d7..21cd866 100644 --- a/include/linux/backlight.h +++ b/include/linux/backlight.h @@ -47,7 +47,7 @@ struct backlight_ops { int (*get_brightness)(struct backlight_device *); /* Check if given framebuffer device is the one bound to this backlight; return 0 if not, !=0 if it is. If NULL, backlight always matches the fb. */ - int (*check_fb)(struct fb_info *); + int (*check_fb)(struct backlight_device *, struct fb_info *); }; /* This structure defines all the properties of a backlight */ -- cgit v0.10.2 From a19a6ee6cad2b20292a774c2f56ba8039b0fac9c Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Wed, 17 Feb 2010 16:39:44 -0500 Subject: backlight: Allow properties to be passed at registration Values such as max_brightness should be set before backlights are registered, but the current API doesn't allow that. Add a parameter to backlight_device_register and update drivers to ensure that they set this correctly. Signed-off-by: Matthew Garrett Signed-off-by: Richard Purdie diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 2ff2b6ab..cbe6f39 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -998,6 +998,7 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) } if (acpi_video_backlight_support()) { + struct backlight_properties props; int result; static int count = 0; char *name; @@ -1010,12 +1011,14 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) return; sprintf(name, "acpi_video%d", count++); - device->backlight = backlight_device_register(name, - NULL, device, &acpi_backlight_ops); + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = device->brightness->count - 3; + device->backlight = backlight_device_register(name, NULL, device, + &acpi_backlight_ops, + &props); kfree(name); if (IS_ERR(device->backlight)) return; - device->backlight->props.max_brightness = device->brightness->count-3; result = sysfs_create_link(&device->backlight->dev.kobj, &device->dev->dev.kobj, "device"); diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c b/drivers/gpu/drm/nouveau/nouveau_backlight.c index 20564f8..406228f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_backlight.c +++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c @@ -89,19 +89,21 @@ static struct backlight_ops nv50_bl_ops = { static int nouveau_nv40_backlight_init(struct drm_device *dev) { + struct backlight_properties props; struct drm_nouveau_private *dev_priv = dev->dev_private; struct backlight_device *bd; if (!(nv_rd32(dev, NV40_PMC_BACKLIGHT) & NV40_PMC_BACKLIGHT_MASK)) return 0; + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = 31; bd = backlight_device_register("nv_backlight", &dev->pdev->dev, dev, - &nv40_bl_ops); + &nv40_bl_ops, &props); if (IS_ERR(bd)) return PTR_ERR(bd); dev_priv->backlight = bd; - bd->props.max_brightness = 31; bd->props.brightness = nv40_get_intensity(bd); backlight_update_status(bd); @@ -110,19 +112,21 @@ static int nouveau_nv40_backlight_init(struct drm_device *dev) static int nouveau_nv50_backlight_init(struct drm_device *dev) { + struct backlight_properties props; struct drm_nouveau_private *dev_priv = dev->dev_private; struct backlight_device *bd; if (!nv_rd32(dev, NV50_PDISPLAY_SOR_BACKLIGHT)) return 0; + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = 1025; bd = backlight_device_register("nv_backlight", &dev->pdev->dev, dev, - &nv50_bl_ops); + &nv50_bl_ops, &props); if (IS_ERR(bd)) return PTR_ERR(bd); dev_priv->backlight = bd; - bd->props.max_brightness = 1025; bd->props.brightness = nv50_get_intensity(bd); backlight_update_status(bd); return 0; diff --git a/drivers/macintosh/via-pmu-backlight.c b/drivers/macintosh/via-pmu-backlight.c index 4f3c447..1cec02f 100644 --- a/drivers/macintosh/via-pmu-backlight.c +++ b/drivers/macintosh/via-pmu-backlight.c @@ -144,6 +144,7 @@ void pmu_backlight_set_sleep(int sleep) void __init pmu_backlight_init() { + struct backlight_properties props; struct backlight_device *bd; char name[10]; int level, autosave; @@ -161,13 +162,15 @@ void __init pmu_backlight_init() snprintf(name, sizeof(name), "pmubl"); - bd = backlight_device_register(name, NULL, NULL, &pmu_backlight_data); + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = FB_BACKLIGHT_LEVELS - 1; + bd = backlight_device_register(name, NULL, NULL, &pmu_backlight_data, + &props); if (IS_ERR(bd)) { printk(KERN_ERR "PMU Backlight registration failed\n"); return; } uses_pmu_bl = 1; - bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1; pmu_backlight_init_curve(0x7F, 0x46, 0x0E); level = bd->props.max_brightness; diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index 226b3e9..cbca40a 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c @@ -922,9 +922,13 @@ static struct backlight_ops acer_bl_ops = { static int __devinit acer_backlight_init(struct device *dev) { + struct backlight_properties props; struct backlight_device *bd; - bd = backlight_device_register("acer-wmi", dev, NULL, &acer_bl_ops); + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = max_brightness; + bd = backlight_device_register("acer-wmi", dev, NULL, &acer_bl_ops, + &props); if (IS_ERR(bd)) { printk(ACER_ERR "Could not register Acer backlight device\n"); acer_backlight_device = NULL; @@ -935,7 +939,6 @@ static int __devinit acer_backlight_init(struct device *dev) bd->props.power = FB_BLANK_UNBLANK; bd->props.brightness = read_brightness(bd); - bd->props.max_brightness = max_brightness; backlight_update_status(bd); return 0; } diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index 791fcf3..db5f7db 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c @@ -639,12 +639,16 @@ static int asus_backlight_init(struct asus_laptop *asus) { struct backlight_device *bd; struct device *dev = &asus->platform_device->dev; + struct backlight_properties props; if (!acpi_check_handle(asus->handle, METHOD_BRIGHTNESS_GET, NULL) && !acpi_check_handle(asus->handle, METHOD_BRIGHTNESS_SET, NULL) && lcd_switch_handle) { + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = 15; + bd = backlight_device_register(ASUS_LAPTOP_FILE, dev, - asus, &asusbl_ops); + asus, &asusbl_ops, &props); if (IS_ERR(bd)) { pr_err("Could not register asus backlight device\n"); asus->backlight_device = NULL; @@ -653,7 +657,6 @@ static int asus_backlight_init(struct asus_laptop *asus) asus->backlight_device = bd; - bd->props.max_brightness = 15; bd->props.power = FB_BLANK_UNBLANK; bd->props.brightness = asus_read_brightness(bd); backlight_update_status(bd); diff --git a/drivers/platform/x86/asus_acpi.c b/drivers/platform/x86/asus_acpi.c index 1381430..ee52035 100644 --- a/drivers/platform/x86/asus_acpi.c +++ b/drivers/platform/x86/asus_acpi.c @@ -1481,6 +1481,7 @@ static void asus_acpi_exit(void) static int __init asus_acpi_init(void) { + struct backlight_properties props; int result; result = acpi_bus_register_driver(&asus_hotk_driver); @@ -1507,15 +1508,17 @@ static int __init asus_acpi_init(void) return -ENODEV; } + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = 15; asus_backlight_device = backlight_device_register("asus", NULL, NULL, - &asus_backlight_data); + &asus_backlight_data, + &props); if (IS_ERR(asus_backlight_device)) { printk(KERN_ERR "Could not register asus backlight device\n"); asus_backlight_device = NULL; asus_acpi_exit(); return -ENODEV; } - asus_backlight_device->props.max_brightness = 15; return 0; } diff --git a/drivers/platform/x86/classmate-laptop.c b/drivers/platform/x86/classmate-laptop.c index 035a7dd..6670ed8 100644 --- a/drivers/platform/x86/classmate-laptop.c +++ b/drivers/platform/x86/classmate-laptop.c @@ -462,11 +462,13 @@ static struct backlight_ops cmpc_bl_ops = { static int cmpc_bl_add(struct acpi_device *acpi) { + struct backlight_properties props; struct backlight_device *bd; - bd = backlight_device_register("cmpc_bl", &acpi->dev, - acpi->handle, &cmpc_bl_ops); - bd->props.max_brightness = 7; + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = 7; + bd = backlight_device_register("cmpc_bl", &acpi->dev, acpi->handle, + &cmpc_bl_ops, &props); dev_set_drvdata(&acpi->dev, bd); return 0; } diff --git a/drivers/platform/x86/compal-laptop.c b/drivers/platform/x86/compal-laptop.c index 2740b40..71ff154 100644 --- a/drivers/platform/x86/compal-laptop.c +++ b/drivers/platform/x86/compal-laptop.c @@ -291,12 +291,15 @@ static int __init compal_init(void) /* Register backlight stuff */ if (!acpi_video_backlight_support()) { - compalbl_device = backlight_device_register("compal-laptop", NULL, NULL, - &compalbl_ops); + struct backlight_properties props; + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = COMPAL_LCD_LEVEL_MAX - 1; + compalbl_device = backlight_device_register("compal-laptop", + NULL, NULL, + &compalbl_ops, + &props); if (IS_ERR(compalbl_device)) return PTR_ERR(compalbl_device); - - compalbl_device->props.max_brightness = COMPAL_LCD_LEVEL_MAX-1; } ret = platform_driver_register(&compal_driver); diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index ef61497..46435ac 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c @@ -559,10 +559,14 @@ static int __init dell_init(void) release_buffer(); if (max_intensity) { - dell_backlight_device = backlight_device_register( - "dell_backlight", - &platform_device->dev, NULL, - &dell_ops); + struct backlight_properties props; + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = max_intensity; + dell_backlight_device = backlight_device_register("dell_backlight", + &platform_device->dev, + NULL, + &dell_ops, + &props); if (IS_ERR(dell_backlight_device)) { ret = PTR_ERR(dell_backlight_device); @@ -570,7 +574,6 @@ static int __init dell_init(void) goto fail_backlight; } - dell_backlight_device->props.max_brightness = max_intensity; dell_backlight_device->props.brightness = dell_get_intensity(dell_backlight_device); backlight_update_status(dell_backlight_device); diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 9a844ca..3fdf21e 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -1131,18 +1131,20 @@ static int eeepc_backlight_notify(struct eeepc_laptop *eeepc) static int eeepc_backlight_init(struct eeepc_laptop *eeepc) { + struct backlight_properties props; struct backlight_device *bd; + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = 15; bd = backlight_device_register(EEEPC_LAPTOP_FILE, - &eeepc->platform_device->dev, - eeepc, &eeepcbl_ops); + &eeepc->platform_device->dev, eeepc, + &eeepcbl_ops, &props); if (IS_ERR(bd)) { pr_err("Could not register eeepc backlight device\n"); eeepc->backlight_device = NULL; return PTR_ERR(bd); } eeepc->backlight_device = bd; - bd->props.max_brightness = 15; bd->props.brightness = read_brightness(bd); bd->props.power = FB_BLANK_UNBLANK; backlight_update_status(bd); diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c index 5f3320d..c1074b3 100644 --- a/drivers/platform/x86/fujitsu-laptop.c +++ b/drivers/platform/x86/fujitsu-laptop.c @@ -1126,16 +1126,20 @@ static int __init fujitsu_init(void) /* Register backlight stuff */ if (!acpi_video_backlight_support()) { - fujitsu->bl_device = - backlight_device_register("fujitsu-laptop", NULL, NULL, - &fujitsubl_ops); + struct backlight_properties props; + + memset(&props, 0, sizeof(struct backlight_properties)); + max_brightness = fujitsu->max_brightness; + props.max_brightness = max_brightness - 1; + fujitsu->bl_device = backlight_device_register("fujitsu-laptop", + NULL, NULL, + &fujitsubl_ops, + &props); if (IS_ERR(fujitsu->bl_device)) { ret = PTR_ERR(fujitsu->bl_device); fujitsu->bl_device = NULL; goto fail_sysfs_group; } - max_brightness = fujitsu->max_brightness; - fujitsu->bl_device->props.max_brightness = max_brightness - 1; fujitsu->bl_device->props.brightness = fujitsu->brightness_level; } diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c index c2b05da..996223a 100644 --- a/drivers/platform/x86/msi-laptop.c +++ b/drivers/platform/x86/msi-laptop.c @@ -683,11 +683,14 @@ static int __init msi_init(void) printk(KERN_INFO "MSI: Brightness ignored, must be controlled " "by ACPI video driver\n"); } else { + struct backlight_properties props; + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = MSI_LCD_LEVEL_MAX - 1; msibl_device = backlight_device_register("msi-laptop-bl", NULL, - NULL, &msibl_ops); + NULL, &msibl_ops, + &props); if (IS_ERR(msibl_device)) return PTR_ERR(msibl_device); - msibl_device->props.max_brightness = MSI_LCD_LEVEL_MAX-1; } ret = platform_driver_register(&msipf_driver); diff --git a/drivers/platform/x86/msi-wmi.c b/drivers/platform/x86/msi-wmi.c index f5f70d4..fb7ccaa 100644 --- a/drivers/platform/x86/msi-wmi.c +++ b/drivers/platform/x86/msi-wmi.c @@ -249,12 +249,15 @@ static int __init msi_wmi_init(void) goto err_uninstall_notifier; if (!acpi_video_backlight_support()) { - backlight = backlight_device_register(DRV_NAME, - NULL, NULL, &msi_backlight_ops); + struct backlight_properties props; + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = ARRAY_SIZE(backlight_map) - 1; + backlight = backlight_device_register(DRV_NAME, NULL, NULL, + &msi_backlight_ops, + &props); if (IS_ERR(backlight)) goto err_free_input; - backlight->props.max_brightness = ARRAY_SIZE(backlight_map) - 1; err = bl_get(NULL); if (err < 0) goto err_free_backlight; diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c index c9fc479..ab5c9ce 100644 --- a/drivers/platform/x86/panasonic-laptop.c +++ b/drivers/platform/x86/panasonic-laptop.c @@ -600,6 +600,7 @@ static int acpi_pcc_hotkey_resume(struct acpi_device *device) static int acpi_pcc_hotkey_add(struct acpi_device *device) { + struct backlight_properties props; struct pcc_acpi *pcc; int num_sifr, result; @@ -637,24 +638,23 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device) if (result) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error installing keyinput handler\n")); - goto out_sinf; + goto out_hotkey; } - /* initialize backlight */ - pcc->backlight = backlight_device_register("panasonic", NULL, pcc, - &pcc_backlight_ops); - if (IS_ERR(pcc->backlight)) - goto out_input; - if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf)) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Couldn't retrieve BIOS data\n")); - goto out_backlight; + goto out_input; } + /* initialize backlight */ + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = pcc->sinf[SINF_AC_MAX_BRIGHT]; + pcc->backlight = backlight_device_register("panasonic", NULL, pcc, + &pcc_backlight_ops, &props); + if (IS_ERR(pcc->backlight)) + goto out_sinf; /* read the initial brightness setting from the hardware */ - pcc->backlight->props.max_brightness = - pcc->sinf[SINF_AC_MAX_BRIGHT]; pcc->backlight->props.brightness = pcc->sinf[SINF_AC_CUR_BRIGHT]; /* read the initial sticky key mode from the hardware */ @@ -669,12 +669,12 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device) out_backlight: backlight_device_unregister(pcc->backlight); +out_sinf: + kfree(pcc->sinf); out_input: input_unregister_device(pcc->input_dev); /* no need to input_free_device() since core input API refcount and * free()s the device */ -out_sinf: - kfree(pcc->sinf); out_hotkey: kfree(pcc); diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index 5a3d851..6553b91 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c @@ -1291,9 +1291,13 @@ static int sony_nc_add(struct acpi_device *device) "controlled by ACPI video driver\n"); } else if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT", &handle))) { + struct backlight_properties props; + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = SONY_MAX_BRIGHTNESS - 1; sony_backlight_device = backlight_device_register("sony", NULL, NULL, - &sony_backlight_ops); + &sony_backlight_ops, + &props); if (IS_ERR(sony_backlight_device)) { printk(KERN_WARNING DRV_PFX "unable to register backlight device\n"); @@ -1302,8 +1306,6 @@ static int sony_nc_add(struct acpi_device *device) sony_backlight_device->props.brightness = sony_backlight_get_brightness (sony_backlight_device); - sony_backlight_device->props.max_brightness = - SONY_MAX_BRIGHTNESS - 1; } } diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index c64e352..770b853 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -6170,6 +6170,7 @@ static const struct tpacpi_quirk brightness_quirk_table[] __initconst = { static int __init brightness_init(struct ibm_init_struct *iibm) { + struct backlight_properties props; int b; unsigned long quirks; @@ -6259,9 +6260,12 @@ static int __init brightness_init(struct ibm_init_struct *iibm) printk(TPACPI_INFO "detected a 16-level brightness capable ThinkPad\n"); - ibm_backlight_device = backlight_device_register( - TPACPI_BACKLIGHT_DEV_NAME, NULL, NULL, - &ibm_backlight_data); + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = (tp_features.bright_16levels) ? 15 : 7; + ibm_backlight_device = backlight_device_register(TPACPI_BACKLIGHT_DEV_NAME, + NULL, NULL, + &ibm_backlight_data, + &props); if (IS_ERR(ibm_backlight_device)) { int rc = PTR_ERR(ibm_backlight_device); ibm_backlight_device = NULL; @@ -6280,8 +6284,6 @@ static int __init brightness_init(struct ibm_init_struct *iibm) "or not on your ThinkPad\n", TPACPI_MAIL); } - ibm_backlight_device->props.max_brightness = - (tp_features.bright_16levels)? 15 : 7; ibm_backlight_device->props.brightness = b & TP_EC_BACKLIGHT_LVLMSK; backlight_update_status(ibm_backlight_device); diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index 789240d..def4841 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -924,6 +924,7 @@ static int __init toshiba_acpi_init(void) u32 hci_result; bool bt_present; int ret = 0; + struct backlight_properties props; if (acpi_disabled) return -ENODEV; @@ -974,10 +975,12 @@ static int __init toshiba_acpi_init(void) } } + props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1; toshiba_backlight_device = backlight_device_register("toshiba", - &toshiba_acpi.p_dev->dev, - NULL, - &toshiba_backlight_data); + &toshiba_acpi.p_dev->dev, + NULL, + &toshiba_backlight_data, + &props); if (IS_ERR(toshiba_backlight_device)) { ret = PTR_ERR(toshiba_backlight_device); @@ -986,7 +989,6 @@ static int __init toshiba_acpi_init(void) toshiba_acpi_exit(); return ret; } - toshiba_backlight_device->props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1; /* Register rfkill switch for Bluetooth */ if (hci_get_bt_present(&bt_present) == HCI_SUCCESS && bt_present) { diff --git a/drivers/staging/samsung-laptop/samsung-laptop.c b/drivers/staging/samsung-laptop/samsung-laptop.c index dd7ea4c0..eb44b60 100644 --- a/drivers/staging/samsung-laptop/samsung-laptop.c +++ b/drivers/staging/samsung-laptop/samsung-laptop.c @@ -394,6 +394,7 @@ MODULE_DEVICE_TABLE(dmi, samsung_dmi_table); static int __init samsung_init(void) { + struct backlight_properties props; struct sabi_retval sretval; const char *testStr = "SECLINUX"; void __iomem *memcheck; @@ -486,12 +487,14 @@ static int __init samsung_init(void) goto error_no_platform; /* create a backlight device to talk to this one */ + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = MAX_BRIGHT; backlight_device = backlight_device_register("samsung", &sdev->dev, - NULL, &backlight_ops); + NULL, &backlight_ops, + &props); if (IS_ERR(backlight_device)) goto error_no_backlight; - backlight_device->props.max_brightness = MAX_BRIGHT; backlight_device->props.brightness = read_brightness(); backlight_device->props.power = FB_BLANK_UNBLANK; backlight_update_status(backlight_device); diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c index 4d2952f..3adab04 100644 --- a/drivers/usb/misc/appledisplay.c +++ b/drivers/usb/misc/appledisplay.c @@ -202,6 +202,7 @@ static void appledisplay_work(struct work_struct *work) static int appledisplay_probe(struct usb_interface *iface, const struct usb_device_id *id) { + struct backlight_properties props; struct appledisplay *pdata; struct usb_device *udev = interface_to_usbdev(iface); struct usb_host_interface *iface_desc; @@ -279,16 +280,16 @@ static int appledisplay_probe(struct usb_interface *iface, /* Register backlight device */ snprintf(bl_name, sizeof(bl_name), "appledisplay%d", atomic_inc_return(&count_displays) - 1); + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = 0xff; pdata->bd = backlight_device_register(bl_name, NULL, pdata, - &appledisplay_bl_data); + &appledisplay_bl_data, &props); if (IS_ERR(pdata->bd)) { dev_err(&iface->dev, "Backlight registration failed\n"); retval = PTR_ERR(pdata->bd); goto error; } - pdata->bd->props.max_brightness = 0xff; - /* Try to get brightness */ brightness = appledisplay_bl_get_brightness(pdata->bd); diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index 3d886c6..11de3bf 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c @@ -117,6 +117,7 @@ static struct backlight_ops atmel_lcdc_bl_ops = { static void init_backlight(struct atmel_lcdfb_info *sinfo) { + struct backlight_properties props; struct backlight_device *bl; sinfo->bl_power = FB_BLANK_UNBLANK; @@ -124,8 +125,10 @@ static void init_backlight(struct atmel_lcdfb_info *sinfo) if (sinfo->backlight) return; - bl = backlight_device_register("backlight", &sinfo->pdev->dev, - sinfo, &atmel_lcdc_bl_ops); + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = 0xff; + bl = backlight_device_register("backlight", &sinfo->pdev->dev, sinfo, + &atmel_lcdc_bl_ops, &props); if (IS_ERR(bl)) { dev_err(&sinfo->pdev->dev, "error %ld on backlight register\n", PTR_ERR(bl)); @@ -135,7 +138,6 @@ static void init_backlight(struct atmel_lcdfb_info *sinfo) bl->props.power = FB_BLANK_UNBLANK; bl->props.fb_blank = FB_BLANK_UNBLANK; - bl->props.max_brightness = 0xff; bl->props.brightness = atmel_bl_get_brightness(bl); } diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c index 9ee67d6..a489be0 100644 --- a/drivers/video/aty/aty128fb.c +++ b/drivers/video/aty/aty128fb.c @@ -1802,6 +1802,7 @@ static void aty128_bl_set_power(struct fb_info *info, int power) static void aty128_bl_init(struct aty128fb_par *par) { + struct backlight_properties props; struct fb_info *info = pci_get_drvdata(par->pdev); struct backlight_device *bd; char name[12]; @@ -1817,7 +1818,10 @@ static void aty128_bl_init(struct aty128fb_par *par) snprintf(name, sizeof(name), "aty128bl%d", info->node); - bd = backlight_device_register(name, info->dev, par, &aty128_bl_data); + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = FB_BACKLIGHT_LEVELS - 1; + bd = backlight_device_register(name, info->dev, par, &aty128_bl_data, + &props); if (IS_ERR(bd)) { info->bl_dev = NULL; printk(KERN_WARNING "aty128: Backlight registration failed\n"); @@ -1829,7 +1833,6 @@ static void aty128_bl_init(struct aty128fb_par *par) 63 * FB_BACKLIGHT_MAX / MAX_LEVEL, 219 * FB_BACKLIGHT_MAX / MAX_LEVEL); - bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1; bd->props.brightness = bd->props.max_brightness; bd->props.power = FB_BLANK_UNBLANK; backlight_update_status(bd); diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index e45ab8d..29d7285 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c @@ -2232,6 +2232,7 @@ static struct backlight_ops aty_bl_data = { static void aty_bl_init(struct atyfb_par *par) { + struct backlight_properties props; struct fb_info *info = pci_get_drvdata(par->pdev); struct backlight_device *bd; char name[12]; @@ -2243,7 +2244,10 @@ static void aty_bl_init(struct atyfb_par *par) snprintf(name, sizeof(name), "atybl%d", info->node); - bd = backlight_device_register(name, info->dev, par, &aty_bl_data); + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = FB_BACKLIGHT_LEVELS - 1; + bd = backlight_device_register(name, info->dev, par, &aty_bl_data, + &props); if (IS_ERR(bd)) { info->bl_dev = NULL; printk(KERN_WARNING "aty: Backlight registration failed\n"); @@ -2255,7 +2259,6 @@ static void aty_bl_init(struct atyfb_par *par) 0x3F * FB_BACKLIGHT_MAX / MAX_LEVEL, 0xFF * FB_BACKLIGHT_MAX / MAX_LEVEL); - bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1; bd->props.brightness = bd->props.max_brightness; bd->props.power = FB_BLANK_UNBLANK; backlight_update_status(bd); diff --git a/drivers/video/aty/radeon_backlight.c b/drivers/video/aty/radeon_backlight.c index fa1198c..9fc8c66 100644 --- a/drivers/video/aty/radeon_backlight.c +++ b/drivers/video/aty/radeon_backlight.c @@ -134,6 +134,7 @@ static struct backlight_ops radeon_bl_data = { void radeonfb_bl_init(struct radeonfb_info *rinfo) { + struct backlight_properties props; struct backlight_device *bd; struct radeon_bl_privdata *pdata; char name[12]; @@ -155,7 +156,10 @@ void radeonfb_bl_init(struct radeonfb_info *rinfo) snprintf(name, sizeof(name), "radeonbl%d", rinfo->info->node); - bd = backlight_device_register(name, rinfo->info->dev, pdata, &radeon_bl_data); + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = FB_BACKLIGHT_LEVELS - 1; + bd = backlight_device_register(name, rinfo->info->dev, pdata, + &radeon_bl_data, &props); if (IS_ERR(bd)) { rinfo->info->bl_dev = NULL; printk("radeonfb: Backlight registration failed\n"); @@ -185,7 +189,6 @@ void radeonfb_bl_init(struct radeonfb_info *rinfo) 63 * FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL, 217 * FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL); - bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1; bd->props.brightness = bd->props.max_brightness; bd->props.power = FB_BLANK_UNBLANK; backlight_update_status(bd); diff --git a/drivers/video/backlight/88pm860x_bl.c b/drivers/video/backlight/88pm860x_bl.c index b8f705c..93e25c7 100644 --- a/drivers/video/backlight/88pm860x_bl.c +++ b/drivers/video/backlight/88pm860x_bl.c @@ -187,6 +187,7 @@ static int pm860x_backlight_probe(struct platform_device *pdev) struct pm860x_backlight_data *data; struct backlight_device *bl; struct resource *res; + struct backlight_properties props; unsigned char value; char name[MFD_NAME_SIZE]; int ret; @@ -223,14 +224,15 @@ static int pm860x_backlight_probe(struct platform_device *pdev) return -EINVAL; } + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = MAX_BRIGHTNESS; bl = backlight_device_register(name, &pdev->dev, data, - &pm860x_backlight_ops); + &pm860x_backlight_ops, &props); if (IS_ERR(bl)) { dev_err(&pdev->dev, "failed to register backlight\n"); kfree(data); return PTR_ERR(bl); } - bl->props.max_brightness = MAX_BRIGHTNESS; bl->props.brightness = MAX_BRIGHTNESS; platform_set_drvdata(pdev, bl); diff --git a/drivers/video/backlight/adp5520_bl.c b/drivers/video/backlight/adp5520_bl.c index 86d95c22..5183f0e 100644 --- a/drivers/video/backlight/adp5520_bl.c +++ b/drivers/video/backlight/adp5520_bl.c @@ -278,6 +278,7 @@ static const struct attribute_group adp5520_bl_attr_group = { static int __devinit adp5520_bl_probe(struct platform_device *pdev) { + struct backlight_properties props; struct backlight_device *bl; struct adp5520_bl *data; int ret = 0; @@ -300,17 +301,17 @@ static int __devinit adp5520_bl_probe(struct platform_device *pdev) mutex_init(&data->lock); - bl = backlight_device_register(pdev->name, data->master, - data, &adp5520_bl_ops); + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = ADP5020_MAX_BRIGHTNESS; + bl = backlight_device_register(pdev->name, data->master, data, + &adp5520_bl_ops, &props); if (IS_ERR(bl)) { dev_err(&pdev->dev, "failed to register backlight\n"); kfree(data); return PTR_ERR(bl); } - bl->props.max_brightness = - bl->props.brightness = ADP5020_MAX_BRIGHTNESS; - + bl->props.brightness = ADP5020_MAX_BRIGHTNESS; if (data->pdata->en_ambl_sens) ret = sysfs_create_group(&bl->dev.kobj, &adp5520_bl_attr_group); diff --git a/drivers/video/backlight/adx_bl.c b/drivers/video/backlight/adx_bl.c index a683dd1..b0624b9 100644 --- a/drivers/video/backlight/adx_bl.c +++ b/drivers/video/backlight/adx_bl.c @@ -70,6 +70,7 @@ static const struct backlight_ops adx_backlight_ops = { static int __devinit adx_backlight_probe(struct platform_device *pdev) { + struct backlight_properties props; struct backlight_device *bldev; struct resource *res; struct adxbl *bl; @@ -101,14 +102,15 @@ static int __devinit adx_backlight_probe(struct platform_device *pdev) goto out; } - bldev = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, bl, - &adx_backlight_ops); + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = 0xff; + bldev = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, + bl, &adx_backlight_ops, &props); if (!bldev) { ret = -ENOMEM; goto out; } - bldev->props.max_brightness = 0xff; bldev->props.brightness = 0xff; bldev->props.power = FB_BLANK_UNBLANK; diff --git a/drivers/video/backlight/atmel-pwm-bl.c b/drivers/video/backlight/atmel-pwm-bl.c index f625ffc..2d97605 100644 --- a/drivers/video/backlight/atmel-pwm-bl.c +++ b/drivers/video/backlight/atmel-pwm-bl.c @@ -120,6 +120,7 @@ static const struct backlight_ops atmel_pwm_bl_ops = { static int atmel_pwm_bl_probe(struct platform_device *pdev) { + struct backlight_properties props; const struct atmel_pwm_bl_platform_data *pdata; struct backlight_device *bldev; struct atmel_pwm_bl *pwmbl; @@ -165,8 +166,10 @@ static int atmel_pwm_bl_probe(struct platform_device *pdev) goto err_free_gpio; } - bldev = backlight_device_register("atmel-pwm-bl", - &pdev->dev, pwmbl, &atmel_pwm_bl_ops); + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = pdata->pwm_duty_max - pdata->pwm_duty_min; + bldev = backlight_device_register("atmel-pwm-bl", &pdev->dev, pwmbl, + &atmel_pwm_bl_ops, &props); if (IS_ERR(bldev)) { retval = PTR_ERR(bldev); goto err_free_gpio; @@ -178,7 +181,6 @@ static int atmel_pwm_bl_probe(struct platform_device *pdev) /* Power up the backlight by default at middle intesity. */ bldev->props.power = FB_BLANK_UNBLANK; - bldev->props.max_brightness = pdata->pwm_duty_max - pdata->pwm_duty_min; bldev->props.brightness = bldev->props.max_brightness / 2; retval = atmel_pwm_bl_init_pwm(pwmbl); diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index b800cd4..68bb838 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c @@ -269,7 +269,8 @@ EXPORT_SYMBOL(backlight_force_update); * ERR_PTR() or a pointer to the newly allocated device. */ struct backlight_device *backlight_device_register(const char *name, - struct device *parent, void *devdata, const struct backlight_ops *ops) + struct device *parent, void *devdata, const struct backlight_ops *ops, + const struct backlight_properties *props) { struct backlight_device *new_bd; int rc; @@ -289,6 +290,11 @@ struct backlight_device *backlight_device_register(const char *name, dev_set_name(&new_bd->dev, name); dev_set_drvdata(&new_bd->dev, devdata); + /* Set default properties */ + if (props) + memcpy(&new_bd->props, props, + sizeof(struct backlight_properties)); + rc = device_register(&new_bd->dev); if (rc) { kfree(new_bd); diff --git a/drivers/video/backlight/corgi_lcd.c b/drivers/video/backlight/corgi_lcd.c index b4bcf80..73bdd84 100644 --- a/drivers/video/backlight/corgi_lcd.c +++ b/drivers/video/backlight/corgi_lcd.c @@ -533,6 +533,7 @@ err_free_backlight_on: static int __devinit corgi_lcd_probe(struct spi_device *spi) { + struct backlight_properties props; struct corgi_lcd_platform_data *pdata = spi->dev.platform_data; struct corgi_lcd *lcd; int ret = 0; @@ -559,13 +560,14 @@ static int __devinit corgi_lcd_probe(struct spi_device *spi) lcd->power = FB_BLANK_POWERDOWN; lcd->mode = (pdata) ? pdata->init_mode : CORGI_LCD_MODE_VGA; - lcd->bl_dev = backlight_device_register("corgi_bl", &spi->dev, - lcd, &corgi_bl_ops); + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = pdata->max_intensity; + lcd->bl_dev = backlight_device_register("corgi_bl", &spi->dev, lcd, + &corgi_bl_ops, &props); if (IS_ERR(lcd->bl_dev)) { ret = PTR_ERR(lcd->bl_dev); goto err_unregister_lcd; } - lcd->bl_dev->props.max_brightness = pdata->max_intensity; lcd->bl_dev->props.brightness = pdata->default_intensity; lcd->bl_dev->props.power = FB_BLANK_UNBLANK; diff --git a/drivers/video/backlight/cr_bllcd.c b/drivers/video/backlight/cr_bllcd.c index da86db4..1cce603 100644 --- a/drivers/video/backlight/cr_bllcd.c +++ b/drivers/video/backlight/cr_bllcd.c @@ -170,6 +170,7 @@ static struct lcd_ops cr_lcd_ops = { static int cr_backlight_probe(struct platform_device *pdev) { + struct backlight_properties props; struct backlight_device *bdp; struct lcd_device *ldp; struct cr_panel *crp; @@ -190,8 +191,9 @@ static int cr_backlight_probe(struct platform_device *pdev) return -ENODEV; } - bdp = backlight_device_register("cr-backlight", - &pdev->dev, NULL, &cr_backlight_ops); + memset(&props, 0, sizeof(struct backlight_properties)); + bdp = backlight_device_register("cr-backlight", &pdev->dev, NULL, + &cr_backlight_ops, &props); if (IS_ERR(bdp)) { pci_dev_put(lpc_dev); return PTR_ERR(bdp); @@ -220,9 +222,7 @@ static int cr_backlight_probe(struct platform_device *pdev) crp->cr_lcd_device = ldp; crp->cr_backlight_device->props.power = FB_BLANK_UNBLANK; crp->cr_backlight_device->props.brightness = 0; - crp->cr_backlight_device->props.max_brightness = 0; cr_backlight_set_intensity(crp->cr_backlight_device); - cr_lcd_set_power(crp->cr_lcd_device, FB_BLANK_UNBLANK); platform_set_drvdata(pdev, crp); diff --git a/drivers/video/backlight/da903x_bl.c b/drivers/video/backlight/da903x_bl.c index 74cdc64..686e4a7 100644 --- a/drivers/video/backlight/da903x_bl.c +++ b/drivers/video/backlight/da903x_bl.c @@ -105,6 +105,7 @@ static int da903x_backlight_probe(struct platform_device *pdev) struct da9034_backlight_pdata *pdata = pdev->dev.platform_data; struct da903x_backlight_data *data; struct backlight_device *bl; + struct backlight_properties props; int max_brightness; data = kzalloc(sizeof(*data), GFP_KERNEL); @@ -134,15 +135,15 @@ static int da903x_backlight_probe(struct platform_device *pdev) da903x_write(data->da903x_dev, DA9034_WLED_CONTROL2, DA9034_WLED_ISET(pdata->output_current)); - bl = backlight_device_register(pdev->name, data->da903x_dev, - data, &da903x_backlight_ops); + props.max_brightness = max_brightness; + bl = backlight_device_register(pdev->name, data->da903x_dev, data, + &da903x_backlight_ops, &props); if (IS_ERR(bl)) { dev_err(&pdev->dev, "failed to register backlight\n"); kfree(data); return PTR_ERR(bl); } - bl->props.max_brightness = max_brightness; bl->props.brightness = max_brightness; platform_set_drvdata(pdev, bl); diff --git a/drivers/video/backlight/generic_bl.c b/drivers/video/backlight/generic_bl.c index e6d348e..312ca61 100644 --- a/drivers/video/backlight/generic_bl.c +++ b/drivers/video/backlight/generic_bl.c @@ -78,6 +78,7 @@ static const struct backlight_ops genericbl_ops = { static int genericbl_probe(struct platform_device *pdev) { + struct backlight_properties props; struct generic_bl_info *machinfo = pdev->dev.platform_data; const char *name = "generic-bl"; struct backlight_device *bd; @@ -89,14 +90,15 @@ static int genericbl_probe(struct platform_device *pdev) if (machinfo->name) name = machinfo->name; - bd = backlight_device_register (name, - &pdev->dev, NULL, &genericbl_ops); + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = machinfo->max_intensity; + bd = backlight_device_register(name, &pdev->dev, NULL, &genericbl_ops, + &props); if (IS_ERR (bd)) return PTR_ERR (bd); platform_set_drvdata(pdev, bd); - bd->props.max_brightness = machinfo->max_intensity; bd->props.power = FB_BLANK_UNBLANK; bd->props.brightness = machinfo->default_intensity; backlight_update_status(bd); diff --git a/drivers/video/backlight/hp680_bl.c b/drivers/video/backlight/hp680_bl.c index f7cc528..267d23f 100644 --- a/drivers/video/backlight/hp680_bl.c +++ b/drivers/video/backlight/hp680_bl.c @@ -105,16 +105,18 @@ static const struct backlight_ops hp680bl_ops = { static int __devinit hp680bl_probe(struct platform_device *pdev) { + struct backlight_properties props; struct backlight_device *bd; - bd = backlight_device_register ("hp680-bl", &pdev->dev, NULL, - &hp680bl_ops); + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = HP680_MAX_INTENSITY; + bd = backlight_device_register("hp680-bl", &pdev->dev, NULL, + &hp680bl_ops, &props); if (IS_ERR(bd)) return PTR_ERR(bd); platform_set_drvdata(pdev, bd); - bd->props.max_brightness = HP680_MAX_INTENSITY; bd->props.brightness = HP680_DEFAULT_INTENSITY; hp680bl_send_intensity(bd); diff --git a/drivers/video/backlight/jornada720_bl.c b/drivers/video/backlight/jornada720_bl.c index db9071f..2f177b3 100644 --- a/drivers/video/backlight/jornada720_bl.c +++ b/drivers/video/backlight/jornada720_bl.c @@ -101,10 +101,14 @@ static const struct backlight_ops jornada_bl_ops = { static int jornada_bl_probe(struct platform_device *pdev) { + struct backlight_properties props; int ret; struct backlight_device *bd; - bd = backlight_device_register(S1D_DEVICENAME, &pdev->dev, NULL, &jornada_bl_ops); + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = BL_MAX_BRIGHT; + bd = backlight_device_register(S1D_DEVICENAME, &pdev->dev, NULL, + &jornada_bl_ops, &props); if (IS_ERR(bd)) { ret = PTR_ERR(bd); @@ -117,7 +121,6 @@ static int jornada_bl_probe(struct platform_device *pdev) /* note. make sure max brightness is set otherwise you will get seemingly non-related errors when trying to change brightness */ - bd->props.max_brightness = BL_MAX_BRIGHT; jornada_bl_update_status(bd); platform_set_drvdata(pdev, bd); diff --git a/drivers/video/backlight/kb3886_bl.c b/drivers/video/backlight/kb3886_bl.c index 939e7b8..f439a86 100644 --- a/drivers/video/backlight/kb3886_bl.c +++ b/drivers/video/backlight/kb3886_bl.c @@ -141,20 +141,24 @@ static const struct backlight_ops kb3886bl_ops = { static int kb3886bl_probe(struct platform_device *pdev) { + struct backlight_properties props; struct kb3886bl_machinfo *machinfo = pdev->dev.platform_data; bl_machinfo = machinfo; if (!machinfo->limit_mask) machinfo->limit_mask = -1; + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = machinfo->max_intensity; kb3886_backlight_device = backlight_device_register("kb3886-bl", - &pdev->dev, NULL, &kb3886bl_ops); + &pdev->dev, NULL, + &kb3886bl_ops, + &props); if (IS_ERR(kb3886_backlight_device)) return PTR_ERR(kb3886_backlight_device); platform_set_drvdata(pdev, kb3886_backlight_device); - kb3886_backlight_device->props.max_brightness = machinfo->max_intensity; kb3886_backlight_device->props.power = FB_BLANK_UNBLANK; kb3886_backlight_device->props.brightness = machinfo->default_intensity; backlight_update_status(kb3886_backlight_device); diff --git a/drivers/video/backlight/locomolcd.c b/drivers/video/backlight/locomolcd.c index 00a9591..7571bc2 100644 --- a/drivers/video/backlight/locomolcd.c +++ b/drivers/video/backlight/locomolcd.c @@ -167,6 +167,7 @@ static int locomolcd_resume(struct locomo_dev *dev) static int locomolcd_probe(struct locomo_dev *ldev) { + struct backlight_properties props; unsigned long flags; local_irq_save(flags); @@ -182,13 +183,16 @@ static int locomolcd_probe(struct locomo_dev *ldev) local_irq_restore(flags); - locomolcd_bl_device = backlight_device_register("locomo-bl", &ldev->dev, NULL, &locomobl_data); + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = 4; + locomolcd_bl_device = backlight_device_register("locomo-bl", + &ldev->dev, NULL, + &locomobl_data, &props); if (IS_ERR (locomolcd_bl_device)) return PTR_ERR (locomolcd_bl_device); /* Set up frontlight so that screen is readable */ - locomolcd_bl_device->props.max_brightness = 4, locomolcd_bl_device->props.brightness = 2; locomolcd_set_intensity(locomolcd_bl_device); diff --git a/drivers/video/backlight/max8925_bl.c b/drivers/video/backlight/max8925_bl.c index c267069..c91adaf 100644 --- a/drivers/video/backlight/max8925_bl.c +++ b/drivers/video/backlight/max8925_bl.c @@ -104,6 +104,7 @@ static int __devinit max8925_backlight_probe(struct platform_device *pdev) struct max8925_backlight_pdata *pdata = NULL; struct max8925_backlight_data *data; struct backlight_device *bl; + struct backlight_properties props; struct resource *res; char name[MAX8925_NAME_SIZE]; unsigned char value; @@ -133,14 +134,15 @@ static int __devinit max8925_backlight_probe(struct platform_device *pdev) data->chip = chip; data->current_brightness = 0; + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = MAX_BRIGHTNESS; bl = backlight_device_register(name, &pdev->dev, data, - &max8925_backlight_ops); + &max8925_backlight_ops, &props); if (IS_ERR(bl)) { dev_err(&pdev->dev, "failed to register backlight\n"); kfree(data); return PTR_ERR(bl); } - bl->props.max_brightness = MAX_BRIGHTNESS; bl->props.brightness = MAX_BRIGHTNESS; platform_set_drvdata(pdev, bl); diff --git a/drivers/video/backlight/mbp_nvidia_bl.c b/drivers/video/backlight/mbp_nvidia_bl.c index 2e78b07..0881358 100644 --- a/drivers/video/backlight/mbp_nvidia_bl.c +++ b/drivers/video/backlight/mbp_nvidia_bl.c @@ -250,6 +250,7 @@ static const struct dmi_system_id __initdata mbp_device_table[] = { static int __init mbp_init(void) { + struct backlight_properties props; if (!dmi_check_system(mbp_device_table)) return -ENODEV; @@ -257,14 +258,17 @@ static int __init mbp_init(void) "Macbook Pro backlight")) return -ENXIO; - mbp_backlight_device = backlight_device_register("mbp_backlight", - NULL, NULL, &driver_data->backlight_ops); + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = 15; + mbp_backlight_device = backlight_device_register("mbp_backlight", NULL, + NULL, + &driver_data->backlight_ops, + &props); if (IS_ERR(mbp_backlight_device)) { release_region(driver_data->iostart, driver_data->iolen); return PTR_ERR(mbp_backlight_device); } - mbp_backlight_device->props.max_brightness = 15; mbp_backlight_device->props.brightness = driver_data->backlight_ops.get_brightness(mbp_backlight_device); backlight_update_status(mbp_backlight_device); diff --git a/drivers/video/backlight/omap1_bl.c b/drivers/video/backlight/omap1_bl.c index a3a7f89..333d28e 100644 --- a/drivers/video/backlight/omap1_bl.c +++ b/drivers/video/backlight/omap1_bl.c @@ -132,6 +132,7 @@ static const struct backlight_ops omapbl_ops = { static int omapbl_probe(struct platform_device *pdev) { + struct backlight_properties props; struct backlight_device *dev; struct omap_backlight *bl; struct omap_backlight_config *pdata = pdev->dev.platform_data; @@ -143,7 +144,10 @@ static int omapbl_probe(struct platform_device *pdev) if (unlikely(!bl)) return -ENOMEM; - dev = backlight_device_register("omap-bl", &pdev->dev, bl, &omapbl_ops); + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = OMAPBL_MAX_INTENSITY; + dev = backlight_device_register("omap-bl", &pdev->dev, bl, &omapbl_ops, + &props); if (IS_ERR(dev)) { kfree(bl); return PTR_ERR(dev); @@ -160,7 +164,6 @@ static int omapbl_probe(struct platform_device *pdev) omap_cfg_reg(PWL); /* Conflicts with UART3 */ dev->props.fb_blank = FB_BLANK_UNBLANK; - dev->props.max_brightness = OMAPBL_MAX_INTENSITY; dev->props.brightness = pdata->default_intensity; omapbl_update_status(dev); diff --git a/drivers/video/backlight/progear_bl.c b/drivers/video/backlight/progear_bl.c index 2ec16de..809278c 100644 --- a/drivers/video/backlight/progear_bl.c +++ b/drivers/video/backlight/progear_bl.c @@ -61,6 +61,7 @@ static const struct backlight_ops progearbl_ops = { static int progearbl_probe(struct platform_device *pdev) { + struct backlight_properties props; u8 temp; struct backlight_device *progear_backlight_device; int ret; @@ -82,9 +83,12 @@ static int progearbl_probe(struct platform_device *pdev) pci_read_config_byte(sb_dev, SB_MPS1, &temp); pci_write_config_byte(sb_dev, SB_MPS1, temp | 0x20); + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = HW_LEVEL_MAX - HW_LEVEL_MIN; progear_backlight_device = backlight_device_register("progear-bl", &pdev->dev, NULL, - &progearbl_ops); + &progearbl_ops, + &props); if (IS_ERR(progear_backlight_device)) { ret = PTR_ERR(progear_backlight_device); goto put_sb; @@ -94,7 +98,6 @@ static int progearbl_probe(struct platform_device *pdev) progear_backlight_device->props.power = FB_BLANK_UNBLANK; progear_backlight_device->props.brightness = HW_LEVEL_MAX - HW_LEVEL_MIN; - progear_backlight_device->props.max_brightness = HW_LEVEL_MAX - HW_LEVEL_MIN; progearbl_set_intensity(progear_backlight_device); return 0; diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index 9d2ec2a..b89eebc 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c @@ -65,6 +65,7 @@ static const struct backlight_ops pwm_backlight_ops = { static int pwm_backlight_probe(struct platform_device *pdev) { + struct backlight_properties props; struct platform_pwm_backlight_data *data = pdev->dev.platform_data; struct backlight_device *bl; struct pwm_bl_data *pb; @@ -100,15 +101,16 @@ static int pwm_backlight_probe(struct platform_device *pdev) } else dev_dbg(&pdev->dev, "got pwm for backlight\n"); - bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, - pb, &pwm_backlight_ops); + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = data->max_brightness; + bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, pb, + &pwm_backlight_ops, &props); if (IS_ERR(bl)) { dev_err(&pdev->dev, "failed to register backlight\n"); ret = PTR_ERR(bl); goto err_bl; } - bl->props.max_brightness = data->max_brightness; bl->props.brightness = data->dft_brightness; backlight_update_status(bl); diff --git a/drivers/video/backlight/tosa_bl.c b/drivers/video/backlight/tosa_bl.c index e14ce4d..f57bbf1 100644 --- a/drivers/video/backlight/tosa_bl.c +++ b/drivers/video/backlight/tosa_bl.c @@ -80,6 +80,7 @@ static const struct backlight_ops bl_ops = { static int __devinit tosa_bl_probe(struct i2c_client *client, const struct i2c_device_id *id) { + struct backlight_properties props; struct tosa_bl_data *data = kzalloc(sizeof(struct tosa_bl_data), GFP_KERNEL); int ret = 0; if (!data) @@ -99,15 +100,16 @@ static int __devinit tosa_bl_probe(struct i2c_client *client, i2c_set_clientdata(client, data); data->i2c = client; - data->bl = backlight_device_register("tosa-bl", &client->dev, - data, &bl_ops); + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = 512 - 1; + data->bl = backlight_device_register("tosa-bl", &client->dev, data, + &bl_ops, &props); if (IS_ERR(data->bl)) { ret = PTR_ERR(data->bl); goto err_reg; } data->bl->props.brightness = 69; - data->bl->props.max_brightness = 512 - 1; data->bl->props.power = FB_BLANK_UNBLANK; backlight_update_status(data->bl); diff --git a/drivers/video/backlight/wm831x_bl.c b/drivers/video/backlight/wm831x_bl.c index e32add3..a431270 100644 --- a/drivers/video/backlight/wm831x_bl.c +++ b/drivers/video/backlight/wm831x_bl.c @@ -125,6 +125,7 @@ static int wm831x_backlight_probe(struct platform_device *pdev) struct wm831x_backlight_pdata *pdata; struct wm831x_backlight_data *data; struct backlight_device *bl; + struct backlight_properties props; int ret, i, max_isel, isink_reg, dcdc_cfg; /* We need platform data */ @@ -191,15 +192,15 @@ static int wm831x_backlight_probe(struct platform_device *pdev) data->current_brightness = 0; data->isink_reg = isink_reg; - bl = backlight_device_register("wm831x", &pdev->dev, - data, &wm831x_backlight_ops); + props.max_brightness = max_isel; + bl = backlight_device_register("wm831x", &pdev->dev, data, + &wm831x_backlight_ops, &props); if (IS_ERR(bl)) { dev_err(&pdev->dev, "failed to register backlight\n"); kfree(data); return PTR_ERR(bl); } - bl->props.max_brightness = max_isel; bl->props.brightness = max_isel; platform_set_drvdata(pdev, bl); diff --git a/drivers/video/bf54x-lq043fb.c b/drivers/video/bf54x-lq043fb.c index 814312a..54df3d4 100644 --- a/drivers/video/bf54x-lq043fb.c +++ b/drivers/video/bf54x-lq043fb.c @@ -501,6 +501,7 @@ static irqreturn_t bfin_bf54x_irq_error(int irq, void *dev_id) static int __devinit bfin_bf54x_probe(struct platform_device *pdev) { + struct backlight_properties props; struct bfin_bf54xfb_info *info; struct fb_info *fbinfo; int ret; @@ -645,10 +646,10 @@ static int __devinit bfin_bf54x_probe(struct platform_device *pdev) goto out8; } #ifndef NO_BL_SUPPORT - bl_dev = - backlight_device_register("bf54x-bl", NULL, NULL, - &bfin_lq043fb_bl_ops); - bl_dev->props.max_brightness = 255; + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = 255; + bl_dev = backlight_device_register("bf54x-bl", NULL, NULL, + &bfin_lq043fb_bl_ops, &props); lcd_dev = lcd_device_register(DRIVER_NAME, &pdev->dev, NULL, &bfin_lcd_ops); lcd_dev->props.max_contrast = 255, printk(KERN_INFO "Done.\n"); diff --git a/drivers/video/bfin-t350mcqb-fb.c b/drivers/video/bfin-t350mcqb-fb.c index 5653d08..3a8e811 100644 --- a/drivers/video/bfin-t350mcqb-fb.c +++ b/drivers/video/bfin-t350mcqb-fb.c @@ -419,6 +419,7 @@ static irqreturn_t bfin_t350mcqb_irq_error(int irq, void *dev_id) static int __devinit bfin_t350mcqb_probe(struct platform_device *pdev) { + struct backlight_properties props; struct bfin_t350mcqbfb_info *info; struct fb_info *fbinfo; int ret; @@ -540,10 +541,10 @@ static int __devinit bfin_t350mcqb_probe(struct platform_device *pdev) goto out8; } #ifndef NO_BL_SUPPORT - bl_dev = - backlight_device_register("bf52x-bl", NULL, NULL, - &bfin_lq043fb_bl_ops); - bl_dev->props.max_brightness = 255; + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = 255; + bl_dev = backlight_device_register("bf52x-bl", NULL, NULL, + &bfin_lq043fb_bl_ops, &props); lcd_dev = lcd_device_register(DRIVER_NAME, NULL, &bfin_lcd_ops); lcd_dev->props.max_contrast = 255, printk(KERN_INFO "Done.\n"); diff --git a/drivers/video/nvidia/nv_backlight.c b/drivers/video/nvidia/nv_backlight.c index 443e3c8..2fb552a 100644 --- a/drivers/video/nvidia/nv_backlight.c +++ b/drivers/video/nvidia/nv_backlight.c @@ -94,6 +94,7 @@ static struct backlight_ops nvidia_bl_ops = { void nvidia_bl_init(struct nvidia_par *par) { + struct backlight_properties props; struct fb_info *info = pci_get_drvdata(par->pci_dev); struct backlight_device *bd; char name[12]; @@ -109,7 +110,10 @@ void nvidia_bl_init(struct nvidia_par *par) snprintf(name, sizeof(name), "nvidiabl%d", info->node); - bd = backlight_device_register(name, info->dev, par, &nvidia_bl_ops); + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = FB_BACKLIGHT_LEVELS - 1; + bd = backlight_device_register(name, info->dev, par, &nvidia_bl_ops, + &props); if (IS_ERR(bd)) { info->bl_dev = NULL; printk(KERN_WARNING "nvidia: Backlight registration failed\n"); @@ -121,7 +125,6 @@ void nvidia_bl_init(struct nvidia_par *par) 0x158 * FB_BACKLIGHT_MAX / MAX_LEVEL, 0x534 * FB_BACKLIGHT_MAX / MAX_LEVEL); - bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1; bd->props.brightness = bd->props.max_brightness; bd->props.power = FB_BLANK_UNBLANK; backlight_update_status(bd); diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c index fcd6a61..59769e8 100644 --- a/drivers/video/omap2/displays/panel-taal.c +++ b/drivers/video/omap2/displays/panel-taal.c @@ -486,6 +486,7 @@ static struct attribute_group taal_attr_group = { static int taal_probe(struct omap_dss_device *dssdev) { + struct backlight_properties props; struct taal_data *td; struct backlight_device *bldev; int r; @@ -520,11 +521,16 @@ static int taal_probe(struct omap_dss_device *dssdev) /* if no platform set_backlight() defined, presume DSI backlight * control */ + memset(&props, 0, sizeof(struct backlight_properties)); if (!dssdev->set_backlight) td->use_dsi_bl = true; + if (td->use_dsi_bl) + props.max_brightness = 255; + else + props.max_brightness = 127; bldev = backlight_device_register("taal", &dssdev->dev, dssdev, - &taal_bl_ops); + &taal_bl_ops, &props); if (IS_ERR(bldev)) { r = PTR_ERR(bldev); goto err2; @@ -534,13 +540,10 @@ static int taal_probe(struct omap_dss_device *dssdev) bldev->props.fb_blank = FB_BLANK_UNBLANK; bldev->props.power = FB_BLANK_UNBLANK; - if (td->use_dsi_bl) { - bldev->props.max_brightness = 255; + if (td->use_dsi_bl) bldev->props.brightness = 255; - } else { - bldev->props.max_brightness = 127; + else bldev->props.brightness = 127; - } taal_bl_update_status(bldev); diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c index d94c57f..618f36b 100644 --- a/drivers/video/riva/fbdev.c +++ b/drivers/video/riva/fbdev.c @@ -338,6 +338,7 @@ static struct backlight_ops riva_bl_ops = { static void riva_bl_init(struct riva_par *par) { + struct backlight_properties props; struct fb_info *info = pci_get_drvdata(par->pdev); struct backlight_device *bd; char name[12]; @@ -353,7 +354,10 @@ static void riva_bl_init(struct riva_par *par) snprintf(name, sizeof(name), "rivabl%d", info->node); - bd = backlight_device_register(name, info->dev, par, &riva_bl_ops); + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = FB_BACKLIGHT_LEVELS - 1; + bd = backlight_device_register(name, info->dev, par, &riva_bl_ops, + &props); if (IS_ERR(bd)) { info->bl_dev = NULL; printk(KERN_WARNING "riva: Backlight registration failed\n"); @@ -365,7 +369,6 @@ static void riva_bl_init(struct riva_par *par) MIN_LEVEL * FB_BACKLIGHT_MAX / MAX_LEVEL, FB_BACKLIGHT_MAX); - bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1; bd->props.brightness = bd->props.max_brightness; bd->props.power = FB_BLANK_UNBLANK; backlight_update_status(bd); diff --git a/include/linux/backlight.h b/include/linux/backlight.h index 21cd866..4a3d52e 100644 --- a/include/linux/backlight.h +++ b/include/linux/backlight.h @@ -103,7 +103,8 @@ static inline void backlight_update_status(struct backlight_device *bd) } extern struct backlight_device *backlight_device_register(const char *name, - struct device *dev, void *devdata, const struct backlight_ops *ops); + struct device *dev, void *devdata, const struct backlight_ops *ops, + const struct backlight_properties *props); extern void backlight_device_unregister(struct backlight_device *bd); extern void backlight_force_update(struct backlight_device *bd, enum backlight_update_reason reason); -- cgit v0.10.2 From 936034026280facd7050c96c3b28339f28b09cdd Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Sun, 10 Jan 2010 13:27:54 +0100 Subject: leds: ALIX2: Add dependency to !GPIO_CS5335 The ALIX2 LED driver and the CS5535 GPIO drivers share the same I/O range which causes a conflict if they're both enabled. Fix this for now by adding Kconfig dependencies. While at it, also drop the EXPERIMENTAL flag, as the code has been around for awhile already. Note that this is a hack. At some point, a real platform support for this board should be added which handles the LEDs via the leds-gpio driver. Signed-off-by: Daniel Mack Signed-off-by: Richard Purdie diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index e0b6431..023eda6 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -79,7 +79,7 @@ config LEDS_WRAP config LEDS_ALIX2 tristate "LED Support for ALIX.2 and ALIX.3 series" - depends on LEDS_CLASS && X86 && EXPERIMENTAL + depends on LEDS_CLASS && X86 && !GPIO_CS5535 && !CS5535_GPIO help This option enables support for the PCEngines ALIX.2 and ALIX.3 LEDs. You have to set leds-alix2.force=1 for boards with Award BIOS. -- cgit v0.10.2 From 5e89a3484dea8a3d962f83fe497d064fbcde4e55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20N=C3=A9meth?= Date: Sun, 10 Jan 2010 01:11:03 +0100 Subject: leds: make PCI device id constant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The id_table field of the struct pci_driver is constant in so it is worth to make pci_device_id also constant. The semantic match that finds this kind of pattern is as follows: (http://coccinelle.lip6.fr/) // @r@ disable decl_init,const_decl_init; identifier I1, I2, x; @@ struct I1 { ... const struct I2 *x; ... }; @s@ identifier r.I1, y; identifier r.x, E; @@ struct I1 y = { .x = E, }; @c@ identifier r.I2; identifier s.E; @@ const struct I2 E[] = ... ; @depends on !c@ identifier r.I2; identifier s.E; @@ + const struct I2 E[] = ...; // Signed-off-by: Márton Németh Signed-off-by: Richard Purdie diff --git a/drivers/leds/leds-ss4200.c b/drivers/leds/leds-ss4200.c index 97f0498..51477ec 100644 --- a/drivers/leds/leds-ss4200.c +++ b/drivers/leds/leds-ss4200.c @@ -63,7 +63,7 @@ MODULE_LICENSE("GPL"); /* * PCI ID of the Intel ICH7 LPC Device within which the GPIO block lives. */ -static struct pci_device_id ich7_lpc_pci_id[] = +static const struct pci_device_id ich7_lpc_pci_id[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1) }, -- cgit v0.10.2 From bb9b6ef70f08f256ab4b8ec127c17ee629b85350 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 6 Jan 2010 15:34:55 -0700 Subject: leds: led-class.c - Quiet boot messages As each led device gets registered a kernel message gets printed. In an embedded system with a number of leds this can produce a lot of output that just looks like noise. Change the message type to KERN_DEBUG since it might be useful in the dmesg output "after" booting. Signed-off-by: H Hartley Sweeten Signed-off-by: Richard Purdie diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index 782f958..349e073 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -164,7 +164,7 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) led_trigger_set_default(led_cdev); #endif - printk(KERN_INFO "Registered led device: %s\n", + printk(KERN_DEBUG "Registered led device: %s\n", led_cdev->name); return 0; -- cgit v0.10.2 From d09e16664be88dc8463fe7508a2123460bf6d676 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 20 Jan 2010 16:08:30 -0700 Subject: leds: Kconfig cleanup Remove the need for "depends on LEDS_CLASS" by wrapping the affected config options in an if/endif block. Similar for "depends on LEDS_TRIGGERS". LEDS_COBALT_RAQ still has a "depends on LEDS_CLASS=y" since it cannot be selected to build as a module. Signed-off-by: H Hartley Sweeten Signed-off-by: Richard Purdie diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 023eda6..d86e1a3 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -15,6 +15,8 @@ config LEDS_CLASS This option enables the led sysfs class in /sys/class/leds. You'll need this to do anything useful with LEDs. If unsure, say N. +if LEDS_CLASS + comment "LED drivers" config LEDS_88PM860X @@ -26,73 +28,73 @@ config LEDS_88PM860X config LEDS_ATMEL_PWM tristate "LED Support using Atmel PWM outputs" - depends on LEDS_CLASS && ATMEL_PWM + depends on ATMEL_PWM help This option enables support for LEDs driven using outputs of the dedicated PWM controller found on newer Atmel SOCs. config LEDS_LOCOMO tristate "LED Support for Locomo device" - depends on LEDS_CLASS && SHARP_LOCOMO + depends on SHARP_LOCOMO help This option enables support for the LEDs on Sharp Locomo. Zaurus models SL-5500 and SL-5600. config LEDS_MIKROTIK_RB532 tristate "LED Support for Mikrotik Routerboard 532" - depends on LEDS_CLASS && MIKROTIK_RB532 + depends on MIKROTIK_RB532 help This option enables support for the so called "User LED" of Mikrotik's Routerboard 532. config LEDS_S3C24XX tristate "LED Support for Samsung S3C24XX GPIO LEDs" - depends on LEDS_CLASS && ARCH_S3C2410 + depends on ARCH_S3C2410 help This option enables support for LEDs connected to GPIO lines on Samsung S3C24XX series CPUs, such as the S3C2410 and S3C2440. config LEDS_AMS_DELTA tristate "LED Support for the Amstrad Delta (E3)" - depends on LEDS_CLASS && MACH_AMS_DELTA + depends on MACH_AMS_DELTA help This option enables support for the LEDs on Amstrad Delta (E3). config LEDS_NET48XX tristate "LED Support for Soekris net48xx series Error LED" - depends on LEDS_CLASS && SCx200_GPIO + depends on SCx200_GPIO help This option enables support for the Soekris net4801 and net4826 error LED. config LEDS_FSG tristate "LED Support for the Freecom FSG-3" - depends on LEDS_CLASS && MACH_FSG + depends on MACH_FSG help This option enables support for the LEDs on the Freecom FSG-3. config LEDS_WRAP tristate "LED Support for the WRAP series LEDs" - depends on LEDS_CLASS && SCx200_GPIO + depends on SCx200_GPIO help This option enables support for the PCEngines WRAP programmable LEDs. config LEDS_ALIX2 tristate "LED Support for ALIX.2 and ALIX.3 series" - depends on LEDS_CLASS && X86 && !GPIO_CS5535 && !CS5535_GPIO + depends on X86 && !GPIO_CS5535 && !CS5535_GPIO help This option enables support for the PCEngines ALIX.2 and ALIX.3 LEDs. You have to set leds-alix2.force=1 for boards with Award BIOS. config LEDS_H1940 tristate "LED Support for iPAQ H1940 device" - depends on LEDS_CLASS && ARCH_H1940 + depends on ARCH_H1940 help This option enables support for the LEDs on the h1940. config LEDS_COBALT_QUBE tristate "LED Support for the Cobalt Qube series front LED" - depends on LEDS_CLASS && MIPS_COBALT + depends on MIPS_COBALT help This option enables support for the front LED on Cobalt Qube series @@ -105,7 +107,7 @@ config LEDS_COBALT_RAQ config LEDS_SUNFIRE tristate "LED support for SunFire servers." - depends on LEDS_CLASS && SPARC64 + depends on SPARC64 select LEDS_TRIGGERS help This option enables support for the Left, Middle, and Right @@ -113,14 +115,14 @@ config LEDS_SUNFIRE config LEDS_HP6XX tristate "LED Support for the HP Jornada 6xx" - depends on LEDS_CLASS && SH_HP6XX + depends on SH_HP6XX help This option enables LED support for the handheld HP Jornada 620/660/680/690. config LEDS_PCA9532 tristate "LED driver for PCA9532 dimmer" - depends on LEDS_CLASS && I2C && INPUT && EXPERIMENTAL + depends on I2C && INPUT && EXPERIMENTAL help This option enables support for NXP pca9532 LED controller. It is generally only useful @@ -128,7 +130,7 @@ config LEDS_PCA9532 config LEDS_GPIO tristate "LED Support for GPIO connected LEDs" - depends on LEDS_CLASS && GENERIC_GPIO + depends on GENERIC_GPIO help This option enables support for the LEDs connected to GPIO outputs. To be useful the particular board must have LEDs @@ -155,7 +157,7 @@ config LEDS_GPIO_OF config LEDS_LP3944 tristate "LED Support for N.S. LP3944 (Fun Light) I2C chip" - depends on LEDS_CLASS && I2C + depends on I2C help This option enables support for LEDs connected to the National Semiconductor LP3944 Lighting Management Unit (LMU) also known as @@ -166,7 +168,7 @@ config LEDS_LP3944 config LEDS_CLEVO_MAIL tristate "Mail LED on Clevo notebook" - depends on LEDS_CLASS && X86 && SERIO_I8042 && DMI + depends on X86 && SERIO_I8042 && DMI help This driver makes the mail LED accessible from userspace programs through the leds subsystem. This LED have three @@ -196,7 +198,7 @@ config LEDS_CLEVO_MAIL config LEDS_PCA955X tristate "LED Support for PCA955x I2C chips" - depends on LEDS_CLASS && I2C + depends on I2C help This option enables support for LEDs connected to PCA955x LED driver chips accessed via the I2C bus. Supported @@ -204,54 +206,54 @@ config LEDS_PCA955X config LEDS_WM831X_STATUS tristate "LED support for status LEDs on WM831x PMICs" - depends on LEDS_CLASS && MFD_WM831X + depends on MFD_WM831X help This option enables support for the status LEDs of the WM831x series of PMICs. config LEDS_WM8350 tristate "LED Support for WM8350 AudioPlus PMIC" - depends on LEDS_CLASS && MFD_WM8350 + depends on MFD_WM8350 help This option enables support for LEDs driven by the Wolfson Microelectronics WM8350 AudioPlus PMIC. config LEDS_DA903X tristate "LED Support for DA9030/DA9034 PMIC" - depends on LEDS_CLASS && PMIC_DA903X + depends on PMIC_DA903X help This option enables support for on-chip LED drivers found on Dialog Semiconductor DA9030/DA9034 PMICs. config LEDS_DAC124S085 tristate "LED Support for DAC124S085 SPI DAC" - depends on LEDS_CLASS && SPI + depends on SPI help This option enables support for DAC124S085 SPI DAC from NatSemi, which can be used to control up to four LEDs. config LEDS_PWM tristate "PWM driven LED Support" - depends on LEDS_CLASS && HAVE_PWM + depends on HAVE_PWM help This option enables support for pwm driven LEDs config LEDS_REGULATOR tristate "REGULATOR driven LED support" - depends on LEDS_CLASS && REGULATOR + depends on REGULATOR help This option enables support for regulator driven LEDs. config LEDS_BD2802 tristate "LED driver for BD2802 RGB LED" - depends on LEDS_CLASS && I2C + depends on I2C help This option enables support for BD2802GU RGB LED driver chips accessed via the I2C bus. config LEDS_INTEL_SS4200 tristate "LED driver for Intel NAS SS4200 series" - depends on LEDS_CLASS && PCI && DMI + depends on PCI && DMI help This option enables support for the Intel SS4200 series of Network Attached Storage servers. You may control the hard @@ -260,7 +262,7 @@ config LEDS_INTEL_SS4200 config LEDS_LT3593 tristate "LED driver for LT3593 controllers" - depends on LEDS_CLASS && GENERIC_GPIO + depends on GENERIC_GPIO help This option enables support for LEDs driven by a Linear Technology LT3593 controller. This controller uses a special one-wire pulse @@ -268,7 +270,7 @@ config LEDS_LT3593 config LEDS_ADP5520 tristate "LED Support for ADP5520/ADP5501 PMIC" - depends on LEDS_CLASS && PMIC_ADP5520 + depends on PMIC_ADP5520 help This option enables support for on-chip LED drivers found on Analog Devices ADP5520/ADP5501 PMICs. @@ -276,8 +278,6 @@ config LEDS_ADP5520 To compile this driver as a module, choose M here: the module will be called leds-adp5520. -comment "LED Triggers" - config LEDS_TRIGGERS bool "LED Trigger support" help @@ -285,9 +285,12 @@ config LEDS_TRIGGERS These triggers allow kernel events to drive the LEDs and can be configured via sysfs. If unsure, say Y. +if LEDS_TRIGGERS + +comment "LED Triggers" + config LEDS_TRIGGER_TIMER tristate "LED Timer Trigger" - depends on LEDS_TRIGGERS help This allows LEDs to be controlled by a programmable timer via sysfs. Some LED hardware can be programmed to start @@ -298,14 +301,13 @@ config LEDS_TRIGGER_TIMER config LEDS_TRIGGER_IDE_DISK bool "LED IDE Disk Trigger" - depends on LEDS_TRIGGERS && IDE_GD_ATA + depends on IDE_GD_ATA help This allows LEDs to be controlled by IDE disk activity. If unsure, say Y. config LEDS_TRIGGER_HEARTBEAT tristate "LED Heartbeat Trigger" - depends on LEDS_TRIGGERS help This allows LEDs to be controlled by a CPU load average. The flash frequency is a hyperbolic function of the 1-minute @@ -314,7 +316,6 @@ config LEDS_TRIGGER_HEARTBEAT config LEDS_TRIGGER_BACKLIGHT tristate "LED backlight Trigger" - depends on LEDS_TRIGGERS help This allows LEDs to be controlled as a backlight device: they turn off and on when the display is blanked and unblanked. @@ -323,7 +324,6 @@ config LEDS_TRIGGER_BACKLIGHT config LEDS_TRIGGER_GPIO tristate "LED GPIO Trigger" - depends on LEDS_TRIGGERS depends on GPIOLIB help This allows LEDs to be controlled by gpio events. It's good @@ -336,7 +336,6 @@ config LEDS_TRIGGER_GPIO config LEDS_TRIGGER_DEFAULT_ON tristate "LED Default ON Trigger" - depends on LEDS_TRIGGERS help This allows LEDs to be initialised in the ON state. If unsure, say Y. @@ -344,4 +343,8 @@ config LEDS_TRIGGER_DEFAULT_ON comment "iptables trigger is under Netfilter config (LED target)" depends on LEDS_TRIGGERS +endif # LEDS_TRIGGERS + +endif # LEDS_CLASS + endif # NEW_LEDS -- cgit v0.10.2 From 72dcd8d08aca4ac6154dc37243880ee306c7ea73 Mon Sep 17 00:00:00 2001 From: Bob Rodgers Date: Wed, 17 Feb 2010 15:23:31 -0600 Subject: leds: Add Dell Business Class Netbook LED driver This patch adds an LED driver to support the Dell Activity LED on the Dell Latitude 2100 netbook and future products to come. The Activity LED is visible externally in the lid so classroom instructors can observe it from a distance. The driver uses the sysfs led_class and provides a standard LED interface. Signed-off by: Bob Rodgers Signed-off-by: Louis Davis Signed-off-by: Jim Dailey , Developers Acked-by: Matthew Garrett Acked-by: Dmitry Torokhov Signed-off-by: Richard Purdie diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index d86e1a3..505eb64 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -278,6 +278,13 @@ config LEDS_ADP5520 To compile this driver as a module, choose M here: the module will be called leds-adp5520. +config LEDS_DELL_NETBOOKS + tristate "External LED on Dell Business Netbooks" + depends on X86 && ACPI_WMI + help + This adds support for the Latitude 2100 and similar + notebooks that have an external LED. + config LEDS_TRIGGERS bool "LED Trigger support" help diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index d76fb32..0cd8b99 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -34,6 +34,7 @@ obj-$(CONFIG_LEDS_REGULATOR) += leds-regulator.o obj-$(CONFIG_LEDS_INTEL_SS4200) += leds-ss4200.o obj-$(CONFIG_LEDS_LT3593) += leds-lt3593.o obj-$(CONFIG_LEDS_ADP5520) += leds-adp5520.o +obj-$(CONFIG_LEDS_DELL_NETBOOKS) += dell-led.o # LED SPI Drivers obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o diff --git a/drivers/leds/dell-led.c b/drivers/leds/dell-led.c new file mode 100644 index 0000000..ee31089 --- /dev/null +++ b/drivers/leds/dell-led.c @@ -0,0 +1,200 @@ +/* + * dell_led.c - Dell LED Driver + * + * Copyright (C) 2010 Dell Inc. + * Louis Davis + * Jim Dailey + * + * 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. + * + */ + +#include +#include + +MODULE_AUTHOR("Louis Davis/Jim Dailey"); +MODULE_DESCRIPTION("Dell LED Control Driver"); +MODULE_LICENSE("GPL"); + +#define DELL_LED_BIOS_GUID "F6E4FE6E-909D-47cb-8BAB-C9F6F2F8D396" +MODULE_ALIAS("wmi:" DELL_LED_BIOS_GUID); + +/* Error Result Codes: */ +#define INVALID_DEVICE_ID 250 +#define INVALID_PARAMETER 251 +#define INVALID_BUFFER 252 +#define INTERFACE_ERROR 253 +#define UNSUPPORTED_COMMAND 254 +#define UNSPECIFIED_ERROR 255 + +/* Device ID */ +#define DEVICE_ID_PANEL_BACK 1 + +/* LED Commands */ +#define CMD_LED_ON 16 +#define CMD_LED_OFF 17 +#define CMD_LED_BLINK 18 + +struct bios_args { + unsigned char length; + unsigned char result_code; + unsigned char device_id; + unsigned char command; + unsigned char on_time; + unsigned char off_time; +}; + +static int dell_led_perform_fn(u8 length, + u8 result_code, + u8 device_id, + u8 command, + u8 on_time, + u8 off_time) +{ + struct bios_args *bios_return; + u8 return_code; + union acpi_object *obj; + struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; + struct acpi_buffer input; + acpi_status status; + + struct bios_args args; + args.length = length; + args.result_code = result_code; + args.device_id = device_id; + args.command = command; + args.on_time = on_time; + args.off_time = off_time; + + input.length = sizeof(struct bios_args); + input.pointer = &args; + + status = wmi_evaluate_method(DELL_LED_BIOS_GUID, + 1, + 1, + &input, + &output); + + if (ACPI_FAILURE(status)) + return status; + + obj = output.pointer; + + if (!obj) + return -EINVAL; + else if (obj->type != ACPI_TYPE_BUFFER) { + kfree(obj); + return -EINVAL; + } + + bios_return = ((struct bios_args *)obj->buffer.pointer); + return_code = bios_return->result_code; + + kfree(obj); + + return return_code; +} + +static int led_on(void) +{ + return dell_led_perform_fn(3, /* Length of command */ + INTERFACE_ERROR, /* Init to INTERFACE_ERROR */ + DEVICE_ID_PANEL_BACK, /* Device ID */ + CMD_LED_ON, /* Command */ + 0, /* not used */ + 0); /* not used */ +} + +static int led_off(void) +{ + return dell_led_perform_fn(3, /* Length of command */ + INTERFACE_ERROR, /* Init to INTERFACE_ERROR */ + DEVICE_ID_PANEL_BACK, /* Device ID */ + CMD_LED_OFF, /* Command */ + 0, /* not used */ + 0); /* not used */ +} + +static int led_blink(unsigned char on_eighths, + unsigned char off_eighths) +{ + return dell_led_perform_fn(5, /* Length of command */ + INTERFACE_ERROR, /* Init to INTERFACE_ERROR */ + DEVICE_ID_PANEL_BACK, /* Device ID */ + CMD_LED_BLINK, /* Command */ + on_eighths, /* blink on in eigths of a second */ + off_eighths); /* blink off in eights of a second */ +} + +static void dell_led_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + if (value == LED_OFF) + led_off(); + else + led_on(); +} + +static int dell_led_blink(struct led_classdev *led_cdev, + unsigned long *delay_on, + unsigned long *delay_off) +{ + unsigned long on_eighths; + unsigned long off_eighths; + + /* The Dell LED delay is based on 125ms intervals. + Need to round up to next interval. */ + + on_eighths = (*delay_on + 124) / 125; + if (0 == on_eighths) + on_eighths = 1; + if (on_eighths > 255) + on_eighths = 255; + *delay_on = on_eighths * 125; + + off_eighths = (*delay_off + 124) / 125; + if (0 == off_eighths) + off_eighths = 1; + if (off_eighths > 255) + off_eighths = 255; + *delay_off = off_eighths * 125; + + led_blink(on_eighths, off_eighths); + + return 0; +} + +static struct led_classdev dell_led = { + .name = "dell::lid", + .brightness = LED_OFF, + .max_brightness = 1, + .brightness_set = dell_led_set, + .blink_set = dell_led_blink, + .flags = LED_CORE_SUSPENDRESUME, +}; + +static int __init dell_led_init(void) +{ + int error = 0; + + if (!wmi_has_guid(DELL_LED_BIOS_GUID)) + return -ENODEV; + + error = led_off(); + if (error != 0) + return -ENODEV; + + return led_classdev_register(NULL, &dell_led); +} + +static void __exit dell_led_exit(void) +{ + led_classdev_unregister(&dell_led); + + led_off(); +} + +module_init(dell_led_init); +module_exit(dell_led_exit); -- cgit v0.10.2 From 0493a4ff10959ff4c8e0d65efee25b7ffd4fa5db Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Thu, 11 Mar 2010 13:58:47 -0800 Subject: leds-gpio: fix default state handling on OF platforms The driver wrongly sets default state for LEDs that don't specify default-state property. Currently the driver handles default state this way: memset(&led, 0, sizeof(led)); for_each_child_of_node(np, child) { state = of_get_property(child, "default-state", NULL); if (state) { if (!strcmp(state, "keep")) led.default_state = LEDS_GPIO_DEFSTATE_KEEP; ... } ret = create_gpio_led(&led, ...); } Which means that all LEDs that do not specify default-state will inherit the last value of the default-state property, which is wrong. This patch fixes the issue by moving LED's template initialization into the loop body. Signed-off-by: Anton Vorontsov Signed-off-by: Andrew Morton Signed-off-by: Richard Purdie diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index e5225d2..0823e26 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c @@ -211,7 +211,6 @@ static int __devinit of_gpio_leds_probe(struct of_device *ofdev, const struct of_device_id *match) { struct device_node *np = ofdev->node, *child; - struct gpio_led led; struct gpio_led_of_platform_data *pdata; int count = 0, ret; @@ -226,8 +225,8 @@ static int __devinit of_gpio_leds_probe(struct of_device *ofdev, if (!pdata) return -ENOMEM; - memset(&led, 0, sizeof(led)); for_each_child_of_node(np, child) { + struct gpio_led led = {}; enum of_gpio_flags flags; const char *state; -- cgit v0.10.2 From 36bc5ee6a8d13333980fa54e97d3469d3d4cda98 Mon Sep 17 00:00:00 2001 From: Evan McClain Date: Tue, 9 Mar 2010 19:20:58 -0500 Subject: backlight: mbp_nvidia_bl - add five more MacBook variants This adds the MacBook 1,1 2,1 3,1 4,1 and 4,2 to the DMI tables. Signed-off-by: Evan McClain Signed-off-by: Richard Purdie diff --git a/drivers/video/backlight/mbp_nvidia_bl.c b/drivers/video/backlight/mbp_nvidia_bl.c index 0881358..1b5d3fe 100644 --- a/drivers/video/backlight/mbp_nvidia_bl.c +++ b/drivers/video/backlight/mbp_nvidia_bl.c @@ -139,6 +139,51 @@ static int mbp_dmi_match(const struct dmi_system_id *id) static const struct dmi_system_id __initdata mbp_device_table[] = { { .callback = mbp_dmi_match, + .ident = "MacBook 1,1", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBook1,1"), + }, + .driver_data = (void *)&intel_chipset_data, + }, + { + .callback = mbp_dmi_match, + .ident = "MacBook 2,1", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBook2,1"), + }, + .driver_data = (void *)&intel_chipset_data, + }, + { + .callback = mbp_dmi_match, + .ident = "MacBook 3,1", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBook3,1"), + }, + .driver_data = (void *)&intel_chipset_data, + }, + { + .callback = mbp_dmi_match, + .ident = "MacBook 4,1", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBook4,1"), + }, + .driver_data = (void *)&intel_chipset_data, + }, + { + .callback = mbp_dmi_match, + .ident = "MacBook 4,2", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBook4,2"), + }, + .driver_data = (void *)&intel_chipset_data, + }, + { + .callback = mbp_dmi_match, .ident = "MacBookPro 3,1", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), -- cgit v0.10.2 From f0af78991363d704694a3618b638662c97d8a110 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bruno=20Pr=C3=A9mont?= Date: Fri, 26 Feb 2010 12:59:39 +0100 Subject: backlight: classmate-laptop - Fix missing registration failure handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Check newly registered backlight_device for error and properly return error to parent. Mark struct backlight_ops as const. Signed-off-by: Bruno Prémont Signed-off-by: Richard Purdie diff --git a/drivers/platform/x86/classmate-laptop.c b/drivers/platform/x86/classmate-laptop.c index 6670ed8..c696cf1 100644 --- a/drivers/platform/x86/classmate-laptop.c +++ b/drivers/platform/x86/classmate-laptop.c @@ -455,7 +455,7 @@ static int cmpc_bl_update_status(struct backlight_device *bd) return -1; } -static struct backlight_ops cmpc_bl_ops = { +static const struct backlight_ops cmpc_bl_ops = { .get_brightness = cmpc_bl_get_brightness, .update_status = cmpc_bl_update_status }; @@ -469,6 +469,8 @@ static int cmpc_bl_add(struct acpi_device *acpi) props.max_brightness = 7; bd = backlight_device_register("cmpc_bl", &acpi->dev, acpi->handle, &cmpc_bl_ops, &props); + if (IS_ERR(bd)) + return PTR_ERR(bd); dev_set_drvdata(&acpi->dev, bd); return 0; } -- cgit v0.10.2 From fa11de0a33e214a00e205494c27fb5a7bb71a5fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bruno=20Pr=C3=A9mont?= Date: Fri, 26 Feb 2010 13:04:54 +0100 Subject: backlight: blackfin - Fix missing registration failure handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Check newly registered backlight_device for error and properly return error to parent Mark struct backlight_ops as const. Signed-off-by: Bruno Prémont Acked-by: Mike Frysinger (constify struct backlight_ops) Signed-off-by: Richard Purdie diff --git a/drivers/video/bf54x-lq043fb.c b/drivers/video/bf54x-lq043fb.c index 54df3d4..23b2a8c 100644 --- a/drivers/video/bf54x-lq043fb.c +++ b/drivers/video/bf54x-lq043fb.c @@ -433,7 +433,7 @@ static int bl_get_brightness(struct backlight_device *bd) return 0; } -static struct backlight_ops bfin_lq043fb_bl_ops = { +static const struct backlight_ops bfin_lq043fb_bl_ops = { .get_brightness = bl_get_brightness, }; @@ -650,6 +650,12 @@ static int __devinit bfin_bf54x_probe(struct platform_device *pdev) props.max_brightness = 255; bl_dev = backlight_device_register("bf54x-bl", NULL, NULL, &bfin_lq043fb_bl_ops, &props); + if (IS_ERR(bl_dev)) { + printk(KERN_ERR DRIVER_NAME + ": unable to register backlight.\n"); + ret = -EINVAL; + goto out9; + } lcd_dev = lcd_device_register(DRIVER_NAME, &pdev->dev, NULL, &bfin_lcd_ops); lcd_dev->props.max_contrast = 255, printk(KERN_INFO "Done.\n"); @@ -657,6 +663,8 @@ static int __devinit bfin_bf54x_probe(struct platform_device *pdev) return 0; +out9: + unregister_framebuffer(fbinfo); out8: free_irq(info->irq, info); out7: diff --git a/drivers/video/bfin-t350mcqb-fb.c b/drivers/video/bfin-t350mcqb-fb.c index 3a8e811..31a2dec 100644 --- a/drivers/video/bfin-t350mcqb-fb.c +++ b/drivers/video/bfin-t350mcqb-fb.c @@ -352,7 +352,7 @@ static int bl_get_brightness(struct backlight_device *bd) return 0; } -static struct backlight_ops bfin_lq043fb_bl_ops = { +static const struct backlight_ops bfin_lq043fb_bl_ops = { .get_brightness = bl_get_brightness, }; @@ -545,6 +545,12 @@ static int __devinit bfin_t350mcqb_probe(struct platform_device *pdev) props.max_brightness = 255; bl_dev = backlight_device_register("bf52x-bl", NULL, NULL, &bfin_lq043fb_bl_ops, &props); + if (IS_ERR(bl_dev)) { + printk(KERN_ERR DRIVER_NAME + ": unable to register backlight.\n"); + ret = -EINVAL; + goto out9; + } lcd_dev = lcd_device_register(DRIVER_NAME, NULL, &bfin_lcd_ops); lcd_dev->props.max_contrast = 255, printk(KERN_INFO "Done.\n"); @@ -552,6 +558,8 @@ static int __devinit bfin_t350mcqb_probe(struct platform_device *pdev) return 0; +out9: + unregister_framebuffer(fbinfo); out8: free_irq(info->irq, info); out7: -- cgit v0.10.2 From 28d85873cd6d8d3176e30e02b941b1329df1024c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bruno=20Pr=C3=A9mont?= Date: Fri, 26 Feb 2010 13:17:16 +0100 Subject: backlight: msi-laptop, msi-wmi: fix incomplete registration failure handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Properly return backlight registration error to parent. Mark struct backlight_ops as const. Signed-off-by: Bruno Prémont Reviewed-by: Anisse Astier Signed-off-by: Richard Purdie diff --git a/drivers/platform/x86/msi-wmi.c b/drivers/platform/x86/msi-wmi.c index fb7ccaa..367caaa 100644 --- a/drivers/platform/x86/msi-wmi.c +++ b/drivers/platform/x86/msi-wmi.c @@ -138,7 +138,7 @@ static int bl_set_status(struct backlight_device *bd) return msi_wmi_set_block(0, backlight_map[bright]); } -static struct backlight_ops msi_backlight_ops = { +static const struct backlight_ops msi_backlight_ops = { .get_brightness = bl_get, .update_status = bl_set_status, }; @@ -255,8 +255,10 @@ static int __init msi_wmi_init(void) backlight = backlight_device_register(DRV_NAME, NULL, NULL, &msi_backlight_ops, &props); - if (IS_ERR(backlight)) + if (IS_ERR(backlight)) { + err = PTR_ERR(backlight); goto err_free_input; + } err = bl_get(NULL); if (err < 0) -- cgit v0.10.2 From ec57af9c2ece22ae6234189972105d777ff5f939 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bruno=20Pr=C3=A9mont?= Date: Fri, 26 Feb 2010 13:20:10 +0100 Subject: backlight: panasonic-laptop - Fix incomplete registration failure handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Properly return backlight registration error to parent. Mark struct backlight_ops as const. Signed-off-by: Bruno Prémont Acked-by: Harald Welte (registration failure) Signed-off-by: Richard Purdie diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c index ab5c9ce..726f02a 100644 --- a/drivers/platform/x86/panasonic-laptop.c +++ b/drivers/platform/x86/panasonic-laptop.c @@ -352,7 +352,7 @@ static int bl_set_status(struct backlight_device *bd) return acpi_pcc_write_sset(pcc, SINF_DC_CUR_BRIGHT, bright); } -static struct backlight_ops pcc_backlight_ops = { +static const struct backlight_ops pcc_backlight_ops = { .get_brightness = bl_get, .update_status = bl_set_status, }; @@ -651,8 +651,10 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device) props.max_brightness = pcc->sinf[SINF_AC_MAX_BRIGHT]; pcc->backlight = backlight_device_register("panasonic", NULL, pcc, &pcc_backlight_ops, &props); - if (IS_ERR(pcc->backlight)) + if (IS_ERR(pcc->backlight)) { + result = PTR_ERR(pcc->backlight); goto out_sinf; + } /* read the initial brightness setting from the hardware */ pcc->backlight->props.brightness = pcc->sinf[SINF_AC_CUR_BRIGHT]; -- cgit v0.10.2 From 14b5d6dd40b3091cb5f566568baa4a74dc619286 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Wed, 10 Mar 2010 18:32:18 +0100 Subject: leds: Fix race between LED device uevent and actual attributes creation If we were to dynamically register/unregister leds and have udev or other daemons handle the leds class uevents, we would be notified of the adding of a new LED and if the daemon immediately tries to open one of the attributes of the led device, it would fail with a "no such file or directory" error since this the attributes are not yet created. Fix this by switching attributes to be class-wide, such that the driver core will register these attributes with device_add_attrs and then emit the kobject_uevent ADD signal. Signed-off-by: Fainelli Signed-off-by: Richard Purdie diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index 349e073..69e7d86 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -72,11 +72,14 @@ static ssize_t led_max_brightness_show(struct device *dev, return sprintf(buf, "%u\n", led_cdev->max_brightness); } -static DEVICE_ATTR(brightness, 0644, led_brightness_show, led_brightness_store); -static DEVICE_ATTR(max_brightness, 0444, led_max_brightness_show, NULL); +static struct device_attribute led_class_attrs[] = { + __ATTR(brightness, 0644, led_brightness_show, led_brightness_store), + __ATTR(max_brightness, 0644, led_max_brightness_show, NULL), #ifdef CONFIG_LEDS_TRIGGERS -static DEVICE_ATTR(trigger, 0644, led_trigger_show, led_trigger_store); + __ATTR(trigger, 0644, led_trigger_show, led_trigger_store), #endif + __ATTR_NULL, +}; /** * led_classdev_suspend - suspend an led_classdev. @@ -127,18 +130,11 @@ static int led_resume(struct device *dev) */ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) { - int rc; - led_cdev->dev = device_create(leds_class, parent, 0, led_cdev, "%s", led_cdev->name); if (IS_ERR(led_cdev->dev)) return PTR_ERR(led_cdev->dev); - /* register the attributes */ - rc = device_create_file(led_cdev->dev, &dev_attr_brightness); - if (rc) - goto err_out; - #ifdef CONFIG_LEDS_TRIGGERS init_rwsem(&led_cdev->trigger_lock); #endif @@ -150,17 +146,9 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) if (!led_cdev->max_brightness) led_cdev->max_brightness = LED_FULL; - rc = device_create_file(led_cdev->dev, &dev_attr_max_brightness); - if (rc) - goto err_out_attr_max; - led_update_brightness(led_cdev); #ifdef CONFIG_LEDS_TRIGGERS - rc = device_create_file(led_cdev->dev, &dev_attr_trigger); - if (rc) - goto err_out_led_list; - led_trigger_set_default(led_cdev); #endif @@ -168,18 +156,8 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) led_cdev->name); return 0; - -#ifdef CONFIG_LEDS_TRIGGERS -err_out_led_list: - device_remove_file(led_cdev->dev, &dev_attr_max_brightness); -#endif -err_out_attr_max: - device_remove_file(led_cdev->dev, &dev_attr_brightness); - list_del(&led_cdev->node); -err_out: - device_unregister(led_cdev->dev); - return rc; } + EXPORT_SYMBOL_GPL(led_classdev_register); /** @@ -190,10 +168,7 @@ EXPORT_SYMBOL_GPL(led_classdev_register); */ void led_classdev_unregister(struct led_classdev *led_cdev) { - device_remove_file(led_cdev->dev, &dev_attr_max_brightness); - device_remove_file(led_cdev->dev, &dev_attr_brightness); #ifdef CONFIG_LEDS_TRIGGERS - device_remove_file(led_cdev->dev, &dev_attr_trigger); down_write(&led_cdev->trigger_lock); if (led_cdev->trigger) led_trigger_set(led_cdev, NULL); @@ -215,6 +190,7 @@ static int __init leds_init(void) return PTR_ERR(leds_class); leds_class->suspend = led_suspend; leds_class->resume = led_resume; + leds_class->dev_attrs = led_class_attrs; return 0; } -- cgit v0.10.2 From cd9640a70d542ca026a812ac34733799da0a39c9 Mon Sep 17 00:00:00 2001 From: Alex Elder Date: Tue, 16 Mar 2010 18:55:54 +0000 Subject: xfs: remove old vmap cache Re-apply a commit that had been reverted due to regressions that have since been fixed. Original commit: d2859751cd0bf586941ffa7308635a293f943c17 Author: Nick Piggin Date: Tue, 6 Jan 2009 14:40:44 +1100 XFS's vmap batching simply defers a number (up to 64) of vunmaps, and keeps track of them in a list. To purge the batch, it just goes through the list and calls vunamp on each one. This is pretty poor: a global TLB flush is generally still performed on each vunmap, with the most expensive parts of the operation being the broadcast IPIs and locking involved in the SMP callouts, and the locking involved in the vmap management -- none of these are avoided by just batching up the calls. I'm actually surprised it ever made much difference. (Now that the lazy vmap allocator is upstream, this description is not quite right, but the vunmap batching still doesn't seem to do much). Rip all this logic out of XFS completely. I will improve vmap performance and scalability directly in subsequent patch. Signed-off-by: Nick Piggin Reviewed-by: Christoph Hellwig Signed-off-by: Lachlan McIlroy The only change I made was to use the "new" xfs_buf_is_vmapped() function in a place it had been open-coded in the original. Modified-by: Alex Elder Signed-off-by: Christoph Hellwig Signed-off-by: Alex Elder diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index 6f76ba8..81f4ef2 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c @@ -168,75 +168,6 @@ test_page_region( } /* - * Mapping of multi-page buffers into contiguous virtual space - */ - -typedef struct a_list { - void *vm_addr; - struct a_list *next; -} a_list_t; - -static a_list_t *as_free_head; -static int as_list_len; -static DEFINE_SPINLOCK(as_lock); - -/* - * Try to batch vunmaps because they are costly. - */ -STATIC void -free_address( - void *addr) -{ - a_list_t *aentry; - -#ifdef CONFIG_XEN - /* - * Xen needs to be able to make sure it can get an exclusive - * RO mapping of pages it wants to turn into a pagetable. If - * a newly allocated page is also still being vmap()ed by xfs, - * it will cause pagetable construction to fail. This is a - * quick workaround to always eagerly unmap pages so that Xen - * is happy. - */ - vunmap(addr); - return; -#endif - - aentry = kmalloc(sizeof(a_list_t), GFP_NOWAIT); - if (likely(aentry)) { - spin_lock(&as_lock); - aentry->next = as_free_head; - aentry->vm_addr = addr; - as_free_head = aentry; - as_list_len++; - spin_unlock(&as_lock); - } else { - vunmap(addr); - } -} - -STATIC void -purge_addresses(void) -{ - a_list_t *aentry, *old; - - if (as_free_head == NULL) - return; - - spin_lock(&as_lock); - aentry = as_free_head; - as_free_head = NULL; - as_list_len = 0; - spin_unlock(&as_lock); - - while ((old = aentry) != NULL) { - vunmap(aentry->vm_addr); - aentry = aentry->next; - kfree(old); - } -} - -/* * Internal xfs_buf_t object manipulation */ @@ -337,7 +268,7 @@ xfs_buf_free( uint i; if (xfs_buf_is_vmapped(bp)) - free_address(bp->b_addr - bp->b_offset); + vunmap(bp->b_addr - bp->b_offset); for (i = 0; i < bp->b_page_count; i++) { struct page *page = bp->b_pages[i]; @@ -457,8 +388,6 @@ _xfs_buf_map_pages( bp->b_addr = page_address(bp->b_pages[0]) + bp->b_offset; bp->b_flags |= XBF_MAPPED; } else if (flags & XBF_MAPPED) { - if (as_list_len > 64) - purge_addresses(); bp->b_addr = vmap(bp->b_pages, bp->b_page_count, VM_MAP, PAGE_KERNEL); if (unlikely(bp->b_addr == NULL)) @@ -1955,9 +1884,6 @@ xfsbufd( xfs_buf_iostrategy(bp); count++; } - - if (as_list_len > 0) - purge_addresses(); if (count) blk_run_address_space(target->bt_mapping); -- cgit v0.10.2 From 8a262e573d30187b32b5534ec489446931239cc5 Mon Sep 17 00:00:00 2001 From: Alex Elder Date: Tue, 16 Mar 2010 18:55:56 +0000 Subject: xfs: use scalable vmap API Re-apply a commit that had been reverted due to regressions that have since been fixed. From 95f8e302c04c0b0c6de35ab399a5551605eeb006 Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Tue, 6 Jan 2009 14:43:09 +1100 Implement XFS's large buffer support with the new vmap APIs. See the vmap rewrite (db64fe02) for some numbers. The biggest improvement that comes from using the new APIs is avoiding the global KVA allocation lock on every call. Signed-off-by: Nick Piggin Reviewed-by: Christoph Hellwig Signed-off-by: Lachlan McIlroy Only modifications here were a minor reformat, plus making the patch apply given the new use of xfs_buf_is_vmapped(). Modified-by: Alex Elder Signed-off-by: Christoph Hellwig Signed-off-by: Alex Elder diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index 81f4ef2..bd111b7 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c @@ -268,7 +268,8 @@ xfs_buf_free( uint i; if (xfs_buf_is_vmapped(bp)) - vunmap(bp->b_addr - bp->b_offset); + vm_unmap_ram(bp->b_addr - bp->b_offset, + bp->b_page_count); for (i = 0; i < bp->b_page_count; i++) { struct page *page = bp->b_pages[i]; @@ -388,8 +389,8 @@ _xfs_buf_map_pages( bp->b_addr = page_address(bp->b_pages[0]) + bp->b_offset; bp->b_flags |= XBF_MAPPED; } else if (flags & XBF_MAPPED) { - bp->b_addr = vmap(bp->b_pages, bp->b_page_count, - VM_MAP, PAGE_KERNEL); + bp->b_addr = vm_map_ram(bp->b_pages, bp->b_page_count, + -1, PAGE_KERNEL); if (unlikely(bp->b_addr == NULL)) return -ENOMEM; bp->b_addr += bp->b_offset; -- cgit v0.10.2 From e8c3753ce4cd6a805ebcfdb3aa6d30e6f4b8b3e0 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Mon, 15 Mar 2010 02:36:35 +0000 Subject: xfs: don't warn about page discards on shutdown If we are doing a forced shutdown, we can get lots of noise about delalloc pages being discarded. This is happens by design during a forced shutdown, so don't spam the logs with these messages. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig Signed-off-by: Alex Elder diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 9083357..9962850 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c @@ -932,6 +932,9 @@ xfs_aops_discard_page( if (!xfs_is_delayed_page(page, IOMAP_DELAY)) goto out_invalidate; + if (XFS_FORCED_SHUTDOWN(ip->i_mount)) + goto out_invalidate; + xfs_fs_cmn_err(CE_ALERT, ip->i_mount, "page discard on page %p, inode 0x%llx, offset %llu.", page, ip->i_ino, offset); @@ -964,8 +967,10 @@ xfs_aops_discard_page( if (error) { /* something screwed, just bail */ - xfs_fs_cmn_err(CE_ALERT, ip->i_mount, - "page discard failed delalloc mapping lookup."); + if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) { + xfs_fs_cmn_err(CE_ALERT, ip->i_mount, + "page discard failed delalloc mapping lookup."); + } break; } if (!nimaps) { @@ -991,8 +996,10 @@ xfs_aops_discard_page( ASSERT(!flist.xbf_count && !flist.xbf_first); if (error) { /* something screwed, just bail */ - xfs_fs_cmn_err(CE_ALERT, ip->i_mount, + if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) { + xfs_fs_cmn_err(CE_ALERT, ip->i_mount, "page discard unable to remove delalloc mapping."); + } break; } next_buffer: -- cgit v0.10.2 From 6ad34145cf809384359fe513481d6e16638a57a3 Mon Sep 17 00:00:00 2001 From: Tilman Schmidt Date: Tue, 16 Mar 2010 07:04:01 +0000 Subject: gigaset: correct range checking off by one error Correct a potential array overrun due to an off by one error in the range check on the CAPI CONNECT_REQ CIPValue parameter. Found and reported by Dan Carpenter using smatch. Impact: bugfix Signed-off-by: Tilman Schmidt Signed-off-by: David S. Miller diff --git a/drivers/isdn/gigaset/capi.c b/drivers/isdn/gigaset/capi.c index 4a31962..0220c19 100644 --- a/drivers/isdn/gigaset/capi.c +++ b/drivers/isdn/gigaset/capi.c @@ -1301,7 +1301,7 @@ static void do_connect_req(struct gigaset_capi_ctr *iif, } /* check parameter: CIP Value */ - if (cmsg->CIPValue > ARRAY_SIZE(cip2bchlc) || + if (cmsg->CIPValue >= ARRAY_SIZE(cip2bchlc) || (cmsg->CIPValue > 0 && cip2bchlc[cmsg->CIPValue].bc == NULL)) { dev_notice(cs->dev, "%s: unknown CIP value %d\n", "CONNECT_REQ", cmsg->CIPValue); -- cgit v0.10.2 From edee39321be9f88c47627379e8abadfce0508768 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 16 Mar 2010 04:53:50 +0000 Subject: NET: ksz884x, fix lock imbalance Stanse found that one error path (when alloc_skb fails) in netdev_tx omits to unlock hw_priv->hwlock. Fix that. Signed-off-by: Jiri Slaby Cc: Tristram Ha Cc: David S. Miller Signed-off-by: David S. Miller diff --git a/drivers/net/ksz884x.c b/drivers/net/ksz884x.c index 7264a3e..0f59099 100644 --- a/drivers/net/ksz884x.c +++ b/drivers/net/ksz884x.c @@ -4899,8 +4899,10 @@ static int netdev_tx(struct sk_buff *skb, struct net_device *dev) struct sk_buff *org_skb = skb; skb = dev_alloc_skb(org_skb->len); - if (!skb) - return NETDEV_TX_BUSY; + if (!skb) { + rc = NETDEV_TX_BUSY; + goto unlock; + } skb_copy_and_csum_dev(org_skb, skb->data); org_skb->ip_summed = 0; skb->len = org_skb->len; @@ -4914,7 +4916,7 @@ static int netdev_tx(struct sk_buff *skb, struct net_device *dev) netif_stop_queue(dev); rc = NETDEV_TX_BUSY; } - +unlock: spin_unlock_irq(&hw_priv->hwlock); return rc; -- cgit v0.10.2 From c5e49fb5189dbce00bc37f27c83ab0f9e4748bc6 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Tue, 16 Mar 2010 05:27:40 +0000 Subject: ne: Do not use slashes in irq name string This patch fixes following warning introduced by commit 12bac0d9f4dbf3445a0319beee848d15fa32775e ("proc: warn on non-existing proc entries"): WARNING: at /work/mips-linux/make/linux/fs/proc/generic.c:316 __xlate_proc_name+0xe0/0xe8() name 'RBHMA4X00/RTL8019' Signed-off-by: Atsushi Nemoto Signed-off-by: David S. Miller diff --git a/drivers/net/ne.c b/drivers/net/ne.c index 992dbff..f4347f8 100644 --- a/drivers/net/ne.c +++ b/drivers/net/ne.c @@ -142,7 +142,7 @@ bad_clone_list[] __initdata = { {"PCM-4823", "PCM-4823", {0x00, 0xc0, 0x6c}}, /* Broken Advantech MoBo */ {"REALTEK", "RTL8019", {0x00, 0x00, 0xe8}}, /* no-name with Realtek chip */ #ifdef CONFIG_MACH_TX49XX - {"RBHMA4X00-RTL8019", "RBHMA4X00/RTL8019", {0x00, 0x60, 0x0a}}, /* Toshiba built-in */ + {"RBHMA4X00-RTL8019", "RBHMA4X00-RTL8019", {0x00, 0x60, 0x0a}}, /* Toshiba built-in */ #endif {"LCS-8834", "LCS-8836", {0x04, 0x04, 0x37}}, /* ShinyNet (SET) */ {NULL,} -- cgit v0.10.2 From d0cad871703b898a442e4049c532ec39168e5b57 Mon Sep 17 00:00:00 2001 From: Steve Glendinning Date: Tue, 16 Mar 2010 08:46:46 +0000 Subject: smsc75xx: SMSC LAN75xx USB gigabit ethernet adapter driver This patch adds a driver for SMSC's LAN7500 family of USB 2.0 to gigabit ethernet adapters. It's loosely based on the smsc95xx driver but the device registers for LAN7500 are completely different. Signed-off-by: Steve Glendinning Signed-off-by: David S. Miller diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index 32d9356..ba56ce4 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig @@ -204,6 +204,14 @@ config USB_NET_DM9601 This option adds support for Davicom DM9601 based USB 1.1 10/100 Ethernet adapters. +config USB_NET_SMSC75XX + tristate "SMSC LAN75XX based USB 2.0 gigabit ethernet devices" + depends on USB_USBNET + select CRC32 + help + This option adds support for SMSC LAN95XX based USB 2.0 + Gigabit Ethernet adapters. + config USB_NET_SMSC95XX tristate "SMSC LAN95XX based USB 2.0 10/100 ethernet devices" depends on USB_USBNET diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile index e17afb7..82ea629 100644 --- a/drivers/net/usb/Makefile +++ b/drivers/net/usb/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_USB_NET_AX8817X) += asix.o obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o obj-$(CONFIG_USB_NET_CDC_EEM) += cdc_eem.o obj-$(CONFIG_USB_NET_DM9601) += dm9601.o +obj-$(CONFIG_USB_NET_SMSC75XX) += smsc75xx.o obj-$(CONFIG_USB_NET_SMSC95XX) += smsc95xx.o obj-$(CONFIG_USB_NET_GL620A) += gl620a.o obj-$(CONFIG_USB_NET_NET1080) += net1080.o diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c new file mode 100644 index 0000000..300e3e7 --- /dev/null +++ b/drivers/net/usb/smsc75xx.c @@ -0,0 +1,1288 @@ + /*************************************************************************** + * + * Copyright (C) 2007-2010 SMSC + * + * 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. + * + *****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "smsc75xx.h" + +#define SMSC_CHIPNAME "smsc75xx" +#define SMSC_DRIVER_VERSION "1.0.0" +#define HS_USB_PKT_SIZE (512) +#define FS_USB_PKT_SIZE (64) +#define DEFAULT_HS_BURST_CAP_SIZE (16 * 1024 + 5 * HS_USB_PKT_SIZE) +#define DEFAULT_FS_BURST_CAP_SIZE (6 * 1024 + 33 * FS_USB_PKT_SIZE) +#define DEFAULT_BULK_IN_DELAY (0x00002000) +#define MAX_SINGLE_PACKET_SIZE (9000) +#define LAN75XX_EEPROM_MAGIC (0x7500) +#define EEPROM_MAC_OFFSET (0x01) +#define DEFAULT_TX_CSUM_ENABLE (true) +#define DEFAULT_RX_CSUM_ENABLE (true) +#define DEFAULT_TSO_ENABLE (true) +#define SMSC75XX_INTERNAL_PHY_ID (1) +#define SMSC75XX_TX_OVERHEAD (8) +#define MAX_RX_FIFO_SIZE (20 * 1024) +#define MAX_TX_FIFO_SIZE (12 * 1024) +#define USB_VENDOR_ID_SMSC (0x0424) +#define USB_PRODUCT_ID_LAN7500 (0x7500) +#define USB_PRODUCT_ID_LAN7505 (0x7505) + +#define check_warn(ret, fmt, args...) \ + ({ if (ret < 0) netdev_warn(dev->net, fmt, ##args); }) + +#define check_warn_return(ret, fmt, args...) \ + ({ if (ret < 0) { netdev_warn(dev->net, fmt, ##args); return ret; } }) + +#define check_warn_goto_done(ret, fmt, args...) \ + ({ if (ret < 0) { netdev_warn(dev->net, fmt, ##args); goto done; } }) + +struct smsc75xx_priv { + struct usbnet *dev; + u32 rfe_ctl; + u32 multicast_hash_table[DP_SEL_VHF_HASH_LEN]; + bool use_rx_csum; + struct mutex dataport_mutex; + spinlock_t rfe_ctl_lock; + struct work_struct set_multicast; +}; + +struct usb_context { + struct usb_ctrlrequest req; + struct usbnet *dev; +}; + +static int turbo_mode = true; +module_param(turbo_mode, bool, 0644); +MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction"); + +static int __must_check smsc75xx_read_reg(struct usbnet *dev, u32 index, + u32 *data) +{ + u32 *buf = kmalloc(4, GFP_KERNEL); + int ret; + + BUG_ON(!dev); + + if (!buf) + return -ENOMEM; + + ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), + USB_VENDOR_REQUEST_READ_REGISTER, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 00, index, buf, 4, USB_CTRL_GET_TIMEOUT); + + if (unlikely(ret < 0)) + netdev_warn(dev->net, + "Failed to read register index 0x%08x", index); + + le32_to_cpus(buf); + *data = *buf; + kfree(buf); + + return ret; +} + +static int __must_check smsc75xx_write_reg(struct usbnet *dev, u32 index, + u32 data) +{ + u32 *buf = kmalloc(4, GFP_KERNEL); + int ret; + + BUG_ON(!dev); + + if (!buf) + return -ENOMEM; + + *buf = data; + cpu_to_le32s(buf); + + ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), + USB_VENDOR_REQUEST_WRITE_REGISTER, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 00, index, buf, 4, USB_CTRL_SET_TIMEOUT); + + if (unlikely(ret < 0)) + netdev_warn(dev->net, + "Failed to write register index 0x%08x", index); + + kfree(buf); + + return ret; +} + +/* Loop until the read is completed with timeout + * called with phy_mutex held */ +static int smsc75xx_phy_wait_not_busy(struct usbnet *dev) +{ + unsigned long start_time = jiffies; + u32 val; + int ret; + + do { + ret = smsc75xx_read_reg(dev, MII_ACCESS, &val); + check_warn_return(ret, "Error reading MII_ACCESS"); + + if (!(val & MII_ACCESS_BUSY)) + return 0; + } while (!time_after(jiffies, start_time + HZ)); + + return -EIO; +} + +static int smsc75xx_mdio_read(struct net_device *netdev, int phy_id, int idx) +{ + struct usbnet *dev = netdev_priv(netdev); + u32 val, addr; + int ret; + + mutex_lock(&dev->phy_mutex); + + /* confirm MII not busy */ + ret = smsc75xx_phy_wait_not_busy(dev); + check_warn_goto_done(ret, "MII is busy in smsc75xx_mdio_read"); + + /* set the address, index & direction (read from PHY) */ + phy_id &= dev->mii.phy_id_mask; + idx &= dev->mii.reg_num_mask; + addr = ((phy_id << MII_ACCESS_PHY_ADDR_SHIFT) & MII_ACCESS_PHY_ADDR) + | ((idx << MII_ACCESS_REG_ADDR_SHIFT) & MII_ACCESS_REG_ADDR) + | MII_ACCESS_READ; + ret = smsc75xx_write_reg(dev, MII_ACCESS, addr); + check_warn_goto_done(ret, "Error writing MII_ACCESS"); + + ret = smsc75xx_phy_wait_not_busy(dev); + check_warn_goto_done(ret, "Timed out reading MII reg %02X", idx); + + ret = smsc75xx_read_reg(dev, MII_DATA, &val); + check_warn_goto_done(ret, "Error reading MII_DATA"); + + ret = (u16)(val & 0xFFFF); + +done: + mutex_unlock(&dev->phy_mutex); + return ret; +} + +static void smsc75xx_mdio_write(struct net_device *netdev, int phy_id, int idx, + int regval) +{ + struct usbnet *dev = netdev_priv(netdev); + u32 val, addr; + int ret; + + mutex_lock(&dev->phy_mutex); + + /* confirm MII not busy */ + ret = smsc75xx_phy_wait_not_busy(dev); + check_warn_goto_done(ret, "MII is busy in smsc75xx_mdio_write"); + + val = regval; + ret = smsc75xx_write_reg(dev, MII_DATA, val); + check_warn_goto_done(ret, "Error writing MII_DATA"); + + /* set the address, index & direction (write to PHY) */ + phy_id &= dev->mii.phy_id_mask; + idx &= dev->mii.reg_num_mask; + addr = ((phy_id << MII_ACCESS_PHY_ADDR_SHIFT) & MII_ACCESS_PHY_ADDR) + | ((idx << MII_ACCESS_REG_ADDR_SHIFT) & MII_ACCESS_REG_ADDR) + | MII_ACCESS_WRITE; + ret = smsc75xx_write_reg(dev, MII_ACCESS, addr); + check_warn_goto_done(ret, "Error writing MII_ACCESS"); + + ret = smsc75xx_phy_wait_not_busy(dev); + check_warn_goto_done(ret, "Timed out writing MII reg %02X", idx); + +done: + mutex_unlock(&dev->phy_mutex); +} + +static int smsc75xx_wait_eeprom(struct usbnet *dev) +{ + unsigned long start_time = jiffies; + u32 val; + int ret; + + do { + ret = smsc75xx_read_reg(dev, E2P_CMD, &val); + check_warn_return(ret, "Error reading E2P_CMD"); + + if (!(val & E2P_CMD_BUSY) || (val & E2P_CMD_TIMEOUT)) + break; + udelay(40); + } while (!time_after(jiffies, start_time + HZ)); + + if (val & (E2P_CMD_TIMEOUT | E2P_CMD_BUSY)) { + netdev_warn(dev->net, "EEPROM read operation timeout"); + return -EIO; + } + + return 0; +} + +static int smsc75xx_eeprom_confirm_not_busy(struct usbnet *dev) +{ + unsigned long start_time = jiffies; + u32 val; + int ret; + + do { + ret = smsc75xx_read_reg(dev, E2P_CMD, &val); + check_warn_return(ret, "Error reading E2P_CMD"); + + if (!(val & E2P_CMD_BUSY)) + return 0; + + udelay(40); + } while (!time_after(jiffies, start_time + HZ)); + + netdev_warn(dev->net, "EEPROM is busy"); + return -EIO; +} + +static int smsc75xx_read_eeprom(struct usbnet *dev, u32 offset, u32 length, + u8 *data) +{ + u32 val; + int i, ret; + + BUG_ON(!dev); + BUG_ON(!data); + + ret = smsc75xx_eeprom_confirm_not_busy(dev); + if (ret) + return ret; + + for (i = 0; i < length; i++) { + val = E2P_CMD_BUSY | E2P_CMD_READ | (offset & E2P_CMD_ADDR); + ret = smsc75xx_write_reg(dev, E2P_CMD, val); + check_warn_return(ret, "Error writing E2P_CMD"); + + ret = smsc75xx_wait_eeprom(dev); + if (ret < 0) + return ret; + + ret = smsc75xx_read_reg(dev, E2P_DATA, &val); + check_warn_return(ret, "Error reading E2P_DATA"); + + data[i] = val & 0xFF; + offset++; + } + + return 0; +} + +static int smsc75xx_write_eeprom(struct usbnet *dev, u32 offset, u32 length, + u8 *data) +{ + u32 val; + int i, ret; + + BUG_ON(!dev); + BUG_ON(!data); + + ret = smsc75xx_eeprom_confirm_not_busy(dev); + if (ret) + return ret; + + /* Issue write/erase enable command */ + val = E2P_CMD_BUSY | E2P_CMD_EWEN; + ret = smsc75xx_write_reg(dev, E2P_CMD, val); + check_warn_return(ret, "Error writing E2P_CMD"); + + ret = smsc75xx_wait_eeprom(dev); + if (ret < 0) + return ret; + + for (i = 0; i < length; i++) { + + /* Fill data register */ + val = data[i]; + ret = smsc75xx_write_reg(dev, E2P_DATA, val); + check_warn_return(ret, "Error writing E2P_DATA"); + + /* Send "write" command */ + val = E2P_CMD_BUSY | E2P_CMD_WRITE | (offset & E2P_CMD_ADDR); + ret = smsc75xx_write_reg(dev, E2P_CMD, val); + check_warn_return(ret, "Error writing E2P_CMD"); + + ret = smsc75xx_wait_eeprom(dev); + if (ret < 0) + return ret; + + offset++; + } + + return 0; +} + +static int smsc75xx_dataport_wait_not_busy(struct usbnet *dev) +{ + int i, ret; + + for (i = 0; i < 100; i++) { + u32 dp_sel; + ret = smsc75xx_read_reg(dev, DP_SEL, &dp_sel); + check_warn_return(ret, "Error reading DP_SEL"); + + if (dp_sel & DP_SEL_DPRDY) + return 0; + + udelay(40); + } + + netdev_warn(dev->net, "smsc75xx_dataport_wait_not_busy timed out"); + + return -EIO; +} + +static int smsc75xx_dataport_write(struct usbnet *dev, u32 ram_select, u32 addr, + u32 length, u32 *buf) +{ + struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); + u32 dp_sel; + int i, ret; + + mutex_lock(&pdata->dataport_mutex); + + ret = smsc75xx_dataport_wait_not_busy(dev); + check_warn_goto_done(ret, "smsc75xx_dataport_write busy on entry"); + + ret = smsc75xx_read_reg(dev, DP_SEL, &dp_sel); + check_warn_goto_done(ret, "Error reading DP_SEL"); + + dp_sel &= ~DP_SEL_RSEL; + dp_sel |= ram_select; + ret = smsc75xx_write_reg(dev, DP_SEL, dp_sel); + check_warn_goto_done(ret, "Error writing DP_SEL"); + + for (i = 0; i < length; i++) { + ret = smsc75xx_write_reg(dev, DP_ADDR, addr + i); + check_warn_goto_done(ret, "Error writing DP_ADDR"); + + ret = smsc75xx_write_reg(dev, DP_DATA, buf[i]); + check_warn_goto_done(ret, "Error writing DP_DATA"); + + ret = smsc75xx_write_reg(dev, DP_CMD, DP_CMD_WRITE); + check_warn_goto_done(ret, "Error writing DP_CMD"); + + ret = smsc75xx_dataport_wait_not_busy(dev); + check_warn_goto_done(ret, "smsc75xx_dataport_write timeout"); + } + +done: + mutex_unlock(&pdata->dataport_mutex); + return ret; +} + +/* returns hash bit number for given MAC address */ +static u32 smsc75xx_hash(char addr[ETH_ALEN]) +{ + return (ether_crc(ETH_ALEN, addr) >> 23) & 0x1ff; +} + +static void smsc75xx_deferred_multicast_write(struct work_struct *param) +{ + struct smsc75xx_priv *pdata = + container_of(param, struct smsc75xx_priv, set_multicast); + struct usbnet *dev = pdata->dev; + int ret; + + netif_dbg(dev, drv, dev->net, "deferred multicast write 0x%08x", + pdata->rfe_ctl); + + smsc75xx_dataport_write(dev, DP_SEL_VHF, DP_SEL_VHF_VLAN_LEN, + DP_SEL_VHF_HASH_LEN, pdata->multicast_hash_table); + + ret = smsc75xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl); + check_warn(ret, "Error writing RFE_CRL"); +} + +static void smsc75xx_set_multicast(struct net_device *netdev) +{ + struct usbnet *dev = netdev_priv(netdev); + struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); + unsigned long flags; + int i; + + spin_lock_irqsave(&pdata->rfe_ctl_lock, flags); + + pdata->rfe_ctl &= + ~(RFE_CTL_AU | RFE_CTL_AM | RFE_CTL_DPF | RFE_CTL_MHF); + pdata->rfe_ctl |= RFE_CTL_AB; + + for (i = 0; i < DP_SEL_VHF_HASH_LEN; i++) + pdata->multicast_hash_table[i] = 0; + + if (dev->net->flags & IFF_PROMISC) { + netif_dbg(dev, drv, dev->net, "promiscuous mode enabled"); + pdata->rfe_ctl |= RFE_CTL_AM | RFE_CTL_AU; + } else if (dev->net->flags & IFF_ALLMULTI) { + netif_dbg(dev, drv, dev->net, "receive all multicast enabled"); + pdata->rfe_ctl |= RFE_CTL_AM | RFE_CTL_DPF; + } else if (!netdev_mc_empty(dev->net)) { + struct dev_mc_list *mc_list; + + netif_dbg(dev, drv, dev->net, "receive multicast hash filter"); + + pdata->rfe_ctl |= RFE_CTL_MHF | RFE_CTL_DPF; + + netdev_for_each_mc_addr(mc_list, netdev) { + u32 bitnum = smsc75xx_hash(mc_list->dmi_addr); + pdata->multicast_hash_table[bitnum / 32] |= + (1 << (bitnum % 32)); + } + } else { + netif_dbg(dev, drv, dev->net, "receive own packets only"); + pdata->rfe_ctl |= RFE_CTL_DPF; + } + + spin_unlock_irqrestore(&pdata->rfe_ctl_lock, flags); + + /* defer register writes to a sleepable context */ + schedule_work(&pdata->set_multicast); +} + +static int smsc75xx_update_flowcontrol(struct usbnet *dev, u8 duplex, + u16 lcladv, u16 rmtadv) +{ + u32 flow = 0, fct_flow = 0; + int ret; + + if (duplex == DUPLEX_FULL) { + u8 cap = mii_resolve_flowctrl_fdx(lcladv, rmtadv); + + if (cap & FLOW_CTRL_TX) { + flow = (FLOW_TX_FCEN | 0xFFFF); + /* set fct_flow thresholds to 20% and 80% */ + fct_flow = (8 << 8) | 32; + } + + if (cap & FLOW_CTRL_RX) + flow |= FLOW_RX_FCEN; + + netif_dbg(dev, link, dev->net, "rx pause %s, tx pause %s", + (cap & FLOW_CTRL_RX ? "enabled" : "disabled"), + (cap & FLOW_CTRL_TX ? "enabled" : "disabled")); + } else { + netif_dbg(dev, link, dev->net, "half duplex"); + } + + ret = smsc75xx_write_reg(dev, FLOW, flow); + check_warn_return(ret, "Error writing FLOW"); + + ret = smsc75xx_write_reg(dev, FCT_FLOW, fct_flow); + check_warn_return(ret, "Error writing FCT_FLOW"); + + return 0; +} + +static int smsc75xx_link_reset(struct usbnet *dev) +{ + struct mii_if_info *mii = &dev->mii; + struct ethtool_cmd ecmd; + u16 lcladv, rmtadv; + int ret; + + /* clear interrupt status */ + ret = smsc75xx_mdio_read(dev->net, mii->phy_id, PHY_INT_SRC); + check_warn_return(ret, "Error reading PHY_INT_SRC"); + + ret = smsc75xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL); + check_warn_return(ret, "Error writing INT_STS"); + + mii_check_media(mii, 1, 1); + mii_ethtool_gset(&dev->mii, &ecmd); + lcladv = smsc75xx_mdio_read(dev->net, mii->phy_id, MII_ADVERTISE); + rmtadv = smsc75xx_mdio_read(dev->net, mii->phy_id, MII_LPA); + + netif_dbg(dev, link, dev->net, "speed: %d duplex: %d lcladv: %04x" + " rmtadv: %04x", ecmd.speed, ecmd.duplex, lcladv, rmtadv); + + return smsc75xx_update_flowcontrol(dev, ecmd.duplex, lcladv, rmtadv); +} + +static void smsc75xx_status(struct usbnet *dev, struct urb *urb) +{ + u32 intdata; + + if (urb->actual_length != 4) { + netdev_warn(dev->net, + "unexpected urb length %d", urb->actual_length); + return; + } + + memcpy(&intdata, urb->transfer_buffer, 4); + le32_to_cpus(&intdata); + + netif_dbg(dev, link, dev->net, "intdata: 0x%08X", intdata); + + if (intdata & INT_ENP_PHY_INT) + usbnet_defer_kevent(dev, EVENT_LINK_RESET); + else + netdev_warn(dev->net, + "unexpected interrupt, intdata=0x%08X", intdata); +} + +/* Enable or disable Rx checksum offload engine */ +static int smsc75xx_set_rx_csum_offload(struct usbnet *dev) +{ + struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); + unsigned long flags; + int ret; + + spin_lock_irqsave(&pdata->rfe_ctl_lock, flags); + + if (pdata->use_rx_csum) + pdata->rfe_ctl |= RFE_CTL_TCPUDP_CKM | RFE_CTL_IP_CKM; + else + pdata->rfe_ctl &= ~(RFE_CTL_TCPUDP_CKM | RFE_CTL_IP_CKM); + + spin_unlock_irqrestore(&pdata->rfe_ctl_lock, flags); + + ret = smsc75xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl); + check_warn_return(ret, "Error writing RFE_CTL"); + + return 0; +} + +static int smsc75xx_ethtool_get_eeprom_len(struct net_device *net) +{ + return MAX_EEPROM_SIZE; +} + +static int smsc75xx_ethtool_get_eeprom(struct net_device *netdev, + struct ethtool_eeprom *ee, u8 *data) +{ + struct usbnet *dev = netdev_priv(netdev); + + ee->magic = LAN75XX_EEPROM_MAGIC; + + return smsc75xx_read_eeprom(dev, ee->offset, ee->len, data); +} + +static int smsc75xx_ethtool_set_eeprom(struct net_device *netdev, + struct ethtool_eeprom *ee, u8 *data) +{ + struct usbnet *dev = netdev_priv(netdev); + + if (ee->magic != LAN75XX_EEPROM_MAGIC) { + netdev_warn(dev->net, + "EEPROM: magic value mismatch: 0x%x", ee->magic); + return -EINVAL; + } + + return smsc75xx_write_eeprom(dev, ee->offset, ee->len, data); +} + +static u32 smsc75xx_ethtool_get_rx_csum(struct net_device *netdev) +{ + struct usbnet *dev = netdev_priv(netdev); + struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); + + return pdata->use_rx_csum; +} + +static int smsc75xx_ethtool_set_rx_csum(struct net_device *netdev, u32 val) +{ + struct usbnet *dev = netdev_priv(netdev); + struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); + + pdata->use_rx_csum = !!val; + + return smsc75xx_set_rx_csum_offload(dev); +} + +static int smsc75xx_ethtool_set_tso(struct net_device *netdev, u32 data) +{ + if (data) + netdev->features |= NETIF_F_TSO | NETIF_F_TSO6; + else + netdev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6); + + return 0; +} + +static const struct ethtool_ops smsc75xx_ethtool_ops = { + .get_link = usbnet_get_link, + .nway_reset = usbnet_nway_reset, + .get_drvinfo = usbnet_get_drvinfo, + .get_msglevel = usbnet_get_msglevel, + .set_msglevel = usbnet_set_msglevel, + .get_settings = usbnet_get_settings, + .set_settings = usbnet_set_settings, + .get_eeprom_len = smsc75xx_ethtool_get_eeprom_len, + .get_eeprom = smsc75xx_ethtool_get_eeprom, + .set_eeprom = smsc75xx_ethtool_set_eeprom, + .get_tx_csum = ethtool_op_get_tx_csum, + .set_tx_csum = ethtool_op_set_tx_hw_csum, + .get_rx_csum = smsc75xx_ethtool_get_rx_csum, + .set_rx_csum = smsc75xx_ethtool_set_rx_csum, + .get_tso = ethtool_op_get_tso, + .set_tso = smsc75xx_ethtool_set_tso, +}; + +static int smsc75xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) +{ + struct usbnet *dev = netdev_priv(netdev); + + if (!netif_running(netdev)) + return -EINVAL; + + return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); +} + +static void smsc75xx_init_mac_address(struct usbnet *dev) +{ + /* try reading mac address from EEPROM */ + if (smsc75xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN, + dev->net->dev_addr) == 0) { + if (is_valid_ether_addr(dev->net->dev_addr)) { + /* eeprom values are valid so use them */ + netif_dbg(dev, ifup, dev->net, + "MAC address read from EEPROM"); + return; + } + } + + /* no eeprom, or eeprom values are invalid. generate random MAC */ + random_ether_addr(dev->net->dev_addr); + netif_dbg(dev, ifup, dev->net, "MAC address set to random_ether_addr"); +} + +static int smsc75xx_set_mac_address(struct usbnet *dev) +{ + u32 addr_lo = dev->net->dev_addr[0] | dev->net->dev_addr[1] << 8 | + dev->net->dev_addr[2] << 16 | dev->net->dev_addr[3] << 24; + u32 addr_hi = dev->net->dev_addr[4] | dev->net->dev_addr[5] << 8; + + int ret = smsc75xx_write_reg(dev, RX_ADDRH, addr_hi); + check_warn_return(ret, "Failed to write RX_ADDRH: %d", ret); + + ret = smsc75xx_write_reg(dev, RX_ADDRL, addr_lo); + check_warn_return(ret, "Failed to write RX_ADDRL: %d", ret); + + addr_hi |= ADDR_FILTX_FB_VALID; + ret = smsc75xx_write_reg(dev, ADDR_FILTX, addr_hi); + check_warn_return(ret, "Failed to write ADDR_FILTX: %d", ret); + + ret = smsc75xx_write_reg(dev, ADDR_FILTX + 4, addr_lo); + check_warn_return(ret, "Failed to write ADDR_FILTX+4: %d", ret); + + return 0; +} + +static int smsc75xx_phy_initialize(struct usbnet *dev) +{ + int bmcr, timeout = 0; + + /* Initialize MII structure */ + dev->mii.dev = dev->net; + dev->mii.mdio_read = smsc75xx_mdio_read; + dev->mii.mdio_write = smsc75xx_mdio_write; + dev->mii.phy_id_mask = 0x1f; + dev->mii.reg_num_mask = 0x1f; + dev->mii.phy_id = SMSC75XX_INTERNAL_PHY_ID; + + /* reset phy and wait for reset to complete */ + smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET); + + do { + msleep(10); + bmcr = smsc75xx_mdio_read(dev->net, dev->mii.phy_id, MII_BMCR); + check_warn_return(bmcr, "Error reading MII_BMCR"); + timeout++; + } while ((bmcr & MII_BMCR) && (timeout < 100)); + + if (timeout >= 100) { + netdev_warn(dev->net, "timeout on PHY Reset"); + return -EIO; + } + + smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE, + ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP | + ADVERTISE_PAUSE_ASYM); + + /* read to clear */ + smsc75xx_mdio_read(dev->net, dev->mii.phy_id, PHY_INT_SRC); + check_warn_return(bmcr, "Error reading PHY_INT_SRC"); + + smsc75xx_mdio_write(dev->net, dev->mii.phy_id, PHY_INT_MASK, + PHY_INT_MASK_DEFAULT); + mii_nway_restart(&dev->mii); + + netif_dbg(dev, ifup, dev->net, "phy initialised successfully"); + return 0; +} + +static int smsc75xx_set_rx_max_frame_length(struct usbnet *dev, int size) +{ + int ret = 0; + u32 buf; + bool rxenabled; + + ret = smsc75xx_read_reg(dev, MAC_RX, &buf); + check_warn_return(ret, "Failed to read MAC_RX: %d", ret); + + rxenabled = ((buf & MAC_RX_RXEN) != 0); + + if (rxenabled) { + buf &= ~MAC_RX_RXEN; + ret = smsc75xx_write_reg(dev, MAC_RX, buf); + check_warn_return(ret, "Failed to write MAC_RX: %d", ret); + } + + /* add 4 to size for FCS */ + buf &= ~MAC_RX_MAX_SIZE; + buf |= (((size + 4) << MAC_RX_MAX_SIZE_SHIFT) & MAC_RX_MAX_SIZE); + + ret = smsc75xx_write_reg(dev, MAC_RX, buf); + check_warn_return(ret, "Failed to write MAC_RX: %d", ret); + + if (rxenabled) { + buf |= MAC_RX_RXEN; + ret = smsc75xx_write_reg(dev, MAC_RX, buf); + check_warn_return(ret, "Failed to write MAC_RX: %d", ret); + } + + return 0; +} + +static int smsc75xx_change_mtu(struct net_device *netdev, int new_mtu) +{ + struct usbnet *dev = netdev_priv(netdev); + + int ret = smsc75xx_set_rx_max_frame_length(dev, new_mtu); + check_warn_return(ret, "Failed to set mac rx frame length"); + + return usbnet_change_mtu(netdev, new_mtu); +} + +static int smsc75xx_reset(struct usbnet *dev) +{ + struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); + u32 buf; + int ret = 0, timeout; + + netif_dbg(dev, ifup, dev->net, "entering smsc75xx_reset"); + + ret = smsc75xx_read_reg(dev, HW_CFG, &buf); + check_warn_return(ret, "Failed to read HW_CFG: %d", ret); + + buf |= HW_CFG_LRST; + + ret = smsc75xx_write_reg(dev, HW_CFG, buf); + check_warn_return(ret, "Failed to write HW_CFG: %d", ret); + + timeout = 0; + do { + msleep(10); + ret = smsc75xx_read_reg(dev, HW_CFG, &buf); + check_warn_return(ret, "Failed to read HW_CFG: %d", ret); + timeout++; + } while ((buf & HW_CFG_LRST) && (timeout < 100)); + + if (timeout >= 100) { + netdev_warn(dev->net, "timeout on completion of Lite Reset"); + return -EIO; + } + + netif_dbg(dev, ifup, dev->net, "Lite reset complete, resetting PHY"); + + ret = smsc75xx_read_reg(dev, PMT_CTL, &buf); + check_warn_return(ret, "Failed to read PMT_CTL: %d", ret); + + buf |= PMT_CTL_PHY_RST; + + ret = smsc75xx_write_reg(dev, PMT_CTL, buf); + check_warn_return(ret, "Failed to write PMT_CTL: %d", ret); + + timeout = 0; + do { + msleep(10); + ret = smsc75xx_read_reg(dev, PMT_CTL, &buf); + check_warn_return(ret, "Failed to read PMT_CTL: %d", ret); + timeout++; + } while ((buf & PMT_CTL_PHY_RST) && (timeout < 100)); + + if (timeout >= 100) { + netdev_warn(dev->net, "timeout waiting for PHY Reset"); + return -EIO; + } + + netif_dbg(dev, ifup, dev->net, "PHY reset complete"); + + smsc75xx_init_mac_address(dev); + + ret = smsc75xx_set_mac_address(dev); + check_warn_return(ret, "Failed to set mac address"); + + netif_dbg(dev, ifup, dev->net, "MAC Address: %pM", dev->net->dev_addr); + + ret = smsc75xx_read_reg(dev, HW_CFG, &buf); + check_warn_return(ret, "Failed to read HW_CFG: %d", ret); + + netif_dbg(dev, ifup, dev->net, "Read Value from HW_CFG : 0x%08x", buf); + + buf |= HW_CFG_BIR; + + ret = smsc75xx_write_reg(dev, HW_CFG, buf); + check_warn_return(ret, "Failed to write HW_CFG: %d", ret); + + ret = smsc75xx_read_reg(dev, HW_CFG, &buf); + check_warn_return(ret, "Failed to read HW_CFG: %d", ret); + + netif_dbg(dev, ifup, dev->net, "Read Value from HW_CFG after " + "writing HW_CFG_BIR: 0x%08x", buf); + + if (!turbo_mode) { + buf = 0; + dev->rx_urb_size = MAX_SINGLE_PACKET_SIZE; + } else if (dev->udev->speed == USB_SPEED_HIGH) { + buf = DEFAULT_HS_BURST_CAP_SIZE / HS_USB_PKT_SIZE; + dev->rx_urb_size = DEFAULT_HS_BURST_CAP_SIZE; + } else { + buf = DEFAULT_FS_BURST_CAP_SIZE / FS_USB_PKT_SIZE; + dev->rx_urb_size = DEFAULT_FS_BURST_CAP_SIZE; + } + + netif_dbg(dev, ifup, dev->net, "rx_urb_size=%ld", + (ulong)dev->rx_urb_size); + + ret = smsc75xx_write_reg(dev, BURST_CAP, buf); + check_warn_return(ret, "Failed to write BURST_CAP: %d", ret); + + ret = smsc75xx_read_reg(dev, BURST_CAP, &buf); + check_warn_return(ret, "Failed to read BURST_CAP: %d", ret); + + netif_dbg(dev, ifup, dev->net, + "Read Value from BURST_CAP after writing: 0x%08x", buf); + + ret = smsc75xx_write_reg(dev, BULK_IN_DLY, DEFAULT_BULK_IN_DELAY); + check_warn_return(ret, "Failed to write BULK_IN_DLY: %d", ret); + + ret = smsc75xx_read_reg(dev, BULK_IN_DLY, &buf); + check_warn_return(ret, "Failed to read BULK_IN_DLY: %d", ret); + + netif_dbg(dev, ifup, dev->net, + "Read Value from BULK_IN_DLY after writing: 0x%08x", buf); + + if (turbo_mode) { + ret = smsc75xx_read_reg(dev, HW_CFG, &buf); + check_warn_return(ret, "Failed to read HW_CFG: %d", ret); + + netif_dbg(dev, ifup, dev->net, "HW_CFG: 0x%08x", buf); + + buf |= (HW_CFG_MEF | HW_CFG_BCE); + + ret = smsc75xx_write_reg(dev, HW_CFG, buf); + check_warn_return(ret, "Failed to write HW_CFG: %d", ret); + + ret = smsc75xx_read_reg(dev, HW_CFG, &buf); + check_warn_return(ret, "Failed to read HW_CFG: %d", ret); + + netif_dbg(dev, ifup, dev->net, "HW_CFG: 0x%08x", buf); + } + + /* set FIFO sizes */ + buf = (MAX_RX_FIFO_SIZE - 512) / 512; + ret = smsc75xx_write_reg(dev, FCT_RX_FIFO_END, buf); + check_warn_return(ret, "Failed to write FCT_RX_FIFO_END: %d", ret); + + netif_dbg(dev, ifup, dev->net, "FCT_RX_FIFO_END set to 0x%08x", buf); + + buf = (MAX_TX_FIFO_SIZE - 512) / 512; + ret = smsc75xx_write_reg(dev, FCT_TX_FIFO_END, buf); + check_warn_return(ret, "Failed to write FCT_TX_FIFO_END: %d", ret); + + netif_dbg(dev, ifup, dev->net, "FCT_TX_FIFO_END set to 0x%08x", buf); + + ret = smsc75xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL); + check_warn_return(ret, "Failed to write INT_STS: %d", ret); + + ret = smsc75xx_read_reg(dev, ID_REV, &buf); + check_warn_return(ret, "Failed to read ID_REV: %d", ret); + + netif_dbg(dev, ifup, dev->net, "ID_REV = 0x%08x", buf); + + /* Configure GPIO pins as LED outputs */ + ret = smsc75xx_read_reg(dev, LED_GPIO_CFG, &buf); + check_warn_return(ret, "Failed to read LED_GPIO_CFG: %d", ret); + + buf &= ~(LED_GPIO_CFG_LED2_FUN_SEL | LED_GPIO_CFG_LED10_FUN_SEL); + buf |= LED_GPIO_CFG_LEDGPIO_EN | LED_GPIO_CFG_LED2_FUN_SEL; + + ret = smsc75xx_write_reg(dev, LED_GPIO_CFG, buf); + check_warn_return(ret, "Failed to write LED_GPIO_CFG: %d", ret); + + ret = smsc75xx_write_reg(dev, FLOW, 0); + check_warn_return(ret, "Failed to write FLOW: %d", ret); + + ret = smsc75xx_write_reg(dev, FCT_FLOW, 0); + check_warn_return(ret, "Failed to write FCT_FLOW: %d", ret); + + /* Don't need rfe_ctl_lock during initialisation */ + ret = smsc75xx_read_reg(dev, RFE_CTL, &pdata->rfe_ctl); + check_warn_return(ret, "Failed to read RFE_CTL: %d", ret); + + pdata->rfe_ctl |= RFE_CTL_AB | RFE_CTL_DPF; + + ret = smsc75xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl); + check_warn_return(ret, "Failed to write RFE_CTL: %d", ret); + + ret = smsc75xx_read_reg(dev, RFE_CTL, &pdata->rfe_ctl); + check_warn_return(ret, "Failed to read RFE_CTL: %d", ret); + + netif_dbg(dev, ifup, dev->net, "RFE_CTL set to 0x%08x", pdata->rfe_ctl); + + /* Enable or disable checksum offload engines */ + ethtool_op_set_tx_hw_csum(dev->net, DEFAULT_TX_CSUM_ENABLE); + ret = smsc75xx_set_rx_csum_offload(dev); + check_warn_return(ret, "Failed to set rx csum offload: %d", ret); + + smsc75xx_ethtool_set_tso(dev->net, DEFAULT_TSO_ENABLE); + + smsc75xx_set_multicast(dev->net); + + ret = smsc75xx_phy_initialize(dev); + check_warn_return(ret, "Failed to initialize PHY: %d", ret); + + ret = smsc75xx_read_reg(dev, INT_EP_CTL, &buf); + check_warn_return(ret, "Failed to read INT_EP_CTL: %d", ret); + + /* enable PHY interrupts */ + buf |= INT_ENP_PHY_INT; + + ret = smsc75xx_write_reg(dev, INT_EP_CTL, buf); + check_warn_return(ret, "Failed to write INT_EP_CTL: %d", ret); + + ret = smsc75xx_read_reg(dev, MAC_TX, &buf); + check_warn_return(ret, "Failed to read MAC_TX: %d", ret); + + buf |= MAC_TX_TXEN; + + ret = smsc75xx_write_reg(dev, MAC_TX, buf); + check_warn_return(ret, "Failed to write MAC_TX: %d", ret); + + netif_dbg(dev, ifup, dev->net, "MAC_TX set to 0x%08x", buf); + + ret = smsc75xx_read_reg(dev, FCT_TX_CTL, &buf); + check_warn_return(ret, "Failed to read FCT_TX_CTL: %d", ret); + + buf |= FCT_TX_CTL_EN; + + ret = smsc75xx_write_reg(dev, FCT_TX_CTL, buf); + check_warn_return(ret, "Failed to write FCT_TX_CTL: %d", ret); + + netif_dbg(dev, ifup, dev->net, "FCT_TX_CTL set to 0x%08x", buf); + + ret = smsc75xx_set_rx_max_frame_length(dev, 1514); + check_warn_return(ret, "Failed to set max rx frame length"); + + ret = smsc75xx_read_reg(dev, MAC_RX, &buf); + check_warn_return(ret, "Failed to read MAC_RX: %d", ret); + + buf |= MAC_RX_RXEN; + + ret = smsc75xx_write_reg(dev, MAC_RX, buf); + check_warn_return(ret, "Failed to write MAC_RX: %d", ret); + + netif_dbg(dev, ifup, dev->net, "MAC_RX set to 0x%08x", buf); + + ret = smsc75xx_read_reg(dev, FCT_RX_CTL, &buf); + check_warn_return(ret, "Failed to read FCT_RX_CTL: %d", ret); + + buf |= FCT_RX_CTL_EN; + + ret = smsc75xx_write_reg(dev, FCT_RX_CTL, buf); + check_warn_return(ret, "Failed to write FCT_RX_CTL: %d", ret); + + netif_dbg(dev, ifup, dev->net, "FCT_RX_CTL set to 0x%08x", buf); + + netif_dbg(dev, ifup, dev->net, "smsc75xx_reset, return 0"); + return 0; +} + +static const struct net_device_ops smsc75xx_netdev_ops = { + .ndo_open = usbnet_open, + .ndo_stop = usbnet_stop, + .ndo_start_xmit = usbnet_start_xmit, + .ndo_tx_timeout = usbnet_tx_timeout, + .ndo_change_mtu = smsc75xx_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, + .ndo_do_ioctl = smsc75xx_ioctl, + .ndo_set_multicast_list = smsc75xx_set_multicast, +}; + +static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf) +{ + struct smsc75xx_priv *pdata = NULL; + int ret; + + printk(KERN_INFO SMSC_CHIPNAME " v" SMSC_DRIVER_VERSION "\n"); + + ret = usbnet_get_endpoints(dev, intf); + check_warn_return(ret, "usbnet_get_endpoints failed: %d", ret); + + dev->data[0] = (unsigned long)kzalloc(sizeof(struct smsc75xx_priv), + GFP_KERNEL); + + pdata = (struct smsc75xx_priv *)(dev->data[0]); + if (!pdata) { + netdev_warn(dev->net, "Unable to allocate smsc75xx_priv"); + return -ENOMEM; + } + + pdata->dev = dev; + + spin_lock_init(&pdata->rfe_ctl_lock); + mutex_init(&pdata->dataport_mutex); + + INIT_WORK(&pdata->set_multicast, smsc75xx_deferred_multicast_write); + + pdata->use_rx_csum = DEFAULT_RX_CSUM_ENABLE; + + /* We have to advertise SG otherwise TSO cannot be enabled */ + dev->net->features |= NETIF_F_SG; + + /* Init all registers */ + ret = smsc75xx_reset(dev); + + dev->net->netdev_ops = &smsc75xx_netdev_ops; + dev->net->ethtool_ops = &smsc75xx_ethtool_ops; + dev->net->flags |= IFF_MULTICAST; + dev->net->hard_header_len += SMSC75XX_TX_OVERHEAD; + return 0; +} + +static void smsc75xx_unbind(struct usbnet *dev, struct usb_interface *intf) +{ + struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); + if (pdata) { + netif_dbg(dev, ifdown, dev->net, "free pdata"); + kfree(pdata); + pdata = NULL; + dev->data[0] = 0; + } +} + +static void smsc75xx_rx_csum_offload(struct sk_buff *skb, u32 rx_cmd_a, + u32 rx_cmd_b) +{ + if (unlikely(rx_cmd_a & RX_CMD_A_LCSM)) { + skb->ip_summed = CHECKSUM_NONE; + } else { + skb->csum = ntohs((u16)(rx_cmd_b >> RX_CMD_B_CSUM_SHIFT)); + skb->ip_summed = CHECKSUM_COMPLETE; + } +} + +static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) +{ + struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]); + + while (skb->len > 0) { + u32 rx_cmd_a, rx_cmd_b, align_count, size; + struct sk_buff *ax_skb; + unsigned char *packet; + + memcpy(&rx_cmd_a, skb->data, sizeof(rx_cmd_a)); + le32_to_cpus(&rx_cmd_a); + skb_pull(skb, 4); + + memcpy(&rx_cmd_b, skb->data, sizeof(rx_cmd_b)); + le32_to_cpus(&rx_cmd_b); + skb_pull(skb, 4 + NET_IP_ALIGN); + + packet = skb->data; + + /* get the packet length */ + size = (rx_cmd_a & RX_CMD_A_LEN) - NET_IP_ALIGN; + align_count = (4 - ((size + NET_IP_ALIGN) % 4)) % 4; + + if (unlikely(rx_cmd_a & RX_CMD_A_RED)) { + netif_dbg(dev, rx_err, dev->net, + "Error rx_cmd_a=0x%08x", rx_cmd_a); + dev->net->stats.rx_errors++; + dev->net->stats.rx_dropped++; + + if (rx_cmd_a & RX_CMD_A_FCS) + dev->net->stats.rx_crc_errors++; + else if (rx_cmd_a & (RX_CMD_A_LONG | RX_CMD_A_RUNT)) + dev->net->stats.rx_frame_errors++; + } else { + /* ETH_FRAME_LEN + 4(CRC) + 2(COE) + 4(Vlan) */ + if (unlikely(size > (ETH_FRAME_LEN + 12))) { + netif_dbg(dev, rx_err, dev->net, + "size err rx_cmd_a=0x%08x", rx_cmd_a); + return 0; + } + + /* last frame in this batch */ + if (skb->len == size) { + if (pdata->use_rx_csum) + smsc75xx_rx_csum_offload(skb, rx_cmd_a, + rx_cmd_b); + else + skb->ip_summed = CHECKSUM_NONE; + + skb_trim(skb, skb->len - 4); /* remove fcs */ + skb->truesize = size + sizeof(struct sk_buff); + + return 1; + } + + ax_skb = skb_clone(skb, GFP_ATOMIC); + if (unlikely(!ax_skb)) { + netdev_warn(dev->net, "Error allocating skb"); + return 0; + } + + ax_skb->len = size; + ax_skb->data = packet; + skb_set_tail_pointer(ax_skb, size); + + if (pdata->use_rx_csum) + smsc75xx_rx_csum_offload(ax_skb, rx_cmd_a, + rx_cmd_b); + else + ax_skb->ip_summed = CHECKSUM_NONE; + + skb_trim(ax_skb, ax_skb->len - 4); /* remove fcs */ + ax_skb->truesize = size + sizeof(struct sk_buff); + + usbnet_skb_return(dev, ax_skb); + } + + skb_pull(skb, size); + + /* padding bytes before the next frame starts */ + if (skb->len) + skb_pull(skb, align_count); + } + + if (unlikely(skb->len < 0)) { + netdev_warn(dev->net, "invalid rx length<0 %d", skb->len); + return 0; + } + + return 1; +} + +static struct sk_buff *smsc75xx_tx_fixup(struct usbnet *dev, + struct sk_buff *skb, gfp_t flags) +{ + u32 tx_cmd_a, tx_cmd_b; + + skb_linearize(skb); + + if (skb_headroom(skb) < SMSC75XX_TX_OVERHEAD) { + struct sk_buff *skb2 = + skb_copy_expand(skb, SMSC75XX_TX_OVERHEAD, 0, flags); + dev_kfree_skb_any(skb); + skb = skb2; + if (!skb) + return NULL; + } + + tx_cmd_a = (u32)(skb->len & TX_CMD_A_LEN) | TX_CMD_A_FCS; + + if (skb->ip_summed == CHECKSUM_PARTIAL) + tx_cmd_a |= TX_CMD_A_IPE | TX_CMD_A_TPE; + + if (skb_is_gso(skb)) { + u16 mss = max(skb_shinfo(skb)->gso_size, TX_MSS_MIN); + tx_cmd_b = (mss << TX_CMD_B_MSS_SHIFT) & TX_CMD_B_MSS; + + tx_cmd_a |= TX_CMD_A_LSO; + } else { + tx_cmd_b = 0; + } + + skb_push(skb, 4); + cpu_to_le32s(&tx_cmd_b); + memcpy(skb->data, &tx_cmd_b, 4); + + skb_push(skb, 4); + cpu_to_le32s(&tx_cmd_a); + memcpy(skb->data, &tx_cmd_a, 4); + + return skb; +} + +static const struct driver_info smsc75xx_info = { + .description = "smsc75xx USB 2.0 Gigabit Ethernet", + .bind = smsc75xx_bind, + .unbind = smsc75xx_unbind, + .link_reset = smsc75xx_link_reset, + .reset = smsc75xx_reset, + .rx_fixup = smsc75xx_rx_fixup, + .tx_fixup = smsc75xx_tx_fixup, + .status = smsc75xx_status, + .flags = FLAG_ETHER | FLAG_SEND_ZLP, +}; + +static const struct usb_device_id products[] = { + { + /* SMSC7500 USB Gigabit Ethernet Device */ + USB_DEVICE(USB_VENDOR_ID_SMSC, USB_PRODUCT_ID_LAN7500), + .driver_info = (unsigned long) &smsc75xx_info, + }, + { + /* SMSC7500 USB Gigabit Ethernet Device */ + USB_DEVICE(USB_VENDOR_ID_SMSC, USB_PRODUCT_ID_LAN7505), + .driver_info = (unsigned long) &smsc75xx_info, + }, + { }, /* END */ +}; +MODULE_DEVICE_TABLE(usb, products); + +static struct usb_driver smsc75xx_driver = { + .name = SMSC_CHIPNAME, + .id_table = products, + .probe = usbnet_probe, + .suspend = usbnet_suspend, + .resume = usbnet_resume, + .disconnect = usbnet_disconnect, +}; + +static int __init smsc75xx_init(void) +{ + return usb_register(&smsc75xx_driver); +} +module_init(smsc75xx_init); + +static void __exit smsc75xx_exit(void) +{ + usb_deregister(&smsc75xx_driver); +} +module_exit(smsc75xx_exit); + +MODULE_AUTHOR("Nancy Lin"); +MODULE_AUTHOR("Steve Glendinning "); +MODULE_DESCRIPTION("SMSC75XX USB 2.0 Gigabit Ethernet Devices"); +MODULE_LICENSE("GPL"); diff --git a/drivers/net/usb/smsc75xx.h b/drivers/net/usb/smsc75xx.h new file mode 100644 index 0000000..16e98c7 --- /dev/null +++ b/drivers/net/usb/smsc75xx.h @@ -0,0 +1,421 @@ + /*************************************************************************** + * + * Copyright (C) 2007-2010 SMSC + * + * 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. + * + *****************************************************************************/ + +#ifndef _SMSC75XX_H +#define _SMSC75XX_H + +/* Tx command words */ +#define TX_CMD_A_LSO (0x08000000) +#define TX_CMD_A_IPE (0x04000000) +#define TX_CMD_A_TPE (0x02000000) +#define TX_CMD_A_IVTG (0x01000000) +#define TX_CMD_A_RVTG (0x00800000) +#define TX_CMD_A_FCS (0x00400000) +#define TX_CMD_A_LEN (0x000FFFFF) + +#define TX_CMD_B_MSS (0x3FFF0000) +#define TX_CMD_B_MSS_SHIFT (16) +#define TX_MSS_MIN ((u16)8) +#define TX_CMD_B_VTAG (0x0000FFFF) + +/* Rx command words */ +#define RX_CMD_A_ICE (0x80000000) +#define RX_CMD_A_TCE (0x40000000) +#define RX_CMD_A_IPV (0x20000000) +#define RX_CMD_A_PID (0x18000000) +#define RX_CMD_A_PID_NIP (0x00000000) +#define RX_CMD_A_PID_TCP (0x08000000) +#define RX_CMD_A_PID_UDP (0x10000000) +#define RX_CMD_A_PID_PP (0x18000000) +#define RX_CMD_A_PFF (0x04000000) +#define RX_CMD_A_BAM (0x02000000) +#define RX_CMD_A_MAM (0x01000000) +#define RX_CMD_A_FVTG (0x00800000) +#define RX_CMD_A_RED (0x00400000) +#define RX_CMD_A_RWT (0x00200000) +#define RX_CMD_A_RUNT (0x00100000) +#define RX_CMD_A_LONG (0x00080000) +#define RX_CMD_A_RXE (0x00040000) +#define RX_CMD_A_DRB (0x00020000) +#define RX_CMD_A_FCS (0x00010000) +#define RX_CMD_A_UAM (0x00008000) +#define RX_CMD_A_LCSM (0x00004000) +#define RX_CMD_A_LEN (0x00003FFF) + +#define RX_CMD_B_CSUM (0xFFFF0000) +#define RX_CMD_B_CSUM_SHIFT (16) +#define RX_CMD_B_VTAG (0x0000FFFF) + +/* SCSRs */ +#define ID_REV (0x0000) + +#define FPGA_REV (0x0004) + +#define BOND_CTL (0x0008) + +#define INT_STS (0x000C) +#define INT_STS_RDFO_INT (0x00400000) +#define INT_STS_TXE_INT (0x00200000) +#define INT_STS_MACRTO_INT (0x00100000) +#define INT_STS_TX_DIS_INT (0x00080000) +#define INT_STS_RX_DIS_INT (0x00040000) +#define INT_STS_PHY_INT_ (0x00020000) +#define INT_STS_MAC_ERR_INT (0x00008000) +#define INT_STS_TDFU (0x00004000) +#define INT_STS_TDFO (0x00002000) +#define INT_STS_GPIOS (0x00000FFF) +#define INT_STS_CLEAR_ALL (0xFFFFFFFF) + +#define HW_CFG (0x0010) +#define HW_CFG_SMDET_STS (0x00008000) +#define HW_CFG_SMDET_EN (0x00004000) +#define HW_CFG_EEM (0x00002000) +#define HW_CFG_RST_PROTECT (0x00001000) +#define HW_CFG_PORT_SWAP (0x00000800) +#define HW_CFG_PHY_BOOST (0x00000600) +#define HW_CFG_PHY_BOOST_NORMAL (0x00000000) +#define HW_CFG_PHY_BOOST_4 (0x00002000) +#define HW_CFG_PHY_BOOST_8 (0x00004000) +#define HW_CFG_PHY_BOOST_12 (0x00006000) +#define HW_CFG_LEDB (0x00000100) +#define HW_CFG_BIR (0x00000080) +#define HW_CFG_SBP (0x00000040) +#define HW_CFG_IME (0x00000020) +#define HW_CFG_MEF (0x00000010) +#define HW_CFG_ETC (0x00000008) +#define HW_CFG_BCE (0x00000004) +#define HW_CFG_LRST (0x00000002) +#define HW_CFG_SRST (0x00000001) + +#define PMT_CTL (0x0014) +#define PMT_CTL_PHY_PWRUP (0x00000400) +#define PMT_CTL_RES_CLR_WKP_EN (0x00000100) +#define PMT_CTL_DEV_RDY (0x00000080) +#define PMT_CTL_SUS_MODE (0x00000060) +#define PMT_CTL_SUS_MODE_0 (0x00000000) +#define PMT_CTL_SUS_MODE_1 (0x00000020) +#define PMT_CTL_SUS_MODE_2 (0x00000040) +#define PMT_CTL_SUS_MODE_3 (0x00000060) +#define PMT_CTL_PHY_RST (0x00000010) +#define PMT_CTL_WOL_EN (0x00000008) +#define PMT_CTL_ED_EN (0x00000004) +#define PMT_CTL_WUPS (0x00000003) +#define PMT_CTL_WUPS_NO (0x00000000) +#define PMT_CTL_WUPS_ED (0x00000001) +#define PMT_CTL_WUPS_WOL (0x00000002) +#define PMT_CTL_WUPS_MULTI (0x00000003) + +#define LED_GPIO_CFG (0x0018) +#define LED_GPIO_CFG_LED2_FUN_SEL (0x80000000) +#define LED_GPIO_CFG_LED10_FUN_SEL (0x40000000) +#define LED_GPIO_CFG_LEDGPIO_EN (0x0000F000) +#define LED_GPIO_CFG_LEDGPIO_EN_0 (0x00001000) +#define LED_GPIO_CFG_LEDGPIO_EN_1 (0x00002000) +#define LED_GPIO_CFG_LEDGPIO_EN_2 (0x00004000) +#define LED_GPIO_CFG_LEDGPIO_EN_3 (0x00008000) +#define LED_GPIO_CFG_GPBUF (0x00000F00) +#define LED_GPIO_CFG_GPBUF_0 (0x00000100) +#define LED_GPIO_CFG_GPBUF_1 (0x00000200) +#define LED_GPIO_CFG_GPBUF_2 (0x00000400) +#define LED_GPIO_CFG_GPBUF_3 (0x00000800) +#define LED_GPIO_CFG_GPDIR (0x000000F0) +#define LED_GPIO_CFG_GPDIR_0 (0x00000010) +#define LED_GPIO_CFG_GPDIR_1 (0x00000020) +#define LED_GPIO_CFG_GPDIR_2 (0x00000040) +#define LED_GPIO_CFG_GPDIR_3 (0x00000080) +#define LED_GPIO_CFG_GPDATA (0x0000000F) +#define LED_GPIO_CFG_GPDATA_0 (0x00000001) +#define LED_GPIO_CFG_GPDATA_1 (0x00000002) +#define LED_GPIO_CFG_GPDATA_2 (0x00000004) +#define LED_GPIO_CFG_GPDATA_3 (0x00000008) + +#define GPIO_CFG (0x001C) +#define GPIO_CFG_SHIFT (24) +#define GPIO_CFG_GPEN (0xFF000000) +#define GPIO_CFG_GPBUF (0x00FF0000) +#define GPIO_CFG_GPDIR (0x0000FF00) +#define GPIO_CFG_GPDATA (0x000000FF) + +#define GPIO_WAKE (0x0020) +#define GPIO_WAKE_PHY_LINKUP_EN (0x80000000) +#define GPIO_WAKE_POL (0x0FFF0000) +#define GPIO_WAKE_POL_SHIFT (16) +#define GPIO_WAKE_WK (0x00000FFF) + +#define DP_SEL (0x0024) +#define DP_SEL_DPRDY (0x80000000) +#define DP_SEL_RSEL (0x0000000F) +#define DP_SEL_URX (0x00000000) +#define DP_SEL_VHF (0x00000001) +#define DP_SEL_VHF_HASH_LEN (16) +#define DP_SEL_VHF_VLAN_LEN (128) +#define DP_SEL_LSO_HEAD (0x00000002) +#define DP_SEL_FCT_RX (0x00000003) +#define DP_SEL_FCT_TX (0x00000004) +#define DP_SEL_DESCRIPTOR (0x00000005) +#define DP_SEL_WOL (0x00000006) + +#define DP_CMD (0x0028) +#define DP_CMD_WRITE (0x01) +#define DP_CMD_READ (0x00) + +#define DP_ADDR (0x002C) + +#define DP_DATA (0x0030) + +#define BURST_CAP (0x0034) +#define BURST_CAP_MASK (0x0000000F) + +#define INT_EP_CTL (0x0038) +#define INT_EP_CTL_INTEP_ON (0x80000000) +#define INT_EP_CTL_RDFO_EN (0x00400000) +#define INT_EP_CTL_TXE_EN (0x00200000) +#define INT_EP_CTL_MACROTO_EN (0x00100000) +#define INT_EP_CTL_TX_DIS_EN (0x00080000) +#define INT_EP_CTL_RX_DIS_EN (0x00040000) +#define INT_EP_CTL_PHY_EN_ (0x00020000) +#define INT_EP_CTL_MAC_ERR_EN (0x00008000) +#define INT_EP_CTL_TDFU_EN (0x00004000) +#define INT_EP_CTL_TDFO_EN (0x00002000) +#define INT_EP_CTL_RX_FIFO_EN (0x00001000) +#define INT_EP_CTL_GPIOX_EN (0x00000FFF) + +#define BULK_IN_DLY (0x003C) +#define BULK_IN_DLY_MASK (0xFFFF) + +#define E2P_CMD (0x0040) +#define E2P_CMD_BUSY (0x80000000) +#define E2P_CMD_MASK (0x70000000) +#define E2P_CMD_READ (0x00000000) +#define E2P_CMD_EWDS (0x10000000) +#define E2P_CMD_EWEN (0x20000000) +#define E2P_CMD_WRITE (0x30000000) +#define E2P_CMD_WRAL (0x40000000) +#define E2P_CMD_ERASE (0x50000000) +#define E2P_CMD_ERAL (0x60000000) +#define E2P_CMD_RELOAD (0x70000000) +#define E2P_CMD_TIMEOUT (0x00000400) +#define E2P_CMD_LOADED (0x00000200) +#define E2P_CMD_ADDR (0x000001FF) + +#define MAX_EEPROM_SIZE (512) + +#define E2P_DATA (0x0044) +#define E2P_DATA_MASK_ (0x000000FF) + +#define RFE_CTL (0x0060) +#define RFE_CTL_TCPUDP_CKM (0x00001000) +#define RFE_CTL_IP_CKM (0x00000800) +#define RFE_CTL_AB (0x00000400) +#define RFE_CTL_AM (0x00000200) +#define RFE_CTL_AU (0x00000100) +#define RFE_CTL_VS (0x00000080) +#define RFE_CTL_UF (0x00000040) +#define RFE_CTL_VF (0x00000020) +#define RFE_CTL_SPF (0x00000010) +#define RFE_CTL_MHF (0x00000008) +#define RFE_CTL_DHF (0x00000004) +#define RFE_CTL_DPF (0x00000002) +#define RFE_CTL_RST_RF (0x00000001) + +#define VLAN_TYPE (0x0064) +#define VLAN_TYPE_MASK (0x0000FFFF) + +#define FCT_RX_CTL (0x0090) +#define FCT_RX_CTL_EN (0x80000000) +#define FCT_RX_CTL_RST (0x40000000) +#define FCT_RX_CTL_SBF (0x02000000) +#define FCT_RX_CTL_OVERFLOW (0x01000000) +#define FCT_RX_CTL_FRM_DROP (0x00800000) +#define FCT_RX_CTL_RX_NOT_EMPTY (0x00400000) +#define FCT_RX_CTL_RX_EMPTY (0x00200000) +#define FCT_RX_CTL_RX_DISABLED (0x00100000) +#define FCT_RX_CTL_RXUSED (0x0000FFFF) + +#define FCT_TX_CTL (0x0094) +#define FCT_TX_CTL_EN (0x80000000) +#define FCT_TX_CTL_RST (0x40000000) +#define FCT_TX_CTL_TX_NOT_EMPTY (0x00400000) +#define FCT_TX_CTL_TX_EMPTY (0x00200000) +#define FCT_TX_CTL_TX_DISABLED (0x00100000) +#define FCT_TX_CTL_TXUSED (0x0000FFFF) + +#define FCT_RX_FIFO_END (0x0098) +#define FCT_RX_FIFO_END_MASK (0x0000007F) + +#define FCT_TX_FIFO_END (0x009C) +#define FCT_TX_FIFO_END_MASK (0x0000003F) + +#define FCT_FLOW (0x00A0) +#define FCT_FLOW_THRESHOLD_OFF (0x00007F00) +#define FCT_FLOW_THRESHOLD_OFF_SHIFT (8) +#define FCT_FLOW_THRESHOLD_ON (0x0000007F) + +/* MAC CSRs */ +#define MAC_CR (0x100) +#define MAC_CR_ADP (0x00002000) +#define MAC_CR_ADD (0x00001000) +#define MAC_CR_ASD (0x00000800) +#define MAC_CR_INT_LOOP (0x00000400) +#define MAC_CR_BOLMT (0x000000C0) +#define MAC_CR_FDPX (0x00000008) +#define MAC_CR_CFG (0x00000006) +#define MAC_CR_CFG_10 (0x00000000) +#define MAC_CR_CFG_100 (0x00000002) +#define MAC_CR_CFG_1000 (0x00000004) +#define MAC_CR_RST (0x00000001) + +#define MAC_RX (0x104) +#define MAC_RX_MAX_SIZE (0x3FFF0000) +#define MAC_RX_MAX_SIZE_SHIFT (16) +#define MAC_RX_FCS_STRIP (0x00000010) +#define MAC_RX_FSE (0x00000004) +#define MAC_RX_RXD (0x00000002) +#define MAC_RX_RXEN (0x00000001) + +#define MAC_TX (0x108) +#define MAC_TX_BFCS (0x00000004) +#define MAC_TX_TXD (0x00000002) +#define MAC_TX_TXEN (0x00000001) + +#define FLOW (0x10C) +#define FLOW_FORCE_FC (0x80000000) +#define FLOW_TX_FCEN (0x40000000) +#define FLOW_RX_FCEN (0x20000000) +#define FLOW_FPF (0x10000000) +#define FLOW_PAUSE_TIME (0x0000FFFF) + +#define RAND_SEED (0x110) +#define RAND_SEED_MASK (0x0000FFFF) + +#define ERR_STS (0x114) +#define ERR_STS_FCS_ERR (0x00000100) +#define ERR_STS_LFRM_ERR (0x00000080) +#define ERR_STS_RUNT_ERR (0x00000040) +#define ERR_STS_COLLISION_ERR (0x00000010) +#define ERR_STS_ALIGN_ERR (0x00000008) +#define ERR_STS_URUN_ERR (0x00000004) + +#define RX_ADDRH (0x118) +#define RX_ADDRH_MASK (0x0000FFFF) + +#define RX_ADDRL (0x11C) + +#define MII_ACCESS (0x120) +#define MII_ACCESS_PHY_ADDR (0x0000F800) +#define MII_ACCESS_PHY_ADDR_SHIFT (11) +#define MII_ACCESS_REG_ADDR (0x000007C0) +#define MII_ACCESS_REG_ADDR_SHIFT (6) +#define MII_ACCESS_READ (0x00000000) +#define MII_ACCESS_WRITE (0x00000002) +#define MII_ACCESS_BUSY (0x00000001) + +#define MII_DATA (0x124) +#define MII_DATA_MASK (0x0000FFFF) + +#define WUCSR (0x140) +#define WUCSR_PFDA_FR (0x00000080) +#define WUCSR_WUFR (0x00000040) +#define WUCSR_MPR (0x00000020) +#define WUCSR_BCAST_FR (0x00000010) +#define WUCSR_PFDA_EN (0x00000008) +#define WUCSR_WUEN (0x00000004) +#define WUCSR_MPEN (0x00000002) +#define WUCSR_BCST_EN (0x00000001) + +#define WUF_CFGX (0x144) +#define WUF_CFGX_EN (0x80000000) +#define WUF_CFGX_ATYPE (0x03000000) +#define WUF_CFGX_ATYPE_UNICAST (0x00000000) +#define WUF_CFGX_ATYPE_MULTICAST (0x02000000) +#define WUF_CFGX_ATYPE_ALL (0x03000000) +#define WUF_CFGX_PATTERN_OFFSET (0x007F0000) +#define WUF_CFGX_PATTERN_OFFSET_SHIFT (16) +#define WUF_CFGX_CRC16 (0x0000FFFF) +#define WUF_NUM (8) + +#define WUF_MASKX (0x170) +#define WUF_MASKX_AVALID (0x80000000) +#define WUF_MASKX_ATYPE (0x40000000) + +#define ADDR_FILTX (0x300) +#define ADDR_FILTX_FB_VALID (0x80000000) +#define ADDR_FILTX_FB_TYPE (0x40000000) +#define ADDR_FILTX_FB_ADDRHI (0x0000FFFF) +#define ADDR_FILTX_SB_ADDRLO (0xFFFFFFFF) + +#define WUCSR2 (0x500) +#define WUCSR2_NS_RCD (0x00000040) +#define WUCSR2_ARP_RCD (0x00000020) +#define WUCSR2_TCPSYN_RCD (0x00000010) +#define WUCSR2_NS_OFFLOAD (0x00000004) +#define WUCSR2_ARP_OFFLOAD (0x00000002) +#define WUCSR2_TCPSYN_OFFLOAD (0x00000001) + +#define WOL_FIFO_STS (0x504) + +#define IPV6_ADDRX (0x510) + +#define IPV4_ADDRX (0x590) + + +/* Vendor-specific PHY Definitions */ + +/* Mode Control/Status Register */ +#define PHY_MODE_CTRL_STS (17) +#define MODE_CTRL_STS_EDPWRDOWN ((u16)0x2000) +#define MODE_CTRL_STS_ENERGYON ((u16)0x0002) + +#define PHY_INT_SRC (29) +#define PHY_INT_SRC_ENERGY_ON ((u16)0x0080) +#define PHY_INT_SRC_ANEG_COMP ((u16)0x0040) +#define PHY_INT_SRC_REMOTE_FAULT ((u16)0x0020) +#define PHY_INT_SRC_LINK_DOWN ((u16)0x0010) + +#define PHY_INT_MASK (30) +#define PHY_INT_MASK_ENERGY_ON ((u16)0x0080) +#define PHY_INT_MASK_ANEG_COMP ((u16)0x0040) +#define PHY_INT_MASK_REMOTE_FAULT ((u16)0x0020) +#define PHY_INT_MASK_LINK_DOWN ((u16)0x0010) +#define PHY_INT_MASK_DEFAULT (PHY_INT_MASK_ANEG_COMP | \ + PHY_INT_MASK_LINK_DOWN) + +#define PHY_SPECIAL (31) +#define PHY_SPECIAL_SPD ((u16)0x001C) +#define PHY_SPECIAL_SPD_10HALF ((u16)0x0004) +#define PHY_SPECIAL_SPD_10FULL ((u16)0x0014) +#define PHY_SPECIAL_SPD_100HALF ((u16)0x0008) +#define PHY_SPECIAL_SPD_100FULL ((u16)0x0018) + +/* USB Vendor Requests */ +#define USB_VENDOR_REQUEST_WRITE_REGISTER 0xA0 +#define USB_VENDOR_REQUEST_READ_REGISTER 0xA1 +#define USB_VENDOR_REQUEST_GET_STATS 0xA2 + +/* Interrupt Endpoint status word bitfields */ +#define INT_ENP_RDFO_INT ((u32)BIT(22)) +#define INT_ENP_TXE_INT ((u32)BIT(21)) +#define INT_ENP_TX_DIS_INT ((u32)BIT(19)) +#define INT_ENP_RX_DIS_INT ((u32)BIT(18)) +#define INT_ENP_PHY_INT ((u32)BIT(17)) +#define INT_ENP_MAC_ERR_INT ((u32)BIT(15)) +#define INT_ENP_RX_FIFO_DATA_INT ((u32)BIT(12)) + +#endif /* _SMSC75XX_H */ -- cgit v0.10.2 From 3feec9095d12e311b7d4eb7fe7e5dfa75d4a72a5 Mon Sep 17 00:00:00 2001 From: James Chapman Date: Tue, 16 Mar 2010 06:46:31 +0000 Subject: l2tp: Fix oops in pppol2tp_xmit When transmitting L2TP frames, we derive the outgoing interface's UDP checksum hardware assist capabilities from the tunnel dst dev. This can sometimes be NULL, especially when routing protocols are used and routing changes occur. This patch just checks for NULL dst or dev pointers when checking for netdev hardware assist features. BUG: unable to handle kernel NULL pointer dereference at 0000000c IP: [] pppol2tp_xmit+0x341/0x4da [pppol2tp] *pde = 00000000 Oops: 0000 [#1] SMP last sysfs file: /sys/class/net/lo/operstate Modules linked in: pppol2tp pppox ppp_generic slhc ipv6 dummy loop snd_hda_codec_atihdmi snd_hda_intel snd_hda_codec snd_pcm snd_timer snd soundcore snd_page_alloc evdev psmouse serio_raw processor button i2c_piix4 i2c_core ati_agp agpgart pcspkr ext3 jbd mbcache sd_mod ide_pci_generic atiixp ide_core ahci ata_generic floppy ehci_hcd ohci_hcd libata e1000e scsi_mod usbcore nls_base thermal fan thermal_sys [last unloaded: scsi_wait_scan] Pid: 0, comm: swapper Not tainted (2.6.32.8 #1) EIP: 0060:[] EFLAGS: 00010297 CPU: 3 EIP is at pppol2tp_xmit+0x341/0x4da [pppol2tp] EAX: 00000000 EBX: f64d1680 ECX: 000005b9 EDX: 00000000 ESI: f6b91850 EDI: f64d16ac EBP: f6a0c4c0 ESP: f70a9cac DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068 Process swapper (pid: 0, ti=f70a8000 task=f70a31c0 task.ti=f70a8000) Stack: 000005a9 000005b9 f734c400 f66652c0 f7352e00 f67dc800 00000000 f6b91800 <0> 000005a3 f70ef6c4 f67dcda9 000005a3 f89b192e 00000246 000005a3 f64d1680 <0> f63633e0 f6363320 f64d1680 f65a7320 f65a7364 f65856c0 f64d1680 f679f02f Call Trace: [] ? ppp_push+0x459/0x50e [ppp_generic] [] ? ppp_xmit_process+0x3b6/0x430 [ppp_generic] [] ? ppp_start_xmit+0x10d/0x120 [ppp_generic] [] ? dev_hard_start_xmit+0x21f/0x2b2 [] ? sch_direct_xmit+0x48/0x10e [] ? dev_queue_xmit+0x263/0x3a6 [] ? ip_finish_output+0x1f7/0x221 [] ? ip_forward_finish+0x2e/0x30 [] ? ip_rcv_finish+0x295/0x2a9 [] ? netif_receive_skb+0x3e9/0x404 [] ? e1000_clean_rx_irq+0x253/0x2fc [e1000e] [] ? e1000_clean+0x63/0x1fc [e1000e] [] ? sched_clock_local+0x15/0x11b [] ? net_rx_action+0x96/0x195 [] ? __do_softirq+0xaa/0x151 [] ? do_softirq+0x31/0x3c [] ? irq_exit+0x26/0x58 [] ? do_IRQ+0x78/0x89 [] ? common_interrupt+0x29/0x30 [] ? native_safe_halt+0x2/0x3 [] ? default_idle+0x55/0x75 [] ? c1e_idle+0xd2/0xd5 [] ? cpu_idle+0x46/0x62 Code: 8d 45 08 f0 ff 45 08 89 6b 08 c7 43 68 7e fb 9c f8 8a 45 24 83 e0 0c 3c 04 75 09 80 63 64 f3 e9 b4 00 00 00 8b 43 18 8b 4c 24 04 <8b> 40 0c 8d 79 11 f6 40 44 0e 8a 43 64 75 51 6a 00 8b 4c 24 08 EIP: [] pppol2tp_xmit+0x341/0x4da [pppol2tp] SS:ESP 0068:f70a9cac CR2: 000000000000000c Signed-off-by: James Chapman Signed-off-by: David S. Miller diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c index 9fbb2eb..5861ee9 100644 --- a/drivers/net/pppol2tp.c +++ b/drivers/net/pppol2tp.c @@ -1180,7 +1180,8 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) /* Calculate UDP checksum if configured to do so */ if (sk_tun->sk_no_check == UDP_CSUM_NOXMIT) skb->ip_summed = CHECKSUM_NONE; - else if (!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM)) { + else if ((skb_dst(skb) && skb_dst(skb)->dev) && + (!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM))) { skb->ip_summed = CHECKSUM_COMPLETE; csum = skb_checksum(skb, 0, udp_len, 0); uh->check = csum_tcpudp_magic(inet->inet_saddr, -- cgit v0.10.2 From db443c441e204cecc1bcec490d40997db988ce3a Mon Sep 17 00:00:00 2001 From: Steve Glendinning Date: Tue, 16 Mar 2010 09:03:06 +0000 Subject: smsc95xx: wait for PHY to complete reset during init This patch ensures the PHY correctly completes its reset before setting register values. Signed-off-by: Steve Glendinning Signed-off-by: David S. Miller diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index df9179a..d222d7e 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -709,6 +709,8 @@ static void smsc95xx_start_rx_path(struct usbnet *dev) static int smsc95xx_phy_initialize(struct usbnet *dev) { + int bmcr, timeout = 0; + /* Initialize MII structure */ dev->mii.dev = dev->net; dev->mii.mdio_read = smsc95xx_mdio_read; @@ -717,7 +719,20 @@ static int smsc95xx_phy_initialize(struct usbnet *dev) dev->mii.reg_num_mask = 0x1f; dev->mii.phy_id = SMSC95XX_INTERNAL_PHY_ID; + /* reset phy and wait for reset to complete */ smsc95xx_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET); + + do { + msleep(10); + bmcr = smsc95xx_mdio_read(dev->net, dev->mii.phy_id, MII_BMCR); + timeout++; + } while ((bmcr & MII_BMCR) && (timeout < 100)); + + if (timeout >= 100) { + netdev_warn(dev->net, "timeout on PHY Reset"); + return -EIO; + } + smsc95xx_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE, ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM); -- cgit v0.10.2 From c3259c8a7060d480e8eb2166da0a99d6879146b4 Mon Sep 17 00:00:00 2001 From: James Chapman Date: Tue, 16 Mar 2010 06:29:20 +0000 Subject: l2tp: Fix UDP socket reference count bugs in the pppol2tp driver This patch fixes UDP socket refcnt bugs in the pppol2tp driver. A bug can cause a kernel stack trace when a tunnel socket is closed. A way to reproduce the issue is to prepare the UDP socket for L2TP (by opening a tunnel pppol2tp socket) and then close it before any L2TP sessions are added to it. The sequence is Create UDP socket Create tunnel pppol2tp socket to prepare UDP socket for L2TP pppol2tp_connect: session_id=0, peer_session_id=0 L2TP SCCRP control frame received (tunnel_id==0) pppol2tp_recv_core: sock_hold() pppol2tp_recv_core: sock_put L2TP ZLB control frame received (tunnel_id=nnn) pppol2tp_recv_core: sock_hold() pppol2tp_recv_core: sock_put Close tunnel management socket pppol2tp_release: session_id=0, peer_session_id=0 Close UDP socket udp_lib_close: BUG The addition of sock_hold() in pppol2tp_connect() solves the problem. For data frames, two sock_put() calls were added to plug a refcnt leak per received data frame. The ref that is grabbed at the top of pppol2tp_recv_core() must always be released, but this wasn't done for accepted data frames or data frames discarded because of bad UDP checksums. This leak meant that any UDP socket that had passed L2TP data traffic (i.e. L2TP data frames, not just L2TP control frames) using pppol2tp would not be released by the kernel. WARNING: at include/net/sock.h:435 udp_lib_unhash+0x117/0x120() Pid: 1086, comm: openl2tpd Not tainted 2.6.33-rc1 #8 Call Trace: [] ? udp_lib_unhash+0x117/0x120 [] ? warn_slowpath_common+0x71/0xd0 [] ? udp_lib_unhash+0x117/0x120 [] ? warn_slowpath_null+0x13/0x20 [] ? udp_lib_unhash+0x117/0x120 [] ? sk_common_release+0x17/0x90 [] ? inet_release+0x33/0x60 [] ? sock_release+0x10/0x60 [] ? sock_close+0xf/0x30 [] ? __fput+0x52/0x150 [] ? filp_close+0x3e/0x70 [] ? put_files_struct+0x62/0xb0 [] ? do_exit+0x5e7/0x650 [] ? mntput_no_expire+0x13/0x70 [] ? filp_close+0x3e/0x70 [] ? do_group_exit+0x2a/0x70 [] ? sys_exit_group+0x11/0x20 [] ? sysenter_do_call+0x12/0x26 Signed-off-by: James Chapman Signed-off-by: David S. Miller diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c index 5861ee9..449a982 100644 --- a/drivers/net/pppol2tp.c +++ b/drivers/net/pppol2tp.c @@ -756,6 +756,7 @@ static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb) /* Try to dequeue as many skbs from reorder_q as we can. */ pppol2tp_recv_dequeue(session); + sock_put(sock); return 0; @@ -772,6 +773,7 @@ discard_bad_csum: UDP_INC_STATS_USER(&init_net, UDP_MIB_INERRORS, 0); tunnel->stats.rx_errors++; kfree_skb(skb); + sock_put(sock); return 0; @@ -1662,6 +1664,7 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr, if (tunnel_sock == NULL) goto end; + sock_hold(tunnel_sock); tunnel = tunnel_sock->sk_user_data; } else { tunnel = pppol2tp_tunnel_find(sock_net(sk), sp->pppol2tp.s_tunnel); -- cgit v0.10.2 From a2f46ee1ba5ee249ce2ca1ee7a7a0ac46529fb4f Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Tue, 16 Mar 2010 08:14:33 +0000 Subject: tipc: fix lockdep warning on address assignment So in the forward porting of various tipc packages, I was constantly getting this lockdep warning everytime I used tipc-config to set a network address for the protocol: [ INFO: possible circular locking dependency detected ] 2.6.33 #1 tipc-config/1326 is trying to acquire lock: (ref_table_lock){+.-...}, at: [] tipc_ref_discard+0x53/0xd4 [tipc] but task is already holding lock: (&(&entry->lock)->rlock#2){+.-...}, at: [] tipc_ref_lock+0x43/0x63 [tipc] which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #1 (&(&entry->lock)->rlock#2){+.-...}: [] __lock_acquire+0xb67/0xd0f [] lock_acquire+0xdc/0x102 [] _raw_spin_lock_bh+0x3b/0x6e [] tipc_ref_acquire+0xe8/0x11b [tipc] [] tipc_createport_raw+0x78/0x1b9 [tipc] [] tipc_createport+0x8b/0x125 [tipc] [] tipc_subscr_start+0xce/0x126 [tipc] [] process_signal_queue+0x47/0x7d [tipc] [] tasklet_action+0x8c/0xf4 [] __do_softirq+0xf8/0x1cd [] call_softirq+0x1c/0x30 [] _local_bh_enable_ip+0xb8/0xd7 [] local_bh_enable_ip+0xe/0x10 [] _raw_spin_unlock_bh+0x34/0x39 [] spin_unlock_bh.clone.0+0x15/0x17 [tipc] [] tipc_k_signal+0x8d/0xb1 [tipc] [] tipc_core_start+0x8a/0xad [tipc] [] 0xffffffffa01b1087 [] do_one_initcall+0x72/0x18a [] sys_init_module+0xd8/0x23a [] system_call_fastpath+0x16/0x1b -> #0 (ref_table_lock){+.-...}: [] __lock_acquire+0xa11/0xd0f [] lock_acquire+0xdc/0x102 [] _raw_write_lock_bh+0x3b/0x6e [] tipc_ref_discard+0x53/0xd4 [tipc] [] tipc_deleteport+0x40/0x119 [tipc] [] release+0xeb/0x137 [tipc] [] sock_release+0x1f/0x6f [] sock_close+0x27/0x2b [] __fput+0x12a/0x1df [] fput+0x1a/0x1c [] filp_close+0x68/0x72 [] sys_close+0xad/0xe7 [] system_call_fastpath+0x16/0x1b Finally decided I should fix this. Its a straightforward inversion, tipc_ref_acquire takes two locks in this order: ref_table_lock entry->lock while tipc_deleteport takes them in this order: entry->lock (via tipc_port_lock()) ref_table_lock (via tipc_ref_discard()) when the same entry is referenced, we get the above warning. The fix is equally straightforward. Theres no real relation between the entry->lock and the ref_table_lock (they just are needed at the same time), so move the entry->lock aquisition in tipc_ref_acquire down, after we unlock ref_table_lock (this is safe since the ref_table_lock guards changes to the reference table, and we've already claimed a slot there. I've tested the below fix and confirmed that it clears up the lockdep issue Signed-off-by: Neil Horman CC: Allan Stephens Signed-off-by: David S. Miller diff --git a/net/tipc/ref.c b/net/tipc/ref.c index 414fc34..8dea665 100644 --- a/net/tipc/ref.c +++ b/net/tipc/ref.c @@ -153,11 +153,11 @@ void tipc_ref_table_stop(void) u32 tipc_ref_acquire(void *object, spinlock_t **lock) { - struct reference *entry; u32 index; u32 index_mask; u32 next_plus_upper; u32 ref; + struct reference *entry = NULL; if (!object) { err("Attempt to acquire reference to non-existent object\n"); @@ -175,30 +175,36 @@ u32 tipc_ref_acquire(void *object, spinlock_t **lock) index = tipc_ref_table.first_free; entry = &(tipc_ref_table.entries[index]); index_mask = tipc_ref_table.index_mask; - /* take lock in case a previous user of entry still holds it */ - spin_lock_bh(&entry->lock); next_plus_upper = entry->ref; tipc_ref_table.first_free = next_plus_upper & index_mask; ref = (next_plus_upper & ~index_mask) + index; - entry->ref = ref; - entry->object = object; - *lock = &entry->lock; } else if (tipc_ref_table.init_point < tipc_ref_table.capacity) { index = tipc_ref_table.init_point++; entry = &(tipc_ref_table.entries[index]); spin_lock_init(&entry->lock); - spin_lock_bh(&entry->lock); ref = tipc_ref_table.start_mask + index; - entry->ref = ref; - entry->object = object; - *lock = &entry->lock; } else { ref = 0; } write_unlock_bh(&ref_table_lock); + /* + * Grab the lock so no one else can modify this entry + * While we assign its ref value & object pointer + */ + if (entry) { + spin_lock_bh(&entry->lock); + entry->ref = ref; + entry->object = object; + *lock = &entry->lock; + /* + * keep it locked, the caller is responsible + * for unlocking this when they're done with it + */ + } + return ref; } -- cgit v0.10.2 From 21edbb223ed2af88b090e7945af7d91d672e3aa6 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 16 Mar 2010 05:29:54 +0000 Subject: NET: netpoll, fix potential NULL ptr dereference Stanse found that one error path in netpoll_setup dereferences npinfo even though it is NULL. Avoid that by adding new label and go to that instead. Signed-off-by: Jiri Slaby Cc: Daniel Borkmann Cc: David S. Miller Acked-by: chavey@google.com Acked-by: Matt Mackall Signed-off-by: David S. Miller diff --git a/net/core/netpoll.c b/net/core/netpoll.c index 7aa6972..d4ec38f 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -735,7 +735,7 @@ int netpoll_setup(struct netpoll *np) npinfo = kmalloc(sizeof(*npinfo), GFP_KERNEL); if (!npinfo) { err = -ENOMEM; - goto release; + goto put; } npinfo->rx_flags = 0; @@ -845,7 +845,7 @@ int netpoll_setup(struct netpoll *np) kfree(npinfo); } - +put: dev_put(ndev); return err; } -- cgit v0.10.2 From 0ba8c9ec25465cd0680b80c0f5836f558e3b972d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?YOSHIFUJI=20Hideaki=20/=20=E5=90=89=E8=97=A4=E8=8B=B1?= =?UTF-8?q?=E6=98=8E?= Date: Mon, 15 Mar 2010 19:27:00 +0000 Subject: bridge br_multicast: Fix handling of Max Response Code in IGMPv3 message. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: David S. Miller diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 398221e..19618f2 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -852,8 +852,8 @@ static int br_multicast_query(struct net_bridge *br, if (ih3->nsrcs) goto out; - max_delay = ih3->code ? 1 : - IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE); + max_delay = ih3->code ? + IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE) : 1; } if (!group) -- cgit v0.10.2 From 8440853bb70010f2f8edc26cb0f7af60da8b2c5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?YOSHIFUJI=20Hideaki=20/=20=E5=90=89=E8=97=A4=E8=8B=B1?= =?UTF-8?q?=E6=98=8E?= Date: Mon, 15 Mar 2010 19:26:56 +0000 Subject: bridge br_multicast: Fix skb leakage in error path. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: David S. Miller diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 19618f2..6980625 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -991,7 +991,7 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br, err = pskb_trim_rcsum(skb2, len); if (err) - return err; + goto err_out; } len -= ip_hdrlen(skb2); @@ -1013,7 +1013,7 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br, case CHECKSUM_NONE: skb2->csum = 0; if (skb_checksum_complete(skb2)) - return -EINVAL; + goto out; } err = 0; @@ -1040,6 +1040,7 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br, out: __skb_push(skb2, offset); +err_out: if (skb2 != skb) kfree_skb(skb2); return err; -- cgit v0.10.2 From 858a18a6a2f74e8f0e5b2e9671d4b74694aba708 Mon Sep 17 00:00:00 2001 From: Vitaliy Gusev Date: Tue, 16 Mar 2010 01:07:51 +0000 Subject: route: Fix caught BUG_ON during rt_secret_rebuild_oneshot() route: Fix caught BUG_ON during rt_secret_rebuild_oneshot() Call rt_secret_rebuild can cause BUG_ON(timer_pending(&net->ipv4.rt_secret_timer)) in add_timer as there is not any synchronization for call rt_secret_rebuild_oneshot() for the same net namespace. Also this issue affects to rt_secret_reschedule(). Thus use mod_timer enstead. Signed-off-by: Vitaliy Gusev Acked-by: Neil Horman Signed-off-by: David S. Miller diff --git a/net/ipv4/route.c b/net/ipv4/route.c index d9b4024..a770df24 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -932,10 +932,8 @@ static void rt_secret_rebuild_oneshot(struct net *net) { del_timer_sync(&net->ipv4.rt_secret_timer); rt_cache_invalidate(net); - if (ip_rt_secret_interval) { - net->ipv4.rt_secret_timer.expires += ip_rt_secret_interval; - add_timer(&net->ipv4.rt_secret_timer); - } + if (ip_rt_secret_interval) + mod_timer(&net->ipv4.rt_secret_timer, jiffies + ip_rt_secret_interval); } static void rt_emergency_hash_rebuild(struct net *net) @@ -3103,22 +3101,20 @@ static void rt_secret_reschedule(int old) rtnl_lock(); for_each_net(net) { int deleted = del_timer_sync(&net->ipv4.rt_secret_timer); + long time; if (!new) continue; if (deleted) { - long time = net->ipv4.rt_secret_timer.expires - jiffies; + time = net->ipv4.rt_secret_timer.expires - jiffies; if (time <= 0 || (time += diff) <= 0) time = 0; - - net->ipv4.rt_secret_timer.expires = time; } else - net->ipv4.rt_secret_timer.expires = new; + time = new; - net->ipv4.rt_secret_timer.expires += jiffies; - add_timer(&net->ipv4.rt_secret_timer); + mod_timer(&net->ipv4.rt_secret_timer, jiffies + time); } rtnl_unlock(); } -- cgit v0.10.2 From 32dec5dd0233ebffa9cae25ce7ba6daeb7df4467 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?YOSHIFUJI=20Hideaki=20/=20=E5=90=89=E8=97=A4=E8=8B=B1?= =?UTF-8?q?=E6=98=8E?= Date: Mon, 15 Mar 2010 21:51:18 +0000 Subject: bridge br_multicast: Don't refer to BR_INPUT_SKB_CB(skb)->mrouters_only without IGMP snooping. Without CONFIG_BRIDGE_IGMP_SNOOPING, BR_INPUT_SKB_CB(skb)->mrouters_only is not appropriately initialized, so we can see garbage. A clear option to fix this is to set it even without that config, but we cannot optimize out the branch. Let's introduce a macro that returns value of mrouters_only and let it return 0 without CONFIG_BRIDGE_IGMP_SNOOPING. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: David S. Miller diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index eb7062d..90a9024 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c @@ -40,7 +40,7 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev) goto out; mdst = br_mdb_get(br, skb); - if (mdst || BR_INPUT_SKB_CB(skb)->mrouters_only) + if (mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) br_multicast_deliver(mdst, skb); else br_flood_deliver(br, skb); diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 08a72e6..d74d570 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c @@ -70,7 +70,7 @@ int br_handle_frame_finish(struct sk_buff *skb) if (is_multicast_ether_addr(dest)) { mdst = br_mdb_get(br, skb); - if (mdst || BR_INPUT_SKB_CB(skb)->mrouters_only) { + if (mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) { if ((mdst && !hlist_unhashed(&mdst->mglist)) || br_multicast_is_router(br)) skb2 = skb; diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index bfb8feb..846d7d1 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -206,12 +206,20 @@ struct net_bridge struct br_input_skb_cb { struct net_device *brdev; +#ifdef CONFIG_BRIDGE_IGMP_SNOOPING int igmp; int mrouters_only; +#endif }; #define BR_INPUT_SKB_CB(__skb) ((struct br_input_skb_cb *)(__skb)->cb) +#ifdef CONFIG_BRIDGE_IGMP_SNOOPING +# define BR_INPUT_SKB_CB_MROUTERS_ONLY(__skb) (BR_INPUT_SKB_CB(__skb)->mrouters_only) +#else +# define BR_INPUT_SKB_CB_MROUTERS_ONLY(__skb) (0) +#endif + extern struct notifier_block br_device_notifier; extern const u8 br_group_address[ETH_ALEN]; -- cgit v0.10.2 From 87faf3ccf1c939938600ab57c6c9ed5bd2e5f4cc Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 16 Mar 2010 14:37:47 -0700 Subject: bridge: Make first arg to deliver_clone const. Otherwise we get a warning from the call in br_forward(). Signed-off-by: David S. Miller diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c index 8347916..8dbec83 100644 --- a/net/bridge/br_forward.c +++ b/net/bridge/br_forward.c @@ -19,7 +19,8 @@ #include #include "br_private.h" -static int deliver_clone(struct net_bridge_port *prev, struct sk_buff *skb, +static int deliver_clone(const struct net_bridge_port *prev, + struct sk_buff *skb, void (*__packet_hook)(const struct net_bridge_port *p, struct sk_buff *skb)); @@ -112,7 +113,8 @@ void br_forward(const struct net_bridge_port *to, struct sk_buff *skb, struct sk kfree_skb(skb); } -static int deliver_clone(struct net_bridge_port *prev, struct sk_buff *skb, +static int deliver_clone(const struct net_bridge_port *prev, + struct sk_buff *skb, void (*__packet_hook)(const struct net_bridge_port *p, struct sk_buff *skb)) { -- cgit v0.10.2 From f04e879bf296d136bcafd8c5a26e95599b141671 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 16 Mar 2010 14:40:42 -0700 Subject: sunxvr1000: Add missing FB=y depenency. Signed-off-by: David S. Miller diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index a5755b8..f15fb02 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -911,7 +911,7 @@ config FB_XVR2500 config FB_XVR1000 bool "Sun XVR-1000 support" - depends on SPARC64 + depends on (FB = y) && SPARC64 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT -- cgit v0.10.2 From 00909e955125e90a6ebb34671c56c4c851e62951 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 16 Mar 2010 18:28:46 -0300 Subject: perf top: Add missing initialization to zero MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The dso_short_width has to start as zero, as we're calculating the maximum short DSO name length, somehow I missed this one. Reported-by: Frédéric Weisbecker Signed-off-by: Arnaldo Carvalho de Melo Cc: Frédéric Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Paul Mackerras LKML-Reference: <1268774926-27488-1-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 8364c8a..1f52932 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -455,7 +455,7 @@ static void print_sym_table(void) struct sym_entry *syme, *n; struct rb_root tmp = RB_ROOT; struct rb_node *nd; - int sym_width = 0, dso_width = 0, dso_short_width; + int sym_width = 0, dso_width = 0, dso_short_width = 0; const int win_width = winsize.ws_col - 1; samples = userspace_samples = 0; -- cgit v0.10.2 From d6ccb1f55ddf5146219707c0e71b85e3a52179b4 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 10 Mar 2010 23:33:25 -0600 Subject: powerpc/85xx: Make sure lwarx hint isn't set on ppc32 e500v1/v2 based chips will treat any reserved field being set in an opcode as illegal. Thus always setting the hint in the opcode is a bad idea. Anton should be kept away from the powerpc opcode map. Signed-off-by: Kumar Gala diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h index aea7147..d553bbe 100644 --- a/arch/powerpc/include/asm/ppc-opcode.h +++ b/arch/powerpc/include/asm/ppc-opcode.h @@ -25,7 +25,7 @@ #define PPC_INST_LDARX 0x7c0000a8 #define PPC_INST_LSWI 0x7c0004aa #define PPC_INST_LSWX 0x7c00042a -#define PPC_INST_LWARX 0x7c000029 +#define PPC_INST_LWARX 0x7c000028 #define PPC_INST_LWSYNC 0x7c2004ac #define PPC_INST_LXVD2X 0x7c000698 #define PPC_INST_MCRXR 0x7c000400 @@ -62,8 +62,8 @@ #define __PPC_T_TLB(t) (((t) & 0x3) << 21) #define __PPC_WC(w) (((w) & 0x3) << 21) /* - * Only use the larx hint bit on 64bit CPUs. Once we verify it doesn't have - * any side effects on all 32bit processors, we can do this all the time. + * Only use the larx hint bit on 64bit CPUs. e500v1/v2 based CPUs will treat a + * larx with EH set as an illegal instruction. */ #ifdef CONFIG_PPC64 #define __PPC_EH(eh) (((eh) & 0x1) << 0) -- cgit v0.10.2 From 9d296cfa69b3d4abc9d556986d544f0727988eed Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Tue, 16 Mar 2010 23:39:56 -0500 Subject: powerpc/fsl-booke: Get coherent bit from PTE We shouldn't be always setting 'M' in the TLB entry since its reasonable for somethings to be mapped non-coherent. The PTE should have 'M' set properly. Signed-off-by: Kumar Gala diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index 25793bb..a7cf493 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -747,9 +747,6 @@ finish_tlb_load: #else rlwimi r12, r11, 26, 27, 31 /* extract WIMGE from pte */ #endif -#ifdef CONFIG_SMP - ori r12, r12, MAS2_M -#endif mtspr SPRN_MAS2, r12 #ifdef CONFIG_PTE_64BIT -- cgit v0.10.2 From 8bc037fb89bb3104b9ae290d18c877624cd7d9cc Mon Sep 17 00:00:00 2001 From: KOSAKI Motohiro Date: Wed, 17 Mar 2010 09:36:58 +0900 Subject: sched: Use proper type in sched_getaffinity() Using the proper type fixes the following compiler warning: kernel/sched.c:4850: warning: comparison of distinct pointer types lacks a cast Signed-off-by: KOSAKI Motohiro Cc: torvalds@linux-foundation.org Cc: travis@sgi.com Cc: peterz@infradead.org Cc: drepper@redhat.com Cc: rja@sgi.com Cc: sharyath@in.ibm.com Cc: steiner@sgi.com LKML-Reference: <20100317090046.4C79.A69D9226@jp.fujitsu.com> Signed-off-by: Ingo Molnar diff --git a/kernel/sched.c b/kernel/sched.c index 82975b5..49d2fa7 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -4912,7 +4912,7 @@ SYSCALL_DEFINE3(sched_getaffinity, pid_t, pid, unsigned int, len, ret = sched_getaffinity(pid, mask); if (ret == 0) { - int retlen = min(len, cpumask_size()); + size_t retlen = min_t(size_t, len, cpumask_size()); if (copy_to_user(user_mask_ptr, mask, retlen)) ret = -EFAULT; -- cgit v0.10.2 From dcd5c1662db59a6b82942f47fb6ac9dd63f6d3dd Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Tue, 16 Mar 2010 01:05:02 +0100 Subject: perf: Fix unexported generic perf_arch_fetch_caller_regs perf_arch_fetch_caller_regs() is exported for the overriden x86 version, but not for the generic weak version. As a general rule, weak functions should not have their symbol exported in the same file they are defined. So let's export it on trace_event_perf.c as it is used by trace events only. This fixes: ERROR: ".perf_arch_fetch_caller_regs" [fs/xfs/xfs.ko] undefined! ERROR: ".perf_arch_fetch_caller_regs" [arch/powerpc/platforms/cell/spufs/spufs.ko] undefined! -v2: And also only build it if trace events are enabled. -v3: Fix changelog mistake Reported-by: Stephen Rothwell Signed-off-by: Frederic Weisbecker Cc: Peter Zijlstra Cc: Xiao Guangrong Cc: Paul Mackerras LKML-Reference: <1268697902-9518-1-git-send-regression-fweisbec@gmail.com> Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 7645fae..60398a0 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -1702,6 +1702,7 @@ struct perf_callchain_entry *perf_callchain(struct pt_regs *regs) return entry; } +#ifdef CONFIG_EVENT_TRACING void perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int skip) { regs->ip = ip; @@ -1713,4 +1714,4 @@ void perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int ski regs->cs = __KERNEL_CS; local_save_flags(regs->flags); } -EXPORT_SYMBOL_GPL(perf_arch_fetch_caller_regs); +#endif diff --git a/kernel/perf_event.c b/kernel/perf_event.c index fb3031c..574ee58 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c @@ -2786,10 +2786,12 @@ __weak struct perf_callchain_entry *perf_callchain(struct pt_regs *regs) return NULL; } +#ifdef CONFIG_EVENT_TRACING __weak void perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int skip) { } +#endif /* * Output diff --git a/kernel/trace/trace_event_perf.c b/kernel/trace/trace_event_perf.c index 0709e4f..7d79a10 100644 --- a/kernel/trace/trace_event_perf.c +++ b/kernel/trace/trace_event_perf.c @@ -12,6 +12,8 @@ DEFINE_PER_CPU(struct pt_regs, perf_trace_regs); EXPORT_PER_CPU_SYMBOL_GPL(perf_trace_regs); +EXPORT_SYMBOL_GPL(perf_arch_fetch_caller_regs); + static char *perf_trace_buf; static char *perf_trace_buf_nmi; -- cgit v0.10.2 From 0e255572121180c900e24e33b87047abd8153cce Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 8 Mar 2010 23:24:22 +0200 Subject: vhost: fix interrupt mitigation with raw sockets A thinko in code means we never trigger interrupt mitigation. Fix this. Reported-by: Juan Quintela Reported-by: Unai Uribarri Signed-off-by: Michael S. Tsirkin diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index fcafb6b..a6a88df 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c @@ -125,7 +125,7 @@ static void handle_tx(struct vhost_net *net) mutex_lock(&vq->mutex); vhost_disable_notify(vq); - if (wmem < sock->sk->sk_sndbuf * 2) + if (wmem < sock->sk->sk_sndbuf / 2) tx_poll_stop(net); hdr_size = vq->hdr_size; -- cgit v0.10.2 From dadf28a10c3eb29421837a2e413ab869ebd9e168 Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Wed, 17 Mar 2010 13:14:13 -0400 Subject: ACPI: EC: Allow multibyte access to EC http://bugzilla.kernel.org/show_bug.cgi?id=14667 Signed-off-by: Alexey Starikovskiy Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/exprep.c b/drivers/acpi/acpica/exprep.c index edf62bf..a610ebe 100644 --- a/drivers/acpi/acpica/exprep.c +++ b/drivers/acpi/acpica/exprep.c @@ -468,6 +468,18 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info) acpi_ut_add_reference(obj_desc->field.region_obj); + /* allow full data read from EC address space */ + if (obj_desc->field.region_obj->region.space_id == + ACPI_ADR_SPACE_EC) { + if (obj_desc->common_field.bit_length > 8) + obj_desc->common_field.access_bit_width = + ACPI_ROUND_UP(obj_desc->common_field. + bit_length, 8); + obj_desc->common_field.access_byte_width = + ACPI_DIV_8(obj_desc->common_field. + access_bit_width); + } + ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, "RegionField: BitOff %X, Off %X, Gran %X, Region %p\n", obj_desc->field.start_field_bit_offset, diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 1ac28c6..7208a69 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -628,12 +628,12 @@ static u32 acpi_ec_gpe_handler(void *data) static acpi_status acpi_ec_space_handler(u32 function, acpi_physical_address address, - u32 bits, u64 *value, + u32 bits, u64 *value64, void *handler_context, void *region_context) { struct acpi_ec *ec = handler_context; - int result = 0, i; - u8 temp = 0; + int result = 0, i, bytes = bits / 8; + u8 *value = (u8 *)value64; if ((address > 0xFF) || !value || !handler_context) return AE_BAD_PARAMETER; @@ -641,32 +641,15 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address, if (function != ACPI_READ && function != ACPI_WRITE) return AE_BAD_PARAMETER; - if (bits != 8 && acpi_strict) - return AE_BAD_PARAMETER; - - if (EC_FLAGS_MSI) + if (EC_FLAGS_MSI || bits > 8) acpi_ec_burst_enable(ec); - if (function == ACPI_READ) { - result = acpi_ec_read(ec, address, &temp); - *value = temp; - } else { - temp = 0xff & (*value); - result = acpi_ec_write(ec, address, temp); - } - - for (i = 8; unlikely(bits - i > 0); i += 8) { - ++address; - if (function == ACPI_READ) { - result = acpi_ec_read(ec, address, &temp); - (*value) |= ((u64)temp) << i; - } else { - temp = 0xff & ((*value) >> i); - result = acpi_ec_write(ec, address, temp); - } - } + for (i = 0; i < bytes; ++i, ++address, ++value) + result = (function == ACPI_READ) ? + acpi_ec_read(ec, address, value) : + acpi_ec_write(ec, address, *value); - if (EC_FLAGS_MSI) + if (EC_FLAGS_MSI || bits > 8) acpi_ec_burst_disable(ec); switch (result) { -- cgit v0.10.2 From 603037c3d1a42d5013f035355a2c60b0006a9fdf Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 11 Mar 2010 11:37:16 +0900 Subject: ahci: add missing nv IDs bko#15481 shows that we're missing some NVIDIA ahci PCI IDs. Peer Chen confirms that IDs 0x580-0x58f are reserved for cases where Linux ID option is selected in the BIOS and are only used for mcp65-73. Add 0x0581-0x058f. http://bugzilla.kernel.org/show_bug.cgi?id=15481 Signed-off-by: Tejun Heo Cc: Peer Chen Signed-off-by: Jeff Garzik diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 6bd930b..9e5b121 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -641,6 +641,21 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(NVIDIA, 0x055a), board_ahci_yesncq }, /* MCP67 */ { PCI_VDEVICE(NVIDIA, 0x055b), board_ahci_yesncq }, /* MCP67 */ { PCI_VDEVICE(NVIDIA, 0x0580), board_ahci_yesncq }, /* Linux ID */ + { PCI_VDEVICE(NVIDIA, 0x0581), board_ahci_yesncq }, /* Linux ID */ + { PCI_VDEVICE(NVIDIA, 0x0582), board_ahci_yesncq }, /* Linux ID */ + { PCI_VDEVICE(NVIDIA, 0x0583), board_ahci_yesncq }, /* Linux ID */ + { PCI_VDEVICE(NVIDIA, 0x0584), board_ahci_yesncq }, /* Linux ID */ + { PCI_VDEVICE(NVIDIA, 0x0585), board_ahci_yesncq }, /* Linux ID */ + { PCI_VDEVICE(NVIDIA, 0x0586), board_ahci_yesncq }, /* Linux ID */ + { PCI_VDEVICE(NVIDIA, 0x0587), board_ahci_yesncq }, /* Linux ID */ + { PCI_VDEVICE(NVIDIA, 0x0588), board_ahci_yesncq }, /* Linux ID */ + { PCI_VDEVICE(NVIDIA, 0x0589), board_ahci_yesncq }, /* Linux ID */ + { PCI_VDEVICE(NVIDIA, 0x058a), board_ahci_yesncq }, /* Linux ID */ + { PCI_VDEVICE(NVIDIA, 0x058b), board_ahci_yesncq }, /* Linux ID */ + { PCI_VDEVICE(NVIDIA, 0x058c), board_ahci_yesncq }, /* Linux ID */ + { PCI_VDEVICE(NVIDIA, 0x058d), board_ahci_yesncq }, /* Linux ID */ + { PCI_VDEVICE(NVIDIA, 0x058e), board_ahci_yesncq }, /* Linux ID */ + { PCI_VDEVICE(NVIDIA, 0x058f), board_ahci_yesncq }, /* Linux ID */ { PCI_VDEVICE(NVIDIA, 0x07f0), board_ahci_yesncq }, /* MCP73 */ { PCI_VDEVICE(NVIDIA, 0x07f1), board_ahci_yesncq }, /* MCP73 */ { PCI_VDEVICE(NVIDIA, 0x07f2), board_ahci_yesncq }, /* MCP73 */ -- cgit v0.10.2 From 9deb343189b3cf45e84dd08480f330575ffe2004 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 16 Mar 2010 09:50:26 +0900 Subject: ahci: use BIOS date in broken_suspend list HP is recycling both DMI_PRODUCT_NAME and DMI_BIOS_VERSION making ahci_broken_suspend() trigger for later products which are not affected by the original problems. Match BIOS date instead of version and add references to bko's so that full information can be found easier later. This fixes http://bugzilla.kernel.org/show_bug.cgi?id=15462 Signed-off-by: Tejun Heo Reported-by: tigerfishdaisy@gmail.com Signed-off-by: Jeff Garzik diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 9e5b121..e7e2c7a 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -3037,6 +3037,14 @@ static bool ahci_broken_suspend(struct pci_dev *pdev) * On HP dv[4-6] and HDX18 with earlier BIOSen, link * to the harddisk doesn't become online after * resuming from STR. Warn and fail suspend. + * + * http://bugzilla.kernel.org/show_bug.cgi?id=12276 + * + * Use dates instead of versions to match as HP is + * apparently recycling both product and version + * strings. + * + * http://bugzilla.kernel.org/show_bug.cgi?id=15462 */ { .ident = "dv4", @@ -3045,7 +3053,7 @@ static bool ahci_broken_suspend(struct pci_dev *pdev) DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4 Notebook PC"), }, - .driver_data = "F.30", /* cutoff BIOS version */ + .driver_data = "20090105", /* F.30 */ }, { .ident = "dv5", @@ -3054,7 +3062,7 @@ static bool ahci_broken_suspend(struct pci_dev *pdev) DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv5 Notebook PC"), }, - .driver_data = "F.16", /* cutoff BIOS version */ + .driver_data = "20090506", /* F.16 */ }, { .ident = "dv6", @@ -3063,7 +3071,7 @@ static bool ahci_broken_suspend(struct pci_dev *pdev) DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv6 Notebook PC"), }, - .driver_data = "F.21", /* cutoff BIOS version */ + .driver_data = "20090423", /* F.21 */ }, { .ident = "HDX18", @@ -3072,7 +3080,7 @@ static bool ahci_broken_suspend(struct pci_dev *pdev) DMI_MATCH(DMI_PRODUCT_NAME, "HP HDX18 Notebook PC"), }, - .driver_data = "F.23", /* cutoff BIOS version */ + .driver_data = "20090430", /* F.23 */ }, /* * Acer eMachines G725 has the same problem. BIOS @@ -3080,6 +3088,8 @@ static bool ahci_broken_suspend(struct pci_dev *pdev) * work. Inbetween, there are V1.06, V2.06 and V3.03 * that we don't have much idea about. For now, * blacklist anything older than V3.04. + * + * http://bugzilla.kernel.org/show_bug.cgi?id=15104 */ { .ident = "G725", @@ -3087,19 +3097,21 @@ static bool ahci_broken_suspend(struct pci_dev *pdev) DMI_MATCH(DMI_SYS_VENDOR, "eMachines"), DMI_MATCH(DMI_PRODUCT_NAME, "eMachines G725"), }, - .driver_data = "V3.04", /* cutoff BIOS version */ + .driver_data = "20091216", /* V3.04 */ }, { } /* terminate list */ }; const struct dmi_system_id *dmi = dmi_first_match(sysids); - const char *ver; + int year, month, date; + char buf[9]; if (!dmi || pdev->bus->number || pdev->devfn != PCI_DEVFN(0x1f, 2)) return false; - ver = dmi_get_system_info(DMI_BIOS_VERSION); + dmi_get_date(DMI_BIOS_DATE, &year, &month, &date); + snprintf(buf, sizeof(buf), "%04d%02d%02d", year, month, date); - return !ver || strcmp(ver, dmi->driver_data) < 0; + return strcmp(buf, dmi->driver_data) < 0; } static bool ahci_broken_online(struct pci_dev *pdev) -- cgit v0.10.2 From ee860b6a650360c91f5d5f9a94262aad9be90015 Mon Sep 17 00:00:00 2001 From: Sachin Prabhu Date: Wed, 10 Mar 2010 10:28:40 -0500 Subject: [PATCH] Skip check for mandatory locks when unlocking ocfs2_lock() will skip locks on file which has mode set to 02666. This is a problem in cases where the mode of the file is changed after a process has obtained a lock on the file. ocfs2_lock() should skip the check for mandatory locks when unlocking a file. Signed-off-by: Sachin Prabhu Signed-off-by: Joel Becker diff --git a/fs/ocfs2/locks.c b/fs/ocfs2/locks.c index 544ac62..b5cb3ed 100644 --- a/fs/ocfs2/locks.c +++ b/fs/ocfs2/locks.c @@ -133,7 +133,7 @@ int ocfs2_lock(struct file *file, int cmd, struct file_lock *fl) if (!(fl->fl_flags & FL_POSIX)) return -ENOLCK; - if (__mandatory_lock(inode)) + if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK) return -ENOLCK; return ocfs2_plock(osb->cconn, OCFS2_I(inode)->ip_blkno, file, cmd, fl); -- cgit v0.10.2 From 78c37eb0d5e6a9727b12ea0f1821795ffaa66cfe Mon Sep 17 00:00:00 2001 From: Tao Ma Date: Wed, 3 Mar 2010 11:26:27 +0800 Subject: ocfs2: Change bg_chain check for ocfs2_validate_gd_parent. In ocfs2_validate_gd_parent, we check bg_chain against the cl_next_free_rec of the dinode. Actually in resize, we have the chance of bg_chain == cl_next_free_rec. So add some additional condition check for it. I also rename paramter "clean_error" to "resize", since the old one is not clearly enough to indicate that we should only meet with this case in resize. btw, the correpsonding bug is http://oss.oracle.com/bugzilla/show_bug.cgi?id=1230. Signed-off-by: Tao Ma Signed-off-by: Joel Becker diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c index c3c60bc..0016503 100644 --- a/fs/ocfs2/suballoc.c +++ b/fs/ocfs2/suballoc.c @@ -152,7 +152,7 @@ static u32 ocfs2_bits_per_group(struct ocfs2_chain_list *cl) #define do_error(fmt, ...) \ do{ \ - if (clean_error) \ + if (resize) \ mlog(ML_ERROR, fmt "\n", ##__VA_ARGS__); \ else \ ocfs2_error(sb, fmt, ##__VA_ARGS__); \ @@ -160,7 +160,7 @@ static u32 ocfs2_bits_per_group(struct ocfs2_chain_list *cl) static int ocfs2_validate_gd_self(struct super_block *sb, struct buffer_head *bh, - int clean_error) + int resize) { struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *)bh->b_data; @@ -211,7 +211,7 @@ static int ocfs2_validate_gd_self(struct super_block *sb, static int ocfs2_validate_gd_parent(struct super_block *sb, struct ocfs2_dinode *di, struct buffer_head *bh, - int clean_error) + int resize) { unsigned int max_bits; struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *)bh->b_data; @@ -233,8 +233,11 @@ static int ocfs2_validate_gd_parent(struct super_block *sb, return -EINVAL; } - if (le16_to_cpu(gd->bg_chain) >= - le16_to_cpu(di->id2.i_chain.cl_next_free_rec)) { + /* In resize, we may meet the case bg_chain == cl_next_free_rec. */ + if ((le16_to_cpu(gd->bg_chain) > + le16_to_cpu(di->id2.i_chain.cl_next_free_rec)) || + ((le16_to_cpu(gd->bg_chain) == + le16_to_cpu(di->id2.i_chain.cl_next_free_rec)) && !resize)) { do_error("Group descriptor #%llu has bad chain %u", (unsigned long long)bh->b_blocknr, le16_to_cpu(gd->bg_chain)); -- cgit v0.10.2 From 6527f8f848ec84b9daf1cb07601266126b8507ab Mon Sep 17 00:00:00 2001 From: Tao Ma Date: Wed, 10 Mar 2010 09:56:52 +0800 Subject: ocfs2: Update i_blocks in reflink operations. In reflink, we need to upate i_blocks for the target inode. Reported-by: Jie Liu Signed-off-by: Tao Ma Signed-off-by: Joel Becker diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c index 9e96921..29405f2 100644 --- a/fs/ocfs2/refcounttree.c +++ b/fs/ocfs2/refcounttree.c @@ -4075,6 +4075,7 @@ static int ocfs2_complete_reflink(struct inode *s_inode, OCFS2_I(t_inode)->ip_dyn_features = OCFS2_I(s_inode)->ip_dyn_features; spin_unlock(&OCFS2_I(t_inode)->ip_lock); i_size_write(t_inode, size); + t_inode->i_blocks = s_inode->i_blocks; di->i_xattr_inline_size = s_di->i_xattr_inline_size; di->i_clusters = s_di->i_clusters; -- cgit v0.10.2 From fcefd25ac89239cb57fa198f125a79ff85468c75 Mon Sep 17 00:00:00 2001 From: Mark Fasheh Date: Mon, 15 Mar 2010 15:39:00 -0700 Subject: ocfs2: set i_mode on disk during acl operations ocfs2_set_acl() and ocfs2_init_acl() were setting i_mode on the in-memory inode, but never setting it on the disk copy. Thus, acls were some times not getting propagated between nodes. This patch fixes the issue by adding a helper function ocfs2_acl_set_mode() which does this the right way. ocfs2_set_acl() and ocfs2_init_acl() are then updated to call ocfs2_acl_set_mode(). Signed-off-by: Mark Fasheh Signed-off-by: Joel Becker diff --git a/fs/ocfs2/acl.c b/fs/ocfs2/acl.c index 0501974..8ccf0f8 100644 --- a/fs/ocfs2/acl.c +++ b/fs/ocfs2/acl.c @@ -30,6 +30,8 @@ #include "alloc.h" #include "dlmglue.h" #include "file.h" +#include "inode.h" +#include "journal.h" #include "ocfs2_fs.h" #include "xattr.h" @@ -166,6 +168,60 @@ static struct posix_acl *ocfs2_get_acl(struct inode *inode, int type) } /* + * Helper function to set i_mode in memory and disk. Some call paths + * will not have di_bh or a journal handle to pass, in which case it + * will create it's own. + */ +static int ocfs2_acl_set_mode(struct inode *inode, struct buffer_head *di_bh, + handle_t *handle, umode_t new_mode) +{ + int ret, commit_handle = 0; + struct ocfs2_dinode *di; + + if (di_bh == NULL) { + ret = ocfs2_read_inode_block(inode, &di_bh); + if (ret) { + mlog_errno(ret); + goto out; + } + } else + get_bh(di_bh); + + if (handle == NULL) { + handle = ocfs2_start_trans(OCFS2_SB(inode->i_sb), + OCFS2_INODE_UPDATE_CREDITS); + if (IS_ERR(handle)) { + ret = PTR_ERR(handle); + mlog_errno(ret); + goto out_brelse; + } + + commit_handle = 1; + } + + di = (struct ocfs2_dinode *)di_bh->b_data; + ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), di_bh, + OCFS2_JOURNAL_ACCESS_WRITE); + if (ret) { + mlog_errno(ret); + goto out_commit; + } + + inode->i_mode = new_mode; + di->i_mode = cpu_to_le16(inode->i_mode); + + ocfs2_journal_dirty(handle, di_bh); + +out_commit: + if (commit_handle) + ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle); +out_brelse: + brelse(di_bh); +out: + return ret; +} + +/* * Set the access or default ACL of an inode. */ static int ocfs2_set_acl(handle_t *handle, @@ -193,9 +249,14 @@ static int ocfs2_set_acl(handle_t *handle, if (ret < 0) return ret; else { - inode->i_mode = mode; if (ret == 0) acl = NULL; + + ret = ocfs2_acl_set_mode(inode, di_bh, + handle, mode); + if (ret) + return ret; + } } break; @@ -283,6 +344,7 @@ int ocfs2_init_acl(handle_t *handle, struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); struct posix_acl *acl = NULL; int ret = 0; + mode_t mode; if (!S_ISLNK(inode->i_mode)) { if (osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) { @@ -291,12 +353,17 @@ int ocfs2_init_acl(handle_t *handle, if (IS_ERR(acl)) return PTR_ERR(acl); } - if (!acl) - inode->i_mode &= ~current_umask(); + if (!acl) { + mode = inode->i_mode & ~current_umask(); + ret = ocfs2_acl_set_mode(inode, di_bh, handle, mode); + if (ret) { + mlog_errno(ret); + goto cleanup; + } + } } if ((osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) && acl) { struct posix_acl *clone; - mode_t mode; if (S_ISDIR(inode->i_mode)) { ret = ocfs2_set_acl(handle, inode, di_bh, @@ -313,7 +380,7 @@ int ocfs2_init_acl(handle_t *handle, mode = inode->i_mode; ret = posix_acl_create_masq(clone, &mode); if (ret >= 0) { - inode->i_mode = mode; + ret = ocfs2_acl_set_mode(inode, di_bh, handle, mode); if (ret > 0) { ret = ocfs2_set_acl(handle, inode, di_bh, ACL_TYPE_ACCESS, -- cgit v0.10.2 From 5db5b0215af94a36d4bf10900ff9707b6d5c1610 Mon Sep 17 00:00:00 2001 From: Shane Huang Date: Tue, 16 Mar 2010 18:08:55 +0800 Subject: ahci: pp->active_link is not reliable when FBS is enabled pp->active_link is not reliable when FBS is enabled. Both PORT_SCR_ACT and PORT_CMD_ISSUE should be checked because mixed NCQ and non-NCQ commands may be in flight. Signed-off-by: Shane Huang Signed-off-by: Jeff Garzik diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index e7e2c7a..fdc9bcb 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -2278,7 +2278,7 @@ static void ahci_port_intr(struct ata_port *ap) struct ahci_port_priv *pp = ap->private_data; struct ahci_host_priv *hpriv = ap->host->private_data; int resetting = !!(ap->pflags & ATA_PFLAG_RESETTING); - u32 status, qc_active; + u32 status, qc_active = 0; int rc; status = readl(port_mmio + PORT_IRQ_STAT); @@ -2336,11 +2336,22 @@ static void ahci_port_intr(struct ata_port *ap) } } - /* pp->active_link is valid iff any command is in flight */ - if (ap->qc_active && pp->active_link->sactive) - qc_active = readl(port_mmio + PORT_SCR_ACT); - else - qc_active = readl(port_mmio + PORT_CMD_ISSUE); + /* pp->active_link is not reliable once FBS is enabled, both + * PORT_SCR_ACT and PORT_CMD_ISSUE should be checked because + * NCQ and non-NCQ commands may be in flight at the same time. + */ + if (pp->fbs_enabled) { + if (ap->qc_active) { + qc_active = readl(port_mmio + PORT_SCR_ACT); + qc_active |= readl(port_mmio + PORT_CMD_ISSUE); + } + } else { + /* pp->active_link is valid iff any command is in flight */ + if (ap->qc_active && pp->active_link->sactive) + qc_active = readl(port_mmio + PORT_SCR_ACT); + else + qc_active = readl(port_mmio + PORT_CMD_ISSUE); + } rc = ata_qc_complete_multiple(ap, qc_active); -- cgit v0.10.2 From f05dd2f09cac422c423dae8f9b8e2be13df05a8f Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 26 Feb 2010 13:32:11 -0800 Subject: drm/i915: Don't bother with the BKL for GEM ioctls. We probably don't need it for most of the other driver ioctls as well, but we explicitly did locking when doing the GEM pieces. On CPU-bound graphics tasks, the BKL was showing up as 1-2% of CPU time. Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 8bfc0bb..a9f8589 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1881,29 +1881,29 @@ struct drm_ioctl_desc i915_ioctls[] = { DRM_IOCTL_DEF(DRM_I915_GET_VBLANK_PIPE, i915_vblank_pipe_get, DRM_AUTH ), DRM_IOCTL_DEF(DRM_I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH), DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER2, i915_gem_execbuffer2, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH), - DRM_IOCTL_DEF(DRM_I915_GEM_ENTERVT, i915_gem_entervt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_I915_GEM_LEAVEVT, i915_gem_leavevt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_I915_GEM_CREATE, i915_gem_create_ioctl, 0), - DRM_IOCTL_DEF(DRM_I915_GEM_PREAD, i915_gem_pread_ioctl, 0), - DRM_IOCTL_DEF(DRM_I915_GEM_PWRITE, i915_gem_pwrite_ioctl, 0), - DRM_IOCTL_DEF(DRM_I915_GEM_MMAP, i915_gem_mmap_ioctl, 0), - DRM_IOCTL_DEF(DRM_I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, 0), - DRM_IOCTL_DEF(DRM_I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, 0), - DRM_IOCTL_DEF(DRM_I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, 0), - DRM_IOCTL_DEF(DRM_I915_GEM_SET_TILING, i915_gem_set_tiling, 0), - DRM_IOCTL_DEF(DRM_I915_GEM_GET_TILING, i915_gem_get_tiling, 0), - DRM_IOCTL_DEF(DRM_I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, 0), - DRM_IOCTL_DEF(DRM_I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, 0), - DRM_IOCTL_DEF(DRM_I915_GEM_MADVISE, i915_gem_madvise_ioctl, 0), - DRM_IOCTL_DEF(DRM_I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image, DRM_MASTER|DRM_CONTROL_ALLOW), - DRM_IOCTL_DEF(DRM_I915_OVERLAY_ATTRS, intel_overlay_attrs, DRM_MASTER|DRM_CONTROL_ALLOW), + DRM_IOCTL_DEF(DRM_I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER2, i915_gem_execbuffer2, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I915_GEM_ENTERVT, i915_gem_entervt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I915_GEM_LEAVEVT, i915_gem_leavevt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I915_GEM_CREATE, i915_gem_create_ioctl, DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I915_GEM_PREAD, i915_gem_pread_ioctl, DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I915_GEM_PWRITE, i915_gem_pwrite_ioctl, DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I915_GEM_MMAP, i915_gem_mmap_ioctl, DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I915_GEM_SET_TILING, i915_gem_set_tiling, DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I915_GEM_GET_TILING, i915_gem_get_tiling, DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I915_GEM_MADVISE, i915_gem_madvise_ioctl, DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_I915_OVERLAY_ATTRS, intel_overlay_attrs, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), }; int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); -- cgit v0.10.2 From 5d9391628e8eb3b0830697697a95bfd0c3c35b9e Mon Sep 17 00:00:00 2001 From: "Owain G. Ainsworth" Date: Wed, 3 Mar 2010 05:34:29 +0000 Subject: drm/i915: remove an unnecessary wait_request() The continue just after this call with loop around and wait for the request just added just fine. This leads to slightly more compact code. Signed-Off-by: Owain G. Ainsworth Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index fba37e9..e52a277 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2227,11 +2227,6 @@ i915_gem_evict_something(struct drm_device *dev, int min_size) seqno = i915_add_request(dev, NULL, obj->write_domain); if (seqno == 0) return -ENOMEM; - - ret = i915_wait_request(dev, seqno); - if (ret) - return ret; - continue; } } -- cgit v0.10.2 From 4967790112b284f276c5065dc724f7340a2fd7a5 Mon Sep 17 00:00:00 2001 From: Priit Laes Date: Tue, 2 Mar 2010 11:37:00 +0200 Subject: drm/i915: Rename FBC_C3_IDLE to FBC_CTL_C3_IDLE to match other registers Signed-off-by: Priit Laes Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 3d59862..1fcc4c9 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -366,7 +366,7 @@ #define FBC_CTL_PERIODIC (1<<30) #define FBC_CTL_INTERVAL_SHIFT (16) #define FBC_CTL_UNCOMPRESSIBLE (1<<14) -#define FBC_C3_IDLE (1<<13) +#define FBC_CTL_C3_IDLE (1<<13) #define FBC_CTL_STRIDE_SHIFT (5) #define FBC_CTL_FENCENO (1<<0) #define FBC_COMMAND 0x0320c diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 9cd6de5..0e2c5da 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1032,7 +1032,7 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval) /* enable it... */ fbc_ctl = FBC_CTL_EN | FBC_CTL_PERIODIC; if (IS_I945GM(dev)) - fbc_ctl |= FBC_C3_IDLE; /* 945 needs special SR handling */ + fbc_ctl |= FBC_CTL_C3_IDLE; /* 945 needs special SR handling */ fbc_ctl |= (dev_priv->cfb_pitch & 0xff) << FBC_CTL_STRIDE_SHIFT; fbc_ctl |= (interval & 0x2fff) << FBC_CTL_INTERVAL_SHIFT; if (obj_priv->tiling_mode != I915_TILING_NONE) -- cgit v0.10.2 From 71cf39b117d5aa817a4693f4478397e6b04bee25 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 8 Mar 2010 23:41:55 -0800 Subject: drm/i915: Enable VS timer dispatch. This could resolve HW deadlocks where a unit downstream of the VS is waiting for more input, the VS has one vertex queued up but not dispatched because it hopes to get one more vertex for 2x4 dispatch, and software isn't handing more vertices down because it's waiting for rendering to complete. The B-Spec says you should always have this bit set. Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index e52a277..134973f 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4725,6 +4725,11 @@ i915_gem_init_ringbuffer(struct drm_device *dev) ring->space += ring->Size; } + if (IS_I9XX(dev) && !IS_GEN3(dev)) { + I915_WRITE(MI_MODE, + (VS_TIMER_DISPATCH) << 16 | VS_TIMER_DISPATCH); + } + return 0; } diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 1fcc4c9..2720bc2 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -298,6 +298,10 @@ #define INSTDONE 0x02090 #define NOPID 0x02094 #define HWSTAM 0x02098 + +#define MI_MODE 0x0209c +# define VS_TIMER_DISPATCH (1 << 6) + #define SCPD0 0x0209c /* 915+ only */ #define IER 0x020a0 #define IIR 0x020a4 -- cgit v0.10.2 From 76e47c30bdc591815eeb5598f1e2a243a30bd585 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 11 Mar 2010 14:01:38 -0800 Subject: drivers/gpu/drm/i915/intel_bios.c: fix continuation line formats String constants that are continued on subsequent lines with \ will cause spurious whitespace in the resulting output. Signed-off-by: Joe Perches Cc: Dave Airlie Cc: Eric Anholt Cc: Jesse Barnes Signed-off-by: Andrew Morton [anholt: whacked it to wrap to 80 columns instead] Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 70c9d4b..f9ba452 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -417,8 +417,9 @@ parse_edp(struct drm_i915_private *dev_priv, struct bdb_header *bdb) edp = find_section(bdb, BDB_EDP); if (!edp) { if (SUPPORTS_EDP(dev_priv->dev) && dev_priv->edp_support) { - DRM_DEBUG_KMS("No eDP BDB found but eDP panel supported,\ - assume 18bpp panel color depth.\n"); + DRM_DEBUG_KMS("No eDP BDB found but eDP panel " + "supported, assume 18bpp panel color " + "depth.\n"); dev_priv->edp_bpp = 18; } return; -- cgit v0.10.2 From 59f2d0fc4bdfbbfabfa3715ba17d0609e5964c7e Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Tue, 9 Mar 2010 23:37:07 +0800 Subject: drm/i915: Fix check with IS_GEN6 IS_GEN6 missed to include SandyBridge mobile chip, which failed in i915_probe_agp() for memory config detection. Fix it with a device info flag. Signed-off-by: Zhenyu Wang Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 1b2e954..4b26919 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -139,12 +139,12 @@ const static struct intel_device_info intel_ironlake_m_info = { const static struct intel_device_info intel_sandybridge_d_info = { .is_i965g = 1, .is_i9xx = 1, .need_gfx_hws = 1, - .has_hotplug = 1, + .has_hotplug = 1, .is_gen6 = 1, }; const static struct intel_device_info intel_sandybridge_m_info = { .is_i965g = 1, .is_mobile = 1, .is_i9xx = 1, .need_gfx_hws = 1, - .has_hotplug = 1, + .has_hotplug = 1, .is_gen6 = 1, }; const static struct pci_device_id pciidlist[] = { diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 979439c..aba8260 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -205,6 +205,7 @@ struct intel_device_info { u8 is_g4x : 1; u8 is_pineview : 1; u8 is_ironlake : 1; + u8 is_gen6 : 1; u8 has_fbc : 1; u8 has_rc6 : 1; u8 has_pipe_cxsr : 1; @@ -1084,6 +1085,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define IS_IRONLAKE_M(dev) ((dev)->pci_device == 0x0046) #define IS_IRONLAKE(dev) (INTEL_INFO(dev)->is_ironlake) #define IS_I9XX(dev) (INTEL_INFO(dev)->is_i9xx) +#define IS_GEN6(dev) (INTEL_INFO(dev)->is_gen6) #define IS_MOBILE(dev) (INTEL_INFO(dev)->is_mobile) #define IS_GEN3(dev) (IS_I915G(dev) || \ @@ -1107,8 +1109,6 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws) -#define IS_GEN6(dev) ((dev)->pci_device == 0x0102) - /* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte * rows, which changed the alignment requirements and fence programming. */ -- cgit v0.10.2 From 1f2b10131f83f7caa67bf1273cec126b4283015d Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 12 Mar 2010 19:52:55 +0000 Subject: drm/i915: Avoid NULL deref in get_pages() unwind after error. Fixes: http://bugzilla.kernel.org/show_bug.cgi?id=15527 NULL pointer dereference in i915_gem_object_save_bit_17_swizzle BUG: unable to handle kernel NULL pointer dereference at (null) IP: [] i915_gem_object_save_bit_17_swizzle+0x5b/0xc0 [i915] Call Trace: [] ? i915_gem_object_put_pages+0x125/0x150 [i915] [] ? i915_gem_object_get_pages+0xf1/0x110 [i915] [] ? i915_gem_object_bind_to_gtt+0xb8/0x2a0 [i915] [] ? drm_mm_get_block_generic+0x4d/0x180 [] ? i915_gem_mmap_gtt_ioctl+0x16d/0x240 [i915] [] ? i915_gem_madvise_ioctl+0x86/0x120 [i915] Signed-off-by: Chris Wilson Reported-by: maciej.rutecki@gmail.com Cc: stable@kernel.org Reviewed-by: Eric Anholt Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 134973f..933e865 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1466,9 +1466,6 @@ i915_gem_object_put_pages(struct drm_gem_object *obj) obj_priv->dirty = 0; for (i = 0; i < page_count; i++) { - if (obj_priv->pages[i] == NULL) - break; - if (obj_priv->dirty) set_page_dirty(obj_priv->pages[i]); @@ -2251,7 +2248,6 @@ i915_gem_object_get_pages(struct drm_gem_object *obj, struct address_space *mapping; struct inode *inode; struct page *page; - int ret; if (obj_priv->pages_refcount++ != 0) return 0; @@ -2274,11 +2270,9 @@ i915_gem_object_get_pages(struct drm_gem_object *obj, mapping_gfp_mask (mapping) | __GFP_COLD | gfpmask); - if (IS_ERR(page)) { - ret = PTR_ERR(page); - i915_gem_object_put_pages(obj); - return ret; - } + if (IS_ERR(page)) + goto err_pages; + obj_priv->pages[i] = page; } @@ -2286,6 +2280,15 @@ i915_gem_object_get_pages(struct drm_gem_object *obj, i915_gem_object_do_bit_17_swizzle(obj); return 0; + +err_pages: + while (i--) + page_cache_release(obj_priv->pages[i]); + + drm_free_large(obj_priv->pages); + obj_priv->pages = NULL; + obj_priv->pages_refcount--; + return PTR_ERR(page); } static void sandybridge_write_fence_reg(struct drm_i915_fence_reg *reg) -- cgit v0.10.2 From 915a428e43acfd05e4ffeaf40549b0cf163eebe2 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 6 Mar 2010 14:05:39 +0300 Subject: drm/i915: fix small leak on overlay error path We should free "params" before returning. Signed-off-by: Dan Carpenter Reviewed-by: Daniel Vetter Cc: stable@kernel.org (for .33) Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index d355d1d..60595fc 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -1068,14 +1068,18 @@ int intel_overlay_put_image(struct drm_device *dev, void *data, drmmode_obj = drm_mode_object_find(dev, put_image_rec->crtc_id, DRM_MODE_OBJECT_CRTC); - if (!drmmode_obj) - return -ENOENT; + if (!drmmode_obj) { + ret = -ENOENT; + goto out_free; + } crtc = to_intel_crtc(obj_to_crtc(drmmode_obj)); new_bo = drm_gem_object_lookup(dev, file_priv, put_image_rec->bo_handle); - if (!new_bo) - return -ENOENT; + if (!new_bo) { + ret = -ENOENT; + goto out_free; + } mutex_lock(&dev->mode_config.mutex); mutex_lock(&dev->struct_mutex); @@ -1165,6 +1169,7 @@ out_unlock: mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->mode_config.mutex); drm_gem_object_unreference_unlocked(new_bo); +out_free: kfree(params); return ret; -- cgit v0.10.2 From 535297a6ae4c3b7a0562e71fac15c213eeec68e7 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Wed, 17 Mar 2010 16:06:11 +0200 Subject: vhost: fix error handling in vring ioctls Stanse found a locking problem in vhost_set_vring: several returns from VHOST_SET_VRING_KICK, VHOST_SET_VRING_CALL, VHOST_SET_VRING_ERR with the vq->mutex held. Fix these up. Reported-by: Jiri Slaby Acked-by: Laurent Chavey Signed-off-by: Michael S. Tsirkin diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 7cd55e0..7bd7a1e 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -476,8 +476,10 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp) if (r < 0) break; eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd); - if (IS_ERR(eventfp)) - return PTR_ERR(eventfp); + if (IS_ERR(eventfp)) { + r = PTR_ERR(eventfp); + break; + } if (eventfp != vq->kick) { pollstop = filep = vq->kick; pollstart = vq->kick = eventfp; @@ -489,8 +491,10 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp) if (r < 0) break; eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd); - if (IS_ERR(eventfp)) - return PTR_ERR(eventfp); + if (IS_ERR(eventfp)) { + r = PTR_ERR(eventfp); + break; + } if (eventfp != vq->call) { filep = vq->call; ctx = vq->call_ctx; @@ -505,8 +509,10 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp) if (r < 0) break; eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd); - if (IS_ERR(eventfp)) - return PTR_ERR(eventfp); + if (IS_ERR(eventfp)) { + r = PTR_ERR(eventfp); + break; + } if (eventfp != vq->error) { filep = vq->error; vq->error = eventfp; -- cgit v0.10.2 From 22001a13d09d82772e831dcdac0553994a4bac5d Mon Sep 17 00:00:00 2001 From: Tilman Schmidt Date: Wed, 17 Mar 2010 14:22:07 -0700 Subject: gigaset: fix build failure Update the dummy LL interface to the LL interface change introduced by commit daab433c03c15fd642c71c94eb51bdd3f32602c8. This fixes the build failure occurring after that commit when enabling ISDN_DRV_GIGASET but neither ISDN_I4L nor ISDN_CAPI. Impact: bugfix Signed-off-by: Tilman Schmidt Signed-off-by: David S. Miller diff --git a/drivers/isdn/gigaset/dummyll.c b/drivers/isdn/gigaset/dummyll.c index 5b27c99..bd0b1ea 100644 --- a/drivers/isdn/gigaset/dummyll.c +++ b/drivers/isdn/gigaset/dummyll.c @@ -57,12 +57,20 @@ void gigaset_isdn_stop(struct cardstate *cs) { } -int gigaset_isdn_register(struct cardstate *cs, const char *isdnid) +int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid) { - pr_info("no ISDN subsystem interface\n"); return 1; } -void gigaset_isdn_unregister(struct cardstate *cs) +void gigaset_isdn_unregdev(struct cardstate *cs) +{ +} + +void gigaset_isdn_regdrv(void) +{ + pr_info("no ISDN subsystem interface\n"); +} + +void gigaset_isdn_unregdrv(void) { } -- cgit v0.10.2 From 8301b91ba0b2d15c86fdf5357efe7c04eb767a6e Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Wed, 17 Mar 2010 11:07:55 +0100 Subject: firewire: ohci: add cycle timer quirk for the TI TSB12LV22 Among the many entries in the TSB12LV22 errata list (TI literature number SLLS312) is the following: PCI Slave reads of the Cycle Timer register may occasionally get an incorrect value. Software may be able to validate value by reading the register multiple times rapidly and evaluating for a reasonable difference. Signed-off-by: Clemens Ladisch (untested) Signed-off-by: Stefan Richter (added #define) diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 75dc698..e33917b 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -231,6 +231,8 @@ static inline struct fw_ohci *fw_ohci(struct fw_card *card) static char ohci_driver_name[] = KBUILD_MODNAME; +#define PCI_DEVICE_ID_TI_TSB12LV22 0x8009 + #define QUIRK_CYCLE_TIMER 1 #define QUIRK_RESET_PACKET 2 #define QUIRK_BE_HEADERS 4 @@ -239,6 +241,8 @@ static char ohci_driver_name[] = KBUILD_MODNAME; static const struct { unsigned short vendor, device, flags; } ohci_quirks[] = { + {PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TSB12LV22, QUIRK_CYCLE_TIMER | + QUIRK_RESET_PACKET}, {PCI_VENDOR_ID_TI, PCI_ANY_ID, QUIRK_RESET_PACKET}, {PCI_VENDOR_ID_AL, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, {PCI_VENDOR_ID_NEC, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, -- cgit v0.10.2 From e9e58a4ec3b1086d1ed8c915311aef1ae55454fd Mon Sep 17 00:00:00 2001 From: KAMEZAWA Hiroyuki Date: Mon, 15 Mar 2010 00:34:57 -0400 Subject: memcg: avoid use cmpxchg in swap cgroup maintainance swap_cgroup uses 2bytes data and uses cmpxchg in a new operation. 2byte cmpxchg/xchg is not available on some archs. This patch replaces cmpxchg/xchg with operations under lock. Signed-off-by: KAMEZAWA Hiroyuki Reported-by: Sachin Sant wrote: Acked-by: Balbir Singh Acked-by: Daisuke Nishimura Cc: Li Zefan Cc: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/mm/page_cgroup.c b/mm/page_cgroup.c index 3dd8853..6c00814 100644 --- a/mm/page_cgroup.c +++ b/mm/page_cgroup.c @@ -284,6 +284,7 @@ static DEFINE_MUTEX(swap_cgroup_mutex); struct swap_cgroup_ctrl { struct page **map; unsigned long length; + spinlock_t lock; }; struct swap_cgroup_ctrl swap_cgroup_ctrl[MAX_SWAPFILES]; @@ -353,16 +354,22 @@ unsigned short swap_cgroup_cmpxchg(swp_entry_t ent, struct swap_cgroup_ctrl *ctrl; struct page *mappage; struct swap_cgroup *sc; + unsigned long flags; + unsigned short retval; ctrl = &swap_cgroup_ctrl[type]; mappage = ctrl->map[idx]; sc = page_address(mappage); sc += pos; - if (cmpxchg(&sc->id, old, new) == old) - return old; + spin_lock_irqsave(&ctrl->lock, flags); + retval = sc->id; + if (retval == old) + sc->id = new; else - return 0; + retval = 0; + spin_unlock_irqrestore(&ctrl->lock, flags); + return retval; } /** @@ -383,13 +390,17 @@ unsigned short swap_cgroup_record(swp_entry_t ent, unsigned short id) struct page *mappage; struct swap_cgroup *sc; unsigned short old; + unsigned long flags; ctrl = &swap_cgroup_ctrl[type]; mappage = ctrl->map[idx]; sc = page_address(mappage); sc += pos; - old = xchg(&sc->id, id); + spin_lock_irqsave(&ctrl->lock, flags); + old = sc->id; + sc->id = id; + spin_unlock_irqrestore(&ctrl->lock, flags); return old; } @@ -441,6 +452,7 @@ int swap_cgroup_swapon(int type, unsigned long max_pages) mutex_lock(&swap_cgroup_mutex); ctrl->length = length; ctrl->map = array; + spin_lock_init(&ctrl->lock); if (swap_cgroup_prepare(type)) { /* memory shortage */ ctrl->map = NULL; -- cgit v0.10.2 From bcc54e2a6d8e93ff83ec398511930b0a73e19151 Mon Sep 17 00:00:00 2001 From: Venkatesh Pallipadi Date: Mon, 15 Mar 2010 00:34:59 -0400 Subject: jffs2: fix up rb_root initializations to use RB_ROOT jffs2 uses rb_node = NULL; to zero rb_root. The problem with this is that 17d9ddc72fb8bba0d4f678 ("rbtree: Add support for augmented rbtrees") in the linux-next tree adds a new field to that struct which needs to be NULL as well. This patch uses RB_ROOT as the intializer so all of the relevant fields will be NULL'd. Signed-off-by: Venkatesh Pallipadi Cc: Eric Paris Acked-by: David Woodhouse Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c index e22de83..d32ee94 100644 --- a/fs/jffs2/readinode.c +++ b/fs/jffs2/readinode.c @@ -567,7 +567,7 @@ static void jffs2_free_tmp_dnode_info_list(struct rb_root *list) else BUG(); } } - list->rb_node = NULL; + *list = RB_ROOT; } static void jffs2_free_full_dirent_list(struct jffs2_full_dirent *fd) -- cgit v0.10.2 From c4af96449e20f9245cf3d904098db508cdebcda8 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Mon, 15 Mar 2010 00:35:00 -0400 Subject: ntfs: use bitmap_weight Use bitmap_weight() instead of doing hweight32() for each u32 element in the page. Signed-off-by: Akinobu Mita Cc: Anton Altaparmakov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c index 1cf39df..0de1db6 100644 --- a/fs/ntfs/super.c +++ b/fs/ntfs/super.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "sysctl.h" #include "logfile.h" @@ -2458,7 +2459,6 @@ static void ntfs_put_super(struct super_block *sb) static s64 get_nr_free_clusters(ntfs_volume *vol) { s64 nr_free = vol->nr_clusters; - u32 *kaddr; struct address_space *mapping = vol->lcnbmp_ino->i_mapping; struct page *page; pgoff_t index, max_index; @@ -2477,7 +2477,8 @@ static s64 get_nr_free_clusters(ntfs_volume *vol) ntfs_debug("Reading $Bitmap, max_index = 0x%lx, max_size = 0x%lx.", max_index, PAGE_CACHE_SIZE / 4); for (index = 0; index < max_index; index++) { - unsigned int i; + unsigned long *kaddr; + /* * Read the page from page cache, getting it from backing store * if necessary, and increment the use count. @@ -2490,16 +2491,16 @@ static s64 get_nr_free_clusters(ntfs_volume *vol) nr_free -= PAGE_CACHE_SIZE * 8; continue; } - kaddr = (u32*)kmap_atomic(page, KM_USER0); + kaddr = kmap_atomic(page, KM_USER0); /* - * For each 4 bytes, subtract the number of set bits. If this + * Subtract the number of set bits. If this * is the last page and it is partial we don't really care as * it just means we do a little extra work but it won't affect * the result as all out of range bytes are set to zero by * ntfs_readpage(). */ - for (i = 0; i < PAGE_CACHE_SIZE / 4; i++) - nr_free -= (s64)hweight32(kaddr[i]); + nr_free -= bitmap_weight(kaddr, + PAGE_CACHE_SIZE * BITS_PER_BYTE); kunmap_atomic(kaddr, KM_USER0); page_cache_release(page); } @@ -2538,7 +2539,6 @@ static s64 get_nr_free_clusters(ntfs_volume *vol) static unsigned long __get_nr_free_mft_records(ntfs_volume *vol, s64 nr_free, const pgoff_t max_index) { - u32 *kaddr; struct address_space *mapping = vol->mftbmp_ino->i_mapping; struct page *page; pgoff_t index; @@ -2548,7 +2548,8 @@ static unsigned long __get_nr_free_mft_records(ntfs_volume *vol, ntfs_debug("Reading $MFT/$BITMAP, max_index = 0x%lx, max_size = " "0x%lx.", max_index, PAGE_CACHE_SIZE / 4); for (index = 0; index < max_index; index++) { - unsigned int i; + unsigned long *kaddr; + /* * Read the page from page cache, getting it from backing store * if necessary, and increment the use count. @@ -2561,16 +2562,16 @@ static unsigned long __get_nr_free_mft_records(ntfs_volume *vol, nr_free -= PAGE_CACHE_SIZE * 8; continue; } - kaddr = (u32*)kmap_atomic(page, KM_USER0); + kaddr = kmap_atomic(page, KM_USER0); /* - * For each 4 bytes, subtract the number of set bits. If this + * Subtract the number of set bits. If this * is the last page and it is partial we don't really care as * it just means we do a little extra work but it won't affect * the result as all out of range bytes are set to zero by * ntfs_readpage(). */ - for (i = 0; i < PAGE_CACHE_SIZE / 4; i++) - nr_free -= (s64)hweight32(kaddr[i]); + nr_free -= bitmap_weight(kaddr, + PAGE_CACHE_SIZE * BITS_PER_BYTE); kunmap_atomic(kaddr, KM_USER0); page_cache_release(page); } -- cgit v0.10.2 From e5d6151115aee73825c1752aff7cd09adfece839 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Mon, 15 Mar 2010 00:35:01 -0400 Subject: hpet: use for_each_set_bit() Replace open-coded loop with for_each_set_bit(). Signed-off-by: Akinobu Mita Cc: Clemens Ladisch Cc: Bob Picco Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index e481c59..9c5eea3 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c @@ -215,9 +215,7 @@ static void hpet_timer_set_irq(struct hpet_dev *devp) else v &= ~0xffff; - for (irq = find_first_bit(&v, HPET_MAX_IRQ); irq < HPET_MAX_IRQ; - irq = find_next_bit(&v, HPET_MAX_IRQ, 1 + irq)) { - + for_each_set_bit(irq, &v, HPET_MAX_IRQ) { if (irq >= nr_irqs) { irq = HPET_MAX_IRQ; break; -- cgit v0.10.2 From bc32df00894f0e1dbf583cc3dab210d2969b078a Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 15 Mar 2010 00:35:03 -0400 Subject: memory hotplug: allow setting of phys_device /sys/devices/system/memory/memoryX/phys_device is supposed to contain the number of the physical device that the corresponding piece of memory belongs to. In case a physical device should be replaced or taken offline for whatever reason it is necessary to set all corresponding memory pieces offline. The current implementation always sets phys_device to '0' and there is no way or hook to change that. Seems like there was a plan to implement that but it wasn't finished for whatever reason. So add a weak function which architectures can override to actually set the phys_device from within add_memory_block(). Signed-off-by: Heiko Carstens Cc: Dave Hansen Cc: Gerald Schaefer Cc: KAMEZAWA Hiroyuki Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 2f86915..db0848e 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -429,12 +429,16 @@ static inline int memory_fail_init(void) * differentiation between which *physical* devices each * section belongs to... */ +int __weak arch_get_memory_phys_device(unsigned long start_pfn) +{ + return 0; +} static int add_memory_block(int nid, struct mem_section *section, - unsigned long state, int phys_device, - enum mem_add_context context) + unsigned long state, enum mem_add_context context) { struct memory_block *mem = kzalloc(sizeof(*mem), GFP_KERNEL); + unsigned long start_pfn; int ret = 0; if (!mem) @@ -443,7 +447,8 @@ static int add_memory_block(int nid, struct mem_section *section, mem->phys_index = __section_nr(section); mem->state = state; mutex_init(&mem->state_mutex); - mem->phys_device = phys_device; + start_pfn = section_nr_to_pfn(mem->phys_index); + mem->phys_device = arch_get_memory_phys_device(start_pfn); ret = register_memory(mem, section); if (!ret) @@ -515,7 +520,7 @@ int remove_memory_block(unsigned long node_id, struct mem_section *section, */ int register_new_memory(int nid, struct mem_section *section) { - return add_memory_block(nid, section, MEM_OFFLINE, 0, HOTPLUG); + return add_memory_block(nid, section, MEM_OFFLINE, HOTPLUG); } int unregister_memory_section(struct mem_section *section) @@ -548,7 +553,7 @@ int __init memory_dev_init(void) if (!present_section_nr(i)) continue; err = add_memory_block(0, __nr_to_section(i), MEM_ONLINE, - 0, BOOT); + BOOT); if (!ret) ret = err; } diff --git a/include/linux/memory.h b/include/linux/memory.h index 1adfe77..85582e1 100644 --- a/include/linux/memory.h +++ b/include/linux/memory.h @@ -36,6 +36,8 @@ struct memory_block { struct sys_device sysdev; }; +int arch_get_memory_phys_device(unsigned long start_pfn); + /* These states are exposed to userspace as text strings in sysfs */ #define MEM_ONLINE (1<<0) /* exposed to userspace */ #define MEM_GOING_OFFLINE (1<<1) /* exposed to userspace */ -- cgit v0.10.2 From 57b552ba0b2faf7cce66d476ef8ce7f6210c62fd Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 15 Mar 2010 00:35:05 -0400 Subject: memory hotplug/s390: set phys_device Implement arch specific arch_get_memory_phys_device function and initialize phys_device for each memory section. That way we finally can tell which piece of memory belongs to which physical device. This makes s390's /sys/devices/system/memory/memoryX/phys_device display the correct thing? Signed-off-by: Heiko Carstens Cc: Dave Hansen Cc: Gerald Schaefer Cc: KAMEZAWA Hiroyuki Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c index b3beab6..fc7ae05 100644 --- a/drivers/s390/char/sclp_cmd.c +++ b/drivers/s390/char/sclp_cmd.c @@ -704,6 +704,13 @@ int sclp_chp_deconfigure(struct chp_id chpid) return do_chp_configure(SCLP_CMDW_DECONFIGURE_CHPATH | chpid.id << 8); } +int arch_get_memory_phys_device(unsigned long start_pfn) +{ + if (!rzm) + return 0; + return PFN_PHYS(start_pfn) / rzm; +} + struct chp_info_sccb { struct sccb_header header; u8 recognized[SCLP_CHP_INFO_MASK_SIZE]; -- cgit v0.10.2 From 9eff26ea48bfbe2885b158742a7512a097ec911b Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 18 Mar 2010 16:05:13 +1100 Subject: powerpc/perf_events: Fix call-graph recording, add perf_arch_fetch_caller_regs This implements a powerpc version of perf_arch_fetch_caller_regs to get correct call-graphs. It's implemented in assembly because that way we can be sure there isn't a stack frame for perf_arch_fetch_caller_regs. If it was in C, gcc might or might not create a stack frame for it, which would affect the number of levels we have to skip. With this, we see results from perf record -e lock:lock_acquire like this: # Samples: 24878 # # Overhead Command Shared Object Symbol # ........ .............. ................. ...... # 14.99% perf [kernel.kallsyms] [k] ._raw_spin_lock | --- ._raw_spin_lock | |--25.00%-- .alloc_fd | (nil) | | | |--50.00%-- .anon_inode_getfd | | .sys_perf_event_open | | syscall_exit | | syscall | | create_counter | | __cmd_record | | run_builtin | | main | | 0xfd2e704 | | 0xfd2e8c0 | | (nil) ... etc. Signed-off-by: Paul Mackerras Acked-by: Benjamin Herrenschmidt Cc: anton@samba.org Cc: linuxppc-dev@ozlabs.org Cc: Peter Zijlstra Cc: Frederic Weisbecker LKML-Reference: <20100318050513.GA6575@drongo> Signed-off-by: Ingo Molnar diff --git a/arch/powerpc/include/asm/asm-compat.h b/arch/powerpc/include/asm/asm-compat.h index c1b475a..a9b91ed 100644 --- a/arch/powerpc/include/asm/asm-compat.h +++ b/arch/powerpc/include/asm/asm-compat.h @@ -28,6 +28,7 @@ #define PPC_LLARX(t, a, b, eh) PPC_LDARX(t, a, b, eh) #define PPC_STLCX stringify_in_c(stdcx.) #define PPC_CNTLZL stringify_in_c(cntlzd) +#define PPC_LR_STKOFF 16 /* Move to CR, single-entry optimized version. Only available * on POWER4 and later. @@ -51,6 +52,7 @@ #define PPC_STLCX stringify_in_c(stwcx.) #define PPC_CNTLZL stringify_in_c(cntlzw) #define PPC_MTOCRF stringify_in_c(mtcrf) +#define PPC_LR_STKOFF 4 #endif diff --git a/arch/powerpc/kernel/misc.S b/arch/powerpc/kernel/misc.S index 2d29752..b485a87 100644 --- a/arch/powerpc/kernel/misc.S +++ b/arch/powerpc/kernel/misc.S @@ -127,3 +127,31 @@ _GLOBAL(__setup_cpu_power7) _GLOBAL(__restore_cpu_power7) /* place holder */ blr + +#ifdef CONFIG_EVENT_TRACING +/* + * Get a minimal set of registers for our caller's nth caller. + * r3 = regs pointer, r5 = n. + * + * We only get R1 (stack pointer), NIP (next instruction pointer) + * and LR (link register). These are all we can get in the + * general case without doing complicated stack unwinding, but + * fortunately they are enough to do a stack backtrace, which + * is all we need them for. + */ +_GLOBAL(perf_arch_fetch_caller_regs) + mr r6,r1 + cmpwi r5,0 + mflr r4 + ble 2f + mtctr r5 +1: PPC_LL r6,0(r6) + bdnz 1b + PPC_LL r4,PPC_LR_STKOFF(r6) +2: PPC_LL r7,0(r6) + PPC_LL r7,PPC_LR_STKOFF(r7) + PPC_STL r6,GPR1-STACK_FRAME_OVERHEAD(r3) + PPC_STL r4,_NIP-STACK_FRAME_OVERHEAD(r3) + PPC_STL r7,_LINK-STACK_FRAME_OVERHEAD(r3) + blr +#endif /* CONFIG_EVENT_TRACING */ -- cgit v0.10.2 From da3b062e306452ffb74cf5e9e5128f9f1e0502ab Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 18 Mar 2010 09:39:59 +0100 Subject: ASoC: SIU driver shall select FW_LOADER The SIU ASoC driver must load firmware to program the DSP, therefore it has to select FW_LOADER in its Kconfig entry. Signed-off-by: Guennadi Liakhovetski Acked-by: Liam Girdwood Signed-off-by: Mark Brown diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig index 1066749..f07f6d8 100644 --- a/sound/soc/sh/Kconfig +++ b/sound/soc/sh/Kconfig @@ -32,6 +32,7 @@ config SND_SOC_SH4_SIU select DMA_ENGINE select DMADEVICES select SH_DMAE + select FW_LOADER ## ## Boards -- cgit v0.10.2 From 1976152fd8e706135deed6cf333e347c08416056 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 18 Mar 2010 07:30:31 -0600 Subject: of: Fix comparison of "compatible" properties Commit 7c7b60cb87547b1664a4385c187f029bf514a737 "of: put default string compare and #a/s-cell values into common header" Breaks various things on powerpc due to using strncasecmp instead of strcasecmp for comparing against "compatible" strings. This causes things like the 4xx PCI code to fail miserably due to the partial matches in code like this: for_each_compatible_node(np, NULL, "ibm,plb-pcix") ppc4xx_probe_pcix_bridge(np); for_each_compatible_node(np, NULL, "ibm,plb-pci") ppc4xx_probe_pci_bridge(np); It's not quite right to do partial name match. Entries in a compatible list are meant to be matched whole. If a device is compatible with both "foo" and "foo1", then the device should have both strings in its "compatible" property. This patch reverts powerpc and microblaze us to use strcasecmp. Signed-off-by: Benjamin Herrenschmidt (for patch description) Signed-off-by: Grant Likely Acked-by: David S. Miller Acked-by: Michal Simek diff --git a/include/linux/of.h b/include/linux/of.h index f6d9cbc..a367e19 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -127,7 +127,7 @@ static inline unsigned long of_read_ulong(const __be32 *cell, int size) /* Default string compare functions, Allow arch asm/prom.h to override */ #if !defined(of_compat_cmp) -#define of_compat_cmp(s1, s2, l) strncasecmp((s1), (s2), (l)) +#define of_compat_cmp(s1, s2, l) strcasecmp((s1), (s2)) #define of_prop_cmp(s1, s2) strcmp((s1), (s2)) #define of_node_cmp(s1, s2) strcasecmp((s1), (s2)) #endif -- cgit v0.10.2 From 9205124c66a69664c6825501cb062ebd2acd3b3a Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 18 Mar 2010 14:01:18 -0600 Subject: powerpc/5200: Build fix for mpc52xx watchdog timer code mpc52xx_gpt_wdt_setup is defined as 0, which causes the following build failure with gcc 4.5, since it's built with -Werror. arch/powerpc/platforms/52xx/mpc52xx_gpt.c:761:3: error: statement with no effect Changing it to a static inline fixes the problem. Reported-by: Jeff Mahoney Signed-off-by: Grant Likely diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c index 072b948..5d7cc88 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c @@ -711,7 +711,11 @@ static int __devinit mpc52xx_gpt_wdt_init(void) return 0; } -#define mpc52xx_gpt_wdt_setup(x, y) (0) +static inline int mpc52xx_gpt_wdt_setup(struct mpc52xx_gpt_priv *gpt, + const u32 *period) +{ + return 0; +} #endif /* CONFIG_MPC5200_WDT */ -- cgit v0.10.2 From abc6e1341bda974e2d0eddb75f57a20ac18e9b33 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Thu, 18 Mar 2010 12:10:08 -0400 Subject: Btrfs: fix key checks and advance in the search ioctl The search ioctl was working well for finding tree roots, but using it for generic searches requires a few changes to how the keys are advanced. This treats the search control min fields for objectid, type and offset more like a key, where we drop the offset to zero once we bump the type, etc. The downside of this is that we are changing the min_type and min_offset fields during the search, and so the ioctl caller needs extra checks to make sure the keys in the result are the ones it wanted. This also changes key_in_sk to use btrfs_comp_cpu_keys, just to make things more readable. Signed-off-by: Chris Mason diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 4329610..291aa51 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -914,17 +914,23 @@ out: static noinline int key_in_sk(struct btrfs_key *key, struct btrfs_ioctl_search_key *sk) { - if (key->objectid < sk->min_objectid) - return 0; - if (key->offset < sk->min_offset) - return 0; - if (key->type < sk->min_type) - return 0; - if (key->objectid > sk->max_objectid) - return 0; - if (key->type > sk->max_type) + struct btrfs_key test; + int ret; + + test.objectid = sk->min_objectid; + test.type = sk->min_type; + test.offset = sk->min_offset; + + ret = btrfs_comp_cpu_keys(key, &test); + if (ret < 0) return 0; - if (key->offset > sk->max_offset) + + test.objectid = sk->max_objectid; + test.type = sk->max_type; + test.offset = sk->max_offset; + + ret = btrfs_comp_cpu_keys(key, &test); + if (ret > 0) return 0; return 1; } @@ -998,13 +1004,18 @@ static noinline int copy_to_sk(struct btrfs_root *root, break; } advance_key: - if (key->offset < (u64)-1) + ret = 0; + if (key->offset < (u64)-1 && key->offset < sk->max_offset) key->offset++; - else if (key->type < (u8)-1) + else if (key->type < (u8)-1 && key->type < sk->max_type) { + key->offset = 0; key->type++; - else if (key->objectid < (u64)-1) + } else if (key->objectid < (u64)-1 && key->objectid < sk->max_objectid) { + key->offset = 0; + key->type = 0; key->objectid++; - ret = 0; + } else + ret = 1; overflow: *num_found += found; return ret; -- cgit v0.10.2 From 90fdde147fd32d18a20be5b498d5f26e56cca8a3 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Thu, 18 Mar 2010 12:14:54 -0400 Subject: Btrfs: return keys for large items to the search ioctl The search ioctl was skipping large items entirely (ones that are too big for the results buffer). This changes things to at least copy the item header so that we can send information about the item back to userland. Signed-off-by: Chris Mason diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 291aa51..fd757f5 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -997,8 +997,8 @@ static noinline int copy_to_sk(struct btrfs_root *root, read_extent_buffer(leaf, p, item_off, item_len); *sk_offset += item_len; - found++; } + found++; if (*num_found >= sk->nr_items) break; -- cgit v0.10.2 From 1b53ac4d1b75b23bdc2b54ace787b8f718a987ef Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Thu, 18 Mar 2010 12:17:05 -0400 Subject: Btrfs: allow treeid==0 in the inode lookup ioctl When a root id of 0 is sent to the inode lookup ioctl, it will use the root of the file we're ioctling and pass the root id back to userland along with the results. This allows userland to do searches based on that root later on. Signed-off-by: Chris Mason diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index fd757f5..1e462de 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -1215,6 +1215,9 @@ static noinline int btrfs_ioctl_ino_lookup(struct file *file, } inode = fdentry(file)->d_inode; + if (args->treeid == 0) + args->treeid = BTRFS_I(inode)->root->root_key.objectid; + ret = btrfs_search_path_in_tree(BTRFS_I(inode)->root->fs_info, args->treeid, args->objectid, args->name); -- cgit v0.10.2 From 8ad6fcab564c5bc956bdc3dfa440ab152b6e780f Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Thu, 18 Mar 2010 12:23:10 -0400 Subject: Btrfs: fix the inode ref searches done by btrfs_search_path_in_tree This is used by the inode lookup ioctl to follow all the backrefs up to the subvol root. But the search being done would sometimes land one past the last item in the leaf instead of finding the backref. This changes the search to look for the highest possible backref and hop back one item. It also fixes a leaked path on failure to find the root. Signed-off-by: Chris Mason diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 1e462de..2845c6c 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -1147,12 +1147,13 @@ static noinline int btrfs_search_path_in_tree(struct btrfs_fs_info *info, root = btrfs_read_fs_root_no_name(info, &key); if (IS_ERR(root)) { printk(KERN_ERR "could not find root %llu\n", tree_id); - return -ENOENT; + ret = -ENOENT; + goto out; } key.objectid = dirid; key.type = BTRFS_INODE_REF_KEY; - key.offset = 0; + key.offset = (u64)-1; while(1) { ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); @@ -1161,6 +1162,8 @@ static noinline int btrfs_search_path_in_tree(struct btrfs_fs_info *info, l = path->nodes[0]; slot = path->slots[0]; + if (ret > 0 && slot > 0) + slot--; btrfs_item_key_to_cpu(l, &key, slot); if (ret > 0 && (key.objectid != dirid || @@ -1184,7 +1187,7 @@ static noinline int btrfs_search_path_in_tree(struct btrfs_fs_info *info, btrfs_release_path(root, path); key.objectid = key.offset; - key.offset = 0; + key.offset = (u64)-1; dirid = key.objectid; } -- cgit v0.10.2 From b22b63ebafb97b66d1054e69941ee049d790c6cf Mon Sep 17 00:00:00 2001 From: Mark Fasheh Date: Thu, 11 Mar 2010 18:43:46 -0800 Subject: ocfs2: Always try for maximum bits with new local alloc windows What we were doing before was to ask for the current window size as the maximum allocation. This had the effect of limiting the amount of allocation we could get for the local alloc during times when the window size was shrunk due to fragmentation. In some cases, that could actually *increase* fragmentation by artificially limiting the number of bits we can accept. So while we still want to ask for a minimum number of bits equal to window size, there is no reason why we should limit the number of bits the local alloc should accept. Hence always allow the maximum number of local alloc bits. Signed-off-by: Mark Fasheh Signed-off-by: Joel Becker diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c index ca992d9..171c691 100644 --- a/fs/ocfs2/localalloc.c +++ b/fs/ocfs2/localalloc.c @@ -984,8 +984,7 @@ static int ocfs2_local_alloc_reserve_for_window(struct ocfs2_super *osb, } retry_enospc: - (*ac)->ac_bits_wanted = osb->local_alloc_bits; - + (*ac)->ac_bits_wanted = osb->local_alloc_default_bits; status = ocfs2_reserve_cluster_bitmap_bits(osb, *ac); if (status == -ENOSPC) { if (ocfs2_recalc_la_window(osb, OCFS2_LA_EVENT_ENOSPC) == @@ -1061,6 +1060,7 @@ retry_enospc: OCFS2_LA_DISABLED) goto bail; + ac->ac_bits_wanted = osb->local_alloc_default_bits; status = ocfs2_claim_clusters(osb, handle, ac, osb->local_alloc_bits, &cluster_off, -- cgit v0.10.2 From 0cff810f54b3b52075c27f7a7021d5b195264b6c Mon Sep 17 00:00:00 2001 From: Lai Jiangshan Date: Thu, 18 Mar 2010 12:25:33 -0700 Subject: rcu: Fix local_irq_disable() CONFIG_PROVE_RCU=y false positives It is documented that local_irq_disable() also delimits RCU_SCHED read-site critical sections. See the document of synchronize_sched() or Documentation/RCU/whatisRCU.txt. So we have to test irqs_disabled() in rcu_read_lock_sched_held(). Otherwise rcu-lockdep brings incorrect complaint. Signed-off-by: Lai Jiangshan Signed-off-by: Paul E. McKenney Cc: dipankar@in.ibm.com Cc: mathieu.desnoyers@polymtl.ca Cc: josh@joshtriplett.org Cc: dvhltc@us.ibm.com Cc: niv@us.ibm.com Cc: peterz@infradead.org Cc: rostedt@goodmis.org Cc: Valdis.Kletnieks@vt.edu Cc: dhowells@redhat.com Cc: eric.dumazet@gmail.com LKML-Reference: <1268940334-10892-1-git-send-email-paulmck@linux.vnet.ibm.com> Signed-off-by: Ingo Molnar diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index e1bdc4b..872a98e 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -149,7 +149,7 @@ static inline int rcu_read_lock_sched_held(void) return 1; if (debug_locks) lockdep_opinion = lock_is_held(&rcu_sched_lock_map); - return lockdep_opinion || preempt_count() != 0; + return lockdep_opinion || preempt_count() != 0 || irqs_disabled(); } #else /* #ifdef CONFIG_PREEMPT */ static inline int rcu_read_lock_sched_held(void) @@ -180,7 +180,7 @@ static inline int rcu_read_lock_bh_held(void) #ifdef CONFIG_PREEMPT static inline int rcu_read_lock_sched_held(void) { - return !rcu_scheduler_active || preempt_count() != 0; + return !rcu_scheduler_active || preempt_count() != 0 || irqs_disabled(); } #else /* #ifdef CONFIG_PREEMPT */ static inline int rcu_read_lock_sched_held(void) -- cgit v0.10.2 From 285aca8e2a7f8af2a18cf89d1dfa95df2f9c9132 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 18 Mar 2010 11:24:06 -0700 Subject: agp/intel: Respect the GTT size on Sandybridge for scratch page setup. This is similar to 14bc490bbdf1b194ad1f5f3d2a0a27edfdf78986 which respected it for how much of the GTT we would actually use. Now we won't clear beyond allocated memory when filling the GTT with scratch page addresses. Signed-off-by: Eric Anholt diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index a3e10dc..f499c5e 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -175,6 +175,10 @@ extern int agp_memory_reserved; #define SNB_GMCH_GMS_STOLEN_448M (0xe << 3) #define SNB_GMCH_GMS_STOLEN_480M (0xf << 3) #define SNB_GMCH_GMS_STOLEN_512M (0x10 << 3) +#define SNB_GTT_SIZE_0M (0 << 8) +#define SNB_GTT_SIZE_1M (1 << 8) +#define SNB_GTT_SIZE_2M (2 << 8) +#define SNB_GTT_SIZE_MASK (3 << 8) static const struct aper_size_info_fixed intel_i810_sizes[] = { @@ -1438,6 +1442,8 @@ static unsigned long intel_i965_mask_memory(struct agp_bridge_data *bridge, static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size) { + u16 snb_gmch_ctl; + switch (agp_bridge->dev->device) { case PCI_DEVICE_ID_INTEL_GM45_HB: case PCI_DEVICE_ID_INTEL_EAGLELAKE_HB: @@ -1449,9 +1455,26 @@ static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size) case PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB: case PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB: case PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB: + *gtt_offset = *gtt_size = MB(2); + break; case PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB: case PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB: - *gtt_offset = *gtt_size = MB(2); + *gtt_offset = MB(2); + + pci_read_config_word(intel_private.pcidev, SNB_GMCH_CTRL, &snb_gmch_ctl); + switch (snb_gmch_ctl & SNB_GTT_SIZE_MASK) { + default: + case SNB_GTT_SIZE_0M: + printk(KERN_ERR "Bad GTT size mask: 0x%04x.\n", snb_gmch_ctl); + *gtt_size = MB(0); + break; + case SNB_GTT_SIZE_1M: + *gtt_size = MB(1); + break; + case SNB_GTT_SIZE_2M: + *gtt_size = MB(2); + break; + } break; default: *gtt_offset = *gtt_size = KB(512); -- cgit v0.10.2 From 66f6ff09ff67c45919b336395c4d7d0ed3a97edc Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 18 Mar 2010 12:19:37 -0700 Subject: agp/intel: Don't do the chipset flush on Sandybridge. This CPU should be coherent with graphics in this direction, though flushing graphics caches are still required. Fixes a system reset on module load on Sandybridge with 4G+ memory. Signed-off-by: Eric Anholt diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index f499c5e..b78d5c3 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -97,6 +97,9 @@ EXPORT_SYMBOL(intel_agp_enabled); #define IS_PINEVIEW (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB || \ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_HB) +#define IS_SNB (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB || \ + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB) + #define IS_G4X (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_EAGLELAKE_HB || \ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q45_HB || \ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G45_HB || \ @@ -107,8 +110,7 @@ EXPORT_SYMBOL(intel_agp_enabled); agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB || \ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB || \ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB || \ - agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB || \ - agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB) + IS_SNB) extern int agp_memory_reserved; @@ -1204,6 +1206,9 @@ static void intel_i9xx_setup_flush(void) if (intel_private.ifp_resource.start) return; + if (IS_SNB) + return; + /* setup a resource for this object */ intel_private.ifp_resource.name = "Intel Flush Page"; intel_private.ifp_resource.flags = IORESOURCE_MEM; -- cgit v0.10.2 From 8956c8bba5b11b3d3aec000e6c6184943011a8d4 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 18 Mar 2010 13:21:14 -0700 Subject: drm/i915: Set up the documented clock gating on Sandybridge and Ironlake. Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 2720bc2..cbbf59f 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2176,6 +2176,14 @@ #define DISPLAY_PORT_PLL_BIOS_1 0x46010 #define DISPLAY_PORT_PLL_BIOS_2 0x46014 +#define PCH_DSPCLK_GATE_D 0x42020 +# define DPFDUNIT_CLOCK_GATE_DISABLE (1 << 7) +# define DPARBUNIT_CLOCK_GATE_DISABLE (1 << 5) + +#define PCH_3DCGDIS0 0x46020 +# define MARIUNIT_CLOCK_GATE_DISABLE (1 << 18) +# define SVSMUNIT_CLOCK_GATE_DISABLE (1 << 1) + #define FDI_PLL_FREQ_CTL 0x46030 #define FDI_PLL_FREQ_CHANGE_REQUEST (1<<24) #define FDI_PLL_FREQ_LOCK_LIMIT_MASK 0xfff00 diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 0e2c5da..58fc7fa 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4717,6 +4717,20 @@ void intel_init_clock_gating(struct drm_device *dev) * specs, but enable as much else as we can. */ if (HAS_PCH_SPLIT(dev)) { + uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE; + + if (IS_IRONLAKE(dev)) { + /* Required for FBC */ + dspclk_gate |= DPFDUNIT_CLOCK_GATE_DISABLE; + /* Required for CxSR */ + dspclk_gate |= DPARBUNIT_CLOCK_GATE_DISABLE; + + I915_WRITE(PCH_3DCGDIS0, + MARIUNIT_CLOCK_GATE_DISABLE | + SVSMUNIT_CLOCK_GATE_DISABLE); + } + + I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate); return; } else if (IS_G4X(dev)) { uint32_t dspclk_gate; -- cgit v0.10.2 From fe305198d4bf481d6dd017df35c566c9d477fada Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 18 Mar 2010 09:22:12 +0100 Subject: drm/intel: fix up set_tiling for untiled->tiled transition Bug introduced in commit 10ae9bd25acf394c8fa2f9d795dfa9cec4d19ed6 Author: Daniel Vetter Date: Mon Feb 1 13:59:17 2010 +0100 drm/i915: blow away userspace mappings before fence change The problem is that when there's no fence reg assigned and the object is mapped at a fenceable offset in the gtt, the userspace mappings won't be torn down. Which happens on untiled->tiled transition quite often on 4th gen and later because there fencing does not have any special alignment constraints (as opposed to 2nd and 3rd gen on which I've tested the original commit). Bugzilla: http://bugs.freedesktop.org/show_bug.cgi?id=26993 Signed-off-by: Daniel Vetter Tested-by: Eric Anholt (fixes OpenArena) Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index b5c55d8..c01c878 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -325,9 +325,12 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, * need to ensure that any fence register is cleared. */ if (!i915_gem_object_fence_offset_ok(obj, args->tiling_mode)) - ret = i915_gem_object_unbind(obj); + ret = i915_gem_object_unbind(obj); + else if (obj_priv->fence_reg != I915_FENCE_REG_NONE) + ret = i915_gem_object_put_fence_reg(obj); else - ret = i915_gem_object_put_fence_reg(obj); + i915_gem_release_mmap(obj); + if (ret != 0) { WARN(ret != -ERESTARTSYS, "failed to reset object for tiling switch"); -- cgit v0.10.2 From 2a238a96358dde09aa52de9b9f97a383165ca651 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Mon, 1 Mar 2010 13:25:49 -0500 Subject: alpha: use __ratelimit Replace open-coded rate limiting logic with __ratelimit(). Signed-off-by: Akinobu Mita Cc: Richard Henderson Cc: Ivan Kokshaysky Cc: linux-alpha@vger.kernel.org Signed-off-by: Matt Turner diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c index 6ee7655..b14f015 100644 --- a/arch/alpha/kernel/traps.c +++ b/arch/alpha/kernel/traps.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -771,8 +772,7 @@ asmlinkage void do_entUnaUser(void __user * va, unsigned long opcode, unsigned long reg, struct pt_regs *regs) { - static int cnt = 0; - static unsigned long last_time; + static DEFINE_RATELIMIT_STATE(ratelimit, 5 * HZ, 5); unsigned long tmp1, tmp2, tmp3, tmp4; unsigned long fake_reg, *reg_addr = &fake_reg; @@ -783,15 +783,11 @@ do_entUnaUser(void __user * va, unsigned long opcode, with the unaliged access. */ if (!test_thread_flag (TIF_UAC_NOPRINT)) { - if (cnt >= 5 && time_after(jiffies, last_time + 5 * HZ)) { - cnt = 0; - } - if (++cnt < 5) { + if (__ratelimit(&ratelimit)) { printk("%s(%d): unaligned trap at %016lx: %p %lx %ld\n", current->comm, task_pid_nr(current), regs->pc - 4, va, opcode, reg); } - last_time = jiffies; } if (test_thread_flag (TIF_UAC_SIGBUS)) goto give_sigbus; -- cgit v0.10.2 From 7f2d889c9cdcd33e8942a23765623adbd468cf04 Mon Sep 17 00:00:00 2001 From: Frans Pop Date: Mon, 1 Mar 2010 13:29:14 -0500 Subject: alpha: remove trailing spaces in messages Signed-off-by: Frans Pop Cc: linux-alpha@vger.kernel.org Signed-off-by: Matt Turner diff --git a/arch/alpha/kernel/sys_dp264.c b/arch/alpha/kernel/sys_dp264.c index d64e1e4..4026502 100644 --- a/arch/alpha/kernel/sys_dp264.c +++ b/arch/alpha/kernel/sys_dp264.c @@ -224,7 +224,7 @@ static void dp264_device_interrupt(unsigned long vector) { #if 1 - printk("dp264_device_interrupt: NOT IMPLEMENTED YET!! \n"); + printk("dp264_device_interrupt: NOT IMPLEMENTED YET!!\n"); #else unsigned long pld; unsigned int i; diff --git a/arch/alpha/kernel/sys_titan.c b/arch/alpha/kernel/sys_titan.c index 2880533..9008d0f 100644 --- a/arch/alpha/kernel/sys_titan.c +++ b/arch/alpha/kernel/sys_titan.c @@ -171,7 +171,7 @@ titan_set_irq_affinity(unsigned int irq, const struct cpumask *affinity) static void titan_device_interrupt(unsigned long vector) { - printk("titan_device_interrupt: NOT IMPLEMENTED YET!! \n"); + printk("titan_device_interrupt: NOT IMPLEMENTED YET!!\n"); } static void -- cgit v0.10.2 From 5286944d75cbe21dd21b0d57335cc6206622b62a Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Thu, 18 Mar 2010 22:35:28 -0400 Subject: alpha: fix compile errors in dma-mapping-common.h The commit c186caca3dbe7f44da624cb4f9d78e1b1dfb13b8 leads to the following errors with CONFIG_ALPHA_{TSUNAMI, TITAN, RAWHIDE, MARVEL}: /home/fujita/git/linux-2.6/include/asm-generic/dma-mapping-common.h: In function `dma_map_sg_attrs': /home/fujita/git/linux-2.6/include/asm-generic/dma-mapping-common.h:49: error: implicit declaration of function `for_each_sg' /home/fujita/git/linux-2.6/include/asm-generic/dma-mapping-common.h:50: error: syntax error before "kmemcheck_mark_initialized" Signed-off-by: FUJITA Tomonori Reported-by: Michael Cree Signed-off-by: Matt Turner diff --git a/arch/alpha/include/asm/core_marvel.h b/arch/alpha/include/asm/core_marvel.h index 30d55fe..dad300f 100644 --- a/arch/alpha/include/asm/core_marvel.h +++ b/arch/alpha/include/asm/core_marvel.h @@ -12,7 +12,6 @@ #define __ALPHA_MARVEL__H__ #include -#include #include #include diff --git a/arch/alpha/include/asm/core_mcpcia.h b/arch/alpha/include/asm/core_mcpcia.h index acf55b4..21ac533 100644 --- a/arch/alpha/include/asm/core_mcpcia.h +++ b/arch/alpha/include/asm/core_mcpcia.h @@ -6,7 +6,6 @@ #define MCPCIA_ONE_HAE_WINDOW 1 #include -#include #include /* diff --git a/arch/alpha/include/asm/core_titan.h b/arch/alpha/include/asm/core_titan.h index a17f6f3..8cf79d1 100644 --- a/arch/alpha/include/asm/core_titan.h +++ b/arch/alpha/include/asm/core_titan.h @@ -2,7 +2,6 @@ #define __ALPHA_TITAN__H__ #include -#include #include /* diff --git a/arch/alpha/include/asm/core_tsunami.h b/arch/alpha/include/asm/core_tsunami.h index 58d4fe4..8e39ecf 100644 --- a/arch/alpha/include/asm/core_tsunami.h +++ b/arch/alpha/include/asm/core_tsunami.h @@ -2,7 +2,6 @@ #define __ALPHA_TSUNAMI__H__ #include -#include #include /* -- cgit v0.10.2 From 2271048d1b3b0aabf83d25b29c20646dcabedc05 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 18 Mar 2010 17:54:19 -0400 Subject: ring-buffer: Do 8 byte alignment for 64 bit that can not handle 4 byte align The ring buffer uses 4 byte alignment while recording events into the buffer, even on 64bit machines. This saves space when there are lots of events being recorded at 4 byte boundaries. The ring buffer has a zero copy method to write into the buffer, with the reserving of space and then committing it. This may cause problems when writing an 8 byte word into a 4 byte alignment (not 8). For x86 and PPC this is not an issue, but on some architectures this would cause an out-of-alignment exception. This patch uses CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS to determine if it is OK to use 4 byte alignments on 64 bit machines. If it is not, it forces the ring buffer event header to be 8 bytes and not 4, and will align the length of the data to be 8 byte aligned. This keeps the data payload at 8 byte alignments and will allow these machines to run without issue. The trick to this is that the header can be either 4 bytes or 8 bytes depending on the length of the data payload. The 4 byte header has a length field that supports up to 112 bytes. If the length of the data is more than 112, the length field is set to zero, and the actual length is stored in the next 4 bytes after the header. When CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set, the code forces zero in the 4 byte header forcing the length to be stored in the 4 byte array, even with a small data load. It also forces the length of the data load to be 8 byte aligned. The combination of these two guarantee that the data is always at 8 byte alignment. Tested-by: Frederic Weisbecker (on sparc64) Reported-by: Frederic Weisbecker Acked-by: David S. Miller Signed-off-by: Steven Rostedt diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 05a9f83..d1187ef 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -207,6 +207,14 @@ EXPORT_SYMBOL_GPL(tracing_is_on); #define RB_MAX_SMALL_DATA (RB_ALIGNMENT * RINGBUF_TYPE_DATA_TYPE_LEN_MAX) #define RB_EVNT_MIN_SIZE 8U /* two 32bit words */ +#if !defined(CONFIG_64BIT) || defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) +# define RB_FORCE_8BYTE_ALIGNMENT 0 +# define RB_ARCH_ALIGNMENT RB_ALIGNMENT +#else +# define RB_FORCE_8BYTE_ALIGNMENT 1 +# define RB_ARCH_ALIGNMENT 8U +#endif + /* define RINGBUF_TYPE_DATA for 'case RINGBUF_TYPE_DATA:' */ #define RINGBUF_TYPE_DATA 0 ... RINGBUF_TYPE_DATA_TYPE_LEN_MAX @@ -1547,7 +1555,7 @@ rb_update_event(struct ring_buffer_event *event, case 0: length -= RB_EVNT_HDR_SIZE; - if (length > RB_MAX_SMALL_DATA) + if (length > RB_MAX_SMALL_DATA || RB_FORCE_8BYTE_ALIGNMENT) event->array[0] = length; else event->type_len = DIV_ROUND_UP(length, RB_ALIGNMENT); @@ -1722,11 +1730,11 @@ static unsigned rb_calculate_event_length(unsigned length) if (!length) length = 1; - if (length > RB_MAX_SMALL_DATA) + if (length > RB_MAX_SMALL_DATA || RB_FORCE_8BYTE_ALIGNMENT) length += sizeof(event.array[0]); length += RB_EVNT_HDR_SIZE; - length = ALIGN(length, RB_ALIGNMENT); + length = ALIGN(length, RB_ARCH_ALIGNMENT); return length; } -- cgit v0.10.2 From b634f87522dff87712df8bda2a6c9061954d552a Mon Sep 17 00:00:00 2001 From: Alexandra Kossovsky Date: Thu, 18 Mar 2010 20:29:24 -0700 Subject: tcp: Fix OOB POLLIN avoidance. From: Alexandra.Kossovsky@oktetlabs.ru Fixes kernel bugzilla #15541 Signed-off-by: David S. Miller diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 5901010..ae16f80 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -429,7 +429,7 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait) if (tp->urg_seq == tp->copied_seq && !sock_flag(sk, SOCK_URGINLINE) && tp->urg_data) - target--; + target++; /* Potential race condition. If read of tp below will * escape above sk->sk_state, we can be illegally awaken -- cgit v0.10.2 From 658cc524305c9759019c4430ded231f631472482 Mon Sep 17 00:00:00 2001 From: Abraham Arce Date: Tue, 16 Mar 2010 12:24:54 +0000 Subject: KS8851: Avoid NULL pointer in set rx mode Kernel NULL pointer dereference when setting mode for IFF_MULTICAST. Tested on SDP OMAP4430 board. ks8851 spi1.0: message enable is 0 ks8851 spi1.0: revision 0, MAC f2:f4:2f:56:37:de, IRQ 194 Unable to handle kernel NULL pointer dereference at virtual address 00000000 pgd = c0004000 [00000000] *pgd=00000000 Internal error: Oops: 5 [#1] PREEMPT SMP last sysfs file: Modules linked in: CPU: 0 Not tainted (2.6.34-rc1-01039-g38d7ed1-dirty #3) PC is at ks8851_set_rx_mode+0x88/0x124 LR is at bitrev32+0x24/0x2c Backtrace: [] ? (ks8851_set_rx_mode+0x0/0x124) [] (__dev_set_rx_mode+0x0/0x90) [] (dev_mc_add+0x0/0x78) [] (igmp_group_added+0x0/0x64) [] (ip_mc_inc_group+0x0/0x150) [] (ip_mc_up+0x0/0x64) [] (inetdev_event+0x0/0x3d4) [] (notifier_call_chain+0x0/0x78) [] (__raw_notifier_call_chain+0x0/0x24) [] (raw_notifier_call_chain+0x0/0x28) [] (call_netdevice_notifiers+0x0/0x24) [] (__dev_notify_flags+0x0/0x68) [] (dev_change_flags+0x0/0x4c) [] (ip_auto_config+0x0/0xf1c) [] (do_one_initcall+0x0/0x1bc) [] (kernel_init+0x0/0x234) Code: e15130bc e1833012 e14130bc e5943000 (e5934000) ---[ end trace ed0fb00a94142792 ]--- Kernel panic - not syncing: Fatal exception in interrupt Signed-off-by: Abraham Arce Signed-off-by: David S. Miller diff --git a/drivers/net/ks8851.c b/drivers/net/ks8851.c index 0573e0b..13cc1ca 100644 --- a/drivers/net/ks8851.c +++ b/drivers/net/ks8851.c @@ -976,7 +976,6 @@ static void ks8851_set_rx_mode(struct net_device *dev) crc >>= (32 - 6); /* get top six bits */ rxctrl.mchash[crc >> 4] |= (1 << (crc & 0xf)); - mcptr = mcptr->next; } rxctrl.rxcr1 = RXCR1_RXME | RXCR1_RXPAFMA; -- cgit v0.10.2 From 17da69b8bfbe441a33a873ad5dd7d3d85800bf2b Mon Sep 17 00:00:00 2001 From: Guo-Fu Tseng Date: Wed, 17 Mar 2010 00:09:29 +0000 Subject: jme: Fix VLAN memory leak Fix memory leak while receiving 8021q tagged packet which is not registered by user. Signed-off-by: Guo-Fu Tseng Cc: stable@kernel.org Signed-off-by: David S. Miller diff --git a/drivers/net/jme.c b/drivers/net/jme.c index 0f31497..cfc7b98 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c @@ -946,6 +946,8 @@ jme_alloc_and_feed_skb(struct jme_adapter *jme, int idx) jme->jme_vlan_rx(skb, jme->vlgrp, le16_to_cpu(rxdesc->descwb.vlan)); NET_STAT(jme).rx_bytes += 4; + } else { + dev_kfree_skb(skb); } } else { jme->jme_rx(skb); -- cgit v0.10.2 From bf5e5360fd1df1ae429ebbd81838d7d0879797d1 Mon Sep 17 00:00:00 2001 From: Guo-Fu Tseng Date: Wed, 17 Mar 2010 00:09:30 +0000 Subject: jme: Protect vlgrp structure by pause RX actions. Temporary stop the RX IRQ, and disable (sync) tasklet or napi. And restore it after finished the vlgrp pointer assignment. Signed-off-by: Guo-Fu Tseng Cc: stable@kernel.org Signed-off-by: David S. Miller diff --git a/drivers/net/jme.c b/drivers/net/jme.c index cfc7b98..c0b59a5 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c @@ -2083,12 +2083,45 @@ jme_tx_timeout(struct net_device *netdev) jme_reset_link(jme); } +static inline void jme_pause_rx(struct jme_adapter *jme) +{ + atomic_dec(&jme->link_changing); + + jme_set_rx_pcc(jme, PCC_OFF); + if (test_bit(JME_FLAG_POLL, &jme->flags)) { + JME_NAPI_DISABLE(jme); + } else { + tasklet_disable(&jme->rxclean_task); + tasklet_disable(&jme->rxempty_task); + } +} + +static inline void jme_resume_rx(struct jme_adapter *jme) +{ + struct dynpcc_info *dpi = &(jme->dpi); + + if (test_bit(JME_FLAG_POLL, &jme->flags)) { + JME_NAPI_ENABLE(jme); + } else { + tasklet_hi_enable(&jme->rxclean_task); + tasklet_hi_enable(&jme->rxempty_task); + } + dpi->cur = PCC_P1; + dpi->attempt = PCC_P1; + dpi->cnt = 0; + jme_set_rx_pcc(jme, PCC_P1); + + atomic_inc(&jme->link_changing); +} + static void jme_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp) { struct jme_adapter *jme = netdev_priv(netdev); + jme_pause_rx(jme); jme->vlgrp = grp; + jme_resume_rx(jme); } static void -- cgit v0.10.2 From 54d259d474e1fee6f6bb8f0f1360d85195199ac5 Mon Sep 17 00:00:00 2001 From: Guo-Fu Tseng Date: Wed, 17 Mar 2010 00:09:31 +0000 Subject: jme: Advance driver version number Advance driver version number after some bug fix. Signed-off-by: Guo-Fu Tseng Signed-off-by: David S. Miller diff --git a/drivers/net/jme.h b/drivers/net/jme.h index c19db91..07ad3a4 100644 --- a/drivers/net/jme.h +++ b/drivers/net/jme.h @@ -25,7 +25,7 @@ #define __JME_H_INCLUDED__ #define DRV_NAME "jme" -#define DRV_VERSION "1.0.5" +#define DRV_VERSION "1.0.6" #define PFX DRV_NAME ": " #define PCI_DEVICE_ID_JMICRON_JMC250 0x0250 -- cgit v0.10.2 From 0641e4fbf2f824faee00ea74c459a088d94905fd Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 18 Mar 2010 21:16:45 -0700 Subject: net: Potential null skb->dev dereference When doing "ifenslave -d bond0 eth0", there is chance to get NULL dereference in netif_receive_skb(), because dev->master suddenly becomes NULL after we tested it. We should use ACCESS_ONCE() to avoid this (or rcu_dereference()) Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index c79a88b..fa8b476 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -2059,12 +2059,12 @@ static inline void skb_bond_set_mac_by_master(struct sk_buff *skb, * duplicates except for 802.3ad ETH_P_SLOW, alb non-mcast/bcast, and * ARP on active-backup slaves with arp_validate enabled. */ -static inline int skb_bond_should_drop(struct sk_buff *skb) +static inline int skb_bond_should_drop(struct sk_buff *skb, + struct net_device *master) { - struct net_device *dev = skb->dev; - struct net_device *master = dev->master; - if (master) { + struct net_device *dev = skb->dev; + if (master->priv_flags & IFF_MASTER_ARPMON) dev->last_rx = jiffies; diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index c0316e0..c584a0a 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c @@ -11,7 +11,7 @@ int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp, if (netpoll_rx(skb)) return NET_RX_DROP; - if (skb_bond_should_drop(skb)) + if (skb_bond_should_drop(skb, ACCESS_ONCE(skb->dev->master))) goto drop; skb->skb_iif = skb->dev->ifindex; @@ -83,7 +83,7 @@ vlan_gro_common(struct napi_struct *napi, struct vlan_group *grp, { struct sk_buff *p; - if (skb_bond_should_drop(skb)) + if (skb_bond_should_drop(skb, ACCESS_ONCE(skb->dev->master))) goto drop; skb->skb_iif = skb->dev->ifindex; diff --git a/net/core/dev.c b/net/core/dev.c index bcc490c..59d4394 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2483,6 +2483,7 @@ int netif_receive_skb(struct sk_buff *skb) { struct packet_type *ptype, *pt_prev; struct net_device *orig_dev; + struct net_device *master; struct net_device *null_or_orig; struct net_device *null_or_bond; int ret = NET_RX_DROP; @@ -2503,11 +2504,12 @@ int netif_receive_skb(struct sk_buff *skb) null_or_orig = NULL; orig_dev = skb->dev; - if (orig_dev->master) { - if (skb_bond_should_drop(skb)) + master = ACCESS_ONCE(orig_dev->master); + if (master) { + if (skb_bond_should_drop(skb, master)) null_or_orig = orig_dev; /* deliver only exact match */ else - skb->dev = orig_dev->master; + skb->dev = master; } __get_cpu_var(netdev_rx_stat).total++; -- cgit v0.10.2 From 1097cd17700c4e9903b7bbfcec1432f61784cb53 Mon Sep 17 00:00:00 2001 From: Mallikarjuna R Chilakala Date: Thu, 18 Mar 2010 14:34:52 +0000 Subject: ixgbe: Fix 82599 multispeed fiber link issues due to Tx laser flapping Fix 82599 link issues during driver load and unload test using multi-speed 10G & 1G fiber modules. When connected back to back sometime 82599 multispeed fiber modules would link at 1G speed instead of 10G highest speed, due to a race condition in autotry process involving Tx laser flapping. Move autotry autoneg-37 tx laser flapping process from multispeed module init setup to driver unload. This will alert the link partner to restart its autotry process when it tries to establish the link with the link partner Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index 1f30e16..b405a00 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -39,6 +39,7 @@ #define IXGBE_82599_MC_TBL_SIZE 128 #define IXGBE_82599_VFT_TBL_SIZE 128 +void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw); s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg, @@ -68,7 +69,9 @@ static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw) if (hw->phy.multispeed_fiber) { /* Set up dual speed SFP+ support */ mac->ops.setup_link = &ixgbe_setup_mac_link_multispeed_fiber; + mac->ops.flap_tx_laser = &ixgbe_flap_tx_laser_multispeed_fiber; } else { + mac->ops.flap_tx_laser = NULL; if ((mac->ops.get_media_type(hw) == ixgbe_media_type_backplane) && (hw->phy.smart_speed == ixgbe_smart_speed_auto || @@ -413,6 +416,41 @@ s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw, } /** + * ixgbe_flap_tx_laser_multispeed_fiber - Flap Tx laser + * @hw: pointer to hardware structure + * + * When the driver changes the link speeds that it can support, + * it sets autotry_restart to true to indicate that we need to + * initiate a new autotry session with the link partner. To do + * so, we set the speed then disable and re-enable the tx laser, to + * alert the link partner that it also needs to restart autotry on its + * end. This is consistent with true clause 37 autoneg, which also + * involves a loss of signal. + **/ +void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw) +{ + u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP); + + hw_dbg(hw, "ixgbe_flap_tx_laser_multispeed_fiber\n"); + + if (hw->mac.autotry_restart) { + /* Disable tx laser; allow 100us to go dark per spec */ + esdp_reg |= IXGBE_ESDP_SDP3; + IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); + IXGBE_WRITE_FLUSH(hw); + udelay(100); + + /* Enable tx laser; allow 100ms to light up */ + esdp_reg &= ~IXGBE_ESDP_SDP3; + IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); + IXGBE_WRITE_FLUSH(hw); + msleep(100); + + hw->mac.autotry_restart = false; + } +} + +/** * ixgbe_setup_mac_link_multispeed_fiber - Set MAC link speed * @hw: pointer to hardware structure * @speed: new link speed @@ -440,16 +478,6 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, speed &= phy_link_speed; /* - * When the driver changes the link speeds that it can support, - * it sets autotry_restart to true to indicate that we need to - * initiate a new autotry session with the link partner. To do - * so, we set the speed then disable and re-enable the tx laser, to - * alert the link partner that it also needs to restart autotry on its - * end. This is consistent with true clause 37 autoneg, which also - * involves a loss of signal. - */ - - /* * Try each speed one by one, highest priority first. We do this in * software because 10gb fiber doesn't support speed autonegotiation. */ @@ -466,6 +494,7 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, /* Set the module link speed */ esdp_reg |= (IXGBE_ESDP_SDP5_DIR | IXGBE_ESDP_SDP5); IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); + IXGBE_WRITE_FLUSH(hw); /* Allow module to change analog characteristics (1G->10G) */ msleep(40); @@ -478,19 +507,7 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, return status; /* Flap the tx laser if it has not already been done */ - if (hw->mac.autotry_restart) { - /* Disable tx laser; allow 100us to go dark per spec */ - esdp_reg |= IXGBE_ESDP_SDP3; - IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); - udelay(100); - - /* Enable tx laser; allow 2ms to light up per spec */ - esdp_reg &= ~IXGBE_ESDP_SDP3; - IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); - msleep(2); - - hw->mac.autotry_restart = false; - } + hw->mac.ops.flap_tx_laser(hw); /* * Wait for the controller to acquire link. Per IEEE 802.3ap, @@ -525,6 +542,7 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, esdp_reg &= ~IXGBE_ESDP_SDP5; esdp_reg |= IXGBE_ESDP_SDP5_DIR; IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); + IXGBE_WRITE_FLUSH(hw); /* Allow module to change analog characteristics (10G->1G) */ msleep(40); @@ -537,19 +555,7 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, return status; /* Flap the tx laser if it has not already been done */ - if (hw->mac.autotry_restart) { - /* Disable tx laser; allow 100us to go dark per spec */ - esdp_reg |= IXGBE_ESDP_SDP3; - IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); - udelay(100); - - /* Enable tx laser; allow 2ms to light up per spec */ - esdp_reg &= ~IXGBE_ESDP_SDP3; - IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); - msleep(2); - - hw->mac.autotry_restart = false; - } + hw->mac.ops.flap_tx_laser(hw); /* Wait for the link partner to also set speed */ msleep(100); diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 684af37..b858a1a 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -5018,6 +5018,7 @@ static void ixgbe_multispeed_fiber_task(struct work_struct *work) autoneg = hw->phy.autoneg_advertised; if ((!autoneg) && (hw->mac.ops.get_link_capabilities)) hw->mac.ops.get_link_capabilities(hw, &autoneg, &negotiation); + hw->mac.autotry_restart = false; if (hw->mac.ops.setup_link) hw->mac.ops.setup_link(hw, autoneg, negotiation, true); adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE; @@ -6380,6 +6381,16 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev) del_timer_sync(&adapter->sfp_timer); cancel_work_sync(&adapter->watchdog_task); cancel_work_sync(&adapter->sfp_task); + if (adapter->hw.phy.multispeed_fiber) { + struct ixgbe_hw *hw = &adapter->hw; + /* + * Restart clause 37 autoneg, disable and re-enable + * the tx laser, to clear & alert the link partner + * that it needs to restart autotry + */ + hw->mac.autotry_restart = true; + hw->mac.ops.flap_tx_laser(hw); + } cancel_work_sync(&adapter->multispeed_fiber_task); cancel_work_sync(&adapter->sfp_config_module_task); if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE || diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 2be9074..0ed5ab3 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -2397,6 +2397,7 @@ struct ixgbe_mac_operations { s32 (*enable_rx_dma)(struct ixgbe_hw *, u32); /* Link */ + void (*flap_tx_laser)(struct ixgbe_hw *); s32 (*setup_link)(struct ixgbe_hw *, ixgbe_link_speed, bool, bool); s32 (*check_link)(struct ixgbe_hw *, ixgbe_link_speed *, bool *, bool); s32 (*get_link_capabilities)(struct ixgbe_hw *, ixgbe_link_speed *, -- cgit v0.10.2 From 0ecad5a262923967147e2d1725e277a2a5fbcdd4 Mon Sep 17 00:00:00 2001 From: Mallikarjuna R Chilakala Date: Thu, 18 Mar 2010 15:16:56 +0000 Subject: ixgbe: Fix 82599 KX4 Wake on LAN issue after an improper system shutdown Advanced Power Management is disabled for 82599 KX4 connections by clearing GRC.APME bit, causing it to not wake the system from an improper system shutdown. By default GRC.APME is enabled and software is not supposed to clear these settings during adapter probe. Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index b858a1a..18b5b21 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -6246,9 +6246,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, case IXGBE_DEV_ID_82599_KX4: adapter->wol = (IXGBE_WUFC_MAG | IXGBE_WUFC_EX | IXGBE_WUFC_MC | IXGBE_WUFC_BC); - /* Enable ACPI wakeup in GRC */ - IXGBE_WRITE_REG(hw, IXGBE_GRC, - (IXGBE_READ_REG(hw, IXGBE_GRC) & ~IXGBE_GRC_APME)); break; default: adapter->wol = 0; -- cgit v0.10.2 From 11bc3088373e913f165a8652601c6f8b8dc4aea2 Mon Sep 17 00:00:00 2001 From: Steve Glendinning Date: Thu, 18 Mar 2010 22:18:41 -0700 Subject: smsc95xx: Fix tx checksum offload for small packets TX checksum offload does not work properly when transmitting UDP packets with 0, 1 or 2 bytes of data. This patch works around the problem by calculating checksums for these packets in the driver. Signed-off-by: Steve Glendinning Signed-off-by: David S. Miller diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index d222d7e..73f9a31 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -1189,9 +1189,21 @@ static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev, } if (csum) { - u32 csum_preamble = smsc95xx_calc_csum_preamble(skb); - skb_push(skb, 4); - memcpy(skb->data, &csum_preamble, 4); + if (skb->len <= 45) { + /* workaround - hardware tx checksum does not work + * properly with extremely small packets */ + long csstart = skb->csum_start - skb_headroom(skb); + __wsum calc = csum_partial(skb->data + csstart, + skb->len - csstart, 0); + *((__sum16 *)(skb->data + csstart + + skb->csum_offset)) = csum_fold(calc); + + csum = false; + } else { + u32 csum_preamble = smsc95xx_calc_csum_preamble(skb); + skb_push(skb, 4); + memcpy(skb->data, &csum_preamble, 4); + } } skb_push(skb, 4); -- cgit v0.10.2 From 409d241b7bb2cf0278186040ace1c4704fb2a82f Mon Sep 17 00:00:00 2001 From: Nathan Lynch Date: Fri, 12 Mar 2010 13:16:02 +0000 Subject: powerpc: Use correct ccr bit for syscall error status The powerpc implementations of syscall_get_error and syscall_set_return_value should use CCR0:S0 (0x10000000) for testing and setting syscall error status. Fortunately these APIs don't seem to be used at the moment. Signed-off-by: Nathan Lynch Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/include/asm/syscall.h b/arch/powerpc/include/asm/syscall.h index efa7f0b..23913e9 100644 --- a/arch/powerpc/include/asm/syscall.h +++ b/arch/powerpc/include/asm/syscall.h @@ -30,7 +30,7 @@ static inline void syscall_rollback(struct task_struct *task, static inline long syscall_get_error(struct task_struct *task, struct pt_regs *regs) { - return (regs->ccr & 0x1000) ? -regs->gpr[3] : 0; + return (regs->ccr & 0x10000000) ? -regs->gpr[3] : 0; } static inline long syscall_get_return_value(struct task_struct *task, @@ -44,10 +44,10 @@ static inline void syscall_set_return_value(struct task_struct *task, int error, long val) { if (error) { - regs->ccr |= 0x1000L; + regs->ccr |= 0x10000000L; regs->gpr[3] = -error; } else { - regs->ccr &= ~0x1000L; + regs->ccr &= ~0x10000000L; regs->gpr[3] = val; } } -- cgit v0.10.2 From 09156a7a409cf93d1ca2706bf05d714879a5b7ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20N=C3=A9meth?= Date: Sat, 6 Mar 2010 22:43:55 +0000 Subject: powerpc: Do not call prink when CONFIG_PRINTK is not defined MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When printk() is disabled (CONFIG_PRINTK) at menu item General setup -> Configure standard kernel features (for small systems) -> Enable support for printk then there should be no printk() calls at all. Signed-off-by: Márton Németh Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index a7cf493..7255265 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -884,13 +884,17 @@ KernelSPE: lwz r3,_MSR(r1) oris r3,r3,MSR_SPE@h stw r3,_MSR(r1) /* enable use of SPE after return */ +#ifdef CONFIG_PRINTK lis r3,87f@h ori r3,r3,87f@l mr r4,r2 /* current */ lwz r5,_NIP(r1) bl printk +#endif b ret_from_except +#ifdef CONFIG_PRINTK 87: .string "SPE used in kernel (task=%p, pc=%x) \n" +#endif .align 4,0 #endif /* CONFIG_SPE */ -- cgit v0.10.2 From a93272969c6b1d59883fcbb04845420bd72c9a20 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 16 Mar 2010 13:16:25 +0000 Subject: powerpc: Fix swiotlb to respect the boot option powerpc initializes swiotlb before parsing the kernel boot options so swiotlb options (e.g. specifying the swiotlb buffer size) are ignored. Any time before freeing bootmem works for swiotlb so this patch moves powerpc's swiotlb initialization after parsing the kernel boot options, mem_init (as x86 does). Signed-off-by: FUJITA Tomonori Tested-by: Becky Bruce Tested-by: Albert Herranz Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index b152de3..8f58986 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -39,7 +39,6 @@ #include #include #include -#include #include "setup.h" @@ -343,11 +342,6 @@ void __init setup_arch(char **cmdline_p) ppc_md.setup_arch(); if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab); -#ifdef CONFIG_SWIOTLB - if (ppc_swiotlb_enable) - swiotlb_init(1); -#endif - paging_init(); /* Initialize the MMU context management stuff */ diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 6354739..9143891 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -61,7 +61,6 @@ #include #include #include -#include #include #include "setup.h" @@ -541,11 +540,6 @@ void __init setup_arch(char **cmdline_p) if (ppc_md.setup_arch) ppc_md.setup_arch(); -#ifdef CONFIG_SWIOTLB - if (ppc_swiotlb_enable) - swiotlb_init(1); -#endif - paging_init(); /* Initialize the MMU context management stuff */ diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 311224c..448f972 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -48,6 +48,7 @@ #include #include #include +#include #include "mmu_decl.h" @@ -320,6 +321,11 @@ void __init mem_init(void) struct page *page; unsigned long reservedpages = 0, codesize, initsize, datasize, bsssize; +#ifdef CONFIG_SWIOTLB + if (ppc_swiotlb_enable) + swiotlb_init(1); +#endif + num_physpages = lmb.memory.size >> PAGE_SHIFT; high_memory = (void *) __va(max_low_pfn * PAGE_SIZE); -- cgit v0.10.2 From 191aee58b6568cf8143901bfa3f57a9b8faa6f1c Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 2 Mar 2010 14:25:38 +0000 Subject: powerpc: Remove IOMMU_VMERGE config option The description says: Cause IO segments sent to a device for DMA to be merged virtually by the IOMMU when they happen to have been allocated contiguously. This doesn't add pressure to the IOMMU allocator. However, some drivers don't support getting large merged segments coming back from *_map_sg(). Most drivers don't have this problem; it is safe to say Y here. It's out of date. Long ago, drivers didn't have a way to tell IOMMUs about their segment length limit (that is, the maximum segment length that they can handle). So IOMMUs merged as many segments as possible and gave too large segments to drivers. dma_get_max_seg_size() was introduced to solve the above problem. Device drives can use the API to tell IOMMU about the maximum segment length that they can handle. In addition, the default limit (64K) should be safe for everyone. So this config option seems to be unnecessary. Note that this config option just enables users to disable the virtual merging by default. Users can still disable the virtual merging by the boot parameter. Signed-off-by: FUJITA Tomonori Signed-off-by: Benjamin Herrenschmidt diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 8a54eb8..2e19500 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -313,19 +313,6 @@ config 8XX_MINIMAL_FPEMU It is recommended that you build a soft-float userspace instead. -config IOMMU_VMERGE - bool "Enable IOMMU virtual merging" - depends on PPC64 - default y - help - Cause IO segments sent to a device for DMA to be merged virtually - by the IOMMU when they happen to have been allocated contiguously. - This doesn't add pressure to the IOMMU allocator. However, some - drivers don't support getting large merged segments coming back - from *_map_sg(). - - Most drivers don't have this problem; it is safe to say Y here. - config IOMMU_HELPER def_bool PPC64 diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index 5547ae6..ec94f90 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c @@ -42,12 +42,7 @@ #define DBG(...) -#ifdef CONFIG_IOMMU_VMERGE -static int novmerge = 0; -#else -static int novmerge = 1; -#endif - +static int novmerge; static int protect4gb = 1; static void __iommu_free(struct iommu_table *, dma_addr_t, unsigned int); -- cgit v0.10.2 From e9ce335df51ff782035a15c261a3c0c9892a1767 Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Fri, 19 Mar 2010 08:03:04 +0100 Subject: cfq-iosched: fix a kbuild regression Alex Shi reported a kbuild regression which is about 10% performance lost. He bisected to this commit: 3dde36ddea3e07dd025c4c1ba47edec91606fec0. The reason is cfqq_close() can't find close cooperator. Restoring cfq_rq_close()'s threshold to original value makes the regression go away. Since for_preempt parameter isn't used anymore, this patch deletes it. Reported-by: Alex Shi Signed-off-by: Shaohua Li Acked-by: Corrado Zoccolo Signed-off-by: Jens Axboe diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index dee9d93..8d5a2f2 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -47,6 +47,7 @@ static const int cfq_hist_divisor = 4; #define CFQ_SERVICE_SHIFT 12 #define CFQQ_SEEK_THR (sector_t)(8 * 100) +#define CFQQ_CLOSE_THR (sector_t)(8 * 1024) #define CFQQ_SECT_THR_NONROT (sector_t)(2 * 32) #define CFQQ_SEEKY(cfqq) (hweight32(cfqq->seek_history) > 32/8) @@ -1660,9 +1661,9 @@ static inline sector_t cfq_dist_from_last(struct cfq_data *cfqd, } static inline int cfq_rq_close(struct cfq_data *cfqd, struct cfq_queue *cfqq, - struct request *rq, bool for_preempt) + struct request *rq) { - return cfq_dist_from_last(cfqd, rq) <= CFQQ_SEEK_THR; + return cfq_dist_from_last(cfqd, rq) <= CFQQ_CLOSE_THR; } static struct cfq_queue *cfqq_close(struct cfq_data *cfqd, @@ -1689,7 +1690,7 @@ static struct cfq_queue *cfqq_close(struct cfq_data *cfqd, * will contain the closest sector. */ __cfqq = rb_entry(parent, struct cfq_queue, p_node); - if (cfq_rq_close(cfqd, cur_cfqq, __cfqq->next_rq, false)) + if (cfq_rq_close(cfqd, cur_cfqq, __cfqq->next_rq)) return __cfqq; if (blk_rq_pos(__cfqq->next_rq) < sector) @@ -1700,7 +1701,7 @@ static struct cfq_queue *cfqq_close(struct cfq_data *cfqd, return NULL; __cfqq = rb_entry(node, struct cfq_queue, p_node); - if (cfq_rq_close(cfqd, cur_cfqq, __cfqq->next_rq, false)) + if (cfq_rq_close(cfqd, cur_cfqq, __cfqq->next_rq)) return __cfqq; return NULL; @@ -3103,7 +3104,7 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq, * if this request is as-good as one we would expect from the * current cfqq, let it preempt */ - if (cfq_rq_close(cfqd, cfqq, rq, true)) + if (cfq_rq_close(cfqd, cfqq, rq)) return true; return false; -- cgit v0.10.2 From 181fdde3b4268cb7b4af76ba6337e7ec8accbb36 Mon Sep 17 00:00:00 2001 From: Richard Kennedy Date: Fri, 19 Mar 2010 08:58:16 +0100 Subject: block: remove 16 bytes of padding from struct request on 64bits Remove alignment padding to shrink struct request from 336 to 320 bytes so needing one fewer cacheline and therefore removing 48 bytes from struct request_queue. Signed-off-by: Richard Kennedy Signed-off-by: Jens Axboe diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 41551c9..6690e8b 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -158,7 +158,6 @@ enum rq_flag_bits { struct request { struct list_head queuelist; struct call_single_data csd; - int cpu; struct request_queue *q; @@ -166,9 +165,11 @@ struct request { enum rq_cmd_type_bits cmd_type; unsigned long atomic_flags; + int cpu; + /* the following two fields are internal, NEVER access directly */ - sector_t __sector; /* sector cursor */ unsigned int __data_len; /* total data len */ + sector_t __sector; /* sector cursor */ struct bio *bio; struct bio *biotail; @@ -201,20 +202,20 @@ struct request { unsigned short ioprio; + int ref_count; + void *special; /* opaque pointer available for LLD use */ char *buffer; /* kaddr of the current segment if available */ int tag; int errors; - int ref_count; - /* * when request is used as a packet command carrier */ - unsigned short cmd_len; unsigned char __cmd[BLK_MAX_CDB]; unsigned char *cmd; + unsigned short cmd_len; unsigned int extra_len; /* length of alignment and padding */ unsigned int sense_len; -- cgit v0.10.2 From 48fae657f04924c06fe8c9afdb149efdd99d68dd Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 18 Mar 2010 16:55:45 +0100 Subject: i.MX51 Babbage: Add uncompress output Signed-off-by: Sascha Hauer diff --git a/arch/arm/plat-mxc/include/mach/uncompress.h b/arch/arm/plat-mxc/include/mach/uncompress.h index 52e476a..b6d3d0f 100644 --- a/arch/arm/plat-mxc/include/mach/uncompress.h +++ b/arch/arm/plat-mxc/include/mach/uncompress.h @@ -66,6 +66,7 @@ static inline void flush(void) #define MX2X_UART1_BASE_ADDR 0x1000a000 #define MX3X_UART1_BASE_ADDR 0x43F90000 #define MX3X_UART2_BASE_ADDR 0x43F94000 +#define MX51_UART1_BASE_ADDR 0x73fbc000 static __inline__ void __arch_decomp_setup(unsigned long arch_id) { @@ -101,6 +102,9 @@ static __inline__ void __arch_decomp_setup(unsigned long arch_id) case MACH_TYPE_MAGX_ZN5: uart_base = MX3X_UART2_BASE_ADDR; break; + case MACH_TYPE_MX51_BABBAGE: + uart_base = MX51_UART1_BASE_ADDR; + break; default: break; } -- cgit v0.10.2 From 1b6a2b2d0ff2ced5fe608e0b2e13ccd2b7a283e5 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 18 Mar 2010 16:56:11 +0100 Subject: i.MX51: Use correct clock for gpt The gpt uses the ipg clock, not ipg_perclk Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx5/clock-mx51.c b/arch/arm/mach-mx5/clock-mx51.c index be90c03..8f85f73 100644 --- a/arch/arm/mach-mx5/clock-mx51.c +++ b/arch/arm/mach-mx5/clock-mx51.c @@ -757,7 +757,7 @@ DEFINE_CLOCK(uart3_ipg_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG7_OFFSET, /* GPT */ DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET, - NULL, NULL, &ipg_perclk, NULL); + NULL, NULL, &ipg_clk, NULL); DEFINE_CLOCK(gpt_ipg_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG10_OFFSET, NULL, NULL, &ipg_clk, NULL); -- cgit v0.10.2 From 3d1bc8626c7b17facfcb7fb5dee4686f47a1e75d Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 18 Mar 2010 16:56:30 +0100 Subject: i.MX51: map TZIC dynamically This looks cleaner and allows us to call mx51_revision later when we can use ioremap to determine the silicon revision dynamically. Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx5/mm.c b/arch/arm/mach-mx5/mm.c index c21e18b..9fe7beb 100644 --- a/arch/arm/mach-mx5/mm.c +++ b/arch/arm/mach-mx5/mm.c @@ -35,11 +35,6 @@ static struct map_desc mxc_io_desc[] __initdata = { .length = MX51_DEBUG_SIZE, .type = MT_DEVICE }, { - .virtual = MX51_TZIC_BASE_ADDR_VIRT, - .pfn = __phys_to_pfn(MX51_TZIC_BASE_ADDR), - .length = MX51_TZIC_SIZE, - .type = MT_DEVICE - }, { .virtual = MX51_AIPS1_BASE_ADDR_VIRT, .pfn = __phys_to_pfn(MX51_AIPS1_BASE_ADDR), .length = MX51_AIPS1_SIZE, @@ -69,14 +64,6 @@ static struct map_desc mxc_io_desc[] __initdata = { */ void __init mx51_map_io(void) { - u32 tzic_addr; - - if (mx51_revision() < MX51_CHIP_REV_2_0) - tzic_addr = 0x8FFFC000; - else - tzic_addr = 0xE0003000; - mxc_io_desc[2].pfn = __phys_to_pfn(tzic_addr); - mxc_set_cpu_type(MXC_CPU_MX51); mxc_iomux_v3_init(MX51_IO_ADDRESS(MX51_IOMUXC_BASE_ADDR)); mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG_BASE_ADDR)); @@ -85,5 +72,17 @@ void __init mx51_map_io(void) void __init mx51_init_irq(void) { - tzic_init_irq(MX51_IO_ADDRESS(MX51_TZIC_BASE_ADDR)); + unsigned long tzic_addr; + void __iomem *tzic_virt; + + if (mx51_revision() < MX51_CHIP_REV_2_0) + tzic_addr = MX51_TZIC_BASE_ADDR_TO1; + else + tzic_addr = MX51_TZIC_BASE_ADDR; + + tzic_virt = ioremap(tzic_addr, SZ_16K); + if (!tzic_virt) + panic("unable to map TZIC interrupt controller\n"); + + tzic_init_irq(tzic_virt); } diff --git a/arch/arm/plat-mxc/include/mach/mx51.h b/arch/arm/plat-mxc/include/mach/mx51.h index 771532b..f1396bd 100644 --- a/arch/arm/plat-mxc/include/mach/mx51.h +++ b/arch/arm/plat-mxc/include/mach/mx51.h @@ -14,7 +14,7 @@ * FB100000 70000000 1M SPBA 0 * FB000000 73F00000 1M AIPS 1 * FB200000 83F00000 1M AIPS 2 - * FA100000 8FFFC000 16K TZIC (interrupt controller) + * 8FFFC000 16K TZIC (interrupt controller) * 90000000 256M CSD0 SDRAM/DDR * A0000000 256M CSD1 SDRAM/DDR * B0000000 128M CS0 Flash @@ -49,9 +49,8 @@ #define MX51_GPU_BASE_ADDR 0x20000000 #define MX51_GPU2D_BASE_ADDR 0xD0000000 -#define MX51_TZIC_BASE_ADDR 0x8FFFC000 -#define MX51_TZIC_BASE_ADDR_VIRT 0xFA100000 -#define MX51_TZIC_SIZE SZ_16K +#define MX51_TZIC_BASE_ADDR_TO1 0x8FFFC000 +#define MX51_TZIC_BASE_ADDR 0xE0000000 #define MX51_DEBUG_BASE_ADDR 0x60000000 #define MX51_DEBUG_BASE_ADDR_VIRT 0xFA200000 @@ -232,7 +231,6 @@ #define MX51_IO_ADDRESS(x) \ (void __iomem *) \ (MX51_IS_MODULE(x, IRAM) ? MX51_IRAM_IO_ADDRESS(x) : \ - MX51_IS_MODULE(x, TZIC) ? MX51_TZIC_IO_ADDRESS(x) : \ MX51_IS_MODULE(x, DEBUG) ? MX51_DEBUG_IO_ADDRESS(x) : \ MX51_IS_MODULE(x, SPBA0) ? MX51_SPBA0_IO_ADDRESS(x) : \ MX51_IS_MODULE(x, AIPS1) ? MX51_AIPS1_IO_ADDRESS(x) : \ @@ -246,9 +244,6 @@ #define MX51_IRAM_IO_ADDRESS(x) \ (((x) - MX51_IRAM_BASE_ADDR) + MX51_IRAM_BASE_ADDR_VIRT) -#define MX51_TZIC_IO_ADDRESS(x) \ - (((x) - MX51_TZIC_BASE_ADDR) + MX51_TZIC_BASE_ADDR_VIRT) - #define MX51_DEBUG_IO_ADDRESS(x) \ (((x) - MX51_DEBUG_BASE_ADDR) + MX51_DEBUG_BASE_ADDR_VIRT) -- cgit v0.10.2 From 5443856cadac7faaaeefeed9d769f497a8c6fa4b Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 19 Mar 2010 10:50:55 +0100 Subject: i.MX51: determine silicon revision dynamically Freescale redboot passes the silicon revision via ATAG_REVISION. Remove this bootloader dependency by doing the same as redboot does in the Kernel. Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx5/cpu.c b/arch/arm/mach-mx5/cpu.c index 41c769f..2d37785 100644 --- a/arch/arm/mach-mx5/cpu.c +++ b/arch/arm/mach-mx5/cpu.c @@ -14,9 +14,62 @@ #include #include #include +#include #include #include +static int cpu_silicon_rev = -1; + +#define SI_REV 0x48 + +static void query_silicon_parameter(void) +{ + void __iomem *rom = ioremap(MX51_IROM_BASE_ADDR, MX51_IROM_SIZE); + u32 rev; + + if (!rom) { + cpu_silicon_rev = -EINVAL; + return; + } + + rev = readl(rom + SI_REV); + switch (rev) { + case 0x1: + cpu_silicon_rev = MX51_CHIP_REV_1_0; + break; + case 0x2: + cpu_silicon_rev = MX51_CHIP_REV_1_1; + break; + case 0x10: + cpu_silicon_rev = MX51_CHIP_REV_2_0; + break; + case 0x20: + cpu_silicon_rev = MX51_CHIP_REV_3_0; + break; + default: + cpu_silicon_rev = 0; + } + + iounmap(rom); +} + +/* + * Returns: + * the silicon revision of the cpu + * -EINVAL - not a mx51 + */ +int mx51_revision(void) +{ + if (!cpu_is_mx51()) + return -EINVAL; + + if (cpu_silicon_rev == -1) + query_silicon_parameter(); + + return cpu_silicon_rev; +} +EXPORT_SYMBOL(mx51_revision); + static int __init post_cpu_init(void) { unsigned int reg; diff --git a/arch/arm/plat-mxc/include/mach/mx51.h b/arch/arm/plat-mxc/include/mach/mx51.h index f1396bd..fd255a9 100644 --- a/arch/arm/plat-mxc/include/mach/mx51.h +++ b/arch/arm/plat-mxc/include/mach/mx51.h @@ -28,6 +28,12 @@ */ /* + * IROM + */ +#define MX51_IROM_BASE_ADDR 0x0 +#define MX51_IROM_SIZE SZ_64K + +/* * IRAM */ #define MX51_IRAM_BASE_ADDR 0x1FFE0000 /* internal ram */ @@ -438,12 +444,7 @@ #if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS) -extern unsigned int system_rev; - -static inline unsigned int mx51_revision(void) -{ - return system_rev; -} +extern int mx51_revision(void); #endif #endif /* __ASM_ARCH_MXC_MX51_H__ */ -- cgit v0.10.2 From fc300206ad07e771ed003d35b1dc179eaf0c508f Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 19 Mar 2010 11:12:02 +0100 Subject: i.MX51: remove NFC AXI static mapping This area contains the Nand Flash controller registers. There is no need to map them statically as the Nand driver uses ioremap(). Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx5/mm.c b/arch/arm/mach-mx5/mm.c index 9fe7beb..b7677ef 100644 --- a/arch/arm/mach-mx5/mm.c +++ b/arch/arm/mach-mx5/mm.c @@ -49,11 +49,6 @@ static struct map_desc mxc_io_desc[] __initdata = { .pfn = __phys_to_pfn(MX51_AIPS2_BASE_ADDR), .length = MX51_AIPS2_SIZE, .type = MT_DEVICE - }, { - .virtual = MX51_NFC_AXI_BASE_ADDR_VIRT, - .pfn = __phys_to_pfn(MX51_NFC_AXI_BASE_ADDR), - .length = MX51_NFC_AXI_SIZE, - .type = MT_DEVICE }, }; diff --git a/arch/arm/plat-mxc/include/mach/mx51.h b/arch/arm/plat-mxc/include/mach/mx51.h index fd255a9..5aad344 100644 --- a/arch/arm/plat-mxc/include/mach/mx51.h +++ b/arch/arm/plat-mxc/include/mach/mx51.h @@ -23,7 +23,7 @@ * C8000000 64M CS3 Flash * CC000000 32M CS4 SRAM * CE000000 32M CS5 SRAM - * F9000000 CFFF0000 64K NFC (NAND Flash AXI) + * CFFF0000 64K NFC (NAND Flash AXI) * */ @@ -46,7 +46,6 @@ * NFC */ #define MX51_NFC_AXI_BASE_ADDR 0xCFFF0000 /* NAND flash AXI */ -#define MX51_NFC_AXI_BASE_ADDR_VIRT 0xF9000000 #define MX51_NFC_AXI_SIZE SZ_64K /* @@ -240,8 +239,7 @@ MX51_IS_MODULE(x, DEBUG) ? MX51_DEBUG_IO_ADDRESS(x) : \ MX51_IS_MODULE(x, SPBA0) ? MX51_SPBA0_IO_ADDRESS(x) : \ MX51_IS_MODULE(x, AIPS1) ? MX51_AIPS1_IO_ADDRESS(x) : \ - MX51_IS_MODULE(x, AIPS2) ? MX51_AIPS2_IO_ADDRESS(x) : \ - MX51_IS_MODULE(x, NFC_AXI) ? MX51_NFC_AXI_IO_ADDRESS(x) : \ + MX51_IS_MODULE(x, AIPS2) ? MX51_AIPS2_IO_ADDRESS(x) : \ 0xDEADBEEF) /* @@ -262,9 +260,6 @@ #define MX51_AIPS2_IO_ADDRESS(x) \ (((x) - MX51_AIPS2_BASE_ADDR) + MX51_AIPS2_BASE_ADDR_VIRT) -#define MX51_NFC_AXI_IO_ADDRESS(x) \ - (((x) - MX51_NFC_AXI_BASE_ADDR) + MX51_NFC_AXI_BASE_ADDR_VIRT) - #define MX51_IS_MEM_DEVICE_NONSHARED(x) 0 /* -- cgit v0.10.2 From 44f497b4e0bba6ce1b73a107cc13636393344252 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 19 Mar 2010 11:10:19 +0200 Subject: ASoC: tlv320dac33: Fix DSP modes To make DSP_A mode working correctly the data delay should be configured to 0. DSP_B mode thus can not be used with DAC33, so remove it. Signed-off-by: Peter Ujfalusi Acked-by: Liam Girdwood Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index f9f367d..00d6f36 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c @@ -1038,11 +1038,7 @@ static int dac33_set_dai_fmt(struct snd_soc_dai *codec_dai, case SND_SOC_DAIFMT_DSP_A: aictrl_a |= DAC33_AFMT_DSP; aictrl_b &= ~DAC33_DATA_DELAY_MASK; - aictrl_b |= DAC33_DATA_DELAY(1); /* 1 bit delay */ - break; - case SND_SOC_DAIFMT_DSP_B: - aictrl_a |= DAC33_AFMT_DSP; - aictrl_b &= ~DAC33_DATA_DELAY_MASK; /* No delay */ + aictrl_b |= DAC33_DATA_DELAY(0); break; case SND_SOC_DAIFMT_RIGHT_J: aictrl_a |= DAC33_AFMT_RIGHT_J; -- cgit v0.10.2 From fdb6b1e195757a66670801702e4b5fcc66ed3d72 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 19 Mar 2010 11:10:20 +0200 Subject: ASoC: tlv320dac33: Internal clocking changes During validation of the internal clocking setup it has been found that the following settings were not configured in an optimal way: ASRC_CTRL_A: SRCLKDIV was incorrect, instad of divide ratio 3, ratio of 2 has to be used (as the comment stated) DAC_CTRL_A: Fs = Fsref is the desired configuration instead of Fs = Fsref / 1.5 Signed-off-by: Peter Ujfalusi Acked-by: Liam Girdwood Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index 00d6f36..d50f169 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c @@ -778,7 +778,7 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream) if (dac33->fifo_mode) { /* Generic for all FIFO modes */ /* 50-51 : ASRC Control registers */ - dac33_write(codec, DAC33_ASRC_CTRL_A, (1 << 4)); /* div=2 */ + dac33_write(codec, DAC33_ASRC_CTRL_A, DAC33_SRCLKDIV(1)); dac33_write(codec, DAC33_ASRC_CTRL_B, 1); /* ??? */ /* Write registers 0x34 and 0x35 (MSB, LSB) */ @@ -1062,7 +1062,7 @@ static void dac33_init_chip(struct snd_soc_codec *codec) { /* 44-46: DAC Control Registers */ /* A : DAC sample rate Fsref/1.5 */ - dac33_write(codec, DAC33_DAC_CTRL_A, DAC33_DACRATE(1)); + dac33_write(codec, DAC33_DAC_CTRL_A, DAC33_DACRATE(0)); /* B : DAC src=normal, not muted */ dac33_write(codec, DAC33_DAC_CTRL_B, DAC33_DACSRCR_RIGHT | DAC33_DACSRCL_LEFT); -- cgit v0.10.2 From 6937c947d31186750f72c9f8c942bbcc6fe63585 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 18 Mar 2010 12:25:35 +0000 Subject: ASoC: Bail out of wm_hubs DC servo if calibration fails We're keeping track of the number of times we've iterated but never actually using this to bail out if the chip looks stuck. Signed-off-by: Mark Brown Acked-by: Liam Girdwood diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index 0ad9f5d..486bdd2 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c @@ -74,7 +74,7 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec) msleep(1); reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_0); dev_dbg(codec->dev, "DC servo: %x\n", reg); - } while (reg & WM8993_DCS_DATAPATH_BUSY); + } while (reg & WM8993_DCS_DATAPATH_BUSY && count < 400); if (reg & WM8993_DCS_DATAPATH_BUSY) dev_err(codec->dev, "Timed out waiting for DC Servo\n"); -- cgit v0.10.2 From e1955ca0ee55286cbc65a8ed7471d540ae83dac8 Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Tue, 9 Mar 2010 19:30:28 +0100 Subject: sysfs: use sysfs_bin_attr_init in firmware class driver Annotate dynamic sysfs attribute in fw_setup_device(). This gets rid of the following lockdep warning: bnx2 0000:08:00.0: firmware: requesting bnx2/bnx2-mips-06-5.0.0.j6.fw BUG: key ffff880008293470 not in .data! ------------[ cut here ]------------ WARNING: at kernel/lockdep.c:2706 lockdep_init_map+0x562/0x620() Modules linked in: bnx2(+) sg tpm_bios floppy rtc_lib usb_storage i2c_piix4 joydev button container shpchp i2c_core sr_mod cdrom pci_hotplug usbhid hid ohci_hcd ehci_hcd sd_mod usbcore edd ext3 mbcache jbd fan ata_generic sata_svw pata_serverworks libata scsi_mod thermal processor Pid: 1915, comm: work_for_cpu Not tainted 2.6.34-rc1-default #81 Call Trace: [] ? lockdep_init_map+0x562/0x620 [] warn_slowpath_common+0x78/0xd0 [] warn_slowpath_null+0xf/0x20 [] lockdep_init_map+0x562/0x620 [] ? sysfs_new_dirent+0x76/0x120 [] ? put_device+0x12/0x20 [] sysfs_add_file_mode+0x6c/0xd0 [] sysfs_add_file+0xc/0x10 [] sysfs_create_bin_file+0x21/0x30 [] _request_firmware+0x2f1/0x650 [] request_firmware+0xe/0x10 [] bnx2_init_one+0x8f5/0x177e [bnx2] [] ? _raw_spin_unlock_irq+0x2b/0x40 [] ? finish_task_switch+0x69/0x100 [] ? finish_task_switch+0x0/0x100 [] ? do_work_for_cpu+0x0/0x30 [] local_pci_probe+0x12/0x20 [] do_work_for_cpu+0x13/0x30 [] ? do_work_for_cpu+0x0/0x30 [] kthread+0x96/0xa0 [] kernel_thread_helper+0x4/0x10 [] ? restore_args+0x0/0x30 [] ? kthread+0x0/0xa0 [] ? kernel_thread_helper+0x0/0x10 ---[ end trace a2ecee9c9602d195 ]--- Cc: Eric W. Biederman Cc: Greg Kroah-Hartman Signed-off-by: Jiri Kosina Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index d0dc26a..fc7565c 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -442,6 +442,7 @@ static int fw_setup_device(struct firmware *fw, struct device **dev_p, fw_priv = dev_get_drvdata(f_dev); fw_priv->fw = fw; + sysfs_bin_attr_init(&fw_priv->attr_data); retval = sysfs_create_bin_file(&f_dev->kobj, &fw_priv->attr_data); if (retval) { dev_err(device, "%s: sysfs_create_bin_file failed\n", __func__); -- cgit v0.10.2 From 6757eca348fbbdd4ab1020e565f325cd6a6b2698 Mon Sep 17 00:00:00 2001 From: Mel Gorman Date: Wed, 10 Mar 2010 22:48:34 +0000 Subject: sysfs: Initialised pci bus legacy_mem field before use PPC64 is failing to boot the latest mmotm due to an uninitialised pointer in pci_create_legacy_files(). The surprise is that machines boot at all and it would appear to affect current mainline as well. This patch fixes the problem. Signed-off-by: Mel Gorman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index de29645..9976685 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -655,8 +655,8 @@ void pci_create_legacy_files(struct pci_bus *b) goto legacy_io_err; /* Allocated above after the legacy_io struct */ - sysfs_bin_attr_init(b->legacy_mem); b->legacy_mem = b->legacy_io + 1; + sysfs_bin_attr_init(b->legacy_mem); b->legacy_mem->attr.name = "legacy_mem"; b->legacy_mem->size = 1024*1024; b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR; -- cgit v0.10.2 From c7df670bf702d1c25ae22b4cd49deb05c1e55ecc Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 15 Mar 2010 13:59:51 -0700 Subject: sysfs: fix sysfs lockdep warning in ipmi code This fixes a sysfs lockdep warning in the ipmi code. Thanks to Eric Biederman and Yinghai Lu for the original versions of the patch, unfortunatly they did not submit them in a form they could be applied in. Cc: Yinghai Lu Cc: Eric Biederman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index ec5e3f8..c6ad423 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -2272,42 +2272,52 @@ static int create_files(struct bmc_device *bmc) bmc->device_id_attr.attr.name = "device_id"; bmc->device_id_attr.attr.mode = S_IRUGO; bmc->device_id_attr.show = device_id_show; + sysfs_attr_init(&bmc->device_id_attr.attr); bmc->provides_dev_sdrs_attr.attr.name = "provides_device_sdrs"; bmc->provides_dev_sdrs_attr.attr.mode = S_IRUGO; bmc->provides_dev_sdrs_attr.show = provides_dev_sdrs_show; + sysfs_attr_init(&bmc->provides_dev_sdrs_attr.attr); bmc->revision_attr.attr.name = "revision"; bmc->revision_attr.attr.mode = S_IRUGO; bmc->revision_attr.show = revision_show; + sysfs_attr_init(&bmc->revision_attr.attr); bmc->firmware_rev_attr.attr.name = "firmware_revision"; bmc->firmware_rev_attr.attr.mode = S_IRUGO; bmc->firmware_rev_attr.show = firmware_rev_show; + sysfs_attr_init(&bmc->firmware_rev_attr.attr); bmc->version_attr.attr.name = "ipmi_version"; bmc->version_attr.attr.mode = S_IRUGO; bmc->version_attr.show = ipmi_version_show; + sysfs_attr_init(&bmc->version_attr.attr); bmc->add_dev_support_attr.attr.name = "additional_device_support"; bmc->add_dev_support_attr.attr.mode = S_IRUGO; bmc->add_dev_support_attr.show = add_dev_support_show; + sysfs_attr_init(&bmc->add_dev_support_attr.attr); bmc->manufacturer_id_attr.attr.name = "manufacturer_id"; bmc->manufacturer_id_attr.attr.mode = S_IRUGO; bmc->manufacturer_id_attr.show = manufacturer_id_show; + sysfs_attr_init(&bmc->manufacturer_id_attr.attr); bmc->product_id_attr.attr.name = "product_id"; bmc->product_id_attr.attr.mode = S_IRUGO; bmc->product_id_attr.show = product_id_show; + sysfs_attr_init(&bmc->product_id_attr.attr); bmc->guid_attr.attr.name = "guid"; bmc->guid_attr.attr.mode = S_IRUGO; bmc->guid_attr.show = guid_show; + sysfs_attr_init(&bmc->guid_attr.attr); bmc->aux_firmware_rev_attr.attr.name = "aux_firmware_revision"; bmc->aux_firmware_rev_attr.attr.mode = S_IRUGO; bmc->aux_firmware_rev_attr.show = aux_firmware_rev_show; + sysfs_attr_init(&bmc->aux_firmware_rev_attr.attr); err = device_create_file(&bmc->dev->dev, &bmc->device_id_attr); -- cgit v0.10.2 From 21e3bde964e873bb5d3b1dfef68294b1437fe678 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 15 Mar 2010 14:01:25 -0700 Subject: sysfs: fix sysfs lockdep warning in infiniband code This fixes a sysfs lockdep warning in the infiniband code. Cc: Yinghai Lu Cc: Eric Biederman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c index 1558bb7..f901957 100644 --- a/drivers/infiniband/core/sysfs.c +++ b/drivers/infiniband/core/sysfs.c @@ -461,6 +461,7 @@ alloc_group_attrs(ssize_t (*show)(struct ib_port *, element->attr.attr.mode = S_IRUGO; element->attr.show = show; element->index = i; + sysfs_attr_init(&element->attr.attr); tab_attr[i] = &element->attr.attr; } -- cgit v0.10.2 From 3691c964fa1a8f0eb5e5f00c644ef1bdd7e35a95 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 15 Mar 2010 14:01:55 -0700 Subject: sysfs: fix sysfs lockdep warning in mlx4 code This fixes a sysfs lockdep warning in the mlx4 code. Cc: Yinghai Lu Cc: Eric Biederman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c index 8f6e816..b402a95 100644 --- a/drivers/net/mlx4/main.c +++ b/drivers/net/mlx4/main.c @@ -1023,6 +1023,7 @@ static int mlx4_init_port_info(struct mlx4_dev *dev, int port) info->port_attr.attr.mode = S_IRUGO | S_IWUSR; info->port_attr.show = show_port_type; info->port_attr.store = set_port_type; + sysfs_attr_init(&info->port_attr.attr); err = device_create_file(&dev->pdev->dev, &info->port_attr); if (err) { -- cgit v0.10.2 From 4d26e139f0b7d4c0700d6993506f1f60e2f2caa5 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 10 Mar 2010 20:50:38 +0900 Subject: Driver core: Early platform kernel-doc update This patch updates the kernel-doc notation for early platform functions. Signed-off-by: Magnus Damm Acked-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 1ba9d617..f6bcf22 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -1052,9 +1052,11 @@ static __initdata LIST_HEAD(early_platform_driver_list); static __initdata LIST_HEAD(early_platform_device_list); /** - * early_platform_driver_register + * early_platform_driver_register - register early platform driver * @epdrv: early_platform driver structure * @buf: string passed from early_param() + * + * Helper function for early_platform_init() / early_platform_init_buffer() */ int __init early_platform_driver_register(struct early_platform_driver *epdrv, char *buf) @@ -1106,9 +1108,12 @@ int __init early_platform_driver_register(struct early_platform_driver *epdrv, } /** - * early_platform_add_devices - add a numbers of early platform devices + * early_platform_add_devices - adds a number of early platform devices * @devs: array of early platform devices to add * @num: number of early platform devices in array + * + * Used by early architecture code to register early platform devices and + * their platform data. */ void __init early_platform_add_devices(struct platform_device **devs, int num) { @@ -1128,8 +1133,12 @@ void __init early_platform_add_devices(struct platform_device **devs, int num) } /** - * early_platform_driver_register_all + * early_platform_driver_register_all - register early platform drivers * @class_str: string to identify early platform driver class + * + * Used by architecture code to register all early platform drivers + * for a certain class. If omitted then only early platform drivers + * with matching kernel command line class parameters will be registered. */ void __init early_platform_driver_register_all(char *class_str) { @@ -1151,7 +1160,7 @@ void __init early_platform_driver_register_all(char *class_str) } /** - * early_platform_match + * early_platform_match - find early platform device matching driver * @epdrv: early platform driver structure * @id: id to match against */ @@ -1169,7 +1178,7 @@ early_platform_match(struct early_platform_driver *epdrv, int id) } /** - * early_platform_left + * early_platform_left - check if early platform driver has matching devices * @epdrv: early platform driver structure * @id: return true if id or above exists */ @@ -1187,7 +1196,7 @@ static __init int early_platform_left(struct early_platform_driver *epdrv, } /** - * early_platform_driver_probe_id + * early_platform_driver_probe_id - probe drivers matching class_str and id * @class_str: string to identify early platform driver class * @id: id to match against * @nr_probe: number of platform devices to successfully probe before exiting @@ -1257,10 +1266,14 @@ static int __init early_platform_driver_probe_id(char *class_str, } /** - * early_platform_driver_probe + * early_platform_driver_probe - probe a class of registered drivers * @class_str: string to identify early platform driver class * @nr_probe: number of platform devices to successfully probe before exiting * @user_only: only probe user specified early platform devices + * + * Used by architecture code to probe registered early platform drivers + * within a certain class. For probe to happen a registered early platform + * device matching a registered early platform driver is needed. */ int __init early_platform_driver_probe(char *class_str, int nr_probe, -- cgit v0.10.2 From e59817bf089a3893e05a059026c668fb65f8c748 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 10 Mar 2010 11:47:58 -0800 Subject: driver-core: fix missing kernel-doc in firmware_class Fix kernel-doc warning in firmware_class.c: Warning(drivers/base/firmware_class.c:94): No description found for parameter 'attr' Signed-off-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index fc7565c..18518ba 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -78,6 +78,7 @@ firmware_timeout_show(struct class *class, /** * firmware_timeout_store - set number of seconds to wait for firmware * @class: device class pointer + * @attr: device attribute pointer * @buf: buffer to scan for timeout value * @count: number of bytes in @buf * -- cgit v0.10.2 From 462bd295a3d74c7d1641501bda549bccf404be5b Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Thu, 11 Mar 2010 07:59:09 -0500 Subject: kobject: documentation: Fix erroneous example in kobject doc. Replace uio_mem example for kobjects with uio_map, since the uio_mem struct no longer contains a kobject. Signed-off-by: Robert P. J. Day Signed-off-by: Greg Kroah-Hartman diff --git a/Documentation/kobject.txt b/Documentation/kobject.txt index bdb1381..668cb83 100644 --- a/Documentation/kobject.txt +++ b/Documentation/kobject.txt @@ -59,37 +59,56 @@ nice to have in other objects. The C language does not allow for the direct expression of inheritance, so other techniques - such as structure embedding - must be used. -So, for example, the UIO code has a structure that defines the memory -region associated with a uio device: +(As an aside, for those familiar with the kernel linked list implementation, +this is analogous as to how "list_head" structs are rarely useful on +their own, but are invariably found embedded in the larger objects of +interest.) -struct uio_mem { +So, for example, the UIO code in drivers/uio/uio.c has a structure that +defines the memory region associated with a uio device: + + struct uio_map { struct kobject kobj; - unsigned long addr; - unsigned long size; - int memtype; - void __iomem *internal_addr; -}; + struct uio_mem *mem; + }; -If you have a struct uio_mem structure, finding its embedded kobject is +If you have a struct uio_map structure, finding its embedded kobject is just a matter of using the kobj member. Code that works with kobjects will often have the opposite problem, however: given a struct kobject pointer, what is the pointer to the containing structure? You must avoid tricks (such as assuming that the kobject is at the beginning of the structure) and, instead, use the container_of() macro, found in : - container_of(pointer, type, member) + container_of(pointer, type, member) + +where: + + * "pointer" is the pointer to the embedded kobject, + * "type" is the type of the containing structure, and + * "member" is the name of the structure field to which "pointer" points. + +The return value from container_of() is a pointer to the corresponding +container type. So, for example, a pointer "kp" to a struct kobject +embedded *within* a struct uio_map could be converted to a pointer to the +*containing* uio_map structure with: + + struct uio_map *u_map = container_of(kp, struct uio_map, kobj); + +For convenience, programmers often define a simple macro for "back-casting" +kobject pointers to the containing type. Exactly this happens in the +earlier drivers/uio/uio.c, as you can see here: + + struct uio_map { + struct kobject kobj; + struct uio_mem *mem; + }; -where pointer is the pointer to the embedded kobject, type is the type of -the containing structure, and member is the name of the structure field to -which pointer points. The return value from container_of() is a pointer to -the given type. So, for example, a pointer "kp" to a struct kobject -embedded within a struct uio_mem could be converted to a pointer to the -containing uio_mem structure with: + #define to_map(map) container_of(map, struct uio_map, kobj) - struct uio_mem *u_mem = container_of(kp, struct uio_mem, kobj); +where the macro argument "map" is a pointer to the struct kobject in +question. That macro is subsequently invoked with: -Programmers often define a simple macro for "back-casting" kobject pointers -to the containing type. + struct uio_map *map = to_map(kobj); Initialization of kobjects -- cgit v0.10.2 From 67fc233f4fb67907861b4077cea5294035f80dc7 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 16 Mar 2010 10:33:32 +1100 Subject: sysdev: the cpu probe/release attributes should be sysdev_class_attributes This fixes these warnings: drivers/base/cpu.c:264: warning: initialization from incompatible pointer type drivers/base/cpu.c:265: warning: initialization from incompatible pointer type Cc: Andi Kleen Signed-off-by: Stephen Rothwell Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 7036e8e..b5242e1 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -79,24 +79,24 @@ void unregister_cpu(struct cpu *cpu) } #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE -static ssize_t cpu_probe_store(struct sys_device *dev, - struct sysdev_attribute *attr, - const char *buf, +static ssize_t cpu_probe_store(struct sysdev_class *class, + struct sysdev_class_attribute *attr, + const char *buf, size_t count) { return arch_cpu_probe(buf, count); } -static ssize_t cpu_release_store(struct sys_device *dev, - struct sysdev_attribute *attr, - const char *buf, +static ssize_t cpu_release_store(struct sysdev_class *class, + struct sysdev_class_attribute *attr, + const char *buf, size_t count) { return arch_cpu_release(buf, count); } -static SYSDEV_ATTR(probe, S_IWUSR, NULL, cpu_probe_store); -static SYSDEV_ATTR(release, S_IWUSR, NULL, cpu_release_store); +static SYSDEV_CLASS_ATTR(probe, S_IWUSR, NULL, cpu_probe_store); +static SYSDEV_CLASS_ATTR(release, S_IWUSR, NULL, cpu_release_store); #endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */ #else /* ... !CONFIG_HOTPLUG_CPU */ -- cgit v0.10.2 From 178a5b35b2777346206d4b577b36d10061732f8c Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Fri, 12 Mar 2010 07:30:35 -0500 Subject: kobject: documentation: Update to refer to kset-example.c. Signed-off-by: Robert P. J. Day Signed-off-by: Greg Kroah-Hartman diff --git a/Documentation/kobject.txt b/Documentation/kobject.txt index 668cb83..3ab2472 100644 --- a/Documentation/kobject.txt +++ b/Documentation/kobject.txt @@ -406,4 +406,5 @@ called, and the objects in the former circle release each other. Example code to copy from For a more complete example of using ksets and kobjects properly, see the -sample/kobject/kset-example.c code. +example programs samples/kobject/{kobject-example.c,kset-example.c}, +which will be built as loadable modules if you select CONFIG_SAMPLE_KOBJECT. -- cgit v0.10.2 From f0eae0ed3b7d4182a6b4dd03540a738518ea3163 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 11 Mar 2010 18:11:45 +0200 Subject: driver-core: document ERR_PTR() return values A number of functions in the driver core return ERR_PTR() values on error. Document this in the kernel-doc of the functions. Signed-off-by: Jani Nikula Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/base/class.c b/drivers/base/class.c index 0147f47..9c6a0d6 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c @@ -219,6 +219,8 @@ static void class_create_release(struct class *cls) * This is used to create a struct class pointer that can then be used * in calls to device_create(). * + * Returns &struct class pointer on success, or ERR_PTR() on error. + * * Note, the pointer created here is to be destroyed when finished by * making a call to class_destroy(). */ diff --git a/drivers/base/core.c b/drivers/base/core.c index ef55df3..b56a0ba 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -1345,6 +1345,8 @@ static void root_device_release(struct device *dev) * 'module' symlink which points to the @owner directory * in sysfs. * + * Returns &struct device pointer on success, or ERR_PTR() on error. + * * Note: You probably want to use root_device_register(). */ struct device *__root_device_register(const char *name, struct module *owner) @@ -1432,6 +1434,8 @@ static void device_create_release(struct device *dev) * Any further sysfs files that might be required can be created using this * pointer. * + * Returns &struct device pointer on success, or ERR_PTR() on error. + * * Note: the struct class passed to this function must have previously * been created with a call to class_create(). */ @@ -1492,6 +1496,8 @@ EXPORT_SYMBOL_GPL(device_create_vargs); * Any further sysfs files that might be required can be created using this * pointer. * + * Returns &struct device pointer on success, or ERR_PTR() on error. + * * Note: the struct class passed to this function must have previously * been created with a call to class_create(). */ diff --git a/drivers/base/platform.c b/drivers/base/platform.c index f6bcf22..4b4b565 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -362,6 +362,8 @@ EXPORT_SYMBOL_GPL(platform_device_unregister); * enumeration tasks, they don't fully conform to the Linux driver model. * In particular, when such drivers are built as modules, they can't be * "hotplugged". + * + * Returns &struct platform_device pointer on success, or ERR_PTR() on error. */ struct platform_device *platform_device_register_simple(const char *name, int id, @@ -408,6 +410,8 @@ EXPORT_SYMBOL_GPL(platform_device_register_simple); * allocated for the device allows drivers using such devices to be * unloaded without waiting for the last reference to the device to be * dropped. + * + * Returns &struct platform_device pointer on success, or ERR_PTR() on error. */ struct platform_device *platform_device_register_data( struct device *parent, @@ -559,6 +563,8 @@ EXPORT_SYMBOL_GPL(platform_driver_probe); * * Use this in legacy-style modules that probe hardware directly and * register a single platform device and corresponding platform driver. + * + * Returns &struct platform_device pointer on success, or ERR_PTR() on error. */ struct platform_device * __init_or_module platform_create_bundle( struct platform_driver *driver, -- cgit v0.10.2 From 12ee3c0a0ac42bed0939420468fd35f5cdceae4f Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Wed, 10 Mar 2010 14:50:21 -0800 Subject: driver core: numa: fix BUILD_BUG_ON for node_read_distance node_read_distance() has a BUILD_BUG_ON() to prevent buffer overruns when the number of nodes printed will exceed the buffer length. Each node only needs four chars: three for distance (maximum distance is 255) and one for a seperating space or a trailing newline. Signed-off-by: David Rientjes Cc: Ingo Molnar Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/base/node.c b/drivers/base/node.c index ad43185..93b3ac6 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c @@ -165,8 +165,11 @@ static ssize_t node_read_distance(struct sys_device * dev, int len = 0; int i; - /* buf currently PAGE_SIZE, need ~4 chars per node */ - BUILD_BUG_ON(MAX_NUMNODES*4 > PAGE_SIZE/2); + /* + * buf is currently PAGE_SIZE in length and each node needs 4 chars + * at the most (distance + space or newline). + */ + BUILD_BUG_ON(MAX_NUMNODES * 4 > PAGE_SIZE); for_each_online_node(i) len += sprintf(buf + len, "%s%d", i ? " " : "", node_distance(nid, i)); -- cgit v0.10.2 From 87a6aca504d65f242589583e04df5e74b5eae1fe Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 15 Mar 2010 17:14:15 -0700 Subject: Revert "tty: Add a new VT mode which is like VT_PROCESS but doesn't require a VT_RELDISP ioctl call" This reverts commit eec9fe7d1ab4a0dfac4cb43047a7657fffd0002f. Ari writes as the reason this should be reverted: The problems with this patch include: 1. There's at least one subtlety I overlooked - switching between X servers (i.e. from one X VT to another) still requires the cooperation of both X servers. I was assuming that KMS eliminated this. 2. It hasn't been tested at all (no X server patch exists which uses the new mode). As he was the original author of the patch, I'll revert it. Cc: Ari Entlich Cc: Alan Cox Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index 87778dc..6aa1028 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c @@ -888,7 +888,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, ret = -EFAULT; goto out; } - if (tmp.mode != VT_AUTO && tmp.mode != VT_PROCESS && tmp.mode != VT_PROCESS_AUTO) { + if (tmp.mode != VT_AUTO && tmp.mode != VT_PROCESS) { ret = -EINVAL; goto out; } @@ -1622,7 +1622,7 @@ static void complete_change_console(struct vc_data *vc) * telling it that it has acquired. Also check if it has died and * clean up (similar to logic employed in change_console()) */ - if (vc->vt_mode.mode == VT_PROCESS || vc->vt_mode.mode == VT_PROCESS_AUTO) { + if (vc->vt_mode.mode == VT_PROCESS) { /* * Send the signal as privileged - kill_pid() will * tell us if the process has gone or something else @@ -1682,7 +1682,7 @@ void change_console(struct vc_data *new_vc) * vt to auto control. */ vc = vc_cons[fg_console].d; - if (vc->vt_mode.mode == VT_PROCESS || vc->vt_mode.mode == VT_PROCESS_AUTO) { + if (vc->vt_mode.mode == VT_PROCESS) { /* * Send the signal as privileged - kill_pid() will * tell us if the process has gone or something else @@ -1693,28 +1693,27 @@ void change_console(struct vc_data *new_vc) */ vc->vt_newvt = new_vc->vc_num; if (kill_pid(vc->vt_pid, vc->vt_mode.relsig, 1) == 0) { - if(vc->vt_mode.mode == VT_PROCESS) - /* - * It worked. Mark the vt to switch to and - * return. The process needs to send us a - * VT_RELDISP ioctl to complete the switch. - */ - return; - } else { /* - * The controlling process has died, so we revert back to - * normal operation. In this case, we'll also change back - * to KD_TEXT mode. I'm not sure if this is strictly correct - * but it saves the agony when the X server dies and the screen - * remains blanked due to KD_GRAPHICS! It would be nice to do - * this outside of VT_PROCESS but there is no single process - * to account for and tracking tty count may be undesirable. + * It worked. Mark the vt to switch to and + * return. The process needs to send us a + * VT_RELDISP ioctl to complete the switch. */ - reset_vc(vc); + return; } /* - * Fall through to normal (VT_AUTO and VT_PROCESS_AUTO) handling of the switch... + * The controlling process has died, so we revert back to + * normal operation. In this case, we'll also change back + * to KD_TEXT mode. I'm not sure if this is strictly correct + * but it saves the agony when the X server dies and the screen + * remains blanked due to KD_GRAPHICS! It would be nice to do + * this outside of VT_PROCESS but there is no single process + * to account for and tracking tty count may be undesirable. + */ + reset_vc(vc); + + /* + * Fall through to normal (VT_AUTO) handling of the switch... */ } diff --git a/include/linux/vt.h b/include/linux/vt.h index 778b7b2..d5dd0bc 100644 --- a/include/linux/vt.h +++ b/include/linux/vt.h @@ -27,7 +27,7 @@ struct vt_mode { #define VT_SETMODE 0x5602 /* set mode of active vt */ #define VT_AUTO 0x00 /* auto vt switching */ #define VT_PROCESS 0x01 /* process controls switching */ -#define VT_PROCESS_AUTO 0x02 /* process is notified of switching */ +#define VT_ACKACQ 0x02 /* acknowledge switch */ struct vt_stat { unsigned short v_active; /* active vt */ @@ -38,7 +38,6 @@ struct vt_stat { #define VT_SENDSIG 0x5604 /* signal to send to bitmask of vts */ #define VT_RELDISP 0x5605 /* release display */ -#define VT_ACKACQ 0x02 /* acknowledge switch */ #define VT_ACTIVATE 0x5606 /* make vt active */ #define VT_WAITACTIVE 0x5607 /* wait for vt active */ -- cgit v0.10.2 From 352fa6ad16b89f8ffd1a93b4419b1a8f2259feab Mon Sep 17 00:00:00 2001 From: Mel Gorman Date: Tue, 2 Mar 2010 22:24:19 +0000 Subject: tty: Take a 256 byte padding into account when buffering below sub-page units The TTY layer takes some care to ensure that only sub-page allocations are made with interrupts disabled. It does this by setting a goal of "TTY_BUFFER_PAGE" to allocate. Unfortunately, while TTY_BUFFER_PAGE takes the size of tty_buffer into account, it fails to account that tty_buffer_find() rounds the buffer size out to the next 256 byte boundary before adding on the size of the tty_buffer. This patch adjusts the TTY_BUFFER_PAGE calculation to take into account the size of the tty_buffer and the padding. Once applied, tty_buffer_alloc() should not require high-order allocations. Signed-off-by: Mel Gorman Cc: stable Signed-off-by: Greg Kroah-Hartman diff --git a/include/linux/tty.h b/include/linux/tty.h index 568369a..593228a 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -70,12 +70,13 @@ struct tty_buffer { /* * We default to dicing tty buffer allocations to this many characters - * in order to avoid multiple page allocations. We assume tty_buffer itself - * is under 256 bytes. See tty_buffer_find for the allocation logic this - * must match + * in order to avoid multiple page allocations. We know the size of + * tty_buffer itself but it must also be taken into account that the + * the buffer is 256 byte aligned. See tty_buffer_find for the allocation + * logic this must match */ -#define TTY_BUFFER_PAGE ((PAGE_SIZE - 256) / 2) +#define TTY_BUFFER_PAGE (((PAGE_SIZE - sizeof(struct tty_buffer)) / 2) & ~0xFF) struct tty_bufhead { -- cgit v0.10.2 From f157b58511e56d418eb582de96fedc4ea03d8061 Mon Sep 17 00:00:00 2001 From: David Miller Date: Wed, 3 Mar 2010 02:50:26 -0800 Subject: uartlite: Fix build on sparc. We can get this driver enabled via MFD_TIMBERDALE which only requires GPIO to be on. But the of_address_to_resource() function is only present on powerpc and microblaze, so we have to conditionalize the CONFIG_OF probing bits on that. Signed-off-by: David S. Miller Acked-by: Grant Likely Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c index ab2ab3c..f0a6c61 100644 --- a/drivers/serial/uartlite.c +++ b/drivers/serial/uartlite.c @@ -19,7 +19,7 @@ #include #include #include -#if defined(CONFIG_OF) +#if defined(CONFIG_OF) && (defined(CONFIG_PPC32) || defined(CONFIG_MICROBLAZE)) #include #include #include @@ -581,7 +581,7 @@ static struct platform_driver ulite_platform_driver = { /* --------------------------------------------------------------------- * OF bus bindings */ -#if defined(CONFIG_OF) +#if defined(CONFIG_OF) && (defined(CONFIG_PPC32) || defined(CONFIG_MICROBLAZE)) static int __devinit ulite_of_probe(struct of_device *op, const struct of_device_id *match) { @@ -631,11 +631,11 @@ static inline void __exit ulite_of_unregister(void) { of_unregister_platform_driver(&ulite_of_driver); } -#else /* CONFIG_OF */ -/* CONFIG_OF not enabled; do nothing helpers */ +#else /* CONFIG_OF && (CONFIG_PPC32 || CONFIG_MICROBLAZE) */ +/* Appropriate config not enabled; do nothing helpers */ static inline int __init ulite_of_register(void) { return 0; } static inline void __exit ulite_of_unregister(void) { } -#endif /* CONFIG_OF */ +#endif /* CONFIG_OF && (CONFIG_PPC32 || CONFIG_MICROBLAZE) */ /* --------------------------------------------------------------------- * Module setup/teardown -- cgit v0.10.2 From e74d098c66543d0731de62eb747ccd5b636a6f4c Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Fri, 12 Mar 2010 11:53:15 +0530 Subject: hvc_console: Fix race between hvc_close and hvc_remove Alan pointed out a race in the code where hvc_remove is invoked. The recent virtio_console work is the first user of hvc_remove(). Alan describes it thus: The hvc_console assumes that a close and remove call can't occur at the same time. In addition tty_hangup(tty) is problematic as tty_hangup is asynchronous itself.... So this can happen hvc_close hvc_remove hung up ? - no lock tty = hp->tty unlock lock hp->tty = NULL unlock notify del kref_put the hvc struct close completes tty is destroyed tty_hangup dead tty tty->ops will be NULL NULL->... This patch adds some tty krefs and also converts to using tty_vhangup(). Reported-by: Alan Cox Signed-off-by: Amit Shah CC: Alan Cox CC: linuxppc-dev@ozlabs.org CC: Rusty Russell Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index 465185f..ba55bba 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c @@ -312,6 +312,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp) spin_lock_irqsave(&hp->lock, flags); /* Check and then increment for fast path open. */ if (hp->count++ > 0) { + tty_kref_get(tty); spin_unlock_irqrestore(&hp->lock, flags); hvc_kick(); return 0; @@ -319,7 +320,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp) tty->driver_data = hp; - hp->tty = tty; + hp->tty = tty_kref_get(tty); spin_unlock_irqrestore(&hp->lock, flags); @@ -336,6 +337,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp) spin_lock_irqsave(&hp->lock, flags); hp->tty = NULL; spin_unlock_irqrestore(&hp->lock, flags); + tty_kref_put(tty); tty->driver_data = NULL; kref_put(&hp->kref, destroy_hvc_struct); printk(KERN_ERR "hvc_open: request_irq failed with rc %d.\n", rc); @@ -363,13 +365,18 @@ static void hvc_close(struct tty_struct *tty, struct file * filp) return; hp = tty->driver_data; + spin_lock_irqsave(&hp->lock, flags); + tty_kref_get(tty); if (--hp->count == 0) { /* We are done with the tty pointer now. */ hp->tty = NULL; spin_unlock_irqrestore(&hp->lock, flags); + /* Put the ref obtained in hvc_open() */ + tty_kref_put(tty); + if (hp->ops->notifier_del) hp->ops->notifier_del(hp, hp->data); @@ -389,6 +396,7 @@ static void hvc_close(struct tty_struct *tty, struct file * filp) spin_unlock_irqrestore(&hp->lock, flags); } + tty_kref_put(tty); kref_put(&hp->kref, destroy_hvc_struct); } @@ -424,10 +432,11 @@ static void hvc_hangup(struct tty_struct *tty) spin_unlock_irqrestore(&hp->lock, flags); if (hp->ops->notifier_hangup) - hp->ops->notifier_hangup(hp, hp->data); + hp->ops->notifier_hangup(hp, hp->data); while(temp_open_count) { --temp_open_count; + tty_kref_put(tty); kref_put(&hp->kref, destroy_hvc_struct); } } @@ -592,7 +601,7 @@ int hvc_poll(struct hvc_struct *hp) } /* No tty attached, just skip */ - tty = hp->tty; + tty = tty_kref_get(hp->tty); if (tty == NULL) goto bail; @@ -672,6 +681,8 @@ int hvc_poll(struct hvc_struct *hp) tty_flip_buffer_push(tty); } + if (tty) + tty_kref_put(tty); return poll_mask; } @@ -807,7 +818,7 @@ int hvc_remove(struct hvc_struct *hp) struct tty_struct *tty; spin_lock_irqsave(&hp->lock, flags); - tty = hp->tty; + tty = tty_kref_get(hp->tty); if (hp->index < MAX_NR_HVC_CONSOLES) vtermnos[hp->index] = -1; @@ -819,18 +830,18 @@ int hvc_remove(struct hvc_struct *hp) /* * We 'put' the instance that was grabbed when the kref instance * was initialized using kref_init(). Let the last holder of this - * kref cause it to be removed, which will probably be the tty_hangup + * kref cause it to be removed, which will probably be the tty_vhangup * below. */ kref_put(&hp->kref, destroy_hvc_struct); /* - * This function call will auto chain call hvc_hangup. The tty should - * always be valid at this time unless a simultaneous tty close already - * cleaned up the hvc_struct. + * This function call will auto chain call hvc_hangup. */ - if (tty) - tty_hangup(tty); + if (tty) { + tty_vhangup(tty); + tty_kref_put(tty); + } return 0; } EXPORT_SYMBOL_GPL(hvc_remove); -- cgit v0.10.2 From d4bee0a677cfa5a32f964ffa420e27406c65e605 Mon Sep 17 00:00:00 2001 From: Fang Wenqi Date: Tue, 9 Mar 2010 18:54:28 +0800 Subject: tty_buffer: Fix distinct type warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CC drivers/char/tty_buffer.o drivers/char/tty_buffer.c: In function ‘tty_insert_flip_string_fixed_flag’: drivers/char/tty_buffer.c:251: warning: comparison of distinct pointer types lacks a cast drivers/char/tty_buffer.c: In function ‘tty_insert_flip_string_flags’: drivers/char/tty_buffer.c:288: warning: comparison of distinct pointer types lacks a cast Fix it by replacing min() with min_t() in tty_insert_flip_string_flags and tty_insert_flip_string_fixed_flag(). Signed-off-by: Fang Wenqi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/char/tty_buffer.c b/drivers/char/tty_buffer.c index af8d977..7ee5216 100644 --- a/drivers/char/tty_buffer.c +++ b/drivers/char/tty_buffer.c @@ -248,7 +248,7 @@ int tty_insert_flip_string_fixed_flag(struct tty_struct *tty, { int copied = 0; do { - int goal = min(size - copied, TTY_BUFFER_PAGE); + int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE); int space = tty_buffer_request_room(tty, goal); struct tty_buffer *tb = tty->buf.tail; /* If there is no space then tb may be NULL */ @@ -285,7 +285,7 @@ int tty_insert_flip_string_flags(struct tty_struct *tty, { int copied = 0; do { - int goal = min(size - copied, TTY_BUFFER_PAGE); + int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE); int space = tty_buffer_request_room(tty, goal); struct tty_buffer *tb = tty->buf.tail; /* If there is no space then tb may be NULL */ -- cgit v0.10.2 From 231443665882a02214c3748b9f86615a3ce9e5c2 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Thu, 11 Mar 2010 14:08:18 -0800 Subject: tty: cpm_uart: use resource_size() Use the resource_size function instead of manually calculating the resource size. This reduces the chance of introducing off-by-one errors. Signed-off-by: Tobias Klauser Cc: Alan Cox Cc: Kumar Gala Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c index a9802e7..722eac1 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c +++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c @@ -61,7 +61,7 @@ void __iomem *cpm_uart_map_pram(struct uart_cpm_port *port, void __iomem *pram; unsigned long offset; struct resource res; - unsigned long len; + resource_size_t len; /* Don't remap parameter RAM if it has already been initialized * during console setup. @@ -74,7 +74,7 @@ void __iomem *cpm_uart_map_pram(struct uart_cpm_port *port, if (of_address_to_resource(np, 1, &res)) return NULL; - len = 1 + res.end - res.start; + len = resource_size(&res); pram = ioremap(res.start, len); if (!pram) return NULL; -- cgit v0.10.2 From 336cee42dd52824e360ab419eab4e8888eb054ec Mon Sep 17 00:00:00 2001 From: Jason Wessel Date: Mon, 8 Mar 2010 21:50:11 -0600 Subject: tty_port,usb-console: Fix usb serial console open/close regression Commit e1108a63e10d344284011cccc06328b2cd3e5da3 ("usb_serial: Use the shutdown() operation") breaks the ability to use a usb console starting in 2.6.33. This was observed when using console=ttyUSB0,115200 as a boot argument with an FTDI device. The error is: ftdi_sio ttyUSB0: ftdi_submit_read_urb - failed submitting read urb, error -22 The handling of the ASYNCB_INITIALIZED changed in 2.6.32 such that in tty_port_shutdown() it always clears the flag if it is set. The fix is to add a variable to the tty_port struct to indicate when the tty port is a console. CC: Alan Cox CC: Alan Stern CC: Oliver Neukum CC: Andrew Morton Signed-off-by: Jason Wessel Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c index be492dd..a3bd1d0 100644 --- a/drivers/char/tty_port.c +++ b/drivers/char/tty_port.c @@ -119,7 +119,7 @@ EXPORT_SYMBOL(tty_port_tty_set); static void tty_port_shutdown(struct tty_port *port) { mutex_lock(&port->mutex); - if (port->ops->shutdown && + if (port->ops->shutdown && !port->console && test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags)) port->ops->shutdown(port); mutex_unlock(&port->mutex); diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c index b22ac32..f347da2 100644 --- a/drivers/usb/serial/console.c +++ b/drivers/usb/serial/console.c @@ -181,6 +181,7 @@ static int usb_console_setup(struct console *co, char *options) /* The console is special in terms of closing the device so * indicate this port is now acting as a system console. */ port->console = 1; + port->port.console = 1; mutex_unlock(&serial->disc_mutex); return retval; diff --git a/include/linux/tty.h b/include/linux/tty.h index 593228a..4409967 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -224,6 +224,7 @@ struct tty_port { wait_queue_head_t close_wait; /* Close waiters */ wait_queue_head_t delta_msr_wait; /* Modem status change */ unsigned long flags; /* TTY flags ASY_*/ + unsigned char console:1; /* port is a console */ struct mutex mutex; /* Locking */ struct mutex buf_mutex; /* Buffer alloc lock */ unsigned char *xmit_buf; /* Optional buffer */ -- cgit v0.10.2 From 7152b592593b9d48b33f8997b1dfd6df9143f7ec Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Sat, 6 Mar 2010 15:04:03 -0500 Subject: USB: fix usbfs regression This patch (as1352) fixes a bug in the way isochronous input data is returned to userspace for usbfs transfers. The entire buffer must be copied, not just the first actual_length bytes, because the individual packets will be discontiguous if any of them are short. Reported-by: Markus Rechberger Signed-off-by: Alan Stern CC: stable Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index e909ff7..3466fdc 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -1207,6 +1207,13 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, free_async(as); return -ENOMEM; } + /* Isochronous input data may end up being discontiguous + * if some of the packets are short. Clear the buffer so + * that the gaps don't leak kernel data to userspace. + */ + if (is_in && uurb->type == USBDEVFS_URB_TYPE_ISO) + memset(as->urb->transfer_buffer, 0, + uurb->buffer_length); } as->urb->dev = ps->dev; as->urb->pipe = (uurb->type << 30) | @@ -1345,10 +1352,14 @@ static int processcompl(struct async *as, void __user * __user *arg) void __user *addr = as->userurb; unsigned int i; - if (as->userbuffer && urb->actual_length) - if (copy_to_user(as->userbuffer, urb->transfer_buffer, - urb->actual_length)) + if (as->userbuffer && urb->actual_length) { + if (urb->number_of_packets > 0) /* Isochronous */ + i = urb->transfer_buffer_length; + else /* Non-Isoc */ + i = urb->actual_length; + if (copy_to_user(as->userbuffer, urb->transfer_buffer, i)) goto err_out; + } if (put_user(as->status, &userurb->status)) goto err_out; if (put_user(urb->actual_length, &userurb->actual_length)) -- cgit v0.10.2 From 0ae1474367a15e1b65a9deed3a73a14475a419fc Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Sat, 27 Feb 2010 14:05:46 +0100 Subject: USB: serial: fix error message on close in generic driver Resubmitting read urb fails with -EPERM if completion handler runs while urb is being killed on close. This should not be reported as an error. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 89fac36..e560d1d 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -415,11 +415,13 @@ void usb_serial_generic_resubmit_read_urb(struct usb_serial_port *port, ((serial->type->read_bulk_callback) ? serial->type->read_bulk_callback : usb_serial_generic_read_bulk_callback), port); + result = usb_submit_urb(urb, mem_flags); - if (result) + if (result && result != -EPERM) { dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __func__, result); + } } EXPORT_SYMBOL_GPL(usb_serial_generic_resubmit_read_urb); -- cgit v0.10.2 From 6313620228624ff4dcb78b1dbd459d0c208df126 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Sat, 27 Feb 2010 14:06:07 +0100 Subject: USB: serial: fix softint not being called on errors Make sure usb_serial_port_softint is called on errors also when using multi urb writes. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index e560d1d..214bf25 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -500,23 +500,18 @@ void usb_serial_generic_write_bulk_callback(struct urb *urb) if (port->urbs_in_flight < 0) port->urbs_in_flight = 0; spin_unlock_irqrestore(&port->lock, flags); - - if (status) { - dbg("%s - nonzero multi-urb write bulk status " - "received: %d", __func__, status); - return; - } } else { port->write_urb_busy = 0; - if (status) { - dbg("%s - nonzero multi-urb write bulk status " - "received: %d", __func__, status); + if (status) kfifo_reset_out(&port->write_fifo); - } else + else usb_serial_generic_write_start(port); } + if (status) + dbg("%s - non-zero urb status: %d", __func__, status); + usb_serial_port_softint(port); } EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback); -- cgit v0.10.2 From eb8878a881c306ff3eab6e741ab8fc94096f4e1a Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Sat, 27 Feb 2010 16:24:49 +0100 Subject: USB: serial: use port endpoint size to determine if ep is available It is possible to have a multi-port device with a port lacking an in or out bulk endpoint. Only checking for num_bulk_in or num_bulk_out is thus not sufficient to determine whether a specific port has an in or out bulk endpoint. This fixes potential null pointer dereferences in the generic open and write routines, as well as access to uninitialised fifo in write_room and chars_in_buffer. Also let write fail with ENODEV (instead of 0) on missing out endpoint (also on zero-length writes). Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 214bf25..f804acb 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -130,7 +130,7 @@ int usb_serial_generic_open(struct tty_struct *tty, struct usb_serial_port *port spin_unlock_irqrestore(&port->lock, flags); /* if we have a bulk endpoint, start reading from it */ - if (serial->num_bulk_in) { + if (port->bulk_in_size) { /* Start reading from the device */ usb_fill_bulk_urb(port->read_urb, serial->dev, usb_rcvbulkpipe(serial->dev, @@ -159,10 +159,10 @@ static void generic_cleanup(struct usb_serial_port *port) dbg("%s - port %d", __func__, port->number); if (serial->dev) { - /* shutdown any bulk reads that might be going on */ - if (serial->num_bulk_out) + /* shutdown any bulk transfers that might be going on */ + if (port->bulk_out_size) usb_kill_urb(port->write_urb); - if (serial->num_bulk_in) + if (port->bulk_in_size) usb_kill_urb(port->read_urb); } } @@ -333,15 +333,15 @@ int usb_serial_generic_write(struct tty_struct *tty, dbg("%s - port %d", __func__, port->number); + /* only do something if we have a bulk out endpoint */ + if (!port->bulk_out_size) + return -ENODEV; + if (count == 0) { dbg("%s - write request of 0 bytes", __func__); return 0; } - /* only do something if we have a bulk out endpoint */ - if (!serial->num_bulk_out) - return 0; - if (serial->type->max_in_flight_urbs) return usb_serial_multi_urb_write(tty, port, buf, count); @@ -364,14 +364,19 @@ int usb_serial_generic_write_room(struct tty_struct *tty) int room = 0; dbg("%s - port %d", __func__, port->number); + + if (!port->bulk_out_size) + return 0; + spin_lock_irqsave(&port->lock, flags); if (serial->type->max_in_flight_urbs) { if (port->urbs_in_flight < serial->type->max_in_flight_urbs) room = port->bulk_out_size * (serial->type->max_in_flight_urbs - port->urbs_in_flight); - } else if (serial->num_bulk_out) + } else { room = kfifo_avail(&port->write_fifo); + } spin_unlock_irqrestore(&port->lock, flags); dbg("%s - returns %d", __func__, room); @@ -382,15 +387,18 @@ int usb_serial_generic_chars_in_buffer(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; struct usb_serial *serial = port->serial; - int chars = 0; unsigned long flags; + int chars; dbg("%s - port %d", __func__, port->number); + if (!port->bulk_out_size) + return 0; + spin_lock_irqsave(&port->lock, flags); if (serial->type->max_in_flight_urbs) chars = port->tx_bytes_flight; - else if (serial->num_bulk_out) + else chars = kfifo_len(&port->write_fifo); spin_unlock_irqrestore(&port->lock, flags); -- cgit v0.10.2 From cd0e8aa1f4d36ece677b8ecf270ba921843dc6ca Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Sat, 27 Feb 2010 22:56:28 +0100 Subject: USB: unusual_devs.h: Fix capacity for SL11R-IDE 2.6c SL11R-IDE 2.6c (at least) reports wrong capacity (one sector more). Reading that last sector causes the device not to work anymore (and looks like HAL or something does that automatically after plugging in): sd 5:0:0:0: [sdc] Device not ready sd 5:0:0:0: [sdc] Result: hostbyte=0x00 driverbyte=0x08 sd 5:0:0:0: [sdc] Sense Key : 0x2 [current] sd 5:0:0:0: [sdc] ASC=0x0 ASCQ=0x0 sd 5:0:0:0: [sdc] CDB: cdb[0]=0x28: 28 00 04 a8 b5 70 00 00 01 00 Add unusual_devs entry to fix the capacity. Signed-off-by: Ondrej Zary Signed-off-by: Phil Dibowitz Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 98b549b..61c8b9d 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -374,6 +374,15 @@ UNUSUAL_DEV( 0x04ce, 0x0002, 0x0074, 0x0074, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY), +/* Reported by Ondrej Zary + * The device reports one sector more and breaks when that sector is accessed + */ +UNUSUAL_DEV( 0x04ce, 0x0002, 0x026c, 0x026c, + "ScanLogic", + "SL11R-IDE", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY), + /* Reported by Kriston Fincher * Patch submitted by Sean Millichamp * This is to support the Panasonic PalmCam PV-SD4090 -- cgit v0.10.2 From bf162019b7f5bda9eb3241ae22de831df2126132 Mon Sep 17 00:00:00 2001 From: Huang Ying Date: Sun, 28 Feb 2010 13:51:29 +0800 Subject: USB: Option: Add support for a variant of DLink DWM 652 U5 I found a DLink DWM 652 U5 USB 3G modem has product ID 0xce1e instead of orignal 0xce16. The new ID is added. And I found there are two entries for 0xce16, one has raw number, the other has symbol DLINK_PRODUCT_DWM_652_U5. This is fixed too. Signed-off-by: Huang Ying Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 847b805..3ab1a04 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -309,6 +309,7 @@ static int option_resume(struct usb_serial *serial); #define DLINK_VENDOR_ID 0x1186 #define DLINK_PRODUCT_DWM_652 0x3e04 #define DLINK_PRODUCT_DWM_652_U5 0xce16 +#define DLINK_PRODUCT_DWM_652_U5A 0xce1e #define QISDA_VENDOR_ID 0x1da5 #define QISDA_PRODUCT_H21_4512 0x4512 @@ -659,6 +660,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, { USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5) }, /* Yes, ALINK_VENDOR_ID */ + { USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5A) }, { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4512) }, { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4523) }, { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4515) }, @@ -666,7 +668,6 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_G450) }, { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */ { USB_DEVICE(ALINK_VENDOR_ID, 0x9000) }, - { USB_DEVICE(ALINK_VENDOR_ID, 0xce16) }, { USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) }, { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S) }, { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) }, -- cgit v0.10.2 From 92bc3648e6027384479852b770a542722fadee7c Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 1 Mar 2010 09:12:50 +0100 Subject: USB: EHCI: fix ITD list order When isochronous URBs are shorter than one frame and when more than one ITD in a frame has been completed before the interrupt can be handled, scan_periodic() completes the URBs in the order in which they are found in the descriptor list. Therefore, the descriptor list must contain the ITDs in the correct order, i.e., a new ITD must be linked in after any previous ITDs of the same endpoint. This should fix garbled capture data in the USB audio drivers. Signed-off-by: Clemens Ladisch Reported-by: Colin Fletcher Cc: stable Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 39340ae..cd1e8bf 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -1565,13 +1565,27 @@ itd_patch( static inline void itd_link (struct ehci_hcd *ehci, unsigned frame, struct ehci_itd *itd) { - /* always prepend ITD/SITD ... only QH tree is order-sensitive */ - itd->itd_next = ehci->pshadow [frame]; - itd->hw_next = ehci->periodic [frame]; - ehci->pshadow [frame].itd = itd; + union ehci_shadow *prev = &ehci->pshadow[frame]; + __hc32 *hw_p = &ehci->periodic[frame]; + union ehci_shadow here = *prev; + __hc32 type = 0; + + /* skip any iso nodes which might belong to previous microframes */ + while (here.ptr) { + type = Q_NEXT_TYPE(ehci, *hw_p); + if (type == cpu_to_hc32(ehci, Q_TYPE_QH)) + break; + prev = periodic_next_shadow(ehci, prev, type); + hw_p = shadow_next_periodic(ehci, &here, type); + here = *prev; + } + + itd->itd_next = here; + itd->hw_next = *hw_p; + prev->itd = itd; itd->frame = frame; wmb (); - ehci->periodic[frame] = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD); + *hw_p = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD); } /* fit urb's itds into the selected schedule slot; activate as needed */ -- cgit v0.10.2 From 1082f57abfa26590b60c43f503afb24102a37016 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 1 Mar 2010 17:18:56 +0100 Subject: USB: EHCI: adjust ehci_iso_stream for changes in ehci_qh The EHCI driver stores in usb_host_endpoint.hcpriv a pointer to either an ehci_qh or an ehci_iso_stream structure, and uses the contents of the hw_info1 field to distinguish the two cases. After ehci_qh was split into hw and sw parts, ehci_iso_stream must also be adjusted so that it again looks like an ehci_qh structure. This fixes a NULL pointer access in ehci_endpoint_disable() when it tries to access qh->hw->hw_info1. Signed-off-by: Clemens Ladisch Reported-by: Colin Fletcher Cc: stable Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index d8d6d34..dc55a62 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -995,7 +995,7 @@ rescan: /* endpoints can be iso streams. for now, we don't * accelerate iso completions ... so spin a while. */ - if (qh->hw->hw_info1 == 0) { + if (qh->hw == NULL) { ehci_vdbg (ehci, "iso delay\n"); goto idle_timeout; } diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index cd1e8bf..a0aaaaf 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -1123,8 +1123,8 @@ iso_stream_find (struct ehci_hcd *ehci, struct urb *urb) urb->interval); } - /* if dev->ep [epnum] is a QH, info1.maxpacket is nonzero */ - } else if (unlikely (stream->hw_info1 != 0)) { + /* if dev->ep [epnum] is a QH, hw is set */ + } else if (unlikely (stream->hw != NULL)) { ehci_dbg (ehci, "dev %s ep%d%s, not iso??\n", urb->dev->devpath, epnum, usb_pipein(urb->pipe) ? "in" : "out"); diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 2d85e21..b1dce96 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -394,9 +394,8 @@ struct ehci_iso_sched { * acts like a qh would, if EHCI had them for ISO. */ struct ehci_iso_stream { - /* first two fields match QH, but info1 == 0 */ - __hc32 hw_next; - __hc32 hw_info1; + /* first field matches ehci_hq, but is NULL */ + struct ehci_qh_hw *hw; u32 refcount; u8 bEndpointAddress; -- cgit v0.10.2 From f0730924e9e32bb8935c60040a26d94179355088 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Wed, 3 Mar 2010 00:37:56 +0100 Subject: USB: cdc-acm: Fix stupid NULL pointer in resume() Stupid logic bug passing a just nulled pointer Signed-off-by: Oliver Neukum Cc: stable Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 975d556..be6331e 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1441,7 +1441,7 @@ static int acm_resume(struct usb_interface *intf) wb = acm->delayed_wb; acm->delayed_wb = NULL; spin_unlock_irq(&acm->write_lock); - acm_start_wb(acm, acm->delayed_wb); + acm_start_wb(acm, wb); } else { spin_unlock_irq(&acm->write_lock); } -- cgit v0.10.2 From 0725e95ea56698774e893edb7e7276b1d6890954 Mon Sep 17 00:00:00 2001 From: Bernhard Rosenkraenzer Date: Wed, 10 Mar 2010 12:36:43 +0100 Subject: USB: qcserial: add new device ids This patch adds various USB device IDs for Gobi 2000 devices, as found in the drivers available at https://www.codeaurora.org/wiki/GOBI_Releases Signed-off-by: Bernhard Rosenkraenzer Cc: stable Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index 310ff6e..53a2d5a 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c @@ -47,6 +47,35 @@ static const struct usb_device_id id_table[] = { {USB_DEVICE(0x05c6, 0x9221)}, /* Generic Gobi QDL device */ {USB_DEVICE(0x05c6, 0x9231)}, /* Generic Gobi QDL device */ {USB_DEVICE(0x1f45, 0x0001)}, /* Unknown Gobi QDL device */ + {USB_DEVICE(0x413c, 0x8185)}, /* Dell Gobi 2000 QDL device (N0218, VU936) */ + {USB_DEVICE(0x413c, 0x8186)}, /* Dell Gobi 2000 Modem device (N0218, VU936) */ + {USB_DEVICE(0x05c6, 0x9224)}, /* Sony Gobi 2000 QDL device (N0279, VU730) */ + {USB_DEVICE(0x05c6, 0x9225)}, /* Sony Gobi 2000 Modem device (N0279, VU730) */ + {USB_DEVICE(0x05c6, 0x9244)}, /* Samsung Gobi 2000 QDL device (VL176) */ + {USB_DEVICE(0x05c6, 0x9245)}, /* Samsung Gobi 2000 Modem device (VL176) */ + {USB_DEVICE(0x03f0, 0x241d)}, /* HP Gobi 2000 QDL device (VP412) */ + {USB_DEVICE(0x03f0, 0x251d)}, /* HP Gobi 2000 Modem device (VP412) */ + {USB_DEVICE(0x05c6, 0x9214)}, /* Acer Gobi 2000 QDL device (VP413) */ + {USB_DEVICE(0x05c6, 0x9215)}, /* Acer Gobi 2000 Modem device (VP413) */ + {USB_DEVICE(0x05c6, 0x9264)}, /* Asus Gobi 2000 QDL device (VR305) */ + {USB_DEVICE(0x05c6, 0x9265)}, /* Asus Gobi 2000 Modem device (VR305) */ + {USB_DEVICE(0x05c6, 0x9234)}, /* Top Global Gobi 2000 QDL device (VR306) */ + {USB_DEVICE(0x05c6, 0x9235)}, /* Top Global Gobi 2000 Modem device (VR306) */ + {USB_DEVICE(0x05c6, 0x9274)}, /* iRex Technologies Gobi 2000 QDL device (VR307) */ + {USB_DEVICE(0x05c6, 0x9275)}, /* iRex Technologies Gobi 2000 Modem device (VR307) */ + {USB_DEVICE(0x1199, 0x9000)}, /* Sierra Wireless Gobi 2000 QDL device (VT773) */ + {USB_DEVICE(0x1199, 0x9001)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ + {USB_DEVICE(0x1199, 0x9002)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ + {USB_DEVICE(0x1199, 0x9003)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ + {USB_DEVICE(0x1199, 0x9004)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ + {USB_DEVICE(0x1199, 0x9005)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ + {USB_DEVICE(0x1199, 0x9006)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ + {USB_DEVICE(0x1199, 0x9007)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ + {USB_DEVICE(0x1199, 0x9008)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ + {USB_DEVICE(0x1199, 0x9009)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ + {USB_DEVICE(0x1199, 0x900a)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ + {USB_DEVICE(0x16d8, 0x8001)}, /* CMDTech Gobi 2000 QDL device (VU922) */ + {USB_DEVICE(0x16d8, 0x8002)}, /* CMDTech Gobi 2000 Modem device (VU922) */ { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, id_table); -- cgit v0.10.2 From ae926976ac362efc9db2365a07891cc52414f2ec Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Mon, 8 Mar 2010 11:26:01 -0500 Subject: USB: musb: fix build error introduced by isoc change The recent commit "usb: musb: Fix for isochronous IN transfer" (f82a689fa) seems to have been against an older kernel version. It uses the old style naming of variables. Unfortunately, this breaks building for most MUSB users out there since "bDesiredMode" has been renamed to "desired_mode". Signed-off-by: Sonic Zhang Signed-off-by: Mike Frysinger Acked-by: Felipe Balbi Acked-by: Anand Gadiyar Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 3421cf9..dec896e 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -1689,7 +1689,7 @@ void musb_host_rx(struct musb *musb, u8 epnum) dma->desired_mode = 1; if (rx_count < hw_ep->max_packet_sz_rx) { length = rx_count; - dma->bDesiredMode = 0; + dma->desired_mode = 0; } else { length = urb->transfer_buffer_length; } -- cgit v0.10.2 From bc75fa3825cdbbdeee3a65d91cc5583bdfe41edf Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Tue, 16 Mar 2010 14:48:45 -0600 Subject: USB: xhci: rename driver to xhci_hcd Naming consistency with other USB HCDs. Signed-off-by: Alex Chiang Cc: Sarah Sharp Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 4e0c67f..b6315aa 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -12,7 +12,7 @@ fhci-objs := fhci-hcd.o fhci-hub.o fhci-q.o fhci-mem.o \ ifeq ($(CONFIG_FHCI_DEBUG),y) fhci-objs += fhci-dbg.o endif -xhci-objs := xhci-hcd.o xhci-mem.o xhci-pci.o xhci-ring.o xhci-hub.o xhci-dbg.o +xhci-hcd-objs := xhci.o xhci-mem.o xhci-pci.o xhci-ring.o xhci-hub.o xhci-dbg.o obj-$(CONFIG_USB_WHCI_HCD) += whci/ @@ -25,7 +25,7 @@ obj-$(CONFIG_USB_ISP1362_HCD) += isp1362-hcd.o obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o obj-$(CONFIG_USB_FHCI_HCD) += fhci.o -obj-$(CONFIG_USB_XHCI_HCD) += xhci.o +obj-$(CONFIG_USB_XHCI_HCD) += xhci-hcd.o obj-$(CONFIG_USB_SL811_HCD) += sl811-hcd.o obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o diff --git a/drivers/usb/host/xhci-hcd.c b/drivers/usb/host/xhci-hcd.c deleted file mode 100644 index 4cb69e0..0000000 --- a/drivers/usb/host/xhci-hcd.c +++ /dev/null @@ -1,1916 +0,0 @@ -/* - * xHCI host controller driver - * - * Copyright (C) 2008 Intel Corp. - * - * Author: Sarah Sharp - * Some code borrowed from the Linux EHCI driver. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include - -#include "xhci.h" - -#define DRIVER_AUTHOR "Sarah Sharp" -#define DRIVER_DESC "'eXtensible' Host Controller (xHC) Driver" - -/* Some 0.95 hardware can't handle the chain bit on a Link TRB being cleared */ -static int link_quirk; -module_param(link_quirk, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(link_quirk, "Don't clear the chain bit on a link TRB"); - -/* TODO: copied from ehci-hcd.c - can this be refactored? */ -/* - * handshake - spin reading hc until handshake completes or fails - * @ptr: address of hc register to be read - * @mask: bits to look at in result of read - * @done: value of those bits when handshake succeeds - * @usec: timeout in microseconds - * - * Returns negative errno, or zero on success - * - * Success happens when the "mask" bits have the specified value (hardware - * handshake done). There are two failure modes: "usec" have passed (major - * hardware flakeout), or the register reads as all-ones (hardware removed). - */ -static int handshake(struct xhci_hcd *xhci, void __iomem *ptr, - u32 mask, u32 done, int usec) -{ - u32 result; - - do { - result = xhci_readl(xhci, ptr); - if (result == ~(u32)0) /* card removed */ - return -ENODEV; - result &= mask; - if (result == done) - return 0; - udelay(1); - usec--; - } while (usec > 0); - return -ETIMEDOUT; -} - -/* - * Disable interrupts and begin the xHCI halting process. - */ -void xhci_quiesce(struct xhci_hcd *xhci) -{ - u32 halted; - u32 cmd; - u32 mask; - - mask = ~(XHCI_IRQS); - halted = xhci_readl(xhci, &xhci->op_regs->status) & STS_HALT; - if (!halted) - mask &= ~CMD_RUN; - - cmd = xhci_readl(xhci, &xhci->op_regs->command); - cmd &= mask; - xhci_writel(xhci, cmd, &xhci->op_regs->command); -} - -/* - * Force HC into halt state. - * - * Disable any IRQs and clear the run/stop bit. - * HC will complete any current and actively pipelined transactions, and - * should halt within 16 microframes of the run/stop bit being cleared. - * Read HC Halted bit in the status register to see when the HC is finished. - * XXX: shouldn't we set HC_STATE_HALT here somewhere? - */ -int xhci_halt(struct xhci_hcd *xhci) -{ - xhci_dbg(xhci, "// Halt the HC\n"); - xhci_quiesce(xhci); - - return handshake(xhci, &xhci->op_regs->status, - STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC); -} - -/* - * Reset a halted HC, and set the internal HC state to HC_STATE_HALT. - * - * This resets pipelines, timers, counters, state machines, etc. - * Transactions will be terminated immediately, and operational registers - * will be set to their defaults. - */ -int xhci_reset(struct xhci_hcd *xhci) -{ - u32 command; - u32 state; - - state = xhci_readl(xhci, &xhci->op_regs->status); - if ((state & STS_HALT) == 0) { - xhci_warn(xhci, "Host controller not halted, aborting reset.\n"); - return 0; - } - - xhci_dbg(xhci, "// Reset the HC\n"); - command = xhci_readl(xhci, &xhci->op_regs->command); - command |= CMD_RESET; - xhci_writel(xhci, command, &xhci->op_regs->command); - /* XXX: Why does EHCI set this here? Shouldn't other code do this? */ - xhci_to_hcd(xhci)->state = HC_STATE_HALT; - - return handshake(xhci, &xhci->op_regs->command, CMD_RESET, 0, 250 * 1000); -} - - -#if 0 -/* Set up MSI-X table for entry 0 (may claim other entries later) */ -static int xhci_setup_msix(struct xhci_hcd *xhci) -{ - int ret; - struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); - - xhci->msix_count = 0; - /* XXX: did I do this right? ixgbe does kcalloc for more than one */ - xhci->msix_entries = kmalloc(sizeof(struct msix_entry), GFP_KERNEL); - if (!xhci->msix_entries) { - xhci_err(xhci, "Failed to allocate MSI-X entries\n"); - return -ENOMEM; - } - xhci->msix_entries[0].entry = 0; - - ret = pci_enable_msix(pdev, xhci->msix_entries, xhci->msix_count); - if (ret) { - xhci_err(xhci, "Failed to enable MSI-X\n"); - goto free_entries; - } - - /* - * Pass the xhci pointer value as the request_irq "cookie". - * If more irqs are added, this will need to be unique for each one. - */ - ret = request_irq(xhci->msix_entries[0].vector, &xhci_irq, 0, - "xHCI", xhci_to_hcd(xhci)); - if (ret) { - xhci_err(xhci, "Failed to allocate MSI-X interrupt\n"); - goto disable_msix; - } - xhci_dbg(xhci, "Finished setting up MSI-X\n"); - return 0; - -disable_msix: - pci_disable_msix(pdev); -free_entries: - kfree(xhci->msix_entries); - xhci->msix_entries = NULL; - return ret; -} - -/* XXX: code duplication; can xhci_setup_msix call this? */ -/* Free any IRQs and disable MSI-X */ -static void xhci_cleanup_msix(struct xhci_hcd *xhci) -{ - struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); - if (!xhci->msix_entries) - return; - - free_irq(xhci->msix_entries[0].vector, xhci); - pci_disable_msix(pdev); - kfree(xhci->msix_entries); - xhci->msix_entries = NULL; - xhci_dbg(xhci, "Finished cleaning up MSI-X\n"); -} -#endif - -/* - * Initialize memory for HCD and xHC (one-time init). - * - * Program the PAGESIZE register, initialize the device context array, create - * device contexts (?), set up a command ring segment (or two?), create event - * ring (one for now). - */ -int xhci_init(struct usb_hcd *hcd) -{ - struct xhci_hcd *xhci = hcd_to_xhci(hcd); - int retval = 0; - - xhci_dbg(xhci, "xhci_init\n"); - spin_lock_init(&xhci->lock); - if (link_quirk) { - xhci_dbg(xhci, "QUIRK: Not clearing Link TRB chain bits.\n"); - xhci->quirks |= XHCI_LINK_TRB_QUIRK; - } else { - xhci_dbg(xhci, "xHCI doesn't need link TRB QUIRK\n"); - } - retval = xhci_mem_init(xhci, GFP_KERNEL); - xhci_dbg(xhci, "Finished xhci_init\n"); - - return retval; -} - -/* - * Called in interrupt context when there might be work - * queued on the event ring - * - * xhci->lock must be held by caller. - */ -static void xhci_work(struct xhci_hcd *xhci) -{ - u32 temp; - u64 temp_64; - - /* - * Clear the op reg interrupt status first, - * so we can receive interrupts from other MSI-X interrupters. - * Write 1 to clear the interrupt status. - */ - temp = xhci_readl(xhci, &xhci->op_regs->status); - temp |= STS_EINT; - xhci_writel(xhci, temp, &xhci->op_regs->status); - /* FIXME when MSI-X is supported and there are multiple vectors */ - /* Clear the MSI-X event interrupt status */ - - /* Acknowledge the interrupt */ - temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); - temp |= 0x3; - xhci_writel(xhci, temp, &xhci->ir_set->irq_pending); - /* Flush posted writes */ - xhci_readl(xhci, &xhci->ir_set->irq_pending); - - if (xhci->xhc_state & XHCI_STATE_DYING) - xhci_dbg(xhci, "xHCI dying, ignoring interrupt. " - "Shouldn't IRQs be disabled?\n"); - else - /* FIXME this should be a delayed service routine - * that clears the EHB. - */ - xhci_handle_event(xhci); - - /* Clear the event handler busy flag (RW1C); the event ring should be empty. */ - temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); - xhci_write_64(xhci, temp_64 | ERST_EHB, &xhci->ir_set->erst_dequeue); - /* Flush posted writes -- FIXME is this necessary? */ - xhci_readl(xhci, &xhci->ir_set->irq_pending); -} - -/*-------------------------------------------------------------------------*/ - -/* - * xHCI spec says we can get an interrupt, and if the HC has an error condition, - * we might get bad data out of the event ring. Section 4.10.2.7 has a list of - * indicators of an event TRB error, but we check the status *first* to be safe. - */ -irqreturn_t xhci_irq(struct usb_hcd *hcd) -{ - struct xhci_hcd *xhci = hcd_to_xhci(hcd); - u32 temp, temp2; - union xhci_trb *trb; - - spin_lock(&xhci->lock); - trb = xhci->event_ring->dequeue; - /* Check if the xHC generated the interrupt, or the irq is shared */ - temp = xhci_readl(xhci, &xhci->op_regs->status); - temp2 = xhci_readl(xhci, &xhci->ir_set->irq_pending); - if (temp == 0xffffffff && temp2 == 0xffffffff) - goto hw_died; - - if (!(temp & STS_EINT) && !ER_IRQ_PENDING(temp2)) { - spin_unlock(&xhci->lock); - return IRQ_NONE; - } - xhci_dbg(xhci, "op reg status = %08x\n", temp); - xhci_dbg(xhci, "ir set irq_pending = %08x\n", temp2); - xhci_dbg(xhci, "Event ring dequeue ptr:\n"); - xhci_dbg(xhci, "@%llx %08x %08x %08x %08x\n", - (unsigned long long)xhci_trb_virt_to_dma(xhci->event_ring->deq_seg, trb), - lower_32_bits(trb->link.segment_ptr), - upper_32_bits(trb->link.segment_ptr), - (unsigned int) trb->link.intr_target, - (unsigned int) trb->link.control); - - if (temp & STS_FATAL) { - xhci_warn(xhci, "WARNING: Host System Error\n"); - xhci_halt(xhci); -hw_died: - xhci_to_hcd(xhci)->state = HC_STATE_HALT; - spin_unlock(&xhci->lock); - return -ESHUTDOWN; - } - - xhci_work(xhci); - spin_unlock(&xhci->lock); - - return IRQ_HANDLED; -} - -#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING -void xhci_event_ring_work(unsigned long arg) -{ - unsigned long flags; - int temp; - u64 temp_64; - struct xhci_hcd *xhci = (struct xhci_hcd *) arg; - int i, j; - - xhci_dbg(xhci, "Poll event ring: %lu\n", jiffies); - - spin_lock_irqsave(&xhci->lock, flags); - temp = xhci_readl(xhci, &xhci->op_regs->status); - xhci_dbg(xhci, "op reg status = 0x%x\n", temp); - if (temp == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING)) { - xhci_dbg(xhci, "HW died, polling stopped.\n"); - spin_unlock_irqrestore(&xhci->lock, flags); - return; - } - - temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); - xhci_dbg(xhci, "ir_set 0 pending = 0x%x\n", temp); - xhci_dbg(xhci, "No-op commands handled = %d\n", xhci->noops_handled); - xhci_dbg(xhci, "HC error bitmask = 0x%x\n", xhci->error_bitmask); - xhci->error_bitmask = 0; - xhci_dbg(xhci, "Event ring:\n"); - xhci_debug_segment(xhci, xhci->event_ring->deq_seg); - xhci_dbg_ring_ptrs(xhci, xhci->event_ring); - temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); - temp_64 &= ~ERST_PTR_MASK; - xhci_dbg(xhci, "ERST deq = 64'h%0lx\n", (long unsigned int) temp_64); - xhci_dbg(xhci, "Command ring:\n"); - xhci_debug_segment(xhci, xhci->cmd_ring->deq_seg); - xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring); - xhci_dbg_cmd_ptrs(xhci); - for (i = 0; i < MAX_HC_SLOTS; ++i) { - if (!xhci->devs[i]) - continue; - for (j = 0; j < 31; ++j) { - struct xhci_ring *ring = xhci->devs[i]->eps[j].ring; - if (!ring) - continue; - xhci_dbg(xhci, "Dev %d endpoint ring %d:\n", i, j); - xhci_debug_segment(xhci, ring->deq_seg); - } - } - - if (xhci->noops_submitted != NUM_TEST_NOOPS) - if (xhci_setup_one_noop(xhci)) - xhci_ring_cmd_db(xhci); - spin_unlock_irqrestore(&xhci->lock, flags); - - if (!xhci->zombie) - mod_timer(&xhci->event_ring_timer, jiffies + POLL_TIMEOUT * HZ); - else - xhci_dbg(xhci, "Quit polling the event ring.\n"); -} -#endif - -/* - * Start the HC after it was halted. - * - * This function is called by the USB core when the HC driver is added. - * Its opposite is xhci_stop(). - * - * xhci_init() must be called once before this function can be called. - * Reset the HC, enable device slot contexts, program DCBAAP, and - * set command ring pointer and event ring pointer. - * - * Setup MSI-X vectors and enable interrupts. - */ -int xhci_run(struct usb_hcd *hcd) -{ - u32 temp; - u64 temp_64; - struct xhci_hcd *xhci = hcd_to_xhci(hcd); - void (*doorbell)(struct xhci_hcd *) = NULL; - - hcd->uses_new_polling = 1; - hcd->poll_rh = 0; - - xhci_dbg(xhci, "xhci_run\n"); -#if 0 /* FIXME: MSI not setup yet */ - /* Do this at the very last minute */ - ret = xhci_setup_msix(xhci); - if (!ret) - return ret; - - return -ENOSYS; -#endif -#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING - init_timer(&xhci->event_ring_timer); - xhci->event_ring_timer.data = (unsigned long) xhci; - xhci->event_ring_timer.function = xhci_event_ring_work; - /* Poll the event ring */ - xhci->event_ring_timer.expires = jiffies + POLL_TIMEOUT * HZ; - xhci->zombie = 0; - xhci_dbg(xhci, "Setting event ring polling timer\n"); - add_timer(&xhci->event_ring_timer); -#endif - - xhci_dbg(xhci, "Command ring memory map follows:\n"); - xhci_debug_ring(xhci, xhci->cmd_ring); - xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring); - xhci_dbg_cmd_ptrs(xhci); - - xhci_dbg(xhci, "ERST memory map follows:\n"); - xhci_dbg_erst(xhci, &xhci->erst); - xhci_dbg(xhci, "Event ring:\n"); - xhci_debug_ring(xhci, xhci->event_ring); - xhci_dbg_ring_ptrs(xhci, xhci->event_ring); - temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); - temp_64 &= ~ERST_PTR_MASK; - xhci_dbg(xhci, "ERST deq = 64'h%0lx\n", (long unsigned int) temp_64); - - xhci_dbg(xhci, "// Set the interrupt modulation register\n"); - temp = xhci_readl(xhci, &xhci->ir_set->irq_control); - temp &= ~ER_IRQ_INTERVAL_MASK; - temp |= (u32) 160; - xhci_writel(xhci, temp, &xhci->ir_set->irq_control); - - /* Set the HCD state before we enable the irqs */ - hcd->state = HC_STATE_RUNNING; - temp = xhci_readl(xhci, &xhci->op_regs->command); - temp |= (CMD_EIE); - xhci_dbg(xhci, "// Enable interrupts, cmd = 0x%x.\n", - temp); - xhci_writel(xhci, temp, &xhci->op_regs->command); - - temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); - xhci_dbg(xhci, "// Enabling event ring interrupter %p by writing 0x%x to irq_pending\n", - xhci->ir_set, (unsigned int) ER_IRQ_ENABLE(temp)); - xhci_writel(xhci, ER_IRQ_ENABLE(temp), - &xhci->ir_set->irq_pending); - xhci_print_ir_set(xhci, xhci->ir_set, 0); - - if (NUM_TEST_NOOPS > 0) - doorbell = xhci_setup_one_noop(xhci); - - temp = xhci_readl(xhci, &xhci->op_regs->command); - temp |= (CMD_RUN); - xhci_dbg(xhci, "// Turn on HC, cmd = 0x%x.\n", - temp); - xhci_writel(xhci, temp, &xhci->op_regs->command); - /* Flush PCI posted writes */ - temp = xhci_readl(xhci, &xhci->op_regs->command); - xhci_dbg(xhci, "// @%p = 0x%x\n", &xhci->op_regs->command, temp); - if (doorbell) - (*doorbell)(xhci); - - xhci_dbg(xhci, "Finished xhci_run\n"); - return 0; -} - -/* - * Stop xHCI driver. - * - * This function is called by the USB core when the HC driver is removed. - * Its opposite is xhci_run(). - * - * Disable device contexts, disable IRQs, and quiesce the HC. - * Reset the HC, finish any completed transactions, and cleanup memory. - */ -void xhci_stop(struct usb_hcd *hcd) -{ - u32 temp; - struct xhci_hcd *xhci = hcd_to_xhci(hcd); - - spin_lock_irq(&xhci->lock); - xhci_halt(xhci); - xhci_reset(xhci); - spin_unlock_irq(&xhci->lock); - -#if 0 /* No MSI yet */ - xhci_cleanup_msix(xhci); -#endif -#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING - /* Tell the event ring poll function not to reschedule */ - xhci->zombie = 1; - del_timer_sync(&xhci->event_ring_timer); -#endif - - xhci_dbg(xhci, "// Disabling event ring interrupts\n"); - temp = xhci_readl(xhci, &xhci->op_regs->status); - xhci_writel(xhci, temp & ~STS_EINT, &xhci->op_regs->status); - temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); - xhci_writel(xhci, ER_IRQ_DISABLE(temp), - &xhci->ir_set->irq_pending); - xhci_print_ir_set(xhci, xhci->ir_set, 0); - - xhci_dbg(xhci, "cleaning up memory\n"); - xhci_mem_cleanup(xhci); - xhci_dbg(xhci, "xhci_stop completed - status = %x\n", - xhci_readl(xhci, &xhci->op_regs->status)); -} - -/* - * Shutdown HC (not bus-specific) - * - * This is called when the machine is rebooting or halting. We assume that the - * machine will be powered off, and the HC's internal state will be reset. - * Don't bother to free memory. - */ -void xhci_shutdown(struct usb_hcd *hcd) -{ - struct xhci_hcd *xhci = hcd_to_xhci(hcd); - - spin_lock_irq(&xhci->lock); - xhci_halt(xhci); - spin_unlock_irq(&xhci->lock); - -#if 0 - xhci_cleanup_msix(xhci); -#endif - - xhci_dbg(xhci, "xhci_shutdown completed - status = %x\n", - xhci_readl(xhci, &xhci->op_regs->status)); -} - -/*-------------------------------------------------------------------------*/ - -/** - * xhci_get_endpoint_index - Used for passing endpoint bitmasks between the core and - * HCDs. Find the index for an endpoint given its descriptor. Use the return - * value to right shift 1 for the bitmask. - * - * Index = (epnum * 2) + direction - 1, - * where direction = 0 for OUT, 1 for IN. - * For control endpoints, the IN index is used (OUT index is unused), so - * index = (epnum * 2) + direction - 1 = (epnum * 2) + 1 - 1 = (epnum * 2) - */ -unsigned int xhci_get_endpoint_index(struct usb_endpoint_descriptor *desc) -{ - unsigned int index; - if (usb_endpoint_xfer_control(desc)) - index = (unsigned int) (usb_endpoint_num(desc)*2); - else - index = (unsigned int) (usb_endpoint_num(desc)*2) + - (usb_endpoint_dir_in(desc) ? 1 : 0) - 1; - return index; -} - -/* Find the flag for this endpoint (for use in the control context). Use the - * endpoint index to create a bitmask. The slot context is bit 0, endpoint 0 is - * bit 1, etc. - */ -unsigned int xhci_get_endpoint_flag(struct usb_endpoint_descriptor *desc) -{ - return 1 << (xhci_get_endpoint_index(desc) + 1); -} - -/* Find the flag for this endpoint (for use in the control context). Use the - * endpoint index to create a bitmask. The slot context is bit 0, endpoint 0 is - * bit 1, etc. - */ -unsigned int xhci_get_endpoint_flag_from_index(unsigned int ep_index) -{ - return 1 << (ep_index + 1); -} - -/* Compute the last valid endpoint context index. Basically, this is the - * endpoint index plus one. For slot contexts with more than valid endpoint, - * we find the most significant bit set in the added contexts flags. - * e.g. ep 1 IN (with epnum 0x81) => added_ctxs = 0b1000 - * fls(0b1000) = 4, but the endpoint context index is 3, so subtract one. - */ -unsigned int xhci_last_valid_endpoint(u32 added_ctxs) -{ - return fls(added_ctxs) - 1; -} - -/* Returns 1 if the arguments are OK; - * returns 0 this is a root hub; returns -EINVAL for NULL pointers. - */ -int xhci_check_args(struct usb_hcd *hcd, struct usb_device *udev, - struct usb_host_endpoint *ep, int check_ep, const char *func) { - if (!hcd || (check_ep && !ep) || !udev) { - printk(KERN_DEBUG "xHCI %s called with invalid args\n", - func); - return -EINVAL; - } - if (!udev->parent) { - printk(KERN_DEBUG "xHCI %s called for root hub\n", - func); - return 0; - } - if (!udev->slot_id) { - printk(KERN_DEBUG "xHCI %s called with unaddressed device\n", - func); - return -EINVAL; - } - return 1; -} - -static int xhci_configure_endpoint(struct xhci_hcd *xhci, - struct usb_device *udev, struct xhci_command *command, - bool ctx_change, bool must_succeed); - -/* - * Full speed devices may have a max packet size greater than 8 bytes, but the - * USB core doesn't know that until it reads the first 8 bytes of the - * descriptor. If the usb_device's max packet size changes after that point, - * we need to issue an evaluate context command and wait on it. - */ -static int xhci_check_maxpacket(struct xhci_hcd *xhci, unsigned int slot_id, - unsigned int ep_index, struct urb *urb) -{ - struct xhci_container_ctx *in_ctx; - struct xhci_container_ctx *out_ctx; - struct xhci_input_control_ctx *ctrl_ctx; - struct xhci_ep_ctx *ep_ctx; - int max_packet_size; - int hw_max_packet_size; - int ret = 0; - - out_ctx = xhci->devs[slot_id]->out_ctx; - ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index); - hw_max_packet_size = MAX_PACKET_DECODED(ep_ctx->ep_info2); - max_packet_size = urb->dev->ep0.desc.wMaxPacketSize; - if (hw_max_packet_size != max_packet_size) { - xhci_dbg(xhci, "Max Packet Size for ep 0 changed.\n"); - xhci_dbg(xhci, "Max packet size in usb_device = %d\n", - max_packet_size); - xhci_dbg(xhci, "Max packet size in xHCI HW = %d\n", - hw_max_packet_size); - xhci_dbg(xhci, "Issuing evaluate context command.\n"); - - /* Set up the modified control endpoint 0 */ - xhci_endpoint_copy(xhci, xhci->devs[slot_id]->in_ctx, - xhci->devs[slot_id]->out_ctx, ep_index); - in_ctx = xhci->devs[slot_id]->in_ctx; - ep_ctx = xhci_get_ep_ctx(xhci, in_ctx, ep_index); - ep_ctx->ep_info2 &= ~MAX_PACKET_MASK; - ep_ctx->ep_info2 |= MAX_PACKET(max_packet_size); - - /* Set up the input context flags for the command */ - /* FIXME: This won't work if a non-default control endpoint - * changes max packet sizes. - */ - ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); - ctrl_ctx->add_flags = EP0_FLAG; - ctrl_ctx->drop_flags = 0; - - xhci_dbg(xhci, "Slot %d input context\n", slot_id); - xhci_dbg_ctx(xhci, in_ctx, ep_index); - xhci_dbg(xhci, "Slot %d output context\n", slot_id); - xhci_dbg_ctx(xhci, out_ctx, ep_index); - - ret = xhci_configure_endpoint(xhci, urb->dev, NULL, - true, false); - - /* Clean up the input context for later use by bandwidth - * functions. - */ - ctrl_ctx->add_flags = SLOT_FLAG; - } - return ret; -} - -/* - * non-error returns are a promise to giveback() the urb later - * we drop ownership so next owner (or urb unlink) can get it - */ -int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) -{ - struct xhci_hcd *xhci = hcd_to_xhci(hcd); - unsigned long flags; - int ret = 0; - unsigned int slot_id, ep_index; - - - if (!urb || xhci_check_args(hcd, urb->dev, urb->ep, true, __func__) <= 0) - return -EINVAL; - - slot_id = urb->dev->slot_id; - ep_index = xhci_get_endpoint_index(&urb->ep->desc); - - if (!xhci->devs || !xhci->devs[slot_id]) { - if (!in_interrupt()) - dev_warn(&urb->dev->dev, "WARN: urb submitted for dev with no Slot ID\n"); - ret = -EINVAL; - goto exit; - } - if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) { - if (!in_interrupt()) - xhci_dbg(xhci, "urb submitted during PCI suspend\n"); - ret = -ESHUTDOWN; - goto exit; - } - if (usb_endpoint_xfer_control(&urb->ep->desc)) { - /* Check to see if the max packet size for the default control - * endpoint changed during FS device enumeration - */ - if (urb->dev->speed == USB_SPEED_FULL) { - ret = xhci_check_maxpacket(xhci, slot_id, - ep_index, urb); - if (ret < 0) - return ret; - } - - /* We have a spinlock and interrupts disabled, so we must pass - * atomic context to this function, which may allocate memory. - */ - spin_lock_irqsave(&xhci->lock, flags); - if (xhci->xhc_state & XHCI_STATE_DYING) - goto dying; - ret = xhci_queue_ctrl_tx(xhci, GFP_ATOMIC, urb, - slot_id, ep_index); - spin_unlock_irqrestore(&xhci->lock, flags); - } else if (usb_endpoint_xfer_bulk(&urb->ep->desc)) { - spin_lock_irqsave(&xhci->lock, flags); - if (xhci->xhc_state & XHCI_STATE_DYING) - goto dying; - ret = xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb, - slot_id, ep_index); - spin_unlock_irqrestore(&xhci->lock, flags); - } else if (usb_endpoint_xfer_int(&urb->ep->desc)) { - spin_lock_irqsave(&xhci->lock, flags); - if (xhci->xhc_state & XHCI_STATE_DYING) - goto dying; - ret = xhci_queue_intr_tx(xhci, GFP_ATOMIC, urb, - slot_id, ep_index); - spin_unlock_irqrestore(&xhci->lock, flags); - } else { - ret = -EINVAL; - } -exit: - return ret; -dying: - xhci_dbg(xhci, "Ep 0x%x: URB %p submitted for " - "non-responsive xHCI host.\n", - urb->ep->desc.bEndpointAddress, urb); - spin_unlock_irqrestore(&xhci->lock, flags); - return -ESHUTDOWN; -} - -/* - * Remove the URB's TD from the endpoint ring. This may cause the HC to stop - * USB transfers, potentially stopping in the middle of a TRB buffer. The HC - * should pick up where it left off in the TD, unless a Set Transfer Ring - * Dequeue Pointer is issued. - * - * The TRBs that make up the buffers for the canceled URB will be "removed" from - * the ring. Since the ring is a contiguous structure, they can't be physically - * removed. Instead, there are two options: - * - * 1) If the HC is in the middle of processing the URB to be canceled, we - * simply move the ring's dequeue pointer past those TRBs using the Set - * Transfer Ring Dequeue Pointer command. This will be the common case, - * when drivers timeout on the last submitted URB and attempt to cancel. - * - * 2) If the HC is in the middle of a different TD, we turn the TRBs into a - * series of 1-TRB transfer no-op TDs. (No-ops shouldn't be chained.) The - * HC will need to invalidate the any TRBs it has cached after the stop - * endpoint command, as noted in the xHCI 0.95 errata. - * - * 3) The TD may have completed by the time the Stop Endpoint Command - * completes, so software needs to handle that case too. - * - * This function should protect against the TD enqueueing code ringing the - * doorbell while this code is waiting for a Stop Endpoint command to complete. - * It also needs to account for multiple cancellations on happening at the same - * time for the same endpoint. - * - * Note that this function can be called in any context, or so says - * usb_hcd_unlink_urb() - */ -int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) -{ - unsigned long flags; - int ret; - u32 temp; - struct xhci_hcd *xhci; - struct xhci_td *td; - unsigned int ep_index; - struct xhci_ring *ep_ring; - struct xhci_virt_ep *ep; - - xhci = hcd_to_xhci(hcd); - spin_lock_irqsave(&xhci->lock, flags); - /* Make sure the URB hasn't completed or been unlinked already */ - ret = usb_hcd_check_unlink_urb(hcd, urb, status); - if (ret || !urb->hcpriv) - goto done; - temp = xhci_readl(xhci, &xhci->op_regs->status); - if (temp == 0xffffffff) { - xhci_dbg(xhci, "HW died, freeing TD.\n"); - td = (struct xhci_td *) urb->hcpriv; - - usb_hcd_unlink_urb_from_ep(hcd, urb); - spin_unlock_irqrestore(&xhci->lock, flags); - usb_hcd_giveback_urb(xhci_to_hcd(xhci), urb, -ESHUTDOWN); - kfree(td); - return ret; - } - if (xhci->xhc_state & XHCI_STATE_DYING) { - xhci_dbg(xhci, "Ep 0x%x: URB %p to be canceled on " - "non-responsive xHCI host.\n", - urb->ep->desc.bEndpointAddress, urb); - /* Let the stop endpoint command watchdog timer (which set this - * state) finish cleaning up the endpoint TD lists. We must - * have caught it in the middle of dropping a lock and giving - * back an URB. - */ - goto done; - } - - xhci_dbg(xhci, "Cancel URB %p\n", urb); - xhci_dbg(xhci, "Event ring:\n"); - xhci_debug_ring(xhci, xhci->event_ring); - ep_index = xhci_get_endpoint_index(&urb->ep->desc); - ep = &xhci->devs[urb->dev->slot_id]->eps[ep_index]; - ep_ring = ep->ring; - xhci_dbg(xhci, "Endpoint ring:\n"); - xhci_debug_ring(xhci, ep_ring); - td = (struct xhci_td *) urb->hcpriv; - - list_add_tail(&td->cancelled_td_list, &ep->cancelled_td_list); - /* Queue a stop endpoint command, but only if this is - * the first cancellation to be handled. - */ - if (!(ep->ep_state & EP_HALT_PENDING)) { - ep->ep_state |= EP_HALT_PENDING; - ep->stop_cmds_pending++; - ep->stop_cmd_timer.expires = jiffies + - XHCI_STOP_EP_CMD_TIMEOUT * HZ; - add_timer(&ep->stop_cmd_timer); - xhci_queue_stop_endpoint(xhci, urb->dev->slot_id, ep_index); - xhci_ring_cmd_db(xhci); - } -done: - spin_unlock_irqrestore(&xhci->lock, flags); - return ret; -} - -/* Drop an endpoint from a new bandwidth configuration for this device. - * Only one call to this function is allowed per endpoint before - * check_bandwidth() or reset_bandwidth() must be called. - * A call to xhci_drop_endpoint() followed by a call to xhci_add_endpoint() will - * add the endpoint to the schedule with possibly new parameters denoted by a - * different endpoint descriptor in usb_host_endpoint. - * A call to xhci_add_endpoint() followed by a call to xhci_drop_endpoint() is - * not allowed. - * - * The USB core will not allow URBs to be queued to an endpoint that is being - * disabled, so there's no need for mutual exclusion to protect - * the xhci->devs[slot_id] structure. - */ -int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, - struct usb_host_endpoint *ep) -{ - struct xhci_hcd *xhci; - struct xhci_container_ctx *in_ctx, *out_ctx; - struct xhci_input_control_ctx *ctrl_ctx; - struct xhci_slot_ctx *slot_ctx; - unsigned int last_ctx; - unsigned int ep_index; - struct xhci_ep_ctx *ep_ctx; - u32 drop_flag; - u32 new_add_flags, new_drop_flags, new_slot_info; - int ret; - - ret = xhci_check_args(hcd, udev, ep, 1, __func__); - if (ret <= 0) - return ret; - xhci = hcd_to_xhci(hcd); - xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); - - drop_flag = xhci_get_endpoint_flag(&ep->desc); - if (drop_flag == SLOT_FLAG || drop_flag == EP0_FLAG) { - xhci_dbg(xhci, "xHCI %s - can't drop slot or ep 0 %#x\n", - __func__, drop_flag); - return 0; - } - - if (!xhci->devs || !xhci->devs[udev->slot_id]) { - xhci_warn(xhci, "xHCI %s called with unaddressed device\n", - __func__); - return -EINVAL; - } - - in_ctx = xhci->devs[udev->slot_id]->in_ctx; - out_ctx = xhci->devs[udev->slot_id]->out_ctx; - ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); - ep_index = xhci_get_endpoint_index(&ep->desc); - ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index); - /* If the HC already knows the endpoint is disabled, - * or the HCD has noted it is disabled, ignore this request - */ - if ((ep_ctx->ep_info & EP_STATE_MASK) == EP_STATE_DISABLED || - ctrl_ctx->drop_flags & xhci_get_endpoint_flag(&ep->desc)) { - xhci_warn(xhci, "xHCI %s called with disabled ep %p\n", - __func__, ep); - return 0; - } - - ctrl_ctx->drop_flags |= drop_flag; - new_drop_flags = ctrl_ctx->drop_flags; - - ctrl_ctx->add_flags &= ~drop_flag; - new_add_flags = ctrl_ctx->add_flags; - - last_ctx = xhci_last_valid_endpoint(ctrl_ctx->add_flags); - slot_ctx = xhci_get_slot_ctx(xhci, in_ctx); - /* Update the last valid endpoint context, if we deleted the last one */ - if ((slot_ctx->dev_info & LAST_CTX_MASK) > LAST_CTX(last_ctx)) { - slot_ctx->dev_info &= ~LAST_CTX_MASK; - slot_ctx->dev_info |= LAST_CTX(last_ctx); - } - new_slot_info = slot_ctx->dev_info; - - xhci_endpoint_zero(xhci, xhci->devs[udev->slot_id], ep); - - xhci_dbg(xhci, "drop ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x, new slot info = %#x\n", - (unsigned int) ep->desc.bEndpointAddress, - udev->slot_id, - (unsigned int) new_drop_flags, - (unsigned int) new_add_flags, - (unsigned int) new_slot_info); - return 0; -} - -/* Add an endpoint to a new possible bandwidth configuration for this device. - * Only one call to this function is allowed per endpoint before - * check_bandwidth() or reset_bandwidth() must be called. - * A call to xhci_drop_endpoint() followed by a call to xhci_add_endpoint() will - * add the endpoint to the schedule with possibly new parameters denoted by a - * different endpoint descriptor in usb_host_endpoint. - * A call to xhci_add_endpoint() followed by a call to xhci_drop_endpoint() is - * not allowed. - * - * The USB core will not allow URBs to be queued to an endpoint until the - * configuration or alt setting is installed in the device, so there's no need - * for mutual exclusion to protect the xhci->devs[slot_id] structure. - */ -int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, - struct usb_host_endpoint *ep) -{ - struct xhci_hcd *xhci; - struct xhci_container_ctx *in_ctx, *out_ctx; - unsigned int ep_index; - struct xhci_ep_ctx *ep_ctx; - struct xhci_slot_ctx *slot_ctx; - struct xhci_input_control_ctx *ctrl_ctx; - u32 added_ctxs; - unsigned int last_ctx; - u32 new_add_flags, new_drop_flags, new_slot_info; - int ret = 0; - - ret = xhci_check_args(hcd, udev, ep, 1, __func__); - if (ret <= 0) { - /* So we won't queue a reset ep command for a root hub */ - ep->hcpriv = NULL; - return ret; - } - xhci = hcd_to_xhci(hcd); - - added_ctxs = xhci_get_endpoint_flag(&ep->desc); - last_ctx = xhci_last_valid_endpoint(added_ctxs); - if (added_ctxs == SLOT_FLAG || added_ctxs == EP0_FLAG) { - /* FIXME when we have to issue an evaluate endpoint command to - * deal with ep0 max packet size changing once we get the - * descriptors - */ - xhci_dbg(xhci, "xHCI %s - can't add slot or ep 0 %#x\n", - __func__, added_ctxs); - return 0; - } - - if (!xhci->devs || !xhci->devs[udev->slot_id]) { - xhci_warn(xhci, "xHCI %s called with unaddressed device\n", - __func__); - return -EINVAL; - } - - in_ctx = xhci->devs[udev->slot_id]->in_ctx; - out_ctx = xhci->devs[udev->slot_id]->out_ctx; - ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); - ep_index = xhci_get_endpoint_index(&ep->desc); - ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index); - /* If the HCD has already noted the endpoint is enabled, - * ignore this request. - */ - if (ctrl_ctx->add_flags & xhci_get_endpoint_flag(&ep->desc)) { - xhci_warn(xhci, "xHCI %s called with enabled ep %p\n", - __func__, ep); - return 0; - } - - /* - * Configuration and alternate setting changes must be done in - * process context, not interrupt context (or so documenation - * for usb_set_interface() and usb_set_configuration() claim). - */ - if (xhci_endpoint_init(xhci, xhci->devs[udev->slot_id], - udev, ep, GFP_NOIO) < 0) { - dev_dbg(&udev->dev, "%s - could not initialize ep %#x\n", - __func__, ep->desc.bEndpointAddress); - return -ENOMEM; - } - - ctrl_ctx->add_flags |= added_ctxs; - new_add_flags = ctrl_ctx->add_flags; - - /* If xhci_endpoint_disable() was called for this endpoint, but the - * xHC hasn't been notified yet through the check_bandwidth() call, - * this re-adds a new state for the endpoint from the new endpoint - * descriptors. We must drop and re-add this endpoint, so we leave the - * drop flags alone. - */ - new_drop_flags = ctrl_ctx->drop_flags; - - slot_ctx = xhci_get_slot_ctx(xhci, in_ctx); - /* Update the last valid endpoint context, if we just added one past */ - if ((slot_ctx->dev_info & LAST_CTX_MASK) < LAST_CTX(last_ctx)) { - slot_ctx->dev_info &= ~LAST_CTX_MASK; - slot_ctx->dev_info |= LAST_CTX(last_ctx); - } - new_slot_info = slot_ctx->dev_info; - - /* Store the usb_device pointer for later use */ - ep->hcpriv = udev; - - xhci_dbg(xhci, "add ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x, new slot info = %#x\n", - (unsigned int) ep->desc.bEndpointAddress, - udev->slot_id, - (unsigned int) new_drop_flags, - (unsigned int) new_add_flags, - (unsigned int) new_slot_info); - return 0; -} - -static void xhci_zero_in_ctx(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev) -{ - struct xhci_input_control_ctx *ctrl_ctx; - struct xhci_ep_ctx *ep_ctx; - struct xhci_slot_ctx *slot_ctx; - int i; - - /* When a device's add flag and drop flag are zero, any subsequent - * configure endpoint command will leave that endpoint's state - * untouched. Make sure we don't leave any old state in the input - * endpoint contexts. - */ - ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); - ctrl_ctx->drop_flags = 0; - ctrl_ctx->add_flags = 0; - slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx); - slot_ctx->dev_info &= ~LAST_CTX_MASK; - /* Endpoint 0 is always valid */ - slot_ctx->dev_info |= LAST_CTX(1); - for (i = 1; i < 31; ++i) { - ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, i); - ep_ctx->ep_info = 0; - ep_ctx->ep_info2 = 0; - ep_ctx->deq = 0; - ep_ctx->tx_info = 0; - } -} - -static int xhci_configure_endpoint_result(struct xhci_hcd *xhci, - struct usb_device *udev, int *cmd_status) -{ - int ret; - - switch (*cmd_status) { - case COMP_ENOMEM: - dev_warn(&udev->dev, "Not enough host controller resources " - "for new device state.\n"); - ret = -ENOMEM; - /* FIXME: can we allocate more resources for the HC? */ - break; - case COMP_BW_ERR: - dev_warn(&udev->dev, "Not enough bandwidth " - "for new device state.\n"); - ret = -ENOSPC; - /* FIXME: can we go back to the old state? */ - break; - case COMP_TRB_ERR: - /* the HCD set up something wrong */ - dev_warn(&udev->dev, "ERROR: Endpoint drop flag = 0, " - "add flag = 1, " - "and endpoint is not disabled.\n"); - ret = -EINVAL; - break; - case COMP_SUCCESS: - dev_dbg(&udev->dev, "Successful Endpoint Configure command\n"); - ret = 0; - break; - default: - xhci_err(xhci, "ERROR: unexpected command completion " - "code 0x%x.\n", *cmd_status); - ret = -EINVAL; - break; - } - return ret; -} - -static int xhci_evaluate_context_result(struct xhci_hcd *xhci, - struct usb_device *udev, int *cmd_status) -{ - int ret; - struct xhci_virt_device *virt_dev = xhci->devs[udev->slot_id]; - - switch (*cmd_status) { - case COMP_EINVAL: - dev_warn(&udev->dev, "WARN: xHCI driver setup invalid evaluate " - "context command.\n"); - ret = -EINVAL; - break; - case COMP_EBADSLT: - dev_warn(&udev->dev, "WARN: slot not enabled for" - "evaluate context command.\n"); - case COMP_CTX_STATE: - dev_warn(&udev->dev, "WARN: invalid context state for " - "evaluate context command.\n"); - xhci_dbg_ctx(xhci, virt_dev->out_ctx, 1); - ret = -EINVAL; - break; - case COMP_SUCCESS: - dev_dbg(&udev->dev, "Successful evaluate context command\n"); - ret = 0; - break; - default: - xhci_err(xhci, "ERROR: unexpected command completion " - "code 0x%x.\n", *cmd_status); - ret = -EINVAL; - break; - } - return ret; -} - -/* Issue a configure endpoint command or evaluate context command - * and wait for it to finish. - */ -static int xhci_configure_endpoint(struct xhci_hcd *xhci, - struct usb_device *udev, - struct xhci_command *command, - bool ctx_change, bool must_succeed) -{ - int ret; - int timeleft; - unsigned long flags; - struct xhci_container_ctx *in_ctx; - struct completion *cmd_completion; - int *cmd_status; - struct xhci_virt_device *virt_dev; - - spin_lock_irqsave(&xhci->lock, flags); - virt_dev = xhci->devs[udev->slot_id]; - if (command) { - in_ctx = command->in_ctx; - cmd_completion = command->completion; - cmd_status = &command->status; - command->command_trb = xhci->cmd_ring->enqueue; - list_add_tail(&command->cmd_list, &virt_dev->cmd_list); - } else { - in_ctx = virt_dev->in_ctx; - cmd_completion = &virt_dev->cmd_completion; - cmd_status = &virt_dev->cmd_status; - } - - if (!ctx_change) - ret = xhci_queue_configure_endpoint(xhci, in_ctx->dma, - udev->slot_id, must_succeed); - else - ret = xhci_queue_evaluate_context(xhci, in_ctx->dma, - udev->slot_id); - if (ret < 0) { - if (command) - list_del(&command->cmd_list); - spin_unlock_irqrestore(&xhci->lock, flags); - xhci_dbg(xhci, "FIXME allocate a new ring segment\n"); - return -ENOMEM; - } - xhci_ring_cmd_db(xhci); - spin_unlock_irqrestore(&xhci->lock, flags); - - /* Wait for the configure endpoint command to complete */ - timeleft = wait_for_completion_interruptible_timeout( - cmd_completion, - USB_CTRL_SET_TIMEOUT); - if (timeleft <= 0) { - xhci_warn(xhci, "%s while waiting for %s command\n", - timeleft == 0 ? "Timeout" : "Signal", - ctx_change == 0 ? - "configure endpoint" : - "evaluate context"); - /* FIXME cancel the configure endpoint command */ - return -ETIME; - } - - if (!ctx_change) - return xhci_configure_endpoint_result(xhci, udev, cmd_status); - return xhci_evaluate_context_result(xhci, udev, cmd_status); -} - -/* Called after one or more calls to xhci_add_endpoint() or - * xhci_drop_endpoint(). If this call fails, the USB core is expected - * to call xhci_reset_bandwidth(). - * - * Since we are in the middle of changing either configuration or - * installing a new alt setting, the USB core won't allow URBs to be - * enqueued for any endpoint on the old config or interface. Nothing - * else should be touching the xhci->devs[slot_id] structure, so we - * don't need to take the xhci->lock for manipulating that. - */ -int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) -{ - int i; - int ret = 0; - struct xhci_hcd *xhci; - struct xhci_virt_device *virt_dev; - struct xhci_input_control_ctx *ctrl_ctx; - struct xhci_slot_ctx *slot_ctx; - - ret = xhci_check_args(hcd, udev, NULL, 0, __func__); - if (ret <= 0) - return ret; - xhci = hcd_to_xhci(hcd); - - if (!udev->slot_id || !xhci->devs || !xhci->devs[udev->slot_id]) { - xhci_warn(xhci, "xHCI %s called with unaddressed device\n", - __func__); - return -EINVAL; - } - xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); - virt_dev = xhci->devs[udev->slot_id]; - - /* See section 4.6.6 - A0 = 1; A1 = D0 = D1 = 0 */ - ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); - ctrl_ctx->add_flags |= SLOT_FLAG; - ctrl_ctx->add_flags &= ~EP0_FLAG; - ctrl_ctx->drop_flags &= ~SLOT_FLAG; - ctrl_ctx->drop_flags &= ~EP0_FLAG; - xhci_dbg(xhci, "New Input Control Context:\n"); - slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx); - xhci_dbg_ctx(xhci, virt_dev->in_ctx, - LAST_CTX_TO_EP_NUM(slot_ctx->dev_info)); - - ret = xhci_configure_endpoint(xhci, udev, NULL, - false, false); - if (ret) { - /* Callee should call reset_bandwidth() */ - return ret; - } - - xhci_dbg(xhci, "Output context after successful config ep cmd:\n"); - xhci_dbg_ctx(xhci, virt_dev->out_ctx, - LAST_CTX_TO_EP_NUM(slot_ctx->dev_info)); - - xhci_zero_in_ctx(xhci, virt_dev); - /* Install new rings and free or cache any old rings */ - for (i = 1; i < 31; ++i) { - if (!virt_dev->eps[i].new_ring) - continue; - /* Only cache or free the old ring if it exists. - * It may not if this is the first add of an endpoint. - */ - if (virt_dev->eps[i].ring) { - xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); - } - virt_dev->eps[i].ring = virt_dev->eps[i].new_ring; - virt_dev->eps[i].new_ring = NULL; - } - - return ret; -} - -void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) -{ - struct xhci_hcd *xhci; - struct xhci_virt_device *virt_dev; - int i, ret; - - ret = xhci_check_args(hcd, udev, NULL, 0, __func__); - if (ret <= 0) - return; - xhci = hcd_to_xhci(hcd); - - if (!xhci->devs || !xhci->devs[udev->slot_id]) { - xhci_warn(xhci, "xHCI %s called with unaddressed device\n", - __func__); - return; - } - xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); - virt_dev = xhci->devs[udev->slot_id]; - /* Free any rings allocated for added endpoints */ - for (i = 0; i < 31; ++i) { - if (virt_dev->eps[i].new_ring) { - xhci_ring_free(xhci, virt_dev->eps[i].new_ring); - virt_dev->eps[i].new_ring = NULL; - } - } - xhci_zero_in_ctx(xhci, virt_dev); -} - -static void xhci_setup_input_ctx_for_config_ep(struct xhci_hcd *xhci, - struct xhci_container_ctx *in_ctx, - struct xhci_container_ctx *out_ctx, - u32 add_flags, u32 drop_flags) -{ - struct xhci_input_control_ctx *ctrl_ctx; - ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); - ctrl_ctx->add_flags = add_flags; - ctrl_ctx->drop_flags = drop_flags; - xhci_slot_copy(xhci, in_ctx, out_ctx); - ctrl_ctx->add_flags |= SLOT_FLAG; - - xhci_dbg(xhci, "Input Context:\n"); - xhci_dbg_ctx(xhci, in_ctx, xhci_last_valid_endpoint(add_flags)); -} - -void xhci_setup_input_ctx_for_quirk(struct xhci_hcd *xhci, - unsigned int slot_id, unsigned int ep_index, - struct xhci_dequeue_state *deq_state) -{ - struct xhci_container_ctx *in_ctx; - struct xhci_ep_ctx *ep_ctx; - u32 added_ctxs; - dma_addr_t addr; - - xhci_endpoint_copy(xhci, xhci->devs[slot_id]->in_ctx, - xhci->devs[slot_id]->out_ctx, ep_index); - in_ctx = xhci->devs[slot_id]->in_ctx; - ep_ctx = xhci_get_ep_ctx(xhci, in_ctx, ep_index); - addr = xhci_trb_virt_to_dma(deq_state->new_deq_seg, - deq_state->new_deq_ptr); - if (addr == 0) { - xhci_warn(xhci, "WARN Cannot submit config ep after " - "reset ep command\n"); - xhci_warn(xhci, "WARN deq seg = %p, deq ptr = %p\n", - deq_state->new_deq_seg, - deq_state->new_deq_ptr); - return; - } - ep_ctx->deq = addr | deq_state->new_cycle_state; - - added_ctxs = xhci_get_endpoint_flag_from_index(ep_index); - xhci_setup_input_ctx_for_config_ep(xhci, xhci->devs[slot_id]->in_ctx, - xhci->devs[slot_id]->out_ctx, added_ctxs, added_ctxs); -} - -void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, - struct usb_device *udev, unsigned int ep_index) -{ - struct xhci_dequeue_state deq_state; - struct xhci_virt_ep *ep; - - xhci_dbg(xhci, "Cleaning up stalled endpoint ring\n"); - ep = &xhci->devs[udev->slot_id]->eps[ep_index]; - /* We need to move the HW's dequeue pointer past this TD, - * or it will attempt to resend it on the next doorbell ring. - */ - xhci_find_new_dequeue_state(xhci, udev->slot_id, - ep_index, ep->stopped_td, - &deq_state); - - /* HW with the reset endpoint quirk will use the saved dequeue state to - * issue a configure endpoint command later. - */ - if (!(xhci->quirks & XHCI_RESET_EP_QUIRK)) { - xhci_dbg(xhci, "Queueing new dequeue state\n"); - xhci_queue_new_dequeue_state(xhci, udev->slot_id, - ep_index, &deq_state); - } else { - /* Better hope no one uses the input context between now and the - * reset endpoint completion! - */ - xhci_dbg(xhci, "Setting up input context for " - "configure endpoint command\n"); - xhci_setup_input_ctx_for_quirk(xhci, udev->slot_id, - ep_index, &deq_state); - } -} - -/* Deal with stalled endpoints. The core should have sent the control message - * to clear the halt condition. However, we need to make the xHCI hardware - * reset its sequence number, since a device will expect a sequence number of - * zero after the halt condition is cleared. - * Context: in_interrupt - */ -void xhci_endpoint_reset(struct usb_hcd *hcd, - struct usb_host_endpoint *ep) -{ - struct xhci_hcd *xhci; - struct usb_device *udev; - unsigned int ep_index; - unsigned long flags; - int ret; - struct xhci_virt_ep *virt_ep; - - xhci = hcd_to_xhci(hcd); - udev = (struct usb_device *) ep->hcpriv; - /* Called with a root hub endpoint (or an endpoint that wasn't added - * with xhci_add_endpoint() - */ - if (!ep->hcpriv) - return; - ep_index = xhci_get_endpoint_index(&ep->desc); - virt_ep = &xhci->devs[udev->slot_id]->eps[ep_index]; - if (!virt_ep->stopped_td) { - xhci_dbg(xhci, "Endpoint 0x%x not halted, refusing to reset.\n", - ep->desc.bEndpointAddress); - return; - } - if (usb_endpoint_xfer_control(&ep->desc)) { - xhci_dbg(xhci, "Control endpoint stall already handled.\n"); - return; - } - - xhci_dbg(xhci, "Queueing reset endpoint command\n"); - spin_lock_irqsave(&xhci->lock, flags); - ret = xhci_queue_reset_ep(xhci, udev->slot_id, ep_index); - /* - * Can't change the ring dequeue pointer until it's transitioned to the - * stopped state, which is only upon a successful reset endpoint - * command. Better hope that last command worked! - */ - if (!ret) { - xhci_cleanup_stalled_ring(xhci, udev, ep_index); - kfree(virt_ep->stopped_td); - xhci_ring_cmd_db(xhci); - } - spin_unlock_irqrestore(&xhci->lock, flags); - - if (ret) - xhci_warn(xhci, "FIXME allocate a new ring segment\n"); -} - -/* - * This submits a Reset Device Command, which will set the device state to 0, - * set the device address to 0, and disable all the endpoints except the default - * control endpoint. The USB core should come back and call - * xhci_address_device(), and then re-set up the configuration. If this is - * called because of a usb_reset_and_verify_device(), then the old alternate - * settings will be re-installed through the normal bandwidth allocation - * functions. - * - * Wait for the Reset Device command to finish. Remove all structures - * associated with the endpoints that were disabled. Clear the input device - * structure? Cache the rings? Reset the control endpoint 0 max packet size? - */ -int xhci_reset_device(struct usb_hcd *hcd, struct usb_device *udev) -{ - int ret, i; - unsigned long flags; - struct xhci_hcd *xhci; - unsigned int slot_id; - struct xhci_virt_device *virt_dev; - struct xhci_command *reset_device_cmd; - int timeleft; - int last_freed_endpoint; - - ret = xhci_check_args(hcd, udev, NULL, 0, __func__); - if (ret <= 0) - return ret; - xhci = hcd_to_xhci(hcd); - slot_id = udev->slot_id; - virt_dev = xhci->devs[slot_id]; - if (!virt_dev) { - xhci_dbg(xhci, "%s called with invalid slot ID %u\n", - __func__, slot_id); - return -EINVAL; - } - - xhci_dbg(xhci, "Resetting device with slot ID %u\n", slot_id); - /* Allocate the command structure that holds the struct completion. - * Assume we're in process context, since the normal device reset - * process has to wait for the device anyway. Storage devices are - * reset as part of error handling, so use GFP_NOIO instead of - * GFP_KERNEL. - */ - reset_device_cmd = xhci_alloc_command(xhci, false, true, GFP_NOIO); - if (!reset_device_cmd) { - xhci_dbg(xhci, "Couldn't allocate command structure.\n"); - return -ENOMEM; - } - - /* Attempt to submit the Reset Device command to the command ring */ - spin_lock_irqsave(&xhci->lock, flags); - reset_device_cmd->command_trb = xhci->cmd_ring->enqueue; - list_add_tail(&reset_device_cmd->cmd_list, &virt_dev->cmd_list); - ret = xhci_queue_reset_device(xhci, slot_id); - if (ret) { - xhci_dbg(xhci, "FIXME: allocate a command ring segment\n"); - list_del(&reset_device_cmd->cmd_list); - spin_unlock_irqrestore(&xhci->lock, flags); - goto command_cleanup; - } - xhci_ring_cmd_db(xhci); - spin_unlock_irqrestore(&xhci->lock, flags); - - /* Wait for the Reset Device command to finish */ - timeleft = wait_for_completion_interruptible_timeout( - reset_device_cmd->completion, - USB_CTRL_SET_TIMEOUT); - if (timeleft <= 0) { - xhci_warn(xhci, "%s while waiting for reset device command\n", - timeleft == 0 ? "Timeout" : "Signal"); - spin_lock_irqsave(&xhci->lock, flags); - /* The timeout might have raced with the event ring handler, so - * only delete from the list if the item isn't poisoned. - */ - if (reset_device_cmd->cmd_list.next != LIST_POISON1) - list_del(&reset_device_cmd->cmd_list); - spin_unlock_irqrestore(&xhci->lock, flags); - ret = -ETIME; - goto command_cleanup; - } - - /* The Reset Device command can't fail, according to the 0.95/0.96 spec, - * unless we tried to reset a slot ID that wasn't enabled, - * or the device wasn't in the addressed or configured state. - */ - ret = reset_device_cmd->status; - switch (ret) { - case COMP_EBADSLT: /* 0.95 completion code for bad slot ID */ - case COMP_CTX_STATE: /* 0.96 completion code for same thing */ - xhci_info(xhci, "Can't reset device (slot ID %u) in %s state\n", - slot_id, - xhci_get_slot_state(xhci, virt_dev->out_ctx)); - xhci_info(xhci, "Not freeing device rings.\n"); - /* Don't treat this as an error. May change my mind later. */ - ret = 0; - goto command_cleanup; - case COMP_SUCCESS: - xhci_dbg(xhci, "Successful reset device command.\n"); - break; - default: - if (xhci_is_vendor_info_code(xhci, ret)) - break; - xhci_warn(xhci, "Unknown completion code %u for " - "reset device command.\n", ret); - ret = -EINVAL; - goto command_cleanup; - } - - /* Everything but endpoint 0 is disabled, so free or cache the rings. */ - last_freed_endpoint = 1; - for (i = 1; i < 31; ++i) { - if (!virt_dev->eps[i].ring) - continue; - xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); - last_freed_endpoint = i; - } - xhci_dbg(xhci, "Output context after successful reset device cmd:\n"); - xhci_dbg_ctx(xhci, virt_dev->out_ctx, last_freed_endpoint); - ret = 0; - -command_cleanup: - xhci_free_command(xhci, reset_device_cmd); - return ret; -} - -/* - * At this point, the struct usb_device is about to go away, the device has - * disconnected, and all traffic has been stopped and the endpoints have been - * disabled. Free any HC data structures associated with that device. - */ -void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev) -{ - struct xhci_hcd *xhci = hcd_to_xhci(hcd); - struct xhci_virt_device *virt_dev; - unsigned long flags; - u32 state; - int i; - - if (udev->slot_id == 0) - return; - virt_dev = xhci->devs[udev->slot_id]; - if (!virt_dev) - return; - - /* Stop any wayward timer functions (which may grab the lock) */ - for (i = 0; i < 31; ++i) { - virt_dev->eps[i].ep_state &= ~EP_HALT_PENDING; - del_timer_sync(&virt_dev->eps[i].stop_cmd_timer); - } - - spin_lock_irqsave(&xhci->lock, flags); - /* Don't disable the slot if the host controller is dead. */ - state = xhci_readl(xhci, &xhci->op_regs->status); - if (state == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING)) { - xhci_free_virt_device(xhci, udev->slot_id); - spin_unlock_irqrestore(&xhci->lock, flags); - return; - } - - if (xhci_queue_slot_control(xhci, TRB_DISABLE_SLOT, udev->slot_id)) { - spin_unlock_irqrestore(&xhci->lock, flags); - xhci_dbg(xhci, "FIXME: allocate a command ring segment\n"); - return; - } - xhci_ring_cmd_db(xhci); - spin_unlock_irqrestore(&xhci->lock, flags); - /* - * Event command completion handler will free any data structures - * associated with the slot. XXX Can free sleep? - */ -} - -/* - * Returns 0 if the xHC ran out of device slots, the Enable Slot command - * timed out, or allocating memory failed. Returns 1 on success. - */ -int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) -{ - struct xhci_hcd *xhci = hcd_to_xhci(hcd); - unsigned long flags; - int timeleft; - int ret; - - spin_lock_irqsave(&xhci->lock, flags); - ret = xhci_queue_slot_control(xhci, TRB_ENABLE_SLOT, 0); - if (ret) { - spin_unlock_irqrestore(&xhci->lock, flags); - xhci_dbg(xhci, "FIXME: allocate a command ring segment\n"); - return 0; - } - xhci_ring_cmd_db(xhci); - spin_unlock_irqrestore(&xhci->lock, flags); - - /* XXX: how much time for xHC slot assignment? */ - timeleft = wait_for_completion_interruptible_timeout(&xhci->addr_dev, - USB_CTRL_SET_TIMEOUT); - if (timeleft <= 0) { - xhci_warn(xhci, "%s while waiting for a slot\n", - timeleft == 0 ? "Timeout" : "Signal"); - /* FIXME cancel the enable slot request */ - return 0; - } - - if (!xhci->slot_id) { - xhci_err(xhci, "Error while assigning device slot ID\n"); - return 0; - } - /* xhci_alloc_virt_device() does not touch rings; no need to lock */ - if (!xhci_alloc_virt_device(xhci, xhci->slot_id, udev, GFP_KERNEL)) { - /* Disable slot, if we can do it without mem alloc */ - xhci_warn(xhci, "Could not allocate xHCI USB device data structures\n"); - spin_lock_irqsave(&xhci->lock, flags); - if (!xhci_queue_slot_control(xhci, TRB_DISABLE_SLOT, udev->slot_id)) - xhci_ring_cmd_db(xhci); - spin_unlock_irqrestore(&xhci->lock, flags); - return 0; - } - udev->slot_id = xhci->slot_id; - /* Is this a LS or FS device under a HS hub? */ - /* Hub or peripherial? */ - return 1; -} - -/* - * Issue an Address Device command (which will issue a SetAddress request to - * the device). - * We should be protected by the usb_address0_mutex in khubd's hub_port_init, so - * we should only issue and wait on one address command at the same time. - * - * We add one to the device address issued by the hardware because the USB core - * uses address 1 for the root hubs (even though they're not really devices). - */ -int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) -{ - unsigned long flags; - int timeleft; - struct xhci_virt_device *virt_dev; - int ret = 0; - struct xhci_hcd *xhci = hcd_to_xhci(hcd); - struct xhci_slot_ctx *slot_ctx; - struct xhci_input_control_ctx *ctrl_ctx; - u64 temp_64; - - if (!udev->slot_id) { - xhci_dbg(xhci, "Bad Slot ID %d\n", udev->slot_id); - return -EINVAL; - } - - virt_dev = xhci->devs[udev->slot_id]; - - /* If this is a Set Address to an unconfigured device, setup ep 0 */ - if (!udev->config) - xhci_setup_addressable_virt_dev(xhci, udev); - /* Otherwise, assume the core has the device configured how it wants */ - xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id); - xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2); - - spin_lock_irqsave(&xhci->lock, flags); - ret = xhci_queue_address_device(xhci, virt_dev->in_ctx->dma, - udev->slot_id); - if (ret) { - spin_unlock_irqrestore(&xhci->lock, flags); - xhci_dbg(xhci, "FIXME: allocate a command ring segment\n"); - return ret; - } - xhci_ring_cmd_db(xhci); - spin_unlock_irqrestore(&xhci->lock, flags); - - /* ctrl tx can take up to 5 sec; XXX: need more time for xHC? */ - timeleft = wait_for_completion_interruptible_timeout(&xhci->addr_dev, - USB_CTRL_SET_TIMEOUT); - /* FIXME: From section 4.3.4: "Software shall be responsible for timing - * the SetAddress() "recovery interval" required by USB and aborting the - * command on a timeout. - */ - if (timeleft <= 0) { - xhci_warn(xhci, "%s while waiting for a slot\n", - timeleft == 0 ? "Timeout" : "Signal"); - /* FIXME cancel the address device command */ - return -ETIME; - } - - switch (virt_dev->cmd_status) { - case COMP_CTX_STATE: - case COMP_EBADSLT: - xhci_err(xhci, "Setup ERROR: address device command for slot %d.\n", - udev->slot_id); - ret = -EINVAL; - break; - case COMP_TX_ERR: - dev_warn(&udev->dev, "Device not responding to set address.\n"); - ret = -EPROTO; - break; - case COMP_SUCCESS: - xhci_dbg(xhci, "Successful Address Device command\n"); - break; - default: - xhci_err(xhci, "ERROR: unexpected command completion " - "code 0x%x.\n", virt_dev->cmd_status); - xhci_dbg(xhci, "Slot ID %d Output Context:\n", udev->slot_id); - xhci_dbg_ctx(xhci, virt_dev->out_ctx, 2); - ret = -EINVAL; - break; - } - if (ret) { - return ret; - } - temp_64 = xhci_read_64(xhci, &xhci->op_regs->dcbaa_ptr); - xhci_dbg(xhci, "Op regs DCBAA ptr = %#016llx\n", temp_64); - xhci_dbg(xhci, "Slot ID %d dcbaa entry @%p = %#016llx\n", - udev->slot_id, - &xhci->dcbaa->dev_context_ptrs[udev->slot_id], - (unsigned long long) - xhci->dcbaa->dev_context_ptrs[udev->slot_id]); - xhci_dbg(xhci, "Output Context DMA address = %#08llx\n", - (unsigned long long)virt_dev->out_ctx->dma); - xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id); - xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2); - xhci_dbg(xhci, "Slot ID %d Output Context:\n", udev->slot_id); - xhci_dbg_ctx(xhci, virt_dev->out_ctx, 2); - /* - * USB core uses address 1 for the roothubs, so we add one to the - * address given back to us by the HC. - */ - slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->out_ctx); - udev->devnum = (slot_ctx->dev_state & DEV_ADDR_MASK) + 1; - /* Zero the input context control for later use */ - ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); - ctrl_ctx->add_flags = 0; - ctrl_ctx->drop_flags = 0; - - xhci_dbg(xhci, "Device address = %d\n", udev->devnum); - /* XXX Meh, not sure if anyone else but choose_address uses this. */ - set_bit(udev->devnum, udev->bus->devmap.devicemap); - - return 0; -} - -/* Once a hub descriptor is fetched for a device, we need to update the xHC's - * internal data structures for the device. - */ -int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev, - struct usb_tt *tt, gfp_t mem_flags) -{ - struct xhci_hcd *xhci = hcd_to_xhci(hcd); - struct xhci_virt_device *vdev; - struct xhci_command *config_cmd; - struct xhci_input_control_ctx *ctrl_ctx; - struct xhci_slot_ctx *slot_ctx; - unsigned long flags; - unsigned think_time; - int ret; - - /* Ignore root hubs */ - if (!hdev->parent) - return 0; - - vdev = xhci->devs[hdev->slot_id]; - if (!vdev) { - xhci_warn(xhci, "Cannot update hub desc for unknown device.\n"); - return -EINVAL; - } - config_cmd = xhci_alloc_command(xhci, true, true, mem_flags); - if (!config_cmd) { - xhci_dbg(xhci, "Could not allocate xHCI command structure.\n"); - return -ENOMEM; - } - - spin_lock_irqsave(&xhci->lock, flags); - xhci_slot_copy(xhci, config_cmd->in_ctx, vdev->out_ctx); - ctrl_ctx = xhci_get_input_control_ctx(xhci, config_cmd->in_ctx); - ctrl_ctx->add_flags |= SLOT_FLAG; - slot_ctx = xhci_get_slot_ctx(xhci, config_cmd->in_ctx); - slot_ctx->dev_info |= DEV_HUB; - if (tt->multi) - slot_ctx->dev_info |= DEV_MTT; - if (xhci->hci_version > 0x95) { - xhci_dbg(xhci, "xHCI version %x needs hub " - "TT think time and number of ports\n", - (unsigned int) xhci->hci_version); - slot_ctx->dev_info2 |= XHCI_MAX_PORTS(hdev->maxchild); - /* Set TT think time - convert from ns to FS bit times. - * 0 = 8 FS bit times, 1 = 16 FS bit times, - * 2 = 24 FS bit times, 3 = 32 FS bit times. - */ - think_time = tt->think_time; - if (think_time != 0) - think_time = (think_time / 666) - 1; - slot_ctx->tt_info |= TT_THINK_TIME(think_time); - } else { - xhci_dbg(xhci, "xHCI version %x doesn't need hub " - "TT think time or number of ports\n", - (unsigned int) xhci->hci_version); - } - slot_ctx->dev_state = 0; - spin_unlock_irqrestore(&xhci->lock, flags); - - xhci_dbg(xhci, "Set up %s for hub device.\n", - (xhci->hci_version > 0x95) ? - "configure endpoint" : "evaluate context"); - xhci_dbg(xhci, "Slot %u Input Context:\n", hdev->slot_id); - xhci_dbg_ctx(xhci, config_cmd->in_ctx, 0); - - /* Issue and wait for the configure endpoint or - * evaluate context command. - */ - if (xhci->hci_version > 0x95) - ret = xhci_configure_endpoint(xhci, hdev, config_cmd, - false, false); - else - ret = xhci_configure_endpoint(xhci, hdev, config_cmd, - true, false); - - xhci_dbg(xhci, "Slot %u Output Context:\n", hdev->slot_id); - xhci_dbg_ctx(xhci, vdev->out_ctx, 0); - - xhci_free_command(xhci, config_cmd); - return ret; -} - -int xhci_get_frame(struct usb_hcd *hcd) -{ - struct xhci_hcd *xhci = hcd_to_xhci(hcd); - /* EHCI mods by the periodic size. Why? */ - return xhci_readl(xhci, &xhci->run_regs->microframe_index) >> 3; -} - -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_LICENSE("GPL"); - -static int __init xhci_hcd_init(void) -{ -#ifdef CONFIG_PCI - int retval = 0; - - retval = xhci_register_pci(); - - if (retval < 0) { - printk(KERN_DEBUG "Problem registering PCI driver."); - return retval; - } -#endif - /* - * Check the compiler generated sizes of structures that must be laid - * out in specific ways for hardware access. - */ - BUILD_BUG_ON(sizeof(struct xhci_doorbell_array) != 256*32/8); - BUILD_BUG_ON(sizeof(struct xhci_slot_ctx) != 8*32/8); - BUILD_BUG_ON(sizeof(struct xhci_ep_ctx) != 8*32/8); - /* xhci_device_control has eight fields, and also - * embeds one xhci_slot_ctx and 31 xhci_ep_ctx - */ - BUILD_BUG_ON(sizeof(struct xhci_stream_ctx) != 4*32/8); - BUILD_BUG_ON(sizeof(union xhci_trb) != 4*32/8); - BUILD_BUG_ON(sizeof(struct xhci_erst_entry) != 4*32/8); - BUILD_BUG_ON(sizeof(struct xhci_cap_regs) != 7*32/8); - BUILD_BUG_ON(sizeof(struct xhci_intr_reg) != 8*32/8); - /* xhci_run_regs has eight fields and embeds 128 xhci_intr_regs */ - BUILD_BUG_ON(sizeof(struct xhci_run_regs) != (8+8*128)*32/8); - BUILD_BUG_ON(sizeof(struct xhci_doorbell_array) != 256*32/8); - return 0; -} -module_init(xhci_hcd_init); - -static void __exit xhci_hcd_cleanup(void) -{ -#ifdef CONFIG_PCI - xhci_unregister_pci(); -#endif -} -module_exit(xhci_hcd_cleanup); diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c new file mode 100644 index 0000000..4cb69e0 --- /dev/null +++ b/drivers/usb/host/xhci.c @@ -0,0 +1,1916 @@ +/* + * xHCI host controller driver + * + * Copyright (C) 2008 Intel Corp. + * + * Author: Sarah Sharp + * Some code borrowed from the Linux EHCI driver. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include + +#include "xhci.h" + +#define DRIVER_AUTHOR "Sarah Sharp" +#define DRIVER_DESC "'eXtensible' Host Controller (xHC) Driver" + +/* Some 0.95 hardware can't handle the chain bit on a Link TRB being cleared */ +static int link_quirk; +module_param(link_quirk, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(link_quirk, "Don't clear the chain bit on a link TRB"); + +/* TODO: copied from ehci-hcd.c - can this be refactored? */ +/* + * handshake - spin reading hc until handshake completes or fails + * @ptr: address of hc register to be read + * @mask: bits to look at in result of read + * @done: value of those bits when handshake succeeds + * @usec: timeout in microseconds + * + * Returns negative errno, or zero on success + * + * Success happens when the "mask" bits have the specified value (hardware + * handshake done). There are two failure modes: "usec" have passed (major + * hardware flakeout), or the register reads as all-ones (hardware removed). + */ +static int handshake(struct xhci_hcd *xhci, void __iomem *ptr, + u32 mask, u32 done, int usec) +{ + u32 result; + + do { + result = xhci_readl(xhci, ptr); + if (result == ~(u32)0) /* card removed */ + return -ENODEV; + result &= mask; + if (result == done) + return 0; + udelay(1); + usec--; + } while (usec > 0); + return -ETIMEDOUT; +} + +/* + * Disable interrupts and begin the xHCI halting process. + */ +void xhci_quiesce(struct xhci_hcd *xhci) +{ + u32 halted; + u32 cmd; + u32 mask; + + mask = ~(XHCI_IRQS); + halted = xhci_readl(xhci, &xhci->op_regs->status) & STS_HALT; + if (!halted) + mask &= ~CMD_RUN; + + cmd = xhci_readl(xhci, &xhci->op_regs->command); + cmd &= mask; + xhci_writel(xhci, cmd, &xhci->op_regs->command); +} + +/* + * Force HC into halt state. + * + * Disable any IRQs and clear the run/stop bit. + * HC will complete any current and actively pipelined transactions, and + * should halt within 16 microframes of the run/stop bit being cleared. + * Read HC Halted bit in the status register to see when the HC is finished. + * XXX: shouldn't we set HC_STATE_HALT here somewhere? + */ +int xhci_halt(struct xhci_hcd *xhci) +{ + xhci_dbg(xhci, "// Halt the HC\n"); + xhci_quiesce(xhci); + + return handshake(xhci, &xhci->op_regs->status, + STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC); +} + +/* + * Reset a halted HC, and set the internal HC state to HC_STATE_HALT. + * + * This resets pipelines, timers, counters, state machines, etc. + * Transactions will be terminated immediately, and operational registers + * will be set to their defaults. + */ +int xhci_reset(struct xhci_hcd *xhci) +{ + u32 command; + u32 state; + + state = xhci_readl(xhci, &xhci->op_regs->status); + if ((state & STS_HALT) == 0) { + xhci_warn(xhci, "Host controller not halted, aborting reset.\n"); + return 0; + } + + xhci_dbg(xhci, "// Reset the HC\n"); + command = xhci_readl(xhci, &xhci->op_regs->command); + command |= CMD_RESET; + xhci_writel(xhci, command, &xhci->op_regs->command); + /* XXX: Why does EHCI set this here? Shouldn't other code do this? */ + xhci_to_hcd(xhci)->state = HC_STATE_HALT; + + return handshake(xhci, &xhci->op_regs->command, CMD_RESET, 0, 250 * 1000); +} + + +#if 0 +/* Set up MSI-X table for entry 0 (may claim other entries later) */ +static int xhci_setup_msix(struct xhci_hcd *xhci) +{ + int ret; + struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); + + xhci->msix_count = 0; + /* XXX: did I do this right? ixgbe does kcalloc for more than one */ + xhci->msix_entries = kmalloc(sizeof(struct msix_entry), GFP_KERNEL); + if (!xhci->msix_entries) { + xhci_err(xhci, "Failed to allocate MSI-X entries\n"); + return -ENOMEM; + } + xhci->msix_entries[0].entry = 0; + + ret = pci_enable_msix(pdev, xhci->msix_entries, xhci->msix_count); + if (ret) { + xhci_err(xhci, "Failed to enable MSI-X\n"); + goto free_entries; + } + + /* + * Pass the xhci pointer value as the request_irq "cookie". + * If more irqs are added, this will need to be unique for each one. + */ + ret = request_irq(xhci->msix_entries[0].vector, &xhci_irq, 0, + "xHCI", xhci_to_hcd(xhci)); + if (ret) { + xhci_err(xhci, "Failed to allocate MSI-X interrupt\n"); + goto disable_msix; + } + xhci_dbg(xhci, "Finished setting up MSI-X\n"); + return 0; + +disable_msix: + pci_disable_msix(pdev); +free_entries: + kfree(xhci->msix_entries); + xhci->msix_entries = NULL; + return ret; +} + +/* XXX: code duplication; can xhci_setup_msix call this? */ +/* Free any IRQs and disable MSI-X */ +static void xhci_cleanup_msix(struct xhci_hcd *xhci) +{ + struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); + if (!xhci->msix_entries) + return; + + free_irq(xhci->msix_entries[0].vector, xhci); + pci_disable_msix(pdev); + kfree(xhci->msix_entries); + xhci->msix_entries = NULL; + xhci_dbg(xhci, "Finished cleaning up MSI-X\n"); +} +#endif + +/* + * Initialize memory for HCD and xHC (one-time init). + * + * Program the PAGESIZE register, initialize the device context array, create + * device contexts (?), set up a command ring segment (or two?), create event + * ring (one for now). + */ +int xhci_init(struct usb_hcd *hcd) +{ + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + int retval = 0; + + xhci_dbg(xhci, "xhci_init\n"); + spin_lock_init(&xhci->lock); + if (link_quirk) { + xhci_dbg(xhci, "QUIRK: Not clearing Link TRB chain bits.\n"); + xhci->quirks |= XHCI_LINK_TRB_QUIRK; + } else { + xhci_dbg(xhci, "xHCI doesn't need link TRB QUIRK\n"); + } + retval = xhci_mem_init(xhci, GFP_KERNEL); + xhci_dbg(xhci, "Finished xhci_init\n"); + + return retval; +} + +/* + * Called in interrupt context when there might be work + * queued on the event ring + * + * xhci->lock must be held by caller. + */ +static void xhci_work(struct xhci_hcd *xhci) +{ + u32 temp; + u64 temp_64; + + /* + * Clear the op reg interrupt status first, + * so we can receive interrupts from other MSI-X interrupters. + * Write 1 to clear the interrupt status. + */ + temp = xhci_readl(xhci, &xhci->op_regs->status); + temp |= STS_EINT; + xhci_writel(xhci, temp, &xhci->op_regs->status); + /* FIXME when MSI-X is supported and there are multiple vectors */ + /* Clear the MSI-X event interrupt status */ + + /* Acknowledge the interrupt */ + temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); + temp |= 0x3; + xhci_writel(xhci, temp, &xhci->ir_set->irq_pending); + /* Flush posted writes */ + xhci_readl(xhci, &xhci->ir_set->irq_pending); + + if (xhci->xhc_state & XHCI_STATE_DYING) + xhci_dbg(xhci, "xHCI dying, ignoring interrupt. " + "Shouldn't IRQs be disabled?\n"); + else + /* FIXME this should be a delayed service routine + * that clears the EHB. + */ + xhci_handle_event(xhci); + + /* Clear the event handler busy flag (RW1C); the event ring should be empty. */ + temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); + xhci_write_64(xhci, temp_64 | ERST_EHB, &xhci->ir_set->erst_dequeue); + /* Flush posted writes -- FIXME is this necessary? */ + xhci_readl(xhci, &xhci->ir_set->irq_pending); +} + +/*-------------------------------------------------------------------------*/ + +/* + * xHCI spec says we can get an interrupt, and if the HC has an error condition, + * we might get bad data out of the event ring. Section 4.10.2.7 has a list of + * indicators of an event TRB error, but we check the status *first* to be safe. + */ +irqreturn_t xhci_irq(struct usb_hcd *hcd) +{ + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + u32 temp, temp2; + union xhci_trb *trb; + + spin_lock(&xhci->lock); + trb = xhci->event_ring->dequeue; + /* Check if the xHC generated the interrupt, or the irq is shared */ + temp = xhci_readl(xhci, &xhci->op_regs->status); + temp2 = xhci_readl(xhci, &xhci->ir_set->irq_pending); + if (temp == 0xffffffff && temp2 == 0xffffffff) + goto hw_died; + + if (!(temp & STS_EINT) && !ER_IRQ_PENDING(temp2)) { + spin_unlock(&xhci->lock); + return IRQ_NONE; + } + xhci_dbg(xhci, "op reg status = %08x\n", temp); + xhci_dbg(xhci, "ir set irq_pending = %08x\n", temp2); + xhci_dbg(xhci, "Event ring dequeue ptr:\n"); + xhci_dbg(xhci, "@%llx %08x %08x %08x %08x\n", + (unsigned long long)xhci_trb_virt_to_dma(xhci->event_ring->deq_seg, trb), + lower_32_bits(trb->link.segment_ptr), + upper_32_bits(trb->link.segment_ptr), + (unsigned int) trb->link.intr_target, + (unsigned int) trb->link.control); + + if (temp & STS_FATAL) { + xhci_warn(xhci, "WARNING: Host System Error\n"); + xhci_halt(xhci); +hw_died: + xhci_to_hcd(xhci)->state = HC_STATE_HALT; + spin_unlock(&xhci->lock); + return -ESHUTDOWN; + } + + xhci_work(xhci); + spin_unlock(&xhci->lock); + + return IRQ_HANDLED; +} + +#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING +void xhci_event_ring_work(unsigned long arg) +{ + unsigned long flags; + int temp; + u64 temp_64; + struct xhci_hcd *xhci = (struct xhci_hcd *) arg; + int i, j; + + xhci_dbg(xhci, "Poll event ring: %lu\n", jiffies); + + spin_lock_irqsave(&xhci->lock, flags); + temp = xhci_readl(xhci, &xhci->op_regs->status); + xhci_dbg(xhci, "op reg status = 0x%x\n", temp); + if (temp == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING)) { + xhci_dbg(xhci, "HW died, polling stopped.\n"); + spin_unlock_irqrestore(&xhci->lock, flags); + return; + } + + temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); + xhci_dbg(xhci, "ir_set 0 pending = 0x%x\n", temp); + xhci_dbg(xhci, "No-op commands handled = %d\n", xhci->noops_handled); + xhci_dbg(xhci, "HC error bitmask = 0x%x\n", xhci->error_bitmask); + xhci->error_bitmask = 0; + xhci_dbg(xhci, "Event ring:\n"); + xhci_debug_segment(xhci, xhci->event_ring->deq_seg); + xhci_dbg_ring_ptrs(xhci, xhci->event_ring); + temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); + temp_64 &= ~ERST_PTR_MASK; + xhci_dbg(xhci, "ERST deq = 64'h%0lx\n", (long unsigned int) temp_64); + xhci_dbg(xhci, "Command ring:\n"); + xhci_debug_segment(xhci, xhci->cmd_ring->deq_seg); + xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring); + xhci_dbg_cmd_ptrs(xhci); + for (i = 0; i < MAX_HC_SLOTS; ++i) { + if (!xhci->devs[i]) + continue; + for (j = 0; j < 31; ++j) { + struct xhci_ring *ring = xhci->devs[i]->eps[j].ring; + if (!ring) + continue; + xhci_dbg(xhci, "Dev %d endpoint ring %d:\n", i, j); + xhci_debug_segment(xhci, ring->deq_seg); + } + } + + if (xhci->noops_submitted != NUM_TEST_NOOPS) + if (xhci_setup_one_noop(xhci)) + xhci_ring_cmd_db(xhci); + spin_unlock_irqrestore(&xhci->lock, flags); + + if (!xhci->zombie) + mod_timer(&xhci->event_ring_timer, jiffies + POLL_TIMEOUT * HZ); + else + xhci_dbg(xhci, "Quit polling the event ring.\n"); +} +#endif + +/* + * Start the HC after it was halted. + * + * This function is called by the USB core when the HC driver is added. + * Its opposite is xhci_stop(). + * + * xhci_init() must be called once before this function can be called. + * Reset the HC, enable device slot contexts, program DCBAAP, and + * set command ring pointer and event ring pointer. + * + * Setup MSI-X vectors and enable interrupts. + */ +int xhci_run(struct usb_hcd *hcd) +{ + u32 temp; + u64 temp_64; + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + void (*doorbell)(struct xhci_hcd *) = NULL; + + hcd->uses_new_polling = 1; + hcd->poll_rh = 0; + + xhci_dbg(xhci, "xhci_run\n"); +#if 0 /* FIXME: MSI not setup yet */ + /* Do this at the very last minute */ + ret = xhci_setup_msix(xhci); + if (!ret) + return ret; + + return -ENOSYS; +#endif +#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING + init_timer(&xhci->event_ring_timer); + xhci->event_ring_timer.data = (unsigned long) xhci; + xhci->event_ring_timer.function = xhci_event_ring_work; + /* Poll the event ring */ + xhci->event_ring_timer.expires = jiffies + POLL_TIMEOUT * HZ; + xhci->zombie = 0; + xhci_dbg(xhci, "Setting event ring polling timer\n"); + add_timer(&xhci->event_ring_timer); +#endif + + xhci_dbg(xhci, "Command ring memory map follows:\n"); + xhci_debug_ring(xhci, xhci->cmd_ring); + xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring); + xhci_dbg_cmd_ptrs(xhci); + + xhci_dbg(xhci, "ERST memory map follows:\n"); + xhci_dbg_erst(xhci, &xhci->erst); + xhci_dbg(xhci, "Event ring:\n"); + xhci_debug_ring(xhci, xhci->event_ring); + xhci_dbg_ring_ptrs(xhci, xhci->event_ring); + temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); + temp_64 &= ~ERST_PTR_MASK; + xhci_dbg(xhci, "ERST deq = 64'h%0lx\n", (long unsigned int) temp_64); + + xhci_dbg(xhci, "// Set the interrupt modulation register\n"); + temp = xhci_readl(xhci, &xhci->ir_set->irq_control); + temp &= ~ER_IRQ_INTERVAL_MASK; + temp |= (u32) 160; + xhci_writel(xhci, temp, &xhci->ir_set->irq_control); + + /* Set the HCD state before we enable the irqs */ + hcd->state = HC_STATE_RUNNING; + temp = xhci_readl(xhci, &xhci->op_regs->command); + temp |= (CMD_EIE); + xhci_dbg(xhci, "// Enable interrupts, cmd = 0x%x.\n", + temp); + xhci_writel(xhci, temp, &xhci->op_regs->command); + + temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); + xhci_dbg(xhci, "// Enabling event ring interrupter %p by writing 0x%x to irq_pending\n", + xhci->ir_set, (unsigned int) ER_IRQ_ENABLE(temp)); + xhci_writel(xhci, ER_IRQ_ENABLE(temp), + &xhci->ir_set->irq_pending); + xhci_print_ir_set(xhci, xhci->ir_set, 0); + + if (NUM_TEST_NOOPS > 0) + doorbell = xhci_setup_one_noop(xhci); + + temp = xhci_readl(xhci, &xhci->op_regs->command); + temp |= (CMD_RUN); + xhci_dbg(xhci, "// Turn on HC, cmd = 0x%x.\n", + temp); + xhci_writel(xhci, temp, &xhci->op_regs->command); + /* Flush PCI posted writes */ + temp = xhci_readl(xhci, &xhci->op_regs->command); + xhci_dbg(xhci, "// @%p = 0x%x\n", &xhci->op_regs->command, temp); + if (doorbell) + (*doorbell)(xhci); + + xhci_dbg(xhci, "Finished xhci_run\n"); + return 0; +} + +/* + * Stop xHCI driver. + * + * This function is called by the USB core when the HC driver is removed. + * Its opposite is xhci_run(). + * + * Disable device contexts, disable IRQs, and quiesce the HC. + * Reset the HC, finish any completed transactions, and cleanup memory. + */ +void xhci_stop(struct usb_hcd *hcd) +{ + u32 temp; + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + + spin_lock_irq(&xhci->lock); + xhci_halt(xhci); + xhci_reset(xhci); + spin_unlock_irq(&xhci->lock); + +#if 0 /* No MSI yet */ + xhci_cleanup_msix(xhci); +#endif +#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING + /* Tell the event ring poll function not to reschedule */ + xhci->zombie = 1; + del_timer_sync(&xhci->event_ring_timer); +#endif + + xhci_dbg(xhci, "// Disabling event ring interrupts\n"); + temp = xhci_readl(xhci, &xhci->op_regs->status); + xhci_writel(xhci, temp & ~STS_EINT, &xhci->op_regs->status); + temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); + xhci_writel(xhci, ER_IRQ_DISABLE(temp), + &xhci->ir_set->irq_pending); + xhci_print_ir_set(xhci, xhci->ir_set, 0); + + xhci_dbg(xhci, "cleaning up memory\n"); + xhci_mem_cleanup(xhci); + xhci_dbg(xhci, "xhci_stop completed - status = %x\n", + xhci_readl(xhci, &xhci->op_regs->status)); +} + +/* + * Shutdown HC (not bus-specific) + * + * This is called when the machine is rebooting or halting. We assume that the + * machine will be powered off, and the HC's internal state will be reset. + * Don't bother to free memory. + */ +void xhci_shutdown(struct usb_hcd *hcd) +{ + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + + spin_lock_irq(&xhci->lock); + xhci_halt(xhci); + spin_unlock_irq(&xhci->lock); + +#if 0 + xhci_cleanup_msix(xhci); +#endif + + xhci_dbg(xhci, "xhci_shutdown completed - status = %x\n", + xhci_readl(xhci, &xhci->op_regs->status)); +} + +/*-------------------------------------------------------------------------*/ + +/** + * xhci_get_endpoint_index - Used for passing endpoint bitmasks between the core and + * HCDs. Find the index for an endpoint given its descriptor. Use the return + * value to right shift 1 for the bitmask. + * + * Index = (epnum * 2) + direction - 1, + * where direction = 0 for OUT, 1 for IN. + * For control endpoints, the IN index is used (OUT index is unused), so + * index = (epnum * 2) + direction - 1 = (epnum * 2) + 1 - 1 = (epnum * 2) + */ +unsigned int xhci_get_endpoint_index(struct usb_endpoint_descriptor *desc) +{ + unsigned int index; + if (usb_endpoint_xfer_control(desc)) + index = (unsigned int) (usb_endpoint_num(desc)*2); + else + index = (unsigned int) (usb_endpoint_num(desc)*2) + + (usb_endpoint_dir_in(desc) ? 1 : 0) - 1; + return index; +} + +/* Find the flag for this endpoint (for use in the control context). Use the + * endpoint index to create a bitmask. The slot context is bit 0, endpoint 0 is + * bit 1, etc. + */ +unsigned int xhci_get_endpoint_flag(struct usb_endpoint_descriptor *desc) +{ + return 1 << (xhci_get_endpoint_index(desc) + 1); +} + +/* Find the flag for this endpoint (for use in the control context). Use the + * endpoint index to create a bitmask. The slot context is bit 0, endpoint 0 is + * bit 1, etc. + */ +unsigned int xhci_get_endpoint_flag_from_index(unsigned int ep_index) +{ + return 1 << (ep_index + 1); +} + +/* Compute the last valid endpoint context index. Basically, this is the + * endpoint index plus one. For slot contexts with more than valid endpoint, + * we find the most significant bit set in the added contexts flags. + * e.g. ep 1 IN (with epnum 0x81) => added_ctxs = 0b1000 + * fls(0b1000) = 4, but the endpoint context index is 3, so subtract one. + */ +unsigned int xhci_last_valid_endpoint(u32 added_ctxs) +{ + return fls(added_ctxs) - 1; +} + +/* Returns 1 if the arguments are OK; + * returns 0 this is a root hub; returns -EINVAL for NULL pointers. + */ +int xhci_check_args(struct usb_hcd *hcd, struct usb_device *udev, + struct usb_host_endpoint *ep, int check_ep, const char *func) { + if (!hcd || (check_ep && !ep) || !udev) { + printk(KERN_DEBUG "xHCI %s called with invalid args\n", + func); + return -EINVAL; + } + if (!udev->parent) { + printk(KERN_DEBUG "xHCI %s called for root hub\n", + func); + return 0; + } + if (!udev->slot_id) { + printk(KERN_DEBUG "xHCI %s called with unaddressed device\n", + func); + return -EINVAL; + } + return 1; +} + +static int xhci_configure_endpoint(struct xhci_hcd *xhci, + struct usb_device *udev, struct xhci_command *command, + bool ctx_change, bool must_succeed); + +/* + * Full speed devices may have a max packet size greater than 8 bytes, but the + * USB core doesn't know that until it reads the first 8 bytes of the + * descriptor. If the usb_device's max packet size changes after that point, + * we need to issue an evaluate context command and wait on it. + */ +static int xhci_check_maxpacket(struct xhci_hcd *xhci, unsigned int slot_id, + unsigned int ep_index, struct urb *urb) +{ + struct xhci_container_ctx *in_ctx; + struct xhci_container_ctx *out_ctx; + struct xhci_input_control_ctx *ctrl_ctx; + struct xhci_ep_ctx *ep_ctx; + int max_packet_size; + int hw_max_packet_size; + int ret = 0; + + out_ctx = xhci->devs[slot_id]->out_ctx; + ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index); + hw_max_packet_size = MAX_PACKET_DECODED(ep_ctx->ep_info2); + max_packet_size = urb->dev->ep0.desc.wMaxPacketSize; + if (hw_max_packet_size != max_packet_size) { + xhci_dbg(xhci, "Max Packet Size for ep 0 changed.\n"); + xhci_dbg(xhci, "Max packet size in usb_device = %d\n", + max_packet_size); + xhci_dbg(xhci, "Max packet size in xHCI HW = %d\n", + hw_max_packet_size); + xhci_dbg(xhci, "Issuing evaluate context command.\n"); + + /* Set up the modified control endpoint 0 */ + xhci_endpoint_copy(xhci, xhci->devs[slot_id]->in_ctx, + xhci->devs[slot_id]->out_ctx, ep_index); + in_ctx = xhci->devs[slot_id]->in_ctx; + ep_ctx = xhci_get_ep_ctx(xhci, in_ctx, ep_index); + ep_ctx->ep_info2 &= ~MAX_PACKET_MASK; + ep_ctx->ep_info2 |= MAX_PACKET(max_packet_size); + + /* Set up the input context flags for the command */ + /* FIXME: This won't work if a non-default control endpoint + * changes max packet sizes. + */ + ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); + ctrl_ctx->add_flags = EP0_FLAG; + ctrl_ctx->drop_flags = 0; + + xhci_dbg(xhci, "Slot %d input context\n", slot_id); + xhci_dbg_ctx(xhci, in_ctx, ep_index); + xhci_dbg(xhci, "Slot %d output context\n", slot_id); + xhci_dbg_ctx(xhci, out_ctx, ep_index); + + ret = xhci_configure_endpoint(xhci, urb->dev, NULL, + true, false); + + /* Clean up the input context for later use by bandwidth + * functions. + */ + ctrl_ctx->add_flags = SLOT_FLAG; + } + return ret; +} + +/* + * non-error returns are a promise to giveback() the urb later + * we drop ownership so next owner (or urb unlink) can get it + */ +int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) +{ + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + unsigned long flags; + int ret = 0; + unsigned int slot_id, ep_index; + + + if (!urb || xhci_check_args(hcd, urb->dev, urb->ep, true, __func__) <= 0) + return -EINVAL; + + slot_id = urb->dev->slot_id; + ep_index = xhci_get_endpoint_index(&urb->ep->desc); + + if (!xhci->devs || !xhci->devs[slot_id]) { + if (!in_interrupt()) + dev_warn(&urb->dev->dev, "WARN: urb submitted for dev with no Slot ID\n"); + ret = -EINVAL; + goto exit; + } + if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) { + if (!in_interrupt()) + xhci_dbg(xhci, "urb submitted during PCI suspend\n"); + ret = -ESHUTDOWN; + goto exit; + } + if (usb_endpoint_xfer_control(&urb->ep->desc)) { + /* Check to see if the max packet size for the default control + * endpoint changed during FS device enumeration + */ + if (urb->dev->speed == USB_SPEED_FULL) { + ret = xhci_check_maxpacket(xhci, slot_id, + ep_index, urb); + if (ret < 0) + return ret; + } + + /* We have a spinlock and interrupts disabled, so we must pass + * atomic context to this function, which may allocate memory. + */ + spin_lock_irqsave(&xhci->lock, flags); + if (xhci->xhc_state & XHCI_STATE_DYING) + goto dying; + ret = xhci_queue_ctrl_tx(xhci, GFP_ATOMIC, urb, + slot_id, ep_index); + spin_unlock_irqrestore(&xhci->lock, flags); + } else if (usb_endpoint_xfer_bulk(&urb->ep->desc)) { + spin_lock_irqsave(&xhci->lock, flags); + if (xhci->xhc_state & XHCI_STATE_DYING) + goto dying; + ret = xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb, + slot_id, ep_index); + spin_unlock_irqrestore(&xhci->lock, flags); + } else if (usb_endpoint_xfer_int(&urb->ep->desc)) { + spin_lock_irqsave(&xhci->lock, flags); + if (xhci->xhc_state & XHCI_STATE_DYING) + goto dying; + ret = xhci_queue_intr_tx(xhci, GFP_ATOMIC, urb, + slot_id, ep_index); + spin_unlock_irqrestore(&xhci->lock, flags); + } else { + ret = -EINVAL; + } +exit: + return ret; +dying: + xhci_dbg(xhci, "Ep 0x%x: URB %p submitted for " + "non-responsive xHCI host.\n", + urb->ep->desc.bEndpointAddress, urb); + spin_unlock_irqrestore(&xhci->lock, flags); + return -ESHUTDOWN; +} + +/* + * Remove the URB's TD from the endpoint ring. This may cause the HC to stop + * USB transfers, potentially stopping in the middle of a TRB buffer. The HC + * should pick up where it left off in the TD, unless a Set Transfer Ring + * Dequeue Pointer is issued. + * + * The TRBs that make up the buffers for the canceled URB will be "removed" from + * the ring. Since the ring is a contiguous structure, they can't be physically + * removed. Instead, there are two options: + * + * 1) If the HC is in the middle of processing the URB to be canceled, we + * simply move the ring's dequeue pointer past those TRBs using the Set + * Transfer Ring Dequeue Pointer command. This will be the common case, + * when drivers timeout on the last submitted URB and attempt to cancel. + * + * 2) If the HC is in the middle of a different TD, we turn the TRBs into a + * series of 1-TRB transfer no-op TDs. (No-ops shouldn't be chained.) The + * HC will need to invalidate the any TRBs it has cached after the stop + * endpoint command, as noted in the xHCI 0.95 errata. + * + * 3) The TD may have completed by the time the Stop Endpoint Command + * completes, so software needs to handle that case too. + * + * This function should protect against the TD enqueueing code ringing the + * doorbell while this code is waiting for a Stop Endpoint command to complete. + * It also needs to account for multiple cancellations on happening at the same + * time for the same endpoint. + * + * Note that this function can be called in any context, or so says + * usb_hcd_unlink_urb() + */ +int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) +{ + unsigned long flags; + int ret; + u32 temp; + struct xhci_hcd *xhci; + struct xhci_td *td; + unsigned int ep_index; + struct xhci_ring *ep_ring; + struct xhci_virt_ep *ep; + + xhci = hcd_to_xhci(hcd); + spin_lock_irqsave(&xhci->lock, flags); + /* Make sure the URB hasn't completed or been unlinked already */ + ret = usb_hcd_check_unlink_urb(hcd, urb, status); + if (ret || !urb->hcpriv) + goto done; + temp = xhci_readl(xhci, &xhci->op_regs->status); + if (temp == 0xffffffff) { + xhci_dbg(xhci, "HW died, freeing TD.\n"); + td = (struct xhci_td *) urb->hcpriv; + + usb_hcd_unlink_urb_from_ep(hcd, urb); + spin_unlock_irqrestore(&xhci->lock, flags); + usb_hcd_giveback_urb(xhci_to_hcd(xhci), urb, -ESHUTDOWN); + kfree(td); + return ret; + } + if (xhci->xhc_state & XHCI_STATE_DYING) { + xhci_dbg(xhci, "Ep 0x%x: URB %p to be canceled on " + "non-responsive xHCI host.\n", + urb->ep->desc.bEndpointAddress, urb); + /* Let the stop endpoint command watchdog timer (which set this + * state) finish cleaning up the endpoint TD lists. We must + * have caught it in the middle of dropping a lock and giving + * back an URB. + */ + goto done; + } + + xhci_dbg(xhci, "Cancel URB %p\n", urb); + xhci_dbg(xhci, "Event ring:\n"); + xhci_debug_ring(xhci, xhci->event_ring); + ep_index = xhci_get_endpoint_index(&urb->ep->desc); + ep = &xhci->devs[urb->dev->slot_id]->eps[ep_index]; + ep_ring = ep->ring; + xhci_dbg(xhci, "Endpoint ring:\n"); + xhci_debug_ring(xhci, ep_ring); + td = (struct xhci_td *) urb->hcpriv; + + list_add_tail(&td->cancelled_td_list, &ep->cancelled_td_list); + /* Queue a stop endpoint command, but only if this is + * the first cancellation to be handled. + */ + if (!(ep->ep_state & EP_HALT_PENDING)) { + ep->ep_state |= EP_HALT_PENDING; + ep->stop_cmds_pending++; + ep->stop_cmd_timer.expires = jiffies + + XHCI_STOP_EP_CMD_TIMEOUT * HZ; + add_timer(&ep->stop_cmd_timer); + xhci_queue_stop_endpoint(xhci, urb->dev->slot_id, ep_index); + xhci_ring_cmd_db(xhci); + } +done: + spin_unlock_irqrestore(&xhci->lock, flags); + return ret; +} + +/* Drop an endpoint from a new bandwidth configuration for this device. + * Only one call to this function is allowed per endpoint before + * check_bandwidth() or reset_bandwidth() must be called. + * A call to xhci_drop_endpoint() followed by a call to xhci_add_endpoint() will + * add the endpoint to the schedule with possibly new parameters denoted by a + * different endpoint descriptor in usb_host_endpoint. + * A call to xhci_add_endpoint() followed by a call to xhci_drop_endpoint() is + * not allowed. + * + * The USB core will not allow URBs to be queued to an endpoint that is being + * disabled, so there's no need for mutual exclusion to protect + * the xhci->devs[slot_id] structure. + */ +int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, + struct usb_host_endpoint *ep) +{ + struct xhci_hcd *xhci; + struct xhci_container_ctx *in_ctx, *out_ctx; + struct xhci_input_control_ctx *ctrl_ctx; + struct xhci_slot_ctx *slot_ctx; + unsigned int last_ctx; + unsigned int ep_index; + struct xhci_ep_ctx *ep_ctx; + u32 drop_flag; + u32 new_add_flags, new_drop_flags, new_slot_info; + int ret; + + ret = xhci_check_args(hcd, udev, ep, 1, __func__); + if (ret <= 0) + return ret; + xhci = hcd_to_xhci(hcd); + xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); + + drop_flag = xhci_get_endpoint_flag(&ep->desc); + if (drop_flag == SLOT_FLAG || drop_flag == EP0_FLAG) { + xhci_dbg(xhci, "xHCI %s - can't drop slot or ep 0 %#x\n", + __func__, drop_flag); + return 0; + } + + if (!xhci->devs || !xhci->devs[udev->slot_id]) { + xhci_warn(xhci, "xHCI %s called with unaddressed device\n", + __func__); + return -EINVAL; + } + + in_ctx = xhci->devs[udev->slot_id]->in_ctx; + out_ctx = xhci->devs[udev->slot_id]->out_ctx; + ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); + ep_index = xhci_get_endpoint_index(&ep->desc); + ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index); + /* If the HC already knows the endpoint is disabled, + * or the HCD has noted it is disabled, ignore this request + */ + if ((ep_ctx->ep_info & EP_STATE_MASK) == EP_STATE_DISABLED || + ctrl_ctx->drop_flags & xhci_get_endpoint_flag(&ep->desc)) { + xhci_warn(xhci, "xHCI %s called with disabled ep %p\n", + __func__, ep); + return 0; + } + + ctrl_ctx->drop_flags |= drop_flag; + new_drop_flags = ctrl_ctx->drop_flags; + + ctrl_ctx->add_flags &= ~drop_flag; + new_add_flags = ctrl_ctx->add_flags; + + last_ctx = xhci_last_valid_endpoint(ctrl_ctx->add_flags); + slot_ctx = xhci_get_slot_ctx(xhci, in_ctx); + /* Update the last valid endpoint context, if we deleted the last one */ + if ((slot_ctx->dev_info & LAST_CTX_MASK) > LAST_CTX(last_ctx)) { + slot_ctx->dev_info &= ~LAST_CTX_MASK; + slot_ctx->dev_info |= LAST_CTX(last_ctx); + } + new_slot_info = slot_ctx->dev_info; + + xhci_endpoint_zero(xhci, xhci->devs[udev->slot_id], ep); + + xhci_dbg(xhci, "drop ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x, new slot info = %#x\n", + (unsigned int) ep->desc.bEndpointAddress, + udev->slot_id, + (unsigned int) new_drop_flags, + (unsigned int) new_add_flags, + (unsigned int) new_slot_info); + return 0; +} + +/* Add an endpoint to a new possible bandwidth configuration for this device. + * Only one call to this function is allowed per endpoint before + * check_bandwidth() or reset_bandwidth() must be called. + * A call to xhci_drop_endpoint() followed by a call to xhci_add_endpoint() will + * add the endpoint to the schedule with possibly new parameters denoted by a + * different endpoint descriptor in usb_host_endpoint. + * A call to xhci_add_endpoint() followed by a call to xhci_drop_endpoint() is + * not allowed. + * + * The USB core will not allow URBs to be queued to an endpoint until the + * configuration or alt setting is installed in the device, so there's no need + * for mutual exclusion to protect the xhci->devs[slot_id] structure. + */ +int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, + struct usb_host_endpoint *ep) +{ + struct xhci_hcd *xhci; + struct xhci_container_ctx *in_ctx, *out_ctx; + unsigned int ep_index; + struct xhci_ep_ctx *ep_ctx; + struct xhci_slot_ctx *slot_ctx; + struct xhci_input_control_ctx *ctrl_ctx; + u32 added_ctxs; + unsigned int last_ctx; + u32 new_add_flags, new_drop_flags, new_slot_info; + int ret = 0; + + ret = xhci_check_args(hcd, udev, ep, 1, __func__); + if (ret <= 0) { + /* So we won't queue a reset ep command for a root hub */ + ep->hcpriv = NULL; + return ret; + } + xhci = hcd_to_xhci(hcd); + + added_ctxs = xhci_get_endpoint_flag(&ep->desc); + last_ctx = xhci_last_valid_endpoint(added_ctxs); + if (added_ctxs == SLOT_FLAG || added_ctxs == EP0_FLAG) { + /* FIXME when we have to issue an evaluate endpoint command to + * deal with ep0 max packet size changing once we get the + * descriptors + */ + xhci_dbg(xhci, "xHCI %s - can't add slot or ep 0 %#x\n", + __func__, added_ctxs); + return 0; + } + + if (!xhci->devs || !xhci->devs[udev->slot_id]) { + xhci_warn(xhci, "xHCI %s called with unaddressed device\n", + __func__); + return -EINVAL; + } + + in_ctx = xhci->devs[udev->slot_id]->in_ctx; + out_ctx = xhci->devs[udev->slot_id]->out_ctx; + ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); + ep_index = xhci_get_endpoint_index(&ep->desc); + ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index); + /* If the HCD has already noted the endpoint is enabled, + * ignore this request. + */ + if (ctrl_ctx->add_flags & xhci_get_endpoint_flag(&ep->desc)) { + xhci_warn(xhci, "xHCI %s called with enabled ep %p\n", + __func__, ep); + return 0; + } + + /* + * Configuration and alternate setting changes must be done in + * process context, not interrupt context (or so documenation + * for usb_set_interface() and usb_set_configuration() claim). + */ + if (xhci_endpoint_init(xhci, xhci->devs[udev->slot_id], + udev, ep, GFP_NOIO) < 0) { + dev_dbg(&udev->dev, "%s - could not initialize ep %#x\n", + __func__, ep->desc.bEndpointAddress); + return -ENOMEM; + } + + ctrl_ctx->add_flags |= added_ctxs; + new_add_flags = ctrl_ctx->add_flags; + + /* If xhci_endpoint_disable() was called for this endpoint, but the + * xHC hasn't been notified yet through the check_bandwidth() call, + * this re-adds a new state for the endpoint from the new endpoint + * descriptors. We must drop and re-add this endpoint, so we leave the + * drop flags alone. + */ + new_drop_flags = ctrl_ctx->drop_flags; + + slot_ctx = xhci_get_slot_ctx(xhci, in_ctx); + /* Update the last valid endpoint context, if we just added one past */ + if ((slot_ctx->dev_info & LAST_CTX_MASK) < LAST_CTX(last_ctx)) { + slot_ctx->dev_info &= ~LAST_CTX_MASK; + slot_ctx->dev_info |= LAST_CTX(last_ctx); + } + new_slot_info = slot_ctx->dev_info; + + /* Store the usb_device pointer for later use */ + ep->hcpriv = udev; + + xhci_dbg(xhci, "add ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x, new slot info = %#x\n", + (unsigned int) ep->desc.bEndpointAddress, + udev->slot_id, + (unsigned int) new_drop_flags, + (unsigned int) new_add_flags, + (unsigned int) new_slot_info); + return 0; +} + +static void xhci_zero_in_ctx(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev) +{ + struct xhci_input_control_ctx *ctrl_ctx; + struct xhci_ep_ctx *ep_ctx; + struct xhci_slot_ctx *slot_ctx; + int i; + + /* When a device's add flag and drop flag are zero, any subsequent + * configure endpoint command will leave that endpoint's state + * untouched. Make sure we don't leave any old state in the input + * endpoint contexts. + */ + ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); + ctrl_ctx->drop_flags = 0; + ctrl_ctx->add_flags = 0; + slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx); + slot_ctx->dev_info &= ~LAST_CTX_MASK; + /* Endpoint 0 is always valid */ + slot_ctx->dev_info |= LAST_CTX(1); + for (i = 1; i < 31; ++i) { + ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, i); + ep_ctx->ep_info = 0; + ep_ctx->ep_info2 = 0; + ep_ctx->deq = 0; + ep_ctx->tx_info = 0; + } +} + +static int xhci_configure_endpoint_result(struct xhci_hcd *xhci, + struct usb_device *udev, int *cmd_status) +{ + int ret; + + switch (*cmd_status) { + case COMP_ENOMEM: + dev_warn(&udev->dev, "Not enough host controller resources " + "for new device state.\n"); + ret = -ENOMEM; + /* FIXME: can we allocate more resources for the HC? */ + break; + case COMP_BW_ERR: + dev_warn(&udev->dev, "Not enough bandwidth " + "for new device state.\n"); + ret = -ENOSPC; + /* FIXME: can we go back to the old state? */ + break; + case COMP_TRB_ERR: + /* the HCD set up something wrong */ + dev_warn(&udev->dev, "ERROR: Endpoint drop flag = 0, " + "add flag = 1, " + "and endpoint is not disabled.\n"); + ret = -EINVAL; + break; + case COMP_SUCCESS: + dev_dbg(&udev->dev, "Successful Endpoint Configure command\n"); + ret = 0; + break; + default: + xhci_err(xhci, "ERROR: unexpected command completion " + "code 0x%x.\n", *cmd_status); + ret = -EINVAL; + break; + } + return ret; +} + +static int xhci_evaluate_context_result(struct xhci_hcd *xhci, + struct usb_device *udev, int *cmd_status) +{ + int ret; + struct xhci_virt_device *virt_dev = xhci->devs[udev->slot_id]; + + switch (*cmd_status) { + case COMP_EINVAL: + dev_warn(&udev->dev, "WARN: xHCI driver setup invalid evaluate " + "context command.\n"); + ret = -EINVAL; + break; + case COMP_EBADSLT: + dev_warn(&udev->dev, "WARN: slot not enabled for" + "evaluate context command.\n"); + case COMP_CTX_STATE: + dev_warn(&udev->dev, "WARN: invalid context state for " + "evaluate context command.\n"); + xhci_dbg_ctx(xhci, virt_dev->out_ctx, 1); + ret = -EINVAL; + break; + case COMP_SUCCESS: + dev_dbg(&udev->dev, "Successful evaluate context command\n"); + ret = 0; + break; + default: + xhci_err(xhci, "ERROR: unexpected command completion " + "code 0x%x.\n", *cmd_status); + ret = -EINVAL; + break; + } + return ret; +} + +/* Issue a configure endpoint command or evaluate context command + * and wait for it to finish. + */ +static int xhci_configure_endpoint(struct xhci_hcd *xhci, + struct usb_device *udev, + struct xhci_command *command, + bool ctx_change, bool must_succeed) +{ + int ret; + int timeleft; + unsigned long flags; + struct xhci_container_ctx *in_ctx; + struct completion *cmd_completion; + int *cmd_status; + struct xhci_virt_device *virt_dev; + + spin_lock_irqsave(&xhci->lock, flags); + virt_dev = xhci->devs[udev->slot_id]; + if (command) { + in_ctx = command->in_ctx; + cmd_completion = command->completion; + cmd_status = &command->status; + command->command_trb = xhci->cmd_ring->enqueue; + list_add_tail(&command->cmd_list, &virt_dev->cmd_list); + } else { + in_ctx = virt_dev->in_ctx; + cmd_completion = &virt_dev->cmd_completion; + cmd_status = &virt_dev->cmd_status; + } + + if (!ctx_change) + ret = xhci_queue_configure_endpoint(xhci, in_ctx->dma, + udev->slot_id, must_succeed); + else + ret = xhci_queue_evaluate_context(xhci, in_ctx->dma, + udev->slot_id); + if (ret < 0) { + if (command) + list_del(&command->cmd_list); + spin_unlock_irqrestore(&xhci->lock, flags); + xhci_dbg(xhci, "FIXME allocate a new ring segment\n"); + return -ENOMEM; + } + xhci_ring_cmd_db(xhci); + spin_unlock_irqrestore(&xhci->lock, flags); + + /* Wait for the configure endpoint command to complete */ + timeleft = wait_for_completion_interruptible_timeout( + cmd_completion, + USB_CTRL_SET_TIMEOUT); + if (timeleft <= 0) { + xhci_warn(xhci, "%s while waiting for %s command\n", + timeleft == 0 ? "Timeout" : "Signal", + ctx_change == 0 ? + "configure endpoint" : + "evaluate context"); + /* FIXME cancel the configure endpoint command */ + return -ETIME; + } + + if (!ctx_change) + return xhci_configure_endpoint_result(xhci, udev, cmd_status); + return xhci_evaluate_context_result(xhci, udev, cmd_status); +} + +/* Called after one or more calls to xhci_add_endpoint() or + * xhci_drop_endpoint(). If this call fails, the USB core is expected + * to call xhci_reset_bandwidth(). + * + * Since we are in the middle of changing either configuration or + * installing a new alt setting, the USB core won't allow URBs to be + * enqueued for any endpoint on the old config or interface. Nothing + * else should be touching the xhci->devs[slot_id] structure, so we + * don't need to take the xhci->lock for manipulating that. + */ +int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) +{ + int i; + int ret = 0; + struct xhci_hcd *xhci; + struct xhci_virt_device *virt_dev; + struct xhci_input_control_ctx *ctrl_ctx; + struct xhci_slot_ctx *slot_ctx; + + ret = xhci_check_args(hcd, udev, NULL, 0, __func__); + if (ret <= 0) + return ret; + xhci = hcd_to_xhci(hcd); + + if (!udev->slot_id || !xhci->devs || !xhci->devs[udev->slot_id]) { + xhci_warn(xhci, "xHCI %s called with unaddressed device\n", + __func__); + return -EINVAL; + } + xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); + virt_dev = xhci->devs[udev->slot_id]; + + /* See section 4.6.6 - A0 = 1; A1 = D0 = D1 = 0 */ + ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); + ctrl_ctx->add_flags |= SLOT_FLAG; + ctrl_ctx->add_flags &= ~EP0_FLAG; + ctrl_ctx->drop_flags &= ~SLOT_FLAG; + ctrl_ctx->drop_flags &= ~EP0_FLAG; + xhci_dbg(xhci, "New Input Control Context:\n"); + slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx); + xhci_dbg_ctx(xhci, virt_dev->in_ctx, + LAST_CTX_TO_EP_NUM(slot_ctx->dev_info)); + + ret = xhci_configure_endpoint(xhci, udev, NULL, + false, false); + if (ret) { + /* Callee should call reset_bandwidth() */ + return ret; + } + + xhci_dbg(xhci, "Output context after successful config ep cmd:\n"); + xhci_dbg_ctx(xhci, virt_dev->out_ctx, + LAST_CTX_TO_EP_NUM(slot_ctx->dev_info)); + + xhci_zero_in_ctx(xhci, virt_dev); + /* Install new rings and free or cache any old rings */ + for (i = 1; i < 31; ++i) { + if (!virt_dev->eps[i].new_ring) + continue; + /* Only cache or free the old ring if it exists. + * It may not if this is the first add of an endpoint. + */ + if (virt_dev->eps[i].ring) { + xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); + } + virt_dev->eps[i].ring = virt_dev->eps[i].new_ring; + virt_dev->eps[i].new_ring = NULL; + } + + return ret; +} + +void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) +{ + struct xhci_hcd *xhci; + struct xhci_virt_device *virt_dev; + int i, ret; + + ret = xhci_check_args(hcd, udev, NULL, 0, __func__); + if (ret <= 0) + return; + xhci = hcd_to_xhci(hcd); + + if (!xhci->devs || !xhci->devs[udev->slot_id]) { + xhci_warn(xhci, "xHCI %s called with unaddressed device\n", + __func__); + return; + } + xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); + virt_dev = xhci->devs[udev->slot_id]; + /* Free any rings allocated for added endpoints */ + for (i = 0; i < 31; ++i) { + if (virt_dev->eps[i].new_ring) { + xhci_ring_free(xhci, virt_dev->eps[i].new_ring); + virt_dev->eps[i].new_ring = NULL; + } + } + xhci_zero_in_ctx(xhci, virt_dev); +} + +static void xhci_setup_input_ctx_for_config_ep(struct xhci_hcd *xhci, + struct xhci_container_ctx *in_ctx, + struct xhci_container_ctx *out_ctx, + u32 add_flags, u32 drop_flags) +{ + struct xhci_input_control_ctx *ctrl_ctx; + ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); + ctrl_ctx->add_flags = add_flags; + ctrl_ctx->drop_flags = drop_flags; + xhci_slot_copy(xhci, in_ctx, out_ctx); + ctrl_ctx->add_flags |= SLOT_FLAG; + + xhci_dbg(xhci, "Input Context:\n"); + xhci_dbg_ctx(xhci, in_ctx, xhci_last_valid_endpoint(add_flags)); +} + +void xhci_setup_input_ctx_for_quirk(struct xhci_hcd *xhci, + unsigned int slot_id, unsigned int ep_index, + struct xhci_dequeue_state *deq_state) +{ + struct xhci_container_ctx *in_ctx; + struct xhci_ep_ctx *ep_ctx; + u32 added_ctxs; + dma_addr_t addr; + + xhci_endpoint_copy(xhci, xhci->devs[slot_id]->in_ctx, + xhci->devs[slot_id]->out_ctx, ep_index); + in_ctx = xhci->devs[slot_id]->in_ctx; + ep_ctx = xhci_get_ep_ctx(xhci, in_ctx, ep_index); + addr = xhci_trb_virt_to_dma(deq_state->new_deq_seg, + deq_state->new_deq_ptr); + if (addr == 0) { + xhci_warn(xhci, "WARN Cannot submit config ep after " + "reset ep command\n"); + xhci_warn(xhci, "WARN deq seg = %p, deq ptr = %p\n", + deq_state->new_deq_seg, + deq_state->new_deq_ptr); + return; + } + ep_ctx->deq = addr | deq_state->new_cycle_state; + + added_ctxs = xhci_get_endpoint_flag_from_index(ep_index); + xhci_setup_input_ctx_for_config_ep(xhci, xhci->devs[slot_id]->in_ctx, + xhci->devs[slot_id]->out_ctx, added_ctxs, added_ctxs); +} + +void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, + struct usb_device *udev, unsigned int ep_index) +{ + struct xhci_dequeue_state deq_state; + struct xhci_virt_ep *ep; + + xhci_dbg(xhci, "Cleaning up stalled endpoint ring\n"); + ep = &xhci->devs[udev->slot_id]->eps[ep_index]; + /* We need to move the HW's dequeue pointer past this TD, + * or it will attempt to resend it on the next doorbell ring. + */ + xhci_find_new_dequeue_state(xhci, udev->slot_id, + ep_index, ep->stopped_td, + &deq_state); + + /* HW with the reset endpoint quirk will use the saved dequeue state to + * issue a configure endpoint command later. + */ + if (!(xhci->quirks & XHCI_RESET_EP_QUIRK)) { + xhci_dbg(xhci, "Queueing new dequeue state\n"); + xhci_queue_new_dequeue_state(xhci, udev->slot_id, + ep_index, &deq_state); + } else { + /* Better hope no one uses the input context between now and the + * reset endpoint completion! + */ + xhci_dbg(xhci, "Setting up input context for " + "configure endpoint command\n"); + xhci_setup_input_ctx_for_quirk(xhci, udev->slot_id, + ep_index, &deq_state); + } +} + +/* Deal with stalled endpoints. The core should have sent the control message + * to clear the halt condition. However, we need to make the xHCI hardware + * reset its sequence number, since a device will expect a sequence number of + * zero after the halt condition is cleared. + * Context: in_interrupt + */ +void xhci_endpoint_reset(struct usb_hcd *hcd, + struct usb_host_endpoint *ep) +{ + struct xhci_hcd *xhci; + struct usb_device *udev; + unsigned int ep_index; + unsigned long flags; + int ret; + struct xhci_virt_ep *virt_ep; + + xhci = hcd_to_xhci(hcd); + udev = (struct usb_device *) ep->hcpriv; + /* Called with a root hub endpoint (or an endpoint that wasn't added + * with xhci_add_endpoint() + */ + if (!ep->hcpriv) + return; + ep_index = xhci_get_endpoint_index(&ep->desc); + virt_ep = &xhci->devs[udev->slot_id]->eps[ep_index]; + if (!virt_ep->stopped_td) { + xhci_dbg(xhci, "Endpoint 0x%x not halted, refusing to reset.\n", + ep->desc.bEndpointAddress); + return; + } + if (usb_endpoint_xfer_control(&ep->desc)) { + xhci_dbg(xhci, "Control endpoint stall already handled.\n"); + return; + } + + xhci_dbg(xhci, "Queueing reset endpoint command\n"); + spin_lock_irqsave(&xhci->lock, flags); + ret = xhci_queue_reset_ep(xhci, udev->slot_id, ep_index); + /* + * Can't change the ring dequeue pointer until it's transitioned to the + * stopped state, which is only upon a successful reset endpoint + * command. Better hope that last command worked! + */ + if (!ret) { + xhci_cleanup_stalled_ring(xhci, udev, ep_index); + kfree(virt_ep->stopped_td); + xhci_ring_cmd_db(xhci); + } + spin_unlock_irqrestore(&xhci->lock, flags); + + if (ret) + xhci_warn(xhci, "FIXME allocate a new ring segment\n"); +} + +/* + * This submits a Reset Device Command, which will set the device state to 0, + * set the device address to 0, and disable all the endpoints except the default + * control endpoint. The USB core should come back and call + * xhci_address_device(), and then re-set up the configuration. If this is + * called because of a usb_reset_and_verify_device(), then the old alternate + * settings will be re-installed through the normal bandwidth allocation + * functions. + * + * Wait for the Reset Device command to finish. Remove all structures + * associated with the endpoints that were disabled. Clear the input device + * structure? Cache the rings? Reset the control endpoint 0 max packet size? + */ +int xhci_reset_device(struct usb_hcd *hcd, struct usb_device *udev) +{ + int ret, i; + unsigned long flags; + struct xhci_hcd *xhci; + unsigned int slot_id; + struct xhci_virt_device *virt_dev; + struct xhci_command *reset_device_cmd; + int timeleft; + int last_freed_endpoint; + + ret = xhci_check_args(hcd, udev, NULL, 0, __func__); + if (ret <= 0) + return ret; + xhci = hcd_to_xhci(hcd); + slot_id = udev->slot_id; + virt_dev = xhci->devs[slot_id]; + if (!virt_dev) { + xhci_dbg(xhci, "%s called with invalid slot ID %u\n", + __func__, slot_id); + return -EINVAL; + } + + xhci_dbg(xhci, "Resetting device with slot ID %u\n", slot_id); + /* Allocate the command structure that holds the struct completion. + * Assume we're in process context, since the normal device reset + * process has to wait for the device anyway. Storage devices are + * reset as part of error handling, so use GFP_NOIO instead of + * GFP_KERNEL. + */ + reset_device_cmd = xhci_alloc_command(xhci, false, true, GFP_NOIO); + if (!reset_device_cmd) { + xhci_dbg(xhci, "Couldn't allocate command structure.\n"); + return -ENOMEM; + } + + /* Attempt to submit the Reset Device command to the command ring */ + spin_lock_irqsave(&xhci->lock, flags); + reset_device_cmd->command_trb = xhci->cmd_ring->enqueue; + list_add_tail(&reset_device_cmd->cmd_list, &virt_dev->cmd_list); + ret = xhci_queue_reset_device(xhci, slot_id); + if (ret) { + xhci_dbg(xhci, "FIXME: allocate a command ring segment\n"); + list_del(&reset_device_cmd->cmd_list); + spin_unlock_irqrestore(&xhci->lock, flags); + goto command_cleanup; + } + xhci_ring_cmd_db(xhci); + spin_unlock_irqrestore(&xhci->lock, flags); + + /* Wait for the Reset Device command to finish */ + timeleft = wait_for_completion_interruptible_timeout( + reset_device_cmd->completion, + USB_CTRL_SET_TIMEOUT); + if (timeleft <= 0) { + xhci_warn(xhci, "%s while waiting for reset device command\n", + timeleft == 0 ? "Timeout" : "Signal"); + spin_lock_irqsave(&xhci->lock, flags); + /* The timeout might have raced with the event ring handler, so + * only delete from the list if the item isn't poisoned. + */ + if (reset_device_cmd->cmd_list.next != LIST_POISON1) + list_del(&reset_device_cmd->cmd_list); + spin_unlock_irqrestore(&xhci->lock, flags); + ret = -ETIME; + goto command_cleanup; + } + + /* The Reset Device command can't fail, according to the 0.95/0.96 spec, + * unless we tried to reset a slot ID that wasn't enabled, + * or the device wasn't in the addressed or configured state. + */ + ret = reset_device_cmd->status; + switch (ret) { + case COMP_EBADSLT: /* 0.95 completion code for bad slot ID */ + case COMP_CTX_STATE: /* 0.96 completion code for same thing */ + xhci_info(xhci, "Can't reset device (slot ID %u) in %s state\n", + slot_id, + xhci_get_slot_state(xhci, virt_dev->out_ctx)); + xhci_info(xhci, "Not freeing device rings.\n"); + /* Don't treat this as an error. May change my mind later. */ + ret = 0; + goto command_cleanup; + case COMP_SUCCESS: + xhci_dbg(xhci, "Successful reset device command.\n"); + break; + default: + if (xhci_is_vendor_info_code(xhci, ret)) + break; + xhci_warn(xhci, "Unknown completion code %u for " + "reset device command.\n", ret); + ret = -EINVAL; + goto command_cleanup; + } + + /* Everything but endpoint 0 is disabled, so free or cache the rings. */ + last_freed_endpoint = 1; + for (i = 1; i < 31; ++i) { + if (!virt_dev->eps[i].ring) + continue; + xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); + last_freed_endpoint = i; + } + xhci_dbg(xhci, "Output context after successful reset device cmd:\n"); + xhci_dbg_ctx(xhci, virt_dev->out_ctx, last_freed_endpoint); + ret = 0; + +command_cleanup: + xhci_free_command(xhci, reset_device_cmd); + return ret; +} + +/* + * At this point, the struct usb_device is about to go away, the device has + * disconnected, and all traffic has been stopped and the endpoints have been + * disabled. Free any HC data structures associated with that device. + */ +void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev) +{ + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + struct xhci_virt_device *virt_dev; + unsigned long flags; + u32 state; + int i; + + if (udev->slot_id == 0) + return; + virt_dev = xhci->devs[udev->slot_id]; + if (!virt_dev) + return; + + /* Stop any wayward timer functions (which may grab the lock) */ + for (i = 0; i < 31; ++i) { + virt_dev->eps[i].ep_state &= ~EP_HALT_PENDING; + del_timer_sync(&virt_dev->eps[i].stop_cmd_timer); + } + + spin_lock_irqsave(&xhci->lock, flags); + /* Don't disable the slot if the host controller is dead. */ + state = xhci_readl(xhci, &xhci->op_regs->status); + if (state == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING)) { + xhci_free_virt_device(xhci, udev->slot_id); + spin_unlock_irqrestore(&xhci->lock, flags); + return; + } + + if (xhci_queue_slot_control(xhci, TRB_DISABLE_SLOT, udev->slot_id)) { + spin_unlock_irqrestore(&xhci->lock, flags); + xhci_dbg(xhci, "FIXME: allocate a command ring segment\n"); + return; + } + xhci_ring_cmd_db(xhci); + spin_unlock_irqrestore(&xhci->lock, flags); + /* + * Event command completion handler will free any data structures + * associated with the slot. XXX Can free sleep? + */ +} + +/* + * Returns 0 if the xHC ran out of device slots, the Enable Slot command + * timed out, or allocating memory failed. Returns 1 on success. + */ +int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) +{ + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + unsigned long flags; + int timeleft; + int ret; + + spin_lock_irqsave(&xhci->lock, flags); + ret = xhci_queue_slot_control(xhci, TRB_ENABLE_SLOT, 0); + if (ret) { + spin_unlock_irqrestore(&xhci->lock, flags); + xhci_dbg(xhci, "FIXME: allocate a command ring segment\n"); + return 0; + } + xhci_ring_cmd_db(xhci); + spin_unlock_irqrestore(&xhci->lock, flags); + + /* XXX: how much time for xHC slot assignment? */ + timeleft = wait_for_completion_interruptible_timeout(&xhci->addr_dev, + USB_CTRL_SET_TIMEOUT); + if (timeleft <= 0) { + xhci_warn(xhci, "%s while waiting for a slot\n", + timeleft == 0 ? "Timeout" : "Signal"); + /* FIXME cancel the enable slot request */ + return 0; + } + + if (!xhci->slot_id) { + xhci_err(xhci, "Error while assigning device slot ID\n"); + return 0; + } + /* xhci_alloc_virt_device() does not touch rings; no need to lock */ + if (!xhci_alloc_virt_device(xhci, xhci->slot_id, udev, GFP_KERNEL)) { + /* Disable slot, if we can do it without mem alloc */ + xhci_warn(xhci, "Could not allocate xHCI USB device data structures\n"); + spin_lock_irqsave(&xhci->lock, flags); + if (!xhci_queue_slot_control(xhci, TRB_DISABLE_SLOT, udev->slot_id)) + xhci_ring_cmd_db(xhci); + spin_unlock_irqrestore(&xhci->lock, flags); + return 0; + } + udev->slot_id = xhci->slot_id; + /* Is this a LS or FS device under a HS hub? */ + /* Hub or peripherial? */ + return 1; +} + +/* + * Issue an Address Device command (which will issue a SetAddress request to + * the device). + * We should be protected by the usb_address0_mutex in khubd's hub_port_init, so + * we should only issue and wait on one address command at the same time. + * + * We add one to the device address issued by the hardware because the USB core + * uses address 1 for the root hubs (even though they're not really devices). + */ +int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) +{ + unsigned long flags; + int timeleft; + struct xhci_virt_device *virt_dev; + int ret = 0; + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + struct xhci_slot_ctx *slot_ctx; + struct xhci_input_control_ctx *ctrl_ctx; + u64 temp_64; + + if (!udev->slot_id) { + xhci_dbg(xhci, "Bad Slot ID %d\n", udev->slot_id); + return -EINVAL; + } + + virt_dev = xhci->devs[udev->slot_id]; + + /* If this is a Set Address to an unconfigured device, setup ep 0 */ + if (!udev->config) + xhci_setup_addressable_virt_dev(xhci, udev); + /* Otherwise, assume the core has the device configured how it wants */ + xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id); + xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2); + + spin_lock_irqsave(&xhci->lock, flags); + ret = xhci_queue_address_device(xhci, virt_dev->in_ctx->dma, + udev->slot_id); + if (ret) { + spin_unlock_irqrestore(&xhci->lock, flags); + xhci_dbg(xhci, "FIXME: allocate a command ring segment\n"); + return ret; + } + xhci_ring_cmd_db(xhci); + spin_unlock_irqrestore(&xhci->lock, flags); + + /* ctrl tx can take up to 5 sec; XXX: need more time for xHC? */ + timeleft = wait_for_completion_interruptible_timeout(&xhci->addr_dev, + USB_CTRL_SET_TIMEOUT); + /* FIXME: From section 4.3.4: "Software shall be responsible for timing + * the SetAddress() "recovery interval" required by USB and aborting the + * command on a timeout. + */ + if (timeleft <= 0) { + xhci_warn(xhci, "%s while waiting for a slot\n", + timeleft == 0 ? "Timeout" : "Signal"); + /* FIXME cancel the address device command */ + return -ETIME; + } + + switch (virt_dev->cmd_status) { + case COMP_CTX_STATE: + case COMP_EBADSLT: + xhci_err(xhci, "Setup ERROR: address device command for slot %d.\n", + udev->slot_id); + ret = -EINVAL; + break; + case COMP_TX_ERR: + dev_warn(&udev->dev, "Device not responding to set address.\n"); + ret = -EPROTO; + break; + case COMP_SUCCESS: + xhci_dbg(xhci, "Successful Address Device command\n"); + break; + default: + xhci_err(xhci, "ERROR: unexpected command completion " + "code 0x%x.\n", virt_dev->cmd_status); + xhci_dbg(xhci, "Slot ID %d Output Context:\n", udev->slot_id); + xhci_dbg_ctx(xhci, virt_dev->out_ctx, 2); + ret = -EINVAL; + break; + } + if (ret) { + return ret; + } + temp_64 = xhci_read_64(xhci, &xhci->op_regs->dcbaa_ptr); + xhci_dbg(xhci, "Op regs DCBAA ptr = %#016llx\n", temp_64); + xhci_dbg(xhci, "Slot ID %d dcbaa entry @%p = %#016llx\n", + udev->slot_id, + &xhci->dcbaa->dev_context_ptrs[udev->slot_id], + (unsigned long long) + xhci->dcbaa->dev_context_ptrs[udev->slot_id]); + xhci_dbg(xhci, "Output Context DMA address = %#08llx\n", + (unsigned long long)virt_dev->out_ctx->dma); + xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id); + xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2); + xhci_dbg(xhci, "Slot ID %d Output Context:\n", udev->slot_id); + xhci_dbg_ctx(xhci, virt_dev->out_ctx, 2); + /* + * USB core uses address 1 for the roothubs, so we add one to the + * address given back to us by the HC. + */ + slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->out_ctx); + udev->devnum = (slot_ctx->dev_state & DEV_ADDR_MASK) + 1; + /* Zero the input context control for later use */ + ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); + ctrl_ctx->add_flags = 0; + ctrl_ctx->drop_flags = 0; + + xhci_dbg(xhci, "Device address = %d\n", udev->devnum); + /* XXX Meh, not sure if anyone else but choose_address uses this. */ + set_bit(udev->devnum, udev->bus->devmap.devicemap); + + return 0; +} + +/* Once a hub descriptor is fetched for a device, we need to update the xHC's + * internal data structures for the device. + */ +int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev, + struct usb_tt *tt, gfp_t mem_flags) +{ + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + struct xhci_virt_device *vdev; + struct xhci_command *config_cmd; + struct xhci_input_control_ctx *ctrl_ctx; + struct xhci_slot_ctx *slot_ctx; + unsigned long flags; + unsigned think_time; + int ret; + + /* Ignore root hubs */ + if (!hdev->parent) + return 0; + + vdev = xhci->devs[hdev->slot_id]; + if (!vdev) { + xhci_warn(xhci, "Cannot update hub desc for unknown device.\n"); + return -EINVAL; + } + config_cmd = xhci_alloc_command(xhci, true, true, mem_flags); + if (!config_cmd) { + xhci_dbg(xhci, "Could not allocate xHCI command structure.\n"); + return -ENOMEM; + } + + spin_lock_irqsave(&xhci->lock, flags); + xhci_slot_copy(xhci, config_cmd->in_ctx, vdev->out_ctx); + ctrl_ctx = xhci_get_input_control_ctx(xhci, config_cmd->in_ctx); + ctrl_ctx->add_flags |= SLOT_FLAG; + slot_ctx = xhci_get_slot_ctx(xhci, config_cmd->in_ctx); + slot_ctx->dev_info |= DEV_HUB; + if (tt->multi) + slot_ctx->dev_info |= DEV_MTT; + if (xhci->hci_version > 0x95) { + xhci_dbg(xhci, "xHCI version %x needs hub " + "TT think time and number of ports\n", + (unsigned int) xhci->hci_version); + slot_ctx->dev_info2 |= XHCI_MAX_PORTS(hdev->maxchild); + /* Set TT think time - convert from ns to FS bit times. + * 0 = 8 FS bit times, 1 = 16 FS bit times, + * 2 = 24 FS bit times, 3 = 32 FS bit times. + */ + think_time = tt->think_time; + if (think_time != 0) + think_time = (think_time / 666) - 1; + slot_ctx->tt_info |= TT_THINK_TIME(think_time); + } else { + xhci_dbg(xhci, "xHCI version %x doesn't need hub " + "TT think time or number of ports\n", + (unsigned int) xhci->hci_version); + } + slot_ctx->dev_state = 0; + spin_unlock_irqrestore(&xhci->lock, flags); + + xhci_dbg(xhci, "Set up %s for hub device.\n", + (xhci->hci_version > 0x95) ? + "configure endpoint" : "evaluate context"); + xhci_dbg(xhci, "Slot %u Input Context:\n", hdev->slot_id); + xhci_dbg_ctx(xhci, config_cmd->in_ctx, 0); + + /* Issue and wait for the configure endpoint or + * evaluate context command. + */ + if (xhci->hci_version > 0x95) + ret = xhci_configure_endpoint(xhci, hdev, config_cmd, + false, false); + else + ret = xhci_configure_endpoint(xhci, hdev, config_cmd, + true, false); + + xhci_dbg(xhci, "Slot %u Output Context:\n", hdev->slot_id); + xhci_dbg_ctx(xhci, vdev->out_ctx, 0); + + xhci_free_command(xhci, config_cmd); + return ret; +} + +int xhci_get_frame(struct usb_hcd *hcd) +{ + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + /* EHCI mods by the periodic size. Why? */ + return xhci_readl(xhci, &xhci->run_regs->microframe_index) >> 3; +} + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_LICENSE("GPL"); + +static int __init xhci_hcd_init(void) +{ +#ifdef CONFIG_PCI + int retval = 0; + + retval = xhci_register_pci(); + + if (retval < 0) { + printk(KERN_DEBUG "Problem registering PCI driver."); + return retval; + } +#endif + /* + * Check the compiler generated sizes of structures that must be laid + * out in specific ways for hardware access. + */ + BUILD_BUG_ON(sizeof(struct xhci_doorbell_array) != 256*32/8); + BUILD_BUG_ON(sizeof(struct xhci_slot_ctx) != 8*32/8); + BUILD_BUG_ON(sizeof(struct xhci_ep_ctx) != 8*32/8); + /* xhci_device_control has eight fields, and also + * embeds one xhci_slot_ctx and 31 xhci_ep_ctx + */ + BUILD_BUG_ON(sizeof(struct xhci_stream_ctx) != 4*32/8); + BUILD_BUG_ON(sizeof(union xhci_trb) != 4*32/8); + BUILD_BUG_ON(sizeof(struct xhci_erst_entry) != 4*32/8); + BUILD_BUG_ON(sizeof(struct xhci_cap_regs) != 7*32/8); + BUILD_BUG_ON(sizeof(struct xhci_intr_reg) != 8*32/8); + /* xhci_run_regs has eight fields and embeds 128 xhci_intr_regs */ + BUILD_BUG_ON(sizeof(struct xhci_run_regs) != (8+8*128)*32/8); + BUILD_BUG_ON(sizeof(struct xhci_doorbell_array) != 256*32/8); + return 0; +} +module_init(xhci_hcd_init); + +static void __exit xhci_hcd_cleanup(void) +{ +#ifdef CONFIG_PCI + xhci_unregister_pci(); +#endif +} +module_exit(xhci_hcd_cleanup); -- cgit v0.10.2 From 1d68064a7d80da4a7334cab0356162e36229c1a1 Mon Sep 17 00:00:00 2001 From: Andiry Xu Date: Fri, 12 Mar 2010 17:10:04 +0800 Subject: USB: xHCI: re-initialize cmd_completion When a signal interrupts a Configure Endpoint command, the cmd_completion used in xhci_configure_endpoint() is not re-initialized and the wait_for_completion_interruptible_timeout() will return failure. Initialize cmd_completion in xhci_configure_endpoint(). Signed-off-by: Andiry Xu Signed-off-by: Sarah Sharp Cc: stable Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 4cb69e0..492a61c 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1173,6 +1173,7 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci, cmd_completion = &virt_dev->cmd_completion; cmd_status = &virt_dev->cmd_status; } + init_completion(cmd_completion); if (!ctx_change) ret = xhci_queue_configure_endpoint(xhci, in_ctx->dma, -- cgit v0.10.2 From dee5658b482e9e2ac7d6205dc876fc11d4008138 Mon Sep 17 00:00:00 2001 From: Daniel Sangorrin Date: Thu, 11 Mar 2010 14:10:58 -0800 Subject: USB: serial: ftdi: add CONTEC vendor and product id This is a patch to ftdi_sio_ids.h and ftdi_sio.c that adds identifiers for CONTEC USB serial converter. I tested it with the device COM-1(USB)H [akpm@linux-foundation.org: keep the VIDs sorted a bit] Signed-off-by: Daniel Sangorrin Cc: Andreas Mohr Cc: Radek Liboska Cc: stable Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 6af0dfa..6fc09dc 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -658,6 +658,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) }, { USB_DEVICE(EVOLUTION_VID, EVO_HYBRID_PID) }, { USB_DEVICE(EVOLUTION_VID, EVO_RCM4_PID) }, + { USB_DEVICE(CONTEC_VID, CONTEC_COM1USBH_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16C_PID) }, diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 0727e19..75482cb 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -501,6 +501,13 @@ #define CONTEC_COM1USBH_PID 0x8311 /* COM-1(USB)H */ /* + * Contec products (http://www.contec.com) + * Submitted by Daniel Sangorrin + */ +#define CONTEC_VID 0x06CE /* Vendor ID */ +#define CONTEC_COM1USBH_PID 0x8311 /* COM-1(USB)H */ + +/* * Definitions for B&B Electronics products. */ #define BANDB_VID 0x0856 /* B&B Electronics Vendor ID */ -- cgit v0.10.2 From eaff4cdc978f414cf7b5441a333de3070d80e9c7 Mon Sep 17 00:00:00 2001 From: Nathaniel McCallum Date: Thu, 11 Mar 2010 13:09:24 -0500 Subject: USB: option: fix incorrect manufacturer name in usb/serial/option: MAXON->CMOTECH Signed-off-by: Nathaniel McCallum Cc: stable Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 3ab1a04..f19fd333 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -288,7 +288,7 @@ static int option_resume(struct usb_serial *serial); #define QUALCOMM_VENDOR_ID 0x05C6 -#define MAXON_VENDOR_ID 0x16d8 +#define CMOTECH_VENDOR_ID 0x16d8 #define TELIT_VENDOR_ID 0x1bc7 #define TELIT_PRODUCT_UC864E 0x1003 @@ -548,7 +548,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ - { USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */ + { USB_DEVICE(CMOTECH_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */ { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864G) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ -- cgit v0.10.2 From bb73ed2a268a29ab1b7d8cc50b5f248578e7e188 Mon Sep 17 00:00:00 2001 From: Nathaniel McCallum Date: Thu, 11 Mar 2010 13:01:17 -0500 Subject: USB: option: move hardcoded PID to a macro in usb/serial/option Signed-off-by: Nathaniel McCallum Cc: stable Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index f19fd333..132ad93 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -289,6 +289,7 @@ static int option_resume(struct usb_serial *serial); #define QUALCOMM_VENDOR_ID 0x05C6 #define CMOTECH_VENDOR_ID 0x16d8 +#define CMOTECH_PRODUCT_6280 0x6280 #define TELIT_VENDOR_ID 0x1bc7 #define TELIT_PRODUCT_UC864E 0x1003 @@ -548,7 +549,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ - { USB_DEVICE(CMOTECH_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */ + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6280) }, /* BP3-USB & BP3-EXT HSDPA */ { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864G) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ -- cgit v0.10.2 From 3b04872aa75006e2a4adaaec21e9c9ede8b8ad9d Mon Sep 17 00:00:00 2001 From: Nathaniel McCallum Date: Thu, 11 Mar 2010 13:09:26 -0500 Subject: USB: option: add support for a new CMOTECH device to usb/serial/option Signed-off-by: Nathaniel McCallum Cc: stable Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 132ad93..3af1eb8 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -289,6 +289,7 @@ static int option_resume(struct usb_serial *serial); #define QUALCOMM_VENDOR_ID 0x05C6 #define CMOTECH_VENDOR_ID 0x16d8 +#define CMOTECH_PRODUCT_6008 0x6008 #define CMOTECH_PRODUCT_6280 0x6280 #define TELIT_VENDOR_ID 0x1bc7 @@ -550,6 +551,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6280) }, /* BP3-USB & BP3-EXT HSDPA */ + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6008) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864G) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ -- cgit v0.10.2 From 1e63ef0e0c2cfb5deb9331420c9857fbe04bea73 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Fri, 12 Mar 2010 11:27:21 +0100 Subject: USB: Fix documentation for avoid_reset_quirk The name used in the documentation doesn't match reality. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman diff --git a/Documentation/ABI/testing/sysfs-bus-usb b/Documentation/ABI/testing/sysfs-bus-usb index a986e9b..bcebb9e 100644 --- a/Documentation/ABI/testing/sysfs-bus-usb +++ b/Documentation/ABI/testing/sysfs-bus-usb @@ -160,7 +160,7 @@ Description: match the driver to the device. For example: # echo "046d c315" > /sys/bus/usb/drivers/foo/remove_id -What: /sys/bus/usb/device/.../avoid_reset +What: /sys/bus/usb/device/.../avoid_reset_quirk Date: December 2009 Contact: Oliver Neukum Description: -- cgit v0.10.2 From fa7bf3424ead0a496f5176abb3253b8176bb2935 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 11 Mar 2010 15:06:54 -0700 Subject: usb/gadget: fix compile error on r8a66597-udc.c C file uses IS_ERR and PTR_ERR, but doesn't include Signed-off-by: Grant Likely Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c index 8b45145..5e13d23 100644 --- a/drivers/usb/gadget/r8a66597-udc.c +++ b/drivers/usb/gadget/r8a66597-udc.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include -- cgit v0.10.2 From 9957dd97ec5e98dd334f87ade1d9a0b24d1f86eb Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Fri, 12 Mar 2010 10:35:20 +0200 Subject: usb: musb: Fix compile error for omaps for musb_hdrc CONFIG_ARCH_OMAP34XX is now CONFIG_ARCH_OMAP3. But since drivers/usb/musb/omap2430.c use CONFIG_PM for these registers and functions, do the same for the header. Otherwise we get the following for most omap3 defconfigs: drivers/usb/musb/omap2430.c:261: error: expected identifier or '(' before 'do' drivers/usb/musb/omap2430.c:261: error: expected identifier or '(' before 'while' drivers/usb/musb/omap2430.c:268: error: expected identifier or '(' before 'do' drivers/usb/musb/omap2430.c:268: error: expected identifier or '(' before 'while' Signed-off-by: Tony Lindgren Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index d849fb8..cd9f4a9 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -469,7 +469,7 @@ struct musb_csr_regs { struct musb_context_registers { -#if defined(CONFIG_ARCH_OMAP34XX) || defined(CONFIG_ARCH_OMAP2430) +#ifdef CONFIG_PM u32 otg_sysconfig, otg_forcestandby; #endif u8 power; @@ -483,7 +483,7 @@ struct musb_context_registers { struct musb_csr_regs index_regs[MUSB_C_NUM_EPS]; }; -#if defined(CONFIG_ARCH_OMAP34XX) || defined(CONFIG_ARCH_OMAP2430) +#ifdef CONFIG_PM extern void musb_platform_save_context(struct musb *musb, struct musb_context_registers *musb_context); extern void musb_platform_restore_context(struct musb *musb, -- cgit v0.10.2 From adb3ee421d6d39fbfadadf7093a587461ac4597e Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 12 Mar 2010 10:27:21 +0200 Subject: usb: musb: abstract out ULPI_BUSCONTROL register reads/writes The USB PHY on current Blackfin processors is a UTMI+ level 2 PHY. However, it has no ULPI support - so there are no registers at all. That means accesses to ULPI_BUSCONTROL have to be abstracted away like other MUSB registers. This fixes building for Blackfin parts again. Signed-off-by: Mike Frysinger Acked-by: Anand Gadiyar Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index b4bbf8f..e54e468 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -2007,7 +2007,6 @@ bad_config: /* host side needs more setup */ if (is_host_enabled(musb)) { struct usb_hcd *hcd = musb_to_hcd(musb); - u8 busctl; otg_set_host(musb->xceiv, &hcd->self); @@ -2018,9 +2017,9 @@ bad_config: /* program PHY to use external vBus if required */ if (plat->extvbus) { - busctl = musb_readb(musb->mregs, MUSB_ULPI_BUSCONTROL); + u8 busctl = musb_read_ulpi_buscontrol(musb->mregs); busctl |= MUSB_ULPI_USE_EXTVBUS; - musb_writeb(musb->mregs, MUSB_ULPI_BUSCONTROL, busctl); + musb_write_ulpi_buscontrol(musb->mregs, busctl); } } diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h index 8d8062b..327d0ed 100644 --- a/drivers/usb/musb/musb_regs.h +++ b/drivers/usb/musb/musb_regs.h @@ -326,6 +326,11 @@ static inline void musb_write_rxfifoadd(void __iomem *mbase, u16 c_off) musb_writew(mbase, MUSB_RXFIFOADD, c_off); } +static inline void musb_write_ulpi_buscontrol(void __iomem *mbase, u8 val) +{ + musb_writeb(mbase, MUSB_ULPI_BUSCONTROL, val); +} + static inline u8 musb_read_txfifosz(void __iomem *mbase) { return musb_readb(mbase, MUSB_TXFIFOSZ); @@ -346,6 +351,11 @@ static inline u16 musb_read_rxfifoadd(void __iomem *mbase) return musb_readw(mbase, MUSB_RXFIFOADD); } +static inline u8 musb_read_ulpi_buscontrol(void __iomem *mbase) +{ + return musb_readb(mbase, MUSB_ULPI_BUSCONTROL); +} + static inline u8 musb_read_configdata(void __iomem *mbase) { musb_writeb(mbase, MUSB_INDEX, 0); @@ -510,6 +520,10 @@ static inline void musb_write_rxfifoadd(void __iomem *mbase, u16 c_off) { } +static inline void musb_write_ulpi_buscontrol(void __iomem *mbase, u8 val) +{ +} + static inline u8 musb_read_txfifosz(void __iomem *mbase) { } @@ -526,6 +540,11 @@ static inline u16 musb_read_rxfifoadd(void __iomem *mbase) { } +static inline u8 musb_read_ulpi_buscontrol(void __iomem *mbase) +{ + return 0; +} + static inline u8 musb_read_configdata(void __iomem *mbase) { return 0; -- cgit v0.10.2 From 7f4bca4049941ba8dac35775fe462d4ef9f0dce4 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 12 Mar 2010 10:27:23 +0200 Subject: USB: musb: fix warnings in Blackfin regs The recent commit "usb: musb: Add context save and restore support" added some stubs for the Blackfin code so things would compile, but it also added a bunch of warnings due to missing return statements. Signed-off-by: Mike Frysinger Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h index 327d0ed..fa55aac 100644 --- a/drivers/usb/musb/musb_regs.h +++ b/drivers/usb/musb/musb_regs.h @@ -526,18 +526,22 @@ static inline void musb_write_ulpi_buscontrol(void __iomem *mbase, u8 val) static inline u8 musb_read_txfifosz(void __iomem *mbase) { + return 0; } static inline u16 musb_read_txfifoadd(void __iomem *mbase) { + return 0; } static inline u8 musb_read_rxfifosz(void __iomem *mbase) { + return 0; } static inline u16 musb_read_rxfifoadd(void __iomem *mbase) { + return 0; } static inline u8 musb_read_ulpi_buscontrol(void __iomem *mbase) @@ -596,22 +600,27 @@ static inline void musb_write_txhubport(void __iomem *mbase, u8 epnum, static inline u8 musb_read_rxfunaddr(void __iomem *mbase, u8 epnum) { + return 0; } static inline u8 musb_read_rxhubaddr(void __iomem *mbase, u8 epnum) { + return 0; } static inline u8 musb_read_rxhubport(void __iomem *mbase, u8 epnum) { + return 0; } static inline u8 musb_read_txfunaddr(void __iomem *mbase, u8 epnum) { + return 0; } static inline u8 musb_read_txhubaddr(void __iomem *mbase, u8 epnum) { + return 0; } static inline void musb_read_txhubport(void __iomem *mbase, u8 epnum) -- cgit v0.10.2 From aa4714560b4ea359bb7830188ebd06bce71bcdea Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 12 Mar 2010 10:27:24 +0200 Subject: usb: musb: core: declare mbase only where it's used ... and avoid a compilation if we disable host side of musb. Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index e54e468..0e8b8ab 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -379,7 +379,6 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, u8 devctl, u8 power) { irqreturn_t handled = IRQ_NONE; - void __iomem *mbase = musb->mregs; DBG(3, "<== Power=%02x, DevCtl=%02x, int_usb=0x%x\n", power, devctl, int_usb); @@ -394,6 +393,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, if (devctl & MUSB_DEVCTL_HM) { #ifdef CONFIG_USB_MUSB_HDRC_HCD + void __iomem *mbase = musb->mregs; + switch (musb->xceiv->state) { case OTG_STATE_A_SUSPEND: /* remote wakeup? later, GetPortStatus @@ -471,6 +472,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, #ifdef CONFIG_USB_MUSB_HDRC_HCD /* see manual for the order of the tests */ if (int_usb & MUSB_INTR_SESSREQ) { + void __iomem *mbase = musb->mregs; + DBG(1, "SESSION_REQUEST (%s)\n", otg_state_string(musb)); /* IRQ arrives from ID pin sense or (later, if VBUS power @@ -519,6 +522,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, case OTG_STATE_A_WAIT_BCON: case OTG_STATE_A_WAIT_VRISE: if (musb->vbuserr_retry) { + void __iomem *mbase = musb->mregs; + musb->vbuserr_retry--; ignore = 1; devctl |= MUSB_DEVCTL_SESSION; @@ -622,6 +627,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, if (int_usb & MUSB_INTR_CONNECT) { struct usb_hcd *hcd = musb_to_hcd(musb); + void __iomem *mbase = musb->mregs; handled = IRQ_HANDLED; musb->is_active = 1; -- cgit v0.10.2 From 860e41a71c1731e79e1920dc42676bafc925af5e Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Sat, 27 Feb 2010 20:54:24 +0100 Subject: usb: cdc-wdm: Fix race between write and disconnect Unify mutexes to fix a race between write and disconnect and shift the test for disconnection to always report it. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 18aafcb..cf1c5fb 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -87,9 +87,7 @@ struct wdm_device { int count; dma_addr_t shandle; dma_addr_t ihandle; - struct mutex wlock; - struct mutex rlock; - struct mutex plock; + struct mutex lock; wait_queue_head_t wait; struct work_struct rxwork; int werr; @@ -305,14 +303,38 @@ static ssize_t wdm_write if (we < 0) return -EIO; - r = mutex_lock_interruptible(&desc->wlock); /* concurrent writes */ + desc->outbuf = buf = kmalloc(count, GFP_KERNEL); + if (!buf) { + rv = -ENOMEM; + goto outnl; + } + + r = copy_from_user(buf, buffer, count); + if (r > 0) { + kfree(buf); + rv = -EFAULT; + goto outnl; + } + + /* concurrent writes and disconnect */ + r = mutex_lock_interruptible(&desc->lock); rv = -ERESTARTSYS; - if (r) + if (r) { + kfree(buf); goto outnl; + } + + if (test_bit(WDM_DISCONNECTING, &desc->flags)) { + kfree(buf); + rv = -ENODEV; + goto outnp; + } r = usb_autopm_get_interface(desc->intf); - if (r < 0) + if (r < 0) { + kfree(buf); goto outnp; + } if (!file->f_flags && O_NONBLOCK) r = wait_event_interruptible(desc->wait, !test_bit(WDM_IN_USE, @@ -320,24 +342,8 @@ static ssize_t wdm_write else if (test_bit(WDM_IN_USE, &desc->flags)) r = -EAGAIN; - if (r < 0) - goto out; - - if (test_bit(WDM_DISCONNECTING, &desc->flags)) { - rv = -ENODEV; - goto out; - } - - desc->outbuf = buf = kmalloc(count, GFP_KERNEL); - if (!buf) { - rv = -ENOMEM; - goto out; - } - - r = copy_from_user(buf, buffer, count); - if (r > 0) { + if (r < 0) { kfree(buf); - rv = -EFAULT; goto out; } @@ -374,7 +380,7 @@ static ssize_t wdm_write out: usb_autopm_put_interface(desc->intf); outnp: - mutex_unlock(&desc->wlock); + mutex_unlock(&desc->lock); outnl: return rv < 0 ? rv : count; } @@ -387,7 +393,7 @@ static ssize_t wdm_read struct wdm_device *desc = file->private_data; - rv = mutex_lock_interruptible(&desc->rlock); /*concurrent reads */ + rv = mutex_lock_interruptible(&desc->lock); /*concurrent reads */ if (rv < 0) return -ERESTARTSYS; @@ -465,7 +471,7 @@ retry: rv = cntr; err: - mutex_unlock(&desc->rlock); + mutex_unlock(&desc->lock); if (rv < 0 && rv != -EAGAIN) dev_err(&desc->intf->dev, "wdm_read: exit error\n"); return rv; @@ -533,7 +539,7 @@ static int wdm_open(struct inode *inode, struct file *file) } intf->needs_remote_wakeup = 1; - mutex_lock(&desc->plock); + mutex_lock(&desc->lock); if (!desc->count++) { rv = usb_submit_urb(desc->validity, GFP_KERNEL); if (rv < 0) { @@ -544,7 +550,7 @@ static int wdm_open(struct inode *inode, struct file *file) } else { rv = 0; } - mutex_unlock(&desc->plock); + mutex_unlock(&desc->lock); usb_autopm_put_interface(desc->intf); out: mutex_unlock(&wdm_mutex); @@ -556,9 +562,9 @@ static int wdm_release(struct inode *inode, struct file *file) struct wdm_device *desc = file->private_data; mutex_lock(&wdm_mutex); - mutex_lock(&desc->plock); + mutex_lock(&desc->lock); desc->count--; - mutex_unlock(&desc->plock); + mutex_unlock(&desc->lock); if (!desc->count) { dev_dbg(&desc->intf->dev, "wdm_release: cleanup"); @@ -655,9 +661,7 @@ next_desc: desc = kzalloc(sizeof(struct wdm_device), GFP_KERNEL); if (!desc) goto out; - mutex_init(&desc->wlock); - mutex_init(&desc->rlock); - mutex_init(&desc->plock); + mutex_init(&desc->lock); spin_lock_init(&desc->iuspin); init_waitqueue_head(&desc->wait); desc->wMaxCommand = maxcom; @@ -772,7 +776,9 @@ static void wdm_disconnect(struct usb_interface *intf) clear_bit(WDM_IN_USE, &desc->flags); spin_unlock_irqrestore(&desc->iuspin, flags); cancel_work_sync(&desc->rxwork); + mutex_lock(&desc->lock); kill_urbs(desc); + mutex_unlock(&desc->lock); wake_up_all(&desc->wait); if (!desc->count) cleanup(desc); @@ -786,7 +792,7 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message) dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor); - mutex_lock(&desc->plock); + mutex_lock(&desc->lock); #ifdef CONFIG_PM if ((message.event & PM_EVENT_AUTO) && test_bit(WDM_IN_USE, &desc->flags)) { @@ -798,7 +804,7 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message) #ifdef CONFIG_PM } #endif - mutex_unlock(&desc->plock); + mutex_unlock(&desc->lock); return rv; } @@ -821,9 +827,9 @@ static int wdm_resume(struct usb_interface *intf) int rv; dev_dbg(&desc->intf->dev, "wdm%d_resume\n", intf->minor); - mutex_lock(&desc->plock); + mutex_lock(&desc->lock); rv = recover_from_urb_loss(desc); - mutex_unlock(&desc->plock); + mutex_unlock(&desc->lock); return rv; } @@ -831,7 +837,7 @@ static int wdm_pre_reset(struct usb_interface *intf) { struct wdm_device *desc = usb_get_intfdata(intf); - mutex_lock(&desc->plock); + mutex_lock(&desc->lock); return 0; } @@ -841,7 +847,7 @@ static int wdm_post_reset(struct usb_interface *intf) int rv; rv = recover_from_urb_loss(desc); - mutex_unlock(&desc->plock); + mutex_unlock(&desc->lock); return 0; } -- cgit v0.10.2 From 922a5eadd5a3aa0b806be0c18694b618d41d0784 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Sat, 27 Feb 2010 20:54:59 +0100 Subject: usb: cdc-wdm: Fix race between autosuspend and reading from the device While an available response is read the device must not be autosuspended. This requires a flag dedicated to that purpose. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index cf1c5fb..940b17a 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -52,6 +52,7 @@ MODULE_DEVICE_TABLE (usb, wdm_ids); #define WDM_READ 4 #define WDM_INT_STALL 5 #define WDM_POLL_RUNNING 6 +#define WDM_RESPONDING 7 #define WDM_MAX 16 @@ -115,21 +116,22 @@ static void wdm_in_callback(struct urb *urb) int status = urb->status; spin_lock(&desc->iuspin); + clear_bit(WDM_RESPONDING, &desc->flags); if (status) { switch (status) { case -ENOENT: dev_dbg(&desc->intf->dev, "nonzero urb status received: -ENOENT"); - break; + goto skip_error; case -ECONNRESET: dev_dbg(&desc->intf->dev, "nonzero urb status received: -ECONNRESET"); - break; + goto skip_error; case -ESHUTDOWN: dev_dbg(&desc->intf->dev, "nonzero urb status received: -ESHUTDOWN"); - break; + goto skip_error; case -EPIPE: dev_err(&desc->intf->dev, "nonzero urb status received: -EPIPE\n"); @@ -145,6 +147,7 @@ static void wdm_in_callback(struct urb *urb) desc->reslength = urb->actual_length; memmove(desc->ubuf + desc->length, desc->inbuf, desc->reslength); desc->length += desc->reslength; +skip_error: wake_up(&desc->wait); set_bit(WDM_READ, &desc->flags); @@ -227,6 +230,7 @@ static void wdm_int_callback(struct urb *urb) desc->response->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; spin_lock(&desc->iuspin); clear_bit(WDM_READ, &desc->flags); + set_bit(WDM_RESPONDING, &desc->flags); if (!test_bit(WDM_DISCONNECTING, &desc->flags)) { rv = usb_submit_urb(desc->response, GFP_ATOMIC); dev_dbg(&desc->intf->dev, "%s: usb_submit_urb %d", @@ -234,6 +238,7 @@ static void wdm_int_callback(struct urb *urb) } spin_unlock(&desc->iuspin); if (rv < 0) { + clear_bit(WDM_RESPONDING, &desc->flags); if (rv == -EPERM) return; if (rv == -ENOMEM) { @@ -795,7 +800,8 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message) mutex_lock(&desc->lock); #ifdef CONFIG_PM if ((message.event & PM_EVENT_AUTO) && - test_bit(WDM_IN_USE, &desc->flags)) { + (test_bit(WDM_IN_USE, &desc->flags) + || test_bit(WDM_RESPONDING, &desc->flags))) { rv = -EBUSY; } else { #endif -- cgit v0.10.2 From d855fe2e9c19edaa47baba0e7f95e17f7a24dba8 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Sat, 27 Feb 2010 20:55:26 +0100 Subject: usb: cdc-wdm: Fix race between disconnect and debug messages dev_dbg() and dev_err() cannot be used to report failures that may have been caused by a device's removal Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 940b17a..72e2eb0 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -435,11 +435,8 @@ retry: spin_lock_irq(&desc->iuspin); if (desc->rerr) { /* read completed, error happened */ - int t = desc->rerr; desc->rerr = 0; spin_unlock_irq(&desc->iuspin); - dev_err(&desc->intf->dev, - "reading had resulted in %d\n", t); rv = -EIO; goto err; } @@ -477,8 +474,6 @@ retry: err: mutex_unlock(&desc->lock); - if (rv < 0 && rv != -EAGAIN) - dev_err(&desc->intf->dev, "wdm_read: exit error\n"); return rv; } -- cgit v0.10.2 From beb1d35f1690fe27694472a010a8e4a9ae11cc50 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Sat, 27 Feb 2010 20:55:52 +0100 Subject: usb: cdc-wdm: Fix submission of URB after suspension There's a window under which cdc-wdm may submit an URB to a device about to be suspended. This introduces a flag to prevent it. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 72e2eb0..a6b5e9f 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -53,7 +53,7 @@ MODULE_DEVICE_TABLE (usb, wdm_ids); #define WDM_INT_STALL 5 #define WDM_POLL_RUNNING 6 #define WDM_RESPONDING 7 - +#define WDM_SUSPENDING 8 #define WDM_MAX 16 @@ -231,7 +231,8 @@ static void wdm_int_callback(struct urb *urb) spin_lock(&desc->iuspin); clear_bit(WDM_READ, &desc->flags); set_bit(WDM_RESPONDING, &desc->flags); - if (!test_bit(WDM_DISCONNECTING, &desc->flags)) { + if (!test_bit(WDM_DISCONNECTING, &desc->flags) + && !test_bit(WDM_SUSPENDING, &desc->flags)) { rv = usb_submit_urb(desc->response, GFP_ATOMIC); dev_dbg(&desc->intf->dev, "%s: usb_submit_urb %d", __func__, rv); @@ -800,6 +801,7 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message) rv = -EBUSY; } else { #endif + set_bit(WDM_SUSPENDING, &desc->flags); cancel_work_sync(&desc->rxwork); kill_urbs(desc); #ifdef CONFIG_PM @@ -830,6 +832,7 @@ static int wdm_resume(struct usb_interface *intf) dev_dbg(&desc->intf->dev, "wdm%d_resume\n", intf->minor); mutex_lock(&desc->lock); rv = recover_from_urb_loss(desc); + clear_bit(WDM_SUSPENDING, &desc->flags); mutex_unlock(&desc->lock); return rv; } -- cgit v0.10.2 From 62e6685470fb04fb7688ecef96c39160498721d5 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Sat, 27 Feb 2010 20:56:22 +0100 Subject: usb: cdc-wdm:Fix loss of data due to autosuspend The guarding flag must be set and tested under spinlock and cleared before the URBs are resubmitted in resume. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index a6b5e9f..07c1297 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -794,14 +794,17 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message) dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor); mutex_lock(&desc->lock); + spin_lock_irq(&desc->iuspin); #ifdef CONFIG_PM if ((message.event & PM_EVENT_AUTO) && (test_bit(WDM_IN_USE, &desc->flags) || test_bit(WDM_RESPONDING, &desc->flags))) { + spin_unlock_irq(&desc->iuspin); rv = -EBUSY; } else { #endif set_bit(WDM_SUSPENDING, &desc->flags); + spin_unlock_irq(&desc->iuspin); cancel_work_sync(&desc->rxwork); kill_urbs(desc); #ifdef CONFIG_PM @@ -831,8 +834,8 @@ static int wdm_resume(struct usb_interface *intf) dev_dbg(&desc->intf->dev, "wdm%d_resume\n", intf->minor); mutex_lock(&desc->lock); - rv = recover_from_urb_loss(desc); clear_bit(WDM_SUSPENDING, &desc->flags); + rv = recover_from_urb_loss(desc); mutex_unlock(&desc->lock); return rv; } -- cgit v0.10.2 From d93d16e9aa58887feadd999ea26b7b8139e98b56 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Sat, 27 Feb 2010 20:56:47 +0100 Subject: usb: cdc-wdm: Fix order in disconnect and fix locking - as the callback can schedule work, URBs must be killed first - if the driver causes an autoresume, the caller must handle locking Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 07c1297..b574905 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -776,9 +776,9 @@ static void wdm_disconnect(struct usb_interface *intf) /* to terminate pending flushes */ clear_bit(WDM_IN_USE, &desc->flags); spin_unlock_irqrestore(&desc->iuspin, flags); - cancel_work_sync(&desc->rxwork); mutex_lock(&desc->lock); kill_urbs(desc); + cancel_work_sync(&desc->rxwork); mutex_unlock(&desc->lock); wake_up_all(&desc->wait); if (!desc->count) @@ -786,6 +786,7 @@ static void wdm_disconnect(struct usb_interface *intf) mutex_unlock(&wdm_mutex); } +#ifdef CONFIG_PM static int wdm_suspend(struct usb_interface *intf, pm_message_t message) { struct wdm_device *desc = usb_get_intfdata(intf); @@ -793,27 +794,30 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message) dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor); - mutex_lock(&desc->lock); + /* if this is an autosuspend the caller does the locking */ + if (!(message.event & PM_EVENT_AUTO)) + mutex_lock(&desc->lock); spin_lock_irq(&desc->iuspin); -#ifdef CONFIG_PM + if ((message.event & PM_EVENT_AUTO) && (test_bit(WDM_IN_USE, &desc->flags) || test_bit(WDM_RESPONDING, &desc->flags))) { spin_unlock_irq(&desc->iuspin); rv = -EBUSY; } else { -#endif + set_bit(WDM_SUSPENDING, &desc->flags); spin_unlock_irq(&desc->iuspin); - cancel_work_sync(&desc->rxwork); + /* callback submits work - order is essential */ kill_urbs(desc); -#ifdef CONFIG_PM + cancel_work_sync(&desc->rxwork); } -#endif - mutex_unlock(&desc->lock); + if (!(message.event & PM_EVENT_AUTO)) + mutex_unlock(&desc->lock); return rv; } +#endif static int recover_from_urb_loss(struct wdm_device *desc) { @@ -827,6 +831,8 @@ static int recover_from_urb_loss(struct wdm_device *desc) } return rv; } + +#ifdef CONFIG_PM static int wdm_resume(struct usb_interface *intf) { struct wdm_device *desc = usb_get_intfdata(intf); @@ -839,6 +845,7 @@ static int wdm_resume(struct usb_interface *intf) mutex_unlock(&desc->lock); return rv; } +#endif static int wdm_pre_reset(struct usb_interface *intf) { @@ -862,9 +869,11 @@ static struct usb_driver wdm_driver = { .name = "cdc_wdm", .probe = wdm_probe, .disconnect = wdm_disconnect, +#ifdef CONFIG_PM .suspend = wdm_suspend, .resume = wdm_resume, .reset_resume = wdm_resume, +#endif .pre_reset = wdm_pre_reset, .post_reset = wdm_post_reset, .id_table = wdm_ids, -- cgit v0.10.2 From 338124c1f18c2c737656ac58735f040d90b23d8c Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Sat, 27 Feb 2010 20:57:12 +0100 Subject: usb: cdc-wdm: Fix deadlock between write and resume The new runtime PM scheme allows resume() to have no locks. This fixes the deadlock. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index b574905..189141c 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -839,10 +839,10 @@ static int wdm_resume(struct usb_interface *intf) int rv; dev_dbg(&desc->intf->dev, "wdm%d_resume\n", intf->minor); - mutex_lock(&desc->lock); + clear_bit(WDM_SUSPENDING, &desc->flags); rv = recover_from_urb_loss(desc); - mutex_unlock(&desc->lock); + return rv; } #endif -- cgit v0.10.2 From 510607db7e2ad5078c554911418a71b469886076 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Wed, 3 Mar 2010 19:37:12 +0100 Subject: USB: serial: Fix module name typo for qcaux Kconfig entry. The module is called qcaux and not moto_modem. Also use help instead of ---help-- to be in sync with the other Kconfig entries. Signed-off-by: Stefan Schmidt Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index c78b255..a0ecb42 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig @@ -474,14 +474,14 @@ config USB_SERIAL_OTI6858 config USB_SERIAL_QCAUX tristate "USB Qualcomm Auxiliary Serial Port Driver" - ---help--- + help Say Y here if you want to use the auxiliary serial ports provided by many modems based on Qualcomm chipsets. These ports often use a proprietary protocol called DM and cannot be used for AT- or PPP-based communication. To compile this driver as a module, choose M here: the - module will be called moto_modem. If unsure, choose N. + module will be called qcaux. If unsure, choose N. config USB_SERIAL_QUALCOMM tristate "USB Qualcomm Serial modem" -- cgit v0.10.2 From 33c387529b7931248c6637bf9720ac7504a0b28b Mon Sep 17 00:00:00 2001 From: spark Date: Fri, 5 Mar 2010 14:18:05 +0800 Subject: USB: option.c: Add Pirelli VID/PID and indicate Pirelli's modem interface is 0xff Signed-off-by: spark Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 3af1eb8..950cb31 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -335,6 +335,24 @@ static int option_resume(struct usb_serial *serial); #define ALCATEL_VENDOR_ID 0x1bbb #define ALCATEL_PRODUCT_X060S 0x0000 +#define PIRELLI_VENDOR_ID 0x1266 +#define PIRELLI_PRODUCT_C100_1 0x1002 +#define PIRELLI_PRODUCT_C100_2 0x1003 +#define PIRELLI_PRODUCT_1004 0x1004 +#define PIRELLI_PRODUCT_1005 0x1005 +#define PIRELLI_PRODUCT_1006 0x1006 +#define PIRELLI_PRODUCT_1007 0x1007 +#define PIRELLI_PRODUCT_1008 0x1008 +#define PIRELLI_PRODUCT_1009 0x1009 +#define PIRELLI_PRODUCT_100A 0x100a +#define PIRELLI_PRODUCT_100B 0x100b +#define PIRELLI_PRODUCT_100C 0x100c +#define PIRELLI_PRODUCT_100D 0x100d +#define PIRELLI_PRODUCT_100E 0x100e +#define PIRELLI_PRODUCT_100F 0x100f +#define PIRELLI_PRODUCT_1011 0x1011 +#define PIRELLI_PRODUCT_1012 0x1012 + /* Airplus products */ #define AIRPLUS_VENDOR_ID 0x1011 #define AIRPLUS_PRODUCT_MCD650 0x3198 @@ -679,6 +697,24 @@ static const struct usb_device_id option_ids[] = { .driver_info = (kernel_ulong_t)&four_g_w14_blacklist }, { USB_DEVICE(HAIER_VENDOR_ID, HAIER_PRODUCT_CE100) }, + /* Pirelli */ + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_C100_1)}, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_C100_2)}, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1004)}, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1005)}, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1006)}, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1007)}, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1008)}, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1009)}, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100A)}, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100B) }, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100C) }, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100D) }, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100E) }, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100F) }, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1011)}, + { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1012)}, + { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, option_ids); @@ -802,12 +838,19 @@ static int option_probe(struct usb_serial *serial, const struct usb_device_id *id) { struct option_intf_private *data; + /* D-Link DWM 652 still exposes CD-Rom emulation interface in modem mode */ if (serial->dev->descriptor.idVendor == DLINK_VENDOR_ID && serial->dev->descriptor.idProduct == DLINK_PRODUCT_DWM_652 && serial->interface->cur_altsetting->desc.bInterfaceClass == 0x8) return -ENODEV; + /* Bandrich modem and AT command interface is 0xff */ + if ((serial->dev->descriptor.idVendor == BANDRICH_VENDOR_ID || + serial->dev->descriptor.idVendor == PIRELLI_VENDOR_ID) && + serial->interface->cur_altsetting->desc.bInterfaceClass != 0xff) + return -ENODEV; + data = serial->private = kzalloc(sizeof(struct option_intf_private), GFP_KERNEL); if (!data) return -ENOMEM; -- cgit v0.10.2 From 872f8b42544c58dfa241956d220ada115a8e93c7 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 6 Mar 2010 14:08:56 +0300 Subject: USB: goku_udc: remove potential null dereference "dev" is always null here. In the end it's only used to get the pci_name() of "pdev" which is redundant information and so I removed it. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index e8edc64..1088d08 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c @@ -1768,7 +1768,7 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id) * usb_gadget_driver_{register,unregister}() must change. */ if (the_controller) { - WARNING(dev, "ignoring %s\n", pci_name(pdev)); + pr_warning("ignoring %s\n", pci_name(pdev)); return -EBUSY; } if (!pdev->irq) { -- cgit v0.10.2 From f2984a333fb5e325d478950c9d8af3693869e69c Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 9 Mar 2010 00:35:22 -0500 Subject: USB: gadget: fix Blackfin builds after gadget cleansing The recent change to clean out dead gadget drivers (90f7976880bbbf99) missed the call to gadget_is_musbhsfc() behind CONFIG_BLACKFIN. This causes Blackfin gadget builds to fail since the function no longer exists anywhere. Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index 65a5f94..3568de2 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/drivers/usb/gadget/epautoconf.c @@ -266,7 +266,7 @@ struct usb_ep * __init usb_ep_autoconfig ( } #ifdef CONFIG_BLACKFIN - } else if (gadget_is_musbhsfc(gadget) || gadget_is_musbhdrc(gadget)) { + } else if (gadget_is_musbhdrc(gadget)) { if ((USB_ENDPOINT_XFER_BULK == type) || (USB_ENDPOINT_XFER_ISOC == type)) { if (USB_DIR_IN & desc->bEndpointAddress) -- cgit v0.10.2 From f88f6691b73a35b0c6dcabb9e587aa4c63d09010 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sun, 7 Mar 2010 10:36:27 -0500 Subject: USB: g_mass_storage: fix section mismatch warnings The recent commit (0e530b45783f75) that moved usb_ep_autoconfig from the __devinit section to the __init section missed the mass storage device. Its fsg_bind() function uses the usb_ep_autoconfig() function from non __init context leading to: WARNING: drivers/usb/gadget/g_mass_storage.o(.text): Section mismatch in reference from the function _fsg_bind() to the function .init.text:_usb_ep_autoconfig() So move fsg_bind() into __init as well. Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 5a3cdd0..db08de2 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -2910,7 +2910,7 @@ static void fsg_unbind(struct usb_configuration *c, struct usb_function *f) } -static int fsg_bind(struct usb_configuration *c, struct usb_function *f) +static int __init fsg_bind(struct usb_configuration *c, struct usb_function *f) { struct fsg_dev *fsg = fsg_from_func(f); struct usb_gadget *gadget = c->cdev->gadget; -- cgit v0.10.2 From f479d70b4f7674083c2e3c3e603b15811713fb18 Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Fri, 12 Mar 2010 15:55:28 +0100 Subject: USB: gadget: f_mass_storage::fsg_bind(): fix error handling Contrary to the comment in fsg_add, fsg_bind calls fsg_unbind on errors, which decreases refcount and frees the fsg_dev structure, causing trouble when fsg_add does the same. Fix it by simply leaving up cleanup to fsg_add(). Signed-off-by: Peter Korsgaard Acked-by: Michal Nazarewicz Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index db08de2..f4911c0 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -2954,7 +2954,6 @@ static int __init fsg_bind(struct usb_configuration *c, struct usb_function *f) autoconf_fail: ERROR(fsg, "unable to autoconfigure all endpoints\n"); rc = -ENOTSUPP; - fsg_unbind(c, f); return rc; } -- cgit v0.10.2 From 11b10d999469dc0514447a15e88c7ef14ec0761d Mon Sep 17 00:00:00 2001 From: Michal Nazarewicz Date: Mon, 15 Mar 2010 11:10:23 +0100 Subject: USB: g_mass_storage: fixed module name in Kconfig The Kconfig help message for Mass Storage Gadget claimed the module will be named "g_file_storage" whereas it should be "g_mass_storage". Signed-off-by: Michal Nazarewicz Cc: Kyungmin Park Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 7460cd7..11a3e0f 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -747,7 +747,7 @@ config USB_MASS_STORAGE which may be used with composite framework. Say "y" to link the driver statically, or "m" to build - a dynamically linked module called "g_file_storage". If unsure, + a dynamically linked module called "g_mass_storage". If unsure, consider File-backed Storage Gadget. config USB_G_SERIAL -- cgit v0.10.2 From 9c67d28e4e7683b4f667fa4c7b6f9aee92b44b5c Mon Sep 17 00:00:00 2001 From: Alessio Igor Bogani Date: Sat, 13 Mar 2010 18:35:14 +0100 Subject: USB: ftdi_sio: Fix locking for change_speed() function The change_speed() function should be serialized against multiple calls. Use the cfg_lock mutex to do this. Signed-off-by: Alessio Igor Bogani Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 6fc09dc..1d7c4fa 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -91,7 +91,7 @@ struct ftdi_private { unsigned long tx_outstanding_bytes; unsigned long tx_outstanding_urbs; unsigned short max_packet_size; - struct mutex cfg_lock; /* Avoid mess by parallel calls of config ioctl() */ + struct mutex cfg_lock; /* Avoid mess by parallel calls of config ioctl() and change_speed() */ }; /* struct ftdi_sio_quirk is used by devices requiring special attention. */ @@ -1273,8 +1273,8 @@ check_and_exit: (priv->flags & ASYNC_SPD_MASK)) || (((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) && (old_priv.custom_divisor != priv->custom_divisor))) { - mutex_unlock(&priv->cfg_lock); change_speed(tty, port); + mutex_unlock(&priv->cfg_lock); } else mutex_unlock(&priv->cfg_lock); @@ -2265,9 +2265,11 @@ static void ftdi_set_termios(struct tty_struct *tty, clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); } else { /* set the baudrate determined before */ + mutex_lock(&priv->cfg_lock); if (change_speed(tty, port)) dev_err(&port->dev, "%s urb failed to set baudrate\n", __func__); + mutex_unlock(&priv->cfg_lock); /* Ensure RTS and DTR are raised when baudrate changed from 0 */ if (!old_termios || (old_termios->c_cflag & CBAUD) == B0) set_mctrl(port, TIOCM_DTR | TIOCM_RTS); -- cgit v0.10.2 From 83ba11d93434e6f0cc2e060336b0b19a3f687fa3 Mon Sep 17 00:00:00 2001 From: Maurus Cuelenaere Date: Mon, 8 Mar 2010 18:20:59 +0100 Subject: USB: gadget: add gadget controller number for s3c-hsotg driver This prevents some drivers from complaining that no bcdDevice id was set. Signed-off-by: Maurus Cuelenaere Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h index 1edbc12..e511fec 100644 --- a/drivers/usb/gadget/gadget_chips.h +++ b/drivers/usb/gadget/gadget_chips.h @@ -136,6 +136,12 @@ #define gadget_is_r8a66597(g) 0 #endif +#ifdef CONFIG_USB_S3C_HSOTG +#define gadget_is_s3c_hsotg(g) (!strcmp("s3c-hsotg", (g)->name)) +#else +#define gadget_is_s3c_hsotg(g) 0 +#endif + /** * usb_gadget_controller_number - support bcdDevice id convention @@ -192,6 +198,8 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget) return 0x24; else if (gadget_is_r8a66597(gadget)) return 0x25; + else if (gadget_is_s3c_hsotg(gadget)) + return 0x26; return -ENOENT; } -- cgit v0.10.2 From 7f56cfd253d929c06ce4ed5bfb99a8c6805075c9 Mon Sep 17 00:00:00 2001 From: Christoph Egger Date: Wed, 10 Mar 2010 12:33:11 +0100 Subject: USB: Remove last bit of CONFIG_USB_BERRY_CHARGE One last bit was missed while removing the USB_BERRY_CHARGE config option in a8d4211f33a9573f7b1bdcfd9c9c48631d1515ee which gets dropped by this patch. Signed-off-by: Christoph Egger Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 61c8b9d..ccf1dbb 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1389,20 +1389,6 @@ UNUSUAL_DEV( 0x0f19, 0x0105, 0x0100, 0x0100, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_IGNORE_RESIDUE ), -/* Jeremy Katz : - * The Blackberry Pearl can run in two modes; a usb-storage only mode - * and a mode that allows access via mass storage and to its database. - * The berry_charge module will set the device to dual mode and thus we - * should ignore its native mode if that module is built - */ -#ifdef CONFIG_USB_BERRY_CHARGE -UNUSUAL_DEV( 0x0fca, 0x0006, 0x0001, 0x0001, - "RIM", - "Blackberry Pearl", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_IGNORE_DEVICE ), -#endif - /* Reported by Michael Stattmann */ UNUSUAL_DEV( 0x0fce, 0xd008, 0x0000, 0x0000, "Sony Ericsson", -- cgit v0.10.2 From e549a17f698e266373f6757bd068d1e98397b4c0 Mon Sep 17 00:00:00 2001 From: Michael Brunner Date: Wed, 10 Mar 2010 23:26:37 +0100 Subject: USB: cp210x: Remove double usb_control_msg from cp210x_set_config This patch removes a double usb_control_msg that sets the cp210x configuration registers a second time when calling cp210x_set_config. For data sizes >2 the second write gets corrupted. The patch has been created against 2.6.34-rc1, but all cp210x driver revisions are affected. Signed-off-by: Michael Brunner Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 507382b..ec9b044 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -313,11 +313,6 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request, return -EPROTO; } - /* Single data value */ - result = usb_control_msg(serial->dev, - usb_sndctrlpipe(serial->dev, 0), - request, REQTYPE_HOST_TO_DEVICE, data[0], - 0, NULL, 0, 300); return 0; } -- cgit v0.10.2 From f09a15e6e69884cedec4d1c022089a973aa01f1e Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 16 Mar 2010 12:55:44 -0700 Subject: USB: Fix usb_fill_int_urb for SuperSpeed devices USB 3 and Wireless USB specify a logarithmic encoding of the endpoint interval that matches the USB 2 specification. usb_fill_int_urb() didn't know that and was filling in the interval as if it was USB 1.1. Fix usb_fill_int_urb() for SuperSpeed devices, but leave the wireless case alone, because David Vrabel wants to keep the old encoding. Update the struct urb kernel doc to note that SuperSpeed URBs must have urb->interval specified in microframes. Add a missing break statement in the usb_submit_urb() interrupt URB checking, since wireless USB and SuperSpeed USB encode urb->interval differently. This allows xHCI roothubs to actually register with khubd. Signed-off-by: Matthew Wilcox Signed-off-by: Sarah Sharp Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 2708056..45a32da 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c @@ -453,6 +453,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) if (urb->interval > (1 << 15)) return -EINVAL; max = 1 << 15; + break; case USB_SPEED_WIRELESS: if (urb->interval > 16) return -EINVAL; diff --git a/include/linux/usb.h b/include/linux/usb.h index 8c9f053..ce1323c 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -1055,7 +1055,8 @@ typedef void (*usb_complete_t)(struct urb *); * @number_of_packets: Lists the number of ISO transfer buffers. * @interval: Specifies the polling interval for interrupt or isochronous * transfers. The units are frames (milliseconds) for full and low - * speed devices, and microframes (1/8 millisecond) for highspeed ones. + * speed devices, and microframes (1/8 millisecond) for highspeed + * and SuperSpeed devices. * @error_count: Returns the number of ISO transfers that reported errors. * @context: For use in completion functions. This normally points to * request-specific driver context. @@ -1286,9 +1287,16 @@ static inline void usb_fill_bulk_urb(struct urb *urb, * * Initializes a interrupt urb with the proper information needed to submit * it to a device. - * Note that high speed interrupt endpoints use a logarithmic encoding of - * the endpoint interval, and express polling intervals in microframes - * (eight per millisecond) rather than in frames (one per millisecond). + * + * Note that High Speed and SuperSpeed interrupt endpoints use a logarithmic + * encoding of the endpoint interval, and express polling intervals in + * microframes (eight per millisecond) rather than in frames (one per + * millisecond). + * + * Wireless USB also uses the logarithmic encoding, but specifies it in units of + * 128us instead of 125us. For Wireless USB devices, the interval is passed + * through to the host controller, rather than being translated into microframe + * units. */ static inline void usb_fill_int_urb(struct urb *urb, struct usb_device *dev, @@ -1305,7 +1313,7 @@ static inline void usb_fill_int_urb(struct urb *urb, urb->transfer_buffer_length = buffer_length; urb->complete = complete_fn; urb->context = context; - if (dev->speed == USB_SPEED_HIGH) + if (dev->speed == USB_SPEED_HIGH || dev->speed == USB_SPEED_SUPER) urb->interval = 1 << (interval - 1); else urb->interval = interval; -- cgit v0.10.2 From 9ce669a8924c61b7321d6e2f27ed67bcd46c1fbb Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Tue, 16 Mar 2010 12:59:24 -0700 Subject: USB: xhci: Make endpoint interval debugging clearer. The xHCI hardware can only handle polling intervals that are a power of two. When we add a new endpoint during a bandwidth allocation, and the polling interval is rounded down to a power of two, print the original polling interval in the endpoint descriptor. Signed-off-by: Sarah Sharp Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 49f7d72..bba9b19 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -566,8 +566,13 @@ static inline unsigned int xhci_get_endpoint_interval(struct usb_device *udev, if (interval < 3) interval = 3; if ((1 << interval) != 8*ep->desc.bInterval) - dev_warn(&udev->dev, "ep %#x - rounding interval to %d microframes\n", - ep->desc.bEndpointAddress, 1 << interval); + dev_warn(&udev->dev, + "ep %#x - rounding interval" + " to %d microframes, " + "ep desc says %d microframes\n", + ep->desc.bEndpointAddress, + 1 << interval, + 8*ep->desc.bInterval); } break; default: -- cgit v0.10.2 From d835933436ac0d1e8f5b35fe809fd4e767e55d6e Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Tue, 16 Mar 2010 12:29:35 +0900 Subject: usb: r8a66597-hcd: fix removed from an attached hub fix the problem that when a USB hub is attached to the r8a66597-hcd and a device is removed from that hub, it's likely that a kernel panic follows. Reported-by: Markus Pietrek Signed-off-by: Yoshihiro Shimoda Cc: stable Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index bee558ae..f71a73a 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -418,7 +418,7 @@ static u8 alloc_usb_address(struct r8a66597 *r8a66597, struct urb *urb) /* this function must be called with interrupt disabled */ static void free_usb_address(struct r8a66597 *r8a66597, - struct r8a66597_device *dev) + struct r8a66597_device *dev, int reset) { int port; @@ -430,7 +430,13 @@ static void free_usb_address(struct r8a66597 *r8a66597, dev->state = USB_STATE_DEFAULT; r8a66597->address_map &= ~(1 << dev->address); dev->address = 0; - dev_set_drvdata(&dev->udev->dev, NULL); + /* + * Only when resetting USB, it is necessary to erase drvdata. When + * a usb device with usb hub is disconnect, "dev->udev" is already + * freed on usb_desconnect(). So we cannot access the data. + */ + if (reset) + dev_set_drvdata(&dev->udev->dev, NULL); list_del(&dev->device_list); kfree(dev); @@ -1069,7 +1075,7 @@ static void r8a66597_usb_disconnect(struct r8a66597 *r8a66597, int port) struct r8a66597_device *dev = r8a66597->root_hub[port].dev; disable_r8a66597_pipe_all(r8a66597, dev); - free_usb_address(r8a66597, dev); + free_usb_address(r8a66597, dev, 0); start_root_hub_sampling(r8a66597, port, 0); } @@ -2085,7 +2091,7 @@ static void update_usb_address_map(struct r8a66597 *r8a66597, spin_lock_irqsave(&r8a66597->lock, flags); dev = get_r8a66597_device(r8a66597, addr); disable_r8a66597_pipe_all(r8a66597, dev); - free_usb_address(r8a66597, dev); + free_usb_address(r8a66597, dev, 0); put_child_connect_map(r8a66597, addr); spin_unlock_irqrestore(&r8a66597->lock, flags); } @@ -2228,7 +2234,7 @@ static int r8a66597_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, rh->port |= (1 << USB_PORT_FEAT_RESET); disable_r8a66597_pipe_all(r8a66597, dev); - free_usb_address(r8a66597, dev); + free_usb_address(r8a66597, dev, 1); r8a66597_mdfy(r8a66597, USBRST, USBRST | UACT, get_dvstctr_reg(port)); -- cgit v0.10.2 From 4cb80cda51ff950614701fb30c9d4e583fe5a31f Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Fri, 12 Mar 2010 12:33:15 +0100 Subject: USB: gadget/multi: cdc_do_config: remove redundant check cdc_do_config() had a double ret check after fsg_add(). Signed-off-by: Peter Korsgaard Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c index 76496f5..a930d7f 100644 --- a/drivers/usb/gadget/multi.c +++ b/drivers/usb/gadget/multi.c @@ -211,8 +211,6 @@ static int __init cdc_do_config(struct usb_configuration *c) ret = fsg_add(c->cdev, c, fsg_common); if (ret < 0) return ret; - if (ret < 0) - return ret; return 0; } -- cgit v0.10.2 From 8727b909bb2348d29e62c599cd7a5d610da3760f Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Sun, 28 Feb 2010 10:42:38 +0800 Subject: ASoC: pxa-pcm-lib: initialize DMA channel to -1 This fixes a warning ("pxa_free_dma: trying to free channel 0 which is already freed") when a device was opened but the hw_params() call failed. Signed-off-by: Daniel Mack Acked-by: Liam Girdwood Signed-off-by: Mark Brown diff --git a/sound/arm/pxa2xx-pcm-lib.c b/sound/arm/pxa2xx-pcm-lib.c index 743ac6a..fd51fa8 100644 --- a/sound/arm/pxa2xx-pcm-lib.c +++ b/sound/arm/pxa2xx-pcm-lib.c @@ -205,6 +205,7 @@ int __pxa2xx_pcm_open(struct snd_pcm_substream *substream) if (!rtd->dma_desc_array) goto err1; + rtd->dma_ch = -1; runtime->private_data = rtd; return 0; -- cgit v0.10.2 From d812e575822a2b7ab1a7cadae2571505ec6ec2bd Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 19 Mar 2010 13:55:17 -0400 Subject: NFS: Prevent another deadlock in nfs_release_page() We should not attempt to free the page if __GFP_FS is not set. Otherwise we can deadlock as per http://bugzilla.kernel.org/show_bug.cgi?id=15578 Signed-off-by: Trond Myklebust Cc: stable@kernel.org diff --git a/fs/nfs/file.c b/fs/nfs/file.c index ae8d022..ae0d927 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -491,7 +491,8 @@ static int nfs_release_page(struct page *page, gfp_t gfp) { dfprintk(PAGECACHE, "NFS: release_page(%p)\n", page); - if (gfp & __GFP_WAIT) + /* Only do I/O if gfp is a superset of GFP_KERNEL */ + if ((gfp & GFP_KERNEL) == GFP_KERNEL) nfs_wb_page(page->mapping->host, page); /* If PagePrivate() is set, then the page is not freeable */ if (PagePrivate(page)) -- cgit v0.10.2 From 17cf4442497cb2551eae1dedee638515db47c23e Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Fri, 19 Mar 2010 14:25:45 -0400 Subject: Delete zero-length file drivers/mtd/maps/omap_nor.c The content was deleted in cc87edb173effdf74e680ee6d622a935ff0c1d6f, but the file remained as a zero-length file. Signed-off-by: Jeff Garzik diff --git a/drivers/mtd/maps/omap_nor.c b/drivers/mtd/maps/omap_nor.c deleted file mode 100644 index e69de29..0000000 -- cgit v0.10.2 From 25daeb550b69e89aff59bc6a84218a12b5203531 Mon Sep 17 00:00:00 2001 From: Dean Nelson Date: Tue, 9 Mar 2010 22:26:40 -0500 Subject: PCI: fix return value from pcix_get_max_mmrbc() For the PCI_X_STATUS register, pcix_get_max_mmrbc() is returning an incorrect value, which is based on: (stat & PCI_X_STATUS_MAX_READ) >> 12 Valid return values are 512, 1024, 2048, 4096, which correspond to a 'stat' (masked and right shifted by 21) of 0, 1, 2, 3, respectively. A right shift by 11 would generate the correct return value when 'stat' (masked and right shifted by 21) has a value of 1 or 2. But for a value of 0 or 3 it's not possible to generate the correct return value by only right shifting. Fix is based on pcix_get_mmrbc()'s similar dealings with the PCI_X_CMD register. Cc: stable@kernel.org Signed-off-by: Dean Nelson Signed-off-by: Jesse Barnes diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index cb1dd5f..ed9eb68 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -2587,7 +2587,7 @@ int pcix_get_max_mmrbc(struct pci_dev *dev) if (err) return -EINVAL; - return (stat & PCI_X_STATUS_MAX_READ) >> 12; + return 512 << ((stat & PCI_X_STATUS_MAX_READ) >> 21); } EXPORT_SYMBOL(pcix_get_max_mmrbc); -- cgit v0.10.2 From ded1d8f29b4d315a2093cafc3ee17ac870a87972 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 11 Mar 2010 14:08:33 -0800 Subject: PCI: kill off pci_register_set_vga_state() symbol export. When pci_register_set_vga_state() was made __init, the EXPORT_SYMBOL() was retained, which now leaves us with a section mismatch. Signed-off-by: Paul Mundt Cc: Mike Travis Signed-off-by: Andrew Morton Signed-off-by: Jesse Barnes diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index ed9eb68..9af9860 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -3023,7 +3023,6 @@ EXPORT_SYMBOL(pcim_pin_device); EXPORT_SYMBOL(pci_disable_device); EXPORT_SYMBOL(pci_find_capability); EXPORT_SYMBOL(pci_bus_find_capability); -EXPORT_SYMBOL(pci_register_set_vga_state); EXPORT_SYMBOL(pci_release_regions); EXPORT_SYMBOL(pci_request_regions); EXPORT_SYMBOL(pci_request_regions_exclusive); -- cgit v0.10.2 From bdc2bda7c4dd253026cc1fce45fc939304749029 Mon Sep 17 00:00:00 2001 From: Dean Nelson Date: Tue, 9 Mar 2010 22:26:48 -0500 Subject: PCI: fix access of PCI_X_CMD by pcix get and set mmrbc functions An e1000 driver on a system with a PCI-X bus was always being returned a value of 135 from both pcix_get_mmrbc() and pcix_set_mmrbc(). This value reflects an error return of PCIBIOS_BAD_REGISTER_NUMBER from pci_bus_read_config_dword(,, cap + PCI_X_CMD,). This is because for a dword, the following portion of the PCI_OP_READ() macro: if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; expands to: if (pos & 3) return PCIBIOS_BAD_REGISTER_NUMBER; And is always true for 'cap + PCI_X_CMD', which is 0xe4 + 2 = 0xe6. ('cap' is the result of calling pci_find_capability(, PCI_CAP_ID_PCIX).) The same problem exists for pci_bus_write_config_dword(,, cap + PCI_X_CMD,). In both cases, instead of calling _dword(), _word() should be called. Cc: stable@kernel.org Signed-off-by: Dean Nelson Signed-off-by: Jesse Barnes diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 9af9860..5c80b59 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -2601,13 +2601,13 @@ EXPORT_SYMBOL(pcix_get_max_mmrbc); int pcix_get_mmrbc(struct pci_dev *dev) { int ret, cap; - u32 cmd; + u16 cmd; cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); if (!cap) return -EINVAL; - ret = pci_read_config_dword(dev, cap + PCI_X_CMD, &cmd); + ret = pci_read_config_word(dev, cap + PCI_X_CMD, &cmd); if (!ret) ret = 512 << ((cmd & PCI_X_CMD_MAX_READ) >> 2); @@ -2627,7 +2627,8 @@ EXPORT_SYMBOL(pcix_get_mmrbc); int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc) { int cap, err = -EINVAL; - u32 stat, cmd, v, o; + u32 stat, v, o; + u16 cmd; if (mmrbc < 512 || mmrbc > 4096 || !is_power_of_2(mmrbc)) goto out; @@ -2645,7 +2646,7 @@ int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc) if (v > (stat & PCI_X_STATUS_MAX_READ) >> 21) return -E2BIG; - err = pci_read_config_dword(dev, cap + PCI_X_CMD, &cmd); + err = pci_read_config_word(dev, cap + PCI_X_CMD, &cmd); if (err) goto out; @@ -2657,7 +2658,7 @@ int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc) cmd &= ~PCI_X_CMD_MAX_READ; cmd |= v << 2; - err = pci_write_config_dword(dev, cap + PCI_X_CMD, cmd); + err = pci_write_config_word(dev, cap + PCI_X_CMD, cmd); } out: return err; -- cgit v0.10.2 From 7c9e2b1c4784c6e574f69dbd904b2822f2e04d6e Mon Sep 17 00:00:00 2001 From: Dean Nelson Date: Tue, 9 Mar 2010 22:26:55 -0500 Subject: PCI: cleanup error return for pcix get and set mmrbc functions pcix_get_mmrbc() returns the maximum memory read byte count (mmrbc), if successful, or an appropriate error value, if not. Distinguishing errors from correct values and understanding the meaning of an error can be somewhat confusing in that: correct values: 512, 1024, 2048, 4096 errors: -EINVAL -22 PCIBIOS_FUNC_NOT_SUPPORTED 0x81 PCIBIOS_BAD_VENDOR_ID 0x83 PCIBIOS_DEVICE_NOT_FOUND 0x86 PCIBIOS_BAD_REGISTER_NUMBER 0x87 PCIBIOS_SET_FAILED 0x88 PCIBIOS_BUFFER_TOO_SMALL 0x89 The PCIBIOS_ errors are returned from the PCI functions generated by the PCI_OP_READ() and PCI_OP_WRITE() macros. In a similar manner, pcix_set_mmrbc() also returns the PCIBIOS_ error values returned from pci_read_config_[word|dword]() and pci_write_config_word(). Following pcix_get_max_mmrbc()'s example, the following patch simply returns -EINVAL for all PCIBIOS_ errors encountered by pcix_get_mmrbc(), and -EINVAL or -EIO for those encountered by pcix_set_mmrbc(). This simplification was chosen in light of the fact that none of the current callers of these functions are interested in the specific type of error encountered. In the future, should this change, one could simply create a function that maps each PCIBIOS_ error to a corresponding unique errno value, which could be called by pcix_get_max_mmrbc(), pcix_get_mmrbc(), and pcix_set_mmrbc(). Additionally, this patch eliminates some unnecessary variables. Cc: stable@kernel.org Signed-off-by: Dean Nelson Signed-off-by: Jesse Barnes diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 5c80b59..1531f3a 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -2576,15 +2576,14 @@ EXPORT_SYMBOL_GPL(pci_reset_function); */ int pcix_get_max_mmrbc(struct pci_dev *dev) { - int err, cap; + int cap; u32 stat; cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); if (!cap) return -EINVAL; - err = pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat); - if (err) + if (pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat)) return -EINVAL; return 512 << ((stat & PCI_X_STATUS_MAX_READ) >> 21); @@ -2600,18 +2599,17 @@ EXPORT_SYMBOL(pcix_get_max_mmrbc); */ int pcix_get_mmrbc(struct pci_dev *dev) { - int ret, cap; + int cap; u16 cmd; cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); if (!cap) return -EINVAL; - ret = pci_read_config_word(dev, cap + PCI_X_CMD, &cmd); - if (!ret) - ret = 512 << ((cmd & PCI_X_CMD_MAX_READ) >> 2); + if (pci_read_config_word(dev, cap + PCI_X_CMD, &cmd)) + return -EINVAL; - return ret; + return 512 << ((cmd & PCI_X_CMD_MAX_READ) >> 2); } EXPORT_SYMBOL(pcix_get_mmrbc); @@ -2626,29 +2624,27 @@ EXPORT_SYMBOL(pcix_get_mmrbc); */ int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc) { - int cap, err = -EINVAL; + int cap; u32 stat, v, o; u16 cmd; if (mmrbc < 512 || mmrbc > 4096 || !is_power_of_2(mmrbc)) - goto out; + return -EINVAL; v = ffs(mmrbc) - 10; cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); if (!cap) - goto out; + return -EINVAL; - err = pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat); - if (err) - goto out; + if (pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat)) + return -EINVAL; if (v > (stat & PCI_X_STATUS_MAX_READ) >> 21) return -E2BIG; - err = pci_read_config_word(dev, cap + PCI_X_CMD, &cmd); - if (err) - goto out; + if (pci_read_config_word(dev, cap + PCI_X_CMD, &cmd)) + return -EINVAL; o = (cmd & PCI_X_CMD_MAX_READ) >> 2; if (o != v) { @@ -2658,10 +2654,10 @@ int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc) cmd &= ~PCI_X_CMD_MAX_READ; cmd |= v << 2; - err = pci_write_config_word(dev, cap + PCI_X_CMD, cmd); + if (pci_write_config_word(dev, cap + PCI_X_CMD, cmd)) + return -EIO; } -out: - return err; + return 0; } EXPORT_SYMBOL(pcix_set_mmrbc); -- cgit v0.10.2 From 035a02c1e1de31888e8b6adac0ff667971ac04db Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Fri, 19 Mar 2010 12:09:22 +0100 Subject: x86, amd: Restrict usage of c1e_idle() Currently c1e_idle returns true for all CPUs greater than or equal to family 0xf model 0x40. This covers too many CPUs. Meanwhile a respective erratum for the underlying problem was filed (#400). This patch adds the logic to check whether erratum #400 applies to a given CPU. Especially for CPUs where SMI/HW triggered C1e is not supported, c1e_idle() doesn't need to be used. We can check this by looking at the respective OSVW bit for erratum #400. Cc: # .32.x .33.x Signed-off-by: Andreas Herrmann LKML-Reference: <20100319110922.GA19614@alberich.amd.com> Signed-off-by: H. Peter Anvin diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index 1cd58cd..4604e6a 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -105,6 +105,8 @@ #define MSR_AMD64_PATCH_LEVEL 0x0000008b #define MSR_AMD64_NB_CFG 0xc001001f #define MSR_AMD64_PATCH_LOADER 0xc0010020 +#define MSR_AMD64_OSVW_ID_LENGTH 0xc0010140 +#define MSR_AMD64_OSVW_STATUS 0xc0010141 #define MSR_AMD64_IBSFETCHCTL 0xc0011030 #define MSR_AMD64_IBSFETCHLINAD 0xc0011031 #define MSR_AMD64_IBSFETCHPHYSAD 0xc0011032 diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index ad95406..28ad9f4 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -526,21 +526,37 @@ static int __cpuinit mwait_usable(const struct cpuinfo_x86 *c) } /* - * Check for AMD CPUs, which have potentially C1E support + * Check for AMD CPUs, where APIC timer interrupt does not wake up CPU from C1e. + * For more information see + * - Erratum #400 for NPT family 0xf and family 0x10 CPUs + * - Erratum #365 for family 0x11 (not affected because C1e not in use) */ static int __cpuinit check_c1e_idle(const struct cpuinfo_x86 *c) { + u64 val; if (c->x86_vendor != X86_VENDOR_AMD) - return 0; - - if (c->x86 < 0x0F) - return 0; + goto no_c1e_idle; /* Family 0x0f models < rev F do not have C1E */ - if (c->x86 == 0x0f && c->x86_model < 0x40) - return 0; + if (c->x86 == 0x0F && c->x86_model >= 0x40) + return 1; - return 1; + if (c->x86 == 0x10) { + /* + * check OSVW bit for CPUs that are not affected + * by erratum #400 + */ + rdmsrl(MSR_AMD64_OSVW_ID_LENGTH, val); + if (val >= 2) { + rdmsrl(MSR_AMD64_OSVW_STATUS, val); + if (!(val & BIT(1))) + goto no_c1e_idle; + } + return 1; + } + +no_c1e_idle: + return 0; } static cpumask_var_t c1e_mask; -- cgit v0.10.2 From dfe4d3d6a6f707fff1dbfd4b8fce65e64a91b809 Mon Sep 17 00:00:00 2001 From: Tao Ma Date: Fri, 19 Mar 2010 15:04:23 +0800 Subject: ocfs2: Fix the update of name_offset when removing xattrs When replacing a xattr's value, in some case we wipe its name/value first and then re-add it. The wipe is done by ocfs2_xa_block_wipe_namevalue() when the xattr is in the inode or block. We currently adjust name_offset for all the entries which have (offset < name_offset). This does not adjust the entrie we're replacing. Since we are replacing the entry, we don't adjust the total entry count. When we calculate a new namevalue location, we trust the entries now-wrong offset in ocfs2_xa_get_free_start(). The solution is to also adjust the name_offset for the replaced entry, allowing ocfs2_xa_get_free_start() to calculate the new namevalue location correctly. The following script can trigger a kernel panic easily. echo 'y'|mkfs.ocfs2 --fs-features=local,xattr -b 4K $DEVICE mount -t ocfs2 $DEVICE $MNT_DIR FILE=$MNT_DIR/$RANDOM for((i=0;i<76;i++)) do string_76="a$string_76" done string_78="aa$string_76" string_82="aaaa$string_78" touch $FILE setfattr -n 'user.test1234567890' -v $string_76 $FILE setfattr -n 'user.test1234567890' -v $string_78 $FILE setfattr -n 'user.test1234567890' -v $string_82 $FILE Signed-off-by: Tao Ma Signed-off-by: Joel Becker diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index d1b0d38..82c2a0b 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c @@ -1622,7 +1622,7 @@ static void ocfs2_xa_block_wipe_namevalue(struct ocfs2_xa_loc *loc) /* Now tell xh->xh_entries about it */ for (i = 0; i < count; i++) { offset = le16_to_cpu(xh->xh_entries[i].xe_name_offset); - if (offset < namevalue_offset) + if (offset <= namevalue_offset) le16_add_cpu(&xh->xh_entries[i].xe_name_offset, namevalue_size); } -- cgit v0.10.2 From b23179681c90a55e2a2083e1dde9f727ecffb2b7 Mon Sep 17 00:00:00 2001 From: Tao Ma Date: Fri, 19 Mar 2010 15:04:24 +0800 Subject: ocfs2: Init meta_ac properly in ocfs2_create_empty_xattr_block. You can't store a pointer that you haven't filled in yet and expect it to work. Signed-off-by: Tao Ma Signed-off-by: Joel Becker diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index 82c2a0b..3e77730 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c @@ -6528,13 +6528,11 @@ static int ocfs2_create_empty_xattr_block(struct inode *inode, int indexed) { int ret; - struct ocfs2_alloc_context *meta_ac; struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); - struct ocfs2_xattr_set_ctxt ctxt = { - .meta_ac = meta_ac, - }; + struct ocfs2_xattr_set_ctxt ctxt; - ret = ocfs2_reserve_new_metadata_blocks(osb, 1, &meta_ac); + memset(&ctxt, 0, sizeof(ctxt)); + ret = ocfs2_reserve_new_metadata_blocks(osb, 1, &ctxt.meta_ac); if (ret < 0) { mlog_errno(ret); return ret; @@ -6556,7 +6554,7 @@ static int ocfs2_create_empty_xattr_block(struct inode *inode, ocfs2_commit_trans(osb, ctxt.handle); out: - ocfs2_free_alloc_context(meta_ac); + ocfs2_free_alloc_context(ctxt.meta_ac); return ret; } -- cgit v0.10.2 From 220bf991b0366cc50a94feede3d7341fa5710ee4 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 19 Mar 2010 18:17:57 -0700 Subject: Linux 2.6.34-rc2 diff --git a/Makefile b/Makefile index 08ff02d..a5ba759 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 34 -EXTRAVERSION = -rc1 +EXTRAVERSION = -rc2 NAME = Man-Eating Seals of Antiquity # *DOCUMENTATION* -- cgit v0.10.2 From d11a4dc18bf41719c9f0d7ed494d295dd2973b92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Thu, 18 Mar 2010 23:20:20 +0000 Subject: ipv4: check rt_genid in dst_check Xfrm_dst keeps a reference to ipv4 rtable entries on each cached bundle. The only way to renew xfrm_dst when the underlying route has changed, is to implement dst_check for this. This is what ipv6 side does too. The problems started after 87c1e12b5eeb7b30b4b41291bef8e0b41fc3dde9 ("ipsec: Fix bogus bundle flowi") which fixed a bug causing xfrm_dst to not get reused, until that all lookups always generated new xfrm_dst with new route reference and path mtu worked. But after the fix, the old routes started to get reused even after they were expired causing pmtu to break (well it would occationally work if the rtable gc had run recently and marked the route obsolete causing dst_check to get called). Signed-off-by: Timo Teras Acked-by: Herbert Xu Signed-off-by: David S. Miller diff --git a/net/ipv4/route.c b/net/ipv4/route.c index a770df24..32d3961 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1441,7 +1441,7 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, dev_hold(rt->u.dst.dev); if (rt->idev) in_dev_hold(rt->idev); - rt->u.dst.obsolete = 0; + rt->u.dst.obsolete = -1; rt->u.dst.lastuse = jiffies; rt->u.dst.path = &rt->u.dst; rt->u.dst.neighbour = NULL; @@ -1506,7 +1506,7 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst) struct dst_entry *ret = dst; if (rt) { - if (dst->obsolete) { + if (dst->obsolete > 0) { ip_rt_put(rt); ret = NULL; } else if ((rt->rt_flags & RTCF_REDIRECTED) || @@ -1726,7 +1726,9 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu) static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie) { - return NULL; + if (rt_is_expired((struct rtable *)dst)) + return NULL; + return dst; } static void ipv4_dst_destroy(struct dst_entry *dst) @@ -1888,7 +1890,8 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, if (!rth) goto e_nobufs; - rth->u.dst.output= ip_rt_bug; + rth->u.dst.output = ip_rt_bug; + rth->u.dst.obsolete = -1; atomic_set(&rth->u.dst.__refcnt, 1); rth->u.dst.flags= DST_HOST; @@ -2054,6 +2057,7 @@ static int __mkroute_input(struct sk_buff *skb, rth->fl.oif = 0; rth->rt_spec_dst= spec_dst; + rth->u.dst.obsolete = -1; rth->u.dst.input = ip_forward; rth->u.dst.output = ip_output; rth->rt_genid = rt_genid(dev_net(rth->u.dst.dev)); @@ -2218,6 +2222,7 @@ local_input: goto e_nobufs; rth->u.dst.output= ip_rt_bug; + rth->u.dst.obsolete = -1; rth->rt_genid = rt_genid(net); atomic_set(&rth->u.dst.__refcnt, 1); @@ -2444,6 +2449,7 @@ static int __mkroute_output(struct rtable **result, rth->rt_spec_dst= fl->fl4_src; rth->u.dst.output=ip_output; + rth->u.dst.obsolete = -1; rth->rt_genid = rt_genid(dev_net(dev_out)); RT_CACHE_STAT_INC(out_slow_tot); -- cgit v0.10.2 From 10414444cb8a8ee8893e00390b7cf40502e28352 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 18 Mar 2010 23:00:22 +0000 Subject: ipv6: Remove redundant dst NULL check in ip6_dst_check As the only path leading to ip6_dst_check makes an indirect call through dst->ops, dst cannot be NULL in ip6_dst_check. This patch removes this check in case it misleads people who come across this code. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 52cd3ef..7fcb0e5 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -879,7 +879,7 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie) rt = (struct rt6_info *) dst; - if (rt && rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) + if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) return dst; return NULL; -- cgit v0.10.2 From 97e3ecd112ba45eb217cddab59f48659bc15d9d0 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Thu, 18 Mar 2010 11:27:32 +0000 Subject: TCP: check min TTL on received ICMP packets This adds RFC5082 checks for TTL on received ICMP packets. It adds some security against spoofed ICMP packets disrupting GTSM protected sessions. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 70df409..f4df5f9 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -370,6 +370,11 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info) if (sk->sk_state == TCP_CLOSE) goto out; + if (unlikely(iph->ttl < inet_sk(sk)->min_ttl)) { + NET_INC_STATS_BH(net, LINUX_MIB_TCPMINTTLDROP); + goto out; + } + icsk = inet_csk(sk); tp = tcp_sk(sk); seq = ntohl(th->seq); -- cgit v0.10.2 From 936332b8e00103fc20eb7e915c9a3bcb2835a11a Mon Sep 17 00:00:00 2001 From: Vasu Dev Date: Fri, 19 Mar 2010 04:33:10 +0000 Subject: ixgbe: fix for real_num_tx_queues update issue Currently netdev_features_change is called before fcoe tx queues setup is done, so this patch moves calling of netdev_features_change after tx queues setup is done in ixgbe_init_interrupt_scheme, so that real_num_tx_queues is updated correctly on each fcoe enable or disable. This allows additional fcoe queues updated correctly in vlan driver for their correct queue selection. Signed-off-by: Vasu Dev Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c index 4123dec..700cfc0 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.c +++ b/drivers/net/ixgbe/ixgbe_fcoe.c @@ -614,9 +614,9 @@ int ixgbe_fcoe_enable(struct net_device *netdev) netdev->vlan_features |= NETIF_F_FSO; netdev->vlan_features |= NETIF_F_FCOE_MTU; netdev->fcoe_ddp_xid = IXGBE_FCOE_DDP_MAX - 1; - netdev_features_change(netdev); ixgbe_init_interrupt_scheme(adapter); + netdev_features_change(netdev); if (netif_running(netdev)) netdev->netdev_ops->ndo_open(netdev); @@ -660,11 +660,11 @@ int ixgbe_fcoe_disable(struct net_device *netdev) netdev->vlan_features &= ~NETIF_F_FSO; netdev->vlan_features &= ~NETIF_F_FCOE_MTU; netdev->fcoe_ddp_xid = 0; - netdev_features_change(netdev); ixgbe_cleanup_fcoe(adapter); - ixgbe_init_interrupt_scheme(adapter); + netdev_features_change(netdev); + if (netif_running(netdev)) netdev->netdev_ops->ndo_open(netdev); rc = 0; -- cgit v0.10.2 From fd3686a842717b890fbe3024b83a616c54d5dba0 Mon Sep 17 00:00:00 2001 From: Mallikarjuna R Chilakala Date: Fri, 19 Mar 2010 04:41:33 +0000 Subject: ixgbe: Set IXGBE_RSC_CB(skb)->DMA field to zero after unmapping the address As per Simon Horman's feedback set IXGBE_RSC_CB(skb)->dma to zero after unmapping HWRSC DMA address to avoid double freeing. Signed-off-by: Mallikarjuna R Chilakala Acked-by: Peter P Waskiewicz Jr Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 18b5b21..d75c46f 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -935,10 +935,12 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, if (skb->prev) skb = ixgbe_transform_rsc_queue(skb, &(rx_ring->rsc_count)); if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) { - if (IXGBE_RSC_CB(skb)->dma) + if (IXGBE_RSC_CB(skb)->dma) { pci_unmap_single(pdev, IXGBE_RSC_CB(skb)->dma, rx_ring->rx_buf_len, PCI_DMA_FROMDEVICE); + IXGBE_RSC_CB(skb)->dma = 0; + } if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) rx_ring->rsc_count += skb_shinfo(skb)->nr_frags; else @@ -3126,10 +3128,12 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter, rx_buffer_info->skb = NULL; do { struct sk_buff *this = skb; - if (IXGBE_RSC_CB(this)->dma) + if (IXGBE_RSC_CB(this)->dma) { pci_unmap_single(pdev, IXGBE_RSC_CB(this)->dma, rx_ring->rx_buf_len, PCI_DMA_FROMDEVICE); + IXGBE_RSC_CB(this)->dma = 0; + } skb = skb->prev; dev_kfree_skb(this); } while (skb); -- cgit v0.10.2 From 33bd9f601ea21c4389870e425ae4eaf210d49b95 Mon Sep 17 00:00:00 2001 From: Greg Rose Date: Fri, 19 Mar 2010 02:59:52 +0000 Subject: ixgbevf: Fix VF Stats accounting after reset The counters in the 82599 Virtual Function are not clear on read. They accumulate to the maximum value and then roll over. They are also not cleared when the VF executes a soft reset, so it is possible they are non-zero when the driver loads and starts. This has all been accounted for in the code that keeps the stats up to date but there is one case that is not. When the PF driver is reset the counters in the VF are all reset to zero. This adds an additional accounting overhead into the VF driver when the PF is reset under its feet. This patch adds additional counters that are used by the VF driver to accumulate and save stats after a PF reset has been detected. Prior to this patch displaying the stats in the VF after the PF has reset would show bogus data. Signed-off-by: Greg Rose Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller diff --git a/drivers/net/ixgbevf/ethtool.c b/drivers/net/ixgbevf/ethtool.c index 399be0c..6fdd651 100644 --- a/drivers/net/ixgbevf/ethtool.c +++ b/drivers/net/ixgbevf/ethtool.c @@ -46,22 +46,32 @@ struct ixgbe_stats { int sizeof_stat; int stat_offset; int base_stat_offset; + int saved_reset_offset; }; -#define IXGBEVF_STAT(m, b) sizeof(((struct ixgbevf_adapter *)0)->m), \ - offsetof(struct ixgbevf_adapter, m), \ - offsetof(struct ixgbevf_adapter, b) +#define IXGBEVF_STAT(m, b, r) sizeof(((struct ixgbevf_adapter *)0)->m), \ + offsetof(struct ixgbevf_adapter, m), \ + offsetof(struct ixgbevf_adapter, b), \ + offsetof(struct ixgbevf_adapter, r) static struct ixgbe_stats ixgbe_gstrings_stats[] = { - {"rx_packets", IXGBEVF_STAT(stats.vfgprc, stats.base_vfgprc)}, - {"tx_packets", IXGBEVF_STAT(stats.vfgptc, stats.base_vfgptc)}, - {"rx_bytes", IXGBEVF_STAT(stats.vfgorc, stats.base_vfgorc)}, - {"tx_bytes", IXGBEVF_STAT(stats.vfgotc, stats.base_vfgotc)}, - {"tx_busy", IXGBEVF_STAT(tx_busy, zero_base)}, - {"multicast", IXGBEVF_STAT(stats.vfmprc, stats.base_vfmprc)}, - {"rx_csum_offload_good", IXGBEVF_STAT(hw_csum_rx_good, zero_base)}, - {"rx_csum_offload_errors", IXGBEVF_STAT(hw_csum_rx_error, zero_base)}, - {"tx_csum_offload_ctxt", IXGBEVF_STAT(hw_csum_tx_good, zero_base)}, - {"rx_header_split", IXGBEVF_STAT(rx_hdr_split, zero_base)}, + {"rx_packets", IXGBEVF_STAT(stats.vfgprc, stats.base_vfgprc, + stats.saved_reset_vfgprc)}, + {"tx_packets", IXGBEVF_STAT(stats.vfgptc, stats.base_vfgptc, + stats.saved_reset_vfgptc)}, + {"rx_bytes", IXGBEVF_STAT(stats.vfgorc, stats.base_vfgorc, + stats.saved_reset_vfgorc)}, + {"tx_bytes", IXGBEVF_STAT(stats.vfgotc, stats.base_vfgotc, + stats.saved_reset_vfgotc)}, + {"tx_busy", IXGBEVF_STAT(tx_busy, zero_base, zero_base)}, + {"multicast", IXGBEVF_STAT(stats.vfmprc, stats.base_vfmprc, + stats.saved_reset_vfmprc)}, + {"rx_csum_offload_good", IXGBEVF_STAT(hw_csum_rx_good, zero_base, + zero_base)}, + {"rx_csum_offload_errors", IXGBEVF_STAT(hw_csum_rx_error, zero_base, + zero_base)}, + {"tx_csum_offload_ctxt", IXGBEVF_STAT(hw_csum_tx_good, zero_base, + zero_base)}, + {"rx_header_split", IXGBEVF_STAT(rx_hdr_split, zero_base, zero_base)}, }; #define IXGBE_QUEUE_STATS_LEN 0 @@ -455,10 +465,14 @@ static void ixgbevf_get_ethtool_stats(struct net_device *netdev, ixgbe_gstrings_stats[i].stat_offset; char *b = (char *)adapter + ixgbe_gstrings_stats[i].base_stat_offset; + char *r = (char *)adapter + + ixgbe_gstrings_stats[i].saved_reset_offset; data[i] = ((ixgbe_gstrings_stats[i].sizeof_stat == sizeof(u64)) ? *(u64 *)p : *(u32 *)p) - ((ixgbe_gstrings_stats[i].sizeof_stat == - sizeof(u64)) ? *(u64 *)b : *(u32 *)b); + sizeof(u64)) ? *(u64 *)b : *(u32 *)b) + + ((ixgbe_gstrings_stats[i].sizeof_stat == + sizeof(u64)) ? *(u64 *)r : *(u32 *)r); } } diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c index ca653c4..43927e1 100644 --- a/drivers/net/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ixgbevf/ixgbevf_main.c @@ -1610,6 +1610,44 @@ static inline void ixgbevf_rx_desc_queue_enable(struct ixgbevf_adapter *adapter, (adapter->rx_ring[rxr].count - 1)); } +static void ixgbevf_save_reset_stats(struct ixgbevf_adapter *adapter) +{ + /* Only save pre-reset stats if there are some */ + if (adapter->stats.vfgprc || adapter->stats.vfgptc) { + adapter->stats.saved_reset_vfgprc += adapter->stats.vfgprc - + adapter->stats.base_vfgprc; + adapter->stats.saved_reset_vfgptc += adapter->stats.vfgptc - + adapter->stats.base_vfgptc; + adapter->stats.saved_reset_vfgorc += adapter->stats.vfgorc - + adapter->stats.base_vfgorc; + adapter->stats.saved_reset_vfgotc += adapter->stats.vfgotc - + adapter->stats.base_vfgotc; + adapter->stats.saved_reset_vfmprc += adapter->stats.vfmprc - + adapter->stats.base_vfmprc; + } +} + +static void ixgbevf_init_last_counter_stats(struct ixgbevf_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + + adapter->stats.last_vfgprc = IXGBE_READ_REG(hw, IXGBE_VFGPRC); + adapter->stats.last_vfgorc = IXGBE_READ_REG(hw, IXGBE_VFGORC_LSB); + adapter->stats.last_vfgorc |= + (((u64)(IXGBE_READ_REG(hw, IXGBE_VFGORC_MSB))) << 32); + adapter->stats.last_vfgptc = IXGBE_READ_REG(hw, IXGBE_VFGPTC); + adapter->stats.last_vfgotc = IXGBE_READ_REG(hw, IXGBE_VFGOTC_LSB); + adapter->stats.last_vfgotc |= + (((u64)(IXGBE_READ_REG(hw, IXGBE_VFGOTC_MSB))) << 32); + adapter->stats.last_vfmprc = IXGBE_READ_REG(hw, IXGBE_VFMPRC); + + adapter->stats.base_vfgprc = adapter->stats.last_vfgprc; + adapter->stats.base_vfgorc = adapter->stats.last_vfgorc; + adapter->stats.base_vfgptc = adapter->stats.last_vfgptc; + adapter->stats.base_vfgotc = adapter->stats.last_vfgotc; + adapter->stats.base_vfmprc = adapter->stats.last_vfmprc; +} + static int ixgbevf_up_complete(struct ixgbevf_adapter *adapter) { struct net_device *netdev = adapter->netdev; @@ -1656,6 +1694,9 @@ static int ixgbevf_up_complete(struct ixgbevf_adapter *adapter) /* enable transmits */ netif_tx_start_all_queues(netdev); + ixgbevf_save_reset_stats(adapter); + ixgbevf_init_last_counter_stats(adapter); + /* bring the link up in the watchdog, this could race with our first * link up interrupt but shouldn't be a problem */ adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE; @@ -2228,27 +2269,6 @@ out: return err; } -static void ixgbevf_init_last_counter_stats(struct ixgbevf_adapter *adapter) -{ - struct ixgbe_hw *hw = &adapter->hw; - - adapter->stats.last_vfgprc = IXGBE_READ_REG(hw, IXGBE_VFGPRC); - adapter->stats.last_vfgorc = IXGBE_READ_REG(hw, IXGBE_VFGORC_LSB); - adapter->stats.last_vfgorc |= - (((u64)(IXGBE_READ_REG(hw, IXGBE_VFGORC_MSB))) << 32); - adapter->stats.last_vfgptc = IXGBE_READ_REG(hw, IXGBE_VFGPTC); - adapter->stats.last_vfgotc = IXGBE_READ_REG(hw, IXGBE_VFGOTC_LSB); - adapter->stats.last_vfgotc |= - (((u64)(IXGBE_READ_REG(hw, IXGBE_VFGOTC_MSB))) << 32); - adapter->stats.last_vfmprc = IXGBE_READ_REG(hw, IXGBE_VFMPRC); - - adapter->stats.base_vfgprc = adapter->stats.last_vfgprc; - adapter->stats.base_vfgorc = adapter->stats.last_vfgorc; - adapter->stats.base_vfgptc = adapter->stats.last_vfgptc; - adapter->stats.base_vfgotc = adapter->stats.last_vfgotc; - adapter->stats.base_vfmprc = adapter->stats.last_vfmprc; -} - #define UPDATE_VF_COUNTER_32bit(reg, last_counter, counter) \ { \ u32 current_counter = IXGBE_READ_REG(hw, reg); \ @@ -2416,9 +2436,9 @@ static void ixgbevf_watchdog_task(struct work_struct *work) } } -pf_has_reset: ixgbevf_update_stats(adapter); +pf_has_reset: /* Force detection of hung controller every watchdog period */ adapter->detect_tx_hung = true; @@ -3390,8 +3410,6 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev, /* setup the private structure */ err = ixgbevf_sw_init(adapter); - ixgbevf_init_last_counter_stats(adapter); - #ifdef MAX_SKB_FRAGS netdev->features = NETIF_F_SG | NETIF_F_IP_CSUM | @@ -3449,6 +3467,8 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev, adapter->netdev_registered = true; + ixgbevf_init_last_counter_stats(adapter); + /* print the MAC address */ hw_dbg(hw, "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", netdev->dev_addr[0], diff --git a/drivers/net/ixgbevf/vf.h b/drivers/net/ixgbevf/vf.h index 799600e..1f31b05 100644 --- a/drivers/net/ixgbevf/vf.h +++ b/drivers/net/ixgbevf/vf.h @@ -157,6 +157,12 @@ struct ixgbevf_hw_stats { u64 vfgorc; u64 vfgotc; u64 vfmprc; + + u64 saved_reset_vfgprc; + u64 saved_reset_vfgptc; + u64 saved_reset_vfgorc; + u64 saved_reset_vfgotc; + u64 saved_reset_vfmprc; }; struct ixgbevf_info { -- cgit v0.10.2 From 4c3a822395c01d50ca2ba3aa4529e19d237a2f8c Mon Sep 17 00:00:00 2001 From: Greg Rose Date: Fri, 19 Mar 2010 03:00:12 +0000 Subject: ixgbevf: Shorten up delay timer for watchdog task The recovery from PF reset works better when you shorten up the delay until the watchdog task executes. Signed-off-by: Greg Rose Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c index 43927e1..3de93ae 100644 --- a/drivers/net/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ixgbevf/ixgbevf_main.c @@ -965,7 +965,7 @@ static irqreturn_t ixgbevf_msix_mbx(int irq, void *data) if ((msg & IXGBE_MBVFICR_VFREQ_MASK) == IXGBE_PF_CONTROL_MSG) mod_timer(&adapter->watchdog_timer, - round_jiffies(jiffies + 10)); + round_jiffies(jiffies + 1)); return IRQ_HANDLED; } -- cgit v0.10.2 From 29b8dd024bd48c3d1d1e5140f5bbb683786f998e Mon Sep 17 00:00:00 2001 From: Greg Rose Date: Fri, 19 Mar 2010 03:00:31 +0000 Subject: ixgbevf: Message formatting cleanups Clean up some text output formatting. Signed-off-by: Greg Rose Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c index 3de93ae..d6cbd94 100644 --- a/drivers/net/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ixgbevf/ixgbevf_main.c @@ -2419,7 +2419,7 @@ static void ixgbevf_watchdog_task(struct work_struct *work) if (!netif_carrier_ok(netdev)) { hw_dbg(&adapter->hw, "NIC Link is Up %s, ", ((link_speed == IXGBE_LINK_SPEED_10GB_FULL) ? - "10 Gbps" : "1 Gbps")); + "10 Gbps\n" : "1 Gbps\n")); netif_carrier_on(netdev); netif_tx_wake_all_queues(netdev); } else { @@ -2695,7 +2695,7 @@ static int ixgbevf_open(struct net_device *netdev) if (hw->adapter_stopped) { err = IXGBE_ERR_MBX; printk(KERN_ERR "Unable to start - perhaps the PF" - "Driver isn't up yet\n"); + " Driver isn't up yet\n"); goto err_setup_reset; } } -- cgit v0.10.2 From b894fa2627e28c078740dc7041cd08c7e2c353ab Mon Sep 17 00:00:00 2001 From: Carolyn Wyborny Date: Fri, 19 Mar 2010 06:07:48 +0000 Subject: igb: Add support for 82576 ET2 Quad Port Server Adapter Signed-off-by: Carolyn Wyborny Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c index 9d7fa2f..0bc990e 100644 --- a/drivers/net/igb/e1000_82575.c +++ b/drivers/net/igb/e1000_82575.c @@ -94,6 +94,7 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) case E1000_DEV_ID_82576_FIBER: case E1000_DEV_ID_82576_SERDES: case E1000_DEV_ID_82576_QUAD_COPPER: + case E1000_DEV_ID_82576_QUAD_COPPER_ET2: case E1000_DEV_ID_82576_SERDES_QUAD: mac->type = e1000_82576; break; diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h index 4480052..82a533f 100644 --- a/drivers/net/igb/e1000_hw.h +++ b/drivers/net/igb/e1000_hw.h @@ -41,6 +41,7 @@ struct e1000_hw; #define E1000_DEV_ID_82576_FIBER 0x10E6 #define E1000_DEV_ID_82576_SERDES 0x10E7 #define E1000_DEV_ID_82576_QUAD_COPPER 0x10E8 +#define E1000_DEV_ID_82576_QUAD_COPPER_ET2 0x1526 #define E1000_DEV_ID_82576_NS 0x150A #define E1000_DEV_ID_82576_NS_SERDES 0x1518 #define E1000_DEV_ID_82576_SERDES_QUAD 0x150D diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 0ed25f0..45a0e4f 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -72,6 +72,7 @@ static DEFINE_PCI_DEVICE_TABLE(igb_pci_tbl) = { { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_FIBER), board_82575 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_SERDES), board_82575 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_SERDES_QUAD), board_82575 }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_QUAD_COPPER_ET2), board_82575 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_QUAD_COPPER), board_82575 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82575EB_COPPER), board_82575 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82575EB_FIBER_SERDES), board_82575 }, -- cgit v0.10.2 From ea93fd9456ad32cd85b2d7914b58c6313cc40c9e Mon Sep 17 00:00:00 2001 From: Yegor Yefremov Date: Fri, 19 Mar 2010 22:43:29 -0700 Subject: KS8695: update ksp->next_rx_desc_read at the end of rx loop There is no need to adjust the next rx descriptor after each packet, so do it only once at the end of the routine. Signed-off-by: Eric Dumazet Signed-off-by: Yegor Yefremov diff --git a/drivers/net/arm/ks8695net.c b/drivers/net/arm/ks8695net.c index a1d4188..e7810b7 100644 --- a/drivers/net/arm/ks8695net.c +++ b/drivers/net/arm/ks8695net.c @@ -449,11 +449,10 @@ ks8695_rx_irq(int irq, void *dev_id) } /** - * ks8695_rx - Receive packets called by NAPI poll method + * ks8695_rx - Receive packets called by NAPI poll method * @ksp: Private data for the KS8695 Ethernet - * @budget: The max packets would be receive + * @budget: Number of packets allowed to process */ - static int ks8695_rx(struct ks8695_priv *ksp, int budget) { struct net_device *ndev = ksp->ndev; @@ -461,7 +460,6 @@ static int ks8695_rx(struct ks8695_priv *ksp, int budget) int buff_n; u32 flags; int pktlen; - int last_rx_processed = -1; int received = 0; buff_n = ksp->next_rx_desc_read; @@ -471,6 +469,7 @@ static int ks8695_rx(struct ks8695_priv *ksp, int budget) cpu_to_le32(RDES_OWN)))) { rmb(); flags = le32_to_cpu(ksp->rx_ring[buff_n].status); + /* Found an SKB which we own, this means we * received a packet */ @@ -533,23 +532,18 @@ rx_failure: ksp->rx_ring[buff_n].status = cpu_to_le32(RDES_OWN); rx_finished: received++; - /* And note this as processed so we can start - * from here next time - */ - last_rx_processed = buff_n; buff_n = (buff_n + 1) & MAX_RX_DESC_MASK; - /*And note which RX descriptor we last did */ - if (likely(last_rx_processed != -1)) - ksp->next_rx_desc_read = - (last_rx_processed + 1) & - MAX_RX_DESC_MASK; } + + /* And note which RX descriptor we last did */ + ksp->next_rx_desc_read = buff_n; + /* And refill the buffers */ ks8695_refill_rxbuffers(ksp); - /* Kick the RX DMA engine, in case it became - * suspended */ + /* Kick the RX DMA engine, in case it became suspended */ ks8695_writereg(ksp, KS8695_DRSC, 0); + return received; } -- cgit v0.10.2 From a50436f2cd6e85794f7e1aad795ca8302177b896 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 17 Mar 2010 06:04:14 +0000 Subject: net: ipmr/ip6mr: fix potential out-of-bounds vif_table access mfc_parent of cache entries is used to index into the vif_table and is initialised from mfcctl->mfcc_parent. This can take values of to 2^16-1, while the vif_table has only MAXVIFS (32) entries. The same problem affects ip6mr. Refuse invalid values to fix a potential out-of-bounds access. Unlike the other validity checks, this is checked in ipmr_mfc_add() instead of the setsockopt handler since its unused in the delete path and might be uninitialized. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 8582e12..0b9d03c 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -802,6 +802,9 @@ static int ipmr_mfc_add(struct net *net, struct mfcctl *mfc, int mrtsock) int line; struct mfc_cache *uc, *c, **cp; + if (mfc->mfcc_parent >= MAXVIFS) + return -ENFILE; + line = MFC_HASH(mfc->mfcc_mcastgrp.s_addr, mfc->mfcc_origin.s_addr); for (cp = &net->ipv4.mfc_cache_array[line]; diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 52e0f74..23e4ac0 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c @@ -1113,6 +1113,9 @@ static int ip6mr_mfc_add(struct net *net, struct mf6cctl *mfc, int mrtsock) unsigned char ttls[MAXMIFS]; int i; + if (mfc->mf6cc_parent >= MAXMIFS) + return -ENFILE; + memset(ttls, 255, MAXMIFS); for (i = 0; i < MAXMIFS; i++) { if (IF_ISSET(i, &mfc->mf6cc_ifset)) -- cgit v0.10.2 From 6830c25b7d08fbbd922959425193791bc42079f2 Mon Sep 17 00:00:00 2001 From: Lennart Schulte Date: Wed, 17 Mar 2010 02:16:29 +0000 Subject: tcp: Fix tcp_mark_head_lost() with packets == 0 A packet is marked as lost in case packets == 0, although nothing should be done. This results in a too early retransmitted packet during recovery in some cases. This small patch fixes this issue by returning immediately. Signed-off-by: Lennart Schulte Signed-off-by: Arnd Hannemann Signed-off-by: David S. Miller diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 788851c..c096a42 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -2511,6 +2511,9 @@ static void tcp_mark_head_lost(struct sock *sk, int packets) int err; unsigned int mss; + if (packets == 0) + return; + WARN_ON(packets > tp->packets_out); if (tp->lost_skb_hint) { skb = tp->lost_skb_hint; -- cgit v0.10.2 From f5d410f2ea7ba340f11815a56e05b9fa9421c421 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 16 Mar 2010 13:30:44 +0000 Subject: netlink: fix unaligned access in nla_get_be64() This patch fixes a unaligned access in nla_get_be64() that was introduced by myself in a17c859849402315613a0015ac8fbf101acf0cc1. Signed-off-by: Pablo Neira Ayuso Signed-off-by: David S. Miller diff --git a/include/net/netlink.h b/include/net/netlink.h index f82e463..4fc05b5 100644 --- a/include/net/netlink.h +++ b/include/net/netlink.h @@ -945,7 +945,11 @@ static inline u64 nla_get_u64(const struct nlattr *nla) */ static inline __be64 nla_get_be64(const struct nlattr *nla) { - return *(__be64 *) nla_data(nla); + __be64 tmp; + + nla_memcpy(&tmp, nla, sizeof(tmp)); + + return tmp; } /** -- cgit v0.10.2 From 88fcf710c13bd41f2b98c5411e4f21ab98da4fb4 Mon Sep 17 00:00:00 2001 From: Yong Wang Date: Fri, 19 Mar 2010 23:02:16 -0700 Subject: Input: sparse-keymap - free the right keymap on error 'map' is allocated in sparse_keymap_setup() and it it the one that should be freed on error instead of 'keymap'. Signed-off-by: Yong Wang Cc: stable@kernel.org Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/sparse-keymap.c b/drivers/input/sparse-keymap.c index e6bde55..f64e004 100644 --- a/drivers/input/sparse-keymap.c +++ b/drivers/input/sparse-keymap.c @@ -163,7 +163,7 @@ int sparse_keymap_setup(struct input_dev *dev, return 0; err_out: - kfree(keymap); + kfree(map); return error; } -- cgit v0.10.2 From d90e6f6aad0ffdc674bc3a05c85c40dcc18e604c Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Sat, 20 Mar 2010 00:06:40 -0700 Subject: Input: bcm5974 - retract efi-broken suspend_resume With the recent system-wide improvements on suspend/resume and EFI booting the suspend_resume method of the bcm5974 has broken. When waking up from the S3 state on the MacBookAir, the trackpad is found in a yet unknown state, unable to switch to the proper multitouch mode. The result is a frozen touchpad, and a flood of errors of the kind bcm5974: bad trackpad package, length: 8. This patch retracts the reset_resume method altogether, falling back on the generic unbind/rebind functionality of the usb layer until further investigations can be made as how to reset the device when booting from efi. Signed-off-by: Henrik Rydberg Signed-off-by: Andrew Morton Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c index 4f8fe08..b89879b 100644 --- a/drivers/input/mouse/bcm5974.c +++ b/drivers/input/mouse/bcm5974.c @@ -803,7 +803,6 @@ static struct usb_driver bcm5974_driver = { .disconnect = bcm5974_disconnect, .suspend = bcm5974_suspend, .resume = bcm5974_resume, - .reset_resume = bcm5974_resume, .id_table = bcm5974_table, .supports_autosuspend = 1, }; -- cgit v0.10.2 From 0372c38047394e23278fe6dbc0827db12ce60bd3 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 20 Mar 2010 15:33:09 +0000 Subject: ARM: Fix IXP23xx build error in mach/memory.h One to many close parens. In file included from arch/arm/include/asm/page.h:202, from include/linux/mm_types.h:15, from include/linux/sched.h:63, from arch/arm/kernel/asm-offsets.c:13: arch/arm/include/asm/memory.h: In function 'virt_to_bus': arch/arm/include/asm/memory.h:214: error: expected ';' before ')' token arch/arm/include/asm/memory.h:214: error: expected statement before ')' token arch/arm/include/asm/memory.h: In function 'bus_to_virt': arch/arm/include/asm/memory.h:219: error: expected ';' before ')' token arch/arm/include/asm/memory.h:219: error: expected statement before ')' token Signed-off-by: Russell King diff --git a/arch/arm/mach-ixp23xx/include/mach/memory.h b/arch/arm/mach-ixp23xx/include/mach/memory.h index 94a3a86..6ef65d8 100644 --- a/arch/arm/mach-ixp23xx/include/mach/memory.h +++ b/arch/arm/mach-ixp23xx/include/mach/memory.h @@ -19,7 +19,7 @@ */ #define PHYS_OFFSET (0x00000000) -#define IXP23XX_PCI_SDRAM_OFFSET (*((volatile int *)IXP23XX_PCI_SDRAM_BAR) & 0xfffffff0)) +#define IXP23XX_PCI_SDRAM_OFFSET (*((volatile int *)IXP23XX_PCI_SDRAM_BAR) & 0xfffffff0) #define __phys_to_bus(x) ((x) + (IXP23XX_PCI_SDRAM_OFFSET - PHYS_OFFSET)) #define __bus_to_phys(x) ((x) - (IXP23XX_PCI_SDRAM_OFFSET - PHYS_OFFSET)) -- cgit v0.10.2 From 48edcfcfbfcb3ffa76539f237b5527b62d72133a Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 20 Mar 2010 15:37:39 +0000 Subject: ARM: Update mach-types Signed-off-by: Russell King diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index 31c2f4c..1536f17 100644 --- a/arch/arm/tools/mach-types +++ b/arch/arm/tools/mach-types @@ -12,7 +12,7 @@ # # http://www.arm.linux.org.uk/developer/machines/?action=new # -# Last update: Sat Feb 20 14:16:15 2010 +# Last update: Sat Mar 20 15:35:41 2010 # # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number # @@ -2663,7 +2663,7 @@ reb01 MACH_REB01 REB01 2675 aquila MACH_AQUILA AQUILA 2676 spark_sls_hw2 MACH_SPARK_SLS_HW2 SPARK_SLS_HW2 2677 sheeva_esata MACH_ESATA_SHEEVAPLUG ESATA_SHEEVAPLUG 2678 -surf7x30 MACH_SURF7X30 SURF7X30 2679 +msm7x30_surf MACH_MSM7X30_SURF MSM7X30_SURF 2679 micro2440 MACH_MICRO2440 MICRO2440 2680 am2440 MACH_AM2440 AM2440 2681 tq2440 MACH_TQ2440 TQ2440 2682 @@ -2678,3 +2678,74 @@ vc088x MACH_VC088X VC088X 2690 mioa702 MACH_MIOA702 MIOA702 2691 hpmin MACH_HPMIN HPMIN 2692 ak880xak MACH_AK880XAK AK880XAK 2693 +arm926tomap850 MACH_ARM926TOMAP850 ARM926TOMAP850 2694 +lkevm MACH_LKEVM LKEVM 2695 +mw6410 MACH_MW6410 MW6410 2696 +terastation_wxl MACH_TERASTATION_WXL TERASTATION_WXL 2697 +cpu8000e MACH_CPU8000E CPU8000E 2698 +catania MACH_CATANIA CATANIA 2699 +tokyo MACH_TOKYO TOKYO 2700 +msm7201a_surf MACH_MSM7201A_SURF MSM7201A_SURF 2701 +msm7201a_ffa MACH_MSM7201A_FFA MSM7201A_FFA 2702 +msm7x25_surf MACH_MSM7X25_SURF MSM7X25_SURF 2703 +msm7x25_ffa MACH_MSM7X25_FFA MSM7X25_FFA 2704 +msm7x27_surf MACH_MSM7X27_SURF MSM7X27_SURF 2705 +msm7x27_ffa MACH_MSM7X27_FFA MSM7X27_FFA 2706 +msm7x30_ffa MACH_MSM7X30_FFA MSM7X30_FFA 2707 +qsd8x50_surf MACH_QSD8X50_SURF QSD8X50_SURF 2708 +qsd8x50_comet MACH_QSD8X50_COMET QSD8X50_COMET 2709 +qsd8x50_ffa MACH_QSD8X50_FFA QSD8X50_FFA 2710 +qsd8x50a_surf MACH_QSD8X50A_SURF QSD8X50A_SURF 2711 +qsd8x50a_ffa MACH_QSD8X50A_FFA QSD8X50A_FFA 2712 +adx_xgcp10 MACH_ADX_XGCP10 ADX_XGCP10 2713 +mcgwumts2a MACH_MCGWUMTS2A MCGWUMTS2A 2714 +mobikt MACH_MOBIKT MOBIKT 2715 +mx53_evk MACH_MX53_EVK MX53_EVK 2716 +igep0030 MACH_IGEP0030 IGEP0030 2717 +axell_h40_h50_ctrl MACH_AXELL_H40_H50_CTRL AXELL_H40_H50_CTRL 2718 +dtcommod MACH_DTCOMMOD DTCOMMOD 2719 +gould MACH_GOULD GOULD 2720 +siberia MACH_SIBERIA SIBERIA 2721 +sbc3530 MACH_SBC3530 SBC3530 2722 +qarm MACH_QARM QARM 2723 +mips MACH_MIPS MIPS 2724 +mx27grb MACH_MX27GRB MX27GRB 2725 +sbc8100 MACH_SBC8100 SBC8100 2726 +saarb MACH_SAARB SAARB 2727 +omap3mini MACH_OMAP3MINI OMAP3MINI 2728 +cnmbook7se MACH_CNMBOOK7SE CNMBOOK7SE 2729 +catan MACH_CATAN CATAN 2730 +harmony MACH_HARMONY HARMONY 2731 +tonga MACH_TONGA TONGA 2732 +cybook_orizon MACH_CYBOOK_ORIZON CYBOOK_ORIZON 2733 +htcrhodiumcdma MACH_HTCRHODIUMCDMA HTCRHODIUMCDMA 2734 +epc_g45 MACH_EPC_G45 EPC_G45 2735 +epc_lpc3250 MACH_EPC_LPC3250 EPC_LPC3250 2736 +mxc91341evb MACH_MXC91341EVB MXC91341EVB 2737 +rtw1000 MACH_RTW1000 RTW1000 2738 +bobcat MACH_BOBCAT BOBCAT 2739 +trizeps6 MACH_TRIZEPS6 TRIZEPS6 2740 +msm7x30_fluid MACH_MSM7X30_FLUID MSM7X30_FLUID 2741 +nedap9263 MACH_NEDAP9263 NEDAP9263 2742 +netgear_ms2110 MACH_NETGEAR_MS2110 NETGEAR_MS2110 2743 +bmx MACH_BMX BMX 2744 +netstream MACH_NETSTREAM NETSTREAM 2745 +vpnext_rcu MACH_VPNEXT_RCU VPNEXT_RCU 2746 +vpnext_mpu MACH_VPNEXT_MPU VPNEXT_MPU 2747 +bcmring_tablet_v1 MACH_BCMRING_TABLET_V1 BCMRING_TABLET_V1 2748 +sgarm10 MACH_SGARM10 SGARM10 2749 +cm_t3517 MACH_CM_T3517 CM_T3517 2750 +omap3_cps MACH_OMAP3_CPS OMAP3_CPS 2751 +axar1500_receiver MACH_AXAR1500_RECEIVER AXAR1500_RECEIVER 2752 +wbd222 MACH_WBD222 WBD222 2753 +mt65xx MACH_MT65XX MT65XX 2754 +msm8x60_surf MACH_MSM8X60_SURF MSM8X60_SURF 2755 +msm8x60_sim MACH_MSM8X60_SIM MSM8X60_SIM 2756 +vmc300 MACH_VMC300 VMC300 2757 +tcc8000_sdk MACH_TCC8000_SDK TCC8000_SDK 2758 +nanos MACH_NANOS NANOS 2759 +stamp9g10 MACH_STAMP9G10 STAMP9G10 2760 +stamp9g45 MACH_STAMP9G45 STAMP9G45 2761 +h6053 MACH_H6053 H6053 2762 +smint01 MACH_SMINT01 SMINT01 2763 +prtlvt2 MACH_PRTLVT2 PRTLVT2 2764 -- cgit v0.10.2 From 73852e8151b7d7a529fbe019ab6d2d0c02d8f3f2 Mon Sep 17 00:00:00 2001 From: "Steven J. Magnani" Date: Tue, 16 Mar 2010 05:22:44 +0000 Subject: NET_DMA: free skbs periodically Under NET_DMA, data transfer can grind to a halt when userland issues a large read on a socket with a high RCVLOWAT (i.e., 512 KB for both). This appears to be because the NET_DMA design queues up lots of memcpy operations, but doesn't issue or wait for them (and thus free the associated skbs) until it is time for tcp_recvmesg() to return. The socket hangs when its TCP window goes to zero before enough data is available to satisfy the read. Periodically issue asynchronous memcpy operations, and free skbs for ones that have completed, to prevent sockets from going into zero-window mode. Signed-off-by: Steven J. Magnani Signed-off-by: David S. Miller diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index ae16f80..6afb6d8 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -1254,6 +1254,39 @@ static void tcp_prequeue_process(struct sock *sk) tp->ucopy.memory = 0; } +#ifdef CONFIG_NET_DMA +static void tcp_service_net_dma(struct sock *sk, bool wait) +{ + dma_cookie_t done, used; + dma_cookie_t last_issued; + struct tcp_sock *tp = tcp_sk(sk); + + if (!tp->ucopy.dma_chan) + return; + + last_issued = tp->ucopy.dma_cookie; + dma_async_memcpy_issue_pending(tp->ucopy.dma_chan); + + do { + if (dma_async_memcpy_complete(tp->ucopy.dma_chan, + last_issued, &done, + &used) == DMA_SUCCESS) { + /* Safe to free early-copied skbs now */ + __skb_queue_purge(&sk->sk_async_wait_queue); + break; + } else { + struct sk_buff *skb; + while ((skb = skb_peek(&sk->sk_async_wait_queue)) && + (dma_async_is_complete(skb->dma_cookie, done, + used) == DMA_SUCCESS)) { + __skb_dequeue(&sk->sk_async_wait_queue); + kfree_skb(skb); + } + } + } while (wait); +} +#endif + static inline struct sk_buff *tcp_recv_skb(struct sock *sk, u32 seq, u32 *off) { struct sk_buff *skb; @@ -1546,6 +1579,10 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, /* __ Set realtime policy in scheduler __ */ } +#ifdef CONFIG_NET_DMA + if (tp->ucopy.dma_chan) + dma_async_memcpy_issue_pending(tp->ucopy.dma_chan); +#endif if (copied >= target) { /* Do not sleep, just process backlog. */ release_sock(sk); @@ -1554,6 +1591,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, sk_wait_data(sk, &timeo); #ifdef CONFIG_NET_DMA + tcp_service_net_dma(sk, false); /* Don't block */ tp->ucopy.wakeup = 0; #endif @@ -1633,6 +1671,9 @@ do_prequeue: copied = -EFAULT; break; } + + dma_async_memcpy_issue_pending(tp->ucopy.dma_chan); + if ((offset + used) == skb->len) copied_early = 1; @@ -1702,27 +1743,9 @@ skip_copy: } #ifdef CONFIG_NET_DMA - if (tp->ucopy.dma_chan) { - dma_cookie_t done, used; - - dma_async_memcpy_issue_pending(tp->ucopy.dma_chan); - - while (dma_async_memcpy_complete(tp->ucopy.dma_chan, - tp->ucopy.dma_cookie, &done, - &used) == DMA_IN_PROGRESS) { - /* do partial cleanup of sk_async_wait_queue */ - while ((skb = skb_peek(&sk->sk_async_wait_queue)) && - (dma_async_is_complete(skb->dma_cookie, done, - used) == DMA_SUCCESS)) { - __skb_dequeue(&sk->sk_async_wait_queue); - kfree_skb(skb); - } - } + tcp_service_net_dma(sk, true); /* Wait for queue to drain */ + tp->ucopy.dma_chan = NULL; - /* Safe to free early-copied skbs now */ - __skb_queue_purge(&sk->sk_async_wait_queue); - tp->ucopy.dma_chan = NULL; - } if (tp->ucopy.pinned_list) { dma_unpin_iovec_pages(tp->ucopy.pinned_list); tp->ucopy.pinned_list = NULL; -- cgit v0.10.2 From 1a50307ba1826e4da0024e64b245ce4eadf7688a Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Thu, 18 Mar 2010 14:24:42 +0000 Subject: netlink: fix NETLINK_RECV_NO_ENOBUFS in netlink_set_err() Currently, ENOBUFS errors are reported to the socket via netlink_set_err() even if NETLINK_RECV_NO_ENOBUFS is set. However, that should not happen. This fixes this problem and it changes the prototype of netlink_set_err() to return the number of sockets that have set the NETLINK_RECV_NO_ENOBUFS socket option. This return value is used in the next patch in these bugfix series. Signed-off-by: Pablo Neira Ayuso Signed-off-by: David S. Miller diff --git a/include/linux/netlink.h b/include/linux/netlink.h index fde27c0..6eaca5e 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h @@ -188,7 +188,7 @@ extern int netlink_has_listeners(struct sock *sk, unsigned int group); extern int netlink_unicast(struct sock *ssk, struct sk_buff *skb, __u32 pid, int nonblock); extern int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, __u32 pid, __u32 group, gfp_t allocation); -extern void netlink_set_err(struct sock *ssk, __u32 pid, __u32 group, int code); +extern int netlink_set_err(struct sock *ssk, __u32 pid, __u32 group, int code); extern int netlink_register_notifier(struct notifier_block *nb); extern int netlink_unregister_notifier(struct notifier_block *nb); diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 320d042..acbbae1 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -1093,6 +1093,7 @@ static inline int do_one_set_err(struct sock *sk, struct netlink_set_err_data *p) { struct netlink_sock *nlk = nlk_sk(sk); + int ret = 0; if (sk == p->exclude_sk) goto out; @@ -1104,10 +1105,15 @@ static inline int do_one_set_err(struct sock *sk, !test_bit(p->group - 1, nlk->groups)) goto out; + if (p->code == ENOBUFS && nlk->flags & NETLINK_RECV_NO_ENOBUFS) { + ret = 1; + goto out; + } + sk->sk_err = p->code; sk->sk_error_report(sk); out: - return 0; + return ret; } /** @@ -1116,12 +1122,16 @@ out: * @pid: the PID of a process that we want to skip (if any) * @groups: the broadcast group that will notice the error * @code: error code, must be negative (as usual in kernelspace) + * + * This function returns the number of broadcast listeners that have set the + * NETLINK_RECV_NO_ENOBUFS socket option. */ -void netlink_set_err(struct sock *ssk, u32 pid, u32 group, int code) +int netlink_set_err(struct sock *ssk, u32 pid, u32 group, int code) { struct netlink_set_err_data info; struct hlist_node *node; struct sock *sk; + int ret = 0; info.exclude_sk = ssk; info.pid = pid; @@ -1132,9 +1142,10 @@ void netlink_set_err(struct sock *ssk, u32 pid, u32 group, int code) read_lock(&nl_table_lock); sk_for_each_bound(sk, node, &nl_table[ssk->sk_protocol].mc_list) - do_one_set_err(sk, &info); + ret += do_one_set_err(sk, &info); read_unlock(&nl_table_lock); + return ret; } EXPORT_SYMBOL(netlink_set_err); -- cgit v0.10.2 From 37b7ef7203240b3aba577bb1ff6765fe15225976 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 16 Mar 2010 13:30:21 +0000 Subject: netfilter: ctnetlink: fix reliable event delivery if message building fails This patch fixes a bug that allows to lose events when reliable event delivery mode is used, ie. if NETLINK_BROADCAST_SEND_ERROR and NETLINK_RECV_NO_ENOBUFS socket options are set. Signed-off-by: Pablo Neira Ayuso Signed-off-by: David S. Miller diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h index 5392386..361d6b5 100644 --- a/include/linux/netfilter/nfnetlink.h +++ b/include/linux/netfilter/nfnetlink.h @@ -76,7 +76,7 @@ extern int nfnetlink_subsys_unregister(const struct nfnetlink_subsystem *n); extern int nfnetlink_has_listeners(struct net *net, unsigned int group); extern int nfnetlink_send(struct sk_buff *skb, struct net *net, u32 pid, unsigned group, int echo, gfp_t flags); -extern void nfnetlink_set_err(struct net *net, u32 pid, u32 group, int error); +extern int nfnetlink_set_err(struct net *net, u32 pid, u32 group, int error); extern int nfnetlink_unicast(struct sk_buff *skb, struct net *net, u_int32_t pid, int flags); extern void nfnl_lock(void); diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 2b2af63..569410a 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -582,7 +582,9 @@ nla_put_failure: nlmsg_failure: kfree_skb(skb); errout: - nfnetlink_set_err(net, 0, group, -ENOBUFS); + if (nfnetlink_set_err(net, 0, group, -ENOBUFS) > 0) + return -ENOBUFS; + return 0; } #endif /* CONFIG_NF_CONNTRACK_EVENTS */ diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c index 8eb0cc2..6afa3d5 100644 --- a/net/netfilter/nfnetlink.c +++ b/net/netfilter/nfnetlink.c @@ -113,9 +113,9 @@ int nfnetlink_send(struct sk_buff *skb, struct net *net, u32 pid, } EXPORT_SYMBOL_GPL(nfnetlink_send); -void nfnetlink_set_err(struct net *net, u32 pid, u32 group, int error) +int nfnetlink_set_err(struct net *net, u32 pid, u32 group, int error) { - netlink_set_err(net->nfnl, pid, group, error); + return netlink_set_err(net->nfnl, pid, group, error); } EXPORT_SYMBOL_GPL(nfnetlink_set_err); -- cgit v0.10.2 From 978097c907b58a2d085bbf7632bee1a5a7e6f6ba Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 8 Mar 2010 15:27:53 -0800 Subject: ceph: implemented caps should always be superset of issued caps Added assertion, and cleared one case where the implemented caps were not following the issued caps. Signed-off-by: Yehuda Sadeh Signed-off-by: Sage Weil diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index db122bb..57d9b44 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -2334,6 +2334,7 @@ static int handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant, revoked_rdcache) reply = 2; /* send revoke ack in check_caps */ cap->issued = newcaps; + cap->implemented |= newcaps; } else if (cap->issued == newcaps) { dout("caps unchanged: %s -> %s\n", ceph_cap_string(cap->issued), ceph_cap_string(newcaps)); @@ -2346,6 +2347,7 @@ static int handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant, * pending revocation */ wake = 1; } + BUG_ON(cap->issued & ~cap->implemented); spin_unlock(&inode->i_lock); if (writeback) -- cgit v0.10.2 From 052bb34af3bf8ae2001b9f03d884ba0def3e427c Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 9 Mar 2010 12:52:26 -0800 Subject: ceph: add missing locking to protect i_snap_realm_item during split All ci->i_snap_realm_item/realm->inodes_with_caps manipulation should be protected by realm->inodes_with_caps_lock. This bug would have only bit us in a rare race with a realm split (during some snap creations). Signed-off-by: Sage Weil diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c index bf2a5f3..8a43bc8 100644 --- a/fs/ceph/snap.c +++ b/fs/ceph/snap.c @@ -818,7 +818,9 @@ void ceph_handle_snap(struct ceph_mds_client *mdsc, * queued (again) by ceph_update_snap_trace() * below. Queue it _now_, under the old context. */ + spin_lock(&realm->inodes_with_caps_lock); list_del_init(&ci->i_snap_realm_item); + spin_unlock(&realm->inodes_with_caps_lock); spin_unlock(&inode->i_lock); ceph_queue_cap_snap(ci, -- cgit v0.10.2 From 8b218b8a4a65bf4e304ae8690cadb9100ef029c0 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 9 Mar 2010 12:59:08 -0800 Subject: ceph: fix inode removal from snap realm when racing with migration When an inode was dropped while being migrated between two MDSs, i_cap_exporting_issued was non-zero such that issue caps were non-zero and __ceph_is_any_caps(ci) was true. This prevented the inode from being removed from the snap realm, even as it was dropped from the cache. Fix this by dropping any residual i_snap_realm ref in destroy_inode. Signed-off-by: Sage Weil diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 7abe1ae..aca82d5 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -378,6 +378,22 @@ void ceph_destroy_inode(struct inode *inode) ceph_queue_caps_release(inode); + /* + * we may still have a snap_realm reference if there are stray + * caps in i_cap_exporting_issued or i_snap_caps. + */ + if (ci->i_snap_realm) { + struct ceph_mds_client *mdsc = + &ceph_client(ci->vfs_inode.i_sb)->mdsc; + struct ceph_snap_realm *realm = ci->i_snap_realm; + + dout(" dropping residual ref to snap realm %p\n", realm); + spin_lock(&realm->inodes_with_caps_lock); + list_del_init(&ci->i_snap_realm_item); + spin_unlock(&realm->inodes_with_caps_lock); + ceph_put_snap_realm(mdsc, realm); + } + kfree(ci->i_symlink); while ((n = rb_first(&ci->i_fragtree)) != NULL) { frag = rb_entry(n, struct ceph_inode_frag, node); -- cgit v0.10.2 From 63733a0fc55cca74b1911769633dc5dfd1a45907 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 15 Mar 2010 15:47:22 -0700 Subject: ceph: fix authenticator timeout We were failing to reconnect to services due to an old authenticator, even though we had the new ticket, because we weren't properly retrying the connect handshake, because we were calling an old/incorrect helper that left in_base_pos incorrect. The result was a failure to reconnect to the OSD or MDS (with an authentication error) if the MDS restarted after the service had been up a few hours (long enough for the original authenticator to be invalid). This was only a problem if the AUTH_X authentication was enabled. Now that the 'negotiate' and 'connect' stages are fully separated, we should use the prepare_read_connect() helper instead, and remove the obsolete one. Signed-off-by: Sage Weil diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index 781656a..203c435 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -830,13 +830,6 @@ static void prepare_read_connect(struct ceph_connection *con) con->in_base_pos = 0; } -static void prepare_read_connect_retry(struct ceph_connection *con) -{ - dout("prepare_read_connect_retry %p\n", con); - con->in_base_pos = strlen(CEPH_BANNER) + sizeof(con->actual_peer_addr) - + sizeof(con->peer_addr_for_me); -} - static void prepare_read_ack(struct ceph_connection *con) { dout("prepare_read_ack %p\n", con); @@ -1146,7 +1139,7 @@ static int process_connect(struct ceph_connection *con) } con->auth_retry = 1; prepare_write_connect(con->msgr, con, 0); - prepare_read_connect_retry(con); + prepare_read_connect(con); break; case CEPH_MSGR_TAG_RESETSESSION: -- cgit v0.10.2 From 807c86e2ceba8febe79b289d50cd0d5e0b0af917 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 15 Mar 2010 15:52:17 -0700 Subject: ceph: fix authenticator buffer size calculation The buffer size was incorrectly calculated for the ceph_x_encrypt() encapsulated ticket blob. Use a helper (with correct arithmetic) and BUG out if we were wrong. Signed-off-by: Sage Weil diff --git a/fs/ceph/auth_x.c b/fs/ceph/auth_x.c index f031842..96e7aaa 100644 --- a/fs/ceph/auth_x.c +++ b/fs/ceph/auth_x.c @@ -28,6 +28,12 @@ static int ceph_x_is_authenticated(struct ceph_auth_client *ac) return (ac->want_keys & xi->have_keys) == ac->want_keys; } +static int ceph_x_encrypt_buflen(int ilen) +{ + return sizeof(struct ceph_x_encrypt_header) + ilen + 16 + + sizeof(u32); +} + static int ceph_x_encrypt(struct ceph_crypto_key *secret, void *ibuf, int ilen, void *obuf, size_t olen) { @@ -242,7 +248,7 @@ static int ceph_x_build_authorizer(struct ceph_auth_client *ac, struct ceph_x_ticket_handler *th, struct ceph_x_authorizer *au) { - int len; + int maxlen; struct ceph_x_authorize_a *msg_a; struct ceph_x_authorize_b msg_b; void *p, *end; @@ -253,15 +259,15 @@ static int ceph_x_build_authorizer(struct ceph_auth_client *ac, dout("build_authorizer for %s %p\n", ceph_entity_type_name(th->service), au); - len = sizeof(*msg_a) + sizeof(msg_b) + sizeof(u32) + - ticket_blob_len + 16; - dout(" need len %d\n", len); - if (au->buf && au->buf->alloc_len < len) { + maxlen = sizeof(*msg_a) + sizeof(msg_b) + + ceph_x_encrypt_buflen(ticket_blob_len); + dout(" need len %d\n", maxlen); + if (au->buf && au->buf->alloc_len < maxlen) { ceph_buffer_put(au->buf); au->buf = NULL; } if (!au->buf) { - au->buf = ceph_buffer_new(len, GFP_NOFS); + au->buf = ceph_buffer_new(maxlen, GFP_NOFS); if (!au->buf) return -ENOMEM; } @@ -296,6 +302,7 @@ static int ceph_x_build_authorizer(struct ceph_auth_client *ac, au->buf->vec.iov_len = p - au->buf->vec.iov_base; dout(" built authorizer nonce %llx len %d\n", au->nonce, (int)au->buf->vec.iov_len); + BUG_ON(au->buf->vec.iov_len > maxlen); return 0; out_buf: -- cgit v0.10.2 From 5b3dbb44ab40660a080d03585bd35f45b2890c49 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 15 Mar 2010 15:57:04 -0700 Subject: ceph: release old ticket_blob buffer Release the old ticket_blob buffer when we get an updated service ticket from the monitor. Previously these were getting leaked. Signed-off-by: Sage Weil diff --git a/fs/ceph/auth_x.c b/fs/ceph/auth_x.c index 96e7aaa..33d3ad4 100644 --- a/fs/ceph/auth_x.c +++ b/fs/ceph/auth_x.c @@ -156,6 +156,7 @@ static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac, struct timespec validity; struct ceph_crypto_key old_key; void *tp, *tpend; + struct ceph_buffer *new_ticket_blob; ceph_decode_need(&p, end, sizeof(u32) + 1, bad); @@ -223,9 +224,12 @@ static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac, ceph_decode_need(&tp, tpend, 1 + sizeof(u64), bad); struct_v = ceph_decode_8(&tp); th->secret_id = ceph_decode_64(&tp); - ret = ceph_decode_buffer(&th->ticket_blob, &tp, tpend); + ret = ceph_decode_buffer(&new_ticket_blob, &tp, tpend); if (ret) goto out; + if (th->ticket_blob) + ceph_buffer_put(th->ticket_blob); + th->ticket_blob = new_ticket_blob; dout(" got ticket service %d (%s) secret_id %lld len %d\n", type, ceph_entity_type_name(type), th->secret_id, (int)th->ticket_blob->vec.iov_len); -- cgit v0.10.2 From 101545f6fef4a0a3ea8daf0b5b880df2c6a92a69 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 15 Mar 2010 14:12:58 -0700 Subject: Bluetooth: Fix potential bad memory access with sysfs files When creating a high number of Bluetooth sockets (L2CAP, SCO and RFCOMM) it is possible to scribble repeatedly on arbitrary pages of memory. Ensure that the content of these sysfs files is always less than one page. Even if this means truncating. The files in question are scheduled to be moved over to debugfs in the future anyway. Based on initial patches from Neil Brown and Linus Torvalds Reported-by: Neil Brown Signed-off-by: Marcel Holtmann diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 4db7ae2..2755182 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -3944,16 +3944,24 @@ static ssize_t l2cap_sysfs_show(struct class *dev, struct sock *sk; struct hlist_node *node; char *str = buf; + int size = PAGE_SIZE; read_lock_bh(&l2cap_sk_list.lock); sk_for_each(sk, node, &l2cap_sk_list.head) { struct l2cap_pinfo *pi = l2cap_pi(sk); + int len; - str += sprintf(str, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n", + len = snprintf(str, size, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n", batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), sk->sk_state, __le16_to_cpu(pi->psm), pi->scid, pi->dcid, pi->imtu, pi->omtu, pi->sec_level); + + size -= len; + if (size <= 0) + break; + + str += len; } read_unlock_bh(&l2cap_sk_list.lock); diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index db8a68e..cf16407 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c @@ -2105,6 +2105,7 @@ static ssize_t rfcomm_dlc_sysfs_show(struct class *dev, struct rfcomm_session *s; struct list_head *pp, *p; char *str = buf; + int size = PAGE_SIZE; rfcomm_lock(); @@ -2113,11 +2114,21 @@ static ssize_t rfcomm_dlc_sysfs_show(struct class *dev, list_for_each(pp, &s->dlcs) { struct sock *sk = s->sock->sk; struct rfcomm_dlc *d = list_entry(pp, struct rfcomm_dlc, list); + int len; - str += sprintf(str, "%s %s %ld %d %d %d %d\n", + len = snprintf(str, size, "%s %s %ld %d %d %d %d\n", batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), d->state, d->dlci, d->mtu, d->rx_credits, d->tx_credits); + + size -= len; + if (size <= 0) + break; + + str += len; } + + if (size <= 0) + break; } rfcomm_unlock(); diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index ca87d6a..8d0ee0b 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c @@ -1068,13 +1068,22 @@ static ssize_t rfcomm_sock_sysfs_show(struct class *dev, struct sock *sk; struct hlist_node *node; char *str = buf; + int size = PAGE_SIZE; read_lock_bh(&rfcomm_sk_list.lock); sk_for_each(sk, node, &rfcomm_sk_list.head) { - str += sprintf(str, "%s %s %d %d\n", + int len; + + len = snprintf(str, size, "%s %s %d %d\n", batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), sk->sk_state, rfcomm_pi(sk)->channel); + + size -= len; + if (size <= 0) + break; + + str += len; } read_unlock_bh(&rfcomm_sk_list.lock); diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index f93b939..967a751 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -960,13 +960,22 @@ static ssize_t sco_sysfs_show(struct class *dev, struct sock *sk; struct hlist_node *node; char *str = buf; + int size = PAGE_SIZE; read_lock_bh(&sco_sk_list.lock); sk_for_each(sk, node, &sco_sk_list.head) { - str += sprintf(str, "%s %s %d\n", + int len; + + len = snprintf(str, size, "%s %s %d\n", batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), sk->sk_state); + + size -= len; + if (size <= 0) + break; + + str += len; } read_unlock_bh(&sco_sk_list.lock); -- cgit v0.10.2 From aef7d97cc604309b66f6f45cce02cd734934cd4e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 21 Mar 2010 05:27:45 +0100 Subject: Bluetooth: Convert debug files to actually use debugfs instead of sysfs Some of the debug files ended up wrongly in sysfs, because at that point of time, debugfs didn't exist. Convert these files to use debugfs and also seq_file. This patch converts all of these files at once and then removes the exported symbol for the Bluetooth sysfs class. Signed-off-by: Marcel Holtmann diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 04a6908..ff77e8f 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h @@ -176,6 +176,6 @@ extern void hci_sock_cleanup(void); extern int bt_sysfs_init(void); extern void bt_sysfs_cleanup(void); -extern struct class *bt_class; +extern struct dentry *bt_debugfs; #endif /* __BLUETOOTH_H */ diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index cafb55b..05fd125 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c @@ -8,8 +8,7 @@ #include #include -struct class *bt_class = NULL; -EXPORT_SYMBOL_GPL(bt_class); +static struct class *bt_class; struct dentry *bt_debugfs = NULL; EXPORT_SYMBOL_GPL(bt_debugfs); diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 2755182..43e17f7 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -40,6 +40,8 @@ #include #include #include +#include +#include #include #include #include @@ -3937,39 +3939,42 @@ drop: return 0; } -static ssize_t l2cap_sysfs_show(struct class *dev, - struct class_attribute *attr, - char *buf) +static int l2cap_debugfs_show(struct seq_file *f, void *p) { struct sock *sk; struct hlist_node *node; - char *str = buf; - int size = PAGE_SIZE; read_lock_bh(&l2cap_sk_list.lock); sk_for_each(sk, node, &l2cap_sk_list.head) { struct l2cap_pinfo *pi = l2cap_pi(sk); - int len; - - len = snprintf(str, size, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n", - batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), - sk->sk_state, __le16_to_cpu(pi->psm), pi->scid, - pi->dcid, pi->imtu, pi->omtu, pi->sec_level); - - size -= len; - if (size <= 0) - break; - str += len; + seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n", + batostr(&bt_sk(sk)->src), + batostr(&bt_sk(sk)->dst), + sk->sk_state, __le16_to_cpu(pi->psm), + pi->scid, pi->dcid, + pi->imtu, pi->omtu, pi->sec_level); } read_unlock_bh(&l2cap_sk_list.lock); - return str - buf; + return 0; } -static CLASS_ATTR(l2cap, S_IRUGO, l2cap_sysfs_show, NULL); +static int l2cap_debugfs_open(struct inode *inode, struct file *file) +{ + return single_open(file, l2cap_debugfs_show, inode->i_private); +} + +static const struct file_operations l2cap_debugfs_fops = { + .open = l2cap_debugfs_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static struct dentry *l2cap_debugfs; static const struct proto_ops l2cap_sock_ops = { .family = PF_BLUETOOTH, @@ -4029,8 +4034,12 @@ static int __init l2cap_init(void) goto error; } - if (class_create_file(bt_class, &class_attr_l2cap) < 0) - BT_ERR("Failed to create L2CAP info file"); + if (bt_debugfs) { + l2cap_debugfs = debugfs_create_file("l2cap", 0444, + bt_debugfs, NULL, &l2cap_debugfs_fops); + if (!l2cap_debugfs) + BT_ERR("Failed to create L2CAP debug file"); + } BT_INFO("L2CAP ver %s", VERSION); BT_INFO("L2CAP socket layer initialized"); @@ -4044,7 +4053,7 @@ error: static void __exit l2cap_exit(void) { - class_remove_file(bt_class, &class_attr_l2cap); + debugfs_remove(l2cap_debugfs); if (bt_sock_unregister(BTPROTO_L2CAP) < 0) BT_ERR("L2CAP socket unregistration failed"); diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index cf16407..13f114e 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c @@ -33,6 +33,8 @@ #include #include #include +#include +#include #include #include #include @@ -2098,14 +2100,10 @@ static struct hci_cb rfcomm_cb = { .security_cfm = rfcomm_security_cfm }; -static ssize_t rfcomm_dlc_sysfs_show(struct class *dev, - struct class_attribute *attr, - char *buf) +static int rfcomm_dlc_debugfs_show(struct seq_file *f, void *x) { struct rfcomm_session *s; struct list_head *pp, *p; - char *str = buf; - int size = PAGE_SIZE; rfcomm_lock(); @@ -2114,29 +2112,33 @@ static ssize_t rfcomm_dlc_sysfs_show(struct class *dev, list_for_each(pp, &s->dlcs) { struct sock *sk = s->sock->sk; struct rfcomm_dlc *d = list_entry(pp, struct rfcomm_dlc, list); - int len; - len = snprintf(str, size, "%s %s %ld %d %d %d %d\n", - batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), - d->state, d->dlci, d->mtu, d->rx_credits, d->tx_credits); - - size -= len; - if (size <= 0) - break; - - str += len; + seq_printf(f, "%s %s %ld %d %d %d %d\n", + batostr(&bt_sk(sk)->src), + batostr(&bt_sk(sk)->dst), + d->state, d->dlci, d->mtu, + d->rx_credits, d->tx_credits); } - - if (size <= 0) - break; } rfcomm_unlock(); - return (str - buf); + return 0; +} + +static int rfcomm_dlc_debugfs_open(struct inode *inode, struct file *file) +{ + return single_open(file, rfcomm_dlc_debugfs_show, inode->i_private); } -static CLASS_ATTR(rfcomm_dlc, S_IRUGO, rfcomm_dlc_sysfs_show, NULL); +static const struct file_operations rfcomm_dlc_debugfs_fops = { + .open = rfcomm_dlc_debugfs_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static struct dentry *rfcomm_dlc_debugfs; /* ---- Initialization ---- */ static int __init rfcomm_init(void) @@ -2153,8 +2155,12 @@ static int __init rfcomm_init(void) goto unregister; } - if (class_create_file(bt_class, &class_attr_rfcomm_dlc) < 0) - BT_ERR("Failed to create RFCOMM info file"); + if (bt_debugfs) { + rfcomm_dlc_debugfs = debugfs_create_file("rfcomm_dlc", 0444, + bt_debugfs, NULL, &rfcomm_dlc_debugfs_fops); + if (!rfcomm_dlc_debugfs) + BT_ERR("Failed to create RFCOMM debug file"); + } err = rfcomm_init_ttys(); if (err < 0) @@ -2182,7 +2188,7 @@ unregister: static void __exit rfcomm_exit(void) { - class_remove_file(bt_class, &class_attr_rfcomm_dlc); + debugfs_remove(rfcomm_dlc_debugfs); hci_unregister_cb(&rfcomm_cb); diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 8d0ee0b..7f43976 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c @@ -40,6 +40,8 @@ #include #include #include +#include +#include #include #include @@ -1061,37 +1063,38 @@ done: return result; } -static ssize_t rfcomm_sock_sysfs_show(struct class *dev, - struct class_attribute *attr, - char *buf) +static int rfcomm_sock_debugfs_show(struct seq_file *f, void *p) { struct sock *sk; struct hlist_node *node; - char *str = buf; - int size = PAGE_SIZE; read_lock_bh(&rfcomm_sk_list.lock); sk_for_each(sk, node, &rfcomm_sk_list.head) { - int len; - - len = snprintf(str, size, "%s %s %d %d\n", - batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), + seq_printf(f, "%s %s %d %d\n", + batostr(&bt_sk(sk)->src), + batostr(&bt_sk(sk)->dst), sk->sk_state, rfcomm_pi(sk)->channel); - - size -= len; - if (size <= 0) - break; - - str += len; } read_unlock_bh(&rfcomm_sk_list.lock); - return (str - buf); + return 0; } -static CLASS_ATTR(rfcomm, S_IRUGO, rfcomm_sock_sysfs_show, NULL); +static int rfcomm_sock_debugfs_open(struct inode *inode, struct file *file) +{ + return single_open(file, rfcomm_sock_debugfs_show, inode->i_private); +} + +static const struct file_operations rfcomm_sock_debugfs_fops = { + .open = rfcomm_sock_debugfs_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static struct dentry *rfcomm_sock_debugfs; static const struct proto_ops rfcomm_sock_ops = { .family = PF_BLUETOOTH, @@ -1131,8 +1134,12 @@ int __init rfcomm_init_sockets(void) if (err < 0) goto error; - if (class_create_file(bt_class, &class_attr_rfcomm) < 0) - BT_ERR("Failed to create RFCOMM info file"); + if (bt_debugfs) { + rfcomm_sock_debugfs = debugfs_create_file("rfcomm", 0444, + bt_debugfs, NULL, &rfcomm_sock_debugfs_fops); + if (!rfcomm_sock_debugfs) + BT_ERR("Failed to create RFCOMM debug file"); + } BT_INFO("RFCOMM socket layer initialized"); @@ -1146,7 +1153,7 @@ error: void rfcomm_cleanup_sockets(void) { - class_remove_file(bt_class, &class_attr_rfcomm); + debugfs_remove(rfcomm_sock_debugfs); if (bt_sock_unregister(BTPROTO_RFCOMM) < 0) BT_ERR("RFCOMM socket layer unregistration failed"); diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 967a751..e5b16b7 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -38,6 +38,8 @@ #include #include #include +#include +#include #include #include @@ -953,37 +955,36 @@ drop: return 0; } -static ssize_t sco_sysfs_show(struct class *dev, - struct class_attribute *attr, - char *buf) +static int sco_debugfs_show(struct seq_file *f, void *p) { struct sock *sk; struct hlist_node *node; - char *str = buf; - int size = PAGE_SIZE; read_lock_bh(&sco_sk_list.lock); sk_for_each(sk, node, &sco_sk_list.head) { - int len; - - len = snprintf(str, size, "%s %s %d\n", - batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), - sk->sk_state); - - size -= len; - if (size <= 0) - break; - - str += len; + seq_printf(f, "%s %s %d\n", batostr(&bt_sk(sk)->src), + batostr(&bt_sk(sk)->dst), sk->sk_state); } read_unlock_bh(&sco_sk_list.lock); - return (str - buf); + return 0; } -static CLASS_ATTR(sco, S_IRUGO, sco_sysfs_show, NULL); +static int sco_debugfs_open(struct inode *inode, struct file *file) +{ + return single_open(file, sco_debugfs_show, inode->i_private); +} + +static const struct file_operations sco_debugfs_fops = { + .open = sco_debugfs_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static struct dentry *sco_debugfs; static const struct proto_ops sco_sock_ops = { .family = PF_BLUETOOTH, @@ -1041,8 +1042,12 @@ static int __init sco_init(void) goto error; } - if (class_create_file(bt_class, &class_attr_sco) < 0) - BT_ERR("Failed to create SCO info file"); + if (bt_debugfs) { + sco_debugfs = debugfs_create_file("sco", 0444, + bt_debugfs, NULL, &sco_debugfs_fops); + if (!sco_debugfs) + BT_ERR("Failed to create SCO debug file"); + } BT_INFO("SCO (Voice Link) ver %s", VERSION); BT_INFO("SCO socket layer initialized"); @@ -1056,7 +1061,7 @@ error: static void __exit sco_exit(void) { - class_remove_file(bt_class, &class_attr_sco); + debugfs_remove(sco_debugfs); if (bt_sock_unregister(BTPROTO_SCO) < 0) BT_ERR("SCO socket unregistration failed"); -- cgit v0.10.2 From c2c77ec83bdad17fb688557b5b3fdc36661dd1c6 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Fri, 19 Mar 2010 10:26:28 +0200 Subject: Bluetooth: Fix kernel crash on L2CAP stress tests Added very simple check that req buffer has enough space to fit configuration parameters. Shall be enough to reject packets with configuration size more than req buffer. Crash trace below [ 6069.659393] Unable to handle kernel paging request at virtual address 02000205 [ 6069.673034] Internal error: Oops: 805 [#1] PREEMPT ... [ 6069.727172] PC is at l2cap_add_conf_opt+0x70/0xf0 [l2cap] [ 6069.732604] LR is at l2cap_recv_frame+0x1350/0x2e78 [l2cap] ... [ 6070.030303] Backtrace: [ 6070.032806] [] (l2cap_add_conf_opt+0x0/0xf0 [l2cap]) from [] (l2cap_recv_frame+0x1350/0x2e78 [l2cap]) [ 6070.043823] r8:dc5d3100 r7:df2a91d6 r6:00000001 r5:df2a8000 r4:00000200 [ 6070.050659] [] (l2cap_recv_frame+0x0/0x2e78 [l2cap]) from [] (l2cap_recv_acldata+0x2bc/0x350 [l2cap]) [ 6070.061798] [] (l2cap_recv_acldata+0x0/0x350 [l2cap]) from [] (hci_rx_task+0x244/0x478 [bluetooth]) [ 6070.072631] r6:dc647700 r5:00000001 r4:df2ab740 [ 6070.077362] [] (hci_rx_task+0x0/0x478 [bluetooth]) from [] (tasklet_action+0x78/0xd8) [ 6070.087005] [] (tasklet_action+0x0/0xd8) from [] Signed-off-by: Andrei Emeltchenko Acked-by: Gustavo F. Padovan Signed-off-by: Marcel Holtmann diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 43e17f7..7794a2e 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -2832,6 +2832,11 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr int len = cmd->len - sizeof(*rsp); char req[64]; + if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) { + l2cap_send_disconn_req(conn, sk); + goto done; + } + /* throw out any old stored conf requests */ result = L2CAP_CONF_SUCCESS; len = l2cap_parse_conf_rsp(sk, rsp->data, -- cgit v0.10.2 From fc8aa7b16a5fcfe9c6d0be9bb587f1fcedd9145f Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 18 Mar 2010 07:53:11 +0100 Subject: sound/oss/vidc.c: change the field used with DMA_ACTIVE The constant DMA_ACTIVE is defined with the dma_buffparams structure rather than with the audio_operations structure. Takashi Iwai suggested that the dmap_out field of the audio_operations structure should be used instead. This is not tested. Signed-off-by: Julia Lawall Signed-off-by: Takashi Iwai diff --git a/sound/oss/vidc.c b/sound/oss/vidc.c index 725fef0..a4127ba 100644 --- a/sound/oss/vidc.c +++ b/sound/oss/vidc.c @@ -363,13 +363,13 @@ static void vidc_audio_trigger(int dev, int enable_bits) struct audio_operations *adev = audio_devs[dev]; if (enable_bits & PCM_ENABLE_OUTPUT) { - if (!(adev->flags & DMA_ACTIVE)) { + if (!(adev->dmap_out->flags & DMA_ACTIVE)) { unsigned long flags; local_irq_save(flags); /* prevent recusion */ - adev->flags |= DMA_ACTIVE; + adev->dmap_out->flags |= DMA_ACTIVE; dma_interrupt = vidc_audio_dma_interrupt; vidc_sound_dma_irq(0, NULL); -- cgit v0.10.2 From e3d2530a6cea80987f77b75d8784a00f3aaf22ff Mon Sep 17 00:00:00 2001 From: Kunal Gangakhedkar Date: Sat, 20 Mar 2010 23:08:01 +0530 Subject: ALSA: hda - Add PCI quirk for HP dv6-1110ax. Adding this PCI quirk fixes the board config detection. This also fixes jack sensing by using "hp_detect=1" via properly detected board config. Signed-off-by: Kunal Gangakhedkar Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 8c416bb..c4be3fa 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -1730,6 +1730,8 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { "HP HDX", STAC_HP_HDX), /* HDX16 */ SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3620, "HP dv6", STAC_HP_DV5), + SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3061, + "HP dv6", STAC_HP_DV5), /* HP dv6-1110ax */ SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x7010, "HP", STAC_HP_DV5), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233, -- cgit v0.10.2 From cdead7cf12896c0e50a8be2e52de52c364603095 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 19 Mar 2010 15:36:22 -0400 Subject: SUNRPC: Fix a potential memory leak in auth_gss The function alloc_enc_pages() currently fails to release the pointer rqstp->rq_enc_pages in the error path. Signed-off-by: Trond Myklebust Acked-by: J. Bruce Fields Cc: stable@kernel.org diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 0cfccc2a..c389ccf 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c @@ -1280,9 +1280,8 @@ alloc_enc_pages(struct rpc_rqst *rqstp) rqstp->rq_release_snd_buf = priv_release_snd_buf; return 0; out_free: - for (i--; i >= 0; i--) { - __free_page(rqstp->rq_enc_pages[i]); - } + rqstp->rq_enc_pages_num = i; + priv_release_snd_buf(rqstp); out: return -EAGAIN; } -- cgit v0.10.2 From 8c2eb4805d422bdbf60ba00ff233c794d23c3c00 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Fri, 19 Mar 2010 10:28:02 +0000 Subject: softlockup: Stop spurious softlockup messages due to overflow Ensure additions on touch_ts do not overflow. This can occur when the top 32 bits of the TSC reach 0xffffffff causing additions to touch_ts to overflow and this in turn generates spurious softlockup warnings. Signed-off-by: Colin Ian King Cc: Peter Zijlstra Cc: Eric Dumazet Cc: LKML-Reference: <1268994482.1798.6.camel@lenovo> Signed-off-by: Ingo Molnar diff --git a/kernel/softlockup.c b/kernel/softlockup.c index 0d4c789..4b493f6 100644 --- a/kernel/softlockup.c +++ b/kernel/softlockup.c @@ -155,11 +155,11 @@ void softlockup_tick(void) * Wake up the high-prio watchdog task twice per * threshold timespan. */ - if (now > touch_ts + softlockup_thresh/2) + if (time_after(now - softlockup_thresh/2, touch_ts)) wake_up_process(per_cpu(softlockup_watchdog, this_cpu)); /* Warn about unreasonable delays: */ - if (now <= (touch_ts + softlockup_thresh)) + if (time_before_eq(now - softlockup_thresh, touch_ts)) return; per_cpu(softlockup_print_ts, this_cpu) = touch_ts; -- cgit v0.10.2 From 634a4b2038a6eba4c211fb906fa2f6ec9a4bbfc7 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Sun, 21 Mar 2010 18:01:05 -0700 Subject: net: suppress lockdep-RCU false positive in FIB trie. Allow fib_find_node() to be called either under rcu_read_lock() protection or with RTNL held. Signed-off-by: Paul E. McKenney Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index af5d897..01ef8ba 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -961,7 +961,9 @@ fib_find_node(struct trie *t, u32 key) struct node *n; pos = 0; - n = rcu_dereference(t->trie); + n = rcu_dereference_check(t->trie, + rcu_read_lock_held() || + lockdep_rtnl_is_held()); while (n != NULL && NODE_TYPE(n) == T_TNODE) { tn = (struct tnode *) n; -- cgit v0.10.2 From 5e016cbf6cffd4a53b7922e0c91b775399d7fe47 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sun, 21 Mar 2010 20:55:13 -0700 Subject: ipv4: Don't drop redirected route cache entry unless PTMU actually expired TCP sessions over IPv4 can get stuck if routers between endpoints do not fragment packets but implement PMTU instead, and we are using those routers because of an ICMP redirect. Setup is as follows MTU1 MTU2 MTU1 A--------B------C------D with MTU1 > MTU2. A and D are endpoints, B and C are routers. B and C implement PMTU and drop packets larger than MTU2 (for example because DF is set on all packets). TCP sessions are initiated between A and D. There is packet loss between A and D, causing frequent TCP retransmits. After the number of retransmits on a TCP session reaches tcp_retries1, tcp calls dst_negative_advice() prior to each retransmit. This results in route cache entries for the peer to be deleted in ipv4_negative_advice() if the Path MTU is set. If the outstanding data on an affected TCP session is larger than MTU2, packets sent from the endpoints will be dropped by B or C, and ICMP NEEDFRAG will be returned. A and D receive NEEDFRAG messages and update PMTU. Before the next retransmit, tcp will again call dst_negative_advice(), causing the route cache entry (with correct PMTU) to be deleted. The retransmitted packet will be larger than MTU2, causing it to be dropped again. This sequence repeats until the TCP session aborts or is terminated. Problem is fixed by removing redirected route cache entries in ipv4_negative_advice() only if the PMTU is expired. Signed-off-by: Guenter Roeck Signed-off-by: David S. Miller diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 32d3961..54fd68c 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1510,7 +1510,8 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst) ip_rt_put(rt); ret = NULL; } else if ((rt->rt_flags & RTCF_REDIRECTED) || - rt->u.dst.expires) { + (rt->u.dst.expires && + time_after_eq(jiffies, rt->u.dst.expires))) { unsigned hash = rt_hash(rt->fl.fl4_dst, rt->fl.fl4_src, rt->fl.oif, rt_genid(dev_net(dst->dev))); -- cgit v0.10.2 From 2a8ac187e03027a958b289dd8701ca9c013ab096 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Mon, 8 Mar 2010 17:44:19 +0000 Subject: [ARM] pxa: fix for variables in uncompress.h being discarded Due to commit: 5de813b ARM: Eliminate decompressor -Dstatic= PIC hack The data section will be discarded for the decompressor, thus move the static variables into BSS section by initializing them at run time. Signed-off-by: Jonathan Cameron Signed-off-by: Eric Miao diff --git a/arch/arm/mach-pxa/include/mach/uncompress.h b/arch/arm/mach-pxa/include/mach/uncompress.h index 5ef91d9..759b851 100644 --- a/arch/arm/mach-pxa/include/mach/uncompress.h +++ b/arch/arm/mach-pxa/include/mach/uncompress.h @@ -16,9 +16,9 @@ #define BTUART_BASE (0x40200000) #define STUART_BASE (0x40700000) -static unsigned long uart_base = FFUART_BASE; -static unsigned int uart_shift = 2; -static unsigned int uart_is_pxa = 1; +static unsigned long uart_base; +static unsigned int uart_shift; +static unsigned int uart_is_pxa; static inline unsigned char uart_read(int offset) { @@ -56,6 +56,11 @@ static inline void flush(void) static inline void arch_decomp_setup(void) { + /* initialize to default */ + uart_base = FFUART_BASE; + uart_shift = 2; + uart_is_pxa = 1; + if (machine_is_littleton() || machine_is_intelmote2() || machine_is_csb726() || machine_is_stargate2() || machine_is_cm_x300() || machine_is_balloon3()) -- cgit v0.10.2 From 7471f46d74e0e2a668f4bc085ef486b1079b3466 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Mon, 22 Mar 2010 09:39:58 +0800 Subject: [ARM] mmp: fix for variables in uncompress.h being discarded Due to commit: 5de813b ARM: Eliminate decompressor -Dstatic= PIC hack The data section will be discarded for the decompressor, thus move the static variables into BSS section by initializing them at run time. Reported-by: Jonathan Cameron Signed-off-by: Eric Miao diff --git a/arch/arm/mach-mmp/include/mach/uncompress.h b/arch/arm/mach-mmp/include/mach/uncompress.h index a7dcc53..85bd8a2 100644 --- a/arch/arm/mach-mmp/include/mach/uncompress.h +++ b/arch/arm/mach-mmp/include/mach/uncompress.h @@ -14,7 +14,7 @@ #define UART2_BASE (APB_PHYS_BASE + 0x17000) #define UART3_BASE (APB_PHYS_BASE + 0x18000) -static volatile unsigned long *UART = (unsigned long *)UART2_BASE; +static volatile unsigned long *UART; static inline void putc(char c) { @@ -37,6 +37,9 @@ static inline void flush(void) static inline void arch_decomp_setup(void) { + /* default to UART2 */ + UART = (unsigned long *)UART2_BASE; + if (machine_is_avengers_lite()) UART = (unsigned long *)UART3_BASE; } -- cgit v0.10.2 From ef80936f99ce558a470c5379040abd0ece52c2ff Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sun, 7 Mar 2010 21:59:16 +0000 Subject: [ARM] pxa: remove spi cs gpio direction to avoid clash with driver Signed-off-by: Jonathan Cameron Signed-off-by: Eric Miao diff --git a/arch/arm/mach-pxa/imote2.c b/arch/arm/mach-pxa/imote2.c index b2f878b..5161dca 100644 --- a/arch/arm/mach-pxa/imote2.c +++ b/arch/arm/mach-pxa/imote2.c @@ -559,10 +559,6 @@ static void __init imote2_init(void) pxa_set_btuart_info(NULL); pxa_set_stuart_info(NULL); - /* SPI chip select directions - all other directions should - * be handled by drivers.*/ - gpio_direction_output(37, 0); - platform_add_devices(imote2_devices, ARRAY_SIZE(imote2_devices)); pxa2xx_set_spi_info(1, &pxa_ssp_master_0_info); diff --git a/arch/arm/mach-pxa/stargate2.c b/arch/arm/mach-pxa/stargate2.c index a98a434..2041eb1 100644 --- a/arch/arm/mach-pxa/stargate2.c +++ b/arch/arm/mach-pxa/stargate2.c @@ -764,11 +764,6 @@ static void __init stargate2_init(void) pxa_set_btuart_info(NULL); pxa_set_stuart_info(NULL); - /* spi chip selects */ - gpio_direction_output(37, 0); - gpio_direction_output(24, 0); - gpio_direction_output(39, 0); - platform_add_devices(ARRAY_AND_SIZE(stargate2_devices)); pxa2xx_set_spi_info(1, &pxa_ssp_master_0_info); -- cgit v0.10.2 From 1fe2b6b527779ca966bc285dc27f84835bc1591a Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Tue, 9 Mar 2010 11:04:44 +0800 Subject: [ARM] pxa: remove unnecessary 'select FB_W100' from some platforms Reported-by: Jonathan Cameron Signed-off-by: Eric Miao diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 38fbd0a..c5b2f0a 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -272,7 +272,6 @@ config MACH_H5000 config MACH_HIMALAYA bool "HTC Himalaya Support" select CPU_PXA26x - select FB_W100 config MACH_MAGICIAN bool "Enable HTC Magician Support" @@ -547,7 +546,6 @@ config MACH_E740 bool "Toshiba e740" default y depends on ARCH_PXA_ESERIES - select FB_W100 help Say Y here if you intend to run this kernel on a Toshiba e740 family PDA. @@ -556,7 +554,6 @@ config MACH_E750 bool "Toshiba e750" default y depends on ARCH_PXA_ESERIES - select FB_W100 help Say Y here if you intend to run this kernel on a Toshiba e750 family PDA. @@ -573,7 +570,6 @@ config MACH_E800 bool "Toshiba e800" default y depends on ARCH_PXA_ESERIES - select FB_W100 help Say Y here if you intend to run this kernel on a Toshiba e800 family PDA. -- cgit v0.10.2 From 6533be390b1210285854fb2fc7ea80c0ada60b13 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Tue, 9 Mar 2010 10:34:27 +0800 Subject: [ARM] pxa/sharpsl: add dependency of max1111 driver to sharpsl_pm sharpsl_pm.c actually depends on max1111 driver being built-in when not using legacy ssp code. Reported-by: Jonathan Cameron Signed-off-by: Eric Miao diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index c5b2f0a..5b6ee46 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -453,6 +453,13 @@ config PXA_SHARPSL config SHARPSL_PM bool select APM_EMULATION + select SHARPSL_PM_MAX1111 + +config SHARPSL_PM_MAX1111 + bool + depends on !CORGI_SSP_DEPRECATED + select HWMON + select SENSORS_MAX1111 config CORGI_SSP_DEPRECATED bool -- cgit v0.10.2 From 1b0d76cb9d5a65567230097a2512046f09f30523 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 22 Mar 2010 10:33:58 +0800 Subject: [ARM] locomo: fix SPI register offset The locomo spi registers are all defined in locomo.h as offsets from the first spi register LOCOMO_SPI (0x60), which is itself an offset from the locomo base address. To correctly access these registers LOCOMO_SPI must always be included in the address calculation. There are two places in locomo.c where this is not done. The first one, in locomo_suspend, actually results in a write to LOCOMO_ST instead of LOCOMO_SPICT. The second is in __locomo_probe and results in a write to LOCOMO_MCSX2 instead of LOCOMO_SPIIE. Fix these by including LOCOMO_SPI in the calculation. Signed-off-by: H Hartley Sweeten Signed-off-by: Eric Miao diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c index 90ae00b..4f9ccf6 100644 --- a/arch/arm/common/locomo.c +++ b/arch/arm/common/locomo.c @@ -290,7 +290,7 @@ static int locomo_suspend(struct platform_device *dev, pm_message_t state) save->LCM_GPO = locomo_readl(lchip->base + LOCOMO_GPO); /* GPIO */ locomo_writel(0x00, lchip->base + LOCOMO_GPO); save->LCM_SPICT = locomo_readl(lchip->base + LOCOMO_SPI + LOCOMO_SPICT); /* SPI */ - locomo_writel(0x40, lchip->base + LOCOMO_SPICT); + locomo_writel(0x40, lchip->base + LOCOMO_SPI + LOCOMO_SPICT); save->LCM_GPE = locomo_readl(lchip->base + LOCOMO_GPE); /* GPIO */ locomo_writel(0x00, lchip->base + LOCOMO_GPE); save->LCM_ASD = locomo_readl(lchip->base + LOCOMO_ASD); /* ADSTART */ @@ -418,7 +418,7 @@ __locomo_probe(struct device *me, struct resource *mem, int irq) /* Longtime timer */ locomo_writel(0, lchip->base + LOCOMO_LTINT); /* SPI */ - locomo_writel(0, lchip->base + LOCOMO_SPIIE); + locomo_writel(0, lchip->base + LOCOMO_SPI + LOCOMO_SPIIE); locomo_writel(6 + 8 + 320 + 30 - 10, lchip->base + LOCOMO_ASD); r = locomo_readl(lchip->base + LOCOMO_ASD); -- cgit v0.10.2 From c8c3dcb9df8025ed48f8b14bf4b8a77801d88758 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 22 Mar 2010 11:09:20 +0800 Subject: [ARM] locomo: fix unpaired spin_lock_irqsave The function locomo_m62332_senddata sends a three byte i2c message to a M62332 DAC. This entire function is guarded with a spin_lock_irqsave at the start of the function and a spin_unlock_irqrestore at the end. As each byte is transferred, the i2c ACK from the DAC is checked. Currently, if the ACK is missing the function simply returns without the unlock. It also leaves the i2c bus in an invalid state since the last byte transferred did not have a "stop" condition and leave the bus idle. Fix this by adding an exit path using goto. Signed-off-by: H Hartley Sweeten Signed-off-by: Eric Miao diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c index 4f9ccf6..9dff07c 100644 --- a/arch/arm/common/locomo.c +++ b/arch/arm/common/locomo.c @@ -707,7 +707,7 @@ void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4.7 usec */ if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) { /* High is error */ printk(KERN_WARNING "locomo: m62332_senddata Error 1\n"); - return; + goto out; } /* Send Sub address (LSB is channel select) */ @@ -735,7 +735,7 @@ void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4.7 usec */ if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) { /* High is error */ printk(KERN_WARNING "locomo: m62332_senddata Error 2\n"); - return; + goto out; } /* Send DAC data */ @@ -760,9 +760,9 @@ void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4.7 usec */ if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) { /* High is error */ printk(KERN_WARNING "locomo: m62332_senddata Error 3\n"); - return; } +out: /* stop */ r = locomo_readl(mapbase + LOCOMO_DAC); r &= ~(LOCOMO_DAC_SCLOEB); -- cgit v0.10.2 From af089f517a1fea0af2053f105c9360df614be07c Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Mon, 22 Mar 2010 11:51:05 +0800 Subject: [ARM] pxa/raumfeld: remove duplicated #include Remove duplicated #include('s) in arch/arm/mach-pxa/raumfeld.c Signed-off-by: Huang Weiyi Signed-off-by: Eric Miao diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c index 3184bdc..9d23f69 100644 --- a/arch/arm/mach-pxa/raumfeld.c +++ b/arch/arm/mach-pxa/raumfeld.c @@ -37,8 +37,6 @@ #include #include #include -#include -#include #include #include #include -- cgit v0.10.2 From fe3ebaad3229c5e842e8b24cf2a24d7049a6481c Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Thu, 18 Mar 2010 19:37:29 +0100 Subject: [ARM] pxa/raumfeld: fix button name This fixes a warning when booting 2.6.34-rc2: [ 26.619814] ------------[ cut here ]------------ [ 26.624604] WARNING: at fs/proc/generic.c:316 __xlate_proc_name+0xac/0xc0() [ 26.631555] name 'on/off button' [ 26.634753] Modules linked in: Signed-off-by: Daniel Mack Cc: Sven Neumann Signed-off-by: Eric Miao diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c index 9d23f69..44bb675 100644 --- a/arch/arm/mach-pxa/raumfeld.c +++ b/arch/arm/mach-pxa/raumfeld.c @@ -442,7 +442,7 @@ static struct gpio_keys_button gpio_keys_button[] = { .active_low = 0, .wakeup = 0, .debounce_interval = 5, /* ms */ - .desc = "on/off button", + .desc = "on_off button", }, }; -- cgit v0.10.2 From 9bf35c8dddd56f7f247a27346f74f5adc18071f4 Mon Sep 17 00:00:00 2001 From: Paulius Zaleckas Date: Sun, 21 Mar 2010 21:19:02 -0700 Subject: if_tunnel.h: add missing ams/byteorder.h include When compiling userspace application which includes if_tunnel.h and uses GRE_* defines you will get undefined reference to __cpu_to_be16. Fix this by adding missing #include Cc: stable@kernel.org Signed-off-by: Paulius Zaleckas Signed-off-by: David S. Miller diff --git a/include/linux/if_tunnel.h b/include/linux/if_tunnel.h index 1822d63..16b92d0 100644 --- a/include/linux/if_tunnel.h +++ b/include/linux/if_tunnel.h @@ -2,6 +2,7 @@ #define _IF_TUNNEL_H_ #include +#include #ifdef __KERNEL__ #include -- cgit v0.10.2 From 243aad830e8a4cdda261626fbaeddde16b08d04a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Sat, 20 Mar 2010 02:27:58 +0000 Subject: ip_gre: include route header_len in max_headroom calculation Taking route's header_len into account, and updating gre device needed_headroom will give better hints on upper bound of required headroom. This is useful if the gre traffic is xfrm'ed. Signed-off-by: Timo Teras Acked-by: Herbert Xu Signed-off-by: David S. Miller diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index f47c9f7..f78402d 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -810,11 +810,13 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev tunnel->err_count = 0; } - max_headroom = LL_RESERVED_SPACE(tdev) + gre_hlen; + max_headroom = LL_RESERVED_SPACE(tdev) + gre_hlen + rt->u.dst.header_len; if (skb_headroom(skb) < max_headroom || skb_shared(skb)|| (skb_cloned(skb) && !skb_clone_writable(skb, 0))) { struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom); + if (max_headroom > dev->needed_headroom) + dev->needed_headroom = max_headroom; if (!new_skb) { ip_rt_put(rt); txq->tx_dropped++; -- cgit v0.10.2 From 97065e033ec5fd824d0133ecd0c614fe1e5c20bd Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Sun, 21 Mar 2010 22:31:26 -0700 Subject: Input: clarify the no-finger event in multitouch protocol The current documentation does not explicitly specify how to report zero fingers, leaving a potential problem in the driver implementations and giving no parsing directive to userland. This patch defines two equally valid ways. Signed-off-by: Henrik Rydberg Signed-off-by: Dmitry Torokhov diff --git a/Documentation/input/multi-touch-protocol.txt b/Documentation/input/multi-touch-protocol.txt index 8490480..eacb226 100644 --- a/Documentation/input/multi-touch-protocol.txt +++ b/Documentation/input/multi-touch-protocol.txt @@ -68,6 +68,22 @@ like: SYN_MT_REPORT SYN_REPORT +Here is the sequence after lifting one of the fingers: + + ABS_MT_POSITION_X + ABS_MT_POSITION_Y + SYN_MT_REPORT + SYN_REPORT + +And here is the sequence after lifting the remaining finger: + + SYN_MT_REPORT + SYN_REPORT + +If the driver reports one of BTN_TOUCH or ABS_PRESSURE in addition to the +ABS_MT events, the last SYN_MT_REPORT event may be omitted. Otherwise, the +last SYN_REPORT will be dropped by the input core, resulting in no +zero-finger event reaching userland. Event Semantics --------------- -- cgit v0.10.2 From 13bad37b04c779d98983307a27f97e9caa36f9b1 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Sun, 21 Mar 2010 22:31:26 -0700 Subject: Input: update the status of the Multitouch X driver project The Multitouch X driver project has moved to alpha status. This patch updates the documentation accordingly. Signed-off-by: Henrik Rydberg Signed-off-by: Dmitry Torokhov diff --git a/Documentation/input/multi-touch-protocol.txt b/Documentation/input/multi-touch-protocol.txt index eacb226..c0fc1c7 100644 --- a/Documentation/input/multi-touch-protocol.txt +++ b/Documentation/input/multi-touch-protocol.txt @@ -233,11 +233,6 @@ where examples can be found. difference between the contact position and the approaching tool position could be used to derive tilt. [2] The list can of course be extended. -[3] The multi-touch X driver is currently in the prototyping stage. At the -time of writing (April 2009), the MT protocol is not yet merged, and the -prototype implements finger matching, basic mouse support and two-finger -scrolling. The project aims at improving the quality of current multi-touch -functionality available in the Synaptics X driver, and in addition -implement more advanced gestures. +[3] Multitouch X driver project: http://bitmath.org/code/multitouch/. [4] See the section on event computation. [5] See the section on finger tracking. -- cgit v0.10.2 From 2d8428acaee5468d194d8a84de22a0797791cb33 Mon Sep 17 00:00:00 2001 From: Ryusuke Konishi Date: Mon, 22 Mar 2010 14:01:24 +0900 Subject: nilfs2: fix duplicate call to nilfs_segctor_cancel_freev Andreas Beckmann gave me a report that nilfs logged the following warnings when it got a disk full: nilfs_sufile_do_cancel_free: segment 0 must be clean nilfs_sufile_do_cancel_free: segment 1 must be clean These arise from a duplicate call to nilfs_segctor_cancel_freev in an error path of log writer. This will fix the issue. Reported-by: Andreas Beckmann Signed-off-by: Ryusuke Konishi diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index 69576a9..b622123 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c @@ -1510,6 +1510,12 @@ static int nilfs_segctor_collect(struct nilfs_sc_info *sci, if (mode != SC_LSEG_SR || sci->sc_stage.scnt < NILFS_ST_CPFILE) break; + nilfs_clear_logs(&sci->sc_segbufs); + + err = nilfs_segctor_extend_segments(sci, nilfs, nadd); + if (unlikely(err)) + return err; + if (sci->sc_stage.flags & NILFS_CF_SUFREED) { err = nilfs_sufile_cancel_freev(nilfs->ns_sufile, sci->sc_freesegs, @@ -1517,12 +1523,6 @@ static int nilfs_segctor_collect(struct nilfs_sc_info *sci, NULL); WARN_ON(err); /* do not happen */ } - nilfs_clear_logs(&sci->sc_segbufs); - - err = nilfs_segctor_extend_segments(sci, nilfs, nadd); - if (unlikely(err)) - return err; - nadd = min_t(int, nadd << 1, SC_MAX_SEGDELTA); sci->sc_stage = prev_stage; } -- cgit v0.10.2 From 2e2e3b96d98d5c17e9c09bc6088df3e182a71814 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 21 Mar 2010 22:56:15 -0700 Subject: Input: sparse-keymap - implement safer freeing of the keymap Allow calling sparse_keymap_free() before unregistering input device whithout risk of racing with EVIOCGETKEYCODE and EVIOCSETKEYCODE. This makes life of drivers writers easier. Acked-by: Yong Wang Signed-off-by: Dmitry Torokhov diff --git a/drivers/input/input.c b/drivers/input/input.c index e2aad0a..be18fa9 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -659,7 +659,14 @@ static int input_default_setkeycode(struct input_dev *dev, int input_get_keycode(struct input_dev *dev, unsigned int scancode, unsigned int *keycode) { - return dev->getkeycode(dev, scancode, keycode); + unsigned long flags; + int retval; + + spin_lock_irqsave(&dev->event_lock, flags); + retval = dev->getkeycode(dev, scancode, keycode); + spin_unlock_irqrestore(&dev->event_lock, flags); + + return retval; } EXPORT_SYMBOL(input_get_keycode); diff --git a/drivers/input/sparse-keymap.c b/drivers/input/sparse-keymap.c index f64e004..2434ac5 100644 --- a/drivers/input/sparse-keymap.c +++ b/drivers/input/sparse-keymap.c @@ -67,12 +67,14 @@ static int sparse_keymap_getkeycode(struct input_dev *dev, unsigned int scancode, unsigned int *keycode) { - const struct key_entry *key = - sparse_keymap_entry_from_scancode(dev, scancode); + const struct key_entry *key; - if (key && key->type == KE_KEY) { - *keycode = key->keycode; - return 0; + if (dev->keycode) { + key = sparse_keymap_entry_from_scancode(dev, scancode); + if (key && key->type == KE_KEY) { + *keycode = key->keycode; + return 0; + } } return -EINVAL; @@ -85,17 +87,16 @@ static int sparse_keymap_setkeycode(struct input_dev *dev, struct key_entry *key; int old_keycode; - if (keycode < 0 || keycode > KEY_MAX) - return -EINVAL; - - key = sparse_keymap_entry_from_scancode(dev, scancode); - if (key && key->type == KE_KEY) { - old_keycode = key->keycode; - key->keycode = keycode; - set_bit(keycode, dev->keybit); - if (!sparse_keymap_entry_from_keycode(dev, old_keycode)) - clear_bit(old_keycode, dev->keybit); - return 0; + if (dev->keycode) { + key = sparse_keymap_entry_from_scancode(dev, scancode); + if (key && key->type == KE_KEY) { + old_keycode = key->keycode; + key->keycode = keycode; + set_bit(keycode, dev->keybit); + if (!sparse_keymap_entry_from_keycode(dev, old_keycode)) + clear_bit(old_keycode, dev->keybit); + return 0; + } } return -EINVAL; @@ -175,14 +176,27 @@ EXPORT_SYMBOL(sparse_keymap_setup); * * This function is used to free memory allocated by sparse keymap * in an input device that was set up by sparse_keymap_setup(). + * NOTE: It is safe to cal this function while input device is + * still registered (however the drivers should care not to try to + * use freed keymap and thus have to shut off interrups/polling + * before freeing the keymap). */ void sparse_keymap_free(struct input_dev *dev) { + unsigned long flags; + + /* + * Take event lock to prevent racing with input_get_keycode() + * and input_set_keycode() if we are called while input device + * is still registered. + */ + spin_lock_irqsave(&dev->event_lock, flags); + kfree(dev->keycode); dev->keycode = NULL; dev->keycodemax = 0; - dev->getkeycode = NULL; - dev->setkeycode = NULL; + + spin_unlock_irqrestore(&dev->event_lock, flags); } EXPORT_SYMBOL(sparse_keymap_free); -- cgit v0.10.2 From 025f206c9e0f96cc41567b01c07fb852d8900da1 Mon Sep 17 00:00:00 2001 From: Daniel T Chen Date: Sun, 21 Mar 2010 18:34:43 -0400 Subject: ALSA: hda: Fix 0 dB offset for HP laptops using CX20551 (Waikiki) BugLink: https://launchpad.net/bugs/420578 The OR has verified that his hardware distorts because of the 0 dB offset not corresponding to the highest PCM level. Fix this by capping said PCM level to 0 dB similarly to what we do for CX20549 (Venice). Reported-by: Mike Pontillo Tested-by: Mike Pontillo Cc: Signed-off-by: Daniel T Chen Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 194a28c..61682e1 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -1591,6 +1591,21 @@ static int patch_cxt5047(struct hda_codec *codec) #endif } spec->vmaster_nid = 0x13; + + switch (codec->subsystem_id >> 16) { + case 0x103c: + /* HP laptops have really bad sound over 0 dB on NID 0x10. + * Fix max PCM level to 0 dB (originally it has 0x1e steps + * with 0 dB offset 0x17) + */ + snd_hda_override_amp_caps(codec, 0x10, HDA_INPUT, + (0x17 << AC_AMPCAP_OFFSET_SHIFT) | + (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) | + (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) | + (1 << AC_AMPCAP_MUTE_SHIFT)); + break; + } + return 0; } -- cgit v0.10.2 From e933e9e5238b79870b04718024416a6dcf602a27 Mon Sep 17 00:00:00 2001 From: Derek Kelly Date: Mon, 22 Mar 2010 08:04:19 +0100 Subject: ALSA: hda - Add support of Nvidia GT220 HDMI This patch adds the device id for Nvidia GT220 cards to the nvhdmi driver. I have tested it and confirmed it to be working. Original patch download link: https://gist.github.com/324070/ Signed-off-by: Derek Kelly Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c index 70669a2..9e47717 100644 --- a/sound/pci/hda/patch_nvhdmi.c +++ b/sound/pci/hda/patch_nvhdmi.c @@ -554,6 +554,8 @@ static struct hda_codec_preset snd_hda_preset_nvhdmi[] = { .patch = patch_nvhdmi_8ch_89 }, { .id = 0x10de000b, .name = "GT21x HDMI", .patch = patch_nvhdmi_8ch_89 }, + { .id = 0x10de000a, .name = "GT220 HDMI", + .patch = patch_nvhdmi_8ch_89 }, { .id = 0x10de000d, .name = "GT240 HDMI", .patch = patch_nvhdmi_8ch_89 }, {} /* terminator */ @@ -568,6 +570,7 @@ MODULE_ALIAS("snd-hda-codec-id:10de0067"); MODULE_ALIAS("snd-hda-codec-id:10de8001"); MODULE_ALIAS("snd-hda-codec-id:10de000c"); MODULE_ALIAS("snd-hda-codec-id:10de000b"); +MODULE_ALIAS("snd-hda-codec-id:10de000a"); MODULE_ALIAS("snd-hda-codec-id:10de000d"); MODULE_LICENSE("GPL"); -- cgit v0.10.2 From ea823c08912cfb6d4af2fa8b6dd5d8deb2fb486a Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 22 Mar 2010 08:07:55 +0100 Subject: ALSA: hda - Sort codec entry list of Nvidia HDMI Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c index 9e47717..3c10c0b 100644 --- a/sound/pci/hda/patch_nvhdmi.c +++ b/sound/pci/hda/patch_nvhdmi.c @@ -538,8 +538,6 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec) * patch entries */ static struct hda_codec_preset snd_hda_preset_nvhdmi[] = { - { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch }, - { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch }, { .id = 0x10de0002, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x }, { .id = 0x10de0003, .name = "MCP77/78 HDMI", @@ -550,14 +548,16 @@ static struct hda_codec_preset snd_hda_preset_nvhdmi[] = { .patch = patch_nvhdmi_8ch_7x }, { .id = 0x10de0007, .name = "MCP79/7A HDMI", .patch = patch_nvhdmi_8ch_7x }, - { .id = 0x10de000c, .name = "MCP89 HDMI", + { .id = 0x10de000a, .name = "GT220 HDMI", .patch = patch_nvhdmi_8ch_89 }, { .id = 0x10de000b, .name = "GT21x HDMI", .patch = patch_nvhdmi_8ch_89 }, - { .id = 0x10de000a, .name = "GT220 HDMI", + { .id = 0x10de000c, .name = "MCP89 HDMI", .patch = patch_nvhdmi_8ch_89 }, { .id = 0x10de000d, .name = "GT240 HDMI", .patch = patch_nvhdmi_8ch_89 }, + { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch }, + { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch }, {} /* terminator */ }; @@ -566,12 +566,12 @@ MODULE_ALIAS("snd-hda-codec-id:10de0003"); MODULE_ALIAS("snd-hda-codec-id:10de0005"); MODULE_ALIAS("snd-hda-codec-id:10de0006"); MODULE_ALIAS("snd-hda-codec-id:10de0007"); -MODULE_ALIAS("snd-hda-codec-id:10de0067"); -MODULE_ALIAS("snd-hda-codec-id:10de8001"); -MODULE_ALIAS("snd-hda-codec-id:10de000c"); -MODULE_ALIAS("snd-hda-codec-id:10de000b"); MODULE_ALIAS("snd-hda-codec-id:10de000a"); +MODULE_ALIAS("snd-hda-codec-id:10de000b"); +MODULE_ALIAS("snd-hda-codec-id:10de000c"); MODULE_ALIAS("snd-hda-codec-id:10de000d"); +MODULE_ALIAS("snd-hda-codec-id:10de0067"); +MODULE_ALIAS("snd-hda-codec-id:10de8001"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("NVIDIA HDMI HD-audio codec"); -- cgit v0.10.2 From bae84e70d66fe46c12231082cf1c4848ea22f3ef Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 22 Mar 2010 08:30:20 +0100 Subject: ALSA: hda - Fix access-after-free in patch_realtek.c alc_free_kctls() has to be called after all jobs done in alc_build_controls(). Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 4ec5763..053d53d 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -2532,8 +2532,6 @@ static int alc_build_controls(struct hda_codec *codec) return err; } - alc_free_kctls(codec); /* no longer needed */ - /* assign Capture Source enums to NID */ kctl = snd_hda_find_mixer_ctl(codec, "Capture Source"); if (!kctl) @@ -2602,6 +2600,9 @@ static int alc_build_controls(struct hda_codec *codec) } } } + + alc_free_kctls(codec); /* no longer needed */ + return 0; } -- cgit v0.10.2 From c9acb42ef1904d15d0fb315061cefbe638f67f3a Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 19 Mar 2010 15:36:22 -0400 Subject: SUNRPC: Fix a use after free bug with the NFSv4.1 backchannel The ->release_request() callback was designed to allow the transport layer to do housekeeping after the RPC call is done. It cannot be used to free the request itself, and doing so leads to a use-after-free bug in xprt_release(). Signed-off-by: Trond Myklebust diff --git a/include/linux/sunrpc/bc_xprt.h b/include/linux/sunrpc/bc_xprt.h index d7152b4..7c91260 100644 --- a/include/linux/sunrpc/bc_xprt.h +++ b/include/linux/sunrpc/bc_xprt.h @@ -36,7 +36,6 @@ struct rpc_rqst *xprt_alloc_bc_request(struct rpc_xprt *xprt); void xprt_free_bc_request(struct rpc_rqst *req); int xprt_setup_backchannel(struct rpc_xprt *, unsigned int min_reqs); void xprt_destroy_backchannel(struct rpc_xprt *, int max_reqs); -void bc_release_request(struct rpc_task *); int bc_send(struct rpc_rqst *req); /* @@ -59,6 +58,10 @@ static inline int svc_is_backchannel(const struct svc_rqst *rqstp) { return 0; } + +static inline void xprt_free_bc_request(struct rpc_rqst *req) +{ +} #endif /* CONFIG_NFS_V4_1 */ #endif /* _LINUX_SUNRPC_BC_XPRT_H */ diff --git a/net/sunrpc/bc_svc.c b/net/sunrpc/bc_svc.c index 13f214f..f0c05d3 100644 --- a/net/sunrpc/bc_svc.c +++ b/net/sunrpc/bc_svc.c @@ -37,21 +37,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define RPCDBG_FACILITY RPCDBG_SVCDSP -void bc_release_request(struct rpc_task *task) -{ - struct rpc_rqst *req = task->tk_rqstp; - - dprintk("RPC: bc_release_request: task= %p\n", task); - - /* - * Release this request only if it's a backchannel - * preallocated request - */ - if (!bc_prealloc(req)) - return; - xprt_free_bc_request(req); -} - /* Empty callback ops */ static const struct rpc_call_ops nfs41_callback_ops = { }; diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 469de29..42f09ad 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -46,6 +46,7 @@ #include #include +#include #include "sunrpc.h" @@ -1032,21 +1033,16 @@ void xprt_release(struct rpc_task *task) if (req->rq_release_snd_buf) req->rq_release_snd_buf(req); - /* - * Early exit if this is a backchannel preallocated request. - * There is no need to have it added to the RPC slot list. - */ - if (is_bc_request) - return; - - memset(req, 0, sizeof(*req)); /* mark unused */ - dprintk("RPC: %5u release request %p\n", task->tk_pid, req); + if (likely(!is_bc_request)) { + memset(req, 0, sizeof(*req)); /* mark unused */ - spin_lock(&xprt->reserve_lock); - list_add(&req->rq_list, &xprt->free); - rpc_wake_up_next(&xprt->backlog); - spin_unlock(&xprt->reserve_lock); + spin_lock(&xprt->reserve_lock); + list_add(&req->rq_list, &xprt->free); + rpc_wake_up_next(&xprt->backlog); + spin_unlock(&xprt->reserve_lock); + } else + xprt_free_bc_request(req); } /** diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index e4839c0..9847c30 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c @@ -2251,9 +2251,6 @@ static struct rpc_xprt_ops xs_tcp_ops = { .buf_free = rpc_free, .send_request = xs_tcp_send_request, .set_retrans_timeout = xprt_set_retrans_timeout_def, -#if defined(CONFIG_NFS_V4_1) - .release_request = bc_release_request, -#endif /* CONFIG_NFS_V4_1 */ .close = xs_tcp_close, .destroy = xs_destroy, .print_stats = xs_tcp_print_stats, -- cgit v0.10.2 From ff0901f8036a1586037c30a365c9666e946af0f1 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 19 Mar 2010 16:17:45 -0400 Subject: SUNRPC: Fix the return value of rpc_run_bc_task() Currently rpc_run_bc_task() will return NULL if the task allocation failed. However the only caller is bc_send, which assumes that the return value will be an ERR_PTR. Signed-off-by: Trond Myklebust diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 154034b..19c9983 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -659,6 +659,7 @@ struct rpc_task *rpc_run_bc_task(struct rpc_rqst *req, task = rpc_new_task(&task_setup_data); if (!task) { xprt_free_bc_request(req); + task = ERR_PTR(-ENOMEM); goto out; } task->tk_rqstp = req; -- cgit v0.10.2 From f1f0abe192a72e75d7c59972e30784d043fd8d73 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sun, 21 Mar 2010 12:10:34 -0400 Subject: sunrpc: handle allocation errors from __rpc_lookup_create() __rpc_lookup_create() can return ERR_PTR(-ENOMEM). Signed-off-by: Dan Carpenter Signed-off-by: Trond Myklebust Cc: stable@kernel.org diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 8d63f8f..20e30c6 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c @@ -587,6 +587,8 @@ static struct dentry *__rpc_lookup_create_exclusive(struct dentry *parent, struct dentry *dentry; dentry = __rpc_lookup_create(parent, name); + if (IS_ERR(dentry)) + return dentry; if (dentry->d_inode == NULL) return dentry; dput(dentry); -- cgit v0.10.2 From 556ae3bb32cabe483375b857dda1322384c57b65 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Sun, 21 Mar 2010 12:10:36 -0400 Subject: NFS: don't try to decode GETATTR if DELEGRETURN returned error The reply parsing code attempts to decode the GETATTR response even if the DELEGRETURN portion of the compound returned an error. The GETATTR response won't actually exist if that's the case and we're asking the parser to read past the end of the response. This bug is fairly benign. The parser catches this without reading past the end of the response and decode_getfattr returns -EIO. Earlier kernels however had decode_op_hdr using the READ_BUF macro, and this bug would make this printk pop any time the client got an error from a delegreturn: kernel: decode_op_hdr: reply buffer overflowed in line XXXX More recent kernels seem to have replaced this printk with a dprintk. Signed-off-by: Jeff Layton Signed-off-by: Trond Myklebust diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 4d338be..dd17713 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -5552,6 +5552,8 @@ static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, __be32 *p, struct nf if (status != 0) goto out; status = decode_delegreturn(&xdr); + if (status != 0) + goto out; decode_getfattr(&xdr, res->fattr, res->server, !RPC_IS_ASYNC(rqstp->rq_task)); out: -- cgit v0.10.2 From 3cc4e53f86dab635166929bfa47cc68d59b28c26 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 12 Feb 2010 14:39:36 +0000 Subject: ASoC: Remove BROKEN from i.MX audio after dependencies merged Signed-off-by: Mark Brown Acked-by: Liam Girdwood diff --git a/sound/soc/imx/Kconfig b/sound/soc/imx/Kconfig index c7d0fd9..7174b4c 100644 --- a/sound/soc/imx/Kconfig +++ b/sound/soc/imx/Kconfig @@ -1,6 +1,6 @@ config SND_IMX_SOC tristate "SoC Audio for Freescale i.MX CPUs" - depends on ARCH_MXC && BROKEN + depends on ARCH_MXC select SND_PCM select FIQ select SND_SOC_AC97_BUS -- cgit v0.10.2 From ec64213c4d482ee4d15b34511441eaecdd002adf Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Fri, 19 Mar 2010 17:36:43 +0530 Subject: virtio: console: Generate a kobject CHANGE event on adding 'name' attribute When the host lets us know what 'name' a port is assigned, we create the sysfs 'name' attribute. Generate a 'change' event after this so that udev wakes up and acts on the rules for virtio-ports (currently there's only one rule that creates a symlink from the 'name' to the actual char device). Signed-off-by: Amit Shah Signed-off-by: Michael S. Tsirkin diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index f404ccf..67b474b 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -947,11 +947,18 @@ static void handle_control_message(struct ports_device *portdev, */ err = sysfs_create_group(&port->dev->kobj, &port_attribute_group); - if (err) + if (err) { dev_err(port->dev, "Error %d creating sysfs device attributes\n", err); - + } else { + /* + * Generate a udev event so that appropriate + * symlinks can be created based on udev + * rules. + */ + kobject_uevent(&port->dev->kobj, KOBJ_CHANGE); + } break; case VIRTIO_CONSOLE_PORT_REMOVE: /* -- cgit v0.10.2 From 2de16a493cc6153f7fa0b9da12a3862d063e3425 Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Fri, 19 Mar 2010 17:36:44 +0530 Subject: virtio: console: Check if port is valid in resize_console The console port could have been hot-unplugged. Check if it is valid before working on it. Signed-off-by: Amit Shah Signed-off-by: Michael S. Tsirkin diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 67b474b..44288ce 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -681,6 +681,10 @@ static void resize_console(struct port *port) struct virtio_device *vdev; struct winsize ws; + /* The port could have been hot-unplugged */ + if (!port) + return; + vdev = port->portdev->vdev; if (virtio_has_feature(vdev, VIRTIO_CONSOLE_F_SIZE)) { vdev->config->get(vdev, -- cgit v0.10.2 From e3396b263c6a8f086a99f1d524272ff409d66de0 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 22 Mar 2010 15:10:35 +0300 Subject: pxa168fb: fix incorrect resource calculation The size calculation is not correct. It should be end - start + 1. Use resource_size() to caculate it. Signed-off-by: Dan Carpenter Signed-off-by: Eric Miao diff --git a/drivers/video/pxa168fb.c b/drivers/video/pxa168fb.c index 75285d3..c91a7f7 100644 --- a/drivers/video/pxa168fb.c +++ b/drivers/video/pxa168fb.c @@ -668,7 +668,7 @@ static int __init pxa168fb_probe(struct platform_device *pdev) /* * Map LCD controller registers. */ - fbi->reg_base = ioremap_nocache(res->start, res->end - res->start); + fbi->reg_base = ioremap_nocache(res->start, resource_size(res)); if (fbi->reg_base == NULL) { ret = -ENOMEM; goto failed; -- cgit v0.10.2 From 5b89d2f9ace1970324facc68ca9b8fae19ce8096 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Tue, 9 Mar 2010 20:38:48 +0100 Subject: edac, mce: Filter out invalid values Print the CPU associated with the error only when the field is valid. Cc: # .32.x .33.x Signed-off-by: Borislav Petkov diff --git a/drivers/edac/edac_mce_amd.c b/drivers/edac/edac_mce_amd.c index 8fc91a0..f5b6d9f 100644 --- a/drivers/edac/edac_mce_amd.c +++ b/drivers/edac/edac_mce_amd.c @@ -316,7 +316,12 @@ void amd_decode_nb_mce(int node_id, struct err_regs *regs, int handle_errors) if (regs->nbsh & K8_NBSH_ERR_CPU_VAL) pr_cont(", core: %u\n", (u8)(regs->nbsh & 0xf)); } else { - pr_cont(", core: %d\n", fls((regs->nbsh & 0xf) - 1)); + u8 assoc_cpus = regs->nbsh & 0xf; + + if (assoc_cpus > 0) + pr_cont(", core: %d", fls(assoc_cpus) - 1); + + pr_cont("\n"); } pr_emerg("%s.\n", EXT_ERR_MSG(xec)); -- cgit v0.10.2 From a90110c61073eab95d1986322693c2b9a8a6a5f6 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 21 Mar 2010 21:51:51 +0100 Subject: x86 / perf: Fix suspend to RAM on HP nx6325 Commit 3f6da3905398826d85731247e7fbcf53400c18bd (perf: Rework and fix the arch CPU-hotplug hooks) broke suspend to RAM on my HP nx6325 (and most likely on other AMD-based boxes too) by allowing amd_pmu_cpu_offline() to be executed for CPUs that are going offline as part of the suspend process. The problem is that cpuhw->amd_nb may be NULL already, so the function should make sure it's not NULL before accessing the object pointed to by it. Signed-off-by: Rafael J. Wysocki Signed-off-by: Linus Torvalds diff --git a/arch/x86/kernel/cpu/perf_event_amd.c b/arch/x86/kernel/cpu/perf_event_amd.c index 573458f..b87e0b6 100644 --- a/arch/x86/kernel/cpu/perf_event_amd.c +++ b/arch/x86/kernel/cpu/perf_event_amd.c @@ -348,10 +348,12 @@ static void amd_pmu_cpu_offline(int cpu) raw_spin_lock(&amd_nb_lock); - if (--cpuhw->amd_nb->refcnt == 0) - kfree(cpuhw->amd_nb); + if (cpuhw->amd_nb) { + if (--cpuhw->amd_nb->refcnt == 0) + kfree(cpuhw->amd_nb); - cpuhw->amd_nb = NULL; + cpuhw->amd_nb = NULL; + } raw_spin_unlock(&amd_nb_lock); } -- cgit v0.10.2 From 45575f5a426c01ec68cd33d998267ba2f6278fac Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Mon, 22 Mar 2010 17:47:59 +1100 Subject: ppc64 sys_ipc breakage in 2.6.34-rc2 I chased down a fail on ppc64 on 2.6.34-rc2 where an application that uses shared memory was getting a SEGV. Commit baed7fc9b580bd3fb8252ff1d9b36eaf1f86b670 ("Add generic sys_ipc wrapper") changed the second argument from an unsigned long to an int. When we call shmget the system call wrappers for sys_ipc will sign extend second (ie the size) which truncates it. It took a while to track down because the call succeeds and strace shows the untruncated size :) The patch below changes second from an int to an unsigned long which fixes shmget on ppc64 (and I assume s390, sparc64 and mips64). Signed-off-by: Anton Blanchard -- I assume the function prototypes for the other IPC methods would cause us to sign or zero extend second where appropriate (avoiding any security issues). Come to think of it, the syscall wrappers for each method should do that for us as well. Signed-off-by: Linus Torvalds diff --git a/ipc/syscall.c b/ipc/syscall.c index 355a3da..1d6f53f 100644 --- a/ipc/syscall.c +++ b/ipc/syscall.c @@ -13,7 +13,7 @@ #include #include -SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, int, second, +SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second, unsigned long, third, void __user *, ptr, long, fifth) { int version, ret; -- cgit v0.10.2 From 99b437a9257cb6b267bf32adfb7675948dc6d485 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 22 Mar 2010 13:07:14 +0000 Subject: AFS: Potential null dereference It seems clear from the surrounding code that xpermits is allowed to be NULL here. Signed-off-by: Dan Carpenter Signed-off-by: David Howells Signed-off-by: Linus Torvalds diff --git a/fs/afs/security.c b/fs/afs/security.c index 3ef5043..bb4ed14 100644 --- a/fs/afs/security.c +++ b/fs/afs/security.c @@ -189,8 +189,9 @@ void afs_cache_permit(struct afs_vnode *vnode, struct key *key, long acl_order) if (!permits) goto out_unlock; - memcpy(permits->permits, xpermits->permits, - count * sizeof(struct afs_permit)); + if (xpermits) + memcpy(permits->permits, xpermits->permits, + count * sizeof(struct afs_permit)); _debug("key %x access %x", key_serial(key), vnode->status.caller_access); -- cgit v0.10.2 From c3824d21eb653fe7017476724257ccaa8bf3d9e1 Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Mon, 22 Mar 2010 13:50:19 +0000 Subject: rxrpc: Check allocation failure. alloc_skb() can return NULL. Signed-off-by: Tetsuo Handa Signed-off-by: David Howells Signed-off-by: Linus Torvalds diff --git a/net/rxrpc/ar-accept.c b/net/rxrpc/ar-accept.c index 77228f2..2d744f2 100644 --- a/net/rxrpc/ar-accept.c +++ b/net/rxrpc/ar-accept.c @@ -88,6 +88,11 @@ static int rxrpc_accept_incoming_call(struct rxrpc_local *local, /* get a notification message to send to the server app */ notification = alloc_skb(0, GFP_NOFS); + if (!notification) { + _debug("no memory"); + ret = -ENOMEM; + goto error_nofree; + } rxrpc_new_skb(notification); notification->mark = RXRPC_SKB_MARK_NEW_CALL; @@ -189,6 +194,7 @@ invalid_service: ret = -ECONNREFUSED; error: rxrpc_free_skb(notification); +error_nofree: _leave(" = %d", ret); return ret; } -- cgit v0.10.2 From 7c3456fdb503071787f7f972de1069b9cacd16f0 Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Mon, 22 Mar 2010 10:22:55 -0700 Subject: rxrpc: Check allocation failure. alloc_skb() can return NULL. Signed-off-by: Tetsuo Handa Signed-off-by: David Howells Signed-off-by: David S. Miller diff --git a/net/rxrpc/ar-accept.c b/net/rxrpc/ar-accept.c index 77228f2..2d744f2 100644 --- a/net/rxrpc/ar-accept.c +++ b/net/rxrpc/ar-accept.c @@ -88,6 +88,11 @@ static int rxrpc_accept_incoming_call(struct rxrpc_local *local, /* get a notification message to send to the server app */ notification = alloc_skb(0, GFP_NOFS); + if (!notification) { + _debug("no memory"); + ret = -ENOMEM; + goto error_nofree; + } rxrpc_new_skb(notification); notification->mark = RXRPC_SKB_MARK_NEW_CALL; @@ -189,6 +194,7 @@ invalid_service: ret = -ECONNREFUSED; error: rxrpc_free_skb(notification); +error_nofree: _leave(" = %d", ret); return ret; } -- cgit v0.10.2 From ef1691504c83ba3eb636c0cfd3ed33f7a6d0b4ee Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 22 Mar 2010 18:25:20 +0100 Subject: netfilter: xt_recent: fix regression in rules using a zero hit_count Commit 8ccb92ad (netfilter: xt_recent: fix false match) fixed supposedly false matches in rules using a zero hit_count. As it turns out there is nothing false about these matches and people are actually using entries with a hit_count of zero to make rules dependant on addresses inserted manually through /proc. Since this slipped past the eyes of three reviewers, instead of reverting the commit in question, this patch explicitly checks for a hit_count of zero to make the intentions more clear. Reported-by: Thomas Jarosch Tested-by: Thomas Jarosch Cc: stable@kernel.org Signed-off-by: Patrick McHardy diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c index 7073dbb..971d172 100644 --- a/net/netfilter/xt_recent.c +++ b/net/netfilter/xt_recent.c @@ -267,7 +267,7 @@ recent_mt(const struct sk_buff *skb, const struct xt_match_param *par) for (i = 0; i < e->nstamps; i++) { if (info->seconds && time_after(time, e->stamps[i])) continue; - if (info->hit_count && ++hits >= info->hit_count) { + if (!info->hit_count || ++hits >= info->hit_count) { ret = !ret; break; } -- cgit v0.10.2 From 3fff6c04d81a2852821135736fad2d8386464753 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 23 Feb 2010 23:38:55 -0800 Subject: Regulators: max8925-regulator - clean up driver data after removal It is a good tone to reset driver data after unbinding the device. Also change find_regulator_info() fro inline to __devinit - let compiler figure out if it wants it to be inlined or not. Signed-off-by: Dmitry Torokhov Acked-by: Mark Brown Signed-off-by: Liam Girdwood diff --git a/drivers/regulator/max8925-regulator.c b/drivers/regulator/max8925-regulator.c index 67873f0..b6218f1 100644 --- a/drivers/regulator/max8925-regulator.c +++ b/drivers/regulator/max8925-regulator.c @@ -230,7 +230,7 @@ static struct max8925_regulator_info max8925_regulator_info[] = { MAX8925_LDO(20, 750, 3900, 50), }; -static inline struct max8925_regulator_info *find_regulator_info(int id) +static struct max8925_regulator_info * __devinit find_regulator_info(int id) { struct max8925_regulator_info *ri; int i; @@ -247,7 +247,7 @@ static int __devinit max8925_regulator_probe(struct platform_device *pdev) { struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent); struct max8925_platform_data *pdata = chip->dev->platform_data; - struct max8925_regulator_info *ri = NULL; + struct max8925_regulator_info *ri; struct regulator_dev *rdev; ri = find_regulator_info(pdev->id); @@ -274,7 +274,9 @@ static int __devexit max8925_regulator_remove(struct platform_device *pdev) { struct regulator_dev *rdev = platform_get_drvdata(pdev); + platform_set_drvdata(pdev, NULL); regulator_unregister(rdev); + return 0; } -- cgit v0.10.2 From 67e46f347eb25222e2b415540b6ba3fd2574afe2 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sun, 7 Mar 2010 15:36:45 +0300 Subject: regulator: handle kcalloc() failure Return -ENOMEM if kcalloc() fails Signed-off-by: Dan Carpenter Acked-by: Mark Brown Acked-by: Wolfram Sang Signed-off-by: Liam Girdwood diff --git a/drivers/regulator/lp3971.c b/drivers/regulator/lp3971.c index f5532ed..55fab4a 100644 --- a/drivers/regulator/lp3971.c +++ b/drivers/regulator/lp3971.c @@ -439,6 +439,10 @@ static int __devinit setup_regulators(struct lp3971 *lp3971, lp3971->num_regulators = pdata->num_regulators; lp3971->rdev = kcalloc(pdata->num_regulators, sizeof(struct regulator_dev *), GFP_KERNEL); + if (!lp3971->rdev) { + err = -ENOMEM; + goto err_nomem; + } /* Instantiate the regulators */ for (i = 0; i < pdata->num_regulators; i++) { @@ -461,6 +465,7 @@ error: regulator_unregister(lp3971->rdev[i]); kfree(lp3971->rdev); lp3971->rdev = NULL; +err_nomem: return err; } -- cgit v0.10.2 From 4f26a2abe1eed18dc6adddf2d0ae5553e51578c2 Mon Sep 17 00:00:00 2001 From: Ameya Palande Date: Fri, 12 Mar 2010 20:09:01 +0200 Subject: regulator: Get rid of lockdep warning WARNING: at kernel/lockdep.c:2706 sysfs_add_file_mode+0x4c/0xa8() Difference between v1 and v2: Moved sysfs_attr_init() call as first one to access the structure. Signed-off-by: Ameya Palande CC: Liam Girdwood CC: Mark Brown CC: David Brownell Acked-by: Mark Brown Signed-off-by: Liam Girdwood diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index c7bbe30..5af16c2 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1038,6 +1038,7 @@ static struct regulator *create_regulator(struct regulator_dev *rdev, goto overflow_err; regulator->dev = dev; + sysfs_attr_init(®ulator->dev_attr.attr); regulator->dev_attr.attr.name = kstrdup(buf, GFP_KERNEL); if (regulator->dev_attr.attr.name == NULL) goto attr_name_err; -- cgit v0.10.2 From cdb868f58103825856e27aa4e1f26943fc119e41 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 9 Mar 2010 16:53:59 +0800 Subject: lp3971: Fix setting val for LDO2 and LDO4 In lp3971_ldo_set_voltage function, it requires val to left shift 4 bits for LDO2 and LDO4. This patch fix this issue. Signed-off-by: Axel Lin Acked-by: Marek Szyprowski Acked-by: Mark Brown Signed-off-by: Liam Girdwood diff --git a/drivers/regulator/lp3971.c b/drivers/regulator/lp3971.c index 55fab4a..8bdcf41 100644 --- a/drivers/regulator/lp3971.c +++ b/drivers/regulator/lp3971.c @@ -187,7 +187,8 @@ static int lp3971_ldo_set_voltage(struct regulator_dev *dev, return -EINVAL; return lp3971_set_bits(lp3971, LP3971_LDO_VOL_CONTR_REG(ldo), - LDO_VOL_CONTR_MASK << LDO_VOL_CONTR_SHIFT(ldo), val); + LDO_VOL_CONTR_MASK << LDO_VOL_CONTR_SHIFT(ldo), + val << LDO_VOL_CONTR_SHIFT(ldo)); } static struct regulator_ops lp3971_ldo_ops = { -- cgit v0.10.2 From 451a73cd46573444f68f412c87439c0a291718ec Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 11 Mar 2010 09:50:07 +0800 Subject: lp3971: Fix BUCK_VOL_CHANGE_SHIFT logic Given x=0,1,2, current implementation of BUCK_VOL_CHANGE_SHIFT(x) returns 0,4,8. The correct return value should be 0,4,6. This patch fix the logic. Signed-off-by: Axel Lin Acked-by: Marek Szyprowski Acked-by: Mark Brown Signed-off-by: Liam Girdwood diff --git a/drivers/regulator/lp3971.c b/drivers/regulator/lp3971.c index 8bdcf41..b20b3e1 100644 --- a/drivers/regulator/lp3971.c +++ b/drivers/regulator/lp3971.c @@ -45,7 +45,7 @@ static int lp3971_set_bits(struct lp3971 *lp3971, u8 reg, u16 mask, u16 val); LP3971_BUCK2 -> 4 LP3971_BUCK3 -> 6 */ -#define BUCK_VOL_CHANGE_SHIFT(x) (((1 << x) & ~0x01) << 1) +#define BUCK_VOL_CHANGE_SHIFT(x) (((!!x) << 2) | (x & ~0x01)) #define BUCK_VOL_CHANGE_FLAG_GO 0x01 #define BUCK_VOL_CHANGE_FLAG_TARGET 0x02 #define BUCK_VOL_CHANGE_FLAG_MASK 0x03 -- cgit v0.10.2 From 8b4709ecea4aab1957ae7b726d6824485404a3a5 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Sat, 20 Mar 2010 15:12:58 +0100 Subject: regulator: fix dangling pointers Fix I2C-drivers which missed setting clientdata to NULL before freeing the structure it points to. Also fix drivers which do this _after_ the structure was freed already. Signed-off-by: Wolfram Sang Cc: Liam Girdwood Cc: Mark Brown Acked-by: Mark Brown Signed-off-by: Liam Girdwood diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c index a49fc95..c0b09e1 100644 --- a/drivers/regulator/max1586.c +++ b/drivers/regulator/max1586.c @@ -243,8 +243,8 @@ static int __devexit max1586_pmic_remove(struct i2c_client *client) for (i = 0; i <= MAX1586_V6; i++) if (rdev[i]) regulator_unregister(rdev[i]); - kfree(rdev); i2c_set_clientdata(client, NULL); + kfree(rdev); return 0; } diff --git a/drivers/regulator/max8649.c b/drivers/regulator/max8649.c index 3ebdf69..833aaed 100644 --- a/drivers/regulator/max8649.c +++ b/drivers/regulator/max8649.c @@ -356,6 +356,7 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client, dev_info(info->dev, "Max8649 regulator device is detected.\n"); return 0; out: + i2c_set_clientdata(client, NULL); kfree(info); return ret; } @@ -367,9 +368,9 @@ static int __devexit max8649_regulator_remove(struct i2c_client *client) if (info) { if (info->regulator) regulator_unregister(info->regulator); + i2c_set_clientdata(client, NULL); kfree(info); } - i2c_set_clientdata(client, NULL); return 0; } diff --git a/drivers/regulator/max8660.c b/drivers/regulator/max8660.c index f12f1bb..47f90b2 100644 --- a/drivers/regulator/max8660.c +++ b/drivers/regulator/max8660.c @@ -470,8 +470,8 @@ static int __devexit max8660_remove(struct i2c_client *client) for (i = 0; i < MAX8660_V_END; i++) if (rdev[i]) regulator_unregister(rdev[i]); - kfree(rdev); i2c_set_clientdata(client, NULL); + kfree(rdev); return 0; } -- cgit v0.10.2 From ae6be51ed01d6c4aaf249a207b4434bc7785853b Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 22 Mar 2010 13:12:33 -0700 Subject: Fix up prototype for sys_ipc breakage Commit 45575f5a426c ("ppc64 sys_ipc breakage in 2.6.34-rc2") fixed the definition of the sys_ipc() helper, but didn't fix the prototype in Reported-and-tested-by: Andreas Schwab Signed-off-by: Linus Torvalds diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index f994ae5..057929b 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -688,7 +688,7 @@ asmlinkage long sys_shmat(int shmid, char __user *shmaddr, int shmflg); asmlinkage long sys_shmget(key_t key, size_t size, int flag); asmlinkage long sys_shmdt(char __user *shmaddr); asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf); -asmlinkage long sys_ipc(unsigned int call, int first, int second, +asmlinkage long sys_ipc(unsigned int call, int first, unsigned long second, unsigned long third, void __user *ptr, long fifth); asmlinkage long sys_mq_open(const char __user *name, int oflag, mode_t mode, struct mq_attr __user *attr); -- cgit v0.10.2 From 4f1deba435ef75380c1d06fda860c7a15ea16fdf Mon Sep 17 00:00:00 2001 From: "JosephChan@via.com.tw" Date: Fri, 19 Mar 2010 14:08:11 +0800 Subject: pata_via: Add VIA VX900 support Signed-off-by: Joseph Chan Signed-off-by: Jeff Garzik diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index 3059ec0..95d39c3 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c @@ -677,6 +677,7 @@ static const struct pci_device_id via[] = { { PCI_VDEVICE(VIA, 0x3164), }, { PCI_VDEVICE(VIA, 0x5324), }, { PCI_VDEVICE(VIA, 0xC409), VIA_IDFLAG_SINGLE }, + { PCI_VDEVICE(VIA, 0x9001), VIA_IDFLAG_SINGLE }, { }, }; -- cgit v0.10.2 From 21afc27c9f9ae1f6370c47b323be7f3b75106569 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sun, 21 Mar 2010 21:06:01 +0000 Subject: can: bfin_can: switch to common Blackfin can header The MMR bits are being moved to this header, so include it. Signed-off-by: Mike Frysinger Acked-by: Wolfgang Grandegger Signed-off-by: David S. Miller diff --git a/drivers/net/can/bfin_can.c b/drivers/net/can/bfin_can.c index 866905f..0348986 100644 --- a/drivers/net/can/bfin_can.c +++ b/drivers/net/can/bfin_can.c @@ -22,6 +22,7 @@ #include #include +#include #include #define DRV_NAME "bfin_can" @@ -29,90 +30,6 @@ #define TX_ECHO_SKB_MAX 1 /* - * transmit and receive channels - */ -#define TRANSMIT_CHL 24 -#define RECEIVE_STD_CHL 0 -#define RECEIVE_EXT_CHL 4 -#define RECEIVE_RTR_CHL 8 -#define RECEIVE_EXT_RTR_CHL 12 -#define MAX_CHL_NUMBER 32 - -/* - * bfin can registers layout - */ -struct bfin_can_mask_regs { - u16 aml; - u16 dummy1; - u16 amh; - u16 dummy2; -}; - -struct bfin_can_channel_regs { - u16 data[8]; - u16 dlc; - u16 dummy1; - u16 tsv; - u16 dummy2; - u16 id0; - u16 dummy3; - u16 id1; - u16 dummy4; -}; - -struct bfin_can_regs { - /* - * global control and status registers - */ - u16 mc1; /* offset 0 */ - u16 dummy1; - u16 md1; /* offset 4 */ - u16 rsv1[13]; - u16 mbtif1; /* offset 0x20 */ - u16 dummy2; - u16 mbrif1; /* offset 0x24 */ - u16 dummy3; - u16 mbim1; /* offset 0x28 */ - u16 rsv2[11]; - u16 mc2; /* offset 0x40 */ - u16 dummy4; - u16 md2; /* offset 0x44 */ - u16 dummy5; - u16 trs2; /* offset 0x48 */ - u16 rsv3[11]; - u16 mbtif2; /* offset 0x60 */ - u16 dummy6; - u16 mbrif2; /* offset 0x64 */ - u16 dummy7; - u16 mbim2; /* offset 0x68 */ - u16 rsv4[11]; - u16 clk; /* offset 0x80 */ - u16 dummy8; - u16 timing; /* offset 0x84 */ - u16 rsv5[3]; - u16 status; /* offset 0x8c */ - u16 dummy9; - u16 cec; /* offset 0x90 */ - u16 dummy10; - u16 gis; /* offset 0x94 */ - u16 dummy11; - u16 gim; /* offset 0x98 */ - u16 rsv6[3]; - u16 ctrl; /* offset 0xa0 */ - u16 dummy12; - u16 intr; /* offset 0xa4 */ - u16 rsv7[7]; - u16 esr; /* offset 0xb4 */ - u16 rsv8[37]; - - /* - * channel(mailbox) mask and message registers - */ - struct bfin_can_mask_regs msk[MAX_CHL_NUMBER]; /* offset 0x100 */ - struct bfin_can_channel_regs chl[MAX_CHL_NUMBER]; /* offset 0x200 */ -}; - -/* * bfin can private data */ struct bfin_can_priv { @@ -163,7 +80,7 @@ static int bfin_can_set_bittiming(struct net_device *dev) if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) timing |= SAM; - bfin_write16(®->clk, clk); + bfin_write16(®->clock, clk); bfin_write16(®->timing, timing); dev_info(dev->dev.parent, "setting CLOCK=0x%04x TIMING=0x%04x\n", @@ -185,11 +102,11 @@ static void bfin_can_set_reset_mode(struct net_device *dev) bfin_write16(®->gim, 0); /* reset can and enter configuration mode */ - bfin_write16(®->ctrl, SRS | CCR); + bfin_write16(®->control, SRS | CCR); SSYNC(); - bfin_write16(®->ctrl, CCR); + bfin_write16(®->control, CCR); SSYNC(); - while (!(bfin_read16(®->ctrl) & CCA)) { + while (!(bfin_read16(®->control) & CCA)) { udelay(10); if (--timeout == 0) { dev_err(dev->dev.parent, @@ -244,7 +161,7 @@ static void bfin_can_set_normal_mode(struct net_device *dev) /* * leave configuration mode */ - bfin_write16(®->ctrl, bfin_read16(®->ctrl) & ~CCR); + bfin_write16(®->control, bfin_read16(®->control) & ~CCR); while (bfin_read16(®->status) & CCA) { udelay(10); @@ -726,7 +643,7 @@ static int bfin_can_suspend(struct platform_device *pdev, pm_message_t mesg) if (netif_running(dev)) { /* enter sleep mode */ - bfin_write16(®->ctrl, bfin_read16(®->ctrl) | SMR); + bfin_write16(®->control, bfin_read16(®->control) | SMR); SSYNC(); while (!(bfin_read16(®->intr) & SMACK)) { udelay(10); -- cgit v0.10.2 From 5fc05f8764f301138003ff562a31ad3721f1675f Mon Sep 17 00:00:00 2001 From: Amerigo Wang Date: Sun, 21 Mar 2010 22:59:58 +0000 Subject: netpoll: warn when there are spaces in parameters v2: update according to Frans' comments. Currently, if we leave spaces before dst port, netconsole will silently accept it as 0. Warn about this. Also, when spaces appear in other places, make them visible in error messages. Signed-off-by: WANG Cong Cc: David Miller Acked-by: Neil Horman Signed-off-by: David S. Miller diff --git a/net/core/netpoll.c b/net/core/netpoll.c index d4ec38f..6f9206b 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -614,7 +614,7 @@ void netpoll_print_options(struct netpoll *np) np->name, np->local_port); printk(KERN_INFO "%s: local IP %pI4\n", np->name, &np->local_ip); - printk(KERN_INFO "%s: interface %s\n", + printk(KERN_INFO "%s: interface '%s'\n", np->name, np->dev_name); printk(KERN_INFO "%s: remote port %d\n", np->name, np->remote_port); @@ -661,6 +661,9 @@ int netpoll_parse_options(struct netpoll *np, char *opt) if ((delim = strchr(cur, '@')) == NULL) goto parse_failed; *delim = 0; + if (*cur == ' ' || *cur == '\t') + printk(KERN_INFO "%s: warning: whitespace" + "is not allowed\n", np->name); np->remote_port = simple_strtol(cur, NULL, 10); cur = delim; } @@ -708,7 +711,7 @@ int netpoll_parse_options(struct netpoll *np, char *opt) return 0; parse_failed: - printk(KERN_INFO "%s: couldn't parse config at %s!\n", + printk(KERN_INFO "%s: couldn't parse config at '%s'!\n", np->name, cur); return -1; } -- cgit v0.10.2 From 688328c7ec3cd0dc3b16342aeb045d28012cc955 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Wed, 17 Mar 2010 22:24:39 +0000 Subject: netxen: The driver doesn't work on NX_P3_B1 so cause probe to fail. I haven't been able to get link up on a NX_P3_B1 since 2.6.31. The driver complains about a firmware hang instead. When I asked I was told rev 0x41 was a preproduction rev. So disable support in the driver so no one is surprised the code doesn't work. Signed-off-by: Eric W. Biederman Signed-off-by: David S. Miller diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 08780ef..9a7a0f3 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -1246,8 +1246,8 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) int pci_func_id = PCI_FUNC(pdev->devfn); uint8_t revision_id; - if (pdev->revision >= NX_P3_A0 && pdev->revision < NX_P3_B1) { - pr_warning("%s: chip revisions between 0x%x-0x%x" + if (pdev->revision >= NX_P3_A0 && pdev->revision <= NX_P3_B1) { + pr_warning("%s: chip revisions between 0x%x-0x%x " "will not be enabled.\n", module_name(THIS_MODULE), NX_P3_A0, NX_P3_B1); return -ENODEV; -- cgit v0.10.2 From 1ee4d61fd9822fb89e63b88a66848477087cd82e Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 22 Mar 2010 15:46:49 +0800 Subject: ACPI dock: support multiple ACPI dock devices There may be multiple ACPI dock devices exist in ACPI namespace and we should probe all of them. http://bugzilla.kernel.org/show_bug.cgi?id=15521 CC: Li Shaohua Signed-off-by: Zhang Rui Signed-off-by: Len Brown diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index d9a85f1..9d67bc6 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -1025,13 +1025,10 @@ static int dock_remove(struct dock_station *ds) static acpi_status find_dock(acpi_handle handle, u32 lvl, void *context, void **rv) { - acpi_status status = AE_OK; - if (is_dock(handle)) - if (dock_add(handle) >= 0) - status = AE_CTRL_TERMINATE; + dock_add(handle); - return status; + return AE_OK; } static acpi_status -- cgit v0.10.2 From bc73675b99fd9850dd914be01d71af99c5d2a1ae Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 22 Mar 2010 15:48:54 +0800 Subject: ACPI: fixes a false alarm from lockdep fixes a false alarm from lockdep, as acpi hotplug workqueue waits other workqueues. http://bugzilla.kernel.org/show_bug.cgi?id=14553 https://bugzilla.kernel.org/show_bug.cgi?id=15521 Original-patch-from: Andrew Morton Signed-off-by: Shaohua Li Signed-off-by: Zhang Rui Signed-off-by: Len Brown diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 8e6d866..900da68 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -758,7 +758,14 @@ static acpi_status __acpi_os_execute(acpi_execute_type type, queue = hp ? kacpi_hotplug_wq : (type == OSL_NOTIFY_HANDLER ? kacpi_notify_wq : kacpid_wq); dpc->wait = hp ? 1 : 0; - INIT_WORK(&dpc->work, acpi_os_execute_deferred); + + if (queue == kacpi_hotplug_wq) + INIT_WORK(&dpc->work, acpi_os_execute_deferred); + else if (queue == kacpi_notify_wq) + INIT_WORK(&dpc->work, acpi_os_execute_deferred); + else + INIT_WORK(&dpc->work, acpi_os_execute_deferred); + ret = queue_work(queue, &dpc->work); if (!ret) { -- cgit v0.10.2 From b230eb32c8d568284c1f33f5d06005eb97d4f897 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 16 Mar 2010 02:01:33 +0000 Subject: sh: mach-ecovec24: Add i2c_put_adapter on sh_eth_init i2c_put_adapter is needed after i2c_get_adapter Signed-off-by: Kuninori Morimoto Signed-off-by: Paul Mundt diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index 39ed872..6c13b92 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c @@ -836,6 +836,8 @@ static void __init sh_eth_init(struct sh_eth_plat_data *pd) pd->mac_addr[i] = mac_read(a, 0x10 + i); msleep(10); } + + i2c_put_adapter(a); } #else static void __init sh_eth_init(struct sh_eth_plat_data *pd) -- cgit v0.10.2 From bec9fb072f58a77a449c4bb3b1b036fcecc68663 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 16 Mar 2010 02:01:53 +0000 Subject: sh: ms7724: Add tiny-document for sound Signed-off-by: Kuninori Morimoto Signed-off-by: Paul Mundt diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c index 66cdbc3..ccaa290 100644 --- a/arch/sh/boards/mach-se/7724/setup.c +++ b/arch/sh/boards/mach-se/7724/setup.c @@ -52,6 +52,13 @@ * and change SW41 to use 720p */ +/* + * about sound + * + * This setup.c supports FSI slave mode. + * Please change J20, J21, J22 pin to 1-2 connection. + */ + /* Heartbeat */ static struct resource heartbeat_resource = { .start = PA_LED, @@ -276,6 +283,7 @@ static struct clk fsimcka_clk = { .rate = 0, /* unknown */ }; +/* change J20, J21, J22 pin to 1-2 connection to use slave mode */ struct sh_fsi_platform_info fsi_info = { .porta_flags = SH_FSI_BRS_INV | SH_FSI_OUT_SLAVE_MODE | -- cgit v0.10.2 From 67eaa3e4fb29a758f92c9296ca006264a034e9c2 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 16 Mar 2010 02:02:08 +0000 Subject: sh: Add watch-dog register address for SH7722/SH7723/SH7724 Signed-off-by: Kuninori Morimoto Signed-off-by: Paul Mundt diff --git a/arch/sh/include/cpu-sh4/cpu/watchdog.h b/arch/sh/include/cpu-sh4/cpu/watchdog.h index 7672301..7f62b93 100644 --- a/arch/sh/include/cpu-sh4/cpu/watchdog.h +++ b/arch/sh/include/cpu-sh4/cpu/watchdog.h @@ -21,6 +21,12 @@ #define WTCNT 0xffcc0000 /*WDTST*/ #define WTST WTCNT #define WTBST 0xffcc0008 /*WDTBST*/ +/* Register definitions */ +#elif defined(CONFIG_CPU_SUBTYPE_SH7722) || \ + defined(CONFIG_CPU_SUBTYPE_SH7723) || \ + defined(CONFIG_CPU_SUBTYPE_SH7724) +#define WTCNT 0xa4520000 +#define WTCSR 0xa4520004 #else /* Register definitions */ #define WTCNT 0xffc00008 -- cgit v0.10.2 From bf02bd2590eb78d79ba1033d6df80c778b2f5ddf Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 16 Mar 2010 23:21:55 +0100 Subject: ACPI / ACPICA: Do not check reference counters in acpi_ev_enable_gpe() acpi_ev_enable_gpe() should enable the GPE at the hardware level regardless of the value of the GPE's runtime reference counter. There are only two callers of acpi_ev_enable_gpe(), acpi_enable_gpe() and acpi_set_gpe(). The first one checks the GPE's runtime reference counter itself and only calls acpi_ev_enable_gpe() if it's equal to one, and the other one is supposed to enable the GPE unconditionally (if called with ACPI_GPE_ENABLE). This change fixes the problem in acpi_enable_wakeup_device() where the GPE will not be enabled for wakeup if it's runtime reference counter is zero, which is a regression from 2.6.33. Signed-off-by: Rafael J. Wysocki Reported-by: Robert Moore Signed-off-by: Len Brown diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index 837de66..78c5550 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c @@ -117,19 +117,14 @@ acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) if (ACPI_FAILURE(status)) return_ACPI_STATUS(status); - /* Mark wake-enabled or HW enable, or both */ - - if (gpe_event_info->runtime_count) { - /* Clear the GPE (of stale events), then enable it */ - status = acpi_hw_clear_gpe(gpe_event_info); - if (ACPI_FAILURE(status)) - return_ACPI_STATUS(status); - - /* Enable the requested runtime GPE */ - status = acpi_hw_write_gpe_enable_reg(gpe_event_info); - } + /* Clear the GPE (of stale events), then enable it */ + status = acpi_hw_clear_gpe(gpe_event_info); + if (ACPI_FAILURE(status)) + return_ACPI_STATUS(status); - return_ACPI_STATUS(AE_OK); + /* Enable the requested GPE */ + status = acpi_hw_write_gpe_enable_reg(gpe_event_info); + return_ACPI_STATUS(status); } /******************************************************************************* -- cgit v0.10.2 From 8d099d4446fcb23ca6cc054bde3c35b417e29b3b Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 16 Mar 2010 11:21:07 +0000 Subject: serial: sh-sci: fix SH-Mobile SH breakage The follwing commit breaks SH-Mobile on non-ARM platforms: "8a77b8d serial: sh-sci: Support ARM-based SH-Mobile CPUs." The commit assumed that CONFIG_ARCH_SHMOBILE only was set on ARM platforms, but it turns out that this kconfig is also set by all SH-based SoCs. Sh7724 and other older SH-Mobile SoCs are all broken without this fix. This patch converts the "defined(CONFIG_ARCH_SHMOBILE)" into one "defined()" per SoC model - similar to existing SH code. Reported-by: Guennadi Liakhovetski Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h index fad67d3..be6e1d2 100644 --- a/drivers/serial/sh-sci.h +++ b/drivers/serial/sh-sci.h @@ -31,7 +31,9 @@ # define SCSCR_INIT(port) (port->mapbase == SCIF2) ? 0xF3 : 0xF0 #elif defined(CONFIG_CPU_SUBTYPE_SH7720) || \ defined(CONFIG_CPU_SUBTYPE_SH7721) || \ - defined(CONFIG_ARCH_SHMOBILE) + defined(CONFIG_ARCH_SH7367) || \ + defined(CONFIG_ARCH_SH7377) || \ + defined(CONFIG_ARCH_SH7372) # define SCSCR_INIT(port) 0x0030 /* TIE=0,RIE=0,TE=1,RE=1 */ # define PORT_PTCR 0xA405011EUL # define PORT_PVCR 0xA4050122UL @@ -230,7 +232,9 @@ #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ defined(CONFIG_CPU_SUBTYPE_SH7720) || \ defined(CONFIG_CPU_SUBTYPE_SH7721) || \ - defined(CONFIG_ARCH_SHMOBILE) + defined(CONFIG_ARCH_SH7367) || \ + defined(CONFIG_ARCH_SH7377) || \ + defined(CONFIG_ARCH_SH7372) # define SCIF_ORER 0x0200 # define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK | SCIF_ORER) # define SCIF_RFDC_MASK 0x007f @@ -264,7 +268,9 @@ #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ defined(CONFIG_CPU_SUBTYPE_SH7720) || \ defined(CONFIG_CPU_SUBTYPE_SH7721) || \ - defined(CONFIG_ARCH_SHMOBILE) + defined(CONFIG_ARCH_SH7367) || \ + defined(CONFIG_ARCH_SH7377) || \ + defined(CONFIG_ARCH_SH7372) # define SCxSR_RDxF_CLEAR(port) (sci_in(port, SCxSR) & 0xfffc) # define SCxSR_ERROR_CLEAR(port) (sci_in(port, SCxSR) & 0xfd73) # define SCxSR_TDxE_CLEAR(port) (sci_in(port, SCxSR) & 0xffdf) @@ -359,7 +365,10 @@ SCI_OUT(sci_size, sci_offset, value); \ } -#if defined(CONFIG_CPU_SH3) || defined(CONFIG_ARCH_SHMOBILE) +#if defined(CONFIG_CPU_SH3) || \ + defined(CONFIG_ARCH_SH7367) || \ + defined(CONFIG_ARCH_SH7377) || \ + defined(CONFIG_ARCH_SH7372) #if defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) #define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \ sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size, \ @@ -370,7 +379,9 @@ #elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \ defined(CONFIG_CPU_SUBTYPE_SH7720) || \ defined(CONFIG_CPU_SUBTYPE_SH7721) || \ - defined(CONFIG_ARCH_SHMOBILE) + defined(CONFIG_ARCH_SH7367) || \ + defined(CONFIG_ARCH_SH7377) || \ + defined(CONFIG_ARCH_SH7372) #define SCIF_FNS(name, scif_offset, scif_size) \ CPU_SCIF_FNS(name, scif_offset, scif_size) #else @@ -406,7 +417,9 @@ #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ defined(CONFIG_CPU_SUBTYPE_SH7720) || \ defined(CONFIG_CPU_SUBTYPE_SH7721) || \ - defined(CONFIG_ARCH_SHMOBILE) + defined(CONFIG_ARCH_SH7367) || \ + defined(CONFIG_ARCH_SH7377) || \ + defined(CONFIG_ARCH_SH7372) SCIF_FNS(SCSMR, 0x00, 16) SCIF_FNS(SCBRR, 0x04, 8) @@ -589,7 +602,9 @@ static inline int sci_rxd_in(struct uart_port *port) #elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \ defined(CONFIG_CPU_SUBTYPE_SH7720) || \ defined(CONFIG_CPU_SUBTYPE_SH7721) || \ - defined(CONFIG_ARCH_SHMOBILE) + defined(CONFIG_ARCH_SH7367) || \ + defined(CONFIG_ARCH_SH7377) || \ + defined(CONFIG_ARCH_SH7372) #define SCBRR_VALUE(bps, clk) (((clk*2)+16*bps)/(32*bps)-1) #elif defined(CONFIG_CPU_SUBTYPE_SH7723) ||\ defined(CONFIG_CPU_SUBTYPE_SH7724) -- cgit v0.10.2 From d7bbf7f50e03c427debb6d7d960c48b9b934e7e2 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 19 Mar 2010 13:52:35 +0000 Subject: SH: fix SCIFA SCASCR register bit definitions Signed-off-by: Guennadi Liakhovetski Signed-off-by: Paul Mundt diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h index be6e1d2..f70c49f 100644 --- a/drivers/serial/sh-sci.h +++ b/drivers/serial/sh-sci.h @@ -96,7 +96,9 @@ # define SCSCR_INIT(port) 0x0038 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ #elif defined(CONFIG_CPU_SUBTYPE_SH7724) # define SCIF_ORER 0x0001 /* overrun error bit */ -# define SCSCR_INIT(port) 0x0038 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ +# define SCSCR_INIT(port) ((port)->type == PORT_SCIFA ? \ + 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */ : \ + 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ ) #elif defined(CONFIG_CPU_SUBTYPE_SH4_202) # define SCSPTR2 0xffe80020 /* 16 bit SCIF */ # define SCIF_ORER 0x0001 /* overrun error bit */ @@ -199,6 +201,8 @@ defined(CONFIG_CPU_SUBTYPE_SH7786) || \ defined(CONFIG_CPU_SUBTYPE_SHX3) #define SCI_CTRL_FLAGS_REIE 0x08 /* 7750 SCIF */ +#elif defined(CONFIG_CPU_SUBTYPE_SH7724) +#define SCI_CTRL_FLAGS_REIE ((port)->type == PORT_SCIFA ? 0 : 8) #else #define SCI_CTRL_FLAGS_REIE 0 #endif -- cgit v0.10.2 From 0a60a210ede8942c5149526bf6847176cee5c184 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 19 Mar 2010 13:53:36 +0000 Subject: SH: remove superfluous warning from the serial driver This warning has been introduced during the SCI DMA support developmenr and is not needed any more. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Paul Mundt diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index f7b9aff..309de6b 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -779,10 +779,6 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) if ((ssr_status & SCxSR_BRK(port)) && err_enabled) ret = sci_br_interrupt(irq, ptr); - WARN_ONCE(ret == IRQ_NONE, - "%s: %d IRQ %d, status %x, control %x\n", __func__, - irq, port->line, ssr_status, scr_status); - return ret; } -- cgit v0.10.2 From 685abecfc2a6036b713229617570980c566c7500 Mon Sep 17 00:00:00 2001 From: Andreas Bombe Date: Sat, 20 Mar 2010 00:38:01 +0000 Subject: sh64: Remove long unused mid_sched macro interruptible_sleep_on() is referenced for use in the mid_sched macro which is not used anywhere. Remove reference and macro as well as the comment which appears to belong with them. Signed-off-by: Andreas Bombe Signed-off-by: Paul Mundt diff --git a/arch/sh/kernel/process_64.c b/arch/sh/kernel/process_64.c index c90957a..c0d40f6 100644 --- a/arch/sh/kernel/process_64.c +++ b/arch/sh/kernel/process_64.c @@ -504,13 +504,6 @@ out: return error; } -/* - * These bracket the sleeping functions.. - */ -extern void interruptible_sleep_on(wait_queue_head_t *q); - -#define mid_sched ((unsigned long) interruptible_sleep_on) - #ifdef CONFIG_FRAME_POINTER static int in_sh64_switch_to(unsigned long pc) { -- cgit v0.10.2 From a9eb4f6d1a168c830a206306dfbb1f95a7fed6b3 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Sun, 21 Mar 2010 19:51:43 +0000 Subject: sh: Flush ITLB too in PTEAEX's flush_tlb_page() flush_tlb_page() can be used to flush TLB entries that map executable pages. Therefore, we need to ensure that the ITLB is also flushed in local_flush_tlb_page(). Signed-off-by: Matt Fleming Signed-off-by: Paul Mundt diff --git a/arch/sh/include/cpu-sh4/cpu/mmu_context.h b/arch/sh/include/cpu-sh4/cpu/mmu_context.h index 03ea75c..310ec92 100644 --- a/arch/sh/include/cpu-sh4/cpu/mmu_context.h +++ b/arch/sh/include/cpu-sh4/cpu/mmu_context.h @@ -19,6 +19,8 @@ #define MMUCR 0xFF000010 /* MMU Control Register */ +#define MMU_ITLB_ADDRESS_ARRAY 0xF2000000 +#define MMU_ITLB_ADDRESS_ARRAY2 0xF2800000 #define MMU_UTLB_ADDRESS_ARRAY 0xF6000000 #define MMU_UTLB_ADDRESS_ARRAY2 0xF6800000 #define MMU_PAGE_ASSOC_BIT 0x80 diff --git a/arch/sh/mm/tlb-pteaex.c b/arch/sh/mm/tlb-pteaex.c index 32dc674..bdd0982 100644 --- a/arch/sh/mm/tlb-pteaex.c +++ b/arch/sh/mm/tlb-pteaex.c @@ -73,5 +73,7 @@ void local_flush_tlb_one(unsigned long asid, unsigned long page) jump_to_uncached(); __raw_writel(page, MMU_UTLB_ADDRESS_ARRAY | MMU_PAGE_ASSOC_BIT); __raw_writel(asid, MMU_UTLB_ADDRESS_ARRAY2 | MMU_PAGE_ASSOC_BIT); + __raw_writel(page, MMU_ITLB_ADDRESS_ARRAY | MMU_PAGE_ASSOC_BIT); + __raw_writel(asid, MMU_ITLB_ADDRESS_ARRAY2 | MMU_PAGE_ASSOC_BIT); back_to_cached(); } -- cgit v0.10.2 From b5b6c7eea1124de5b110a48ac62650a690ed2419 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Sun, 21 Mar 2010 19:51:52 +0000 Subject: sh: Replace unsafe manipulation of MMUCR Setting the TI in MMUCR causes all the TLB bits in MMUCR to be cleared. Unfortunately, the TLB wired bits are also cleared when setting the TI bit, causing any wired TLB entries to become unwired. Use local_flush_tlb_all() which implements TLB flushing in a safer manner by using the memory-mapped TLB registers. As each CPU has its own PMB the modifications in pmb_init() only affect the local CPU, so only flush the local CPU's TLB. Signed-off-by: Matt Fleming Signed-off-by: Paul Mundt diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c index a4662e2..0b14dcf 100644 --- a/arch/sh/mm/pmb.c +++ b/arch/sh/mm/pmb.c @@ -802,7 +802,7 @@ void __init pmb_init(void) writel_uncached(0, PMB_IRMCR); /* Flush out the TLB */ - __raw_writel(__raw_readl(MMUCR) | MMUCR_TI, MMUCR); + local_flush_tlb_all(); ctrl_barrier(); } diff --git a/arch/sh/mm/tlbflush_32.c b/arch/sh/mm/tlbflush_32.c index 004bb3f..77dc5ef 100644 --- a/arch/sh/mm/tlbflush_32.c +++ b/arch/sh/mm/tlbflush_32.c @@ -123,18 +123,27 @@ void local_flush_tlb_mm(struct mm_struct *mm) void local_flush_tlb_all(void) { unsigned long flags, status; + int i; /* * Flush all the TLB. - * - * Write to the MMU control register's bit: - * TF-bit for SH-3, TI-bit for SH-4. - * It's same position, bit #2. */ local_irq_save(flags); + jump_to_uncached(); + status = __raw_readl(MMUCR); - status |= 0x04; - __raw_writel(status, MMUCR); + status = ((status & MMUCR_URB) >> MMUCR_URB_SHIFT); + + if (status == 0) + status = MMUCR_URB_NENTRIES; + + for (i = 0; i < status; i++) + __raw_writel(0x0, MMU_UTLB_ADDRESS_ARRAY | (i << 8)); + + for (i = 0; i < 4; i++) + __raw_writel(0x0, MMU_ITLB_ADDRESS_ARRAY | (i << 8)); + + back_to_cached(); ctrl_barrier(); local_irq_restore(flags); } -- cgit v0.10.2 From 3fe0f36c7edcd20af0a3cafc68bdd62534c0a7f0 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Mon, 22 Mar 2010 22:09:58 +0000 Subject: sh: Fix build after dynamic PMB rework set_pmb_entry() is now only used by a function that is wrapped in #ifdef CONFIG_PM, so wrap set_pmb_entry() in CONFIG_PM too. Signed-off-by: Matt Fleming Signed-off-by: Paul Mundt diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c index 0b14dcf..3cc2193 100644 --- a/arch/sh/mm/pmb.c +++ b/arch/sh/mm/pmb.c @@ -323,6 +323,7 @@ static void __clear_pmb_entry(struct pmb_entry *pmbe) writel_uncached(data_val & ~PMB_V, data); } +#ifdef CONFIG_PM static void set_pmb_entry(struct pmb_entry *pmbe) { unsigned long flags; @@ -331,6 +332,7 @@ static void set_pmb_entry(struct pmb_entry *pmbe) __set_pmb_entry(pmbe); spin_unlock_irqrestore(&pmbe->lock, flags); } +#endif /* CONFIG_PM */ int pmb_bolt_mapping(unsigned long vaddr, phys_addr_t phys, unsigned long size, pgprot_t prot) -- cgit v0.10.2 From 90851c40769791a6ddeef691c482ecf69bae4a5c Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 23 Mar 2010 17:06:47 +0900 Subject: sh: Tidy up a couple of section mismatches. select_idle_routine() and register_sh_pmu() both needed their annotations fixed up to silence section mismatch warnings. Signed-off-by: Paul Mundt diff --git a/arch/sh/kernel/idle.c b/arch/sh/kernel/idle.c index 0fd7b41..273f890 100644 --- a/arch/sh/kernel/idle.c +++ b/arch/sh/kernel/idle.c @@ -112,7 +112,7 @@ void cpu_idle(void) } } -void __cpuinit select_idle_routine(void) +void __init select_idle_routine(void) { /* * If a platform has set its own idle routine, leave it alone. diff --git a/arch/sh/kernel/perf_event.c b/arch/sh/kernel/perf_event.c index 9f253e9..81b6de4 100644 --- a/arch/sh/kernel/perf_event.c +++ b/arch/sh/kernel/perf_event.c @@ -315,7 +315,7 @@ void hw_perf_disable(void) sh_pmu->disable_all(); } -int register_sh_pmu(struct sh_pmu *pmu) +int __cpuinit register_sh_pmu(struct sh_pmu *pmu) { if (sh_pmu) return -EBUSY; -- cgit v0.10.2 From 4e1a2594094020bdb41c18681c1765671138d06a Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 23 Mar 2010 17:07:41 +0900 Subject: sh: Silence unintialized variable warnings in dwarf unwinder. The parent rb_node needs to be initialized to shut up the compiler, even though we're unlikely to ever hit this issue at run time. Signed-off-by: Paul Mundt diff --git a/arch/sh/kernel/dwarf.c b/arch/sh/kernel/dwarf.c index bd1c497..94739ee 100644 --- a/arch/sh/kernel/dwarf.c +++ b/arch/sh/kernel/dwarf.c @@ -727,7 +727,7 @@ static int dwarf_parse_cie(void *entry, void *p, unsigned long len, unsigned char *end, struct module *mod) { struct rb_node **rb_node = &cie_root.rb_node; - struct rb_node *parent; + struct rb_node *parent = *rb_node; struct dwarf_cie *cie; unsigned long flags; int count; @@ -856,7 +856,7 @@ static int dwarf_parse_fde(void *entry, u32 entry_type, unsigned char *end, struct module *mod) { struct rb_node **rb_node = &fde_root.rb_node; - struct rb_node *parent; + struct rb_node *parent = *rb_node; struct dwarf_fde *fde; struct dwarf_cie *cie; unsigned long flags; -- cgit v0.10.2 From 332ac7ff77cdc6a183d78ab129545d7b14a1d57c Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 23 Mar 2010 12:24:08 +0900 Subject: libata-sff: fix spurious IRQ handling Commit 27943620cbd960f710a385ff4a538e14ed3f1922 introduced spurious IRQ handling but it has a race condition where valid completion can be lost while trying to clear spurious IRQ leading to occassional command timeouts. This patch improves SFF interrupt handler such that 1. Once BMDMA HSM is stopped, the condition is never considered spurious. As there's no way to resume stopped BMDMA HSM, if device status doesn't agree with BMDMA status, the only way out is aborting the command (otherwise, it will just end up timing out). 2. ap->ops->sff_check_status() can be safely called to clear spurious device IRQ as it atomically returns completion status but BMDMA IRQ status can't be cleared in safe way if command is in flight. After a spurious IRQ, call ap->ops->sff_irq_clear() only if the respective device is idle and retry completion if sff_check_status() indicates command completion. Please note that ata_piix uses bmdma_status for sff_irq_check() and #2 won't weaken spurious IRQ handling even with in-flight command because if bmdma_status indicates IRQ pending but device status is not on spurious check, the next IRQ handler invocation will abort the command due to #1. This fixes bko#15537. https://bugzilla.kernel.org/show_bug.cgi?id=15537 Signed-off-by: Tejun Heo Cc: Andrew Benton Cc: Petr Uzel Cc: Rafael J. Wysocki Signed-off-by: Jeff Garzik diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 561dec2..2774772 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -1667,6 +1667,7 @@ unsigned int ata_sff_host_intr(struct ata_port *ap, { struct ata_eh_info *ehi = &ap->link.eh_info; u8 status, host_stat = 0; + bool bmdma_stopped = false; VPRINTK("ata%u: protocol %d task_state %d\n", ap->print_id, qc->tf.protocol, ap->hsm_task_state); @@ -1699,6 +1700,7 @@ unsigned int ata_sff_host_intr(struct ata_port *ap, /* before we do anything else, clear DMA-Start bit */ ap->ops->bmdma_stop(qc); + bmdma_stopped = true; if (unlikely(host_stat & ATA_DMA_ERR)) { /* error when transfering data to/from memory */ @@ -1716,8 +1718,14 @@ unsigned int ata_sff_host_intr(struct ata_port *ap, /* check main status, clearing INTRQ if needed */ status = ata_sff_irq_status(ap); - if (status & ATA_BUSY) - goto idle_irq; + if (status & ATA_BUSY) { + if (bmdma_stopped) { + /* BMDMA engine is already stopped, we're screwed */ + qc->err_mask |= AC_ERR_HSM; + ap->hsm_task_state = HSM_ST_ERR; + } else + goto idle_irq; + } /* ack bmdma irq events */ ap->ops->sff_irq_clear(ap); @@ -1762,13 +1770,16 @@ EXPORT_SYMBOL_GPL(ata_sff_host_intr); irqreturn_t ata_sff_interrupt(int irq, void *dev_instance) { struct ata_host *host = dev_instance; + bool retried = false; unsigned int i; - unsigned int handled = 0, polling = 0; + unsigned int handled, idle, polling; unsigned long flags; /* TODO: make _irqsave conditional on x86 PCI IDE legacy mode */ spin_lock_irqsave(&host->lock, flags); +retry: + handled = idle = polling = 0; for (i = 0; i < host->n_ports; i++) { struct ata_port *ap = host->ports[i]; struct ata_queued_cmd *qc; @@ -1782,7 +1793,8 @@ irqreturn_t ata_sff_interrupt(int irq, void *dev_instance) handled |= ata_sff_host_intr(ap, qc); else polling |= 1 << i; - } + } else + idle |= 1 << i; } /* @@ -1790,7 +1802,9 @@ irqreturn_t ata_sff_interrupt(int irq, void *dev_instance) * asserting IRQ line, nobody cared will ensue. Check IRQ * pending status if available and clear spurious IRQ. */ - if (!handled) { + if (!handled && !retried) { + bool retry = false; + for (i = 0; i < host->n_ports; i++) { struct ata_port *ap = host->ports[i]; @@ -1805,8 +1819,23 @@ irqreturn_t ata_sff_interrupt(int irq, void *dev_instance) ata_port_printk(ap, KERN_INFO, "clearing spurious IRQ\n"); - ap->ops->sff_check_status(ap); - ap->ops->sff_irq_clear(ap); + if (idle & (1 << i)) { + ap->ops->sff_check_status(ap); + ap->ops->sff_irq_clear(ap); + } else { + /* clear INTRQ and check if BUSY cleared */ + if (!(ap->ops->sff_check_status(ap) & ATA_BUSY)) + retry |= true; + /* + * With command in flight, we can't do + * sff_irq_clear() w/o racing with completion. + */ + } + } + + if (retry) { + retried = true; + goto retry; } } -- cgit v0.10.2 From 0a990e7093566ceb07e38951e1a01686923d4f09 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 15 Mar 2010 16:12:25 -0700 Subject: ceph: clean up service ticket decoding Previously we would decode state directly into our current ticket_handler. This is problematic if for some reason we fail to decode, because we end up with half new state and half old state. We are probably already in bad shape if we get an update we can't decode, but we may as well be tidy anyway. Decode into new_* temporaries and update the ticket_handler only on success. Signed-off-by: Sage Weil diff --git a/fs/ceph/auth_x.c b/fs/ceph/auth_x.c index 33d3ad4..8d8a849 100644 --- a/fs/ceph/auth_x.c +++ b/fs/ceph/auth_x.c @@ -156,7 +156,11 @@ static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac, struct timespec validity; struct ceph_crypto_key old_key; void *tp, *tpend; + struct ceph_timespec new_validity; + struct ceph_crypto_key new_session_key; struct ceph_buffer *new_ticket_blob; + unsigned long new_expires, new_renew_after; + u64 new_secret_id; ceph_decode_need(&p, end, sizeof(u32) + 1, bad); @@ -189,16 +193,16 @@ static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac, goto bad; memcpy(&old_key, &th->session_key, sizeof(old_key)); - ret = ceph_crypto_key_decode(&th->session_key, &dp, dend); + ret = ceph_crypto_key_decode(&new_session_key, &dp, dend); if (ret) goto out; - ceph_decode_copy(&dp, &th->validity, sizeof(th->validity)); - ceph_decode_timespec(&validity, &th->validity); - th->expires = get_seconds() + validity.tv_sec; - th->renew_after = th->expires - (validity.tv_sec / 4); - dout(" expires=%lu renew_after=%lu\n", th->expires, - th->renew_after); + ceph_decode_copy(&dp, &new_validity, sizeof(new_validity)); + ceph_decode_timespec(&validity, &new_validity); + new_expires = get_seconds() + validity.tv_sec; + new_renew_after = new_expires - (validity.tv_sec / 4); + dout(" expires=%lu renew_after=%lu\n", new_expires, + new_renew_after); /* ticket blob for service */ ceph_decode_8_safe(&p, end, is_enc, bad); @@ -223,13 +227,21 @@ static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac, dout(" ticket blob is %d bytes\n", dlen); ceph_decode_need(&tp, tpend, 1 + sizeof(u64), bad); struct_v = ceph_decode_8(&tp); - th->secret_id = ceph_decode_64(&tp); + new_secret_id = ceph_decode_64(&tp); ret = ceph_decode_buffer(&new_ticket_blob, &tp, tpend); if (ret) goto out; + + /* all is well, update our ticket */ + ceph_crypto_key_destroy(&th->session_key); if (th->ticket_blob) ceph_buffer_put(th->ticket_blob); + th->session_key = new_session_key; th->ticket_blob = new_ticket_blob; + th->validity = new_validity; + th->secret_id = new_secret_id; + th->expires = new_expires; + th->renew_after = new_renew_after; dout(" got ticket service %d (%s) secret_id %lld len %d\n", type, ceph_entity_type_name(type), th->secret_id, (int)th->ticket_blob->vec.iov_len); -- cgit v0.10.2 From 12eadc190038e68b5884a4aa313b6ab89ba60f5e Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 15 Mar 2010 22:20:39 -0700 Subject: ceph: fix null pointer deref of r_osd in debug output This causes an oops when debug output is enabled and we kick an osd request with no current r_osd (sometime after an osd failure). Check the pointer before dereferencing. Signed-off-by: Sage Weil diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index dbe63db9..2210382 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -913,7 +913,7 @@ static int __kick_requests(struct ceph_osd_client *osdc, kick: dout("kicking %p tid %llu osd%d\n", req, req->r_tid, - req->r_osd->o_osd); + req->r_osd ? req->r_osd->o_osd : -1); req->r_flags |= CEPH_OSD_FLAG_RETRY; err = __send_request(osdc, req); if (err) { -- cgit v0.10.2 From 4ea0043a29c82ca52ca54728d837314563bec574 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 16 Mar 2010 10:36:40 -0700 Subject: ceph: drop unnecessary WARN_ON in caps migration If we don't have the exported cap it's because we already released it. No need to WARN. Signed-off-by: Sage Weil diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 57d9b44..726c8d4 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -2550,9 +2550,8 @@ static void handle_cap_export(struct inode *inode, struct ceph_mds_caps *ex, ci->i_cap_exporting_issued = cap->issued; } __ceph_remove_cap(cap); - } else { - WARN_ON(!cap); } + /* else, we already released it */ spin_unlock(&inode->i_lock); } -- cgit v0.10.2 From cdc2ce056a3620139056b60ad7f6d355ad13f445 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 16 Mar 2010 13:39:28 -0700 Subject: ceph: fix session locking in handle_caps, ceph_check_caps Passing a session pointer to ceph_check_caps() used to mean it would leave the session mutex locked. That wasn't always possible if it wasn't passed CHECK_CAPS_AUTHONLY. If could unlock the passed session and lock a differet session mutex, which was clearly wrong, and also emitted a warning when it a racing CPU retook it and we did an unlock from the wrong context. This was only a problem when there was more than one MDS. First, make ceph_check_caps unconditionally drop the session mutex, so that it is free to lock other sessions as needed. Then adjust the one caller that passes in a session (handle_cap_grant) accordingly. Signed-off-by: Sage Weil diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 726c8d4..7828486 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -1407,6 +1407,7 @@ static int try_nonblocking_invalidate(struct inode *inode) */ void ceph_check_caps(struct ceph_inode_info *ci, int flags, struct ceph_mds_session *session) + __releases(session->s_mutex) { struct ceph_client *client = ceph_inode_to_client(&ci->vfs_inode); struct ceph_mds_client *mdsc = &client->mdsc; @@ -1414,7 +1415,6 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags, struct ceph_cap *cap; int file_wanted, used; int took_snap_rwsem = 0; /* true if mdsc->snap_rwsem held */ - int drop_session_lock = session ? 0 : 1; int issued, implemented, want, retain, revoking, flushing = 0; int mds = -1; /* keep track of how far we've gone through i_caps list to avoid an infinite loop on retry */ @@ -1639,7 +1639,7 @@ ack: if (queue_invalidate) ceph_queue_invalidate(inode); - if (session && drop_session_lock) + if (session) mutex_unlock(&session->s_mutex); if (took_snap_rwsem) up_read(&mdsc->snap_rwsem); @@ -2688,14 +2688,17 @@ void ceph_handle_caps(struct ceph_mds_session *session, case CEPH_CAP_OP_REVOKE: case CEPH_CAP_OP_GRANT: r = handle_cap_grant(inode, h, session, cap, msg->middle); - if (r == 1) + if (r == 1) { ceph_check_caps(ceph_inode(inode), CHECK_CAPS_NODELAY|CHECK_CAPS_AUTHONLY, session); - else if (r == 2) + session = NULL; + } else if (r == 2) { ceph_check_caps(ceph_inode(inode), CHECK_CAPS_NODELAY, session); + session = NULL; + } break; case CEPH_CAP_OP_FLUSH_ACK: @@ -2713,7 +2716,8 @@ void ceph_handle_caps(struct ceph_mds_session *session, } done: - mutex_unlock(&session->s_mutex); + if (session) + mutex_unlock(&session->s_mutex); if (check_caps) ceph_check_caps(ceph_inode(inode), CHECK_CAPS_NODELAY, NULL); -- cgit v0.10.2 From 15637c8b1251c38694c32214eba69b72a30e9d9b Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 16 Mar 2010 13:42:00 -0700 Subject: ceph: clean up handle_cap_grant, handle_caps wrt session mutex Drop session mutex unconditionally in handle_cap_grant, and do the check_caps from the handle_cap_grant helper. This avoids using a magic return value. Also avoid using a flag variable in the IMPORT case and call check_caps at the appropriate point. Signed-off-by: Sage Weil diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 7828486..d9e860f 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -2195,18 +2195,19 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr, * Handle a cap GRANT message from the MDS. (Note that a GRANT may * actually be a revocation if it specifies a smaller cap set.) * - * caller holds s_mutex. + * caller holds s_mutex and i_lock, we drop both. + * * return value: * 0 - ok * 1 - check_caps on auth cap only (writeback) * 2 - check_caps (ack revoke) */ -static int handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant, - struct ceph_mds_session *session, - struct ceph_cap *cap, - struct ceph_buffer *xattr_buf) +static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant, + struct ceph_mds_session *session, + struct ceph_cap *cap, + struct ceph_buffer *xattr_buf) __releases(inode->i_lock) - + __releases(session->s_mutex) { struct ceph_inode_info *ci = ceph_inode(inode); int mds = session->s_mds; @@ -2216,7 +2217,7 @@ static int handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant, u64 size = le64_to_cpu(grant->size); u64 max_size = le64_to_cpu(grant->max_size); struct timespec mtime, atime, ctime; - int reply = 0; + int check_caps = 0; int wake = 0; int writeback = 0; int revoked_rdcache = 0; @@ -2329,10 +2330,10 @@ static int handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant, if ((used & ~newcaps) & CEPH_CAP_FILE_BUFFER) writeback = 1; /* will delay ack */ else if (dirty & ~newcaps) - reply = 1; /* initiate writeback in check_caps */ + check_caps = 1; /* initiate writeback in check_caps */ else if (((used & ~newcaps) & CEPH_CAP_FILE_CACHE) == 0 || revoked_rdcache) - reply = 2; /* send revoke ack in check_caps */ + check_caps = 2; /* send revoke ack in check_caps */ cap->issued = newcaps; cap->implemented |= newcaps; } else if (cap->issued == newcaps) { @@ -2361,7 +2362,14 @@ static int handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant, ceph_queue_invalidate(inode); if (wake) wake_up(&ci->i_cap_wq); - return reply; + + if (check_caps == 1) + ceph_check_caps(ci, CHECK_CAPS_NODELAY|CHECK_CAPS_AUTHONLY, + session); + else if (check_caps == 2) + ceph_check_caps(ci, CHECK_CAPS_NODELAY, session); + else + mutex_unlock(&session->s_mutex); } /* @@ -2622,9 +2630,7 @@ void ceph_handle_caps(struct ceph_mds_session *session, u64 cap_id; u64 size, max_size; u64 tid; - int check_caps = 0; void *snaptrace; - int r; dout("handle_caps from mds%d\n", mds); @@ -2669,8 +2675,9 @@ void ceph_handle_caps(struct ceph_mds_session *session, case CEPH_CAP_OP_IMPORT: handle_cap_import(mdsc, inode, h, session, snaptrace, le32_to_cpu(h->snap_trace_len)); - check_caps = 1; /* we may have sent a RELEASE to the old auth */ - goto done; + ceph_check_caps(ceph_inode(inode), CHECK_CAPS_NODELAY, + session); + goto done_unlocked; } /* the rest require a cap */ @@ -2687,19 +2694,8 @@ void ceph_handle_caps(struct ceph_mds_session *session, switch (op) { case CEPH_CAP_OP_REVOKE: case CEPH_CAP_OP_GRANT: - r = handle_cap_grant(inode, h, session, cap, msg->middle); - if (r == 1) { - ceph_check_caps(ceph_inode(inode), - CHECK_CAPS_NODELAY|CHECK_CAPS_AUTHONLY, - session); - session = NULL; - } else if (r == 2) { - ceph_check_caps(ceph_inode(inode), - CHECK_CAPS_NODELAY, - session); - session = NULL; - } - break; + handle_cap_grant(inode, h, session, cap, msg->middle); + goto done_unlocked; case CEPH_CAP_OP_FLUSH_ACK: handle_cap_flush_ack(inode, tid, h, session, cap); @@ -2716,11 +2712,8 @@ void ceph_handle_caps(struct ceph_mds_session *session, } done: - if (session) - mutex_unlock(&session->s_mutex); - - if (check_caps) - ceph_check_caps(ceph_inode(inode), CHECK_CAPS_NODELAY, NULL); + mutex_unlock(&session->s_mutex); +done_unlocked: if (inode) iput(inode); return; -- cgit v0.10.2 From 916623da10e270c7e9e802a7ddfe1ec8f890982d Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 16 Mar 2010 15:01:07 -0700 Subject: ceph: only release unused caps with mds requests We were releasing used caps (e.g. FILE_CACHE) from encode_inode_release with MDS requests (e.g. setattr). We don't carry refs on most caps, so this code worked most of the time, but for setattr (utimes) we try to drop Fscr. This causes cap state to get slightly out of sync with reality, and may result in subsequent mds revoke messages getting ignored. Fix by only releasing unused caps. Signed-off-by: Sage Weil diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index d9e860f..7d0a0d0 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -2836,11 +2836,18 @@ int ceph_encode_inode_release(void **p, struct inode *inode, struct ceph_cap *cap; struct ceph_mds_request_release *rel = *p; int ret = 0; - - dout("encode_inode_release %p mds%d drop %s unless %s\n", inode, - mds, ceph_cap_string(drop), ceph_cap_string(unless)); + int used = 0; spin_lock(&inode->i_lock); + used = __ceph_caps_used(ci); + + dout("encode_inode_release %p mds%d used %s drop %s unless %s\n", inode, + mds, ceph_cap_string(used), ceph_cap_string(drop), + ceph_cap_string(unless)); + + /* only drop unused caps */ + drop &= ~used; + cap = __get_cap_for_mds(ci, mds); if (cap && __cap_is_valid(cap)) { if (force || -- cgit v0.10.2 From 80fc7314a7e26e8d2e4ba5b3d8cc2d4aeb750015 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 16 Mar 2010 15:28:54 -0700 Subject: ceph: fix mds sync() race with completing requests The wait_unsafe_requests() helper dropped the mdsc mutex to wait for each request to complete, and then examined r_node to get the next request after retaking the lock. But the request completion removes the request from the tree, so r_node was always undefined at this point. Since it's a small race, it usually led to a valid request, but not always. The result was an occasional crash in rb_next() while dereferencing node->rb_left. Fix this by clearing the rb_node when removing the request from the request tree, and not walking off into the weeds when we are done waiting for a request. Since the request we waited on will _always_ be out of the request tree, take a ref on the next request, in the hopes that it won't be. But if it is, it's ok: we can start over from the beginning (and traverse over older read requests again). Signed-off-by: Sage Weil diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index a260010..5ec8641 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -529,6 +529,7 @@ static void __unregister_request(struct ceph_mds_client *mdsc, { dout("__unregister_request %p tid %lld\n", req, req->r_tid); rb_erase(&req->r_node, &mdsc->request_tree); + RB_CLEAR_NODE(&req->r_node); ceph_mdsc_put_request(req); if (req->r_unsafe_dir) { @@ -2682,29 +2683,41 @@ void ceph_mdsc_pre_umount(struct ceph_mds_client *mdsc) */ static void wait_unsafe_requests(struct ceph_mds_client *mdsc, u64 want_tid) { - struct ceph_mds_request *req = NULL; + struct ceph_mds_request *req = NULL, *nextreq; struct rb_node *n; mutex_lock(&mdsc->mutex); dout("wait_unsafe_requests want %lld\n", want_tid); +restart: req = __get_oldest_req(mdsc); while (req && req->r_tid <= want_tid) { + /* find next request */ + n = rb_next(&req->r_node); + if (n) + nextreq = rb_entry(n, struct ceph_mds_request, r_node); + else + nextreq = NULL; if ((req->r_op & CEPH_MDS_OP_WRITE)) { /* write op */ ceph_mdsc_get_request(req); + if (nextreq) + ceph_mdsc_get_request(nextreq); mutex_unlock(&mdsc->mutex); dout("wait_unsafe_requests wait on %llu (want %llu)\n", req->r_tid, want_tid); wait_for_completion(&req->r_safe_completion); mutex_lock(&mdsc->mutex); - n = rb_next(&req->r_node); ceph_mdsc_put_request(req); - } else { - n = rb_next(&req->r_node); + if (!nextreq) + break; /* next dne before, so we're done! */ + if (RB_EMPTY_NODE(&nextreq->r_node)) { + /* next request was removed from tree */ + ceph_mdsc_put_request(nextreq); + goto restart; + } + ceph_mdsc_put_request(nextreq); /* won't go away */ } - if (!n) - break; - req = rb_entry(n, struct ceph_mds_request, r_node); + req = nextreq; } mutex_unlock(&mdsc->mutex); dout("wait_unsafe_requests done\n"); -- cgit v0.10.2 From efd7576b2392cc5a0934352936d793e8884c46bf Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 17 Mar 2010 10:05:28 -0700 Subject: ceph: fix pg pool decoding from incremental osdmap update The incremental map decoding of pg pool updates wasn't skipping the snaps and removed_snaps vectors. This caused osd requests to stall when pool snapshots were created or fs snapshots were deleted. Use a common helper for full and incremental map decoders that decodes pools properly. Signed-off-by: Sage Weil diff --git a/fs/ceph/osdmap.c b/fs/ceph/osdmap.c index b83f269..d82fe87 100644 --- a/fs/ceph/osdmap.c +++ b/fs/ceph/osdmap.c @@ -480,6 +480,14 @@ static struct ceph_pg_pool_info *__lookup_pg_pool(struct rb_root *root, int id) return NULL; } +void __decode_pool(void **p, struct ceph_pg_pool_info *pi) +{ + ceph_decode_copy(p, &pi->v, sizeof(pi->v)); + calc_pg_masks(pi); + *p += le32_to_cpu(pi->v.num_snaps) * sizeof(u64); + *p += le32_to_cpu(pi->v.num_removed_snap_intervals) * sizeof(u64) * 2; +} + /* * decode a full map. */ @@ -526,12 +534,8 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end) ev, CEPH_PG_POOL_VERSION); goto bad; } - ceph_decode_copy(p, &pi->v, sizeof(pi->v)); + __decode_pool(p, pi); __insert_pg_pool(&map->pg_pools, pi); - calc_pg_masks(pi); - *p += le32_to_cpu(pi->v.num_snaps) * sizeof(u64); - *p += le32_to_cpu(pi->v.num_removed_snap_intervals) - * sizeof(u64) * 2; } ceph_decode_32_safe(p, end, map->pool_max, bad); @@ -714,8 +718,7 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, pi->id = pool; __insert_pg_pool(&map->pg_pools, pi); } - ceph_decode_copy(p, &pi->v, sizeof(pi->v)); - calc_pg_masks(pi); + __decode_pool(p, pi); } /* old_pool */ -- cgit v0.10.2 From e4cb4cb8a03adde1aa4b874623c50b9a5b56e635 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 18 Mar 2010 13:43:09 -0700 Subject: ceph: prevent dup stale messages to console for restarting mds Prevent duplicate 'mds0 caps stale' message from spamming the console every few seconds while the MDS restarts. Set s_renew_requested earlier, so that we only print the message once, even if we don't send an actual request. Signed-off-by: Sage Weil diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 5ec8641..5cbf46a 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -863,6 +863,7 @@ static int send_renew_caps(struct ceph_mds_client *mdsc, if (time_after_eq(jiffies, session->s_cap_ttl) && time_after_eq(session->s_cap_ttl, session->s_renew_requested)) pr_info("mds%d caps stale\n", session->s_mds); + session->s_renew_requested = jiffies; /* do not try to renew caps until a recovering mds has reconnected * with its clients. */ @@ -875,7 +876,6 @@ static int send_renew_caps(struct ceph_mds_client *mdsc, dout("send_renew_caps to mds%d (%s)\n", session->s_mds, ceph_mds_state_name(state)); - session->s_renew_requested = jiffies; msg = create_session_msg(CEPH_SESSION_REQUEST_RENEWCAPS, ++session->s_renew_seq); if (IS_ERR(msg)) -- cgit v0.10.2 From 3c3f2e32effd4c6acc3a9434bd7eecb0af653d89 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 18 Mar 2010 15:20:53 -0700 Subject: ceph: fix connection fault con_work reentrancy problem The messenger fault was clearing the BUSY bit, for reasons unclear. This made it possible for the con->ops->fault function to reopen the connection, and requeue work in the workqueue--even though the current thread was already in con_work. This avoids a problem where the client busy loops with connection failures on an unreachable OSD, but doesn't address the root cause of that problem. Signed-off-by: Sage Weil diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index 203c435..9832855 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -1836,8 +1836,6 @@ static void ceph_fault(struct ceph_connection *con) goto out; } - clear_bit(BUSY, &con->state); /* to avoid an improbable race */ - mutex_lock(&con->mutex); if (test_bit(CLOSED, &con->state)) goto out_unlock; -- cgit v0.10.2 From 3dd72fc0e6dc49c79fa9e7cd7c654deac7ccaa29 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 22 Mar 2010 14:42:30 -0700 Subject: ceph: rename r_sent_stamp r_stamp Make variable name slightly more generic, since it will (soon) reflect either the time the request was sent OR the time it was last determined to be still retrying. Signed-off-by: Sage Weil diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index 2210382..04359217 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -633,7 +633,7 @@ static int __send_request(struct ceph_osd_client *osdc, reqhead->flags |= cpu_to_le32(req->r_flags); /* e.g., RETRY */ reqhead->reassert_version = req->r_reassert_version; - req->r_sent_stamp = jiffies; + req->r_stamp = jiffies; list_move_tail(&osdc->req_lru, &req->r_req_lru_item); ceph_msg_get(req->r_request); /* send consumes a ref */ @@ -660,7 +660,7 @@ static void handle_timeout(struct work_struct *work) unsigned long timeout = osdc->client->mount_args->osd_timeout * HZ; unsigned long keepalive = osdc->client->mount_args->osd_keepalive_timeout * HZ; - unsigned long last_sent = 0; + unsigned long last_stamp = 0; struct rb_node *p; struct list_head slow_osds; @@ -697,12 +697,12 @@ static void handle_timeout(struct work_struct *work) req = list_entry(osdc->req_lru.next, struct ceph_osd_request, r_req_lru_item); - if (time_before(jiffies, req->r_sent_stamp + timeout)) + if (time_before(jiffies, req->r_stamp + timeout)) break; - BUG_ON(req == last_req && req->r_sent_stamp == last_sent); + BUG_ON(req == last_req && req->r_stamp == last_stamp); last_req = req; - last_sent = req->r_sent_stamp; + last_stamp = req->r_stamp; osd = req->r_osd; BUG_ON(!osd); @@ -718,7 +718,7 @@ static void handle_timeout(struct work_struct *work) */ INIT_LIST_HEAD(&slow_osds); list_for_each_entry(req, &osdc->req_lru, r_req_lru_item) { - if (time_before(jiffies, req->r_sent_stamp + keepalive)) + if (time_before(jiffies, req->r_stamp + keepalive)) break; osd = req->r_osd; diff --git a/fs/ceph/osd_client.h b/fs/ceph/osd_client.h index 1b1a3ca..b075991 100644 --- a/fs/ceph/osd_client.h +++ b/fs/ceph/osd_client.h @@ -70,7 +70,7 @@ struct ceph_osd_request { char r_oid[40]; /* object name */ int r_oid_len; - unsigned long r_sent_stamp; + unsigned long r_stamp; /* send OR check time */ bool r_resend; /* msg send failed, needs retry */ struct ceph_file_layout r_file_layout; -- cgit v0.10.2 From 87b315a5b5cec5d7086494b203577602f5befc8c Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 22 Mar 2010 14:51:18 -0700 Subject: ceph: avoid reopening osd connections when address hasn't changed We get a fault callback on _every_ tcp connection fault. Normally, we want to reopen the connection when that happens. If the address we have is bad, however, and connection attempts always result in a connection refused or similar error, explicitly closing and reopening the msgr connection just prevents the messenger's backoff logic from kicking in. The result can be a console full of [ 3974.417106] ceph: osd11 10.3.14.138:6800 connection failed [ 3974.423295] ceph: osd11 10.3.14.138:6800 connection failed [ 3974.429709] ceph: osd11 10.3.14.138:6800 connection failed Instead, if we get a fault, and have outstanding requests, but the osd address hasn't changed and the connection never successfully connected in the first place, do nothing to the osd connection. The messenger layer will back off and retry periodically, because we never connected and thus the lossy bit is not set. Instead, touch each request's r_stamp so that handle_timeout can tell the request is still alive and kicking. Signed-off-by: Sage Weil diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index 9832855..a32f0f8 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c @@ -366,6 +366,14 @@ void ceph_con_open(struct ceph_connection *con, struct ceph_entity_addr *addr) } /* + * return true if this connection ever successfully opened + */ +bool ceph_con_opened(struct ceph_connection *con) +{ + return con->connect_seq > 0; +} + +/* * generic get/put */ struct ceph_connection *ceph_con_get(struct ceph_connection *con) diff --git a/fs/ceph/messenger.h b/fs/ceph/messenger.h index 4caaa59..a343dae 100644 --- a/fs/ceph/messenger.h +++ b/fs/ceph/messenger.h @@ -223,6 +223,7 @@ extern void ceph_con_init(struct ceph_messenger *msgr, struct ceph_connection *con); extern void ceph_con_open(struct ceph_connection *con, struct ceph_entity_addr *addr); +extern bool ceph_con_opened(struct ceph_connection *con); extern void ceph_con_close(struct ceph_connection *con); extern void ceph_con_send(struct ceph_connection *con, struct ceph_msg *msg); extern void ceph_con_revoke(struct ceph_connection *con, struct ceph_msg *msg); diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index 04359217..c7b4ded 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -413,11 +413,22 @@ static void remove_old_osds(struct ceph_osd_client *osdc, int remove_all) */ static int __reset_osd(struct ceph_osd_client *osdc, struct ceph_osd *osd) { + struct ceph_osd_request *req; int ret = 0; dout("__reset_osd %p osd%d\n", osd, osd->o_osd); if (list_empty(&osd->o_requests)) { __remove_osd(osdc, osd); + } else if (memcmp(&osdc->osdmap->osd_addr[osd->o_osd], + &osd->o_con.peer_addr, + sizeof(osd->o_con.peer_addr)) == 0 && + !ceph_con_opened(&osd->o_con)) { + dout(" osd addr hasn't changed and connection never opened," + " letting msgr retry"); + /* touch each r_stamp for handle_timeout()'s benfit */ + list_for_each_entry(req, &osd->o_requests, r_osd_item) + req->r_stamp = jiffies; + ret = -EAGAIN; } else { ceph_con_close(&osd->o_con); ceph_con_open(&osd->o_con, &osdc->osdmap->osd_addr[osd->o_osd]); @@ -862,7 +873,9 @@ static int __kick_requests(struct ceph_osd_client *osdc, dout("kick_requests osd%d\n", kickosd ? kickosd->o_osd : -1); if (kickosd) { - __reset_osd(osdc, kickosd); + err = __reset_osd(osdc, kickosd); + if (err == -EAGAIN) + return 1; } else { for (p = rb_first(&osdc->osds); p; p = n) { struct ceph_osd *osd = -- cgit v0.10.2 From ec4318bcb4c59d8b8bf7037c9f444a9887ccb265 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 19 Mar 2010 13:24:39 -0700 Subject: ceph: fix snap rebuild condition We were rebuilding the snap context when it was not necessary (i.e. when the realm seq hadn't changed _and_ the parent seq was still older), which caused page snapc pointers to not match the realm's snapc pointer (even though the snap context itself was identical). This confused begin_write and put it into an endless loop. The correct logic is: rebuild snapc if _my_ realm seq changed, or if my parent realm's seq is newer than mine (and thus mine needs to be rebuilt too). Signed-off-by: Sage Weil diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c index 8a43bc8..df04e21 100644 --- a/fs/ceph/snap.c +++ b/fs/ceph/snap.c @@ -314,9 +314,9 @@ static int build_snap_context(struct ceph_snap_realm *realm) because we rebuild_snap_realms() works _downward_ in hierarchy after each update.) */ if (realm->cached_context && - realm->cached_context->seq <= realm->seq && + realm->cached_context->seq == realm->seq && (!parent || - realm->cached_context->seq <= parent->cached_context->seq)) { + realm->cached_context->seq >= parent->cached_context->seq)) { dout("build_snap_context %llx %p: %p seq %lld (%d snaps)" " (unchanged)\n", realm->ino, realm, realm->cached_context, -- cgit v0.10.2 From 8f883c24de33ba929c95e018ac0ba66e4f46734b Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 19 Mar 2010 13:27:53 -0700 Subject: ceph: make write_begin wait propagate ERESTARTSYS Currently, if the wait_event_interruptible is interrupted, we return EAGAIN unconditionally and loop, such that we aren't, in fact, interruptible. So, propagate ERESTARTSYS if we get it. Signed-off-by: Sage Weil diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index 23bb0ce..ce8ef61 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c @@ -919,6 +919,10 @@ static int context_is_writeable_or_written(struct inode *inode, /* * We are only allowed to write into/dirty the page if the page is * clean, or already dirty within the same snap context. + * + * called with page locked. + * return success with page locked, + * or any failure (incl -EAGAIN) with page unlocked. */ static int ceph_update_writeable_page(struct file *file, loff_t pos, unsigned len, @@ -961,9 +965,11 @@ retry_locked: snapc = ceph_get_snap_context((void *)page->private); unlock_page(page); ceph_queue_writeback(inode); - wait_event_interruptible(ci->i_cap_wq, + r = wait_event_interruptible(ci->i_cap_wq, context_is_writeable_or_written(inode, snapc)); ceph_put_snap_context(snapc); + if (r == -ERESTARTSYS) + return r; return -EAGAIN; } @@ -1035,7 +1041,7 @@ static int ceph_write_begin(struct file *file, struct address_space *mapping, int r; do { - /* get a page*/ + /* get a page */ page = grab_cache_page_write_begin(mapping, index, 0); if (!page) return -ENOMEM; -- cgit v0.10.2 From 9c423956b8a495f0c048143abc5da955a70eac97 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Sat, 20 Mar 2010 20:43:28 -0700 Subject: ceph: propagate mds session allocation failures to caller Return error to original caller if register_session() fails. Signed-off-by: Sage Weil diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 5cbf46a..b6b5348 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -1567,8 +1567,13 @@ static int __do_request(struct ceph_mds_client *mdsc, /* get, open session */ session = __ceph_lookup_mds_session(mdsc, mds); - if (!session) + if (!session) { session = register_session(mdsc, mds); + if (IS_ERR(session)) { + err = PTR_ERR(session); + goto finish; + } + } dout("do_request mds%d session %p state %s\n", mds, session, session_state_name(session->s_state)); if (session->s_state != CEPH_MDS_SESSION_OPEN && -- cgit v0.10.2 From 4736b009b880b7c19bea36327a71032a6dbee402 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 20 Mar 2010 15:30:16 +0300 Subject: ceph: handle kmalloc() failure Return ERR_PTR(-ENOMEM) if kmalloc() fails. We handle allocation failures the same way later in the function. Signed-off-by: Dan Carpenter Signed-off-by: Sage Weil diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index b6b5348..ad0fbc3 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -328,6 +328,8 @@ static struct ceph_mds_session *register_session(struct ceph_mds_client *mdsc, struct ceph_mds_session *s; s = kzalloc(sizeof(*s), GFP_NOFS); + if (!s) + return ERR_PTR(-ENOMEM); s->s_mdsc = mdsc; s->s_mds = mds; s->s_state = CEPH_MDS_SESSION_NEW; -- cgit v0.10.2 From d96d60498ff748c5a88c72ec5d1cc4ba9a583e7e Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Sat, 20 Mar 2010 20:50:58 -0700 Subject: ceph: fix session check on mds reply Fix a broken check that a reply came back from the same MDS we sent the request to. I don't think a case that actually triggers this would ever come up in practice, but it's clearly wrong and easy to fix. Reported-by: Dan Carpenter Signed-off-by: Sage Weil diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index ad0fbc3..5268d40 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -1778,7 +1778,7 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg) dout("handle_reply %p\n", req); /* correct session? */ - if (!req->r_session && req->r_session != session) { + if (req->r_session != session) { pr_err("mdsc_handle_reply got %llu on session mds%d" " not mds%d\n", tid, session->s_mds, req->r_session ? req->r_session->s_mds : -1); -- cgit v0.10.2 From 393f66209669ad23f4f6d4191234c1df4367df3c Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 10 Mar 2010 12:03:32 -0800 Subject: ceph: fix possible double-free of mds request reference Clear pointer to mds request after dropping the reference to ensure we don't drop it again, as there is at least one error path through this function that does not reset fi->last_readdir to a new value. Signed-off-by: Sage Weil diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 5107384..8a9116e 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c @@ -288,8 +288,10 @@ more: CEPH_MDS_OP_LSSNAP : CEPH_MDS_OP_READDIR; /* discard old result, if any */ - if (fi->last_readdir) + if (fi->last_readdir) { ceph_mdsc_put_request(fi->last_readdir); + fi->last_readdir = NULL; + } /* requery frag tree, as the frag topology may have changed */ frag = ceph_choose_frag(ceph_inode(inode), frag, NULL, NULL); -- cgit v0.10.2 From 23ab15ad7a9d042afa7303b735b6e24faa607241 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 22 Mar 2010 09:37:14 -0700 Subject: ceph: avoid loaded term 'OSD' in documention 'OSD' means different things to different people; avoid it here to avoid confusion. Signed-off-by: Sage Weil diff --git a/Documentation/filesystems/ceph.txt b/Documentation/filesystems/ceph.txt index 6e03917..523fdf0 100644 --- a/Documentation/filesystems/ceph.txt +++ b/Documentation/filesystems/ceph.txt @@ -115,7 +115,7 @@ Mount Options number of entries in that directory. nocrc - Disable CRC32C calculation for data writes. If set, the OSD + Disable CRC32C calculation for data writes. If set, the storage node must rely on TCP's error correction to detect data corruption in the data payload. -- cgit v0.10.2 From 110d735a0ae69bdd11af9acb6ea3b979137eb118 Mon Sep 17 00:00:00 2001 From: Ryusuke Konishi Date: Mon, 22 Mar 2010 21:36:06 +0900 Subject: nilfs2: fix hang-up of cleaner after log writer returned with error According to the report from Andreas Beckmann (Message-ID: <4BA54677.3090902@abeckmann.de>), nilfs in 2.6.33 kernel got stuck after a disk full error. This turned out to be a regression by log writer updates merged at kernel 2.6.33. nilfs_segctor_abort_construction, which is a cleanup function for erroneous cases, was skipping writeback completion for some logs. This fixes the bug and would resolve the hang issue. Reported-by: Andreas Beckmann Signed-off-by: Ryusuke Konishi Tested-by: Ryusuke Konishi Cc: stable [2.6.33.x] diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index b622123..c161d89 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c @@ -1897,8 +1897,7 @@ static void nilfs_segctor_abort_construction(struct nilfs_sc_info *sci, list_splice_tail_init(&sci->sc_write_logs, &logs); ret = nilfs_wait_on_logs(&logs); - if (ret) - nilfs_abort_logs(&logs, NULL, sci->sc_super_root, ret); + nilfs_abort_logs(&logs, NULL, sci->sc_super_root, ret ? : err); list_splice_tail_init(&sci->sc_segbufs, &logs); nilfs_cancel_segusage(&logs, nilfs->ns_sufile); -- cgit v0.10.2 From d8e4ebf8b603bdcd091540e6b5bddf0dec10d516 Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Tue, 23 Mar 2010 16:32:37 +0100 Subject: HID: fix oops in gyration_event() Fix oops caused by dereferencing field->hidinput in cases where the device hasn't been claimed by hid-input. Reported-by: Andreas Demmer Signed-off-by: Jiri Kosina diff --git a/drivers/hid/hid-gyration.c b/drivers/hid/hid-gyration.c index cab13e8..62416e6 100644 --- a/drivers/hid/hid-gyration.c +++ b/drivers/hid/hid-gyration.c @@ -53,10 +53,13 @@ static int gyration_input_mapping(struct hid_device *hdev, struct hid_input *hi, static int gyration_event(struct hid_device *hdev, struct hid_field *field, struct hid_usage *usage, __s32 value) { - struct input_dev *input = field->hidinput->input; + + if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput) + return 0; if ((usage->hid & HID_USAGE_PAGE) == HID_UP_GENDESK && (usage->hid & 0xff) == 0x82) { + struct input_dev *input = field->hidinput->input; input_event(input, usage->type, usage->code, 1); input_sync(input); input_event(input, usage->type, usage->code, 0); -- cgit v0.10.2 From 5cbb2b941d2cc77e6b915e8e55d375be632c9f6a Mon Sep 17 00:00:00 2001 From: Komuro Date: Sat, 20 Mar 2010 06:39:19 +0900 Subject: pd6729: Coding Style fixes Signed-off-by: Komuro Signed-off-by: Dominik Brodowski diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c index 7ba57a5..47f342f 100644 --- a/drivers/pcmcia/pd6729.c +++ b/drivers/pcmcia/pd6729.c @@ -14,13 +14,13 @@ #include #include #include +#include #include #include #include #include -#include #include "pd6729.h" #include "i82365.h" @@ -222,9 +222,9 @@ static irqreturn_t pd6729_interrupt(int irq, void *dev) ? SS_READY : 0; } - if (events) { + if (events) pcmcia_parse_events(&socket[i].socket, events); - } + active |= events; } @@ -256,9 +256,8 @@ static int pd6729_get_status(struct pcmcia_socket *sock, u_int *value) status = indirect_read(socket, I365_STATUS); *value = 0; - if ((status & I365_CS_DETECT) == I365_CS_DETECT) { + if ((status & I365_CS_DETECT) == I365_CS_DETECT) *value |= SS_DETECT; - } /* * IO cards have a different meaning of bits 0,1 @@ -308,7 +307,7 @@ static int pd6729_set_socket(struct pcmcia_socket *sock, socket_state_t *state) socket->card_irq = state->io_irq; reg = 0; - /* The reset bit has "inverse" logic */ + /* The reset bit has "inverse" logic */ if (!(state->flags & SS_RESET)) reg |= I365_PC_RESET; if (state->flags & SS_IOCARD) @@ -380,7 +379,7 @@ static int pd6729_set_socket(struct pcmcia_socket *sock, socket_state_t *state) indirect_write(socket, I365_POWER, reg); if (irq_mode == 1) { - /* all interrupts are to be done as PCI interrupts */ + /* all interrupts are to be done as PCI interrupts */ data = PD67_EC1_INV_MGMT_IRQ | PD67_EC1_INV_CARD_IRQ; } else data = 0; @@ -391,9 +390,9 @@ static int pd6729_set_socket(struct pcmcia_socket *sock, socket_state_t *state) /* Enable specific interrupt events */ reg = 0x00; - if (state->csc_mask & SS_DETECT) { + if (state->csc_mask & SS_DETECT) reg |= I365_CSC_DETECT; - } + if (state->flags & SS_IOCARD) { if (state->csc_mask & SS_STSCHG) reg |= I365_CSC_STSCHG; @@ -450,9 +449,12 @@ static int pd6729_set_io_map(struct pcmcia_socket *sock, ioctl = indirect_read(socket, I365_IOCTL) & ~I365_IOCTL_MASK(map); - if (io->flags & MAP_0WS) ioctl |= I365_IOCTL_0WS(map); - if (io->flags & MAP_16BIT) ioctl |= I365_IOCTL_16BIT(map); - if (io->flags & MAP_AUTOSZ) ioctl |= I365_IOCTL_IOCS16(map); + if (io->flags & MAP_0WS) + ioctl |= I365_IOCTL_0WS(map); + if (io->flags & MAP_16BIT) + ioctl |= I365_IOCTL_16BIT(map); + if (io->flags & MAP_AUTOSZ) + ioctl |= I365_IOCTL_IOCS16(map); indirect_write(socket, I365_IOCTL, ioctl); @@ -497,7 +499,7 @@ static int pd6729_set_mem_map(struct pcmcia_socket *sock, /* write the stop address */ - i= (mem->res->end >> 12) & 0x0fff; + i = (mem->res->end >> 12) & 0x0fff; switch (to_cycles(mem->speed)) { case 0: break; @@ -563,7 +565,7 @@ static int pd6729_init(struct pcmcia_socket *sock) /* the pccard structure and its functions */ static struct pccard_operations pd6729_operations = { - .init = pd6729_init, + .init = pd6729_init, .get_status = pd6729_get_status, .set_socket = pd6729_set_socket, .set_io_map = pd6729_set_io_map, @@ -578,8 +580,13 @@ static irqreturn_t pd6729_test(int irq, void *dev) static int pd6729_check_irq(int irq) { - if (request_irq(irq, pd6729_test, IRQF_PROBE_SHARED, "x", pd6729_test) - != 0) return -1; + int ret; + + ret = request_irq(irq, pd6729_test, IRQF_PROBE_SHARED, "x", + pd6729_test); + if (ret) + return -1; + free_irq(irq, pd6729_test); return 0; } @@ -591,7 +598,7 @@ static u_int __devinit pd6729_isa_scan(void) if (irq_mode == 1) { printk(KERN_INFO "pd6729: PCI card interrupts, " - "PCI status changes\n"); + "PCI status changes\n"); return 0; } @@ -607,9 +614,10 @@ static u_int __devinit pd6729_isa_scan(void) if (mask & (1<dev, "failed to kzalloc socket.\n"); return -ENOMEM; + } - if ((ret = pci_enable_device(dev))) + ret = pci_enable_device(dev); + if (ret) { + dev_warn(&dev->dev, "failed to enable pci_device.\n"); goto err_out_free_mem; + } if (!pci_resource_start(dev, 0)) { dev_warn(&dev->dev, "refusing to load the driver as the " @@ -639,7 +652,7 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev, dev_info(&dev->dev, "Cirrus PD6729 PCI to PCMCIA Bridge at 0x%llx " "on irq %d\n", (unsigned long long)pci_resource_start(dev, 0), dev->irq); - /* + /* * Since we have no memory BARs some firmware may not * have had PCI_COMMAND_MEMORY enabled, yet the device needs it. */ @@ -685,8 +698,9 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev, pci_set_drvdata(dev, socket); if (irq_mode == 1) { /* Register the interrupt handler */ - if ((ret = request_irq(dev->irq, pd6729_interrupt, IRQF_SHARED, - "pd6729", socket))) { + ret = request_irq(dev->irq, pd6729_interrupt, IRQF_SHARED, + "pd6729", socket); + if (ret) { dev_err(&dev->dev, "Failed to register irq %d\n", dev->irq); goto err_out_free_res; -- cgit v0.10.2 From 830ec0458c390f29c6c99e1ff7feab9e36368d12 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Thu, 18 Mar 2010 14:47:30 -0700 Subject: time: Fix accumulation bug triggered by long delay. The logarithmic accumulation done in the timekeeping has some overflow protection that limits the max shift value. That means it will take more then shift loops to accumulate all of the cycles. This causes the shift decrement to underflow, which causes the loop to never exit. The simplest fix would be simply to do a: if (shift) shift--; However that is not optimal, as we know the cycle offset is larger then the interval << shift, the above would make shift drop to zero, then we would be spinning for quite awhile accumulating at interval chunks at a time. Instead, this patch only decreases shift if the offset is smaller then cycle_interval << shift. This makes sure we accumulate using the largest chunks possible without overflowing tick_length, and limits the number of iterations through the loop. This issue was found and reported by Sonic Zhang, who also tested the fix. Many thanks your explanation and testing! Reported-by: Sonic Zhang Signed-off-by: John Stultz Tested-by: Sonic Zhang LKML-Reference: <1268948850-5225-1-git-send-email-johnstul@us.ibm.com> Signed-off-by: Thomas Gleixner diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 1673637..39f6177 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -818,7 +818,8 @@ void update_wall_time(void) shift = min(shift, maxshift); while (offset >= timekeeper.cycle_interval) { offset = logarithmic_accumulation(offset, shift); - shift--; + if(offset < timekeeper.cycle_interval< Date: Mon, 22 Mar 2010 19:33:43 +0900 Subject: nilfs2: fix imperfect completion wait in nilfs_wait_on_logs nilfs_wait_on_logs has a potential to slip out before completion of all bio requests when it met an error. This synchronization fault may cause unexpected results, for instance, violative access to freed segment buffers from an end-bio callback routine. This fixes the issue by ensuring that nilfs_wait_on_logs waits all given logs. Signed-off-by: Ryusuke Konishi diff --git a/fs/nilfs2/segbuf.c b/fs/nilfs2/segbuf.c index 636eaaf..6129a43 100644 --- a/fs/nilfs2/segbuf.c +++ b/fs/nilfs2/segbuf.c @@ -323,14 +323,14 @@ int nilfs_write_logs(struct list_head *logs, struct the_nilfs *nilfs) int nilfs_wait_on_logs(struct list_head *logs) { struct nilfs_segment_buffer *segbuf; - int err; + int err, ret = 0; list_for_each_entry(segbuf, logs, sb_list) { err = nilfs_segbuf_wait(segbuf); - if (err) - return err; + if (err && !ret) + ret = err; } - return 0; + return ret; } /* -- cgit v0.10.2 From 157f1071354db1aed885816094888e0e257c9d0a Mon Sep 17 00:00:00 2001 From: Tyler Hicks Date: Thu, 11 Feb 2010 07:10:38 -0600 Subject: eCryptfs: Fix metadata in xattr feature regression Fixes regression in 8faece5f906725c10e7a1f6caf84452abadbdc7b When using the ecryptfs_xattr_metadata mount option, eCryptfs stores the metadata (normally stored at the front of the file) in the user.ecryptfs xattr. This causes ecryptfs_crypt_stat.num_header_bytes_at_front to be 0, since there is no header data at the front of the file. This results in too much memory being requested and ENOMEM being returned from ecryptfs_write_metadata(). This patch fixes the problem by using the num_header_bytes_at_front variable for specifying the max size of the metadata, despite whether it is stored in the header or xattr. Reviewed-by: Eric Sandeen Signed-off-by: Tyler Hicks diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index 7cb0a59..c907f6f 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c @@ -381,8 +381,8 @@ out: static void ecryptfs_lower_offset_for_extent(loff_t *offset, loff_t extent_num, struct ecryptfs_crypt_stat *crypt_stat) { - (*offset) = (crypt_stat->num_header_bytes_at_front - + (crypt_stat->extent_size * extent_num)); + (*offset) = ecryptfs_lower_header_size(crypt_stat) + + (crypt_stat->extent_size * extent_num); } /** @@ -834,7 +834,8 @@ void ecryptfs_set_default_sizes(struct ecryptfs_crypt_stat *crypt_stat) set_extent_mask_and_shift(crypt_stat); crypt_stat->iv_bytes = ECRYPTFS_DEFAULT_IV_BYTES; if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) - crypt_stat->num_header_bytes_at_front = 0; + crypt_stat->num_header_bytes_at_front = + ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE; else { if (PAGE_CACHE_SIZE <= ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE) crypt_stat->num_header_bytes_at_front = diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index 542f625..8456f70 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h @@ -464,6 +464,14 @@ struct ecryptfs_daemon { extern struct mutex ecryptfs_daemon_hash_mux; +static inline size_t +ecryptfs_lower_header_size(struct ecryptfs_crypt_stat *crypt_stat) +{ + if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) + return 0; + return crypt_stat->num_header_bytes_at_front; +} + static inline struct ecryptfs_file_info * ecryptfs_file_to_private(struct file *file) { diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 4a430ab..1a73953 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -768,7 +768,7 @@ upper_size_to_lower_size(struct ecryptfs_crypt_stat *crypt_stat, { loff_t lower_size; - lower_size = crypt_stat->num_header_bytes_at_front; + lower_size = ecryptfs_lower_header_size(crypt_stat); if (upper_size != 0) { loff_t num_extents; diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index df4ce99..5a30e01 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c @@ -97,19 +97,6 @@ out: * (big-endian) * Octet 26: Begin RFC 2440 authentication token packet set */ -static void set_header_info(char *page_virt, - struct ecryptfs_crypt_stat *crypt_stat) -{ - size_t written; - size_t save_num_header_bytes_at_front = - crypt_stat->num_header_bytes_at_front; - - crypt_stat->num_header_bytes_at_front = - ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE; - ecryptfs_write_header_metadata(page_virt + 20, crypt_stat, &written); - crypt_stat->num_header_bytes_at_front = - save_num_header_bytes_at_front; -} /** * ecryptfs_copy_up_encrypted_with_header @@ -146,9 +133,13 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page, memset(page_virt, 0, PAGE_CACHE_SIZE); /* TODO: Support more than one header extent */ if (view_extent_num == 0) { + size_t written; + rc = ecryptfs_read_xattr_region( page_virt, page->mapping->host); - set_header_info(page_virt, crypt_stat); + ecryptfs_write_header_metadata(page_virt + 20, + crypt_stat, + &written); } kunmap_atomic(page_virt, KM_USER0); flush_dcache_page(page); -- cgit v0.10.2 From fa3ef1cb4e6e9958a9bfaa977c107c515907f102 Mon Sep 17 00:00:00 2001 From: Tyler Hicks Date: Thu, 11 Feb 2010 05:09:14 -0600 Subject: eCryptfs: Rename ecryptfs_crypt_stat.num_header_bytes_at_front This patch renames the num_header_bytes_at_front variable to metadata_size since it now contains the max size of the metadata. Reviewed-by: Eric Sandeen Signed-off-by: Tyler Hicks diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index c907f6f..391f558 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c @@ -834,14 +834,13 @@ void ecryptfs_set_default_sizes(struct ecryptfs_crypt_stat *crypt_stat) set_extent_mask_and_shift(crypt_stat); crypt_stat->iv_bytes = ECRYPTFS_DEFAULT_IV_BYTES; if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) - crypt_stat->num_header_bytes_at_front = - ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE; + crypt_stat->metadata_size = ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE; else { if (PAGE_CACHE_SIZE <= ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE) - crypt_stat->num_header_bytes_at_front = + crypt_stat->metadata_size = ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE; else - crypt_stat->num_header_bytes_at_front = PAGE_CACHE_SIZE; + crypt_stat->metadata_size = PAGE_CACHE_SIZE; } } @@ -1238,8 +1237,7 @@ ecryptfs_write_header_metadata(char *virt, header_extent_size = (u32)crypt_stat->extent_size; num_header_extents_at_front = - (u16)(crypt_stat->num_header_bytes_at_front - / crypt_stat->extent_size); + (u16)(crypt_stat->metadata_size / crypt_stat->extent_size); put_unaligned_be32(header_extent_size, virt); virt += 4; put_unaligned_be16(num_header_extents_at_front, virt); @@ -1382,7 +1380,7 @@ int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry) rc = -EINVAL; goto out; } - virt_len = crypt_stat->num_header_bytes_at_front; + virt_len = crypt_stat->metadata_size; order = get_order(virt_len); /* Released in this function */ virt = (char *)ecryptfs_get_zeroed_pages(GFP_KERNEL, order); @@ -1428,16 +1426,15 @@ static int parse_header_metadata(struct ecryptfs_crypt_stat *crypt_stat, header_extent_size = get_unaligned_be32(virt); virt += sizeof(__be32); num_header_extents_at_front = get_unaligned_be16(virt); - crypt_stat->num_header_bytes_at_front = - (((size_t)num_header_extents_at_front - * (size_t)header_extent_size)); + crypt_stat->metadata_size = (((size_t)num_header_extents_at_front + * (size_t)header_extent_size)); (*bytes_read) = (sizeof(__be32) + sizeof(__be16)); if ((validate_header_size == ECRYPTFS_VALIDATE_HEADER_SIZE) - && (crypt_stat->num_header_bytes_at_front + && (crypt_stat->metadata_size < ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE)) { rc = -EINVAL; printk(KERN_WARNING "Invalid header size: [%zd]\n", - crypt_stat->num_header_bytes_at_front); + crypt_stat->metadata_size); } return rc; } @@ -1452,8 +1449,7 @@ static int parse_header_metadata(struct ecryptfs_crypt_stat *crypt_stat, */ static void set_default_header_data(struct ecryptfs_crypt_stat *crypt_stat) { - crypt_stat->num_header_bytes_at_front = - ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE; + crypt_stat->metadata_size = ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE; } /** diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index 8456f70..d031efd 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h @@ -273,7 +273,7 @@ struct ecryptfs_crypt_stat { u32 flags; unsigned int file_version; size_t iv_bytes; - size_t num_header_bytes_at_front; + size_t metadata_size; size_t extent_size; /* Data extent size; default is 4096 */ size_t key_size; size_t extent_shift; @@ -469,7 +469,7 @@ ecryptfs_lower_header_size(struct ecryptfs_crypt_stat *crypt_stat) { if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) return 0; - return crypt_stat->num_header_bytes_at_front; + return crypt_stat->metadata_size; } static inline struct ecryptfs_file_info * diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 1a73953..a50efb1 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -335,7 +335,7 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, ecryptfs_dentry->d_sb)->mount_crypt_stat; if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) { if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) - file_size = (crypt_stat->num_header_bytes_at_front + file_size = (crypt_stat->metadata_size + i_size_read(lower_dentry->d_inode)); else file_size = i_size_read(lower_dentry->d_inode); diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index 5a30e01..270f42a 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c @@ -122,8 +122,7 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page, * num_extents_per_page) + extent_num_in_page); size_t num_header_extents_at_front = - (crypt_stat->num_header_bytes_at_front - / crypt_stat->extent_size); + (crypt_stat->metadata_size / crypt_stat->extent_size); if (view_extent_num < num_header_extents_at_front) { /* This is a header extent */ @@ -152,7 +151,7 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page, /* This is an encrypted data extent */ loff_t lower_offset = ((view_extent_num * crypt_stat->extent_size) - - crypt_stat->num_header_bytes_at_front); + - crypt_stat->metadata_size); rc = ecryptfs_read_lower_page_segment( page, (lower_offset >> PAGE_CACHE_SHIFT), -- cgit v0.10.2 From 1984c23f9e0cdb432d90a85ecf88b424d36878fc Mon Sep 17 00:00:00 2001 From: Tyler Hicks Date: Wed, 10 Feb 2010 23:17:44 -0600 Subject: eCryptfs: Clear buffer before reading in metadata xattr We initially read in the first PAGE_CACHE_SIZE of a file to if the eCryptfs header marker can be found. If it isn't found and ecryptfs_xattr_metadata was given as a mount option, then the user.ecryptfs xattr is read into the same buffer. Since the data from the first page of the file wasn't cleared, it is possible that we think we've found a second tag 3 or tag 1 packet and then error out after the packet contents aren't as expected. This patch clears the buffer before filling it with metadata from the user.ecryptfs xattr. Reviewed-by: Eric Sandeen Signed-off-by: Tyler Hicks diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index 391f558..4d9db0e 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c @@ -1603,6 +1603,7 @@ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry) ecryptfs_dentry, ECRYPTFS_VALIDATE_HEADER_SIZE); if (rc) { + memset(page_virt, 0, PAGE_CACHE_SIZE); rc = ecryptfs_read_xattr_region(page_virt, ecryptfs_inode); if (rc) { printk(KERN_DEBUG "Valid eCryptfs headers not found in " diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index a50efb1..ddbd096 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -323,6 +323,7 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, rc = ecryptfs_read_and_validate_header_region(page_virt, ecryptfs_dentry->d_inode); if (rc) { + memset(page_virt, 0, PAGE_CACHE_SIZE); rc = ecryptfs_read_and_validate_xattr_region(page_virt, ecryptfs_dentry); if (rc) { -- cgit v0.10.2 From f4e60e6b303bc46cdc477d3174dbf9cb5dd013aa Mon Sep 17 00:00:00 2001 From: Tyler Hicks Date: Thu, 11 Feb 2010 00:02:32 -0600 Subject: eCryptfs: Strip metadata in xattr flag in encrypted view The ecryptfs_encrypted_view mount option provides a unified way of viewing encrypted eCryptfs files. If the metadata is stored in a xattr, the metadata is moved to the file header when the file is read inside the eCryptfs mount. Because of this, we should strip the ECRYPTFS_METADATA_IN_XATTR flag from the header's flag section. This allows eCryptfs to treat the file as an eCryptfs file with a header at the front. Reviewed-by: Eric Sandeen Signed-off-by: Tyler Hicks diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index 4d9db0e..fad5bf6 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c @@ -1107,9 +1107,9 @@ static void write_ecryptfs_marker(char *page_virt, size_t *written) (*written) = MAGIC_ECRYPTFS_MARKER_SIZE_BYTES; } -static void -write_ecryptfs_flags(char *page_virt, struct ecryptfs_crypt_stat *crypt_stat, - size_t *written) +void ecryptfs_write_crypt_stat_flags(char *page_virt, + struct ecryptfs_crypt_stat *crypt_stat, + size_t *written) { u32 flags = 0; int i; @@ -1290,7 +1290,8 @@ static int ecryptfs_write_headers_virt(char *page_virt, size_t max, offset = ECRYPTFS_FILE_SIZE_BYTES; write_ecryptfs_marker((page_virt + offset), &written); offset += written; - write_ecryptfs_flags((page_virt + offset), crypt_stat, &written); + ecryptfs_write_crypt_stat_flags((page_virt + offset), crypt_stat, + &written); offset += written; ecryptfs_write_header_metadata((page_virt + offset), crypt_stat, &written); diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index d031efd..bc71154 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h @@ -659,6 +659,9 @@ int ecryptfs_decrypt_page(struct page *page); int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry); int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry); int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry); +void ecryptfs_write_crypt_stat_flags(char *page_virt, + struct ecryptfs_crypt_stat *crypt_stat, + size_t *written); int ecryptfs_read_and_validate_header_region(char *data, struct inode *ecryptfs_inode); int ecryptfs_read_and_validate_xattr_region(char *page_virt, diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index 270f42a..bea998a 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c @@ -82,6 +82,19 @@ out: return rc; } +static void strip_xattr_flag(char *page_virt, + struct ecryptfs_crypt_stat *crypt_stat) +{ + if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) { + size_t written; + + crypt_stat->flags &= ~ECRYPTFS_METADATA_IN_XATTR; + ecryptfs_write_crypt_stat_flags(page_virt, crypt_stat, + &written); + crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR; + } +} + /** * Header Extent: * Octets 0-7: Unencrypted file size (big-endian) @@ -136,6 +149,7 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page, rc = ecryptfs_read_xattr_region( page_virt, page->mapping->host); + strip_xattr_flag(page_virt + 16, crypt_stat); ecryptfs_write_header_metadata(page_virt + 20, crypt_stat, &written); -- cgit v0.10.2 From 9705c3961e73054b656720884f0da0a5a438fbae Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Mon, 8 Mar 2010 15:25:29 -0800 Subject: [ARM] Kirkwood: WPS button keycode mapping Commit "Input: add KEY_WPS_BUTTON definition" added a generic keycode for WPS button. Let's use it, instead of "F1" mapping. Signed-off-by: Christian Lamparter Signed-off-by: Nicolas Pitre diff --git a/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c b/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c index 0358f45..5e6f711 100644 --- a/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c +++ b/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c @@ -74,9 +74,9 @@ static struct gpio_keys_button mv88f6281gtw_ge_button_pins[] = { .desc = "SWR Button", .active_low = 1, }, { - .code = KEY_F1, + .code = KEY_WPS_BUTTON, .gpio = 46, - .desc = "WPS Button(F1)", + .desc = "WPS Button", .active_low = 1, }, }; -- cgit v0.10.2 From bb456928913fda2b360376afb13d9a0bc72c761c Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Mon, 8 Mar 2010 15:26:35 -0800 Subject: [ARM] Orion5x: replace KEY_WLAN with KEY_WPS_BUTTON "Input: add KEY_WPS_BUTTON definition" introduced a generic keycode for WPS input events. Signed-off-by: Christian Lamparter Signed-off-by: Nicolas Pitre diff --git a/arch/arm/mach-orion5x/wrt350n-v2-setup.c b/arch/arm/mach-orion5x/wrt350n-v2-setup.c index cb0feca..f9f222e 100644 --- a/arch/arm/mach-orion5x/wrt350n-v2-setup.c +++ b/arch/arm/mach-orion5x/wrt350n-v2-setup.c @@ -77,7 +77,7 @@ static struct gpio_keys_button wrt350n_v2_buttons[] = { .desc = "Reset Button", .active_low = 1, }, { - .code = KEY_WLAN, + .code = KEY_WPS_BUTTON, .gpio = 2, .desc = "WPS Button", .active_low = 1, -- cgit v0.10.2 From 9713ab28ec92d0c44b2ac5765dfc26c619d9cadd Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 23 Mar 2010 16:05:00 +0100 Subject: pcmcia: do not use ioports < 0x100 on x86 On x86 systems using ACPI _CRS information -- now the default for post-2008 systems -- the PCI root bus no longer pretends to be offering the root ioport_resource. To avoid accidentally hitting some platform / system device, use only I/O ports >= 0x100 for PCMCIA devices on x86. Reported-by: Komuro CC: Bjorn Helgaas Signed-off-by: Dominik Brodowski diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index 4663b3f..dcc6021 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c @@ -810,6 +810,13 @@ static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long unsigned long size = end - start + 1; int ret = 0; +#if defined(CONFIG_X86) + /* on x86, avoid anything < 0x100 for it is often used for + * legacy platform devices */ + if (start < 0x100) + start = 0x100; +#endif + if (end < start) return -EINVAL; -- cgit v0.10.2 From 6e6c822868f113dabe3c33bdd91e883cc28fa11b Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 17 Mar 2010 13:48:06 -0700 Subject: drm/i915: Stop trying to use ACPI lid status to determine LVDS connection. I've been getting more and more quirk reports about this. It seems clear at this point that other OSes are not using this for determining whether the integrated panel should be turned on, and it is not reliable for doing so. Better to light up an unintended panel than to not light up the only usable output on the system. Signed-off-by: Eric Anholt Acked-by: Jesse Barnes diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 14e516f..2b3fa7a 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -607,53 +607,6 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder, I915_WRITE(PFIT_CONTROL, lvds_priv->pfit_control); } -/* Some lid devices report incorrect lid status, assume they're connected */ -static const struct dmi_system_id bad_lid_status[] = { - { - .ident = "Compaq nx9020", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_BOARD_NAME, "3084"), - }, - }, - { - .ident = "Samsung SX20S", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Samsung Electronics"), - DMI_MATCH(DMI_BOARD_NAME, "SX20S"), - }, - }, - { - .ident = "Aspire One", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "Aspire one"), - }, - }, - { - .ident = "Aspire 1810T", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1810T"), - }, - }, - { - .ident = "PC-81005", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "MALATA"), - DMI_MATCH(DMI_PRODUCT_NAME, "PC-81005"), - }, - }, - { - .ident = "Clevo M5x0N", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "CLEVO Co."), - DMI_MATCH(DMI_BOARD_NAME, "M5x0N"), - }, - }, - { } -}; - /** * Detect the LVDS connection. * @@ -669,12 +622,9 @@ static enum drm_connector_status intel_lvds_detect(struct drm_connector *connect /* ACPI lid methods were generally unreliable in this generation, so * don't even bother. */ - if (IS_GEN2(dev)) + if (IS_GEN2(dev) || IS_GEN3(dev)) return connector_status_connected; - if (!dmi_check_system(bad_lid_status) && !acpi_lid_open()) - status = connector_status_disconnected; - return status; } -- cgit v0.10.2 From 8e039d84b323c4503c4d56863faa47c783660826 Mon Sep 17 00:00:00 2001 From: Ben Blum Date: Tue, 23 Mar 2010 05:24:03 +0000 Subject: cgroups: net_cls as module Allows the net_cls cgroup subsystem to be compiled as a module This patch modifies net/sched/cls_cgroup.c to allow the net_cls subsystem to be optionally compiled as a module instead of builtin. The cgroup_subsys struct is moved around a bit to allow the subsys_id to be either declared as a compile-time constant by the cgroup_subsys.h include in cgroup.h, or, if it's a module, initialized within the struct by cgroup_load_subsys. Signed-off-by: Ben Blum Acked-by: Li Zefan Cc: Paul Menage Cc: "David S. Miller" Cc: KAMEZAWA Hiroyuki Cc: Lai Jiangshan Signed-off-by: Andrew Morton Signed-off-by: David S. Miller diff --git a/net/sched/Kconfig b/net/sched/Kconfig index 21f9c76..2f691fb 100644 --- a/net/sched/Kconfig +++ b/net/sched/Kconfig @@ -328,13 +328,16 @@ config NET_CLS_FLOW module will be called cls_flow. config NET_CLS_CGROUP - bool "Control Group Classifier" + tristate "Control Group Classifier" select NET_CLS depends on CGROUPS ---help--- Say Y here if you want to classify packets based on the control cgroup of their process. + To compile this code as a module, choose M here: the + module will be called cls_cgroup. + config NET_EMATCH bool "Extended Matches" select NET_CLS diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c index e4877ca..7f27d2c 100644 --- a/net/sched/cls_cgroup.c +++ b/net/sched/cls_cgroup.c @@ -24,6 +24,25 @@ struct cgroup_cls_state u32 classid; }; +static struct cgroup_subsys_state *cgrp_create(struct cgroup_subsys *ss, + struct cgroup *cgrp); +static void cgrp_destroy(struct cgroup_subsys *ss, struct cgroup *cgrp); +static int cgrp_populate(struct cgroup_subsys *ss, struct cgroup *cgrp); + +struct cgroup_subsys net_cls_subsys = { + .name = "net_cls", + .create = cgrp_create, + .destroy = cgrp_destroy, + .populate = cgrp_populate, +#ifdef CONFIG_NET_CLS_CGROUP + .subsys_id = net_cls_subsys_id, +#else +#define net_cls_subsys_id net_cls_subsys.subsys_id +#endif + .module = THIS_MODULE, +}; + + static inline struct cgroup_cls_state *cgrp_cls_state(struct cgroup *cgrp) { return container_of(cgroup_subsys_state(cgrp, net_cls_subsys_id), @@ -79,14 +98,6 @@ static int cgrp_populate(struct cgroup_subsys *ss, struct cgroup *cgrp) return cgroup_add_files(cgrp, ss, ss_files, ARRAY_SIZE(ss_files)); } -struct cgroup_subsys net_cls_subsys = { - .name = "net_cls", - .create = cgrp_create, - .destroy = cgrp_destroy, - .populate = cgrp_populate, - .subsys_id = net_cls_subsys_id, -}; - struct cls_cgroup_head { u32 handle; @@ -277,12 +288,19 @@ static struct tcf_proto_ops cls_cgroup_ops __read_mostly = { static int __init init_cgroup_cls(void) { - return register_tcf_proto_ops(&cls_cgroup_ops); + int ret = register_tcf_proto_ops(&cls_cgroup_ops); + if (ret) + return ret; + ret = cgroup_load_subsys(&net_cls_subsys); + if (ret) + unregister_tcf_proto_ops(&cls_cgroup_ops); + return ret; } static void __exit exit_cgroup_cls(void) { unregister_tcf_proto_ops(&cls_cgroup_ops); + cgroup_unload_subsys(&net_cls_subsys); } module_init(init_cgroup_cls); -- cgit v0.10.2 From 4881a4f89a95cc5fef6d32953954bcc3443eefd5 Mon Sep 17 00:00:00 2001 From: Jens Rottmann Date: Tue, 23 Mar 2010 04:23:50 +0000 Subject: ksz884x: fix return value of netdev_set_eeprom ksz884x: fix return value of netdev_set_eeprom netdev_set_eeprom() confused ethtool by just returning 1 on error instead of a proper -EINVAL. Signed-off-by: Jens Rottmann Signed-off-by: David S. Miller diff --git a/drivers/net/ksz884x.c b/drivers/net/ksz884x.c index 0f59099..6c5327a 100644 --- a/drivers/net/ksz884x.c +++ b/drivers/net/ksz884x.c @@ -6322,7 +6322,7 @@ static int netdev_set_eeprom(struct net_device *dev, int len; if (eeprom->magic != EEPROM_MAGIC) - return 1; + return -EINVAL; len = (eeprom->offset + eeprom->len + 1) / 2; for (i = eeprom->offset / 2; i < len; i++) -- cgit v0.10.2 From 66f1207bce10fd80ee8ce99b67d617644612f05e Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 11 Mar 2010 17:01:09 -0700 Subject: resources: add interfaces that return conflict information request_resource() and insert_resource() only return success or failure, which no information about what existing resource conflicted with the proposed new reservation. This patch adds request_resource_conflict() and insert_resource_conflict(), which return the conflicting resource. Callers may use this for better error messages or to adjust the new resource and retry the request. Signed-off-by: Bjorn Helgaas Signed-off-by: Jesse Barnes diff --git a/include/linux/ioport.h b/include/linux/ioport.h index 71ab79d..26fad18 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h @@ -112,12 +112,14 @@ struct resource_list { extern struct resource ioport_resource; extern struct resource iomem_resource; +extern struct resource *request_resource_conflict(struct resource *root, struct resource *new); extern int request_resource(struct resource *root, struct resource *new); extern int release_resource(struct resource *new); void release_child_resources(struct resource *new); extern void reserve_region_with_split(struct resource *root, resource_size_t start, resource_size_t end, const char *name); +extern struct resource *insert_resource_conflict(struct resource *parent, struct resource *new); extern int insert_resource(struct resource *parent, struct resource *new); extern void insert_resource_expand_to_fit(struct resource *root, struct resource *new); extern int allocate_resource(struct resource *root, struct resource *new, diff --git a/kernel/resource.c b/kernel/resource.c index 2d5be5d..9c358e2 100644 --- a/kernel/resource.c +++ b/kernel/resource.c @@ -219,19 +219,34 @@ void release_child_resources(struct resource *r) } /** - * request_resource - request and reserve an I/O or memory resource + * request_resource_conflict - request and reserve an I/O or memory resource * @root: root resource descriptor * @new: resource descriptor desired by caller * - * Returns 0 for success, negative error code on error. + * Returns 0 for success, conflict resource on error. */ -int request_resource(struct resource *root, struct resource *new) +struct resource *request_resource_conflict(struct resource *root, struct resource *new) { struct resource *conflict; write_lock(&resource_lock); conflict = __request_resource(root, new); write_unlock(&resource_lock); + return conflict; +} + +/** + * request_resource - request and reserve an I/O or memory resource + * @root: root resource descriptor + * @new: resource descriptor desired by caller + * + * Returns 0 for success, negative error code on error. + */ +int request_resource(struct resource *root, struct resource *new) +{ + struct resource *conflict; + + conflict = request_resource_conflict(root, new); return conflict ? -EBUSY : 0; } @@ -474,25 +489,40 @@ static struct resource * __insert_resource(struct resource *parent, struct resou } /** - * insert_resource - Inserts a resource in the resource tree + * insert_resource_conflict - Inserts resource in the resource tree * @parent: parent of the new resource * @new: new resource to insert * - * Returns 0 on success, -EBUSY if the resource can't be inserted. + * Returns 0 on success, conflict resource if the resource can't be inserted. * - * This function is equivalent to request_resource when no conflict + * This function is equivalent to request_resource_conflict when no conflict * happens. If a conflict happens, and the conflicting resources * entirely fit within the range of the new resource, then the new * resource is inserted and the conflicting resources become children of * the new resource. */ -int insert_resource(struct resource *parent, struct resource *new) +struct resource *insert_resource_conflict(struct resource *parent, struct resource *new) { struct resource *conflict; write_lock(&resource_lock); conflict = __insert_resource(parent, new); write_unlock(&resource_lock); + return conflict; +} + +/** + * insert_resource - Inserts a resource in the resource tree + * @parent: parent of the new resource + * @new: new resource to insert + * + * Returns 0 on success, -EBUSY if the resource can't be inserted. + */ +int insert_resource(struct resource *parent, struct resource *new) +{ + struct resource *conflict; + + conflict = insert_resource_conflict(parent, new); return conflict ? -EBUSY : 0; } -- cgit v0.10.2 From b4414eea0e7b9c134262c801a87e338bf675962c Mon Sep 17 00:00:00 2001 From: Mark Fasheh Date: Thu, 11 Mar 2010 18:31:09 -0800 Subject: ocfs2: Clear undo bits when local alloc is freed When the local alloc file changes windows, unused bits are freed back to the global bitmap. By defnition, those bits can not be in use by any file. Also, the local alloc will never have been able to allocate those bits if they were part of a previous truncate. Therefore it makes sense that we should clear unused local alloc bits in the undo buffer so that they can be used immediatly. [ Modified to call it ocfs2_release_clusters() -- Joel ] Signed-off-by: Mark Fasheh Signed-off-by: Joel Becker diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c index 171c691..c983715 100644 --- a/fs/ocfs2/localalloc.c +++ b/fs/ocfs2/localalloc.c @@ -872,8 +872,10 @@ static int ocfs2_sync_local_to_main(struct ocfs2_super *osb, (unsigned long long)la_start_blk, (unsigned long long)blkno); - status = ocfs2_free_clusters(handle, main_bm_inode, - main_bm_bh, blkno, count); + status = ocfs2_release_clusters(handle, + main_bm_inode, + main_bm_bh, blkno, + count); if (status < 0) { mlog_errno(status); goto bail; diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h index 1238b49..adf5e2e 100644 --- a/fs/ocfs2/ocfs2.h +++ b/fs/ocfs2/ocfs2.h @@ -763,8 +763,18 @@ static inline unsigned int ocfs2_megabytes_to_clusters(struct super_block *sb, return megs << (20 - OCFS2_SB(sb)->s_clustersize_bits); } -#define ocfs2_set_bit ext2_set_bit -#define ocfs2_clear_bit ext2_clear_bit +static inline void _ocfs2_set_bit(unsigned int bit, unsigned long *bitmap) +{ + ext2_set_bit(bit, bitmap); +} +#define ocfs2_set_bit(bit, addr) _ocfs2_set_bit((bit), (unsigned long *)(addr)) + +static inline void _ocfs2_clear_bit(unsigned int bit, unsigned long *bitmap) +{ + ext2_clear_bit(bit, bitmap); +} +#define ocfs2_clear_bit(bit, addr) _ocfs2_clear_bit((bit), (unsigned long *)(addr)) + #define ocfs2_test_bit ext2_test_bit #define ocfs2_find_next_zero_bit ext2_find_next_zero_bit #define ocfs2_find_next_bit ext2_find_next_bit diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c index 0016503..19ba00f 100644 --- a/fs/ocfs2/suballoc.c +++ b/fs/ocfs2/suballoc.c @@ -95,13 +95,6 @@ static inline int ocfs2_block_group_set_bits(handle_t *handle, struct buffer_head *group_bh, unsigned int bit_off, unsigned int num_bits); -static inline int ocfs2_block_group_clear_bits(handle_t *handle, - struct inode *alloc_inode, - struct ocfs2_group_desc *bg, - struct buffer_head *group_bh, - unsigned int bit_off, - unsigned int num_bits); - static int ocfs2_relink_block_group(handle_t *handle, struct inode *alloc_inode, struct buffer_head *fe_bh, @@ -1978,18 +1971,18 @@ int ocfs2_claim_clusters(struct ocfs2_super *osb, bits_wanted, cluster_start, num_clusters); } -static inline int ocfs2_block_group_clear_bits(handle_t *handle, - struct inode *alloc_inode, - struct ocfs2_group_desc *bg, - struct buffer_head *group_bh, - unsigned int bit_off, - unsigned int num_bits) +static int ocfs2_block_group_clear_bits(handle_t *handle, + struct inode *alloc_inode, + struct ocfs2_group_desc *bg, + struct buffer_head *group_bh, + unsigned int bit_off, + unsigned int num_bits, + void (*undo_fn)(unsigned int bit, + unsigned long *bmap)) { int status; unsigned int tmp; - int journal_type = OCFS2_JOURNAL_ACCESS_WRITE; struct ocfs2_group_desc *undo_bg = NULL; - int cluster_bitmap = 0; mlog_entry_void(); @@ -1999,20 +1992,18 @@ static inline int ocfs2_block_group_clear_bits(handle_t *handle, mlog(0, "off = %u, num = %u\n", bit_off, num_bits); - if (ocfs2_is_cluster_bitmap(alloc_inode)) - journal_type = OCFS2_JOURNAL_ACCESS_UNDO; - + BUG_ON(undo_fn && !ocfs2_is_cluster_bitmap(alloc_inode)); status = ocfs2_journal_access_gd(handle, INODE_CACHE(alloc_inode), - group_bh, journal_type); + group_bh, + undo_fn ? + OCFS2_JOURNAL_ACCESS_UNDO : + OCFS2_JOURNAL_ACCESS_WRITE); if (status < 0) { mlog_errno(status); goto bail; } - if (ocfs2_is_cluster_bitmap(alloc_inode)) - cluster_bitmap = 1; - - if (cluster_bitmap) { + if (undo_fn) { jbd_lock_bh_state(group_bh); undo_bg = (struct ocfs2_group_desc *) bh2jh(group_bh)->b_committed_data; @@ -2023,13 +2014,13 @@ static inline int ocfs2_block_group_clear_bits(handle_t *handle, while(tmp--) { ocfs2_clear_bit((bit_off + tmp), (unsigned long *) bg->bg_bitmap); - if (cluster_bitmap) - ocfs2_set_bit(bit_off + tmp, - (unsigned long *) undo_bg->bg_bitmap); + if (undo_fn) + undo_fn(bit_off + tmp, + (unsigned long *) undo_bg->bg_bitmap); } le16_add_cpu(&bg->bg_free_bits_count, num_bits); - if (cluster_bitmap) + if (undo_fn) jbd_unlock_bh_state(group_bh); status = ocfs2_journal_dirty(handle, group_bh); @@ -2042,12 +2033,14 @@ bail: /* * expects the suballoc inode to already be locked. */ -int ocfs2_free_suballoc_bits(handle_t *handle, - struct inode *alloc_inode, - struct buffer_head *alloc_bh, - unsigned int start_bit, - u64 bg_blkno, - unsigned int count) +static int _ocfs2_free_suballoc_bits(handle_t *handle, + struct inode *alloc_inode, + struct buffer_head *alloc_bh, + unsigned int start_bit, + u64 bg_blkno, + unsigned int count, + void (*undo_fn)(unsigned int bit, + unsigned long *bitmap)) { int status = 0; u32 tmp_used; @@ -2082,7 +2075,7 @@ int ocfs2_free_suballoc_bits(handle_t *handle, status = ocfs2_block_group_clear_bits(handle, alloc_inode, group, group_bh, - start_bit, count); + start_bit, count, undo_fn); if (status < 0) { mlog_errno(status); goto bail; @@ -2113,6 +2106,17 @@ bail: return status; } +int ocfs2_free_suballoc_bits(handle_t *handle, + struct inode *alloc_inode, + struct buffer_head *alloc_bh, + unsigned int start_bit, + u64 bg_blkno, + unsigned int count) +{ + return _ocfs2_free_suballoc_bits(handle, alloc_inode, alloc_bh, + start_bit, bg_blkno, count, NULL); +} + int ocfs2_free_dinode(handle_t *handle, struct inode *inode_alloc_inode, struct buffer_head *inode_alloc_bh, @@ -2126,11 +2130,13 @@ int ocfs2_free_dinode(handle_t *handle, inode_alloc_bh, bit, bg_blkno, 1); } -int ocfs2_free_clusters(handle_t *handle, - struct inode *bitmap_inode, - struct buffer_head *bitmap_bh, - u64 start_blk, - unsigned int num_clusters) +static int _ocfs2_free_clusters(handle_t *handle, + struct inode *bitmap_inode, + struct buffer_head *bitmap_bh, + u64 start_blk, + unsigned int num_clusters, + void (*undo_fn)(unsigned int bit, + unsigned long *bitmap)) { int status; u16 bg_start_bit; @@ -2157,9 +2163,9 @@ int ocfs2_free_clusters(handle_t *handle, mlog(0, "bg_blkno = %llu, bg_start_bit = %u\n", (unsigned long long)bg_blkno, bg_start_bit); - status = ocfs2_free_suballoc_bits(handle, bitmap_inode, bitmap_bh, - bg_start_bit, bg_blkno, - num_clusters); + status = _ocfs2_free_suballoc_bits(handle, bitmap_inode, bitmap_bh, + bg_start_bit, bg_blkno, + num_clusters, undo_fn); if (status < 0) { mlog_errno(status); goto out; @@ -2173,6 +2179,32 @@ out: return status; } +int ocfs2_free_clusters(handle_t *handle, + struct inode *bitmap_inode, + struct buffer_head *bitmap_bh, + u64 start_blk, + unsigned int num_clusters) +{ + return _ocfs2_free_clusters(handle, bitmap_inode, bitmap_bh, + start_blk, num_clusters, + _ocfs2_set_bit); +} + +/* + * Give never-used clusters back to the global bitmap. We don't need + * to protect these bits in the undo buffer. + */ +int ocfs2_release_clusters(handle_t *handle, + struct inode *bitmap_inode, + struct buffer_head *bitmap_bh, + u64 start_blk, + unsigned int num_clusters) +{ + return _ocfs2_free_clusters(handle, bitmap_inode, bitmap_bh, + start_blk, num_clusters, + _ocfs2_clear_bit); +} + static inline void ocfs2_debug_bg(struct ocfs2_group_desc *bg) { printk("Block Group:\n"); diff --git a/fs/ocfs2/suballoc.h b/fs/ocfs2/suballoc.h index fa60723..e0f46df 100644 --- a/fs/ocfs2/suballoc.h +++ b/fs/ocfs2/suballoc.h @@ -127,6 +127,11 @@ int ocfs2_free_clusters(handle_t *handle, struct buffer_head *bitmap_bh, u64 start_blk, unsigned int num_clusters); +int ocfs2_release_clusters(handle_t *handle, + struct inode *bitmap_inode, + struct buffer_head *bitmap_bh, + u64 start_blk, + unsigned int num_clusters); static inline u64 ocfs2_which_suballoc_group(u64 block, unsigned int bit) { -- cgit v0.10.2 From 3939fda4b389993caf8741df5739b3e49f33a263 Mon Sep 17 00:00:00 2001 From: Tristan Ye Date: Fri, 19 Mar 2010 09:21:09 +0800 Subject: Ocfs2: Journaling i_flags and i_orphaned_slot when adding inode to orphan dir. Currently, some callers were missing to journal the dirty inode after adding it to orphan dir. Now we're going to journal such modifications within the ocfs2_orphan_add() itself, It's safe to do so, though some existing caller may duplicate this, and it makes the logic look more straightforward anyway. Signed-off-by: Tristan Ye Signed-off-by: Joel Becker diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index d9cd4e3..b1eb50a 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c @@ -84,7 +84,7 @@ static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb, static int ocfs2_orphan_add(struct ocfs2_super *osb, handle_t *handle, struct inode *inode, - struct ocfs2_dinode *fe, + struct buffer_head *fe_bh, char *name, struct ocfs2_dir_lookup_result *lookup, struct inode *orphan_dir_inode); @@ -879,7 +879,7 @@ static int ocfs2_unlink(struct inode *dir, fe = (struct ocfs2_dinode *) fe_bh->b_data; if (inode_is_unlinkable(inode)) { - status = ocfs2_orphan_add(osb, handle, inode, fe, orphan_name, + status = ocfs2_orphan_add(osb, handle, inode, fe_bh, orphan_name, &orphan_insert, orphan_dir); if (status < 0) { mlog_errno(status); @@ -1300,7 +1300,7 @@ static int ocfs2_rename(struct inode *old_dir, if (S_ISDIR(new_inode->i_mode) || (ocfs2_read_links_count(newfe) == 1)) { status = ocfs2_orphan_add(osb, handle, new_inode, - newfe, orphan_name, + newfe_bh, orphan_name, &orphan_insert, orphan_dir); if (status < 0) { mlog_errno(status); @@ -1911,7 +1911,7 @@ leave: static int ocfs2_orphan_add(struct ocfs2_super *osb, handle_t *handle, struct inode *inode, - struct ocfs2_dinode *fe, + struct buffer_head *fe_bh, char *name, struct ocfs2_dir_lookup_result *lookup, struct inode *orphan_dir_inode) @@ -1919,6 +1919,7 @@ static int ocfs2_orphan_add(struct ocfs2_super *osb, struct buffer_head *orphan_dir_bh = NULL; int status = 0; struct ocfs2_dinode *orphan_fe; + struct ocfs2_dinode *fe = (struct ocfs2_dinode *) fe_bh->b_data; mlog_entry("(inode->i_ino = %lu)\n", inode->i_ino); @@ -1959,6 +1960,21 @@ static int ocfs2_orphan_add(struct ocfs2_super *osb, goto leave; } + /* + * We're going to journal the change of i_flags and i_orphaned_slot. + * It's safe anyway, though some callers may duplicate the journaling. + * Journaling within the func just make the logic look more + * straightforward. + */ + status = ocfs2_journal_access_di(handle, + INODE_CACHE(inode), + fe_bh, + OCFS2_JOURNAL_ACCESS_WRITE); + if (status < 0) { + mlog_errno(status); + goto leave; + } + le32_add_cpu(&fe->i_flags, OCFS2_ORPHANED_FL); /* Record which orphan dir our inode now resides @@ -1966,6 +1982,8 @@ static int ocfs2_orphan_add(struct ocfs2_super *osb, * dir to lock. */ fe->i_orphaned_slot = cpu_to_le16(osb->slot_num); + ocfs2_journal_dirty(handle, fe_bh); + mlog(0, "Inode %llu orphaned in slot %d\n", (unsigned long long)OCFS2_I(inode)->ip_blkno, osb->slot_num); @@ -2123,7 +2141,7 @@ int ocfs2_create_inode_in_orphan(struct inode *dir, } di = (struct ocfs2_dinode *)new_di_bh->b_data; - status = ocfs2_orphan_add(osb, handle, inode, di, orphan_name, + status = ocfs2_orphan_add(osb, handle, inode, new_di_bh, orphan_name, &orphan_insert, orphan_dir); if (status < 0) { mlog_errno(status); -- cgit v0.10.2 From b54c2ca475fa7d7450a45b6d778dae9dbe0bcbfe Mon Sep 17 00:00:00 2001 From: Tristan Ye Date: Fri, 19 Mar 2010 09:21:10 +0800 Subject: Ocfs2: Handle deletion of reflinked oprhan inodes correctly. The rule is that all inodes in the orphan dir have ORPHANED_FL, otherwise we treated it as an ERROR. This rule works well except for some rare cases of reflink operation: http://oss.oracle.com/bugzilla/show_bug.cgi?id=1215 The problem is caused by how reflink and our orphan_scan thread interact. * The orphan scan pulls the orphans into a queue first, then runs the queue at a later time. We only hold the orphan_dir's lock during scanning. * Reflink create a oprhaned target in orphan_dir as its first step. It removes the target and clears the flag as the final step. These two steps take the orphan_dir's lock, but it is not held for the duration. Based on the above semantics, a reflink inode can be moved out of the orphan dir and have its ORPHANED_FL cleared before the queue of orphans is run. This leads to a ERROR in ocfs2_query_wipde_inode(). This patch teaches ocfs2_query_wipe_inode() to detect previously orphaned reflink targets. If a reflink fails or a crash occurs during the relfink operation, the inode will retain ORPHANED_FL and will be properly wiped. Signed-off-by: Tristan Ye Signed-off-by: Joel Becker diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index 278a223..ab20790 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c @@ -891,6 +891,21 @@ static int ocfs2_query_inode_wipe(struct inode *inode, /* Do some basic inode verification... */ di = (struct ocfs2_dinode *) di_bh->b_data; if (!(di->i_flags & cpu_to_le32(OCFS2_ORPHANED_FL))) { + /* + * Inodes in the orphan dir must have ORPHANED_FL. The only + * inodes that come back out of the orphan dir are reflink + * targets. A reflink target may be moved out of the orphan + * dir between the time we scan the directory and the time we + * process it. This would lead to HAS_REFCOUNT_FL being set but + * ORPHANED_FL not. + */ + if (di->i_dyn_features & cpu_to_le16(OCFS2_HAS_REFCOUNT_FL)) { + mlog(0, "Reflinked inode %llu is no longer orphaned. " + "it shouldn't be deleted\n", + (unsigned long long)oi->ip_blkno); + goto bail; + } + /* for lack of a better error? */ status = -EEXIST; mlog(ML_ERROR, -- cgit v0.10.2 From 14741472a05245ed5778aa0aec055e1f920b6ef8 Mon Sep 17 00:00:00 2001 From: Srinivas Eeda Date: Mon, 22 Mar 2010 16:50:47 -0700 Subject: ocfs2: Fix a race in o2dlm lockres mastery In o2dlm, the master of a lock resource keeps a map of all interested nodes. This prevents the master from purging the resource before an interested node can create a lock. A race between the mastery thread and the mastery handler allowed an interested node to discover who the master is without informing the master directly. This is easily fixed by holding the dlm spinlock a little longer in the mastery handler. Signed-off-by: Srinivas Eeda Signed-off-by: Joel Becker diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index a659606..9289b43 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c @@ -1875,7 +1875,6 @@ int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data, ok: spin_unlock(&res->spinlock); } - spin_unlock(&dlm->spinlock); // mlog(0, "woo! got an assert_master from node %u!\n", // assert->node_idx); @@ -1926,7 +1925,6 @@ ok: /* master is known, detach if not already detached. * ensures that only one assert_master call will happen * on this mle. */ - spin_lock(&dlm->spinlock); spin_lock(&dlm->master_lock); rr = atomic_read(&mle->mle_refs.refcount); @@ -1959,7 +1957,6 @@ ok: __dlm_put_mle(mle); } spin_unlock(&dlm->master_lock); - spin_unlock(&dlm->spinlock); } else if (res) { if (res->owner != assert->node_idx) { mlog(0, "assert_master from %u, but current " @@ -1967,6 +1964,7 @@ ok: res->owner, namelen, name); } } + spin_unlock(&dlm->spinlock); done: ret = 0; -- cgit v0.10.2 From 37f328eb60a94779dd020084209fc4db2d6444a0 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Wed, 24 Mar 2010 20:06:41 -0400 Subject: ext4: Fix spelling of CONTIG_FS_EXT3 to CONFIG_FS_EXT3 Oops. (Blush.) Thanks to Sedat Dilek for pointing this out. Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/super.c b/fs/ext4/super.c index ce84a6e..f4b038f 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -4068,7 +4068,7 @@ static int ext4_get_sb(struct file_system_type *fs_type, int flags, return get_sb_bdev(fs_type, flags, dev_name, data, ext4_fill_super,mnt); } -#if !defined(CONTIG_EXT2_FS) && !defined(CONFIG_EXT2_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23) +#if !defined(CONFIG_EXT2_FS) && !defined(CONFIG_EXT2_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23) static struct file_system_type ext2_fs_type = { .owner = THIS_MODULE, .name = "ext2", @@ -4095,7 +4095,7 @@ static inline void register_as_ext2(void) { } static inline void unregister_as_ext2(void) { } #endif -#if !defined(CONTIG_EXT3_FS) && !defined(CONFIG_EXT3_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23) +#if !defined(CONFIG_EXT3_FS) && !defined(CONFIG_EXT3_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23) static struct file_system_type ext3_fs_type = { .owner = THIS_MODULE, .name = "ext3", -- cgit v0.10.2 From ba69f9ab7df844125898104e854e063b47c26637 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Wed, 24 Mar 2010 20:18:37 -0400 Subject: ext4: Don't use delayed allocation by default when used instead of ext3 When ext4 driver is used to mount a filesystem instead of the ext3 file system driver (through CONFIG_EXT4_USE_FOR_EXT23), do not enable delayed allocation by default since some ext3 users and application writers have developed unfortunate expectations about the safety of writing files on systems subject to sudden and violent death without using fsync(). Signed-off-by: Jan Kara Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/super.c b/fs/ext4/super.c index f4b038f..29c6875 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -68,7 +68,21 @@ static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf); static int ext4_unfreeze(struct super_block *sb); static void ext4_write_super(struct super_block *sb); static int ext4_freeze(struct super_block *sb); +static int ext4_get_sb(struct file_system_type *fs_type, int flags, + const char *dev_name, void *data, struct vfsmount *mnt); +#if !defined(CONFIG_EXT3_FS) && !defined(CONFIG_EXT3_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23) +static struct file_system_type ext3_fs_type = { + .owner = THIS_MODULE, + .name = "ext3", + .get_sb = ext4_get_sb, + .kill_sb = kill_block_super, + .fs_flags = FS_REQUIRES_DEV, +}; +#define IS_EXT3_SB(sb) ((sb)->s_bdev->bd_holder == &ext3_fs_type) +#else +#define IS_EXT3_SB(sb) (0) +#endif ext4_fsblk_t ext4_block_bitmap(struct super_block *sb, struct ext4_group_desc *bg) @@ -2539,7 +2553,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) * enable delayed allocation by default * Use -o nodelalloc to turn it off */ - set_opt(sbi->s_mount_opt, DELALLOC); + if (!IS_EXT3_SB(sb)) + set_opt(sbi->s_mount_opt, DELALLOC); if (!parse_options((char *) data, sb, &journal_devnum, &journal_ioprio, NULL, 0)) @@ -4096,14 +4111,6 @@ static inline void unregister_as_ext2(void) { } #endif #if !defined(CONFIG_EXT3_FS) && !defined(CONFIG_EXT3_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23) -static struct file_system_type ext3_fs_type = { - .owner = THIS_MODULE, - .name = "ext3", - .get_sb = ext4_get_sb, - .kill_sb = kill_block_super, - .fs_flags = FS_REQUIRES_DEV, -}; - static inline void register_as_ext3(void) { int err = register_filesystem(&ext3_fs_type); -- cgit v0.10.2 From c4caae25187ff3f5e837c6f04eb1acc2723c72d3 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Tue, 23 Mar 2010 21:32:00 -0400 Subject: ext4: Fixed inode allocator to correctly track a flex_bg's used_dirs When used_dirs was introduced for the flex_groups struct, it looks like the accounting was not put into place properly, in some places manipulating free_inodes rather than used_dirs. Signed-off-by: Eric Sandeen Signed-off-by: "Theodore Ts'o" diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 361c0b9..57f6eef 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -263,7 +263,7 @@ void ext4_free_inode(handle_t *handle, struct inode *inode) ext4_group_t f; f = ext4_flex_group(sbi, block_group); - atomic_dec(&sbi->s_flex_groups[f].free_inodes); + atomic_dec(&sbi->s_flex_groups[f].used_dirs); } } @@ -773,7 +773,7 @@ static int ext4_claim_inode(struct super_block *sb, if (sbi->s_log_groups_per_flex) { ext4_group_t f = ext4_flex_group(sbi, group); - atomic_inc(&sbi->s_flex_groups[f].free_inodes); + atomic_inc(&sbi->s_flex_groups[f].used_dirs); } } gdp->bg_checksum = ext4_group_desc_csum(sbi, group, gdp); -- cgit v0.10.2 From 4327ba435a56ada13eedf3eb332e583c7a0586a9 Mon Sep 17 00:00:00 2001 From: Benjamin Li Date: Tue, 23 Mar 2010 13:13:11 +0000 Subject: bnx2: Fix netpoll crash. The bnx2 driver calls netif_napi_add() for all the NAPI structs during ->probe() time but not all of them will be used if we're not in MSI-X mode. This creates a problem for netpoll since it will poll all the NAPI structs in the dev_list whether or not they are scheduled, resulting in a crash when we access structure fields not initialized for that vector. We fix it by moving the netif_napi_add() call to ->open() after the number of IRQ vectors has been determined. Signed-off-by: Benjamin Li Signed-off-by: Michael Chan Signed-off-by: David S. Miller diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 381887b..417de1c 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -246,6 +246,8 @@ static const struct flash_spec flash_5709 = { MODULE_DEVICE_TABLE(pci, bnx2_pci_tbl); +static void bnx2_init_napi(struct bnx2 *bp); + static inline u32 bnx2_tx_avail(struct bnx2 *bp, struct bnx2_tx_ring_info *txr) { u32 diff; @@ -6197,6 +6199,7 @@ bnx2_open(struct net_device *dev) bnx2_disable_int(bp); bnx2_setup_int_mode(bp, disable_msi); + bnx2_init_napi(bp); bnx2_napi_enable(bp); rc = bnx2_alloc_mem(bp); if (rc) @@ -8207,7 +8210,7 @@ bnx2_init_napi(struct bnx2 *bp) { int i; - for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) { + for (i = 0; i < bp->irq_nvecs; i++) { struct bnx2_napi *bnapi = &bp->bnx2_napi[i]; int (*poll)(struct napi_struct *, int); @@ -8276,7 +8279,6 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) dev->ethtool_ops = &bnx2_ethtool_ops; bp = netdev_priv(dev); - bnx2_init_napi(bp); pci_set_drvdata(pdev, dev); -- cgit v0.10.2 From 1bf1e347ef254ed8a13e7971a30e1bf3983da3d1 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Tue, 23 Mar 2010 13:13:12 +0000 Subject: bnx2: Use proper handler during netpoll. Netpoll needs to call the proper handler depending on the IRQ mode and the vector. Signed-off-by: Michael Chan Signed-off-by: David S. Miller diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 417de1c..a257bab 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -7646,9 +7646,11 @@ poll_bnx2(struct net_device *dev) int i; for (i = 0; i < bp->irq_nvecs; i++) { - disable_irq(bp->irq_tbl[i].vector); - bnx2_interrupt(bp->irq_tbl[i].vector, &bp->bnx2_napi[i]); - enable_irq(bp->irq_tbl[i].vector); + struct bnx2_irq *irq = &bp->irq_tbl[i]; + + disable_irq(irq->vector); + irq->handler(irq->vector, &bp->bnx2_napi[i]); + enable_irq(irq->vector); } } #endif -- cgit v0.10.2 From fa3d9a6d55014b5bce5575aeab1cf711cff748ab Mon Sep 17 00:00:00 2001 From: Mitch Williams Date: Tue, 23 Mar 2010 18:34:38 +0000 Subject: igb: count Rx FIFO errors correctly Don't aggregate rx_no_buffer_count into rx_fifo_errors. RNBC counts packets that get queued temporarily in the adapter's FIFO. These packets are not dropped and are not errors. The correct counter is rx_missed_errors (MPC). Signed-off-by: Mitch Williams Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 45a0e4f..70dc03b 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -3963,7 +3963,7 @@ void igb_update_stats(struct igb_adapter *adapter) struct net_device_stats *net_stats = igb_get_stats(adapter->netdev); struct e1000_hw *hw = &adapter->hw; struct pci_dev *pdev = adapter->pdev; - u32 rnbc, reg; + u32 reg, mpc; u16 phy_tmp; int i; u64 bytes, packets; @@ -4021,7 +4021,9 @@ void igb_update_stats(struct igb_adapter *adapter) adapter->stats.symerrs += rd32(E1000_SYMERRS); adapter->stats.sec += rd32(E1000_SEC); - adapter->stats.mpc += rd32(E1000_MPC); + mpc = rd32(E1000_MPC); + adapter->stats.mpc += mpc; + net_stats->rx_fifo_errors += mpc; adapter->stats.scc += rd32(E1000_SCC); adapter->stats.ecol += rd32(E1000_ECOL); adapter->stats.mcc += rd32(E1000_MCC); @@ -4036,9 +4038,7 @@ void igb_update_stats(struct igb_adapter *adapter) adapter->stats.gptc += rd32(E1000_GPTC); adapter->stats.gotc += rd32(E1000_GOTCL); rd32(E1000_GOTCH); /* clear GOTCL */ - rnbc = rd32(E1000_RNBC); - adapter->stats.rnbc += rnbc; - net_stats->rx_fifo_errors += rnbc; + adapter->stats.rnbc += rd32(E1000_RNBC); adapter->stats.ruc += rd32(E1000_RUC); adapter->stats.rfc += rd32(E1000_RFC); adapter->stats.rjc += rd32(E1000_RJC); -- cgit v0.10.2 From d07f3e375f608e52a1f8958fbde105bb27b7629a Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Tue, 23 Mar 2010 18:34:57 +0000 Subject: igb: do not modify tx_queue_len on link speed change Previously the driver tweaked txqueuelen to avoid false Tx hang reports seen at half duplex. This had the effect of overriding user set values on link change/reset. Testing shows that adjusting only the timeout factor is sufficient to prevent Tx hang reports at half duplex. Based on e1000e patch by Franco Fichtner Signed-off-by: Emil Tantilov Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h index a177570..3b772b8 100644 --- a/drivers/net/igb/igb.h +++ b/drivers/net/igb/igb.h @@ -267,7 +267,6 @@ struct igb_adapter { /* TX */ struct igb_ring *tx_ring[16]; - unsigned long tx_queue_len; u32 tx_timeout_count; /* RX */ diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 70dc03b..e72760c 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -1105,9 +1105,6 @@ static void igb_configure(struct igb_adapter *adapter) struct igb_ring *ring = adapter->rx_ring[i]; igb_alloc_rx_buffers_adv(ring, igb_desc_unused(ring)); } - - - adapter->tx_queue_len = netdev->tx_queue_len; } /** @@ -1213,7 +1210,6 @@ void igb_down(struct igb_adapter *adapter) del_timer_sync(&adapter->watchdog_timer); del_timer_sync(&adapter->phy_info_timer); - netdev->tx_queue_len = adapter->tx_queue_len; netif_carrier_off(netdev); /* record the stats before reset*/ @@ -3106,17 +3102,13 @@ static void igb_watchdog_task(struct work_struct *work) ((ctrl & E1000_CTRL_RFCE) ? "RX" : ((ctrl & E1000_CTRL_TFCE) ? "TX" : "None"))); - /* tweak tx_queue_len according to speed/duplex and - * adjust the timeout factor */ - netdev->tx_queue_len = adapter->tx_queue_len; + /* adjust timeout factor according to speed/duplex */ adapter->tx_timeout_factor = 1; switch (adapter->link_speed) { case SPEED_10: - netdev->tx_queue_len = 10; adapter->tx_timeout_factor = 14; break; case SPEED_100: - netdev->tx_queue_len = 100; /* maybe add some timeout factor ? */ break; } -- cgit v0.10.2 From 31b24b955c3ebbb6f3008a6374e61cf7c05a193c Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 23 Mar 2010 18:35:18 +0000 Subject: igb: only use vlan_gro_receive if vlans are registered This change makes it so that vlan_gro_receive is only used if vlans have been registered to the adapter structure. Previously we were just sending all vlan tagged frames in via this function but this results in a null pointer dereference when vlans are not registered. [ This fixes bugzilla entry 15582 -Eric Dumazet] Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Acked-by: Eric Dumazet Signed-off-by: David S. Miller diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index e72760c..01c65c7 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -5102,7 +5102,7 @@ static void igb_receive_skb(struct igb_q_vector *q_vector, { struct igb_adapter *adapter = q_vector->adapter; - if (vlan_tag) + if (vlan_tag && adapter->vlgrp) vlan_gro_receive(&q_vector->napi, adapter->vlgrp, vlan_tag, skb); else -- cgit v0.10.2 From 1c583063a5c769fe2ec604752e383972c69e6d9b Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Wed, 24 Mar 2010 07:10:54 +0100 Subject: ALSA: cmipci: work around invalid PCM pointer When the CMI8738 FRAME2 register is read, the chip sometimes (probably when wrapping around) returns an invalid value that would be outside the programmed DMA buffer. This leads to an inconsistent PCM pointer that is likely to result in an underrun. To work around this, read the register multiple times until we get a valid value; the error state seems to be very short-lived. Signed-off-by: Clemens Ladisch Reported-and-tested-by: Matija Nalis Cc: Signed-off-by: Takashi Iwai diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index 1ded64e..329968e 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c @@ -941,13 +941,21 @@ static snd_pcm_uframes_t snd_cmipci_pcm_pointer(struct cmipci *cm, struct cmipci struct snd_pcm_substream *substream) { size_t ptr; - unsigned int reg; + unsigned int reg, rem, tries; + if (!rec->running) return 0; #if 1 // this seems better.. reg = rec->ch ? CM_REG_CH1_FRAME2 : CM_REG_CH0_FRAME2; - ptr = rec->dma_size - (snd_cmipci_read_w(cm, reg) + 1); - ptr >>= rec->shift; + for (tries = 0; tries < 3; tries++) { + rem = snd_cmipci_read_w(cm, reg); + if (rem < rec->dma_size) + goto ok; + } + printk(KERN_ERR "cmipci: invalid PCM pointer: %#x\n", rem); + return SNDRV_PCM_POS_XRUN; +ok: + ptr = (rec->dma_size - (rem + 1)) >> rec->shift; #else reg = rec->ch ? CM_REG_CH1_FRAME1 : CM_REG_CH0_FRAME1; ptr = snd_cmipci_read(cm, reg) - rec->offset; -- cgit v0.10.2 From 8a6d9b149f105f8bdfa8e42dd9753e45a1887a16 Mon Sep 17 00:00:00 2001 From: Ferenc Wagner Date: Wed, 24 Mar 2010 08:20:03 +0100 Subject: i2o: Remove the dangerous kobj_to_i2o_device macro This macro worked only when applied to variables named 'kobj'. While this could have been fixed by simply renaming the macro argument, a more type-safe replacement by an inline function would be preferred. However, nobody uses this macro, so it's simpler to just remove it. Signed-off-by: Ferenc Wagner Signed-off-by: Jens Axboe diff --git a/include/linux/i2o.h b/include/linux/i2o.h index 87018dc..9e7a12d 100644 --- a/include/linux/i2o.h +++ b/include/linux/i2o.h @@ -782,7 +782,6 @@ extern int i2o_exec_lct_get(struct i2o_controller *); #define to_i2o_driver(drv) container_of(drv,struct i2o_driver, driver) #define to_i2o_device(dev) container_of(dev, struct i2o_device, device) #define to_i2o_controller(dev) container_of(dev, struct i2o_controller, device) -#define kobj_to_i2o_device(kobj) to_i2o_device(container_of(kobj, struct device, kobj)) /** * i2o_out_to_virt - Turn an I2O message to a virtual address -- cgit v0.10.2 From 7d7ba8d31eb293016bc91a5c8fc36b21fd917265 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Wed, 24 Mar 2010 10:49:14 +0100 Subject: pcmcia: allow for four multifunction subdevices (again) Commit aa584ca4 broke what 6cf5be51 had already fixed: there may be four multifunction devices, but just two pseudo-multifunction devices per PCMCIA card. Signed-off-by: Dominik Brodowski diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index ad93ebd..52d33b2 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -509,8 +509,12 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu p_dev->device_no = (s->device_count++); mutex_unlock(&s->ops_mutex); - /* max of 2 devices per card */ - if (p_dev->device_no >= 2) + /* max of 2 PFC devices */ + if ((p_dev->device_no >= 2) && (function == 0)) + goto err_free; + + /* max of 4 devices overall */ + if (p_dev->device_no >= 4) goto err_free; p_dev->socket = s; -- cgit v0.10.2 From e7176a37d436a214f6a7727ea7986c654cbee8f0 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Mon, 15 Mar 2010 21:43:11 +0100 Subject: power: support _noirq actions on device types and classes The new-style dev_pm_ops provide callbacks for both IRQs enabled and disabled. However, the _noirq variants were only called for buses registered with a device, not for classes and types. In order to properly use dev_pm_ops in class pcmcia_socket_class, support _noirq actions also on classes and types. Signed-off-by: Dominik Brodowski Acked-by: Rafael J. Wysocki diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index d477f4d..941fcb8 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -439,8 +439,23 @@ static int device_resume_noirq(struct device *dev, pm_message_t state) if (dev->bus && dev->bus->pm) { pm_dev_dbg(dev, state, "EARLY "); error = pm_noirq_op(dev, dev->bus->pm, state); + if (error) + goto End; } + if (dev->type && dev->type->pm) { + pm_dev_dbg(dev, state, "EARLY type "); + error = pm_noirq_op(dev, dev->type->pm, state); + if (error) + goto End; + } + + if (dev->class && dev->class->pm) { + pm_dev_dbg(dev, state, "EARLY class "); + error = pm_noirq_op(dev, dev->class->pm, state); + } + +End: TRACE_RESUME(error); return error; } @@ -735,10 +750,26 @@ static int device_suspend_noirq(struct device *dev, pm_message_t state) { int error = 0; + if (dev->class && dev->class->pm) { + pm_dev_dbg(dev, state, "LATE class "); + error = pm_noirq_op(dev, dev->class->pm, state); + if (error) + goto End; + } + + if (dev->type && dev->type->pm) { + pm_dev_dbg(dev, state, "LATE type "); + error = pm_noirq_op(dev, dev->type->pm, state); + if (error) + goto End; + } + if (dev->bus && dev->bus->pm) { pm_dev_dbg(dev, state, "LATE "); error = pm_noirq_op(dev, dev->bus->pm, state); } + +End: return error; } -- cgit v0.10.2 From d7646f7632549124fe70fec8af834c7c1246f365 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Mon, 15 Mar 2010 21:46:34 +0100 Subject: pcmcia: use dev_pm_ops for class pcmcia_socket_class Instead of requiring PCMCIA socket drivers to call various functions during their (bus) resume and suspend functions, register an own dev_pm_ops for this class. This fixes several suspend/resume bugs seen on db1xxx-ss, and probably on some other socket drivers, too. With regard to the asymmetry with only _noirq suspend, but split up resume, please see bug 14334 and commit 9905d1b411946fb3 . Signed-off-by: Dominik Brodowski diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c index 5d22807..fb904f4 100644 --- a/drivers/pcmcia/at91_cf.c +++ b/drivers/pcmcia/at91_cf.c @@ -361,7 +361,6 @@ static int at91_cf_suspend(struct platform_device *pdev, pm_message_t mesg) struct at91_cf_socket *cf = platform_get_drvdata(pdev); struct at91_cf_data *board = cf->board; - pcmcia_socket_dev_suspend(&pdev->dev); if (device_may_wakeup(&pdev->dev)) { enable_irq_wake(board->det_pin); if (board->irq_pin) @@ -381,7 +380,6 @@ static int at91_cf_resume(struct platform_device *pdev) disable_irq_wake(board->irq_pin); } - pcmcia_socket_dev_resume(&pdev->dev); return 0; } diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c index 171c8a6..ac4d089 100644 --- a/drivers/pcmcia/au1000_generic.c +++ b/drivers/pcmcia/au1000_generic.c @@ -510,17 +510,6 @@ static int au1x00_drv_pcmcia_probe(struct platform_device *dev) return ret; } -static int au1x00_drv_pcmcia_suspend(struct platform_device *dev, - pm_message_t state) -{ - return pcmcia_socket_dev_suspend(&dev->dev); -} - -static int au1x00_drv_pcmcia_resume(struct platform_device *dev) -{ - return pcmcia_socket_dev_resume(&dev->dev); -} - static struct platform_driver au1x00_pcmcia_driver = { .driver = { .name = "au1x00-pcmcia", @@ -528,8 +517,6 @@ static struct platform_driver au1x00_pcmcia_driver = { }, .probe = au1x00_drv_pcmcia_probe, .remove = au1x00_drv_pcmcia_remove, - .suspend = au1x00_drv_pcmcia_suspend, - .resume = au1x00_drv_pcmcia_resume, }; diff --git a/drivers/pcmcia/bfin_cf_pcmcia.c b/drivers/pcmcia/bfin_cf_pcmcia.c index 2482ce7..93f9dde 100644 --- a/drivers/pcmcia/bfin_cf_pcmcia.c +++ b/drivers/pcmcia/bfin_cf_pcmcia.c @@ -300,16 +300,6 @@ static int __devexit bfin_cf_remove(struct platform_device *pdev) return 0; } -static int bfin_cf_suspend(struct platform_device *pdev, pm_message_t mesg) -{ - return pcmcia_socket_dev_suspend(&pdev->dev); -} - -static int bfin_cf_resume(struct platform_device *pdev) -{ - return pcmcia_socket_dev_resume(&pdev->dev); -} - static struct platform_driver bfin_cf_driver = { .driver = { .name = (char *)driver_name, @@ -317,8 +307,6 @@ static struct platform_driver bfin_cf_driver = { }, .probe = bfin_cf_probe, .remove = __devexit_p(bfin_cf_remove), - .suspend = bfin_cf_suspend, - .resume = bfin_cf_resume, }; static int __init bfin_cf_init(void) diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index e679e70..75ed866 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c @@ -76,65 +76,6 @@ DECLARE_RWSEM(pcmcia_socket_list_rwsem); EXPORT_SYMBOL(pcmcia_socket_list_rwsem); -/* - * Low-level PCMCIA socket drivers need to register with the PCCard - * core using pcmcia_register_socket. - * - * socket drivers are expected to use the following callbacks in their - * .drv struct: - * - pcmcia_socket_dev_suspend - * - pcmcia_socket_dev_resume - * These functions check for the appropriate struct pcmcia_soket arrays, - * and pass them to the low-level functions pcmcia_{suspend,resume}_socket - */ -static int socket_early_resume(struct pcmcia_socket *skt); -static int socket_late_resume(struct pcmcia_socket *skt); -static int socket_resume(struct pcmcia_socket *skt); -static int socket_suspend(struct pcmcia_socket *skt); - -static void pcmcia_socket_dev_run(struct device *dev, - int (*cb)(struct pcmcia_socket *)) -{ - struct pcmcia_socket *socket; - - down_read(&pcmcia_socket_list_rwsem); - list_for_each_entry(socket, &pcmcia_socket_list, socket_list) { - if (socket->dev.parent != dev) - continue; - mutex_lock(&socket->skt_mutex); - cb(socket); - mutex_unlock(&socket->skt_mutex); - } - up_read(&pcmcia_socket_list_rwsem); -} - -int pcmcia_socket_dev_suspend(struct device *dev) -{ - pcmcia_socket_dev_run(dev, socket_suspend); - return 0; -} -EXPORT_SYMBOL(pcmcia_socket_dev_suspend); - -void pcmcia_socket_dev_early_resume(struct device *dev) -{ - pcmcia_socket_dev_run(dev, socket_early_resume); -} -EXPORT_SYMBOL(pcmcia_socket_dev_early_resume); - -void pcmcia_socket_dev_late_resume(struct device *dev) -{ - pcmcia_socket_dev_run(dev, socket_late_resume); -} -EXPORT_SYMBOL(pcmcia_socket_dev_late_resume); - -int pcmcia_socket_dev_resume(struct device *dev) -{ - pcmcia_socket_dev_run(dev, socket_resume); - return 0; -} -EXPORT_SYMBOL(pcmcia_socket_dev_resume); - - struct pcmcia_socket *pcmcia_get_socket(struct pcmcia_socket *skt) { struct device *dev = get_device(&skt->dev); @@ -578,12 +519,18 @@ static int socket_early_resume(struct pcmcia_socket *skt) static int socket_late_resume(struct pcmcia_socket *skt) { + int ret; + mutex_lock(&skt->ops_mutex); skt->state &= ~SOCKET_SUSPEND; mutex_unlock(&skt->ops_mutex); - if (!(skt->state & SOCKET_PRESENT)) - return socket_insert(skt); + if (!(skt->state & SOCKET_PRESENT)) { + ret = socket_insert(skt); + if (ret == -ENODEV) + ret = 0; + return ret; + } if (skt->resume_status) { socket_shutdown(skt); @@ -919,11 +866,66 @@ static void pcmcia_release_socket_class(struct class *data) } +#ifdef CONFIG_PM + +static int __pcmcia_pm_op(struct device *dev, + int (*callback) (struct pcmcia_socket *skt)) +{ + struct pcmcia_socket *s = container_of(dev, struct pcmcia_socket, dev); + int ret; + + mutex_lock(&s->skt_mutex); + ret = callback(s); + mutex_unlock(&s->skt_mutex); + + return ret; +} + +static int pcmcia_socket_dev_suspend_noirq(struct device *dev) +{ + return __pcmcia_pm_op(dev, socket_suspend); +} + +static int pcmcia_socket_dev_resume_noirq(struct device *dev) +{ + return __pcmcia_pm_op(dev, socket_early_resume); +} + +static int pcmcia_socket_dev_resume(struct device *dev) +{ + return __pcmcia_pm_op(dev, socket_late_resume); +} + +static const struct dev_pm_ops pcmcia_socket_pm_ops = { + /* dev_resume may be called with IRQs enabled */ + SET_SYSTEM_SLEEP_PM_OPS(NULL, + pcmcia_socket_dev_resume) + + /* late suspend must be called with IRQs disabled */ + .suspend_noirq = pcmcia_socket_dev_suspend_noirq, + .freeze_noirq = pcmcia_socket_dev_suspend_noirq, + .poweroff_noirq = pcmcia_socket_dev_suspend_noirq, + + /* early resume must be called with IRQs disabled */ + .resume_noirq = pcmcia_socket_dev_resume_noirq, + .thaw_noirq = pcmcia_socket_dev_resume_noirq, + .restore_noirq = pcmcia_socket_dev_resume_noirq, +}; + +#define PCMCIA_SOCKET_CLASS_PM_OPS (&pcmcia_socket_pm_ops) + +#else /* CONFIG_PM */ + +#define PCMCIA_SOCKET_CLASS_PM_OPS NULL + +#endif /* CONFIG_PM */ + struct class pcmcia_socket_class = { .name = "pcmcia_socket", .dev_uevent = pcmcia_socket_uevent, .dev_release = pcmcia_release_socket, .class_release = pcmcia_release_socket_class, + .pm = PCMCIA_SOCKET_CLASS_PM_OPS, }; EXPORT_SYMBOL(pcmcia_socket_class); diff --git a/drivers/pcmcia/db1xxx_ss.c b/drivers/pcmcia/db1xxx_ss.c index 9254ab0..a520193 100644 --- a/drivers/pcmcia/db1xxx_ss.c +++ b/drivers/pcmcia/db1xxx_ss.c @@ -558,37 +558,10 @@ static int __devexit db1x_pcmcia_socket_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM -static int db1x_pcmcia_suspend(struct device *dev) -{ - return pcmcia_socket_dev_suspend(dev); -} - -static int db1x_pcmcia_resume(struct device *dev) -{ - return pcmcia_socket_dev_resume(dev); -} - -static struct dev_pm_ops db1x_pcmcia_pmops = { - .resume = db1x_pcmcia_resume, - .suspend = db1x_pcmcia_suspend, - .thaw = db1x_pcmcia_resume, - .freeze = db1x_pcmcia_suspend, -}; - -#define DB1XXX_SS_PMOPS &db1x_pcmcia_pmops - -#else - -#define DB1XXX_SS_PMOPS NULL - -#endif - static struct platform_driver db1x_pcmcia_socket_driver = { .driver = { .name = "db1xxx_pcmcia", .owner = THIS_MODULE, - .pm = DB1XXX_SS_PMOPS }, .probe = db1x_pcmcia_socket_probe, .remove = __devexit_p(db1x_pcmcia_socket_remove), diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c index f5da626..3003bb3 100644 --- a/drivers/pcmcia/i82092.c +++ b/drivers/pcmcia/i82092.c @@ -39,27 +39,11 @@ static struct pci_device_id i82092aa_pci_ids[] = { }; MODULE_DEVICE_TABLE(pci, i82092aa_pci_ids); -#ifdef CONFIG_PM -static int i82092aa_socket_suspend (struct pci_dev *dev, pm_message_t state) -{ - return pcmcia_socket_dev_suspend(&dev->dev); -} - -static int i82092aa_socket_resume (struct pci_dev *dev) -{ - return pcmcia_socket_dev_resume(&dev->dev); -} -#endif - static struct pci_driver i82092aa_pci_driver = { .name = "i82092aa", .id_table = i82092aa_pci_ids, .probe = i82092aa_pci_probe, .remove = __devexit_p(i82092aa_pci_remove), -#ifdef CONFIG_PM - .suspend = i82092aa_socket_suspend, - .resume = i82092aa_socket_resume, -#endif }; diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c index c13fd93..d53d9b5 100644 --- a/drivers/pcmcia/i82365.c +++ b/drivers/pcmcia/i82365.c @@ -1223,16 +1223,7 @@ static int pcic_init(struct pcmcia_socket *s) return 0; } -static int i82365_drv_pcmcia_suspend(struct platform_device *dev, - pm_message_t state) -{ - return pcmcia_socket_dev_suspend(&dev->dev); -} -static int i82365_drv_pcmcia_resume(struct platform_device *dev) -{ - return pcmcia_socket_dev_resume(&dev->dev); -} static struct pccard_operations pcic_operations = { .init = pcic_init, .get_status = pcic_get_status, @@ -1248,8 +1239,6 @@ static struct platform_driver i82365_driver = { .name = "i82365", .owner = THIS_MODULE, }, - .suspend = i82365_drv_pcmcia_suspend, - .resume = i82365_drv_pcmcia_resume, }; static struct platform_device *i82365_device; diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c index 0ece2cd..ab21264 100644 --- a/drivers/pcmcia/m32r_cfc.c +++ b/drivers/pcmcia/m32r_cfc.c @@ -685,16 +685,7 @@ static struct pccard_operations pcc_operations = { .set_mem_map = pcc_set_mem_map, }; -static int cfc_drv_pcmcia_suspend(struct platform_device *dev, - pm_message_t state) -{ - return pcmcia_socket_dev_suspend(&dev->dev); -} -static int cfc_drv_pcmcia_resume(struct platform_device *dev) -{ - return pcmcia_socket_dev_resume(&dev->dev); -} /*====================================================================*/ static struct platform_driver pcc_driver = { @@ -702,8 +693,6 @@ static struct platform_driver pcc_driver = { .name = "cfc", .owner = THIS_MODULE, }, - .suspend = cfc_drv_pcmcia_suspend, - .resume = cfc_drv_pcmcia_resume, }; static struct platform_device pcc_device = { diff --git a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c index 72844c5..0caf3db 100644 --- a/drivers/pcmcia/m32r_pcc.c +++ b/drivers/pcmcia/m32r_pcc.c @@ -663,16 +663,6 @@ static struct pccard_operations pcc_operations = { .set_mem_map = pcc_set_mem_map, }; -static int pcc_drv_pcmcia_suspend(struct platform_device *dev, - pm_message_t state) -{ - return pcmcia_socket_dev_suspend(&dev->dev); -} - -static int pcc_drv_pcmcia_resume(struct platform_device *dev) -{ - return pcmcia_socket_dev_resume(&dev->dev); -} /*====================================================================*/ static struct platform_driver pcc_driver = { @@ -680,8 +670,6 @@ static struct platform_driver pcc_driver = { .name = "pcc", .owner = THIS_MODULE, }, - .suspend = pcc_drv_pcmcia_suspend, - .resume = pcc_drv_pcmcia_resume, }; static struct platform_device pcc_device = { diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c index 61c2159..01ef7de 100644 --- a/drivers/pcmcia/m8xx_pcmcia.c +++ b/drivers/pcmcia/m8xx_pcmcia.c @@ -1288,21 +1288,6 @@ static int m8xx_remove(struct of_device *ofdev) return 0; } -#ifdef CONFIG_PM -static int m8xx_suspend(struct platform_device *pdev, pm_message_t state) -{ - return pcmcia_socket_dev_suspend(&pdev->dev); -} - -static int m8xx_resume(struct platform_device *pdev) -{ - return pcmcia_socket_dev_resume(&pdev->dev); -} -#else -#define m8xx_suspend NULL -#define m8xx_resume NULL -#endif - static const struct of_device_id m8xx_pcmcia_match[] = { { .type = "pcmcia", @@ -1318,8 +1303,6 @@ static struct of_platform_driver m8xx_pcmcia_driver = { .match_table = m8xx_pcmcia_match, .probe = m8xx_probe, .remove = m8xx_remove, - .suspend = m8xx_suspend, - .resume = m8xx_resume, }; static int __init m8xx_init(void) diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c index 3ef9915..9edc396 100644 --- a/drivers/pcmcia/omap_cf.c +++ b/drivers/pcmcia/omap_cf.c @@ -330,24 +330,12 @@ static int __exit omap_cf_remove(struct platform_device *pdev) return 0; } -static int omap_cf_suspend(struct platform_device *pdev, pm_message_t mesg) -{ - return pcmcia_socket_dev_suspend(&pdev->dev); -} - -static int omap_cf_resume(struct platform_device *pdev) -{ - return pcmcia_socket_dev_resume(&pdev->dev); -} - static struct platform_driver omap_cf_driver = { .driver = { .name = (char *) driver_name, .owner = THIS_MODULE, }, .remove = __exit_p(omap_cf_remove), - .suspend = omap_cf_suspend, - .resume = omap_cf_resume, }; static int __init omap_cf_init(void) diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c index 47f342f..4a34268 100644 --- a/drivers/pcmcia/pd6729.c +++ b/drivers/pcmcia/pd6729.c @@ -764,18 +764,6 @@ static void __devexit pd6729_pci_remove(struct pci_dev *dev) kfree(socket); } -#ifdef CONFIG_PM -static int pd6729_socket_suspend(struct pci_dev *dev, pm_message_t state) -{ - return pcmcia_socket_dev_suspend(&dev->dev); -} - -static int pd6729_socket_resume(struct pci_dev *dev) -{ - return pcmcia_socket_dev_resume(&dev->dev); -} -#endif - static struct pci_device_id pd6729_pci_ids[] = { { .vendor = PCI_VENDOR_ID_CIRRUS, @@ -792,10 +780,6 @@ static struct pci_driver pd6729_pci_driver = { .id_table = pd6729_pci_ids, .probe = pd6729_pci_probe, .remove = __devexit_p(pd6729_pci_remove), -#ifdef CONFIG_PM - .suspend = pd6729_socket_suspend, - .resume = pd6729_socket_resume, -#endif }; static int pd6729_module_init(void) diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c index 76e640b..0a876fa 100644 --- a/drivers/pcmcia/pxa2xx_base.c +++ b/drivers/pcmcia/pxa2xx_base.c @@ -325,19 +325,13 @@ static int pxa2xx_drv_pcmcia_remove(struct platform_device *dev) return 0; } -static int pxa2xx_drv_pcmcia_suspend(struct device *dev) -{ - return pcmcia_socket_dev_suspend(dev); -} - static int pxa2xx_drv_pcmcia_resume(struct device *dev) { pxa2xx_configure_sockets(dev); - return pcmcia_socket_dev_resume(dev); + return 0; } static const struct dev_pm_ops pxa2xx_drv_pcmcia_pm_ops = { - .suspend = pxa2xx_drv_pcmcia_suspend, .resume = pxa2xx_drv_pcmcia_resume, }; diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c index 8db86b9..5188962 100644 --- a/drivers/pcmcia/sa1100_generic.c +++ b/drivers/pcmcia/sa1100_generic.c @@ -95,17 +95,6 @@ static int sa11x0_drv_pcmcia_remove(struct platform_device *dev) return 0; } -static int sa11x0_drv_pcmcia_suspend(struct platform_device *dev, - pm_message_t state) -{ - return pcmcia_socket_dev_suspend(&dev->dev); -} - -static int sa11x0_drv_pcmcia_resume(struct platform_device *dev) -{ - return pcmcia_socket_dev_resume(&dev->dev); -} - static struct platform_driver sa11x0_pcmcia_driver = { .driver = { .name = "sa11x0-pcmcia", @@ -113,8 +102,6 @@ static struct platform_driver sa11x0_pcmcia_driver = { }, .probe = sa11x0_drv_pcmcia_probe, .remove = sa11x0_drv_pcmcia_remove, - .suspend = sa11x0_drv_pcmcia_suspend, - .resume = sa11x0_drv_pcmcia_resume, }; /* sa11x0_pcmcia_init() diff --git a/drivers/pcmcia/sa1111_generic.c b/drivers/pcmcia/sa1111_generic.c index db79ca6..799e979 100644 --- a/drivers/pcmcia/sa1111_generic.c +++ b/drivers/pcmcia/sa1111_generic.c @@ -213,16 +213,6 @@ static int __devexit pcmcia_remove(struct sa1111_dev *dev) return 0; } -static int pcmcia_suspend(struct sa1111_dev *dev, pm_message_t state) -{ - return pcmcia_socket_dev_suspend(&dev->dev); -} - -static int pcmcia_resume(struct sa1111_dev *dev) -{ - return pcmcia_socket_dev_resume(&dev->dev); -} - static struct sa1111_driver pcmcia_driver = { .drv = { .name = "sa1111-pcmcia", @@ -230,8 +220,6 @@ static struct sa1111_driver pcmcia_driver = { .devid = SA1111_DEVID_PCMCIA, .probe = pcmcia_probe, .remove = __devexit_p(pcmcia_remove), - .suspend = pcmcia_suspend, - .resume = pcmcia_resume, }; static int __init sa1111_drv_pcmcia_init(void) diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c index 12c49ee..bac85f3 100644 --- a/drivers/pcmcia/tcic.c +++ b/drivers/pcmcia/tcic.c @@ -348,16 +348,6 @@ static int __init get_tcic_id(void) return id; } -static int tcic_drv_pcmcia_suspend(struct platform_device *dev, - pm_message_t state) -{ - return pcmcia_socket_dev_suspend(&dev->dev); -} - -static int tcic_drv_pcmcia_resume(struct platform_device *dev) -{ - return pcmcia_socket_dev_resume(&dev->dev); -} /*====================================================================*/ static struct platform_driver tcic_driver = { @@ -365,8 +355,6 @@ static struct platform_driver tcic_driver = { .name = "tcic-pcmcia", .owner = THIS_MODULE, }, - .suspend = tcic_drv_pcmcia_suspend, - .resume = tcic_drv_pcmcia_resume, }; static struct platform_device tcic_device = { diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c index aaccdb9..86e4a1a 100644 --- a/drivers/pcmcia/vrc4171_card.c +++ b/drivers/pcmcia/vrc4171_card.c @@ -705,24 +705,11 @@ static int __devinit vrc4171_card_setup(char *options) __setup("vrc4171_card=", vrc4171_card_setup); -static int vrc4171_card_suspend(struct platform_device *dev, - pm_message_t state) -{ - return pcmcia_socket_dev_suspend(&dev->dev); -} - -static int vrc4171_card_resume(struct platform_device *dev) -{ - return pcmcia_socket_dev_resume(&dev->dev); -} - static struct platform_driver vrc4171_card_driver = { .driver = { .name = vrc4171_card_name, .owner = THIS_MODULE, }, - .suspend = vrc4171_card_suspend, - .resume = vrc4171_card_resume, }; static int __devinit vrc4171_card_init(void) diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index 418988a..f19ad02 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c @@ -1290,12 +1290,9 @@ static int yenta_dev_suspend_noirq(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct yenta_socket *socket = pci_get_drvdata(pdev); - int ret; - - ret = pcmcia_socket_dev_suspend(dev); if (!socket) - return ret; + return 0; if (socket->type && socket->type->save_state) socket->type->save_state(socket); @@ -1312,7 +1309,7 @@ static int yenta_dev_suspend_noirq(struct device *dev) */ /* pci_set_power_state(dev, 3); */ - return ret; + return 0; } static int yenta_dev_resume_noirq(struct device *dev) @@ -1336,26 +1333,16 @@ static int yenta_dev_resume_noirq(struct device *dev) if (socket->type && socket->type->restore_state) socket->type->restore_state(socket); - pcmcia_socket_dev_early_resume(dev); - return 0; -} - -static int yenta_dev_resume(struct device *dev) -{ - pcmcia_socket_dev_late_resume(dev); return 0; } static const struct dev_pm_ops yenta_pm_ops = { .suspend_noirq = yenta_dev_suspend_noirq, .resume_noirq = yenta_dev_resume_noirq, - .resume = yenta_dev_resume, .freeze_noirq = yenta_dev_suspend_noirq, .thaw_noirq = yenta_dev_resume_noirq, - .thaw = yenta_dev_resume, .poweroff_noirq = yenta_dev_suspend_noirq, .restore_noirq = yenta_dev_resume_noirq, - .restore = yenta_dev_resume, }; #define YENTA_PM_OPS (¥ta_pm_ops) diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h index 32896a7..2e488b6 100644 --- a/include/pcmcia/ss.h +++ b/include/pcmcia/ss.h @@ -277,12 +277,6 @@ extern struct pccard_resource_ops pccard_nonstatic_ops; #endif -/* socket drivers are expected to use these callbacks in their .drv struct */ -extern int pcmcia_socket_dev_suspend(struct device *dev); -extern void pcmcia_socket_dev_early_resume(struct device *dev); -extern void pcmcia_socket_dev_late_resume(struct device *dev); -extern int pcmcia_socket_dev_resume(struct device *dev); - /* socket drivers use this callback in their IRQ handler */ extern void pcmcia_parse_events(struct pcmcia_socket *socket, unsigned int events); -- cgit v0.10.2 From 92fe31329cb3a2b02f1c7616965872d6a34bcf08 Mon Sep 17 00:00:00 2001 From: Michael Holzheu Date: Wed, 24 Mar 2010 11:49:50 +0100 Subject: [S390] zcore: CPU registers are not saved under LPAR To save the registers for all CPUs a sigp "store status" is done that stores the registers to address absolute zero. To access storage at absolute zero, normally the address of the prefix register of the accessing CPU has to be used. This does not work when large pages are active (currently only under LPAR). In order to fix that problem, instead of memcpy memcpy_real is used, which switches to real mode where prefixing works. Signed-off-by: Michael Holzheu Signed-off-by: Martin Schwidefsky diff --git a/arch/s390/include/asm/system.h b/arch/s390/include/asm/system.h index 67ee6c3..12be42b 100644 --- a/arch/s390/include/asm/system.h +++ b/arch/s390/include/asm/system.h @@ -110,6 +110,7 @@ extern void pfault_fini(void); #endif /* CONFIG_PFAULT */ extern void cmma_init(void); +extern int memcpy_real(void *, void *, size_t); #define finish_arch_switch(prev) do { \ set_fs(current->thread.mm_segment); \ diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 29f65bc..d7d24fc 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -292,9 +292,9 @@ static void __init smp_get_save_area(unsigned int cpu, unsigned int phy_cpu) zfcpdump_save_areas[cpu] = kmalloc(sizeof(struct save_area), GFP_KERNEL); while (raw_sigp(phy_cpu, sigp_stop_and_store_status) == sigp_busy) cpu_relax(); - memcpy(zfcpdump_save_areas[cpu], - (void *)(unsigned long) store_prefix() + SAVE_AREA_BASE, - sizeof(struct save_area)); + memcpy_real(zfcpdump_save_areas[cpu], + (void *)(unsigned long) store_prefix() + SAVE_AREA_BASE, + sizeof(struct save_area)); } struct save_area *zfcpdump_save_areas[NR_CPUS + 1]; diff --git a/arch/s390/mm/maccess.c b/arch/s390/mm/maccess.c index 8175627..a8c2af8 100644 --- a/arch/s390/mm/maccess.c +++ b/arch/s390/mm/maccess.c @@ -59,3 +59,29 @@ long probe_kernel_write(void *dst, void *src, size_t size) } return copied < 0 ? -EFAULT : 0; } + +int memcpy_real(void *dest, void *src, size_t count) +{ + register unsigned long _dest asm("2") = (unsigned long) dest; + register unsigned long _len1 asm("3") = (unsigned long) count; + register unsigned long _src asm("4") = (unsigned long) src; + register unsigned long _len2 asm("5") = (unsigned long) count; + unsigned long flags; + int rc = -EFAULT; + + if (!count) + return 0; + flags = __raw_local_irq_stnsm(0xf8UL); + asm volatile ( + "0: mvcle %1,%2,0x0\n" + "1: jo 0b\n" + " lhi %0,0x0\n" + "2:\n" + EX_TABLE(1b,2b) + : "+d" (rc), "+d" (_dest), "+d" (_src), "+d" (_len1), + "+d" (_len2), "=m" (*((long *) dest)) + : "m" (*((long *) src)) + : "cc", "memory"); + __raw_local_irq_ssm(flags); + return rc; +} diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c index 3438658..3166d85 100644 --- a/drivers/s390/char/zcore.c +++ b/drivers/s390/char/zcore.c @@ -141,33 +141,6 @@ static int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count) return memcpy_hsa(dest, src, count, TO_KERNEL); } -static int memcpy_real(void *dest, unsigned long src, size_t count) -{ - unsigned long flags; - int rc = -EFAULT; - register unsigned long _dest asm("2") = (unsigned long) dest; - register unsigned long _len1 asm("3") = (unsigned long) count; - register unsigned long _src asm("4") = src; - register unsigned long _len2 asm("5") = (unsigned long) count; - - if (count == 0) - return 0; - flags = __raw_local_irq_stnsm(0xf8UL); /* switch to real mode */ - asm volatile ( - "0: mvcle %1,%2,0x0\n" - "1: jo 0b\n" - " lhi %0,0x0\n" - "2:\n" - EX_TABLE(1b,2b) - : "+d" (rc), "+d" (_dest), "+d" (_src), "+d" (_len1), - "+d" (_len2), "=m" (*((long*)dest)) - : "m" (*((long*)src)) - : "cc", "memory"); - __raw_local_irq_ssm(flags); - - return rc; -} - static int memcpy_real_user(void __user *dest, unsigned long src, size_t count) { static char buf[4096]; @@ -175,7 +148,7 @@ static int memcpy_real_user(void __user *dest, unsigned long src, size_t count) while (offs < count) { size = min(sizeof(buf), count - offs); - if (memcpy_real(buf, src + offs, size)) + if (memcpy_real(buf, (void *) src + offs, size)) return -EFAULT; if (copy_to_user(dest + offs, buf, size)) return -EFAULT; @@ -663,7 +636,7 @@ static int __init zcore_reipl_init(void) if (ipib_info.ipib < ZFCPDUMP_HSA_SIZE) rc = memcpy_hsa_kernel(ipl_block, ipib_info.ipib, PAGE_SIZE); else - rc = memcpy_real(ipl_block, ipib_info.ipib, PAGE_SIZE); + rc = memcpy_real(ipl_block, (void *) ipib_info.ipib, PAGE_SIZE); if (rc) { free_page((unsigned long) ipl_block); return rc; -- cgit v0.10.2 From a08786568a7e334d8a07a7bb8f4fafa3f7afb89c Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 24 Mar 2010 11:49:51 +0100 Subject: [S390] smp: fix lowcore allocation The intermediate lowcore for CONFIG_SMP is allocated using a call to __alloc_bootmem() with a goal of 0. That however doesn't guarantee that the allocated piece of memory is below 2GB. Instead we should call __alloc_bootmem_low(). Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 77a63ae..ba363d9 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -401,7 +401,7 @@ setup_lowcore(void) * Setup lowcore for boot cpu */ BUILD_BUG_ON(sizeof(struct _lowcore) != LC_PAGES * 4096); - lc = __alloc_bootmem(LC_PAGES * PAGE_SIZE, LC_PAGES * PAGE_SIZE, 0); + lc = __alloc_bootmem_low(LC_PAGES * PAGE_SIZE, LC_PAGES * PAGE_SIZE, 0); lc->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY; lc->restart_psw.addr = PSW_ADDR_AMODE | (unsigned long) restart_int_handler; @@ -433,7 +433,7 @@ setup_lowcore(void) #ifndef CONFIG_64BIT if (MACHINE_HAS_IEEE) { lc->extended_save_area_addr = (__u32) - __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0); + __alloc_bootmem_low(PAGE_SIZE, PAGE_SIZE, 0); /* enable extended save area */ __ctl_set_bit(14, 29); } -- cgit v0.10.2 From 1bff779285f89cd0b62955c20cca70ada4074236 Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Wed, 24 Mar 2010 11:49:52 +0100 Subject: [S390] system.h: Fix compile error for 1 and 2 byte cmpxchg commit 024914477e15ef8b17f271ec47f1bb8a589f0806 "memcg: move charges of anonymous swap" revealed that the 1 byte and 2 byte cmpxchg is currently broken: arch/s390/include/asm/system.h: Assembler messages: arch/s390/include/asm/system.h:241: Error: junk at end of line: `(%r5)' make[1]: *** [mm/page_cgroup.o] Error 1 make[1]: *** Waiting for unfinished jobs.... It turned out that commit 987bcdacb18a3adc2a48d85c9b005069c2f4dd7b ([S390] use inline assembly contraints available with gcc 3.3.3) broke the inline assembly. The or operands are now in constraint 3 and 4 instead of 2 and 3. Signed-off-by: Christian Borntraeger Signed-off-by: Martin Schwidefsky diff --git a/arch/s390/include/asm/system.h b/arch/s390/include/asm/system.h index 12be42b..1741c15 100644 --- a/arch/s390/include/asm/system.h +++ b/arch/s390/include/asm/system.h @@ -219,8 +219,8 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) " l %0,%2\n" "0: nr %0,%5\n" " lr %1,%0\n" - " or %0,%2\n" - " or %1,%3\n" + " or %0,%3\n" + " or %1,%4\n" " cs %0,%1,%2\n" " jnl 1f\n" " xr %1,%0\n" @@ -240,8 +240,8 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) " l %0,%2\n" "0: nr %0,%5\n" " lr %1,%0\n" - " or %0,%2\n" - " or %1,%3\n" + " or %0,%3\n" + " or %1,%4\n" " cs %0,%1,%2\n" " jnl 1f\n" " xr %1,%0\n" -- cgit v0.10.2 From 4a31ba57cae853ce1ac00a22c0f5d80bd36685ed Mon Sep 17 00:00:00 2001 From: Stefan Weinhuber Date: Wed, 24 Mar 2010 11:49:53 +0100 Subject: [S390] dasd: fix alignment of transport mode recovery TCW All TCWs need to be aligned on a 64 byte boundary or the I/O will be rejected. For recovery requests we create fresh TCWs, so we need to do the proper alignment here as well. Signed-off-by: Stefan Weinhuber Signed-off-by: Martin Schwidefsky diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c index 51224f7..b3736b8 100644 --- a/drivers/s390/block/dasd_3990_erp.c +++ b/drivers/s390/block/dasd_3990_erp.c @@ -2287,7 +2287,8 @@ static struct dasd_ccw_req *dasd_3990_erp_add_erp(struct dasd_ccw_req *cqr) if (cqr->cpmode == 1) { cplength = 0; - datasize = sizeof(struct tcw) + sizeof(struct tsb); + /* TCW needs to be 64 byte aligned, so leave enough room */ + datasize = 64 + sizeof(struct tcw) + sizeof(struct tsb); } else { cplength = 2; datasize = 0; @@ -2316,8 +2317,8 @@ static struct dasd_ccw_req *dasd_3990_erp_add_erp(struct dasd_ccw_req *cqr) if (cqr->cpmode == 1) { /* make a shallow copy of the original tcw but set new tsb */ erp->cpmode = 1; - erp->cpaddr = erp->data; - tcw = erp->data; + erp->cpaddr = PTR_ALIGN(erp->data, 64); + tcw = erp->cpaddr; tsb = (struct tsb *) &tcw[1]; *tcw = *((struct tcw *)cqr->cpaddr); tcw->tsb = (long)tsb; -- cgit v0.10.2 From b8fde7224d771ce55bfd67cb57d7c4c8f430972f Mon Sep 17 00:00:00 2001 From: Stefan Haberland Date: Wed, 24 Mar 2010 11:49:54 +0100 Subject: [S390] dasd: check tsb validity Check tsb validity before the tcw_get_tsb function is called. Signed-off-by: Stefan Haberland Signed-off-by: Martin Schwidefsky diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 01f4e7a..0cb2331 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c @@ -3155,11 +3155,11 @@ static void dasd_eckd_dump_sense_tcw(struct dasd_device *device, tsb = NULL; sense = NULL; - if (irb->scsw.tm.tcw) + if (irb->scsw.tm.tcw && (irb->scsw.tm.fcxs == 0x01)) tsb = tcw_get_tsb( (struct tcw *)(unsigned long)irb->scsw.tm.tcw); - if (tsb && (irb->scsw.tm.fcxs == 0x01)) { + if (tsb) { len += sprintf(page + len, KERN_ERR PRINTK_HEADER " tsb->length %d\n", tsb->length); len += sprintf(page + len, KERN_ERR PRINTK_HEADER -- cgit v0.10.2 From 9c95258c0d5911ae263bf50d854e402ce973ab32 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 24 Mar 2010 11:49:55 +0100 Subject: [S390] sclp: avoid 64 bit division Avoid 64 bit division to fix this compile error on 32 bit: drivers/s390/char/sclp_cmd.c:711: undefined reference to `__udivdi3' Also move the whole arch_get_memory_phys_device function to the memory hotplug related functions. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c index fc7ae05..4b60ede 100644 --- a/drivers/s390/char/sclp_cmd.c +++ b/drivers/s390/char/sclp_cmd.c @@ -308,6 +308,13 @@ struct assign_storage_sccb { u16 rn; } __packed; +int arch_get_memory_phys_device(unsigned long start_pfn) +{ + if (!rzm) + return 0; + return PFN_PHYS(start_pfn) >> ilog2(rzm); +} + static unsigned long long rn2addr(u16 rn) { return (unsigned long long) (rn - 1) * rzm; @@ -704,13 +711,6 @@ int sclp_chp_deconfigure(struct chp_id chpid) return do_chp_configure(SCLP_CMDW_DECONFIGURE_CHPATH | chpid.id << 8); } -int arch_get_memory_phys_device(unsigned long start_pfn) -{ - if (!rzm) - return 0; - return PFN_PHYS(start_pfn) / rzm; -} - struct chp_info_sccb { struct sccb_header header; u8 recognized[SCLP_CHP_INFO_MASK_SIZE]; -- cgit v0.10.2 From 7b26d82f5ea7de5667f87bb5ac6570111d7bff9f Mon Sep 17 00:00:00 2001 From: Hans-Joachim Picht Date: Wed, 24 Mar 2010 11:49:56 +0100 Subject: [S390] fix broken proc interface for sclp_async This patch now allows the use of the proc interface to either activate or deactivate call home on panic. e.g. echo 1 > /proc/sys/kernel/callhome strict_strtoul() requires _either_'\n\0' _or_ '\0' termination. This was missing and therefore the interface did not recognise valid input. Signed-off-by: Hans-Joachim Picht Signed-off-by: Martin Schwidefsky diff --git a/drivers/s390/char/sclp_async.c b/drivers/s390/char/sclp_async.c index 740fe40..f449c69 100644 --- a/drivers/s390/char/sclp_async.c +++ b/drivers/s390/char/sclp_async.c @@ -84,6 +84,7 @@ static int proc_handler_callhome(struct ctl_table *ctl, int write, rc = copy_from_user(buf, buffer, sizeof(buf)); if (rc != 0) return -EFAULT; + buf[len - 1] = '\0'; if (strict_strtoul(buf, 0, &val) != 0) return -EINVAL; if (val != 0 && val != 1) -- cgit v0.10.2 From 06c0dd72aea3985d0ea036f771ebb1d1083bf69f Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Wed, 24 Mar 2010 11:49:57 +0100 Subject: [S390] fix boot failures with compressed kernels Fix two bugs with the kernel image compression: 1) reset the bss section of the compressed vmlinux 2) clear the high half of the registers for 64 bit early enough for the decompression step Signed-off-by: Martin Schwidefsky diff --git a/arch/s390/boot/compressed/misc.c b/arch/s390/boot/compressed/misc.c index a97d695..14e0479 100644 --- a/arch/s390/boot/compressed/misc.c +++ b/arch/s390/boot/compressed/misc.c @@ -24,8 +24,8 @@ /* Symbols defined by linker scripts */ extern char input_data[]; extern int input_len; -extern int _text; -extern int _end; +extern char _text, _end; +extern char _bss, _ebss; static void error(char *m); @@ -129,12 +129,12 @@ unsigned long decompress_kernel(void) unsigned long output_addr; unsigned char *output; + check_ipl_parmblock((void *) 0, (unsigned long) output + SZ__bss_start); + memset(&_bss, 0, &_ebss - &_bss); free_mem_ptr = (unsigned long)&_end; free_mem_end_ptr = free_mem_ptr + HEAP_SIZE; output = (unsigned char *) ((free_mem_end_ptr + 4095UL) & -4096UL); - check_ipl_parmblock((void *) 0, (unsigned long) output + SZ__bss_start); - #ifdef CONFIG_BLK_DEV_INITRD /* * Move the initrd right behind the end of the decompressed diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S index ca4a62b..9d1f767 100644 --- a/arch/s390/kernel/head.S +++ b/arch/s390/kernel/head.S @@ -517,7 +517,10 @@ startup: lhi %r1,2 # mode 2 = esame (dump) sigp %r1,%r0,0x12 # switch to esame mode sam64 # switch to 64 bit mode + larl %r13,4f + lmh %r0,%r15,0(%r13) # clear high-order half jg startup_continue +4: .fill 16,4,0x0 #else mvi __LC_AR_MODE_ID,0 # set ESA flag (mode 0) l %r13,4f-.LPG0(%r13) diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S index 39580e7..1f70970 100644 --- a/arch/s390/kernel/head64.S +++ b/arch/s390/kernel/head64.S @@ -21,7 +21,6 @@ startup_continue: larl %r1,sched_clock_base_cc mvc 0(8,%r1),__LC_LAST_UPDATE_CLOCK larl %r13,.LPG1 # get base - lmh %r0,%r15,.Lzero64-.LPG1(%r13) # clear high-order half lctlg %c0,%c15,.Lctl-.LPG1(%r13) # load control registers lg %r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area # move IPL device to lowcore @@ -67,7 +66,6 @@ startup_continue: .L4malign:.quad 0xffffffffffc00000 .Lscan2g:.quad 0x80000000 + 0x20000 - 8 # 2GB + 128K - 8 .Lnop: .long 0x07000700 -.Lzero64:.fill 16,4,0x0 .Lparmaddr: .quad PARMAREA .align 64 -- cgit v0.10.2 From cc8c3b78433222e5dbc1fdfcfdde29e1743f181a Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 23 Mar 2010 22:40:53 +0100 Subject: genirq: Protect access to irq_desc->action in can_request_irq() can_request_irq() accesses and dereferences irq_desc->action w/o holding irq_desc->lock. So action can be freed on another CPU before it's dereferenced. Unlikely, but ... Protect it with desc->lock. Signed-off-by: Thomas Gleixner diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 69a3d7b..398fda15 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -382,6 +382,7 @@ int can_request_irq(unsigned int irq, unsigned long irqflags) { struct irq_desc *desc = irq_to_desc(irq); struct irqaction *action; + unsigned long flags; if (!desc) return 0; @@ -389,11 +390,14 @@ int can_request_irq(unsigned int irq, unsigned long irqflags) if (desc->status & IRQ_NOREQUEST) return 0; + raw_spin_lock_irqsave(&desc->lock, flags); action = desc->action; if (action) if (irqflags & action->flags & IRQF_SHARED) action = NULL; + raw_spin_unlock_irqrestore(&desc->lock, flags); + return !action; } -- cgit v0.10.2 From 860652bfb890bd861c999ec39fcffabe5b712f85 Mon Sep 17 00:00:00 2001 From: Henrik Kretzschmar Date: Wed, 24 Mar 2010 12:59:20 +0100 Subject: genirq: Move two IRQ functions from .init.text to .text Both functions should not be marked as __init, since they be called from modules after the init section is freed. Signed-off-by: Henrik Kretzschmar Cc: Yinghai Lu Cc: Peter Zijlstra Cc: Jiri Kosina LKML-Reference: <1269431961-5731-1-git-send-email-henne@nachtwindheim.de> Signed-off-by: Thomas Gleixner diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 71eba24..3c2d6e7 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -729,7 +729,7 @@ set_irq_chip_and_handler_name(unsigned int irq, struct irq_chip *chip, __set_irq_handler(irq, handle, 0, name); } -void __init set_irq_noprobe(unsigned int irq) +void set_irq_noprobe(unsigned int irq) { struct irq_desc *desc = irq_to_desc(irq); unsigned long flags; @@ -744,7 +744,7 @@ void __init set_irq_noprobe(unsigned int irq) raw_spin_unlock_irqrestore(&desc->lock, flags); } -void __init set_irq_probe(unsigned int irq) +void set_irq_probe(unsigned int irq) { struct irq_desc *desc = irq_to_desc(irq); unsigned long flags; -- cgit v0.10.2 From 222e82ac9ffbd3b80ab1b0b1d2c8c60ddb47d69d Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Wed, 24 Mar 2010 14:38:37 +0100 Subject: acpi: Support IBM SMBus CMI devices On some old IBM workstations and desktop computers, the BIOS presents in the DSDT an SMBus object that is missing the HID identifier that the i2c-scmi driver looks for. Modify the ACPI device scan code to insert the missing HID if it finds an IBM system with such an object. Affected machines: IntelliStation Z20/Z30. Note that the i2c-i801 driver no longer works on these machines because of ACPI resource conflicts. Signed-off-by: Darrick J. Wong Signed-off-by: Jean Delvare diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index fb7fc24..189cbc2 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -8,6 +8,7 @@ #include #include #include +#include #include @@ -1032,6 +1033,41 @@ static void acpi_add_id(struct acpi_device *device, const char *dev_id) list_add_tail(&id->list, &device->pnp.ids); } +/* + * Old IBM workstations have a DSDT bug wherein the SMBus object + * lacks the SMBUS01 HID and the methods do not have the necessary "_" + * prefix. Work around this. + */ +static int acpi_ibm_smbus_match(struct acpi_device *device) +{ + acpi_handle h_dummy; + struct acpi_buffer path = {ACPI_ALLOCATE_BUFFER, NULL}; + int result; + + if (!dmi_name_in_vendors("IBM")) + return -ENODEV; + + /* Look for SMBS object */ + result = acpi_get_name(device->handle, ACPI_SINGLE_NAME, &path); + if (result) + return result; + + if (strcmp("SMBS", path.pointer)) { + result = -ENODEV; + goto out; + } + + /* Does it have the necessary (but misnamed) methods? */ + result = -ENODEV; + if (ACPI_SUCCESS(acpi_get_handle(device->handle, "SBI", &h_dummy)) && + ACPI_SUCCESS(acpi_get_handle(device->handle, "SBR", &h_dummy)) && + ACPI_SUCCESS(acpi_get_handle(device->handle, "SBW", &h_dummy))) + result = 0; +out: + kfree(path.pointer); + return result; +} + static void acpi_device_set_id(struct acpi_device *device) { acpi_status status; @@ -1082,6 +1118,8 @@ static void acpi_device_set_id(struct acpi_device *device) acpi_add_id(device, ACPI_BAY_HID); else if (ACPI_SUCCESS(acpi_dock_match(device))) acpi_add_id(device, ACPI_DOCK_HID); + else if (!acpi_ibm_smbus_match(device)) + acpi_add_id(device, ACPI_SMBUS_IBM_HID); break; case ACPI_BUS_TYPE_POWER: diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h index 3a4767c..4f7b448 100644 --- a/include/acpi/acpi_drivers.h +++ b/include/acpi/acpi_drivers.h @@ -65,6 +65,8 @@ #define ACPI_VIDEO_HID "LNXVIDEO" #define ACPI_BAY_HID "LNXIOBAY" #define ACPI_DOCK_HID "LNXDOCK" +/* Quirk for broken IBM BIOSes */ +#define ACPI_SMBUS_IBM_HID "SMBUSIBM" /* * For fixed hardware buttons, we fabricate acpi_devices with HID -- cgit v0.10.2 From e82e15ddd322e4c5847536f044a40812b7ec12bd Mon Sep 17 00:00:00 2001 From: Crane Cai Date: Wed, 24 Mar 2010 14:38:38 +0100 Subject: i2c-scmi: Support IBM SMBus CMI devices *) add a new HID for IBM SMBus CMI devices *) add methods for IBM SMBus CMI devices *) hook different HID with different control methods set *) minor tweaks as suggested by Jean Delvare Slightly modified by Darrick to use #define'd IBM SMBUS HID from Darrick's ACPI scan quirk patch. Signed-off-by: Crane Cai Signed-off-by: Darrick J. Wong Signed-off-by: Jean Delvare diff --git a/drivers/i2c/busses/i2c-scmi.c b/drivers/i2c/busses/i2c-scmi.c index 365e0be..4c9fb4c 100644 --- a/drivers/i2c/busses/i2c-scmi.c +++ b/drivers/i2c/busses/i2c-scmi.c @@ -33,6 +33,7 @@ struct acpi_smbus_cmi { u8 cap_info:1; u8 cap_read:1; u8 cap_write:1; + struct smbus_methods_t *methods; }; static const struct smbus_methods_t smbus_methods = { @@ -41,8 +42,16 @@ static const struct smbus_methods_t smbus_methods = { .mt_sbw = "_SBW", }; +/* Some IBM BIOSes omit the leading underscore */ +static const struct smbus_methods_t ibm_smbus_methods = { + .mt_info = "SBI_", + .mt_sbr = "SBR_", + .mt_sbw = "SBW_", +}; + static const struct acpi_device_id acpi_smbus_cmi_ids[] = { - {"SMBUS01", 0}, + {"SMBUS01", (kernel_ulong_t)&smbus_methods}, + {ACPI_SMBUS_IBM_HID, (kernel_ulong_t)&ibm_smbus_methods}, {"", 0} }; @@ -150,11 +159,11 @@ acpi_smbus_cmi_access(struct i2c_adapter *adap, u16 addr, unsigned short flags, if (read_write == I2C_SMBUS_READ) { protocol |= ACPI_SMBUS_PRTCL_READ; - method = smbus_methods.mt_sbr; + method = smbus_cmi->methods->mt_sbr; input.count = 3; } else { protocol |= ACPI_SMBUS_PRTCL_WRITE; - method = smbus_methods.mt_sbw; + method = smbus_cmi->methods->mt_sbw; input.count = 5; } @@ -290,13 +299,13 @@ static int acpi_smbus_cmi_add_cap(struct acpi_smbus_cmi *smbus_cmi, union acpi_object *obj; acpi_status status; - if (!strcmp(name, smbus_methods.mt_info)) { + if (!strcmp(name, smbus_cmi->methods->mt_info)) { status = acpi_evaluate_object(smbus_cmi->handle, - smbus_methods.mt_info, + smbus_cmi->methods->mt_info, NULL, &buffer); if (ACPI_FAILURE(status)) { ACPI_ERROR((AE_INFO, "Evaluating %s: %i", - smbus_methods.mt_info, status)); + smbus_cmi->methods->mt_info, status)); return -EIO; } @@ -319,9 +328,9 @@ static int acpi_smbus_cmi_add_cap(struct acpi_smbus_cmi *smbus_cmi, kfree(buffer.pointer); smbus_cmi->cap_info = 1; - } else if (!strcmp(name, smbus_methods.mt_sbr)) + } else if (!strcmp(name, smbus_cmi->methods->mt_sbr)) smbus_cmi->cap_read = 1; - else if (!strcmp(name, smbus_methods.mt_sbw)) + else if (!strcmp(name, smbus_cmi->methods->mt_sbw)) smbus_cmi->cap_write = 1; else ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Unsupported CMI method: %s\n", @@ -349,6 +358,7 @@ static acpi_status acpi_smbus_cmi_query_methods(acpi_handle handle, u32 level, static int acpi_smbus_cmi_add(struct acpi_device *device) { struct acpi_smbus_cmi *smbus_cmi; + const struct acpi_device_id *id; smbus_cmi = kzalloc(sizeof(struct acpi_smbus_cmi), GFP_KERNEL); if (!smbus_cmi) @@ -362,6 +372,11 @@ static int acpi_smbus_cmi_add(struct acpi_device *device) smbus_cmi->cap_read = 0; smbus_cmi->cap_write = 0; + for (id = acpi_smbus_cmi_ids; id->id[0]; id++) + if (!strcmp(id->id, acpi_device_hid(device))) + smbus_cmi->methods = + (struct smbus_methods_t *) id->driver_data; + acpi_walk_namespace(ACPI_TYPE_METHOD, smbus_cmi->handle, 1, acpi_smbus_cmi_query_methods, NULL, smbus_cmi, NULL); -- cgit v0.10.2 From 0f5ed04cb365ce0117b0588c4d9ed89f2623650b Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Wed, 24 Mar 2010 14:38:39 +0100 Subject: i2c-scmi: Provide module aliases for automatic loading Provide module aliases for automatic loading. Signed-off-by: Darrick J. Wong Signed-off-by: Jean Delvare diff --git a/drivers/i2c/busses/i2c-scmi.c b/drivers/i2c/busses/i2c-scmi.c index 4c9fb4c..388cbdc 100644 --- a/drivers/i2c/busses/i2c-scmi.c +++ b/drivers/i2c/busses/i2c-scmi.c @@ -54,6 +54,7 @@ static const struct acpi_device_id acpi_smbus_cmi_ids[] = { {ACPI_SMBUS_IBM_HID, (kernel_ulong_t)&ibm_smbus_methods}, {"", 0} }; +MODULE_DEVICE_TABLE(acpi, acpi_smbus_cmi_ids); #define ACPI_SMBUS_STATUS_OK 0x00 #define ACPI_SMBUS_STATUS_FAIL 0x07 -- cgit v0.10.2 From a8462bde78fdb77c8ede61e1af99617905a78ccf Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 24 Mar 2010 14:58:34 +0300 Subject: ASoC: wm8994: playback => capture Sparse caught that initialize "playback" two times instead of initializing "capture". Signed-off-by: Dan Carpenter Acked-by: Liam Girdwood Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 29f3771..d10d651 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -3401,7 +3401,7 @@ struct snd_soc_dai wm8994_dai[] = { .rates = WM8994_RATES, .formats = WM8994_FORMATS, }, - .playback = { + .capture = { .stream_name = "AIF3 Capture", .channels_min = 2, .channels_max = 2, -- cgit v0.10.2 From 669d3e0babb40018dd6e78f4093c13a2eac73866 Mon Sep 17 00:00:00 2001 From: Vasu Dev Date: Tue, 23 Mar 2010 14:41:45 +0000 Subject: vlan: adds vlan_dev_select_queue This is required to correctly select vlan tx queue for a driver supporting multi tx queue with ndo_select_queue implemented since currently selected vlan tx queue is unaligned to selected queue by real net_devce ndo_select_queue. Unaligned vlan tx queue selection causes thrash with higher vlan tx lock contention for least fcoe traffic and wrong socket tx queue_mapping for ixgbe having ndo_select_queue implemented. -v2 As per Eric Dumazet comments, mirrored vlan net_device_ops to have them with and without vlan_dev_select_queue and then select according to real dev ndo_select_queue present or not for a vlan net_device. This is to completely skip vlan_dev_select_queue calling for real net_device not supporting ndo_select_queue. Signed-off-by: Vasu Dev Signed-off-by: Jeff Kirsher Acked-by: Eric Dumazet Signed-off-by: David S. Miller diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 9e83272..2fd057c 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -361,6 +361,14 @@ static netdev_tx_t vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, return ret; } +static u16 vlan_dev_select_queue(struct net_device *dev, struct sk_buff *skb) +{ + struct net_device *rdev = vlan_dev_info(dev)->real_dev; + const struct net_device_ops *ops = rdev->netdev_ops; + + return ops->ndo_select_queue(rdev, skb); +} + static int vlan_dev_change_mtu(struct net_device *dev, int new_mtu) { /* TODO: gotta make sure the underlying layer can handle it, @@ -688,7 +696,8 @@ static const struct header_ops vlan_header_ops = { .parse = eth_header_parse, }; -static const struct net_device_ops vlan_netdev_ops, vlan_netdev_accel_ops; +static const struct net_device_ops vlan_netdev_ops, vlan_netdev_accel_ops, + vlan_netdev_ops_sq, vlan_netdev_accel_ops_sq; static int vlan_dev_init(struct net_device *dev) { @@ -722,11 +731,17 @@ static int vlan_dev_init(struct net_device *dev) if (real_dev->features & NETIF_F_HW_VLAN_TX) { dev->header_ops = real_dev->header_ops; dev->hard_header_len = real_dev->hard_header_len; - dev->netdev_ops = &vlan_netdev_accel_ops; + if (real_dev->netdev_ops->ndo_select_queue) + dev->netdev_ops = &vlan_netdev_accel_ops_sq; + else + dev->netdev_ops = &vlan_netdev_accel_ops; } else { dev->header_ops = &vlan_header_ops; dev->hard_header_len = real_dev->hard_header_len + VLAN_HLEN; - dev->netdev_ops = &vlan_netdev_ops; + if (real_dev->netdev_ops->ndo_select_queue) + dev->netdev_ops = &vlan_netdev_ops_sq; + else + dev->netdev_ops = &vlan_netdev_ops; } if (is_vlan_dev(real_dev)) @@ -865,6 +880,56 @@ static const struct net_device_ops vlan_netdev_accel_ops = { #endif }; +static const struct net_device_ops vlan_netdev_ops_sq = { + .ndo_select_queue = vlan_dev_select_queue, + .ndo_change_mtu = vlan_dev_change_mtu, + .ndo_init = vlan_dev_init, + .ndo_uninit = vlan_dev_uninit, + .ndo_open = vlan_dev_open, + .ndo_stop = vlan_dev_stop, + .ndo_start_xmit = vlan_dev_hard_start_xmit, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = vlan_dev_set_mac_address, + .ndo_set_rx_mode = vlan_dev_set_rx_mode, + .ndo_set_multicast_list = vlan_dev_set_rx_mode, + .ndo_change_rx_flags = vlan_dev_change_rx_flags, + .ndo_do_ioctl = vlan_dev_ioctl, + .ndo_neigh_setup = vlan_dev_neigh_setup, + .ndo_get_stats = vlan_dev_get_stats, +#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) + .ndo_fcoe_ddp_setup = vlan_dev_fcoe_ddp_setup, + .ndo_fcoe_ddp_done = vlan_dev_fcoe_ddp_done, + .ndo_fcoe_enable = vlan_dev_fcoe_enable, + .ndo_fcoe_disable = vlan_dev_fcoe_disable, + .ndo_fcoe_get_wwn = vlan_dev_fcoe_get_wwn, +#endif +}; + +static const struct net_device_ops vlan_netdev_accel_ops_sq = { + .ndo_select_queue = vlan_dev_select_queue, + .ndo_change_mtu = vlan_dev_change_mtu, + .ndo_init = vlan_dev_init, + .ndo_uninit = vlan_dev_uninit, + .ndo_open = vlan_dev_open, + .ndo_stop = vlan_dev_stop, + .ndo_start_xmit = vlan_dev_hwaccel_hard_start_xmit, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = vlan_dev_set_mac_address, + .ndo_set_rx_mode = vlan_dev_set_rx_mode, + .ndo_set_multicast_list = vlan_dev_set_rx_mode, + .ndo_change_rx_flags = vlan_dev_change_rx_flags, + .ndo_do_ioctl = vlan_dev_ioctl, + .ndo_neigh_setup = vlan_dev_neigh_setup, + .ndo_get_stats = vlan_dev_get_stats, +#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) + .ndo_fcoe_ddp_setup = vlan_dev_fcoe_ddp_setup, + .ndo_fcoe_ddp_done = vlan_dev_fcoe_ddp_done, + .ndo_fcoe_enable = vlan_dev_fcoe_enable, + .ndo_fcoe_disable = vlan_dev_fcoe_disable, + .ndo_fcoe_get_wwn = vlan_dev_fcoe_get_wwn, +#endif +}; + void vlan_setup(struct net_device *dev) { ether_setup(dev); -- cgit v0.10.2 From f6b9f4b263f3178fc0f23f0e67d04386528cc727 Mon Sep 17 00:00:00 2001 From: Vasu Dev Date: Tue, 23 Mar 2010 14:42:05 +0000 Subject: vlan: updates vlan real_num_tx_queues Updates real_num_tx_queues in case underlying real device has changed real_num_tx_queues. -v2 As per Eric Dumazet comment:- -- adds BUG_ON to catch case of real_num_tx_queues exceeding num_tx_queues. -- created this self contained patch to just update real_num_tx_queues. Signed-off-by: Vasu Dev Signed-off-by: Jeff Kirsher Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 4535122..db783d7 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -378,6 +378,8 @@ static void vlan_transfer_features(struct net_device *dev, #if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) vlandev->fcoe_ddp_xid = dev->fcoe_ddp_xid; #endif + vlandev->real_num_tx_queues = dev->real_num_tx_queues; + BUG_ON(vlandev->real_num_tx_queues > vlandev->num_tx_queues); if (old_features != vlandev->features) netdev_features_change(vlandev); -- cgit v0.10.2 From 03e6d819c2cb2cc8ce5642669a0a7c72336ee7a2 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 23 Mar 2010 20:40:50 +0000 Subject: skbuff: remove unused dma_head & dma_maps fields The dma map fields in the skb_shared_info structure no longer has any users and can be dropped since it is making the skb_shared_info unecessarily larger. Running slabtop show that we were using 4K slabs for the skb->head on x86_64 w/ an allocation size of 1522. It turns out that the dma_head and dma_maps array made skb_shared large enough that we had crossed over the 2k boundary with standard frames and as such we were using 4k blocks of memory for all skbs. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Acked-by: Eric Dumazet Signed-off-by: David S. Miller diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 03f816a..124f90c 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -190,9 +190,6 @@ struct skb_shared_info { atomic_t dataref; unsigned short nr_frags; unsigned short gso_size; -#ifdef CONFIG_HAS_DMA - dma_addr_t dma_head; -#endif /* Warning: this field is not always filled in (UFO)! */ unsigned short gso_segs; unsigned short gso_type; @@ -201,9 +198,6 @@ struct skb_shared_info { struct sk_buff *frag_list; struct skb_shared_hwtstamps hwtstamps; skb_frag_t frags[MAX_SKB_FRAGS]; -#ifdef CONFIG_HAS_DMA - dma_addr_t dma_maps[MAX_SKB_FRAGS]; -#endif /* Intermediate layers must ensure that destructor_arg * remains valid until skb destructor */ void * destructor_arg; -- cgit v0.10.2 From c26f91a3df1999ec1b3298372d73f90cbab81106 Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Mon, 22 Mar 2010 09:32:26 +0100 Subject: x86: Remove excessive early_res debug output Commit 08677214e318297 ("x86: Make 64 bit use early_res instead of bootmem before slab") introduced early_res replacement for bootmem, but left code in __free_pages_memory() which dumps all the ranges that are beeing freed, without any additional information, causing some noise in dmesg during bootup. Just remove printing of the ranges, that doesn't provide anything useful anyway. While at it, remove other commented-out KERN_DEBUG messages in the NO_BOOTMEM code as well. Signed-off-by: Jiri Kosina Found-OK-by: Andrew Morton Cc: Johannes Weiner Cc: Yinghai Lu LKML-Reference: Signed-off-by: Ingo Molnar diff --git a/mm/bootmem.c b/mm/bootmem.c index d7c791e..9b13446 100644 --- a/mm/bootmem.c +++ b/mm/bootmem.c @@ -180,19 +180,12 @@ static void __init __free_pages_memory(unsigned long start, unsigned long end) end_aligned = end & ~(BITS_PER_LONG - 1); if (end_aligned <= start_aligned) { -#if 1 - printk(KERN_DEBUG " %lx - %lx\n", start, end); -#endif for (i = start; i < end; i++) __free_pages_bootmem(pfn_to_page(i), 0); return; } -#if 1 - printk(KERN_DEBUG " %lx %lx - %lx %lx\n", - start, start_aligned, end_aligned, end); -#endif for (i = start; i < start_aligned; i++) __free_pages_bootmem(pfn_to_page(i), 0); @@ -428,9 +421,6 @@ void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr, { #ifdef CONFIG_NO_BOOTMEM free_early(physaddr, physaddr + size); -#if 0 - printk(KERN_DEBUG "free %lx %lx\n", physaddr, size); -#endif #else unsigned long start, end; @@ -456,9 +446,6 @@ void __init free_bootmem(unsigned long addr, unsigned long size) { #ifdef CONFIG_NO_BOOTMEM free_early(addr, addr + size); -#if 0 - printk(KERN_DEBUG "free %lx %lx\n", addr, size); -#endif #else unsigned long start, end; -- cgit v0.10.2 From 966f3a7570447c5025d67a618d408e68a3ae3167 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 11 Mar 2010 17:01:19 -0700 Subject: PCI: for address space collisions, show conflicting resource With request_resource_conflict(), we can learn what the actual conflict is, so print that info for debugging purposes. Signed-off-by: Bjorn Helgaas Signed-off-by: Jesse Barnes diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 7d678bb..17bed18 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c @@ -93,8 +93,7 @@ void pci_update_resource(struct pci_dev *dev, int resno) int pci_claim_resource(struct pci_dev *dev, int resource) { struct resource *res = &dev->resource[resource]; - struct resource *root; - int err; + struct resource *root, *conflict; root = pci_find_parent_resource(dev, res); if (!root) { @@ -103,12 +102,15 @@ int pci_claim_resource(struct pci_dev *dev, int resource) return -EINVAL; } - err = request_resource(root, res); - if (err) + conflict = request_resource_conflict(root, res); + if (conflict) { dev_err(&dev->dev, - "address space collision: %pR already in use\n", res); + "address space collision: %pR conflicts with %s %pR\n", + res, conflict->name, conflict); + return -EBUSY; + } - return err; + return 0; } EXPORT_SYMBOL(pci_claim_resource); -- cgit v0.10.2 From 99ddd552fef7e6e3b7dc76ba8fee9ea5869d1e14 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 16 Mar 2010 15:52:58 -0600 Subject: PCI: break out primary/secondary/subordinate for readability No functional change; just add names for the primary/secondary/subordinate bus numbers read from config space rather than repeatedly masking/shifting. Signed-off-by: Bjorn Helgaas Signed-off-by: Jesse Barnes diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 2a94309..7feacf5 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -673,16 +673,20 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS); u32 buses, i, j = 0; u16 bctl; + u8 primary, secondary, subordinate; int broken = 0; pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses); + primary = buses & 0xFF; + secondary = (buses >> 8) & 0xFF; + subordinate = (buses >> 16) & 0xFF; - dev_dbg(&dev->dev, "scanning behind bridge, config %06x, pass %d\n", - buses & 0xffffff, pass); + dev_dbg(&dev->dev, "scanning [bus %02x-%02x] behind bridge, pass %d\n", + secondary, subordinate, pass); /* Check if setup is sensible at all */ if (!pass && - ((buses & 0xff) != bus->number || ((buses >> 8) & 0xff) <= bus->number)) { + (primary != bus->number || secondary <= bus->number)) { dev_dbg(&dev->dev, "bus configuration invalid, reconfiguring\n"); broken = 1; } @@ -693,15 +697,15 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bctl & ~PCI_BRIDGE_CTL_MASTER_ABORT); - if ((buses & 0xffff00) && !pcibios_assign_all_busses() && !is_cardbus && !broken) { - unsigned int cmax, busnr; + if ((secondary || subordinate) && !pcibios_assign_all_busses() && + !is_cardbus && !broken) { + unsigned int cmax; /* * Bus already configured by firmware, process it in the first * pass and just note the configuration. */ if (pass) goto out; - busnr = (buses >> 8) & 0xFF; /* * If we already got to this bus through a different bridge, @@ -710,13 +714,13 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, * However, we continue to descend down the hierarchy and * scan remaining child buses. */ - child = pci_find_bus(pci_domain_nr(bus), busnr); + child = pci_find_bus(pci_domain_nr(bus), secondary); if (!child) { - child = pci_add_new_bus(bus, dev, busnr); + child = pci_add_new_bus(bus, dev, secondary); if (!child) goto out; - child->primary = buses & 0xFF; - child->subordinate = (buses >> 16) & 0xFF; + child->primary = primary; + child->subordinate = subordinate; child->bridge_ctl = bctl; } -- cgit v0.10.2 From 7b8ff6da028232aadae6bcc7c7406c8966d0b3c4 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 16 Mar 2010 15:53:03 -0600 Subject: PCI: make disabled window printk style match the enabled ones No functional change; this just tweaks the changes from 349e1823a405 so the new printks for disabled PCI-to-PCI bridge windows match the ones for the enabled windows. Signed-off-by: Bjorn Helgaas CC: Yinghai Lu Signed-off-by: Jesse Barnes diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 7feacf5..c82548a 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -312,7 +312,7 @@ static void __devinit pci_read_bridge_io(struct pci_bus *child) dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); } else { dev_printk(KERN_DEBUG, &dev->dev, - " bridge window [io %04lx - %04lx] reg reading\n", + " bridge window [io %#06lx-%#06lx] (disabled)\n", base, limit); } } @@ -336,7 +336,7 @@ static void __devinit pci_read_bridge_mmio(struct pci_bus *child) dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); } else { dev_printk(KERN_DEBUG, &dev->dev, - " bridge window [mem 0x%08lx - 0x%08lx] reg reading\n", + " bridge window [mem %#010lx-%#010lx] (disabled)\n", base, limit + 0xfffff); } } @@ -387,7 +387,7 @@ static void __devinit pci_read_bridge_mmio_pref(struct pci_bus *child) dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); } else { dev_printk(KERN_DEBUG, &dev->dev, - " bridge window [mem 0x%08lx - %08lx pref] reg reading\n", + " bridge window [mem %#010lx-%#010lx pref] (disabled)\n", base, limit + 0xfffff); } } -- cgit v0.10.2 From e1944c6b0fba80a7837c1cbc47dfbf46e1274a4b Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 16 Mar 2010 15:53:08 -0600 Subject: PCI: print resources consistently with %pR No functional change; just print resources in the conventional style. Signed-off-by: Bjorn Helgaas Signed-off-by: Jesse Barnes diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 40b48f5..9665d6b 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -832,9 +832,8 @@ static inline void dbg_ctrl(struct controller *ctrl) for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { if (!pci_resource_len(pdev, i)) continue; - ctrl_info(ctrl, " PCI resource [%d] : 0x%llx@0x%llx\n", - i, (unsigned long long)pci_resource_len(pdev, i), - (unsigned long long)pci_resource_start(pdev, i)); + ctrl_info(ctrl, " PCI resource [%d] : %pR\n", + i, &pdev->resource[i]); } ctrl_info(ctrl, "Slot Capabilities : 0x%08x\n", ctrl->slot_cap); ctrl_info(ctrl, " Physical Slot Number : %d\n", PSN(ctrl)); diff --git a/drivers/pci/ioapic.c b/drivers/pci/ioapic.c index 3e0d7b5..fb9fdf4 100644 --- a/drivers/pci/ioapic.c +++ b/drivers/pci/ioapic.c @@ -31,9 +31,9 @@ static int ioapic_probe(struct pci_dev *dev, const struct pci_device_id *ent) acpi_status status; unsigned long long gsb; struct ioapic *ioapic; - u64 addr; int ret; char *type; + struct resource *res; handle = DEVICE_ACPI_HANDLE(&dev->dev); if (!handle) @@ -69,13 +69,12 @@ static int ioapic_probe(struct pci_dev *dev, const struct pci_device_id *ent) if (pci_request_region(dev, 0, type)) goto exit_disable; - addr = pci_resource_start(dev, 0); - if (acpi_register_ioapic(ioapic->handle, addr, ioapic->gsi_base)) + res = &dev->resource[0]; + if (acpi_register_ioapic(ioapic->handle, res->start, ioapic->gsi_base)) goto exit_release; pci_set_drvdata(dev, ioapic); - dev_info(&dev->dev, "%s at %#llx, GSI %u\n", type, addr, - ioapic->gsi_base); + dev_info(&dev->dev, "%s at %pR, GSI %u\n", type, res, ioapic->gsi_base); return 0; exit_release: diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index 4663b3f..b4968ca 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c @@ -867,10 +867,8 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s) if (res == &ioport_resource) continue; dev_printk(KERN_INFO, &s->cb_dev->dev, - "pcmcia: parent PCI bridge I/O " - "window: 0x%llx - 0x%llx\n", - (unsigned long long)res->start, - (unsigned long long)res->end); + "pcmcia: parent PCI bridge window: %pR\n", + res); if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end)) done |= IORESOURCE_IO; @@ -880,10 +878,8 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s) if (res == &iomem_resource) continue; dev_printk(KERN_INFO, &s->cb_dev->dev, - "pcmcia: parent PCI bridge Memory " - "window: 0x%llx - 0x%llx\n", - (unsigned long long)res->start, - (unsigned long long)res->end); + "pcmcia: parent PCI bridge window: %pR\n", + res); if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end)) done |= IORESOURCE_MEM; } -- cgit v0.10.2 From c519a5a7dab2d8e9a114f003e2d369bcf8e913f3 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 19 Mar 2010 14:56:27 -0600 Subject: PCI: complain about devices that seem to be broken If we can tell that a device isn't working correctly, we should tell the user to make debugging easier. Otherwise, it can take a lot of work to determine whether the problem is in the driver, PCMCIA, PCI, hardware, etc., as in http://bugzilla.kernel.org/show_bug.cgi?id=12006 Signed-off-by: Bjorn Helgaas Signed-off-by: Jesse Barnes diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index c82548a..882bd8d 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -174,14 +174,19 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, pci_read_config_dword(dev, pos, &sz); pci_write_config_dword(dev, pos, l); + if (!sz) + goto fail; /* BAR not implemented */ + /* * All bits set in sz means the device isn't working properly. - * If the BAR isn't implemented, all bits must be 0. If it's a - * memory BAR or a ROM, bit 0 must be clear; if it's an io BAR, bit - * 1 must be clear. + * If it's a memory BAR or a ROM, bit 0 must be clear; if it's + * an io BAR, bit 1 must be clear. */ - if (!sz || sz == 0xffffffff) + if (sz == 0xffffffff) { + dev_err(&dev->dev, "reg %x: invalid size %#x; broken device?\n", + pos, sz); goto fail; + } /* * I don't know how l can have all bits set. Copied from old code. @@ -244,13 +249,17 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, pos, res); } } else { - sz = pci_size(l, sz, mask); + u32 size = pci_size(l, sz, mask); - if (!sz) + if (!size) { + dev_err(&dev->dev, "reg %x: invalid size " + "(l %#x sz %#x mask %#x); broken device?", + pos, l, sz, mask); goto fail; + } res->start = l; - res->end = l + sz; + res->end = l + size; dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", pos, res); } -- cgit v0.10.2 From ca8463926306580c25e62eb901a206530d480cae Mon Sep 17 00:00:00 2001 From: Tim Yamin Date: Fri, 19 Mar 2010 14:22:58 -0700 Subject: PCI quirk: only apply CX700 PCI bus parking quirk if external VT6212L is present Apply the CX700 quirk only when an external VT6212L is present (which is the case for the errant hardware the quirk was written for), don't touch the settings otherwise -- Hauppage PVR-500 tuners need PCI Bus Parking in order to work and when that's turned on everything seems to behave fine. I guess the underlying problem is a combination of an external VT6212L and the CX700 rather than the CX700's PCI being broken completely for all cases... Reported-by: Jeroen Roos Signed-off-by: Tim Yamin Signed-off-by: Jesse Barnes diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 81d19d5..8284958 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -1977,11 +1977,25 @@ static void __devinit quirk_via_cx700_pci_parking_caching(struct pci_dev *dev) /* * Disable PCI Bus Parking and PCI Master read caching on CX700 * which causes unspecified timing errors with a VT6212L on the PCI - * bus leading to USB2.0 packet loss. The defaults are that these - * features are turned off but some BIOSes turn them on. + * bus leading to USB2.0 packet loss. + * + * This quirk is only enabled if a second (on the external PCI bus) + * VT6212L is found -- the CX700 core itself also contains a USB + * host controller with the same PCI ID as the VT6212L. */ + /* Count VT6212L instances */ + struct pci_dev *p = pci_get_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_8235_USB_2, NULL); uint8_t b; + + /* p should contain the first (internal) VT6212L -- see if we have + an external one by searching again */ + p = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235_USB_2, p); + if (!p) + return; + pci_dev_put(p); + if (pci_read_config_byte(dev, 0x76, &b) == 0) { if (b & 0x40) { /* Turn off PCI Bus Parking */ @@ -2008,7 +2022,7 @@ static void __devinit quirk_via_cx700_pci_parking_caching(struct pci_dev *dev) } } } -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_VIA, 0x324e, quirk_via_cx700_pci_parking_caching); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, 0x324e, quirk_via_cx700_pci_parking_caching); /* * For Broadcom 5706, 5708, 5709 rev. A nics, any read beyond the -- cgit v0.10.2 From a5ee4eb75413c145334c30e43f1af9875dad6fd7 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 22 Mar 2010 09:52:16 +0100 Subject: PCI quirk: RS780/RS880: work around missing MSI initialization AMD says in section 2.5.4 (GFX MSI Enable) of #43291 (AMD 780G Family Register Programming Requirements): The SBIOS must enable internal graphics MSI capability in GCCFG by setting the following: NBCFG.NB_CNTL.STRAP_MSI_ENABLE='1' Quite a few BIOS writers misinterpret this sentence and think that enabling MSI is an optional feature. However, clearing that bit just prevents delivery of MSI messages but does not remove the MSI PCI capabilities registers, and so leaves these devices unusable for any driver that attempts to use MSI. Setting that bit is not possible after the BIOS has locked down the configuration registers, so we have to manually disable MSI for the affected devices. This fixes the codec communication errors in the HDA driver when accessing the HDMI audio device, and allows us to get rid of the overcautious quirk in radeon_irq_kms.c. Signed-off-by: Clemens Ladisch Tested-by: Alex Deucher Cc: Signed-off-by: Jesse Barnes diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index 3cfd60f..ea4c645 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c @@ -116,13 +116,7 @@ int radeon_irq_kms_init(struct radeon_device *rdev) } /* enable msi */ rdev->msi_enabled = 0; - /* MSIs don't seem to work on my rs780; - * not sure about rs880 or other rs780s. - * Needs more investigation. - */ - if ((rdev->family >= CHIP_RV380) && - (rdev->family != CHIP_RS780) && - (rdev->family != CHIP_RS880)) { + if (rdev->family >= CHIP_RV380) { int ret = pci_enable_msi(rdev->pdev); if (!ret) { rdev->msi_enabled = 1; diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 8284958..bb5b46a 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -2493,6 +2493,39 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4374, DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4375, quirk_msi_intx_disable_bug); +/* + * MSI does not work with the AMD RS780/RS880 internal graphics and HDMI audio + * devices unless the BIOS has initialized the nb_cntl.strap_msi_enable bit. + */ +static void __init rs780_int_gfx_disable_msi(struct pci_dev *int_gfx_bridge) +{ + u32 nb_cntl; + + if (!int_gfx_bridge->subordinate) + return; + + pci_bus_write_config_dword(int_gfx_bridge->bus, PCI_DEVFN(0, 0), + 0x60, 0); + pci_bus_read_config_dword(int_gfx_bridge->bus, PCI_DEVFN(0, 0), + 0x64, &nb_cntl); + + if (!(nb_cntl & BIT(10))) { + dev_warn(&int_gfx_bridge->dev, + FW_WARN "RS780: MSI for internal graphics disabled\n"); + int_gfx_bridge->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI; + } +} + +#define PCI_DEVICE_ID_AMD_RS780_P2P_INT_GFX 0x9602 + +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, + PCI_DEVICE_ID_AMD_RS780_P2P_INT_GFX, + rs780_int_gfx_disable_msi); +/* wrong vendor ID on M4A785TD motherboard: */ +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ASUSTEK, + PCI_DEVICE_ID_AMD_RS780_P2P_INT_GFX, + rs780_int_gfx_disable_msi); + #endif /* CONFIG_PCI_MSI */ #ifdef CONFIG_PCI_IOV -- cgit v0.10.2 From 9a127aad4d60968fba96622008ea0d243688f2b0 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 24 Mar 2010 01:47:00 +0000 Subject: af_key: return error if pfkey_xfrm_policy2msg_prep() fails The original code saved the error value but just returned 0 in the end. Signed-off-by: Dan Carpenter Acked-by: Jamal Hadi Salim Signed-off-by: David S. Miller diff --git a/net/key/af_key.c b/net/key/af_key.c index 3687078..344145f 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c @@ -2129,10 +2129,9 @@ static int key_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *c int err; out_skb = pfkey_xfrm_policy2msg_prep(xp); - if (IS_ERR(out_skb)) { - err = PTR_ERR(out_skb); - goto out; - } + if (IS_ERR(out_skb)) + return PTR_ERR(out_skb); + err = pfkey_xfrm_policy2msg(out_skb, xp, dir); if (err < 0) return err; @@ -2148,7 +2147,6 @@ static int key_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *c out_hdr->sadb_msg_seq = c->seq; out_hdr->sadb_msg_pid = c->pid; pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ALL, NULL, xp_net(xp)); -out: return 0; } -- cgit v0.10.2 From 5ae73518cb39dd81e641dfa7ce20751c853579e0 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Fri, 19 Mar 2010 00:38:29 +0100 Subject: firewire: core: fix Model_ID in modalias MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The modalias string of devices that represent units on a FireWire node did not show Module_ID entries within unit directories. This was because firewire-core searched only the root directory of the configuration ROM for a Model_ID entry. We now search first the root directory, then the unit directory. IOW honor a unit directory's Model_ID if present, otherwise fall back to the root directory's model ID (if present). Furthermore, apply the same change to Vendor_ID. This had the same issue but it was less apparent because most devices provide Vendor_ID only in the root directory. And finally, also use this strategy for the remaining two IDs in the modalias, Specifier_ID and Version. It does not actually make sense to look for them elsewhere than in the unit directory because they are mandatory there. However, a uniform search order simplifies the implementation and has no adverse affect in practice. Side notes: - The older counterpart of this, nodemgr.c of ieee1394, looked for Vendor_ID first in the root directory, then in the unit directory, and for Model_ID only in the unit directory. - There is a single mainline driver which requires Vendor_ID and Model_ID --- the firedtv driver. This one worked because FireDTVs provide Vendor_ID in the root directory and Model_ID identically in root directory and unit directory. - Apart from firedtv, there are currently no drivers known to me (including userspace drivers) that look at the Vendor_ID or Model_ID of the modalias. Reported-by: Maciej Żenczykowski Signed-off-by: Stefan Richter diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c index 014cabd..c91d717 100644 --- a/drivers/firewire/core-device.c +++ b/drivers/firewire/core-device.c @@ -180,44 +180,32 @@ static int fw_unit_match(struct device *dev, struct device_driver *drv) return 0; } -static int get_modalias(struct fw_unit *unit, char *buffer, size_t buffer_size) +static void get_modalias_ids(const u32 *directory, int *id) { - struct fw_device *device = fw_parent_device(unit); struct fw_csr_iterator ci; - int key, value; - int vendor = 0; - int model = 0; - int specifier_id = 0; - int version = 0; - fw_csr_iterator_init(&ci, &device->config_rom[5]); + fw_csr_iterator_init(&ci, directory); while (fw_csr_iterator_next(&ci, &key, &value)) { switch (key) { - case CSR_VENDOR: - vendor = value; - break; - case CSR_MODEL: - model = value; - break; + case CSR_VENDOR: id[0] = value; break; + case CSR_MODEL: id[1] = value; break; + case CSR_SPECIFIER_ID: id[2] = value; break; + case CSR_VERSION: id[3] = value; break; } } +} - fw_csr_iterator_init(&ci, unit->directory); - while (fw_csr_iterator_next(&ci, &key, &value)) { - switch (key) { - case CSR_SPECIFIER_ID: - specifier_id = value; - break; - case CSR_VERSION: - version = value; - break; - } - } +static int get_modalias(struct fw_unit *unit, char *buffer, size_t buffer_size) +{ + int id[] = {0, 0, 0, 0}; + + get_modalias_ids(&fw_parent_device(unit)->config_rom[5], id); + get_modalias_ids(unit->directory, id); return snprintf(buffer, buffer_size, "ieee1394:ven%08Xmo%08Xsp%08Xver%08X", - vendor, model, specifier_id, version); + id[0], id[1], id[2], id[3]); } static int fw_unit_uevent(struct device *dev, struct kobj_uevent_env *env) -- cgit v0.10.2 From fe43d6d9cf59d8f8cbfdcde2018de13ffd1285c7 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Fri, 19 Mar 2010 00:39:07 +0100 Subject: firewire: core: align driver match with modalias The driver match strategy was: - Match vendor/model/specifier/version of the unit directory. - If that was a miss, match vendor from the root directory and model/specifier/version of the unit directory. This was inconsistent with how the modalias string was constructed until recently (take vendor/model from root directory and specifier/ version from unit directory). It was also inconsistent with how it is done since the parent commit: - Use vendor/model/specifier/version of the unit directory if possible, - fall back to one or more of vendor/model/specifier/version from the root directory depending on which ones are not present at the unit directory. Fix this inconsistency by sharing the ROM scanner function between modalias printer function and driver match function. Signed-off-by: Stefan Richter diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c index c91d717..92b633d 100644 --- a/drivers/firewire/core-device.c +++ b/drivers/firewire/core-device.c @@ -127,81 +127,70 @@ int fw_csr_string(const u32 *directory, int key, char *buf, size_t size) } EXPORT_SYMBOL(fw_csr_string); -static bool is_fw_unit(struct device *dev); - -static int match_unit_directory(const u32 *directory, u32 match_flags, - const struct ieee1394_device_id *id) +static void get_ids(const u32 *directory, int *id) { struct fw_csr_iterator ci; - int key, value, match; + int key, value; - match = 0; fw_csr_iterator_init(&ci, directory); while (fw_csr_iterator_next(&ci, &key, &value)) { - if (key == CSR_VENDOR && value == id->vendor_id) - match |= IEEE1394_MATCH_VENDOR_ID; - if (key == CSR_MODEL && value == id->model_id) - match |= IEEE1394_MATCH_MODEL_ID; - if (key == CSR_SPECIFIER_ID && value == id->specifier_id) - match |= IEEE1394_MATCH_SPECIFIER_ID; - if (key == CSR_VERSION && value == id->version) - match |= IEEE1394_MATCH_VERSION; + switch (key) { + case CSR_VENDOR: id[0] = value; break; + case CSR_MODEL: id[1] = value; break; + case CSR_SPECIFIER_ID: id[2] = value; break; + case CSR_VERSION: id[3] = value; break; + } } +} - return (match & match_flags) == match_flags; +static void get_modalias_ids(struct fw_unit *unit, int *id) +{ + get_ids(&fw_parent_device(unit)->config_rom[5], id); + get_ids(unit->directory, id); +} + +static bool match_ids(const struct ieee1394_device_id *id_table, int *id) +{ + int match = 0; + + if (id[0] == id_table->vendor_id) + match |= IEEE1394_MATCH_VENDOR_ID; + if (id[1] == id_table->model_id) + match |= IEEE1394_MATCH_MODEL_ID; + if (id[2] == id_table->specifier_id) + match |= IEEE1394_MATCH_SPECIFIER_ID; + if (id[3] == id_table->version) + match |= IEEE1394_MATCH_VERSION; + + return (match & id_table->match_flags) == id_table->match_flags; } +static bool is_fw_unit(struct device *dev); + static int fw_unit_match(struct device *dev, struct device_driver *drv) { - struct fw_unit *unit = fw_unit(dev); - struct fw_device *device; - const struct ieee1394_device_id *id; + const struct ieee1394_device_id *id_table = + container_of(drv, struct fw_driver, driver)->id_table; + int id[] = {0, 0, 0, 0}; /* We only allow binding to fw_units. */ if (!is_fw_unit(dev)) return 0; - device = fw_parent_device(unit); - id = container_of(drv, struct fw_driver, driver)->id_table; + get_modalias_ids(fw_unit(dev), id); - for (; id->match_flags != 0; id++) { - if (match_unit_directory(unit->directory, id->match_flags, id)) + for (; id_table->match_flags != 0; id_table++) + if (match_ids(id_table, id)) return 1; - /* Also check vendor ID in the root directory. */ - if ((id->match_flags & IEEE1394_MATCH_VENDOR_ID) && - match_unit_directory(&device->config_rom[5], - IEEE1394_MATCH_VENDOR_ID, id) && - match_unit_directory(unit->directory, id->match_flags - & ~IEEE1394_MATCH_VENDOR_ID, id)) - return 1; - } - return 0; } -static void get_modalias_ids(const u32 *directory, int *id) -{ - struct fw_csr_iterator ci; - int key, value; - - fw_csr_iterator_init(&ci, directory); - while (fw_csr_iterator_next(&ci, &key, &value)) { - switch (key) { - case CSR_VENDOR: id[0] = value; break; - case CSR_MODEL: id[1] = value; break; - case CSR_SPECIFIER_ID: id[2] = value; break; - case CSR_VERSION: id[3] = value; break; - } - } -} - static int get_modalias(struct fw_unit *unit, char *buffer, size_t buffer_size) { int id[] = {0, 0, 0, 0}; - get_modalias_ids(&fw_parent_device(unit)->config_rom[5], id); - get_modalias_ids(unit->directory, id); + get_modalias_ids(unit, id); return snprintf(buffer, buffer_size, "ieee1394:ven%08Xmo%08Xsp%08Xver%08X", -- cgit v0.10.2 From 5cfb80a73b5a52fb19d8b0611203e4dd58e8e9a2 Mon Sep 17 00:00:00 2001 From: Daisuke Nishimura Date: Tue, 23 Mar 2010 13:35:11 -0700 Subject: memcg: disable move charge in no mmu case In commit 02491447 ("memcg: move charges of anonymous swap"), I tried to disable move charge feature in no mmu case by enclosing all the related functions with "#ifdef CONFIG_MMU", but the commit places these ifdefs in wrong place. (it seems that it's mangled while handling some fixes...) This patch fixes it up. Signed-off-by: Daisuke Nishimura Cc: Balbir Singh Cc: KAMEZAWA Hiroyuki Cc: Daisuke Nishimura Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 7973b52..00dda35 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -3946,28 +3946,6 @@ one_by_one: } return ret; } -#else /* !CONFIG_MMU */ -static int mem_cgroup_can_attach(struct cgroup_subsys *ss, - struct cgroup *cgroup, - struct task_struct *p, - bool threadgroup) -{ - return 0; -} -static void mem_cgroup_cancel_attach(struct cgroup_subsys *ss, - struct cgroup *cgroup, - struct task_struct *p, - bool threadgroup) -{ -} -static void mem_cgroup_move_task(struct cgroup_subsys *ss, - struct cgroup *cont, - struct cgroup *old_cont, - struct task_struct *p, - bool threadgroup) -{ -} -#endif /** * is_target_pte_for_mc - check a pte whether it is valid for move charge @@ -4330,6 +4308,28 @@ static void mem_cgroup_move_task(struct cgroup_subsys *ss, } mem_cgroup_clear_mc(); } +#else /* !CONFIG_MMU */ +static int mem_cgroup_can_attach(struct cgroup_subsys *ss, + struct cgroup *cgroup, + struct task_struct *p, + bool threadgroup) +{ + return 0; +} +static void mem_cgroup_cancel_attach(struct cgroup_subsys *ss, + struct cgroup *cgroup, + struct task_struct *p, + bool threadgroup) +{ +} +static void mem_cgroup_move_task(struct cgroup_subsys *ss, + struct cgroup *cont, + struct cgroup *old_cont, + struct task_struct *p, + bool threadgroup) +{ +} +#endif struct cgroup_subsys mem_cgroup_subsys = { .name = "memory", -- cgit v0.10.2 From 9d34706f42f9b8c15185423d9af98d37ba21d011 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Tue, 23 Mar 2010 13:35:12 -0700 Subject: cgroups: remove duplicate include commit e6a1105b ("cgroups: subsystem module loading interface") and commit c50cc752 ("sched, cgroups: Fix module export") result in duplicate including of module.h Signed-off-by: Li Zefan Acked-by: Paul Menage Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/kernel/cgroup.c b/kernel/cgroup.c index ef909a3..e2769e1 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -27,7 +27,6 @@ */ #include -#include #include #include #include -- cgit v0.10.2 From e7bbcdf3747e3919c31cfa87853c69d178bce548 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 23 Mar 2010 13:35:12 -0700 Subject: memcontrol: fix potential null deref There was a potential null deref introduced in c62b1a3b31b5 ("memcg: use generic percpu instead of private implementation"). Signed-off-by: Dan Carpenter Acked-by: KAMEZAWA Hiroyuki Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 00dda35..9ed760d 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -3691,8 +3691,10 @@ static struct mem_cgroup *mem_cgroup_alloc(void) else mem = vmalloc(size); - if (mem) - memset(mem, 0, size); + if (!mem) + return NULL; + + memset(mem, 0, size); mem->stat = alloc_percpu(struct mem_cgroup_stat_cpu); if (!mem->stat) { if (size < PAGE_SIZE) -- cgit v0.10.2 From 05731b979476969d4d1cbbcb535fc0f5ea90dba7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 23 Mar 2010 13:35:13 -0700 Subject: rtc/mc13783: fix use after free bug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This was introduced by v2.6.34-rc1~38: 4c014e8 (rtc/mc13783: protect rtc {,un}registration by mc13783 lock) Signed-off-by: Uwe Kleine-König Reported-by: Dan Carpenter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/rtc/rtc-mc13783.c b/drivers/rtc/rtc-mc13783.c index d60c81b..1379c7f 100644 --- a/drivers/rtc/rtc-mc13783.c +++ b/drivers/rtc/rtc-mc13783.c @@ -319,35 +319,38 @@ static int __devinit mc13783_rtc_probe(struct platform_device *pdev) { int ret; struct mc13783_rtc *priv; + struct mc13783 *mc13783; int rtcrst_pending; priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; - priv->mc13783 = dev_get_drvdata(pdev->dev.parent); + mc13783 = dev_get_drvdata(pdev->dev.parent); + priv->mc13783 = mc13783; + platform_set_drvdata(pdev, priv); - mc13783_lock(priv->mc13783); + mc13783_lock(mc13783); - ret = mc13783_irq_request(priv->mc13783, MC13783_IRQ_RTCRST, + ret = mc13783_irq_request(mc13783, MC13783_IRQ_RTCRST, mc13783_rtc_reset_handler, DRIVER_NAME, priv); if (ret) goto err_reset_irq_request; - ret = mc13783_irq_status(priv->mc13783, MC13783_IRQ_RTCRST, + ret = mc13783_irq_status(mc13783, MC13783_IRQ_RTCRST, NULL, &rtcrst_pending); if (ret) goto err_reset_irq_status; priv->valid = !rtcrst_pending; - ret = mc13783_irq_request_nounmask(priv->mc13783, MC13783_IRQ_1HZ, + ret = mc13783_irq_request_nounmask(mc13783, MC13783_IRQ_1HZ, mc13783_rtc_update_handler, DRIVER_NAME, priv); if (ret) goto err_update_irq_request; - ret = mc13783_irq_request_nounmask(priv->mc13783, MC13783_IRQ_TODA, + ret = mc13783_irq_request_nounmask(mc13783, MC13783_IRQ_TODA, mc13783_rtc_alarm_handler, DRIVER_NAME, priv); if (ret) goto err_alarm_irq_request; @@ -357,22 +360,22 @@ static int __devinit mc13783_rtc_probe(struct platform_device *pdev) if (IS_ERR(priv->rtc)) { ret = PTR_ERR(priv->rtc); - mc13783_irq_free(priv->mc13783, MC13783_IRQ_TODA, priv); + mc13783_irq_free(mc13783, MC13783_IRQ_TODA, priv); err_alarm_irq_request: - mc13783_irq_free(priv->mc13783, MC13783_IRQ_1HZ, priv); + mc13783_irq_free(mc13783, MC13783_IRQ_1HZ, priv); err_update_irq_request: err_reset_irq_status: - mc13783_irq_free(priv->mc13783, MC13783_IRQ_RTCRST, priv); + mc13783_irq_free(mc13783, MC13783_IRQ_RTCRST, priv); err_reset_irq_request: platform_set_drvdata(pdev, NULL); kfree(priv); } - mc13783_unlock(priv->mc13783); + mc13783_unlock(mc13783); return ret; } -- cgit v0.10.2 From ef5da59f12602815baa8fad98241b77dedea3b31 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 23 Mar 2010 13:35:14 -0700 Subject: scripts/kernel-doc: handle struct member __aligned scripts/kernel-doc erroneously says: Warning(include/linux/skbuff.h:410): Excess struct/union/enum/typedef member 'cb' description in 'sk_buff' on this line in struct sk_buff: char cb[48] __aligned(8); due to treating the last field as the struct member name, so teach kernel-doc to ignore __aligned(x) in structs. Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/scripts/kernel-doc b/scripts/kernel-doc index c7865c3..c297eb4 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1424,6 +1424,8 @@ sub dump_struct($$) { $nested =~ s/\/\*.*?\*\///gos; # strip kmemcheck_bitfield_{begin,end}.*; $members =~ s/kmemcheck_bitfield_.*?;//gos; + # strip attributes + $members =~ s/__aligned\s*\(\d+\)//gos; create_parameterlist($members, ';', $file); check_sections($file, $declaration_name, "struct", $sectcheck, $struct_actual, $nested); -- cgit v0.10.2 From 7731d9a5d415414aa6903709453786d4a5ff57e4 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Tue, 23 Mar 2010 13:35:15 -0700 Subject: fs/binfmt_aout.c: fix pointer warnings fs/binfmt_aout.c: In function `aout_core_dump': fs/binfmt_aout.c:125: warning: passing argument 2 of `dump_write' makes pointer from integer without a cast include/linux/coredump.h:12: note: expected `const void *' but argument is of type `long unsigned int' fs/binfmt_aout.c:132: warning: passing argument 2 of `dump_write' makes pointer from integer without a cast include/linux/coredump.h:12: note: expected `const void *' but argument is of type `long unsigned int' due to dump_write() expecting a user void *. Fold casts into the START_DATA/START_STACK macros and shut up the warnings. Signed-off-by: Borislav Petkov Cc: Daisuke HATAYAMA Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c index 15d80bb..9b6aef0f 100644 --- a/fs/binfmt_aout.c +++ b/fs/binfmt_aout.c @@ -75,14 +75,16 @@ static int aout_core_dump(struct coredump_params *cprm) struct file *file = cprm->file; mm_segment_t fs; int has_dumped = 0; - unsigned long dump_start, dump_size; + void __user *dump_start; + int dump_size; struct user dump; #ifdef __alpha__ -# define START_DATA(u) (u.start_data) +# define START_DATA(u) ((void __user *)u.start_data) #else -# define START_DATA(u) ((u.u_tsize << PAGE_SHIFT) + u.start_code) +# define START_DATA(u) ((void __user *)((u.u_tsize << PAGE_SHIFT) + \ + u.start_code)) #endif -# define START_STACK(u) (u.start_stack) +# define START_STACK(u) ((void __user *)u.start_stack) fs = get_fs(); set_fs(KERNEL_DS); @@ -104,9 +106,9 @@ static int aout_core_dump(struct coredump_params *cprm) /* make sure we actually have a data and stack area to dump */ set_fs(USER_DS); - if (!access_ok(VERIFY_READ, (void __user *)START_DATA(dump), dump.u_dsize << PAGE_SHIFT)) + if (!access_ok(VERIFY_READ, START_DATA(dump), dump.u_dsize << PAGE_SHIFT)) dump.u_dsize = 0; - if (!access_ok(VERIFY_READ, (void __user *)START_STACK(dump), dump.u_ssize << PAGE_SHIFT)) + if (!access_ok(VERIFY_READ, START_STACK(dump), dump.u_ssize << PAGE_SHIFT)) dump.u_ssize = 0; set_fs(KERNEL_DS); -- cgit v0.10.2 From 091e635e6735fa4496c4a18e7e967b58e961303c Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 23 Mar 2010 13:35:16 -0700 Subject: Documentation/volatile-considered-harmful.txt: correct cpu_relax() documentation cpu_relax() is documented in volatile-considered-harmful.txt to be a memory barrier. However, everyone with the exception of Blackfin and possibly ia64 defines cpu_relax() to be a compiler barrier. Make the documentation reflect the general concensus. Linus sayeth: : I don't think it was ever the intention that it would be seen as anything : but a compiler barrier, although it is obviously implied that it might : well perform some per-architecture actions that have "memory barrier-like" : semantics. : : After all, the whole and only point of the "cpu_relax()" thing is to tell : the CPU that we're busy-looping on some event. : : And that "event" might be (and often is) about reading the same memory : location over and over until it changes to what we want it to be. So it's : quite possible that on various architectures the "cpu_relax()" could be : about making sure that such a tight loop on loads doesn't starve cache : transactions, for example - and as such look a bit like a memory barrier : from a CPU standpoint. : : But it's not meant to have any kind of architectural memory ordering : semantics as far as the kernel is concerned - those must come from other : sources. Signed-off-by: Russell King Cc: Acked-by: Linus Torvalds Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/Documentation/volatile-considered-harmful.txt b/Documentation/volatile-considered-harmful.txt index 991c26a..db0cb22 100644 --- a/Documentation/volatile-considered-harmful.txt +++ b/Documentation/volatile-considered-harmful.txt @@ -63,9 +63,9 @@ way to perform a busy wait is: cpu_relax(); The cpu_relax() call can lower CPU power consumption or yield to a -hyperthreaded twin processor; it also happens to serve as a memory barrier, -so, once again, volatile is unnecessary. Of course, busy-waiting is -generally an anti-social act to begin with. +hyperthreaded twin processor; it also happens to serve as a compiler +barrier, so, once again, volatile is unnecessary. Of course, busy- +waiting is generally an anti-social act to begin with. There are still a few rare situations where volatile makes sense in the kernel: -- cgit v0.10.2 From 1d53661d26aa779dcd74f8a1c5a94e181cc101d8 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 23 Mar 2010 13:35:17 -0700 Subject: blackfin: enable DEBUG_SECTION_MISMATCH We see only one section mismatch now after thousands of randconfigs, and a bug has been filed about that one. Signed-off-by: Mike Frysinger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 8e5ec5e..1fafb4b 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -103,7 +103,8 @@ config HEADERS_CHECK config DEBUG_SECTION_MISMATCH bool "Enable full Section mismatch analysis" - depends on UNDEFINED + depends on UNDEFINED || (BLACKFIN) + default y # This option is on purpose disabled for now. # It will be enabled when we are down to a reasonable number # of section mismatch warnings (< 10 for an allyesconfig build) -- cgit v0.10.2 From 3a4df13d2420ae1998e5c7d26275f8714e84da30 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Tue, 23 Mar 2010 13:35:18 -0700 Subject: get_maintainer: repair STDIN usage Commit 22dd5b0cba50a197aaa3bd2790a29ee2e8e4e372 (fix perlcritic warnings) broke the ability to handle STDIN because the three argument version of open() cannot handle standard IO-streams (which is mentioned in PerlBestPractices, too). Signed-off-by: Wolfram Sang Cc: Stephen Hemminger Acked-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index f76f3d1..6f97a13 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -284,7 +284,7 @@ foreach my $file (@ARGV) { my $file_cnt = @files; my $lastfile; - open(my $patch, '<', $file) + open(my $patch, "< $file") or die "$P: Can't open $file: $!\n"; while (<$patch>) { my $patch_line = $_; -- cgit v0.10.2 From 5ca9ea9a17a14c68611d3774d1e8a7ab6c7f4763 Mon Sep 17 00:00:00 2001 From: Greg Thelen Date: Tue, 23 Mar 2010 13:35:19 -0700 Subject: memcg: fix typo in memcg documentation Update memory.txt to be more consistent: s/swapiness/swappiness/ Signed-off-by: Greg Thelen Acked-by: Balbir Singh Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/Documentation/cgroups/memory.txt b/Documentation/cgroups/memory.txt index f8bc802..3a6aecd 100644 --- a/Documentation/cgroups/memory.txt +++ b/Documentation/cgroups/memory.txt @@ -340,7 +340,7 @@ Note: 5.3 swappiness Similar to /proc/sys/vm/swappiness, but affecting a hierarchy of groups only. - Following cgroups' swapiness can't be changed. + Following cgroups' swappiness can't be changed. - root cgroup (uses /proc/sys/vm/swappiness). - a cgroup which uses hierarchy and it has child cgroup. - a cgroup which uses hierarchy and not the root of hierarchy. -- cgit v0.10.2 From 06ca02b06fc26b3f940d223f319397a72a591ddf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Richard=20R=C3=B6jfors?= Date: Tue, 23 Mar 2010 13:35:20 -0700 Subject: drivers/gpio/max730x.c: add license macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to the header in max730x it is licensed GPLv2. Add a MODULE_LICENSE to avoid getting the kernel tainted. [w.sang@pengutronix.de: add MODULE_AUTHOR and MODULE_DESCRIPTION also] Signed-off-by: Richard Röjfors Signed-off-by: Wolfram Sang Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/gpio/max730x.c b/drivers/gpio/max730x.c index c9bced5..4a7d662 100644 --- a/drivers/gpio/max730x.c +++ b/drivers/gpio/max730x.c @@ -242,3 +242,7 @@ int __devexit __max730x_remove(struct device *dev) return ret; } EXPORT_SYMBOL_GPL(__max730x_remove); + +MODULE_AUTHOR("Juergen Beisert, Wolfram Sang"); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("MAX730x GPIO-Expanders, generic parts"); -- cgit v0.10.2 From 28b8e8d4e2e3e27aa911b5aee59d5194a878f53e Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 23 Mar 2010 13:35:20 -0700 Subject: MAINTAINERS: use tab not spaces for delimiter Keeps MAINTAINERS a bit more consistent. done via sed -r -i -e 's/^([A-Z]):[ \t]+/\1:\t/g' MAINTAINERS Signed-off-by: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/MAINTAINERS b/MAINTAINERS index 449d444..fbc3d65 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -797,12 +797,12 @@ M: Michael Petchkovsky S: Maintained ARM/NOMADIK ARCHITECTURE -M: Alessandro Rubini -M: STEricsson -L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) -S: Maintained -F: arch/arm/mach-nomadik/ -F: arch/arm/plat-nomadik/ +M: Alessandro Rubini +M: STEricsson +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +S: Maintained +F: arch/arm/mach-nomadik/ +F: arch/arm/plat-nomadik/ ARM/OPENMOKO NEO FREERUNNER (GTA02) MACHINE SUPPORT M: Nelson Castillo @@ -1926,17 +1926,17 @@ F: drivers/scsi/dpt* F: drivers/scsi/dpt/ DRBD DRIVER -P: Philipp Reisner -P: Lars Ellenberg -M: drbd-dev@lists.linbit.com -L: drbd-user@lists.linbit.com -W: http://www.drbd.org -T: git git://git.drbd.org/linux-2.6-drbd.git drbd -T: git git://git.drbd.org/drbd-8.3.git -S: Supported -F: drivers/block/drbd/ -F: lib/lru_cache.c -F: Documentation/blockdev/drbd/ +P: Philipp Reisner +P: Lars Ellenberg +M: drbd-dev@lists.linbit.com +L: drbd-user@lists.linbit.com +W: http://www.drbd.org +T: git git://git.drbd.org/linux-2.6-drbd.git drbd +T: git git://git.drbd.org/drbd-8.3.git +S: Supported +F: drivers/block/drbd/ +F: lib/lru_cache.c +F: Documentation/blockdev/drbd/ DRIVER CORE, KOBJECTS, AND SYSFS M: Greg Kroah-Hartman @@ -3518,8 +3518,8 @@ F: drivers/scsi/sym53c8xx_2/ LTP (Linux Test Project) M: Rishikesh K Rajak M: Garrett Cooper -M: Mike Frysinger -M: Subrata Modak +M: Mike Frysinger +M: Subrata Modak L: ltp-list@lists.sourceforge.net (subscribers-only) W: http://ltp.sourceforge.net/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/galak/ltp.git @@ -6201,7 +6201,7 @@ F: arch/x86/ X86 PLATFORM DRIVERS M: Matthew Garrett L: platform-driver-x86@vger.kernel.org -T: git git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platform-drivers-x86.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platform-drivers-x86.git S: Maintained F: drivers/platform/x86 -- cgit v0.10.2 From 3fa30460ea502133a18a07b14452cd660906f16f Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 23 Mar 2010 13:35:21 -0700 Subject: nommu: fix an incorrect comment in the do_mmap_shared_file() Fix an incorrect comment in the do_mmap_shared_file(). If a mapping is requested MAP_SHARED, then a private copy cannot be made and still provide correct semantics. Signed-off-by: David Howells Reported-by: Dave Hudson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/mm/nommu.c b/mm/nommu.c index 605ace8..e4b8f4d 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -1040,10 +1040,9 @@ static int do_mmap_shared_file(struct vm_area_struct *vma) if (ret != -ENOSYS) return ret; - /* getting an ENOSYS error indicates that direct mmap isn't - * possible (as opposed to tried but failed) so we'll fall - * through to making a private copy of the data and mapping - * that if we can */ + /* getting -ENOSYS indicates that direct mmap isn't possible (as + * opposed to tried but failed) so we can only give a suitable error as + * it's not possible to make a private copy if MAP_SHARED was given */ return -ENODEV; } -- cgit v0.10.2 From 4c87684d32e8f95715d53039dcd2d998dc63d1eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20H=C3=A4rdeman?= Date: Tue, 23 Mar 2010 13:35:22 -0700 Subject: kfifo: fix KFIFO_INIT in include/linux/kfifo.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit include/linux/kfifo.h first defines and then undefines __kfifo_initializer which is used by INIT_KFIFO (which is also a macro, so building a module which uses INIT_KFIFO will fail). Signed-off-by: David Härdeman Acked-by: Stefani Seibold Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/include/linux/kfifo.h b/include/linux/kfifo.h index bc0fc79..ece0b1c 100644 --- a/include/linux/kfifo.h +++ b/include/linux/kfifo.h @@ -102,8 +102,6 @@ union { \ unsigned char name##kfifo_buffer[size]; \ struct kfifo name = __kfifo_initializer(size, name##kfifo_buffer) -#undef __kfifo_initializer - extern void kfifo_init(struct kfifo *fifo, void *buffer, unsigned int size); extern __must_check int kfifo_alloc(struct kfifo *fifo, unsigned int size, -- cgit v0.10.2 From 5e07c2c7301bd2c82e55cf5cbb36f7b5bddeb8e9 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 23 Mar 2010 13:35:23 -0700 Subject: Documentation: rename PCI/PCI-DMA-mapping.txt to DMA-API-HOWTO.txt This patch renames PCI/PCI-DMA-mapping.txt to DMA-API-HOWTO.txt. The commit 51e7364ef281e540371f084008732b13292622f0 "Documentation: rename PCI-DMA-mapping.txt to DMA-API-HOWTO.txt" was supposed to do this but it didn't. Signed-off-by: FUJITA Tomonori Acked-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/Documentation/DMA-API-HOWTO.txt b/Documentation/DMA-API-HOWTO.txt new file mode 100644 index 0000000..52618ab --- /dev/null +++ b/Documentation/DMA-API-HOWTO.txt @@ -0,0 +1,758 @@ + Dynamic DMA mapping Guide + ========================= + + David S. Miller + Richard Henderson + Jakub Jelinek + +This is a guide to device driver writers on how to use the DMA API +with example pseudo-code. For a concise description of the API, see +DMA-API.txt. + +Most of the 64bit platforms have special hardware that translates bus +addresses (DMA addresses) into physical addresses. This is similar to +how page tables and/or a TLB translates virtual addresses to physical +addresses on a CPU. This is needed so that e.g. PCI devices can +access with a Single Address Cycle (32bit DMA address) any page in the +64bit physical address space. Previously in Linux those 64bit +platforms had to set artificial limits on the maximum RAM size in the +system, so that the virt_to_bus() static scheme works (the DMA address +translation tables were simply filled on bootup to map each bus +address to the physical page __pa(bus_to_virt())). + +So that Linux can use the dynamic DMA mapping, it needs some help from the +drivers, namely it has to take into account that DMA addresses should be +mapped only for the time they are actually used and unmapped after the DMA +transfer. + +The following API will work of course even on platforms where no such +hardware exists. + +Note that the DMA API works with any bus independent of the underlying +microprocessor architecture. You should use the DMA API rather than +the bus specific DMA API (e.g. pci_dma_*). + +First of all, you should make sure + +#include + +is in your driver. This file will obtain for you the definition of the +dma_addr_t (which can hold any valid DMA address for the platform) +type which should be used everywhere you hold a DMA (bus) address +returned from the DMA mapping functions. + + What memory is DMA'able? + +The first piece of information you must know is what kernel memory can +be used with the DMA mapping facilities. There has been an unwritten +set of rules regarding this, and this text is an attempt to finally +write them down. + +If you acquired your memory via the page allocator +(i.e. __get_free_page*()) or the generic memory allocators +(i.e. kmalloc() or kmem_cache_alloc()) then you may DMA to/from +that memory using the addresses returned from those routines. + +This means specifically that you may _not_ use the memory/addresses +returned from vmalloc() for DMA. It is possible to DMA to the +_underlying_ memory mapped into a vmalloc() area, but this requires +walking page tables to get the physical addresses, and then +translating each of those pages back to a kernel address using +something like __va(). [ EDIT: Update this when we integrate +Gerd Knorr's generic code which does this. ] + +This rule also means that you may use neither kernel image addresses +(items in data/text/bss segments), nor module image addresses, nor +stack addresses for DMA. These could all be mapped somewhere entirely +different than the rest of physical memory. Even if those classes of +memory could physically work with DMA, you'd need to ensure the I/O +buffers were cacheline-aligned. Without that, you'd see cacheline +sharing problems (data corruption) on CPUs with DMA-incoherent caches. +(The CPU could write to one word, DMA would write to a different one +in the same cache line, and one of them could be overwritten.) + +Also, this means that you cannot take the return of a kmap() +call and DMA to/from that. This is similar to vmalloc(). + +What about block I/O and networking buffers? The block I/O and +networking subsystems make sure that the buffers they use are valid +for you to DMA from/to. + + DMA addressing limitations + +Does your device have any DMA addressing limitations? For example, is +your device only capable of driving the low order 24-bits of address? +If so, you need to inform the kernel of this fact. + +By default, the kernel assumes that your device can address the full +32-bits. For a 64-bit capable device, this needs to be increased. +And for a device with limitations, as discussed in the previous +paragraph, it needs to be decreased. + +Special note about PCI: PCI-X specification requires PCI-X devices to +support 64-bit addressing (DAC) for all transactions. And at least +one platform (SGI SN2) requires 64-bit consistent allocations to +operate correctly when the IO bus is in PCI-X mode. + +For correct operation, you must interrogate the kernel in your device +probe routine to see if the DMA controller on the machine can properly +support the DMA addressing limitation your device has. It is good +style to do this even if your device holds the default setting, +because this shows that you did think about these issues wrt. your +device. + +The query is performed via a call to dma_set_mask(): + + int dma_set_mask(struct device *dev, u64 mask); + +The query for consistent allocations is performed via a call to +dma_set_coherent_mask(): + + int dma_set_coherent_mask(struct device *dev, u64 mask); + +Here, dev is a pointer to the device struct of your device, and mask +is a bit mask describing which bits of an address your device +supports. It returns zero if your card can perform DMA properly on +the machine given the address mask you provided. In general, the +device struct of your device is embedded in the bus specific device +struct of your device. For example, a pointer to the device struct of +your PCI device is pdev->dev (pdev is a pointer to the PCI device +struct of your device). + +If it returns non-zero, your device cannot perform DMA properly on +this platform, and attempting to do so will result in undefined +behavior. You must either use a different mask, or not use DMA. + +This means that in the failure case, you have three options: + +1) Use another DMA mask, if possible (see below). +2) Use some non-DMA mode for data transfer, if possible. +3) Ignore this device and do not initialize it. + +It is recommended that your driver print a kernel KERN_WARNING message +when you end up performing either #2 or #3. In this manner, if a user +of your driver reports that performance is bad or that the device is not +even detected, you can ask them for the kernel messages to find out +exactly why. + +The standard 32-bit addressing device would do something like this: + + if (dma_set_mask(dev, DMA_BIT_MASK(32))) { + printk(KERN_WARNING + "mydev: No suitable DMA available.\n"); + goto ignore_this_device; + } + +Another common scenario is a 64-bit capable device. The approach here +is to try for 64-bit addressing, but back down to a 32-bit mask that +should not fail. The kernel may fail the 64-bit mask not because the +platform is not capable of 64-bit addressing. Rather, it may fail in +this case simply because 32-bit addressing is done more efficiently +than 64-bit addressing. For example, Sparc64 PCI SAC addressing is +more efficient than DAC addressing. + +Here is how you would handle a 64-bit capable device which can drive +all 64-bits when accessing streaming DMA: + + int using_dac; + + if (!dma_set_mask(dev, DMA_BIT_MASK(64))) { + using_dac = 1; + } else if (!dma_set_mask(dev, DMA_BIT_MASK(32))) { + using_dac = 0; + } else { + printk(KERN_WARNING + "mydev: No suitable DMA available.\n"); + goto ignore_this_device; + } + +If a card is capable of using 64-bit consistent allocations as well, +the case would look like this: + + int using_dac, consistent_using_dac; + + if (!dma_set_mask(dev, DMA_BIT_MASK(64))) { + using_dac = 1; + consistent_using_dac = 1; + dma_set_coherent_mask(dev, DMA_BIT_MASK(64)); + } else if (!dma_set_mask(dev, DMA_BIT_MASK(32))) { + using_dac = 0; + consistent_using_dac = 0; + dma_set_coherent_mask(dev, DMA_BIT_MASK(32)); + } else { + printk(KERN_WARNING + "mydev: No suitable DMA available.\n"); + goto ignore_this_device; + } + +dma_set_coherent_mask() will always be able to set the same or a +smaller mask as dma_set_mask(). However for the rare case that a +device driver only uses consistent allocations, one would have to +check the return value from dma_set_coherent_mask(). + +Finally, if your device can only drive the low 24-bits of +address you might do something like: + + if (dma_set_mask(dev, DMA_BIT_MASK(24))) { + printk(KERN_WARNING + "mydev: 24-bit DMA addressing not available.\n"); + goto ignore_this_device; + } + +When dma_set_mask() is successful, and returns zero, the kernel saves +away this mask you have provided. The kernel will use this +information later when you make DMA mappings. + +There is a case which we are aware of at this time, which is worth +mentioning in this documentation. If your device supports multiple +functions (for example a sound card provides playback and record +functions) and the various different functions have _different_ +DMA addressing limitations, you may wish to probe each mask and +only provide the functionality which the machine can handle. It +is important that the last call to dma_set_mask() be for the +most specific mask. + +Here is pseudo-code showing how this might be done: + + #define PLAYBACK_ADDRESS_BITS DMA_BIT_MASK(32) + #define RECORD_ADDRESS_BITS DMA_BIT_MASK(24) + + struct my_sound_card *card; + struct device *dev; + + ... + if (!dma_set_mask(dev, PLAYBACK_ADDRESS_BITS)) { + card->playback_enabled = 1; + } else { + card->playback_enabled = 0; + printk(KERN_WARNING "%s: Playback disabled due to DMA limitations.\n", + card->name); + } + if (!dma_set_mask(dev, RECORD_ADDRESS_BITS)) { + card->record_enabled = 1; + } else { + card->record_enabled = 0; + printk(KERN_WARNING "%s: Record disabled due to DMA limitations.\n", + card->name); + } + +A sound card was used as an example here because this genre of PCI +devices seems to be littered with ISA chips given a PCI front end, +and thus retaining the 16MB DMA addressing limitations of ISA. + + Types of DMA mappings + +There are two types of DMA mappings: + +- Consistent DMA mappings which are usually mapped at driver + initialization, unmapped at the end and for which the hardware should + guarantee that the device and the CPU can access the data + in parallel and will see updates made by each other without any + explicit software flushing. + + Think of "consistent" as "synchronous" or "coherent". + + The current default is to return consistent memory in the low 32 + bits of the bus space. However, for future compatibility you should + set the consistent mask even if this default is fine for your + driver. + + Good examples of what to use consistent mappings for are: + + - Network card DMA ring descriptors. + - SCSI adapter mailbox command data structures. + - Device firmware microcode executed out of + main memory. + + The invariant these examples all require is that any CPU store + to memory is immediately visible to the device, and vice + versa. Consistent mappings guarantee this. + + IMPORTANT: Consistent DMA memory does not preclude the usage of + proper memory barriers. The CPU may reorder stores to + consistent memory just as it may normal memory. Example: + if it is important for the device to see the first word + of a descriptor updated before the second, you must do + something like: + + desc->word0 = address; + wmb(); + desc->word1 = DESC_VALID; + + in order to get correct behavior on all platforms. + + Also, on some platforms your driver may need to flush CPU write + buffers in much the same way as it needs to flush write buffers + found in PCI bridges (such as by reading a register's value + after writing it). + +- Streaming DMA mappings which are usually mapped for one DMA + transfer, unmapped right after it (unless you use dma_sync_* below) + and for which hardware can optimize for sequential accesses. + + This of "streaming" as "asynchronous" or "outside the coherency + domain". + + Good examples of what to use streaming mappings for are: + + - Networking buffers transmitted/received by a device. + - Filesystem buffers written/read by a SCSI device. + + The interfaces for using this type of mapping were designed in + such a way that an implementation can make whatever performance + optimizations the hardware allows. To this end, when using + such mappings you must be explicit about what you want to happen. + +Neither type of DMA mapping has alignment restrictions that come from +the underlying bus, although some devices may have such restrictions. +Also, systems with caches that aren't DMA-coherent will work better +when the underlying buffers don't share cache lines with other data. + + + Using Consistent DMA mappings. + +To allocate and map large (PAGE_SIZE or so) consistent DMA regions, +you should do: + + dma_addr_t dma_handle; + + cpu_addr = dma_alloc_coherent(dev, size, &dma_handle, gfp); + +where device is a struct device *. This may be called in interrupt +context with the GFP_ATOMIC flag. + +Size is the length of the region you want to allocate, in bytes. + +This routine will allocate RAM for that region, so it acts similarly to +__get_free_pages (but takes size instead of a page order). If your +driver needs regions sized smaller than a page, you may prefer using +the dma_pool interface, described below. + +The consistent DMA mapping interfaces, for non-NULL dev, will by +default return a DMA address which is 32-bit addressable. Even if the +device indicates (via DMA mask) that it may address the upper 32-bits, +consistent allocation will only return > 32-bit addresses for DMA if +the consistent DMA mask has been explicitly changed via +dma_set_coherent_mask(). This is true of the dma_pool interface as +well. + +dma_alloc_coherent returns two values: the virtual address which you +can use to access it from the CPU and dma_handle which you pass to the +card. + +The cpu return address and the DMA bus master address are both +guaranteed to be aligned to the smallest PAGE_SIZE order which +is greater than or equal to the requested size. This invariant +exists (for example) to guarantee that if you allocate a chunk +which is smaller than or equal to 64 kilobytes, the extent of the +buffer you receive will not cross a 64K boundary. + +To unmap and free such a DMA region, you call: + + dma_free_coherent(dev, size, cpu_addr, dma_handle); + +where dev, size are the same as in the above call and cpu_addr and +dma_handle are the values dma_alloc_coherent returned to you. +This function may not be called in interrupt context. + +If your driver needs lots of smaller memory regions, you can write +custom code to subdivide pages returned by dma_alloc_coherent, +or you can use the dma_pool API to do that. A dma_pool is like +a kmem_cache, but it uses dma_alloc_coherent not __get_free_pages. +Also, it understands common hardware constraints for alignment, +like queue heads needing to be aligned on N byte boundaries. + +Create a dma_pool like this: + + struct dma_pool *pool; + + pool = dma_pool_create(name, dev, size, align, alloc); + +The "name" is for diagnostics (like a kmem_cache name); dev and size +are as above. The device's hardware alignment requirement for this +type of data is "align" (which is expressed in bytes, and must be a +power of two). If your device has no boundary crossing restrictions, +pass 0 for alloc; passing 4096 says memory allocated from this pool +must not cross 4KByte boundaries (but at that time it may be better to +go for dma_alloc_coherent directly instead). + +Allocate memory from a dma pool like this: + + cpu_addr = dma_pool_alloc(pool, flags, &dma_handle); + +flags are SLAB_KERNEL if blocking is permitted (not in_interrupt nor +holding SMP locks), SLAB_ATOMIC otherwise. Like dma_alloc_coherent, +this returns two values, cpu_addr and dma_handle. + +Free memory that was allocated from a dma_pool like this: + + dma_pool_free(pool, cpu_addr, dma_handle); + +where pool is what you passed to dma_pool_alloc, and cpu_addr and +dma_handle are the values dma_pool_alloc returned. This function +may be called in interrupt context. + +Destroy a dma_pool by calling: + + dma_pool_destroy(pool); + +Make sure you've called dma_pool_free for all memory allocated +from a pool before you destroy the pool. This function may not +be called in interrupt context. + + DMA Direction + +The interfaces described in subsequent portions of this document +take a DMA direction argument, which is an integer and takes on +one of the following values: + + DMA_BIDIRECTIONAL + DMA_TO_DEVICE + DMA_FROM_DEVICE + DMA_NONE + +One should provide the exact DMA direction if you know it. + +DMA_TO_DEVICE means "from main memory to the device" +DMA_FROM_DEVICE means "from the device to main memory" +It is the direction in which the data moves during the DMA +transfer. + +You are _strongly_ encouraged to specify this as precisely +as you possibly can. + +If you absolutely cannot know the direction of the DMA transfer, +specify DMA_BIDIRECTIONAL. It means that the DMA can go in +either direction. The platform guarantees that you may legally +specify this, and that it will work, but this may be at the +cost of performance for example. + +The value DMA_NONE is to be used for debugging. One can +hold this in a data structure before you come to know the +precise direction, and this will help catch cases where your +direction tracking logic has failed to set things up properly. + +Another advantage of specifying this value precisely (outside of +potential platform-specific optimizations of such) is for debugging. +Some platforms actually have a write permission boolean which DMA +mappings can be marked with, much like page protections in the user +program address space. Such platforms can and do report errors in the +kernel logs when the DMA controller hardware detects violation of the +permission setting. + +Only streaming mappings specify a direction, consistent mappings +implicitly have a direction attribute setting of +DMA_BIDIRECTIONAL. + +The SCSI subsystem tells you the direction to use in the +'sc_data_direction' member of the SCSI command your driver is +working on. + +For Networking drivers, it's a rather simple affair. For transmit +packets, map/unmap them with the DMA_TO_DEVICE direction +specifier. For receive packets, just the opposite, map/unmap them +with the DMA_FROM_DEVICE direction specifier. + + Using Streaming DMA mappings + +The streaming DMA mapping routines can be called from interrupt +context. There are two versions of each map/unmap, one which will +map/unmap a single memory region, and one which will map/unmap a +scatterlist. + +To map a single region, you do: + + struct device *dev = &my_dev->dev; + dma_addr_t dma_handle; + void *addr = buffer->ptr; + size_t size = buffer->len; + + dma_handle = dma_map_single(dev, addr, size, direction); + +and to unmap it: + + dma_unmap_single(dev, dma_handle, size, direction); + +You should call dma_unmap_single when the DMA activity is finished, e.g. +from the interrupt which told you that the DMA transfer is done. + +Using cpu pointers like this for single mappings has a disadvantage, +you cannot reference HIGHMEM memory in this way. Thus, there is a +map/unmap interface pair akin to dma_{map,unmap}_single. These +interfaces deal with page/offset pairs instead of cpu pointers. +Specifically: + + struct device *dev = &my_dev->dev; + dma_addr_t dma_handle; + struct page *page = buffer->page; + unsigned long offset = buffer->offset; + size_t size = buffer->len; + + dma_handle = dma_map_page(dev, page, offset, size, direction); + + ... + + dma_unmap_page(dev, dma_handle, size, direction); + +Here, "offset" means byte offset within the given page. + +With scatterlists, you map a region gathered from several regions by: + + int i, count = dma_map_sg(dev, sglist, nents, direction); + struct scatterlist *sg; + + for_each_sg(sglist, sg, count, i) { + hw_address[i] = sg_dma_address(sg); + hw_len[i] = sg_dma_len(sg); + } + +where nents is the number of entries in the sglist. + +The implementation is free to merge several consecutive sglist entries +into one (e.g. if DMA mapping is done with PAGE_SIZE granularity, any +consecutive sglist entries can be merged into one provided the first one +ends and the second one starts on a page boundary - in fact this is a huge +advantage for cards which either cannot do scatter-gather or have very +limited number of scatter-gather entries) and returns the actual number +of sg entries it mapped them to. On failure 0 is returned. + +Then you should loop count times (note: this can be less than nents times) +and use sg_dma_address() and sg_dma_len() macros where you previously +accessed sg->address and sg->length as shown above. + +To unmap a scatterlist, just call: + + dma_unmap_sg(dev, sglist, nents, direction); + +Again, make sure DMA activity has already finished. + +PLEASE NOTE: The 'nents' argument to the dma_unmap_sg call must be + the _same_ one you passed into the dma_map_sg call, + it should _NOT_ be the 'count' value _returned_ from the + dma_map_sg call. + +Every dma_map_{single,sg} call should have its dma_unmap_{single,sg} +counterpart, because the bus address space is a shared resource (although +in some ports the mapping is per each BUS so less devices contend for the +same bus address space) and you could render the machine unusable by eating +all bus addresses. + +If you need to use the same streaming DMA region multiple times and touch +the data in between the DMA transfers, the buffer needs to be synced +properly in order for the cpu and device to see the most uptodate and +correct copy of the DMA buffer. + +So, firstly, just map it with dma_map_{single,sg}, and after each DMA +transfer call either: + + dma_sync_single_for_cpu(dev, dma_handle, size, direction); + +or: + + dma_sync_sg_for_cpu(dev, sglist, nents, direction); + +as appropriate. + +Then, if you wish to let the device get at the DMA area again, +finish accessing the data with the cpu, and then before actually +giving the buffer to the hardware call either: + + dma_sync_single_for_device(dev, dma_handle, size, direction); + +or: + + dma_sync_sg_for_device(dev, sglist, nents, direction); + +as appropriate. + +After the last DMA transfer call one of the DMA unmap routines +dma_unmap_{single,sg}. If you don't touch the data from the first dma_map_* +call till dma_unmap_*, then you don't have to call the dma_sync_* +routines at all. + +Here is pseudo code which shows a situation in which you would need +to use the dma_sync_*() interfaces. + + my_card_setup_receive_buffer(struct my_card *cp, char *buffer, int len) + { + dma_addr_t mapping; + + mapping = dma_map_single(cp->dev, buffer, len, DMA_FROM_DEVICE); + + cp->rx_buf = buffer; + cp->rx_len = len; + cp->rx_dma = mapping; + + give_rx_buf_to_card(cp); + } + + ... + + my_card_interrupt_handler(int irq, void *devid, struct pt_regs *regs) + { + struct my_card *cp = devid; + + ... + if (read_card_status(cp) == RX_BUF_TRANSFERRED) { + struct my_card_header *hp; + + /* Examine the header to see if we wish + * to accept the data. But synchronize + * the DMA transfer with the CPU first + * so that we see updated contents. + */ + dma_sync_single_for_cpu(&cp->dev, cp->rx_dma, + cp->rx_len, + DMA_FROM_DEVICE); + + /* Now it is safe to examine the buffer. */ + hp = (struct my_card_header *) cp->rx_buf; + if (header_is_ok(hp)) { + dma_unmap_single(&cp->dev, cp->rx_dma, cp->rx_len, + DMA_FROM_DEVICE); + pass_to_upper_layers(cp->rx_buf); + make_and_setup_new_rx_buf(cp); + } else { + /* Just sync the buffer and give it back + * to the card. + */ + dma_sync_single_for_device(&cp->dev, + cp->rx_dma, + cp->rx_len, + DMA_FROM_DEVICE); + give_rx_buf_to_card(cp); + } + } + } + +Drivers converted fully to this interface should not use virt_to_bus any +longer, nor should they use bus_to_virt. Some drivers have to be changed a +little bit, because there is no longer an equivalent to bus_to_virt in the +dynamic DMA mapping scheme - you have to always store the DMA addresses +returned by the dma_alloc_coherent, dma_pool_alloc, and dma_map_single +calls (dma_map_sg stores them in the scatterlist itself if the platform +supports dynamic DMA mapping in hardware) in your driver structures and/or +in the card registers. + +All drivers should be using these interfaces with no exceptions. It +is planned to completely remove virt_to_bus() and bus_to_virt() as +they are entirely deprecated. Some ports already do not provide these +as it is impossible to correctly support them. + + Optimizing Unmap State Space Consumption + +On many platforms, dma_unmap_{single,page}() is simply a nop. +Therefore, keeping track of the mapping address and length is a waste +of space. Instead of filling your drivers up with ifdefs and the like +to "work around" this (which would defeat the whole purpose of a +portable API) the following facilities are provided. + +Actually, instead of describing the macros one by one, we'll +transform some example code. + +1) Use DEFINE_DMA_UNMAP_{ADDR,LEN} in state saving structures. + Example, before: + + struct ring_state { + struct sk_buff *skb; + dma_addr_t mapping; + __u32 len; + }; + + after: + + struct ring_state { + struct sk_buff *skb; + DEFINE_DMA_UNMAP_ADDR(mapping); + DEFINE_DMA_UNMAP_LEN(len); + }; + +2) Use dma_unmap_{addr,len}_set to set these values. + Example, before: + + ringp->mapping = FOO; + ringp->len = BAR; + + after: + + dma_unmap_addr_set(ringp, mapping, FOO); + dma_unmap_len_set(ringp, len, BAR); + +3) Use dma_unmap_{addr,len} to access these values. + Example, before: + + dma_unmap_single(dev, ringp->mapping, ringp->len, + DMA_FROM_DEVICE); + + after: + + dma_unmap_single(dev, + dma_unmap_addr(ringp, mapping), + dma_unmap_len(ringp, len), + DMA_FROM_DEVICE); + +It really should be self-explanatory. We treat the ADDR and LEN +separately, because it is possible for an implementation to only +need the address in order to perform the unmap operation. + + Platform Issues + +If you are just writing drivers for Linux and do not maintain +an architecture port for the kernel, you can safely skip down +to "Closing". + +1) Struct scatterlist requirements. + + Struct scatterlist must contain, at a minimum, the following + members: + + struct page *page; + unsigned int offset; + unsigned int length; + + The base address is specified by a "page+offset" pair. + + Previous versions of struct scatterlist contained a "void *address" + field that was sometimes used instead of page+offset. As of Linux + 2.5., page+offset is always used, and the "address" field has been + deleted. + +2) More to come... + + Handling Errors + +DMA address space is limited on some architectures and an allocation +failure can be determined by: + +- checking if dma_alloc_coherent returns NULL or dma_map_sg returns 0 + +- checking the returned dma_addr_t of dma_map_single and dma_map_page + by using dma_mapping_error(): + + dma_addr_t dma_handle; + + dma_handle = dma_map_single(dev, addr, size, direction); + if (dma_mapping_error(dev, dma_handle)) { + /* + * reduce current DMA mapping usage, + * delay and try again later or + * reset driver. + */ + } + + Closing + +This document, and the API itself, would not be in it's current +form without the feedback and suggestions from numerous individuals. +We would like to specifically mention, in no particular order, the +following people: + + Russell King + Leo Dagum + Ralf Baechle + Grant Grundler + Jay Estabrook + Thomas Sailer + Andrea Arcangeli + Jens Axboe + David Mosberger-Tang diff --git a/Documentation/PCI/PCI-DMA-mapping.txt b/Documentation/PCI/PCI-DMA-mapping.txt deleted file mode 100644 index 52618ab..0000000 --- a/Documentation/PCI/PCI-DMA-mapping.txt +++ /dev/null @@ -1,758 +0,0 @@ - Dynamic DMA mapping Guide - ========================= - - David S. Miller - Richard Henderson - Jakub Jelinek - -This is a guide to device driver writers on how to use the DMA API -with example pseudo-code. For a concise description of the API, see -DMA-API.txt. - -Most of the 64bit platforms have special hardware that translates bus -addresses (DMA addresses) into physical addresses. This is similar to -how page tables and/or a TLB translates virtual addresses to physical -addresses on a CPU. This is needed so that e.g. PCI devices can -access with a Single Address Cycle (32bit DMA address) any page in the -64bit physical address space. Previously in Linux those 64bit -platforms had to set artificial limits on the maximum RAM size in the -system, so that the virt_to_bus() static scheme works (the DMA address -translation tables were simply filled on bootup to map each bus -address to the physical page __pa(bus_to_virt())). - -So that Linux can use the dynamic DMA mapping, it needs some help from the -drivers, namely it has to take into account that DMA addresses should be -mapped only for the time they are actually used and unmapped after the DMA -transfer. - -The following API will work of course even on platforms where no such -hardware exists. - -Note that the DMA API works with any bus independent of the underlying -microprocessor architecture. You should use the DMA API rather than -the bus specific DMA API (e.g. pci_dma_*). - -First of all, you should make sure - -#include - -is in your driver. This file will obtain for you the definition of the -dma_addr_t (which can hold any valid DMA address for the platform) -type which should be used everywhere you hold a DMA (bus) address -returned from the DMA mapping functions. - - What memory is DMA'able? - -The first piece of information you must know is what kernel memory can -be used with the DMA mapping facilities. There has been an unwritten -set of rules regarding this, and this text is an attempt to finally -write them down. - -If you acquired your memory via the page allocator -(i.e. __get_free_page*()) or the generic memory allocators -(i.e. kmalloc() or kmem_cache_alloc()) then you may DMA to/from -that memory using the addresses returned from those routines. - -This means specifically that you may _not_ use the memory/addresses -returned from vmalloc() for DMA. It is possible to DMA to the -_underlying_ memory mapped into a vmalloc() area, but this requires -walking page tables to get the physical addresses, and then -translating each of those pages back to a kernel address using -something like __va(). [ EDIT: Update this when we integrate -Gerd Knorr's generic code which does this. ] - -This rule also means that you may use neither kernel image addresses -(items in data/text/bss segments), nor module image addresses, nor -stack addresses for DMA. These could all be mapped somewhere entirely -different than the rest of physical memory. Even if those classes of -memory could physically work with DMA, you'd need to ensure the I/O -buffers were cacheline-aligned. Without that, you'd see cacheline -sharing problems (data corruption) on CPUs with DMA-incoherent caches. -(The CPU could write to one word, DMA would write to a different one -in the same cache line, and one of them could be overwritten.) - -Also, this means that you cannot take the return of a kmap() -call and DMA to/from that. This is similar to vmalloc(). - -What about block I/O and networking buffers? The block I/O and -networking subsystems make sure that the buffers they use are valid -for you to DMA from/to. - - DMA addressing limitations - -Does your device have any DMA addressing limitations? For example, is -your device only capable of driving the low order 24-bits of address? -If so, you need to inform the kernel of this fact. - -By default, the kernel assumes that your device can address the full -32-bits. For a 64-bit capable device, this needs to be increased. -And for a device with limitations, as discussed in the previous -paragraph, it needs to be decreased. - -Special note about PCI: PCI-X specification requires PCI-X devices to -support 64-bit addressing (DAC) for all transactions. And at least -one platform (SGI SN2) requires 64-bit consistent allocations to -operate correctly when the IO bus is in PCI-X mode. - -For correct operation, you must interrogate the kernel in your device -probe routine to see if the DMA controller on the machine can properly -support the DMA addressing limitation your device has. It is good -style to do this even if your device holds the default setting, -because this shows that you did think about these issues wrt. your -device. - -The query is performed via a call to dma_set_mask(): - - int dma_set_mask(struct device *dev, u64 mask); - -The query for consistent allocations is performed via a call to -dma_set_coherent_mask(): - - int dma_set_coherent_mask(struct device *dev, u64 mask); - -Here, dev is a pointer to the device struct of your device, and mask -is a bit mask describing which bits of an address your device -supports. It returns zero if your card can perform DMA properly on -the machine given the address mask you provided. In general, the -device struct of your device is embedded in the bus specific device -struct of your device. For example, a pointer to the device struct of -your PCI device is pdev->dev (pdev is a pointer to the PCI device -struct of your device). - -If it returns non-zero, your device cannot perform DMA properly on -this platform, and attempting to do so will result in undefined -behavior. You must either use a different mask, or not use DMA. - -This means that in the failure case, you have three options: - -1) Use another DMA mask, if possible (see below). -2) Use some non-DMA mode for data transfer, if possible. -3) Ignore this device and do not initialize it. - -It is recommended that your driver print a kernel KERN_WARNING message -when you end up performing either #2 or #3. In this manner, if a user -of your driver reports that performance is bad or that the device is not -even detected, you can ask them for the kernel messages to find out -exactly why. - -The standard 32-bit addressing device would do something like this: - - if (dma_set_mask(dev, DMA_BIT_MASK(32))) { - printk(KERN_WARNING - "mydev: No suitable DMA available.\n"); - goto ignore_this_device; - } - -Another common scenario is a 64-bit capable device. The approach here -is to try for 64-bit addressing, but back down to a 32-bit mask that -should not fail. The kernel may fail the 64-bit mask not because the -platform is not capable of 64-bit addressing. Rather, it may fail in -this case simply because 32-bit addressing is done more efficiently -than 64-bit addressing. For example, Sparc64 PCI SAC addressing is -more efficient than DAC addressing. - -Here is how you would handle a 64-bit capable device which can drive -all 64-bits when accessing streaming DMA: - - int using_dac; - - if (!dma_set_mask(dev, DMA_BIT_MASK(64))) { - using_dac = 1; - } else if (!dma_set_mask(dev, DMA_BIT_MASK(32))) { - using_dac = 0; - } else { - printk(KERN_WARNING - "mydev: No suitable DMA available.\n"); - goto ignore_this_device; - } - -If a card is capable of using 64-bit consistent allocations as well, -the case would look like this: - - int using_dac, consistent_using_dac; - - if (!dma_set_mask(dev, DMA_BIT_MASK(64))) { - using_dac = 1; - consistent_using_dac = 1; - dma_set_coherent_mask(dev, DMA_BIT_MASK(64)); - } else if (!dma_set_mask(dev, DMA_BIT_MASK(32))) { - using_dac = 0; - consistent_using_dac = 0; - dma_set_coherent_mask(dev, DMA_BIT_MASK(32)); - } else { - printk(KERN_WARNING - "mydev: No suitable DMA available.\n"); - goto ignore_this_device; - } - -dma_set_coherent_mask() will always be able to set the same or a -smaller mask as dma_set_mask(). However for the rare case that a -device driver only uses consistent allocations, one would have to -check the return value from dma_set_coherent_mask(). - -Finally, if your device can only drive the low 24-bits of -address you might do something like: - - if (dma_set_mask(dev, DMA_BIT_MASK(24))) { - printk(KERN_WARNING - "mydev: 24-bit DMA addressing not available.\n"); - goto ignore_this_device; - } - -When dma_set_mask() is successful, and returns zero, the kernel saves -away this mask you have provided. The kernel will use this -information later when you make DMA mappings. - -There is a case which we are aware of at this time, which is worth -mentioning in this documentation. If your device supports multiple -functions (for example a sound card provides playback and record -functions) and the various different functions have _different_ -DMA addressing limitations, you may wish to probe each mask and -only provide the functionality which the machine can handle. It -is important that the last call to dma_set_mask() be for the -most specific mask. - -Here is pseudo-code showing how this might be done: - - #define PLAYBACK_ADDRESS_BITS DMA_BIT_MASK(32) - #define RECORD_ADDRESS_BITS DMA_BIT_MASK(24) - - struct my_sound_card *card; - struct device *dev; - - ... - if (!dma_set_mask(dev, PLAYBACK_ADDRESS_BITS)) { - card->playback_enabled = 1; - } else { - card->playback_enabled = 0; - printk(KERN_WARNING "%s: Playback disabled due to DMA limitations.\n", - card->name); - } - if (!dma_set_mask(dev, RECORD_ADDRESS_BITS)) { - card->record_enabled = 1; - } else { - card->record_enabled = 0; - printk(KERN_WARNING "%s: Record disabled due to DMA limitations.\n", - card->name); - } - -A sound card was used as an example here because this genre of PCI -devices seems to be littered with ISA chips given a PCI front end, -and thus retaining the 16MB DMA addressing limitations of ISA. - - Types of DMA mappings - -There are two types of DMA mappings: - -- Consistent DMA mappings which are usually mapped at driver - initialization, unmapped at the end and for which the hardware should - guarantee that the device and the CPU can access the data - in parallel and will see updates made by each other without any - explicit software flushing. - - Think of "consistent" as "synchronous" or "coherent". - - The current default is to return consistent memory in the low 32 - bits of the bus space. However, for future compatibility you should - set the consistent mask even if this default is fine for your - driver. - - Good examples of what to use consistent mappings for are: - - - Network card DMA ring descriptors. - - SCSI adapter mailbox command data structures. - - Device firmware microcode executed out of - main memory. - - The invariant these examples all require is that any CPU store - to memory is immediately visible to the device, and vice - versa. Consistent mappings guarantee this. - - IMPORTANT: Consistent DMA memory does not preclude the usage of - proper memory barriers. The CPU may reorder stores to - consistent memory just as it may normal memory. Example: - if it is important for the device to see the first word - of a descriptor updated before the second, you must do - something like: - - desc->word0 = address; - wmb(); - desc->word1 = DESC_VALID; - - in order to get correct behavior on all platforms. - - Also, on some platforms your driver may need to flush CPU write - buffers in much the same way as it needs to flush write buffers - found in PCI bridges (such as by reading a register's value - after writing it). - -- Streaming DMA mappings which are usually mapped for one DMA - transfer, unmapped right after it (unless you use dma_sync_* below) - and for which hardware can optimize for sequential accesses. - - This of "streaming" as "asynchronous" or "outside the coherency - domain". - - Good examples of what to use streaming mappings for are: - - - Networking buffers transmitted/received by a device. - - Filesystem buffers written/read by a SCSI device. - - The interfaces for using this type of mapping were designed in - such a way that an implementation can make whatever performance - optimizations the hardware allows. To this end, when using - such mappings you must be explicit about what you want to happen. - -Neither type of DMA mapping has alignment restrictions that come from -the underlying bus, although some devices may have such restrictions. -Also, systems with caches that aren't DMA-coherent will work better -when the underlying buffers don't share cache lines with other data. - - - Using Consistent DMA mappings. - -To allocate and map large (PAGE_SIZE or so) consistent DMA regions, -you should do: - - dma_addr_t dma_handle; - - cpu_addr = dma_alloc_coherent(dev, size, &dma_handle, gfp); - -where device is a struct device *. This may be called in interrupt -context with the GFP_ATOMIC flag. - -Size is the length of the region you want to allocate, in bytes. - -This routine will allocate RAM for that region, so it acts similarly to -__get_free_pages (but takes size instead of a page order). If your -driver needs regions sized smaller than a page, you may prefer using -the dma_pool interface, described below. - -The consistent DMA mapping interfaces, for non-NULL dev, will by -default return a DMA address which is 32-bit addressable. Even if the -device indicates (via DMA mask) that it may address the upper 32-bits, -consistent allocation will only return > 32-bit addresses for DMA if -the consistent DMA mask has been explicitly changed via -dma_set_coherent_mask(). This is true of the dma_pool interface as -well. - -dma_alloc_coherent returns two values: the virtual address which you -can use to access it from the CPU and dma_handle which you pass to the -card. - -The cpu return address and the DMA bus master address are both -guaranteed to be aligned to the smallest PAGE_SIZE order which -is greater than or equal to the requested size. This invariant -exists (for example) to guarantee that if you allocate a chunk -which is smaller than or equal to 64 kilobytes, the extent of the -buffer you receive will not cross a 64K boundary. - -To unmap and free such a DMA region, you call: - - dma_free_coherent(dev, size, cpu_addr, dma_handle); - -where dev, size are the same as in the above call and cpu_addr and -dma_handle are the values dma_alloc_coherent returned to you. -This function may not be called in interrupt context. - -If your driver needs lots of smaller memory regions, you can write -custom code to subdivide pages returned by dma_alloc_coherent, -or you can use the dma_pool API to do that. A dma_pool is like -a kmem_cache, but it uses dma_alloc_coherent not __get_free_pages. -Also, it understands common hardware constraints for alignment, -like queue heads needing to be aligned on N byte boundaries. - -Create a dma_pool like this: - - struct dma_pool *pool; - - pool = dma_pool_create(name, dev, size, align, alloc); - -The "name" is for diagnostics (like a kmem_cache name); dev and size -are as above. The device's hardware alignment requirement for this -type of data is "align" (which is expressed in bytes, and must be a -power of two). If your device has no boundary crossing restrictions, -pass 0 for alloc; passing 4096 says memory allocated from this pool -must not cross 4KByte boundaries (but at that time it may be better to -go for dma_alloc_coherent directly instead). - -Allocate memory from a dma pool like this: - - cpu_addr = dma_pool_alloc(pool, flags, &dma_handle); - -flags are SLAB_KERNEL if blocking is permitted (not in_interrupt nor -holding SMP locks), SLAB_ATOMIC otherwise. Like dma_alloc_coherent, -this returns two values, cpu_addr and dma_handle. - -Free memory that was allocated from a dma_pool like this: - - dma_pool_free(pool, cpu_addr, dma_handle); - -where pool is what you passed to dma_pool_alloc, and cpu_addr and -dma_handle are the values dma_pool_alloc returned. This function -may be called in interrupt context. - -Destroy a dma_pool by calling: - - dma_pool_destroy(pool); - -Make sure you've called dma_pool_free for all memory allocated -from a pool before you destroy the pool. This function may not -be called in interrupt context. - - DMA Direction - -The interfaces described in subsequent portions of this document -take a DMA direction argument, which is an integer and takes on -one of the following values: - - DMA_BIDIRECTIONAL - DMA_TO_DEVICE - DMA_FROM_DEVICE - DMA_NONE - -One should provide the exact DMA direction if you know it. - -DMA_TO_DEVICE means "from main memory to the device" -DMA_FROM_DEVICE means "from the device to main memory" -It is the direction in which the data moves during the DMA -transfer. - -You are _strongly_ encouraged to specify this as precisely -as you possibly can. - -If you absolutely cannot know the direction of the DMA transfer, -specify DMA_BIDIRECTIONAL. It means that the DMA can go in -either direction. The platform guarantees that you may legally -specify this, and that it will work, but this may be at the -cost of performance for example. - -The value DMA_NONE is to be used for debugging. One can -hold this in a data structure before you come to know the -precise direction, and this will help catch cases where your -direction tracking logic has failed to set things up properly. - -Another advantage of specifying this value precisely (outside of -potential platform-specific optimizations of such) is for debugging. -Some platforms actually have a write permission boolean which DMA -mappings can be marked with, much like page protections in the user -program address space. Such platforms can and do report errors in the -kernel logs when the DMA controller hardware detects violation of the -permission setting. - -Only streaming mappings specify a direction, consistent mappings -implicitly have a direction attribute setting of -DMA_BIDIRECTIONAL. - -The SCSI subsystem tells you the direction to use in the -'sc_data_direction' member of the SCSI command your driver is -working on. - -For Networking drivers, it's a rather simple affair. For transmit -packets, map/unmap them with the DMA_TO_DEVICE direction -specifier. For receive packets, just the opposite, map/unmap them -with the DMA_FROM_DEVICE direction specifier. - - Using Streaming DMA mappings - -The streaming DMA mapping routines can be called from interrupt -context. There are two versions of each map/unmap, one which will -map/unmap a single memory region, and one which will map/unmap a -scatterlist. - -To map a single region, you do: - - struct device *dev = &my_dev->dev; - dma_addr_t dma_handle; - void *addr = buffer->ptr; - size_t size = buffer->len; - - dma_handle = dma_map_single(dev, addr, size, direction); - -and to unmap it: - - dma_unmap_single(dev, dma_handle, size, direction); - -You should call dma_unmap_single when the DMA activity is finished, e.g. -from the interrupt which told you that the DMA transfer is done. - -Using cpu pointers like this for single mappings has a disadvantage, -you cannot reference HIGHMEM memory in this way. Thus, there is a -map/unmap interface pair akin to dma_{map,unmap}_single. These -interfaces deal with page/offset pairs instead of cpu pointers. -Specifically: - - struct device *dev = &my_dev->dev; - dma_addr_t dma_handle; - struct page *page = buffer->page; - unsigned long offset = buffer->offset; - size_t size = buffer->len; - - dma_handle = dma_map_page(dev, page, offset, size, direction); - - ... - - dma_unmap_page(dev, dma_handle, size, direction); - -Here, "offset" means byte offset within the given page. - -With scatterlists, you map a region gathered from several regions by: - - int i, count = dma_map_sg(dev, sglist, nents, direction); - struct scatterlist *sg; - - for_each_sg(sglist, sg, count, i) { - hw_address[i] = sg_dma_address(sg); - hw_len[i] = sg_dma_len(sg); - } - -where nents is the number of entries in the sglist. - -The implementation is free to merge several consecutive sglist entries -into one (e.g. if DMA mapping is done with PAGE_SIZE granularity, any -consecutive sglist entries can be merged into one provided the first one -ends and the second one starts on a page boundary - in fact this is a huge -advantage for cards which either cannot do scatter-gather or have very -limited number of scatter-gather entries) and returns the actual number -of sg entries it mapped them to. On failure 0 is returned. - -Then you should loop count times (note: this can be less than nents times) -and use sg_dma_address() and sg_dma_len() macros where you previously -accessed sg->address and sg->length as shown above. - -To unmap a scatterlist, just call: - - dma_unmap_sg(dev, sglist, nents, direction); - -Again, make sure DMA activity has already finished. - -PLEASE NOTE: The 'nents' argument to the dma_unmap_sg call must be - the _same_ one you passed into the dma_map_sg call, - it should _NOT_ be the 'count' value _returned_ from the - dma_map_sg call. - -Every dma_map_{single,sg} call should have its dma_unmap_{single,sg} -counterpart, because the bus address space is a shared resource (although -in some ports the mapping is per each BUS so less devices contend for the -same bus address space) and you could render the machine unusable by eating -all bus addresses. - -If you need to use the same streaming DMA region multiple times and touch -the data in between the DMA transfers, the buffer needs to be synced -properly in order for the cpu and device to see the most uptodate and -correct copy of the DMA buffer. - -So, firstly, just map it with dma_map_{single,sg}, and after each DMA -transfer call either: - - dma_sync_single_for_cpu(dev, dma_handle, size, direction); - -or: - - dma_sync_sg_for_cpu(dev, sglist, nents, direction); - -as appropriate. - -Then, if you wish to let the device get at the DMA area again, -finish accessing the data with the cpu, and then before actually -giving the buffer to the hardware call either: - - dma_sync_single_for_device(dev, dma_handle, size, direction); - -or: - - dma_sync_sg_for_device(dev, sglist, nents, direction); - -as appropriate. - -After the last DMA transfer call one of the DMA unmap routines -dma_unmap_{single,sg}. If you don't touch the data from the first dma_map_* -call till dma_unmap_*, then you don't have to call the dma_sync_* -routines at all. - -Here is pseudo code which shows a situation in which you would need -to use the dma_sync_*() interfaces. - - my_card_setup_receive_buffer(struct my_card *cp, char *buffer, int len) - { - dma_addr_t mapping; - - mapping = dma_map_single(cp->dev, buffer, len, DMA_FROM_DEVICE); - - cp->rx_buf = buffer; - cp->rx_len = len; - cp->rx_dma = mapping; - - give_rx_buf_to_card(cp); - } - - ... - - my_card_interrupt_handler(int irq, void *devid, struct pt_regs *regs) - { - struct my_card *cp = devid; - - ... - if (read_card_status(cp) == RX_BUF_TRANSFERRED) { - struct my_card_header *hp; - - /* Examine the header to see if we wish - * to accept the data. But synchronize - * the DMA transfer with the CPU first - * so that we see updated contents. - */ - dma_sync_single_for_cpu(&cp->dev, cp->rx_dma, - cp->rx_len, - DMA_FROM_DEVICE); - - /* Now it is safe to examine the buffer. */ - hp = (struct my_card_header *) cp->rx_buf; - if (header_is_ok(hp)) { - dma_unmap_single(&cp->dev, cp->rx_dma, cp->rx_len, - DMA_FROM_DEVICE); - pass_to_upper_layers(cp->rx_buf); - make_and_setup_new_rx_buf(cp); - } else { - /* Just sync the buffer and give it back - * to the card. - */ - dma_sync_single_for_device(&cp->dev, - cp->rx_dma, - cp->rx_len, - DMA_FROM_DEVICE); - give_rx_buf_to_card(cp); - } - } - } - -Drivers converted fully to this interface should not use virt_to_bus any -longer, nor should they use bus_to_virt. Some drivers have to be changed a -little bit, because there is no longer an equivalent to bus_to_virt in the -dynamic DMA mapping scheme - you have to always store the DMA addresses -returned by the dma_alloc_coherent, dma_pool_alloc, and dma_map_single -calls (dma_map_sg stores them in the scatterlist itself if the platform -supports dynamic DMA mapping in hardware) in your driver structures and/or -in the card registers. - -All drivers should be using these interfaces with no exceptions. It -is planned to completely remove virt_to_bus() and bus_to_virt() as -they are entirely deprecated. Some ports already do not provide these -as it is impossible to correctly support them. - - Optimizing Unmap State Space Consumption - -On many platforms, dma_unmap_{single,page}() is simply a nop. -Therefore, keeping track of the mapping address and length is a waste -of space. Instead of filling your drivers up with ifdefs and the like -to "work around" this (which would defeat the whole purpose of a -portable API) the following facilities are provided. - -Actually, instead of describing the macros one by one, we'll -transform some example code. - -1) Use DEFINE_DMA_UNMAP_{ADDR,LEN} in state saving structures. - Example, before: - - struct ring_state { - struct sk_buff *skb; - dma_addr_t mapping; - __u32 len; - }; - - after: - - struct ring_state { - struct sk_buff *skb; - DEFINE_DMA_UNMAP_ADDR(mapping); - DEFINE_DMA_UNMAP_LEN(len); - }; - -2) Use dma_unmap_{addr,len}_set to set these values. - Example, before: - - ringp->mapping = FOO; - ringp->len = BAR; - - after: - - dma_unmap_addr_set(ringp, mapping, FOO); - dma_unmap_len_set(ringp, len, BAR); - -3) Use dma_unmap_{addr,len} to access these values. - Example, before: - - dma_unmap_single(dev, ringp->mapping, ringp->len, - DMA_FROM_DEVICE); - - after: - - dma_unmap_single(dev, - dma_unmap_addr(ringp, mapping), - dma_unmap_len(ringp, len), - DMA_FROM_DEVICE); - -It really should be self-explanatory. We treat the ADDR and LEN -separately, because it is possible for an implementation to only -need the address in order to perform the unmap operation. - - Platform Issues - -If you are just writing drivers for Linux and do not maintain -an architecture port for the kernel, you can safely skip down -to "Closing". - -1) Struct scatterlist requirements. - - Struct scatterlist must contain, at a minimum, the following - members: - - struct page *page; - unsigned int offset; - unsigned int length; - - The base address is specified by a "page+offset" pair. - - Previous versions of struct scatterlist contained a "void *address" - field that was sometimes used instead of page+offset. As of Linux - 2.5., page+offset is always used, and the "address" field has been - deleted. - -2) More to come... - - Handling Errors - -DMA address space is limited on some architectures and an allocation -failure can be determined by: - -- checking if dma_alloc_coherent returns NULL or dma_map_sg returns 0 - -- checking the returned dma_addr_t of dma_map_single and dma_map_page - by using dma_mapping_error(): - - dma_addr_t dma_handle; - - dma_handle = dma_map_single(dev, addr, size, direction); - if (dma_mapping_error(dev, dma_handle)) { - /* - * reduce current DMA mapping usage, - * delay and try again later or - * reset driver. - */ - } - - Closing - -This document, and the API itself, would not be in it's current -form without the feedback and suggestions from numerous individuals. -We would like to specifically mention, in no particular order, the -following people: - - Russell King - Leo Dagum - Ralf Baechle - Grant Grundler - Jay Estabrook - Thomas Sailer - Andrea Arcangeli - Jens Axboe - David Mosberger-Tang -- cgit v0.10.2 From 20072205fcdf7d85cd3101f1f11dfab333c5fd0c Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 23 Mar 2010 13:35:24 -0700 Subject: scripts/kernel-doc: fix fatal error on function prototype Fix a fatal error in scripts/kernel-doc when a function signature uses __init_or_module (just ignore that string): Error(drivers/base/platform.c:568): cannot understand prototype: 'struct platform_device * __init_or_module platform_create_bundle(struct platform_driver *driver, int (*probe)(struct platform_device *), struct resource *res, unsigned int n_res, const void *data, size_t size) ' Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/scripts/kernel-doc b/scripts/kernel-doc index c297eb4..fcdfb24 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1730,6 +1730,7 @@ sub dump_function($$) { $prototype =~ s/^noinline +//; $prototype =~ s/__devinit +//; $prototype =~ s/__init +//; + $prototype =~ s/__init_or_module +//; $prototype =~ s/^#\s*define\s+//; #ak added $prototype =~ s/__attribute__\s*\(\([a-z,]*\)\)//; -- cgit v0.10.2 From cb53237513bd1e090cce120efe12ede72c932b5f Mon Sep 17 00:00:00 2001 From: Robin Holt Date: Tue, 23 Mar 2010 13:35:26 -0700 Subject: mm/ksm.c is doing an unneeded _notify in write_protect_page. ksm.c's write_protect_page implements a lockless means of verifying a page does not have any users of the page which are not accounted for via other kernel tracking means. It does this by removing the writable pte with TLB flushes, checking the page_count against the total known users, and then using set_pte_at_notify to make it a read-only entry. An unneeded mmu_notifier callout is made in the case where the known users does not match the page_count. In that event, we are inserting the identical pte and there is no need for the set_pte_at_notify, but rather the simpler set_pte_at suffices. Signed-off-by: Robin Holt Acked-by: Izik Eidus Acked-by: Andrea Arcangeli Acked-by: Hugh Dickins Cc: Chris Wright Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/mm/ksm.c b/mm/ksm.c index a93f1b7..8cdfc2a 100644 --- a/mm/ksm.c +++ b/mm/ksm.c @@ -751,7 +751,7 @@ static int write_protect_page(struct vm_area_struct *vma, struct page *page, * page */ if (page_mapcount(page) + 1 + swapped != page_count(page)) { - set_pte_at_notify(mm, addr, ptep, entry); + set_pte_at(mm, addr, ptep, entry); goto out_unlock; } entry = pte_wrprotect(entry); -- cgit v0.10.2 From 8c363afe94b885d39ae2e93e41680282a470ad84 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 23 Mar 2010 13:35:27 -0700 Subject: c2port: fix device_create() return value check Use IS_ERR() instead of comparing to NULL. [akpm@linux-foundation.org: preserve the error code] Signed-off-by: Jani Nikula Cc: Vegard Nossum Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/misc/c2port/core.c b/drivers/misc/c2port/core.c index b5346b4..b7a85f4 100644 --- a/drivers/misc/c2port/core.c +++ b/drivers/misc/c2port/core.c @@ -912,8 +912,8 @@ struct c2port_device *c2port_device_register(char *name, c2dev->dev = device_create(c2port_class, NULL, 0, c2dev, "c2port%d", id); - if (unlikely(!c2dev->dev)) { - ret = -ENOMEM; + if (unlikely(IS_ERR(c2dev->dev))) { + ret = PTR_ERR(c2dev->dev); goto error_device_create; } dev_set_drvdata(c2dev->dev, c2dev); -- cgit v0.10.2 From 413b43deab8377819aba1dbad2abf0c15d59b491 Mon Sep 17 00:00:00 2001 From: Ravikiran G Thirumalai Date: Tue, 23 Mar 2010 13:35:28 -0700 Subject: tmpfs: fix oops on mounts with mpol=default Fix an 'oops' when a tmpfs mount point is mounted with the mpol=default mempolicy. Upon remounting a tmpfs mount point with 'mpol=default' option, the mount code crashed with a null pointer dereference. The initial problem report was on 2.6.27, but the problem exists in mainline 2.6.34-rc as well. On examining the code, we see that mpol_new returns NULL if default mempolicy was requested. This 'NULL' mempolicy is accessed to store the node mask resulting in oops. The following patch fixes it. Signed-off-by: Ravikiran Thirumalai Signed-off-by: KOSAKI Motohiro Cc: Christoph Lameter Cc: Mel Gorman Acked-by: Lee Schermerhorn Cc: Hugh Dickins Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 643f66e..745ce90 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -2215,10 +2215,15 @@ int mpol_parse_str(char *str, struct mempolicy **mpol, int no_context) goto out; mode = MPOL_PREFERRED; break; - + case MPOL_DEFAULT: + /* + * Insist on a empty nodelist + */ + if (!nodelist) + err = 0; + goto out; /* * case MPOL_BIND: mpol_new() enforces non-empty nodemask. - * case MPOL_DEFAULT: mpol_new() enforces empty nodemask, ignores flags. */ } -- cgit v0.10.2 From d69b2e63e9172afb4d07c305601b79a55509ac4c Mon Sep 17 00:00:00 2001 From: KOSAKI Motohiro Date: Tue, 23 Mar 2010 13:35:30 -0700 Subject: tmpfs: mpol=bind:0 don't cause mount error. Currently, following mount operation cause mount error. % mount -t tmpfs -ompol=bind:0 none /tmp Because commit 71fe804b6d5 (mempolicy: use struct mempolicy pointer in shmem_sb_info) corrupted MPOL_BIND parse code. This patch restore the needed one. Signed-off-by: KOSAKI Motohiro Cc: Ravikiran Thirumalai Cc: Christoph Lameter Cc: Mel Gorman Acked-by: Lee Schermerhorn Cc: Hugh Dickins Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 745ce90..10db44f 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -2222,9 +2222,13 @@ int mpol_parse_str(char *str, struct mempolicy **mpol, int no_context) if (!nodelist) err = 0; goto out; - /* - * case MPOL_BIND: mpol_new() enforces non-empty nodemask. - */ + case MPOL_BIND: + /* + * Insist on a nodelist + */ + if (!nodelist) + goto out; + err = 0; } mode_flags = 0; -- cgit v0.10.2 From 12821f5fb942e795f8009ece14bde868893bd811 Mon Sep 17 00:00:00 2001 From: KOSAKI Motohiro Date: Tue, 23 Mar 2010 13:35:31 -0700 Subject: tmpfs: handle MPOL_LOCAL mount option properly commit 71fe804b6d5 (mempolicy: use struct mempolicy pointer in shmem_sb_info) added mpol=local mount option. but its feature is broken since it was born. because such code always return 1 (i.e. mount failure). This patch fixes it. Signed-off-by: KOSAKI Motohiro Cc: Ravikiran Thirumalai Cc: Christoph Lameter Cc: Mel Gorman Acked-by: Lee Schermerhorn Cc: Hugh Dickins Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 10db44f..fb71790 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -2214,6 +2214,7 @@ int mpol_parse_str(char *str, struct mempolicy **mpol, int no_context) if (nodelist) goto out; mode = MPOL_PREFERRED; + err = 0; break; case MPOL_DEFAULT: /* -- cgit v0.10.2 From 926f2ae04f183098cf9a30521776fb2759c8afeb Mon Sep 17 00:00:00 2001 From: KOSAKI Motohiro Date: Tue, 23 Mar 2010 13:35:32 -0700 Subject: tmpfs: cleanup mpol_parse_str() mpol_parse_str() made lots 'err' variable related bug. Because it is ugly and reviewing unfriendly. This patch simplifies it. Signed-off-by: KOSAKI Motohiro Cc: Ravikiran Thirumalai Cc: Christoph Lameter Cc: Mel Gorman Acked-by: Lee Schermerhorn Cc: Hugh Dickins Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/mm/mempolicy.c b/mm/mempolicy.c index fb71790..6cdfa1d 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -2195,8 +2195,8 @@ int mpol_parse_str(char *str, struct mempolicy **mpol, int no_context) char *rest = nodelist; while (isdigit(*rest)) rest++; - if (!*rest) - err = 0; + if (*rest) + goto out; } break; case MPOL_INTERLEAVE: @@ -2205,7 +2205,6 @@ int mpol_parse_str(char *str, struct mempolicy **mpol, int no_context) */ if (!nodelist) nodes = node_states[N_HIGH_MEMORY]; - err = 0; break; case MPOL_LOCAL: /* @@ -2214,7 +2213,6 @@ int mpol_parse_str(char *str, struct mempolicy **mpol, int no_context) if (nodelist) goto out; mode = MPOL_PREFERRED; - err = 0; break; case MPOL_DEFAULT: /* @@ -2229,7 +2227,6 @@ int mpol_parse_str(char *str, struct mempolicy **mpol, int no_context) */ if (!nodelist) goto out; - err = 0; } mode_flags = 0; @@ -2243,13 +2240,14 @@ int mpol_parse_str(char *str, struct mempolicy **mpol, int no_context) else if (!strcmp(flags, "relative")) mode_flags |= MPOL_F_RELATIVE_NODES; else - err = 1; + goto out; } new = mpol_new(mode, mode_flags, &nodes); if (IS_ERR(new)) - err = 1; - else { + goto out; + + { int ret; NODEMASK_SCRATCH(scratch); if (scratch) { @@ -2260,13 +2258,15 @@ int mpol_parse_str(char *str, struct mempolicy **mpol, int no_context) ret = -ENOMEM; NODEMASK_SCRATCH_FREE(scratch); if (ret) { - err = 1; mpol_put(new); - } else if (no_context) { - /* save for contextualization */ - new->w.user_nodemask = nodes; + goto out; } } + err = 0; + if (no_context) { + /* save for contextualization */ + new->w.user_nodemask = nodes; + } out: /* Restore string for error message */ -- cgit v0.10.2 From 5574169613b40b85d6f4c67208fa4846b897a0a1 Mon Sep 17 00:00:00 2001 From: KOSAKI Motohiro Date: Tue, 23 Mar 2010 13:35:33 -0700 Subject: doc: add the documentation for mpol=local commit 3f226aa1c (mempolicy: support mpol=local tmpfs mount option) added new mpol=local mount option. but it didn't add a documentation. This patch does it. Signed-off-by: KOSAKI Motohiro Cc: Ravikiran Thirumalai Cc: Christoph Lameter Cc: Mel Gorman Acked-by: Lee Schermerhorn Cc: Hugh Dickins Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/Documentation/filesystems/tmpfs.txt b/Documentation/filesystems/tmpfs.txt index 3015da0..fe09a2c 100644 --- a/Documentation/filesystems/tmpfs.txt +++ b/Documentation/filesystems/tmpfs.txt @@ -82,11 +82,13 @@ tmpfs has a mount option to set the NUMA memory allocation policy for all files in that instance (if CONFIG_NUMA is enabled) - which can be adjusted on the fly via 'mount -o remount ...' -mpol=default prefers to allocate memory from the local node +mpol=default use the process allocation policy + (see set_mempolicy(2)) mpol=prefer:Node prefers to allocate memory from the given Node mpol=bind:NodeList allocates memory only from nodes in NodeList mpol=interleave prefers to allocate from each node in turn mpol=interleave:NodeList allocates from each node of NodeList in turn +mpol=local prefers to allocate memory from the local node NodeList format is a comma-separated list of decimal numbers and ranges, a range being two hyphen-separated decimal numbers, the smallest and @@ -134,3 +136,5 @@ Author: Christoph Rohland , 1.12.01 Updated: Hugh Dickins, 4 June 2007 +Updated: + KOSAKI Motohiro, 16 Mar 2010 -- cgit v0.10.2 From 5ab116c9349ef52d6fbd2e2917a53f13194b048e Mon Sep 17 00:00:00 2001 From: Miao Xie Date: Tue, 23 Mar 2010 13:35:34 -0700 Subject: cpuset: fix the problem that cpuset_mem_spread_node() returns an offline node cpuset_mem_spread_node() returns an offline node, and causes an oops. This patch fixes it by initializing task->mems_allowed to node_states[N_HIGH_MEMORY], and updating task->mems_allowed when doing memory hotplug. Signed-off-by: Miao Xie Acked-by: David Rientjes Reported-by: Nick Piggin Tested-by: Nick Piggin Cc: Paul Menage Cc: Li Zefan Cc: Ingo Molnar Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/init/main.c b/init/main.c index a1ab78c..cbead27 100644 --- a/init/main.c +++ b/init/main.c @@ -858,7 +858,7 @@ static int __init kernel_init(void * unused) /* * init can allocate pages on any node */ - set_mems_allowed(node_possible_map); + set_mems_allowed(node_states[N_HIGH_MEMORY]); /* * init can run on any cpu. */ diff --git a/kernel/cpuset.c b/kernel/cpuset.c index ba401fa..5d38bd7 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c @@ -920,9 +920,6 @@ static int update_cpumask(struct cpuset *cs, struct cpuset *trialcs, * call to guarantee_online_mems(), as we know no one is changing * our task's cpuset. * - * Hold callback_mutex around the two modifications of our tasks - * mems_allowed to synchronize with cpuset_mems_allowed(). - * * While the mm_struct we are migrating is typically from some * other task, the task_struct mems_allowed that we are hacking * is for our current task, which must allocate new pages for that @@ -1391,11 +1388,10 @@ static void cpuset_attach(struct cgroup_subsys *ss, struct cgroup *cont, if (cs == &top_cpuset) { cpumask_copy(cpus_attach, cpu_possible_mask); - to = node_possible_map; } else { guarantee_online_cpus(cs, cpus_attach); - guarantee_online_mems(cs, &to); } + guarantee_online_mems(cs, &to); /* do per-task migration stuff possibly for each in the threadgroup */ cpuset_attach_task(tsk, &to, cs); @@ -2090,15 +2086,23 @@ static int cpuset_track_online_cpus(struct notifier_block *unused_nb, static int cpuset_track_online_nodes(struct notifier_block *self, unsigned long action, void *arg) { + nodemask_t oldmems; + cgroup_lock(); switch (action) { case MEM_ONLINE: - case MEM_OFFLINE: + oldmems = top_cpuset.mems_allowed; mutex_lock(&callback_mutex); top_cpuset.mems_allowed = node_states[N_HIGH_MEMORY]; mutex_unlock(&callback_mutex); - if (action == MEM_OFFLINE) - scan_for_empty_cpusets(&top_cpuset); + update_tasks_nodemask(&top_cpuset, &oldmems, NULL); + break; + case MEM_OFFLINE: + /* + * needn't update top_cpuset.mems_allowed explicitly because + * scan_for_empty_cpusets() will update it. + */ + scan_for_empty_cpusets(&top_cpuset); break; default: break; diff --git a/kernel/kthread.c b/kernel/kthread.c index 82ed0ea..83911c7 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -219,7 +219,7 @@ int kthreadd(void *unused) set_task_comm(tsk, "kthreadd"); ignore_signals(tsk); set_cpus_allowed_ptr(tsk, cpu_all_mask); - set_mems_allowed(node_possible_map); + set_mems_allowed(node_states[N_HIGH_MEMORY]); current->flags |= PF_NOFREEZE | PF_FREEZER_NOSIG; -- cgit v0.10.2 From 53feb29767c29c877f9d47dcfe14211b5b0f7ebd Mon Sep 17 00:00:00 2001 From: Miao Xie Date: Tue, 23 Mar 2010 13:35:35 -0700 Subject: cpuset: alloc nodemask_t on the heap rather than the stack Signed-off-by: Miao Xie Acked-by: David Rientjes Cc: Nick Piggin Cc: Paul Menage Cc: Li Zefan Cc: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/kernel/cpuset.c b/kernel/cpuset.c index 5d38bd7..d109467 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c @@ -970,15 +970,20 @@ static void cpuset_change_nodemask(struct task_struct *p, struct cpuset *cs; int migrate; const nodemask_t *oldmem = scan->data; - nodemask_t newmems; + NODEMASK_ALLOC(nodemask_t, newmems, GFP_KERNEL); + + if (!newmems) + return; cs = cgroup_cs(scan->cg); - guarantee_online_mems(cs, &newmems); + guarantee_online_mems(cs, newmems); task_lock(p); - cpuset_change_task_nodemask(p, &newmems); + cpuset_change_task_nodemask(p, newmems); task_unlock(p); + NODEMASK_FREE(newmems); + mm = get_task_mm(p); if (!mm) return; @@ -1048,16 +1053,21 @@ static void update_tasks_nodemask(struct cpuset *cs, const nodemask_t *oldmem, static int update_nodemask(struct cpuset *cs, struct cpuset *trialcs, const char *buf) { - nodemask_t oldmem; + NODEMASK_ALLOC(nodemask_t, oldmem, GFP_KERNEL); int retval; struct ptr_heap heap; + if (!oldmem) + return -ENOMEM; + /* * top_cpuset.mems_allowed tracks node_stats[N_HIGH_MEMORY]; * it's read-only */ - if (cs == &top_cpuset) - return -EACCES; + if (cs == &top_cpuset) { + retval = -EACCES; + goto done; + } /* * An empty mems_allowed is ok iff there are no tasks in the cpuset. @@ -1073,11 +1083,13 @@ static int update_nodemask(struct cpuset *cs, struct cpuset *trialcs, goto done; if (!nodes_subset(trialcs->mems_allowed, - node_states[N_HIGH_MEMORY])) - return -EINVAL; + node_states[N_HIGH_MEMORY])) { + retval = -EINVAL; + goto done; + } } - oldmem = cs->mems_allowed; - if (nodes_equal(oldmem, trialcs->mems_allowed)) { + *oldmem = cs->mems_allowed; + if (nodes_equal(*oldmem, trialcs->mems_allowed)) { retval = 0; /* Too easy - nothing to do */ goto done; } @@ -1093,10 +1105,11 @@ static int update_nodemask(struct cpuset *cs, struct cpuset *trialcs, cs->mems_allowed = trialcs->mems_allowed; mutex_unlock(&callback_mutex); - update_tasks_nodemask(cs, &oldmem, &heap); + update_tasks_nodemask(cs, oldmem, &heap); heap_free(&heap); done: + NODEMASK_FREE(oldmem); return retval; } @@ -1381,39 +1394,47 @@ static void cpuset_attach(struct cgroup_subsys *ss, struct cgroup *cont, struct cgroup *oldcont, struct task_struct *tsk, bool threadgroup) { - nodemask_t from, to; struct mm_struct *mm; struct cpuset *cs = cgroup_cs(cont); struct cpuset *oldcs = cgroup_cs(oldcont); + NODEMASK_ALLOC(nodemask_t, from, GFP_KERNEL); + NODEMASK_ALLOC(nodemask_t, to, GFP_KERNEL); + + if (from == NULL || to == NULL) + goto alloc_fail; if (cs == &top_cpuset) { cpumask_copy(cpus_attach, cpu_possible_mask); } else { guarantee_online_cpus(cs, cpus_attach); } - guarantee_online_mems(cs, &to); + guarantee_online_mems(cs, to); /* do per-task migration stuff possibly for each in the threadgroup */ - cpuset_attach_task(tsk, &to, cs); + cpuset_attach_task(tsk, to, cs); if (threadgroup) { struct task_struct *c; rcu_read_lock(); list_for_each_entry_rcu(c, &tsk->thread_group, thread_group) { - cpuset_attach_task(c, &to, cs); + cpuset_attach_task(c, to, cs); } rcu_read_unlock(); } /* change mm; only needs to be done once even if threadgroup */ - from = oldcs->mems_allowed; - to = cs->mems_allowed; + *from = oldcs->mems_allowed; + *to = cs->mems_allowed; mm = get_task_mm(tsk); if (mm) { - mpol_rebind_mm(mm, &to); + mpol_rebind_mm(mm, to); if (is_memory_migrate(cs)) - cpuset_migrate_mm(mm, &from, &to); + cpuset_migrate_mm(mm, from, to); mmput(mm); } + +alloc_fail: + NODEMASK_FREE(from); + NODEMASK_FREE(to); } /* The various types of files and directories in a cpuset file system */ @@ -1558,13 +1579,21 @@ static int cpuset_sprintf_cpulist(char *page, struct cpuset *cs) static int cpuset_sprintf_memlist(char *page, struct cpuset *cs) { - nodemask_t mask; + NODEMASK_ALLOC(nodemask_t, mask, GFP_KERNEL); + int retval; + + if (mask == NULL) + return -ENOMEM; mutex_lock(&callback_mutex); - mask = cs->mems_allowed; + *mask = cs->mems_allowed; mutex_unlock(&callback_mutex); - return nodelist_scnprintf(page, PAGE_SIZE, mask); + retval = nodelist_scnprintf(page, PAGE_SIZE, *mask); + + NODEMASK_FREE(mask); + + return retval; } static ssize_t cpuset_common_file_read(struct cgroup *cont, @@ -1993,7 +2022,10 @@ static void scan_for_empty_cpusets(struct cpuset *root) struct cpuset *cp; /* scans cpusets being updated */ struct cpuset *child; /* scans child cpusets of cp */ struct cgroup *cont; - nodemask_t oldmems; + NODEMASK_ALLOC(nodemask_t, oldmems, GFP_KERNEL); + + if (oldmems == NULL) + return; list_add_tail((struct list_head *)&root->stack_list, &queue); @@ -2010,7 +2042,7 @@ static void scan_for_empty_cpusets(struct cpuset *root) nodes_subset(cp->mems_allowed, node_states[N_HIGH_MEMORY])) continue; - oldmems = cp->mems_allowed; + *oldmems = cp->mems_allowed; /* Remove offline cpus and mems from this cpuset. */ mutex_lock(&callback_mutex); @@ -2026,9 +2058,10 @@ static void scan_for_empty_cpusets(struct cpuset *root) remove_tasks_in_empty_cpuset(cp); else { update_tasks_cpumask(cp, NULL); - update_tasks_nodemask(cp, &oldmems, NULL); + update_tasks_nodemask(cp, oldmems, NULL); } } + NODEMASK_FREE(oldmems); } /* @@ -2086,16 +2119,19 @@ static int cpuset_track_online_cpus(struct notifier_block *unused_nb, static int cpuset_track_online_nodes(struct notifier_block *self, unsigned long action, void *arg) { - nodemask_t oldmems; + NODEMASK_ALLOC(nodemask_t, oldmems, GFP_KERNEL); + + if (oldmems == NULL) + return NOTIFY_DONE; cgroup_lock(); switch (action) { case MEM_ONLINE: - oldmems = top_cpuset.mems_allowed; + *oldmems = top_cpuset.mems_allowed; mutex_lock(&callback_mutex); top_cpuset.mems_allowed = node_states[N_HIGH_MEMORY]; mutex_unlock(&callback_mutex); - update_tasks_nodemask(&top_cpuset, &oldmems, NULL); + update_tasks_nodemask(&top_cpuset, oldmems, NULL); break; case MEM_OFFLINE: /* @@ -2108,6 +2144,8 @@ static int cpuset_track_online_nodes(struct notifier_block *self, break; } cgroup_unlock(); + + NODEMASK_FREE(oldmems); return NOTIFY_OK; } #endif -- cgit v0.10.2 From 298359c5bf06c04258d7cf552426e198c47e83c1 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Tue, 23 Mar 2010 13:35:37 -0700 Subject: exit: fix oops in sync_mm_rss In 2.6.34-rc1, removing vhost_net module causes an oops in sync_mm_rss (called from do_exit) when workqueue is destroyed. This does not happen on net-next, or with vhost on top of to 2.6.33. The issue seems to be introduced by 34e55232e59f7b19050267a05ff1226e5cd122a5 ("mm: avoid false sharing of mm_counter) which added sync_mm_rss() that is passed task->mm, and dereferences it without checking. If task is a kernel thread, mm might be NULL. I think this might also happen e.g. with aio. This patch fixes the oops by calling sync_mm_rss when task->mm is set to NULL. I also added BUG_ON to detect any other cases where counters get incremented while mm is NULL. The oops I observed looks like this: BUG: unable to handle kernel NULL pointer dereference at 00000000000002a8 IP: [] sync_mm_rss+0x33/0x6f PGD 0 Oops: 0002 [#1] SMP last sysfs file: /sys/devices/system/cpu/cpu7/cache/index2/shared_cpu_map CPU 2 Modules linked in: vhost_net(-) tun bridge stp sunrpc ipv6 cpufreq_ondemand acpi_cpufreq freq_table kvm_intel kvm i5000_edac edac_core rtc_cmos bnx2 button i2c_i801 i2c_core rtc_core e1000e sg joydev ide_cd_mod serio_raw pcspkr rtc_lib cdrom virtio_net virtio_blk virtio_pci virtio_ring virtio af_packet e1000 shpchp aacraid uhci_hcd ohci_hcd ehci_hcd [last unloaded: microcode] Pid: 2046, comm: vhost Not tainted 2.6.34-rc1-vhost #25 System Planar/IBM System x3550 -[7978B3G]- RIP: 0010:[] [] sync_mm_rss+0x33/0x6f RSP: 0018:ffff8802379b7e60 EFLAGS: 00010202 RAX: 0000000000000008 RBX: ffff88023f2390c0 RCX: 0000000000000000 RDX: ffff88023f2396b0 RSI: 0000000000000000 RDI: ffff88023f2390c0 RBP: ffff8802379b7e60 R08: 0000000000000000 R09: 0000000000000000 R10: ffff88023aecfbc0 R11: 0000000000013240 R12: 0000000000000000 R13: ffffffff81051a6c R14: ffffe8ffffc0f540 R15: 0000000000000000 FS: 0000000000000000(0000) GS:ffff880001e80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b CR2: 00000000000002a8 CR3: 000000023af23000 CR4: 00000000000406e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Process vhost (pid: 2046, threadinfo ffff8802379b6000, task ffff88023f2390c0) Stack: ffff8802379b7ee0 ffffffff81040687 ffffe8ffffc0f558 ffffffffa00a3e2d <0> 0000000000000000 ffff88023f2390c0 ffffffff81055817 ffff8802379b7e98 <0> ffff8802379b7e98 0000000100000286 ffff8802379b7ee0 ffff88023ad47d78 Call Trace: [] do_exit+0x147/0x6c4 [] ? handle_rx_net+0x0/0x17 [vhost_net] [] ? autoremove_wake_function+0x0/0x39 [] ? worker_thread+0x0/0x229 [] kthreadd+0x0/0xf2 [] kernel_thread_helper+0x4/0x10 [] ? kthread+0x0/0x87 [] ? kernel_thread_helper+0x0/0x10 Code: 00 8b 87 6c 02 00 00 85 c0 74 14 48 98 f0 48 01 86 a0 02 00 00 c7 87 6c 02 00 00 00 00 00 00 8b 87 70 02 00 00 85 c0 74 14 48 98 48 01 86 a8 02 00 00 c7 87 70 02 00 00 00 00 00 00 8b 87 74 RIP [] sync_mm_rss+0x33/0x6f RSP CR2: 00000000000002a8 ---[ end trace 41603ba922beddd2 ]--- Fixing recursive fault but reboot is needed! (note: handle_rx_net is a work item using workqueue in question). sync_mm_rss+0x33/0x6f gave me a hint. I also tried reverting 34e55232e59f7b19050267a05ff1226e5cd122a5 and the oops goes away. The module in question calls use_mm and later unuse_mm from a kernel thread. It is when this kernel thread is destroyed that the crash happens. Signed-off-by: Michael S. Tsirkin Andrea Arcangeli Reviewed-by: Rik van Riel Reviewed-by: KAMEZAWA Hiroyuki Reviewed-by: Minchan Kim Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/mm/memory.c b/mm/memory.c index 5b7f200..bc9ba5a 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -130,6 +130,7 @@ void __sync_task_rss_stat(struct task_struct *task, struct mm_struct *mm) for (i = 0; i < NR_MM_COUNTERS; i++) { if (task->rss_stat.count[i]) { + BUG_ON(!mm); add_mm_counter(mm, i, task->rss_stat.count[i]); task->rss_stat.count[i] = 0; } diff --git a/mm/mmu_context.c b/mm/mmu_context.c index 0777654..9e82e93 100644 --- a/mm/mmu_context.c +++ b/mm/mmu_context.c @@ -53,6 +53,7 @@ void unuse_mm(struct mm_struct *mm) struct task_struct *tsk = current; task_lock(tsk); + sync_mm_rss(tsk, mm); tsk->mm = NULL; /* active_mm is still 'mm' */ enter_lazy_tlb(mm, tsk); -- cgit v0.10.2 From 6cb4aff0a77cc0e6bae9475d62205319e3ebbf3f Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Tue, 23 Mar 2010 13:35:38 -0700 Subject: reiserfs: fix oops while creating privroot with selinux enabled Commit 57fe60df ("reiserfs: add atomic addition of selinux attributes during inode creation") contains a bug that will cause it to oops when mounting a file system that didn't previously contain extended attributes on a system using security.* xattrs. The issue is that while creating the privroot during mount reiserfs_security_init calls reiserfs_xattr_jcreate_nblocks which dereferences the xattr root. The xattr root doesn't exist, so we get an oops. Addresses http://bugzilla.kernel.org/show_bug.cgi?id=15309 Signed-off-by: Jeff Mahoney Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/reiserfs/xattr_security.c b/fs/reiserfs/xattr_security.c index d8b5bfc..de1fcff 100644 --- a/fs/reiserfs/xattr_security.c +++ b/fs/reiserfs/xattr_security.c @@ -76,7 +76,7 @@ int reiserfs_security_init(struct inode *dir, struct inode *inode, return error; } - if (sec->length) { + if (sec->length && reiserfs_xattrs_initialized(inode->i_sb)) { blocks = reiserfs_xattr_jcreate_nblocks(inode) + reiserfs_xattr_nblocks(inode, sec->length); /* We don't want to count the directories twice if we have diff --git a/include/linux/reiserfs_xattr.h b/include/linux/reiserfs_xattr.h index 99928dc..7fa02b4 100644 --- a/include/linux/reiserfs_xattr.h +++ b/include/linux/reiserfs_xattr.h @@ -70,6 +70,11 @@ int reiserfs_security_write(struct reiserfs_transaction_handle *th, void reiserfs_security_free(struct reiserfs_security_handle *sec); #endif +static inline int reiserfs_xattrs_initialized(struct super_block *sb) +{ + return REISERFS_SB(sb)->priv_root != NULL; +} + #define xattr_size(size) ((size) + sizeof(struct reiserfs_xattr_header)) static inline loff_t reiserfs_xattr_nblocks(struct inode *inode, loff_t size) { -- cgit v0.10.2 From 3f8b5ee33293d43ca360771b535dfae8c57259dc Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Tue, 23 Mar 2010 13:35:39 -0700 Subject: reiserfs: properly honor read-only devices The reiserfs journal behaves inconsistently when determining whether to allow a mount of a read-only device. This is due to the use of the continue_replay variable to short circuit the journal scanning. If it's set, it's assumed that there are transactions to replay, but there may not be. If it's unset, it's assumed that there aren't any, and that may not be the case either. I've observed two failure cases: 1) Where a clean file system on a read-only device refuses to mount 2) Where a clean file system on a read-only device passes the optimization and then tries writing the journal header to update the latest mount id. The former is easily observable by using a freshly created file system on a read-only loopback device. This patch moves the check into journal_read_transaction, where it can bail out before it's about to replay a transaction. That way it can go through and skip transactions where appropriate, yet still refuse to mount a file system with outstanding transactions. Signed-off-by: Jeff Mahoney Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index ba98546..f3de5e8 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c @@ -2217,6 +2217,15 @@ static int journal_read_transaction(struct super_block *sb, brelse(d_bh); return 1; } + + if (bdev_read_only(sb->s_bdev)) { + reiserfs_warning(sb, "clm-2076", + "device is readonly, unable to replay log"); + brelse(c_bh); + brelse(d_bh); + return -EROFS; + } + trans_id = get_desc_trans_id(desc); /* now we know we've got a good transaction, and it was inside the valid time ranges */ log_blocks = kmalloc(get_desc_trans_len(desc) * @@ -2459,12 +2468,6 @@ static int journal_read(struct super_block *sb) goto start_log_replay; } - if (continue_replay && bdev_read_only(sb->s_bdev)) { - reiserfs_warning(sb, "clm-2076", - "device is readonly, unable to replay log"); - return -1; - } - /* ok, there are transactions that need to be replayed. start with the first log block, find ** all the valid transactions, and pick out the oldest. */ -- cgit v0.10.2 From 7198f3c9b13c7aa1e5d9f7ff74c0ea303174feff Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Tue, 23 Mar 2010 13:35:40 -0700 Subject: mmc: fix incorrect interpretation of card type bits In the extended CSD register the CARD_TYPE is an 8-bit value of which the upper 6 bits were reserved in JEDEC specifications prior to version 4.4. In version 4.4 two of the reserved bits were designated for identifying support for the newly added High-Speed Dual Data Rate. Unfortunately the mmc_read_ext_csd() function required that the reserved bits be zero instead of ignoring them as it should. This patch makes mmc_read_ext_csd() ignore the CARD_TYPE bits that are reserved or not yet supported. It also stops the function jumping to the end as though an error occurred, when it is only warns that the CARD_TYPE bits (that it does interpret) are invalid. Signed-off-by: Adrian Hunter Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 0eac6c8..e041c00 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -225,7 +225,7 @@ static int mmc_read_ext_csd(struct mmc_card *card) mmc_card_set_blockaddr(card); } - switch (ext_csd[EXT_CSD_CARD_TYPE]) { + switch (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_MASK) { case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: card->ext_csd.hs_max_dtr = 52000000; break; @@ -237,7 +237,6 @@ static int mmc_read_ext_csd(struct mmc_card *card) printk(KERN_WARNING "%s: card is mmc v4 but doesn't " "support any high-speed modes.\n", mmc_hostname(card->host)); - goto out; } if (card->ext_csd.rev >= 3) { diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index c02c8db..8a49cbf 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h @@ -268,6 +268,7 @@ struct _mmc_csd { #define EXT_CSD_CARD_TYPE_26 (1<<0) /* Card can run at 26MHz */ #define EXT_CSD_CARD_TYPE_52 (1<<1) /* Card can run at 52MHz */ +#define EXT_CSD_CARD_TYPE_MASK 0x3 /* Mask out reserved and DDR bits */ #define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */ #define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */ -- cgit v0.10.2 From c6b6ef8bb05af632889c5536513b9f4004961f73 Mon Sep 17 00:00:00 2001 From: Lee Schermerhorn Date: Tue, 23 Mar 2010 13:35:41 -0700 Subject: mempolicy: fix get_mempolicy() for relative and static nodes Discovered while testing other mempolicy changes: get_mempolicy() does not handle static/relative mode flags correctly. Return the value that the user specified so that it can be restored via set_mempolicy() if desired. Signed-off-by: Lee Schermerhorn Cc: Hugh Dickins Cc: Ravikiran Thirumalai Cc: KOSAKI Motohiro Cc: Christoph Lameter Cc: David Rientjes Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 6cdfa1d..8034abd 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -806,9 +806,13 @@ static long do_get_mempolicy(int *policy, nodemask_t *nmask, err = 0; if (nmask) { - task_lock(current); - get_policy_nodemask(pol, nmask); - task_unlock(current); + if (mpol_store_user_nodemask(pol)) { + *nmask = pol->w.user_nodemask; + } else { + task_lock(current); + get_policy_nodemask(pol, nmask); + task_unlock(current); + } } out: -- cgit v0.10.2 From 4fd2c20d964a8fb9861045f1022475c9d200d684 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 23 Mar 2010 13:35:42 -0700 Subject: kcore: fix test for end of list "m" is never NULL here. We need a different test for the end of list condition. Signed-off-by: Dan Carpenter Acked-by: KAMEZAWA Hiroyuki Acked-by: WANG Cong Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c index a44a789..b442dac 100644 --- a/fs/proc/kcore.c +++ b/fs/proc/kcore.c @@ -490,7 +490,7 @@ read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos) } read_unlock(&kclist_lock); - if (m == NULL) { + if (&m->list == &kclist_head) { if (clear_user(buffer, tsz)) return -EFAULT; } else if (is_vmalloc_or_module_addr((void *)start)) { -- cgit v0.10.2 From b5c26f97ec4a17c650055c83cfc1f2ee6d8818eb Mon Sep 17 00:00:00 2001 From: Michael Grzeschik Date: Tue, 23 Mar 2010 13:35:49 -0700 Subject: lxfb: set the H- and V-SYNC polarity of the flatpanel output Fixup for the flatpanel output. The geode_modedb attribute flags are used to set the SYNC polarity of the flatpanel. Without this patch our flatpanel registers stayed unconfigured, so we just saw garbage output. Signed-off-by: Michael Grzeschik Cc: Andres Salomon Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/video/geode/lxfb.h b/drivers/video/geode/lxfb.h index cc781c0..e4c4d89 100644 --- a/drivers/video/geode/lxfb.h +++ b/drivers/video/geode/lxfb.h @@ -365,6 +365,8 @@ enum fp_registers { FP_CRC, /* 0x458 */ }; +#define FP_PT2_HSP (1 << 22) +#define FP_PT2_VSP (1 << 23) #define FP_PT2_SCRC (1 << 27) /* shfclk free */ #define FP_PM_P (1 << 24) /* panel power ctl */ diff --git a/drivers/video/geode/lxfb_ops.c b/drivers/video/geode/lxfb_ops.c index 0e5d8c7..bc35a95 100644 --- a/drivers/video/geode/lxfb_ops.c +++ b/drivers/video/geode/lxfb_ops.c @@ -274,7 +274,15 @@ static void lx_graphics_enable(struct fb_info *info) u32 msrlo, msrhi; write_fp(par, FP_PT1, 0); - write_fp(par, FP_PT2, FP_PT2_SCRC); + temp = FP_PT2_SCRC; + + if (info->var.sync & FB_SYNC_HOR_HIGH_ACT) + temp |= FP_PT2_HSP; + + if (info->var.sync & FB_SYNC_VERT_HIGH_ACT) + temp |= FP_PT2_VSP; + + write_fp(par, FP_PT2, temp); write_fp(par, FP_DFC, FP_DFC_BC); msrlo = MSR_LX_MSR_PADSEL_TFT_SEL_LOW; -- cgit v0.10.2 From 3fbf586cf7f245392142e5407c2a56f1cff979b6 Mon Sep 17 00:00:00 2001 From: Daniel Taylor Date: Tue, 23 Mar 2010 13:35:50 -0700 Subject: fs/partitions/msdos: add support for large disks In order to use disks larger than 2TiB on Windows XP, it is necessary to use 4096-byte logical sectors in an MBR. Although the kernel storage and functions called from msdos.c used "sector_t" internally, msdos.c still used u32 variables, which results in the ability to handle XP-compatible large disks. This patch changes the internal variables to "sector_t". Daniel said: "In the near future, WD will be releasing products that need this patch". [hirofumi@mail.parknet.co.jp: tweaks and fix] Signed-off-by: Daniel Taylor Signed-off-by: OGAWA Hirofumi Cc: "H. Peter Anvin" Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/partitions/msdos.c b/fs/partitions/msdos.c index 0028d2e..b783858 100644 --- a/fs/partitions/msdos.c +++ b/fs/partitions/msdos.c @@ -31,14 +31,17 @@ */ #include -#define SYS_IND(p) (get_unaligned(&p->sys_ind)) -#define NR_SECTS(p) ({ __le32 __a = get_unaligned(&p->nr_sects); \ - le32_to_cpu(__a); \ - }) +#define SYS_IND(p) get_unaligned(&p->sys_ind) -#define START_SECT(p) ({ __le32 __a = get_unaligned(&p->start_sect); \ - le32_to_cpu(__a); \ - }) +static inline sector_t nr_sects(struct partition *p) +{ + return (sector_t)get_unaligned_le32(&p->nr_sects); +} + +static inline sector_t start_sect(struct partition *p) +{ + return (sector_t)get_unaligned_le32(&p->start_sect); +} static inline int is_extended_partition(struct partition *p) { @@ -104,13 +107,13 @@ static int aix_magic_present(unsigned char *p, struct block_device *bdev) static void parse_extended(struct parsed_partitions *state, struct block_device *bdev, - u32 first_sector, u32 first_size) + sector_t first_sector, sector_t first_size) { struct partition *p; Sector sect; unsigned char *data; - u32 this_sector, this_size; - int sector_size = bdev_logical_block_size(bdev) / 512; + sector_t this_sector, this_size; + sector_t sector_size = bdev_logical_block_size(bdev) / 512; int loopct = 0; /* number of links followed without finding a data partition */ int i; @@ -145,14 +148,14 @@ parse_extended(struct parsed_partitions *state, struct block_device *bdev, * First process the data partition(s) */ for (i=0; i<4; i++, p++) { - u32 offs, size, next; - if (!NR_SECTS(p) || is_extended_partition(p)) + sector_t offs, size, next; + if (!nr_sects(p) || is_extended_partition(p)) continue; /* Check the 3rd and 4th entries - these sometimes contain random garbage */ - offs = START_SECT(p)*sector_size; - size = NR_SECTS(p)*sector_size; + offs = start_sect(p)*sector_size; + size = nr_sects(p)*sector_size; next = this_sector + offs; if (i >= 2) { if (offs + size > this_size) @@ -179,13 +182,13 @@ parse_extended(struct parsed_partitions *state, struct block_device *bdev, */ p -= 4; for (i=0; i<4; i++, p++) - if (NR_SECTS(p) && is_extended_partition(p)) + if (nr_sects(p) && is_extended_partition(p)) break; if (i == 4) goto done; /* nothing left to do */ - this_sector = first_sector + START_SECT(p) * sector_size; - this_size = NR_SECTS(p) * sector_size; + this_sector = first_sector + start_sect(p) * sector_size; + this_size = nr_sects(p) * sector_size; put_dev_sector(sect); } done: @@ -197,7 +200,7 @@ done: static void parse_solaris_x86(struct parsed_partitions *state, struct block_device *bdev, - u32 offset, u32 size, int origin) + sector_t offset, sector_t size, int origin) { #ifdef CONFIG_SOLARIS_X86_PARTITION Sector sect; @@ -244,7 +247,7 @@ parse_solaris_x86(struct parsed_partitions *state, struct block_device *bdev, */ static void parse_bsd(struct parsed_partitions *state, struct block_device *bdev, - u32 offset, u32 size, int origin, char *flavour, + sector_t offset, sector_t size, int origin, char *flavour, int max_partitions) { Sector sect; @@ -263,7 +266,7 @@ parse_bsd(struct parsed_partitions *state, struct block_device *bdev, if (le16_to_cpu(l->d_npartitions) < max_partitions) max_partitions = le16_to_cpu(l->d_npartitions); for (p = l->d_partitions; p - l->d_partitions < max_partitions; p++) { - u32 bsd_start, bsd_size; + sector_t bsd_start, bsd_size; if (state->next == state->limit) break; @@ -290,7 +293,7 @@ parse_bsd(struct parsed_partitions *state, struct block_device *bdev, static void parse_freebsd(struct parsed_partitions *state, struct block_device *bdev, - u32 offset, u32 size, int origin) + sector_t offset, sector_t size, int origin) { #ifdef CONFIG_BSD_DISKLABEL parse_bsd(state, bdev, offset, size, origin, @@ -300,7 +303,7 @@ parse_freebsd(struct parsed_partitions *state, struct block_device *bdev, static void parse_netbsd(struct parsed_partitions *state, struct block_device *bdev, - u32 offset, u32 size, int origin) + sector_t offset, sector_t size, int origin) { #ifdef CONFIG_BSD_DISKLABEL parse_bsd(state, bdev, offset, size, origin, @@ -310,7 +313,7 @@ parse_netbsd(struct parsed_partitions *state, struct block_device *bdev, static void parse_openbsd(struct parsed_partitions *state, struct block_device *bdev, - u32 offset, u32 size, int origin) + sector_t offset, sector_t size, int origin) { #ifdef CONFIG_BSD_DISKLABEL parse_bsd(state, bdev, offset, size, origin, @@ -324,7 +327,7 @@ parse_openbsd(struct parsed_partitions *state, struct block_device *bdev, */ static void parse_unixware(struct parsed_partitions *state, struct block_device *bdev, - u32 offset, u32 size, int origin) + sector_t offset, sector_t size, int origin) { #ifdef CONFIG_UNIXWARE_DISKLABEL Sector sect; @@ -348,7 +351,8 @@ parse_unixware(struct parsed_partitions *state, struct block_device *bdev, if (p->s_label != UNIXWARE_FS_UNUSED) put_partition(state, state->next++, - START_SECT(p), NR_SECTS(p)); + le32_to_cpu(p->start_sect), + le32_to_cpu(p->nr_sects)); p++; } put_dev_sector(sect); @@ -363,7 +367,7 @@ parse_unixware(struct parsed_partitions *state, struct block_device *bdev, */ static void parse_minix(struct parsed_partitions *state, struct block_device *bdev, - u32 offset, u32 size, int origin) + sector_t offset, sector_t size, int origin) { #ifdef CONFIG_MINIX_SUBPARTITION Sector sect; @@ -390,7 +394,7 @@ parse_minix(struct parsed_partitions *state, struct block_device *bdev, /* add each partition in use */ if (SYS_IND(p) == MINIX_PARTITION) put_partition(state, state->next++, - START_SECT(p), NR_SECTS(p)); + start_sect(p), nr_sects(p)); } printk(" >\n"); } @@ -401,7 +405,7 @@ parse_minix(struct parsed_partitions *state, struct block_device *bdev, static struct { unsigned char id; void (*parse)(struct parsed_partitions *, struct block_device *, - u32, u32, int); + sector_t, sector_t, int); } subtypes[] = { {FREEBSD_PARTITION, parse_freebsd}, {NETBSD_PARTITION, parse_netbsd}, @@ -415,7 +419,7 @@ static struct { int msdos_partition(struct parsed_partitions *state, struct block_device *bdev) { - int sector_size = bdev_logical_block_size(bdev) / 512; + sector_t sector_size = bdev_logical_block_size(bdev) / 512; Sector sect; unsigned char *data; struct partition *p; @@ -483,8 +487,8 @@ int msdos_partition(struct parsed_partitions *state, struct block_device *bdev) state->next = 5; for (slot = 1 ; slot <= 4 ; slot++, p++) { - u32 start = START_SECT(p)*sector_size; - u32 size = NR_SECTS(p)*sector_size; + sector_t start = start_sect(p)*sector_size; + sector_t size = nr_sects(p)*sector_size; if (!size) continue; if (is_extended_partition(p)) { @@ -513,7 +517,7 @@ int msdos_partition(struct parsed_partitions *state, struct block_device *bdev) unsigned char id = SYS_IND(p); int n; - if (!NR_SECTS(p)) + if (!nr_sects(p)) continue; for (n = 0; subtypes[n].parse && id != subtypes[n].id; n++) @@ -521,8 +525,8 @@ int msdos_partition(struct parsed_partitions *state, struct block_device *bdev) if (!subtypes[n].parse) continue; - subtypes[n].parse(state, bdev, START_SECT(p)*sector_size, - NR_SECTS(p)*sector_size, slot); + subtypes[n].parse(state, bdev, start_sect(p)*sector_size, + nr_sects(p)*sector_size, slot); } put_dev_sector(sect); return 1; -- cgit v0.10.2 From 8e0cc811e0f8029a7225372fb0951fab102c012f Mon Sep 17 00:00:00 2001 From: OGAWA Hirofumi Date: Tue, 23 Mar 2010 13:35:50 -0700 Subject: fs/partition/msdos: fix unusable extended partition for > 512B sector Smaller size than a minimum blocksize can't be used, after all it's handled like 0 size. For extended partition itself, this makes sure to use bigger size than one logical sector size at least. Signed-off-by: OGAWA Hirofumi Cc: Daniel Taylor Cc: "H. Peter Anvin" Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/partitions/msdos.c b/fs/partitions/msdos.c index b783858..90be97f 100644 --- a/fs/partitions/msdos.c +++ b/fs/partitions/msdos.c @@ -492,9 +492,16 @@ int msdos_partition(struct parsed_partitions *state, struct block_device *bdev) if (!size) continue; if (is_extended_partition(p)) { - /* prevent someone doing mkfs or mkswap on an - extended partition, but leave room for LILO */ - put_partition(state, slot, start, size == 1 ? 1 : 2); + /* + * prevent someone doing mkfs or mkswap on an + * extended partition, but leave room for LILO + * FIXME: this uses one logical sector for > 512b + * sector, although it may not be enough/proper. + */ + sector_t n = 2; + n = min(size, max(sector_size, n)); + put_partition(state, slot, start, n); + printk(" <"); parse_extended(state, bdev, start, size); printk(" >"); -- cgit v0.10.2 From 90fddabf5818367c6bd1fe1b256a10e01827862f Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 24 Mar 2010 09:43:00 +0000 Subject: Document Linux's circular buffering capabilities Document the circular buffering capabilities available in Linux. Signed-off-by: David Howells Signed-off-by: Paul E. McKenney Reviewed-by: Randy Dunlap Reviewed-by: Stefan Richter Signed-off-by: Linus Torvalds diff --git a/Documentation/circular-buffers.txt b/Documentation/circular-buffers.txt new file mode 100644 index 0000000..8117e5b --- /dev/null +++ b/Documentation/circular-buffers.txt @@ -0,0 +1,234 @@ + ================ + CIRCULAR BUFFERS + ================ + +By: David Howells + Paul E. McKenney + + +Linux provides a number of features that can be used to implement circular +buffering. There are two sets of such features: + + (1) Convenience functions for determining information about power-of-2 sized + buffers. + + (2) Memory barriers for when the producer and the consumer of objects in the + buffer don't want to share a lock. + +To use these facilities, as discussed below, there needs to be just one +producer and just one consumer. It is possible to handle multiple producers by +serialising them, and to handle multiple consumers by serialising them. + + +Contents: + + (*) What is a circular buffer? + + (*) Measuring power-of-2 buffers. + + (*) Using memory barriers with circular buffers. + - The producer. + - The consumer. + + +========================== +WHAT IS A CIRCULAR BUFFER? +========================== + +First of all, what is a circular buffer? A circular buffer is a buffer of +fixed, finite size into which there are two indices: + + (1) A 'head' index - the point at which the producer inserts items into the + buffer. + + (2) A 'tail' index - the point at which the consumer finds the next item in + the buffer. + +Typically when the tail pointer is equal to the head pointer, the buffer is +empty; and the buffer is full when the head pointer is one less than the tail +pointer. + +The head index is incremented when items are added, and the tail index when +items are removed. The tail index should never jump the head index, and both +indices should be wrapped to 0 when they reach the end of the buffer, thus +allowing an infinite amount of data to flow through the buffer. + +Typically, items will all be of the same unit size, but this isn't strictly +required to use the techniques below. The indices can be increased by more +than 1 if multiple items or variable-sized items are to be included in the +buffer, provided that neither index overtakes the other. The implementer must +be careful, however, as a region more than one unit in size may wrap the end of +the buffer and be broken into two segments. + + +============================ +MEASURING POWER-OF-2 BUFFERS +============================ + +Calculation of the occupancy or the remaining capacity of an arbitrarily sized +circular buffer would normally be a slow operation, requiring the use of a +modulus (divide) instruction. However, if the buffer is of a power-of-2 size, +then a much quicker bitwise-AND instruction can be used instead. + +Linux provides a set of macros for handling power-of-2 circular buffers. These +can be made use of by: + + #include + +The macros are: + + (*) Measure the remaining capacity of a buffer: + + CIRC_SPACE(head_index, tail_index, buffer_size); + + This returns the amount of space left in the buffer[1] into which items + can be inserted. + + + (*) Measure the maximum consecutive immediate space in a buffer: + + CIRC_SPACE_TO_END(head_index, tail_index, buffer_size); + + This returns the amount of consecutive space left in the buffer[1] into + which items can be immediately inserted without having to wrap back to the + beginning of the buffer. + + + (*) Measure the occupancy of a buffer: + + CIRC_CNT(head_index, tail_index, buffer_size); + + This returns the number of items currently occupying a buffer[2]. + + + (*) Measure the non-wrapping occupancy of a buffer: + + CIRC_CNT_TO_END(head_index, tail_index, buffer_size); + + This returns the number of consecutive items[2] that can be extracted from + the buffer without having to wrap back to the beginning of the buffer. + + +Each of these macros will nominally return a value between 0 and buffer_size-1, +however: + + [1] CIRC_SPACE*() are intended to be used in the producer. To the producer + they will return a lower bound as the producer controls the head index, + but the consumer may still be depleting the buffer on another CPU and + moving the tail index. + + To the consumer it will show an upper bound as the producer may be busy + depleting the space. + + [2] CIRC_CNT*() are intended to be used in the consumer. To the consumer they + will return a lower bound as the consumer controls the tail index, but the + producer may still be filling the buffer on another CPU and moving the + head index. + + To the producer it will show an upper bound as the consumer may be busy + emptying the buffer. + + [3] To a third party, the order in which the writes to the indices by the + producer and consumer become visible cannot be guaranteed as they are + independent and may be made on different CPUs - so the result in such a + situation will merely be a guess, and may even be negative. + + +=========================================== +USING MEMORY BARRIERS WITH CIRCULAR BUFFERS +=========================================== + +By using memory barriers in conjunction with circular buffers, you can avoid +the need to: + + (1) use a single lock to govern access to both ends of the buffer, thus + allowing the buffer to be filled and emptied at the same time; and + + (2) use atomic counter operations. + +There are two sides to this: the producer that fills the buffer, and the +consumer that empties it. Only one thing should be filling a buffer at any one +time, and only one thing should be emptying a buffer at any one time, but the +two sides can operate simultaneously. + + +THE PRODUCER +------------ + +The producer will look something like this: + + spin_lock(&producer_lock); + + unsigned long head = buffer->head; + unsigned long tail = ACCESS_ONCE(buffer->tail); + + if (CIRC_SPACE(head, tail, buffer->size) >= 1) { + /* insert one item into the buffer */ + struct item *item = buffer[head]; + + produce_item(item); + + smp_wmb(); /* commit the item before incrementing the head */ + + buffer->head = (head + 1) & (buffer->size - 1); + + /* wake_up() will make sure that the head is committed before + * waking anyone up */ + wake_up(consumer); + } + + spin_unlock(&producer_lock); + +This will instruct the CPU that the contents of the new item must be written +before the head index makes it available to the consumer and then instructs the +CPU that the revised head index must be written before the consumer is woken. + +Note that wake_up() doesn't have to be the exact mechanism used, but whatever +is used must guarantee a (write) memory barrier between the update of the head +index and the change of state of the consumer, if a change of state occurs. + + +THE CONSUMER +------------ + +The consumer will look something like this: + + spin_lock(&consumer_lock); + + unsigned long head = ACCESS_ONCE(buffer->head); + unsigned long tail = buffer->tail; + + if (CIRC_CNT(head, tail, buffer->size) >= 1) { + /* read index before reading contents at that index */ + smp_read_barrier_depends(); + + /* extract one item from the buffer */ + struct item *item = buffer[tail]; + + consume_item(item); + + smp_mb(); /* finish reading descriptor before incrementing tail */ + + buffer->tail = (tail + 1) & (buffer->size - 1); + } + + spin_unlock(&consumer_lock); + +This will instruct the CPU to make sure the index is up to date before reading +the new item, and then it shall make sure the CPU has finished reading the item +before it writes the new tail pointer, which will erase the item. + + +Note the use of ACCESS_ONCE() in both algorithms to read the opposition index. +This prevents the compiler from discarding and reloading its cached value - +which some compilers will do across smp_read_barrier_depends(). This isn't +strictly needed if you can be sure that the opposition index will _only_ be +used the once. + + +=============== +FURTHER READING +=============== + +See also Documentation/memory-barriers.txt for a description of Linux's memory +barrier facilities. diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt index 7f5809e..631ad2f 100644 --- a/Documentation/memory-barriers.txt +++ b/Documentation/memory-barriers.txt @@ -3,6 +3,7 @@ ============================ By: David Howells + Paul E. McKenney Contents: @@ -60,6 +61,10 @@ Contents: - And then there's the Alpha. + (*) Example uses. + + - Circular buffers. + (*) References. @@ -2226,6 +2231,21 @@ The Alpha defines the Linux kernel's memory barrier model. See the subsection on "Cache Coherency" above. +============ +EXAMPLE USES +============ + +CIRCULAR BUFFERS +---------------- + +Memory barriers can be used to implement circular buffering without the need +of a lock to serialise the producer with the consumer. See: + + Documentation/circular-buffers.txt + +for details. + + ========== REFERENCES ========== diff --git a/include/linux/circ_buf.h b/include/linux/circ_buf.h index a2ed059..90f2471 100644 --- a/include/linux/circ_buf.h +++ b/include/linux/circ_buf.h @@ -1,3 +1,7 @@ +/* + * See Documentation/circular-buffers.txt for more information. + */ + #ifndef _LINUX_CIRC_BUF_H #define _LINUX_CIRC_BUF_H 1 -- cgit v0.10.2 From 47568d4c56677ede6e7ff7c8e4e0fd860a9c4372 Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 24 Mar 2010 17:02:28 +0000 Subject: FDPIC: For-loop in elf_core_vma_data_size() is incorrect Fix an incorrect for-loop in elf_core_vma_data_size(). The advance-pointer statement lacks an assignment: CC fs/binfmt_elf_fdpic.o fs/binfmt_elf_fdpic.c: In function 'elf_core_vma_data_size': fs/binfmt_elf_fdpic.c:1593: warning: statement with no effect Signed-off-by: David Howells Signed-off-by: Linus Torvalds diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index 2c32d00..7ab23e0 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c @@ -1590,7 +1590,7 @@ static size_t elf_core_vma_data_size(unsigned long mm_flags) struct vm_area_struct *vma; size_t size = 0; - for (vma = current->mm->mmap; vma; vma->vm_next) + for (vma = current->mm->mmap; vma; vma = vma->vm_next) if (maydump(vma, mm_flags)) size += vma->vm_end - vma->vm_start; return size; -- cgit v0.10.2 From 61964eba5c419ff710ac996c5ed3a84d5af7490f Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 24 Mar 2010 17:09:19 +0000 Subject: do_sync_read/write() should set kiocb.ki_nbytes to be consistent do_sync_read/write() should set kiocb.ki_nbytes to be consistent with do_sync_readv_writev(). Signed-off-by: David Howells Signed-off-by: Linus Torvalds diff --git a/fs/read_write.c b/fs/read_write.c index b7f4a1f..113386d 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -258,6 +258,7 @@ ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *pp init_sync_kiocb(&kiocb, filp); kiocb.ki_pos = *ppos; kiocb.ki_left = len; + kiocb.ki_nbytes = len; for (;;) { ret = filp->f_op->aio_read(&kiocb, &iov, 1, kiocb.ki_pos); @@ -313,6 +314,7 @@ ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, lof init_sync_kiocb(&kiocb, filp); kiocb.ki_pos = *ppos; kiocb.ki_left = len; + kiocb.ki_nbytes = len; for (;;) { ret = filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos); -- cgit v0.10.2 From 1147d0f915e3b4c5c4fa279dae2c40016b8f441d Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 23 Mar 2010 14:48:37 +0000 Subject: fscache: add missing unlock Sparse complained about this missing spin_unlock() Signed-off-by: Dan Carpenter Signed-off-by: David Howells Signed-off-by: Linus Torvalds diff --git a/fs/fscache/page.c b/fs/fscache/page.c index c598ea4..6980902 100644 --- a/fs/fscache/page.c +++ b/fs/fscache/page.c @@ -881,6 +881,7 @@ submit_failed: goto nobufs; nobufs_unlock_obj: + spin_unlock(&cookie->stores_lock); spin_unlock(&object->lock); nobufs: spin_unlock(&cookie->lock); -- cgit v0.10.2 From 6dc2d6bf5148a9ed027af21285b0e17b83b3a8f4 Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Wed, 24 Mar 2010 14:32:16 +0300 Subject: imx31: fix parent clock for rtc According to imx31 reference manual the signal from external low frequency clock is sent to RTC clock. The patch makes redundant the previously defined mxc_rtc clock. Signed-off-by: Vladimir Zapolskiy Cc: Sascha Hauer Cc: Daniel Mack Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx3/clock-imx31.c b/arch/arm/mach-mx3/clock-imx31.c index 80dba99..9a9eb6d 100644 --- a/arch/arm/mach-mx3/clock-imx31.c +++ b/arch/arm/mach-mx3/clock-imx31.c @@ -468,6 +468,7 @@ static struct clk ahb_clk = { } DEFINE_CLOCK(perclk_clk, 0, NULL, 0, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(ckil_clk, 0, NULL, 0, clk_ckil_get_rate, NULL, NULL); DEFINE_CLOCK(sdhc1_clk, 0, MXC_CCM_CGR0, 0, NULL, NULL, &perclk_clk); DEFINE_CLOCK(sdhc2_clk, 1, MXC_CCM_CGR0, 2, NULL, NULL, &perclk_clk); @@ -490,7 +491,7 @@ DEFINE_CLOCK(mpeg4_clk, 0, MXC_CCM_CGR1, 0, NULL, NULL, &ahb_clk); DEFINE_CLOCK(mstick1_clk, 0, MXC_CCM_CGR1, 2, mstick1_get_rate, NULL, &usb_pll_clk); DEFINE_CLOCK(mstick2_clk, 1, MXC_CCM_CGR1, 4, mstick2_get_rate, NULL, &usb_pll_clk); DEFINE_CLOCK1(csi_clk, 0, MXC_CCM_CGR1, 6, csi, NULL, &serial_pll_clk); -DEFINE_CLOCK(rtc_clk, 0, MXC_CCM_CGR1, 8, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(rtc_clk, 0, MXC_CCM_CGR1, 8, NULL, NULL, &ckil_clk); DEFINE_CLOCK(wdog_clk, 0, MXC_CCM_CGR1, 10, NULL, NULL, &ipg_clk); DEFINE_CLOCK(pwm_clk, 0, MXC_CCM_CGR1, 12, NULL, NULL, &perclk_clk); DEFINE_CLOCK(usb_clk2, 0, MXC_CCM_CGR1, 18, usb_get_rate, NULL, &ahb_clk); @@ -514,7 +515,6 @@ DEFINE_CLOCK(usb_clk1, 0, NULL, 0, usb_get_rate, NULL, &usb_pll_clk) DEFINE_CLOCK(nfc_clk, 0, NULL, 0, nfc_get_rate, NULL, &ahb_clk); DEFINE_CLOCK(scc_clk, 0, NULL, 0, NULL, NULL, &ipg_clk); DEFINE_CLOCK(ipg_clk, 0, NULL, 0, ipg_get_rate, NULL, &ahb_clk); -DEFINE_CLOCK(ckil_clk, 0, NULL, 0, clk_ckil_get_rate, NULL, NULL); #define _REGISTER_CLOCK(d, n, c) \ { \ @@ -572,7 +572,6 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK(NULL, "iim", iim_clk) _REGISTER_CLOCK(NULL, "mpeg4", mpeg4_clk) _REGISTER_CLOCK(NULL, "mbx", mbx_clk) - _REGISTER_CLOCK("mxc_rtc", NULL, ckil_clk) }; int __init mx31_clocks_init(unsigned long fref) -- cgit v0.10.2 From 11a332adfeacee2634f73ad21b55aad5cc7fd54a Mon Sep 17 00:00:00 2001 From: Alberto Panizzo Date: Tue, 23 Mar 2010 19:46:57 +0100 Subject: MXC: mach-mx31_3ds: Update variable names over recent mach name modification. Signed-off-by: Alberto Panizzo Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx3/mach-mx31_3ds.c b/arch/arm/mach-mx3/mach-mx31_3ds.c index b88c18a..4a94c3c 100644 --- a/arch/arm/mach-mx3/mach-mx31_3ds.c +++ b/arch/arm/mach-mx3/mach-mx31_3ds.c @@ -31,20 +31,20 @@ #include #include #include -#include +#include #include #include #include "devices.h" /*! - * @file mx31pdk.c + * @file mx31_3ds.c * * @brief This file contains the board-specific initialization routines. * * @ingroup System */ -static int mx31pdk_pins[] = { +static int mx31_3ds_pins[] = { /* UART1 */ MX31_PIN_CTS1__CTS1, MX31_PIN_RTS1__RTS1, @@ -95,7 +95,7 @@ static struct platform_device smsc911x_device = { * LEDs, switches, interrupts for Ethernet. */ -static void mx31pdk_expio_irq_handler(uint32_t irq, struct irq_desc *desc) +static void mx31_3ds_expio_irq_handler(uint32_t irq, struct irq_desc *desc) { uint32_t imr_val; uint32_t int_valid; @@ -163,7 +163,7 @@ static struct irq_chip expio_irq_chip = { .unmask = expio_unmask_irq, }; -static int __init mx31pdk_init_expio(void) +static int __init mx31_3ds_init_expio(void) { int i; int ret; @@ -176,7 +176,7 @@ static int __init mx31pdk_init_expio(void) return -ENODEV; } - pr_info("i.MX31PDK Debug board detected, rev = 0x%04X\n", + pr_info("i.MX31 3DS Debug board detected, rev = 0x%04X\n", __raw_readw(CPLD_CODE_VER_REG)); /* @@ -201,7 +201,7 @@ static int __init mx31pdk_init_expio(void) set_irq_flags(i, IRQF_VALID); } set_irq_type(EXPIO_PARENT_INT, IRQ_TYPE_LEVEL_LOW); - set_irq_chained_handler(EXPIO_PARENT_INT, mx31pdk_expio_irq_handler); + set_irq_chained_handler(EXPIO_PARENT_INT, mx31_3ds_expio_irq_handler); return 0; } @@ -209,7 +209,7 @@ static int __init mx31pdk_init_expio(void) /* * This structure defines the MX31 memory map. */ -static struct map_desc mx31pdk_io_desc[] __initdata = { +static struct map_desc mx31_3ds_io_desc[] __initdata = { { .virtual = MX31_CS5_BASE_ADDR_VIRT, .pfn = __phys_to_pfn(MX31_CS5_BASE_ADDR), @@ -221,10 +221,10 @@ static struct map_desc mx31pdk_io_desc[] __initdata = { /* * Set up static virtual mappings. */ -static void __init mx31pdk_map_io(void) +static void __init mx31_3ds_map_io(void) { mx31_map_io(); - iotable_init(mx31pdk_io_desc, ARRAY_SIZE(mx31pdk_io_desc)); + iotable_init(mx31_3ds_io_desc, ARRAY_SIZE(mx31_3ds_io_desc)); } /*! @@ -232,35 +232,35 @@ static void __init mx31pdk_map_io(void) */ static void __init mxc_board_init(void) { - mxc_iomux_setup_multiple_pins(mx31pdk_pins, ARRAY_SIZE(mx31pdk_pins), - "mx31pdk"); + mxc_iomux_setup_multiple_pins(mx31_3ds_pins, ARRAY_SIZE(mx31_3ds_pins), + "mx31_3ds"); mxc_register_device(&mxc_uart_device0, &uart_pdata); - if (!mx31pdk_init_expio()) + if (!mx31_3ds_init_expio()) platform_device_register(&smsc911x_device); } -static void __init mx31pdk_timer_init(void) +static void __init mx31_3ds_timer_init(void) { mx31_clocks_init(26000000); } -static struct sys_timer mx31pdk_timer = { - .init = mx31pdk_timer_init, +static struct sys_timer mx31_3ds_timer = { + .init = mx31_3ds_timer_init, }; /* * The following uses standard kernel macros defined in arch.h in order to - * initialize __mach_desc_MX31PDK data structure. + * initialize __mach_desc_MX31_3DS data structure. */ MACHINE_START(MX31_3DS, "Freescale MX31PDK (3DS)") /* Maintainer: Freescale Semiconductor, Inc. */ .phys_io = MX31_AIPS1_BASE_ADDR, .io_pg_offst = (MX31_AIPS1_BASE_ADDR_VIRT >> 18) & 0xfffc, .boot_params = MX3x_PHYS_OFFSET + 0x100, - .map_io = mx31pdk_map_io, + .map_io = mx31_3ds_map_io, .init_irq = mx31_init_irq, .init_machine = mxc_board_init, - .timer = &mx31pdk_timer, + .timer = &mx31_3ds_timer, MACHINE_END diff --git a/arch/arm/plat-mxc/include/mach/board-mx31_3ds.h b/arch/arm/plat-mxc/include/mach/board-mx31_3ds.h new file mode 100644 index 0000000..da92933 --- /dev/null +++ b/arch/arm/plat-mxc/include/mach/board-mx31_3ds.h @@ -0,0 +1,59 @@ +/* + * Copyright 2008 Freescale Semiconductor, Inc. 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 version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ASM_ARCH_MXC_BOARD_MX31_3DS_H__ +#define __ASM_ARCH_MXC_BOARD_MX31_3DS_H__ + +/* Definitions for components on the Debug board */ + +/* Base address of CPLD controller on the Debug board */ +#define DEBUG_BASE_ADDRESS CS5_IO_ADDRESS(CS5_BASE_ADDR) + +/* LAN9217 ethernet base address */ +#define LAN9217_BASE_ADDR CS5_BASE_ADDR + +/* CPLD config and interrupt base address */ +#define CPLD_ADDR (DEBUG_BASE_ADDRESS + 0x20000) + +/* LED switchs */ +#define CPLD_LED_REG (CPLD_ADDR + 0x00) +/* buttons */ +#define CPLD_SWITCH_BUTTONS_REG (EXPIO_ADDR + 0x08) +/* status, interrupt */ +#define CPLD_INT_STATUS_REG (CPLD_ADDR + 0x10) +#define CPLD_INT_MASK_REG (CPLD_ADDR + 0x38) +#define CPLD_INT_RESET_REG (CPLD_ADDR + 0x20) +/* magic word for debug CPLD */ +#define CPLD_MAGIC_NUMBER1_REG (CPLD_ADDR + 0x40) +#define CPLD_MAGIC_NUMBER2_REG (CPLD_ADDR + 0x48) +/* CPLD code version */ +#define CPLD_CODE_VER_REG (CPLD_ADDR + 0x50) +/* magic word for debug CPLD */ +#define CPLD_MAGIC_NUMBER3_REG (CPLD_ADDR + 0x58) +/* module reset register */ +#define CPLD_MODULE_RESET_REG (CPLD_ADDR + 0x60) +/* CPU ID and Personality ID */ +#define CPLD_MCU_BOARD_ID_REG (CPLD_ADDR + 0x68) + +/* CPLD IRQ line for external uart, external ethernet etc */ +#define EXPIO_PARENT_INT IOMUX_TO_IRQ(MX31_PIN_GPIO1_1) + +#define MXC_EXP_IO_BASE (MXC_BOARD_IRQ_START) +#define MXC_IRQ_TO_EXPIO(irq) ((irq) - MXC_EXP_IO_BASE) + +#define EXPIO_INT_ENET (MXC_EXP_IO_BASE + 0) +#define EXPIO_INT_XUART_A (MXC_EXP_IO_BASE + 1) +#define EXPIO_INT_XUART_B (MXC_EXP_IO_BASE + 2) +#define EXPIO_INT_BUTTON_A (MXC_EXP_IO_BASE + 3) +#define EXPIO_INT_BUTTON_B (MXC_EXP_IO_BASE + 4) + +#define MXC_MAX_EXP_IO_LINES 16 + +#endif /* __ASM_ARCH_MXC_BOARD_MX31_3DS_H__ */ diff --git a/arch/arm/plat-mxc/include/mach/board-mx31pdk.h b/arch/arm/plat-mxc/include/mach/board-mx31pdk.h deleted file mode 100644 index 2bbd6ed..0000000 --- a/arch/arm/plat-mxc/include/mach/board-mx31pdk.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2008 Freescale Semiconductor, Inc. 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 version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __ASM_ARCH_MXC_BOARD_MX31PDK_H__ -#define __ASM_ARCH_MXC_BOARD_MX31PDK_H__ - -/* Definitions for components on the Debug board */ - -/* Base address of CPLD controller on the Debug board */ -#define DEBUG_BASE_ADDRESS CS5_IO_ADDRESS(CS5_BASE_ADDR) - -/* LAN9217 ethernet base address */ -#define LAN9217_BASE_ADDR CS5_BASE_ADDR - -/* CPLD config and interrupt base address */ -#define CPLD_ADDR (DEBUG_BASE_ADDRESS + 0x20000) - -/* LED switchs */ -#define CPLD_LED_REG (CPLD_ADDR + 0x00) -/* buttons */ -#define CPLD_SWITCH_BUTTONS_REG (EXPIO_ADDR + 0x08) -/* status, interrupt */ -#define CPLD_INT_STATUS_REG (CPLD_ADDR + 0x10) -#define CPLD_INT_MASK_REG (CPLD_ADDR + 0x38) -#define CPLD_INT_RESET_REG (CPLD_ADDR + 0x20) -/* magic word for debug CPLD */ -#define CPLD_MAGIC_NUMBER1_REG (CPLD_ADDR + 0x40) -#define CPLD_MAGIC_NUMBER2_REG (CPLD_ADDR + 0x48) -/* CPLD code version */ -#define CPLD_CODE_VER_REG (CPLD_ADDR + 0x50) -/* magic word for debug CPLD */ -#define CPLD_MAGIC_NUMBER3_REG (CPLD_ADDR + 0x58) -/* module reset register */ -#define CPLD_MODULE_RESET_REG (CPLD_ADDR + 0x60) -/* CPU ID and Personality ID */ -#define CPLD_MCU_BOARD_ID_REG (CPLD_ADDR + 0x68) - -/* CPLD IRQ line for external uart, external ethernet etc */ -#define EXPIO_PARENT_INT IOMUX_TO_IRQ(MX31_PIN_GPIO1_1) - -#define MXC_EXP_IO_BASE (MXC_BOARD_IRQ_START) -#define MXC_IRQ_TO_EXPIO(irq) ((irq) - MXC_EXP_IO_BASE) - -#define EXPIO_INT_ENET (MXC_EXP_IO_BASE + 0) -#define EXPIO_INT_XUART_A (MXC_EXP_IO_BASE + 1) -#define EXPIO_INT_XUART_B (MXC_EXP_IO_BASE + 2) -#define EXPIO_INT_BUTTON_A (MXC_EXP_IO_BASE + 3) -#define EXPIO_INT_BUTTON_B (MXC_EXP_IO_BASE + 4) - -#define MXC_MAX_EXP_IO_LINES 16 - -#endif /* __ASM_ARCH_MXC_BOARD_MX31PDK_H__ */ -- cgit v0.10.2 From a1b67b957ea3b9138ed8239796cb48d8b1bf66b0 Mon Sep 17 00:00:00 2001 From: Alberto Panizzo Date: Tue, 23 Mar 2010 19:49:35 +0100 Subject: MXC: mach-mx31_3ds: Add support for on board NAND Flash. Since the using of Bad Block Table is not constantly a good behave I had made it configurable. Signed-off-by: Alberto Panizzo Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx3/Kconfig b/arch/arm/mach-mx3/Kconfig index 3872af1..9a2911e 100644 --- a/arch/arm/mach-mx3/Kconfig +++ b/arch/arm/mach-mx3/Kconfig @@ -62,6 +62,15 @@ config MACH_MX31_3DS Include support for MX31PDK (3DS) platform. This includes specific configurations for the board and its peripherals. +config MACH_MX31_3DS_MXC_NAND_USE_BBT + bool "Make the MXC NAND driver use the in flash Bad Block Table" + depends on MACH_MX31_3DS + depends on MTD_NAND_MXC + help + Enable this if you want that the MXC NAND driver uses the in flash + Bad Block Table to know what blocks are bad instead of scanning the + entire flash looking for bad block markers. + config MACH_MX31MOBOARD bool "Support mx31moboard platforms (EPFL Mobots group)" select ARCH_MX31 diff --git a/arch/arm/mach-mx3/mach-mx31_3ds.c b/arch/arm/mach-mx3/mach-mx31_3ds.c index 4a94c3c..bf1f54a 100644 --- a/arch/arm/mach-mx3/mach-mx31_3ds.c +++ b/arch/arm/mach-mx3/mach-mx31_3ds.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "devices.h" /*! @@ -53,6 +54,17 @@ static int mx31_3ds_pins[] = { IOMUX_MODE(MX31_PIN_GPIO1_1, IOMUX_CONFIG_GPIO), }; +/* + * NAND Flash + */ +static struct mxc_nand_platform_data imx31_3ds_nand_flash_pdata = { + .width = 1, + .hw_ecc = 1, +#ifdef MACH_MX31_3DS_MXC_NAND_USE_BBT + .flash_bbt = 1, +#endif +}; + static struct imxuart_platform_data uart_pdata = { .flags = IMXUART_HAVE_RTSCTS, }; @@ -236,6 +248,7 @@ static void __init mxc_board_init(void) "mx31_3ds"); mxc_register_device(&mxc_uart_device0, &uart_pdata); + mxc_register_device(&mxc_nand_device, &imx31_3ds_nand_flash_pdata); if (!mx31_3ds_init_expio()) platform_device_register(&smsc911x_device); -- cgit v0.10.2 From a1ac442443342f778d5230b16efadc4c32d96298 Mon Sep 17 00:00:00 2001 From: Alberto Panizzo Date: Tue, 23 Mar 2010 19:50:28 +0100 Subject: MXC: mach-mx31_3ds: Add SPI1 device support. Signed-off-by: Alberto Panizzo Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx3/mach-mx31_3ds.c b/arch/arm/mach-mx3/mach-mx31_3ds.c index bf1f54a..80179cf 100644 --- a/arch/arm/mach-mx3/mach-mx31_3ds.c +++ b/arch/arm/mach-mx3/mach-mx31_3ds.c @@ -35,6 +35,7 @@ #include #include #include +#include #include "devices.h" /*! @@ -52,6 +53,24 @@ static int mx31_3ds_pins[] = { MX31_PIN_TXD1__TXD1, MX31_PIN_RXD1__RXD1, IOMUX_MODE(MX31_PIN_GPIO1_1, IOMUX_CONFIG_GPIO), + /* SPI 1 */ + MX31_PIN_CSPI2_SCLK__SCLK, + MX31_PIN_CSPI2_MOSI__MOSI, + MX31_PIN_CSPI2_MISO__MISO, + MX31_PIN_CSPI2_SPI_RDY__SPI_RDY, + MX31_PIN_CSPI2_SS0__SS0, + MX31_PIN_CSPI2_SS2__SS2, /*CS for MC13783 */ +}; + +/* SPI */ +static int spi1_internal_chipselect[] = { + MXC_SPI_CS(0), + MXC_SPI_CS(2), +}; + +static struct spi_imx_master spi1_pdata = { + .chipselect = spi1_internal_chipselect, + .num_chipselect = ARRAY_SIZE(spi1_internal_chipselect), }; /* @@ -249,6 +268,7 @@ static void __init mxc_board_init(void) mxc_register_device(&mxc_uart_device0, &uart_pdata); mxc_register_device(&mxc_nand_device, &imx31_3ds_nand_flash_pdata); + mxc_register_device(&mxc_spi_device1, &spi1_pdata); if (!mx31_3ds_init_expio()) platform_device_register(&smsc911x_device); -- cgit v0.10.2 From ae7a3f13ab59784d9d5041d8ecb08477a049e2c6 Mon Sep 17 00:00:00 2001 From: Alberto Panizzo Date: Tue, 23 Mar 2010 19:51:45 +0100 Subject: MXC: mach-mx31_3ds: add support for freescale mc13783 power management device. Power Gates must to be always enabled. Signed-off-by: Alberto Panizzo Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx3/mach-mx31_3ds.c b/arch/arm/mach-mx3/mach-mx31_3ds.c index 80179cf..f54af1e 100644 --- a/arch/arm/mach-mx3/mach-mx31_3ds.c +++ b/arch/arm/mach-mx3/mach-mx31_3ds.c @@ -23,6 +23,9 @@ #include #include #include +#include +#include +#include #include #include @@ -60,6 +63,33 @@ static int mx31_3ds_pins[] = { MX31_PIN_CSPI2_SPI_RDY__SPI_RDY, MX31_PIN_CSPI2_SS0__SS0, MX31_PIN_CSPI2_SS2__SS2, /*CS for MC13783 */ + /* MC13783 IRQ */ + IOMUX_MODE(MX31_PIN_GPIO1_3, IOMUX_CONFIG_GPIO), +}; + +/* Regulators */ +static struct regulator_init_data pwgtx_init = { + .constraints = { + .boot_on = 1, + .always_on = 1, + }, +}; + +static struct mc13783_regulator_init_data mx31_3ds_regulators[] = { + { + .id = MC13783_REGU_PWGT1SPI, /* Power Gate for ARM core. */ + .init_data = &pwgtx_init, + }, { + .id = MC13783_REGU_PWGT2SPI, /* Power Gate for L2 Cache. */ + .init_data = &pwgtx_init, + }, +}; + +/* MC13783 */ +static struct mc13783_platform_data mc13783_pdata __initdata = { + .regulators = mx31_3ds_regulators, + .num_regulators = ARRAY_SIZE(mx31_3ds_regulators), + .flags = MC13783_USE_REGULATOR, }; /* SPI */ @@ -73,6 +103,18 @@ static struct spi_imx_master spi1_pdata = { .num_chipselect = ARRAY_SIZE(spi1_internal_chipselect), }; +static struct spi_board_info mx31_3ds_spi_devs[] __initdata = { + { + .modalias = "mc13783", + .max_speed_hz = 1000000, + .bus_num = 1, + .chip_select = 1, /* SS2 */ + .platform_data = &mc13783_pdata, + .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3), + .mode = SPI_CS_HIGH, + }, +}; + /* * NAND Flash */ @@ -268,7 +310,10 @@ static void __init mxc_board_init(void) mxc_register_device(&mxc_uart_device0, &uart_pdata); mxc_register_device(&mxc_nand_device, &imx31_3ds_nand_flash_pdata); + mxc_register_device(&mxc_spi_device1, &spi1_pdata); + spi_register_board_info(mx31_3ds_spi_devs, + ARRAY_SIZE(mx31_3ds_spi_devs)); if (!mx31_3ds_init_expio()) platform_device_register(&smsc911x_device); -- cgit v0.10.2 From 55e0d7cf279177dfe320f54816320558bc370f24 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 25 Mar 2010 11:00:22 +0100 Subject: netfilter: xt_hashlimit: dl_seq_stop() fix If dl_seq_start() memory allocation fails, we crash later in dl_seq_stop(), trying to kfree(ERR_PTR(-ENOMEM)) Signed-off-by: Eric Dumazet Signed-off-by: Patrick McHardy diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c index 9e9c489..70d561a 100644 --- a/net/netfilter/xt_hashlimit.c +++ b/net/netfilter/xt_hashlimit.c @@ -879,7 +879,8 @@ static void dl_seq_stop(struct seq_file *s, void *v) struct xt_hashlimit_htable *htable = s->private; unsigned int *bucket = (unsigned int *)v; - kfree(bucket); + if (!IS_ERR(bucket)) + kfree(bucket); spin_unlock_bh(&htable->lock); } -- cgit v0.10.2 From 9c13886665c43600bd0af4b38e33c654e648e078 Mon Sep 17 00:00:00 2001 From: Jozsef Kadlecsik Date: Thu, 25 Mar 2010 11:17:26 +0100 Subject: netfilter: ip6table_raw: fix table priority The order of the IPv6 raw table is currently reversed, that makes impossible to use the NOTRACK target in IPv6: for example if someone enters ip6tables -t raw -A PREROUTING -p tcp --dport 80 -j NOTRACK and if we receive fragmented packets then the first fragment will be untracked and thus skip nf_ct_frag6_gather (and conntrack), while all subsequent fragments enter nf_ct_frag6_gather and reassembly will never successfully be finished. Singed-off-by: Jozsef Kadlecsik Signed-off-by: Patrick McHardy diff --git a/include/linux/netfilter_ipv6.h b/include/linux/netfilter_ipv6.h index d654873..1f7e300 100644 --- a/include/linux/netfilter_ipv6.h +++ b/include/linux/netfilter_ipv6.h @@ -59,6 +59,7 @@ enum nf_ip6_hook_priorities { NF_IP6_PRI_FIRST = INT_MIN, NF_IP6_PRI_CONNTRACK_DEFRAG = -400, + NF_IP6_PRI_RAW = -300, NF_IP6_PRI_SELINUX_FIRST = -225, NF_IP6_PRI_CONNTRACK = -200, NF_IP6_PRI_MANGLE = -150, diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c index aef31a2..b9cf7cd 100644 --- a/net/ipv6/netfilter/ip6table_raw.c +++ b/net/ipv6/netfilter/ip6table_raw.c @@ -13,7 +13,7 @@ static const struct xt_table packet_raw = { .valid_hooks = RAW_VALID_HOOKS, .me = THIS_MODULE, .af = NFPROTO_IPV6, - .priority = NF_IP6_PRI_FIRST, + .priority = NF_IP6_PRI_RAW, }; /* The work comes in here from netfilter.c. */ -- cgit v0.10.2 From 6a4f2ccb467e00281470cde2dee08fe5ecde62d1 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 25 Mar 2010 15:00:15 +0100 Subject: ALSA: hda - Don't set invalid connection index in Realtek initialiaiton Skip initialization of connections of DAC widgets that aren't used, which resulted in invalid verb parameters. Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 053d53d..9a23444 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -10043,8 +10043,11 @@ static void alc882_auto_set_output_and_unmute(struct hda_codec *codec, alc_set_pin_output(codec, nid, pin_type); if (spec->multiout.dac_nids[dac_idx] == 0x25) idx = 4; - else + else { + if (spec->multiout.num_dacs >= dac_idx) + return; idx = spec->multiout.dac_nids[dac_idx] - 2; + } snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); } -- cgit v0.10.2 From b1ffe737f5b743115ee46ffb59e338e580c54902 Mon Sep 17 00:00:00 2001 From: Divyesh Shah Date: Thu, 25 Mar 2010 15:45:03 +0100 Subject: cfq-iosched: Add additional blktrace log messages in CFQ for easier debugging These have helped us debug some issues we've noticed in earlier IO controller versions and should be useful now as well. The extra logging covers: - idling behavior. Since there are so many conditions based on which we decide to idle or not, this patch adds a log message for some conditions that we've found useful. - workload slices and current prio and workload type Changelog from v1: o moved log message from cfq_set_active_queue() to __cfq_set_active_queue() o changed queue_count to st->count Signed-off-by: Divyesh Shah Signed-off-by: Jens Axboe diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 8d5a2f2..2f91c53 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -1518,7 +1518,8 @@ static void __cfq_set_active_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq) { if (cfqq) { - cfq_log_cfqq(cfqd, cfqq, "set_active"); + cfq_log_cfqq(cfqd, cfqq, "set_active wl_prio:%d wl_type:%d", + cfqd->serving_prio, cfqd->serving_type); cfqq->slice_start = 0; cfqq->dispatch_start = jiffies; cfqq->allocated_slice = 0; @@ -1788,7 +1789,11 @@ static bool cfq_should_idle(struct cfq_data *cfqd, struct cfq_queue *cfqq) * Otherwise, we do only if they are the last ones * in their service tree. */ - return service_tree->count == 1 && cfq_cfqq_sync(cfqq); + if (service_tree->count == 1 && cfq_cfqq_sync(cfqq)) + return 1; + cfq_log_cfqq(cfqd, cfqq, "Not idling. st->count:%d", + service_tree->count); + return 0; } static void cfq_arm_slice_timer(struct cfq_data *cfqd) @@ -1833,8 +1838,11 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd) * time slice. */ if (sample_valid(cic->ttime_samples) && - (cfqq->slice_end - jiffies < cic->ttime_mean)) + (cfqq->slice_end - jiffies < cic->ttime_mean)) { + cfq_log_cfqq(cfqd, cfqq, "Not idling. think_time:%d", + cic->ttime_mean); return; + } cfq_mark_cfqq_wait_request(cfqq); @@ -2042,6 +2050,7 @@ static void choose_service_tree(struct cfq_data *cfqd, struct cfq_group *cfqg) slice = max(slice, 2 * cfqd->cfq_slice_idle); slice = max_t(unsigned, slice, CFQ_MIN_TT); + cfq_log(cfqd, "workload slice:%d", slice); cfqd->workload_expires = jiffies + slice; cfqd->noidle_tree_requires_idle = false; } @@ -3308,6 +3317,7 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq) if (cfq_should_wait_busy(cfqd, cfqq)) { cfqq->slice_end = jiffies + cfqd->cfq_slice_idle; cfq_mark_cfqq_wait_busy(cfqq); + cfq_log_cfqq(cfqd, cfqq, "will busy wait"); } /* -- cgit v0.10.2 From 39c01b219fd30c74869b6fc8749f7900f04e9ef6 Mon Sep 17 00:00:00 2001 From: Divyesh Shah Date: Thu, 25 Mar 2010 15:45:57 +0100 Subject: cfq-iosched: Do not merge queues of BE and IDLE classes Even if they are found to be co-operating. The prio_trees do not have any IDLE cfqqs on them. cfq_close_cooperator() is called from cfq_select_queue() and cfq_completed_request(). The latter ensures that the close cooperator code does not get invoked if the current cfqq is of class IDLE but the former doesn't seem to have any such checks. So an IDLE cfqq may get merged with a BE cfqq from the same group which should be avoided. Signed-off-by: Divyesh Shah Acked-by: Vivek Goyal Signed-off-by: Jens Axboe diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 2f91c53..2c7a0f4 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -1723,6 +1723,8 @@ static struct cfq_queue *cfq_close_cooperator(struct cfq_data *cfqd, { struct cfq_queue *cfqq; + if (cfq_class_idle(cur_cfqq)) + return NULL; if (!cfq_cfqq_sync(cur_cfqq)) return NULL; if (CFQQ_SEEKY(cur_cfqq)) -- cgit v0.10.2 From 134b345081534235dbf228b1005c14590e0570ba Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Wed, 24 Mar 2010 07:11:01 -0600 Subject: PCI quirk: Disable MSI on VIA K8T890 systems Bugzilla 15287 indicates that there's a problem with Message Signalled Interrupts on VIA K8T890 systems. Add a quirk to disable MSI on these systems. Signed-off-by: Matthew Wilcox Tested-by: Jan Kreuzer Tested-by: lh Signed-off-by: Jesse Barnes diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index bb5b46a..f6bbb9c 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -2122,6 +2122,7 @@ static void __devinit quirk_disable_msi(struct pci_dev *dev) } } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_disable_msi); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, 0xa238, quirk_disable_msi); /* Go through the list of Hypertransport capabilities and * return 1 if a HT MSI capability is found and enabled */ -- cgit v0.10.2 From f967a44343e407811898ddac97abc69b293e9810 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Mon, 22 Mar 2010 16:34:05 -0600 Subject: PCI: don't say we claimed a resource if we failed pci_claim_resource() can fail, so pay attention and only claim success when it actually succeeded. If pci_claim_resource() fails, it prints a useful diagnostic. Signed-off-by: Bjorn Helgaas Signed-off-by: Jesse Barnes diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index f6bbb9c..3ea0b29 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -368,8 +368,9 @@ static void __devinit quirk_io_region(struct pci_dev *dev, unsigned region, bus_region.end = res->end; pcibios_bus_to_resource(dev, res, &bus_region); - pci_claim_resource(dev, nr); - dev_info(&dev->dev, "quirk: %pR claimed by %s\n", res, name); + if (pci_claim_resource(dev, nr) == 0) + dev_info(&dev->dev, "quirk: %pR claimed by %s\n", + res, name); } } -- cgit v0.10.2 From c9c9b564717e5b6b2ae8b770da1c73a348c84cce Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Mon, 22 Mar 2010 16:34:10 -0600 Subject: x86/PCI: remove redundant warnings pci_claim_resource() already prints more detailed error messages, so these are really redundant. Signed-off-by: Bjorn Helgaas Signed-off-by: Jesse Barnes diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c index dece3eb..46fd43f 100644 --- a/arch/x86/pci/i386.c +++ b/arch/x86/pci/i386.c @@ -127,9 +127,6 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list) continue; if (!r->start || pci_claim_resource(dev, idx) < 0) { - dev_info(&dev->dev, - "can't reserve window %pR\n", - r); /* * Something is wrong with the region. * Invalidate the resource to prevent @@ -181,8 +178,6 @@ static void __init pcibios_allocate_resources(int pass) "BAR %d: reserving %pr (d=%d, p=%d)\n", idx, r, disabled, pass); if (pci_claim_resource(dev, idx) < 0) { - dev_info(&dev->dev, - "can't reserve %pR\n", r); /* We'll assign a new address later */ r->end -= r->start; r->start = 0; -- cgit v0.10.2 From 99f4692e13ba22b228bdd155473f24ae9bdec1dc Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Mon, 22 Mar 2010 16:34:15 -0600 Subject: frv/PCI: remove redundant warnings pci_claim_resource() already prints more detailed error messages, so these are really redundant. Signed-off-by: Bjorn Helgaas Signed-off-by: Jesse Barnes diff --git a/arch/frv/mb93090-mb00/pci-frv.c b/arch/frv/mb93090-mb00/pci-frv.c index 1ed15d7..16bc2cb 100644 --- a/arch/frv/mb93090-mb00/pci-frv.c +++ b/arch/frv/mb93090-mb00/pci-frv.c @@ -94,8 +94,7 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list) r = &dev->resource[idx]; if (!r->start) continue; - if (pci_claim_resource(dev, idx) < 0) - printk(KERN_ERR "PCI: Cannot allocate resource region %d of bridge %s\n", idx, pci_name(dev)); + pci_claim_resource(dev, idx); } } pcibios_allocate_bus_resources(&bus->children); @@ -125,7 +124,6 @@ static void __init pcibios_allocate_resources(int pass) DBG("PCI: Resource %08lx-%08lx (f=%lx, d=%d, p=%d)\n", r->start, r->end, r->flags, disabled, pass); if (pci_claim_resource(dev, idx) < 0) { - printk(KERN_ERR "PCI: Cannot allocate resource region %d of device %s\n", idx, pci_name(dev)); /* We'll assign a new address later */ r->end -= r->start; r->start = 0; -- cgit v0.10.2 From 8f5992291457c8e6de2f5fe39849de6756be1a96 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 25 Mar 2010 17:25:11 +0100 Subject: netfilter: xt_hashlimit: IPV6 bugfix A missing break statement in hashlimit_ipv6_mask(), and masks between /64 and /95 are not working at all... Signed-off-by: Eric Dumazet Signed-off-by: Patrick McHardy diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c index 70d561a..215a648 100644 --- a/net/netfilter/xt_hashlimit.c +++ b/net/netfilter/xt_hashlimit.c @@ -493,6 +493,7 @@ static void hashlimit_ipv6_mask(__be32 *i, unsigned int p) case 64 ... 95: i[2] = maskl(i[2], p - 64); i[3] = 0; + break; case 96 ... 127: i[3] = maskl(i[3], p - 96); break; -- cgit v0.10.2 From eb9fc8ef7cb1362374e55d9503e3e7458f319991 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 25 Mar 2010 09:28:24 -0600 Subject: x86/PCI: for host bridge address space collisions, show conflicting resource With insert_resource_conflict(), we can learn what the actual conflict is, so print that info for debugging purposes. Signed-off-by: Bjorn Helgaas Signed-off-by: Jesse Barnes diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index 6e22454..75ac3f8 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c @@ -122,7 +122,7 @@ setup_resource(struct acpi_resource *acpi_res, void *data) struct acpi_resource_address64 addr; acpi_status status; unsigned long flags; - struct resource *root; + struct resource *root, *conflict; u64 start, end; status = resource_to_addr(acpi_res, &addr); @@ -157,9 +157,12 @@ setup_resource(struct acpi_resource *acpi_res, void *data) return AE_OK; } - if (insert_resource(root, res)) { + conflict = insert_resource_conflict(root, res); + if (conflict) { dev_err(&info->bridge->dev, - "can't allocate host bridge window %pR\n", res); + "address space collision: host bridge window %pR " + "conflicts with %s %pR\n", + res, conflict->name, conflict); } else { pci_bus_add_resource(info->bus, res, 0); info->res_num++; -- cgit v0.10.2 From d558b483d5a73f5718705b270cb2090f66ea48c8 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 25 Mar 2010 09:28:30 -0600 Subject: x86/PCI: truncate _CRS windows with _LEN > _MAX - _MIN + 1 Yanko's GA-MA78GM-S2H (BIOS F11) reports the following resource in a PCI host bridge _CRS: [07] 32-Bit DWORD Address Space Resource Min Relocatability : MinFixed Max Relocatability : MaxFixed Address Minimum : CFF00000 (_MIN) Address Maximum : FEBFFFFF (_MAX) Address Length : 3EE10000 (_LEN) This is invalid per spec (ACPI 4.0, 6.4.3.5) because it's a fixed size, fixed location descriptor, but _LEN != _MAX - _MIN + 1. Based on https://bugzilla.kernel.org/show_bug.cgi?id=15480#c15, I think Windows handles this by truncating the window so it fits between _MIN and _MAX. I also verified this by modifying the SeaBIOS DSDT and booting Windows 2008 R2 with qemu. This patch makes Linux truncate the window, too, which fixes: http://bugzilla.kernel.org/show_bug.cgi?id=15480 Signed-off-by: Bjorn Helgaas Tested-by: Yanko Kaneti Signed-off-by: Jesse Barnes diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index 75ac3f8..e311602 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c @@ -123,7 +123,7 @@ setup_resource(struct acpi_resource *acpi_res, void *data) acpi_status status; unsigned long flags; struct resource *root, *conflict; - u64 start, end; + u64 start, end, max_len; status = resource_to_addr(acpi_res, &addr); if (!ACPI_SUCCESS(status)) @@ -140,6 +140,17 @@ setup_resource(struct acpi_resource *acpi_res, void *data) } else return AE_OK; + max_len = addr.maximum - addr.minimum + 1; + if (addr.address_length > max_len) { + dev_printk(KERN_DEBUG, &info->bridge->dev, + "host bridge window length %#llx doesn't fit in " + "%#llx-%#llx, trimming\n", + (unsigned long long) addr.address_length, + (unsigned long long) addr.minimum, + (unsigned long long) addr.maximum); + addr.address_length = max_len; + } + start = addr.minimum + addr.translation_offset; end = start + addr.address_length - 1; -- cgit v0.10.2 From 8d06a1e1e9c69244f08beb7d17146483f9dcd120 Mon Sep 17 00:00:00 2001 From: Robert Hooker Date: Fri, 19 Mar 2010 15:13:27 -0400 Subject: drm/i915: Disable FBC on 915GM and 945GM. It is causing hangs after a suspend/resume cycle with the default powersave=1 module option on these chipsets since 2.6.32-rc. BugLink: http://bugs.launchpad.net/bugs/492392 Signed-off-by: Robert Hooker Acked-by: Jesse Barnes Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 4b26919..1a39ec7 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -80,14 +80,14 @@ const static struct intel_device_info intel_i915g_info = { .is_i915g = 1, .is_i9xx = 1, .cursor_needs_physical = 1, }; const static struct intel_device_info intel_i915gm_info = { - .is_i9xx = 1, .is_mobile = 1, .has_fbc = 1, + .is_i9xx = 1, .is_mobile = 1, .cursor_needs_physical = 1, }; const static struct intel_device_info intel_i945g_info = { .is_i9xx = 1, .has_hotplug = 1, .cursor_needs_physical = 1, }; const static struct intel_device_info intel_i945gm_info = { - .is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1, .has_fbc = 1, + .is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1, .has_hotplug = 1, .cursor_needs_physical = 1, }; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 58fc7fa..f021490 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4814,7 +4814,7 @@ static void intel_init_display(struct drm_device *dev) dev_priv->display.fbc_enabled = g4x_fbc_enabled; dev_priv->display.enable_fbc = g4x_enable_fbc; dev_priv->display.disable_fbc = g4x_disable_fbc; - } else if (IS_I965GM(dev) || IS_I945GM(dev) || IS_I915GM(dev)) { + } else if (IS_I965GM(dev)) { dev_priv->display.fbc_enabled = i8xx_fbc_enabled; dev_priv->display.enable_fbc = i8xx_enable_fbc; dev_priv->display.disable_fbc = i8xx_disable_fbc; -- cgit v0.10.2 From 23010e43b353c2cdc9725cbedc7e364708039bf7 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 8 Mar 2010 13:35:02 +0100 Subject: drm/i915: introduce to_intel_bo helper This is a purely cosmetic change to make changes in this area easier. And hey, it's not only clearer and typechecked, but actually shorter, too! [anholt: To clarify, this is a change to let us later make drm_i915_gem_object subclass drm_gem_object, instead of having drm_gem_object have a pointer to i915's private data] Signed-off-by: Daniel Vetter Acked-by: Dave Airlie Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 1376dfe..bb3a4a8 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -225,7 +225,7 @@ static int i915_gem_fence_regs_info(struct seq_file *m, void *data) } else { struct drm_i915_gem_object *obj_priv; - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); seq_printf(m, "Fenced object[%2d] = %p: %s " "%08x %08zx %08x %s %08x %08x %d", i, obj, get_pin_flag(obj_priv), diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 1a39ec7..0af3dcc 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -361,7 +361,7 @@ int i965_reset(struct drm_device *dev, u8 flags) !dev_priv->mm.suspended) { drm_i915_ring_buffer_t *ring = &dev_priv->ring; struct drm_gem_object *obj = ring->ring_obj; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); dev_priv->mm.suspended = 0; /* Stop the ring if it's running. */ diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index aba8260..b7cb4aa 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -731,6 +731,8 @@ struct drm_i915_gem_object { atomic_t pending_flip; }; +#define to_intel_bo(x) ((struct drm_i915_gem_object *) (x)->driver_private) + /** * Request queue structure. * diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 933e865..b85727c 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -162,7 +162,7 @@ fast_shmem_read(struct page **pages, static int i915_gem_object_needs_bit17_swizzle(struct drm_gem_object *obj) { drm_i915_private_t *dev_priv = obj->dev->dev_private; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); return dev_priv->mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_9_10_17 && obj_priv->tiling_mode != I915_TILING_NONE; @@ -263,7 +263,7 @@ i915_gem_shmem_pread_fast(struct drm_device *dev, struct drm_gem_object *obj, struct drm_i915_gem_pread *args, struct drm_file *file_priv) { - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); ssize_t remain; loff_t offset, page_base; char __user *user_data; @@ -284,7 +284,7 @@ i915_gem_shmem_pread_fast(struct drm_device *dev, struct drm_gem_object *obj, if (ret != 0) goto fail_put_pages; - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); offset = args->offset; while (remain > 0) { @@ -353,7 +353,7 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj, struct drm_i915_gem_pread *args, struct drm_file *file_priv) { - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); struct mm_struct *mm = current->mm; struct page **user_pages; ssize_t remain; @@ -402,7 +402,7 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj, if (ret != 0) goto fail_put_pages; - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); offset = args->offset; while (remain > 0) { @@ -478,7 +478,7 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, obj = drm_gem_object_lookup(dev, file_priv, args->handle); if (obj == NULL) return -EBADF; - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); /* Bounds check source. * @@ -580,7 +580,7 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj, struct drm_i915_gem_pwrite *args, struct drm_file *file_priv) { - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); drm_i915_private_t *dev_priv = dev->dev_private; ssize_t remain; loff_t offset, page_base; @@ -604,7 +604,7 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj, if (ret) goto fail; - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); offset = obj_priv->gtt_offset + args->offset; while (remain > 0) { @@ -654,7 +654,7 @@ i915_gem_gtt_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj, struct drm_i915_gem_pwrite *args, struct drm_file *file_priv) { - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); drm_i915_private_t *dev_priv = dev->dev_private; ssize_t remain; loff_t gtt_page_base, offset; @@ -698,7 +698,7 @@ i915_gem_gtt_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj, if (ret) goto out_unpin_object; - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); offset = obj_priv->gtt_offset + args->offset; while (remain > 0) { @@ -760,7 +760,7 @@ i915_gem_shmem_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj, struct drm_i915_gem_pwrite *args, struct drm_file *file_priv) { - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); ssize_t remain; loff_t offset, page_base; char __user *user_data; @@ -780,7 +780,7 @@ i915_gem_shmem_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj, if (ret != 0) goto fail_put_pages; - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); offset = args->offset; obj_priv->dirty = 1; @@ -828,7 +828,7 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj, struct drm_i915_gem_pwrite *args, struct drm_file *file_priv) { - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); struct mm_struct *mm = current->mm; struct page **user_pages; ssize_t remain; @@ -876,7 +876,7 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj, if (ret != 0) goto fail_put_pages; - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); offset = args->offset; obj_priv->dirty = 1; @@ -951,7 +951,7 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, obj = drm_gem_object_lookup(dev, file_priv, args->handle); if (obj == NULL) return -EBADF; - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); /* Bounds check destination. * @@ -1033,7 +1033,7 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, obj = drm_gem_object_lookup(dev, file_priv, args->handle); if (obj == NULL) return -EBADF; - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); mutex_lock(&dev->struct_mutex); @@ -1095,7 +1095,7 @@ i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, DRM_INFO("%s: sw_finish %d (%p %zd)\n", __func__, args->handle, obj, obj->size); #endif - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); /* Pinned buffers may be scanout, so flush the cache */ if (obj_priv->pin_count) @@ -1166,7 +1166,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) struct drm_gem_object *obj = vma->vm_private_data; struct drm_device *dev = obj->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); pgoff_t page_offset; unsigned long pfn; int ret = 0; @@ -1233,7 +1233,7 @@ i915_gem_create_mmap_offset(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; struct drm_gem_mm *mm = dev->mm_private; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); struct drm_map_list *list; struct drm_local_map *map; int ret = 0; @@ -1304,7 +1304,7 @@ void i915_gem_release_mmap(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); if (dev->dev_mapping) unmap_mapping_range(dev->dev_mapping, @@ -1315,7 +1315,7 @@ static void i915_gem_free_mmap_offset(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); struct drm_gem_mm *mm = dev->mm_private; struct drm_map_list *list; @@ -1346,7 +1346,7 @@ static uint32_t i915_gem_get_gtt_alignment(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int start, i; /* @@ -1405,7 +1405,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, mutex_lock(&dev->struct_mutex); - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); if (obj_priv->madv != I915_MADV_WILLNEED) { DRM_ERROR("Attempting to mmap a purgeable buffer\n"); @@ -1449,7 +1449,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, void i915_gem_object_put_pages(struct drm_gem_object *obj) { - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int page_count = obj->size / PAGE_SIZE; int i; @@ -1485,7 +1485,7 @@ i915_gem_object_move_to_active(struct drm_gem_object *obj, uint32_t seqno) { struct drm_device *dev = obj->dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); /* Add a reference if we're newly entering the active list. */ if (!obj_priv->active) { @@ -1505,7 +1505,7 @@ i915_gem_object_move_to_flushing(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); BUG_ON(!obj_priv->active); list_move_tail(&obj_priv->list, &dev_priv->mm.flushing_list); @@ -1516,7 +1516,7 @@ i915_gem_object_move_to_flushing(struct drm_gem_object *obj) static void i915_gem_object_truncate(struct drm_gem_object *obj) { - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); struct inode *inode; inode = obj->filp->f_path.dentry->d_inode; @@ -1537,7 +1537,7 @@ i915_gem_object_move_to_inactive(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); i915_verify_inactive(dev, __FILE__, __LINE__); if (obj_priv->pin_count != 0) @@ -1964,7 +1964,7 @@ static int i915_gem_object_wait_rendering(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int ret; /* This function only exists to support waiting for existing rendering, @@ -1996,7 +1996,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int ret = 0; #if WATCH_BUF @@ -2172,7 +2172,7 @@ i915_gem_evict_something(struct drm_device *dev, int min_size) #if WATCH_LRU DRM_INFO("%s: evicting %p\n", __func__, obj); #endif - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); BUG_ON(obj_priv->pin_count != 0); BUG_ON(obj_priv->active); @@ -2243,7 +2243,7 @@ int i915_gem_object_get_pages(struct drm_gem_object *obj, gfp_t gfpmask) { - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int page_count, i; struct address_space *mapping; struct inode *inode; @@ -2296,7 +2296,7 @@ static void sandybridge_write_fence_reg(struct drm_i915_fence_reg *reg) struct drm_gem_object *obj = reg->obj; struct drm_device *dev = obj->dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int regnum = obj_priv->fence_reg; uint64_t val; @@ -2318,7 +2318,7 @@ static void i965_write_fence_reg(struct drm_i915_fence_reg *reg) struct drm_gem_object *obj = reg->obj; struct drm_device *dev = obj->dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int regnum = obj_priv->fence_reg; uint64_t val; @@ -2338,7 +2338,7 @@ static void i915_write_fence_reg(struct drm_i915_fence_reg *reg) struct drm_gem_object *obj = reg->obj; struct drm_device *dev = obj->dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int regnum = obj_priv->fence_reg; int tile_width; uint32_t fence_reg, val; @@ -2380,7 +2380,7 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg) struct drm_gem_object *obj = reg->obj; struct drm_device *dev = obj->dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int regnum = obj_priv->fence_reg; uint32_t val; uint32_t pitch_val; @@ -2424,7 +2424,7 @@ static int i915_find_fence_reg(struct drm_device *dev) if (!reg->obj) return i; - obj_priv = reg->obj->driver_private; + obj_priv = to_intel_bo(reg->obj); if (!obj_priv->pin_count) avail++; } @@ -2479,7 +2479,7 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); struct drm_i915_fence_reg *reg = NULL; int ret; @@ -2546,7 +2546,7 @@ i915_gem_clear_fence_reg(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); if (IS_GEN6(dev)) { I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + @@ -2582,7 +2582,7 @@ int i915_gem_object_put_fence_reg(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); if (obj_priv->fence_reg == I915_FENCE_REG_NONE) return 0; @@ -2620,7 +2620,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) { struct drm_device *dev = obj->dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); struct drm_mm_node *free_space; gfp_t gfpmask = __GFP_NORETRY | __GFP_NOWARN; int ret; @@ -2727,7 +2727,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) void i915_gem_clflush_object(struct drm_gem_object *obj) { - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); /* If we don't have a page list set up, then we're not pinned * to GPU, and we can ignore the cache flush because it'll happen @@ -2828,7 +2828,7 @@ i915_gem_object_flush_write_domain(struct drm_gem_object *obj) int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write) { - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); uint32_t old_write_domain, old_read_domains; int ret; @@ -2878,7 +2878,7 @@ int i915_gem_object_set_to_display_plane(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); uint32_t old_write_domain, old_read_domains; int ret; @@ -3091,7 +3091,7 @@ static void i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); uint32_t invalidate_domains = 0; uint32_t flush_domains = 0; uint32_t old_read_domains; @@ -3176,7 +3176,7 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj) static void i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *obj) { - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); if (!obj_priv->page_cpu_valid) return; @@ -3216,7 +3216,7 @@ static int i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj, uint64_t offset, uint64_t size) { - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); uint32_t old_read_domains; int i, ret; @@ -3285,7 +3285,7 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, { struct drm_device *dev = obj->dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int i, ret; void __iomem *reloc_page; bool need_fence; @@ -3336,7 +3336,7 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, i915_gem_object_unpin(obj); return -EBADF; } - target_obj_priv = target_obj->driver_private; + target_obj_priv = to_intel_bo(target_obj); #if WATCH_RELOC DRM_INFO("%s: obj %p offset %08x target %d " @@ -3688,7 +3688,7 @@ i915_gem_wait_for_pending_flip(struct drm_device *dev, prepare_to_wait(&dev_priv->pending_flip_queue, &wait, TASK_INTERRUPTIBLE); for (i = 0; i < count; i++) { - obj_priv = object_list[i]->driver_private; + obj_priv = to_intel_bo(object_list[i]); if (atomic_read(&obj_priv->pending_flip) > 0) break; } @@ -3797,7 +3797,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, goto err; } - obj_priv = object_list[i]->driver_private; + obj_priv = to_intel_bo(object_list[i]); if (obj_priv->in_execbuffer) { DRM_ERROR("Object %p appears more than once in object list\n", object_list[i]); @@ -3923,7 +3923,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, for (i = 0; i < args->buffer_count; i++) { struct drm_gem_object *obj = object_list[i]; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); uint32_t old_write_domain = obj->write_domain; obj->write_domain = obj->pending_write_domain; @@ -3998,7 +3998,7 @@ err: for (i = 0; i < args->buffer_count; i++) { if (object_list[i]) { - obj_priv = object_list[i]->driver_private; + obj_priv = to_intel_bo(object_list[i]); obj_priv->in_execbuffer = false; } drm_gem_object_unreference(object_list[i]); @@ -4176,7 +4176,7 @@ int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) { struct drm_device *dev = obj->dev; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int ret; i915_verify_inactive(dev, __FILE__, __LINE__); @@ -4209,7 +4209,7 @@ i915_gem_object_unpin(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); i915_verify_inactive(dev, __FILE__, __LINE__); obj_priv->pin_count--; @@ -4249,7 +4249,7 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data, mutex_unlock(&dev->struct_mutex); return -EBADF; } - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); if (obj_priv->madv != I915_MADV_WILLNEED) { DRM_ERROR("Attempting to pin a purgeable buffer\n"); @@ -4306,7 +4306,7 @@ i915_gem_unpin_ioctl(struct drm_device *dev, void *data, return -EBADF; } - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); if (obj_priv->pin_filp != file_priv) { DRM_ERROR("Not pinned by caller in i915_gem_pin_ioctl(): %d\n", args->handle); @@ -4348,7 +4348,7 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, */ i915_gem_retire_requests(dev); - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); /* Don't count being on the flushing list against the object being * done. Otherwise, a buffer left on the flushing list but not getting * flushed (because nobody's flushing that domain) won't ever return @@ -4394,7 +4394,7 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data, } mutex_lock(&dev->struct_mutex); - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); if (obj_priv->pin_count) { drm_gem_object_unreference(obj); @@ -4455,7 +4455,7 @@ int i915_gem_init_object(struct drm_gem_object *obj) void i915_gem_free_object(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); trace_i915_gem_object_destroy(obj); @@ -4564,7 +4564,7 @@ i915_gem_init_hws(struct drm_device *dev) DRM_ERROR("Failed to allocate status page\n"); return -ENOMEM; } - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); obj_priv->agp_type = AGP_USER_CACHED_MEMORY; ret = i915_gem_object_pin(obj, 4096); @@ -4608,7 +4608,7 @@ i915_gem_cleanup_hws(struct drm_device *dev) return; obj = dev_priv->hws_obj; - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); kunmap(obj_priv->pages[0]); i915_gem_object_unpin(obj); @@ -4642,7 +4642,7 @@ i915_gem_init_ringbuffer(struct drm_device *dev) i915_gem_cleanup_hws(dev); return -ENOMEM; } - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); ret = i915_gem_object_pin(obj, 4096); if (ret != 0) { @@ -4935,7 +4935,7 @@ void i915_gem_detach_phys_object(struct drm_device *dev, int ret; int page_count; - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); if (!obj_priv->phys_obj) return; @@ -4974,7 +4974,7 @@ i915_gem_attach_phys_object(struct drm_device *dev, if (id > I915_MAX_PHYS_OBJECT) return -EINVAL; - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); if (obj_priv->phys_obj) { if (obj_priv->phys_obj->id == id) @@ -5025,7 +5025,7 @@ i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, struct drm_i915_gem_pwrite *args, struct drm_file *file_priv) { - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); void *obj_addr; int ret; char __user *user_data; diff --git a/drivers/gpu/drm/i915/i915_gem_debug.c b/drivers/gpu/drm/i915/i915_gem_debug.c index e602614..35507cf 100644 --- a/drivers/gpu/drm/i915/i915_gem_debug.c +++ b/drivers/gpu/drm/i915/i915_gem_debug.c @@ -72,7 +72,7 @@ void i915_gem_dump_object(struct drm_gem_object *obj, int len, const char *where, uint32_t mark) { - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int page; DRM_INFO("%s: object at offset %08x\n", where, obj_priv->gtt_offset); @@ -137,7 +137,7 @@ void i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle) { struct drm_device *dev = obj->dev; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int page; uint32_t *gtt_mapping; uint32_t *backing_map = NULL; diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index c01c878..449157f 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -240,7 +240,7 @@ bool i915_gem_object_fence_offset_ok(struct drm_gem_object *obj, int tiling_mode) { struct drm_device *dev = obj->dev; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); if (obj_priv->gtt_space == NULL) return true; @@ -280,7 +280,7 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, obj = drm_gem_object_lookup(dev, file_priv, args->handle); if (obj == NULL) return -EINVAL; - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); if (!i915_tiling_ok(dev, args->stride, obj->size, args->tiling_mode)) { drm_gem_object_unreference_unlocked(obj); @@ -364,7 +364,7 @@ i915_gem_get_tiling(struct drm_device *dev, void *data, obj = drm_gem_object_lookup(dev, file_priv, args->handle); if (obj == NULL) return -EINVAL; - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); mutex_lock(&dev->struct_mutex); @@ -427,7 +427,7 @@ i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int page_count = obj->size >> PAGE_SHIFT; int i; @@ -456,7 +456,7 @@ i915_gem_object_save_bit_17_swizzle(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int page_count = obj->size >> PAGE_SHIFT; int i; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 5388354..bfbdad9 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -443,7 +443,7 @@ i915_error_object_create(struct drm_device *dev, if (src == NULL) return NULL; - src_priv = src->driver_private; + src_priv = to_intel_bo(src); if (src_priv->pages == NULL) return NULL; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f021490..7adb3a5 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1002,7 +1002,7 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval) struct drm_i915_private *dev_priv = dev->dev_private; struct drm_framebuffer *fb = crtc->fb; struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); - struct drm_i915_gem_object *obj_priv = intel_fb->obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(intel_fb->obj); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int plane, i; u32 fbc_ctl, fbc_ctl2; @@ -1079,7 +1079,7 @@ static void g4x_enable_fbc(struct drm_crtc *crtc, unsigned long interval) struct drm_i915_private *dev_priv = dev->dev_private; struct drm_framebuffer *fb = crtc->fb; struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); - struct drm_i915_gem_object *obj_priv = intel_fb->obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(intel_fb->obj); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int plane = (intel_crtc->plane == 0 ? DPFC_CTL_PLANEA : DPFC_CTL_PLANEB); @@ -1175,7 +1175,7 @@ static void intel_update_fbc(struct drm_crtc *crtc, return; intel_fb = to_intel_framebuffer(fb); - obj_priv = intel_fb->obj->driver_private; + obj_priv = to_intel_bo(intel_fb->obj); /* * If FBC is already on, we just have to verify that we can @@ -1242,7 +1242,7 @@ out_disable: static int intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_gem_object *obj) { - struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); u32 alignment; int ret; @@ -1322,7 +1322,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, intel_fb = to_intel_framebuffer(crtc->fb); obj = intel_fb->obj; - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); mutex_lock(&dev->struct_mutex); ret = intel_pin_and_fence_fb_obj(dev, obj); @@ -1400,7 +1400,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, if (old_fb) { intel_fb = to_intel_framebuffer(old_fb); - obj_priv = intel_fb->obj->driver_private; + obj_priv = to_intel_bo(intel_fb->obj); i915_gem_object_unpin(intel_fb->obj); } intel_increase_pllclock(crtc, true); @@ -3510,7 +3510,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, if (!bo) return -ENOENT; - obj_priv = bo->driver_private; + obj_priv = to_intel_bo(bo); if (bo->size < width * height * 4) { DRM_ERROR("buffer is to small\n"); @@ -4155,7 +4155,7 @@ void intel_finish_page_flip(struct drm_device *dev, int pipe) work = intel_crtc->unpin_work; if (work == NULL || !work->pending) { if (work && !work->pending) { - obj_priv = work->pending_flip_obj->driver_private; + obj_priv = to_intel_bo(work->pending_flip_obj); DRM_DEBUG_DRIVER("flip finish: %p (%d) not pending?\n", obj_priv, atomic_read(&obj_priv->pending_flip)); @@ -4180,7 +4180,7 @@ void intel_finish_page_flip(struct drm_device *dev, int pipe) spin_unlock_irqrestore(&dev->event_lock, flags); - obj_priv = work->pending_flip_obj->driver_private; + obj_priv = to_intel_bo(work->pending_flip_obj); /* Initial scanout buffer will have a 0 pending flip count */ if ((atomic_read(&obj_priv->pending_flip) == 0) || @@ -4251,7 +4251,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, ret = intel_pin_and_fence_fb_obj(dev, obj); if (ret != 0) { DRM_DEBUG_DRIVER("flip queue: %p pin & fence failed\n", - obj->driver_private); + to_intel_bo(obj)); kfree(work); intel_crtc->unpin_work = NULL; mutex_unlock(&dev->struct_mutex); @@ -4265,7 +4265,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, crtc->fb = fb; i915_gem_object_flush_write_domain(obj); drm_vblank_get(dev, intel_crtc->pipe); - obj_priv = obj->driver_private; + obj_priv = to_intel_bo(obj); atomic_inc(&obj_priv->pending_flip); work->pending_flip_obj = obj; @@ -4778,14 +4778,14 @@ void intel_init_clock_gating(struct drm_device *dev) struct drm_i915_gem_object *obj_priv = NULL; if (dev_priv->pwrctx) { - obj_priv = dev_priv->pwrctx->driver_private; + obj_priv = to_intel_bo(dev_priv->pwrctx); } else { struct drm_gem_object *pwrctx; pwrctx = intel_alloc_power_context(dev); if (pwrctx) { dev_priv->pwrctx = pwrctx; - obj_priv = pwrctx->driver_private; + obj_priv = to_intel_bo(pwrctx); } } @@ -4956,7 +4956,7 @@ void intel_modeset_cleanup(struct drm_device *dev) if (dev_priv->pwrctx) { struct drm_i915_gem_object *obj_priv; - obj_priv = dev_priv->pwrctx->driver_private; + obj_priv = to_intel_bo(dev_priv->pwrctx); I915_WRITE(PWRCTXA, obj_priv->gtt_offset &~ PWRCTX_EN); I915_READ(PWRCTXA); i915_gem_object_unpin(dev_priv->pwrctx); diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index 8cd791d..c9fbdfa 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c @@ -145,7 +145,7 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width, ret = -ENOMEM; goto out; } - obj_priv = fbo->driver_private; + obj_priv = to_intel_bo(fbo); mutex_lock(&dev->struct_mutex); diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index 60595fc..6d524a1 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -724,7 +724,7 @@ int intel_overlay_do_put_image(struct intel_overlay *overlay, int ret, tmp_width; struct overlay_registers *regs; bool scale_changed = false; - struct drm_i915_gem_object *bo_priv = new_bo->driver_private; + struct drm_i915_gem_object *bo_priv = to_intel_bo(new_bo); struct drm_device *dev = overlay->dev; BUG_ON(!mutex_is_locked(&dev->struct_mutex)); @@ -809,7 +809,7 @@ int intel_overlay_do_put_image(struct intel_overlay *overlay, intel_overlay_continue(overlay, scale_changed); overlay->old_vid_bo = overlay->vid_bo; - overlay->vid_bo = new_bo->driver_private; + overlay->vid_bo = to_intel_bo(new_bo); return 0; @@ -1344,7 +1344,7 @@ void intel_setup_overlay(struct drm_device *dev) reg_bo = drm_gem_object_alloc(dev, PAGE_SIZE); if (!reg_bo) goto out_free; - overlay->reg_bo = reg_bo->driver_private; + overlay->reg_bo = to_intel_bo(reg_bo); if (OVERLAY_NONPHYSICAL(dev)) { ret = i915_gem_object_pin(reg_bo, PAGE_SIZE); -- cgit v0.10.2 From 5e64499f3d39c633de49320e399479642c2b1743 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 19 Mar 2010 21:46:23 +0100 Subject: agp/intel: intel_845_driver is an agp driver! ... not a GTT driver. So the additional chipset flush introduced in commit 2162e6a2b0cd5acbb9bd8a3c94e1c1269b078295 Author: Dave Airlie Date: Wed Nov 21 16:36:31 2007 +1000 agp/intel: Add chipset flushing support for i8xx chipsets. to fix a GTT problem makes absolutely no sense. If this would really be needed for AGP chipsets, too, we should add it to all i8xx agp drivers, not just one. Signed-off-by: Daniel Vetter Signed-off-by: Eric Anholt diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index b78d5c3..a34fc9f 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -1816,8 +1816,6 @@ static int intel_845_configure(void) pci_write_config_byte(agp_bridge->dev, INTEL_I845_AGPM, temp2 | (1 << 1)); /* clear any possible error conditions */ pci_write_config_word(agp_bridge->dev, INTEL_I845_ERRSTS, 0x001c); - - intel_i830_setup_flush(); return 0; } @@ -2187,7 +2185,6 @@ static const struct agp_bridge_driver intel_845_driver = { .agp_destroy_page = agp_generic_destroy_page, .agp_destroy_pages = agp_generic_destroy_pages, .agp_type_to_mask_type = agp_generic_type_to_mask_type, - .chipset_flush = intel_i830_chipset_flush, }; static const struct agp_bridge_driver intel_850_driver = { -- cgit v0.10.2 From bcbe53682f65330bdd9ad7eed9575d2ff536353a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 22 Mar 2010 19:59:47 -0700 Subject: via-velocity: Fix FLOW_CNTL_TX_RX handling in set_mii_flow_control() Clear, don't set, ANAR_ASMDIR in this case. Noticed by Roel Kluin. Signed-off-by: David S. Miller diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index 3a486f3..bc278d4 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -812,7 +812,7 @@ static void set_mii_flow_control(struct velocity_info *vptr) case FLOW_CNTL_TX_RX: MII_REG_BITS_ON(ANAR_PAUSE, MII_REG_ANAR, vptr->mac_regs); - MII_REG_BITS_ON(ANAR_ASMDIR, MII_REG_ANAR, vptr->mac_regs); + MII_REG_BITS_OFF(ANAR_ASMDIR, MII_REG_ANAR, vptr->mac_regs); break; case FLOW_CNTL_DISABLE: -- cgit v0.10.2 From 93b39a0dba6a15c35a582b9e8b171b8a6ec971aa Mon Sep 17 00:00:00 2001 From: Henne Date: Thu, 25 Mar 2010 12:05:29 +0000 Subject: isdn: Cleanup Sections in PCMCIA driver sedlbauer Compiling this driver gave a section mismatch, so I reviewed the init/exit paths of the driver and made the correct changes. WARNING: drivers/isdn/hisax/built-in.o(.text+0x558d6): Section mismatch in reference from the function sedlbauer_config() to the function .devinit.text:hisax_init_pcmcia() The function sedlbauer_config() references the function __devinit hisax_init_pcmcia(). This is often because sedlbauer_config lacks a __devinit annotation or the annotation of hisax_init_pcmcia is wrong. Signed-off-by: Henrik Kretzschmar Acked-by: Karsten Keil Signed-off-by: David S. Miller diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c index 7836ec3..71b3dde 100644 --- a/drivers/isdn/hisax/sedlbauer_cs.c +++ b/drivers/isdn/hisax/sedlbauer_cs.c @@ -76,7 +76,7 @@ module_param(protocol, int, 0); event handler. */ -static int sedlbauer_config(struct pcmcia_device *link); +static int sedlbauer_config(struct pcmcia_device *link) __devinit ; static void sedlbauer_release(struct pcmcia_device *link); /* @@ -85,7 +85,7 @@ static void sedlbauer_release(struct pcmcia_device *link); needed to manage one actual PCMCIA card. */ -static void sedlbauer_detach(struct pcmcia_device *p_dev); +static void sedlbauer_detach(struct pcmcia_device *p_dev) __devexit; /* You'll also need to prototype all the functions that will actually @@ -129,7 +129,7 @@ typedef struct local_info_t { ======================================================================*/ -static int sedlbauer_probe(struct pcmcia_device *link) +static int __devinit sedlbauer_probe(struct pcmcia_device *link) { local_info_t *local; @@ -177,7 +177,7 @@ static int sedlbauer_probe(struct pcmcia_device *link) ======================================================================*/ -static void sedlbauer_detach(struct pcmcia_device *link) +static void __devexit sedlbauer_detach(struct pcmcia_device *link) { dev_dbg(&link->dev, "sedlbauer_detach(0x%p)\n", link); @@ -283,7 +283,7 @@ static int sedlbauer_config_check(struct pcmcia_device *p_dev, -static int sedlbauer_config(struct pcmcia_device *link) +static int __devinit sedlbauer_config(struct pcmcia_device *link) { local_info_t *dev = link->priv; win_req_t *req; @@ -441,7 +441,7 @@ static struct pcmcia_driver sedlbauer_driver = { .name = "sedlbauer_cs", }, .probe = sedlbauer_probe, - .remove = sedlbauer_detach, + .remove = __devexit_p(sedlbauer_detach), .id_table = sedlbauer_ids, .suspend = sedlbauer_suspend, .resume = sedlbauer_resume, -- cgit v0.10.2 From 158e33d1c6d0c6bacf577bcb47591aa4293dfcb1 Mon Sep 17 00:00:00 2001 From: Henne Date: Thu, 25 Mar 2010 12:05:30 +0000 Subject: isdn: Cleanup Sections in PCMCIA driver teles Compiling this driver gave a section mismatch, so I reviewed the init/exit paths of the driver and made the correct changes. WARNING: drivers/isdn/hisax/built-in.o(.text+0x56bfb): Section mismatch in reference from the function teles_cs_config() to the function .devinit.text:hisax_init_pcmcia() The function teles_cs_config() references the function __devinit hisax_init_pcmcia(). This is often because teles_cs_config lacks a __devinit annotation or the annotation of hisax_init_pcmcia is wrong. Signed-off-by: Henrik Kretzschmar Acked-by: Karsten Keil Signed-off-by: David S. Miller diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c index b0c5976..d010a0d 100644 --- a/drivers/isdn/hisax/teles_cs.c +++ b/drivers/isdn/hisax/teles_cs.c @@ -57,7 +57,7 @@ module_param(protocol, int, 0); handler. */ -static int teles_cs_config(struct pcmcia_device *link); +static int teles_cs_config(struct pcmcia_device *link) __devinit ; static void teles_cs_release(struct pcmcia_device *link); /* @@ -66,7 +66,7 @@ static void teles_cs_release(struct pcmcia_device *link); needed to manage one actual PCMCIA card. */ -static void teles_detach(struct pcmcia_device *p_dev); +static void teles_detach(struct pcmcia_device *p_dev) __devexit ; /* A linked list of "instances" of the teles_cs device. Each actual @@ -112,7 +112,7 @@ typedef struct local_info_t { ======================================================================*/ -static int teles_probe(struct pcmcia_device *link) +static int __devinit teles_probe(struct pcmcia_device *link) { local_info_t *local; @@ -156,7 +156,7 @@ static int teles_probe(struct pcmcia_device *link) ======================================================================*/ -static void teles_detach(struct pcmcia_device *link) +static void __devexit teles_detach(struct pcmcia_device *link) { local_info_t *info = link->priv; @@ -200,7 +200,7 @@ static int teles_cs_configcheck(struct pcmcia_device *p_dev, return -ENODEV; } -static int teles_cs_config(struct pcmcia_device *link) +static int __devinit teles_cs_config(struct pcmcia_device *link) { local_info_t *dev; int i; @@ -319,7 +319,7 @@ static struct pcmcia_driver teles_cs_driver = { .name = "teles_cs", }, .probe = teles_probe, - .remove = teles_detach, + .remove = __devexit_p(teles_detach), .id_table = teles_ids, .suspend = teles_suspend, .resume = teles_resume, -- cgit v0.10.2 From a465870a808bccba63bf6da30a0b56a2a7abfa5c Mon Sep 17 00:00:00 2001 From: Henne Date: Thu, 25 Mar 2010 12:05:31 +0000 Subject: isdn: Cleanup Sections in PCMCIA driver avma1 Compiling this driver gave a section mismatch, so I reviewed the init/exit paths of the driver and made the correct changes. WARNING: drivers/isdn/hisax/built-in.o(.text+0x56512): Section mismatch in reference from the function avma1cs_config() to the function .devinit.text:hisax_init_pcmcia() The function avma1cs_config() references the function __devinit hisax_init_pcmcia(). This is often because avma1cs_config lacks a __devinit annotation or the annotation of hisax_init_pcmcia is wrong. Signed-off-by: Henrik Kretzschmar Acked-by: Karsten Keil Signed-off-by: David S. Miller diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c index e5deb15..8d1d63a 100644 --- a/drivers/isdn/hisax/avma1_cs.c +++ b/drivers/isdn/hisax/avma1_cs.c @@ -50,7 +50,7 @@ module_param(isdnprot, int, 0); handler. */ -static int avma1cs_config(struct pcmcia_device *link); +static int avma1cs_config(struct pcmcia_device *link) __devinit ; static void avma1cs_release(struct pcmcia_device *link); /* @@ -59,7 +59,7 @@ static void avma1cs_release(struct pcmcia_device *link); needed to manage one actual PCMCIA card. */ -static void avma1cs_detach(struct pcmcia_device *p_dev); +static void avma1cs_detach(struct pcmcia_device *p_dev) __devexit ; /* @@ -99,7 +99,7 @@ typedef struct local_info_t { ======================================================================*/ -static int avma1cs_probe(struct pcmcia_device *p_dev) +static int __devinit avma1cs_probe(struct pcmcia_device *p_dev) { local_info_t *local; @@ -140,7 +140,7 @@ static int avma1cs_probe(struct pcmcia_device *p_dev) ======================================================================*/ -static void avma1cs_detach(struct pcmcia_device *link) +static void __devexit avma1cs_detach(struct pcmcia_device *link) { dev_dbg(&link->dev, "avma1cs_detach(0x%p)\n", link); avma1cs_release(link); @@ -174,7 +174,7 @@ static int avma1cs_configcheck(struct pcmcia_device *p_dev, } -static int avma1cs_config(struct pcmcia_device *link) +static int __devinit avma1cs_config(struct pcmcia_device *link) { local_info_t *dev; int i; @@ -282,7 +282,7 @@ static struct pcmcia_driver avma1cs_driver = { .name = "avma1_cs", }, .probe = avma1cs_probe, - .remove = avma1cs_detach, + .remove = __devexit_p(avma1cs_detach), .id_table = avma1cs_ids, }; -- cgit v0.10.2 From f61bb62e3ed7634fe5b7dfd8c9a52e6b799f4023 Mon Sep 17 00:00:00 2001 From: Henne Date: Thu, 25 Mar 2010 12:05:32 +0000 Subject: isdn: Cleanup Sections in PCMCIA driver elsa Compiling this driver gave a section mismatch, so I reviewed the init/exit paths of the driver and made the correct changes. WARNING: drivers/isdn/hisax/built-in.o(.text+0x55e37): Section mismatch in reference from the function elsa_cs_config() to the function .devinit.text:hisax_init_pcmcia() The function elsa_cs_config() references the function __devinit hisax_init_pcmcia(). This is often because elsa_cs_config lacks a __devinit annotation or the annotation of hisax_init_pcmcia is wrong. Signed-off-by: Henrik Kretzschmar Acked-by: Karsten Keil Signed-off-by: David S. Miller diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c index c9a30b1..c9f2279 100644 --- a/drivers/isdn/hisax/elsa_cs.c +++ b/drivers/isdn/hisax/elsa_cs.c @@ -76,7 +76,7 @@ module_param(protocol, int, 0); handler. */ -static int elsa_cs_config(struct pcmcia_device *link); +static int elsa_cs_config(struct pcmcia_device *link) __devinit ; static void elsa_cs_release(struct pcmcia_device *link); /* @@ -85,7 +85,7 @@ static void elsa_cs_release(struct pcmcia_device *link); needed to manage one actual PCMCIA card. */ -static void elsa_cs_detach(struct pcmcia_device *p_dev); +static void elsa_cs_detach(struct pcmcia_device *p_dev) __devexit; /* A driver needs to provide a dev_node_t structure for each device @@ -121,7 +121,7 @@ typedef struct local_info_t { ======================================================================*/ -static int elsa_cs_probe(struct pcmcia_device *link) +static int __devinit elsa_cs_probe(struct pcmcia_device *link) { local_info_t *local; @@ -166,7 +166,7 @@ static int elsa_cs_probe(struct pcmcia_device *link) ======================================================================*/ -static void elsa_cs_detach(struct pcmcia_device *link) +static void __devexit elsa_cs_detach(struct pcmcia_device *link) { local_info_t *info = link->priv; @@ -210,7 +210,7 @@ static int elsa_cs_configcheck(struct pcmcia_device *p_dev, return -ENODEV; } -static int elsa_cs_config(struct pcmcia_device *link) +static int __devinit elsa_cs_config(struct pcmcia_device *link) { local_info_t *dev; int i; @@ -327,7 +327,7 @@ static struct pcmcia_driver elsa_cs_driver = { .name = "elsa_cs", }, .probe = elsa_cs_probe, - .remove = elsa_cs_detach, + .remove = __devexit_p(elsa_cs_detach), .id_table = elsa_ids, .suspend = elsa_suspend, .resume = elsa_resume, -- cgit v0.10.2 From 21d40d37eca86872f2bf0af995809ebdef25c9d9 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 25 Mar 2010 11:11:14 -0700 Subject: drm/i915: Rename intel_output to intel_encoder. The intel_output naming is inherited from the UMS code, which had a structure of screen -> CRTC -> output. The DRM code has an additional notion of encoder/connector, so the structure is screen -> CRTC -> encoder -> connector. This is a useful structure for SDVO encoders which can support multiple connectors (each of which requires different programming in the one encoder and could be connected to different CRTCs), or for DVI-I, where multiple encoders feed into the connector for whether it's used for digital or analog. Most of our code is encoder-related, so transition it to talking about encoders before we start trying to distinguish connectors. This patch is produced by sed s/intel_output/intel_encoder/ over the driver. Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index bfbdad9..5b53adf 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -259,10 +259,10 @@ static void i915_hotplug_work_func(struct work_struct *work) if (mode_config->num_connector) { list_for_each_entry(connector, &mode_config->connector_list, head) { - struct intel_output *intel_output = to_intel_output(connector); + struct intel_encoder *intel_encoder = to_intel_encoder(connector); - if (intel_output->hot_plug) - (*intel_output->hot_plug) (intel_output); + if (intel_encoder->hot_plug) + (*intel_encoder->hot_plug) (intel_encoder); } } /* Just fire off a uevent and let userspace tell us what to do */ diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index fccf074..36c4ad7 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -246,19 +246,19 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) static bool intel_crt_detect_ddc(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); + struct intel_encoder *intel_encoder = to_intel_encoder(connector); /* CRT should always be at 0, but check anyway */ - if (intel_output->type != INTEL_OUTPUT_ANALOG) + if (intel_encoder->type != INTEL_OUTPUT_ANALOG) return false; - return intel_ddc_probe(intel_output); + return intel_ddc_probe(intel_encoder); } static enum drm_connector_status -intel_crt_load_detect(struct drm_crtc *crtc, struct intel_output *intel_output) +intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder) { - struct drm_encoder *encoder = &intel_output->enc; + struct drm_encoder *encoder = &intel_encoder->enc; struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); @@ -386,8 +386,8 @@ intel_crt_load_detect(struct drm_crtc *crtc, struct intel_output *intel_output) static enum drm_connector_status intel_crt_detect(struct drm_connector *connector) { struct drm_device *dev = connector->dev; - struct intel_output *intel_output = to_intel_output(connector); - struct drm_encoder *encoder = &intel_output->enc; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct drm_encoder *encoder = &intel_encoder->enc; struct drm_crtc *crtc; int dpms_mode; enum drm_connector_status status; @@ -404,13 +404,13 @@ static enum drm_connector_status intel_crt_detect(struct drm_connector *connecto /* for pre-945g platforms use load detect */ if (encoder->crtc && encoder->crtc->enabled) { - status = intel_crt_load_detect(encoder->crtc, intel_output); + status = intel_crt_load_detect(encoder->crtc, intel_encoder); } else { - crtc = intel_get_load_detect_pipe(intel_output, + crtc = intel_get_load_detect_pipe(intel_encoder, NULL, &dpms_mode); if (crtc) { - status = intel_crt_load_detect(crtc, intel_output); - intel_release_load_detect_pipe(intel_output, dpms_mode); + status = intel_crt_load_detect(crtc, intel_encoder); + intel_release_load_detect_pipe(intel_encoder, dpms_mode); } else status = connector_status_unknown; } @@ -420,9 +420,9 @@ static enum drm_connector_status intel_crt_detect(struct drm_connector *connecto static void intel_crt_destroy(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); + struct intel_encoder *intel_encoder = to_intel_encoder(connector); - intel_i2c_destroy(intel_output->ddc_bus); + intel_i2c_destroy(intel_encoder->ddc_bus); drm_sysfs_connector_remove(connector); drm_connector_cleanup(connector); kfree(connector); @@ -431,28 +431,28 @@ static void intel_crt_destroy(struct drm_connector *connector) static int intel_crt_get_modes(struct drm_connector *connector) { int ret; - struct intel_output *intel_output = to_intel_output(connector); + struct intel_encoder *intel_encoder = to_intel_encoder(connector); struct i2c_adapter *ddcbus; struct drm_device *dev = connector->dev; - ret = intel_ddc_get_modes(intel_output); + ret = intel_ddc_get_modes(intel_encoder); if (ret || !IS_G4X(dev)) goto end; - ddcbus = intel_output->ddc_bus; + ddcbus = intel_encoder->ddc_bus; /* Try to probe digital port for output in DVI-I -> VGA mode. */ - intel_output->ddc_bus = + intel_encoder->ddc_bus = intel_i2c_create(connector->dev, GPIOD, "CRTDDC_D"); - if (!intel_output->ddc_bus) { - intel_output->ddc_bus = ddcbus; + if (!intel_encoder->ddc_bus) { + intel_encoder->ddc_bus = ddcbus; dev_printk(KERN_ERR, &connector->dev->pdev->dev, "DDC bus registration failed for CRTDDC_D.\n"); goto end; } /* Try to get modes by GPIOD port */ - ret = intel_ddc_get_modes(intel_output); + ret = intel_ddc_get_modes(intel_encoder); intel_i2c_destroy(ddcbus); end: @@ -505,23 +505,23 @@ static const struct drm_encoder_funcs intel_crt_enc_funcs = { void intel_crt_init(struct drm_device *dev) { struct drm_connector *connector; - struct intel_output *intel_output; + struct intel_encoder *intel_encoder; struct drm_i915_private *dev_priv = dev->dev_private; u32 i2c_reg; - intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL); - if (!intel_output) + intel_encoder = kzalloc(sizeof(struct intel_encoder), GFP_KERNEL); + if (!intel_encoder) return; - connector = &intel_output->base; - drm_connector_init(dev, &intel_output->base, + connector = &intel_encoder->base; + drm_connector_init(dev, &intel_encoder->base, &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA); - drm_encoder_init(dev, &intel_output->enc, &intel_crt_enc_funcs, + drm_encoder_init(dev, &intel_encoder->enc, &intel_crt_enc_funcs, DRM_MODE_ENCODER_DAC); - drm_mode_connector_attach_encoder(&intel_output->base, - &intel_output->enc); + drm_mode_connector_attach_encoder(&intel_encoder->base, + &intel_encoder->enc); /* Set up the DDC bus. */ if (HAS_PCH_SPLIT(dev)) @@ -532,22 +532,22 @@ void intel_crt_init(struct drm_device *dev) if (dev_priv->crt_ddc_bus != 0) i2c_reg = dev_priv->crt_ddc_bus; } - intel_output->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A"); - if (!intel_output->ddc_bus) { + intel_encoder->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A"); + if (!intel_encoder->ddc_bus) { dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " "failed.\n"); return; } - intel_output->type = INTEL_OUTPUT_ANALOG; - intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | + intel_encoder->type = INTEL_OUTPUT_ANALOG; + intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | (1 << INTEL_ANALOG_CLONE_BIT) | (1 << INTEL_SDVO_LVDS_CLONE_BIT); - intel_output->crtc_mask = (1 << 0) | (1 << 1); + intel_encoder->crtc_mask = (1 << 0) | (1 << 1); connector->interlace_allowed = 0; connector->doublescan_allowed = 0; - drm_encoder_helper_add(&intel_output->enc, &intel_crt_helper_funcs); + drm_encoder_helper_add(&intel_encoder->enc, &intel_crt_helper_funcs); drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs); drm_sysfs_connector_add(connector); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 7adb3a5..2595c4c 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -746,8 +746,8 @@ bool intel_pipe_has_type (struct drm_crtc *crtc, int type) list_for_each_entry(l_entry, &mode_config->connector_list, head) { if (l_entry->encoder && l_entry->encoder->crtc == crtc) { - struct intel_output *intel_output = to_intel_output(l_entry); - if (intel_output->type == type) + struct intel_encoder *intel_encoder = to_intel_encoder(l_entry); + if (intel_encoder->type == type) return true; } } @@ -2942,19 +2942,19 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, drm_vblank_pre_modeset(dev, pipe); list_for_each_entry(connector, &mode_config->connector_list, head) { - struct intel_output *intel_output = to_intel_output(connector); + struct intel_encoder *intel_encoder = to_intel_encoder(connector); if (!connector->encoder || connector->encoder->crtc != crtc) continue; - switch (intel_output->type) { + switch (intel_encoder->type) { case INTEL_OUTPUT_LVDS: is_lvds = true; break; case INTEL_OUTPUT_SDVO: case INTEL_OUTPUT_HDMI: is_sdvo = true; - if (intel_output->needs_tv_clock) + if (intel_encoder->needs_tv_clock) is_tv = true; break; case INTEL_OUTPUT_DVO: @@ -3049,7 +3049,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, struct drm_connector *edp; target_clock = mode->clock; edp = intel_pipe_get_output(crtc); - intel_edp_link_config(to_intel_output(edp), + intel_edp_link_config(to_intel_encoder(edp), &lane, &link_bw); } else { /* DP over FDI requires target mode clock @@ -3669,14 +3669,14 @@ static struct drm_display_mode load_detect_mode = { 704, 832, 0, 480, 489, 491, 520, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), }; -struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output, +struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, struct drm_display_mode *mode, int *dpms_mode) { struct intel_crtc *intel_crtc; struct drm_crtc *possible_crtc; struct drm_crtc *supported_crtc =NULL; - struct drm_encoder *encoder = &intel_output->enc; + struct drm_encoder *encoder = &intel_encoder->enc; struct drm_crtc *crtc = NULL; struct drm_device *dev = encoder->dev; struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; @@ -3728,8 +3728,8 @@ struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output, } encoder->crtc = crtc; - intel_output->base.encoder = encoder; - intel_output->load_detect_temp = true; + intel_encoder->base.encoder = encoder; + intel_encoder->load_detect_temp = true; intel_crtc = to_intel_crtc(crtc); *dpms_mode = intel_crtc->dpms_mode; @@ -3754,18 +3754,18 @@ struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output, return crtc; } -void intel_release_load_detect_pipe(struct intel_output *intel_output, int dpms_mode) +void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder, int dpms_mode) { - struct drm_encoder *encoder = &intel_output->enc; + struct drm_encoder *encoder = &intel_encoder->enc; struct drm_device *dev = encoder->dev; struct drm_crtc *crtc = encoder->crtc; struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; - if (intel_output->load_detect_temp) { + if (intel_encoder->load_detect_temp) { encoder->crtc = NULL; - intel_output->base.encoder = NULL; - intel_output->load_detect_temp = false; + intel_encoder->base.encoder = NULL; + intel_encoder->load_detect_temp = false; crtc->enabled = drm_helper_crtc_in_use(crtc); drm_helper_disable_unused_functions(dev); } @@ -4398,8 +4398,8 @@ static int intel_connector_clones(struct drm_device *dev, int type_mask) int entry = 0; list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - struct intel_output *intel_output = to_intel_output(connector); - if (type_mask & intel_output->clone_mask) + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + if (type_mask & intel_encoder->clone_mask) index_mask |= (1 << entry); entry++; } @@ -4494,12 +4494,12 @@ static void intel_setup_outputs(struct drm_device *dev) intel_tv_init(dev); list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - struct intel_output *intel_output = to_intel_output(connector); - struct drm_encoder *encoder = &intel_output->enc; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct drm_encoder *encoder = &intel_encoder->enc; - encoder->possible_crtcs = intel_output->crtc_mask; + encoder->possible_crtcs = intel_encoder->crtc_mask; encoder->possible_clones = intel_connector_clones(dev, - intel_output->clone_mask); + intel_encoder->clone_mask); } } @@ -4977,9 +4977,9 @@ void intel_modeset_cleanup(struct drm_device *dev) */ struct drm_encoder *intel_best_encoder(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); + struct intel_encoder *intel_encoder = to_intel_encoder(connector); - return &intel_output->enc; + return &intel_encoder->enc; } /* diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 3ef3a0d..0a7e326 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -54,23 +54,23 @@ struct intel_dp_priv { uint8_t link_bw; uint8_t lane_count; uint8_t dpcd[4]; - struct intel_output *intel_output; + struct intel_encoder *intel_encoder; struct i2c_adapter adapter; struct i2c_algo_dp_aux_data algo; }; static void -intel_dp_link_train(struct intel_output *intel_output, uint32_t DP, +intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP, uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]); static void -intel_dp_link_down(struct intel_output *intel_output, uint32_t DP); +intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP); void -intel_edp_link_config (struct intel_output *intel_output, +intel_edp_link_config (struct intel_encoder *intel_encoder, int *lane_num, int *link_bw) { - struct intel_dp_priv *dp_priv = intel_output->dev_priv; + struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; *lane_num = dp_priv->lane_count; if (dp_priv->link_bw == DP_LINK_BW_1_62) @@ -80,9 +80,9 @@ intel_edp_link_config (struct intel_output *intel_output, } static int -intel_dp_max_lane_count(struct intel_output *intel_output) +intel_dp_max_lane_count(struct intel_encoder *intel_encoder) { - struct intel_dp_priv *dp_priv = intel_output->dev_priv; + struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; int max_lane_count = 4; if (dp_priv->dpcd[0] >= 0x11) { @@ -98,9 +98,9 @@ intel_dp_max_lane_count(struct intel_output *intel_output) } static int -intel_dp_max_link_bw(struct intel_output *intel_output) +intel_dp_max_link_bw(struct intel_encoder *intel_encoder) { - struct intel_dp_priv *dp_priv = intel_output->dev_priv; + struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; int max_link_bw = dp_priv->dpcd[1]; switch (max_link_bw) { @@ -126,11 +126,11 @@ intel_dp_link_clock(uint8_t link_bw) /* I think this is a fiction */ static int intel_dp_link_required(struct drm_device *dev, - struct intel_output *intel_output, int pixel_clock) + struct intel_encoder *intel_encoder, int pixel_clock) { struct drm_i915_private *dev_priv = dev->dev_private; - if (IS_eDP(intel_output)) + if (IS_eDP(intel_encoder)) return (pixel_clock * dev_priv->edp_bpp) / 8; else return pixel_clock * 3; @@ -140,11 +140,11 @@ static int intel_dp_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { - struct intel_output *intel_output = to_intel_output(connector); - int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_output)); - int max_lanes = intel_dp_max_lane_count(intel_output); + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_encoder)); + int max_lanes = intel_dp_max_lane_count(intel_encoder); - if (intel_dp_link_required(connector->dev, intel_output, mode->clock) + if (intel_dp_link_required(connector->dev, intel_encoder, mode->clock) > max_link_clock * max_lanes) return MODE_CLOCK_HIGH; @@ -208,13 +208,13 @@ intel_hrawclk(struct drm_device *dev) } static int -intel_dp_aux_ch(struct intel_output *intel_output, +intel_dp_aux_ch(struct intel_encoder *intel_encoder, uint8_t *send, int send_bytes, uint8_t *recv, int recv_size) { - struct intel_dp_priv *dp_priv = intel_output->dev_priv; + struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; uint32_t output_reg = dp_priv->output_reg; - struct drm_device *dev = intel_output->base.dev; + struct drm_device *dev = intel_encoder->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; uint32_t ch_ctl = output_reg + 0x10; uint32_t ch_data = ch_ctl + 4; @@ -229,7 +229,7 @@ intel_dp_aux_ch(struct intel_output *intel_output, * and would like to run at 2MHz. So, take the * hrawclk value and divide by 2 and use that */ - if (IS_eDP(intel_output)) + if (IS_eDP(intel_encoder)) aux_clock_divider = 225; /* eDP input clock at 450Mhz */ else if (HAS_PCH_SPLIT(dev)) aux_clock_divider = 62; /* IRL input clock fixed at 125Mhz */ @@ -312,7 +312,7 @@ intel_dp_aux_ch(struct intel_output *intel_output, /* Write data to the aux channel in native mode */ static int -intel_dp_aux_native_write(struct intel_output *intel_output, +intel_dp_aux_native_write(struct intel_encoder *intel_encoder, uint16_t address, uint8_t *send, int send_bytes) { int ret; @@ -329,7 +329,7 @@ intel_dp_aux_native_write(struct intel_output *intel_output, memcpy(&msg[4], send, send_bytes); msg_bytes = send_bytes + 4; for (;;) { - ret = intel_dp_aux_ch(intel_output, msg, msg_bytes, &ack, 1); + ret = intel_dp_aux_ch(intel_encoder, msg, msg_bytes, &ack, 1); if (ret < 0) return ret; if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) @@ -344,15 +344,15 @@ intel_dp_aux_native_write(struct intel_output *intel_output, /* Write a single byte to the aux channel in native mode */ static int -intel_dp_aux_native_write_1(struct intel_output *intel_output, +intel_dp_aux_native_write_1(struct intel_encoder *intel_encoder, uint16_t address, uint8_t byte) { - return intel_dp_aux_native_write(intel_output, address, &byte, 1); + return intel_dp_aux_native_write(intel_encoder, address, &byte, 1); } /* read bytes from a native aux channel */ static int -intel_dp_aux_native_read(struct intel_output *intel_output, +intel_dp_aux_native_read(struct intel_encoder *intel_encoder, uint16_t address, uint8_t *recv, int recv_bytes) { uint8_t msg[4]; @@ -371,7 +371,7 @@ intel_dp_aux_native_read(struct intel_output *intel_output, reply_bytes = recv_bytes + 1; for (;;) { - ret = intel_dp_aux_ch(intel_output, msg, msg_bytes, + ret = intel_dp_aux_ch(intel_encoder, msg, msg_bytes, reply, reply_bytes); if (ret == 0) return -EPROTO; @@ -397,7 +397,7 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, struct intel_dp_priv *dp_priv = container_of(adapter, struct intel_dp_priv, adapter); - struct intel_output *intel_output = dp_priv->intel_output; + struct intel_encoder *intel_encoder = dp_priv->intel_encoder; uint16_t address = algo_data->address; uint8_t msg[5]; uint8_t reply[2]; @@ -436,7 +436,7 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, } for (;;) { - ret = intel_dp_aux_ch(intel_output, + ret = intel_dp_aux_ch(intel_encoder, msg, msg_bytes, reply, reply_bytes); if (ret < 0) { @@ -464,9 +464,9 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, } static int -intel_dp_i2c_init(struct intel_output *intel_output, const char *name) +intel_dp_i2c_init(struct intel_encoder *intel_encoder, const char *name) { - struct intel_dp_priv *dp_priv = intel_output->dev_priv; + struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; DRM_DEBUG_KMS("i2c_init %s\n", name); dp_priv->algo.running = false; @@ -479,7 +479,7 @@ intel_dp_i2c_init(struct intel_output *intel_output, const char *name) strncpy (dp_priv->adapter.name, name, sizeof(dp_priv->adapter.name) - 1); dp_priv->adapter.name[sizeof(dp_priv->adapter.name) - 1] = '\0'; dp_priv->adapter.algo_data = &dp_priv->algo; - dp_priv->adapter.dev.parent = &intel_output->base.kdev; + dp_priv->adapter.dev.parent = &intel_encoder->base.kdev; return i2c_dp_aux_add_bus(&dp_priv->adapter); } @@ -488,18 +488,18 @@ static bool intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { - struct intel_output *intel_output = enc_to_intel_output(encoder); - struct intel_dp_priv *dp_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); + struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; int lane_count, clock; - int max_lane_count = intel_dp_max_lane_count(intel_output); - int max_clock = intel_dp_max_link_bw(intel_output) == DP_LINK_BW_2_7 ? 1 : 0; + int max_lane_count = intel_dp_max_lane_count(intel_encoder); + int max_clock = intel_dp_max_link_bw(intel_encoder) == DP_LINK_BW_2_7 ? 1 : 0; static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { for (clock = 0; clock <= max_clock; clock++) { int link_avail = intel_dp_link_clock(bws[clock]) * lane_count; - if (intel_dp_link_required(encoder->dev, intel_output, mode->clock) + if (intel_dp_link_required(encoder->dev, intel_encoder, mode->clock) <= link_avail) { dp_priv->link_bw = bws[clock]; dp_priv->lane_count = lane_count; @@ -561,16 +561,16 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, struct intel_dp_m_n m_n; /* - * Find the lane count in the intel_output private + * Find the lane count in the intel_encoder private */ list_for_each_entry(connector, &mode_config->connector_list, head) { - struct intel_output *intel_output = to_intel_output(connector); - struct intel_dp_priv *dp_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; if (!connector->encoder || connector->encoder->crtc != crtc) continue; - if (intel_output->type == INTEL_OUTPUT_DISPLAYPORT) { + if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) { lane_count = dp_priv->lane_count; break; } @@ -625,9 +625,9 @@ static void intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { - struct intel_output *intel_output = enc_to_intel_output(encoder); - struct intel_dp_priv *dp_priv = intel_output->dev_priv; - struct drm_crtc *crtc = intel_output->enc.crtc; + struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); + struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; + struct drm_crtc *crtc = intel_encoder->enc.crtc; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); dp_priv->DP = (DP_LINK_TRAIN_OFF | @@ -666,7 +666,7 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, if (intel_crtc->pipe == 1) dp_priv->DP |= DP_PIPEB_SELECT; - if (IS_eDP(intel_output)) { + if (IS_eDP(intel_encoder)) { /* don't miss out required setting for eDP */ dp_priv->DP |= DP_PLL_ENABLE; if (adjusted_mode->clock < 200000) @@ -701,22 +701,22 @@ static void ironlake_edp_backlight_off (struct drm_device *dev) static void intel_dp_dpms(struct drm_encoder *encoder, int mode) { - struct intel_output *intel_output = enc_to_intel_output(encoder); - struct intel_dp_priv *dp_priv = intel_output->dev_priv; - struct drm_device *dev = intel_output->base.dev; + struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); + struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; + struct drm_device *dev = intel_encoder->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; uint32_t dp_reg = I915_READ(dp_priv->output_reg); if (mode != DRM_MODE_DPMS_ON) { if (dp_reg & DP_PORT_EN) { - intel_dp_link_down(intel_output, dp_priv->DP); - if (IS_eDP(intel_output)) + intel_dp_link_down(intel_encoder, dp_priv->DP); + if (IS_eDP(intel_encoder)) ironlake_edp_backlight_off(dev); } } else { if (!(dp_reg & DP_PORT_EN)) { - intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration); - if (IS_eDP(intel_output)) + intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration); + if (IS_eDP(intel_encoder)) ironlake_edp_backlight_on(dev); } } @@ -728,12 +728,12 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) * link status information */ static bool -intel_dp_get_link_status(struct intel_output *intel_output, +intel_dp_get_link_status(struct intel_encoder *intel_encoder, uint8_t link_status[DP_LINK_STATUS_SIZE]) { int ret; - ret = intel_dp_aux_native_read(intel_output, + ret = intel_dp_aux_native_read(intel_encoder, DP_LANE0_1_STATUS, link_status, DP_LINK_STATUS_SIZE); if (ret != DP_LINK_STATUS_SIZE) @@ -751,13 +751,13 @@ intel_dp_link_status(uint8_t link_status[DP_LINK_STATUS_SIZE], static void intel_dp_save(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); - struct drm_device *dev = intel_output->base.dev; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct drm_device *dev = intel_encoder->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_dp_priv *dp_priv = intel_output->dev_priv; + struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; dp_priv->save_DP = I915_READ(dp_priv->output_reg); - intel_dp_aux_native_read(intel_output, DP_LINK_BW_SET, + intel_dp_aux_native_read(intel_encoder, DP_LINK_BW_SET, dp_priv->save_link_configuration, sizeof (dp_priv->save_link_configuration)); } @@ -824,7 +824,7 @@ intel_dp_pre_emphasis_max(uint8_t voltage_swing) } static void -intel_get_adjust_train(struct intel_output *intel_output, +intel_get_adjust_train(struct intel_encoder *intel_encoder, uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count, uint8_t train_set[4]) @@ -941,15 +941,15 @@ intel_channel_eq_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count) } static bool -intel_dp_set_link_train(struct intel_output *intel_output, +intel_dp_set_link_train(struct intel_encoder *intel_encoder, uint32_t dp_reg_value, uint8_t dp_train_pat, uint8_t train_set[4], bool first) { - struct drm_device *dev = intel_output->base.dev; + struct drm_device *dev = intel_encoder->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_dp_priv *dp_priv = intel_output->dev_priv; + struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; int ret; I915_WRITE(dp_priv->output_reg, dp_reg_value); @@ -957,11 +957,11 @@ intel_dp_set_link_train(struct intel_output *intel_output, if (first) intel_wait_for_vblank(dev); - intel_dp_aux_native_write_1(intel_output, + intel_dp_aux_native_write_1(intel_encoder, DP_TRAINING_PATTERN_SET, dp_train_pat); - ret = intel_dp_aux_native_write(intel_output, + ret = intel_dp_aux_native_write(intel_encoder, DP_TRAINING_LANE0_SET, train_set, 4); if (ret != 4) return false; @@ -970,12 +970,12 @@ intel_dp_set_link_train(struct intel_output *intel_output, } static void -intel_dp_link_train(struct intel_output *intel_output, uint32_t DP, +intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP, uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]) { - struct drm_device *dev = intel_output->base.dev; + struct drm_device *dev = intel_encoder->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_dp_priv *dp_priv = intel_output->dev_priv; + struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; uint8_t train_set[4]; uint8_t link_status[DP_LINK_STATUS_SIZE]; int i; @@ -986,7 +986,7 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP, int tries; /* Write the link configuration data */ - intel_dp_aux_native_write(intel_output, 0x100, + intel_dp_aux_native_write(intel_encoder, 0x100, link_configuration, DP_LINK_CONFIGURATION_SIZE); DP |= DP_PORT_EN; @@ -1000,14 +1000,14 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP, uint32_t signal_levels = intel_dp_signal_levels(train_set[0], dp_priv->lane_count); DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; - if (!intel_dp_set_link_train(intel_output, DP | DP_LINK_TRAIN_PAT_1, + if (!intel_dp_set_link_train(intel_encoder, DP | DP_LINK_TRAIN_PAT_1, DP_TRAINING_PATTERN_1, train_set, first)) break; first = false; /* Set training pattern 1 */ udelay(100); - if (!intel_dp_get_link_status(intel_output, link_status)) + if (!intel_dp_get_link_status(intel_encoder, link_status)) break; if (intel_clock_recovery_ok(link_status, dp_priv->lane_count)) { @@ -1032,7 +1032,7 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP, voltage = train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; /* Compute new train_set as requested by target */ - intel_get_adjust_train(intel_output, link_status, dp_priv->lane_count, train_set); + intel_get_adjust_train(intel_encoder, link_status, dp_priv->lane_count, train_set); } /* channel equalization */ @@ -1044,13 +1044,13 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP, DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; /* channel eq pattern */ - if (!intel_dp_set_link_train(intel_output, DP | DP_LINK_TRAIN_PAT_2, + if (!intel_dp_set_link_train(intel_encoder, DP | DP_LINK_TRAIN_PAT_2, DP_TRAINING_PATTERN_2, train_set, false)) break; udelay(400); - if (!intel_dp_get_link_status(intel_output, link_status)) + if (!intel_dp_get_link_status(intel_encoder, link_status)) break; if (intel_channel_eq_ok(link_status, dp_priv->lane_count)) { @@ -1063,26 +1063,26 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP, break; /* Compute new train_set as requested by target */ - intel_get_adjust_train(intel_output, link_status, dp_priv->lane_count, train_set); + intel_get_adjust_train(intel_encoder, link_status, dp_priv->lane_count, train_set); ++tries; } I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_OFF); POSTING_READ(dp_priv->output_reg); - intel_dp_aux_native_write_1(intel_output, + intel_dp_aux_native_write_1(intel_encoder, DP_TRAINING_PATTERN_SET, DP_TRAINING_PATTERN_DISABLE); } static void -intel_dp_link_down(struct intel_output *intel_output, uint32_t DP) +intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP) { - struct drm_device *dev = intel_output->base.dev; + struct drm_device *dev = intel_encoder->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_dp_priv *dp_priv = intel_output->dev_priv; + struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; DRM_DEBUG_KMS("\n"); - if (IS_eDP(intel_output)) { + if (IS_eDP(intel_encoder)) { DP &= ~DP_PLL_ENABLE; I915_WRITE(dp_priv->output_reg, DP); POSTING_READ(dp_priv->output_reg); @@ -1095,7 +1095,7 @@ intel_dp_link_down(struct intel_output *intel_output, uint32_t DP) udelay(17000); - if (IS_eDP(intel_output)) + if (IS_eDP(intel_encoder)) DP |= DP_LINK_TRAIN_OFF; I915_WRITE(dp_priv->output_reg, DP & ~DP_PORT_EN); POSTING_READ(dp_priv->output_reg); @@ -1104,13 +1104,13 @@ intel_dp_link_down(struct intel_output *intel_output, uint32_t DP) static void intel_dp_restore(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); - struct intel_dp_priv *dp_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; if (dp_priv->save_DP & DP_PORT_EN) - intel_dp_link_train(intel_output, dp_priv->save_DP, dp_priv->save_link_configuration); + intel_dp_link_train(intel_encoder, dp_priv->save_DP, dp_priv->save_link_configuration); else - intel_dp_link_down(intel_output, dp_priv->save_DP); + intel_dp_link_down(intel_encoder, dp_priv->save_DP); } /* @@ -1123,32 +1123,32 @@ intel_dp_restore(struct drm_connector *connector) */ static void -intel_dp_check_link_status(struct intel_output *intel_output) +intel_dp_check_link_status(struct intel_encoder *intel_encoder) { - struct intel_dp_priv *dp_priv = intel_output->dev_priv; + struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; uint8_t link_status[DP_LINK_STATUS_SIZE]; - if (!intel_output->enc.crtc) + if (!intel_encoder->enc.crtc) return; - if (!intel_dp_get_link_status(intel_output, link_status)) { - intel_dp_link_down(intel_output, dp_priv->DP); + if (!intel_dp_get_link_status(intel_encoder, link_status)) { + intel_dp_link_down(intel_encoder, dp_priv->DP); return; } if (!intel_channel_eq_ok(link_status, dp_priv->lane_count)) - intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration); + intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration); } static enum drm_connector_status ironlake_dp_detect(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); - struct intel_dp_priv *dp_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; enum drm_connector_status status; status = connector_status_disconnected; - if (intel_dp_aux_native_read(intel_output, + if (intel_dp_aux_native_read(intel_encoder, 0x000, dp_priv->dpcd, sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd)) { @@ -1167,10 +1167,10 @@ ironlake_dp_detect(struct drm_connector *connector) static enum drm_connector_status intel_dp_detect(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); - struct drm_device *dev = intel_output->base.dev; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct drm_device *dev = intel_encoder->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_dp_priv *dp_priv = intel_output->dev_priv; + struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; uint32_t temp, bit; enum drm_connector_status status; @@ -1209,7 +1209,7 @@ intel_dp_detect(struct drm_connector *connector) return connector_status_disconnected; status = connector_status_disconnected; - if (intel_dp_aux_native_read(intel_output, + if (intel_dp_aux_native_read(intel_encoder, 0x000, dp_priv->dpcd, sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd)) { @@ -1221,20 +1221,20 @@ intel_dp_detect(struct drm_connector *connector) static int intel_dp_get_modes(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); - struct drm_device *dev = intel_output->base.dev; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct drm_device *dev = intel_encoder->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; int ret; /* We should parse the EDID data and find out if it has an audio sink */ - ret = intel_ddc_get_modes(intel_output); + ret = intel_ddc_get_modes(intel_encoder); if (ret) return ret; /* if eDP has no EDID, try to use fixed panel mode from VBT */ - if (IS_eDP(intel_output)) { + if (IS_eDP(intel_encoder)) { if (dev_priv->panel_fixed_mode != NULL) { struct drm_display_mode *mode; mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode); @@ -1248,13 +1248,13 @@ static int intel_dp_get_modes(struct drm_connector *connector) static void intel_dp_destroy (struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); + struct intel_encoder *intel_encoder = to_intel_encoder(connector); - if (intel_output->i2c_bus) - intel_i2c_destroy(intel_output->i2c_bus); + if (intel_encoder->i2c_bus) + intel_i2c_destroy(intel_encoder->i2c_bus); drm_sysfs_connector_remove(connector); drm_connector_cleanup(connector); - kfree(intel_output); + kfree(intel_encoder); } static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = { @@ -1290,12 +1290,12 @@ static const struct drm_encoder_funcs intel_dp_enc_funcs = { }; void -intel_dp_hot_plug(struct intel_output *intel_output) +intel_dp_hot_plug(struct intel_encoder *intel_encoder) { - struct intel_dp_priv *dp_priv = intel_output->dev_priv; + struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; if (dp_priv->dpms_mode == DRM_MODE_DPMS_ON) - intel_dp_check_link_status(intel_output); + intel_dp_check_link_status(intel_encoder); } void @@ -1303,53 +1303,53 @@ intel_dp_init(struct drm_device *dev, int output_reg) { struct drm_i915_private *dev_priv = dev->dev_private; struct drm_connector *connector; - struct intel_output *intel_output; + struct intel_encoder *intel_encoder; struct intel_dp_priv *dp_priv; const char *name = NULL; - intel_output = kcalloc(sizeof(struct intel_output) + + intel_encoder = kcalloc(sizeof(struct intel_encoder) + sizeof(struct intel_dp_priv), 1, GFP_KERNEL); - if (!intel_output) + if (!intel_encoder) return; - dp_priv = (struct intel_dp_priv *)(intel_output + 1); + dp_priv = (struct intel_dp_priv *)(intel_encoder + 1); - connector = &intel_output->base; + connector = &intel_encoder->base; drm_connector_init(dev, connector, &intel_dp_connector_funcs, DRM_MODE_CONNECTOR_DisplayPort); drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs); if (output_reg == DP_A) - intel_output->type = INTEL_OUTPUT_EDP; + intel_encoder->type = INTEL_OUTPUT_EDP; else - intel_output->type = INTEL_OUTPUT_DISPLAYPORT; + intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT; if (output_reg == DP_B || output_reg == PCH_DP_B) - intel_output->clone_mask = (1 << INTEL_DP_B_CLONE_BIT); + intel_encoder->clone_mask = (1 << INTEL_DP_B_CLONE_BIT); else if (output_reg == DP_C || output_reg == PCH_DP_C) - intel_output->clone_mask = (1 << INTEL_DP_C_CLONE_BIT); + intel_encoder->clone_mask = (1 << INTEL_DP_C_CLONE_BIT); else if (output_reg == DP_D || output_reg == PCH_DP_D) - intel_output->clone_mask = (1 << INTEL_DP_D_CLONE_BIT); + intel_encoder->clone_mask = (1 << INTEL_DP_D_CLONE_BIT); - if (IS_eDP(intel_output)) - intel_output->clone_mask = (1 << INTEL_EDP_CLONE_BIT); + if (IS_eDP(intel_encoder)) + intel_encoder->clone_mask = (1 << INTEL_EDP_CLONE_BIT); - intel_output->crtc_mask = (1 << 0) | (1 << 1); + intel_encoder->crtc_mask = (1 << 0) | (1 << 1); connector->interlace_allowed = true; connector->doublescan_allowed = 0; - dp_priv->intel_output = intel_output; + dp_priv->intel_encoder = intel_encoder; dp_priv->output_reg = output_reg; dp_priv->has_audio = false; dp_priv->dpms_mode = DRM_MODE_DPMS_ON; - intel_output->dev_priv = dp_priv; + intel_encoder->dev_priv = dp_priv; - drm_encoder_init(dev, &intel_output->enc, &intel_dp_enc_funcs, + drm_encoder_init(dev, &intel_encoder->enc, &intel_dp_enc_funcs, DRM_MODE_ENCODER_TMDS); - drm_encoder_helper_add(&intel_output->enc, &intel_dp_helper_funcs); + drm_encoder_helper_add(&intel_encoder->enc, &intel_dp_helper_funcs); - drm_mode_connector_attach_encoder(&intel_output->base, - &intel_output->enc); + drm_mode_connector_attach_encoder(&intel_encoder->base, + &intel_encoder->enc); drm_sysfs_connector_add(connector); /* Set up the DDC bus. */ @@ -1377,10 +1377,10 @@ intel_dp_init(struct drm_device *dev, int output_reg) break; } - intel_dp_i2c_init(intel_output, name); + intel_dp_i2c_init(intel_encoder, name); - intel_output->ddc_bus = &dp_priv->adapter; - intel_output->hot_plug = intel_dp_hot_plug; + intel_encoder->ddc_bus = &dp_priv->adapter; + intel_encoder->hot_plug = intel_dp_hot_plug; if (output_reg == DP_A) { /* initialize panel mode from VBT if available for eDP */ diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 3a467ca..e302537 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -95,7 +95,7 @@ struct intel_framebuffer { }; -struct intel_output { +struct intel_encoder { struct drm_connector base; struct drm_encoder enc; @@ -105,7 +105,7 @@ struct intel_output { bool load_detect_temp; bool needs_tv_clock; void *dev_priv; - void (*hot_plug)(struct intel_output *); + void (*hot_plug)(struct intel_encoder *); int crtc_mask; int clone_mask; }; @@ -152,15 +152,15 @@ struct intel_crtc { }; #define to_intel_crtc(x) container_of(x, struct intel_crtc, base) -#define to_intel_output(x) container_of(x, struct intel_output, base) -#define enc_to_intel_output(x) container_of(x, struct intel_output, enc) +#define to_intel_encoder(x) container_of(x, struct intel_encoder, base) +#define enc_to_intel_encoder(x) container_of(x, struct intel_encoder, enc) #define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base) struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg, const char *name); void intel_i2c_destroy(struct i2c_adapter *adapter); -int intel_ddc_get_modes(struct intel_output *intel_output); -extern bool intel_ddc_probe(struct intel_output *intel_output); +int intel_ddc_get_modes(struct intel_encoder *intel_encoder); +extern bool intel_ddc_probe(struct intel_encoder *intel_encoder); void intel_i2c_quirk_set(struct drm_device *dev, bool enable); void intel_i2c_reset_gmbus(struct drm_device *dev); @@ -175,7 +175,7 @@ extern void intel_dp_init(struct drm_device *dev, int dp_reg); void intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode); -extern void intel_edp_link_config (struct intel_output *, int *, int *); +extern void intel_edp_link_config (struct intel_encoder *, int *, int *); extern int intel_panel_fitter_pipe (struct drm_device *dev); @@ -191,10 +191,10 @@ int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, struct drm_file *file_priv); extern void intel_wait_for_vblank(struct drm_device *dev); extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe); -extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output, +extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, struct drm_display_mode *mode, int *dpms_mode); -extern void intel_release_load_detect_pipe(struct intel_output *intel_output, +extern void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder, int dpms_mode); extern struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB); diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index a4d2606..62282f3 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c @@ -79,8 +79,8 @@ static struct intel_dvo_device intel_dvo_devices[] = { static void intel_dvo_dpms(struct drm_encoder *encoder, int mode) { struct drm_i915_private *dev_priv = encoder->dev->dev_private; - struct intel_output *intel_output = enc_to_intel_output(encoder); - struct intel_dvo_device *dvo = intel_output->dev_priv; + struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); + struct intel_dvo_device *dvo = intel_encoder->dev_priv; u32 dvo_reg = dvo->dvo_reg; u32 temp = I915_READ(dvo_reg); @@ -98,8 +98,8 @@ static void intel_dvo_dpms(struct drm_encoder *encoder, int mode) static void intel_dvo_save(struct drm_connector *connector) { struct drm_i915_private *dev_priv = connector->dev->dev_private; - struct intel_output *intel_output = to_intel_output(connector); - struct intel_dvo_device *dvo = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_dvo_device *dvo = intel_encoder->dev_priv; /* Each output should probably just save the registers it touches, * but for now, use more overkill. @@ -114,8 +114,8 @@ static void intel_dvo_save(struct drm_connector *connector) static void intel_dvo_restore(struct drm_connector *connector) { struct drm_i915_private *dev_priv = connector->dev->dev_private; - struct intel_output *intel_output = to_intel_output(connector); - struct intel_dvo_device *dvo = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_dvo_device *dvo = intel_encoder->dev_priv; dvo->dev_ops->restore(dvo); @@ -127,8 +127,8 @@ static void intel_dvo_restore(struct drm_connector *connector) static int intel_dvo_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { - struct intel_output *intel_output = to_intel_output(connector); - struct intel_dvo_device *dvo = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_dvo_device *dvo = intel_encoder->dev_priv; if (mode->flags & DRM_MODE_FLAG_DBLSCAN) return MODE_NO_DBLESCAN; @@ -149,8 +149,8 @@ static bool intel_dvo_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { - struct intel_output *intel_output = enc_to_intel_output(encoder); - struct intel_dvo_device *dvo = intel_output->dev_priv; + struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); + struct intel_dvo_device *dvo = intel_encoder->dev_priv; /* If we have timings from the BIOS for the panel, put them in * to the adjusted mode. The CRTC will be set up for this mode, @@ -185,8 +185,8 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder, struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); - struct intel_output *intel_output = enc_to_intel_output(encoder); - struct intel_dvo_device *dvo = intel_output->dev_priv; + struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); + struct intel_dvo_device *dvo = intel_encoder->dev_priv; int pipe = intel_crtc->pipe; u32 dvo_val; u32 dvo_reg = dvo->dvo_reg, dvo_srcdim_reg; @@ -240,23 +240,23 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder, */ static enum drm_connector_status intel_dvo_detect(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); - struct intel_dvo_device *dvo = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_dvo_device *dvo = intel_encoder->dev_priv; return dvo->dev_ops->detect(dvo); } static int intel_dvo_get_modes(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); - struct intel_dvo_device *dvo = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_dvo_device *dvo = intel_encoder->dev_priv; /* We should probably have an i2c driver get_modes function for those * devices which will have a fixed set of modes determined by the chip * (TV-out, for example), but for now with just TMDS and LVDS, * that's not the case. */ - intel_ddc_get_modes(intel_output); + intel_ddc_get_modes(intel_encoder); if (!list_empty(&connector->probed_modes)) return 1; @@ -274,8 +274,8 @@ static int intel_dvo_get_modes(struct drm_connector *connector) static void intel_dvo_destroy (struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); - struct intel_dvo_device *dvo = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_dvo_device *dvo = intel_encoder->dev_priv; if (dvo) { if (dvo->dev_ops->destroy) @@ -285,13 +285,13 @@ static void intel_dvo_destroy (struct drm_connector *connector) /* no need, in i830_dvoices[] now */ //kfree(dvo); } - if (intel_output->i2c_bus) - intel_i2c_destroy(intel_output->i2c_bus); - if (intel_output->ddc_bus) - intel_i2c_destroy(intel_output->ddc_bus); + if (intel_encoder->i2c_bus) + intel_i2c_destroy(intel_encoder->i2c_bus); + if (intel_encoder->ddc_bus) + intel_i2c_destroy(intel_encoder->ddc_bus); drm_sysfs_connector_remove(connector); drm_connector_cleanup(connector); - kfree(intel_output); + kfree(intel_encoder); } #ifdef RANDR_GET_CRTC_INTERFACE @@ -299,8 +299,8 @@ static struct drm_crtc *intel_dvo_get_crtc(struct drm_connector *connector) { struct drm_device *dev = connector->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output = to_intel_output(connector); - struct intel_dvo_device *dvo = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_dvo_device *dvo = intel_encoder->dev_priv; int pipe = !!(I915_READ(dvo->dvo_reg) & SDVO_PIPE_B_SELECT); return intel_pipe_to_crtc(pScrn, pipe); @@ -351,8 +351,8 @@ intel_dvo_get_current_mode (struct drm_connector *connector) { struct drm_device *dev = connector->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output = to_intel_output(connector); - struct intel_dvo_device *dvo = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_dvo_device *dvo = intel_encoder->dev_priv; uint32_t dvo_reg = dvo->dvo_reg; uint32_t dvo_val = I915_READ(dvo_reg); struct drm_display_mode *mode = NULL; @@ -382,24 +382,24 @@ intel_dvo_get_current_mode (struct drm_connector *connector) void intel_dvo_init(struct drm_device *dev) { - struct intel_output *intel_output; + struct intel_encoder *intel_encoder; struct intel_dvo_device *dvo; struct i2c_adapter *i2cbus = NULL; int ret = 0; int i; int encoder_type = DRM_MODE_ENCODER_NONE; - intel_output = kzalloc (sizeof(struct intel_output), GFP_KERNEL); - if (!intel_output) + intel_encoder = kzalloc (sizeof(struct intel_encoder), GFP_KERNEL); + if (!intel_encoder) return; /* Set up the DDC bus */ - intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D"); - if (!intel_output->ddc_bus) + intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D"); + if (!intel_encoder->ddc_bus) goto free_intel; /* Now, try to find a controller */ for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) { - struct drm_connector *connector = &intel_output->base; + struct drm_connector *connector = &intel_encoder->base; int gpio; dvo = &intel_dvo_devices[i]; @@ -434,11 +434,11 @@ void intel_dvo_init(struct drm_device *dev) if (!ret) continue; - intel_output->type = INTEL_OUTPUT_DVO; - intel_output->crtc_mask = (1 << 0) | (1 << 1); + intel_encoder->type = INTEL_OUTPUT_DVO; + intel_encoder->crtc_mask = (1 << 0) | (1 << 1); switch (dvo->type) { case INTEL_DVO_CHIP_TMDS: - intel_output->clone_mask = + intel_encoder->clone_mask = (1 << INTEL_DVO_TMDS_CLONE_BIT) | (1 << INTEL_ANALOG_CLONE_BIT); drm_connector_init(dev, connector, @@ -447,7 +447,7 @@ void intel_dvo_init(struct drm_device *dev) encoder_type = DRM_MODE_ENCODER_TMDS; break; case INTEL_DVO_CHIP_LVDS: - intel_output->clone_mask = + intel_encoder->clone_mask = (1 << INTEL_DVO_LVDS_CLONE_BIT); drm_connector_init(dev, connector, &intel_dvo_connector_funcs, @@ -462,16 +462,16 @@ void intel_dvo_init(struct drm_device *dev) connector->interlace_allowed = false; connector->doublescan_allowed = false; - intel_output->dev_priv = dvo; - intel_output->i2c_bus = i2cbus; + intel_encoder->dev_priv = dvo; + intel_encoder->i2c_bus = i2cbus; - drm_encoder_init(dev, &intel_output->enc, + drm_encoder_init(dev, &intel_encoder->enc, &intel_dvo_enc_funcs, encoder_type); - drm_encoder_helper_add(&intel_output->enc, + drm_encoder_helper_add(&intel_encoder->enc, &intel_dvo_helper_funcs); - drm_mode_connector_attach_encoder(&intel_output->base, - &intel_output->enc); + drm_mode_connector_attach_encoder(&intel_encoder->base, + &intel_encoder->enc); if (dvo->type == INTEL_DVO_CHIP_LVDS) { /* For our LVDS chipsets, we should hopefully be able * to dig the fixed panel mode out of the BIOS data. @@ -489,10 +489,10 @@ void intel_dvo_init(struct drm_device *dev) return; } - intel_i2c_destroy(intel_output->ddc_bus); + intel_i2c_destroy(intel_encoder->ddc_bus); /* Didn't find a chip, so tear down. */ if (i2cbus != NULL) intel_i2c_destroy(i2cbus); free_intel: - kfree(intel_output); + kfree(intel_encoder); } diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index a30f8bf..9777504 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -50,8 +50,8 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder, struct drm_i915_private *dev_priv = dev->dev_private; struct drm_crtc *crtc = encoder->crtc; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct intel_output *intel_output = enc_to_intel_output(encoder); - struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); + struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv; u32 sdvox; sdvox = SDVO_ENCODING_HDMI | @@ -73,8 +73,8 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode) { struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output = enc_to_intel_output(encoder); - struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); + struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv; u32 temp; temp = I915_READ(hdmi_priv->sdvox_reg); @@ -109,8 +109,8 @@ static void intel_hdmi_save(struct drm_connector *connector) { struct drm_device *dev = connector->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output = to_intel_output(connector); - struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv; hdmi_priv->save_SDVOX = I915_READ(hdmi_priv->sdvox_reg); } @@ -119,8 +119,8 @@ static void intel_hdmi_restore(struct drm_connector *connector) { struct drm_device *dev = connector->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output = to_intel_output(connector); - struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv; I915_WRITE(hdmi_priv->sdvox_reg, hdmi_priv->save_SDVOX); POSTING_READ(hdmi_priv->sdvox_reg); @@ -150,21 +150,21 @@ static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder, static enum drm_connector_status intel_hdmi_detect(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); - struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv; struct edid *edid = NULL; enum drm_connector_status status = connector_status_disconnected; hdmi_priv->has_hdmi_sink = false; - edid = drm_get_edid(&intel_output->base, - intel_output->ddc_bus); + edid = drm_get_edid(&intel_encoder->base, + intel_encoder->ddc_bus); if (edid) { if (edid->input & DRM_EDID_INPUT_DIGITAL) { status = connector_status_connected; hdmi_priv->has_hdmi_sink = drm_detect_hdmi_monitor(edid); } - intel_output->base.display_info.raw_edid = NULL; + intel_encoder->base.display_info.raw_edid = NULL; kfree(edid); } @@ -173,24 +173,24 @@ intel_hdmi_detect(struct drm_connector *connector) static int intel_hdmi_get_modes(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); + struct intel_encoder *intel_encoder = to_intel_encoder(connector); /* We should parse the EDID data and find out if it's an HDMI sink so * we can send audio to it. */ - return intel_ddc_get_modes(intel_output); + return intel_ddc_get_modes(intel_encoder); } static void intel_hdmi_destroy(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); + struct intel_encoder *intel_encoder = to_intel_encoder(connector); - if (intel_output->i2c_bus) - intel_i2c_destroy(intel_output->i2c_bus); + if (intel_encoder->i2c_bus) + intel_i2c_destroy(intel_encoder->i2c_bus); drm_sysfs_connector_remove(connector); drm_connector_cleanup(connector); - kfree(intel_output); + kfree(intel_encoder); } static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = { @@ -229,63 +229,63 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) { struct drm_i915_private *dev_priv = dev->dev_private; struct drm_connector *connector; - struct intel_output *intel_output; + struct intel_encoder *intel_encoder; struct intel_hdmi_priv *hdmi_priv; - intel_output = kcalloc(sizeof(struct intel_output) + + intel_encoder = kcalloc(sizeof(struct intel_encoder) + sizeof(struct intel_hdmi_priv), 1, GFP_KERNEL); - if (!intel_output) + if (!intel_encoder) return; - hdmi_priv = (struct intel_hdmi_priv *)(intel_output + 1); + hdmi_priv = (struct intel_hdmi_priv *)(intel_encoder + 1); - connector = &intel_output->base; + connector = &intel_encoder->base; drm_connector_init(dev, connector, &intel_hdmi_connector_funcs, DRM_MODE_CONNECTOR_HDMIA); drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs); - intel_output->type = INTEL_OUTPUT_HDMI; + intel_encoder->type = INTEL_OUTPUT_HDMI; connector->interlace_allowed = 0; connector->doublescan_allowed = 0; - intel_output->crtc_mask = (1 << 0) | (1 << 1); + intel_encoder->crtc_mask = (1 << 0) | (1 << 1); /* Set up the DDC bus. */ if (sdvox_reg == SDVOB) { - intel_output->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT); - intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB"); + intel_encoder->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT); + intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB"); dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS; } else if (sdvox_reg == SDVOC) { - intel_output->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT); - intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC"); + intel_encoder->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT); + intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC"); dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS; } else if (sdvox_reg == HDMIB) { - intel_output->clone_mask = (1 << INTEL_HDMID_CLONE_BIT); - intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOE, + intel_encoder->clone_mask = (1 << INTEL_HDMID_CLONE_BIT); + intel_encoder->ddc_bus = intel_i2c_create(dev, PCH_GPIOE, "HDMIB"); dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS; } else if (sdvox_reg == HDMIC) { - intel_output->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT); - intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOD, + intel_encoder->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT); + intel_encoder->ddc_bus = intel_i2c_create(dev, PCH_GPIOD, "HDMIC"); dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS; } else if (sdvox_reg == HDMID) { - intel_output->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT); - intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOF, + intel_encoder->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT); + intel_encoder->ddc_bus = intel_i2c_create(dev, PCH_GPIOF, "HDMID"); dev_priv->hotplug_supported_mask |= HDMID_HOTPLUG_INT_STATUS; } - if (!intel_output->ddc_bus) + if (!intel_encoder->ddc_bus) goto err_connector; hdmi_priv->sdvox_reg = sdvox_reg; - intel_output->dev_priv = hdmi_priv; + intel_encoder->dev_priv = hdmi_priv; - drm_encoder_init(dev, &intel_output->enc, &intel_hdmi_enc_funcs, + drm_encoder_init(dev, &intel_encoder->enc, &intel_hdmi_enc_funcs, DRM_MODE_ENCODER_TMDS); - drm_encoder_helper_add(&intel_output->enc, &intel_hdmi_helper_funcs); + drm_encoder_helper_add(&intel_encoder->enc, &intel_hdmi_helper_funcs); - drm_mode_connector_attach_encoder(&intel_output->base, - &intel_output->enc); + drm_mode_connector_attach_encoder(&intel_encoder->base, + &intel_encoder->enc); drm_sysfs_connector_add(connector); /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written @@ -301,7 +301,7 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) err_connector: drm_connector_cleanup(connector); - kfree(intel_output); + kfree(intel_encoder); return; } diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 2b3fa7a..9d99ddc 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -238,8 +238,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); struct drm_encoder *tmp_encoder; - struct intel_output *intel_output = enc_to_intel_output(encoder); - struct intel_lvds_priv *lvds_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); + struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv; u32 pfit_control = 0, pfit_pgm_ratios = 0; int left_border = 0, right_border = 0, top_border = 0; int bottom_border = 0; @@ -586,8 +586,8 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder, { struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output = enc_to_intel_output(encoder); - struct intel_lvds_priv *lvds_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); + struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv; /* * The LVDS pin pair will already have been turned on in the @@ -634,11 +634,11 @@ static enum drm_connector_status intel_lvds_detect(struct drm_connector *connect static int intel_lvds_get_modes(struct drm_connector *connector) { struct drm_device *dev = connector->dev; - struct intel_output *intel_output = to_intel_output(connector); + struct intel_encoder *intel_encoder = to_intel_encoder(connector); struct drm_i915_private *dev_priv = dev->dev_private; int ret = 0; - ret = intel_ddc_get_modes(intel_output); + ret = intel_ddc_get_modes(intel_encoder); if (ret) return ret; @@ -714,11 +714,11 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val, static void intel_lvds_destroy(struct drm_connector *connector) { struct drm_device *dev = connector->dev; - struct intel_output *intel_output = to_intel_output(connector); + struct intel_encoder *intel_encoder = to_intel_encoder(connector); struct drm_i915_private *dev_priv = dev->dev_private; - if (intel_output->ddc_bus) - intel_i2c_destroy(intel_output->ddc_bus); + if (intel_encoder->ddc_bus) + intel_i2c_destroy(intel_encoder->ddc_bus); if (dev_priv->lid_notifier.notifier_call) acpi_lid_notifier_unregister(&dev_priv->lid_notifier); drm_sysfs_connector_remove(connector); @@ -731,13 +731,13 @@ static int intel_lvds_set_property(struct drm_connector *connector, uint64_t value) { struct drm_device *dev = connector->dev; - struct intel_output *intel_output = - to_intel_output(connector); + struct intel_encoder *intel_encoder = + to_intel_encoder(connector); if (property == dev->mode_config.scaling_mode_property && connector->encoder) { struct drm_crtc *crtc = connector->encoder->crtc; - struct intel_lvds_priv *lvds_priv = intel_output->dev_priv; + struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv; if (value == DRM_MODE_SCALE_NONE) { DRM_DEBUG_KMS("no scaling not supported\n"); return 0; @@ -967,7 +967,7 @@ static int lvds_is_present_in_vbt(struct drm_device *dev) void intel_lvds_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output; + struct intel_encoder *intel_encoder; struct drm_connector *connector; struct drm_encoder *encoder; struct drm_display_mode *scan; /* *modes, *bios_mode; */ @@ -995,40 +995,40 @@ void intel_lvds_init(struct drm_device *dev) gpio = PCH_GPIOC; } - intel_output = kzalloc(sizeof(struct intel_output) + + intel_encoder = kzalloc(sizeof(struct intel_encoder) + sizeof(struct intel_lvds_priv), GFP_KERNEL); - if (!intel_output) { + if (!intel_encoder) { return; } - connector = &intel_output->base; - encoder = &intel_output->enc; - drm_connector_init(dev, &intel_output->base, &intel_lvds_connector_funcs, + connector = &intel_encoder->base; + encoder = &intel_encoder->enc; + drm_connector_init(dev, &intel_encoder->base, &intel_lvds_connector_funcs, DRM_MODE_CONNECTOR_LVDS); - drm_encoder_init(dev, &intel_output->enc, &intel_lvds_enc_funcs, + drm_encoder_init(dev, &intel_encoder->enc, &intel_lvds_enc_funcs, DRM_MODE_ENCODER_LVDS); - drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); - intel_output->type = INTEL_OUTPUT_LVDS; + drm_mode_connector_attach_encoder(&intel_encoder->base, &intel_encoder->enc); + intel_encoder->type = INTEL_OUTPUT_LVDS; - intel_output->clone_mask = (1 << INTEL_LVDS_CLONE_BIT); - intel_output->crtc_mask = (1 << 1); + intel_encoder->clone_mask = (1 << INTEL_LVDS_CLONE_BIT); + intel_encoder->crtc_mask = (1 << 1); drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs); drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs); connector->display_info.subpixel_order = SubPixelHorizontalRGB; connector->interlace_allowed = false; connector->doublescan_allowed = false; - lvds_priv = (struct intel_lvds_priv *)(intel_output + 1); - intel_output->dev_priv = lvds_priv; + lvds_priv = (struct intel_lvds_priv *)(intel_encoder + 1); + intel_encoder->dev_priv = lvds_priv; /* create the scaling mode property */ drm_mode_create_scaling_mode_property(dev); /* * the initial panel fitting mode will be FULL_SCREEN. */ - drm_connector_attach_property(&intel_output->base, + drm_connector_attach_property(&intel_encoder->base, dev->mode_config.scaling_mode_property, DRM_MODE_SCALE_FULLSCREEN); lvds_priv->fitting_mode = DRM_MODE_SCALE_FULLSCREEN; @@ -1043,8 +1043,8 @@ void intel_lvds_init(struct drm_device *dev) */ /* Set up the DDC bus. */ - intel_output->ddc_bus = intel_i2c_create(dev, gpio, "LVDSDDC_C"); - if (!intel_output->ddc_bus) { + intel_encoder->ddc_bus = intel_i2c_create(dev, gpio, "LVDSDDC_C"); + if (!intel_encoder->ddc_bus) { dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " "failed.\n"); goto failed; @@ -1054,7 +1054,7 @@ void intel_lvds_init(struct drm_device *dev) * Attempt to get the fixed panel mode from DDC. Assume that the * preferred mode is the right one. */ - intel_ddc_get_modes(intel_output); + intel_ddc_get_modes(intel_encoder); list_for_each_entry(scan, &connector->probed_modes, head) { mutex_lock(&dev->mode_config.mutex); @@ -1132,9 +1132,9 @@ out: failed: DRM_DEBUG_KMS("No LVDS modes found, disabling.\n"); - if (intel_output->ddc_bus) - intel_i2c_destroy(intel_output->ddc_bus); + if (intel_encoder->ddc_bus) + intel_i2c_destroy(intel_encoder->ddc_bus); drm_connector_cleanup(connector); drm_encoder_cleanup(encoder); - kfree(intel_output); + kfree(intel_encoder); } diff --git a/drivers/gpu/drm/i915/intel_modes.c b/drivers/gpu/drm/i915/intel_modes.c index 67e2f46..3111a1c 100644 --- a/drivers/gpu/drm/i915/intel_modes.c +++ b/drivers/gpu/drm/i915/intel_modes.c @@ -33,7 +33,7 @@ * intel_ddc_probe * */ -bool intel_ddc_probe(struct intel_output *intel_output) +bool intel_ddc_probe(struct intel_encoder *intel_encoder) { u8 out_buf[] = { 0x0, 0x0}; u8 buf[2]; @@ -53,9 +53,9 @@ bool intel_ddc_probe(struct intel_output *intel_output) } }; - intel_i2c_quirk_set(intel_output->base.dev, true); - ret = i2c_transfer(intel_output->ddc_bus, msgs, 2); - intel_i2c_quirk_set(intel_output->base.dev, false); + intel_i2c_quirk_set(intel_encoder->base.dev, true); + ret = i2c_transfer(intel_encoder->ddc_bus, msgs, 2); + intel_i2c_quirk_set(intel_encoder->base.dev, false); if (ret == 2) return true; @@ -68,19 +68,19 @@ bool intel_ddc_probe(struct intel_output *intel_output) * * Fetch the EDID information from @connector using the DDC bus. */ -int intel_ddc_get_modes(struct intel_output *intel_output) +int intel_ddc_get_modes(struct intel_encoder *intel_encoder) { struct edid *edid; int ret = 0; - intel_i2c_quirk_set(intel_output->base.dev, true); - edid = drm_get_edid(&intel_output->base, intel_output->ddc_bus); - intel_i2c_quirk_set(intel_output->base.dev, false); + intel_i2c_quirk_set(intel_encoder->base.dev, true); + edid = drm_get_edid(&intel_encoder->base, intel_encoder->ddc_bus); + intel_i2c_quirk_set(intel_encoder->base.dev, false); if (edid) { - drm_mode_connector_update_edid_property(&intel_output->base, + drm_mode_connector_update_edid_property(&intel_encoder->base, edid); - ret = drm_add_edid_modes(&intel_output->base, edid); - intel_output->base.display_info.raw_edid = NULL; + ret = drm_add_edid_modes(&intel_encoder->base, edid); + intel_encoder->base.display_info.raw_edid = NULL; kfree(edid); } diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 48daee5..ea6de3b 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -161,18 +161,18 @@ struct intel_sdvo_priv { }; static bool -intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags); +intel_sdvo_output_setup(struct intel_encoder *intel_encoder, uint16_t flags); /** * Writes the SDVOB or SDVOC with the given value, but always writes both * SDVOB and SDVOC to work around apparent hardware issues (according to * comments in the BIOS). */ -static void intel_sdvo_write_sdvox(struct intel_output *intel_output, u32 val) +static void intel_sdvo_write_sdvox(struct intel_encoder *intel_encoder, u32 val) { - struct drm_device *dev = intel_output->base.dev; + struct drm_device *dev = intel_encoder->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; u32 bval = val, cval = val; int i; @@ -195,10 +195,10 @@ static void intel_sdvo_write_sdvox(struct intel_output *intel_output, u32 val) } } -static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr, +static bool intel_sdvo_read_byte(struct intel_encoder *intel_encoder, u8 addr, u8 *ch) { - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; u8 out_buf[2]; u8 buf[2]; int ret; @@ -221,7 +221,7 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr, out_buf[0] = addr; out_buf[1] = 0; - if ((ret = i2c_transfer(intel_output->i2c_bus, msgs, 2)) == 2) + if ((ret = i2c_transfer(intel_encoder->i2c_bus, msgs, 2)) == 2) { *ch = buf[0]; return true; @@ -231,10 +231,10 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr, return false; } -static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr, +static bool intel_sdvo_write_byte(struct intel_encoder *intel_encoder, int addr, u8 ch) { - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; u8 out_buf[2]; struct i2c_msg msgs[] = { { @@ -248,7 +248,7 @@ static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr, out_buf[0] = addr; out_buf[1] = ch; - if (i2c_transfer(intel_output->i2c_bus, msgs, 1) == 1) + if (i2c_transfer(intel_encoder->i2c_bus, msgs, 1) == 1) { return true; } @@ -355,10 +355,10 @@ static const struct _sdvo_cmd_name { #define SDVO_NAME(dev_priv) ((dev_priv)->output_device == SDVOB ? "SDVOB" : "SDVOC") #define SDVO_PRIV(output) ((struct intel_sdvo_priv *) (output)->dev_priv) -static void intel_sdvo_debug_write(struct intel_output *intel_output, u8 cmd, +static void intel_sdvo_debug_write(struct intel_encoder *intel_encoder, u8 cmd, void *args, int args_len) { - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; int i; DRM_DEBUG_KMS("%s: W: %02X ", @@ -378,19 +378,19 @@ static void intel_sdvo_debug_write(struct intel_output *intel_output, u8 cmd, DRM_LOG_KMS("\n"); } -static void intel_sdvo_write_cmd(struct intel_output *intel_output, u8 cmd, +static void intel_sdvo_write_cmd(struct intel_encoder *intel_encoder, u8 cmd, void *args, int args_len) { int i; - intel_sdvo_debug_write(intel_output, cmd, args, args_len); + intel_sdvo_debug_write(intel_encoder, cmd, args, args_len); for (i = 0; i < args_len; i++) { - intel_sdvo_write_byte(intel_output, SDVO_I2C_ARG_0 - i, + intel_sdvo_write_byte(intel_encoder, SDVO_I2C_ARG_0 - i, ((u8*)args)[i]); } - intel_sdvo_write_byte(intel_output, SDVO_I2C_OPCODE, cmd); + intel_sdvo_write_byte(intel_encoder, SDVO_I2C_OPCODE, cmd); } static const char *cmd_status_names[] = { @@ -403,11 +403,11 @@ static const char *cmd_status_names[] = { "Scaling not supported" }; -static void intel_sdvo_debug_response(struct intel_output *intel_output, +static void intel_sdvo_debug_response(struct intel_encoder *intel_encoder, void *response, int response_len, u8 status) { - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; int i; DRM_DEBUG_KMS("%s: R: ", SDVO_NAME(sdvo_priv)); @@ -422,7 +422,7 @@ static void intel_sdvo_debug_response(struct intel_output *intel_output, DRM_LOG_KMS("\n"); } -static u8 intel_sdvo_read_response(struct intel_output *intel_output, +static u8 intel_sdvo_read_response(struct intel_encoder *intel_encoder, void *response, int response_len) { int i; @@ -432,16 +432,16 @@ static u8 intel_sdvo_read_response(struct intel_output *intel_output, while (retry--) { /* Read the command response */ for (i = 0; i < response_len; i++) { - intel_sdvo_read_byte(intel_output, + intel_sdvo_read_byte(intel_encoder, SDVO_I2C_RETURN_0 + i, &((u8 *)response)[i]); } /* read the return status */ - intel_sdvo_read_byte(intel_output, SDVO_I2C_CMD_STATUS, + intel_sdvo_read_byte(intel_encoder, SDVO_I2C_CMD_STATUS, &status); - intel_sdvo_debug_response(intel_output, response, response_len, + intel_sdvo_debug_response(intel_encoder, response, response_len, status); if (status != SDVO_CMD_STATUS_PENDING) return status; @@ -469,10 +469,10 @@ static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode) * another I2C transaction after issuing the DDC bus switch, it will be * switched to the internal SDVO register. */ -static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output, +static void intel_sdvo_set_control_bus_switch(struct intel_encoder *intel_encoder, u8 target) { - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; u8 out_buf[2], cmd_buf[2], ret_value[2], ret; struct i2c_msg msgs[] = { { @@ -496,10 +496,10 @@ static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output, }, }; - intel_sdvo_debug_write(intel_output, SDVO_CMD_SET_CONTROL_BUS_SWITCH, + intel_sdvo_debug_write(intel_encoder, SDVO_CMD_SET_CONTROL_BUS_SWITCH, &target, 1); /* write the DDC switch command argument */ - intel_sdvo_write_byte(intel_output, SDVO_I2C_ARG_0, target); + intel_sdvo_write_byte(intel_encoder, SDVO_I2C_ARG_0, target); out_buf[0] = SDVO_I2C_OPCODE; out_buf[1] = SDVO_CMD_SET_CONTROL_BUS_SWITCH; @@ -508,7 +508,7 @@ static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output, ret_value[0] = 0; ret_value[1] = 0; - ret = i2c_transfer(intel_output->i2c_bus, msgs, 3); + ret = i2c_transfer(intel_encoder->i2c_bus, msgs, 3); if (ret != 3) { /* failure in I2C transfer */ DRM_DEBUG_KMS("I2c transfer returned %d\n", ret); @@ -522,7 +522,7 @@ static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output, return; } -static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool target_0, bool target_1) +static bool intel_sdvo_set_target_input(struct intel_encoder *intel_encoder, bool target_0, bool target_1) { struct intel_sdvo_set_target_input_args targets = {0}; u8 status; @@ -533,10 +533,10 @@ static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool if (target_1) targets.target_1 = 1; - intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_TARGET_INPUT, &targets, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TARGET_INPUT, &targets, sizeof(targets)); - status = intel_sdvo_read_response(intel_output, NULL, 0); + status = intel_sdvo_read_response(intel_encoder, NULL, 0); return (status == SDVO_CMD_STATUS_SUCCESS); } @@ -547,13 +547,13 @@ static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool * This function is making an assumption about the layout of the response, * which should be checked against the docs. */ -static bool intel_sdvo_get_trained_inputs(struct intel_output *intel_output, bool *input_1, bool *input_2) +static bool intel_sdvo_get_trained_inputs(struct intel_encoder *intel_encoder, bool *input_1, bool *input_2) { struct intel_sdvo_get_trained_inputs_response response; u8 status; - intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_TRAINED_INPUTS, NULL, 0); - status = intel_sdvo_read_response(intel_output, &response, sizeof(response)); + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_TRAINED_INPUTS, NULL, 0); + status = intel_sdvo_read_response(intel_encoder, &response, sizeof(response)); if (status != SDVO_CMD_STATUS_SUCCESS) return false; @@ -562,29 +562,29 @@ static bool intel_sdvo_get_trained_inputs(struct intel_output *intel_output, boo return true; } -static bool intel_sdvo_get_active_outputs(struct intel_output *intel_output, +static bool intel_sdvo_get_active_outputs(struct intel_encoder *intel_encoder, u16 *outputs) { u8 status; - intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_OUTPUTS, NULL, 0); - status = intel_sdvo_read_response(intel_output, outputs, sizeof(*outputs)); + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_OUTPUTS, NULL, 0); + status = intel_sdvo_read_response(intel_encoder, outputs, sizeof(*outputs)); return (status == SDVO_CMD_STATUS_SUCCESS); } -static bool intel_sdvo_set_active_outputs(struct intel_output *intel_output, +static bool intel_sdvo_set_active_outputs(struct intel_encoder *intel_encoder, u16 outputs) { u8 status; - intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_OUTPUTS, &outputs, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_OUTPUTS, &outputs, sizeof(outputs)); - status = intel_sdvo_read_response(intel_output, NULL, 0); + status = intel_sdvo_read_response(intel_encoder, NULL, 0); return (status == SDVO_CMD_STATUS_SUCCESS); } -static bool intel_sdvo_set_encoder_power_state(struct intel_output *intel_output, +static bool intel_sdvo_set_encoder_power_state(struct intel_encoder *intel_encoder, int mode) { u8 status, state = SDVO_ENCODER_STATE_ON; @@ -604,24 +604,24 @@ static bool intel_sdvo_set_encoder_power_state(struct intel_output *intel_output break; } - intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ENCODER_POWER_STATE, &state, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ENCODER_POWER_STATE, &state, sizeof(state)); - status = intel_sdvo_read_response(intel_output, NULL, 0); + status = intel_sdvo_read_response(intel_encoder, NULL, 0); return (status == SDVO_CMD_STATUS_SUCCESS); } -static bool intel_sdvo_get_input_pixel_clock_range(struct intel_output *intel_output, +static bool intel_sdvo_get_input_pixel_clock_range(struct intel_encoder *intel_encoder, int *clock_min, int *clock_max) { struct intel_sdvo_pixel_clock_range clocks; u8 status; - intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE, NULL, 0); - status = intel_sdvo_read_response(intel_output, &clocks, sizeof(clocks)); + status = intel_sdvo_read_response(intel_encoder, &clocks, sizeof(clocks)); if (status != SDVO_CMD_STATUS_SUCCESS) return false; @@ -633,31 +633,31 @@ static bool intel_sdvo_get_input_pixel_clock_range(struct intel_output *intel_ou return true; } -static bool intel_sdvo_set_target_output(struct intel_output *intel_output, +static bool intel_sdvo_set_target_output(struct intel_encoder *intel_encoder, u16 outputs) { u8 status; - intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_TARGET_OUTPUT, &outputs, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TARGET_OUTPUT, &outputs, sizeof(outputs)); - status = intel_sdvo_read_response(intel_output, NULL, 0); + status = intel_sdvo_read_response(intel_encoder, NULL, 0); return (status == SDVO_CMD_STATUS_SUCCESS); } -static bool intel_sdvo_get_timing(struct intel_output *intel_output, u8 cmd, +static bool intel_sdvo_get_timing(struct intel_encoder *intel_encoder, u8 cmd, struct intel_sdvo_dtd *dtd) { u8 status; - intel_sdvo_write_cmd(intel_output, cmd, NULL, 0); - status = intel_sdvo_read_response(intel_output, &dtd->part1, + intel_sdvo_write_cmd(intel_encoder, cmd, NULL, 0); + status = intel_sdvo_read_response(intel_encoder, &dtd->part1, sizeof(dtd->part1)); if (status != SDVO_CMD_STATUS_SUCCESS) return false; - intel_sdvo_write_cmd(intel_output, cmd + 1, NULL, 0); - status = intel_sdvo_read_response(intel_output, &dtd->part2, + intel_sdvo_write_cmd(intel_encoder, cmd + 1, NULL, 0); + status = intel_sdvo_read_response(intel_encoder, &dtd->part2, sizeof(dtd->part2)); if (status != SDVO_CMD_STATUS_SUCCESS) return false; @@ -665,54 +665,54 @@ static bool intel_sdvo_get_timing(struct intel_output *intel_output, u8 cmd, return true; } -static bool intel_sdvo_get_input_timing(struct intel_output *intel_output, +static bool intel_sdvo_get_input_timing(struct intel_encoder *intel_encoder, struct intel_sdvo_dtd *dtd) { - return intel_sdvo_get_timing(intel_output, + return intel_sdvo_get_timing(intel_encoder, SDVO_CMD_GET_INPUT_TIMINGS_PART1, dtd); } -static bool intel_sdvo_get_output_timing(struct intel_output *intel_output, +static bool intel_sdvo_get_output_timing(struct intel_encoder *intel_encoder, struct intel_sdvo_dtd *dtd) { - return intel_sdvo_get_timing(intel_output, + return intel_sdvo_get_timing(intel_encoder, SDVO_CMD_GET_OUTPUT_TIMINGS_PART1, dtd); } -static bool intel_sdvo_set_timing(struct intel_output *intel_output, u8 cmd, +static bool intel_sdvo_set_timing(struct intel_encoder *intel_encoder, u8 cmd, struct intel_sdvo_dtd *dtd) { u8 status; - intel_sdvo_write_cmd(intel_output, cmd, &dtd->part1, sizeof(dtd->part1)); - status = intel_sdvo_read_response(intel_output, NULL, 0); + intel_sdvo_write_cmd(intel_encoder, cmd, &dtd->part1, sizeof(dtd->part1)); + status = intel_sdvo_read_response(intel_encoder, NULL, 0); if (status != SDVO_CMD_STATUS_SUCCESS) return false; - intel_sdvo_write_cmd(intel_output, cmd + 1, &dtd->part2, sizeof(dtd->part2)); - status = intel_sdvo_read_response(intel_output, NULL, 0); + intel_sdvo_write_cmd(intel_encoder, cmd + 1, &dtd->part2, sizeof(dtd->part2)); + status = intel_sdvo_read_response(intel_encoder, NULL, 0); if (status != SDVO_CMD_STATUS_SUCCESS) return false; return true; } -static bool intel_sdvo_set_input_timing(struct intel_output *intel_output, +static bool intel_sdvo_set_input_timing(struct intel_encoder *intel_encoder, struct intel_sdvo_dtd *dtd) { - return intel_sdvo_set_timing(intel_output, + return intel_sdvo_set_timing(intel_encoder, SDVO_CMD_SET_INPUT_TIMINGS_PART1, dtd); } -static bool intel_sdvo_set_output_timing(struct intel_output *intel_output, +static bool intel_sdvo_set_output_timing(struct intel_encoder *intel_encoder, struct intel_sdvo_dtd *dtd) { - return intel_sdvo_set_timing(intel_output, + return intel_sdvo_set_timing(intel_encoder, SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd); } static bool -intel_sdvo_create_preferred_input_timing(struct intel_output *output, +intel_sdvo_create_preferred_input_timing(struct intel_encoder *output, uint16_t clock, uint16_t width, uint16_t height) @@ -741,7 +741,7 @@ intel_sdvo_create_preferred_input_timing(struct intel_output *output, return true; } -static bool intel_sdvo_get_preferred_input_timing(struct intel_output *output, +static bool intel_sdvo_get_preferred_input_timing(struct intel_encoder *output, struct intel_sdvo_dtd *dtd) { bool status; @@ -765,12 +765,12 @@ static bool intel_sdvo_get_preferred_input_timing(struct intel_output *output, return false; } -static int intel_sdvo_get_clock_rate_mult(struct intel_output *intel_output) +static int intel_sdvo_get_clock_rate_mult(struct intel_encoder *intel_encoder) { u8 response, status; - intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_CLOCK_RATE_MULT, NULL, 0); - status = intel_sdvo_read_response(intel_output, &response, 1); + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_CLOCK_RATE_MULT, NULL, 0); + status = intel_sdvo_read_response(intel_encoder, &response, 1); if (status != SDVO_CMD_STATUS_SUCCESS) { DRM_DEBUG_KMS("Couldn't get SDVO clock rate multiplier\n"); @@ -782,12 +782,12 @@ static int intel_sdvo_get_clock_rate_mult(struct intel_output *intel_output) return response; } -static bool intel_sdvo_set_clock_rate_mult(struct intel_output *intel_output, u8 val) +static bool intel_sdvo_set_clock_rate_mult(struct intel_encoder *intel_encoder, u8 val) { u8 status; - intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1); - status = intel_sdvo_read_response(intel_output, NULL, 0); + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1); + status = intel_sdvo_read_response(intel_encoder, NULL, 0); if (status != SDVO_CMD_STATUS_SUCCESS) return false; @@ -876,7 +876,7 @@ static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode, mode->flags |= DRM_MODE_FLAG_PVSYNC; } -static bool intel_sdvo_get_supp_encode(struct intel_output *output, +static bool intel_sdvo_get_supp_encode(struct intel_encoder *output, struct intel_sdvo_encode *encode) { uint8_t status; @@ -891,7 +891,7 @@ static bool intel_sdvo_get_supp_encode(struct intel_output *output, return true; } -static bool intel_sdvo_set_encode(struct intel_output *output, uint8_t mode) +static bool intel_sdvo_set_encode(struct intel_encoder *output, uint8_t mode) { uint8_t status; @@ -901,7 +901,7 @@ static bool intel_sdvo_set_encode(struct intel_output *output, uint8_t mode) return (status == SDVO_CMD_STATUS_SUCCESS); } -static bool intel_sdvo_set_colorimetry(struct intel_output *output, +static bool intel_sdvo_set_colorimetry(struct intel_encoder *output, uint8_t mode) { uint8_t status; @@ -913,7 +913,7 @@ static bool intel_sdvo_set_colorimetry(struct intel_output *output, } #if 0 -static void intel_sdvo_dump_hdmi_buf(struct intel_output *output) +static void intel_sdvo_dump_hdmi_buf(struct intel_encoder *output) { int i, j; uint8_t set_buf_index[2]; @@ -943,7 +943,7 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_output *output) } #endif -static void intel_sdvo_set_hdmi_buf(struct intel_output *output, int index, +static void intel_sdvo_set_hdmi_buf(struct intel_encoder *output, int index, uint8_t *data, int8_t size, uint8_t tx_rate) { uint8_t set_buf_index[2]; @@ -1033,7 +1033,7 @@ struct dip_infoframe { } __attribute__ ((packed)) u; } __attribute__((packed)); -static void intel_sdvo_set_avi_infoframe(struct intel_output *output, +static void intel_sdvo_set_avi_infoframe(struct intel_encoder *output, struct drm_display_mode * mode) { struct dip_infoframe avi_if = { @@ -1048,7 +1048,7 @@ static void intel_sdvo_set_avi_infoframe(struct intel_output *output, SDVO_HBUF_TX_VSYNC); } -static void intel_sdvo_set_tv_format(struct intel_output *output) +static void intel_sdvo_set_tv_format(struct intel_encoder *output) { struct intel_sdvo_tv_format format; @@ -1078,7 +1078,7 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { - struct intel_output *output = enc_to_intel_output(encoder); + struct intel_encoder *output = enc_to_intel_encoder(encoder); struct intel_sdvo_priv *dev_priv = output->dev_priv; if (dev_priv->is_tv) { @@ -1181,7 +1181,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, struct drm_i915_private *dev_priv = dev->dev_private; struct drm_crtc *crtc = encoder->crtc; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct intel_output *output = enc_to_intel_output(encoder); + struct intel_encoder *output = enc_to_intel_encoder(encoder); struct intel_sdvo_priv *sdvo_priv = output->dev_priv; u32 sdvox = 0; int sdvo_pixel_multiply; @@ -1305,19 +1305,19 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) { struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output = enc_to_intel_output(encoder); - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; u32 temp; if (mode != DRM_MODE_DPMS_ON) { - intel_sdvo_set_active_outputs(intel_output, 0); + intel_sdvo_set_active_outputs(intel_encoder, 0); if (0) - intel_sdvo_set_encoder_power_state(intel_output, mode); + intel_sdvo_set_encoder_power_state(intel_encoder, mode); if (mode == DRM_MODE_DPMS_OFF) { temp = I915_READ(sdvo_priv->output_device); if ((temp & SDVO_ENABLE) != 0) { - intel_sdvo_write_sdvox(intel_output, temp & ~SDVO_ENABLE); + intel_sdvo_write_sdvox(intel_encoder, temp & ~SDVO_ENABLE); } } } else { @@ -1327,11 +1327,11 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) temp = I915_READ(sdvo_priv->output_device); if ((temp & SDVO_ENABLE) == 0) - intel_sdvo_write_sdvox(intel_output, temp | SDVO_ENABLE); + intel_sdvo_write_sdvox(intel_encoder, temp | SDVO_ENABLE); for (i = 0; i < 2; i++) intel_wait_for_vblank(dev); - status = intel_sdvo_get_trained_inputs(intel_output, &input1, + status = intel_sdvo_get_trained_inputs(intel_encoder, &input1, &input2); @@ -1345,8 +1345,8 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) } if (0) - intel_sdvo_set_encoder_power_state(intel_output, mode); - intel_sdvo_set_active_outputs(intel_output, sdvo_priv->controlled_output); + intel_sdvo_set_encoder_power_state(intel_encoder, mode); + intel_sdvo_set_active_outputs(intel_encoder, sdvo_priv->controlled_output); } return; } @@ -1355,22 +1355,22 @@ static void intel_sdvo_save(struct drm_connector *connector) { struct drm_device *dev = connector->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output = to_intel_output(connector); - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; int o; - sdvo_priv->save_sdvo_mult = intel_sdvo_get_clock_rate_mult(intel_output); - intel_sdvo_get_active_outputs(intel_output, &sdvo_priv->save_active_outputs); + sdvo_priv->save_sdvo_mult = intel_sdvo_get_clock_rate_mult(intel_encoder); + intel_sdvo_get_active_outputs(intel_encoder, &sdvo_priv->save_active_outputs); if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) { - intel_sdvo_set_target_input(intel_output, true, false); - intel_sdvo_get_input_timing(intel_output, + intel_sdvo_set_target_input(intel_encoder, true, false); + intel_sdvo_get_input_timing(intel_encoder, &sdvo_priv->save_input_dtd_1); } if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) { - intel_sdvo_set_target_input(intel_output, false, true); - intel_sdvo_get_input_timing(intel_output, + intel_sdvo_set_target_input(intel_encoder, false, true); + intel_sdvo_get_input_timing(intel_encoder, &sdvo_priv->save_input_dtd_2); } @@ -1379,8 +1379,8 @@ static void intel_sdvo_save(struct drm_connector *connector) u16 this_output = (1 << o); if (sdvo_priv->caps.output_flags & this_output) { - intel_sdvo_set_target_output(intel_output, this_output); - intel_sdvo_get_output_timing(intel_output, + intel_sdvo_set_target_output(intel_encoder, this_output); + intel_sdvo_get_output_timing(intel_encoder, &sdvo_priv->save_output_dtd[o]); } } @@ -1394,60 +1394,60 @@ static void intel_sdvo_save(struct drm_connector *connector) static void intel_sdvo_restore(struct drm_connector *connector) { struct drm_device *dev = connector->dev; - struct intel_output *intel_output = to_intel_output(connector); - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; int o; int i; bool input1, input2; u8 status; - intel_sdvo_set_active_outputs(intel_output, 0); + intel_sdvo_set_active_outputs(intel_encoder, 0); for (o = SDVO_OUTPUT_FIRST; o <= SDVO_OUTPUT_LAST; o++) { u16 this_output = (1 << o); if (sdvo_priv->caps.output_flags & this_output) { - intel_sdvo_set_target_output(intel_output, this_output); - intel_sdvo_set_output_timing(intel_output, &sdvo_priv->save_output_dtd[o]); + intel_sdvo_set_target_output(intel_encoder, this_output); + intel_sdvo_set_output_timing(intel_encoder, &sdvo_priv->save_output_dtd[o]); } } if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) { - intel_sdvo_set_target_input(intel_output, true, false); - intel_sdvo_set_input_timing(intel_output, &sdvo_priv->save_input_dtd_1); + intel_sdvo_set_target_input(intel_encoder, true, false); + intel_sdvo_set_input_timing(intel_encoder, &sdvo_priv->save_input_dtd_1); } if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) { - intel_sdvo_set_target_input(intel_output, false, true); - intel_sdvo_set_input_timing(intel_output, &sdvo_priv->save_input_dtd_2); + intel_sdvo_set_target_input(intel_encoder, false, true); + intel_sdvo_set_input_timing(intel_encoder, &sdvo_priv->save_input_dtd_2); } - intel_sdvo_set_clock_rate_mult(intel_output, sdvo_priv->save_sdvo_mult); + intel_sdvo_set_clock_rate_mult(intel_encoder, sdvo_priv->save_sdvo_mult); if (sdvo_priv->is_tv) { /* XXX: Restore TV format/enhancements. */ } - intel_sdvo_write_sdvox(intel_output, sdvo_priv->save_SDVOX); + intel_sdvo_write_sdvox(intel_encoder, sdvo_priv->save_SDVOX); if (sdvo_priv->save_SDVOX & SDVO_ENABLE) { for (i = 0; i < 2; i++) intel_wait_for_vblank(dev); - status = intel_sdvo_get_trained_inputs(intel_output, &input1, &input2); + status = intel_sdvo_get_trained_inputs(intel_encoder, &input1, &input2); if (status == SDVO_CMD_STATUS_SUCCESS && !input1) DRM_DEBUG_KMS("First %s output reported failure to " "sync\n", SDVO_NAME(sdvo_priv)); } - intel_sdvo_set_active_outputs(intel_output, sdvo_priv->save_active_outputs); + intel_sdvo_set_active_outputs(intel_encoder, sdvo_priv->save_active_outputs); } static int intel_sdvo_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { - struct intel_output *intel_output = to_intel_output(connector); - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; if (mode->flags & DRM_MODE_FLAG_DBLSCAN) return MODE_NO_DBLESCAN; @@ -1472,12 +1472,12 @@ static int intel_sdvo_mode_valid(struct drm_connector *connector, return MODE_OK; } -static bool intel_sdvo_get_capabilities(struct intel_output *intel_output, struct intel_sdvo_caps *caps) +static bool intel_sdvo_get_capabilities(struct intel_encoder *intel_encoder, struct intel_sdvo_caps *caps) { u8 status; - intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_DEVICE_CAPS, NULL, 0); - status = intel_sdvo_read_response(intel_output, caps, sizeof(*caps)); + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_DEVICE_CAPS, NULL, 0); + status = intel_sdvo_read_response(intel_encoder, caps, sizeof(*caps)); if (status != SDVO_CMD_STATUS_SUCCESS) return false; @@ -1487,12 +1487,12 @@ static bool intel_sdvo_get_capabilities(struct intel_output *intel_output, struc struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB) { struct drm_connector *connector = NULL; - struct intel_output *iout = NULL; + struct intel_encoder *iout = NULL; struct intel_sdvo_priv *sdvo; /* find the sdvo connector */ list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - iout = to_intel_output(connector); + iout = to_intel_encoder(connector); if (iout->type != INTEL_OUTPUT_SDVO) continue; @@ -1514,16 +1514,16 @@ int intel_sdvo_supports_hotplug(struct drm_connector *connector) { u8 response[2]; u8 status; - struct intel_output *intel_output; + struct intel_encoder *intel_encoder; DRM_DEBUG_KMS("\n"); if (!connector) return 0; - intel_output = to_intel_output(connector); + intel_encoder = to_intel_encoder(connector); - intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0); - status = intel_sdvo_read_response(intel_output, &response, 2); + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0); + status = intel_sdvo_read_response(intel_encoder, &response, 2); if (response[0] !=0) return 1; @@ -1535,30 +1535,30 @@ void intel_sdvo_set_hotplug(struct drm_connector *connector, int on) { u8 response[2]; u8 status; - struct intel_output *intel_output = to_intel_output(connector); + struct intel_encoder *intel_encoder = to_intel_encoder(connector); - intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); - intel_sdvo_read_response(intel_output, &response, 2); + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); + intel_sdvo_read_response(intel_encoder, &response, 2); if (on) { - intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0); - status = intel_sdvo_read_response(intel_output, &response, 2); + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0); + status = intel_sdvo_read_response(intel_encoder, &response, 2); - intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); } else { response[0] = 0; response[1] = 0; - intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); } - intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); - intel_sdvo_read_response(intel_output, &response, 2); + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); + intel_sdvo_read_response(intel_encoder, &response, 2); } static bool -intel_sdvo_multifunc_encoder(struct intel_output *intel_output) +intel_sdvo_multifunc_encoder(struct intel_encoder *intel_encoder) { - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; int caps = 0; if (sdvo_priv->caps.output_flags & @@ -1592,11 +1592,11 @@ static struct drm_connector * intel_find_analog_connector(struct drm_device *dev) { struct drm_connector *connector; - struct intel_output *intel_output; + struct intel_encoder *intel_encoder; list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - intel_output = to_intel_output(connector); - if (intel_output->type == INTEL_OUTPUT_ANALOG) + intel_encoder = to_intel_encoder(connector); + if (intel_encoder->type == INTEL_OUTPUT_ANALOG) return connector; } return NULL; @@ -1621,16 +1621,16 @@ intel_analog_is_connected(struct drm_device *dev) enum drm_connector_status intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) { - struct intel_output *intel_output = to_intel_output(connector); - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; enum drm_connector_status status = connector_status_connected; struct edid *edid = NULL; - edid = drm_get_edid(&intel_output->base, - intel_output->ddc_bus); + edid = drm_get_edid(&intel_encoder->base, + intel_encoder->ddc_bus); /* This is only applied to SDVO cards with multiple outputs */ - if (edid == NULL && intel_sdvo_multifunc_encoder(intel_output)) { + if (edid == NULL && intel_sdvo_multifunc_encoder(intel_encoder)) { uint8_t saved_ddc, temp_ddc; saved_ddc = sdvo_priv->ddc_bus; temp_ddc = sdvo_priv->ddc_bus >> 1; @@ -1640,8 +1640,8 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) */ while(temp_ddc > 1) { sdvo_priv->ddc_bus = temp_ddc; - edid = drm_get_edid(&intel_output->base, - intel_output->ddc_bus); + edid = drm_get_edid(&intel_encoder->base, + intel_encoder->ddc_bus); if (edid) { /* * When we can get the EDID, maybe it is the @@ -1660,8 +1660,8 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) */ if (edid == NULL && sdvo_priv->analog_ddc_bus && - !intel_analog_is_connected(intel_output->base.dev)) - edid = drm_get_edid(&intel_output->base, + !intel_analog_is_connected(intel_encoder->base.dev)) + edid = drm_get_edid(&intel_encoder->base, sdvo_priv->analog_ddc_bus); if (edid != NULL) { /* Don't report the output as connected if it's a DVI-I @@ -1676,7 +1676,7 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) } kfree(edid); - intel_output->base.display_info.raw_edid = NULL; + intel_encoder->base.display_info.raw_edid = NULL; } else if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) status = connector_status_disconnected; @@ -1688,16 +1688,16 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect { uint16_t response; u8 status; - struct intel_output *intel_output = to_intel_output(connector); - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; - intel_sdvo_write_cmd(intel_output, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0); if (sdvo_priv->is_tv) { /* add 30ms delay when the output type is SDVO-TV */ mdelay(30); } - status = intel_sdvo_read_response(intel_output, &response, 2); + status = intel_sdvo_read_response(intel_encoder, &response, 2); DRM_DEBUG_KMS("SDVO response %d %d\n", response & 0xff, response >> 8); @@ -1707,10 +1707,10 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect if (response == 0) return connector_status_disconnected; - if (intel_sdvo_multifunc_encoder(intel_output) && + if (intel_sdvo_multifunc_encoder(intel_encoder) && sdvo_priv->attached_output != response) { if (sdvo_priv->controlled_output != response && - intel_sdvo_output_setup(intel_output, response) != true) + intel_sdvo_output_setup(intel_encoder, response) != true) return connector_status_unknown; sdvo_priv->attached_output = response; } @@ -1719,12 +1719,12 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; int num_modes; /* set the bus switch and get the modes */ - num_modes = intel_ddc_get_modes(intel_output); + num_modes = intel_ddc_get_modes(intel_encoder); /* * Mac mini hack. On this device, the DVI-I connector shares one DDC @@ -1734,17 +1734,17 @@ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) */ if (num_modes == 0 && sdvo_priv->analog_ddc_bus && - !intel_analog_is_connected(intel_output->base.dev)) { + !intel_analog_is_connected(intel_encoder->base.dev)) { struct i2c_adapter *digital_ddc_bus; /* Switch to the analog ddc bus and try that */ - digital_ddc_bus = intel_output->ddc_bus; - intel_output->ddc_bus = sdvo_priv->analog_ddc_bus; + digital_ddc_bus = intel_encoder->ddc_bus; + intel_encoder->ddc_bus = sdvo_priv->analog_ddc_bus; - (void) intel_ddc_get_modes(intel_output); + (void) intel_ddc_get_modes(intel_encoder); - intel_output->ddc_bus = digital_ddc_bus; + intel_encoder->ddc_bus = digital_ddc_bus; } } @@ -1815,7 +1815,7 @@ struct drm_display_mode sdvo_tv_modes[] = { static void intel_sdvo_get_tv_modes(struct drm_connector *connector) { - struct intel_output *output = to_intel_output(connector); + struct intel_encoder *output = to_intel_encoder(connector); struct intel_sdvo_priv *sdvo_priv = output->dev_priv; struct intel_sdvo_sdtv_resolution_request tv_res; uint32_t reply = 0, format_map = 0; @@ -1857,9 +1857,9 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector) static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); + struct intel_encoder *intel_encoder = to_intel_encoder(connector); struct drm_i915_private *dev_priv = connector->dev->dev_private; - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; struct drm_display_mode *newmode; /* @@ -1867,7 +1867,7 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) * Assume that the preferred modes are * arranged in priority order. */ - intel_ddc_get_modes(intel_output); + intel_ddc_get_modes(intel_encoder); if (list_empty(&connector->probed_modes) == false) goto end; @@ -1896,7 +1896,7 @@ end: static int intel_sdvo_get_modes(struct drm_connector *connector) { - struct intel_output *output = to_intel_output(connector); + struct intel_encoder *output = to_intel_encoder(connector); struct intel_sdvo_priv *sdvo_priv = output->dev_priv; if (sdvo_priv->is_tv) @@ -1914,8 +1914,8 @@ static int intel_sdvo_get_modes(struct drm_connector *connector) static void intel_sdvo_destroy_enhance_property(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; struct drm_device *dev = connector->dev; if (sdvo_priv->is_tv) { @@ -1952,13 +1952,13 @@ void intel_sdvo_destroy_enhance_property(struct drm_connector *connector) static void intel_sdvo_destroy(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; - if (intel_output->i2c_bus) - intel_i2c_destroy(intel_output->i2c_bus); - if (intel_output->ddc_bus) - intel_i2c_destroy(intel_output->ddc_bus); + if (intel_encoder->i2c_bus) + intel_i2c_destroy(intel_encoder->i2c_bus); + if (intel_encoder->ddc_bus) + intel_i2c_destroy(intel_encoder->ddc_bus); if (sdvo_priv->analog_ddc_bus) intel_i2c_destroy(sdvo_priv->analog_ddc_bus); @@ -1976,7 +1976,7 @@ static void intel_sdvo_destroy(struct drm_connector *connector) drm_sysfs_connector_remove(connector); drm_connector_cleanup(connector); - kfree(intel_output); + kfree(intel_encoder); } static int @@ -1984,9 +1984,9 @@ intel_sdvo_set_property(struct drm_connector *connector, struct drm_property *property, uint64_t val) { - struct intel_output *intel_output = to_intel_output(connector); - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; - struct drm_encoder *encoder = &intel_output->enc; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; + struct drm_encoder *encoder = &intel_encoder->enc; struct drm_crtc *crtc = encoder->crtc; int ret = 0; bool changed = false; @@ -2094,8 +2094,8 @@ intel_sdvo_set_property(struct drm_connector *connector, sdvo_priv->cur_brightness = temp_value; } if (cmd) { - intel_sdvo_write_cmd(intel_output, cmd, &temp_value, 2); - status = intel_sdvo_read_response(intel_output, + intel_sdvo_write_cmd(intel_encoder, cmd, &temp_value, 2); + status = intel_sdvo_read_response(intel_encoder, NULL, 0); if (status != SDVO_CMD_STATUS_SUCCESS) { DRM_DEBUG_KMS("Incorrect SDVO command \n"); @@ -2190,7 +2190,7 @@ intel_sdvo_select_ddc_bus(struct intel_sdvo_priv *dev_priv) } static bool -intel_sdvo_get_digital_encoding_mode(struct intel_output *output) +intel_sdvo_get_digital_encoding_mode(struct intel_encoder *output) { struct intel_sdvo_priv *sdvo_priv = output->dev_priv; uint8_t status; @@ -2204,42 +2204,42 @@ intel_sdvo_get_digital_encoding_mode(struct intel_output *output) return true; } -static struct intel_output * -intel_sdvo_chan_to_intel_output(struct intel_i2c_chan *chan) +static struct intel_encoder * +intel_sdvo_chan_to_intel_encoder(struct intel_i2c_chan *chan) { struct drm_device *dev = chan->drm_dev; struct drm_connector *connector; - struct intel_output *intel_output = NULL; + struct intel_encoder *intel_encoder = NULL; list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - if (to_intel_output(connector)->ddc_bus == &chan->adapter) { - intel_output = to_intel_output(connector); + if (to_intel_encoder(connector)->ddc_bus == &chan->adapter) { + intel_encoder = to_intel_encoder(connector); break; } } - return intel_output; + return intel_encoder; } static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) { - struct intel_output *intel_output; + struct intel_encoder *intel_encoder; struct intel_sdvo_priv *sdvo_priv; struct i2c_algo_bit_data *algo_data; const struct i2c_algorithm *algo; algo_data = (struct i2c_algo_bit_data *)i2c_adap->algo_data; - intel_output = - intel_sdvo_chan_to_intel_output( + intel_encoder = + intel_sdvo_chan_to_intel_encoder( (struct intel_i2c_chan *)(algo_data->data)); - if (intel_output == NULL) + if (intel_encoder == NULL) return -EINVAL; - sdvo_priv = intel_output->dev_priv; - algo = intel_output->i2c_bus->algo; + sdvo_priv = intel_encoder->dev_priv; + algo = intel_encoder->i2c_bus->algo; - intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus); + intel_sdvo_set_control_bus_switch(intel_encoder, sdvo_priv->ddc_bus); return algo->master_xfer(i2c_adap, msgs, num); } @@ -2304,15 +2304,15 @@ static struct dmi_system_id intel_sdvo_bad_tv[] = { }; static bool -intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) +intel_sdvo_output_setup(struct intel_encoder *intel_encoder, uint16_t flags) { - struct drm_connector *connector = &intel_output->base; - struct drm_encoder *encoder = &intel_output->enc; - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct drm_connector *connector = &intel_encoder->base; + struct drm_encoder *encoder = &intel_encoder->enc; + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; bool ret = true, registered = false; sdvo_priv->is_tv = false; - intel_output->needs_tv_clock = false; + intel_encoder->needs_tv_clock = false; sdvo_priv->is_lvds = false; if (device_is_registered(&connector->kdev)) { @@ -2330,16 +2330,16 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) encoder->encoder_type = DRM_MODE_ENCODER_TMDS; connector->connector_type = DRM_MODE_CONNECTOR_DVID; - if (intel_sdvo_get_supp_encode(intel_output, + if (intel_sdvo_get_supp_encode(intel_encoder, &sdvo_priv->encode) && - intel_sdvo_get_digital_encoding_mode(intel_output) && + intel_sdvo_get_digital_encoding_mode(intel_encoder) && sdvo_priv->is_hdmi) { /* enable hdmi encoding mode if supported */ - intel_sdvo_set_encode(intel_output, SDVO_ENCODE_HDMI); - intel_sdvo_set_colorimetry(intel_output, + intel_sdvo_set_encode(intel_encoder, SDVO_ENCODE_HDMI); + intel_sdvo_set_colorimetry(intel_encoder, SDVO_COLORIMETRY_RGB256); connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; - intel_output->clone_mask = + intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | (1 << INTEL_ANALOG_CLONE_BIT); } @@ -2350,21 +2350,21 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) encoder->encoder_type = DRM_MODE_ENCODER_TVDAC; connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; sdvo_priv->is_tv = true; - intel_output->needs_tv_clock = true; - intel_output->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; + intel_encoder->needs_tv_clock = true; + intel_encoder->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; } else if (flags & SDVO_OUTPUT_RGB0) { sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0; encoder->encoder_type = DRM_MODE_ENCODER_DAC; connector->connector_type = DRM_MODE_CONNECTOR_VGA; - intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | + intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | (1 << INTEL_ANALOG_CLONE_BIT); } else if (flags & SDVO_OUTPUT_RGB1) { sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1; encoder->encoder_type = DRM_MODE_ENCODER_DAC; connector->connector_type = DRM_MODE_CONNECTOR_VGA; - intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | + intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | (1 << INTEL_ANALOG_CLONE_BIT); } else if (flags & SDVO_OUTPUT_CVBS0) { @@ -2372,15 +2372,15 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) encoder->encoder_type = DRM_MODE_ENCODER_TVDAC; connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; sdvo_priv->is_tv = true; - intel_output->needs_tv_clock = true; - intel_output->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; + intel_encoder->needs_tv_clock = true; + intel_encoder->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; } else if (flags & SDVO_OUTPUT_LVDS0) { sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS0; encoder->encoder_type = DRM_MODE_ENCODER_LVDS; connector->connector_type = DRM_MODE_CONNECTOR_LVDS; sdvo_priv->is_lvds = true; - intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) | + intel_encoder->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) | (1 << INTEL_SDVO_LVDS_CLONE_BIT); } else if (flags & SDVO_OUTPUT_LVDS1) { @@ -2388,7 +2388,7 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) encoder->encoder_type = DRM_MODE_ENCODER_LVDS; connector->connector_type = DRM_MODE_CONNECTOR_LVDS; sdvo_priv->is_lvds = true; - intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) | + intel_encoder->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) | (1 << INTEL_SDVO_LVDS_CLONE_BIT); } else { @@ -2401,7 +2401,7 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) bytes[0], bytes[1]); ret = false; } - intel_output->crtc_mask = (1 << 0) | (1 << 1); + intel_encoder->crtc_mask = (1 << 0) | (1 << 1); if (ret && registered) ret = drm_sysfs_connector_add(connector) == 0 ? true : false; @@ -2413,18 +2413,18 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) static void intel_sdvo_tv_create_property(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; struct intel_sdvo_tv_format format; uint32_t format_map, i; uint8_t status; - intel_sdvo_set_target_output(intel_output, + intel_sdvo_set_target_output(intel_encoder, sdvo_priv->controlled_output); - intel_sdvo_write_cmd(intel_output, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SUPPORTED_TV_FORMATS, NULL, 0); - status = intel_sdvo_read_response(intel_output, + status = intel_sdvo_read_response(intel_encoder, &format, sizeof(format)); if (status != SDVO_CMD_STATUS_SUCCESS) return; @@ -2462,16 +2462,16 @@ static void intel_sdvo_tv_create_property(struct drm_connector *connector) static void intel_sdvo_create_enhance_property(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; struct intel_sdvo_enhancements_reply sdvo_data; struct drm_device *dev = connector->dev; uint8_t status; uint16_t response, data_value[2]; - intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS, NULL, 0); - status = intel_sdvo_read_response(intel_output, &sdvo_data, + status = intel_sdvo_read_response(intel_encoder, &sdvo_data, sizeof(sdvo_data)); if (status != SDVO_CMD_STATUS_SUCCESS) { DRM_DEBUG_KMS(" incorrect response is returned\n"); @@ -2487,18 +2487,18 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) * property */ if (sdvo_data.overscan_h) { - intel_sdvo_write_cmd(intel_output, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_MAX_OVERSCAN_H, NULL, 0); - status = intel_sdvo_read_response(intel_output, + status = intel_sdvo_read_response(intel_encoder, &data_value, 4); if (status != SDVO_CMD_STATUS_SUCCESS) { DRM_DEBUG_KMS("Incorrect SDVO max " "h_overscan\n"); return; } - intel_sdvo_write_cmd(intel_output, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_OVERSCAN_H, NULL, 0); - status = intel_sdvo_read_response(intel_output, + status = intel_sdvo_read_response(intel_encoder, &response, 2); if (status != SDVO_CMD_STATUS_SUCCESS) { DRM_DEBUG_KMS("Incorrect SDVO h_overscan\n"); @@ -2528,18 +2528,18 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) data_value[0], data_value[1], response); } if (sdvo_data.overscan_v) { - intel_sdvo_write_cmd(intel_output, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_MAX_OVERSCAN_V, NULL, 0); - status = intel_sdvo_read_response(intel_output, + status = intel_sdvo_read_response(intel_encoder, &data_value, 4); if (status != SDVO_CMD_STATUS_SUCCESS) { DRM_DEBUG_KMS("Incorrect SDVO max " "v_overscan\n"); return; } - intel_sdvo_write_cmd(intel_output, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_OVERSCAN_V, NULL, 0); - status = intel_sdvo_read_response(intel_output, + status = intel_sdvo_read_response(intel_encoder, &response, 2); if (status != SDVO_CMD_STATUS_SUCCESS) { DRM_DEBUG_KMS("Incorrect SDVO v_overscan\n"); @@ -2569,17 +2569,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) data_value[0], data_value[1], response); } if (sdvo_data.position_h) { - intel_sdvo_write_cmd(intel_output, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_MAX_POSITION_H, NULL, 0); - status = intel_sdvo_read_response(intel_output, + status = intel_sdvo_read_response(intel_encoder, &data_value, 4); if (status != SDVO_CMD_STATUS_SUCCESS) { DRM_DEBUG_KMS("Incorrect SDVO Max h_pos\n"); return; } - intel_sdvo_write_cmd(intel_output, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_POSITION_H, NULL, 0); - status = intel_sdvo_read_response(intel_output, + status = intel_sdvo_read_response(intel_encoder, &response, 2); if (status != SDVO_CMD_STATUS_SUCCESS) { DRM_DEBUG_KMS("Incorrect SDVO get h_postion\n"); @@ -2600,17 +2600,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) data_value[0], data_value[1], response); } if (sdvo_data.position_v) { - intel_sdvo_write_cmd(intel_output, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_MAX_POSITION_V, NULL, 0); - status = intel_sdvo_read_response(intel_output, + status = intel_sdvo_read_response(intel_encoder, &data_value, 4); if (status != SDVO_CMD_STATUS_SUCCESS) { DRM_DEBUG_KMS("Incorrect SDVO Max v_pos\n"); return; } - intel_sdvo_write_cmd(intel_output, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_POSITION_V, NULL, 0); - status = intel_sdvo_read_response(intel_output, + status = intel_sdvo_read_response(intel_encoder, &response, 2); if (status != SDVO_CMD_STATUS_SUCCESS) { DRM_DEBUG_KMS("Incorrect SDVO get v_postion\n"); @@ -2633,17 +2633,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) } if (sdvo_priv->is_tv) { if (sdvo_data.saturation) { - intel_sdvo_write_cmd(intel_output, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_MAX_SATURATION, NULL, 0); - status = intel_sdvo_read_response(intel_output, + status = intel_sdvo_read_response(intel_encoder, &data_value, 4); if (status != SDVO_CMD_STATUS_SUCCESS) { DRM_DEBUG_KMS("Incorrect SDVO Max sat\n"); return; } - intel_sdvo_write_cmd(intel_output, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SATURATION, NULL, 0); - status = intel_sdvo_read_response(intel_output, + status = intel_sdvo_read_response(intel_encoder, &response, 2); if (status != SDVO_CMD_STATUS_SUCCESS) { DRM_DEBUG_KMS("Incorrect SDVO get sat\n"); @@ -2665,17 +2665,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) data_value[0], data_value[1], response); } if (sdvo_data.contrast) { - intel_sdvo_write_cmd(intel_output, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_MAX_CONTRAST, NULL, 0); - status = intel_sdvo_read_response(intel_output, + status = intel_sdvo_read_response(intel_encoder, &data_value, 4); if (status != SDVO_CMD_STATUS_SUCCESS) { DRM_DEBUG_KMS("Incorrect SDVO Max contrast\n"); return; } - intel_sdvo_write_cmd(intel_output, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_CONTRAST, NULL, 0); - status = intel_sdvo_read_response(intel_output, + status = intel_sdvo_read_response(intel_encoder, &response, 2); if (status != SDVO_CMD_STATUS_SUCCESS) { DRM_DEBUG_KMS("Incorrect SDVO get contrast\n"); @@ -2696,17 +2696,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) data_value[0], data_value[1], response); } if (sdvo_data.hue) { - intel_sdvo_write_cmd(intel_output, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_MAX_HUE, NULL, 0); - status = intel_sdvo_read_response(intel_output, + status = intel_sdvo_read_response(intel_encoder, &data_value, 4); if (status != SDVO_CMD_STATUS_SUCCESS) { DRM_DEBUG_KMS("Incorrect SDVO Max hue\n"); return; } - intel_sdvo_write_cmd(intel_output, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_HUE, NULL, 0); - status = intel_sdvo_read_response(intel_output, + status = intel_sdvo_read_response(intel_encoder, &response, 2); if (status != SDVO_CMD_STATUS_SUCCESS) { DRM_DEBUG_KMS("Incorrect SDVO get hue\n"); @@ -2729,17 +2729,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) } if (sdvo_priv->is_tv || sdvo_priv->is_lvds) { if (sdvo_data.brightness) { - intel_sdvo_write_cmd(intel_output, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_MAX_BRIGHTNESS, NULL, 0); - status = intel_sdvo_read_response(intel_output, + status = intel_sdvo_read_response(intel_encoder, &data_value, 4); if (status != SDVO_CMD_STATUS_SUCCESS) { DRM_DEBUG_KMS("Incorrect SDVO Max bright\n"); return; } - intel_sdvo_write_cmd(intel_output, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_BRIGHTNESS, NULL, 0); - status = intel_sdvo_read_response(intel_output, + status = intel_sdvo_read_response(intel_encoder, &response, 2); if (status != SDVO_CMD_STATUS_SUCCESS) { DRM_DEBUG_KMS("Incorrect SDVO get brigh\n"); @@ -2768,40 +2768,40 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) { struct drm_i915_private *dev_priv = dev->dev_private; struct drm_connector *connector; - struct intel_output *intel_output; + struct intel_encoder *intel_encoder; struct intel_sdvo_priv *sdvo_priv; u8 ch[0x40]; int i; - intel_output = kcalloc(sizeof(struct intel_output)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL); - if (!intel_output) { + intel_encoder = kcalloc(sizeof(struct intel_encoder)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL); + if (!intel_encoder) { return false; } - sdvo_priv = (struct intel_sdvo_priv *)(intel_output + 1); + sdvo_priv = (struct intel_sdvo_priv *)(intel_encoder + 1); sdvo_priv->output_device = output_device; - intel_output->dev_priv = sdvo_priv; - intel_output->type = INTEL_OUTPUT_SDVO; + intel_encoder->dev_priv = sdvo_priv; + intel_encoder->type = INTEL_OUTPUT_SDVO; /* setup the DDC bus. */ if (output_device == SDVOB) - intel_output->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB"); + intel_encoder->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB"); else - intel_output->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC"); + intel_encoder->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC"); - if (!intel_output->i2c_bus) + if (!intel_encoder->i2c_bus) goto err_inteloutput; sdvo_priv->slave_addr = intel_sdvo_get_slave_addr(dev, output_device); /* Save the bit-banging i2c functionality for use by the DDC wrapper */ - intel_sdvo_i2c_bit_algo.functionality = intel_output->i2c_bus->algo->functionality; + intel_sdvo_i2c_bit_algo.functionality = intel_encoder->i2c_bus->algo->functionality; /* Read the regs to test if we can talk to the device */ for (i = 0; i < 0x40; i++) { - if (!intel_sdvo_read_byte(intel_output, i, &ch[i])) { + if (!intel_sdvo_read_byte(intel_encoder, i, &ch[i])) { DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n", output_device == SDVOB ? 'B' : 'C'); goto err_i2c; @@ -2810,27 +2810,27 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) /* setup the DDC bus. */ if (output_device == SDVOB) { - intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS"); + intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS"); sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA, "SDVOB/VGA DDC BUS"); dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS; } else { - intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS"); + intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS"); sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA, "SDVOC/VGA DDC BUS"); dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS; } - if (intel_output->ddc_bus == NULL) + if (intel_encoder->ddc_bus == NULL) goto err_i2c; /* Wrap with our custom algo which switches to DDC mode */ - intel_output->ddc_bus->algo = &intel_sdvo_i2c_bit_algo; + intel_encoder->ddc_bus->algo = &intel_sdvo_i2c_bit_algo; /* In default case sdvo lvds is false */ - intel_sdvo_get_capabilities(intel_output, &sdvo_priv->caps); + intel_sdvo_get_capabilities(intel_encoder, &sdvo_priv->caps); - if (intel_sdvo_output_setup(intel_output, + if (intel_sdvo_output_setup(intel_encoder, sdvo_priv->caps.output_flags) != true) { DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n", output_device == SDVOB ? 'B' : 'C'); @@ -2838,7 +2838,7 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) } - connector = &intel_output->base; + connector = &intel_encoder->base; drm_connector_init(dev, connector, &intel_sdvo_connector_funcs, connector->connector_type); @@ -2847,12 +2847,12 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) connector->doublescan_allowed = 0; connector->display_info.subpixel_order = SubPixelHorizontalRGB; - drm_encoder_init(dev, &intel_output->enc, - &intel_sdvo_enc_funcs, intel_output->enc.encoder_type); + drm_encoder_init(dev, &intel_encoder->enc, + &intel_sdvo_enc_funcs, intel_encoder->enc.encoder_type); - drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs); + drm_encoder_helper_add(&intel_encoder->enc, &intel_sdvo_helper_funcs); - drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); + drm_mode_connector_attach_encoder(&intel_encoder->base, &intel_encoder->enc); if (sdvo_priv->is_tv) intel_sdvo_tv_create_property(connector); @@ -2864,9 +2864,9 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) intel_sdvo_select_ddc_bus(sdvo_priv); /* Set the input timing to the screen. Assume always input 0. */ - intel_sdvo_set_target_input(intel_output, true, false); + intel_sdvo_set_target_input(intel_encoder, true, false); - intel_sdvo_get_input_pixel_clock_range(intel_output, + intel_sdvo_get_input_pixel_clock_range(intel_encoder, &sdvo_priv->pixel_clock_min, &sdvo_priv->pixel_clock_max); @@ -2893,12 +2893,12 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) err_i2c: if (sdvo_priv->analog_ddc_bus != NULL) intel_i2c_destroy(sdvo_priv->analog_ddc_bus); - if (intel_output->ddc_bus != NULL) - intel_i2c_destroy(intel_output->ddc_bus); - if (intel_output->i2c_bus != NULL) - intel_i2c_destroy(intel_output->i2c_bus); + if (intel_encoder->ddc_bus != NULL) + intel_i2c_destroy(intel_encoder->ddc_bus); + if (intel_encoder->i2c_bus != NULL) + intel_i2c_destroy(intel_encoder->i2c_bus); err_inteloutput: - kfree(intel_output); + kfree(intel_encoder); return false; } diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index 552ec11..d7d39b2 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c @@ -921,8 +921,8 @@ intel_tv_save(struct drm_connector *connector) { struct drm_device *dev = connector->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output = to_intel_output(connector); - struct intel_tv_priv *tv_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; int i; tv_priv->save_TV_H_CTL_1 = I915_READ(TV_H_CTL_1); @@ -971,8 +971,8 @@ intel_tv_restore(struct drm_connector *connector) { struct drm_device *dev = connector->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_output *intel_output = to_intel_output(connector); - struct intel_tv_priv *tv_priv = intel_output->dev_priv; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; struct drm_crtc *crtc = connector->encoder->crtc; struct intel_crtc *intel_crtc; int i; @@ -1068,9 +1068,9 @@ intel_tv_mode_lookup (char *tv_format) } static const struct tv_mode * -intel_tv_mode_find (struct intel_output *intel_output) +intel_tv_mode_find (struct intel_encoder *intel_encoder) { - struct intel_tv_priv *tv_priv = intel_output->dev_priv; + struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; return intel_tv_mode_lookup(tv_priv->tv_format); } @@ -1078,8 +1078,8 @@ intel_tv_mode_find (struct intel_output *intel_output) static enum drm_mode_status intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { - struct intel_output *intel_output = to_intel_output(connector); - const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output); + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); /* Ensure TV refresh is close to desired refresh */ if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000) @@ -1095,8 +1095,8 @@ intel_tv_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, { struct drm_device *dev = encoder->dev; struct drm_mode_config *drm_config = &dev->mode_config; - struct intel_output *intel_output = enc_to_intel_output(encoder); - const struct tv_mode *tv_mode = intel_tv_mode_find (intel_output); + struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); + const struct tv_mode *tv_mode = intel_tv_mode_find (intel_encoder); struct drm_encoder *other_encoder; if (!tv_mode) @@ -1121,9 +1121,9 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_i915_private *dev_priv = dev->dev_private; struct drm_crtc *crtc = encoder->crtc; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct intel_output *intel_output = enc_to_intel_output(encoder); - struct intel_tv_priv *tv_priv = intel_output->dev_priv; - const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output); + struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); + struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; + const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); u32 tv_ctl; u32 hctl1, hctl2, hctl3; u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7; @@ -1360,9 +1360,9 @@ static const struct drm_display_mode reported_modes[] = { * \return false if TV is disconnected. */ static int -intel_tv_detect_type (struct drm_crtc *crtc, struct intel_output *intel_output) +intel_tv_detect_type (struct drm_crtc *crtc, struct intel_encoder *intel_encoder) { - struct drm_encoder *encoder = &intel_output->enc; + struct drm_encoder *encoder = &intel_encoder->enc; struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; unsigned long irqflags; @@ -1441,9 +1441,9 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct intel_output *intel_output) */ static void intel_tv_find_better_format(struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); - struct intel_tv_priv *tv_priv = intel_output->dev_priv; - const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output); + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; + const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); int i; if ((tv_priv->type == DRM_MODE_CONNECTOR_Component) == @@ -1475,9 +1475,9 @@ intel_tv_detect(struct drm_connector *connector) { struct drm_crtc *crtc; struct drm_display_mode mode; - struct intel_output *intel_output = to_intel_output(connector); - struct intel_tv_priv *tv_priv = intel_output->dev_priv; - struct drm_encoder *encoder = &intel_output->enc; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; + struct drm_encoder *encoder = &intel_encoder->enc; int dpms_mode; int type = tv_priv->type; @@ -1485,12 +1485,12 @@ intel_tv_detect(struct drm_connector *connector) drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V); if (encoder->crtc && encoder->crtc->enabled) { - type = intel_tv_detect_type(encoder->crtc, intel_output); + type = intel_tv_detect_type(encoder->crtc, intel_encoder); } else { - crtc = intel_get_load_detect_pipe(intel_output, &mode, &dpms_mode); + crtc = intel_get_load_detect_pipe(intel_encoder, &mode, &dpms_mode); if (crtc) { - type = intel_tv_detect_type(crtc, intel_output); - intel_release_load_detect_pipe(intel_output, dpms_mode); + type = intel_tv_detect_type(crtc, intel_encoder); + intel_release_load_detect_pipe(intel_encoder, dpms_mode); } else type = -1; } @@ -1525,8 +1525,8 @@ static void intel_tv_chose_preferred_modes(struct drm_connector *connector, struct drm_display_mode *mode_ptr) { - struct intel_output *intel_output = to_intel_output(connector); - const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output); + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480) mode_ptr->type |= DRM_MODE_TYPE_PREFERRED; @@ -1550,8 +1550,8 @@ static int intel_tv_get_modes(struct drm_connector *connector) { struct drm_display_mode *mode_ptr; - struct intel_output *intel_output = to_intel_output(connector); - const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output); + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); int j, count = 0; u64 tmp; @@ -1604,11 +1604,11 @@ intel_tv_get_modes(struct drm_connector *connector) static void intel_tv_destroy (struct drm_connector *connector) { - struct intel_output *intel_output = to_intel_output(connector); + struct intel_encoder *intel_encoder = to_intel_encoder(connector); drm_sysfs_connector_remove(connector); drm_connector_cleanup(connector); - kfree(intel_output); + kfree(intel_encoder); } @@ -1617,9 +1617,9 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop uint64_t val) { struct drm_device *dev = connector->dev; - struct intel_output *intel_output = to_intel_output(connector); - struct intel_tv_priv *tv_priv = intel_output->dev_priv; - struct drm_encoder *encoder = &intel_output->enc; + struct intel_encoder *intel_encoder = to_intel_encoder(connector); + struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; + struct drm_encoder *encoder = &intel_encoder->enc; struct drm_crtc *crtc = encoder->crtc; int ret = 0; bool changed = false; @@ -1740,7 +1740,7 @@ intel_tv_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct drm_connector *connector; - struct intel_output *intel_output; + struct intel_encoder *intel_encoder; struct intel_tv_priv *tv_priv; u32 tv_dac_on, tv_dac_off, save_tv_dac; char **tv_format_names; @@ -1780,28 +1780,28 @@ intel_tv_init(struct drm_device *dev) (tv_dac_off & TVDAC_STATE_CHG_EN) != 0) return; - intel_output = kzalloc(sizeof(struct intel_output) + + intel_encoder = kzalloc(sizeof(struct intel_encoder) + sizeof(struct intel_tv_priv), GFP_KERNEL); - if (!intel_output) { + if (!intel_encoder) { return; } - connector = &intel_output->base; + connector = &intel_encoder->base; drm_connector_init(dev, connector, &intel_tv_connector_funcs, DRM_MODE_CONNECTOR_SVIDEO); - drm_encoder_init(dev, &intel_output->enc, &intel_tv_enc_funcs, + drm_encoder_init(dev, &intel_encoder->enc, &intel_tv_enc_funcs, DRM_MODE_ENCODER_TVDAC); - drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); - tv_priv = (struct intel_tv_priv *)(intel_output + 1); - intel_output->type = INTEL_OUTPUT_TVOUT; - intel_output->crtc_mask = (1 << 0) | (1 << 1); - intel_output->clone_mask = (1 << INTEL_TV_CLONE_BIT); - intel_output->enc.possible_crtcs = ((1 << 0) | (1 << 1)); - intel_output->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT); - intel_output->dev_priv = tv_priv; + drm_mode_connector_attach_encoder(&intel_encoder->base, &intel_encoder->enc); + tv_priv = (struct intel_tv_priv *)(intel_encoder + 1); + intel_encoder->type = INTEL_OUTPUT_TVOUT; + intel_encoder->crtc_mask = (1 << 0) | (1 << 1); + intel_encoder->clone_mask = (1 << INTEL_TV_CLONE_BIT); + intel_encoder->enc.possible_crtcs = ((1 << 0) | (1 << 1)); + intel_encoder->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT); + intel_encoder->dev_priv = tv_priv; tv_priv->type = DRM_MODE_CONNECTOR_Unknown; /* BIOS margin values */ @@ -1812,7 +1812,7 @@ intel_tv_init(struct drm_device *dev) tv_priv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL); - drm_encoder_helper_add(&intel_output->enc, &intel_tv_helper_funcs); + drm_encoder_helper_add(&intel_encoder->enc, &intel_tv_helper_funcs); drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs); connector->interlace_allowed = false; connector->doublescan_allowed = false; -- cgit v0.10.2 From c751ce4f52b11ea93764a7cd44e6ae9c098d361b Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 25 Mar 2010 11:48:48 -0700 Subject: drm/i915: Rename many remaining uses of "output" to encoder or connector. Signed-off-by: Eric Anholt diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 2595c4c..34d2652 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -754,8 +754,8 @@ bool intel_pipe_has_type (struct drm_crtc *crtc, int type) return false; } -struct drm_connector * -intel_pipe_get_output (struct drm_crtc *crtc) +static struct drm_connector * +intel_pipe_get_connector (struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; struct drm_mode_config *mode_config = &dev->mode_config; @@ -2916,7 +2916,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, int dspsize_reg = (plane == 0) ? DSPASIZE : DSPBSIZE; int dsppos_reg = (plane == 0) ? DSPAPOS : DSPBPOS; int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC; - int refclk, num_outputs = 0; + int refclk, num_connectors = 0; intel_clock_t clock, reduced_clock; u32 dpll = 0, fp = 0, fp2 = 0, dspcntr, pipeconf; bool ok, has_reduced_clock = false, is_sdvo = false, is_dvo = false; @@ -2974,10 +2974,10 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, break; } - num_outputs++; + num_connectors++; } - if (is_lvds && dev_priv->lvds_use_ssc && num_outputs < 2) { + if (is_lvds && dev_priv->lvds_use_ssc && num_connectors < 2) { refclk = dev_priv->lvds_ssc_freq * 1000; DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n", refclk / 1000); @@ -3048,7 +3048,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, if (is_edp) { struct drm_connector *edp; target_clock = mode->clock; - edp = intel_pipe_get_output(crtc); + edp = intel_pipe_get_connector(crtc); intel_edp_link_config(to_intel_encoder(edp), &lane, &link_bw); } else { @@ -3230,7 +3230,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, /* XXX: just matching BIOS for now */ /* dpll |= PLL_REF_INPUT_TVCLKINBC; */ dpll |= 3; - else if (is_lvds && dev_priv->lvds_use_ssc && num_outputs < 2) + else if (is_lvds && dev_priv->lvds_use_ssc && num_connectors < 2) dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN; else dpll |= PLL_REF_INPUT_DREFCLK; @@ -3654,9 +3654,9 @@ static void intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, * detection. * * It will be up to the load-detect code to adjust the pipe as appropriate for - * its requirements. The pipe will be connected to no other outputs. + * its requirements. The pipe will be connected to no other encoders. * - * Currently this code will only succeed if there is a pipe with no outputs + * Currently this code will only succeed if there is a pipe with no encoders * configured for it. In the future, it could choose to temporarily disable * some outputs to free up a pipe for its use. * @@ -3770,7 +3770,7 @@ void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder, int dpm drm_helper_disable_unused_functions(dev); } - /* Switch crtc and output back off if necessary */ + /* Switch crtc and encoder back off if necessary */ if (crtc->enabled && dpms_mode != DRM_MODE_DPMS_ON) { if (encoder->crtc == crtc) encoder_funcs->dpms(encoder, dpms_mode); diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index ea6de3b..a5b049f 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -53,7 +53,7 @@ struct intel_sdvo_priv { u8 slave_addr; /* Register for the SDVO device: SDVOB or SDVOC */ - int output_device; + int sdvo_reg; /* Active outputs controlled by this SDVO output */ uint16_t controlled_output; @@ -123,7 +123,7 @@ struct intel_sdvo_priv { */ struct intel_sdvo_encode encode; - /* DDC bus used by this SDVO output */ + /* DDC bus used by this SDVO encoder */ uint8_t ddc_bus; /* Mac mini hack -- use the same DDC as the analog connector */ @@ -176,7 +176,7 @@ static void intel_sdvo_write_sdvox(struct intel_encoder *intel_encoder, u32 val) u32 bval = val, cval = val; int i; - if (sdvo_priv->output_device == SDVOB) { + if (sdvo_priv->sdvo_reg == SDVOB) { cval = I915_READ(SDVOC); } else { bval = I915_READ(SDVOB); @@ -352,8 +352,8 @@ static const struct _sdvo_cmd_name { SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_DATA), }; -#define SDVO_NAME(dev_priv) ((dev_priv)->output_device == SDVOB ? "SDVOB" : "SDVOC") -#define SDVO_PRIV(output) ((struct intel_sdvo_priv *) (output)->dev_priv) +#define SDVO_NAME(dev_priv) ((dev_priv)->sdvo_reg == SDVOB ? "SDVOB" : "SDVOC") +#define SDVO_PRIV(encoder) ((struct intel_sdvo_priv *) (encoder)->dev_priv) static void intel_sdvo_debug_write(struct intel_encoder *intel_encoder, u8 cmd, void *args, int args_len) @@ -712,13 +712,13 @@ static bool intel_sdvo_set_output_timing(struct intel_encoder *intel_encoder, } static bool -intel_sdvo_create_preferred_input_timing(struct intel_encoder *output, +intel_sdvo_create_preferred_input_timing(struct intel_encoder *intel_encoder, uint16_t clock, uint16_t width, uint16_t height) { struct intel_sdvo_preferred_input_timing_args args; - struct intel_sdvo_priv *sdvo_priv = output->dev_priv; + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; uint8_t status; memset(&args, 0, sizeof(args)); @@ -732,32 +732,33 @@ intel_sdvo_create_preferred_input_timing(struct intel_encoder *output, sdvo_priv->sdvo_lvds_fixed_mode->vdisplay != height)) args.scaled = 1; - intel_sdvo_write_cmd(output, SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING, + intel_sdvo_write_cmd(intel_encoder, + SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING, &args, sizeof(args)); - status = intel_sdvo_read_response(output, NULL, 0); + status = intel_sdvo_read_response(intel_encoder, NULL, 0); if (status != SDVO_CMD_STATUS_SUCCESS) return false; return true; } -static bool intel_sdvo_get_preferred_input_timing(struct intel_encoder *output, +static bool intel_sdvo_get_preferred_input_timing(struct intel_encoder *intel_encoder, struct intel_sdvo_dtd *dtd) { bool status; - intel_sdvo_write_cmd(output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1, NULL, 0); - status = intel_sdvo_read_response(output, &dtd->part1, + status = intel_sdvo_read_response(intel_encoder, &dtd->part1, sizeof(dtd->part1)); if (status != SDVO_CMD_STATUS_SUCCESS) return false; - intel_sdvo_write_cmd(output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2, NULL, 0); - status = intel_sdvo_read_response(output, &dtd->part2, + status = intel_sdvo_read_response(intel_encoder, &dtd->part2, sizeof(dtd->part2)); if (status != SDVO_CMD_STATUS_SUCCESS) return false; @@ -876,13 +877,13 @@ static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode, mode->flags |= DRM_MODE_FLAG_PVSYNC; } -static bool intel_sdvo_get_supp_encode(struct intel_encoder *output, +static bool intel_sdvo_get_supp_encode(struct intel_encoder *intel_encoder, struct intel_sdvo_encode *encode) { uint8_t status; - intel_sdvo_write_cmd(output, SDVO_CMD_GET_SUPP_ENCODE, NULL, 0); - status = intel_sdvo_read_response(output, encode, sizeof(*encode)); + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SUPP_ENCODE, NULL, 0); + status = intel_sdvo_read_response(intel_encoder, encode, sizeof(*encode)); if (status != SDVO_CMD_STATUS_SUCCESS) { /* non-support means DVI */ memset(encode, 0, sizeof(*encode)); return false; @@ -891,29 +892,30 @@ static bool intel_sdvo_get_supp_encode(struct intel_encoder *output, return true; } -static bool intel_sdvo_set_encode(struct intel_encoder *output, uint8_t mode) +static bool intel_sdvo_set_encode(struct intel_encoder *intel_encoder, + uint8_t mode) { uint8_t status; - intel_sdvo_write_cmd(output, SDVO_CMD_SET_ENCODE, &mode, 1); - status = intel_sdvo_read_response(output, NULL, 0); + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ENCODE, &mode, 1); + status = intel_sdvo_read_response(intel_encoder, NULL, 0); return (status == SDVO_CMD_STATUS_SUCCESS); } -static bool intel_sdvo_set_colorimetry(struct intel_encoder *output, +static bool intel_sdvo_set_colorimetry(struct intel_encoder *intel_encoder, uint8_t mode) { uint8_t status; - intel_sdvo_write_cmd(output, SDVO_CMD_SET_COLORIMETRY, &mode, 1); - status = intel_sdvo_read_response(output, NULL, 0); + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_COLORIMETRY, &mode, 1); + status = intel_sdvo_read_response(intel_encoder, NULL, 0); return (status == SDVO_CMD_STATUS_SUCCESS); } #if 0 -static void intel_sdvo_dump_hdmi_buf(struct intel_encoder *output) +static void intel_sdvo_dump_hdmi_buf(struct intel_encoder *intel_encoder) { int i, j; uint8_t set_buf_index[2]; @@ -922,43 +924,45 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_encoder *output) uint8_t buf[48]; uint8_t *pos; - intel_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_AV_SPLIT, NULL, 0); - intel_sdvo_read_response(output, &av_split, 1); + intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_AV_SPLIT, NULL, 0); + intel_sdvo_read_response(encoder, &av_split, 1); for (i = 0; i <= av_split; i++) { set_buf_index[0] = i; set_buf_index[1] = 0; - intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_INDEX, + intel_sdvo_write_cmd(encoder, SDVO_CMD_SET_HBUF_INDEX, set_buf_index, 2); - intel_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_INFO, NULL, 0); - intel_sdvo_read_response(output, &buf_size, 1); + intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_INFO, NULL, 0); + intel_sdvo_read_response(encoder, &buf_size, 1); pos = buf; for (j = 0; j <= buf_size; j += 8) { - intel_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_DATA, + intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_DATA, NULL, 0); - intel_sdvo_read_response(output, pos, 8); + intel_sdvo_read_response(encoder, pos, 8); pos += 8; } } } #endif -static void intel_sdvo_set_hdmi_buf(struct intel_encoder *output, int index, - uint8_t *data, int8_t size, uint8_t tx_rate) +static void intel_sdvo_set_hdmi_buf(struct intel_encoder *intel_encoder, + int index, + uint8_t *data, int8_t size, uint8_t tx_rate) { uint8_t set_buf_index[2]; set_buf_index[0] = index; set_buf_index[1] = 0; - intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_INDEX, set_buf_index, 2); + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_INDEX, + set_buf_index, 2); for (; size > 0; size -= 8) { - intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_DATA, data, 8); + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_DATA, data, 8); data += 8; } - intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1); + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1); } static uint8_t intel_sdvo_calc_hbuf_csum(uint8_t *data, uint8_t size) @@ -1033,7 +1037,7 @@ struct dip_infoframe { } __attribute__ ((packed)) u; } __attribute__((packed)); -static void intel_sdvo_set_avi_infoframe(struct intel_encoder *output, +static void intel_sdvo_set_avi_infoframe(struct intel_encoder *intel_encoder, struct drm_display_mode * mode) { struct dip_infoframe avi_if = { @@ -1044,15 +1048,16 @@ static void intel_sdvo_set_avi_infoframe(struct intel_encoder *output, avi_if.checksum = intel_sdvo_calc_hbuf_csum((uint8_t *)&avi_if, 4 + avi_if.len); - intel_sdvo_set_hdmi_buf(output, 1, (uint8_t *)&avi_if, 4 + avi_if.len, + intel_sdvo_set_hdmi_buf(intel_encoder, 1, (uint8_t *)&avi_if, + 4 + avi_if.len, SDVO_HBUF_TX_VSYNC); } -static void intel_sdvo_set_tv_format(struct intel_encoder *output) +static void intel_sdvo_set_tv_format(struct intel_encoder *intel_encoder) { struct intel_sdvo_tv_format format; - struct intel_sdvo_priv *sdvo_priv = output->dev_priv; + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; uint32_t format_map, i; uint8_t status; @@ -1065,10 +1070,10 @@ static void intel_sdvo_set_tv_format(struct intel_encoder *output) memcpy(&format, &format_map, sizeof(format_map) > sizeof(format) ? sizeof(format) : sizeof(format_map)); - intel_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, &format_map, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TV_FORMAT, &format_map, sizeof(format)); - status = intel_sdvo_read_response(output, NULL, 0); + status = intel_sdvo_read_response(intel_encoder, NULL, 0); if (status != SDVO_CMD_STATUS_SUCCESS) DRM_DEBUG_KMS("%s: Failed to set TV format\n", SDVO_NAME(sdvo_priv)); @@ -1078,8 +1083,8 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { - struct intel_encoder *output = enc_to_intel_encoder(encoder); - struct intel_sdvo_priv *dev_priv = output->dev_priv; + struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); + struct intel_sdvo_priv *dev_priv = intel_encoder->dev_priv; if (dev_priv->is_tv) { struct intel_sdvo_dtd output_dtd; @@ -1094,22 +1099,22 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, /* Set output timings */ intel_sdvo_get_dtd_from_mode(&output_dtd, mode); - intel_sdvo_set_target_output(output, + intel_sdvo_set_target_output(intel_encoder, dev_priv->controlled_output); - intel_sdvo_set_output_timing(output, &output_dtd); + intel_sdvo_set_output_timing(intel_encoder, &output_dtd); /* Set the input timing to the screen. Assume always input 0. */ - intel_sdvo_set_target_input(output, true, false); + intel_sdvo_set_target_input(intel_encoder, true, false); - success = intel_sdvo_create_preferred_input_timing(output, + success = intel_sdvo_create_preferred_input_timing(intel_encoder, mode->clock / 10, mode->hdisplay, mode->vdisplay); if (success) { struct intel_sdvo_dtd input_dtd; - intel_sdvo_get_preferred_input_timing(output, + intel_sdvo_get_preferred_input_timing(intel_encoder, &input_dtd); intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags; @@ -1132,16 +1137,16 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, intel_sdvo_get_dtd_from_mode(&output_dtd, dev_priv->sdvo_lvds_fixed_mode); - intel_sdvo_set_target_output(output, + intel_sdvo_set_target_output(intel_encoder, dev_priv->controlled_output); - intel_sdvo_set_output_timing(output, &output_dtd); + intel_sdvo_set_output_timing(intel_encoder, &output_dtd); /* Set the input timing to the screen. Assume always input 0. */ - intel_sdvo_set_target_input(output, true, false); + intel_sdvo_set_target_input(intel_encoder, true, false); success = intel_sdvo_create_preferred_input_timing( - output, + intel_encoder, mode->clock / 10, mode->hdisplay, mode->vdisplay); @@ -1149,7 +1154,7 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, if (success) { struct intel_sdvo_dtd input_dtd; - intel_sdvo_get_preferred_input_timing(output, + intel_sdvo_get_preferred_input_timing(intel_encoder, &input_dtd); intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags; @@ -1181,8 +1186,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, struct drm_i915_private *dev_priv = dev->dev_private; struct drm_crtc *crtc = encoder->crtc; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct intel_encoder *output = enc_to_intel_encoder(encoder); - struct intel_sdvo_priv *sdvo_priv = output->dev_priv; + struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); + struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; u32 sdvox = 0; int sdvo_pixel_multiply; struct intel_sdvo_in_out_map in_out; @@ -1201,12 +1206,12 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, in_out.in0 = sdvo_priv->controlled_output; in_out.in1 = 0; - intel_sdvo_write_cmd(output, SDVO_CMD_SET_IN_OUT_MAP, + intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_IN_OUT_MAP, &in_out, sizeof(in_out)); - status = intel_sdvo_read_response(output, NULL, 0); + status = intel_sdvo_read_response(intel_encoder, NULL, 0); if (sdvo_priv->is_hdmi) { - intel_sdvo_set_avi_infoframe(output, mode); + intel_sdvo_set_avi_infoframe(intel_encoder, mode); sdvox |= SDVO_AUDIO_ENABLE; } @@ -1223,16 +1228,16 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, */ if (!sdvo_priv->is_tv && !sdvo_priv->is_lvds) { /* Set the output timing to the screen */ - intel_sdvo_set_target_output(output, + intel_sdvo_set_target_output(intel_encoder, sdvo_priv->controlled_output); - intel_sdvo_set_output_timing(output, &input_dtd); + intel_sdvo_set_output_timing(intel_encoder, &input_dtd); } /* Set the input timing to the screen. Assume always input 0. */ - intel_sdvo_set_target_input(output, true, false); + intel_sdvo_set_target_input(intel_encoder, true, false); if (sdvo_priv->is_tv) - intel_sdvo_set_tv_format(output); + intel_sdvo_set_tv_format(intel_encoder); /* We would like to use intel_sdvo_create_preferred_input_timing() to * provide the device with a timing it can support, if it supports that @@ -1240,29 +1245,29 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, * output the preferred timing, and we don't support that currently. */ #if 0 - success = intel_sdvo_create_preferred_input_timing(output, clock, + success = intel_sdvo_create_preferred_input_timing(encoder, clock, width, height); if (success) { struct intel_sdvo_dtd *input_dtd; - intel_sdvo_get_preferred_input_timing(output, &input_dtd); - intel_sdvo_set_input_timing(output, &input_dtd); + intel_sdvo_get_preferred_input_timing(encoder, &input_dtd); + intel_sdvo_set_input_timing(encoder, &input_dtd); } #else - intel_sdvo_set_input_timing(output, &input_dtd); + intel_sdvo_set_input_timing(intel_encoder, &input_dtd); #endif switch (intel_sdvo_get_pixel_multiplier(mode)) { case 1: - intel_sdvo_set_clock_rate_mult(output, + intel_sdvo_set_clock_rate_mult(intel_encoder, SDVO_CLOCK_RATE_MULT_1X); break; case 2: - intel_sdvo_set_clock_rate_mult(output, + intel_sdvo_set_clock_rate_mult(intel_encoder, SDVO_CLOCK_RATE_MULT_2X); break; case 4: - intel_sdvo_set_clock_rate_mult(output, + intel_sdvo_set_clock_rate_mult(intel_encoder, SDVO_CLOCK_RATE_MULT_4X); break; } @@ -1273,8 +1278,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, SDVO_VSYNC_ACTIVE_HIGH | SDVO_HSYNC_ACTIVE_HIGH; } else { - sdvox |= I915_READ(sdvo_priv->output_device); - switch (sdvo_priv->output_device) { + sdvox |= I915_READ(sdvo_priv->sdvo_reg); + switch (sdvo_priv->sdvo_reg) { case SDVOB: sdvox &= SDVOB_PRESERVE_MASK; break; @@ -1298,7 +1303,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, if (sdvo_priv->sdvo_flags & SDVO_NEED_TO_STALL) sdvox |= SDVO_STALL_SELECT; - intel_sdvo_write_sdvox(output, sdvox); + intel_sdvo_write_sdvox(intel_encoder, sdvox); } static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) @@ -1315,7 +1320,7 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) intel_sdvo_set_encoder_power_state(intel_encoder, mode); if (mode == DRM_MODE_DPMS_OFF) { - temp = I915_READ(sdvo_priv->output_device); + temp = I915_READ(sdvo_priv->sdvo_reg); if ((temp & SDVO_ENABLE) != 0) { intel_sdvo_write_sdvox(intel_encoder, temp & ~SDVO_ENABLE); } @@ -1325,7 +1330,7 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) int i; u8 status; - temp = I915_READ(sdvo_priv->output_device); + temp = I915_READ(sdvo_priv->sdvo_reg); if ((temp & SDVO_ENABLE) == 0) intel_sdvo_write_sdvox(intel_encoder, temp | SDVO_ENABLE); for (i = 0; i < 2; i++) @@ -1388,7 +1393,7 @@ static void intel_sdvo_save(struct drm_connector *connector) /* XXX: Save TV format/enhancements. */ } - sdvo_priv->save_SDVOX = I915_READ(sdvo_priv->output_device); + sdvo_priv->save_SDVOX = I915_READ(sdvo_priv->sdvo_reg); } static void intel_sdvo_restore(struct drm_connector *connector) @@ -1499,10 +1504,10 @@ struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB) sdvo = iout->dev_priv; - if (sdvo->output_device == SDVOB && sdvoB) + if (sdvo->sdvo_reg == SDVOB && sdvoB) return connector; - if (sdvo->output_device == SDVOC && !sdvoB) + if (sdvo->sdvo_reg == SDVOC && !sdvoB) return connector; } @@ -2248,12 +2253,12 @@ static struct i2c_algorithm intel_sdvo_i2c_bit_algo = { }; static u8 -intel_sdvo_get_slave_addr(struct drm_device *dev, int output_device) +intel_sdvo_get_slave_addr(struct drm_device *dev, int sdvo_reg) { struct drm_i915_private *dev_priv = dev->dev_private; struct sdvo_device_mapping *my_mapping, *other_mapping; - if (output_device == SDVOB) { + if (sdvo_reg == SDVOB) { my_mapping = &dev_priv->sdvo_mappings[0]; other_mapping = &dev_priv->sdvo_mappings[1]; } else { @@ -2278,7 +2283,7 @@ intel_sdvo_get_slave_addr(struct drm_device *dev, int output_device) /* No SDVO device info is found for another DVO port, * so use mapping assumption we had before BIOS parsing. */ - if (output_device == SDVOB) + if (sdvo_reg == SDVOB) return 0x70; else return 0x72; @@ -2764,7 +2769,7 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) return; } -bool intel_sdvo_init(struct drm_device *dev, int output_device) +bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) { struct drm_i915_private *dev_priv = dev->dev_private; struct drm_connector *connector; @@ -2780,13 +2785,13 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) } sdvo_priv = (struct intel_sdvo_priv *)(intel_encoder + 1); - sdvo_priv->output_device = output_device; + sdvo_priv->sdvo_reg = sdvo_reg; intel_encoder->dev_priv = sdvo_priv; intel_encoder->type = INTEL_OUTPUT_SDVO; /* setup the DDC bus. */ - if (output_device == SDVOB) + if (sdvo_reg == SDVOB) intel_encoder->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB"); else intel_encoder->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC"); @@ -2794,7 +2799,7 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) if (!intel_encoder->i2c_bus) goto err_inteloutput; - sdvo_priv->slave_addr = intel_sdvo_get_slave_addr(dev, output_device); + sdvo_priv->slave_addr = intel_sdvo_get_slave_addr(dev, sdvo_reg); /* Save the bit-banging i2c functionality for use by the DDC wrapper */ intel_sdvo_i2c_bit_algo.functionality = intel_encoder->i2c_bus->algo->functionality; @@ -2803,13 +2808,13 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) for (i = 0; i < 0x40; i++) { if (!intel_sdvo_read_byte(intel_encoder, i, &ch[i])) { DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n", - output_device == SDVOB ? 'B' : 'C'); + sdvo_reg == SDVOB ? 'B' : 'C'); goto err_i2c; } } /* setup the DDC bus. */ - if (output_device == SDVOB) { + if (sdvo_reg == SDVOB) { intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS"); sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA, "SDVOB/VGA DDC BUS"); @@ -2833,7 +2838,7 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) if (intel_sdvo_output_setup(intel_encoder, sdvo_priv->caps.output_flags) != true) { DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n", - output_device == SDVOB ? 'B' : 'C'); + sdvo_reg == SDVOB ? 'B' : 'C'); goto err_i2c; } -- cgit v0.10.2 From 7c9f757319ccf7a47ce167b86eda671c87b5b917 Mon Sep 17 00:00:00 2001 From: Jon Maloy Date: Thu, 25 Mar 2010 12:40:09 -0700 Subject: TIPC: Removed inactive maintainer Signed-off-by: Jon Maloy Signed-off-by: David S. Miller diff --git a/MAINTAINERS b/MAINTAINERS index 449d444..5c99bd6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5423,7 +5423,6 @@ S: Maintained F: sound/soc/codecs/twl4030* TIPC NETWORK LAYER -M: Per Liden M: Jon Maloy M: Allan Stephens L: tipc-discussion@lists.sourceforge.net -- cgit v0.10.2 From 7561e8ca0dfaf6fca3feef982830de3b65300e5b Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 25 Mar 2010 16:48:38 +0000 Subject: NOMMU: Revert 'nommu: get_user_pages(): pin last page on non-page-aligned start' Revert the following patch: commit c08c6e1f54c85fc299cf9f88cf330d6dd28a9a1d Author: Steven J. Magnani Date: Fri Mar 5 13:42:24 2010 -0800 nommu: get_user_pages(): pin last page on non-page-aligned start As it assumes that the mappings begin at the start of pages - something that isn't necessarily true on NOMMU systems. On NOMMU systems, it is possible for a mapping to only occupy part of the page, and not necessarily touch either end of it; in fact it's also possible for multiple non-overlapping mappings to coexist on one page (consider direct mappings of ROMFS files, for example). Signed-off-by: David Howells Acked-by: Steven J. Magnani Signed-off-by: Linus Torvalds diff --git a/mm/nommu.c b/mm/nommu.c index e4b8f4d..089982f 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -146,7 +146,7 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE); for (i = 0; i < nr_pages; i++) { - vma = find_extend_vma(mm, start); + vma = find_vma(mm, start); if (!vma) goto finish_or_fault; @@ -764,7 +764,7 @@ EXPORT_SYMBOL(find_vma); */ struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr) { - return find_vma(mm, addr & PAGE_MASK); + return find_vma(mm, addr); } /* -- cgit v0.10.2 From e1ee65d85904c5dd4b9cea1b15d5e85e20eae8a1 Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 25 Mar 2010 16:48:44 +0000 Subject: NOMMU: Fix __get_user_pages() to pin last page on offset buffers Fix __get_user_pages() to make it pin the last page on a buffer that doesn't begin at the start of a page, but is a multiple of PAGE_SIZE in size. The problem is that __get_user_pages() advances the pointer too much when it iterates to the next page if the page it's currently looking at isn't used from the first byte. This can cause the end of a short VMA to be reached prematurely, resulting in the last page being lost. Signed-off-by: Steven J. Magnani Signed-off-by: David Howells Signed-off-by: Linus Torvalds diff --git a/mm/nommu.c b/mm/nommu.c index 089982f..63fa17d 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -162,7 +162,7 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, } if (vmas) vmas[i] = vma; - start += PAGE_SIZE; + start = (start + PAGE_SIZE) & PAGE_MASK; } return i; -- cgit v0.10.2 From 33f663ff9186da1bcc88dc7830b3a632bd472da5 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Wed, 24 Mar 2010 16:46:52 +0100 Subject: ARM: 5993/1: ARM: Move the outer_cache definitions into a separate file (1/4) To avoid #include collisions with subsequent patches in the series, this patch moves the outer_cache definitions to a separate asm/outercache.h file. Signed-off-by: Catalin Marinas Signed-off-by: Russell King diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h index 72da7e0..0d08d41 100644 --- a/arch/arm/include/asm/cacheflush.h +++ b/arch/arm/include/asm/cacheflush.h @@ -15,6 +15,7 @@ #include #include #include +#include #define CACHE_COLOUR(vaddr) ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT) @@ -219,12 +220,6 @@ struct cpu_cache_fns { void (*dma_flush_range)(const void *, const void *); }; -struct outer_cache_fns { - void (*inv_range)(unsigned long, unsigned long); - void (*clean_range)(unsigned long, unsigned long); - void (*flush_range)(unsigned long, unsigned long); -}; - /* * Select the calling method */ @@ -281,37 +276,6 @@ extern void dmac_flush_range(const void *, const void *); #endif -#ifdef CONFIG_OUTER_CACHE - -extern struct outer_cache_fns outer_cache; - -static inline void outer_inv_range(unsigned long start, unsigned long end) -{ - if (outer_cache.inv_range) - outer_cache.inv_range(start, end); -} -static inline void outer_clean_range(unsigned long start, unsigned long end) -{ - if (outer_cache.clean_range) - outer_cache.clean_range(start, end); -} -static inline void outer_flush_range(unsigned long start, unsigned long end) -{ - if (outer_cache.flush_range) - outer_cache.flush_range(start, end); -} - -#else - -static inline void outer_inv_range(unsigned long start, unsigned long end) -{ } -static inline void outer_clean_range(unsigned long start, unsigned long end) -{ } -static inline void outer_flush_range(unsigned long start, unsigned long end) -{ } - -#endif - /* * Copy user data from/to a page which is mapped into a different * processes address space. Really, we want to allow our "user diff --git a/arch/arm/include/asm/outercache.h b/arch/arm/include/asm/outercache.h new file mode 100644 index 0000000..c8571cb --- /dev/null +++ b/arch/arm/include/asm/outercache.h @@ -0,0 +1,61 @@ +/* + * arch/arm/include/asm/outercache.h + * + * Copyright (C) 2010 ARM Ltd. + * Written by Catalin Marinas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ASM_OUTERCACHE_H +#define __ASM_OUTERCACHE_H + +struct outer_cache_fns { + void (*inv_range)(unsigned long, unsigned long); + void (*clean_range)(unsigned long, unsigned long); + void (*flush_range)(unsigned long, unsigned long); +}; + +#ifdef CONFIG_OUTER_CACHE + +extern struct outer_cache_fns outer_cache; + +static inline void outer_inv_range(unsigned long start, unsigned long end) +{ + if (outer_cache.inv_range) + outer_cache.inv_range(start, end); +} +static inline void outer_clean_range(unsigned long start, unsigned long end) +{ + if (outer_cache.clean_range) + outer_cache.clean_range(start, end); +} +static inline void outer_flush_range(unsigned long start, unsigned long end) +{ + if (outer_cache.flush_range) + outer_cache.flush_range(start, end); +} + +#else + +static inline void outer_inv_range(unsigned long start, unsigned long end) +{ } +static inline void outer_clean_range(unsigned long start, unsigned long end) +{ } +static inline void outer_flush_range(unsigned long start, unsigned long end) +{ } + +#endif + +#endif /* __ASM_OUTERCACHE_H */ -- cgit v0.10.2 From 319f551a0a167b49b5bbb4a9ff4802046a572bc5 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Wed, 24 Mar 2010 16:47:53 +0100 Subject: ARM: 5994/1: ARM: Add outer_cache_fns.sync function pointer (2/4) This patch introduces the outer_cache_fns.sync function pointer together with the OUTER_CACHE_SYNC config option that can be used to drain the write buffer of the outer cache. Signed-off-by: Catalin Marinas Signed-off-by: Russell King diff --git a/arch/arm/include/asm/outercache.h b/arch/arm/include/asm/outercache.h index c8571cb..25f76ba 100644 --- a/arch/arm/include/asm/outercache.h +++ b/arch/arm/include/asm/outercache.h @@ -25,6 +25,9 @@ struct outer_cache_fns { void (*inv_range)(unsigned long, unsigned long); void (*clean_range)(unsigned long, unsigned long); void (*flush_range)(unsigned long, unsigned long); +#ifdef CONFIG_OUTER_CACHE_SYNC + void (*sync)(void); +#endif }; #ifdef CONFIG_OUTER_CACHE @@ -58,4 +61,15 @@ static inline void outer_flush_range(unsigned long start, unsigned long end) #endif +#ifdef CONFIG_OUTER_CACHE_SYNC +static inline void outer_sync(void) +{ + if (outer_cache.sync) + outer_cache.sync(); +} +#else +static inline void outer_sync(void) +{ } +#endif + #endif /* __ASM_OUTERCACHE_H */ diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index c4ed9f9..88a24de 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -736,6 +736,12 @@ config NEEDS_SYSCALL_FOR_CMPXCHG config OUTER_CACHE bool +config OUTER_CACHE_SYNC + bool + help + The outer cache has a outer_cache_fns.sync function pointer + that can be used to drain the write buffer of the outer cache. + config CACHE_FEROCEON_L2 bool "Enable the Feroceon L2 cache controller" depends on ARCH_KIRKWOOD || ARCH_MV78XX0 -- cgit v0.10.2 From 23107c542068b2b94390aa333f6b330af64961e4 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Wed, 24 Mar 2010 16:48:53 +0100 Subject: ARM: 5995/1: ARM: Add L2x0 outer_sync() support (3/4) The L2x0 cache controllers need to explicitly drain their write buffer even for Normal Noncacheable memory accesses. Signed-off-by: Catalin Marinas Signed-off-by: Russell King diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 88a24de..55a2a00 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -763,6 +763,7 @@ config CACHE_L2X0 REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX || ARCH_NOMADIK || ARCH_OMAP4 default y select OUTER_CACHE + select OUTER_CACHE_SYNC help This option enables the L2x0 PrimeCell. diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index 0733463..21ad68b 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c @@ -93,6 +93,15 @@ static inline void l2x0_flush_line(unsigned long addr) } #endif +static void l2x0_cache_sync(void) +{ + unsigned long flags; + + spin_lock_irqsave(&l2x0_lock, flags); + cache_sync(); + spin_unlock_irqrestore(&l2x0_lock, flags); +} + static inline void l2x0_inv_all(void) { unsigned long flags; @@ -225,6 +234,7 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) outer_cache.inv_range = l2x0_inv_range; outer_cache.clean_range = l2x0_clean_range; outer_cache.flush_range = l2x0_flush_range; + outer_cache.sync = l2x0_cache_sync; printk(KERN_INFO "L2X0 cache controller enabled\n"); } -- cgit v0.10.2 From e7c5650f6067f65f8e961394f376d4862808d0d2 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Wed, 24 Mar 2010 16:49:54 +0100 Subject: ARM: 5996/1: ARM: Change the mandatory barriers implementation (4/4) The mandatory barriers (mb, rmb, wmb) are used even on uniprocessor systems for things like ordering Normal Non-cacheable memory accesses with DMA transfer (via Device memory writes). The current implementation uses dmb() for mb() and friends but this is not sufficient. The DMB only ensures the relative ordering of the observability of accesses by other processors or devices acting as masters. In case of DMA transfers started by writes to device memory, the relative ordering is not ensured because accesses to slave ports of a device are not considered observable by the DMB definition. A DSB is required for the data to reach the main memory (even if mapped as Normal Non-cacheable) before the device receives the notification to begin the transfer. Furthermore, some L2 cache controllers (like L2x0 or PL310) buffer stores to Normal Non-cacheable memory and this would need to be drained with the outer_sync() function call. The patch also allows platforms to define their own mandatory barriers implementation by selecting CONFIG_ARCH_HAS_BARRIERS and providing a mach/barriers.h file. Note that the SMP barriers are unchanged (being DMBs as before) since they are only guaranteed to work with Normal Cacheable memory. Signed-off-by: Catalin Marinas Signed-off-by: Russell King diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index ca88e6a..4ace45e 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h @@ -60,6 +60,8 @@ #include #include +#include + #define __exception __attribute__((section(".exception.text"))) struct thread_info; @@ -137,10 +139,12 @@ extern unsigned int user_debug; #define dmb() __asm__ __volatile__ ("" : : : "memory") #endif -#if __LINUX_ARM_ARCH__ >= 7 || defined(CONFIG_SMP) -#define mb() dmb() +#ifdef CONFIG_ARCH_HAS_BARRIERS +#include +#elif __LINUX_ARM_ARCH__ >= 7 || defined(CONFIG_SMP) +#define mb() do { dsb(); outer_sync(); } while (0) #define rmb() dmb() -#define wmb() dmb() +#define wmb() mb() #else #define mb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0) #define rmb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0) @@ -152,9 +156,9 @@ extern unsigned int user_debug; #define smp_rmb() barrier() #define smp_wmb() barrier() #else -#define smp_mb() mb() -#define smp_rmb() rmb() -#define smp_wmb() wmb() +#define smp_mb() dmb() +#define smp_rmb() dmb() +#define smp_wmb() dmb() #endif #define read_barrier_depends() do { } while(0) diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 55a2a00..5bd7c89 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -788,3 +788,9 @@ config ARM_L1_CACHE_SHIFT int default 6 if ARM_L1_CACHE_SHIFT_6 default 5 + +config ARCH_HAS_BARRIERS + bool + help + This option allows the use of custom mandatory barriers + included via the mach/barriers.h file. -- cgit v0.10.2 From 4539282dbc20fe612113c8f267d51a90d46a7f50 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Fri, 26 Mar 2010 11:37:16 +0900 Subject: sh: update the TLB replacement counter for entry wiring. Presently the TLB wiring code depends on MMUCR.URB for working out where to place the wired entry, but fails to take the replacment counter in to consideration. This fixes up the wiring logic and ensures that wired entries remain so. Signed-off-by: Matt Fleming Signed-off-by: Paul Mundt diff --git a/arch/sh/include/cpu-sh4/cpu/mmu_context.h b/arch/sh/include/cpu-sh4/cpu/mmu_context.h index 310ec92..5963124 100644 --- a/arch/sh/include/cpu-sh4/cpu/mmu_context.h +++ b/arch/sh/include/cpu-sh4/cpu/mmu_context.h @@ -30,6 +30,8 @@ #define MMUCR_URB 0x00FC0000 #define MMUCR_URB_SHIFT 18 #define MMUCR_URB_NENTRIES 64 +#define MMUCR_URC 0x0000FC00 +#define MMUCR_URC_SHIFT 10 #if defined(CONFIG_32BIT) && defined(CONFIG_CPU_SUBTYPE_ST40) #define MMUCR_SE (1 << 4) diff --git a/arch/sh/mm/tlb-urb.c b/arch/sh/mm/tlb-urb.c index bb5b909..c92ce20 100644 --- a/arch/sh/mm/tlb-urb.c +++ b/arch/sh/mm/tlb-urb.c @@ -24,13 +24,9 @@ void tlb_wire_entry(struct vm_area_struct *vma, unsigned long addr, pte_t pte) local_irq_save(flags); - /* Load the entry into the TLB */ - __update_tlb(vma, addr, pte); - - /* ... and wire it up. */ status = __raw_readl(MMUCR); urb = (status & MMUCR_URB) >> MMUCR_URB_SHIFT; - status &= ~MMUCR_URB; + status &= ~MMUCR_URC; /* * Make sure we're not trying to wire the last TLB entry slot. @@ -39,7 +35,23 @@ void tlb_wire_entry(struct vm_area_struct *vma, unsigned long addr, pte_t pte) urb = urb % MMUCR_URB_NENTRIES; + /* + * Insert this entry into the highest non-wired TLB slot (via + * the URC field). + */ + status |= (urb << MMUCR_URC_SHIFT); + __raw_writel(status, MMUCR); + ctrl_barrier(); + + /* Load the entry into the TLB */ + __update_tlb(vma, addr, pte); + + /* ... and wire it up. */ + status = __raw_readl(MMUCR); + + status &= ~MMUCR_URB; status |= (urb << MMUCR_URB_SHIFT); + __raw_writel(status, MMUCR); ctrl_barrier(); -- cgit v0.10.2 From 72f878cc6f324ecc2ca00ff2f9c0dc2c168cd4cc Mon Sep 17 00:00:00 2001 From: Andrea Gelmini Date: Thu, 25 Mar 2010 18:22:40 +0100 Subject: USB gadget r8a66597-udc.c: duplicated include drivers/usb/gadget/r8a66597-udc.c: linux/err.h is included more than once. Signed-off-by: Andrea Gelmini Signed-off-by: Paul Mundt diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c index 5e13d23..8b45145 100644 --- a/drivers/usb/gadget/r8a66597-udc.c +++ b/drivers/usb/gadget/r8a66597-udc.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include -- cgit v0.10.2 From 3da0ae6298fa10d4f5e2855ae400b2470bc6693d Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 25 Mar 2010 20:32:39 -0700 Subject: isdn: Add netdev to lists in MAINTAINERS entry. Signed-off-by: David S. Miller diff --git a/MAINTAINERS b/MAINTAINERS index 5c99bd6..9ff6341 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3083,6 +3083,7 @@ F: include/scsi/*iscsi* ISDN SUBSYSTEM M: Karsten Keil L: isdn4linux@listserv.isdn4linux.de (subscribers-only) +L: netdev@vger.kernel.org W: http://www.isdn4linux.de T: git git://git.kernel.org/pub/scm/linux/kernel/git/kkeil/isdn-2.6.git S: Maintained -- cgit v0.10.2 From e1f7f02b45cf33a774d56e505ce1718af9392f5e Mon Sep 17 00:00:00 2001 From: Daniel T Chen Date: Thu, 25 Mar 2010 22:38:15 -0700 Subject: ALSA: ac97: Add IBM ThinkPad R40e to Headphone/Line Jack Sense blacklist BugLink: https://launchpad.net/bugs/303789 This model needs both 'Headphone Jack Sense' and 'Line Jack Sense' muted for audible audio, so just add its SSID to the blacklist and don't enumerate the controls. Signed-off-by: Daniel T Chen Cc: Signed-off-by: Takashi Iwai diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index 1caf5e3..1a59b71 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c @@ -1852,6 +1852,7 @@ static unsigned int ad1981_jacks_blacklist[] = { 0x10140523, /* Thinkpad R40 */ 0x10140534, /* Thinkpad X31 */ 0x10140537, /* Thinkpad T41p */ + 0x1014053e, /* Thinkpad R40e */ 0x10140554, /* Thinkpad T42p/R50p */ 0x10140567, /* Thinkpad T43p 2668-G7U */ 0x10140581, /* Thinkpad X41-2527 */ -- cgit v0.10.2 From 0f17014b340b98465fcf0de4c0d6c84a002ec53b Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Fri, 26 Mar 2010 16:07:25 +0200 Subject: ALSA: pcm_lib - fix xrun functionality The commit 4d96eb255c53ab5e39b37fd4d484ea3dc39ab456 broke the interrupt time xrun functionality (stream stop etc.) if the CONFIG_SND_PCM_XRUN_DEBUG is not set. This is because the xrun() is null defined without it. Fix this by letting the function xrun() to be always defined as it was before. Signed-off-by: Jarkko Nikula Cc: Jaroslav Kysela Signed-off-by: Takashi Iwai diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index b546ac2..a2ff861 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -148,6 +148,9 @@ static void pcm_debug_name(struct snd_pcm_substream *substream, #define xrun_debug(substream, mask) \ ((substream)->pstr->xrun_debug & (mask)) +#else +#define xrun_debug(substream, mask) 0 +#endif #define dump_stack_on_xrun(substream) do { \ if (xrun_debug(substream, XRUN_DEBUG_STACK)) \ @@ -169,6 +172,7 @@ static void xrun(struct snd_pcm_substream *substream) } } +#ifdef CONFIG_SND_PCM_XRUN_DEBUG #define hw_ptr_error(substream, fmt, args...) \ do { \ if (xrun_debug(substream, XRUN_DEBUG_BASIC)) { \ @@ -255,8 +259,6 @@ static void xrun_log_show(struct snd_pcm_substream *substream) #else /* ! CONFIG_SND_PCM_XRUN_DEBUG */ -#define xrun_debug(substream, mask) 0 -#define xrun(substream) do { } while (0) #define hw_ptr_error(substream, fmt, args...) do { } while (0) #define xrun_log(substream, pos) do { } while (0) #define xrun_log_show(substream) do { } while (0) -- cgit v0.10.2 From 3e297b613491f0d4928aa652a2cd266aa06dc409 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 26 Mar 2010 12:40:13 -0400 Subject: Restore LOOKUP_DIRECTORY hint handling in final lookup on open() Lose want_dir argument, while we are at it - since now nd->flags & LOOKUP_DIRECTORY is equivalent to it. Signed-off-by: Al Viro diff --git a/fs/namei.c b/fs/namei.c index 1c0fca6..a7dce91 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -1610,8 +1610,7 @@ exit: static struct file *do_last(struct nameidata *nd, struct path *path, int open_flag, int acc_mode, - int mode, const char *pathname, - int *want_dir) + int mode, const char *pathname) { struct dentry *dir = nd->path.dentry; struct file *filp; @@ -1642,7 +1641,7 @@ static struct file *do_last(struct nameidata *nd, struct path *path, if (nd->last.name[nd->last.len]) { if (open_flag & O_CREAT) goto exit; - *want_dir = 1; + nd->flags |= LOOKUP_DIRECTORY; } /* just plain open? */ @@ -1656,8 +1655,10 @@ static struct file *do_last(struct nameidata *nd, struct path *path, if (path->dentry->d_inode->i_op->follow_link) return NULL; error = -ENOTDIR; - if (*want_dir && !path->dentry->d_inode->i_op->lookup) - goto exit_dput; + if (nd->flags & LOOKUP_DIRECTORY) { + if (!path->dentry->d_inode->i_op->lookup) + goto exit_dput; + } path_to_nameidata(path, nd); audit_inode(pathname, nd->path.dentry); goto ok; @@ -1766,7 +1767,6 @@ struct file *do_filp_open(int dfd, const char *pathname, int count = 0; int flag = open_to_namei_flags(open_flag); int force_reval = 0; - int want_dir = open_flag & O_DIRECTORY; if (!(open_flag & O_CREAT)) mode = 0; @@ -1828,7 +1828,9 @@ reval: if (open_flag & O_EXCL) nd.flags |= LOOKUP_EXCL; } - filp = do_last(&nd, &path, open_flag, acc_mode, mode, pathname, &want_dir); + if (open_flag & O_DIRECTORY) + nd.flags |= LOOKUP_DIRECTORY; + filp = do_last(&nd, &path, open_flag, acc_mode, mode, pathname); while (unlikely(!filp)) { /* trailing symlink */ struct path holder; struct inode *inode = path.dentry->d_inode; @@ -1866,7 +1868,7 @@ reval: } holder = path; nd.flags &= ~LOOKUP_PARENT; - filp = do_last(&nd, &path, open_flag, acc_mode, mode, pathname, &want_dir); + filp = do_last(&nd, &path, open_flag, acc_mode, mode, pathname); if (inode->i_op->put_link) inode->i_op->put_link(holder.dentry, &nd, cookie); path_put(&holder); -- cgit v0.10.2 From 4300e8c7f64d95a80ffa7d98d98738f41546bc30 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 26 Mar 2010 10:23:30 -0700 Subject: Revert "r8169: enable 64-bit DMA by default for PCI Express devices (v2)" This reverts commit 353176888386d9025062a12dcec08d49af10cf2c. People are reporting problems due to this change and there is no anticipation that the cause will be tracked down any time soon. We can try next time to selectively re-enable this based upon chip type, or have a black list of some sort. Signed-off-by: David S. Miller diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 9d3ebf3..b93fd23 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -187,7 +187,7 @@ static DEFINE_PCI_DEVICE_TABLE(rtl8169_pci_tbl) = { MODULE_DEVICE_TABLE(pci, rtl8169_pci_tbl); static int rx_copybreak = 200; -static int use_dac = -1; +static int use_dac; static struct { u32 msg_enable; } debug = { -1 }; @@ -511,8 +511,7 @@ MODULE_DESCRIPTION("RealTek RTL-8169 Gigabit Ethernet driver"); module_param(rx_copybreak, int, 0); MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames"); module_param(use_dac, int, 0); -MODULE_PARM_DESC(use_dac, "Enable PCI DAC. -1 defaults on for PCI Express only." -" Unsafe on 32 bit PCI slot."); +MODULE_PARM_DESC(use_dac, "Enable PCI DAC. Unsafe on 32 bit PCI slot."); module_param_named(debug, debug.msg_enable, int, 0); MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., 16=all)"); MODULE_LICENSE("GPL"); @@ -2974,7 +2973,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) void __iomem *ioaddr; unsigned int i; int rc; - int this_use_dac = use_dac; if (netif_msg_drv(&debug)) { printk(KERN_INFO "%s Gigabit Ethernet driver %s loaded\n", @@ -3040,17 +3038,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) tp->cp_cmd = PCIMulRW | RxChkSum; - tp->pcie_cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); - if (!tp->pcie_cap) - netif_info(tp, probe, dev, "no PCI Express capability\n"); - - if (this_use_dac < 0) - this_use_dac = tp->pcie_cap != 0; - if ((sizeof(dma_addr_t) > 4) && - this_use_dac && - !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { - netif_info(tp, probe, dev, "using 64-bit DMA\n"); + !pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) && use_dac) { tp->cp_cmd |= PCIDAC; dev->features |= NETIF_F_HIGHDMA; } else { @@ -3069,6 +3058,10 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_out_free_res_4; } + tp->pcie_cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); + if (!tp->pcie_cap) + netif_info(tp, probe, dev, "no PCI Express capability\n"); + RTL_W16(IntrMask, 0x0000); /* Soft reset the chip. */ -- cgit v0.10.2 From bb2792e0383793d5135ba777e93f0a918371394b Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Fri, 26 Mar 2010 00:30:07 +0000 Subject: netxen: fix bios version calculation Bios sub version from unified fw image is calculated incorrect. Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 1c63610e..7eb925a 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -761,7 +761,7 @@ nx_get_bios_version(struct netxen_adapter *adapter) if (adapter->fw_type == NX_UNIFIED_ROMIMAGE) { bios_ver = cpu_to_le32(*((u32 *) (&fw->data[prd_off]) + NX_UNI_BIOS_VERSION_OFF)); - return (bios_ver << 24) + ((bios_ver >> 8) & 0xff00) + + return (bios_ver << 16) + ((bios_ver >> 8) & 0xff00) + (bios_ver >> 24); } else return cpu_to_le32(*(u32 *)&fw->data[NX_BIOS_VERSION_OFFSET]); -- cgit v0.10.2 From 77c553900c58c3e4f475e233ad4ff6aeb282deb4 Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Fri, 26 Mar 2010 00:30:08 +0000 Subject: netxen: fix warning in ioaddr for NX3031 chip Signed-off-by: Amit Kumar Salecha crb_intr_mask/crb_sts_consumer is predefined for NX2031 not for NX3031. For NX3031, these values get defined in rx context creation. Signed-off-by: David S. Miller diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c index 2a8ef5f..f26e547 100644 --- a/drivers/net/netxen/netxen_nic_ctx.c +++ b/drivers/net/netxen/netxen_nic_ctx.c @@ -669,13 +669,15 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter) } sds_ring->desc_head = (struct status_desc *)addr; - sds_ring->crb_sts_consumer = - netxen_get_ioaddr(adapter, - recv_crb_registers[port].crb_sts_consumer[ring]); + if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { + sds_ring->crb_sts_consumer = + netxen_get_ioaddr(adapter, + recv_crb_registers[port].crb_sts_consumer[ring]); - sds_ring->crb_intr_mask = - netxen_get_ioaddr(adapter, - recv_crb_registers[port].sw_int_mask[ring]); + sds_ring->crb_intr_mask = + netxen_get_ioaddr(adapter, + recv_crb_registers[port].sw_int_mask[ring]); + } } -- cgit v0.10.2 From afbe5cd6c40e0f20fa8832d17fa44ae605591ce1 Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Fri, 26 Mar 2010 00:30:09 +0000 Subject: netxen: added sanity check for pci map Signed-off-by: Amit Kumar Salecha Return value of ioremap is not checked, NULL check added. Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 9a7a0f3..01808b2 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -604,16 +604,14 @@ netxen_cleanup_pci_map(struct netxen_adapter *adapter) static int netxen_setup_pci_map(struct netxen_adapter *adapter) { - void __iomem *mem_ptr0 = NULL; - void __iomem *mem_ptr1 = NULL; - void __iomem *mem_ptr2 = NULL; void __iomem *db_ptr = NULL; resource_size_t mem_base, db_base; - unsigned long mem_len, db_len = 0, pci_len0 = 0; + unsigned long mem_len, db_len = 0; struct pci_dev *pdev = adapter->pdev; int pci_func = adapter->ahw.pci_func; + struct netxen_hardware_context *ahw = &adapter->ahw; int err = 0; @@ -630,24 +628,40 @@ netxen_setup_pci_map(struct netxen_adapter *adapter) /* 128 Meg of memory */ if (mem_len == NETXEN_PCI_128MB_SIZE) { - mem_ptr0 = ioremap(mem_base, FIRST_PAGE_GROUP_SIZE); - mem_ptr1 = ioremap(mem_base + SECOND_PAGE_GROUP_START, + + ahw->pci_base0 = ioremap(mem_base, FIRST_PAGE_GROUP_SIZE); + ahw->pci_base1 = ioremap(mem_base + SECOND_PAGE_GROUP_START, SECOND_PAGE_GROUP_SIZE); - mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START, + ahw->pci_base2 = ioremap(mem_base + THIRD_PAGE_GROUP_START, THIRD_PAGE_GROUP_SIZE); - pci_len0 = FIRST_PAGE_GROUP_SIZE; + if (ahw->pci_base0 == NULL || ahw->pci_base1 == NULL || + ahw->pci_base2 == NULL) { + dev_err(&pdev->dev, "failed to map PCI bar 0\n"); + err = -EIO; + goto err_out; + } + + ahw->pci_len0 = FIRST_PAGE_GROUP_SIZE; + } else if (mem_len == NETXEN_PCI_32MB_SIZE) { - mem_ptr1 = ioremap(mem_base, SECOND_PAGE_GROUP_SIZE); - mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START - + + ahw->pci_base1 = ioremap(mem_base, SECOND_PAGE_GROUP_SIZE); + ahw->pci_base2 = ioremap(mem_base + THIRD_PAGE_GROUP_START - SECOND_PAGE_GROUP_START, THIRD_PAGE_GROUP_SIZE); + if (ahw->pci_base1 == NULL || ahw->pci_base2 == NULL) { + dev_err(&pdev->dev, "failed to map PCI bar 0\n"); + err = -EIO; + goto err_out; + } + } else if (mem_len == NETXEN_PCI_2MB_SIZE) { - mem_ptr0 = pci_ioremap_bar(pdev, 0); - if (mem_ptr0 == NULL) { + ahw->pci_base0 = pci_ioremap_bar(pdev, 0); + if (ahw->pci_base0 == NULL) { dev_err(&pdev->dev, "failed to map PCI bar 0\n"); return -EIO; } - pci_len0 = mem_len; + ahw->pci_len0 = mem_len; } else { return -EIO; } @@ -656,11 +670,6 @@ netxen_setup_pci_map(struct netxen_adapter *adapter) dev_info(&pdev->dev, "%dMB memory map\n", (int)(mem_len>>20)); - adapter->ahw.pci_base0 = mem_ptr0; - adapter->ahw.pci_len0 = pci_len0; - adapter->ahw.pci_base1 = mem_ptr1; - adapter->ahw.pci_base2 = mem_ptr2; - if (NX_IS_REVISION_P3P(adapter->ahw.revision_id)) { adapter->ahw.ocm_win_crb = netxen_get_ioaddr(adapter, NETXEN_PCIX_PS_REG(PCIX_OCM_WINDOW_REG(pci_func))); -- cgit v0.10.2 From 48c11a59c4c1d9926be34920d45da037516eb7b8 Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Fri, 26 Mar 2010 00:30:10 +0000 Subject: netxen: update version to 4.0.73 Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 144d2e8..0f70383 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -53,8 +53,8 @@ #define _NETXEN_NIC_LINUX_MAJOR 4 #define _NETXEN_NIC_LINUX_MINOR 0 -#define _NETXEN_NIC_LINUX_SUBVERSION 72 -#define NETXEN_NIC_LINUX_VERSIONID "4.0.72" +#define _NETXEN_NIC_LINUX_SUBVERSION 73 +#define NETXEN_NIC_LINUX_VERSIONID "4.0.73" #define NETXEN_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c)) #define _major(v) (((v) >> 24) & 0xff) -- cgit v0.10.2 From 65deeed7b34bc5b8d3cbff495e8fa2ae7b563480 Mon Sep 17 00:00:00 2001 From: Greg Rose Date: Wed, 24 Mar 2010 09:35:42 +0000 Subject: ixgbevf: Fix signed/unsigned int error In the Tx mapping function if a DMA error occurred then the unwind of previously mapped sections would improperly check an unsigned int if it was less than zero. Changed the index variable to signed to avoid the error. Signed-off-by: Greg Rose Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c index d6cbd94..1bbbef3 100644 --- a/drivers/net/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ixgbevf/ixgbevf_main.c @@ -2943,9 +2943,10 @@ static int ixgbevf_tx_map(struct ixgbevf_adapter *adapter, struct ixgbevf_tx_buffer *tx_buffer_info; unsigned int len; unsigned int total = skb->len; - unsigned int offset = 0, size, count = 0, i; + unsigned int offset = 0, size, count = 0; unsigned int nr_frags = skb_shinfo(skb)->nr_frags; unsigned int f; + int i; i = tx_ring->next_to_use; -- cgit v0.10.2 From 5809a1ae77721931ca7bd7aeacb37fdabe6f07c0 Mon Sep 17 00:00:00 2001 From: Greg Rose Date: Wed, 24 Mar 2010 09:36:08 +0000 Subject: ixgbe: In SR-IOV mode insert delay before bring the adapter up VFs running in guest VMs do not respond in as timely a manner to PF indication it is going down as they do when running in the host domain. If the adapter is in SR-IOV mode insert a two second delay to guarantee that all VFs have had time to respond to the PF reset. In any case resetting the PF while VFs are active should be discouraged but if it must be done then there will be a two second delay to help synchronize resets among the PF and all the VFs. Signed-off-by: Greg Rose Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index d75c46f..d2cda9e 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -3056,6 +3056,14 @@ void ixgbe_reinit_locked(struct ixgbe_adapter *adapter) while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state)) msleep(1); ixgbe_down(adapter); + /* + * If SR-IOV enabled then wait a bit before bringing the adapter + * back up to give the VFs time to respond to the reset. The + * two second wait is based upon the watchdog timer cycle in + * the VF driver. + */ + if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) + msleep(2000); ixgbe_up(adapter); clear_bit(__IXGBE_RESETTING, &adapter->state); } -- cgit v0.10.2 From 581d1aa777580c1c22169538ffb46676b13c408e Mon Sep 17 00:00:00 2001 From: Greg Rose Date: Wed, 24 Mar 2010 09:36:27 +0000 Subject: ixgbe: Change where clear_to_send_flag is reset to zero. The clear_to_send flag is being cleared before the call to ping all the VFs. It should be called after pinging all the VFs. Signed-off-by: Greg Rose Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index d2cda9e..1066d53 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -3244,13 +3244,15 @@ void ixgbe_down(struct ixgbe_adapter *adapter) /* disable receive for all VFs and wait one second */ if (adapter->num_vfs) { - for (i = 0 ; i < adapter->num_vfs; i++) - adapter->vfinfo[i].clear_to_send = 0; - /* ping all the active vfs to let them know we are going down */ ixgbe_ping_all_vfs(adapter); + /* Disable all VFTE/VFRE TX/RX */ ixgbe_disable_tx_rx(adapter); + + /* Mark all the VFs as inactive */ + for (i = 0 ; i < adapter->num_vfs; i++) + adapter->vfinfo[i].clear_to_send = 0; } /* disable receives */ -- cgit v0.10.2 From e0fce6950b822aba7840d82c2d2018f1e1b8276b Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Wed, 24 Mar 2010 10:01:45 +0000 Subject: ixgbe: cleanup maximum number of tx queues In the last patch I missed an unecessary min_t comparison. This patch removes it, the path allocates at most 72 tx queues for 82599 and 24 for 82598 there is no need for this check. Additionally this sets MAX_[TX|RX]_QUEUES to 72. Which is used as the size for the tx/rx_ring arrays. There is no reason to have more tx_rings/rx_rings then num_tx_queues. Signed-off-by: John Fastabend Signed-off-by: Jeff Kirsher Acked-by: Eric Dumazet Signed-off-by: David S. Miller diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index 19e94ee..79c35ae 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -204,14 +204,17 @@ enum ixgbe_ring_f_enum { #define IXGBE_MAX_FDIR_INDICES 64 #ifdef IXGBE_FCOE #define IXGBE_MAX_FCOE_INDICES 8 +#define MAX_RX_QUEUES (IXGBE_MAX_FDIR_INDICES + IXGBE_MAX_FCOE_INDICES) +#define MAX_TX_QUEUES (IXGBE_MAX_FDIR_INDICES + IXGBE_MAX_FCOE_INDICES) +#else +#define MAX_RX_QUEUES IXGBE_MAX_FDIR_INDICES +#define MAX_TX_QUEUES IXGBE_MAX_FDIR_INDICES #endif /* IXGBE_FCOE */ struct ixgbe_ring_feature { int indices; int mask; } ____cacheline_internodealigned_in_smp; -#define MAX_RX_QUEUES 128 -#define MAX_TX_QUEUES 128 #define MAX_RX_PACKET_BUFFERS ((adapter->flags & IXGBE_FLAG_DCB_ENABLED) \ ? 8 : 1) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 1066d53..208fb4a 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -6061,7 +6061,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, indices += min_t(unsigned int, num_possible_cpus(), IXGBE_MAX_FCOE_INDICES); #endif - indices = min_t(unsigned int, indices, MAX_TX_QUEUES); netdev = alloc_etherdev_mq(sizeof(struct ixgbe_adapter), indices); if (!netdev) { err = -ENOMEM; -- cgit v0.10.2 From a7551b75fe47fb6fb70f679935845e741c5e0855 Mon Sep 17 00:00:00 2001 From: Robert Love Date: Wed, 24 Mar 2010 10:02:04 +0000 Subject: ixgbe: Don't allow user buffer count to exceed 256 If the user buffer count was 256 the shift would place a 1 in the offset region leading to errors. It also overwrites the uers buffer list. This patch makes sure that at most 256 user buffers are allowed for DDP and the buffer count is masked properly such that it doesn't overwrite the offset when shifting the bits. Signed-off-by: Robert Love Signed-off-by: Yi Zou Signed-off-by: Frank Zhang Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c index 700cfc0..e1978da 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.c +++ b/drivers/net/ixgbe/ixgbe_fcoe.c @@ -202,6 +202,15 @@ int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid, addr = sg_dma_address(sg); len = sg_dma_len(sg); while (len) { + /* max number of buffers allowed in one DDP context */ + if (j >= IXGBE_BUFFCNT_MAX) { + netif_err(adapter, drv, adapter->netdev, + "xid=%x:%d,%d,%d:addr=%llx " + "not enough descriptors\n", + xid, i, j, dmacount, (u64)addr); + goto out_noddp_free; + } + /* get the offset of length of current buffer */ thisoff = addr & ((dma_addr_t)bufflen - 1); thislen = min((bufflen - thisoff), len); @@ -227,20 +236,13 @@ int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid, len -= thislen; addr += thislen; j++; - /* max number of buffers allowed in one DDP context */ - if (j > IXGBE_BUFFCNT_MAX) { - DPRINTK(DRV, ERR, "xid=%x:%d,%d,%d:addr=%llx " - "not enough descriptors\n", - xid, i, j, dmacount, (u64)addr); - goto out_noddp_free; - } } } /* only the last buffer may have non-full bufflen */ lastsize = thisoff + thislen; fcbuff = (IXGBE_FCBUFF_4KB << IXGBE_FCBUFF_BUFFSIZE_SHIFT); - fcbuff |= (j << IXGBE_FCBUFF_BUFFCNT_SHIFT); + fcbuff |= ((j & 0xff) << IXGBE_FCBUFF_BUFFCNT_SHIFT); fcbuff |= (firstoff << IXGBE_FCBUFF_OFFSET_SHIFT); fcbuff |= (IXGBE_FCBUFF_VALID); -- cgit v0.10.2 From ca77cd59d28456b4061afa5254972ec47fa8baf5 Mon Sep 17 00:00:00 2001 From: Robert Love Date: Wed, 24 Mar 2010 12:45:00 +0000 Subject: ixgbe: Priority tag FIP frames Currently FIP (FCoE Initialization Protocol) frames are going untagged. This causes various problems with FCFs (switches) that have negotiated a priority over dcbx. This patch tags FIP frames with the same priority as the FCoE frames. Signed-off-by: Robert Love Signed-off-by: Chris Leech Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 208fb4a..0c553f6 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -5648,7 +5648,8 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb) #ifdef IXGBE_FCOE if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) && - (skb->protocol == htons(ETH_P_FCOE))) { + ((skb->protocol == htons(ETH_P_FCOE)) || + (skb->protocol == htons(ETH_P_FIP)))) { txq &= (adapter->ring_feature[RING_F_FCOE].indices - 1); txq += adapter->ring_feature[RING_F_FCOE].mask; return txq; @@ -5695,18 +5696,25 @@ static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb, tx_ring = adapter->tx_ring[skb->queue_mapping]; - if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) && - (skb->protocol == htons(ETH_P_FCOE))) { - tx_flags |= IXGBE_TX_FLAGS_FCOE; #ifdef IXGBE_FCOE + if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) { #ifdef CONFIG_IXGBE_DCB - tx_flags &= ~(IXGBE_TX_FLAGS_VLAN_PRIO_MASK - << IXGBE_TX_FLAGS_VLAN_SHIFT); - tx_flags |= ((adapter->fcoe.up << 13) - << IXGBE_TX_FLAGS_VLAN_SHIFT); -#endif + /* for FCoE with DCB, we force the priority to what + * was specified by the switch */ + if ((skb->protocol == htons(ETH_P_FCOE)) || + (skb->protocol == htons(ETH_P_FIP))) { + tx_flags &= ~(IXGBE_TX_FLAGS_VLAN_PRIO_MASK + << IXGBE_TX_FLAGS_VLAN_SHIFT); + tx_flags |= ((adapter->fcoe.up << 13) + << IXGBE_TX_FLAGS_VLAN_SHIFT); + } #endif + /* flag for FCoE offloads */ + if (skb->protocol == htons(ETH_P_FCOE)) + tx_flags |= IXGBE_TX_FLAGS_FCOE; } +#endif + /* four things can cause us to need a context descriptor */ if (skb_is_gso(skb) || (skb->ip_summed == CHECKSUM_PARTIAL) || -- cgit v0.10.2 From af06393bbde6e8d474622a0517cffc662676e3fe Mon Sep 17 00:00:00 2001 From: Chris Leech Date: Wed, 24 Mar 2010 12:45:21 +0000 Subject: ixgbe: filter FIP frames into the FCoE offload queues During FCF solicitation, the switch is supposed to pad the solicited advertisement out to the endpoints specified maximum FCoE frame size. That means that we need to receive FIP frames that are larger than the standard MTU. To make sure the receive queue is configured correctly, we should be filtering FIP traffic into the FCoE queues. Signed-off-by: Chris Leech Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c index e1978da..9276d59 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.c +++ b/drivers/net/ixgbe/ixgbe_fcoe.c @@ -522,6 +522,9 @@ void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter) /* Enable L2 eth type filter for FCoE */ IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_FCOE), (ETH_P_FCOE | IXGBE_ETQF_FCOE | IXGBE_ETQF_FILTER_EN)); + /* Enable L2 eth type filter for FIP */ + IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_FIP), + (ETH_P_FIP | IXGBE_ETQF_FILTER_EN)); if (adapter->ring_feature[RING_F_FCOE].indices) { /* Use multiple rx queues for FCoE by redirection table */ for (i = 0; i < IXGBE_FCRETA_SIZE; i++) { @@ -532,6 +535,12 @@ void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter) } IXGBE_WRITE_REG(hw, IXGBE_FCRECTL, IXGBE_FCRECTL_ENA); IXGBE_WRITE_REG(hw, IXGBE_ETQS(IXGBE_ETQF_FILTER_FCOE), 0); + fcoe_i = f->mask; + fcoe_i &= IXGBE_FCRETA_ENTRY_MASK; + fcoe_q = adapter->rx_ring[fcoe_i]->reg_idx; + IXGBE_WRITE_REG(hw, IXGBE_ETQS(IXGBE_ETQF_FILTER_FIP), + IXGBE_ETQS_QUEUE_EN | + (fcoe_q << IXGBE_ETQS_RX_QUEUE_SHIFT)); } else { /* Use single rx queue for FCoE */ fcoe_i = f->mask; @@ -541,6 +550,12 @@ void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter) IXGBE_ETQS_QUEUE_EN | (fcoe_q << IXGBE_ETQS_RX_QUEUE_SHIFT)); } + /* send FIP frames to the first FCoE queue */ + fcoe_i = f->mask; + fcoe_q = adapter->rx_ring[fcoe_i]->reg_idx; + IXGBE_WRITE_REG(hw, IXGBE_ETQS(IXGBE_ETQF_FILTER_FIP), + IXGBE_ETQS_QUEUE_EN | + (fcoe_q << IXGBE_ETQS_RX_QUEUE_SHIFT)); IXGBE_WRITE_REG(hw, IXGBE_FCRXCTRL, IXGBE_FCRXCTRL_FCOELLI | diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 0ed5ab3..4ec6dc1 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -1298,6 +1298,7 @@ #define IXGBE_ETQF_FILTER_BCN 1 #define IXGBE_ETQF_FILTER_FCOE 2 #define IXGBE_ETQF_FILTER_1588 3 +#define IXGBE_ETQF_FILTER_FIP 4 /* VLAN Control Bit Masks */ #define IXGBE_VLNCTRL_VET 0x0000FFFF /* bits 0-15 */ #define IXGBE_VLNCTRL_CFI 0x10000000 /* bit 28 */ -- cgit v0.10.2 From 4f598458ea4450f53e8ed929ee4e66b3404a7286 Mon Sep 17 00:00:00 2001 From: Xiaotian Feng Date: Wed, 10 Mar 2010 22:59:13 +0100 Subject: Freezer: Only show the state of tasks refusing to freeze show_state will dump all tasks state, so if freezer failed to freeze any task, kernel will dump all tasks state and flood the dmesg log. This patch makes freezer only show state of tasks refusing to freeze. Signed-off-by: Xiaotian Feng Acked-by: Pavel Machek Acked-by: David Rientjes Signed-off-by: Rafael J. Wysocki diff --git a/kernel/power/process.c b/kernel/power/process.c index 5ade1bd..a0480cd 100644 --- a/kernel/power/process.c +++ b/kernel/power/process.c @@ -88,12 +88,11 @@ static int try_to_freeze_tasks(bool sig_only) printk(KERN_ERR "Freezing of tasks failed after %d.%02d seconds " "(%d tasks refusing to freeze):\n", elapsed_csecs / 100, elapsed_csecs % 100, todo); - show_state(); read_lock(&tasklist_lock); do_each_thread(g, p) { task_lock(p); if (freezing(p) && !freezer_should_skip(p)) - printk(KERN_ERR " %s\n", p->comm); + sched_show_task(p); cancel_freezing(p); task_unlock(p); } while_each_thread(g, p); -- cgit v0.10.2 From 5a7aadfe2fcb0f69e2acc1fbefe22a096e792fc9 Mon Sep 17 00:00:00 2001 From: Matt Helsley Date: Fri, 26 Mar 2010 23:51:44 +0100 Subject: Freezer: Fix buggy resume test for tasks frozen with cgroup freezer When the cgroup freezer is used to freeze tasks we do not want to thaw those tasks during resume. Currently we test the cgroup freezer state of the resuming tasks to see if the cgroup is FROZEN. If so then we don't thaw the task. However, the FREEZING state also indicates that the task should remain frozen. This also avoids a problem pointed out by Oren Ladaan: the freezer state transition from FREEZING to FROZEN is updated lazily when userspace reads or writes the freezer.state file in the cgroup filesystem. This means that resume will thaw tasks in cgroups which should be in the FROZEN state if there is no read/write of the freezer.state file to trigger this transition before suspend. NOTE: Another "simple" solution would be to always update the cgroup freezer state during resume. However it's a bad choice for several reasons: Updating the cgroup freezer state is somewhat expensive because it requires walking all the tasks in the cgroup and checking if they are each frozen. Worse, this could easily make resume run in N^2 time where N is the number of tasks in the cgroup. Finally, updating the freezer state from this code path requires trickier locking because of the way locks must be ordered. Instead of updating the freezer state we rely on the fact that lazy updates only manage the transition from FREEZING to FROZEN. We know that a cgroup with the FREEZING state may actually be FROZEN so test for that state too. This makes sense in the resume path even for partially-frozen cgroups -- those that really are FREEZING but not FROZEN. Reported-by: Oren Ladaan Signed-off-by: Matt Helsley Cc: stable@kernel.org Signed-off-by: Rafael J. Wysocki diff --git a/include/linux/freezer.h b/include/linux/freezer.h index 5a361f8..da7e52b 100644 --- a/include/linux/freezer.h +++ b/include/linux/freezer.h @@ -64,9 +64,12 @@ extern bool freeze_task(struct task_struct *p, bool sig_only); extern void cancel_freezing(struct task_struct *p); #ifdef CONFIG_CGROUP_FREEZER -extern int cgroup_frozen(struct task_struct *task); +extern int cgroup_freezing_or_frozen(struct task_struct *task); #else /* !CONFIG_CGROUP_FREEZER */ -static inline int cgroup_frozen(struct task_struct *task) { return 0; } +static inline int cgroup_freezing_or_frozen(struct task_struct *task) +{ + return 0; +} #endif /* !CONFIG_CGROUP_FREEZER */ /* diff --git a/kernel/cgroup_freezer.c b/kernel/cgroup_freezer.c index 59e9ef6..eb3f34d 100644 --- a/kernel/cgroup_freezer.c +++ b/kernel/cgroup_freezer.c @@ -47,17 +47,20 @@ static inline struct freezer *task_freezer(struct task_struct *task) struct freezer, css); } -int cgroup_frozen(struct task_struct *task) +int cgroup_freezing_or_frozen(struct task_struct *task) { struct freezer *freezer; enum freezer_state state; task_lock(task); freezer = task_freezer(task); - state = freezer->state; + if (!freezer->css.cgroup->parent) + state = CGROUP_THAWED; /* root cgroup can't be frozen */ + else + state = freezer->state; task_unlock(task); - return state == CGROUP_FROZEN; + return (state == CGROUP_FREEZING) || (state == CGROUP_FROZEN); } /* diff --git a/kernel/power/process.c b/kernel/power/process.c index a0480cd..71ae290 100644 --- a/kernel/power/process.c +++ b/kernel/power/process.c @@ -144,7 +144,7 @@ static void thaw_tasks(bool nosig_only) if (nosig_only && should_send_signal(p)) continue; - if (cgroup_frozen(p)) + if (cgroup_freezing_or_frozen(p)) continue; thaw_process(p); -- cgit v0.10.2 From 810627a013163cd294762d57c0ea2ec055ffe4f6 Mon Sep 17 00:00:00 2001 From: Pavel Shilovsky Date: Sat, 27 Mar 2010 02:00:49 +0000 Subject: [CIFS] Add mmap for direct, nobrl cifs mount types without mmap functions in file_ops OpenOffice can't save changes in existing document. The same situation you can see with gedit. Also, a.out format of files can't be executed without mmap. Signed-off-by: Pavel Shilovsky Reviewed-by: Jeff Layton Signed-off-by: Steve French diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 5183bc2..ded66be 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -808,6 +808,7 @@ const struct file_operations cifs_file_direct_nobrl_ops = { .release = cifs_close, .fsync = cifs_fsync, .flush = cifs_flush, + .mmap = cifs_file_mmap, .splice_read = generic_file_splice_read, #ifdef CONFIG_CIFS_POSIX .unlocked_ioctl = cifs_ioctl, -- cgit v0.10.2 From a6d36d5689b1806a3365c909192e9f03a43a632b Mon Sep 17 00:00:00 2001 From: Ben Menchaca Date: Wed, 24 Mar 2010 05:05:02 +0000 Subject: gianfar: fix undo of reserve() Fix undo of reserve() before RX recycle gfar_new_skb reserve()s space in the SKB to align it. If an error occurs, and the skb needs to be returned to the RX recycle queue, the current code attempts to reset head, but did not reset tail. This patch remembers the alignment amount, and reverses the reserve() when needed. Signed-off-by: Ben Menchaca Signed-off-by: David S. Miller diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index b671555..669de02 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -2393,6 +2393,7 @@ struct sk_buff * gfar_new_skb(struct net_device *dev) * as many bytes as needed to align the data properly */ skb_reserve(skb, alignamount); + GFAR_CB(skb)->alignamount = alignamount; return skb; } @@ -2533,13 +2534,13 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit) newskb = skb; else if (skb) { /* - * We need to reset ->data to what it + * We need to un-reserve() the skb to what it * was before gfar_new_skb() re-aligned * it to an RXBUF_ALIGNMENT boundary * before we put the skb back on the * recycle list. */ - skb->data = skb->head + NET_SKB_PAD; + skb_reserve(skb, -GFAR_CB(skb)->alignamount); __skb_queue_head(&priv->rx_recycle, skb); } } else { diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h index 3d72dc4..17d25e7 100644 --- a/drivers/net/gianfar.h +++ b/drivers/net/gianfar.h @@ -566,6 +566,12 @@ struct rxfcb { u16 vlctl; /* VLAN control word */ }; +struct gianfar_skb_cb { + int alignamount; +}; + +#define GFAR_CB(skb) ((struct gianfar_skb_cb *)((skb)->cb)) + struct rmon_mib { u32 tr64; /* 0x.680 - Transmit and Receive 64-byte Frame Counter */ -- cgit v0.10.2 From ac90a149361a331f697d5aa500bedcff22054669 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Fri, 27 Mar 2009 17:23:32 +0000 Subject: tulip: Fix null dereference in uli526x_rx_packet() Acked-by: Grant Grundler Signed-off-by: David S. Miller diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c index 0ab05af..90be57b 100644 --- a/drivers/net/tulip/uli526x.c +++ b/drivers/net/tulip/uli526x.c @@ -851,13 +851,15 @@ static void uli526x_rx_packet(struct net_device *dev, struct uli526x_board_info if ( !(rdes0 & 0x8000) || ((db->cr6_data & CR6_PM) && (rxlen>6)) ) { + struct sk_buff *new_skb = NULL; + skb = rxptr->rx_skb_ptr; /* Good packet, send to upper layer */ /* Shorst packet used new SKB */ - if ( (rxlen < RX_COPY_SIZE) && - ( (skb = dev_alloc_skb(rxlen + 2) ) - != NULL) ) { + if ((rxlen < RX_COPY_SIZE) && + ((new_skb = dev_alloc_skb(rxlen + 2) != NULL))) { + skb = new_skb; /* size less than COPY_SIZE, allocate a rxlen SKB */ skb_reserve(skb, 2); /* 16byte align */ memcpy(skb_put(skb, rxlen), -- cgit v0.10.2 From 4b97efdf392563bf03b4917a0b5add2df65de39a Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Fri, 26 Mar 2010 20:27:49 -0700 Subject: net: fix netlink address dumping in IPv4/IPv6 When a dump is interrupted at the last device in a hash chain and then continued, "idx" won't get incremented past s_idx, so s_ip_idx is not reset when moving on to the next device. This means of all following devices only the last n - s_ip_idx addresses are dumped. Tested-by: Pawel Staszewski Signed-off-by: Patrick McHardy diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 51ca946..3feb2b3 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -1194,7 +1194,7 @@ static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) hlist_for_each_entry_rcu(dev, node, head, index_hlist) { if (idx < s_idx) goto cont; - if (idx > s_idx) + if (h > s_h || idx > s_idx) s_ip_idx = 0; in_dev = __in_dev_get_rcu(dev); if (!in_dev) diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 3381b43..7e567ae 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -3610,7 +3610,7 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, hlist_for_each_entry_rcu(dev, node, head, index_hlist) { if (idx < s_idx) goto cont; - if (idx > s_idx) + if (h > s_h || idx > s_idx) s_ip_idx = 0; ip_idx = 0; if ((idev = __in6_dev_get(dev)) == NULL) -- cgit v0.10.2 From b35ecb5d404c00f2420221ccbb1bbba1139353a4 Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Wed, 24 Mar 2010 07:43:17 +0000 Subject: ipv4: Cleanup struct net dereference in rt_intern_hash There's no need in getting it 3 times and gcc isn't smart enough to understand this himself. This is just a cleanup before the fix (next patch). Signed-off-by: Pavel Emelyanov Signed-off-by: David S. Miller diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 54fd68c..124af16 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1212,11 +1212,11 @@ restart: slow_chain_length(rt_hash_table[hash].chain) > rt_chain_length_max) { struct net *net = dev_net(rt->u.dst.dev); int num = ++net->ipv4.current_rt_cache_rebuild_count; - if (!rt_caching(dev_net(rt->u.dst.dev))) { + if (!rt_caching(net)) { printk(KERN_WARNING "%s: %d rebuilds is over limit, route caching disabled\n", rt->u.dst.dev->name, num); } - rt_emergency_hash_rebuild(dev_net(rt->u.dst.dev)); + rt_emergency_hash_rebuild(net); } } -- cgit v0.10.2 From 6a2bad70d546cf30a46bc6d9ec0cb9a0891a38eb Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Wed, 24 Mar 2010 21:51:22 +0000 Subject: ipv4: Restart rt_intern_hash after emergency rebuild (v2) The the rebuild changes the genid which in turn is used at the hash calculation. Thus if we don't restart and go on with inserting the rt will happen in wrong chain. (Fixed Neil's comment about the index passed into the rt_intern_hash) Signed-off-by: Pavel Emelyanov Reviewed-by: Neil Horman Signed-off-by: David S. Miller diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 124af16..d413b57 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1097,7 +1097,7 @@ static int slow_chain_length(const struct rtable *head) } static int rt_intern_hash(unsigned hash, struct rtable *rt, - struct rtable **rp, struct sk_buff *skb) + struct rtable **rp, struct sk_buff *skb, int ifindex) { struct rtable *rth, **rthp; unsigned long now; @@ -1217,6 +1217,11 @@ restart: rt->u.dst.dev->name, num); } rt_emergency_hash_rebuild(net); + spin_unlock_bh(rt_hash_lock_addr(hash)); + + hash = rt_hash(rt->fl.fl4_dst, rt->fl.fl4_src, + ifindex, rt_genid(net)); + goto restart; } } @@ -1477,7 +1482,7 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, &netevent); rt_del(hash, rth); - if (!rt_intern_hash(hash, rt, &rt, NULL)) + if (!rt_intern_hash(hash, rt, &rt, NULL, rt->fl.oif)) ip_rt_put(rt); goto do_next; } @@ -1931,7 +1936,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, in_dev_put(in_dev); hash = rt_hash(daddr, saddr, dev->ifindex, rt_genid(dev_net(dev))); - return rt_intern_hash(hash, rth, NULL, skb); + return rt_intern_hash(hash, rth, NULL, skb, dev->ifindex); e_nobufs: in_dev_put(in_dev); @@ -2098,7 +2103,7 @@ static int ip_mkroute_input(struct sk_buff *skb, /* put it into the cache */ hash = rt_hash(daddr, saddr, fl->iif, rt_genid(dev_net(rth->u.dst.dev))); - return rt_intern_hash(hash, rth, NULL, skb); + return rt_intern_hash(hash, rth, NULL, skb, fl->iif); } /* @@ -2255,7 +2260,7 @@ local_input: } rth->rt_type = res.type; hash = rt_hash(daddr, saddr, fl.iif, rt_genid(net)); - err = rt_intern_hash(hash, rth, NULL, skb); + err = rt_intern_hash(hash, rth, NULL, skb, fl.iif); goto done; no_route: @@ -2502,7 +2507,7 @@ static int ip_mkroute_output(struct rtable **rp, if (err == 0) { hash = rt_hash(oldflp->fl4_dst, oldflp->fl4_src, oldflp->oif, rt_genid(dev_net(dev_out))); - err = rt_intern_hash(hash, rth, rp, NULL); + err = rt_intern_hash(hash, rth, rp, NULL, oldflp->oif); } return err; -- cgit v0.10.2 From a08af745e4c711d22aeadc2adade36958fe03ce8 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Thu, 25 Mar 2010 12:11:48 +0000 Subject: igbvf: do not modify tx_queue_len on link speed change Previously the driver tweaked txqueuelen to avoid false Tx hang reports seen at half duplex. This had the effect of overriding user set values on link change/reset. Testing shows that adjusting only the timeout factor is sufficient to prevent Tx hang reports at half duplex. Based on e1000e patch by Franco Fichtner CC: Franco Fichtner Signed-off-by: Emil Tantilov Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller diff --git a/drivers/net/igbvf/igbvf.h b/drivers/net/igbvf/igbvf.h index a1774b2..debeee2 100644 --- a/drivers/net/igbvf/igbvf.h +++ b/drivers/net/igbvf/igbvf.h @@ -198,7 +198,6 @@ struct igbvf_adapter { struct igbvf_ring *tx_ring /* One per active queue */ ____cacheline_aligned_in_smp; - unsigned long tx_queue_len; unsigned int restart_queue; u32 txd_cmd; diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c index a77afd8..b41037e 100644 --- a/drivers/net/igbvf/netdev.c +++ b/drivers/net/igbvf/netdev.c @@ -1304,8 +1304,6 @@ static void igbvf_configure_tx(struct igbvf_adapter *adapter) /* enable Report Status bit */ adapter->txd_cmd |= E1000_ADVTXD_DCMD_RS; - - adapter->tx_queue_len = adapter->netdev->tx_queue_len; } /** @@ -1524,7 +1522,6 @@ void igbvf_down(struct igbvf_adapter *adapter) del_timer_sync(&adapter->watchdog_timer); - netdev->tx_queue_len = adapter->tx_queue_len; netif_carrier_off(netdev); /* record the stats before reset*/ @@ -1857,21 +1854,15 @@ static void igbvf_watchdog_task(struct work_struct *work) &adapter->link_duplex); igbvf_print_link_info(adapter); - /* - * tweak tx_queue_len according to speed/duplex - * and adjust the timeout factor - */ - netdev->tx_queue_len = adapter->tx_queue_len; + /* adjust timeout factor according to speed/duplex */ adapter->tx_timeout_factor = 1; switch (adapter->link_speed) { case SPEED_10: txb2b = 0; - netdev->tx_queue_len = 10; adapter->tx_timeout_factor = 16; break; case SPEED_100: txb2b = 0; - netdev->tx_queue_len = 100; /* maybe add some timeout factor ? */ break; } -- cgit v0.10.2 From f49c57e141c7f53353e4265a31dc2324e6215037 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Wed, 24 Mar 2010 12:55:02 +0000 Subject: e1000e: do not modify tx_queue_len on link speed change Previously the driver tweaked txqueuelen to avoid false Tx hang reports seen at half duplex. This had the effect of overriding user set values on link change/reset. Testing shows that adjusting only the timeout factor is sufficient to prevent Tx hang reports at half duplex. This patch removes all instances of tx_queue_len in the driver. Originally reported and patched by Franco Fichtner CC: Franco Fichtner Signed-off-by: Emil Tantilov Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index c2ec095..118bdf4 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h @@ -279,7 +279,6 @@ struct e1000_adapter { struct napi_struct napi; - unsigned long tx_queue_len; unsigned int restart_queue; u32 txd_cmd; diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 88d54d3..e1cceb6 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -2289,8 +2289,6 @@ static void e1000_configure_tx(struct e1000_adapter *adapter) ew32(TCTL, tctl); e1000e_config_collision_dist(hw); - - adapter->tx_queue_len = adapter->netdev->tx_queue_len; } /** @@ -2877,7 +2875,6 @@ void e1000e_down(struct e1000_adapter *adapter) del_timer_sync(&adapter->watchdog_timer); del_timer_sync(&adapter->phy_info_timer); - netdev->tx_queue_len = adapter->tx_queue_len; netif_carrier_off(netdev); adapter->link_speed = 0; adapter->link_duplex = 0; @@ -3588,21 +3585,15 @@ static void e1000_watchdog_task(struct work_struct *work) "link gets many collisions.\n"); } - /* - * tweak tx_queue_len according to speed/duplex - * and adjust the timeout factor - */ - netdev->tx_queue_len = adapter->tx_queue_len; + /* adjust timeout factor according to speed/duplex */ adapter->tx_timeout_factor = 1; switch (adapter->link_speed) { case SPEED_10: txb2b = 0; - netdev->tx_queue_len = 10; adapter->tx_timeout_factor = 16; break; case SPEED_100: txb2b = 0; - netdev->tx_queue_len = 100; adapter->tx_timeout_factor = 10; break; } -- cgit v0.10.2 From 7f809e1f8e2f46c486bfe529579a16a28daacd62 Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Fri, 26 Mar 2010 22:09:56 -0600 Subject: of/flattree: Fix unhandled OF_DT_NOP tag when unflattening the device tree NOPs within the property section are skipped, but NOPs between OF_DT_END_NODE and OF_DT_BEGIN_NODE were not. My firmware NOPs out entire nodes depending on various environment parameters. of_scan_flat_dt already handles NOP more generally. Signed-off-by: Jason Gunthorpe Signed-off-by: Grant Likely diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 406757a..dee4fb5 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -376,8 +376,11 @@ unsigned long __init unflatten_dt_node(unsigned long mem, if (!np->type) np->type = ""; } - while (tag == OF_DT_BEGIN_NODE) { - mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize); + while (tag == OF_DT_BEGIN_NODE || tag == OF_DT_NOP) { + if (tag == OF_DT_NOP) + *p += 4; + else + mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize); tag = be32_to_cpup((__be32 *)(*p)); } if (tag != OF_DT_END_NODE) { -- cgit v0.10.2 From 95d2c8ef08a902953d1ea2cad14928909e91e5d1 Mon Sep 17 00:00:00 2001 From: Timur Tabi Date: Fri, 26 Mar 2010 22:09:57 -0600 Subject: powerpc/fsl: add device tree binding for QE firmware Define a binding for embedding a QE firmware blob into the device tree. Also define a new property for the QE node that links to a firmware node. Signed-off-by: Timur Tabi Signed-off-by: Grant Likely diff --git a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe.txt b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe.txt index 6e37be1..4f89302 100644 --- a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe.txt +++ b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe.txt @@ -21,6 +21,15 @@ Required properties: - fsl,qe-num-snums: define how many serial number(SNUM) the QE can use for the threads. +Optional properties: +- fsl,firmware-phandle: + Usage: required only if there is no fsl,qe-firmware child node + Value type: + Definition: Points to a firmware node (see "QE Firmware Node" below) + that contains the firmware that should be uploaded for this QE. + The compatible property for the firmware node should say, + "fsl,qe-firmware". + Recommended properties - brg-frequency : the internal clock source frequency for baud-rate generators in Hz. @@ -59,3 +68,48 @@ Example: reg = <0 c000>; }; }; + +* QE Firmware Node + +This node defines a firmware binary that is embedded in the device tree, for +the purpose of passing the firmware from bootloader to the kernel, or from +the hypervisor to the guest. + +The firmware node itself contains the firmware binary contents, a compatible +property, and any firmware-specific properties. The node should be placed +inside a QE node that needs it. Doing so eliminates the need for a +fsl,firmware-phandle property. Other QE nodes that need the same firmware +should define an fsl,firmware-phandle property that points to the firmware node +in the first QE node. + +The fsl,firmware property can be specified in the DTS (possibly using incbin) +or can be inserted by the boot loader at boot time. + +Required properties: + - compatible + Usage: required + Value type: + Definition: A standard property. Specify a string that indicates what + kind of firmware it is. For QE, this should be "fsl,qe-firmware". + + - fsl,firmware + Usage: required + Value type: , encoded as an array of bytes + Definition: A standard property. This property contains the firmware + binary "blob". + +Example: + qe1@e0080000 { + compatible = "fsl,qe"; + qe_firmware:qe-firmware { + compatible = "fsl,qe-firmware"; + fsl,firmware = [0x70 0xcd 0x00 0x00 0x01 0x46 0x45 ...]; + }; + ... + }; + + qe2@e0090000 { + compatible = "fsl,qe"; + fsl,firmware-phandle = <&qe_firmware>; + ... + }; -- cgit v0.10.2 From ed01f64b831481762437c8eedddcca8481dc7f67 Mon Sep 17 00:00:00 2001 From: Roman Fietze Date: Fri, 26 Mar 2010 22:09:57 -0600 Subject: powerpc/5200: in lpbfifo, flag DMA irqs as enabled after requesting them This patch avoids unbalanced enable/disable messages for the DMA interrupts when running the 5200 platform SCLPC/BestComm driver in DMA mode. Signed-off-by: Roman Fietze Signed-off-by: Grant Likely diff --git a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c index 929d017..d4f8be3 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c @@ -481,6 +481,8 @@ mpc52xx_lpbfifo_probe(struct of_device *op, const struct of_device_id *match) if (rc) goto err_bcom_rx_irq; + lpbfifo.dma_irqs_enabled = 1; + /* Request the Bestcomm transmit (memory --> fifo) task and IRQ */ lpbfifo.bcom_tx_task = bcom_gen_bd_tx_init(2, res.start + LPBFIFO_REG_FIFO_DATA, -- cgit v0.10.2 From 49137f2efb5cf68724bccaba531ab3d59acd71f9 Mon Sep 17 00:00:00 2001 From: Joern Engel Date: Tue, 16 Mar 2010 21:46:15 +0100 Subject: Open segment file before using it logfs_recover_sb() needs it open. Signed-off-by: Joern Engel diff --git a/fs/logfs/super.c b/fs/logfs/super.c index c66beab..0187281 100644 --- a/fs/logfs/super.c +++ b/fs/logfs/super.c @@ -289,6 +289,10 @@ static int logfs_make_writeable(struct super_block *sb) { int err; + err = logfs_open_segfile(sb); + if (err) + return err; + /* Repair any broken superblock copies */ err = logfs_recover_sb(sb); if (err) @@ -299,10 +303,6 @@ static int logfs_make_writeable(struct super_block *sb) if (err) return err; - err = logfs_open_segfile(sb); - if (err) - return err; - /* Do one GC pass before any data gets dirtied */ logfs_gc_pass(sb); -- cgit v0.10.2 From 59fe27c0a8173a74b105debc803b97582028c90b Mon Sep 17 00:00:00 2001 From: Joern Engel Date: Wed, 17 Mar 2010 13:47:45 +0100 Subject: Limit max_pages for insane devices Intel SSDs have a limit of 0xffff as queue_max_hw_sectors(q). Such a limit may make sense from a hardware pov, but it causes bio_alloc() to return NULL. Signed-off-by: Joern Engel diff --git a/fs/logfs/dev_bdev.c b/fs/logfs/dev_bdev.c index 9718c22..f99f5dc 100644 --- a/fs/logfs/dev_bdev.c +++ b/fs/logfs/dev_bdev.c @@ -97,8 +97,10 @@ static int __bdev_writeseg(struct super_block *sb, u64 ofs, pgoff_t index, unsigned int max_pages = queue_max_hw_sectors(q) >> (PAGE_SHIFT - 9); int i; + if (max_pages > BIO_MAX_PAGES) + max_pages = BIO_MAX_PAGES; bio = bio_alloc(GFP_NOFS, max_pages); - BUG_ON(!bio); /* FIXME: handle this */ + BUG_ON(!bio); for (i = 0; i < nr_pages; i++) { if (i >= max_pages) { @@ -191,8 +193,10 @@ static int do_erase(struct super_block *sb, u64 ofs, pgoff_t index, unsigned int max_pages = queue_max_hw_sectors(q) >> (PAGE_SHIFT - 9); int i; + if (max_pages > BIO_MAX_PAGES) + max_pages = BIO_MAX_PAGES; bio = bio_alloc(GFP_NOFS, max_pages); - BUG_ON(!bio); /* FIXME: handle this */ + BUG_ON(!bio); for (i = 0; i < nr_pages; i++) { if (i >= max_pages) { -- cgit v0.10.2 From e07bf553f37cd4fa470b499ff34d800956df2d48 Mon Sep 17 00:00:00 2001 From: Joern Engel Date: Wed, 17 Mar 2010 15:29:38 +0100 Subject: Plug memory leak in writeseg_end_io Signed-off-by: Joern Engel diff --git a/fs/logfs/dev_bdev.c b/fs/logfs/dev_bdev.c index f99f5dc..a5d0c56 100644 --- a/fs/logfs/dev_bdev.c +++ b/fs/logfs/dev_bdev.c @@ -80,6 +80,7 @@ static void writeseg_end_io(struct bio *bio, int err) prefetchw(&bvec->bv_page->flags); end_page_writeback(page); + page_cache_release(page); } while (bvec >= bio->bi_io_vec); bio_put(bio); if (atomic_dec_and_test(&super->s_pending_writes)) -- cgit v0.10.2 From e326068806ee044cc617b1dc24be1293fca3fbf6 Mon Sep 17 00:00:00 2001 From: Joern Engel Date: Wed, 17 Mar 2010 16:00:07 +0100 Subject: Prevent schedule while atomic in __logfs_readdir Apparently filldir can sleep, which forbids kmap_atomic. Signed-off-by: Joern Engel diff --git a/fs/logfs/dir.c b/fs/logfs/dir.c index 56a8bfb..c76b4b5 100644 --- a/fs/logfs/dir.c +++ b/fs/logfs/dir.c @@ -303,12 +303,12 @@ static int __logfs_readdir(struct file *file, void *buf, filldir_t filldir) (filler_t *)logfs_readpage, NULL); if (IS_ERR(page)) return PTR_ERR(page); - dd = kmap_atomic(page, KM_USER0); + dd = kmap(page); BUG_ON(dd->namelen == 0); full = filldir(buf, (char *)dd->name, be16_to_cpu(dd->namelen), pos, be64_to_cpu(dd->ino), dd->type); - kunmap_atomic(dd, KM_USER0); + kunmap(page); page_cache_release(page); if (full) break; -- cgit v0.10.2 From faaa27ab919799929732c356a92a160f8657ecc6 Mon Sep 17 00:00:00 2001 From: Joern Engel Date: Fri, 26 Mar 2010 10:18:36 +0100 Subject: Write out both superblocks on mismatch If the first superblock is wrong and the second gets written, there will still be a mismatch on next mount. Write both to make sure they match. Signed-off-by: Joern Engel diff --git a/fs/logfs/super.c b/fs/logfs/super.c index 0187281..006670f 100644 --- a/fs/logfs/super.c +++ b/fs/logfs/super.c @@ -277,7 +277,7 @@ static int logfs_recover_sb(struct super_block *sb) } if (valid0 && valid1 && ds_cmp(ds0, ds1)) { printk(KERN_INFO"Superblocks don't match - fixing.\n"); - return write_one_sb(sb, super->s_devops->find_last_sb); + return logfs_write_sb(sb); } /* If neither is valid now, something's wrong. Didn't we properly * check them before?!? */ -- cgit v0.10.2 From 7db8064c17b92e95aec2e333096c035db9ddd4fe Mon Sep 17 00:00:00 2001 From: Joern Engel Date: Fri, 26 Mar 2010 14:45:55 +0100 Subject: Fix logfs_get_sb_final error path rootdir was already allocated, so we must iput it again. Found by Al Viro. Signed-off-by: Joern Engel diff --git a/fs/logfs/super.c b/fs/logfs/super.c index 006670f..2845c41 100644 --- a/fs/logfs/super.c +++ b/fs/logfs/super.c @@ -328,7 +328,7 @@ static int logfs_get_sb_final(struct super_block *sb, struct vfsmount *mnt) sb->s_root = d_alloc_root(rootdir); if (!sb->s_root) - goto fail; + goto fail2; super->s_erase_page = alloc_pages(GFP_KERNEL, 0); if (!super->s_erase_page) -- cgit v0.10.2 From 6f2e9e6a950a165a7d2c399ab7557e6745ef2bfd Mon Sep 17 00:00:00 2001 From: Joern Engel Date: Fri, 26 Mar 2010 14:50:08 +0100 Subject: Use deactivate_locked_super Found by Al Viro. Signed-off-by: Joern Engel diff --git a/fs/logfs/super.c b/fs/logfs/super.c index 2845c41..9d856c4 100644 --- a/fs/logfs/super.c +++ b/fs/logfs/super.c @@ -572,8 +572,7 @@ int logfs_get_sb_device(struct file_system_type *type, int flags, return 0; err1: - up_write(&sb->s_umount); - deactivate_super(sb); + deactivate_locked_super(sb); return err; err0: kfree(super); -- cgit v0.10.2 From e4afb29fa3ea759d408fa537ab6a81800708396e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 27 Mar 2010 07:55:58 -0700 Subject: Revert "via82cxxx: workaround h/w bugs" This reverts commit f931a5d5785d7b7c44871bd7ad2762e29dfddf29. It causes regressions for some users. Signed-off-by: David S. Miller diff --git a/drivers/ide/via82cxxx.c b/drivers/ide/via82cxxx.c index e65d010..48fd4ef 100644 --- a/drivers/ide/via82cxxx.c +++ b/drivers/ide/via82cxxx.c @@ -110,7 +110,6 @@ struct via82cxxx_dev { struct via_isa_bridge *via_config; unsigned int via_80w; - u8 cached_device[2]; }; /** @@ -403,66 +402,10 @@ static const struct ide_port_ops via_port_ops = { .cable_detect = via82cxxx_cable_detect, }; -static void via_write_devctl(ide_hwif_t *hwif, u8 ctl) -{ - struct via82cxxx_dev *vdev = hwif->host->host_priv; - - outb(ctl, hwif->io_ports.ctl_addr); - outb(vdev->cached_device[hwif->channel], hwif->io_ports.device_addr); -} - -static void __via_dev_select(ide_drive_t *drive, u8 select) -{ - ide_hwif_t *hwif = drive->hwif; - struct via82cxxx_dev *vdev = hwif->host->host_priv; - - outb(select, hwif->io_ports.device_addr); - vdev->cached_device[hwif->channel] = select; -} - -static void via_dev_select(ide_drive_t *drive) -{ - __via_dev_select(drive, drive->select | ATA_DEVICE_OBS); -} - -static void via_tf_load(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid) -{ - ide_hwif_t *hwif = drive->hwif; - struct ide_io_ports *io_ports = &hwif->io_ports; - - if (valid & IDE_VALID_FEATURE) - outb(tf->feature, io_ports->feature_addr); - if (valid & IDE_VALID_NSECT) - outb(tf->nsect, io_ports->nsect_addr); - if (valid & IDE_VALID_LBAL) - outb(tf->lbal, io_ports->lbal_addr); - if (valid & IDE_VALID_LBAM) - outb(tf->lbam, io_ports->lbam_addr); - if (valid & IDE_VALID_LBAH) - outb(tf->lbah, io_ports->lbah_addr); - if (valid & IDE_VALID_DEVICE) - __via_dev_select(drive, tf->device); -} - -const struct ide_tp_ops via_tp_ops = { - .exec_command = ide_exec_command, - .read_status = ide_read_status, - .read_altstatus = ide_read_altstatus, - .write_devctl = via_write_devctl, - - .dev_select = via_dev_select, - .tf_load = via_tf_load, - .tf_read = ide_tf_read, - - .input_data = ide_input_data, - .output_data = ide_output_data, -}; - static const struct ide_port_info via82cxxx_chipset __devinitdata = { .name = DRV_NAME, .init_chipset = init_chipset_via82cxxx, .enablebits = { { 0x40, 0x02, 0x02 }, { 0x40, 0x01, 0x01 } }, - .tp_ops = &via_tp_ops, .port_ops = &via_port_ops, .host_flags = IDE_HFLAG_PIO_NO_BLACKLIST | IDE_HFLAG_POST_SET_MODE | -- cgit v0.10.2 From 71c5c1595c04852d6fbf3c4882b47b30b61a4d32 Mon Sep 17 00:00:00 2001 From: Brandon L Black Date: Fri, 26 Mar 2010 16:18:03 +0000 Subject: net: Add MSG_WAITFORONE flag to recvmmsg Add new flag MSG_WAITFORONE for the recvmmsg() syscall. When this flag is specified for a blocking socket, recvmmsg() will only block until at least 1 packet is available. The default behavior is to block until all vlen packets are available. This flag has no effect on non-blocking sockets or when used in combination with MSG_DONTWAIT. Signed-off-by: Brandon L Black Acked-by: Ulrich Drepper Acked-by: Eric Dumazet Acked-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller diff --git a/include/linux/socket.h b/include/linux/socket.h index 7b3aae2..354cc56 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -255,6 +255,7 @@ struct ucred { #define MSG_ERRQUEUE 0x2000 /* Fetch message from error queue */ #define MSG_NOSIGNAL 0x4000 /* Do not generate SIGPIPE */ #define MSG_MORE 0x8000 /* Sender will send more */ +#define MSG_WAITFORONE 0x10000 /* recvmmsg(): block until 1+ packets avail */ #define MSG_EOF MSG_FIN diff --git a/net/socket.c b/net/socket.c index 769c386..f55ffe9 100644 --- a/net/socket.c +++ b/net/socket.c @@ -2135,6 +2135,10 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, break; ++datagrams; + /* MSG_WAITFORONE turns on MSG_DONTWAIT after one packet */ + if (flags & MSG_WAITFORONE) + flags |= MSG_DONTWAIT; + if (timeout) { ktime_get_ts(timeout); *timeout = timespec_sub(end_time, *timeout); -- cgit v0.10.2 From c0e4d4bad4e8cf0aa787a3045392f949d76b5886 Mon Sep 17 00:00:00 2001 From: wzt wzt Date: Thu, 25 Mar 2010 20:12:59 +0000 Subject: benet: Fix compile warnnings in drivers/net/benet/be_ethtool.c Fix the following warnings: be_ethtool.c:493: warning: integer constant is too large for 'long' type be_ethtool.c:493: warning: integer constant is too large for 'long' type Signed-off-by: Zhitong Wang Acked-by: Ajit Khaparde Signed-off-by: David S. Miller diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index 9560d48..51e1065 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c @@ -490,7 +490,7 @@ be_test_ddr_dma(struct be_adapter *adapter) { int ret, i; struct be_dma_mem ddrdma_cmd; - u64 pattern[2] = {0x5a5a5a5a5a5a5a5a, 0xa5a5a5a5a5a5a5a5}; + u64 pattern[2] = {0x5a5a5a5a5a5a5a5aULL, 0xa5a5a5a5a5a5a5a5ULL}; ddrdma_cmd.size = sizeof(struct be_cmd_req_ddrdma_test); ddrdma_cmd.va = pci_alloc_consistent(adapter->pdev, ddrdma_cmd.size, -- cgit v0.10.2 From e017b60316468f21a63bdd4affefaf81a7f988fd Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Thu, 25 Mar 2010 17:15:06 +0000 Subject: igb: use correct bits to identify if managability is enabled igb was previously checking the wrong bits in the MANC register to determine if managability was enabled. As a result it was incorrectly powering down and resetting the phy when it didn't need to. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller diff --git a/drivers/net/igb/e1000_mac.c b/drivers/net/igb/e1000_mac.c index 2a8a886..be8d010 100644 --- a/drivers/net/igb/e1000_mac.c +++ b/drivers/net/igb/e1000_mac.c @@ -1367,7 +1367,8 @@ out: * igb_enable_mng_pass_thru - Enable processing of ARP's * @hw: pointer to the HW structure * - * Verifies the hardware needs to allow ARPs to be processed by the host. + * Verifies the hardware needs to leave interface enabled so that frames can + * be directed to and from the management interface. **/ bool igb_enable_mng_pass_thru(struct e1000_hw *hw) { @@ -1380,8 +1381,7 @@ bool igb_enable_mng_pass_thru(struct e1000_hw *hw) manc = rd32(E1000_MANC); - if (!(manc & E1000_MANC_RCV_TCO_EN) || - !(manc & E1000_MANC_EN_MAC_ADDR_FILTER)) + if (!(manc & E1000_MANC_RCV_TCO_EN)) goto out; if (hw->mac.arc_subsystem_valid) { -- cgit v0.10.2 From e7d481a6f3c13041446b7bb8f98ab861460076a3 Mon Sep 17 00:00:00 2001 From: Greg Rose Date: Thu, 25 Mar 2010 17:06:48 +0000 Subject: ixgbe: Do not run all Diagnostic offline tests when VFs are active When running the offline diagnostic tests check to see if any VFs are online. If so then only run the link test. This is necessary because the VFs running in guest VMs aren't aware of when the PF is taken offline for a diagnostic test. Also put a message to the system log telling the system administrator to take the VFs offline manually if (s)he wants to run a full diagnostic. Return 1 on each of the tests not run to alert the user of the condition. Signed-off-by: Greg Rose Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 7949a44..1959ef7 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -1853,6 +1853,26 @@ static void ixgbe_diag_test(struct net_device *netdev, if (ixgbe_link_test(adapter, &data[4])) eth_test->flags |= ETH_TEST_FL_FAILED; + if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) { + int i; + for (i = 0; i < adapter->num_vfs; i++) { + if (adapter->vfinfo[i].clear_to_send) { + netdev_warn(netdev, "%s", + "offline diagnostic is not " + "supported when VFs are " + "present\n"); + data[0] = 1; + data[1] = 1; + data[2] = 1; + data[3] = 1; + eth_test->flags |= ETH_TEST_FL_FAILED; + clear_bit(__IXGBE_TESTING, + &adapter->state); + goto skip_ol_tests; + } + } + } + if (if_running) /* indicate we're in test mode */ dev_close(netdev); @@ -1908,6 +1928,7 @@ skip_loopback: clear_bit(__IXGBE_TESTING, &adapter->state); } +skip_ol_tests: msleep_interruptible(4 * 1000); } -- cgit v0.10.2 From 7438189baa0a2fe30084bdc97e3d540ebc5444f3 Mon Sep 17 00:00:00 2001 From: Nicolas Dichtel Date: Thu, 25 Mar 2010 23:45:35 +0000 Subject: net: ipmr/ip6mr: prevent out-of-bounds vif_table access When cache is unresolved, c->mf[6]c_parent is set to 65535 and minvif, maxvif are not initialized, hence we must avoid to parse IIF and OIF. A second problem can happen when the user dumps a cache entry where a VIF, that was referenced at creation time, has been removed. Signed-off-by: Nicolas Dichtel Signed-off-by: David S. Miller diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 0b9d03c..d0a6092 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -1616,17 +1616,20 @@ ipmr_fill_mroute(struct sk_buff *skb, struct mfc_cache *c, struct rtmsg *rtm) int ct; struct rtnexthop *nhp; struct net *net = mfc_net(c); - struct net_device *dev = net->ipv4.vif_table[c->mfc_parent].dev; u8 *b = skb_tail_pointer(skb); struct rtattr *mp_head; - if (dev) - RTA_PUT(skb, RTA_IIF, 4, &dev->ifindex); + /* If cache is unresolved, don't try to parse IIF and OIF */ + if (c->mfc_parent > MAXVIFS) + return -ENOENT; + + if (VIF_EXISTS(net, c->mfc_parent)) + RTA_PUT(skb, RTA_IIF, 4, &net->ipv4.vif_table[c->mfc_parent].dev->ifindex); mp_head = (struct rtattr *)skb_put(skb, RTA_LENGTH(0)); for (ct = c->mfc_un.res.minvif; ct < c->mfc_un.res.maxvif; ct++) { - if (c->mfc_un.res.ttls[ct] < 255) { + if (VIF_EXISTS(net, ct) && c->mfc_un.res.ttls[ct] < 255) { if (skb_tailroom(skb) < RTA_ALIGN(RTA_ALIGN(sizeof(*nhp)) + 4)) goto rtattr_failure; nhp = (struct rtnexthop *)skb_put(skb, RTA_ALIGN(sizeof(*nhp))); diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 23e4ac0..27acfb5 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c @@ -1695,17 +1695,20 @@ ip6mr_fill_mroute(struct sk_buff *skb, struct mfc6_cache *c, struct rtmsg *rtm) int ct; struct rtnexthop *nhp; struct net *net = mfc6_net(c); - struct net_device *dev = net->ipv6.vif6_table[c->mf6c_parent].dev; u8 *b = skb_tail_pointer(skb); struct rtattr *mp_head; - if (dev) - RTA_PUT(skb, RTA_IIF, 4, &dev->ifindex); + /* If cache is unresolved, don't try to parse IIF and OIF */ + if (c->mf6c_parent > MAXMIFS) + return -ENOENT; + + if (MIF_EXISTS(net, c->mf6c_parent)) + RTA_PUT(skb, RTA_IIF, 4, &net->ipv6.vif6_table[c->mf6c_parent].dev->ifindex); mp_head = (struct rtattr *)skb_put(skb, RTA_LENGTH(0)); for (ct = c->mfc_un.res.minvif; ct < c->mfc_un.res.maxvif; ct++) { - if (c->mfc_un.res.ttls[ct] < 255) { + if (MIF_EXISTS(net, ct) && c->mfc_un.res.ttls[ct] < 255) { if (skb_tailroom(skb) < RTA_ALIGN(RTA_ALIGN(sizeof(*nhp)) + 4)) goto rtattr_failure; nhp = (struct rtnexthop *)skb_put(skb, RTA_ALIGN(sizeof(*nhp))); -- cgit v0.10.2 From 39ca5f033bb2ea18877632809185268eebbb37a9 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Fri, 26 Mar 2010 11:25:58 +0000 Subject: e1000: do not modify tx_queue_len on link speed change Previously the driver tweaked txqueuelen to avoid false Tx hang reports seen at half duplex. This had the effect of overriding user set values on link change/reset. Testing shows that adjusting only the timeout factor is sufficient to prevent Tx hang reports at half duplex. This patch removes all instances of tx_queue_len in the driver. Based on e1000e patch by Franco Fichtner CC: Franco Fichtner Signed-off-by: Emil Tantilov Acked-by: Jesse Brandeburg Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h index 9902b33..2f29c21 100644 --- a/drivers/net/e1000/e1000.h +++ b/drivers/net/e1000/e1000.h @@ -261,7 +261,6 @@ struct e1000_adapter { /* TX */ struct e1000_tx_ring *tx_ring; /* One per active queue */ unsigned int restart_queue; - unsigned long tx_queue_len; u32 txd_cmd; u32 tx_int_delay; u32 tx_abs_int_delay; diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 8be6fae..b15ece2 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -383,8 +383,6 @@ static void e1000_configure(struct e1000_adapter *adapter) adapter->alloc_rx_buf(adapter, ring, E1000_DESC_UNUSED(ring)); } - - adapter->tx_queue_len = netdev->tx_queue_len; } int e1000_up(struct e1000_adapter *adapter) @@ -503,7 +501,6 @@ void e1000_down(struct e1000_adapter *adapter) del_timer_sync(&adapter->watchdog_timer); del_timer_sync(&adapter->phy_info_timer); - netdev->tx_queue_len = adapter->tx_queue_len; adapter->link_speed = 0; adapter->link_duplex = 0; netif_carrier_off(netdev); @@ -2316,19 +2313,15 @@ static void e1000_watchdog(unsigned long data) E1000_CTRL_RFCE) ? "RX" : ((ctrl & E1000_CTRL_TFCE) ? "TX" : "None" ))); - /* tweak tx_queue_len according to speed/duplex - * and adjust the timeout factor */ - netdev->tx_queue_len = adapter->tx_queue_len; + /* adjust timeout factor according to speed/duplex */ adapter->tx_timeout_factor = 1; switch (adapter->link_speed) { case SPEED_10: txb2b = false; - netdev->tx_queue_len = 10; adapter->tx_timeout_factor = 16; break; case SPEED_100: txb2b = false; - netdev->tx_queue_len = 100; /* maybe add some timeout factor ? */ break; } -- cgit v0.10.2 From 44ebb95290afcc687511ad3f7fd6434e867c270a Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Fri, 26 Mar 2010 16:27:55 +0000 Subject: drivers/net: Fix continuation lines Signed-off-by: Joe Perches Signed-off-by: David S. Miller diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c index 9ba5470..0ebd820 100644 --- a/drivers/net/atlx/atl1.c +++ b/drivers/net/atlx/atl1.c @@ -84,7 +84,7 @@ #define ATLX_DRIVER_VERSION "2.1.3" MODULE_AUTHOR("Xiong Huang , \ - Chris Snook , Jay Cliburn "); +Chris Snook , Jay Cliburn "); MODULE_LICENSE("GPL"); MODULE_VERSION(ATLX_DRIVER_VERSION); -- cgit v0.10.2 From 7469a9acf919d36836f6c635099d8edc9be4528a Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Sat, 27 Mar 2010 08:36:18 -0700 Subject: sparc: Fix use of uid16_t and gid16_t in asm/stat.h Signed-off-by: Rob Landley Signed-off-by: David S. Miller diff --git a/arch/sparc/include/asm/stat.h b/arch/sparc/include/asm/stat.h index 39327d6..a232e9e 100644 --- a/arch/sparc/include/asm/stat.h +++ b/arch/sparc/include/asm/stat.h @@ -53,8 +53,8 @@ struct stat { ino_t st_ino; mode_t st_mode; short st_nlink; - uid16_t st_uid; - gid16_t st_gid; + unsigned short st_uid; + unsigned short st_gid; unsigned short st_rdev; off_t st_size; time_t st_atime; -- cgit v0.10.2 From 4ae0a6c15efcc37e94e3f30e3533bdec03c53126 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Tue, 9 Mar 2010 14:14:51 -0600 Subject: [SCSI] libiscsi: Fix recovery slowdown regression We could be failing/stopping a connection due to libiscsi starting recovery/cleanup, but the xmit path or scsi eh thread path could be dropping the connection at the same time. As a result the session->state gets set to failed instead of in recovery. We end up not blocking the session and so the replacement timeout never gets started and we only end up failing the IO when scsi_softirq_done sees that the cmd has been running for (cmd->allowed + 1) * rq->timeout secs. We used to fail the IO right away so users are seeing a long delay when using dm-multipath. This problem was added in 2.6.28. Signed-off-by: Mike Christie Cc: stable@kernel.org Signed-off-by: James Bottomley diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 685eaec..7688b8f 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -3087,14 +3087,15 @@ static void iscsi_start_session_recovery(struct iscsi_session *session, session->state = ISCSI_STATE_TERMINATE; else if (conn->stop_stage != STOP_CONN_RECOVER) session->state = ISCSI_STATE_IN_RECOVERY; + + old_stop_stage = conn->stop_stage; + conn->stop_stage = flag; spin_unlock_bh(&session->lock); del_timer_sync(&conn->transport_timer); iscsi_suspend_tx(conn); spin_lock_bh(&session->lock); - old_stop_stage = conn->stop_stage; - conn->stop_stage = flag; conn->c_stage = ISCSI_CONN_STOPPED; spin_unlock_bh(&session->lock); -- cgit v0.10.2 From d88a714bfefa7aed7b9cb6c3721707fcd056b472 Mon Sep 17 00:00:00 2001 From: Sarang Radke Date: Wed, 10 Mar 2010 04:03:04 -0600 Subject: [SCSI] scsi_transport_fc: Make sure commands are completed when rport is offline blk_end_request doesn't complete a bidi request successfully The unfinished request eventually triggers a panic in timeout handling routine fc_bsg_job_timeout as req->special is NULL Use blk_end_request_all to end the request unconditionally Signed-off-by: Lalit Chandivade Acked-by: James Smart Signed-off-by: James Bottomley diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index 1d5b721..e37aeeb 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -3852,7 +3852,7 @@ fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost, if (rport && (rport->port_state != FC_PORTSTATE_ONLINE)) { req->errors = -ENXIO; spin_unlock_irq(q->queue_lock); - blk_end_request(req, -ENXIO, blk_rq_bytes(req)); + blk_end_request_all(req, -ENXIO); spin_lock_irq(q->queue_lock); continue; } @@ -3862,7 +3862,7 @@ fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost, ret = fc_req_to_bsgjob(shost, rport, req); if (ret) { req->errors = ret; - blk_end_request(req, ret, blk_rq_bytes(req)); + blk_end_request_all(req, ret); spin_lock_irq(q->queue_lock); continue; } -- cgit v0.10.2 From cad454b12a23c24fd7f409402cf51434655e76c1 Mon Sep 17 00:00:00 2001 From: Santosh Vernekar Date: Fri, 19 Mar 2010 16:59:16 -0700 Subject: [SCSI] qla2xxx: Honour "Extended BB credits" bit for CNAs. We now enable/disable "Additional Receive Credits" in f/w based on nvram parameter "Extended_BB_Credits" bit (i.e. Enhanced-Features: at offset 0x196). This is applicable only for GEN2 CNAs. Signed-off-by: Santosh Vernekar Signed-off-by: Giridhar Malavali Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index cebf4f1..42c5587 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h @@ -1592,10 +1592,22 @@ struct nvram_81xx { /* Offset 384. */ uint8_t reserved_21[16]; - uint16_t reserved_22[8]; + uint16_t reserved_22[3]; + + /* + * BIT 0 = Extended BB credits for LR + * BIT 1 = Virtual Fabric Enable + * BIT 2 = Enhanced Features Unused + * BIT 3-7 = Enhanced Features Reserved + */ + /* Enhanced Features */ + uint8_t enhanced_features; + + uint8_t reserved_23; + uint16_t reserved_24[4]; /* Offset 416. */ - uint16_t reserved_23[32]; + uint16_t reserved_25[32]; /* Offset 480. */ uint8_t model_name[16]; @@ -1603,7 +1615,7 @@ struct nvram_81xx { /* Offset 496. */ uint16_t feature_mask_l; uint16_t feature_mask_h; - uint16_t reserved_24[2]; + uint16_t reserved_26[2]; uint16_t subsystem_vendor_id; uint16_t subsystem_device_id; diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 6e53bdb..3ba9a2b 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -339,6 +339,7 @@ qla2x00_load_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t risc_addr, return rval; } +#define EXTENDED_BB_CREDITS BIT_0 /* * qla2x00_execute_fw * Start adapter firmware. @@ -371,7 +372,12 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr) mcp->mb[1] = MSW(risc_addr); mcp->mb[2] = LSW(risc_addr); mcp->mb[3] = 0; - mcp->mb[4] = 0; + if (IS_QLA81XX(ha)) { + struct nvram_81xx *nv = ha->nvram; + mcp->mb[4] = (nv->enhanced_features & + EXTENDED_BB_CREDITS); + } else + mcp->mb[4] = 0; mcp->out_mb |= MBX_4|MBX_3|MBX_2|MBX_1; mcp->in_mb |= MBX_1; } else { -- cgit v0.10.2 From 12cec63e40f9b9c2a4766a0f43404a9642062f35 Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Fri, 19 Mar 2010 16:59:17 -0700 Subject: [SCSI] qla2xxx: Correct vp_idx checking during PORT_UPDATE processing. Checks should only be done for NPIV-capable ISPs. Original code could result in PORT_UPDATEs being missed on non-NPIV-capable ISPs. Signed-off-by: Andrew Vasquez Signed-off-by: Giridhar Malavali Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index ab90329..295337d 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -620,11 +620,10 @@ skip_rio: * vp_idx does not match * Event is not global, vp_idx does not match */ - if ((mb[1] == 0xffff && (mb[3] & 0xff) != 0xff) - || (mb[1] != 0xffff)) { - if (vha->vp_idx != (mb[3] & 0xff)) - break; - } + if (IS_QLA2XXX_MIDTYPE(ha) && + ((mb[1] == 0xffff && (mb[3] & 0xff) != 0xff) || + (mb[1] != 0xffff)) && vha->vp_idx != (mb[3] & 0xff)) + break; /* Global event -- port logout or port unavailable. */ if (mb[1] == 0xffff && mb[2] == 0x7) { -- cgit v0.10.2 From d84a47c2e8d8880d068f23f3033f6f6987717b17 Mon Sep 17 00:00:00 2001 From: Michael Hernandez Date: Fri, 19 Mar 2010 16:59:18 -0700 Subject: [SCSI] qla2xxx: Check to make sure multique and CPU affinity support is not enabled at the same time. The logic is changed to detect this condition based on following 1) both module parameters are off (ql2xmaxqueues and ql2xmultique_tag). 2) both module parameters are on (ql2xmaxqueues and ql2xmultique_tag). 3) The HBA does not support multi queue. Signed-off-by: Giridhar Malavali Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 46720b2..be3f1d3 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -1676,9 +1676,11 @@ skip_pio: /* Determine queue resources */ ha->max_req_queues = ha->max_rsp_queues = 1; - if ((ql2xmaxqueues <= 1 || ql2xmultique_tag < 1) && + if ((ql2xmaxqueues <= 1 && !ql2xmultique_tag) || + (ql2xmaxqueues > 1 && ql2xmultique_tag) || (!IS_QLA25XX(ha) && !IS_QLA81XX(ha))) goto mqiobase_exit; + ha->mqiobase = ioremap(pci_resource_start(ha->pdev, 3), pci_resource_len(ha->pdev, 3)); if (ha->mqiobase) { -- cgit v0.10.2 From 6377a7ae1ab82859edccdbc8eaea63782efb134d Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 19 Mar 2010 16:59:19 -0700 Subject: [SCSI] qla2xxx: Disable MSI on qla24xx chips other than QLA2432. On specific platforms, MSI is unreliable on some of the QLA24xx chips, resulting in fatal I/O errors under load, as reported in and by some RHEL customers. Signed-off-by: Giridhar Malavali Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 295337d..44df0b7 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -2271,30 +2271,28 @@ qla2x00_request_irqs(struct qla_hw_data *ha, struct rsp_que *rsp) /* If possible, enable MSI-X. */ if (!IS_QLA2432(ha) && !IS_QLA2532(ha) && - !IS_QLA8432(ha) && !IS_QLA8001(ha)) - goto skip_msix; + !IS_QLA8432(ha) && !IS_QLA8001(ha)) + goto skip_msi; + + if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_HP && + (ha->pdev->subsystem_device == 0x7040 || + ha->pdev->subsystem_device == 0x7041 || + ha->pdev->subsystem_device == 0x1705)) { + DEBUG2(qla_printk(KERN_WARNING, ha, + "MSI-X: Unsupported ISP2432 SSVID/SSDID (0x%X,0x%X).\n", + ha->pdev->subsystem_vendor, + ha->pdev->subsystem_device)); + goto skip_msi; + } if (IS_QLA2432(ha) && (ha->pdev->revision < QLA_MSIX_CHIP_REV_24XX || !QLA_MSIX_FW_MODE_1(ha->fw_attributes))) { DEBUG2(qla_printk(KERN_WARNING, ha, "MSI-X: Unsupported ISP2432 (0x%X, 0x%X).\n", ha->pdev->revision, ha->fw_attributes)); - goto skip_msix; } - if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_HP && - (ha->pdev->subsystem_device == 0x7040 || - ha->pdev->subsystem_device == 0x7041 || - ha->pdev->subsystem_device == 0x1705)) { - DEBUG2(qla_printk(KERN_WARNING, ha, - "MSI-X: Unsupported ISP2432 SSVID/SSDID (0x%X, 0x%X).\n", - ha->pdev->subsystem_vendor, - ha->pdev->subsystem_device)); - - goto skip_msi; - } - ret = qla24xx_enable_msix(ha, rsp); if (!ret) { DEBUG2(qla_printk(KERN_INFO, ha, -- cgit v0.10.2 From d6136f3f749cf68c3295c883cea612afd9919100 Mon Sep 17 00:00:00 2001 From: Santosh Vernekar Date: Fri, 19 Mar 2010 16:59:20 -0700 Subject: [SCSI] qla2xxx: Prevent sending mbx commands from sysfs during isp reset. The fix prevents application path from sending get-firmware-state mbx command during as isp reset. Signed-off-by: Giridhar Malavali Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 90d1e06..35a3252 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -1274,7 +1274,11 @@ qla2x00_fw_state_show(struct device *dev, struct device_attribute *attr, int rval = QLA_FUNCTION_FAILED; uint16_t state[5]; - if (!vha->hw->flags.eeh_busy) + if (test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) || + test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags)) + DEBUG2_3_11(printk("%s(%ld): isp reset in progress.\n", + __func__, vha->host_no)); + else if (!vha->hw->flags.eeh_busy) rval = qla2x00_get_firmware_state(vha, state); if (rval != QLA_SUCCESS) memset(state, -1, sizeof(state)); -- cgit v0.10.2 From 89162e9c21de3cb3b7e9e29d50cb7c3e88a09e2b Mon Sep 17 00:00:00 2001 From: Giridhar Malavali Date: Fri, 19 Mar 2010 16:59:21 -0700 Subject: [SCSI] qla2xxx: Updated version number to 8.03.02-k2. Signed-off-by: Giridhar Malavali Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index 8d2fc2f..109068d 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h @@ -7,9 +7,9 @@ /* * Driver version */ -#define QLA2XXX_VERSION "8.03.02-k1" +#define QLA2XXX_VERSION "8.03.02-k2" #define QLA_DRIVER_MAJOR_VER 8 #define QLA_DRIVER_MINOR_VER 3 #define QLA_DRIVER_PATCH_VER 2 -#define QLA_DRIVER_BETA_VER 1 +#define QLA_DRIVER_BETA_VER 2 -- cgit v0.10.2 From cf7474451c3a3cf07811abbf2a39536d33046c36 Mon Sep 17 00:00:00 2001 From: Herton Ronaldo Krzesinski Date: Fri, 19 Mar 2010 19:37:26 -0300 Subject: [SCSI] advansys: fix regression with request_firmware change On newer kernels users of advansys module are reporting system hang when trying to load it without firmware files present. After looking closely at description on https://qa.mandriva.com/show_bug.cgi?id=53220, I think this is related to commit "[SCSI] advansys: use request_firmware". The problem is that after switch to request_firmware, asc_dvc->err_code isn't being set when firmware files aren't found or loading fails. err_code is used by the driver to judge if there was a fatal error or not, as can be seen for example on advansys_board_found, which will only return -ENODEV when err_code is set. Because err_code isn't being set when request_firmware fails, this is a change of behaviour of the code before request_firmware addition, making it continue to load and it fails later as the firmware wasn't really loaded. Signed-off-by: Herton Ronaldo Krzesinski Signed-off-by: James Bottomley diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 22626ab..9201afe 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -4781,12 +4781,14 @@ static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc) if (err) { printk(KERN_ERR "Failed to load image \"%s\" err %d\n", fwname, err); + asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM; return err; } if (fw->size < 4) { printk(KERN_ERR "Bogus length %zu in image \"%s\"\n", fw->size, fwname); release_firmware(fw); + asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM; return -EINVAL; } chksum = (fw->data[3] << 24) | (fw->data[2] << 16) | @@ -5110,12 +5112,14 @@ static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc) if (err) { printk(KERN_ERR "Failed to load image \"%s\" err %d\n", fwname, err); + asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM; return err; } if (fw->size < 4) { printk(KERN_ERR "Bogus length %zu in image \"%s\"\n", fw->size, fwname); release_firmware(fw); + asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM; return -EINVAL; } chksum = (fw->data[3] << 24) | (fw->data[2] << 16) | @@ -5624,12 +5628,14 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc) if (err) { printk(KERN_ERR "Failed to load image \"%s\" err %d\n", fwname, err); + asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM; return err; } if (fw->size < 4) { printk(KERN_ERR "Bogus length %zu in image \"%s\"\n", fw->size, fwname); release_firmware(fw); + asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM; return -EINVAL; } chksum = (fw->data[3] << 24) | (fw->data[2] << 16) | @@ -6124,12 +6130,14 @@ static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc) if (err) { printk(KERN_ERR "Failed to load image \"%s\" err %d\n", fwname, err); + asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM; return err; } if (fw->size < 4) { printk(KERN_ERR "Bogus length %zu in image \"%s\"\n", fw->size, fwname); release_firmware(fw); + asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM; return -EINVAL; } chksum = (fw->data[3] << 24) | (fw->data[2] << 16) | -- cgit v0.10.2 From ebd09ec93c90c8ec571d7e166832fb1fc705bf5e Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Sat, 20 Mar 2010 12:44:12 -0500 Subject: [SCSI] attirbute_container: Initialize sysfs attributes with sysfs_attr_init All of the SCSI transport classes are suddenly spitting lockdep warnings. According to Eric Biderman this is because lockdep needs static initialisers and the attribute container way of doing things end up with dynamic sysfs attributes. Fix this by calling sysfs_attr_init which sets the lockdep key correctly. Tested-by: Christof Schmitt Signed-off-by: James Bottomley diff --git a/drivers/base/attribute_container.c b/drivers/base/attribute_container.c index b9cda05..8fc200b 100644 --- a/drivers/base/attribute_container.c +++ b/drivers/base/attribute_container.c @@ -328,6 +328,7 @@ attribute_container_add_attrs(struct device *classdev) return sysfs_create_group(&classdev->kobj, cont->grp); for (i = 0; attrs[i]; i++) { + sysfs_attr_init(&attrs[i]->attr); error = device_create_file(classdev, attrs[i]); if (error) return error; -- cgit v0.10.2 From 421e33d0045ac0aa119c033b78742e0fbf4c3b21 Mon Sep 17 00:00:00 2001 From: Michael Reed Date: Tue, 23 Mar 2010 15:00:58 -0500 Subject: [SCSI] qla1280: retain firmware for error recovery The qla1280 driver acquires its firmware via udev. During boot the firmware is located in the initrd. If, after root is mounted, the adapter needs to reload firmware (host reset), the firmware load may fail if the root device is on the adapter being reset. This patch modifies qla1280 to retain the firmware loaded via the initial request_firmware() for use during error recovery. [jejb: fix up checkpatch issues] Signed-off-by: Michael Reed Acked-by: Jes Sorensen Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c index 49ac414..66e2dd4 100644 --- a/drivers/scsi/qla1280.c +++ b/drivers/scsi/qla1280.c @@ -17,9 +17,11 @@ * General Public License for more details. * ******************************************************************************/ -#define QLA1280_VERSION "3.27" +#define QLA1280_VERSION "3.27.1" /***************************************************************************** Revision History: + Rev 3.27.1, February 8, 2010, Michael Reed + - Retain firmware image for error recovery. Rev 3.27, February 10, 2009, Michael Reed - General code cleanup. - Improve error recovery. @@ -538,9 +540,9 @@ __setup("qla1280=", qla1280_setup); /*****************************************/ struct qla_boards { - unsigned char name[9]; /* Board ID String */ + char *name; /* Board ID String */ int numPorts; /* Number of SCSI ports */ - char *fwname; /* firmware name */ + int fw_index; /* index into qla1280_fw_tbl for firmware */ }; /* NOTE: the last argument in each entry is used to index ql1280_board_tbl */ @@ -561,15 +563,30 @@ static struct pci_device_id qla1280_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, qla1280_pci_tbl); +DEFINE_MUTEX(qla1280_firmware_mutex); + +struct qla_fw { + char *fwname; + const struct firmware *fw; +}; + +#define QL_NUM_FW_IMAGES 3 + +struct qla_fw qla1280_fw_tbl[QL_NUM_FW_IMAGES] = { + {"qlogic/1040.bin", NULL}, /* image 0 */ + {"qlogic/1280.bin", NULL}, /* image 1 */ + {"qlogic/12160.bin", NULL}, /* image 2 */ +}; + +/* NOTE: Order of boards in this table must match order in qla1280_pci_tbl */ static struct qla_boards ql1280_board_tbl[] = { - /* Name , Number of ports, FW details */ - {"QLA12160", 2, "qlogic/12160.bin"}, - {"QLA1040", 1, "qlogic/1040.bin"}, - {"QLA1080", 1, "qlogic/1280.bin"}, - {"QLA1240", 2, "qlogic/1280.bin"}, - {"QLA1280", 2, "qlogic/1280.bin"}, - {"QLA10160", 1, "qlogic/12160.bin"}, - {" ", 0, " "}, + {.name = "QLA12160", .numPorts = 2, .fw_index = 2}, + {.name = "QLA1040" , .numPorts = 1, .fw_index = 0}, + {.name = "QLA1080" , .numPorts = 1, .fw_index = 1}, + {.name = "QLA1240" , .numPorts = 2, .fw_index = 1}, + {.name = "QLA1280" , .numPorts = 2, .fw_index = 1}, + {.name = "QLA10160", .numPorts = 1, .fw_index = 2}, + {.name = " ", .numPorts = 0, .fw_index = -1}, }; static int qla1280_verbose = 1; @@ -1512,6 +1529,63 @@ qla1280_initialize_adapter(struct scsi_qla_host *ha) } /* + * qla1280_request_firmware + * Acquire firmware for chip. Retain in memory + * for error recovery. + * + * Input: + * ha = adapter block pointer. + * + * Returns: + * Pointer to firmware image or an error code + * cast to pointer via ERR_PTR(). + */ +static const struct firmware * +qla1280_request_firmware(struct scsi_qla_host *ha) +{ + const struct firmware *fw; + int err; + int index; + char *fwname; + + spin_unlock_irq(ha->host->host_lock); + mutex_lock(&qla1280_firmware_mutex); + + index = ql1280_board_tbl[ha->devnum].fw_index; + fw = qla1280_fw_tbl[index].fw; + if (fw) + goto out; + + fwname = qla1280_fw_tbl[index].fwname; + err = request_firmware(&fw, fwname, &ha->pdev->dev); + + if (err) { + printk(KERN_ERR "Failed to load image \"%s\" err %d\n", + fwname, err); + fw = ERR_PTR(err); + goto unlock; + } + if ((fw->size % 2) || (fw->size < 6)) { + printk(KERN_ERR "Invalid firmware length %zu in image \"%s\"\n", + fw->size, fwname); + release_firmware(fw); + fw = ERR_PTR(-EINVAL); + goto unlock; + } + + qla1280_fw_tbl[index].fw = fw; + + out: + ha->fwver1 = fw->data[0]; + ha->fwver2 = fw->data[1]; + ha->fwver3 = fw->data[2]; + unlock: + mutex_unlock(&qla1280_firmware_mutex); + spin_lock_irq(ha->host->host_lock); + return fw; +} + +/* * Chip diagnostics * Test chip for proper operation. * @@ -1634,30 +1708,18 @@ qla1280_chip_diag(struct scsi_qla_host *ha) static int qla1280_load_firmware_pio(struct scsi_qla_host *ha) { + /* enter with host_lock acquired */ + const struct firmware *fw; const __le16 *fw_data; uint16_t risc_address, risc_code_size; uint16_t mb[MAILBOX_REGISTER_COUNT], i; - int err; + int err = 0; + + fw = qla1280_request_firmware(ha); + if (IS_ERR(fw)) + return PTR_ERR(fw); - spin_unlock_irq(ha->host->host_lock); - err = request_firmware(&fw, ql1280_board_tbl[ha->devnum].fwname, - &ha->pdev->dev); - spin_lock_irq(ha->host->host_lock); - if (err) { - printk(KERN_ERR "Failed to load image \"%s\" err %d\n", - ql1280_board_tbl[ha->devnum].fwname, err); - return err; - } - if ((fw->size % 2) || (fw->size < 6)) { - printk(KERN_ERR "Bogus length %zu in image \"%s\"\n", - fw->size, ql1280_board_tbl[ha->devnum].fwname); - err = -EINVAL; - goto out; - } - ha->fwver1 = fw->data[0]; - ha->fwver2 = fw->data[1]; - ha->fwver3 = fw->data[2]; fw_data = (const __le16 *)&fw->data[0]; ha->fwstart = __le16_to_cpu(fw_data[2]); @@ -1675,11 +1737,10 @@ qla1280_load_firmware_pio(struct scsi_qla_host *ha) if (err) { printk(KERN_ERR "scsi(%li): Failed to load firmware\n", ha->host_no); - goto out; + break; } } -out: - release_firmware(fw); + return err; } @@ -1687,6 +1748,7 @@ out: static int qla1280_load_firmware_dma(struct scsi_qla_host *ha) { + /* enter with host_lock acquired */ const struct firmware *fw; const __le16 *fw_data; uint16_t risc_address, risc_code_size; @@ -1701,24 +1763,10 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha) return -ENOMEM; #endif - spin_unlock_irq(ha->host->host_lock); - err = request_firmware(&fw, ql1280_board_tbl[ha->devnum].fwname, - &ha->pdev->dev); - spin_lock_irq(ha->host->host_lock); - if (err) { - printk(KERN_ERR "Failed to load image \"%s\" err %d\n", - ql1280_board_tbl[ha->devnum].fwname, err); - return err; - } - if ((fw->size % 2) || (fw->size < 6)) { - printk(KERN_ERR "Bogus length %zu in image \"%s\"\n", - fw->size, ql1280_board_tbl[ha->devnum].fwname); - err = -EINVAL; - goto out; - } - ha->fwver1 = fw->data[0]; - ha->fwver2 = fw->data[1]; - ha->fwver3 = fw->data[2]; + fw = qla1280_request_firmware(ha); + if (IS_ERR(fw)) + return PTR_ERR(fw); + fw_data = (const __le16 *)&fw->data[0]; ha->fwstart = __le16_to_cpu(fw_data[2]); @@ -1803,7 +1851,6 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha) #if DUMP_IT_BACK pci_free_consistent(ha->pdev, 8000, tbuf, p_tbuf); #endif - release_firmware(fw); return err; } @@ -1842,6 +1889,7 @@ qla1280_start_firmware(struct scsi_qla_host *ha) static int qla1280_load_firmware(struct scsi_qla_host *ha) { + /* enter with host_lock taken */ int err; err = qla1280_chip_diag(ha); @@ -4420,7 +4468,16 @@ qla1280_init(void) static void __exit qla1280_exit(void) { + int i; + pci_unregister_driver(&qla1280_pci_driver); + /* release any allocated firmware images */ + for (i = 0; i < QL_NUM_FW_IMAGES; i++) { + if (qla1280_fw_tbl[i].fw) { + release_firmware(qla1280_fw_tbl[i].fw); + qla1280_fw_tbl[i].fw = NULL; + } + } } module_init(qla1280_init); -- cgit v0.10.2 From a2fd940f4cff74b932728bd6ca12848da21a0234 Mon Sep 17 00:00:00 2001 From: Andy Gospodarek Date: Thu, 25 Mar 2010 14:49:05 +0000 Subject: bonding: fix broken multicast with round-robin mode Round-robin (mode 0) does nothing to ensure that any multicast traffic originally destined for the host will continue to arrive at the host when the link that sent the IGMP join or membership report goes down. One of the benefits of absolute round-robin transmit. Keeping track of subscribed multicast groups for each slave did not seem like a good use of resources, so I decided to simply send on the curr_active slave of the bond (typically the first enslaved device that is up). This makes failover management simple as IGMP membership reports only need to be sent when the curr_active_slave changes. I tested this patch and it appears to work as expected. Originally reported by Lon Hohberger . Signed-off-by: Andy Gospodarek CC: Lon Hohberger CC: Jay Vosburgh Signed-off-by: Jay Vosburgh Signed-off-by: David S. Miller diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 430c022..5b92fbf 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1235,6 +1235,11 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) write_lock_bh(&bond->curr_slave_lock); } } + + /* resend IGMP joins since all were sent on curr_active_slave */ + if (bond->params.mode == BOND_MODE_ROUNDROBIN) { + bond_resend_igmp_join_requests(bond); + } } /** @@ -4138,22 +4143,41 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev struct bonding *bond = netdev_priv(bond_dev); struct slave *slave, *start_at; int i, slave_no, res = 1; + struct iphdr *iph = ip_hdr(skb); read_lock(&bond->lock); if (!BOND_IS_OK(bond)) goto out; - /* - * Concurrent TX may collide on rr_tx_counter; we accept that - * as being rare enough not to justify using an atomic op here + * Start with the curr_active_slave that joined the bond as the + * default for sending IGMP traffic. For failover purposes one + * needs to maintain some consistency for the interface that will + * send the join/membership reports. The curr_active_slave found + * will send all of this type of traffic. */ - slave_no = bond->rr_tx_counter++ % bond->slave_cnt; + if ((iph->protocol == htons(IPPROTO_IGMP)) && + (skb->protocol == htons(ETH_P_IP))) { - bond_for_each_slave(bond, slave, i) { - slave_no--; - if (slave_no < 0) - break; + read_lock(&bond->curr_slave_lock); + slave = bond->curr_active_slave; + read_unlock(&bond->curr_slave_lock); + + if (!slave) + goto out; + } else { + /* + * Concurrent TX may collide on rr_tx_counter; we accept + * that as being rare enough not to justify using an + * atomic op here. + */ + slave_no = bond->rr_tx_counter++ % bond->slave_cnt; + + bond_for_each_slave(bond, slave, i) { + slave_no--; + if (slave_no < 0) + break; + } } start_at = slave; -- cgit v0.10.2 From 1546a713ae1f066f83469cdd99ebdf500d6a65e4 Mon Sep 17 00:00:00 2001 From: Ken Kawasaki Date: Sat, 27 Mar 2010 10:55:37 +0000 Subject: pcnet_cs: add new id pcnet_cs: *add new id (Allied Telesis LM33-PCM-T Lan&Modem multifunction card) *use PROD_ID for LA-PCM.(because LA-PCM and LM33-PCM-T use the same MANF_ID). Signed-off-by: Ken Kawasaki Signed-off-by: David S. Miller diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index 776cad2..1028fcb 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c @@ -1549,6 +1549,7 @@ static struct pcmcia_device_id pcnet_ids[] = { PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x021b, 0x0101), PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x08a1, 0xc0ab), PCMCIA_PFC_DEVICE_PROD_ID12(0, "AnyCom", "Fast Ethernet + 56K COMBO", 0x578ba6e7, 0xb0ac62c4), + PCMCIA_PFC_DEVICE_PROD_ID12(0, "ATKK", "LM33-PCM-T", 0xba9eb7e2, 0x077c174e), PCMCIA_PFC_DEVICE_PROD_ID12(0, "D-Link", "DME336T", 0x1a424a1c, 0xb23897ff), PCMCIA_PFC_DEVICE_PROD_ID12(0, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae), PCMCIA_PFC_DEVICE_PROD_ID12(0, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033), @@ -1740,7 +1741,7 @@ static struct pcmcia_device_id pcnet_ids[] = { PCMCIA_MFC_DEVICE_CIS_PROD_ID12(0, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "cis/DP83903.cis"), PCMCIA_MFC_DEVICE_CIS_PROD_ID4(0, "NSC MF LAN/Modem", 0x58fc6056, "cis/DP83903.cis"), PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0175, 0x0000, "cis/DP83903.cis"), - PCMCIA_DEVICE_CIS_MANF_CARD(0xc00f, 0x0002, "cis/LA-PCM.cis"), + PCMCIA_DEVICE_CIS_PROD_ID12("Allied Telesis,K.K", "Ethernet LAN Card", 0x2ad62f3c, 0x9fd2f0a2, "cis/LA-PCM.cis"), PCMCIA_DEVICE_CIS_PROD_ID12("KTI", "PE520 PLUS", 0xad180345, 0x9d58d392, "cis/PE520.cis"), PCMCIA_DEVICE_CIS_PROD_ID12("NDC", "Ethernet", 0x01c43ae1, 0x00b2e941, "cis/NE2K.cis"), PCMCIA_DEVICE_CIS_PROD_ID12("PMX ", "PE-200", 0x34f3f1c8, 0x10b59f8c, "cis/PE-200.cis"), diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index e91db4b..175d202 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c @@ -745,6 +745,7 @@ static struct pcmcia_device_id serial_ids[] = { PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "REM10", 0x2e3ee845, 0x76df1d29), PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "XEM5600", 0x2e3ee845, 0xf1403719), PCMCIA_PFC_DEVICE_PROD_ID12(1, "AnyCom", "Fast Ethernet + 56K COMBO", 0x578ba6e7, 0xb0ac62c4), + PCMCIA_PFC_DEVICE_PROD_ID12(1, "ATKK", "LM33-PCM-T", 0xba9eb7e2, 0x077c174e), PCMCIA_PFC_DEVICE_PROD_ID12(1, "D-Link", "DME336T", 0x1a424a1c, 0xb23897ff), PCMCIA_PFC_DEVICE_PROD_ID12(1, "Gateway 2000", "XJEM3336", 0xdd9989be, 0x662c394c), PCMCIA_PFC_DEVICE_PROD_ID12(1, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae), -- cgit v0.10.2 From 78f1cd02457252e1ffbc6caa44a17424a45286b8 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Sat, 27 Mar 2010 19:35:46 -0700 Subject: r8169: fix broken register writes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is quite similar to b39fe41f481d20c201012e4483e76c203802dda7 though said registers are not even documented as 64-bit registers - as opposed to the initial TxDescStartAddress ones - but as single bytes which must be combined into 32 bits at the MMIO read/write level before being merged into a 64 bit logical entity. Credits go to Ben Hutchings for the MAR registers (aka "multicast is broken for ages on ARM) and to Timo Teräs for the MAC registers. Signed-off-by: Francois Romieu Signed-off-by: David S. Miller diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index b93fd23..7193afc 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -2820,8 +2820,8 @@ static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr) spin_lock_irq(&tp->lock); RTL_W8(Cfg9346, Cfg9346_Unlock); - RTL_W32(MAC0, low); RTL_W32(MAC4, high); + RTL_W32(MAC0, low); RTL_W8(Cfg9346, Cfg9346_Lock); spin_unlock_irq(&tp->lock); @@ -4747,8 +4747,8 @@ static void rtl_set_rx_mode(struct net_device *dev) mc_filter[1] = swab32(data); } - RTL_W32(MAR0 + 0, mc_filter[0]); RTL_W32(MAR0 + 4, mc_filter[1]); + RTL_W32(MAR0 + 0, mc_filter[0]); RTL_W32(RxConfig, tmp); -- cgit v0.10.2 From d2566af8c4860a03ca685ef0910de406679c3e4e Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 27 Mar 2010 21:11:56 -0700 Subject: arch/sparc/kernel: Use set_cpus_allowed_ptr Use set_cpus_allowed_ptr rather than set_cpus_allowed. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ expression E1,E2; @@ - set_cpus_allowed(E1, cpumask_of_cpu(E2)) + set_cpus_allowed_ptr(E1, cpumask_of(E2)) @@ expression E; identifier I; @@ - set_cpus_allowed(E, I) + set_cpus_allowed_ptr(E, &I) // Signed-off-by: Julia Lawall Signed-off-by: David S. Miller diff --git a/arch/sparc/kernel/sysfs.c b/arch/sparc/kernel/sysfs.c index ca39c60..1eb8b00 100644 --- a/arch/sparc/kernel/sysfs.c +++ b/arch/sparc/kernel/sysfs.c @@ -107,12 +107,12 @@ static unsigned long run_on_cpu(unsigned long cpu, unsigned long ret; /* should return -EINVAL to userspace */ - if (set_cpus_allowed(current, cpumask_of_cpu(cpu))) + if (set_cpus_allowed_ptr(current, cpumask_of(cpu))) return 0; ret = func(arg); - set_cpus_allowed(current, old_affinity); + set_cpus_allowed_ptr(current, &old_affinity); return ret; } diff --git a/arch/sparc/kernel/us2e_cpufreq.c b/arch/sparc/kernel/us2e_cpufreq.c index 791c151..8f982b7 100644 --- a/arch/sparc/kernel/us2e_cpufreq.c +++ b/arch/sparc/kernel/us2e_cpufreq.c @@ -238,12 +238,12 @@ static unsigned int us2e_freq_get(unsigned int cpu) return 0; cpus_allowed = current->cpus_allowed; - set_cpus_allowed(current, cpumask_of_cpu(cpu)); + set_cpus_allowed_ptr(current, cpumask_of(cpu)); clock_tick = sparc64_get_clock_tick(cpu) / 1000; estar = read_hbreg(HBIRD_ESTAR_MODE_ADDR); - set_cpus_allowed(current, cpus_allowed); + set_cpus_allowed_ptr(current, &cpus_allowed); return clock_tick / estar_to_divisor(estar); } @@ -259,7 +259,7 @@ static void us2e_set_cpu_divider_index(unsigned int cpu, unsigned int index) return; cpus_allowed = current->cpus_allowed; - set_cpus_allowed(current, cpumask_of_cpu(cpu)); + set_cpus_allowed_ptr(current, cpumask_of(cpu)); new_freq = clock_tick = sparc64_get_clock_tick(cpu) / 1000; new_bits = index_to_estar_mode(index); @@ -281,7 +281,7 @@ static void us2e_set_cpu_divider_index(unsigned int cpu, unsigned int index) cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - set_cpus_allowed(current, cpus_allowed); + set_cpus_allowed_ptr(current, &cpus_allowed); } static int us2e_freq_target(struct cpufreq_policy *policy, diff --git a/arch/sparc/kernel/us3_cpufreq.c b/arch/sparc/kernel/us3_cpufreq.c index 365b646..f35d1e7 100644 --- a/arch/sparc/kernel/us3_cpufreq.c +++ b/arch/sparc/kernel/us3_cpufreq.c @@ -86,12 +86,12 @@ static unsigned int us3_freq_get(unsigned int cpu) return 0; cpus_allowed = current->cpus_allowed; - set_cpus_allowed(current, cpumask_of_cpu(cpu)); + set_cpus_allowed_ptr(current, cpumask_of(cpu)); reg = read_safari_cfg(); ret = get_current_freq(cpu, reg); - set_cpus_allowed(current, cpus_allowed); + set_cpus_allowed_ptr(current, &cpus_allowed); return ret; } @@ -106,7 +106,7 @@ static void us3_set_cpu_divider_index(unsigned int cpu, unsigned int index) return; cpus_allowed = current->cpus_allowed; - set_cpus_allowed(current, cpumask_of_cpu(cpu)); + set_cpus_allowed_ptr(current, cpumask_of(cpu)); new_freq = sparc64_get_clock_tick(cpu) / 1000; switch (index) { @@ -140,7 +140,7 @@ static void us3_set_cpu_divider_index(unsigned int cpu, unsigned int index) cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - set_cpus_allowed(current, cpus_allowed); + set_cpus_allowed_ptr(current, &cpus_allowed); } static int us3_freq_target(struct cpufreq_policy *policy, -- cgit v0.10.2 From bc8a67386fd462914269fa93446e1891955a8bb3 Mon Sep 17 00:00:00 2001 From: "JosephChan@via.com.tw" Date: Thu, 25 Mar 2010 20:51:47 +0800 Subject: pata_via: fix VT6410/6415/6330 detection issue When using VT6410/6415/6330 chips on some VIA's platforms, the HDD connection to VT6410/6415/6330 cannot be detected. It is because the driver detects wrong via_isa_bridge ID, and then causes this issue to happen. Signed-off-by: Joseph Chan Signed-off-by: Jeff Garzik diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index 95d39c3..c59b4071 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c @@ -576,6 +576,10 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id) u8 rev = isa->revision; pci_dev_put(isa); + if ((id->device == 0x0415 || id->device == 0x3164) && + (config->id != id->device)) + continue; + if (rev >= config->rev_min && rev <= config->rev_max) break; } -- cgit v0.10.2 From 325ffc3633f1c30ef89d98d619f7e1497366e77c Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Fri, 26 Mar 2010 15:44:57 +0100 Subject: ARM: 5997/1: ARM: Correct the VFPv3 detection A CPU has VFPv3 hardware if the FPSID[19:16] bits are 2 or more. Currently Linux was only checking for 3 or more. Signed-off-by: Catalin Marinas Signed-off-by: Russell King diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index 7f3f59f..a420cb9 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c @@ -545,7 +545,7 @@ static int __init vfp_init(void) */ elf_hwcap |= HWCAP_VFP; #ifdef CONFIG_VFPv3 - if (VFP_arch >= 3) { + if (VFP_arch >= 2) { elf_hwcap |= HWCAP_VFPv3; /* -- cgit v0.10.2 From 193219172691e29813821dc8433317768c6ed1a3 Mon Sep 17 00:00:00 2001 From: Joern Engel Date: Sat, 27 Mar 2010 09:56:58 +0100 Subject: Prevent data corruption in logfs_rewrite_block() The comment was correct, so make the code match the comment. As the new comment indicates, we might be able to do a little less work. But for the current -rc series let's keep it simple and just fix the bug. Signed-off-by: Joern Engel diff --git a/fs/logfs/readwrite.c b/fs/logfs/readwrite.c index 7a23b3e..c3a3a68 100644 --- a/fs/logfs/readwrite.c +++ b/fs/logfs/readwrite.c @@ -1594,7 +1594,6 @@ int logfs_delete(struct inode *inode, pgoff_t index, return ret; } -/* Rewrite cannot mark the inode dirty but has to write it immediatly. */ int logfs_rewrite_block(struct inode *inode, u64 bix, u64 ofs, gc_level_t gc_level, long flags) { @@ -1611,6 +1610,18 @@ int logfs_rewrite_block(struct inode *inode, u64 bix, u64 ofs, if (level != 0) alloc_indirect_block(inode, page, 0); err = logfs_write_buf(inode, page, flags); + if (!err && shrink_level(gc_level) == 0) { + /* Rewrite cannot mark the inode dirty but has to + * write it immediatly. + * Q: Can't we just create an alias for the inode + * instead? And if not, why not? + */ + if (inode->i_ino == LOGFS_INO_MASTER) + logfs_write_anchor(inode->i_sb); + else { + err = __logfs_write_inode(inode, flags); + } + } } logfs_put_write_page(page); return err; -- cgit v0.10.2 From 81def6b9862764924a99ac1b680e73ac8c80ac64 Mon Sep 17 00:00:00 2001 From: Joern Engel Date: Sun, 28 Mar 2010 12:47:09 +0200 Subject: Simplify and fix pad_wbuf A comment in the old code read: /* The math in this function can surely use some love */ And indeed it did. In the case that area->a_used_bytes is exactly 4096 bytes below segment size it fell apart. pad_wbuf is now split into two helpers that are significantly less complicated. Signed-off-by: Joern Engel diff --git a/fs/logfs/segment.c b/fs/logfs/segment.c index 1a14f99..ff9d7f3 100644 --- a/fs/logfs/segment.c +++ b/fs/logfs/segment.c @@ -93,50 +93,58 @@ void __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len, } while (len); } -/* - * bdev_writeseg will write full pages. Memset the tail to prevent data leaks. - */ -static void pad_wbuf(struct logfs_area *area, int final) +static void pad_partial_page(struct logfs_area *area) { struct super_block *sb = area->a_sb; - struct logfs_super *super = logfs_super(sb); struct page *page; u64 ofs = dev_ofs(sb, area->a_segno, area->a_used_bytes); pgoff_t index = ofs >> PAGE_SHIFT; long offset = ofs & (PAGE_SIZE-1); u32 len = PAGE_SIZE - offset; - if (len == PAGE_SIZE) { - /* The math in this function can surely use some love */ - len = 0; - } - if (len) { - BUG_ON(area->a_used_bytes >= super->s_segsize); - - page = get_mapping_page(area->a_sb, index, 0); + if (len % PAGE_SIZE) { + page = get_mapping_page(sb, index, 0); BUG_ON(!page); /* FIXME: reserve a pool */ memset(page_address(page) + offset, 0xff, len); SetPagePrivate(page); page_cache_release(page); } +} - if (!final) - return; +static void pad_full_pages(struct logfs_area *area) +{ + struct super_block *sb = area->a_sb; + struct logfs_super *super = logfs_super(sb); + u64 ofs = dev_ofs(sb, area->a_segno, area->a_used_bytes); + u32 len = super->s_segsize - area->a_used_bytes; + pgoff_t index = PAGE_CACHE_ALIGN(ofs) >> PAGE_CACHE_SHIFT; + pgoff_t no_indizes = len >> PAGE_CACHE_SHIFT; + struct page *page; - area->a_used_bytes += len; - for ( ; area->a_used_bytes < super->s_segsize; - area->a_used_bytes += PAGE_SIZE) { - /* Memset another page */ - index++; - page = get_mapping_page(area->a_sb, index, 0); + while (no_indizes) { + page = get_mapping_page(sb, index, 0); BUG_ON(!page); /* FIXME: reserve a pool */ - memset(page_address(page), 0xff, PAGE_SIZE); + SetPageUptodate(page); + memset(page_address(page), 0xff, PAGE_CACHE_SIZE); SetPagePrivate(page); page_cache_release(page); + index++; + no_indizes--; } } /* + * bdev_writeseg will write full pages. Memset the tail to prevent data leaks. + * Also make sure we allocate (and memset) all pages for final writeout. + */ +static void pad_wbuf(struct logfs_area *area, int final) +{ + pad_partial_page(area); + if (final) + pad_full_pages(area); +} + +/* * We have to be careful with the alias tree. Since lookup is done by bix, * it needs to be normalized, so 14, 15, 16, etc. all match when dealing with * indirect blocks. So always use it through accessor functions. -- cgit v0.10.2 From 723b2ff40876678b49e61df34fb1d8001e34639d Mon Sep 17 00:00:00 2001 From: Joern Engel Date: Sun, 28 Mar 2010 18:10:07 +0200 Subject: [LogFS] Clear PagePrivate when moving journal do_logfs_journal_wl_pass() must call freeseg(), thereby clear PagePrivate on all pages of the current journal segment. Signed-off-by: Joern Engel diff --git a/fs/logfs/journal.c b/fs/logfs/journal.c index 6ad30a4..15454ac 100644 --- a/fs/logfs/journal.c +++ b/fs/logfs/journal.c @@ -821,6 +821,7 @@ void do_logfs_journal_wl_pass(struct super_block *sb) logfs_set_segment_reserved(sb, segno); } /* Manually move journal_area */ + freeseg(sb, area->a_segno); area->a_segno = super->s_journal_seg[0]; area->a_is_open = 0; area->a_used_bytes = 0; diff --git a/fs/logfs/logfs.h b/fs/logfs/logfs.h index 1297794..b84b0ee 100644 --- a/fs/logfs/logfs.h +++ b/fs/logfs/logfs.h @@ -587,6 +587,7 @@ void move_page_to_btree(struct page *page); int logfs_init_mapping(struct super_block *sb); void logfs_sync_area(struct logfs_area *area); void logfs_sync_segments(struct super_block *sb); +void freeseg(struct super_block *sb, u32 segno); /* area handling */ int logfs_init_areas(struct super_block *sb); diff --git a/fs/logfs/segment.c b/fs/logfs/segment.c index ff9d7f3..0ecd8f0 100644 --- a/fs/logfs/segment.c +++ b/fs/logfs/segment.c @@ -691,7 +691,7 @@ int logfs_segment_delete(struct inode *inode, struct logfs_shadow *shadow) return 0; } -static void freeseg(struct super_block *sb, u32 segno) +void freeseg(struct super_block *sb, u32 segno) { struct logfs_super *super = logfs_super(sb); struct address_space *mapping = super->s_mapping_inode->i_mapping; -- cgit v0.10.2 From 7855f761998893bb6bf861d55df95036fc9e36ab Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 28 Mar 2010 18:56:34 -0700 Subject: tulip: Add missing parens. As reported by Stephen Rothwell. drivers/net/tulip/uli526x.c: In function 'uli526x_rx_packet': drivers/net/tulip/uli526x.c:861: warning: assignment makes pointer from integer without a cast Signed-off-by: David S. Miller diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c index 90be57b..a4f09d4 100644 --- a/drivers/net/tulip/uli526x.c +++ b/drivers/net/tulip/uli526x.c @@ -858,7 +858,7 @@ static void uli526x_rx_packet(struct net_device *dev, struct uli526x_board_info /* Good packet, send to upper layer */ /* Shorst packet used new SKB */ if ((rxlen < RX_COPY_SIZE) && - ((new_skb = dev_alloc_skb(rxlen + 2) != NULL))) { + (((new_skb = dev_alloc_skb(rxlen + 2)) != NULL))) { skb = new_skb; /* size less than COPY_SIZE, allocate a rxlen SKB */ skb_reserve(skb, 2); /* 16byte align */ -- cgit v0.10.2 From 9ce41aed0d392246eb788786253f242e829fd5e1 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 28 Mar 2010 18:58:28 -0700 Subject: Revert "ide: skip probe if there are no devices on the port (v2)" This reverts commit a20b2a44eca52818ef52a94959480b7e6ea2f528. As requested by David Fries. This makes CDROMs which are slave drives on a ribbon without a master disappear and causes other similar kinds of badness. Signed-off-by: David S. Miller diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index fbedd35..4c3d1bf 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -695,14 +695,8 @@ static int ide_probe_port(ide_hwif_t *hwif) if (irqd) disable_irq(hwif->irq); - rc = ide_port_wait_ready(hwif); - if (rc == -ENODEV) { - printk(KERN_INFO "%s: no devices on the port\n", hwif->name); - goto out; - } else if (rc == -EBUSY) - printk(KERN_ERR "%s: not ready before the probe\n", hwif->name); - else - rc = -ENODEV; + if (ide_port_wait_ready(hwif) == -EBUSY) + printk(KERN_DEBUG "%s: Wait for ready failed before probe !\n", hwif->name); /* * Second drive should only exist if first drive was found, @@ -713,7 +707,7 @@ static int ide_probe_port(ide_hwif_t *hwif) if (drive->dev_flags & IDE_DFLAG_PRESENT) rc = 0; } -out: + /* * Use cached IRQ number. It might be (and is...) changed by probe * code above -- cgit v0.10.2 From 54c1a859efd9fd6cda05bc700315ba2519c14eba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?YOSHIFUJI=20Hideaki=20/=20=E5=90=89=E8=97=A4=E8=8B=B1?= =?UTF-8?q?=E6=98=8E?= Date: Sun, 28 Mar 2010 07:15:45 +0000 Subject: ipv6: Don't drop cache route entry unless timer actually expired. This is ipv6 variant of the commit 5e016cbf6.. ("ipv4: Don't drop redirected route cache entry unless PTMU actually expired") by Guenter Roeck . Remove cache route entry in ipv6_negative_advice() only if the timer is expired. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: David S. Miller diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 7fcb0e5..0d7713c 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -890,12 +890,17 @@ static struct dst_entry *ip6_negative_advice(struct dst_entry *dst) struct rt6_info *rt = (struct rt6_info *) dst; if (rt) { - if (rt->rt6i_flags & RTF_CACHE) - ip6_del_rt(rt); - else + if (rt->rt6i_flags & RTF_CACHE) { + if (rt6_check_expired(rt)) { + ip6_del_rt(rt); + dst = NULL; + } + } else { dst_release(dst); + dst = NULL; + } } - return NULL; + return dst; } static void ip6_link_failure(struct sk_buff *skb) -- cgit v0.10.2 From 5f6c477a35852c6bfa42474537c582f65bdcf9db Mon Sep 17 00:00:00 2001 From: Yusuke Goda Date: Mon, 29 Mar 2010 02:36:54 +0000 Subject: sh: Update ecovec_defconfig Signed-off-by: Yusuke Goda Signed-off-by: Paul Mundt diff --git a/arch/sh/configs/ecovec24_defconfig b/arch/sh/configs/ecovec24_defconfig index 18e3356..6041c66 100644 --- a/arch/sh/configs/ecovec24_defconfig +++ b/arch/sh/configs/ecovec24_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc2 -# Mon Jan 4 11:20:36 2010 +# Linux kernel version: 2.6.34-rc2 +# Mon Mar 29 02:21:58 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y CONFIG_GENERIC_GPIO=y CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -32,6 +32,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_ARCH_HAS_DEFAULT_IDLE=y CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DMA_NONCOHERENT=y +CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -47,9 +48,11 @@ CONFIG_LOCALVERSION="" CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y @@ -71,14 +74,8 @@ CONFIG_RCU_FANOUT=32 # CONFIG_TREE_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set # CONFIG_BLK_DEV_INITRD is not set @@ -107,7 +104,7 @@ CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters # -# CONFIG_PERF_EVENTS is not set +CONFIG_PERF_EVENTS=y # CONFIG_PERF_COUNTERS is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_COMPAT_BRK=y @@ -116,13 +113,13 @@ CONFIG_SLAB=y # CONFIG_SLOB is not set # CONFIG_PROFILING is not set CONFIG_HAVE_OPROFILE=y -CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y # # GCOV-based kernel profiling @@ -234,12 +231,12 @@ CONFIG_CPU_SUBTYPE_SH7724=y CONFIG_QUICKLIST=y CONFIG_MMU=y CONFIG_PAGE_OFFSET=0x80000000 -CONFIG_FORCE_MAX_ZONEORDER=11 +CONFIG_FORCE_MAX_ZONEORDER=12 CONFIG_MEMORY_START=0x08000000 CONFIG_MEMORY_SIZE=0x10000000 CONFIG_29BIT=y -# CONFIG_PMB_ENABLE is not set -# CONFIG_X2TLB is not set +# CONFIG_PMB is not set +CONFIG_X2TLB=y CONFIG_VSYSCALL=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_ENABLE=y @@ -247,6 +244,8 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_MAX_ACTIVE_REGIONS=1 CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_IOREMAP_FIXED=y +CONFIG_UNCACHED_MAPPING=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -262,7 +261,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 +CONFIG_NR_QUICK=1 # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -337,7 +336,6 @@ CONFIG_SECCOMP=y # CONFIG_PREEMPT_VOLUNTARY is not set CONFIG_PREEMPT=y CONFIG_GUSA=y -# CONFIG_SPARSE_IRQ is not set # # Boot options @@ -347,7 +345,7 @@ CONFIG_BOOT_LINK_OFFSET=0x00800000 CONFIG_ENTRY_OFFSET=0x00001000 CONFIG_CMDLINE_OVERWRITE=y # CONFIG_CMDLINE_EXTEND is not set -CONFIG_CMDLINE="console=tty0, console=ttySC0,115200 root=/dev/nfs ip=dhcp mem=120M memchunk.vpu=4m" +CONFIG_CMDLINE="console=tty0, console=ttySC0,115200 root=/dev/nfs ip=dhcp mem=248M memchunk.vpu=8m memchunk.veu0=4m" # # Bus options @@ -373,6 +371,7 @@ CONFIG_SUSPEND=y CONFIG_SUSPEND_FREEZER=y # CONFIG_HIBERNATION is not set CONFIG_PM_RUNTIME=y +CONFIG_PM_OPS=y # CONFIG_CPU_IDLE is not set CONFIG_NET=y @@ -380,7 +379,6 @@ CONFIG_NET=y # Networking options # CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y @@ -445,7 +443,45 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set # CONFIG_CAN is not set -# CONFIG_IRDA is not set +CONFIG_IRDA=y + +# +# IrDA protocols +# +# CONFIG_IRLAN is not set +# CONFIG_IRCOMM is not set +# CONFIG_IRDA_ULTRA is not set + +# +# IrDA options +# +# CONFIG_IRDA_CACHE_LAST_LSAP is not set +# CONFIG_IRDA_FAST_RR is not set +# CONFIG_IRDA_DEBUG is not set + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +# CONFIG_IRTTY_SIR is not set + +# +# Dongle support +# +CONFIG_SH_SIR=y +# CONFIG_KINGSUN_DONGLE is not set +# CONFIG_KSDAZZLE_DONGLE is not set +# CONFIG_KS959_DONGLE is not set + +# +# FIR device drivers +# +# CONFIG_USB_IRDA is not set +# CONFIG_SIGMATEL_FIR is not set +# CONFIG_MCS_FIR is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set CONFIG_WIRELESS=y @@ -556,6 +592,7 @@ CONFIG_MTD_NAND_IDS=y # CONFIG_MTD_NAND_NANDSIM is not set # CONFIG_MTD_NAND_PLATFORM is not set # CONFIG_MTD_ALAUDA is not set +# CONFIG_MTD_NAND_SH_FLCTL is not set # CONFIG_MTD_ONENAND is not set # @@ -597,6 +634,7 @@ CONFIG_MISC_DEVICES=y # CONFIG_ICS932S401 is not set # CONFIG_ENCLOSURE_SERVICES is not set # CONFIG_ISL29003 is not set +# CONFIG_SENSORS_TSL2550 is not set # CONFIG_DS1682 is not set # CONFIG_TI_DAC7512 is not set # CONFIG_C2PORT is not set @@ -616,6 +654,7 @@ CONFIG_HAVE_IDE=y # # SCSI device support # +CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_DMA=y @@ -768,7 +807,29 @@ CONFIG_KEYBOARD_SH_KEYSC=y # CONFIG_INPUT_MOUSE is not set # CONFIG_INPUT_JOYSTICK is not set # CONFIG_INPUT_TABLET is not set -# CONFIG_INPUT_TOUCHSCREEN is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_AD7877 is not set +# CONFIG_TOUCHSCREEN_AD7879_I2C is not set +# CONFIG_TOUCHSCREEN_AD7879_SPI is not set +# CONFIG_TOUCHSCREEN_AD7879 is not set +# CONFIG_TOUCHSCREEN_DYNAPRO is not set +# CONFIG_TOUCHSCREEN_EETI is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +# CONFIG_TOUCHSCREEN_MCS5000 is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_INEXIO is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set +# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +CONFIG_TOUCHSCREEN_TSC2007=y +# CONFIG_TOUCHSCREEN_W90X900 is not set # CONFIG_INPUT_MISC is not set # @@ -802,10 +863,10 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=6 CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_LEGACY_PTYS is not set # CONFIG_IPMI_HANDLER is not set CONFIG_HW_RANDOM=y # CONFIG_HW_RANDOM_TIMERIOMEM is not set @@ -830,6 +891,7 @@ CONFIG_I2C_HELPER_AUTO=y # CONFIG_I2C_OCORES is not set CONFIG_I2C_SH_MOBILE=y # CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set # # External I2C/SMBus adapter drivers @@ -843,15 +905,9 @@ CONFIG_I2C_SH_MOBILE=y # # CONFIG_I2C_PCA_PLATFORM is not set # CONFIG_I2C_STUB is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_SENSORS_TSL2550 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set CONFIG_SPI=y CONFIG_SPI_MASTER=y @@ -882,13 +938,16 @@ CONFIG_GPIOLIB=y # # Memory mapped GPIO expanders: # +# CONFIG_GPIO_IT8761E is not set # # I2C GPIO expanders: # +# CONFIG_GPIO_MAX7300 is not set # CONFIG_GPIO_MAX732X is not set # CONFIG_GPIO_PCA953X is not set # CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_ADP5588 is not set # # PCI GPIO expanders: @@ -919,23 +978,26 @@ CONFIG_SSB_POSSIBLE=y # # Multifunction device drivers # -# CONFIG_MFD_CORE is not set +CONFIG_MFD_CORE=y +# CONFIG_MFD_88PM860X is not set # CONFIG_MFD_SM501 is not set -# CONFIG_MFD_SH_MOBILE_SDHI is not set +CONFIG_MFD_SH_MOBILE_SDHI=y # CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set # CONFIG_TPS65010 is not set # CONFIG_TWL4030_CORE is not set # CONFIG_MFD_TMIO is not set # CONFIG_PMIC_DA903X is not set # CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X is not set # CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_MFD_MC13783 is not set # CONFIG_AB3100_CORE is not set # CONFIG_EZX_PCAP is not set -# CONFIG_MFD_88PM8607 is not set # CONFIG_AB4500_CORE is not set # CONFIG_REGULATOR is not set CONFIG_MEDIA_SUPPORT=y @@ -985,10 +1047,10 @@ CONFIG_SOC_CAMERA=y # CONFIG_SOC_CAMERA_MT9M001 is not set # CONFIG_SOC_CAMERA_MT9M111 is not set # CONFIG_SOC_CAMERA_MT9T031 is not set -# CONFIG_SOC_CAMERA_MT9T112 is not set +CONFIG_SOC_CAMERA_MT9T112=y # CONFIG_SOC_CAMERA_MT9V022 is not set # CONFIG_SOC_CAMERA_RJ54N1 is not set -# CONFIG_SOC_CAMERA_TW9910 is not set +CONFIG_SOC_CAMERA_TW9910=y # CONFIG_SOC_CAMERA_PLATFORM is not set # CONFIG_SOC_CAMERA_OV772X is not set # CONFIG_SOC_CAMERA_OV9640 is not set @@ -1001,6 +1063,7 @@ CONFIG_RADIO_ADAPTERS=y # CONFIG_RADIO_SI470X is not set # CONFIG_USB_MR800 is not set # CONFIG_RADIO_TEA5764 is not set +# CONFIG_RADIO_SAA7706H is not set # CONFIG_RADIO_TEF6862 is not set # CONFIG_DAB is not set @@ -1034,6 +1097,7 @@ CONFIG_FB_DEFERRED_IO=y # # CONFIG_FB_S1D13XXX is not set CONFIG_FB_SH_MOBILE_LCDC=y +# CONFIG_FB_TMIO is not set # CONFIG_FB_VIRTUAL is not set # CONFIG_FB_METRONOME is not set # CONFIG_FB_MB862XX is not set @@ -1062,7 +1126,46 @@ CONFIG_LOGO=y # CONFIG_LOGO_SUPERH_MONO is not set # CONFIG_LOGO_SUPERH_VGA16 is not set CONFIG_LOGO_SUPERH_CLUT224=y -# CONFIG_SOUND is not set +CONFIG_SOUND=y +CONFIG_SOUND_OSS_CORE=y +CONFIG_SOUND_OSS_CORE_PRECLAIM=y +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_JACK=y +CONFIG_SND_SEQUENCER=y +CONFIG_SND_SEQ_DUMMY=y +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=y +CONFIG_SND_PCM_OSS=y +CONFIG_SND_PCM_OSS_PLUGINS=y +# CONFIG_SND_SEQUENCER_OSS is not set +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +# CONFIG_SND_RAWMIDI_SEQ is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +# CONFIG_SND_DRIVERS is not set +# CONFIG_SND_SPI is not set +CONFIG_SND_SUPERH=y +# CONFIG_SND_USB is not set +CONFIG_SND_SOC=y + +# +# SoC Audio support for SuperH +# +CONFIG_SND_SOC_SH4_FSI=y +# CONFIG_SND_FSI_AK4642 is not set +CONFIG_SND_FSI_DA7210=y +CONFIG_SND_SOC_I2C_AND_SPI=y +# CONFIG_SND_SOC_ALL_CODECS is not set +CONFIG_SND_SOC_DA7210=y +# CONFIG_SOUND_PRIME is not set CONFIG_HID_SUPPORT=y CONFIG_HID=y # CONFIG_HIDRAW is not set @@ -1077,6 +1180,7 @@ CONFIG_USB_HID=y # # Special HID drivers # +# CONFIG_HID_3M_PCT is not set # CONFIG_HID_A4TECH is not set # CONFIG_HID_APPLE is not set # CONFIG_HID_BELKIN is not set @@ -1091,12 +1195,16 @@ CONFIG_USB_HID=y # CONFIG_HID_KENSINGTON is not set # CONFIG_HID_LOGITECH is not set # CONFIG_HID_MICROSOFT is not set +# CONFIG_HID_MOSART is not set # CONFIG_HID_MONTEREY is not set # CONFIG_HID_NTRIG is not set +# CONFIG_HID_ORTEK is not set # CONFIG_HID_PANTHERLORD is not set # CONFIG_HID_PETALYNX is not set +# CONFIG_HID_QUANTA is not set # CONFIG_HID_SAMSUNG is not set # CONFIG_HID_SONY is not set +# CONFIG_HID_STANTUM is not set # CONFIG_HID_SUNPLUS is not set # CONFIG_HID_GREENASIA is not set # CONFIG_HID_SMARTJOYPLUS is not set @@ -1136,6 +1244,7 @@ CONFIG_USB_MON=y # CONFIG_USB_SL811_HCD is not set CONFIG_USB_R8A66597_HCD=y # CONFIG_USB_HWA_HCD is not set +# CONFIG_USB_GADGET_MUSB_HDRC is not set # # USB Device Class drivers @@ -1188,7 +1297,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set @@ -1200,8 +1308,45 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_IOWARRIOR is not set # CONFIG_USB_TEST is not set # CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_VST is not set -# CONFIG_USB_GADGET is not set +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_VBUS_DRAW=2 +CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA25X is not set +CONFIG_USB_GADGET_R8A66597=y +CONFIG_USB_R8A66597=y +# CONFIG_USB_GADGET_PXA27X is not set +# CONFIG_USB_GADGET_S3C_HSOTG is not set +# CONFIG_USB_GADGET_IMX is not set +# CONFIG_USB_GADGET_S3C2410 is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_FSL_QE is not set +# CONFIG_USB_GADGET_CI13XXX is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LANGWELL is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_ZERO is not set +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_GADGETFS is not set +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +# CONFIG_USB_MASS_STORAGE is not set +# CONFIG_USB_G_SERIAL is not set +# CONFIG_USB_MIDI_GADGET is not set +# CONFIG_USB_G_PRINTER is not set +# CONFIG_USB_CDC_COMPOSITE is not set +# CONFIG_USB_G_NOKIA is not set +# CONFIG_USB_G_MULTI is not set # # OTG and related infrastructure @@ -1224,10 +1369,8 @@ CONFIG_MMC_BLOCK_BOUNCE=y # MMC/SD/SDIO Host Controller Drivers # # CONFIG_MMC_SDHCI is not set -# CONFIG_MMC_AT91 is not set -# CONFIG_MMC_ATMELMCI is not set CONFIG_MMC_SPI=y -# CONFIG_MMC_TMIO is not set +CONFIG_MMC_TMIO=y # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set # CONFIG_ACCESSIBILITY is not set @@ -1253,10 +1396,10 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_DS1374 is not set # CONFIG_RTC_DRV_DS1672 is not set # CONFIG_RTC_DRV_MAX6900 is not set -# CONFIG_RTC_DRV_RS5C372 is not set +CONFIG_RTC_DRV_RS5C372=y # CONFIG_RTC_DRV_ISL1208 is not set # CONFIG_RTC_DRV_X1205 is not set -CONFIG_RTC_DRV_PCF8563=y +# CONFIG_RTC_DRV_PCF8563 is not set # CONFIG_RTC_DRV_PCF8583 is not set # CONFIG_RTC_DRV_M41T80 is not set # CONFIG_RTC_DRV_BQ32K is not set @@ -1303,8 +1446,6 @@ CONFIG_RTC_DRV_PCF8563=y CONFIG_UIO=y # CONFIG_UIO_PDRV is not set CONFIG_UIO_PDRV_GENIRQ=y -# CONFIG_UIO_SMX is not set -# CONFIG_UIO_SERCOS3 is not set # # TI VLYNQ @@ -1390,6 +1531,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_EFS_FS is not set # CONFIG_JFFS2_FS is not set # CONFIG_UBIFS_FS is not set +# CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set @@ -1418,6 +1560,7 @@ CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set +# CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1487,6 +1630,7 @@ CONFIG_DEBUG_FS=y CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_LKDTM is not set # CONFIG_LATENCYTOP is not set CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_HAVE_FUNCTION_TRACER=y @@ -1618,7 +1762,7 @@ CONFIG_CRYPTO_HW=y # CONFIG_BITREVERSE=y CONFIG_GENERIC_FIND_LAST_BIT=y -# CONFIG_CRC_CCITT is not set +CONFIG_CRC_CCITT=y # CONFIG_CRC16 is not set CONFIG_CRC_T10DIF=y CONFIG_CRC_ITU_T=y -- cgit v0.10.2 From 59a2f7d9fd41c68b7013797e82b8f40fc154ccae Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Fri, 26 Mar 2010 22:03:49 +0000 Subject: arch/sh/kernel: Use set_cpus_allowed_ptr Use set_cpus_allowed_ptr rather than set_cpus_allowed. The semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ expression E1,E2; @@ - set_cpus_allowed(E1, cpumask_of_cpu(E2)) + set_cpus_allowed_ptr(E1, cpumask_of(E2)) @@ expression E; identifier I; @@ - set_cpus_allowed(E, I) + set_cpus_allowed_ptr(E, &I) // Signed-off-by: Julia Lawall Signed-off-by: Paul Mundt diff --git a/arch/sh/kernel/cpufreq.c b/arch/sh/kernel/cpufreq.c index dce4f3f..0ffface 100644 --- a/arch/sh/kernel/cpufreq.c +++ b/arch/sh/kernel/cpufreq.c @@ -48,7 +48,7 @@ static int sh_cpufreq_target(struct cpufreq_policy *policy, return -ENODEV; cpus_allowed = current->cpus_allowed; - set_cpus_allowed(current, cpumask_of_cpu(cpu)); + set_cpus_allowed_ptr(current, cpumask_of(cpu)); BUG_ON(smp_processor_id() != cpu); @@ -66,7 +66,7 @@ static int sh_cpufreq_target(struct cpufreq_policy *policy, freqs.flags = 0; cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - set_cpus_allowed(current, cpus_allowed); + set_cpus_allowed_ptr(current, &cpus_allowed); clk_set_rate(cpuclk, freq); cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); -- cgit v0.10.2 From d5ab780305bb6d60a7b5a74f18cf84eb6ad153b1 Mon Sep 17 00:00:00 2001 From: Andrew Stubbs Date: Mon, 29 Mar 2010 12:04:19 +0900 Subject: sh: Fix FDPIC binary loader Ensure that the aux table is properly initialized, even when optional features are missing. Without this, the FDPIC loader did not work. Signed-off-by: Andrew Stubbs Cc: stable@kernel.org Signed-off-by: Paul Mundt diff --git a/arch/sh/include/asm/elf.h b/arch/sh/include/asm/elf.h index ac04255..ce830fa 100644 --- a/arch/sh/include/asm/elf.h +++ b/arch/sh/include/asm/elf.h @@ -211,7 +211,9 @@ extern void __kernel_vsyscall; #define VSYSCALL_AUX_ENT \ if (vdso_enabled) \ - NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_BASE); + NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_BASE); \ + else \ + NEW_AUX_ENT(AT_IGNORE, 0); #else #define VSYSCALL_AUX_ENT #endif /* CONFIG_VSYSCALL */ @@ -219,7 +221,7 @@ extern void __kernel_vsyscall; #ifdef CONFIG_SH_FPU #define FPU_AUX_ENT NEW_AUX_ENT(AT_FPUCW, FPSCR_INIT) #else -#define FPU_AUX_ENT +#define FPU_AUX_ENT NEW_AUX_ENT(AT_IGNORE, 0) #endif extern int l1i_cache_shape, l1d_cache_shape, l2_cache_shape; -- cgit v0.10.2 From 4bea3418c737891894b9d3d3e9f8bbd67d66fa38 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Sun, 28 Mar 2010 20:08:25 +0000 Subject: sh: Enable the mmu in start_secondary() For the boot, enable_mmu() is called from setup_arch() but we don't call setup_arch() for any of the other cpus. So turn on the non-boot cpu's mmu inside of start_secondary(). I noticed this bug on an SMP board when trying to map I/O memory (smsc911x registers) into the kernel address space. Since the Address Translation bit in MMUCR wasn't set, accessing the virtual address where the smsc911x registers were supposedly mapped actually performed a physical address access. Signed-off-by: Matt Fleming Cc: stable@kernel.org Signed-off-by: Paul Mundt diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c index e124cf7..002cc61 100644 --- a/arch/sh/kernel/smp.c +++ b/arch/sh/kernel/smp.c @@ -69,6 +69,7 @@ asmlinkage void __cpuinit start_secondary(void) unsigned int cpu; struct mm_struct *mm = &init_mm; + enable_mmu(); atomic_inc(&mm->mm_count); atomic_inc(&mm->mm_users); current->active_mm = mm; -- cgit v0.10.2 From 94aa8ae13db2ecf2ec1b4e65a65d3fe92b468e0e Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Sun, 28 Mar 2010 21:22:50 -0700 Subject: ceph: fix use after free on mds __unregister_request There was a use after free in __unregister_request that would trigger whenever the request map held the last reference. This appears to have triggered an oops during 'umount -f' when requests are being torn down. Signed-off-by: Sage Weil diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 5268d40..5c7920b 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -532,7 +532,6 @@ static void __unregister_request(struct ceph_mds_client *mdsc, dout("__unregister_request %p tid %lld\n", req, req->r_tid); rb_erase(&req->r_node, &mdsc->request_tree); RB_CLEAR_NODE(&req->r_node); - ceph_mdsc_put_request(req); if (req->r_unsafe_dir) { struct ceph_inode_info *ci = ceph_inode(req->r_unsafe_dir); @@ -541,6 +540,8 @@ static void __unregister_request(struct ceph_mds_client *mdsc, list_del_init(&req->r_unsafe_dir_item); spin_unlock(&ci->i_unsafe_lock); } + + ceph_mdsc_put_request(req); } /* -- cgit v0.10.2 From 5cd165e7057020884e430941c24454d3df9a799d Mon Sep 17 00:00:00 2001 From: Daniel Chen Date: Sun, 28 Mar 2010 13:32:34 -0700 Subject: ALSA: ac97: Add Toshiba P500 to ac97 jack sense blacklist BugLink: https://launchpad.net/bugs/481058 The OR has verified that both 'Headphone Jack Sense' and 'Line Jack Sense' need to be muted for sound to be audible, so just add the machine's SSID to the ac97 jack sense blacklist. Reported-by: Richard Gagne Tested-by: Richard Gagne Cc: Signed-off-by: Daniel T Chen Signed-off-by: Takashi Iwai diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index 1a59b71..e68c98e 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c @@ -1859,6 +1859,7 @@ static unsigned int ad1981_jacks_blacklist[] = { 0x10280160, /* Dell Dimension 2400 */ 0x104380b0, /* Asus A7V8X-MX */ 0x11790241, /* Toshiba Satellite A-15 S127 */ + 0x1179ff10, /* Toshiba P500 */ 0x144dc01a, /* Samsung NP-X20C004/SEG */ 0 /* end */ }; -- cgit v0.10.2 From 9ec8ddad59fadd8021adfea4cb716a49b0e232e9 Mon Sep 17 00:00:00 2001 From: Daniel T Chen Date: Sun, 28 Mar 2010 02:34:40 -0400 Subject: ALSA: hda: Use LPIB for ga-ma770-ud3 board BugLink: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=575669 The OR states that position_fix=1 is necessary to work around glitching during volume adjustments using PulseAudio. Reported-by: Carlos Laviola Tested-by: Carlos Laviola Cc: Signed-off-by: Daniel T Chen Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 8b29156..4bb9067 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2269,6 +2269,7 @@ static struct snd_pci_quirk position_fix_list[] __devinitdata = { SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB), SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB), SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), + SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB), SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB), SND_PCI_QUIRK(0x1565, 0x820f, "Biostar Microtech", POS_FIX_LPIB), SND_PCI_QUIRK(0x8086, 0xd601, "eMachines T5212", POS_FIX_LPIB), -- cgit v0.10.2 From 5dbd5ec6e1cf2e49128025d80813a275744a7ac5 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 29 Mar 2010 09:16:24 +0200 Subject: ALSA: hda - Fix invalid bit values passed to snd_hda_codec_amp_stereo() The mask and value parameters passed to snd_hda_codec_amp_stereo() should be 8-bit values for mute and volume. Passing AMP_IN_MUTE() is wrong, which is found in many places in patch_realtek.c as a left-over from the conversion to snd_hda_codec_amp_stereo(). Reported-by: Dan Carpenter Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 9a23444..bc55c1e 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -12459,11 +12459,11 @@ static void alc268_aspire_one_speaker_automute(struct hda_codec *codec) unsigned char bits; present = snd_hda_jack_detect(codec, 0x15); - bits = present ? AMP_IN_MUTE(0) : 0; + bits = present ? HDA_AMP_MUTE : 0; snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0, - AMP_IN_MUTE(0), bits); + HDA_AMP_MUTE, bits); snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1, - AMP_IN_MUTE(0), bits); + HDA_AMP_MUTE, bits); } static void alc268_acer_lc_unsol_event(struct hda_codec *codec, @@ -13482,11 +13482,11 @@ static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec) unsigned char bits; present = snd_hda_jack_detect(codec, 0x15); - bits = present ? AMP_IN_MUTE(0) : 0; + bits = present ? HDA_AMP_MUTE : 0; snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, - AMP_IN_MUTE(0), bits); + HDA_AMP_MUTE, bits); snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, - AMP_IN_MUTE(0), bits); + HDA_AMP_MUTE, bits); snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0x0c); @@ -13511,11 +13511,11 @@ static void alc269_lifebook_speaker_automute(struct hda_codec *codec) /* Check port replicator headphone socket */ present |= snd_hda_jack_detect(codec, 0x1a); - bits = present ? AMP_IN_MUTE(0) : 0; + bits = present ? HDA_AMP_MUTE : 0; snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, - AMP_IN_MUTE(0), bits); + HDA_AMP_MUTE, bits); snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, - AMP_IN_MUTE(0), bits); + HDA_AMP_MUTE, bits); snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0x0c); @@ -13646,11 +13646,11 @@ static void alc269_speaker_automute(struct hda_codec *codec) unsigned char bits; present = snd_hda_jack_detect(codec, nid); - bits = present ? AMP_IN_MUTE(0) : 0; + bits = present ? HDA_AMP_MUTE : 0; snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, - AMP_IN_MUTE(0), bits); + HDA_AMP_MUTE, bits); snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, - AMP_IN_MUTE(0), bits); + HDA_AMP_MUTE, bits); } /* unsolicited event for HP jack sensing */ @@ -17115,9 +17115,9 @@ static void alc663_m51va_speaker_automute(struct hda_codec *codec) present = snd_hda_jack_detect(codec, 0x21); bits = present ? HDA_AMP_MUTE : 0; snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, - AMP_IN_MUTE(0), bits); + HDA_AMP_MUTE, bits); snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, - AMP_IN_MUTE(0), bits); + HDA_AMP_MUTE, bits); } static void alc663_21jd_two_speaker_automute(struct hda_codec *codec) @@ -17128,13 +17128,13 @@ static void alc663_21jd_two_speaker_automute(struct hda_codec *codec) present = snd_hda_jack_detect(codec, 0x21); bits = present ? HDA_AMP_MUTE : 0; snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, - AMP_IN_MUTE(0), bits); + HDA_AMP_MUTE, bits); snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, - AMP_IN_MUTE(0), bits); + HDA_AMP_MUTE, bits); snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, - AMP_IN_MUTE(0), bits); + HDA_AMP_MUTE, bits); snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, - AMP_IN_MUTE(0), bits); + HDA_AMP_MUTE, bits); } static void alc663_15jd_two_speaker_automute(struct hda_codec *codec) @@ -17145,13 +17145,13 @@ static void alc663_15jd_two_speaker_automute(struct hda_codec *codec) present = snd_hda_jack_detect(codec, 0x15); bits = present ? HDA_AMP_MUTE : 0; snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, - AMP_IN_MUTE(0), bits); + HDA_AMP_MUTE, bits); snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, - AMP_IN_MUTE(0), bits); + HDA_AMP_MUTE, bits); snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, - AMP_IN_MUTE(0), bits); + HDA_AMP_MUTE, bits); snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, - AMP_IN_MUTE(0), bits); + HDA_AMP_MUTE, bits); } static void alc662_f5z_speaker_automute(struct hda_codec *codec) @@ -17190,14 +17190,14 @@ static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec) if (present1 || present2) { snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, - AMP_IN_MUTE(0), AMP_IN_MUTE(0)); + HDA_AMP_MUTE, HDA_AMP_MUTE); snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, - AMP_IN_MUTE(0), AMP_IN_MUTE(0)); + HDA_AMP_MUTE, HDA_AMP_MUTE); } else { snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, - AMP_IN_MUTE(0), 0); + HDA_AMP_MUTE, 0); snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, - AMP_IN_MUTE(0), 0); + HDA_AMP_MUTE, 0); } } -- cgit v0.10.2 From 259354deaaf03d49a02dbb9975d6ec2a54675672 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 10 Mar 2010 18:56:10 +0900 Subject: module: encapsulate percpu handling better and record percpu_size Better encapsulate module static percpu area handling so that code outsidef of CONFIG_SMP ifdef doesn't deal with mod->percpu directly and add mod->percpu_size and record percpu_size in it. Both percpu fields are compiled out on UP. While at it, mark mod->percpu w/ __percpu. This is to prepare for is_module_percpu_address(). Signed-off-by: Tejun Heo Acked-by: Rusty Russell diff --git a/include/linux/module.h b/include/linux/module.h index 5e869ff..87d247a 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -330,8 +330,11 @@ struct module struct module_notes_attrs *notes_attrs; #endif +#ifdef CONFIG_SMP /* Per-cpu data. */ - void *percpu; + void __percpu *percpu; + unsigned int percpu_size; +#endif /* The command line arguments (may be mangled). People like keeping pointers to this stuff */ diff --git a/kernel/module.c b/kernel/module.c index c968d36..e7a6e53 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -370,27 +370,33 @@ EXPORT_SYMBOL_GPL(find_module); #ifdef CONFIG_SMP -static void *percpu_modalloc(unsigned long size, unsigned long align, - const char *name) +static inline void __percpu *mod_percpu(struct module *mod) { - void *ptr; + return mod->percpu; +} +static int percpu_modalloc(struct module *mod, + unsigned long size, unsigned long align) +{ if (align > PAGE_SIZE) { printk(KERN_WARNING "%s: per-cpu alignment %li > %li\n", - name, align, PAGE_SIZE); + mod->name, align, PAGE_SIZE); align = PAGE_SIZE; } - ptr = __alloc_reserved_percpu(size, align); - if (!ptr) + mod->percpu = __alloc_reserved_percpu(size, align); + if (!mod->percpu) { printk(KERN_WARNING "Could not allocate %lu bytes percpu data\n", size); - return ptr; + return -ENOMEM; + } + mod->percpu_size = size; + return 0; } -static void percpu_modfree(void *freeme) +static void percpu_modfree(struct module *mod) { - free_percpu(freeme); + free_percpu(mod->percpu); } static unsigned int find_pcpusec(Elf_Ehdr *hdr, @@ -400,24 +406,28 @@ static unsigned int find_pcpusec(Elf_Ehdr *hdr, return find_sec(hdr, sechdrs, secstrings, ".data.percpu"); } -static void percpu_modcopy(void *pcpudest, const void *from, unsigned long size) +static void percpu_modcopy(struct module *mod, + const void *from, unsigned long size) { int cpu; for_each_possible_cpu(cpu) - memcpy(pcpudest + per_cpu_offset(cpu), from, size); + memcpy(per_cpu_ptr(mod->percpu, cpu), from, size); } #else /* ... !CONFIG_SMP */ -static inline void *percpu_modalloc(unsigned long size, unsigned long align, - const char *name) +static inline void __percpu *mod_percpu(struct module *mod) { return NULL; } -static inline void percpu_modfree(void *pcpuptr) +static inline int percpu_modalloc(struct module *mod, + unsigned long size, unsigned long align) +{ + return -ENOMEM; +} +static inline void percpu_modfree(struct module *mod) { - BUG(); } static inline unsigned int find_pcpusec(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, @@ -425,8 +435,8 @@ static inline unsigned int find_pcpusec(Elf_Ehdr *hdr, { return 0; } -static inline void percpu_modcopy(void *pcpudst, const void *src, - unsigned long size) +static inline void percpu_modcopy(struct module *mod, + const void *from, unsigned long size) { /* pcpusec should be 0, and size of that section should be 0. */ BUG_ON(size != 0); @@ -1400,8 +1410,7 @@ static void free_module(struct module *mod) /* This may be NULL, but that's OK */ module_free(mod, mod->module_init); kfree(mod->args); - if (mod->percpu) - percpu_modfree(mod->percpu); + percpu_modfree(mod); #if defined(CONFIG_MODULE_UNLOAD) if (mod->refptr) free_percpu(mod->refptr); @@ -1520,7 +1529,7 @@ static int simplify_symbols(Elf_Shdr *sechdrs, default: /* Divert to percpu allocation if a percpu var. */ if (sym[i].st_shndx == pcpuindex) - secbase = (unsigned long)mod->percpu; + secbase = (unsigned long)mod_percpu(mod); else secbase = sechdrs[sym[i].st_shndx].sh_addr; sym[i].st_value += secbase; @@ -1954,7 +1963,7 @@ static noinline struct module *load_module(void __user *umod, unsigned int modindex, versindex, infoindex, pcpuindex; struct module *mod; long err = 0; - void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */ + void *ptr = NULL; /* Stops spurious gcc warning */ unsigned long symoffs, stroffs, *strmap; mm_segment_t old_fs; @@ -2094,15 +2103,11 @@ static noinline struct module *load_module(void __user *umod, if (pcpuindex) { /* We have a special allocation for this section. */ - percpu = percpu_modalloc(sechdrs[pcpuindex].sh_size, - sechdrs[pcpuindex].sh_addralign, - mod->name); - if (!percpu) { - err = -ENOMEM; + err = percpu_modalloc(mod, sechdrs[pcpuindex].sh_size, + sechdrs[pcpuindex].sh_addralign); + if (err) goto free_mod; - } sechdrs[pcpuindex].sh_flags &= ~(unsigned long)SHF_ALLOC; - mod->percpu = percpu; } /* Determine total sizes, and put offsets in sh_entsize. For now @@ -2317,7 +2322,7 @@ static noinline struct module *load_module(void __user *umod, sort_extable(mod->extable, mod->extable + mod->num_exentries); /* Finally, copy percpu area over. */ - percpu_modcopy(mod->percpu, (void *)sechdrs[pcpuindex].sh_addr, + percpu_modcopy(mod, (void *)sechdrs[pcpuindex].sh_addr, sechdrs[pcpuindex].sh_size); add_kallsyms(mod, sechdrs, hdr->e_shnum, symindex, strindex, @@ -2409,8 +2414,7 @@ static noinline struct module *load_module(void __user *umod, module_free(mod, mod->module_core); /* mod will be freed with core. Don't access it beyond this line! */ free_percpu: - if (percpu) - percpu_modfree(percpu); + percpu_modfree(mod); free_mod: kfree(args); kfree(strmap); -- cgit v0.10.2 From 10fad5e46f6c7bdfb01b1a012380a38e3c6ab346 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 10 Mar 2010 18:57:54 +0900 Subject: percpu, module: implement and use is_kernel/module_percpu_address() lockdep has custom code to check whether a pointer belongs to static percpu area which is somewhat broken. Implement proper is_kernel/module_percpu_address() and replace the custom code. On UP, percpu variables are regular static variables and can't be distinguished from them. Always return %false on UP. Signed-off-by: Tejun Heo Acked-by: Peter Zijlstra Cc: Rusty Russell Cc: Ingo Molnar diff --git a/include/linux/module.h b/include/linux/module.h index 87d247a..f0e2659 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -395,6 +395,7 @@ static inline int module_is_live(struct module *mod) struct module *__module_text_address(unsigned long addr); struct module *__module_address(unsigned long addr); bool is_module_address(unsigned long addr); +bool is_module_percpu_address(unsigned long addr); bool is_module_text_address(unsigned long addr); static inline int within_module_core(unsigned long addr, struct module *mod) diff --git a/include/linux/percpu.h b/include/linux/percpu.h index a93e5bf..11d5f83 100644 --- a/include/linux/percpu.h +++ b/include/linux/percpu.h @@ -137,6 +137,7 @@ extern int __init pcpu_page_first_chunk(size_t reserved_size, extern void __percpu *__alloc_reserved_percpu(size_t size, size_t align); extern void __percpu *__alloc_percpu(size_t size, size_t align); extern void free_percpu(void __percpu *__pdata); +extern bool is_kernel_percpu_address(unsigned long addr); extern phys_addr_t per_cpu_ptr_to_phys(void *addr); #ifndef CONFIG_HAVE_SETUP_PER_CPU_AREA @@ -163,6 +164,12 @@ static inline void free_percpu(void __percpu *p) kfree(p); } +/* can't distinguish from other static vars, always false */ +static inline bool is_kernel_percpu_address(unsigned long addr) +{ + return false; +} + static inline phys_addr_t per_cpu_ptr_to_phys(void *addr) { return __pa(addr); diff --git a/kernel/lockdep.c b/kernel/lockdep.c index c927a549..9bbb9c8 100644 --- a/kernel/lockdep.c +++ b/kernel/lockdep.c @@ -582,9 +582,6 @@ static int static_obj(void *obj) unsigned long start = (unsigned long) &_stext, end = (unsigned long) &_end, addr = (unsigned long) obj; -#ifdef CONFIG_SMP - int i; -#endif /* * static variable? @@ -595,24 +592,16 @@ static int static_obj(void *obj) if (arch_is_kernel_data(addr)) return 1; -#ifdef CONFIG_SMP /* - * percpu var? + * in-kernel percpu var? */ - for_each_possible_cpu(i) { - start = (unsigned long) &__per_cpu_start + per_cpu_offset(i); - end = (unsigned long) &__per_cpu_start + PERCPU_ENOUGH_ROOM - + per_cpu_offset(i); - - if ((addr >= start) && (addr < end)) - return 1; - } -#endif + if (is_kernel_percpu_address(addr)) + return 1; /* - * module var? + * module static or percpu var? */ - return is_module_address(addr); + return is_module_address(addr) || is_module_percpu_address(addr); } /* diff --git a/kernel/module.c b/kernel/module.c index e7a6e53..9f8d23d 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -415,6 +415,40 @@ static void percpu_modcopy(struct module *mod, memcpy(per_cpu_ptr(mod->percpu, cpu), from, size); } +/** + * is_module_percpu_address - test whether address is from module static percpu + * @addr: address to test + * + * Test whether @addr belongs to module static percpu area. + * + * RETURNS: + * %true if @addr is from module static percpu area + */ +bool is_module_percpu_address(unsigned long addr) +{ + struct module *mod; + unsigned int cpu; + + preempt_disable(); + + list_for_each_entry_rcu(mod, &modules, list) { + if (!mod->percpu_size) + continue; + for_each_possible_cpu(cpu) { + void *start = per_cpu_ptr(mod->percpu, cpu); + + if ((void *)addr >= start && + (void *)addr < start + mod->percpu_size) { + preempt_enable(); + return true; + } + } + } + + preempt_enable(); + return false; +} + #else /* ... !CONFIG_SMP */ static inline void __percpu *mod_percpu(struct module *mod) @@ -441,6 +475,10 @@ static inline void percpu_modcopy(struct module *mod, /* pcpusec should be 0, and size of that section should be 0. */ BUG_ON(size != 0); } +bool is_module_percpu_address(unsigned long addr) +{ + return false; +} #endif /* CONFIG_SMP */ diff --git a/mm/percpu.c b/mm/percpu.c index 768419d..6e09741 100644 --- a/mm/percpu.c +++ b/mm/percpu.c @@ -1304,6 +1304,32 @@ void free_percpu(void __percpu *ptr) EXPORT_SYMBOL_GPL(free_percpu); /** + * is_kernel_percpu_address - test whether address is from static percpu area + * @addr: address to test + * + * Test whether @addr belongs to in-kernel static percpu area. Module + * static percpu areas are not considered. For those, use + * is_module_percpu_address(). + * + * RETURNS: + * %true if @addr is from in-kernel static percpu area, %false otherwise. + */ +bool is_kernel_percpu_address(unsigned long addr) +{ + const size_t static_size = __per_cpu_end - __per_cpu_start; + void __percpu *base = __addr_to_pcpu_ptr(pcpu_base_addr); + unsigned int cpu; + + for_each_possible_cpu(cpu) { + void *start = per_cpu_ptr(base, cpu); + + if ((void *)addr >= start && (void *)addr < start + static_size) + return true; + } + return false; +} + +/** * per_cpu_ptr_to_phys - convert translated percpu address to physical address * @addr: the address to be converted to physical address * -- cgit v0.10.2 From c565c54d9bf336ec9cd22288d3aa4fb6e372e727 Mon Sep 17 00:00:00 2001 From: Anisse Astier Date: Mon, 29 Mar 2010 16:20:06 +0200 Subject: HID: Add NOGET quirk for Quanta Pixart touchscreen Add the NOGET quirk for the Quanta optical touchscreen present on MSI AE2220, Otherwise, the hid-quanta driver timeouts at load time: drivers/hid/usbhid/hid-core.c: usb_submit_urb(ctrl) failed quanta-touch 0003:0408:3001.0003: timeout initializing reports input: PixArt Imaging Inc. Optical Touch Screen as /class/input/input7 quanta-touch 0003:0408:3001.0003: input: USB HID v1.10 Device [PixArt Imaging Inc. Optical Touch Screen] on usb-0000:00:06.0-2/input0 Signed-off-by: Anisse Astier Signed-off-by: Jiri Kosina diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 928943c..e71e005 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -60,6 +60,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, { USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NOGET }, { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET }, { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET }, { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209, HID_QUIRK_MULTI_INPUT }, -- cgit v0.10.2 From 6694635d3ae1b038d7a0e38b80637db867c7c8e2 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 29 Mar 2010 17:21:45 +0200 Subject: ALSA: hda - Fix ADC/MUX assignment of ALC269 codec ALC269 codec has a few different variants, and each of them may have different ADC and MUX widgets. For example, one model has ADC 0x08 with MUX 0x23 while others has ADC 0x09 or ADC 0x07 with MUX 022 or 0x24. The difference of ADC appears usually as the capability of the digital mic pin (0x12), and the current driver sometimes misses the internal mic pin due to the mismatching ADC. This patch adds a bit more clever way to find the matching ADC instead of the static list. Now the driver checks all active input pins and fills only the ADC/MUX's that contain all of them. Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index bc55c1e..22aea7b 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -4984,6 +4984,69 @@ static void set_capture_mixer(struct hda_codec *codec) } } +/* fill adc_nids (and capsrc_nids) containing all active input pins */ +static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids, + int num_nids) +{ + struct alc_spec *spec = codec->spec; + int n; + hda_nid_t fallback_adc = 0, fallback_cap = 0; + + for (n = 0; n < num_nids; n++) { + hda_nid_t adc, cap; + hda_nid_t conn[HDA_MAX_NUM_INPUTS]; + int nconns, i, j; + + adc = nids[n]; + if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN) + continue; + cap = adc; + nconns = snd_hda_get_connections(codec, cap, conn, + ARRAY_SIZE(conn)); + if (nconns == 1) { + cap = conn[0]; + nconns = snd_hda_get_connections(codec, cap, conn, + ARRAY_SIZE(conn)); + } + if (nconns <= 0) + continue; + if (!fallback_adc) { + fallback_adc = adc; + fallback_cap = cap; + } + for (i = 0; i < AUTO_PIN_LAST; i++) { + hda_nid_t nid = spec->autocfg.input_pins[i]; + if (!nid) + continue; + for (j = 0; j < nconns; j++) { + if (conn[j] == nid) + break; + } + if (j >= nconns) + break; + } + if (i >= AUTO_PIN_LAST) { + int num_adcs = spec->num_adc_nids; + spec->private_adc_nids[num_adcs] = adc; + spec->private_capsrc_nids[num_adcs] = cap; + spec->num_adc_nids++; + spec->adc_nids = spec->private_adc_nids; + if (adc != cap) + spec->capsrc_nids = spec->private_capsrc_nids; + } + } + if (!spec->num_adc_nids) { + printk(KERN_WARNING "hda_codec: %s: no valid ADC found;" + " using fallback 0x%x\n", fallback_adc); + spec->private_adc_nids[0] = fallback_adc; + spec->adc_nids = spec->private_adc_nids; + if (fallback_adc != fallback_cap) { + spec->private_capsrc_nids[0] = fallback_cap; + spec->capsrc_nids = spec->private_adc_nids; + } + } +} + #ifdef CONFIG_SND_HDA_INPUT_BEEP #define set_beep_amp(spec, nid, idx, dir) \ ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) @@ -13333,9 +13396,9 @@ static hda_nid_t alc269vb_capsrc_nids[1] = { 0x22, }; -/* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24), - * not a mux! - */ +static hda_nid_t alc269_adc_candidates[] = { + 0x08, 0x09, 0x07, +}; #define alc269_modes alc260_modes #define alc269_capture_source alc880_lg_lw_capture_source @@ -13842,7 +13905,6 @@ static int alc269_parse_auto_config(struct hda_codec *codec) struct alc_spec *spec = codec->spec; int err; static hda_nid_t alc269_ignore[] = { 0x1d, 0 }; - hda_nid_t real_capsrc_nids; err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, alc269_ignore); @@ -13866,18 +13928,19 @@ static int alc269_parse_auto_config(struct hda_codec *codec) if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010) { add_verb(spec, alc269vb_init_verbs); - real_capsrc_nids = alc269vb_capsrc_nids[0]; alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21); } else { add_verb(spec, alc269_init_verbs); - real_capsrc_nids = alc269_capsrc_nids[0]; alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); } spec->num_mux_defs = 1; spec->input_mux = &spec->private_imux[0]; + fillup_priv_adc_nids(codec, alc269_adc_candidates, + sizeof(alc269_adc_candidates)); + /* set default input source */ - snd_hda_codec_write_cache(codec, real_capsrc_nids, + snd_hda_codec_write_cache(codec, spec->capsrc_nids[0], 0, AC_VERB_SET_CONNECT_SEL, spec->input_mux->items[0].index); @@ -14156,14 +14219,16 @@ static int patch_alc269(struct hda_codec *codec) spec->stream_digital_playback = &alc269_pcm_digital_playback; spec->stream_digital_capture = &alc269_pcm_digital_capture; - if (!is_alc269vb) { - spec->adc_nids = alc269_adc_nids; - spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); - spec->capsrc_nids = alc269_capsrc_nids; - } else { - spec->adc_nids = alc269vb_adc_nids; - spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids); - spec->capsrc_nids = alc269vb_capsrc_nids; + if (!spec->adc_nids) { /* wasn't filled automatically? use default */ + if (!is_alc269vb) { + spec->adc_nids = alc269_adc_nids; + spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); + spec->capsrc_nids = alc269_capsrc_nids; + } else { + spec->adc_nids = alc269vb_adc_nids; + spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids); + spec->capsrc_nids = alc269vb_capsrc_nids; + } } if (!spec->cap_mixer) -- cgit v0.10.2 From 05ad62a5ee2ec2f65142aa2bf5c8a7e2f9cf9590 Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Wed, 10 Mar 2010 00:10:46 -0500 Subject: Staging: et131x: Properly disable FC in txmac. FC disable is bit 3 of the txmac ctl register, but commit 6720949d5562 ("Staging: et131x: Kil the txmac type") accidentally changed the code to set bit 2 instead. Signed-off-by: Nick Bowler Signed-off-by: Linus Torvalds diff --git a/drivers/staging/et131x/et1310_mac.c b/drivers/staging/et131x/et1310_mac.c index a292b1e..737a9f5 100644 --- a/drivers/staging/et131x/et1310_mac.c +++ b/drivers/staging/et131x/et1310_mac.c @@ -226,7 +226,7 @@ void ConfigMACRegs2(struct et131x_adapter *etdev) } /* Enable TXMAC */ - ctl |= 0x05; /* TX mac enable, FC disable */ + ctl |= 0x09; /* TX mac enable, FC disable */ writel(ctl, &etdev->regs->txmac.ctl); /* Ready to start the RXDMA/TXDMA engine */ -- cgit v0.10.2 From 88be12c440cfa2fa3f5be83507360aac9ea1c54e Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 29 Mar 2010 12:01:50 +0100 Subject: slow-work: use get_ref wrapper instead of directly calling get_ref Otherwise we can get an oops if the user has no get_ref/put_ref requirement. Signed-off-by: Dave Airlie Signed-off-by: David Howells Signed-off-by: Linus Torvalds diff --git a/kernel/slow-work.c b/kernel/slow-work.c index 7494bbf..7d3f4fa 100644 --- a/kernel/slow-work.c +++ b/kernel/slow-work.c @@ -637,7 +637,7 @@ int delayed_slow_work_enqueue(struct delayed_slow_work *dwork, goto cancelled; /* the timer holds a reference whilst it is pending */ - ret = work->ops->get_ref(work); + ret = slow_work_get_ref(work); if (ret < 0) goto cant_get_ref; -- cgit v0.10.2 From a53f4f9efaeb1d87cfae066346979d4d70e1abe9 Mon Sep 17 00:00:00 2001 From: David Howells Date: Mon, 29 Mar 2010 13:08:52 +0100 Subject: SLOW_WORK: CONFIG_SLOW_WORK_PROC should be CONFIG_SLOW_WORK_DEBUG CONFIG_SLOW_WORK_PROC was changed to CONFIG_SLOW_WORK_DEBUG, but not in all instances. Change the remaining instances. This makes the debugfs file display the time mark and the owner's description again. Signed-off-by: David Howells Signed-off-by: Linus Torvalds diff --git a/fs/fscache/object.c b/fs/fscache/object.c index e513ac5..0b589a9 100644 --- a/fs/fscache/object.c +++ b/fs/fscache/object.c @@ -53,7 +53,7 @@ const char fscache_object_states_short[FSCACHE_OBJECT__NSTATES][5] = { static void fscache_object_slow_work_put_ref(struct slow_work *); static int fscache_object_slow_work_get_ref(struct slow_work *); static void fscache_object_slow_work_execute(struct slow_work *); -#ifdef CONFIG_SLOW_WORK_PROC +#ifdef CONFIG_SLOW_WORK_DEBUG static void fscache_object_slow_work_desc(struct slow_work *, struct seq_file *); #endif static void fscache_initialise_object(struct fscache_object *); @@ -69,7 +69,7 @@ const struct slow_work_ops fscache_object_slow_work_ops = { .get_ref = fscache_object_slow_work_get_ref, .put_ref = fscache_object_slow_work_put_ref, .execute = fscache_object_slow_work_execute, -#ifdef CONFIG_SLOW_WORK_PROC +#ifdef CONFIG_SLOW_WORK_DEBUG .desc = fscache_object_slow_work_desc, #endif }; @@ -364,7 +364,7 @@ static void fscache_object_slow_work_execute(struct slow_work *work) /* * describe an object for slow-work debugging */ -#ifdef CONFIG_SLOW_WORK_PROC +#ifdef CONFIG_SLOW_WORK_DEBUG static void fscache_object_slow_work_desc(struct slow_work *work, struct seq_file *m) { diff --git a/fs/fscache/operation.c b/fs/fscache/operation.c index 313e79a..9f6c928 100644 --- a/fs/fscache/operation.c +++ b/fs/fscache/operation.c @@ -500,7 +500,7 @@ static void fscache_op_execute(struct slow_work *work) /* * describe an operation for slow-work debugging */ -#ifdef CONFIG_SLOW_WORK_PROC +#ifdef CONFIG_SLOW_WORK_DEBUG static void fscache_op_desc(struct slow_work *work, struct seq_file *m) { struct fscache_operation *op = @@ -517,7 +517,7 @@ const struct slow_work_ops fscache_op_slow_work_ops = { .get_ref = fscache_op_get_ref, .put_ref = fscache_op_put_ref, .execute = fscache_op_execute, -#ifdef CONFIG_SLOW_WORK_PROC +#ifdef CONFIG_SLOW_WORK_DEBUG .desc = fscache_op_desc, #endif }; diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h index 7be0c6f..c57db27 100644 --- a/include/linux/fscache-cache.h +++ b/include/linux/fscache-cache.h @@ -105,7 +105,7 @@ struct fscache_operation { /* operation releaser */ fscache_operation_release_t release; -#ifdef CONFIG_SLOW_WORK_PROC +#ifdef CONFIG_SLOW_WORK_DEBUG const char *name; /* operation name */ const char *state; /* operation state */ #define fscache_set_op_name(OP, N) do { (OP)->name = (N); } while(0) diff --git a/kernel/slow-work.h b/kernel/slow-work.h index 321f3c5..a29ebd1 100644 --- a/kernel/slow-work.h +++ b/kernel/slow-work.h @@ -43,28 +43,28 @@ extern void slow_work_new_thread_desc(struct slow_work *, struct seq_file *); */ static inline void slow_work_set_thread_pid(int id, pid_t pid) { -#ifdef CONFIG_SLOW_WORK_PROC +#ifdef CONFIG_SLOW_WORK_DEBUG slow_work_pids[id] = pid; #endif } static inline void slow_work_mark_time(struct slow_work *work) { -#ifdef CONFIG_SLOW_WORK_PROC +#ifdef CONFIG_SLOW_WORK_DEBUG work->mark = CURRENT_TIME; #endif } static inline void slow_work_begin_exec(int id, struct slow_work *work) { -#ifdef CONFIG_SLOW_WORK_PROC +#ifdef CONFIG_SLOW_WORK_DEBUG slow_work_execs[id] = work; #endif } static inline void slow_work_end_exec(int id, struct slow_work *work) { -#ifdef CONFIG_SLOW_WORK_PROC +#ifdef CONFIG_SLOW_WORK_DEBUG write_lock(&slow_work_execs_lock); slow_work_execs[id] = NULL; write_unlock(&slow_work_execs_lock); -- cgit v0.10.2 From c36207a4624f15020f2918324405c1c88a5d4cbc Mon Sep 17 00:00:00 2001 From: viresh kumar Date: Mon, 29 Mar 2010 05:28:32 +0100 Subject: ARM: 5999/1: Including device.h and resource.h header files in linux/amba/bus.h linux/amba/bus.h have dependencies on linux/device.h and linux/resource.h, but it doesn't include them. We get compilation errors in our files which include bus.h but doesn't include device.h and resource.h. This patch includes device.h and resource.h in linux/amba/bus.h file. Signed-off-by: Viresh Kumar Acked-by: Linux Walleij Signed-off-by: Russell King diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h index 6816be6..8b10386 100644 --- a/include/linux/amba/bus.h +++ b/include/linux/amba/bus.h @@ -14,6 +14,9 @@ #ifndef ASMARM_AMBA_H #define ASMARM_AMBA_H +#include +#include + #define AMBA_NR_IRQS 2 struct amba_device { -- cgit v0.10.2 From aedceb2a490bae56f9d7e80be480421e1cf22ce0 Mon Sep 17 00:00:00 2001 From: viresh kumar Date: Mon, 29 Mar 2010 05:29:57 +0100 Subject: ARM: 6000/1: removing compilation warning comming from irq.h is using struct pt_regs *. Due to this compilation warning is comming. Removing this warning by adding declaration of struct pt_regs. Signed-off-by: Viresh Kumar Signed-off-by: Russell King diff --git a/arch/arm/include/asm/irq.h b/arch/arm/include/asm/irq.h index 328f14a..237282f 100644 --- a/arch/arm/include/asm/irq.h +++ b/arch/arm/include/asm/irq.h @@ -17,6 +17,7 @@ #ifndef __ASSEMBLY__ struct irqaction; +struct pt_regs; extern void migrate_irqs(void); extern void asm_do_IRQ(unsigned int, struct pt_regs *); -- cgit v0.10.2 From 55a07517edbf15b83f323644edf346726eccd7e0 Mon Sep 17 00:00:00 2001 From: viresh kumar Date: Mon, 29 Mar 2010 05:58:51 +0100 Subject: ARM: 6001/1: removing compilation warning comming from clkdev.h clkdev.h is using struct device *. Due to this compilation warning is comming. Removing this warning. Signed-off-by: Viresh Kumar Signed-off-by: Russell King diff --git a/arch/arm/include/asm/clkdev.h b/arch/arm/include/asm/clkdev.h index 7a0690d..b56c138 100644 --- a/arch/arm/include/asm/clkdev.h +++ b/arch/arm/include/asm/clkdev.h @@ -13,6 +13,7 @@ #define __ASM_CLKDEV_H struct clk; +struct device; struct clk_lookup { struct list_head node; -- cgit v0.10.2 From 367d6acceaacff1adc44f121543effb9c060e575 Mon Sep 17 00:00:00 2001 From: viresh kumar Date: Mon, 29 Mar 2010 05:29:56 +0100 Subject: ARM: 6003/1: removing compilation warning from pl061.h pl061.h is using u8 type. including in pl061.h to avoid warning. Signed-off-by: Viresh Kumar Acked-by: Baruch Siach Signed-off-by: Russell King diff --git a/include/linux/amba/pl061.h b/include/linux/amba/pl061.h index b4fbd98..5ddd9ad 100644 --- a/include/linux/amba/pl061.h +++ b/include/linux/amba/pl061.h @@ -1,3 +1,5 @@ +#include + /* platform data for the PL061 GPIO driver */ struct pl061_platform_data { -- cgit v0.10.2 From 782a0fd16723bfc0e765d789e82853d5dc424e76 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Mon, 29 Mar 2010 06:59:16 +0100 Subject: ARM: 6005/1: arm: kprobes: fix register corruption with jprobes Current implementation of jprobes allocates empty pt_regs from the stack which is then passed to kprobe_handler() and eventually to singlestep(). Now when instruction being simulated is STMFD (like in normal function prologues without CONFIG_FRAME_POINTER), stores using SP actually write over top of the fabricated pt_regs structure. This can be reproduced for example by using LKDTM module: # modprobe lkdtm # mount -t debugfs none /sys/kernel/debug # echo PANIC > /sys/kernel/debug/provoke-crash/INT_HW_IRQ_EN after this, it fails with corrupted registers (before the requested crash would occur): lkdtm: Crash point INT_HW_IRQ_EN of type PANIC hit, trigger in 9 rounds lkdtm: Crash point INT_HW_IRQ_EN of type PANIC hit, trigger in 8 rounds Internal error: Oops - undefined instruction: 0 [#1] last sysfs file: /sys/devices/platform/serial8250.0/sleep_timeout Modules linked in: lkdtm CPU: 0 Not tainted (2.6.34-rc2 #69) PC is at irq_desc+0x1638/0xeeb0 LR is at 0x25 pc : [] lr : [<00000025>] psr: c80a0013 sp : ce94bd60 ip : c050b3e8 fp : a0000013 r10: c0aa453c r9 : cf5d4000 r8 : ce9a1822 r7 : c050b424 r6 : 00000025 r5 : c039d8f8 r4 : c050b3e8 r3 : 00000001 r2 : cf4d0440 r1 : c039d8f8 r0 : 00000020 Flags: NZcv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user Control: 10c5387d Table: 8e804019 DAC: 00000015 Process sh (pid: 496, stack limit = 0xce94a2e8) Stack: (0xce94bd60 to 0xce94c000) [...] Code: 000002cd 00000000 00000000 00000001 (dead4ead) ---[ end trace 2b46d5f2b682f370 ]--- Kernel panic - not syncing: Fatal exception in interrupt This patch allocates enough space (2 * sizeof(struct pt_regs)) from the stack to prevent such corruption. Signed-off-by: Mika Westerberg Acked-by: Nicolas Pitre Signed-off-by: Russell King diff --git a/arch/arm/kernel/kprobes.c b/arch/arm/kernel/kprobes.c index 60c62c3..610e0f5 100644 --- a/arch/arm/kernel/kprobes.c +++ b/arch/arm/kernel/kprobes.c @@ -393,6 +393,14 @@ void __kprobes jprobe_return(void) /* * Setup an empty pt_regs. Fill SP and PC fields as * they're needed by longjmp_break_handler. + * + * We allocate some slack between the original SP and start of + * our fabricated regs. To be precise we want to have worst case + * covered which is STMFD with all 16 regs so we allocate 2 * + * sizeof(struct_pt_regs)). + * + * This is to prevent any simulated instruction from writing + * over the regs when they are accessing the stack. */ "sub sp, %0, %1 \n\t" "ldr r0, ="__stringify(JPROBE_MAGIC_ADDR)"\n\t" @@ -410,7 +418,7 @@ void __kprobes jprobe_return(void) "ldmia sp, {r0 - pc} \n\t" : : "r" (kcb->jprobe_saved_regs.ARM_sp), - "I" (sizeof(struct pt_regs)), + "I" (sizeof(struct pt_regs) * 2), "J" (offsetof(struct pt_regs, ARM_sp)), "J" (offsetof(struct pt_regs, ARM_pc)), "J" (offsetof(struct pt_regs, ARM_cpsr)) -- cgit v0.10.2 From fd522a8dec11a08b5fdd23982193808e268be19e Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Mon, 29 Mar 2010 10:29:46 +0100 Subject: ARM: 6006/1: ARM: Use the correct NOP size in memmove for Thumb-2 kernel builds When compiling the kernel to Thumb-2, using a 16-bit NOP in the memmove() implementation causes the preceding ADD PC instruction to branch incorrectly in the middle of a 32-bit LDR or STR instruction. The memmove() code is now similar to the memcpy() template. Signed-off-by: Catalin Marinas Signed-off-by: Russell King diff --git a/arch/arm/lib/memmove.S b/arch/arm/lib/memmove.S index 5025c86..938fc14 100644 --- a/arch/arm/lib/memmove.S +++ b/arch/arm/lib/memmove.S @@ -74,7 +74,7 @@ ENTRY(memmove) rsb ip, ip, #32 addne pc, pc, ip @ C is always clear here b 7f -6: nop +6: W(nop) W(ldr) r3, [r1, #-4]! W(ldr) r4, [r1, #-4]! W(ldr) r5, [r1, #-4]! @@ -85,7 +85,7 @@ ENTRY(memmove) add pc, pc, ip nop - nop + W(nop) W(str) r3, [r0, #-4]! W(str) r4, [r0, #-4]! W(str) r5, [r0, #-4]! -- cgit v0.10.2 From c6c352371c1ce486a62f4eb92e545b05cfcef76b Mon Sep 17 00:00:00 2001 From: Harro Haan Date: Mon, 1 Mar 2010 17:38:37 +0100 Subject: ARM: 5965/1: Fix soft lockup in at91 udc driver Fix a potential soft lockup in the AT91 UDC driver by ensuring that the UDC clock is enabled inside the interrupt handler. If the UDC clock is not enabled then the UDC registers cannot be written to and the interrupt cannot be cleared or masked. Note that this patch (and other parts of the existing AT91 UDC driver) is potentially racy for preempt-rt kernels, but is okay for mainline. For more info see: http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20100203/09cdb3b4/attachment.el http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20100203/8443a1e4/attachment.el Signed-off-by: Ryan Mallon Acked-by: Harro Haan Tested-by: Remy Bohmer Acked-by: Andrew Victor Cc: David Brownell Signed-off-by: Russell King diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index 12ac9cd..df1bae9 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c @@ -1370,6 +1370,12 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc) { struct at91_udc *udc = _udc; u32 rescans = 5; + int disable_clock = 0; + + if (!udc->clocked) { + clk_on(udc); + disable_clock = 1; + } while (rescans--) { u32 status; @@ -1458,6 +1464,9 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc) } } + if (disable_clock) + clk_off(udc); + return IRQ_HANDLED; } -- cgit v0.10.2 From f7454c5d5c33b84fdbb957b7ad4a432e333b2550 Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 24 Mar 2010 16:59:36 +0000 Subject: frv/chris: fix lines with a missing semicolons Commit b26b2d494b659f9 ("resource/PCI: align functions now return start of resource") added lines with missing semicolons. Add the missing semicolons to the FRV and CRIS arch code. Signed-off-by: David Howells Cc: linux@dominikbrodowski.net Signed-off-by: Linus Torvalds diff --git a/arch/cris/arch-v32/drivers/pci/bios.c b/arch/cris/arch-v32/drivers/pci/bios.c index d4b9c36..bc0cfda 100644 --- a/arch/cris/arch-v32/drivers/pci/bios.c +++ b/arch/cris/arch-v32/drivers/pci/bios.c @@ -50,7 +50,7 @@ pcibios_align_resource(void *data, const struct resource *res, if ((res->flags & IORESOURCE_IO) && (start & 0x300)) start = (start + 0x3ff) & ~0x3ff; - return start + return start; } int pcibios_enable_resources(struct pci_dev *dev, int mask) diff --git a/arch/frv/mb93090-mb00/pci-frv.c b/arch/frv/mb93090-mb00/pci-frv.c index 16bc2cb..6b4fb28 100644 --- a/arch/frv/mb93090-mb00/pci-frv.c +++ b/arch/frv/mb93090-mb00/pci-frv.c @@ -41,7 +41,7 @@ pcibios_align_resource(void *data, const struct resource *res, if ((res->flags & IORESOURCE_IO) && (start & 0x300)) start = (start + 0x3ff) & ~0x3ff; - return start + return start; } -- cgit v0.10.2 From 596b711ed6b5235f8545680ef38ace00f9898c32 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sun, 28 Mar 2010 19:42:54 -0700 Subject: x86: Make smp_locks end with page alignment Fix: ------------[ cut here ]------------ WARNING: at arch/x86/mm/init.c:342 free_init_pages+0x4c/0xfa() free_init_pages: range [0x40daf000, 0x40db5c24] is not aligned Modules linked in: Pid: 0, comm: swapper Not tainted 2.6.34-rc2-tip-03946-g4f16b23-dirty #50 Call Trace: [<40232e9f>] warn_slowpath_common+0x65/0x7c [<4021c9f0>] ? free_init_pages+0x4c/0xfa [<40881434>] ? _etext+0x0/0x24 [<40232eea>] warn_slowpath_fmt+0x24/0x27 [<4021c9f0>] free_init_pages+0x4c/0xfa [<40881434>] ? _etext+0x0/0x24 [<40d3f4bd>] alternative_instructions+0xf6/0x100 [<40d3fe4f>] check_bugs+0xbd/0xbf [<40d398a7>] start_kernel+0x2d5/0x2e4 [<40d390ce>] i386_start_kernel+0xce/0xd5 ---[ end trace 4eaa2a86a8e2da22 ]--- Comments in vmlinux.lds.S already said: | /* | * smp_locks might be freed after init | * start/end must be page aligned | */ Signed-off-by: Yinghai Lu Acked-by: Johannes Weiner Cc: David Miller Cc: Benjamin Herrenschmidt Cc: Linus Torvalds LKML-Reference: <1269830604-26214-2-git-send-email-yinghai@kernel.org> Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S index 44879df..2cc2497 100644 --- a/arch/x86/kernel/vmlinux.lds.S +++ b/arch/x86/kernel/vmlinux.lds.S @@ -291,8 +291,8 @@ SECTIONS .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) { __smp_locks = .; *(.smp_locks) - __smp_locks_end = .; . = ALIGN(PAGE_SIZE); + __smp_locks_end = .; } #ifdef CONFIG_X86_64 -- cgit v0.10.2 From 8136b58dd0fce0b4cb649ac690e0493fb6fdacdb Mon Sep 17 00:00:00 2001 From: Cheng Renquan Date: Mon, 29 Mar 2010 19:05:57 +0800 Subject: ceph: some documentations fixes New documentation should have an entry in the 00-INDEX. Correct git urls. Signed-off-by: Cheng Renquan Signed-off-by: Sage Weil diff --git a/Documentation/filesystems/00-INDEX b/Documentation/filesystems/00-INDEX index 3bae418..4303614 100644 --- a/Documentation/filesystems/00-INDEX +++ b/Documentation/filesystems/00-INDEX @@ -16,6 +16,8 @@ befs.txt - information about the BeOS filesystem for Linux. bfs.txt - info for the SCO UnixWare Boot Filesystem (BFS). +ceph.txt + - info for the Ceph Distributed File System cifs.txt - description of the CIFS filesystem. coda.txt diff --git a/Documentation/filesystems/ceph.txt b/Documentation/filesystems/ceph.txt index 523fdf0..0660c9f 100644 --- a/Documentation/filesystems/ceph.txt +++ b/Documentation/filesystems/ceph.txt @@ -8,7 +8,7 @@ Basic features include: * POSIX semantics * Seamless scaling from 1 to many thousands of nodes - * High availability and reliability. No single points of failure. + * High availability and reliability. No single point of failure. * N-way replication of data across storage nodes * Fast recovery from node failures * Automatic rebalancing of data on node addition/removal @@ -94,7 +94,7 @@ Mount Options wsize=X Specify the maximum write size in bytes. By default there is no - maximu. Ceph will normally size writes based on the file stripe + maximum. Ceph will normally size writes based on the file stripe size. rsize=X @@ -133,7 +133,8 @@ For more information on Ceph, see the home page at http://ceph.newdream.net/ The Linux kernel client source tree is available at - git://ceph.newdream.net/linux-ceph-client.git + git://ceph.newdream.net/git/ceph-client.git + git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client.git and the source for the full system is at - git://ceph.newdream.net/ceph.git + git://ceph.newdream.net/git/ceph.git -- cgit v0.10.2 From 82593f87b6c1922a8f8317bb165c6c7794fa4639 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 29 Mar 2010 09:53:23 -0700 Subject: ceph: update discussion list address in MAINTAINERS Signed-off-by: Sage Weil diff --git a/MAINTAINERS b/MAINTAINERS index 449d444..c3b60c0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1443,7 +1443,7 @@ F: arch/powerpc/platforms/cell/ CEPH DISTRIBUTED FILE SYSTEM CLIENT M: Sage Weil -L: ceph-devel@lists.sourceforge.net +L: ceph-devel@vger.kernel.org W: http://ceph.newdream.net/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client.git S: Supported -- cgit v0.10.2 From c967da6a0ba837f762042e931d4afcf72045547c Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sun, 28 Mar 2010 19:42:55 -0700 Subject: x86: Make sure free_init_pages() frees pages on page boundary When CONFIG_NO_BOOTMEM=y, it could use memory more effiently, or in a more compact fashion. Example: Allocated new RAMDISK: 00ec2000 - 0248ce57 Move RAMDISK from 000000002ea04000 - 000000002ffcee56 to 00ec2000 - 0248ce56 The new RAMDISK's end is not page aligned. Last page could be shared with other users. When free_init_pages are called for initrd or .init, the page could be freed and we could corrupt other data. code segment in free_init_pages(): | for (; addr < end; addr += PAGE_SIZE) { | ClearPageReserved(virt_to_page(addr)); | init_page_count(virt_to_page(addr)); | memset((void *)(addr & ~(PAGE_SIZE-1)), | POISON_FREE_INITMEM, PAGE_SIZE); | free_page(addr); | totalram_pages++; | } last half page could be used as one whole free page. So page align the boundaries. -v2: make the original initramdisk to be aligned, according to Johannes, otherwise we have the chance to lose one page. we still need to keep initrd_end not aligned, otherwise it could confuse decompressor. -v3: change to WARN_ON instead, suggested by Johannes. -v4: use PAGE_ALIGN, suggested by Johannes. We may fix that macro name later to PAGE_ALIGN_UP, and PAGE_ALIGN_DOWN Add comments about assuming ramdisk start is aligned in relocate_initrd(), change to re get ramdisk_image instead of save it to make diff smaller. Add warning for wrong range, suggested by Johannes. -v6: remove one WARN() We need to align beginning in free_init_pages() do not copy more than ramdisk_size, noticed by Johannes Reported-by: Stanislaw Gruszka Tested-by: Stanislaw Gruszka Signed-off-by: Yinghai Lu Acked-by: Johannes Weiner Cc: David Miller Cc: Benjamin Herrenschmidt Cc: Linus Torvalds LKML-Reference: <1269830604-26214-3-git-send-email-yinghai@kernel.org> Signed-off-by: Ingo Molnar diff --git a/arch/x86/kernel/head32.c b/arch/x86/kernel/head32.c index adedeef..b2e2460 100644 --- a/arch/x86/kernel/head32.c +++ b/arch/x86/kernel/head32.c @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -44,9 +45,10 @@ void __init i386_start_kernel(void) #ifdef CONFIG_BLK_DEV_INITRD /* Reserve INITRD */ if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) { + /* Assume only end is not page aligned */ u64 ramdisk_image = boot_params.hdr.ramdisk_image; u64 ramdisk_size = boot_params.hdr.ramdisk_size; - u64 ramdisk_end = ramdisk_image + ramdisk_size; + u64 ramdisk_end = PAGE_ALIGN(ramdisk_image + ramdisk_size); reserve_early(ramdisk_image, ramdisk_end, "RAMDISK"); } #endif diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index b5a9896..7147143 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c @@ -103,9 +103,10 @@ void __init x86_64_start_reservations(char *real_mode_data) #ifdef CONFIG_BLK_DEV_INITRD /* Reserve INITRD */ if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) { + /* Assume only end is not page aligned */ unsigned long ramdisk_image = boot_params.hdr.ramdisk_image; unsigned long ramdisk_size = boot_params.hdr.ramdisk_size; - unsigned long ramdisk_end = ramdisk_image + ramdisk_size; + unsigned long ramdisk_end = PAGE_ALIGN(ramdisk_image + ramdisk_size); reserve_early(ramdisk_image, ramdisk_end, "RAMDISK"); } #endif diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 5d7ba1a..d76e185 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -314,16 +314,17 @@ static void __init reserve_brk(void) #define MAX_MAP_CHUNK (NR_FIX_BTMAPS << PAGE_SHIFT) static void __init relocate_initrd(void) { - + /* Assume only end is not page aligned */ u64 ramdisk_image = boot_params.hdr.ramdisk_image; u64 ramdisk_size = boot_params.hdr.ramdisk_size; + u64 area_size = PAGE_ALIGN(ramdisk_size); u64 end_of_lowmem = max_low_pfn_mapped << PAGE_SHIFT; u64 ramdisk_here; unsigned long slop, clen, mapaddr; char *p, *q; /* We need to move the initrd down into lowmem */ - ramdisk_here = find_e820_area(0, end_of_lowmem, ramdisk_size, + ramdisk_here = find_e820_area(0, end_of_lowmem, area_size, PAGE_SIZE); if (ramdisk_here == -1ULL) @@ -332,7 +333,7 @@ static void __init relocate_initrd(void) /* Note: this includes all the lowmem currently occupied by the initrd, we rely on that fact to keep the data intact. */ - reserve_early(ramdisk_here, ramdisk_here + ramdisk_size, + reserve_early(ramdisk_here, ramdisk_here + area_size, "NEW RAMDISK"); initrd_start = ramdisk_here + PAGE_OFFSET; initrd_end = initrd_start + ramdisk_size; @@ -376,9 +377,10 @@ static void __init relocate_initrd(void) static void __init reserve_initrd(void) { + /* Assume only end is not page aligned */ u64 ramdisk_image = boot_params.hdr.ramdisk_image; u64 ramdisk_size = boot_params.hdr.ramdisk_size; - u64 ramdisk_end = ramdisk_image + ramdisk_size; + u64 ramdisk_end = PAGE_ALIGN(ramdisk_image + ramdisk_size); u64 end_of_lowmem = max_low_pfn_mapped << PAGE_SHIFT; if (!boot_params.hdr.type_of_loader || diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c index e71c5cb..452ee5b 100644 --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c @@ -331,11 +331,23 @@ int devmem_is_allowed(unsigned long pagenr) void free_init_pages(char *what, unsigned long begin, unsigned long end) { - unsigned long addr = begin; + unsigned long addr; + unsigned long begin_aligned, end_aligned; - if (addr >= end) + /* Make sure boundaries are page aligned */ + begin_aligned = PAGE_ALIGN(begin); + end_aligned = end & PAGE_MASK; + + if (WARN_ON(begin_aligned != begin || end_aligned != end)) { + begin = begin_aligned; + end = end_aligned; + } + + if (begin >= end) return; + addr = begin; + /* * If debugging page accesses then do not free this memory but * mark them not present - any buggy init-section access will @@ -343,7 +355,7 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end) */ #ifdef CONFIG_DEBUG_PAGEALLOC printk(KERN_INFO "debug: unmapping init memory %08lx..%08lx\n", - begin, PAGE_ALIGN(end)); + begin, end); set_memory_np(begin, (end - begin) >> PAGE_SHIFT); #else /* @@ -358,8 +370,7 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end) for (; addr < end; addr += PAGE_SIZE) { ClearPageReserved(virt_to_page(addr)); init_page_count(virt_to_page(addr)); - memset((void *)(addr & ~(PAGE_SIZE-1)), - POISON_FREE_INITMEM, PAGE_SIZE); + memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE); free_page(addr); totalram_pages++; } @@ -376,6 +387,15 @@ void free_initmem(void) #ifdef CONFIG_BLK_DEV_INITRD void free_initrd_mem(unsigned long start, unsigned long end) { - free_init_pages("initrd memory", start, end); + /* + * end could be not aligned, and We can not align that, + * decompresser could be confused by aligned initrd_end + * We already reserve the end partial page before in + * - i386_start_kernel() + * - x86_64_start_kernel() + * - relocate_initrd() + * So here We can do PAGE_ALIGN() safely to get partial page to be freed + */ + free_init_pages("initrd memory", start, PAGE_ALIGN(end)); } #endif -- cgit v0.10.2 From eed63519e3e74d515d2007ecd895338d0ba2a85c Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Sun, 28 Mar 2010 19:42:56 -0700 Subject: x86: Do not free zero sized per cpu areas This avoids an infinite loop in free_early_partial(). Add a warning to free_early_partial() to catch future problems. -v5: put back start > end back into WARN_ONCE() -v6: use one line for warning, suggested by Linus -v7: more tests -v8: remove the function name as suggested by Johannes WARN_ONCE() will print out that function name. Signed-off-by: Ian Campbell Signed-off-by: Yinghai Lu Tested-by: Konrad Rzeszutek Wilk Tested-by: Joel Becker Tested-by: Stanislaw Gruszka Acked-by: Johannes Weiner Cc: Peter Zijlstra Cc: David Miller Cc: Benjamin Herrenschmidt Cc: Linus Torvalds LKML-Reference: <1269830604-26214-4-git-send-email-yinghai@kernel.org> Signed-off-by: Ingo Molnar diff --git a/kernel/early_res.c b/kernel/early_res.c index 3cb2c66..31aa933 100644 --- a/kernel/early_res.c +++ b/kernel/early_res.c @@ -333,6 +333,12 @@ void __init free_early_partial(u64 start, u64 end) struct early_res *r; int i; + if (start == end) + return; + + if (WARN_ONCE(start > end, " wrong range [%#llx, %#llx]\n", start, end)) + return; + try_next: i = find_overlapped_early(start, end); if (i >= max_early_res) -- cgit v0.10.2 From 0943846ae05603efd98550f2d475e9c98191bde8 Mon Sep 17 00:00:00 2001 From: Joern Engel Date: Mon, 29 Mar 2010 21:13:28 +0200 Subject: [LogFS] Move reserved segments with journal Fixes a GC livelock. Signed-off-by: Joern Engel diff --git a/fs/logfs/journal.c b/fs/logfs/journal.c index 15454ac..25b1345 100644 --- a/fs/logfs/journal.c +++ b/fs/logfs/journal.c @@ -800,6 +800,7 @@ void do_logfs_journal_wl_pass(struct super_block *sb) { struct logfs_super *super = logfs_super(sb); struct logfs_area *area = super->s_journal_area; + struct btree_head32 *head = &super->s_reserved_segments; u32 segno, ec; int i, err; @@ -807,6 +808,7 @@ void do_logfs_journal_wl_pass(struct super_block *sb) /* Drop old segments */ journal_for_each(i) if (super->s_journal_seg[i]) { + btree_remove32(head, super->s_journal_seg[i]); logfs_set_segment_unreserved(sb, super->s_journal_seg[i], super->s_journal_ec[i]); @@ -819,6 +821,8 @@ void do_logfs_journal_wl_pass(struct super_block *sb) super->s_journal_seg[i] = segno; super->s_journal_ec[i] = ec; logfs_set_segment_reserved(sb, segno); + err = btree_insert32(head, segno, (void *)1, GFP_KERNEL); + BUG_ON(err); /* mempool should prevent this */ } /* Manually move journal_area */ freeseg(sb, area->a_segno); -- cgit v0.10.2 From 6be7fa06eb4d721df734bd0946b5e63b27c0589b Mon Sep 17 00:00:00 2001 From: Joern Engel Date: Mon, 29 Mar 2010 21:14:52 +0200 Subject: [LogFS] Erase new journal segments If the device contains on old logfs image and the journal is moved to segment that have never been used by the current logfs and not all journal segments are erased before the next mount, the old content can confuse mount code. To prevent this, always erase the new journal segments. Signed-off-by: Joern Engel diff --git a/fs/logfs/journal.c b/fs/logfs/journal.c index 25b1345..d57c7b0 100644 --- a/fs/logfs/journal.c +++ b/fs/logfs/journal.c @@ -823,6 +823,8 @@ void do_logfs_journal_wl_pass(struct super_block *sb) logfs_set_segment_reserved(sb, segno); err = btree_insert32(head, segno, (void *)1, GFP_KERNEL); BUG_ON(err); /* mempool should prevent this */ + err = logfs_erase_segment(sb, segno, 1); + BUG_ON(err); /* FIXME: remount-ro would be nicer */ } /* Manually move journal_area */ freeseg(sb, area->a_segno); -- cgit v0.10.2 From e36673ec5126f15a8cddf6049aede7bdcf484c26 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Wed, 24 Mar 2010 10:57:37 +0800 Subject: tracing: Fix lockdep warning in global_clock() # echo 1 > events/enable # echo global > trace_clock ------------[ cut here ]------------ WARNING: at kernel/lockdep.c:3162 check_flags+0xb2/0x190() ... ---[ end trace 3f86734a89416623 ]--- possible reason: unannotated irqs-on. ... There's no reason to use the raw_local_irq_save() in trace_clock_global. The local_irq_save() version is fine, and does not cause the bug in lockdep. Acked-by: Peter Zijlstra Signed-off-by: Li Zefan LKML-Reference: <4BA97FA1.7030606@cn.fujitsu.com> Signed-off-by: Steven Rostedt diff --git a/kernel/trace/trace_clock.c b/kernel/trace/trace_clock.c index 6fbfb8f..9d589d8 100644 --- a/kernel/trace/trace_clock.c +++ b/kernel/trace/trace_clock.c @@ -84,7 +84,7 @@ u64 notrace trace_clock_global(void) int this_cpu; u64 now; - raw_local_irq_save(flags); + local_irq_save(flags); this_cpu = raw_smp_processor_id(); now = cpu_clock(this_cpu); @@ -110,7 +110,7 @@ u64 notrace trace_clock_global(void) arch_spin_unlock(&trace_clock_struct.lock); out: - raw_local_irq_restore(flags); + local_irq_restore(flags); return now; } -- cgit v0.10.2 From 292f60c0c4ab44aa2d589ba03c12e64a3b3c5e38 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Mon, 29 Mar 2010 17:37:02 +0200 Subject: ring-buffer: Add missing unlock In some error handling cases the lock is not unlocked. The return is converted to a goto, to share the unlock at the end of the function. A simplified version of the semantic patch that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @r exists@ expression E1; identifier f; @@ f (...) { <+... * spin_lock_irq (E1,...); ... when != E1 * return ...; ...+> } // Signed-off-by: Julia Lawall LKML-Reference: Signed-off-by: Steven Rostedt diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index d1187ef..9a0f9bf 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -1209,18 +1209,19 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned nr_pages) for (i = 0; i < nr_pages; i++) { if (RB_WARN_ON(cpu_buffer, list_empty(cpu_buffer->pages))) - return; + goto out; p = cpu_buffer->pages->next; bpage = list_entry(p, struct buffer_page, list); list_del_init(&bpage->list); free_buffer_page(bpage); } if (RB_WARN_ON(cpu_buffer, list_empty(cpu_buffer->pages))) - return; + goto out; rb_reset_cpu(cpu_buffer); rb_check_pages(cpu_buffer); +out: spin_unlock_irq(&cpu_buffer->reader_lock); } @@ -1237,7 +1238,7 @@ rb_insert_pages(struct ring_buffer_per_cpu *cpu_buffer, for (i = 0; i < nr_pages; i++) { if (RB_WARN_ON(cpu_buffer, list_empty(pages))) - return; + goto out; p = pages->next; bpage = list_entry(p, struct buffer_page, list); list_del_init(&bpage->list); @@ -1246,6 +1247,7 @@ rb_insert_pages(struct ring_buffer_per_cpu *cpu_buffer, rb_reset_cpu(cpu_buffer); rb_check_pages(cpu_buffer); +out: spin_unlock_irq(&cpu_buffer->reader_lock); } -- cgit v0.10.2 From fb48e3c6a4d8888aff61fbf567aadac7d206e973 Mon Sep 17 00:00:00 2001 From: Graham Gower Date: Thu, 25 Mar 2010 10:52:12 +1030 Subject: ASoC: Fix passing platform_data to ac97 bus users and fix a leak [The issue is an attempt to write the pdata without the AC97 device allocated when using ac97.c - also added a comment in soc-core.c for the special case for ac97. -- broonie] Signed-off-by: Graham Gower Acked-by: Liam Girdwood Signed-off-by: Mark Brown diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c index a1bbe16..bcfa532 100644 --- a/sound/soc/codecs/ac97.c +++ b/sound/soc/codecs/ac97.c @@ -80,9 +80,11 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, static int ac97_soc_probe(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_card *card = socdev->card; struct snd_soc_codec *codec; struct snd_ac97_bus *ac97_bus; struct snd_ac97_template ac97_template; + int i; int ret = 0; printk(KERN_INFO "AC97 SoC Audio Codec %s\n", AC97_VERSION); @@ -102,12 +104,6 @@ static int ac97_soc_probe(struct platform_device *pdev) INIT_LIST_HEAD(&codec->dapm_widgets); INIT_LIST_HEAD(&codec->dapm_paths); - ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); - if (ret < 0) { - printk(KERN_ERR "ASoC: failed to init gen ac97 glue\n"); - goto err; - } - /* register pcms */ ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); if (ret < 0) @@ -123,6 +119,13 @@ static int ac97_soc_probe(struct platform_device *pdev) if (ret < 0) goto bus_err; + for (i = 0; i < card->num_links; i++) { + if (card->dai_link[i].codec_dai->ac97_control) { + snd_ac97_dev_add_pdata(codec->ac97, + card->dai_link[i].cpu_dai->ac97_pdata); + } + } + return 0; bus_err: diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index c8b0556..d0efd5e 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1548,7 +1548,8 @@ int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid) mutex_unlock(&codec->mutex); return ret; } - if (card->dai_link[i].codec_dai->ac97_control) { + /* Check for codec->ac97 to handle the ac97.c fun */ + if (card->dai_link[i].codec_dai->ac97_control && codec->ac97) { snd_ac97_dev_add_pdata(codec->ac97, card->dai_link[i].cpu_dai->ac97_pdata); } -- cgit v0.10.2 From fcc6a7462ec8d8a7d63ec59559e91f8fd6991160 Mon Sep 17 00:00:00 2001 From: Prarit Bhargava Date: Mon, 29 Mar 2010 22:02:59 +0200 Subject: hwmon: (coretemp) Fix cpu model output Avoid hex and decimal confusion when printing out the cpu model. Signed-off-by: Prarit Bhargava Signed-off-by: Jean Delvare diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 2d7bcee..f5f975b 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -466,7 +466,7 @@ static int __init coretemp_init(void) family 6 CPU */ if ((c->x86 == 0x6) && (c->x86_model > 0xf)) printk(KERN_WARNING DRVNAME ": Unknown CPU " - "model %x\n", c->x86_model); + "model 0x%x\n", c->x86_model); continue; } -- cgit v0.10.2 From 4d7a5644e4adfafe76c2bd8ee168e3f3b5dae3a8 Mon Sep 17 00:00:00 2001 From: Dean Nelson Date: Mon, 29 Mar 2010 22:03:00 +0200 Subject: hwmon: (coretemp) Add missing newline to dev_warn() message Add missing newline to dev_warn() message string. This is more of an issue with older kernels that don't automatically add a newline if it was missing from the end of the previous line. Signed-off-by: Dean Nelson Cc: stable@kernel.org Signed-off-by: Jean Delvare diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index f5f975b..e9b7fbc 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -228,7 +228,7 @@ static int __devinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device * if (err) { dev_warn(dev, "Unable to access MSR 0xEE, for Tjmax, left" - " at default"); + " at default\n"); } else if (eax & 0x40000000) { tjmax = tjmax_ee; } -- cgit v0.10.2 From 3f7cd7ea9383755eef53f92667c520489165667f Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 29 Mar 2010 22:03:03 +0200 Subject: hwmon: (w83793) Saving negative errors in unsigned "ret" is used to store the return value for watchdog_trigger() and it should be signed for the error handling to work. Signed-off-by: Dan Carpenter Acked-by: Hans de Goede Signed-off-by: Jean Delvare diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c index 9de81a4..612807d 100644 --- a/drivers/hwmon/w83793.c +++ b/drivers/hwmon/w83793.c @@ -1294,7 +1294,7 @@ static int watchdog_close(struct inode *inode, struct file *filp) static ssize_t watchdog_write(struct file *filp, const char __user *buf, size_t count, loff_t *offset) { - size_t ret; + ssize_t ret; struct w83793_data *data = filp->private_data; if (count) { -- cgit v0.10.2 From b00d8a7e299eab9970b0ba75a4e2ea1df39059ad Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Rajput Date: Mon, 29 Mar 2010 22:03:06 +0200 Subject: hwmon: (asc7621) Add X58 entry in Kconfig Intel X58 have asc7621a chip. So added X58 entry in Kconfig for asc7621. Also arranged existing models in ascending order. Signed-off-by: Jaswinder Singh Rajput Signed-off-by: Jean Delvare diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index e4595e6..9be8e17 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -217,8 +217,8 @@ config SENSORS_ASC7621 depends on HWMON && I2C help If you say yes here you get support for the aSC7621 - family of SMBus sensors chip found on most Intel X48, X38, 975, - 965 and 945 desktop boards. Currently supported chips: + family of SMBus sensors chip found on most Intel X38, X48, X58, + 945, 965 and 975 desktop boards. Currently supported chips: aSC7621 aSC7621a -- cgit v0.10.2 From 9e8307ecaf9f8c8b5b3b22145021204c4e73114a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 29 Mar 2010 13:08:52 -0700 Subject: sparc64: Properly truncate pt_regs framepointer in perf callback. For 32-bit processes, we save the full 64-bits of the regs in pt_regs. But unlike when the userspace actually does load and store instructions, the top 32-bits don't get automatically truncated by the cpu in kernel mode (because the kernel doesn't execute with PSTATE_AM address masking enabled). So we have to do it by hand. Reported-by: Frederic Weisbecker Signed-off-by: David S. Miller diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c index 9f2b2ba..610112e 100644 --- a/arch/sparc/kernel/perf_event.c +++ b/arch/sparc/kernel/perf_event.c @@ -1337,7 +1337,7 @@ static void perf_callchain_user_32(struct pt_regs *regs, callchain_store(entry, PERF_CONTEXT_USER); callchain_store(entry, regs->tpc); - ufp = regs->u_regs[UREG_I6]; + ufp = regs->u_regs[UREG_I6] & 0xffffffffUL; do { struct sparc_stackf32 *usf, sf; unsigned long pc; -- cgit v0.10.2 From c0cd884af045338476b8e69a61fceb3f34ff22f1 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Mon, 29 Mar 2010 13:16:02 -0700 Subject: r8169: offical fix for CVE-2009-4537 (overlength frame DMAs) Official patch to fix the r8169 frame length check error. Based on this initial thread: http://marc.info/?l=linux-netdev&m=126202972828626&w=1 This is the official patch to fix the frame length problems in the r8169 driver. As noted in the previous thread, while this patch incurs a performance hit on the driver, its possible to improve performance dynamically by updating the mtu and rx_copybreak values at runtime to return performance to what it was for those NICS which are unaffected by the ideosyncracy (if there are any). Summary: A while back Eric submitted a patch for r8169 in which the proper allocated frame size was written to RXMaxSize to prevent the NIC from dmaing too much data. This was done in commit fdd7b4c3302c93f6833e338903ea77245eb510b4. A long time prior to that however, Francois posted 126fa4b9ca5d9d7cb7d46f779ad3bd3631ca387c, which expiclitly disabled the MaxSize setting due to the fact that the hardware behaved in odd ways when overlong frames were received on NIC's supported by this driver. This was mentioned in a security conference recently: http://events.ccc.de/congress/2009/Fahrplan//events/3596.en.html It seems that if we can't enable frame size filtering, then, as Eric correctly noticed, we can find ourselves DMA-ing too much data to a buffer, causing corruption. As a result is seems that we are forced to allocate a frame which is ready to handle a maximally sized receive. This obviously has performance issues with it, so to mitigate that issue, this patch does two things: 1) Raises the copybreak value to the frame allocation size, which should force appropriately sized packets to get allocated on rx, rather than a full new 16k buffer. 2) This patch only disables frame filtering initially (i.e., during the NIC open), changing the MTU results in ring buffer allocation of a size in relation to the new mtu (along with a warning indicating that this is dangerous). Because of item (2), individuals who can't cope with the performance hit (or can otherwise filter frames to prevent the bug), or who have hardware they are sure is unaffected by this issue, can manually lower the copybreak and reset the mtu such that performance is restored easily. Signed-off-by: Neil Horman Signed-off-by: David S. Miller diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 7193afc..9674005 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -186,7 +186,12 @@ static DEFINE_PCI_DEVICE_TABLE(rtl8169_pci_tbl) = { MODULE_DEVICE_TABLE(pci, rtl8169_pci_tbl); -static int rx_copybreak = 200; +/* + * we set our copybreak very high so that we don't have + * to allocate 16k frames all the time (see note in + * rtl8169_open() + */ +static int rx_copybreak = 16383; static int use_dac; static struct { u32 msg_enable; @@ -3217,9 +3222,13 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev) } static void rtl8169_set_rxbufsize(struct rtl8169_private *tp, - struct net_device *dev) + unsigned int mtu) { - unsigned int max_frame = dev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN; + unsigned int max_frame = mtu + VLAN_ETH_HLEN + ETH_FCS_LEN; + + if (max_frame != 16383) + printk(KERN_WARNING "WARNING! Changing of MTU on this NIC" + "May lead to frame reception errors!\n"); tp->rx_buf_sz = (max_frame > RX_BUF_SIZE) ? max_frame : RX_BUF_SIZE; } @@ -3231,7 +3240,17 @@ static int rtl8169_open(struct net_device *dev) int retval = -ENOMEM; - rtl8169_set_rxbufsize(tp, dev); + /* + * Note that we use a magic value here, its wierd I know + * its done because, some subset of rtl8169 hardware suffers from + * a problem in which frames received that are longer than + * the size set in RxMaxSize register return garbage sizes + * when received. To avoid this we need to turn off filtering, + * which is done by setting a value of 16383 in the RxMaxSize register + * and allocating 16k frames to handle the largest possible rx value + * thats what the magic math below does. + */ + rtl8169_set_rxbufsize(tp, 16383 - VLAN_ETH_HLEN - ETH_FCS_LEN); /* * Rx and Tx desscriptors needs 256 bytes alignment. @@ -3884,7 +3903,7 @@ static int rtl8169_change_mtu(struct net_device *dev, int new_mtu) rtl8169_down(dev); - rtl8169_set_rxbufsize(tp, dev); + rtl8169_set_rxbufsize(tp, dev->mtu); ret = rtl8169_init_ring(dev); if (ret < 0) -- cgit v0.10.2 From de329820e920cd9cfbc2127cad26a37026260cce Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 29 Mar 2010 14:30:19 -0700 Subject: ext3: fix broken handling of EXT3_STATE_NEW In commit 9df93939b735 ("ext3: Use bitops to read/modify EXT3_I(inode)->i_state") ext3 changed its internal 'i_state' variable to use bitops for its state handling. However, unline the same ext4 change, it didn't actually change the name of the field when it changed the semantics of it. As a result, an old use of 'i_state' remained in fs/ext3/ialloc.c that initialized the field to EXT3_STATE_NEW. And that does not work _at_all_ when we're now working with individually named bits rather than values that get masked. So the code tried to mark the state to be new, but in actual fact set the field to EXT3_STATE_JDATA. Which makes no sense at all, and screws up all the code that checks whether the inode was newly allocated. In particular, it made the xattr code unhappy, and caused various random behavior, like apparently https://bugzilla.redhat.com/show_bug.cgi?id=577911 So fix the initialization, and rename the field to match ext4 so that we don't have this happen again. Cc: James Morris Cc: Stephen Smalley Cc: Daniel J Walsh Cc: Eric Paris Cc: Jan Kara Signed-off-by: Linus Torvalds diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c index ef9008b..0d0e97e 100644 --- a/fs/ext3/ialloc.c +++ b/fs/ext3/ialloc.c @@ -582,7 +582,9 @@ got: inode->i_generation = sbi->s_next_generation++; spin_unlock(&sbi->s_next_gen_lock); - ei->i_state = EXT3_STATE_NEW; + ei->i_state_flags = 0; + ext3_set_inode_state(inode, EXT3_STATE_NEW); + ei->i_extra_isize = (EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE) ? sizeof(struct ext3_inode) - EXT3_GOOD_OLD_INODE_SIZE : 0; diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index 7f920b7..ea33bdf 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c @@ -2811,7 +2811,7 @@ struct inode *ext3_iget(struct super_block *sb, unsigned long ino) inode->i_mtime.tv_sec = (signed)le32_to_cpu(raw_inode->i_mtime); inode->i_atime.tv_nsec = inode->i_ctime.tv_nsec = inode->i_mtime.tv_nsec = 0; - ei->i_state = 0; + ei->i_state_flags = 0; ei->i_dir_start_lookup = 0; ei->i_dtime = le32_to_cpu(raw_inode->i_dtime); /* We now have enough fields to check if the inode was active or not. diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h index cac84b0..5f494b4 100644 --- a/include/linux/ext3_fs.h +++ b/include/linux/ext3_fs.h @@ -565,17 +565,17 @@ enum { static inline int ext3_test_inode_state(struct inode *inode, int bit) { - return test_bit(bit, &EXT3_I(inode)->i_state); + return test_bit(bit, &EXT3_I(inode)->i_state_flags); } static inline void ext3_set_inode_state(struct inode *inode, int bit) { - set_bit(bit, &EXT3_I(inode)->i_state); + set_bit(bit, &EXT3_I(inode)->i_state_flags); } static inline void ext3_clear_inode_state(struct inode *inode, int bit) { - clear_bit(bit, &EXT3_I(inode)->i_state); + clear_bit(bit, &EXT3_I(inode)->i_state_flags); } #else /* Assume that user mode programs are passing in an ext3fs superblock, not diff --git a/include/linux/ext3_fs_i.h b/include/linux/ext3_fs_i.h index 7679acd..f42c098 100644 --- a/include/linux/ext3_fs_i.h +++ b/include/linux/ext3_fs_i.h @@ -87,7 +87,7 @@ struct ext3_inode_info { * near to their parent directory's inode. */ __u32 i_block_group; - unsigned long i_state; /* Dynamic state flags for ext3 */ + unsigned long i_state_flags; /* Dynamic state flags for ext3 */ /* block reservation info */ struct ext3_block_alloc_info *i_block_alloc_info; -- cgit v0.10.2 From c4a3987fa075b2d15ebc3d59b01fb7ed403cd3e1 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Mon, 29 Mar 2010 22:33:28 -0700 Subject: drivers/serial/sunsu.c: Correct use after free The of_iounmap is at the out_unmap label, but at that point up has already been freed. The free cannot be moved to the out_unmap label, because that label is reachable from cases where up should not be freed. So the call to of_iounmap is just duplicated, and the goto converted to a return. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression x,e; identifier f; iterator I; statement S; @@ *kfree(x); ... when != &x when != x = e when != I(x,...) S *x->f // Signed-off-by: Julia Lawall Signed-off-by: David S. Miller diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index 170d3d6..cbcfb18 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/serial/sunsu.c @@ -1453,8 +1453,10 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m if (up->su_type == SU_PORT_KBD || up->su_type == SU_PORT_MS) { err = sunsu_kbd_ms_init(up); if (err) { + of_iounmap(&op->resource[0], + up->port.membase, up->reg_size); kfree(up); - goto out_unmap; + return err; } dev_set_drvdata(&op->dev, up); -- cgit v0.10.2 From 1f85d72d2c9c9a1d6d32cf325936bc224ad5d591 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 30 Mar 2010 07:48:05 +0200 Subject: ALSA: hda - Add missing printk argument in previous patch Signed-off-by: Takashi Iwai diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 22aea7b..ca93c4c 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -5037,7 +5037,8 @@ static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids, } if (!spec->num_adc_nids) { printk(KERN_WARNING "hda_codec: %s: no valid ADC found;" - " using fallback 0x%x\n", fallback_adc); + " using fallback 0x%x\n", + codec->chip_name, fallback_adc); spec->private_adc_nids[0] = fallback_adc; spec->adc_nids = spec->private_adc_nids; if (fallback_adc != fallback_cap) { -- cgit v0.10.2 From 570b8fb505896e007fd3bb07573ba6640e51851d Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Tue, 30 Mar 2010 00:04:00 +0100 Subject: CRED: Fix memory leak in error handling Fix a memory leak on an OOM condition in prepare_usermodehelper_creds(). Signed-off-by: Mathieu Desnoyers Signed-off-by: David Howells Signed-off-by: James Morris diff --git a/kernel/cred.c b/kernel/cred.c index 1ed8ca1..1b1129d 100644 --- a/kernel/cred.c +++ b/kernel/cred.c @@ -364,7 +364,7 @@ struct cred *prepare_usermodehelper_creds(void) new = kmem_cache_alloc(cred_jar, GFP_ATOMIC); if (!new) - return NULL; + goto free_tgcred; kdebug("prepare_usermodehelper_creds() alloc %p", new); @@ -397,6 +397,10 @@ struct cred *prepare_usermodehelper_creds(void) error: put_cred(new); +free_tgcred: +#ifdef CONFIG_KEYS + kfree(tgcred); +#endif return NULL; } -- cgit v0.10.2 From a7dc12ba756021a95866730b482c6e34b13f84ee Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Fri, 19 Mar 2010 18:16:37 +0300 Subject: imx3: Add watchdog platform device support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds support for build-in watchdog device found on Freescale imx31 and imx35 SoCs. Signed-off-by: Vladimir Zapolskiy Cc: Sascha Hauer Cc: Uwe Kleine-König Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx3/devices.c b/arch/arm/mach-mx3/devices.c index 6adb586..f891115 100644 --- a/arch/arm/mach-mx3/devices.c +++ b/arch/arm/mach-mx3/devices.c @@ -575,11 +575,26 @@ struct platform_device imx_ssi_device1 = { .resource = imx_ssi_resources1, }; -static int mx3_devices_init(void) +static struct resource imx_wdt_resources[] = { + { + .flags = IORESOURCE_MEM, + }, +}; + +struct platform_device imx_wdt_device0 = { + .name = "imx-wdt", + .id = 0, + .num_resources = ARRAY_SIZE(imx_wdt_resources), + .resource = imx_wdt_resources, +}; + +static int __init mx3_devices_init(void) { if (cpu_is_mx31()) { mxc_nand_resources[0].start = MX31_NFC_BASE_ADDR; mxc_nand_resources[0].end = MX31_NFC_BASE_ADDR + 0xfff; + imx_wdt_resources[0].start = MX31_WDOG_BASE_ADDR; + imx_wdt_resources[0].end = MX31_WDOG_BASE_ADDR + 0x3fff; mxc_register_device(&mxc_rnga_device, NULL); } if (cpu_is_mx35()) { @@ -597,6 +612,8 @@ static int mx3_devices_init(void) imx_ssi_resources0[1].end = MX35_INT_SSI1; imx_ssi_resources1[1].start = MX35_INT_SSI2; imx_ssi_resources1[1].end = MX35_INT_SSI2; + imx_wdt_resources[0].start = MX35_WDOG_BASE_ADDR; + imx_wdt_resources[0].end = MX35_WDOG_BASE_ADDR + 0x3fff; } return 0; diff --git a/arch/arm/mach-mx3/devices.h b/arch/arm/mach-mx3/devices.h index 42cf175..4f77eb5 100644 --- a/arch/arm/mach-mx3/devices.h +++ b/arch/arm/mach-mx3/devices.h @@ -25,4 +25,5 @@ extern struct platform_device mxc_spi_device1; extern struct platform_device mxc_spi_device2; extern struct platform_device imx_ssi_device0; extern struct platform_device imx_ssi_device1; - +extern struct platform_device imx_ssi_device1; +extern struct platform_device imx_wdt_device0; -- cgit v0.10.2 From 7d7a77e56744bb32b8a97a9903fd12433af1c4b2 Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Fri, 19 Mar 2010 18:16:59 +0300 Subject: imx31: add watchdog device on litekit board. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds support for SoC build-in watchdog device on litekit board. Signed-off-by: Vladimir Zapolskiy Cc: Uwe Kleine-König Cc: Sascha Hauer Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx3/mx31lite-db.c b/arch/arm/mach-mx3/mx31lite-db.c index ccd8742..0201683 100644 --- a/arch/arm/mach-mx3/mx31lite-db.c +++ b/arch/arm/mach-mx3/mx31lite-db.c @@ -206,5 +206,6 @@ void __init mx31lite_db_init(void) mxc_register_device(&mxcsdhc_device0, &mmc_pdata); mxc_register_device(&mxc_spi_device0, &spi0_pdata); platform_device_register(&litekit_led_device); + mxc_register_device(&imx_wdt_device0, NULL); } -- cgit v0.10.2 From 034cf2362af85259718c4930bc7b548fa4165c1c Mon Sep 17 00:00:00 2001 From: Andrea Gelmini Date: Thu, 25 Mar 2010 18:22:33 +0100 Subject: ARM mach-mx3: duplicated include arch/arm/mach-mx3/mach-pcm037.c: linux/fsl_devices.h is included more than once. Signed-off-by: Andrea Gelmini Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx3/mach-pcm037.c b/arch/arm/mach-mx3/mach-pcm037.c index 11f5315..a550ae9 100644 --- a/arch/arm/mach-mx3/mach-pcm037.c +++ b/arch/arm/mach-mx3/mach-pcm037.c @@ -35,7 +35,6 @@ #include #include #include -#include #include -- cgit v0.10.2 From 17669fd60e6b245945cdd4bbe87d1186a07a03b6 Mon Sep 17 00:00:00 2001 From: Andrea Gelmini Date: Thu, 25 Mar 2010 18:22:34 +0100 Subject: ARM mach-mx3: duplicated include arch/arm/mach-mx3/mx31lite-db.c: linux/platform_device.h is included more than once. Signed-off-by: Andrea Gelmini Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx3/mx31lite-db.c b/arch/arm/mach-mx3/mx31lite-db.c index 0201683..093c595 100644 --- a/arch/arm/mach-mx3/mx31lite-db.c +++ b/arch/arm/mach-mx3/mx31lite-db.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include -- cgit v0.10.2 From b3aa111f7ac1ad07009081a824b5ce7a71462c4c Mon Sep 17 00:00:00 2001 From: Alberto Panizzo Date: Fri, 26 Feb 2010 18:36:32 +0100 Subject: MXC: mach_armadillo5x0: Add USB Host support. This add USB Host capability. The Armadillo 500 board is supplied with two USB Host connectors driven by the USB OTG and USB Host 2 ports, through two NXP isp 1504 transceivers. Signed-off-by: Alberto Panizzo Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx3/Kconfig b/arch/arm/mach-mx3/Kconfig index 9a2911e..170f68e 100644 --- a/arch/arm/mach-mx3/Kconfig +++ b/arch/arm/mach-mx3/Kconfig @@ -104,6 +104,7 @@ config MACH_PCM043 config MACH_ARMADILLO5X0 bool "Support Atmark Armadillo-500 Development Base Board" select ARCH_MX31 + select MXC_ULPI if USB_ULPI help Include support for Atmark Armadillo-500 platform. This includes specific configurations for the board and its peripherals. diff --git a/arch/arm/mach-mx3/mach-armadillo5x0.c b/arch/arm/mach-mx3/mach-armadillo5x0.c index 3d72b0b..5f72ec9 100644 --- a/arch/arm/mach-mx3/mach-armadillo5x0.c +++ b/arch/arm/mach-mx3/mach-armadillo5x0.c @@ -36,6 +36,9 @@ #include #include #include +#include +#include +#include #include #include @@ -52,6 +55,8 @@ #include #include #include +#include +#include #include "devices.h" #include "crm_regs.h" @@ -103,8 +108,158 @@ static int armadillo5x0_pins[] = { /* I2C2 */ MX31_PIN_CSPI2_MOSI__SCL, MX31_PIN_CSPI2_MISO__SDA, + /* OTG */ + MX31_PIN_USBOTG_DATA0__USBOTG_DATA0, + MX31_PIN_USBOTG_DATA1__USBOTG_DATA1, + MX31_PIN_USBOTG_DATA2__USBOTG_DATA2, + MX31_PIN_USBOTG_DATA3__USBOTG_DATA3, + MX31_PIN_USBOTG_DATA4__USBOTG_DATA4, + MX31_PIN_USBOTG_DATA5__USBOTG_DATA5, + MX31_PIN_USBOTG_DATA6__USBOTG_DATA6, + MX31_PIN_USBOTG_DATA7__USBOTG_DATA7, + MX31_PIN_USBOTG_CLK__USBOTG_CLK, + MX31_PIN_USBOTG_DIR__USBOTG_DIR, + MX31_PIN_USBOTG_NXT__USBOTG_NXT, + MX31_PIN_USBOTG_STP__USBOTG_STP, + /* USB host 2 */ + IOMUX_MODE(MX31_PIN_USBH2_CLK, IOMUX_CONFIG_FUNC), + IOMUX_MODE(MX31_PIN_USBH2_DIR, IOMUX_CONFIG_FUNC), + IOMUX_MODE(MX31_PIN_USBH2_NXT, IOMUX_CONFIG_FUNC), + IOMUX_MODE(MX31_PIN_USBH2_STP, IOMUX_CONFIG_FUNC), + IOMUX_MODE(MX31_PIN_USBH2_DATA0, IOMUX_CONFIG_FUNC), + IOMUX_MODE(MX31_PIN_USBH2_DATA1, IOMUX_CONFIG_FUNC), + IOMUX_MODE(MX31_PIN_STXD3, IOMUX_CONFIG_FUNC), + IOMUX_MODE(MX31_PIN_SRXD3, IOMUX_CONFIG_FUNC), + IOMUX_MODE(MX31_PIN_SCK3, IOMUX_CONFIG_FUNC), + IOMUX_MODE(MX31_PIN_SFS3, IOMUX_CONFIG_FUNC), + IOMUX_MODE(MX31_PIN_STXD6, IOMUX_CONFIG_FUNC), + IOMUX_MODE(MX31_PIN_SRXD6, IOMUX_CONFIG_FUNC), }; +/* USB */ +#if defined(CONFIG_USB_ULPI) + +#define OTG_RESET IOMUX_TO_GPIO(MX31_PIN_STXD4) +#define USBH2_RESET IOMUX_TO_GPIO(MX31_PIN_SCK6) +#define USBH2_CS IOMUX_TO_GPIO(MX31_PIN_GPIO1_3) + +#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \ + PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU) + +static int usbotg_init(struct platform_device *pdev) +{ + int err; + + mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, USB_PAD_CFG); + + /* Chip already enabled by hardware */ + /* OTG phy reset*/ + err = gpio_request(OTG_RESET, "USB-OTG-RESET"); + if (err) { + pr_err("Failed to request the usb otg reset gpio\n"); + return err; + } + + err = gpio_direction_output(OTG_RESET, 1/*HIGH*/); + if (err) { + pr_err("Failed to reset the usb otg phy\n"); + goto otg_free_reset; + } + + gpio_set_value(OTG_RESET, 0/*LOW*/); + mdelay(5); + gpio_set_value(OTG_RESET, 1/*HIGH*/); + + return 0; + +otg_free_reset: + gpio_free(OTG_RESET); + return err; +} + +static int usbh2_init(struct platform_device *pdev) +{ + int err; + + mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_SRXD6, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_STXD6, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_SFS3, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_SCK3, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_SRXD3, USB_PAD_CFG); + mxc_iomux_set_pad(MX31_PIN_STXD3, USB_PAD_CFG); + + mxc_iomux_set_gpr(MUX_PGP_UH2, true); + + + /* Enable the chip */ + err = gpio_request(USBH2_CS, "USB-H2-CS"); + if (err) { + pr_err("Failed to request the usb host 2 CS gpio\n"); + return err; + } + + err = gpio_direction_output(USBH2_CS, 0/*Enabled*/); + if (err) { + pr_err("Failed to drive the usb host 2 CS gpio\n"); + goto h2_free_cs; + } + + /* H2 phy reset*/ + err = gpio_request(USBH2_RESET, "USB-H2-RESET"); + if (err) { + pr_err("Failed to request the usb host 2 reset gpio\n"); + goto h2_free_cs; + } + + err = gpio_direction_output(USBH2_RESET, 1/*HIGH*/); + if (err) { + pr_err("Failed to reset the usb host 2 phy\n"); + goto h2_free_reset; + } + + gpio_set_value(USBH2_RESET, 0/*LOW*/); + mdelay(5); + gpio_set_value(USBH2_RESET, 1/*HIGH*/); + + return 0; + +h2_free_reset: + gpio_free(USBH2_RESET); +h2_free_cs: + gpio_free(USBH2_CS); + return err; +} + +static struct mxc_usbh_platform_data usbotg_pdata = { + .init = usbotg_init, + .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT, + .flags = MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_INTERFACE_DIFF_UNI, +}; + +static struct mxc_usbh_platform_data usbh2_pdata = { + .init = usbh2_init, + .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT, + .flags = MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_INTERFACE_DIFF_UNI, +}; +#endif /* CONFIG_USB_ULPI */ + /* RTC over I2C*/ #define ARMADILLO5X0_RTC_GPIO IOMUX_TO_GPIO(MX31_PIN_SRXD4) @@ -393,6 +548,17 @@ static void __init armadillo5x0_init(void) if (armadillo5x0_i2c_rtc.irq == 0) pr_warning("armadillo5x0_init: failed to get RTC IRQ\n"); i2c_register_board_info(1, &armadillo5x0_i2c_rtc, 1); + + /* USB */ +#if defined(CONFIG_USB_ULPI) + usbotg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, + USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); + usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, + USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT); + + mxc_register_device(&mxc_otg_host, &usbotg_pdata); + mxc_register_device(&mxc_usbh2, &usbh2_pdata); +#endif } static void __init armadillo5x0_timer_init(void) -- cgit v0.10.2 From 57f4c226d1e095a2db20c691c3cf089188fe1c5d Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 23 Mar 2010 15:32:53 +0900 Subject: x86: don't include slab.h from arch/x86/include/asm/pgtable_32.h Including slab.h from x86 pgtable_32.h creates a troublesome dependency chain w/ ftrace enabled. The following chain leads to inclusion of pgtable_32.h from define_trace.h. trace/define_trace.h trace/ftrace.h linux/ftrace_event.h linux/ring_buffer.h linux/mm.h asm/pgtable.h asm/pgtable_32.h slab.h itself defines trace hooks via linux/sl[aou]b_def.h linux/kmemtrace.h trace/events/kmem.h If slab.h is not included before define_trace.h is included, this leads to duplicate definitions of kmemtrace hooks or other include dependency problems. pgtable_32.h doesn't need slab.h to begin with. Don't include it from there. Signed-off-by: Tejun Heo Acked-by: Pekka Enberg Acked-by: Christoph Lameter Cc: Ingo Molnar Cc: Thomas Gleixner Cc: H. Peter Anvin diff --git a/arch/x86/include/asm/pgtable_32.h b/arch/x86/include/asm/pgtable_32.h index 47339a1..2984a25 100644 --- a/arch/x86/include/asm/pgtable_32.h +++ b/arch/x86/include/asm/pgtable_32.h @@ -19,7 +19,6 @@ #include #include -#include #include #include -- cgit v0.10.2 From ed391f4ebf8f701d3566423ce8f17e614cde9806 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 23 Mar 2010 15:55:39 +0900 Subject: iwlwifi: don't include iwl-dev.h from iwl-devtrace.h iwl-devtrace.h is used to declare and define trace points and including iwl-dev.h from the file, which in turn includes other generic headers, can lead to problems like generating duplicate copies of generic trace points depending on the order of includes. Don't include iwl-dev.h from iwl-devtrace.h but include it from its users - iwl-io.h and iwl-devtrace.c. Signed-off-by: Tejun Heo Acked-by: Reinette Chatre Cc: Zhu Yi Cc: Intel Linux Wireless Cc: Ingo Molnar diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.c b/drivers/net/wireless/iwlwifi/iwl-devtrace.c index 36580d8..2ffc2ed 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.c +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.c @@ -28,6 +28,8 @@ /* sparse doesn't like tracepoint macros */ #ifndef __CHECKER__ +#include "iwl-dev.h" + #define CREATE_TRACE_POINTS #include "iwl-devtrace.h" diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h index ff4d012..ae7319b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h @@ -28,7 +28,6 @@ #define __IWLWIFI_DEVICE_TRACE #include -#include "iwl-dev.h" #if !defined(CONFIG_IWLWIFI_DEVICE_TRACING) || defined(__CHECKER__) #undef TRACE_EVENT diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h index c719baf..16eb3ce 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.h +++ b/drivers/net/wireless/iwlwifi/iwl-io.h @@ -31,6 +31,7 @@ #include +#include "iwl-dev.h" #include "iwl-debug.h" #include "iwl-devtrace.h" -- cgit v0.10.2 From 5a0e3ad6af8660be21ca98a971cd00f331318c05 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 24 Mar 2010 17:04:11 +0900 Subject: include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h percpu.h is included by sched.h and module.h and thus ends up being included when building most .c files. percpu.h includes slab.h which in turn includes gfp.h making everything defined by the two files universally available and complicating inclusion dependencies. percpu.h -> slab.h dependency is about to be removed. Prepare for this change by updating users of gfp and slab facilities include those headers directly instead of assuming availability. As this conversion needs to touch large number of source files, the following script is used as the basis of conversion. http://userweb.kernel.org/~tj/misc/slabh-sweep.py The script does the followings. * Scan files for gfp and slab usages and update includes such that only the necessary includes are there. ie. if only gfp is used, gfp.h, if slab is used, slab.h. * When the script inserts a new include, it looks at the include blocks and try to put the new include such that its order conforms to its surrounding. It's put in the include block which contains core kernel includes, in the same order that the rest are ordered - alphabetical, Christmas tree, rev-Xmas-tree or at the end if there doesn't seem to be any matching order. * If the script can't find a place to put a new include (mostly because the file doesn't have fitting include block), it prints out an error message indicating which .h file needs to be added to the file. The conversion was done in the following steps. 1. The initial automatic conversion of all .c files updated slightly over 4000 files, deleting around 700 includes and adding ~480 gfp.h and ~3000 slab.h inclusions. The script emitted errors for ~400 files. 2. Each error was manually checked. Some didn't need the inclusion, some needed manual addition while adding it to implementation .h or embedding .c file was more appropriate for others. This step added inclusions to around 150 files. 3. The script was run again and the output was compared to the edits from #2 to make sure no file was left behind. 4. Several build tests were done and a couple of problems were fixed. e.g. lib/decompress_*.c used malloc/free() wrappers around slab APIs requiring slab.h to be added manually. 5. The script was run on all .h files but without automatically editing them as sprinkling gfp.h and slab.h inclusions around .h files could easily lead to inclusion dependency hell. Most gfp.h inclusion directives were ignored as stuff from gfp.h was usually wildly available and often used in preprocessor macros. Each slab.h inclusion directive was examined and added manually as necessary. 6. percpu.h was updated not to include slab.h. 7. Build test were done on the following configurations and failures were fixed. CONFIG_GCOV_KERNEL was turned off for all tests (as my distributed build env didn't work with gcov compiles) and a few more options had to be turned off depending on archs to make things build (like ipr on powerpc/64 which failed due to missing writeq). * x86 and x86_64 UP and SMP allmodconfig and a custom test config. * powerpc and powerpc64 SMP allmodconfig * sparc and sparc64 SMP allmodconfig * ia64 SMP allmodconfig * s390 SMP allmodconfig * alpha SMP allmodconfig * um on x86_64 SMP allmodconfig 8. percpu.h modifications were reverted so that it could be applied as a separate patch and serve as bisection point. Given the fact that I had only a couple of failures from tests on step 6, I'm fairly confident about the coverage of this conversion patch. If there is a breakage, it's likely to be something in one of the arch headers which should be easily discoverable easily on most builds of the specific arch. Signed-off-by: Tejun Heo Guess-its-ok-by: Christoph Lameter Cc: Ingo Molnar Cc: Lee Schermerhorn diff --git a/Documentation/connector/cn_test.c b/Documentation/connector/cn_test.c index b07add3..7764594 100644 --- a/Documentation/connector/cn_test.c +++ b/Documentation/connector/cn_test.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include diff --git a/arch/alpha/boot/bootp.c b/arch/alpha/boot/bootp.c index 3c8d1b2..be61670 100644 --- a/arch/alpha/boot/bootp.c +++ b/arch/alpha/boot/bootp.c @@ -8,6 +8,7 @@ * based significantly on the arch/alpha/boot/main.c of Linus Torvalds */ #include +#include #include #include #include diff --git a/arch/alpha/boot/bootpz.c b/arch/alpha/boot/bootpz.c index ade3f12..c98865f 100644 --- a/arch/alpha/boot/bootpz.c +++ b/arch/alpha/boot/bootpz.c @@ -10,6 +10,7 @@ * and the decompression code from MILO. */ #include +#include #include #include #include diff --git a/arch/alpha/boot/main.c b/arch/alpha/boot/main.c index 644b7db5..ded57d9 100644 --- a/arch/alpha/boot/main.c +++ b/arch/alpha/boot/main.c @@ -6,6 +6,7 @@ * This file is the bootloader for the Linux/AXP kernel */ #include +#include #include #include #include diff --git a/arch/alpha/boot/misc.c b/arch/alpha/boot/misc.c index 3047a1b..3ff9a95 100644 --- a/arch/alpha/boot/misc.c +++ b/arch/alpha/boot/misc.c @@ -19,6 +19,7 @@ */ #include +#include #include diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c index 5f2cf23..7f912ba 100644 --- a/arch/alpha/kernel/irq.c +++ b/arch/alpha/kernel/irq.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index 53c213f..de9d397 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -37,6 +36,7 @@ #include #include #include +#include #include #include diff --git a/arch/alpha/kernel/pci-noop.c b/arch/alpha/kernel/pci-noop.c index 823a540..246100e 100644 --- a/arch/alpha/kernel/pci-noop.c +++ b/arch/alpha/kernel/pci-noop.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/alpha/kernel/pci-sysfs.c b/arch/alpha/kernel/pci-sysfs.c index 6ea822e..d979e7c 100644 --- a/arch/alpha/kernel/pci-sysfs.c +++ b/arch/alpha/kernel/pci-sysfs.c @@ -10,6 +10,7 @@ */ #include +#include #include static int hose_mmap_page_range(struct pci_controller *hose, diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c index ce9e54c..d1dbd9a 100644 --- a/arch/alpha/kernel/pci_iommu.c +++ b/arch/alpha/kernel/pci_iommu.c @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c index 289039bb..395a464 100644 --- a/arch/alpha/kernel/process.c +++ b/arch/alpha/kernel/process.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -28,6 +27,7 @@ #include #include #include +#include #include #include diff --git a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c index 9acadc6..baa9036 100644 --- a/arch/alpha/kernel/ptrace.c +++ b/arch/alpha/kernel/ptrace.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include diff --git a/arch/alpha/kernel/smc37c669.c b/arch/alpha/kernel/smc37c669.c index bca5bda..0435921d 100644 --- a/arch/alpha/kernel/smc37c669.c +++ b/arch/alpha/kernel/smc37c669.c @@ -3,7 +3,6 @@ */ #include -#include #include #include #include diff --git a/arch/alpha/kernel/smc37c93x.c b/arch/alpha/kernel/smc37c93x.c index 2636cc0..3e6a289 100644 --- a/arch/alpha/kernel/smc37c93x.c +++ b/arch/alpha/kernel/smc37c93x.c @@ -4,7 +4,6 @@ #include -#include #include #include #include diff --git a/arch/alpha/kernel/srm_env.c b/arch/alpha/kernel/srm_env.c index dbbf04f..4afc1a1 100644 --- a/arch/alpha/kernel/srm_env.c +++ b/arch/alpha/kernel/srm_env.c @@ -30,6 +30,7 @@ */ #include +#include #include #include #include diff --git a/arch/alpha/mm/init.c b/arch/alpha/mm/init.c index a0902c2..86425ab 100644 --- a/arch/alpha/mm/init.c +++ b/arch/alpha/mm/init.c @@ -20,6 +20,7 @@ #include #include /* max_low_pfn */ #include +#include #include #include diff --git a/arch/arm/common/clkdev.c b/arch/arm/common/clkdev.c index 6416d5b..dba4c1d 100644 --- a/arch/arm/common/clkdev.c +++ b/arch/arm/common/clkdev.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c index ee1d3b8..7974baa 100644 --- a/arch/arm/common/it8152.c +++ b/arch/arm/common/it8152.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index b7cb45b..3b3d2c8 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/arm/kernel/kprobes.c b/arch/arm/kernel/kprobes.c index 60c62c3..1fb932b 100644 --- a/arch/arm/kernel/kprobes.c +++ b/arch/arm/kernel/kprobes.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c index f28c5e9..c628bdf 100644 --- a/arch/arm/kernel/module.c +++ b/arch/arm/kernel/module.c @@ -16,9 +16,9 @@ #include #include #include -#include #include #include +#include #include #include diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index ba2adef..0e12e0a 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c index 4350f75..c235018 100644 --- a/arch/arm/kernel/sys_arm.c +++ b/arch/arm/kernel/sys_arm.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -27,6 +26,7 @@ #include #include #include +#include /* Fork a new task - this creates a new program thread. * This is called indirectly via a small wrapper diff --git a/arch/arm/lib/uaccess_with_memcpy.c b/arch/arm/lib/uaccess_with_memcpy.c index 6b967ff..e2d2f2c 100644 --- a/arch/arm/lib/uaccess_with_memcpy.c +++ b/arch/arm/lib/uaccess_with_memcpy.c @@ -16,6 +16,7 @@ #include #include #include /* for in_atomic() */ +#include #include #include diff --git a/arch/arm/mach-aaec2000/core.c b/arch/arm/mach-aaec2000/core.c index b5c5fc6b..3ef6833 100644 --- a/arch/arm/mach-aaec2000/core.c +++ b/arch/arm/mach-aaec2000/core.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/mach-bcmring/dma.c b/arch/arm/mach-bcmring/dma.c index 7b20fcc..2ccf670 100644 --- a/arch/arm/mach-bcmring/dma.c +++ b/arch/arm/mach-bcmring/dma.c @@ -28,6 +28,7 @@ #include #include #include +#include #include diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c index d15bece..df4ab21 100644 --- a/arch/arm/mach-davinci/board-dm365-evm.c +++ b/arch/arm/mach-davinci/board-dm365-evm.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/mach-davinci/dma.c index 15dd886..02d9398 100644 --- a/arch/arm/mach-davinci/dma.c +++ b/arch/arm/mach-davinci/dma.c @@ -23,6 +23,7 @@ #include #include #include +#include #include diff --git a/arch/arm/mach-h720x/common.c b/arch/arm/mach-h720x/common.c index 7a26148..bdb3f67 100644 --- a/arch/arm/mach-h720x/common.c +++ b/arch/arm/mach-h720x/common.c @@ -14,7 +14,6 @@ */ #include -#include #include #include #include diff --git a/arch/arm/mach-integrator/cpu.c b/arch/arm/mach-integrator/cpu.c index 44d4c2e..f77f202 100644 --- a/arch/arm/mach-integrator/cpu.c +++ b/arch/arm/mach-integrator/cpu.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c index 0058c93..41b1072 100644 --- a/arch/arm/mach-integrator/impd1.c +++ b/arch/arm/mach-integrator/impd1.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index 66ef86d..15e6cc5 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -21,6 +20,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c index 148d25f..ffbd349 100644 --- a/arch/arm/mach-integrator/pci_v3.c +++ b/arch/arm/mach-integrator/pci_v3.c @@ -22,7 +22,6 @@ */ #include #include -#include #include #include #include diff --git a/arch/arm/mach-iop13xx/pci.c b/arch/arm/mach-iop13xx/pci.c index 4873f26..6d5a908 100644 --- a/arch/arm/mach-iop13xx/pci.c +++ b/arch/arm/mach-iop13xx/pci.c @@ -18,6 +18,7 @@ */ #include +#include #include #include #include diff --git a/arch/arm/mach-iop32x/glantank.c b/arch/arm/mach-iop32x/glantank.c index 93370a4..10384fc 100644 --- a/arch/arm/mach-iop32x/glantank.c +++ b/arch/arm/mach-iop32x/glantank.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/arm/mach-iop32x/iq31244.c b/arch/arm/mach-iop32x/iq31244.c index a7a08dd..d6ac85f 100644 --- a/arch/arm/mach-iop32x/iq31244.c +++ b/arch/arm/mach-iop32x/iq31244.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/arm/mach-iop32x/iq80321.c b/arch/arm/mach-iop32x/iq80321.c index 0200f80..c6a0e4e 100644 --- a/arch/arm/mach-iop32x/iq80321.c +++ b/arch/arm/mach-iop32x/iq80321.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/arm/mach-iop32x/n2100.c b/arch/arm/mach-iop32x/n2100.c index 2a5c6376..5d99039 100644 --- a/arch/arm/mach-iop32x/n2100.c +++ b/arch/arm/mach-iop32x/n2100.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/arm/mach-iop33x/iq80331.c b/arch/arm/mach-iop33x/iq80331.c index 394e95a..c6ff552 100644 --- a/arch/arm/mach-iop33x/iq80331.c +++ b/arch/arm/mach-iop33x/iq80331.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/arm/mach-iop33x/iq80332.c b/arch/arm/mach-iop33x/iq80332.c index a40badf..fbf55140 100644 --- a/arch/arm/mach-iop33x/iq80332.c +++ b/arch/arm/mach-iop33x/iq80332.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/arm/mach-ixp2000/enp2611.c b/arch/arm/mach-ixp2000/enp2611.c index c84dfac..1a557e0 100644 --- a/arch/arm/mach-ixp2000/enp2611.c +++ b/arch/arm/mach-ixp2000/enp2611.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/arm/mach-ixp2000/ixdp2400.c b/arch/arm/mach-ixp2000/ixdp2400.c index 4467c42..55e5c69 100644 --- a/arch/arm/mach-ixp2000/ixdp2400.c +++ b/arch/arm/mach-ixp2000/ixdp2400.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-ixp2000/ixdp2800.c b/arch/arm/mach-ixp2000/ixdp2800.c index 94f68ba..237b61a 100644 --- a/arch/arm/mach-ixp2000/ixdp2800.c +++ b/arch/arm/mach-ixp2000/ixdp2800.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-ixp2000/ixdp2x00.c b/arch/arm/mach-ixp2000/ixdp2x00.c index 3045130..91fffb9 100644 --- a/arch/arm/mach-ixp2000/ixdp2x00.c +++ b/arch/arm/mach-ixp2000/ixdp2x00.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-ixp2000/ixdp2x01.c b/arch/arm/mach-ixp2000/ixdp2x01.c index 4a12327..0369ec4 100644 --- a/arch/arm/mach-ixp2000/ixdp2x01.c +++ b/arch/arm/mach-ixp2000/ixdp2x01.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/arm/mach-ixp2000/pci.c b/arch/arm/mach-ixp2000/pci.c index 60e9fd0..90771ca 100644 --- a/arch/arm/mach-ixp2000/pci.c +++ b/arch/arm/mach-ixp2000/pci.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-ixp23xx/pci.c b/arch/arm/mach-ixp23xx/pci.c index 59022be..4b0e598 100644 --- a/arch/arm/mach-ixp23xx/pci.c +++ b/arch/arm/mach-ixp23xx/pci.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-ixp4xx/avila-setup.c b/arch/arm/mach-ixp4xx/avila-setup.c index 6e558a7..d8bc86d 100644 --- a/arch/arm/mach-ixp4xx/avila-setup.c +++ b/arch/arm/mach-ixp4xx/avila-setup.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/arm/mach-ixp4xx/coyote-setup.c b/arch/arm/mach-ixp4xx/coyote-setup.c index 25bf5ad..31a47f6 100644 --- a/arch/arm/mach-ixp4xx/coyote-setup.c +++ b/arch/arm/mach-ixp4xx/coyote-setup.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-ixp4xx/gateway7001-setup.c b/arch/arm/mach-ixp4xx/gateway7001-setup.c index 59b73a0..2583b2a 100644 --- a/arch/arm/mach-ixp4xx/gateway7001-setup.c +++ b/arch/arm/mach-ixp4xx/gateway7001-setup.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-ixp4xx/gtwx5715-setup.c b/arch/arm/mach-ixp4xx/gtwx5715-setup.c index 0bc7185..c67586b 100644 --- a/arch/arm/mach-ixp4xx/gtwx5715-setup.c +++ b/arch/arm/mach-ixp4xx/gtwx5715-setup.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c index bbb7689..827cbc4 100644 --- a/arch/arm/mach-ixp4xx/ixdp425-setup.c +++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/arm/mach-ixp4xx/ixp4xx_npe.c b/arch/arm/mach-ixp4xx/ixp4xx_npe.c index e8bb257..a17ed79 100644 --- a/arch/arm/mach-ixp4xx/ixp4xx_npe.c +++ b/arch/arm/mach-ixp4xx/ixp4xx_npe.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #define DEBUG_MSG 0 diff --git a/arch/arm/mach-ixp4xx/wg302v2-setup.c b/arch/arm/mach-ixp4xx/wg302v2-setup.c index 7ea7820..4dd7486 100644 --- a/arch/arm/mach-ixp4xx/wg302v2-setup.c +++ b/arch/arm/mach-ixp4xx/wg302v2-setup.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c index a604b2a..dee1eff 100644 --- a/arch/arm/mach-kirkwood/pcie.c +++ b/arch/arm/mach-kirkwood/pcie.c @@ -10,6 +10,7 @@ #include #include +#include #include #include #include diff --git a/arch/arm/mach-lh7a40x/clcd.c b/arch/arm/mach-lh7a40x/clcd.c index c472b9e..7fe4fd3 100644 --- a/arch/arm/mach-lh7a40x/clcd.c +++ b/arch/arm/mach-lh7a40x/clcd.c @@ -10,6 +10,7 @@ */ #include +#include #include #include #include diff --git a/arch/arm/mach-mx3/mach-mx31moboard.c b/arch/arm/mach-mx3/mach-mx31moboard.c index a7dc519..fccb920 100644 --- a/arch/arm/mach-mx3/mach-mx31moboard.c +++ b/arch/arm/mach-mx3/mach-mx31moboard.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/arm/mach-mx3/mach-pcm037.c b/arch/arm/mach-mx3/mach-pcm037.c index 11f5315..034ec81 100644 --- a/arch/arm/mach-mx3/mach-pcm037.c +++ b/arch/arm/mach-mx3/mach-pcm037.c @@ -36,6 +36,7 @@ #include #include #include +#include #include diff --git a/arch/arm/mach-mx3/mx31moboard-devboard.c b/arch/arm/mach-mx3/mx31moboard-devboard.c index 9fbad2e..11b906c 100644 --- a/arch/arm/mach-mx3/mx31moboard-devboard.c +++ b/arch/arm/mach-mx3/mx31moboard-devboard.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/mach-mx3/mx31moboard-marxbot.c b/arch/arm/mach-mx3/mx31moboard-marxbot.c index 3958515..ffb105e 100644 --- a/arch/arm/mach-mx3/mx31moboard-marxbot.c +++ b/arch/arm/mach-mx3/mx31moboard-marxbot.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/mach-netx/fb.c b/arch/arm/mach-netx/fb.c index 1d844e2..5b84bcd 100644 --- a/arch/arm/mach-netx/fb.c +++ b/arch/arm/mach-netx/fb.c @@ -23,6 +23,7 @@ #include #include #include +#include #include diff --git a/arch/arm/mach-netx/xc.c b/arch/arm/mach-netx/xc.c index 181a78b..f009b54 100644 --- a/arch/arm/mach-netx/xc.c +++ b/arch/arm/mach-netx/xc.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/mach-nomadik/gpio.c b/arch/arm/mach-nomadik/gpio.c index 9a09b27..66b1c91 100644 --- a/arch/arm/mach-nomadik/gpio.c +++ b/arch/arm/mach-nomadik/gpio.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/mach-ns9xxx/plat-serial8250.c b/arch/arm/mach-ns9xxx/plat-serial8250.c index 795b15e..463e924 100644 --- a/arch/arm/mach-ns9xxx/plat-serial8250.c +++ b/arch/arm/mach-ns9xxx/plat-serial8250.c @@ -10,6 +10,7 @@ */ #include #include +#include #include #include diff --git a/arch/arm/mach-ns9xxx/processor-ns9360.c b/arch/arm/mach-ns9xxx/processor-ns9360.c index abee833..aed1999 100644 --- a/arch/arm/mach-ns9xxx/processor-ns9360.c +++ b/arch/arm/mach-ns9xxx/processor-ns9360.c @@ -10,7 +10,6 @@ */ #include #include -#include #include #include diff --git a/arch/arm/mach-omap1/mcbsp.c b/arch/arm/mach-omap1/mcbsp.c index f9a5cf7..e9bdff1 100644 --- a/arch/arm/mach-omap1/mcbsp.c +++ b/arch/arm/mach-omap1/mcbsp.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c index 3b1eac4..e60ca4e 100644 --- a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c +++ b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/mach-omap2/iommu2.c b/arch/arm/mach-omap2/iommu2.c index 6f4b7cc..4f63dc6 100644 --- a/arch/arm/mach-omap2/iommu2.c +++ b/arch/arm/mach-omap2/iommu2.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c index be8fce3..2f3cad6 100644 --- a/arch/arm/mach-omap2/mcbsp.c +++ b/arch/arm/mach-omap2/mcbsp.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c index b4ca84e..8b3d269 100644 --- a/arch/arm/mach-omap2/mux.c +++ b/arch/arm/mach-omap2/mux.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c index c18f7f2..6cac981 100644 --- a/arch/arm/mach-omap2/pm-debug.c +++ b/arch/arm/mach-omap2/pm-debug.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index fee2efb..ea0000b 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/mach-orion5x/pci.c b/arch/arm/mach-orion5x/pci.c index bdf96eb..e8706f1 100644 --- a/arch/arm/mach-orion5x/pci.c +++ b/arch/arm/mach-orion5x/pci.c @@ -12,6 +12,7 @@ #include #include +#include #include #include #include diff --git a/arch/arm/mach-pnx4008/dma.c b/arch/arm/mach-pnx4008/dma.c index 425f718..7fa4bf2 100644 --- a/arch/arm/mach-pnx4008/dma.c +++ b/arch/arm/mach-pnx4008/dma.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/mach-pnx4008/pm.c b/arch/arm/mach-pnx4008/pm.c index 1f05853..ee3c29c 100644 --- a/arch/arm/mach-pnx4008/pm.c +++ b/arch/arm/mach-pnx4008/pm.c @@ -19,6 +19,7 @@ #include #include #include +#include #include diff --git a/arch/arm/mach-pxa/corgi_ssp.c b/arch/arm/mach-pxa/corgi_ssp.c index 1d9bc11..9347254 100644 --- a/arch/arm/mach-pxa/corgi_ssp.c +++ b/arch/arm/mach-pxa/corgi_ssp.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/arm/mach-pxa/cpufreq-pxa3xx.c b/arch/arm/mach-pxa/cpufreq-pxa3xx.c index 149cdd9..27fa329 100644 --- a/arch/arm/mach-pxa/cpufreq-pxa3xx.c +++ b/arch/arm/mach-pxa/cpufreq-pxa3xx.c @@ -14,6 +14,7 @@ #include #include #include +#include #include diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c index 843fcca..7a50ed8 100644 --- a/arch/arm/mach-pxa/mioa701.c +++ b/arch/arm/mach-pxa/mioa701.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c index 7693355..166c15f 100644 --- a/arch/arm/mach-pxa/pm.c +++ b/arch/arm/mach-pxa/pm.c @@ -14,6 +14,7 @@ #include #include #include +#include #include diff --git a/arch/arm/mach-pxa/viper.c b/arch/arm/mach-pxa/viper.c index 1dd1334..9e0c5c3 100644 --- a/arch/arm/mach-pxa/viper.c +++ b/arch/arm/mach-pxa/viper.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index 90bd4ef..f2dbce5 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/mach-rpc/dma.c b/arch/arm/mach-rpc/dma.c index c47d974..85883b2 100644 --- a/arch/arm/mach-rpc/dma.c +++ b/arch/arm/mach-rpc/dma.c @@ -9,7 +9,6 @@ * * DMA functions specific to RiscPC architecture */ -#include #include #include #include diff --git a/arch/arm/mach-s3c64xx/dma.c b/arch/arm/mach-s3c64xx/dma.c index b62bdf1..33ccf7b 100644 --- a/arch/arm/mach-s3c64xx/dma.c +++ b/arch/arm/mach-s3c64xx/dma.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/arm/mach-sa1100/jornada720_ssp.c b/arch/arm/mach-sa1100/jornada720_ssp.c index 9b6dee5..9d490c6 100644 --- a/arch/arm/mach-sa1100/jornada720_ssp.c +++ b/arch/arm/mach-sa1100/jornada720_ssp.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c index 0b505d9..c601a75 100644 --- a/arch/arm/mach-sa1100/neponset.c +++ b/arch/arm/mach-sa1100/neponset.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-u300/dummyspichip.c b/arch/arm/mach-u300/dummyspichip.c index 962f9de..5f55012 100644 --- a/arch/arm/mach-u300/dummyspichip.c +++ b/arch/arm/mach-u300/dummyspichip.c @@ -15,6 +15,7 @@ #include #include #include +#include /* * WARNING! Do not include this pl022-specific controller header * for any generic driver. It is only done in this dummy chip diff --git a/arch/arm/mach-u300/mmc.c b/arch/arm/mach-u300/mmc.c index 109f5a6..77fbb1e 100644 --- a/arch/arm/mach-u300/mmc.c +++ b/arch/arm/mach-u300/mmc.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "mmc.h" #include "padmux.h" diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index 9ddb49b..3b1a4ee 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/mach-versatile/pci.c b/arch/arm/mach-versatile/pci.c index 7161ba2..334f0df 100644 --- a/arch/arm/mach-versatile/pci.c +++ b/arch/arm/mach-versatile/pci.c @@ -16,7 +16,6 @@ */ #include #include -#include #include #include #include diff --git a/arch/arm/mach-w90x900/dev.c b/arch/arm/mach-w90x900/dev.c index 4887612..e2958eb 100644 --- a/arch/arm/mach-w90x900/dev.c +++ b/arch/arm/mach-w90x900/dev.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 0da7ecc..1351edc 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -11,7 +11,7 @@ */ #include #include -#include +#include #include #include #include diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c index c9b97e9..0d414c2 100644 --- a/arch/arm/mm/fault-armv.c +++ b/arch/arm/mm/fault-armv.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 7829cb5..83db12a 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/mm/pgd.c b/arch/arm/mm/pgd.c index 2690146..be5f58e 100644 --- a/arch/arm/mm/pgd.c +++ b/arch/arm/mm/pgd.c @@ -8,6 +8,7 @@ * published by the Free Software Foundation. */ #include +#include #include #include diff --git a/arch/arm/plat-mxc/audmux-v2.c b/arch/arm/plat-mxc/audmux-v2.c index d983cd6..0c2cc5c 100644 --- a/arch/arm/plat-mxc/audmux-v2.c +++ b/arch/arm/plat-mxc/audmux-v2.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/plat-mxc/pwm.c b/arch/arm/plat-mxc/pwm.c index 4ff6dfe..c36f263 100644 --- a/arch/arm/plat-mxc/pwm.c +++ b/arch/arm/plat-mxc/pwm.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c index 4a4cd87..95677d1 100644 --- a/arch/arm/plat-omap/devices.c +++ b/arch/arm/plat-omap/devices.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index 2ab224c..5c6c342 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/plat-omap/iommu-debug.c b/arch/arm/plat-omap/iommu-debug.c index afd1c27..e6c0d53 100644 --- a/arch/arm/plat-omap/iommu-debug.c +++ b/arch/arm/plat-omap/iommu-debug.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c index 905ed83..0e13766 100644 --- a/arch/arm/plat-omap/iommu.c +++ b/arch/arm/plat-omap/iommu.c @@ -13,6 +13,7 @@ #include #include +#include #include #include #include diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c index 936aef1..65c6d1f 100644 --- a/arch/arm/plat-omap/iovmm.c +++ b/arch/arm/plat-omap/iovmm.c @@ -11,6 +11,7 @@ */ #include +#include #include #include #include diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index 4229cec..08a2df7 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -25,6 +25,7 @@ #include #include #include +#include #include diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index 52dfcc8..e1d0440 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c index 5904358..0f51974 100644 --- a/arch/arm/plat-omap/omap_device.c +++ b/arch/arm/plat-omap/omap_device.c @@ -79,6 +79,7 @@ #include #include +#include #include #include diff --git a/arch/arm/plat-pxa/dma.c b/arch/arm/plat-pxa/dma.c index 2975798..742350e 100644 --- a/arch/arm/plat-pxa/dma.c +++ b/arch/arm/plat-pxa/dma.c @@ -14,6 +14,7 @@ #include #include +#include #include #include #include diff --git a/arch/arm/plat-pxa/pwm.c b/arch/arm/plat-pxa/pwm.c index 51dc5c8..0732c6c 100644 --- a/arch/arm/plat-pxa/pwm.c +++ b/arch/arm/plat-pxa/pwm.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/arm/plat-s3c24xx/cpu-freq.c b/arch/arm/plat-s3c24xx/cpu-freq.c index 2d42efb..1ecc15b 100644 --- a/arch/arm/plat-s3c24xx/cpu-freq.c +++ b/arch/arm/plat-s3c24xx/cpu-freq.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/plat-s3c24xx/devs.c b/arch/arm/plat-s3c24xx/devs.c index 8c6de1c..9265f09 100644 --- a/arch/arm/plat-s3c24xx/devs.c +++ b/arch/arm/plat-s3c24xx/devs.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/plat-s3c24xx/s3c2410-iotiming.c b/arch/arm/plat-s3c24xx/s3c2410-iotiming.c index 963fb0b..b1908e5 100644 --- a/arch/arm/plat-s3c24xx/s3c2410-iotiming.c +++ b/arch/arm/plat-s3c24xx/s3c2410-iotiming.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/plat-s3c24xx/s3c2412-iotiming.c b/arch/arm/plat-s3c24xx/s3c2412-iotiming.c index 24993dc..0b46d38 100644 --- a/arch/arm/plat-s3c24xx/s3c2412-iotiming.c +++ b/arch/arm/plat-s3c24xx/s3c2412-iotiming.c @@ -21,6 +21,7 @@ #include #include #include +#include #include diff --git a/arch/arm/plat-samsung/adc.c b/arch/arm/plat-samsung/adc.c index 0b5833b..210030d 100644 --- a/arch/arm/plat-samsung/adc.c +++ b/arch/arm/plat-samsung/adc.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/arm/plat-samsung/dev-fb.c b/arch/arm/plat-samsung/dev-fb.c index a90198f..002a15f 100644 --- a/arch/arm/plat-samsung/dev-fb.c +++ b/arch/arm/plat-samsung/dev-fb.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/plat-samsung/dev-i2c0.c b/arch/arm/plat-samsung/dev-i2c0.c index 4c76152..3a601c1 100644 --- a/arch/arm/plat-samsung/dev-i2c0.c +++ b/arch/arm/plat-samsung/dev-i2c0.c @@ -11,6 +11,7 @@ * published by the Free Software Foundation. */ +#include #include #include #include diff --git a/arch/arm/plat-samsung/dev-i2c1.c b/arch/arm/plat-samsung/dev-i2c1.c index d44f791..858ee2a 100644 --- a/arch/arm/plat-samsung/dev-i2c1.c +++ b/arch/arm/plat-samsung/dev-i2c1.c @@ -11,6 +11,7 @@ * published by the Free Software Foundation. */ +#include #include #include #include diff --git a/arch/arm/plat-samsung/dev-nand.c b/arch/arm/plat-samsung/dev-nand.c index a52fb6c..3a7b889 100644 --- a/arch/arm/plat-samsung/dev-nand.c +++ b/arch/arm/plat-samsung/dev-nand.c @@ -6,6 +6,7 @@ * published by the Free Software Foundation. */ +#include #include #include diff --git a/arch/arm/plat-samsung/dev-usb.c b/arch/arm/plat-samsung/dev-usb.c index 8816565..0e0a3bf 100644 --- a/arch/arm/plat-samsung/dev-usb.c +++ b/arch/arm/plat-samsung/dev-usb.c @@ -11,6 +11,7 @@ * published by the Free Software Foundation. */ +#include #include #include #include diff --git a/arch/arm/plat-samsung/pm-check.c b/arch/arm/plat-samsung/pm-check.c index 0b5bb77..e4baf76 100644 --- a/arch/arm/plat-samsung/pm-check.c +++ b/arch/arm/plat-samsung/pm-check.c @@ -17,6 +17,7 @@ #include #include #include +#include #include diff --git a/arch/arm/plat-samsung/pwm.c b/arch/arm/plat-samsung/pwm.c index f2d1139..2eeb49f 100644 --- a/arch/arm/plat-samsung/pwm.c +++ b/arch/arm/plat-samsung/pwm.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/arm/plat-stmp3xxx/dma.c b/arch/arm/plat-stmp3xxx/dma.c index ef88f25..b4dcf8c 100644 --- a/arch/arm/plat-stmp3xxx/dma.c +++ b/arch/arm/plat-stmp3xxx/dma.c @@ -15,6 +15,7 @@ * http://www.opensource.org/licenses/gpl-license.html * http://www.gnu.org/copyleft/gpl.html */ +#include #include #include #include diff --git a/arch/avr32/kernel/process.c b/arch/avr32/kernel/process.c index 93c0342..2d76515 100644 --- a/arch/avr32/kernel/process.c +++ b/arch/avr32/kernel/process.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c index 3a4bc1a..e67c999 100644 --- a/arch/avr32/mach-at32ap/at32ap700x.c +++ b/arch/avr32/mach-at32ap/at32ap700x.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/avr32/mach-at32ap/extint.c b/arch/avr32/mach-at32ap/extint.c index 310477b..e9d1205 100644 --- a/arch/avr32/mach-at32ap/extint.c +++ b/arch/avr32/mach-at32ap/extint.c @@ -14,6 +14,7 @@ #include #include #include +#include #include diff --git a/arch/avr32/mach-at32ap/hsmc.c b/arch/avr32/mach-at32ap/hsmc.c index 2875c11..f7672d3 100644 --- a/arch/avr32/mach-at32ap/hsmc.c +++ b/arch/avr32/mach-at32ap/hsmc.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include diff --git a/arch/avr32/mm/dma-coherent.c b/arch/avr32/mm/dma-coherent.c index 6d8c794..3c00422 100644 --- a/arch/avr32/mm/dma-coherent.c +++ b/arch/avr32/mm/dma-coherent.c @@ -7,6 +7,7 @@ */ #include +#include #include #include diff --git a/arch/avr32/mm/init.c b/arch/avr32/mm/init.c index 9492564..a7314d4 100644 --- a/arch/avr32/mm/init.c +++ b/arch/avr32/mm/init.c @@ -7,6 +7,7 @@ */ #include +#include #include #include #include diff --git a/arch/avr32/mm/ioremap.c b/arch/avr32/mm/ioremap.c index f03b79f..7def0d8 100644 --- a/arch/avr32/mm/ioremap.c +++ b/arch/avr32/mm/ioremap.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include diff --git a/arch/blackfin/include/asm/mmu_context.h b/arch/blackfin/include/asm/mmu_context.h index 7f363d7..e1a9b46 100644 --- a/arch/blackfin/include/asm/mmu_context.h +++ b/arch/blackfin/include/asm/mmu_context.h @@ -7,7 +7,7 @@ #ifndef __BLACKFIN_MMU_CONTEXT_H__ #define __BLACKFIN_MMU_CONTEXT_H__ -#include +#include #include #include #include diff --git a/arch/blackfin/kernel/ipipe.c b/arch/blackfin/kernel/ipipe.c index a77307a..1a496cd 100644 --- a/arch/blackfin/kernel/ipipe.c +++ b/arch/blackfin/kernel/ipipe.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c index 29705ce..93ec07d 100644 --- a/arch/blackfin/kernel/process.c +++ b/arch/blackfin/kernel/process.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c index 8837be4..c1f1ccc8 100644 --- a/arch/blackfin/mach-common/pm.c +++ b/arch/blackfin/mach-common/pm.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c index 7803f22..7cecbaf 100644 --- a/arch/blackfin/mach-common/smp.c +++ b/arch/blackfin/mach-common/smp.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/blackfin/mm/init.c b/arch/blackfin/mm/init.c index bb9c98f..355b87a 100644 --- a/arch/blackfin/mm/init.c +++ b/arch/blackfin/mm/init.c @@ -4,6 +4,7 @@ * Licensed under the GPL-2 or later. */ +#include #include #include #include diff --git a/arch/blackfin/mm/isram-driver.c b/arch/blackfin/mm/isram-driver.c index 9213e23..39b05856 100644 --- a/arch/blackfin/mm/isram-driver.c +++ b/arch/blackfin/mm/isram-driver.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include diff --git a/arch/blackfin/mm/sram-alloc.c b/arch/blackfin/mm/sram-alloc.c index 5732da2..49b2ff2 100644 --- a/arch/blackfin/mm/sram-alloc.c +++ b/arch/blackfin/mm/sram-alloc.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include "blackfin_sram.h" diff --git a/arch/cris/arch-v10/drivers/i2c.c b/arch/cris/arch-v10/drivers/i2c.c index 7f656ae..a8737a8 100644 --- a/arch/cris/arch-v10/drivers/i2c.c +++ b/arch/cris/arch-v10/drivers/i2c.c @@ -14,7 +14,6 @@ #include #include -#include #include #include #include diff --git a/arch/cris/arch-v10/drivers/sync_serial.c b/arch/cris/arch-v10/drivers/sync_serial.c index 562b9a7f..109dcd8 100644 --- a/arch/cris/arch-v10/drivers/sync_serial.c +++ b/arch/cris/arch-v10/drivers/sync_serial.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/cris/arch-v10/kernel/process.c b/arch/cris/arch-v10/kernel/process.c index c4c69cf..93f0f64 100644 --- a/arch/cris/arch-v10/kernel/process.c +++ b/arch/cris/arch-v10/kernel/process.c @@ -11,9 +11,9 @@ */ #include +#include #include #include -#include #include #include diff --git a/arch/cris/arch-v32/drivers/i2c.c b/arch/cris/arch-v32/drivers/i2c.c index 179e7b8..5068263 100644 --- a/arch/cris/arch-v32/drivers/i2c.c +++ b/arch/cris/arch-v32/drivers/i2c.c @@ -27,7 +27,6 @@ #include #include -#include #include #include #include diff --git a/arch/cris/arch-v32/drivers/pci/dma.c b/arch/cris/arch-v32/drivers/pci/dma.c index fbe6595..ee55578 100644 --- a/arch/cris/arch-v32/drivers/pci/dma.c +++ b/arch/cris/arch-v32/drivers/pci/dma.c @@ -13,6 +13,7 @@ #include #include #include +#include #include void *dma_alloc_coherent(struct device *dev, size_t size, diff --git a/arch/cris/arch-v32/drivers/sync_serial.c b/arch/cris/arch-v32/drivers/sync_serial.c index d2a0fbf..4889f19 100644 --- a/arch/cris/arch-v32/drivers/sync_serial.c +++ b/arch/cris/arch-v32/drivers/sync_serial.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/cris/arch-v32/kernel/process.c b/arch/cris/arch-v32/kernel/process.c index 120e7f7..2661a95 100644 --- a/arch/cris/arch-v32/kernel/process.c +++ b/arch/cris/arch-v32/kernel/process.c @@ -9,9 +9,9 @@ */ #include +#include #include #include -#include #include #include #include diff --git a/arch/cris/arch-v32/kernel/signal.c b/arch/cris/arch-v32/kernel/signal.c index 372d0ca..0b7e3f1 100644 --- a/arch/cris/arch-v32/kernel/signal.c +++ b/arch/cris/arch-v32/kernel/signal.c @@ -4,6 +4,7 @@ #include #include +#include #include #include #include diff --git a/arch/cris/kernel/irq.c b/arch/cris/kernel/irq.c index 6d7b9ed..469f7f9 100644 --- a/arch/cris/kernel/irq.c +++ b/arch/cris/kernel/irq.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/cris/kernel/module.c b/arch/cris/kernel/module.c index abc13e3..bcd502f 100644 --- a/arch/cris/kernel/module.c +++ b/arch/cris/kernel/module.c @@ -21,6 +21,7 @@ #include #include #include +#include #if 0 #define DEBUGP printk diff --git a/arch/cris/kernel/profile.c b/arch/cris/kernel/profile.c index 9aa5711..b917549 100644 --- a/arch/cris/kernel/profile.c +++ b/arch/cris/kernel/profile.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/cris/mm/init.c b/arch/cris/mm/init.c index ff68b9f..df33ab8 100644 --- a/arch/cris/mm/init.c +++ b/arch/cris/mm/init.c @@ -8,6 +8,7 @@ * */ +#include #include #include #include diff --git a/arch/frv/kernel/irq.c b/arch/frv/kernel/irq.c index 62d1aba..6251366 100644 --- a/arch/frv/kernel/irq.c +++ b/arch/frv/kernel/irq.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/frv/kernel/sysctl.c b/arch/frv/kernel/sysctl.c index 035516cb..71abd15 100644 --- a/arch/frv/kernel/sysctl.c +++ b/arch/frv/kernel/sysctl.c @@ -9,7 +9,6 @@ * 2 of the License, or (at your option) any later version. */ -#include #include #include #include diff --git a/arch/frv/mb93090-mb00/pci-dma.c b/arch/frv/mb93090-mb00/pci-dma.c index 2c912e8..85d110b 100644 --- a/arch/frv/mb93090-mb00/pci-dma.c +++ b/arch/frv/mb93090-mb00/pci-dma.c @@ -10,7 +10,6 @@ */ #include -#include #include #include #include diff --git a/arch/frv/mb93090-mb00/pci-irq.c b/arch/frv/mb93090-mb00/pci-irq.c index ba58752..20f6497 100644 --- a/arch/frv/mb93090-mb00/pci-irq.c +++ b/arch/frv/mb93090-mb00/pci-irq.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include diff --git a/arch/frv/mb93090-mb00/pci-vdk.c b/arch/frv/mb93090-mb00/pci-vdk.c index c0dcec6..f8dd37e 100644 --- a/arch/frv/mb93090-mb00/pci-vdk.c +++ b/arch/frv/mb93090-mb00/pci-vdk.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include diff --git a/arch/frv/mm/dma-alloc.c b/arch/frv/mm/dma-alloc.c index 44840e7..7a73aae 100644 --- a/arch/frv/mm/dma-alloc.c +++ b/arch/frv/mm/dma-alloc.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include diff --git a/arch/frv/mm/init.c b/arch/frv/mm/init.c index 0708284..ed64588 100644 --- a/arch/frv/mm/init.c +++ b/arch/frv/mm/init.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/frv/mm/pgalloc.c b/arch/frv/mm/pgalloc.c index 66f616f..c42c83d 100644 --- a/arch/frv/mm/pgalloc.c +++ b/arch/frv/mm/pgalloc.c @@ -10,7 +10,7 @@ */ #include -#include +#include #include #include #include diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c index bd883fa..8c8b0ff 100644 --- a/arch/h8300/kernel/process.c +++ b/arch/h8300/kernel/process.c @@ -32,11 +32,11 @@ #include #include #include -#include #include #include #include #include +#include #include #include diff --git a/arch/h8300/mm/init.c b/arch/h8300/mm/init.c index 9942f24..7cc3380 100644 --- a/arch/h8300/mm/init.c +++ b/arch/h8300/mm/init.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/h8300/mm/kmap.c b/arch/h8300/mm/kmap.c index 5c7af09..944a502 100644 --- a/arch/h8300/mm/kmap.c +++ b/arch/h8300/mm/kmap.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include diff --git a/arch/h8300/mm/memory.c b/arch/h8300/mm/memory.c index 40d8aa8..5552ddf 100644 --- a/arch/h8300/mm/memory.c +++ b/arch/h8300/mm/memory.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include diff --git a/arch/ia64/include/asm/dmi.h b/arch/ia64/include/asm/dmi.h index 00eb1b1..1ed4c8f 100644 --- a/arch/ia64/include/asm/dmi.h +++ b/arch/ia64/include/asm/dmi.h @@ -1,6 +1,7 @@ #ifndef _ASM_DMI_H #define _ASM_DMI_H 1 +#include #include /* Use normal IO mappings for DMI */ diff --git a/arch/ia64/kernel/acpi-ext.c b/arch/ia64/kernel/acpi-ext.c index b7515bc..8b9318d 100644 --- a/arch/ia64/kernel/acpi-ext.c +++ b/arch/ia64/kernel/acpi-ext.c @@ -10,6 +10,7 @@ #include #include +#include #include #include diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index f1c9f70..4d1a7e9 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/ia64/kernel/cpufreq/acpi-cpufreq.c b/arch/ia64/kernel/cpufreq/acpi-cpufreq.c index 7b43545..b0b4e6e 100644 --- a/arch/ia64/kernel/cpufreq/acpi-cpufreq.c +++ b/arch/ia64/kernel/cpufreq/acpi-cpufreq.c @@ -10,6 +10,7 @@ */ #include +#include #include #include #include diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c index c745d0a..a0f0019 100644 --- a/arch/ia64/kernel/efi.c +++ b/arch/ia64/kernel/efi.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c index 95ac77a..7ded766 100644 --- a/arch/ia64/kernel/iosapic.c +++ b/arch/ia64/kernel/iosapic.c @@ -86,6 +86,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c index d4093a1..6404793 100644 --- a/arch/ia64/kernel/irq_ia64.c +++ b/arch/ia64/kernel/irq_ia64.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include /* for rand_initialize_irq() */ #include diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index 378b483..a0220dc 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c @@ -85,6 +85,7 @@ #include #include #include +#include #include #include diff --git a/arch/ia64/kernel/mca_drv.c b/arch/ia64/kernel/mca_drv.c index f94aaa8..09b4d68 100644 --- a/arch/ia64/kernel/mca_drv.c +++ b/arch/ia64/kernel/mca_drv.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/arch/ia64/kernel/pci-swiotlb.c b/arch/ia64/kernel/pci-swiotlb.c index 53292ab..3095654 100644 --- a/arch/ia64/kernel/pci-swiotlb.c +++ b/arch/ia64/kernel/pci-swiotlb.c @@ -1,6 +1,7 @@ /* Glue code to lib/swiotlb.c */ #include +#include #include #include #include diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index 703062c..ab985f7 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index d92765c..53f1648 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c @@ -15,11 +15,11 @@ #include #include #include +#include #include #include #include #include -#include #include #include #include diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c index b61afbb..0dec7f7 100644 --- a/arch/ia64/kernel/ptrace.c +++ b/arch/ia64/kernel/ptrace.c @@ -11,7 +11,6 @@ */ #include #include -#include #include #include #include diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c index b3a5818..28f299d 100644 --- a/arch/ia64/kernel/topology.c +++ b/arch/ia64/kernel/topology.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/ia64/kernel/uncached.c b/arch/ia64/kernel/uncached.c index a595823..c4696d2 100644 --- a/arch/ia64/kernel/uncached.c +++ b/arch/ia64/kernel/uncached.c @@ -18,9 +18,9 @@ #include #include #include -#include #include #include +#include #include #include #include diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index 26e0e08..73c5c2b 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c @@ -23,8 +23,8 @@ #include #include #include -#include #include +#include #include #include #include diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c index 8d586d1..6162032 100644 --- a/arch/ia64/mm/discontig.c +++ b/arch/ia64/mm/discontig.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c index b0f6157..1841ee7 100644 --- a/arch/ia64/mm/hugetlbpage.c +++ b/arch/ia64/mm/hugetlbpage.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c index f3de9d7..5dfd916 100644 --- a/arch/ia64/mm/tlb.c +++ b/arch/ia64/mm/tlb.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/arch/ia64/sn/kernel/bte.c b/arch/ia64/sn/kernel/bte.c index c6d6b62..cad775a 100644 --- a/arch/ia64/sn/kernel/bte.c +++ b/arch/ia64/sn/kernel/bte.c @@ -19,6 +19,7 @@ #include #include #include +#include #include diff --git a/arch/ia64/sn/kernel/io_acpi_init.c b/arch/ia64/sn/kernel/io_acpi_init.c index 66f633b..8cdcb17 100644 --- a/arch/ia64/sn/kernel/io_acpi_init.c +++ b/arch/ia64/sn/kernel/io_acpi_init.c @@ -13,6 +13,7 @@ #include #include "xtalk/hubdev.h" #include +#include /* diff --git a/arch/ia64/sn/kernel/io_common.c b/arch/ia64/sn/kernel/io_common.c index 308e659..4433dd0 100644 --- a/arch/ia64/sn/kernel/io_common.c +++ b/arch/ia64/sn/kernel/io_common.c @@ -7,6 +7,7 @@ */ #include +#include #include #include #include diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c index ee774c3..98079f2 100644 --- a/arch/ia64/sn/kernel/io_init.c +++ b/arch/ia64/sn/kernel/io_init.c @@ -6,6 +6,7 @@ * Copyright (C) 1992 - 1997, 2000-2006 Silicon Graphics, Inc. All rights reserved. */ +#include #include #include #include diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c index 40d6eed..13c15d9 100644 --- a/arch/ia64/sn/kernel/irq.c +++ b/arch/ia64/sn/kernel/irq.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/ia64/sn/kernel/msi_sn.c b/arch/ia64/sn/kernel/msi_sn.c index fbbfb97..ebfdd6a 100644 --- a/arch/ia64/sn/kernel/msi_sn.c +++ b/arch/ia64/sn/kernel/msi_sn.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c index 98b6849..a9d310d 100644 --- a/arch/ia64/sn/pci/pci_dma.c +++ b/arch/ia64/sn/pci/pci_dma.c @@ -9,6 +9,7 @@ * a description of how these routines should be used. */ +#include #include #include #include diff --git a/arch/ia64/sn/pci/pcibr/pcibr_provider.c b/arch/ia64/sn/pci/pcibr/pcibr_provider.c index d13e5a2..3cb5cf3 100644 --- a/arch/ia64/sn/pci/pcibr/pcibr_provider.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_provider.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include diff --git a/arch/ia64/sn/pci/tioca_provider.c b/arch/ia64/sn/pci/tioca_provider.c index efb4545..4d4536e 100644 --- a/arch/ia64/sn/pci/tioca_provider.c +++ b/arch/ia64/sn/pci/tioca_provider.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/ia64/sn/pci/tioce_provider.c b/arch/ia64/sn/pci/tioce_provider.c index 012f3b8..27faba0 100644 --- a/arch/ia64/sn/pci/tioce_provider.c +++ b/arch/ia64/sn/pci/tioce_provider.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include diff --git a/arch/ia64/xen/grant-table.c b/arch/ia64/xen/grant-table.c index 777dd9a..48cca37 100644 --- a/arch/ia64/xen/grant-table.c +++ b/arch/ia64/xen/grant-table.c @@ -22,6 +22,7 @@ #include #include +#include #include #include diff --git a/arch/m32r/kernel/process.c b/arch/m32r/kernel/process.c index 67a01e1..bc8c8c1 100644 --- a/arch/m32r/kernel/process.c +++ b/arch/m32r/kernel/process.c @@ -21,10 +21,10 @@ */ #include +#include #include #include #include -#include #include #include diff --git a/arch/m32r/mm/init.c b/arch/m32r/mm/init.c index 9f581df..73e2205 100644 --- a/arch/m32r/mm/init.c +++ b/arch/m32r/mm/init.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/m68k/bvme6000/rtc.c b/arch/m68k/bvme6000/rtc.c index c50bec8..b46ea17 100644 --- a/arch/m68k/bvme6000/rtc.c +++ b/arch/m68k/bvme6000/rtc.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/m68k/kernel/dma.c b/arch/m68k/kernel/dma.c index 2bb4245..4bbb3c2 100644 --- a/arch/m68k/kernel/dma.c +++ b/arch/m68k/kernel/dma.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c index 17c3f32..1a6be27 100644 --- a/arch/m68k/kernel/process.c +++ b/arch/m68k/kernel/process.c @@ -15,13 +15,13 @@ #include #include #include +#include #include #include #include #include #include #include -#include #include #include #include diff --git a/arch/m68k/mac/misc.c b/arch/m68k/mac/misc.c index 5d818568..0f118ca 100644 --- a/arch/m68k/mac/misc.c +++ b/arch/m68k/mac/misc.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/m68k/mm/init.c b/arch/m68k/mm/init.c index 774549a..8bc8425 100644 --- a/arch/m68k/mm/init.c +++ b/arch/m68k/mm/init.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include diff --git a/arch/m68k/mm/memory.c b/arch/m68k/mm/memory.c index b747352..34c77ce 100644 --- a/arch/m68k/mm/memory.c +++ b/arch/m68k/mm/memory.c @@ -9,9 +9,9 @@ #include #include #include -#include #include #include +#include #include #include diff --git a/arch/m68k/mm/motorola.c b/arch/m68k/mm/motorola.c index 4665fc8..02b7a03 100644 --- a/arch/m68k/mm/motorola.c +++ b/arch/m68k/mm/motorola.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include diff --git a/arch/m68k/mvme16x/rtc.c b/arch/m68k/mvme16x/rtc.c index cea5e3e..8da9c25 100644 --- a/arch/m68k/mvme16x/rtc.c +++ b/arch/m68k/mvme16x/rtc.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/m68k/sun3/sun3dvma.c b/arch/m68k/sun3/sun3dvma.c index f9277e8..ca0966c 100644 --- a/arch/m68k/sun3/sun3dvma.c +++ b/arch/m68k/sun3/sun3dvma.c @@ -8,6 +8,7 @@ #include #include +#include #include #include diff --git a/arch/m68k/sun3x/dvma.c b/arch/m68k/sun3x/dvma.c index 117481e..d5ddcda 100644 --- a/arch/m68k/sun3x/dvma.c +++ b/arch/m68k/sun3x/dvma.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include diff --git a/arch/m68knommu/kernel/dma.c b/arch/m68knommu/kernel/dma.c index aaf38bb..fc61541 100644 --- a/arch/m68knommu/kernel/dma.c +++ b/arch/m68knommu/kernel/dma.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include diff --git a/arch/m68knommu/kernel/process.c b/arch/m68knommu/kernel/process.c index 959cb24..6aa6613 100644 --- a/arch/m68knommu/kernel/process.c +++ b/arch/m68knommu/kernel/process.c @@ -23,11 +23,11 @@ #include #include #include -#include #include #include #include #include +#include #include #include diff --git a/arch/m68knommu/mm/init.c b/arch/m68knommu/mm/init.c index f3236d0..8a6653f 100644 --- a/arch/m68knommu/mm/init.c +++ b/arch/m68knommu/mm/init.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/m68knommu/mm/kmap.c b/arch/m68knommu/mm/kmap.c index bc32f38..902c1df 100644 --- a/arch/m68knommu/mm/kmap.c +++ b/arch/m68knommu/mm/kmap.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include diff --git a/arch/m68knommu/mm/memory.c b/arch/m68knommu/mm/memory.c index d5b9e13..8f7949e 100644 --- a/arch/m68knommu/mm/memory.c +++ b/arch/m68knommu/mm/memory.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include diff --git a/arch/microblaze/kernel/cpu/cpuinfo.c b/arch/microblaze/kernel/cpu/cpuinfo.c index 991d713..255ef88 100644 --- a/arch/microblaze/kernel/cpu/cpuinfo.c +++ b/arch/microblaze/kernel/cpu/cpuinfo.c @@ -9,7 +9,6 @@ */ #include -#include #include #include diff --git a/arch/microblaze/kernel/dma.c b/arch/microblaze/kernel/dma.c index b108497..9d69ca4 100644 --- a/arch/microblaze/kernel/dma.c +++ b/arch/microblaze/kernel/dma.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include diff --git a/arch/microblaze/kernel/module.c b/arch/microblaze/kernel/module.c index 5a45b1a..cbecf11 100644 --- a/arch/microblaze/kernel/module.c +++ b/arch/microblaze/kernel/module.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include diff --git a/arch/microblaze/kernel/of_platform.c b/arch/microblaze/kernel/of_platform.c index 1c6d684..0dc7552 100644 --- a/arch/microblaze/kernel/of_platform.c +++ b/arch/microblaze/kernel/of_platform.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/microblaze/kernel/sys_microblaze.c b/arch/microblaze/kernel/sys_microblaze.c index 9f3c205..f4e00b7 100644 --- a/arch/microblaze/kernel/sys_microblaze.c +++ b/arch/microblaze/kernel/sys_microblaze.c @@ -30,6 +30,7 @@ #include #include #include +#include #include diff --git a/arch/microblaze/mm/consistent.c b/arch/microblaze/mm/consistent.c index a9b443e..f956e24 100644 --- a/arch/microblaze/mm/consistent.c +++ b/arch/microblaze/mm/consistent.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include diff --git a/arch/microblaze/mm/init.c b/arch/microblaze/mm/init.c index 1608e2e..77c9e30 100644 --- a/arch/microblaze/mm/init.c +++ b/arch/microblaze/mm/init.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c index 0be3435..740bb32 100644 --- a/arch/microblaze/pci/pci-common.c +++ b/arch/microblaze/pci/pci-common.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include diff --git a/arch/microblaze/pci/pci_32.c b/arch/microblaze/pci/pci_32.c index 7e0c94f..3c3d808 100644 --- a/arch/microblaze/pci/pci_32.c +++ b/arch/microblaze/pci/pci_32.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include diff --git a/arch/mips/jazz/jazzdma.c b/arch/mips/jazz/jazzdma.c index 0d64d0f..9ce9f64 100644 --- a/arch/mips/jazz/jazzdma.c +++ b/arch/mips/jazz/jazzdma.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c index 981f86c..c6345f5 100644 --- a/arch/mips/kernel/irq.c +++ b/arch/mips/kernel/irq.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index a39d059..c2dab14 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -34,6 +33,7 @@ #include #include #include +#include #include #include diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index f3d73e1..463b71b 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c index dcaed1b..26f9b9a 100644 --- a/arch/mips/kernel/rtlx.c +++ b/arch/mips/kernel/rtlx.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index 23499b5..25e825a 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index e96b1c3..9587abc 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -29,6 +28,7 @@ #include #include #include +#include #include #include diff --git a/arch/mips/mipssim/sim_int.c b/arch/mips/mipssim/sim_int.c index 46067ad..5c779be 100644 --- a/arch/mips/mipssim/sim_int.c +++ b/arch/mips/mipssim/sim_int.c @@ -17,7 +17,6 @@ */ #include #include -#include #include #include #include diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index 9367e33..9547bc0 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include diff --git a/arch/mips/mm/hugetlbpage.c b/arch/mips/mm/hugetlbpage.c index cd0660c..a7fee0d 100644 --- a/arch/mips/mm/hugetlbpage.c +++ b/arch/mips/mm/hugetlbpage.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 12539af..2efcbd2 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include diff --git a/arch/mips/mm/ioremap.c b/arch/mips/mm/ioremap.c index 0c43248..cacfd31 100644 --- a/arch/mips/mm/ioremap.c +++ b/arch/mips/mm/ioremap.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c index 2cb5ae7..15949b0 100644 --- a/arch/mips/mti-malta/malta-int.c +++ b/arch/mips/mti-malta/malta-int.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/mips/nxp/pnx833x/common/reset.c b/arch/mips/nxp/pnx833x/common/reset.c index a9bc9ba..e0ea96d 100644 --- a/arch/mips/nxp/pnx833x/common/reset.c +++ b/arch/mips/nxp/pnx833x/common/reset.c @@ -22,7 +22,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include #include #include diff --git a/arch/mips/nxp/pnx8550/common/int.c b/arch/mips/nxp/pnx8550/common/int.c index 7aca7d5..cfed505 100644 --- a/arch/mips/nxp/pnx8550/common/int.c +++ b/arch/mips/nxp/pnx8550/common/int.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/mips/nxp/pnx8550/common/proc.c b/arch/mips/nxp/pnx8550/common/proc.c index af094cd..3bba5ec 100644 --- a/arch/mips/nxp/pnx8550/common/proc.c +++ b/arch/mips/nxp/pnx8550/common/proc.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/mips/nxp/pnx8550/common/reset.c b/arch/mips/nxp/pnx8550/common/reset.c index 7b2cbc5..76bc3ec 100644 --- a/arch/mips/nxp/pnx8550/common/reset.c +++ b/arch/mips/nxp/pnx8550/common/reset.c @@ -20,7 +20,6 @@ * Reset the PNX8550 board. * */ -#include #include #include diff --git a/arch/mips/pci/ops-titan-ht.c b/arch/mips/pci/ops-titan-ht.c index 46c636c..749c192 100644 --- a/arch/mips/pci/ops-titan-ht.c +++ b/arch/mips/pci/ops-titan-ht.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include diff --git a/arch/mips/pmc-sierra/msp71xx/msp_prom.c b/arch/mips/pmc-sierra/msp71xx/msp_prom.c index db98d87..db00deb 100644 --- a/arch/mips/pmc-sierra/msp71xx/msp_prom.c +++ b/arch/mips/pmc-sierra/msp71xx/msp_prom.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include diff --git a/arch/mips/pmc-sierra/yosemite/ht.c b/arch/mips/pmc-sierra/yosemite/ht.c index fd22597..63be40e 100644 --- a/arch/mips/pmc-sierra/yosemite/ht.c +++ b/arch/mips/pmc-sierra/yosemite/ht.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include diff --git a/arch/mips/pmc-sierra/yosemite/irq.c b/arch/mips/pmc-sierra/yosemite/irq.c index 5f673eb..51021cf 100644 --- a/arch/mips/pmc-sierra/yosemite/irq.c +++ b/arch/mips/pmc-sierra/yosemite/irq.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/mips/powertv/asic/asic_devices.c b/arch/mips/powertv/asic/asic_devices.c index 2174242..8ee7788 100644 --- a/arch/mips/powertv/asic/asic_devices.c +++ b/arch/mips/powertv/asic/asic_devices.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/mips/powertv/asic/asic_int.c b/arch/mips/powertv/asic/asic_int.c index 325fab96..529c44a 100644 --- a/arch/mips/powertv/asic/asic_int.c +++ b/arch/mips/powertv/asic/asic_int.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/mips/rb532/irq.c b/arch/mips/rb532/irq.c index f078820..ea6cec3 100644 --- a/arch/mips/rb532/irq.c +++ b/arch/mips/rb532/irq.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c index c1c8e40..6a123ea 100644 --- a/arch/mips/sgi-ip27/ip27-irq.c +++ b/arch/mips/sgi-ip27/ip27-irq.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c index d8b6520..eb40824 100644 --- a/arch/mips/sgi-ip32/ip32-irq.c +++ b/arch/mips/sgi-ip32/ip32-irq.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c index 06e25d9..7a8b0a8 100644 --- a/arch/mips/sibyte/bcm1480/irq.c +++ b/arch/mips/sibyte/bcm1480/irq.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include diff --git a/arch/mips/sibyte/common/sb_tbprof.c b/arch/mips/sibyte/common/sb_tbprof.c index ed2453e..d4ed7a9 100644 --- a/arch/mips/sibyte/common/sb_tbprof.c +++ b/arch/mips/sibyte/common/sb_tbprof.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c index ab44a2f..62371f7 100644 --- a/arch/mips/sibyte/sb1250/irq.c +++ b/arch/mips/sibyte/sb1250/irq.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include diff --git a/arch/mips/txx9/generic/pci.c b/arch/mips/txx9/generic/pci.c index 707cfa9..9a0be81 100644 --- a/arch/mips/txx9/generic/pci.c +++ b/arch/mips/txx9/generic/pci.c @@ -20,6 +20,7 @@ #include #ifdef CONFIG_TOSHIBA_FPCIB0 #include +#include #include #include #endif diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c index 95184a0..adc6929 100644 --- a/arch/mips/txx9/generic/setup.c +++ b/arch/mips/txx9/generic/setup.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/mips/txx9/generic/spi_eeprom.c b/arch/mips/txx9/generic/spi_eeprom.c index 75c3472..103abc1 100644 --- a/arch/mips/txx9/generic/spi_eeprom.c +++ b/arch/mips/txx9/generic/spi_eeprom.c @@ -10,6 +10,7 @@ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) */ #include +#include #include #include #include diff --git a/arch/mips/txx9/rbtx4939/setup.c b/arch/mips/txx9/rbtx4939/setup.c index b0c241e..7dc0faf 100644 --- a/arch/mips/txx9/rbtx4939/setup.c +++ b/arch/mips/txx9/rbtx4939/setup.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/mn10300/kernel/process.c b/arch/mn10300/kernel/process.c index ec8a21d..82b817c 100644 --- a/arch/mn10300/kernel/process.c +++ b/arch/mn10300/kernel/process.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -26,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/mn10300/kernel/setup.c b/arch/mn10300/kernel/setup.c index 3f24c29..d464aff 100644 --- a/arch/mn10300/kernel/setup.c +++ b/arch/mn10300/kernel/setup.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/mn10300/mm/dma-alloc.c b/arch/mn10300/mm/dma-alloc.c index ee82d62..4e34880 100644 --- a/arch/mn10300/mm/dma-alloc.c +++ b/arch/mn10300/mm/dma-alloc.c @@ -14,6 +14,7 @@ #include #include #include +#include #include static unsigned long pci_sram_allocated = 0xbc000000; diff --git a/arch/mn10300/mm/init.c b/arch/mn10300/mm/init.c index dd27a9a..6e6bc0e 100644 --- a/arch/mn10300/mm/init.c +++ b/arch/mn10300/mm/init.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -27,6 +26,7 @@ #include #include #include +#include #include #include diff --git a/arch/mn10300/mm/pgtable.c b/arch/mn10300/mm/pgtable.c index baffc58..9c1624c 100644 --- a/arch/mn10300/mm/pgtable.c +++ b/arch/mn10300/mm/pgtable.c @@ -12,11 +12,11 @@ #include #include #include +#include #include #include #include #include -#include #include #include #include diff --git a/arch/mn10300/unit-asb2305/pci-irq.c b/arch/mn10300/unit-asb2305/pci-irq.c index 58cfb44..91212ea 100644 --- a/arch/mn10300/unit-asb2305/pci-irq.c +++ b/arch/mn10300/unit-asb2305/pci-irq.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/parisc/hpux/fs.c b/arch/parisc/hpux/fs.c index 5407536..6935123 100644 --- a/arch/parisc/hpux/fs.c +++ b/arch/parisc/hpux/fs.c @@ -26,8 +26,8 @@ #include #include #include -#include #include +#include #include #include diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c index 2120746..159a2b8 100644 --- a/arch/parisc/kernel/module.c +++ b/arch/parisc/kernel/module.c @@ -61,6 +61,7 @@ #include #include #include +#include #include diff --git a/arch/parisc/kernel/pci-dma.c b/arch/parisc/kernel/pci-dma.c index c07f618..a029f74 100644 --- a/arch/parisc/kernel/pci-dma.c +++ b/arch/parisc/kernel/pci-dma.c @@ -18,11 +18,11 @@ */ #include +#include #include #include #include #include -#include #include #include #include diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c index 38372e7..9efd974 100644 --- a/arch/parisc/kernel/pci.c +++ b/arch/parisc/kernel/pci.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index 1f3aa8d..76332da 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/parisc/kernel/signal32.c b/arch/parisc/kernel/signal32.c index fb59852..e141324 100644 --- a/arch/parisc/kernel/signal32.c +++ b/arch/parisc/kernel/signal32.c @@ -23,7 +23,6 @@ */ #include -#include #include #include #include diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c index 3f2fce8..69d63d3 100644 --- a/arch/parisc/kernel/smp.c +++ b/arch/parisc/kernel/smp.c @@ -18,7 +18,6 @@ */ #include #include -#include #include #include diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c index 13b6e3e..f4f4d70 100644 --- a/arch/parisc/mm/init.c +++ b/arch/parisc/mm/init.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include /* for hppa_dma_ops and pcxl_dma_ops */ diff --git a/arch/powerpc/kernel/cacheinfo.c b/arch/powerpc/kernel/cacheinfo.c index 01fe9ce..a3c684b 100644 --- a/arch/powerpc/kernel/cacheinfo.c +++ b/arch/powerpc/kernel/cacheinfo.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include "cacheinfo.h" diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c index 6215062..6c1df57 100644 --- a/arch/powerpc/kernel/dma.c +++ b/arch/powerpc/kernel/dma.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c index a4c8b38..71cf280 100644 --- a/arch/powerpc/kernel/ibmebus.c +++ b/arch/powerpc/kernel/ibmebus.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c index 3fd1af9..b36f074 100644 --- a/arch/powerpc/kernel/kprobes.c +++ b/arch/powerpc/kernel/kprobes.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c index d09d1c6..c2c70e1 100644 --- a/arch/powerpc/kernel/lparcfg.c +++ b/arch/powerpc/kernel/lparcfg.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c index 666d08d..6c1dfc3 100644 --- a/arch/powerpc/kernel/of_platform.c +++ b/arch/powerpc/kernel/of_platform.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index f3c42ce5..0c0567e 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c index c13668c..e7db5b4 100644 --- a/arch/powerpc/kernel/pci_32.c +++ b/arch/powerpc/kernel/pci_32.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c index d5e36e5..d56b35e 100644 --- a/arch/powerpc/kernel/pci_dn.c +++ b/arch/powerpc/kernel/pci_dn.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/arch/powerpc/kernel/proc_powerpc.c b/arch/powerpc/kernel/proc_powerpc.c index 1ed3b8d..c8ae371 100644 --- a/arch/powerpc/kernel/proc_powerpc.c +++ b/arch/powerpc/kernel/proc_powerpc.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index fd0d294..7436784 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c index a85117d..bfc2aba 100644 --- a/arch/powerpc/kernel/rtas_flash.c +++ b/arch/powerpc/kernel/rtas_flash.c @@ -15,6 +15,7 @@ #include #include +#include #include #include #include diff --git a/arch/powerpc/kernel/rtasd.c b/arch/powerpc/kernel/rtasd.c index 2e4832a..4190eae 100644 --- a/arch/powerpc/kernel/rtasd.c +++ b/arch/powerpc/kernel/rtasd.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include diff --git a/arch/powerpc/kernel/smp-tbsync.c b/arch/powerpc/kernel/smp-tbsync.c index a5e5452..03e45c4 100644 --- a/arch/powerpc/kernel/smp-tbsync.c +++ b/arch/powerpc/kernel/smp-tbsync.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/powerpc/kernel/softemu8xx.c b/arch/powerpc/kernel/softemu8xx.c index 23c8c5e..af0e829 100644 --- a/arch/powerpc/kernel/softemu8xx.c +++ b/arch/powerpc/kernel/softemu8xx.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c index c5a4732..19471a1 100644 --- a/arch/powerpc/kernel/sys_ppc32.c +++ b/arch/powerpc/kernel/sys_ppc32.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 696626a..29d128e 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index 77f6421..8223717 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/powerpc/kvm/44x.c b/arch/powerpc/kvm/44x.c index f4d1b55..689a57c 100644 --- a/arch/powerpc/kvm/44x.c +++ b/arch/powerpc/kvm/44x.c @@ -18,6 +18,7 @@ */ #include +#include #include #include diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 9a271f0..25da07f 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index 4d686cc..2a3a195 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c index efa1198..669a5c5 100644 --- a/arch/powerpc/kvm/e500.c +++ b/arch/powerpc/kvm/e500.c @@ -13,6 +13,7 @@ */ #include +#include #include #include diff --git a/arch/powerpc/kvm/e500_tlb.c b/arch/powerpc/kvm/e500_tlb.c index 0d772e6..21011e1 100644 --- a/arch/powerpc/kvm/e500_tlb.c +++ b/arch/powerpc/kvm/e500_tlb.c @@ -13,6 +13,7 @@ */ #include +#include #include #include #include diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 51aedd7..297fcd2 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/powerpc/lib/devres.c b/arch/powerpc/lib/devres.c index 292115d..deac4d3 100644 --- a/arch/powerpc/lib/devres.c +++ b/arch/powerpc/lib/devres.c @@ -8,6 +8,7 @@ */ #include /* devres_*(), devm_ioremap_release() */ +#include #include /* ioremap_flags() */ #include /* EXPORT_SYMBOL() */ diff --git a/arch/powerpc/mm/dma-noncoherent.c b/arch/powerpc/mm/dma-noncoherent.c index 36692f5..757c0be 100644 --- a/arch/powerpc/mm/dma-noncoherent.c +++ b/arch/powerpc/mm/dma-noncoherent.c @@ -23,6 +23,7 @@ */ #include +#include #include #include #include diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 123f707..9bb249c 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c index b1dbd9e..7673330 100644 --- a/arch/powerpc/mm/init_32.c +++ b/arch/powerpc/mm/init_32.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c index 776f28d..d7fa50b 100644 --- a/arch/powerpc/mm/init_64.c +++ b/arch/powerpc/mm/init_64.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 448f972..0f594d7 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/powerpc/mm/mmu_context_hash64.c b/arch/powerpc/mm/mmu_context_hash64.c index 51622da..2535828 100644 --- a/arch/powerpc/mm/mmu_context_hash64.c +++ b/arch/powerpc/mm/mmu_context_hash64.c @@ -19,6 +19,7 @@ #include #include #include +#include #include diff --git a/arch/powerpc/mm/mmu_context_nohash.c b/arch/powerpc/mm/mmu_context_nohash.c index dbc6921..1f2d9ff 100644 --- a/arch/powerpc/mm/mmu_context_nohash.c +++ b/arch/powerpc/mm/mmu_context_nohash.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c index 99df697..ebc2f38 100644 --- a/arch/powerpc/mm/pgtable.c +++ b/arch/powerpc/mm/pgtable.c @@ -22,6 +22,7 @@ */ #include +#include #include #include #include diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c index 573b3bd..b9243e7 100644 --- a/arch/powerpc/mm/pgtable_32.c +++ b/arch/powerpc/mm/pgtable_32.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c index 853d556..d95679a 100644 --- a/arch/powerpc/mm/pgtable_64.c +++ b/arch/powerpc/mm/pgtable_64.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include diff --git a/arch/powerpc/mm/subpage-prot.c b/arch/powerpc/mm/subpage-prot.c index a040b81..e4f8f1f 100644 --- a/arch/powerpc/mm/subpage-prot.c +++ b/arch/powerpc/mm/subpage-prot.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/powerpc/oprofile/cell/spu_task_sync.c b/arch/powerpc/oprofile/cell/spu_task_sync.c index 6b793ae..642fca1 100644 --- a/arch/powerpc/oprofile/cell/spu_task_sync.c +++ b/arch/powerpc/oprofile/cell/spu_task_sync.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include "pr_util.h" diff --git a/arch/powerpc/oprofile/cell/vma_map.c b/arch/powerpc/oprofile/cell/vma_map.c index c591339..c579b16 100644 --- a/arch/powerpc/oprofile/cell/vma_map.c +++ b/arch/powerpc/oprofile/cell/vma_map.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "pr_util.h" diff --git a/arch/powerpc/platforms/44x/warp.c b/arch/powerpc/platforms/44x/warp.c index e5c1b09..8f77139 100644 --- a/arch/powerpc/platforms/44x/warp.c +++ b/arch/powerpc/platforms/44x/warp.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c index 2b8d8ef..fda7c2a 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c index 5d7cc88..a60ee39 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c @@ -62,6 +62,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/powerpc/platforms/82xx/ep8248e.c b/arch/powerpc/platforms/82xx/ep8248e.c index f9aee18..f21555d 100644 --- a/arch/powerpc/platforms/82xx/ep8248e.c +++ b/arch/powerpc/platforms/82xx/ep8248e.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff --git a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c index d4a09f8..5a55d87 100644 --- a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c +++ b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include diff --git a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c index 82a9bcb..d119a7c 100644 --- a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c +++ b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include diff --git a/arch/powerpc/platforms/86xx/gef_gpio.c b/arch/powerpc/platforms/86xx/gef_gpio.c index 11f7b2b..b8cb08d 100644 --- a/arch/powerpc/platforms/86xx/gef_gpio.c +++ b/arch/powerpc/platforms/86xx/gef_gpio.c @@ -26,6 +26,7 @@ #include #include #include +#include #define GEF_GPIO_DIRECT 0x00 #define GEF_GPIO_IN 0x04 diff --git a/arch/powerpc/platforms/8xx/m8xx_setup.c b/arch/powerpc/platforms/8xx/m8xx_setup.c index 242954c..60168c1 100644 --- a/arch/powerpc/platforms/8xx/m8xx_setup.c +++ b/arch/powerpc/platforms/8xx/m8xx_setup.c @@ -11,7 +11,6 @@ */ #include -#include #include #include #include diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c index 96fe896..8efe481 100644 --- a/arch/powerpc/platforms/cell/axon_msi.c +++ b/arch/powerpc/platforms/cell/axon_msi.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff --git a/arch/powerpc/platforms/cell/celleb_pci.c b/arch/powerpc/platforms/cell/celleb_pci.c index 00eaaa7..404d1fc 100644 --- a/arch/powerpc/platforms/cell/celleb_pci.c +++ b/arch/powerpc/platforms/cell/celleb_pci.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include diff --git a/arch/powerpc/platforms/cell/celleb_scc_pciex.c b/arch/powerpc/platforms/cell/celleb_scc_pciex.c index 7fca09f..a881bbe 100644 --- a/arch/powerpc/platforms/cell/celleb_scc_pciex.c +++ b/arch/powerpc/platforms/cell/celleb_scc_pciex.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index ca5bfdf..e3ec497 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include diff --git a/arch/powerpc/platforms/cell/ras.c b/arch/powerpc/platforms/cell/ras.c index 608fd2b..1d3c4ef 100644 --- a/arch/powerpc/platforms/cell/ras.c +++ b/arch/powerpc/platforms/cell/ras.c @@ -11,6 +11,7 @@ #include #include +#include #include #include #include diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c index 5930536..50385db 100644 --- a/arch/powerpc/platforms/cell/setup.c +++ b/arch/powerpc/platforms/cell/setup.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/powerpc/platforms/cell/spider-pci.c b/arch/powerpc/platforms/cell/spider-pci.c index 5122ec1..ca7731c 100644 --- a/arch/powerpc/platforms/cell/spider-pci.c +++ b/arch/powerpc/platforms/cell/spider-pci.c @@ -22,6 +22,7 @@ #include #include +#include #include #include diff --git a/arch/powerpc/platforms/cell/spu_manage.c b/arch/powerpc/platforms/cell/spu_manage.c index 891f18e..f465d47 100644 --- a/arch/powerpc/platforms/cell/spu_manage.c +++ b/arch/powerpc/platforms/cell/spu_manage.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/powerpc/platforms/cell/spu_priv1_mmio.c b/arch/powerpc/platforms/cell/spu_priv1_mmio.c index 1410443..121aec3 100644 --- a/arch/powerpc/platforms/cell/spu_priv1_mmio.c +++ b/arch/powerpc/platforms/cell/spu_priv1_mmio.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/powerpc/platforms/cell/spufs/coredump.c b/arch/powerpc/platforms/cell/spufs/coredump.c index eea1202..6cf3ec6 100644 --- a/arch/powerpc/platforms/cell/spufs/coredump.c +++ b/arch/powerpc/platforms/cell/spufs/coredump.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 64a4c2d..5c28082 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include diff --git a/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c b/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c index 0e9f325..a101abf 100644 --- a/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c +++ b/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c @@ -22,6 +22,7 @@ #include #include +#include #include #include diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c index 4678078..0b04662 100644 --- a/arch/powerpc/platforms/cell/spufs/sched.c +++ b/arch/powerpc/platforms/cell/spufs/sched.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/powerpc/platforms/cell/spufs/syscalls.c b/arch/powerpc/platforms/cell/spufs/syscalls.c index c23617c..187a7d3 100644 --- a/arch/powerpc/platforms/cell/spufs/syscalls.c +++ b/arch/powerpc/platforms/cell/spufs/syscalls.c @@ -3,6 +3,7 @@ #include #include #include +#include #include diff --git a/arch/powerpc/platforms/chrp/nvram.c b/arch/powerpc/platforms/chrp/nvram.c index 8efd424..ba3588f 100644 --- a/arch/powerpc/platforms/chrp/nvram.c +++ b/arch/powerpc/platforms/chrp/nvram.c @@ -12,7 +12,6 @@ #include #include -#include #include #include #include diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c index 8f41685..8553cc4 100644 --- a/arch/powerpc/platforms/chrp/setup.c +++ b/arch/powerpc/platforms/chrp/setup.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c index 9d53cb4..ce61cea 100644 --- a/arch/powerpc/platforms/iseries/iommu.c +++ b/arch/powerpc/platforms/iseries/iommu.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c index 6617915..d2c1d49 100644 --- a/arch/powerpc/platforms/iseries/mf.c +++ b/arch/powerpc/platforms/iseries/mf.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c index 175aac8..b841c9a 100644 --- a/arch/powerpc/platforms/iseries/pci.c +++ b/arch/powerpc/platforms/iseries/pci.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/powerpc/platforms/iseries/vio.c b/arch/powerpc/platforms/iseries/vio.c index 2aa8b56..00b6730 100644 --- a/arch/powerpc/platforms/iseries/vio.c +++ b/arch/powerpc/platforms/iseries/vio.c @@ -22,7 +22,7 @@ */ #include #include -#include +#include #include #include #include diff --git a/arch/powerpc/platforms/iseries/viopath.c b/arch/powerpc/platforms/iseries/viopath.c index 5aea94f..b5f05d9 100644 --- a/arch/powerpc/platforms/iseries/viopath.c +++ b/arch/powerpc/platforms/iseries/viopath.c @@ -29,6 +29,7 @@ */ #include #include +#include #include #include #include diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c index 0636a3d..39df705 100644 --- a/arch/powerpc/platforms/maple/setup.c +++ b/arch/powerpc/platforms/maple/setup.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/powerpc/platforms/pasemi/dma_lib.c b/arch/powerpc/platforms/pasemi/dma_lib.c index a6152d9..09695ae 100644 --- a/arch/powerpc/platforms/pasemi/dma_lib.c +++ b/arch/powerpc/platforms/pasemi/dma_lib.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include diff --git a/arch/powerpc/platforms/pasemi/gpio_mdio.c b/arch/powerpc/platforms/pasemi/gpio_mdio.c index 3bf5467..0f881f6 100644 --- a/arch/powerpc/platforms/pasemi/gpio_mdio.c +++ b/arch/powerpc/platforms/pasemi/gpio_mdio.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c index 242f809..ac6fdd9 100644 --- a/arch/powerpc/platforms/pasemi/setup.c +++ b/arch/powerpc/platforms/pasemi/setup.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include diff --git a/arch/powerpc/platforms/powermac/cpufreq_32.c b/arch/powerpc/platforms/powermac/cpufreq_32.c index d4f127d..1e9eba1 100644 --- a/arch/powerpc/platforms/powermac/cpufreq_32.c +++ b/arch/powerpc/platforms/powermac/cpufreq_32.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/powerpc/platforms/powermac/cpufreq_64.c b/arch/powerpc/platforms/powermac/cpufreq_64.c index 3ed288e..3ca09d3 100644 --- a/arch/powerpc/platforms/powermac/cpufreq_64.c +++ b/arch/powerpc/platforms/powermac/cpufreq_64.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c index 345e2da..f45331a 100644 --- a/arch/powerpc/platforms/powermac/low_i2c.c +++ b/arch/powerpc/platforms/powermac/low_i2c.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/powerpc/platforms/powermac/nvram.c b/arch/powerpc/platforms/powermac/nvram.c index 80a5258..b1cdcf9 100644 --- a/arch/powerpc/platforms/powermac/nvram.c +++ b/arch/powerpc/platforms/powermac/nvram.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/powerpc/platforms/powermac/pfunc_core.c b/arch/powerpc/platforms/powermac/pfunc_core.c index ede49e7..cec6359 100644 --- a/arch/powerpc/platforms/powermac/pfunc_core.c +++ b/arch/powerpc/platforms/powermac/pfunc_core.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index c205226..15c2241 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/powerpc/platforms/ps3/device-init.c b/arch/powerpc/platforms/ps3/device-init.c index bb028f1..b341018 100644 --- a/arch/powerpc/platforms/ps3/device-init.c +++ b/arch/powerpc/platforms/ps3/device-init.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c index e81b028..7925751 100644 --- a/arch/powerpc/platforms/ps3/mm.c +++ b/arch/powerpc/platforms/ps3/mm.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/arch/powerpc/platforms/ps3/os-area.c b/arch/powerpc/platforms/ps3/os-area.c index d6487a9..dd521a1 100644 --- a/arch/powerpc/platforms/ps3/os-area.c +++ b/arch/powerpc/platforms/ps3/os-area.c @@ -26,6 +26,7 @@ #include #include #include +#include #include diff --git a/arch/powerpc/platforms/ps3/spu.c b/arch/powerpc/platforms/ps3/spu.c index b3c6a99..39a472e 100644 --- a/arch/powerpc/platforms/ps3/spu.c +++ b/arch/powerpc/platforms/ps3/spu.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c index e34b305..6d09f5e 100644 --- a/arch/powerpc/platforms/ps3/system-bus.c +++ b/arch/powerpc/platforms/ps3/system-bus.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/arch/powerpc/platforms/pseries/cmm.c b/arch/powerpc/platforms/pseries/cmm.c index a277f2e..f480386 100644 --- a/arch/powerpc/platforms/pseries/cmm.c +++ b/arch/powerpc/platforms/pseries/cmm.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c index 37bce52..e1682bc 100644 --- a/arch/powerpc/platforms/pseries/dlpar.c +++ b/arch/powerpc/platforms/pseries/dlpar.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "offline_states.h" #include diff --git a/arch/powerpc/platforms/pseries/dtl.c b/arch/powerpc/platforms/pseries/dtl.c index c5f3116..a00addb5 100644 --- a/arch/powerpc/platforms/pseries/dtl.c +++ b/arch/powerpc/platforms/pseries/dtl.c @@ -21,6 +21,7 @@ */ #include +#include #include #include #include diff --git a/arch/powerpc/platforms/pseries/eeh_cache.c b/arch/powerpc/platforms/pseries/eeh_cache.c index ce37040..30b987b 100644 --- a/arch/powerpc/platforms/pseries/eeh_cache.c +++ b/arch/powerpc/platforms/pseries/eeh_cache.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/powerpc/platforms/pseries/eeh_event.c b/arch/powerpc/platforms/pseries/eeh_event.c index ec5df8f..2ec500c 100644 --- a/arch/powerpc/platforms/pseries/eeh_event.c +++ b/arch/powerpc/platforms/pseries/eeh_event.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/powerpc/platforms/pseries/nvram.c b/arch/powerpc/platforms/pseries/nvram.c index 42f7e38..bc3c7f2 100644 --- a/arch/powerpc/platforms/pseries/nvram.c +++ b/arch/powerpc/platforms/pseries/nvram.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/powerpc/platforms/pseries/phyp_dump.c b/arch/powerpc/platforms/pseries/phyp_dump.c index 225a50a..7ebd9e8 100644 --- a/arch/powerpc/platforms/pseries/phyp_dump.c +++ b/arch/powerpc/platforms/pseries/phyp_dump.c @@ -11,6 +11,7 @@ * */ +#include #include #include #include diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c index d20b96e..db940d2 100644 --- a/arch/powerpc/platforms/pseries/ras.c +++ b/arch/powerpc/platforms/pseries/ras.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c index a2305d2..1a58637 100644 --- a/arch/powerpc/platforms/pseries/reconfig.c +++ b/arch/powerpc/platforms/pseries/reconfig.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff --git a/arch/powerpc/platforms/pseries/scanlog.c b/arch/powerpc/platforms/pseries/scanlog.c index 1b45c45..80e9e76 100644 --- a/arch/powerpc/platforms/pseries/scanlog.c +++ b/arch/powerpc/platforms/pseries/scanlog.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index ca5f2e1..6710761 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c index ecad10d..4dae369 100644 --- a/arch/powerpc/sysdev/cpm1.c +++ b/arch/powerpc/sysdev/cpm1.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c index 9de72c9..88b9812 100644 --- a/arch/powerpc/sysdev/cpm_common.c +++ b/arch/powerpc/sysdev/cpm_common.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c index bafc3f8..c8b96ed 100644 --- a/arch/powerpc/sysdev/dart_iommu.c +++ b/arch/powerpc/sysdev/dart_iommu.c @@ -29,7 +29,6 @@ #include #include -#include #include #include #include @@ -38,6 +37,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/powerpc/sysdev/fsl_gtm.c b/arch/powerpc/sysdev/fsl_gtm.c index 714ec02..eca4545 100644 --- a/arch/powerpc/sysdev/fsl_gtm.c +++ b/arch/powerpc/sysdev/fsl_gtm.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #define GTCFR_STP(x) ((x) & 1 ? 1 << 5 : 1 << 1) diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index e094367..3482e3f 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index e1a028c..a14760f 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index 757a83f..71fba88 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c @@ -23,6 +23,7 @@ #include #include #include +#include #include diff --git a/arch/powerpc/sysdev/mpc8xxx_gpio.c b/arch/powerpc/sysdev/mpc8xxx_gpio.c index ee1c0e1..6478eb1 100644 --- a/arch/powerpc/sysdev/mpc8xxx_gpio.c +++ b/arch/powerpc/sysdev/mpc8xxx_gpio.c @@ -15,6 +15,7 @@ #include #include #include +#include #define MPC8XXX_GPIO_PINS 32 diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 339e8a3..260295b 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include diff --git a/arch/powerpc/sysdev/msi_bitmap.c b/arch/powerpc/sysdev/msi_bitmap.c index 5a32cbe..5287e95 100644 --- a/arch/powerpc/sysdev/msi_bitmap.c +++ b/arch/powerpc/sysdev/msi_bitmap.c @@ -8,6 +8,7 @@ * */ +#include #include #include #include diff --git a/arch/powerpc/sysdev/of_rtc.c b/arch/powerpc/sysdev/of_rtc.c index 3d54450..c9e803f 100644 --- a/arch/powerpc/sysdev/of_rtc.c +++ b/arch/powerpc/sysdev/of_rtc.c @@ -12,6 +12,7 @@ #include #include #include +#include static __initdata struct { const char *compatible; diff --git a/arch/powerpc/sysdev/pmi.c b/arch/powerpc/sysdev/pmi.c index aaa9159..652652d 100644 --- a/arch/powerpc/sysdev/pmi.c +++ b/arch/powerpc/sysdev/pmi.c @@ -25,6 +25,7 @@ */ #include +#include #include #include #include diff --git a/arch/powerpc/sysdev/ppc4xx_gpio.c b/arch/powerpc/sysdev/ppc4xx_gpio.c index 110efe2..3812fc3 100644 --- a/arch/powerpc/sysdev/ppc4xx_gpio.c +++ b/arch/powerpc/sysdev/ppc4xx_gpio.c @@ -29,6 +29,7 @@ #include #include #include +#include #define GPIO_MASK(gpio) (0x80000000 >> (gpio)) #define GPIO_MASK2(gpio) (0xc0000000 >> ((gpio) * 2)) diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c index 8aa3302..106d767 100644 --- a/arch/powerpc/sysdev/ppc4xx_pci.c +++ b/arch/powerpc/sysdev/ppc4xx_pci.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include diff --git a/arch/powerpc/sysdev/qe_lib/gpio.c b/arch/powerpc/sysdev/qe_lib/gpio.c index 8e7a776..dc8f8d6 100644 --- a/arch/powerpc/sysdev/qe_lib/gpio.c +++ b/arch/powerpc/sysdev/qe_lib/gpio.c @@ -19,6 +19,7 @@ #include #include #include +#include #include struct qe_gpio_chip { diff --git a/arch/powerpc/sysdev/qe_lib/ucc.c b/arch/powerpc/sysdev/qe_lib/ucc.c index ebb442e..fa589b2 100644 --- a/arch/powerpc/sysdev/qe_lib/ucc.c +++ b/arch/powerpc/sysdev/qe_lib/ucc.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/powerpc/sysdev/simple_gpio.c b/arch/powerpc/sysdev/simple_gpio.c index 43c4569..d5fb173 100644 --- a/arch/powerpc/sysdev/simple_gpio.c +++ b/arch/powerpc/sysdev/simple_gpio.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include "simple_gpio.h" diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c index 595034c..0ab9281 100644 --- a/arch/powerpc/sysdev/tsi108_pci.c +++ b/arch/powerpc/sysdev/tsi108_pci.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include diff --git a/arch/s390/appldata/appldata_mem.c b/arch/s390/appldata/appldata_mem.c index 4188cbe..e43fe75 100644 --- a/arch/s390/appldata/appldata_mem.c +++ b/arch/s390/appldata/appldata_mem.c @@ -11,7 +11,6 @@ #include #include -#include #include #include #include diff --git a/arch/s390/appldata/appldata_net_sum.c b/arch/s390/appldata/appldata_net_sum.c index 4ce7fa9..9a9586f 100644 --- a/arch/s390/appldata/appldata_net_sum.c +++ b/arch/s390/appldata/appldata_net_sum.c @@ -12,7 +12,6 @@ #include #include -#include #include #include #include diff --git a/arch/s390/crypto/prng.c b/arch/s390/crypto/prng.c index a320990..aa819da 100644 --- a/arch/s390/crypto/prng.c +++ b/arch/s390/crypto/prng.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include diff --git a/arch/s390/hypfs/hypfs_diag.c b/arch/s390/hypfs/hypfs_diag.c index 87cf523..5b1acdb 100644 --- a/arch/s390/hypfs/hypfs_diag.c +++ b/arch/s390/hypfs/hypfs_diag.c @@ -12,7 +12,6 @@ #include #include -#include #include #include #include diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c index cd128b0..c53f8ac 100644 --- a/arch/s390/hypfs/inode.c +++ b/arch/s390/hypfs/inode.c @@ -14,8 +14,8 @@ #include #include #include +#include #include -#include #include #include #include diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index 11c3aba..73b624e 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -52,6 +51,7 @@ #include #include #include +#include #include #include diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 7eedbbc..72c8b0d 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c index 86783ef..3d34eef 100644 --- a/arch/s390/kernel/kprobes.c +++ b/arch/s390/kernel/kprobes.c @@ -29,6 +29,7 @@ #include #include #include +#include DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 00b6d1d..1039fde 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c @@ -16,9 +16,9 @@ #include #include #include +#include #include #include -#include #include #include #include diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index ba363d9..91625f7 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index d7d24fc..e4d98de 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/s390/kernel/sysinfo.c b/arch/s390/kernel/sysinfo.c index b5e75e1..a0ffc771 100644 --- a/arch/s390/kernel/sysinfo.c +++ b/arch/s390/kernel/sysinfo.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index aa2483e..fba6dec 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index 834774d..35c21bf 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include "kvm-s390.h" diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c index 28c5567..4420550 100644 --- a/arch/s390/kvm/priv.c +++ b/arch/s390/kvm/priv.c @@ -12,6 +12,7 @@ */ #include +#include #include #include #include diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c index 241a484..eff3c59 100644 --- a/arch/s390/kvm/sigp.c +++ b/arch/s390/kvm/sigp.c @@ -14,6 +14,7 @@ #include #include +#include #include "gaccess.h" #include "kvm-s390.h" diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c index f16bd04..f87b347 100644 --- a/arch/s390/mm/cmm.c +++ b/arch/s390/mm/cmm.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index d5865e4..acc91c7 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/s390/mm/page-states.c b/arch/s390/mm/page-states.c index 098923a..a90d45e 100644 --- a/arch/s390/mm/page-states.c +++ b/arch/s390/mm/page-states.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #define ESSA_SET_STABLE 1 diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index ad621e0..8d99924 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c @@ -6,11 +6,11 @@ #include #include #include +#include #include #include #include #include -#include #include #include #include diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c index 300ab01..8ea3144 100644 --- a/arch/s390/mm/vmem.c +++ b/arch/s390/mm/vmem.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/score/kernel/sys_score.c b/arch/score/kernel/sys_score.c index 856ed68..651096f 100644 --- a/arch/score/kernel/sys_score.c +++ b/arch/score/kernel/sys_score.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/score/mm/init.c b/arch/score/mm/init.c index 7f001bb..50fdec5 100644 --- a/arch/score/mm/init.c +++ b/arch/score/mm/init.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/sh/drivers/dma/dma-api.c b/arch/sh/drivers/dma/dma-api.c index 727126e..4a27722 100644 --- a/arch/sh/drivers/dma/dma-api.c +++ b/arch/sh/drivers/dma/dma-api.c @@ -17,6 +17,7 @@ #include #include #include +#include #include DEFINE_SPINLOCK(dma_spin_lock); diff --git a/arch/sh/drivers/dma/dmabrg.c b/arch/sh/drivers/dma/dmabrg.c index 72622e3..6ab9c4a 100644 --- a/arch/sh/drivers/dma/dmabrg.c +++ b/arch/sh/drivers/dma/dmabrg.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include diff --git a/arch/sh/drivers/heartbeat.c b/arch/sh/drivers/heartbeat.c index 2acbc79..7efc9c3 100644 --- a/arch/sh/drivers/heartbeat.c +++ b/arch/sh/drivers/heartbeat.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #define DRV_NAME "heartbeat" diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c index ae91a2d..68cb9b0 100644 --- a/arch/sh/drivers/pci/pcie-sh7786.c +++ b/arch/sh/drivers/pci/pcie-sh7786.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "pcie-sh7786.h" #include diff --git a/arch/sh/drivers/push-switch.c b/arch/sh/drivers/push-switch.c index 725be6d..7b42c24 100644 --- a/arch/sh/drivers/push-switch.c +++ b/arch/sh/drivers/push-switch.c @@ -8,6 +8,7 @@ * for more details. */ #include +#include #include #include #include diff --git a/arch/sh/kernel/cpu/fpu.c b/arch/sh/kernel/cpu/fpu.c index f059ed6..7f1b70c 100644 --- a/arch/sh/kernel/cpu/fpu.c +++ b/arch/sh/kernel/cpu/fpu.c @@ -1,4 +1,5 @@ #include +#include #include #include diff --git a/arch/sh/kernel/cpu/hwblk.c b/arch/sh/kernel/cpu/hwblk.c index c0ad7d4..67a1e81 100644 --- a/arch/sh/kernel/cpu/hwblk.c +++ b/arch/sh/kernel/cpu/hwblk.c @@ -1,6 +1,5 @@ #include #include -#include #include #include #include diff --git a/arch/sh/kernel/dwarf.c b/arch/sh/kernel/dwarf.c index 94739ee..a8234b2 100644 --- a/arch/sh/kernel/dwarf.c +++ b/arch/sh/kernel/dwarf.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/sh/kernel/kprobes.c b/arch/sh/kernel/kprobes.c index c96850b..4049d99 100644 --- a/arch/sh/kernel/kprobes.c +++ b/arch/sh/kernel/kprobes.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c index 81add9b..17f89aa 100644 --- a/arch/sh/kernel/process.c +++ b/arch/sh/kernel/process.c @@ -1,5 +1,6 @@ #include #include +#include #include struct kmem_cache *task_xstate_cachep = NULL; diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c index 3cb88f1..0529819 100644 --- a/arch/sh/kernel/process_32.c +++ b/arch/sh/kernel/process_32.c @@ -15,6 +15,7 @@ */ #include #include +#include #include #include #include diff --git a/arch/sh/kernel/process_64.c b/arch/sh/kernel/process_64.c index c0d40f6..d4ca648 100644 --- a/arch/sh/kernel/process_64.c +++ b/arch/sh/kernel/process_64.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c index c625cda..7759a9a 100644 --- a/arch/sh/kernel/ptrace_32.c +++ b/arch/sh/kernel/ptrace_32.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/sh/kernel/vsyscall/vsyscall.c b/arch/sh/kernel/vsyscall/vsyscall.c index 3f7e415..242117c 100644 --- a/arch/sh/kernel/vsyscall/vsyscall.c +++ b/arch/sh/kernel/vsyscall/vsyscall.c @@ -11,7 +11,6 @@ * for more details. */ #include -#include #include #include #include diff --git a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c index 902967e..c86a085 100644 --- a/arch/sh/mm/consistent.c +++ b/arch/sh/mm/consistent.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include diff --git a/arch/sh/mm/hugetlbpage.c b/arch/sh/mm/hugetlbpage.c index 9304117..9163db3 100644 --- a/arch/sh/mm/hugetlbpage.c +++ b/arch/sh/mm/hugetlbpage.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index 68028e8..c505de6 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/sh/mm/ioremap.c b/arch/sh/mm/ioremap.c index 1ab2385..0c99ec2 100644 --- a/arch/sh/mm/ioremap.c +++ b/arch/sh/mm/ioremap.c @@ -14,6 +14,7 @@ */ #include #include +#include #include #include #include diff --git a/arch/sh/mm/ioremap_fixed.c b/arch/sh/mm/ioremap_fixed.c index 7f682e5..efbe84a 100644 --- a/arch/sh/mm/ioremap_fixed.c +++ b/arch/sh/mm/ioremap_fixed.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/sh/mm/pgtable.c b/arch/sh/mm/pgtable.c index 6f21fb1..26e03a1 100644 --- a/arch/sh/mm/pgtable.c +++ b/arch/sh/mm/pgtable.c @@ -1,4 +1,5 @@ #include +#include #define PGALLOC_GFP GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c index 3cc2193..e43ec60 100644 --- a/arch/sh/mm/pmb.c +++ b/arch/sh/mm/pmb.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/sparc/kernel/central.c b/arch/sparc/kernel/central.c index 4589ca3..415c86d 100644 --- a/arch/sparc/kernel/central.c +++ b/arch/sparc/kernel/central.c @@ -5,6 +5,7 @@ #include #include +#include #include #include #include diff --git a/arch/sparc/kernel/cpumap.c b/arch/sparc/kernel/cpumap.c index 7430ed0..8de64c8 100644 --- a/arch/sparc/kernel/cpumap.c +++ b/arch/sparc/kernel/cpumap.c @@ -4,6 +4,7 @@ */ #include +#include #include #include #include diff --git a/arch/sparc/kernel/hvapi.c b/arch/sparc/kernel/hvapi.c index 1d272c3..7c60afb 100644 --- a/arch/sparc/kernel/hvapi.c +++ b/arch/sparc/kernel/hvapi.c @@ -5,7 +5,6 @@ #include #include #include -#include #include #include diff --git a/arch/sparc/kernel/iommu.c b/arch/sparc/kernel/iommu.c index 8414549..47977a7 100644 --- a/arch/sparc/kernel/iommu.c +++ b/arch/sparc/kernel/iommu.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include diff --git a/arch/sparc/kernel/kprobes.c b/arch/sparc/kernel/kprobes.c index 6716584..a39d1ba 100644 --- a/arch/sparc/kernel/kprobes.c +++ b/arch/sparc/kernel/kprobes.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/sparc/kernel/led.c b/arch/sparc/kernel/led.c index 00d034e..3ae36f3 100644 --- a/arch/sparc/kernel/led.c +++ b/arch/sparc/kernel/led.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c index 0409d62..6a7b4db 100644 --- a/arch/sparc/kernel/leon_kernel.c +++ b/arch/sparc/kernel/leon_kernel.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c index 8578757..e1656fc 100644 --- a/arch/sparc/kernel/leon_smp.c +++ b/arch/sparc/kernel/leon_smp.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/arch/sparc/kernel/module.c b/arch/sparc/kernel/module.c index 0ee642f..f848aad 100644 --- a/arch/sparc/kernel/module.c +++ b/arch/sparc/kernel/module.c @@ -9,9 +9,9 @@ #include #include #include +#include #include #include -#include #include #include diff --git a/arch/sparc/kernel/of_device_common.c b/arch/sparc/kernel/of_device_common.c index cb8eb79..0247e68 100644 --- a/arch/sparc/kernel/of_device_common.c +++ b/arch/sparc/kernel/of_device_common.c @@ -4,7 +4,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/sparc/kernel/pci_msi.c b/arch/sparc/kernel/pci_msi.c index e1b0541..e0ef847 100644 --- a/arch/sparc/kernel/pci_msi.c +++ b/arch/sparc/kernel/pci_msi.c @@ -4,6 +4,7 @@ */ #include #include +#include #include #include "pci_impl.h" diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c index c49865b..40e29fc 100644 --- a/arch/sparc/kernel/process_32.c +++ b/arch/sparc/kernel/process_32.c @@ -17,13 +17,13 @@ #include #include #include -#include #include #include #include #include #include #include +#include #include #include diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c index a2a79e7..5f72de6 100644 --- a/arch/sparc/kernel/setup_64.c +++ b/arch/sparc/kernel/setup_64.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c index eb14844..4c53345 100644 --- a/arch/sparc/kernel/smp_64.c +++ b/arch/sparc/kernel/smp_64.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/arch/sparc/kernel/sun4c_irq.c b/arch/sparc/kernel/sun4c_irq.c index bc3adbf..892fb88 100644 --- a/arch/sparc/kernel/sun4c_irq.c +++ b/arch/sparc/kernel/sun4c_irq.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/sparc/kernel/sun4m_irq.c b/arch/sparc/kernel/sun4m_irq.c index 301892e..7f3b97f 100644 --- a/arch/sparc/kernel/sun4m_irq.c +++ b/arch/sparc/kernel/sun4m_irq.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/sparc/kernel/sys_sparc32.c b/arch/sparc/kernel/sys_sparc32.c index daded3b..c0ca875 100644 --- a/arch/sparc/kernel/sys_sparc32.c +++ b/arch/sparc/kernel/sys_sparc32.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -44,6 +43,7 @@ #include #include #include +#include #include #include diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c index bdc05a2..837dfc2 100644 --- a/arch/sparc/kernel/traps_64.c +++ b/arch/sparc/kernel/traps_64.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include diff --git a/arch/sparc/kernel/vio.c b/arch/sparc/kernel/vio.c index c28c714..3cb1def 100644 --- a/arch/sparc/kernel/vio.c +++ b/arch/sparc/kernel/vio.c @@ -10,6 +10,7 @@ */ #include +#include #include #include diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c index f27d103..5fdddf1 100644 --- a/arch/sparc/mm/hugetlbpage.c +++ b/arch/sparc/mm/hugetlbpage.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c index dc7c3b1..6d0e02c 100644 --- a/arch/sparc/mm/init_32.c +++ b/arch/sparc/mm/init_32.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index 9245a82..aaebc48 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -26,6 +25,7 @@ #include #include #include +#include #include #include diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c index df49b20..f5f75a5 100644 --- a/arch/sparc/mm/srmmu.c +++ b/arch/sparc/mm/srmmu.c @@ -10,7 +10,6 @@ #include #include -#include #include #include #include @@ -20,6 +19,7 @@ #include #include #include +#include #include #include diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c index 1865253..cf38846 100644 --- a/arch/sparc/mm/sun4c.c +++ b/arch/sparc/mm/sun4c.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/sparc/mm/tsb.c b/arch/sparc/mm/tsb.c index 36a0813..101d7c8 100644 --- a/arch/sparc/mm/tsb.c +++ b/arch/sparc/mm/tsb.c @@ -5,6 +5,7 @@ #include #include +#include #include #include #include diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index a74245a..f053726 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include "init.h" #include "irq_kern.h" diff --git a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c index 4ebc8a3..a11573b 100644 --- a/arch/um/drivers/port_kern.c +++ b/arch/um/drivers/port_kern.c @@ -7,6 +7,7 @@ #include "linux/interrupt.h" #include "linux/list.h" #include "linux/mutex.h" +#include "linux/slab.h" #include "linux/workqueue.h" #include "asm/atomic.h" #include "init.h" diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index c1ff690..da992a3 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -31,6 +31,7 @@ #include "linux/ctype.h" #include "linux/capability.h" #include "linux/mm.h" +#include "linux/slab.h" #include "linux/vmalloc.h" #include "linux/blkpg.h" #include "linux/genhd.h" diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c index fda30d2..97974c1 100644 --- a/arch/um/kernel/exec.c +++ b/arch/um/kernel/exec.c @@ -8,6 +8,7 @@ #include "linux/smp_lock.h" #include "linux/ptrace.h" #include "linux/sched.h" +#include "linux/slab.h" #include "asm/current.h" #include "asm/processor.h" #include "asm/uaccess.h" diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index 89474ba..a3f0b04 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c @@ -12,6 +12,7 @@ #include "linux/module.h" #include "linux/sched.h" #include "linux/seq_file.h" +#include "linux/slab.h" #include "as-layout.h" #include "kern_util.h" #include "os.h" diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c index a5d5e70..8137ccc 100644 --- a/arch/um/kernel/mem.c +++ b/arch/um/kernel/mem.c @@ -5,10 +5,10 @@ #include #include -#include #include #include #include +#include #include #include #include "as-layout.h" diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index 2f910a1..fab4371 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -7,13 +7,13 @@ #include #include #include -#include #include #include #include #include #include #include +#include #include #include #include diff --git a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c index 00197d3..869bec9 100644 --- a/arch/um/kernel/reboot.c +++ b/arch/um/kernel/reboot.c @@ -4,6 +4,7 @@ */ #include "linux/sched.h" +#include "linux/slab.h" #include "kern_util.h" #include "os.h" #include "skas.h" diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c index 8bfd1e9..3d099f9 100644 --- a/arch/um/kernel/skas/mmu.c +++ b/arch/um/kernel/skas/mmu.c @@ -5,6 +5,7 @@ #include "linux/mm.h" #include "linux/sched.h" +#include "linux/slab.h" #include "asm/pgalloc.h" #include "asm/pgtable.h" #include "as-layout.h" diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c index b6b1096..06d6ccf 100644 --- a/arch/um/os-Linux/helper.c +++ b/arch/um/os-Linux/helper.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include "kern_constants.h" diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c index a4846a8..3f2bf20 100644 --- a/arch/um/sys-i386/ldt.c +++ b/arch/um/sys-i386/ldt.c @@ -5,6 +5,7 @@ #include #include +#include #include #include "os.h" #include "proc_mm.h" diff --git a/arch/x86/crypto/fpu.c b/arch/x86/crypto/fpu.c index daef6cd..1a8f864 100644 --- a/arch/x86/crypto/fpu.c +++ b/arch/x86/crypto/fpu.c @@ -16,6 +16,7 @@ #include #include #include +#include #include struct crypto_fpu_ctx { diff --git a/arch/x86/ia32/ia32_aout.c b/arch/x86/ia32/ia32_aout.c index 280c019..0350311 100644 --- a/arch/x86/ia32/ia32_aout.c +++ b/arch/x86/ia32/ia32_aout.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c index 74c3543..626be15 100644 --- a/arch/x86/ia32/sys_ia32.c +++ b/arch/x86/ia32/sys_ia32.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 0061ea2..cd40aba 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index 3a4bf35..1a160d5 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index adb0ba0..f3dadb5 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c @@ -18,8 +18,8 @@ */ #include -#include #include +#include #include #include #include diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c index 9dc91b4..42f5350 100644 --- a/arch/x86/kernel/amd_iommu_init.c +++ b/arch/x86/kernel/amd_iommu_init.c @@ -19,8 +19,8 @@ #include #include -#include #include +#include #include #include #include diff --git a/arch/x86/kernel/apb_timer.c b/arch/x86/kernel/apb_timer.c index 4b70995..ff469e4 100644 --- a/arch/x86/kernel/apb_timer.c +++ b/arch/x86/kernel/apb_timer.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c index dd2b5f2..03ba1b8 100644 --- a/arch/x86/kernel/apic/es7000_32.c +++ b/arch/x86/kernel/apic/es7000_32.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 463de9a..127b871 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -36,6 +36,7 @@ #include #include #include /* time_after() */ +#include #ifdef CONFIG_ACPI #include #endif diff --git a/arch/x86/kernel/apic/nmi.c b/arch/x86/kernel/apic/nmi.c index 8aa65ad..1edaf15 100644 --- a/arch/x86/kernel/apic/nmi.c +++ b/arch/x86/kernel/apic/nmi.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index 49dbeae..c085d52 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/x86/kernel/bootflag.c b/arch/x86/kernel/bootflag.c index 30f25a7..5de7f4c 100644 --- a/arch/x86/kernel/bootflag.c +++ b/arch/x86/kernel/bootflag.c @@ -5,7 +5,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c index 1b1920f..4591680 100644 --- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include diff --git a/arch/x86/kernel/cpu/cpufreq/elanfreq.c b/arch/x86/kernel/cpu/cpufreq/elanfreq.c index 006b278..c587db4 100644 --- a/arch/x86/kernel/cpu/cpufreq/elanfreq.c +++ b/arch/x86/kernel/cpu/cpufreq/elanfreq.c @@ -20,7 +20,6 @@ #include #include -#include #include #include diff --git a/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c b/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c index ac27ec2..16e3483 100644 --- a/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c +++ b/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c @@ -80,6 +80,7 @@ #include #include #include +#include #include diff --git a/arch/x86/kernel/cpu/cpufreq/longrun.c b/arch/x86/kernel/cpu/cpufreq/longrun.c index da5f70f..e7b559d 100644 --- a/arch/x86/kernel/cpu/cpufreq/longrun.c +++ b/arch/x86/kernel/cpu/cpufreq/longrun.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include diff --git a/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c b/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c index 8696151..7b8a8ba 100644 --- a/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c +++ b/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include diff --git a/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c index ff36d29..ce7cde7 100644 --- a/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c +++ b/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k6.c b/arch/x86/kernel/cpu/cpufreq/powernow-k6.c index cb01dac..b3379d6 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k6.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k6.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c index 8d672ef..9b1ff37 100644 --- a/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c +++ b/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c @@ -20,6 +20,7 @@ #include /* current */ #include #include +#include #include #include diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c index 2ce8e0b..561758e 100644 --- a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c +++ b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include "speedstep-lib.h" diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c b/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c index ad0083a..a94ec6b 100644 --- a/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c +++ b/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c b/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c index 04d73c1..8abd869 100644 --- a/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c +++ b/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/x86/kernel/cpu/mcheck/mce-inject.c b/arch/x86/kernel/cpu/mcheck/mce-inject.c index 73734ba..e7dbde7 100644 --- a/arch/x86/kernel/cpu/mcheck/mce-inject.c +++ b/arch/x86/kernel/cpu/mcheck/mce-inject.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 3ab9c88..8a6f0af 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c index cda932c..224392d 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/x86/kernel/cpu/mcheck/mce_intel.c b/arch/x86/kernel/cpu/mcheck/mce_intel.c index d15df6e..62b48e4 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_intel.c +++ b/arch/x86/kernel/cpu/mcheck/mce_intel.c @@ -5,6 +5,7 @@ * Author: Andi Kleen */ +#include #include #include #include diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c index 9aa5dc7..fd31a44 100644 --- a/arch/x86/kernel/cpu/mtrr/generic.c +++ b/arch/x86/kernel/cpu/mtrr/generic.c @@ -6,7 +6,6 @@ #include #include -#include #include #include diff --git a/arch/x86/kernel/cpu/mtrr/if.c b/arch/x86/kernel/cpu/mtrr/if.c index e006e56..7928963 100644 --- a/arch/x86/kernel/cpu/mtrr/if.c +++ b/arch/x86/kernel/cpu/mtrr/if.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #define LINE_SIZE 80 diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 60398a0..0316ffe 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/x86/kernel/cpuid.c b/arch/x86/kernel/cpuid.c index 83e5e62..8b862d5 100644 --- a/arch/x86/kernel/cpuid.c +++ b/arch/x86/kernel/cpuid.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include diff --git a/arch/x86/kernel/crash_dump_32.c b/arch/x86/kernel/crash_dump_32.c index cd97ce1..6741455 100644 --- a/arch/x86/kernel/crash_dump_32.c +++ b/arch/x86/kernel/crash_dump_32.c @@ -5,6 +5,7 @@ * Copyright (C) IBM Corporation, 2004. All rights reserved */ +#include #include #include #include diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index ee4fa1b..d10a7e7 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c index c01a2b8..54c31c2 100644 --- a/arch/x86/kernel/i387.c +++ b/arch/x86/kernel/i387.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include diff --git a/arch/x86/kernel/i8259.c b/arch/x86/kernel/i8259.c index fb725ee..7c9f02c 100644 --- a/arch/x86/kernel/i8259.c +++ b/arch/x86/kernel/i8259.c @@ -5,7 +5,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c index f01d390..0ed2d30 100644 --- a/arch/x86/kernel/irqinit.c +++ b/arch/x86/kernel/irqinit.c @@ -5,7 +5,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/x86/kernel/k8.c b/arch/x86/kernel/k8.c index 9b89546..0f7bc20 100644 --- a/arch/x86/kernel/k8.c +++ b/arch/x86/kernel/k8.c @@ -2,8 +2,8 @@ * Shared support code for AMD K8 northbridges and derivates. * Copyright 2006 Andi Kleen, SUSE Labs. Subject to GPLv2. */ -#include #include +#include #include #include #include diff --git a/arch/x86/kernel/kdebugfs.c b/arch/x86/kernel/kdebugfs.c index e444357..8afd9f3 100644 --- a/arch/x86/kernel/kdebugfs.c +++ b/arch/x86/kernel/kdebugfs.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c index ec6ef60..ea69726 100644 --- a/arch/x86/kernel/ldt.c +++ b/arch/x86/kernel/ldt.c @@ -7,6 +7,7 @@ */ #include +#include #include #include #include diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c index 4a8bb82..035c8c5 100644 --- a/arch/x86/kernel/machine_kexec_64.c +++ b/arch/x86/kernel/machine_kexec_64.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/x86/kernel/mca_32.c b/arch/x86/kernel/mca_32.c index 845d80c..63eaf65 100644 --- a/arch/x86/kernel/mca_32.c +++ b/arch/x86/kernel/mca_32.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c index 89f386f..e0bc186 100644 --- a/arch/x86/kernel/module.c +++ b/arch/x86/kernel/module.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c index 206735a..4d4468e 100644 --- a/arch/x86/kernel/msr.c +++ b/arch/x86/kernel/msr.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index a4ac764..4b7e3d8 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c index f3af115..68cd24f 100644 --- a/arch/x86/kernel/pci-gart_64.c +++ b/arch/x86/kernel/pci-gart_64.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/x86/kernel/pci-nommu.c b/arch/x86/kernel/pci-nommu.c index 22be12b..3af4af8 100644 --- a/arch/x86/kernel/pci-nommu.c +++ b/arch/x86/kernel/pci-nommu.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index a503b1f..2e9b550 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 5d7ba1a..c08d1e3 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -55,7 +55,6 @@ #include #include #include -#include #include #include diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c index ec1de97..d801210 100644 --- a/arch/x86/kernel/smp.c +++ b/arch/x86/kernel/smp.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 06d98ae..be40f82 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include diff --git a/arch/x86/kernel/tlb_uv.c b/arch/x86/kernel/tlb_uv.c index 364d015ef..17b03dd 100644 --- a/arch/x86/kernel/tlb_uv.c +++ b/arch/x86/kernel/tlb_uv.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include diff --git a/arch/x86/kernel/uv_irq.c b/arch/x86/kernel/uv_irq.c index ece73d8..1d40336 100644 --- a/arch/x86/kernel/uv_irq.c +++ b/arch/x86/kernel/uv_irq.c @@ -10,6 +10,7 @@ #include #include +#include #include #include diff --git a/arch/x86/kernel/uv_time.c b/arch/x86/kernel/uv_time.c index 2b75ef63..56e421b 100644 --- a/arch/x86/kernel/uv_time.c +++ b/arch/x86/kernel/uv_time.c @@ -19,6 +19,7 @@ * Copyright (c) Dimitri Sivanich */ #include +#include #include #include diff --git a/arch/x86/kernel/vmi_32.c b/arch/x86/kernel/vmi_32.c index 7dd599d..ce9fbac 100644 --- a/arch/x86/kernel/vmi_32.c +++ b/arch/x86/kernel/vmi_32.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c index 294698b..0150aff 100644 --- a/arch/x86/kvm/i8254.c +++ b/arch/x86/kvm/i8254.c @@ -32,6 +32,7 @@ #define pr_fmt(fmt) "pit: " fmt #include +#include #include "irq.h" #include "i8254.h" diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c index 07771da..a790fa1 100644 --- a/arch/x86/kvm/i8259.c +++ b/arch/x86/kvm/i8259.c @@ -26,6 +26,7 @@ * Port from Qemu. */ #include +#include #include #include "irq.h" diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 4b224f9..1eb7a4a 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 741373e..48aeee8 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 52f78dd..445c594 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -26,6 +26,7 @@ #include #include #include +#include #include diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 14873b9..686492e 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "kvm_cache_regs.h" #include "x86.h" diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index e46282a..24cd0ee 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #undef TRACE_INCLUDE_FILE #define CREATE_TRACE_POINTS diff --git a/arch/x86/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c index f46c340..069ce7c 100644 --- a/arch/x86/mm/hugetlbpage.c +++ b/arch/x86/mm/hugetlbpage.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c index e71c5cb..a4a7d7d 100644 --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c @@ -1,3 +1,4 @@ +#include #include #include #include diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c index 5cb3f0f..bca7909 100644 --- a/arch/x86/mm/init_32.c +++ b/arch/x86/mm/init_32.c @@ -25,11 +25,11 @@ #include #include #include -#include #include #include #include #include +#include #include #include diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index e9b040e..ee41bba 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include diff --git a/arch/x86/mm/kmmio.c b/arch/x86/mm/kmmio.c index 536fb68..5d0e67f 100644 --- a/arch/x86/mm/kmmio.c +++ b/arch/x86/mm/kmmio.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c index 34a3291..3adff7d 100644 --- a/arch/x86/mm/mmio-mod.c +++ b/arch/x86/mm/mmio-mod.c @@ -26,6 +26,7 @@ #include #include +#include #include #include #include diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index cf07c26..28195c3 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -6,13 +6,13 @@ #include #include #include -#include #include #include #include #include #include #include +#include #include #include diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index ae9648e..edc8b95 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c index c9ba9de..5c4ee42 100644 --- a/arch/x86/mm/pgtable.c +++ b/arch/x86/mm/pgtable.c @@ -1,4 +1,5 @@ #include +#include #include #include #include diff --git a/arch/x86/mm/pgtable_32.c b/arch/x86/mm/pgtable_32.c index 46c8834..1a8faf0 100644 --- a/arch/x86/mm/pgtable_32.c +++ b/arch/x86/mm/pgtable_32.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index e311602..c7b1ebf 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index 294e10c..cf2e938 100644 --- a/arch/x86/pci/common.c +++ b/arch/x86/pci/common.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c index 8b10752..5d362b5 100644 --- a/arch/x86/pci/irq.c +++ b/arch/x86/pci/irq.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c index 8f3f9a5..39b9ebe 100644 --- a/arch/x86/pci/mmconfig-shared.c +++ b/arch/x86/pci/mmconfig-shared.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/x86/pci/pcbios.c b/arch/x86/pci/pcbios.c index 1c975cc..59a225c 100644 --- a/arch/x86/pci/pcbios.c +++ b/arch/x86/pci/pcbios.c @@ -4,6 +4,7 @@ #include #include +#include #include #include #include diff --git a/arch/x86/power/hibernate_32.c b/arch/x86/power/hibernate_32.c index 81197c6..3769079 100644 --- a/arch/x86/power/hibernate_32.c +++ b/arch/x86/power/hibernate_32.c @@ -6,6 +6,7 @@ * Copyright (c) 2006 Rafael J. Wysocki */ +#include #include #include diff --git a/arch/x86/power/hibernate_64.c b/arch/x86/power/hibernate_64.c index 65fdc86..d24f983 100644 --- a/arch/x86/power/hibernate_64.c +++ b/arch/x86/power/hibernate_64.c @@ -8,6 +8,7 @@ * Copyright (c) 2001 Patrick Mochel */ +#include #include #include #include diff --git a/arch/x86/vdso/vma.c b/arch/x86/vdso/vma.c index 21e1aeb..ac74869 100644 --- a/arch/x86/vdso/vma.c +++ b/arch/x86/vdso/vma.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/x86/xen/debugfs.c b/arch/x86/xen/debugfs.c index e133ce2..1304bce 100644 --- a/arch/x86/xen/debugfs.c +++ b/arch/x86/xen/debugfs.c @@ -1,5 +1,6 @@ #include #include +#include #include #include "debugfs.h" diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index b607239..65d8d79 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index f9eb7de..914f046 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index deafb65..a29693f 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c @@ -14,6 +14,7 @@ */ #include #include +#include #include #include diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c index 24ded31..e0500646 100644 --- a/arch/x86/xen/spinlock.c +++ b/arch/x86/xen/spinlock.c @@ -6,6 +6,7 @@ #include #include #include +#include #include diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c index 0d3f07c..32764b8 100644 --- a/arch/x86/xen/time.c +++ b/arch/x86/xen/time.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include diff --git a/arch/xtensa/kernel/pci-dma.c b/arch/xtensa/kernel/pci-dma.c index f5319d7..2783fda 100644 --- a/arch/xtensa/kernel/pci-dma.c +++ b/arch/xtensa/kernel/pci-dma.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c index e1a04a3..f167e0f 100644 --- a/arch/xtensa/kernel/process.c +++ b/arch/xtensa/kernel/process.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -31,6 +30,7 @@ #include #include #include +#include #include #include diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c index cdbc27c..ba150e5 100644 --- a/arch/xtensa/mm/init.c +++ b/arch/xtensa/mm/init.c @@ -18,11 +18,11 @@ #include #include #include +#include #include #include #include #include -#include #include #include diff --git a/arch/xtensa/platforms/iss/console.c b/arch/xtensa/platforms/iss/console.c index e60a1f5..2c723e8 100644 --- a/arch/xtensa/platforms/iss/console.c +++ b/arch/xtensa/platforms/iss/console.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include diff --git a/block/blk-barrier.c b/block/blk-barrier.c index 8618d89..6d88544 100644 --- a/block/blk-barrier.c +++ b/block/blk-barrier.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "blk.h" diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index 4b686ad..5fe03de 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "blk-cgroup.h" static DEFINE_SPINLOCK(blkio_list_lock); diff --git a/block/blk-integrity.c b/block/blk-integrity.c index 96e83c2..edce1ef 100644 --- a/block/blk-integrity.c +++ b/block/blk-integrity.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "blk.h" diff --git a/block/blk-ioc.c b/block/blk-ioc.c index 3f65c8a..d22c4c5 100644 --- a/block/blk-ioc.c +++ b/block/blk-ioc.c @@ -7,6 +7,7 @@ #include #include #include /* for max_pfn/max_low_pfn */ +#include #include "blk.h" diff --git a/block/blk-settings.c b/block/blk-settings.c index 31e7a93..d9a9db5 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c @@ -9,6 +9,7 @@ #include /* for max_pfn/max_low_pfn */ #include #include +#include #include "blk.h" diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index 2ae2cb3..c2b821f 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c @@ -2,6 +2,7 @@ * Functions related to sysfs handling */ #include +#include #include #include #include diff --git a/block/blk-tag.c b/block/blk-tag.c index 6b0f52c..ece65fc 100644 --- a/block/blk-tag.c +++ b/block/blk-tag.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "blk.h" diff --git a/block/bsg.c b/block/bsg.c index 46597a6..82d5882 100644 --- a/block/bsg.c +++ b/block/bsg.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index dee9d93..fc98a48 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -7,6 +7,7 @@ * Copyright (C) 2003 Jens Axboe */ #include +#include #include #include #include diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c index 4eb8e9e..f26051f 100644 --- a/block/compat_ioctl.c +++ b/block/compat_ioctl.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include diff --git a/block/ioctl.c b/block/ioctl.c index be48ea5..8905d2a 100644 --- a/block/ioctl.c +++ b/block/ioctl.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include diff --git a/block/noop-iosched.c b/block/noop-iosched.c index 3a0d369..232c4b3 100644 --- a/block/noop-iosched.c +++ b/block/noop-iosched.c @@ -5,6 +5,7 @@ #include #include #include +#include #include struct noop_data { diff --git a/crypto/algapi.c b/crypto/algapi.c index 3e4524e..76fae27 100644 --- a/crypto/algapi.c +++ b/crypto/algapi.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include "internal.h" diff --git a/crypto/algboss.c b/crypto/algboss.c index 412241c..c3c196b 100644 --- a/crypto/algboss.c +++ b/crypto/algboss.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include "internal.h" diff --git a/crypto/async_tx/async_pq.c b/crypto/async_tx/async_pq.c index ec87f53..fdd8257 100644 --- a/crypto/async_tx/async_pq.c +++ b/crypto/async_tx/async_pq.c @@ -24,6 +24,7 @@ #include #include #include +#include /** * pq_scribble_page - space to hold throwaway P or Q buffer for diff --git a/crypto/async_tx/raid6test.c b/crypto/async_tx/raid6test.c index f84f6b4..c132193 100644 --- a/crypto/async_tx/raid6test.c +++ b/crypto/async_tx/raid6test.c @@ -20,6 +20,7 @@ * */ #include +#include #include #undef pr diff --git a/crypto/hmac.c b/crypto/hmac.c index 15c2eb5..8d9544c 100644 --- a/crypto/hmac.c +++ b/crypto/hmac.c @@ -23,7 +23,6 @@ #include #include #include -#include #include struct hmac_ctx { diff --git a/crypto/rng.c b/crypto/rng.c index ba05e73..f93cb53 100644 --- a/crypto/rng.c +++ b/crypto/rng.c @@ -19,6 +19,7 @@ #include #include #include +#include #include static DEFINE_MUTEX(crypto_default_rng_lock); diff --git a/crypto/seqiv.c b/crypto/seqiv.c index 5a013a8..4c44912 100644 --- a/crypto/seqiv.c +++ b/crypto/seqiv.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index aa3f84c..a351599 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -18,8 +18,8 @@ #include #include #include +#include #include -#include #include #include #include diff --git a/crypto/xor.c b/crypto/xor.c index fc5b836f..b75182d 100644 --- a/crypto/xor.c +++ b/crypto/xor.c @@ -18,6 +18,7 @@ #define BH_TRACE 0 #include +#include #include #include #include diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index b6ed60b..56205a0 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c @@ -25,6 +25,7 @@ #include #include +#include #include #include #ifdef CONFIG_ACPI_PROCFS_POWER diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index 3597d73..d985713 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #define ACPI_MEMORY_DEVICE_CLASS "memory" diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index 7e52295..19dacfd 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 75f39f2..5717bd3 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -32,6 +32,7 @@ #include #include #include +#include #ifdef CONFIG_ACPI_PROCFS_POWER #include diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index b70cd37..37132dc 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -32,6 +32,7 @@ #include #include #include +#include #ifdef CONFIG_X86 #include #endif diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index f53fbe3..fd51c4a 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c index 5faf6c2..45cd03b 100644 --- a/drivers/acpi/container.c +++ b/drivers/acpi/container.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/acpi/debug.c b/drivers/acpi/debug.c index cc421b7..146135e 100644 --- a/drivers/acpi/debug.c +++ b/drivers/acpi/debug.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index d9a85f1..a9c429c 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -24,6 +24,7 @@ #include #include +#include #include #include #include diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 1ac28c6..35ba254 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/acpi/event.c b/drivers/acpi/event.c index c511071..d439314 100644 --- a/drivers/acpi/event.c +++ b/drivers/acpi/event.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 6d5b64b..4af6301 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index 843699e..b0a71ec 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index 04b0f00..8d47a58 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index d724736..aefce33 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include diff --git a/drivers/acpi/pci_slot.c b/drivers/acpi/pci_slot.c index 11f2197..07f7fea 100644 --- a/drivers/acpi/pci_slot.c +++ b/drivers/acpi/pci_slot.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 0f30c3c..ddc7678 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/acpi/power_meter.c b/drivers/acpi/power_meter.c index 834c5af..e8c32a4 100644 --- a/drivers/acpi/power_meter.c +++ b/drivers/acpi/power_meter.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 791ac7b..5128435 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -8,6 +8,7 @@ * - Added _PDC for platforms with Intel CPUs */ #include +#include #include #include diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index b5658cd..5675d97 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 37dfce7..5939e7f 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index d648a98..ba1bd26 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -30,6 +30,7 @@ #include #include #include +#include #ifdef CONFIG_X86 #include diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index 29c6f57..9ade1a5 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index 89ad111..4ff76e8 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c @@ -25,6 +25,7 @@ */ #include +#include #include #include #include diff --git a/drivers/acpi/sbshc.c b/drivers/acpi/sbshc.c index fd09229..36704b8 100644 --- a/drivers/acpi/sbshc.c +++ b/drivers/acpi/sbshc.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include "sbshc.h" diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 189cbc2..0261b11 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -4,6 +4,7 @@ #include #include +#include #include #include #include diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c index 743f244..4aaf249 100644 --- a/drivers/acpi/system.c +++ b/drivers/acpi/system.c @@ -25,6 +25,7 @@ #include #include +#include #include #include #include diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 5d38935..efad1f3 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index c9a49f4..b002a47 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c @@ -25,6 +25,7 @@ #include #include +#include #include #include #include diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index cbe6f39..6a01437 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index fdc9bcb..5326af2 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index c338066..83bc49f 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -90,6 +90,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 292fdbc..7b5eea7 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include "libata.h" diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 4a28420..3f6771e 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -58,6 +58,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c index 51f0ffb..00305f4 100644 --- a/drivers/ata/libata-pmp.c +++ b/drivers/ata/libata-pmp.c @@ -9,6 +9,7 @@ #include #include +#include #include "libata.h" const struct ata_port_operations sata_pmp_port_ops = { diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index bea003a..0088cde 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -33,6 +33,7 @@ * */ +#include #include #include #include diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 2774772..6411e0c 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -33,6 +33,7 @@ */ #include +#include #include #include #include diff --git a/drivers/ata/pata_acpi.c b/drivers/ata/pata_acpi.c index 8e5e132..1ea2be0 100644 --- a/drivers/ata/pata_acpi.c +++ b/drivers/ata/pata_acpi.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include diff --git a/drivers/ata/pata_at32.c b/drivers/ata/pata_at32.c index 5c129f9..66ce6a5 100644 --- a/drivers/ata/pata_at32.c +++ b/drivers/ata/pata_at32.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/ata/pata_at91.c b/drivers/ata/pata_at91.c index 376dd38..c6a946a 100644 --- a/drivers/ata/pata_at91.c +++ b/drivers/ata/pata_at91.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/ata/pata_atp867x.c b/drivers/ata/pata_atp867x.c index 6fe7ded..bb6e074 100644 --- a/drivers/ata/pata_atp867x.c +++ b/drivers/ata/pata_atp867x.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include diff --git a/drivers/ata/pata_cmd640.c b/drivers/ata/pata_cmd640.c index 6cd5d5d..45896b3 100644 --- a/drivers/ata/pata_cmd640.c +++ b/drivers/ata/pata_cmd640.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include diff --git a/drivers/ata/pata_icside.c b/drivers/ata/pata_icside.c index b663b7f..fa812e2 100644 --- a/drivers/ata/pata_icside.c +++ b/drivers/ata/pata_icside.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c index 9bde1cb..5cb286f 100644 --- a/drivers/ata/pata_it821x.c +++ b/drivers/ata/pata_it821x.c @@ -75,6 +75,7 @@ #include #include #include +#include #include #include diff --git a/drivers/ata/pata_macio.c b/drivers/ata/pata_macio.c index 4cc7bbd..211b643 100644 --- a/drivers/ata/pata_macio.c +++ b/drivers/ata/pata_macio.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c index 2bc2dbe..9f5b053 100644 --- a/drivers/ata/pata_mpc52xx.c +++ b/drivers/ata/pata_mpc52xx.c @@ -16,7 +16,7 @@ #include #include -#include +#include #include #include #include diff --git a/drivers/ata/pata_octeon_cf.c b/drivers/ata/pata_octeon_cf.c index 37ef416..005a444 100644 --- a/drivers/ata/pata_octeon_cf.c +++ b/drivers/ata/pata_octeon_cf.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c index 147de2f..3c3172d 100644 --- a/drivers/ata/pata_pcmcia.c +++ b/drivers/ata/pata_pcmcia.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/ata/pata_rb532_cf.c b/drivers/ata/pata_rb532_cf.c index 45f1e10..0ffd631 100644 --- a/drivers/ata/pata_rb532_cf.c +++ b/drivers/ata/pata_rb532_cf.c @@ -19,6 +19,7 @@ * */ +#include #include #include #include diff --git a/drivers/ata/pata_rdc.c b/drivers/ata/pata_rdc.c index 237a24d..37092cf 100644 --- a/drivers/ata/pata_rdc.c +++ b/drivers/ata/pata_rdc.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index c59b4071..741e7cb 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c @@ -58,6 +58,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/ata/pdc_adma.c b/drivers/ata/pdc_adma.c index 6c65b07..5904cfd 100644 --- a/drivers/ata/pdc_adma.c +++ b/drivers/ata/pdc_adma.c @@ -34,6 +34,7 @@ #include #include +#include #include #include #include diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index ce4136e..a69192b 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c index 4406902..27dc6c8 100644 --- a/drivers/ata/sata_inic162x.c +++ b/drivers/ata/sata_inic162x.c @@ -39,6 +39,7 @@ * happy to assist. */ +#include #include #include #include diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index df8ee32..71cc0d4 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -64,6 +64,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index 684fe04..2a98b09 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c @@ -38,6 +38,7 @@ #include #include +#include #include #include #include diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c index 6330628..5356ec0 100644 --- a/drivers/ata/sata_promise.c +++ b/drivers/ata/sata_promise.c @@ -33,6 +33,7 @@ #include #include +#include #include #include #include diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c index 326c0cf..92ba45e 100644 --- a/drivers/ata/sata_qstor.c +++ b/drivers/ata/sata_qstor.c @@ -29,6 +29,7 @@ #include #include +#include #include #include #include diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c index 1370df6..433b6b8 100644 --- a/drivers/ata/sata_sil24.c +++ b/drivers/ata/sata_sil24.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c index bbcf970..232468f 100644 --- a/drivers/ata/sata_sx4.c +++ b/drivers/ata/sata_sx4.c @@ -81,6 +81,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/ata/sata_uli.c b/drivers/ata/sata_uli.c index e5bff47..011e098 100644 --- a/drivers/ata/sata_uli.c +++ b/drivers/ata/sata_uli.c @@ -26,6 +26,7 @@ #include #include +#include #include #include #include diff --git a/drivers/atm/adummy.c b/drivers/atm/adummy.c index 5effec6..6d44f07 100644 --- a/drivers/atm/adummy.c +++ b/drivers/atm/adummy.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c index 8af2341..9d18644 100644 --- a/drivers/atm/ambassador.c +++ b/drivers/atm/ambassador.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include diff --git a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c index 02ad83d..b867121 100644 --- a/drivers/atm/atmtcp.c +++ b/drivers/atm/atmtcp.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c index 0c30261..719ec5a 100644 --- a/drivers/atm/eni.c +++ b/drivers/atm/eni.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c index cd5049a..6e600af 100644 --- a/drivers/atm/firestream.c +++ b/drivers/atm/firestream.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/atm/he.c b/drivers/atm/he.c index e8c6529..c213e0d 100644 --- a/drivers/atm/he.c +++ b/drivers/atm/he.c @@ -67,6 +67,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c index 4e49021..54720ba 100644 --- a/drivers/atm/horizon.c +++ b/drivers/atm/horizon.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include diff --git a/drivers/atm/idt77105.c b/drivers/atm/idt77105.c index 84672dc..dab5cf5 100644 --- a/drivers/atm/idt77105.c +++ b/drivers/atm/idt77105.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c index 01f36c0..98657a6 100644 --- a/drivers/atm/idt77252.c +++ b/drivers/atm/idt77252.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c index 25a4c86..ee9ddeb 100644 --- a/drivers/atm/iphase.c +++ b/drivers/atm/iphase.c @@ -54,6 +54,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c index 23d9505..cbe15a8 100644 --- a/drivers/atm/lanai.c +++ b/drivers/atm/lanai.c @@ -55,6 +55,7 @@ */ #include +#include #include #include #include diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c index 5083840..b7473a6 100644 --- a/drivers/atm/nicstar.c +++ b/drivers/atm/nicstar.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c index 51eed67..ded76c4 100644 --- a/drivers/atm/solos-pci.c +++ b/drivers/atm/solos-pci.c @@ -40,6 +40,7 @@ #include #include #include +#include #define VERSION "0.07" #define PTAG "solos-pci" diff --git a/drivers/atm/suni.c b/drivers/atm/suni.c index 6dd3f59..da4b91f 100644 --- a/drivers/atm/suni.c +++ b/drivers/atm/suni.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/atm/uPD98402.c b/drivers/atm/uPD98402.c index fc8cb07..c45ae05 100644 --- a/drivers/atm/uPD98402.c +++ b/drivers/atm/uPD98402.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c index 2e9635b..702acce 100644 --- a/drivers/atm/zatm.c +++ b/drivers/atm/zatm.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/auxdisplay/cfag12864b.c b/drivers/auxdisplay/cfag12864b.c index eacb175..4975859 100644 --- a/drivers/auxdisplay/cfag12864b.c +++ b/drivers/auxdisplay/cfag12864b.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/auxdisplay/cfag12864bfb.c b/drivers/auxdisplay/cfag12864bfb.c index b0ca5a4..3fecfb4 100644 --- a/drivers/auxdisplay/cfag12864bfb.c +++ b/drivers/auxdisplay/cfag12864bfb.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 71f6af5..12eec3f 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include "base.h" diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index b5242e1..f35719a 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "base.h" diff --git a/drivers/base/devres.c b/drivers/base/devres.c index 05dd307..cf7a0c7 100644 --- a/drivers/base/devres.c +++ b/drivers/base/devres.c @@ -9,6 +9,7 @@ #include #include +#include #include "base.h" diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index dac478c..057cf11 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c @@ -23,6 +23,7 @@ #include #include #include +#include static struct vfsmount *dev_mnt; diff --git a/drivers/base/dma-coherent.c b/drivers/base/dma-coherent.c index 962a3b5..d4d8ce5 100644 --- a/drivers/base/dma-coherent.c +++ b/drivers/base/dma-coherent.c @@ -2,6 +2,7 @@ * Coherent per-device memory handling. * Borrowed from i386 */ +#include #include #include diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c index ca9186f..763d59c 100644 --- a/drivers/base/dma-mapping.c +++ b/drivers/base/dma-mapping.c @@ -8,6 +8,7 @@ */ #include +#include /* * Managed DMA API diff --git a/drivers/base/driver.c b/drivers/base/driver.c index 90c9fff..b631f7c 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include "base.h" diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 18518ba..985da11 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -19,6 +19,7 @@ #include #include #include +#include #define to_dev(obj) container_of(obj, struct device, kobj) diff --git a/drivers/base/memory.c b/drivers/base/memory.c index db0848e..4f4aa58 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/drivers/base/module.c b/drivers/base/module.c index 103be9c..f32f2f9 100644 --- a/drivers/base/module.c +++ b/drivers/base/module.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include "base.h" diff --git a/drivers/base/node.c b/drivers/base/node.c index 93b3ac6..985abd7 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c @@ -15,6 +15,7 @@ #include #include #include +#include static struct sysdev_class_attribute *node_state_attrs[]; diff --git a/drivers/base/sys.c b/drivers/base/sys.c index 8980fee..9354dc1 100644 --- a/drivers/base/sys.c +++ b/drivers/base/sys.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c index 0552258..0182a22 100644 --- a/drivers/block/amiflop.c +++ b/drivers/block/amiflop.c @@ -54,6 +54,7 @@ */ #include +#include #include #include diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c index 3af97d4..035cefe 100644 --- a/drivers/block/aoe/aoeblk.c +++ b/drivers/block/aoe/aoeblk.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include "aoe.h" diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c index 62141ec..4a1b9e74 100644 --- a/drivers/block/aoe/aoechr.c +++ b/drivers/block/aoe/aoechr.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include "aoe.h" diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c index 64a223b..5674bd0 100644 --- a/drivers/block/aoe/aoecmd.c +++ b/drivers/block/aoe/aoecmd.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include diff --git a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c index fa67027..0849280 100644 --- a/drivers/block/aoe/aoedev.c +++ b/drivers/block/aoe/aoedev.c @@ -8,6 +8,7 @@ #include #include #include +#include #include "aoe.h" static void dummy_timer(ulong); diff --git a/drivers/block/aoe/aoenet.c b/drivers/block/aoe/aoenet.c index ce0d62c..4d3bc0d 100644 --- a/drivers/block/aoe/aoenet.c +++ b/drivers/block/aoe/aoenet.c @@ -4,6 +4,7 @@ * Ethernet portion of AoE driver */ +#include #include #include #include diff --git a/drivers/block/brd.c b/drivers/block/brd.c index c6ddeac..6081e81 100644 --- a/drivers/block/brd.c +++ b/drivers/block/brd.c @@ -15,9 +15,9 @@ #include #include #include -#include #include #include /* invalidate_bh_lrus() */ +#include #include diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c index b61057e..3d6f3d9 100644 --- a/drivers/block/drbd/drbd_bitmap.c +++ b/drivers/block/drbd/drbd_bitmap.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include "drbd_int.h" diff --git a/drivers/block/drbd/drbd_proc.c b/drivers/block/drbd/drbd_proc.c index df8ad96..be3374b 100644 --- a/drivers/block/drbd/drbd_proc.c +++ b/drivers/block/drbd/drbd_proc.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/block/hd.c b/drivers/block/hd.c index 5116c65..034e6df 100644 --- a/drivers/block/hd.c +++ b/drivers/block/hd.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/block/loop.c b/drivers/block/loop.c index bd112c8..cb69929 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -71,7 +71,6 @@ #include /* for invalidate_bdev() */ #include #include -#include #include #include diff --git a/drivers/block/mg_disk.c b/drivers/block/mg_disk.c index 5416c9a..28db925 100644 --- a/drivers/block/mg_disk.c +++ b/drivers/block/mg_disk.c @@ -23,6 +23,7 @@ #include #include #include +#include #define MG_RES_SEC (CONFIG_MG_DISK_RES << 1) diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index cc923a5..218d091 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/block/osdblk.c b/drivers/block/osdblk.c index eb2091a..6cd8b70 100644 --- a/drivers/block/osdblk.c +++ b/drivers/block/osdblk.c @@ -63,6 +63,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c index e712cd5..c1e5cd0 100644 --- a/drivers/block/paride/pd.c +++ b/drivers/block/paride/pd.c @@ -145,6 +145,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_GEO, D_SBY, D_DLY, D_SLV}; #include #include +#include #include #include #include diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 39c8514..ddf1942 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c @@ -57,6 +57,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c index bc95469..3b419e3 100644 --- a/drivers/block/ps3disk.c +++ b/drivers/block/ps3disk.c @@ -20,6 +20,7 @@ #include #include +#include #include #include diff --git a/drivers/block/ps3vram.c b/drivers/block/ps3vram.c index e446082..b3bdb8a 100644 --- a/drivers/block/ps3vram.c +++ b/drivers/block/ps3vram.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include diff --git a/drivers/block/swim.c b/drivers/block/swim.c index 821c283..e463657 100644 --- a/drivers/block/swim.c +++ b/drivers/block/swim.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include diff --git a/drivers/block/ub.c b/drivers/block/ub.c index 2e88983..0536b5b 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #define DRV_NAME "ub" diff --git a/drivers/block/umem.c b/drivers/block/umem.c index ad1ba39..2f9470f 100644 --- a/drivers/block/umem.c +++ b/drivers/block/umem.c @@ -40,13 +40,13 @@ #include #include #include +#include #include #include #include #include #include #include -#include #include #include /* O_ACCMODE */ diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 3c64af0..4b12b82 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -1,5 +1,6 @@ //#define DEBUG #include +#include #include #include #include diff --git a/drivers/block/xd.c b/drivers/block/xd.c index 1a325fb..18a80ff 100644 --- a/drivers/block/xd.c +++ b/drivers/block/xd.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 9c09694..82ed403 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include diff --git a/drivers/block/z2ram.c b/drivers/block/z2ram.c index 64f941e..9114654 100644 --- a/drivers/block/z2ram.c +++ b/drivers/block/z2ram.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include diff --git a/drivers/bluetooth/btmrvl_debugfs.c b/drivers/bluetooth/btmrvl_debugfs.c index 3126a3d..b50b41d 100644 --- a/drivers/bluetooth/btmrvl_debugfs.c +++ b/drivers/bluetooth/btmrvl_debugfs.c @@ -19,6 +19,7 @@ **/ #include +#include #include #include diff --git a/drivers/bluetooth/btmrvl_drv.h b/drivers/bluetooth/btmrvl_drv.h index 523d197..2047275 100644 --- a/drivers/bluetooth/btmrvl_drv.h +++ b/drivers/bluetooth/btmrvl_drv.h @@ -21,6 +21,7 @@ #include #include +#include #include #define BTM_HEADER_LEN 4 diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index 94f1f55..0dba76a 100644 --- a/drivers/bluetooth/btmrvl_sdio.c +++ b/drivers/bluetooth/btmrvl_sdio.c @@ -19,6 +19,7 @@ **/ #include +#include #include #include diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c index 73dbf40..a7637d7 100644 --- a/drivers/char/agp/amd-k7-agp.c +++ b/drivers/char/agp/amd-k7-agp.c @@ -6,9 +6,9 @@ #include #include #include -#include #include #include +#include #include "agp.h" #define AMD_MMBASE 0x14 diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c index c3ab46d..ee4f855 100644 --- a/drivers/char/agp/backend.c +++ b/drivers/char/agp/backend.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/char/agp/compat_ioctl.c b/drivers/char/agp/compat_ioctl.c index 58c57cb..9d2c97a 100644 --- a/drivers/char/agp/compat_ioctl.c +++ b/drivers/char/agp/compat_ioctl.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include "agp.h" #include "compat_ioctl.h" diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c index c505439..fb86708e 100644 --- a/drivers/char/agp/generic.c +++ b/drivers/char/agp/generic.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/char/agp/hp-agp.c b/drivers/char/agp/hp-agp.c index 58752b7..056b289 100644 --- a/drivers/char/agp/hp-agp.c +++ b/drivers/char/agp/hp-agp.c @@ -15,6 +15,7 @@ #include #include #include +#include #include diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index b78d5c3..d41331b 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -4,6 +4,7 @@ #include #include +#include #include #include #include diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c index 7e36d2b..10f24e3 100644 --- a/drivers/char/agp/nvidia-agp.c +++ b/drivers/char/agp/nvidia-agp.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/char/agp/sgi-agp.c b/drivers/char/agp/sgi-agp.c index 0d426ae..ffa888c 100644 --- a/drivers/char/agp/sgi-agp.c +++ b/drivers/char/agp/sgi-agp.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c index d89da4a..6f48931 100644 --- a/drivers/char/agp/uninorth-agp.c +++ b/drivers/char/agp/uninorth-agp.c @@ -3,6 +3,7 @@ */ #include #include +#include #include #include #include diff --git a/drivers/char/bfin_jtag_comm.c b/drivers/char/bfin_jtag_comm.c index 2628c74..e397df3 100644 --- a/drivers/char/bfin_jtag_comm.c +++ b/drivers/char/bfin_jtag_comm.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/char/briq_panel.c b/drivers/char/briq_panel.c index d8cff90..555cd93 100644 --- a/drivers/char/briq_panel.c +++ b/drivers/char/briq_panel.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/char/bsr.c b/drivers/char/bsr.c index c02db01..7fef305 100644 --- a/drivers/char/bsr.c +++ b/drivers/char/bsr.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index b861c08..9824b416 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c @@ -79,6 +79,7 @@ #include #include #include +#include #include #include diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c index 85832ab..8a1b28a 100644 --- a/drivers/char/dsp56k.c +++ b/drivers/char/dsp56k.c @@ -24,7 +24,6 @@ */ #include -#include /* for kmalloc() and kfree() */ #include #include #include diff --git a/drivers/char/epca.c b/drivers/char/epca.c index 17b044a..6f5ffe1 100644 --- a/drivers/char/epca.c +++ b/drivers/char/epca.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c index d400cbd..5954ee1 100644 --- a/drivers/char/generic_serial.c +++ b/drivers/char/generic_serial.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #define DEBUG diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index 9c5eea3..9ded667 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index ba55bba..d3890e8 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c @@ -38,6 +38,7 @@ #include #include #include +#include #include diff --git a/drivers/char/hvc_iucv.c b/drivers/char/hvc_iucv.c index 37b0542..5a80ad6 100644 --- a/drivers/char/hvc_iucv.c +++ b/drivers/char/hvc_iucv.c @@ -12,6 +12,7 @@ #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt #include +#include #include #include #include diff --git a/drivers/char/hvcs.c b/drivers/char/hvcs.c index 266b858..bedc6c1 100644 --- a/drivers/char/hvcs.c +++ b/drivers/char/hvcs.c @@ -74,6 +74,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/char/hw_random/intel-rng.c b/drivers/char/hw_random/intel-rng.c index 91b53eb..86fe45c 100644 --- a/drivers/char/hw_random/intel-rng.c +++ b/drivers/char/hw_random/intel-rng.c @@ -30,6 +30,7 @@ #include #include #include +#include #include diff --git a/drivers/char/hw_random/octeon-rng.c b/drivers/char/hw_random/octeon-rng.c index 54b0d9b..9cd0fec 100644 --- a/drivers/char/hw_random/octeon-rng.c +++ b/drivers/char/hw_random/octeon-rng.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff --git a/drivers/char/hw_random/tx4939-rng.c b/drivers/char/hw_random/tx4939-rng.c index 544d908..0bc0cb7 100644 --- a/drivers/char/hw_random/tx4939-rng.c +++ b/drivers/char/hw_random/tx4939-rng.c @@ -14,6 +14,7 @@ #include #include #include +#include #define TX4939_RNG_RCSR 0x00000000 #define TX4939_RNG_ROR(n) (0x00000018 + (n) * 8) diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c index be2e8f9..0fa2e4a 100644 --- a/drivers/char/isicom.c +++ b/drivers/char/isicom.c @@ -130,6 +130,7 @@ #include #include #include +#include #include #include diff --git a/drivers/char/mbcs.c b/drivers/char/mbcs.c index 87c67b4..83bef4e 100644 --- a/drivers/char/mbcs.c +++ b/drivers/char/mbcs.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/char/misc.c b/drivers/char/misc.c index 94a136e..92ab03d 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include #include @@ -49,6 +48,7 @@ #include #include #include +#include /* * Head entry for the doubly linked miscdevice list diff --git a/drivers/char/mmtimer.c b/drivers/char/mmtimer.c index 04fd0d8..ea7c99f 100644 --- a/drivers/char/mmtimer.c +++ b/drivers/char/mmtimer.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c index 166495d..107b0bd 100644 --- a/drivers/char/moxa.c +++ b/drivers/char/moxa.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index e0c5d2a..95c9f54 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c @@ -33,12 +33,12 @@ #include #include #include -#include #include #include #include #include #include +#include #include #include diff --git a/drivers/char/nozomi.c b/drivers/char/nozomi.c index a3f32a1..a663800 100644 --- a/drivers/char/nozomi.c +++ b/drivers/char/nozomi.c @@ -55,6 +55,7 @@ #include #include #include +#include #include #include diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c index 5eb83c3..47e8f7b 100644 --- a/drivers/char/nvram.c +++ b/drivers/char/nvram.c @@ -100,7 +100,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/char/pcmcia/ipwireless/network.c b/drivers/char/pcmcia/ipwireless/network.c index 590762a..6592016 100644 --- a/drivers/char/pcmcia/ipwireless/network.c +++ b/drivers/char/pcmcia/ipwireless/network.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c index 432655b..fdd3754 100644 --- a/drivers/char/ppdev.c +++ b/drivers/char/ppdev.c @@ -64,6 +64,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/char/ps3flash.c b/drivers/char/ps3flash.c index f424d39..606048b 100644 --- a/drivers/char/ps3flash.c +++ b/drivers/char/ps3flash.c @@ -20,6 +20,7 @@ #include #include +#include #include #include diff --git a/drivers/char/pty.c b/drivers/char/pty.c index 5ee4248..d83a431 100644 --- a/drivers/char/pty.c +++ b/drivers/char/pty.c @@ -29,6 +29,7 @@ #include #include #include +#include #include diff --git a/drivers/char/raw.c b/drivers/char/raw.c index 64acd05..d331c59 100644 --- a/drivers/char/raw.c +++ b/drivers/char/raw.c @@ -20,6 +20,7 @@ #include #include #include +#include #include diff --git a/drivers/char/rio/rioinit.c b/drivers/char/rio/rioinit.c index be0ba40..24a282b 100644 --- a/drivers/char/rio/rioinit.c +++ b/drivers/char/rio/rioinit.c @@ -31,7 +31,6 @@ */ #include -#include #include #include #include diff --git a/drivers/char/rio/riointr.c b/drivers/char/rio/riointr.c index 71f8760..2e71aec 100644 --- a/drivers/char/rio/riointr.c +++ b/drivers/char/rio/riointr.c @@ -31,7 +31,6 @@ */ #include -#include #include #include #include diff --git a/drivers/char/rio/rioparam.c b/drivers/char/rio/rioparam.c index d687c17..6415f3f 100644 --- a/drivers/char/rio/rioparam.c +++ b/drivers/char/rio/rioparam.c @@ -31,7 +31,6 @@ */ #include -#include #include #include #include diff --git a/drivers/char/rio/rioroute.c b/drivers/char/rio/rioroute.c index 706c2a2..f9b936a 100644 --- a/drivers/char/rio/rioroute.c +++ b/drivers/char/rio/rioroute.c @@ -31,7 +31,6 @@ */ #include -#include #include #include #include diff --git a/drivers/char/rio/riotty.c b/drivers/char/rio/riotty.c index 47fab7c..8a90393 100644 --- a/drivers/char/rio/riotty.c +++ b/drivers/char/rio/riotty.c @@ -34,7 +34,6 @@ #include #include -#include #include #include #include diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c index 1ec3d5c..8dfd247 100644 --- a/drivers/char/serial167.c +++ b/drivers/char/serial167.c @@ -64,6 +64,7 @@ #include #include #include +#include #include #include diff --git a/drivers/char/snsc_event.c b/drivers/char/snsc_event.c index 55a9589..ee15694 100644 --- a/drivers/char/snsc_event.c +++ b/drivers/char/snsc_event.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index bba727c..73f66d0 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #include diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c index 07ac14d..2c24fcd 100644 --- a/drivers/char/specialix.c +++ b/drivers/char/specialix.c @@ -94,6 +94,7 @@ #include #include #include +#include #include "specialix_io8.h" #include "cd1865.h" diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index 1ae2de7..59de252 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index f06bb37..068c816 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -24,6 +24,7 @@ */ #include +#include #include #include diff --git a/drivers/char/tpm/tpm_bios.c b/drivers/char/tpm/tpm_bios.c index bf2170f..0636520 100644 --- a/drivers/char/tpm/tpm_bios.c +++ b/drivers/char/tpm/tpm_bios.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include "tpm.h" diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c index 70efba2..a605cb7 100644 --- a/drivers/char/tpm/tpm_nsc.c +++ b/drivers/char/tpm/tpm_nsc.c @@ -20,6 +20,7 @@ */ #include +#include #include "tpm.h" /* National definitions */ diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index 2405f17..9434599 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include "tpm.h" diff --git a/drivers/char/tty_audit.c b/drivers/char/tty_audit.c index 283a15b..1b8ee59 100644 --- a/drivers/char/tty_audit.c +++ b/drivers/char/tty_audit.c @@ -10,6 +10,7 @@ */ #include +#include #include struct tty_audit_buf { diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c index 042c814..1144a04 100644 --- a/drivers/char/viotape.c +++ b/drivers/char/viotape.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 44288ce..026ea6c 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/char/vme_scc.c b/drivers/char/vme_scc.c index 8b24729..12de120 100644 --- a/drivers/char/vme_scc.c +++ b/drivers/char/vme_scc.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c index 4846d50..7261b8d 100644 --- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c +++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c @@ -86,6 +86,7 @@ #include #include #include +#include #include #include diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index 578595c..744f748 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c @@ -29,6 +29,7 @@ #include #include #include +#include struct sh_cmt_priv { void __iomem *mapbase; diff --git a/drivers/clocksource/sh_mtu2.c b/drivers/clocksource/sh_mtu2.c index 4c8a759..5fb78bf 100644 --- a/drivers/clocksource/sh_mtu2.c +++ b/drivers/clocksource/sh_mtu2.c @@ -29,6 +29,7 @@ #include #include #include +#include struct sh_mtu2_priv { void __iomem *mapbase; diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c index 961f5b5..fc9ff1e 100644 --- a/drivers/clocksource/sh_tmu.c +++ b/drivers/clocksource/sh_tmu.c @@ -30,6 +30,7 @@ #include #include #include +#include struct sh_tmu_priv { void __iomem *mapbase; diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c index 6069790..a7f046b 100644 --- a/drivers/connector/cn_proc.c +++ b/drivers/connector/cn_proc.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c index 537c29a..1d48f40 100644 --- a/drivers/connector/connector.c +++ b/drivers/connector/connector.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index 5a62d67..00d73fc 100644 --- a/drivers/cpufreq/cpufreq_stats.c +++ b/drivers/cpufreq/cpufreq_stats.c @@ -10,6 +10,7 @@ */ #include +#include #include #include #include diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c index 8719b36..0ba9c8b 100644 --- a/drivers/cpuidle/sysfs.c +++ b/drivers/cpuidle/sysfs.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include "cpuidle.h" diff --git a/drivers/crypto/amcc/crypto4xx_core.c b/drivers/crypto/amcc/crypto4xx_core.c index 1c3849f..6c4c8b7 100644 --- a/drivers/crypto/amcc/crypto4xx_core.c +++ b/drivers/crypto/amcc/crypto4xx_core.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/crypto/ixp4xx_crypto.c b/drivers/crypto/ixp4xx_crypto.c index 6c6656d..f17ddf3 100644 --- a/drivers/crypto/ixp4xx_crypto.c +++ b/drivers/crypto/ixp4xx_crypto.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include diff --git a/drivers/crypto/mv_cesa.c b/drivers/crypto/mv_cesa.c index b21ef63..6f29012 100644 --- a/drivers/crypto/mv_cesa.c +++ b/drivers/crypto/mv_cesa.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "mv_cesa.h" /* diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c index 8c2f370..2e992bc 100644 --- a/drivers/crypto/padlock-aes.c +++ b/drivers/crypto/padlock-aes.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index fd529d6..dc558a0 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include diff --git a/drivers/dca/dca-core.c b/drivers/dca/dca-core.c index 52e6bb7..8661c84 100644 --- a/drivers/dca/dca-core.c +++ b/drivers/dca/dca-core.c @@ -27,6 +27,7 @@ #include #include #include +#include #define DCA_VERSION "1.12.1" diff --git a/drivers/dca/dca-sysfs.c b/drivers/dca/dca-sysfs.c index ee916c9..5e8f335 100644 --- a/drivers/dca/dca-sysfs.c +++ b/drivers/dca/dca-sysfs.c @@ -26,6 +26,7 @@ #include #include #include +#include static struct class *dca_class; static struct idr dca_idr; diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index efc1a61..278cf5b 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "at_hdmac_regs.h" diff --git a/drivers/dma/coh901318_lli.c b/drivers/dma/coh901318_lli.c index 71d58c1..9f7e0e6a 100644 --- a/drivers/dma/coh901318_lli.c +++ b/drivers/dma/coh901318_lli.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include "coh901318_lli.h" diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index 87399ca..d18b5d0 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c @@ -58,6 +58,7 @@ #include #include #include +#include static DEFINE_MUTEX(dma_list_mutex); static LIST_HEAD(dma_device_list); diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c index 6fa55fe..68d58c4 100644 --- a/drivers/dma/dmatest.c +++ b/drivers/dma/dmatest.c @@ -14,6 +14,7 @@ #include #include #include +#include #include static unsigned int test_buf_size = 16384; diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index bbb4be5..88f470f 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c index 0099340..3e5a800 100644 --- a/drivers/dma/ioat/dma.c +++ b/drivers/dma/ioat/dma.c @@ -27,6 +27,7 @@ #include #include +#include #include #include #include diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c index 1ed5d66..b5ae56c 100644 --- a/drivers/dma/ioat/dma_v2.c +++ b/drivers/dma/ioat/dma_v2.c @@ -27,6 +27,7 @@ #include #include +#include #include #include #include diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c index 26febc5..6740e31 100644 --- a/drivers/dma/ioat/dma_v3.c +++ b/drivers/dma/ioat/dma_v3.c @@ -57,6 +57,7 @@ */ #include +#include #include #include #include "registers.h" diff --git a/drivers/dma/ioat/pci.c b/drivers/dma/ioat/pci.c index d545fae..99ec267 100644 --- a/drivers/dma/ioat/pci.c +++ b/drivers/dma/ioat/pci.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "dma.h" #include "dma_v2.h" #include "registers.h" diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c index ca6e6a0..1ebc801 100644 --- a/drivers/dma/iop-adma.c +++ b/drivers/dma/iop-adma.c @@ -32,6 +32,7 @@ #include #include #include +#include #include diff --git a/drivers/dma/iovlock.c b/drivers/dma/iovlock.c index c0a272c..bb48a57 100644 --- a/drivers/dma/iovlock.c +++ b/drivers/dma/iovlock.c @@ -27,6 +27,7 @@ #include #include +#include #include /* for memcpy_toiovec */ #include #include diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c index 3fdf1f4..bbbd585 100644 --- a/drivers/dma/mpc512x_dma.c +++ b/drivers/dma/mpc512x_dma.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index 466ab10..e2fd34d 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c index e69d87f..d44626f 100644 --- a/drivers/dma/ppc4xx/adma.c +++ b/drivers/dma/ppc4xx/adma.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index 5d17e09..7cc31b3 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include diff --git a/drivers/edac/amd76x_edac.c b/drivers/edac/amd76x_edac.c index 2b95f1a..f2330f8 100644 --- a/drivers/edac/amd76x_edac.c +++ b/drivers/edac/amd76x_edac.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include "edac_core.h" diff --git a/drivers/edac/cpc925_edac.c b/drivers/edac/cpc925_edac.c index 3d50274..1609a19 100644 --- a/drivers/edac/cpc925_edac.c +++ b/drivers/edac/cpc925_edac.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "edac_core.h" #include "edac_module.h" diff --git a/drivers/edac/e752x_edac.c b/drivers/edac/e752x_edac.c index 243e9aa..ae3f80c 100644 --- a/drivers/edac/e752x_edac.c +++ b/drivers/edac/e752x_edac.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include "edac_core.h" diff --git a/drivers/edac/e7xxx_edac.c b/drivers/edac/e7xxx_edac.c index c7d11cc..1731d72 100644 --- a/drivers/edac/e7xxx_edac.c +++ b/drivers/edac/e7xxx_edac.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include "edac_core.h" diff --git a/drivers/edac/edac_device_sysfs.c b/drivers/edac/edac_device_sysfs.c index 5fdedbc..0709681 100644 --- a/drivers/edac/edac_device_sysfs.c +++ b/drivers/edac/edac_device_sysfs.c @@ -12,6 +12,7 @@ #include #include +#include #include "edac_core.h" #include "edac_module.h" diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c index 88840e9..418b65f 100644 --- a/drivers/edac/edac_mc_sysfs.c +++ b/drivers/edac/edac_mc_sysfs.c @@ -10,6 +10,7 @@ */ #include +#include #include #include "edac_core.h" diff --git a/drivers/edac/edac_pci_sysfs.c b/drivers/edac/edac_pci_sysfs.c index bef94e3..c39697d 100644 --- a/drivers/edac/edac_pci_sysfs.c +++ b/drivers/edac/edac_pci_sysfs.c @@ -8,6 +8,7 @@ */ #include #include +#include #include #include "edac_core.h" diff --git a/drivers/edac/i3000_edac.c b/drivers/edac/i3000_edac.c index 6c9a0f2..c0510b3 100644 --- a/drivers/edac/i3000_edac.c +++ b/drivers/edac/i3000_edac.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include "edac_core.h" diff --git a/drivers/edac/i3200_edac.c b/drivers/edac/i3200_edac.c index fde4db9..d41f900 100644 --- a/drivers/edac/i3200_edac.c +++ b/drivers/edac/i3200_edac.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include "edac_core.h" diff --git a/drivers/edac/i5100_edac.c b/drivers/edac/i5100_edac.c index 7785d8f..ee9753c 100644 --- a/drivers/edac/i5100_edac.c +++ b/drivers/edac/i5100_edac.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/edac/i82443bxgx_edac.c b/drivers/edac/i82443bxgx_edac.c index 577760a..7f3884f 100644 --- a/drivers/edac/i82443bxgx_edac.c +++ b/drivers/edac/i82443bxgx_edac.c @@ -27,7 +27,6 @@ #include #include -#include #include #include "edac_core.h" diff --git a/drivers/edac/i82860_edac.c b/drivers/edac/i82860_edac.c index c0088ba..b8a95cf 100644 --- a/drivers/edac/i82860_edac.c +++ b/drivers/edac/i82860_edac.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include "edac_core.h" diff --git a/drivers/edac/i82875p_edac.c b/drivers/edac/i82875p_edac.c index b2d83b9..b2fd1e8 100644 --- a/drivers/edac/i82875p_edac.c +++ b/drivers/edac/i82875p_edac.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include "edac_core.h" diff --git a/drivers/edac/i82975x_edac.c b/drivers/edac/i82975x_edac.c index 2eed3ea..3218819 100644 --- a/drivers/edac/i82975x_edac.c +++ b/drivers/edac/i82975x_edac.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include "edac_core.h" diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c index 94cac0a..4471647b 100644 --- a/drivers/edac/mpc85xx_edac.c +++ b/drivers/edac/mpc85xx_edac.c @@ -11,13 +11,13 @@ */ #include #include -#include #include #include #include #include #include #include +#include #include #include diff --git a/drivers/edac/mv64x60_edac.c b/drivers/edac/mv64x60_edac.c index a6b9fec..7e5ff36 100644 --- a/drivers/edac/mv64x60_edac.c +++ b/drivers/edac/mv64x60_edac.c @@ -12,10 +12,10 @@ #include #include -#include #include #include #include +#include #include "edac_core.h" #include "edac_module.h" diff --git a/drivers/edac/pasemi_edac.c b/drivers/edac/pasemi_edac.c index 8e6b91b..7f71ee4 100644 --- a/drivers/edac/pasemi_edac.c +++ b/drivers/edac/pasemi_edac.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include "edac_core.h" diff --git a/drivers/edac/r82600_edac.c b/drivers/edac/r82600_edac.c index 9900675..d55f8e9 100644 --- a/drivers/edac/r82600_edac.c +++ b/drivers/edac/r82600_edac.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include "edac_core.h" diff --git a/drivers/edac/x38_edac.c b/drivers/edac/x38_edac.c index d4ec605..b6f47de 100644 --- a/drivers/edac/x38_edac.c +++ b/drivers/edac/x38_edac.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include "edac_core.h" diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c index 8be720b..702dcc9 100644 --- a/drivers/firewire/core-cdev.c +++ b/drivers/firewire/core-cdev.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c index 882472d..4b8523f 100644 --- a/drivers/firewire/core-device.c +++ b/drivers/firewire/core-device.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/firewire/core-iso.c b/drivers/firewire/core-iso.c index 99c20f1..3784a47 100644 --- a/drivers/firewire/core-iso.c +++ b/drivers/firewire/core-iso.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index 2d3dc7d..7142eee 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index e33917b..0cf4d7f 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -35,6 +34,7 @@ #include #include #include +#include #include #include diff --git a/drivers/firmware/dcdbas.c b/drivers/firmware/dcdbas.c index 18d65fb..fb09bb3 100644 --- a/drivers/firmware/dcdbas.c +++ b/drivers/firmware/dcdbas.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/firmware/dell_rbu.c b/drivers/firmware/dell_rbu.c index b3a0cf5..3a44602 100644 --- a/drivers/firmware/dell_rbu.c +++ b/drivers/firmware/dell_rbu.c @@ -36,6 +36,7 @@ */ #include #include +#include #include #include #include diff --git a/drivers/firmware/dmi-id.c b/drivers/firmware/dmi-id.c index dbdf6fa..a777a35 100644 --- a/drivers/firmware/dmi-id.c +++ b/drivers/firmware/dmi-id.c @@ -11,6 +11,7 @@ #include #include #include +#include struct dmi_device_attribute{ struct device_attribute dev_attr; diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index 31b983d..d464672 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c @@ -5,7 +5,6 @@ #include #include #include -#include #include /* diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index 082f06e..81b70bd 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c @@ -77,6 +77,7 @@ #include #include #include +#include #include diff --git a/drivers/firmware/iscsi_ibft_find.c b/drivers/firmware/iscsi_ibft_find.c index dfb15c0..134dd73 100644 --- a/drivers/firmware/iscsi_ibft_find.c +++ b/drivers/firmware/iscsi_ibft_find.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/firmware/memmap.c b/drivers/firmware/memmap.c index d59f7ca..adc0710 100644 --- a/drivers/firmware/memmap.c +++ b/drivers/firmware/memmap.c @@ -20,6 +20,7 @@ #include #include #include +#include /* * Data types ------------------------------------------------------------------ diff --git a/drivers/gpio/adp5520-gpio.c b/drivers/gpio/adp5520-gpio.c index 0f93105..9f27815 100644 --- a/drivers/gpio/adp5520-gpio.c +++ b/drivers/gpio/adp5520-gpio.c @@ -7,6 +7,7 @@ */ #include +#include #include #include #include diff --git a/drivers/gpio/adp5588-gpio.c b/drivers/gpio/adp5588-gpio.c index afc097a..2e8e9e2 100644 --- a/drivers/gpio/adp5588-gpio.c +++ b/drivers/gpio/adp5588-gpio.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include diff --git a/drivers/gpio/bt8xxgpio.c b/drivers/gpio/bt8xxgpio.c index 2559f22..aa4f09a 100644 --- a/drivers/gpio/bt8xxgpio.c +++ b/drivers/gpio/bt8xxgpio.c @@ -47,6 +47,7 @@ #include #include #include +#include /* Steal the hardware definitions from the bttv driver. */ #include "../media/video/bt8xx/bt848.h" diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 6d1b866..76be229 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -9,6 +9,7 @@ #include #include #include +#include /* Optional implementation infrastructure for GPIO interfaces. diff --git a/drivers/gpio/langwell_gpio.c b/drivers/gpio/langwell_gpio.c index 6c0ebbd..00c3a14 100644 --- a/drivers/gpio/langwell_gpio.c +++ b/drivers/gpio/langwell_gpio.c @@ -29,6 +29,7 @@ #include #include #include +#include struct lnw_gpio_register { u32 GPLR[2]; diff --git a/drivers/gpio/max7300.c b/drivers/gpio/max7300.c index 9d74eef..962f661 100644 --- a/drivers/gpio/max7300.c +++ b/drivers/gpio/max7300.c @@ -16,6 +16,7 @@ #include #include #include +#include static int max7300_i2c_write(struct device *dev, unsigned int reg, unsigned int val) diff --git a/drivers/gpio/max7301.c b/drivers/gpio/max7301.c index 965d9b1..92a100d 100644 --- a/drivers/gpio/max7301.c +++ b/drivers/gpio/max7301.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include diff --git a/drivers/gpio/max730x.c b/drivers/gpio/max730x.c index 4a7d662..7696a56 100644 --- a/drivers/gpio/max730x.c +++ b/drivers/gpio/max730x.c @@ -38,6 +38,7 @@ #include #include #include +#include /* * Pin configurations, see MAX7301 datasheet page 6 diff --git a/drivers/gpio/mc33880.c b/drivers/gpio/mc33880.c index e7d01bd..935479d 100644 --- a/drivers/gpio/mc33880.c +++ b/drivers/gpio/mc33880.c @@ -25,6 +25,7 @@ #include #include #include +#include #define DRIVER_NAME "mc33880" diff --git a/drivers/gpio/mcp23s08.c b/drivers/gpio/mcp23s08.c index cd651ec..69f6f19 100644 --- a/drivers/gpio/mcp23s08.c +++ b/drivers/gpio/mcp23s08.c @@ -9,6 +9,7 @@ #include #include #include +#include /* Registers are all 8 bits wide. diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c index ab5daab..7d521e1 100644 --- a/drivers/gpio/pca953x.c +++ b/drivers/gpio/pca953x.c @@ -18,6 +18,7 @@ #include #include #include +#include #ifdef CONFIG_OF_GPIO #include #include diff --git a/drivers/gpio/pl061.c b/drivers/gpio/pl061.c index 3ad1eeb..5ad8f77 100644 --- a/drivers/gpio/pl061.c +++ b/drivers/gpio/pl061.c @@ -24,6 +24,7 @@ #include #include #include +#include #define GPIODIR 0x400 #define GPIOIS 0x404 diff --git a/drivers/gpio/timbgpio.c b/drivers/gpio/timbgpio.c index d4295fa..ac4d0f0 100644 --- a/drivers/gpio/timbgpio.c +++ b/drivers/gpio/timbgpio.c @@ -27,6 +27,7 @@ #include #include #include +#include #define DRIVER_NAME "timb-gpio" diff --git a/drivers/gpio/twl4030-gpio.c b/drivers/gpio/twl4030-gpio.c index 7fe881e..57635ac 100644 --- a/drivers/gpio/twl4030-gpio.c +++ b/drivers/gpio/twl4030-gpio.c @@ -32,7 +32,6 @@ #include #include #include -#include #include diff --git a/drivers/gpio/wm831x-gpio.c b/drivers/gpio/wm831x-gpio.c index d09021f..1fa449a 100644 --- a/drivers/gpio/wm831x-gpio.c +++ b/drivers/gpio/wm831x-gpio.c @@ -13,6 +13,7 @@ */ #include +#include #include #include #include diff --git a/drivers/gpio/wm8350-gpiolib.c b/drivers/gpio/wm8350-gpiolib.c index 511840d..3599992 100644 --- a/drivers/gpio/wm8350-gpiolib.c +++ b/drivers/gpio/wm8350-gpiolib.c @@ -13,6 +13,7 @@ */ #include +#include #include #include #include diff --git a/drivers/gpio/wm8994-gpio.c b/drivers/gpio/wm8994-gpio.c index de28b4a4..7607cc6 100644 --- a/drivers/gpio/wm8994-gpio.c +++ b/drivers/gpio/wm8994-gpio.c @@ -13,6 +13,7 @@ */ #include +#include #include #include #include diff --git a/drivers/gpio/xilinx_gpio.c b/drivers/gpio/xilinx_gpio.c index 3c1177a..b8fa65b 100644 --- a/drivers/gpio/xilinx_gpio.c +++ b/drivers/gpio/xilinx_gpio.c @@ -19,6 +19,7 @@ #include #include #include +#include /* Register Offset Definitions */ #define XGPIO_DATA_OFFSET (0x0) /* Data register */ diff --git a/drivers/gpu/drm/drm_agpsupport.c b/drivers/gpu/drm/drm_agpsupport.c index d68888f..ba38e01 100644 --- a/drivers/gpu/drm/drm_agpsupport.c +++ b/drivers/gpu/drm/drm_agpsupport.c @@ -33,6 +33,7 @@ #include "drmP.h" #include +#include #if __OS_HAS_AGP diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c index 8417cc4..f7ba82e 100644 --- a/drivers/gpu/drm/drm_bufs.c +++ b/drivers/gpu/drm/drm_bufs.c @@ -34,6 +34,7 @@ */ #include +#include #include #include #include "drmP.h" diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index d91fb8c..61b9bcf 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -30,6 +30,7 @@ * Jesse Barnes */ #include +#include #include "drm.h" #include "drmP.h" #include "drm_crtc.h" diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c index 9903f27..677b275 100644 --- a/drivers/gpu/drm/drm_debugfs.c +++ b/drivers/gpu/drm/drm_debugfs.c @@ -32,6 +32,7 @@ #include #include +#include #include "drmP.h" #if defined(CONFIG_DEBUG_FS) diff --git a/drivers/gpu/drm/drm_dp_i2c_helper.c b/drivers/gpu/drm/drm_dp_i2c_helper.c index 548887c..f7eba0a 100644 --- a/drivers/gpu/drm/drm_dp_i2c_helper.c +++ b/drivers/gpu/drm/drm_dp_i2c_helper.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index f3c58e2..4a66201 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -47,6 +47,7 @@ */ #include +#include #include "drmP.h" #include "drm_core.h" diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index f97e7c4..d196d7e 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -27,6 +27,7 @@ * DEALINGS IN THE SOFTWARE. */ #include +#include #include #include #include "drmP.h" diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 5054970..85cdf05 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -29,6 +29,7 @@ */ #include #include +#include #include #include "drmP.h" #include "drm_crtc.h" diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 08d14df..0d55552 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c @@ -36,6 +36,7 @@ #include "drmP.h" #include +#include #include static int drm_open_helper(struct inode *inode, struct file *filp, diff --git a/drivers/gpu/drm/drm_hashtab.c b/drivers/gpu/drm/drm_hashtab.c index f36b21c..a93d7b4 100644 --- a/drivers/gpu/drm/drm_hashtab.c +++ b/drivers/gpu/drm/drm_hashtab.c @@ -35,6 +35,7 @@ #include "drmP.h" #include "drm_hashtab.h" #include +#include int drm_ht_create(struct drm_open_hash *ht, unsigned int order) { diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index b98384d..3bd8727 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -36,6 +36,7 @@ #include "drmP.h" #include /* For task queue support */ +#include #include /** diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c index e68ebf9..2ea9ad4 100644 --- a/drivers/gpu/drm/drm_pci.c +++ b/drivers/gpu/drm/drm_pci.c @@ -37,6 +37,7 @@ */ #include +#include #include #include "drmP.h" diff --git a/drivers/gpu/drm/drm_proc.c b/drivers/gpu/drm/drm_proc.c index d379c4f..a9ba6b6 100644 --- a/drivers/gpu/drm/drm_proc.c +++ b/drivers/gpu/drm/drm_proc.c @@ -38,6 +38,7 @@ */ #include +#include #include "drmP.h" /*************************************************** diff --git a/drivers/gpu/drm/drm_scatter.c b/drivers/gpu/drm/drm_scatter.c index c7823c8..9034c4c 100644 --- a/drivers/gpu/drm/drm_scatter.c +++ b/drivers/gpu/drm/drm_scatter.c @@ -32,6 +32,7 @@ */ #include +#include #include "drmP.h" #define DEBUG_SCATTER 0 diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index ad73e14..b743411 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c @@ -33,6 +33,7 @@ #include #include +#include #include "drmP.h" #include "drm_core.h" diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 014ce24..1a1825b 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c @@ -14,6 +14,7 @@ #include #include +#include #include #include "drm_sysfs.h" diff --git a/drivers/gpu/drm/drm_vm.c b/drivers/gpu/drm/drm_vm.c index 4ac900f..c3b13fb 100644 --- a/drivers/gpu/drm/drm_vm.c +++ b/drivers/gpu/drm/drm_vm.c @@ -36,6 +36,7 @@ #include "drmP.h" #if defined(__ia64__) #include +#include #endif static void drm_vm_open(struct vm_area_struct *vma); diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c index de32d22..997d917 100644 --- a/drivers/gpu/drm/i810/i810_dma.c +++ b/drivers/gpu/drm/i810/i810_dma.c @@ -36,6 +36,7 @@ #include "i810_drv.h" #include /* For task queue support */ #include +#include #include #define I810_BUF_FREE 2 diff --git a/drivers/gpu/drm/i830/i830_dma.c b/drivers/gpu/drm/i830/i830_dma.c index 06bd732..65759a9 100644 --- a/drivers/gpu/drm/i830/i830_dma.c +++ b/drivers/gpu/drm/i830/i830_dma.c @@ -38,6 +38,7 @@ #include /* For task queue support */ #include #include +#include #include #define I830_BUF_FREE 2 diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 1376dfe..b574503 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -28,6 +28,7 @@ #include #include +#include #include "drmP.h" #include "drm.h" #include "i915_drm.h" diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index a9f8589..2dc9393 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -38,6 +38,7 @@ #include #include #include +#include /* Really want an OS-independent resettable timer. Would like to have * this loop run for (eg) 3 sec, but have the timer reset every time diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 933e865..368d726 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -31,6 +31,7 @@ #include "i915_drv.h" #include "i915_trace.h" #include "intel_drv.h" +#include #include #include diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 5388354..49c458b 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -27,6 +27,7 @@ */ #include +#include #include "drmP.h" #include "drm.h" #include "i915_drm.h" diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index fccf074..38110ce 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -25,6 +25,7 @@ */ #include +#include #include "drmP.h" #include "drm.h" #include "drm_crtc.h" diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 58fc7fa..e7e753b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "drmP.h" #include "intel_drv.h" #include "i915_drm.h" diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 3ef3a0d..8e283f7 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -26,6 +26,7 @@ */ #include +#include #include "drmP.h" #include "drm.h" #include "drm_crtc.h" diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index a4d2606..0427ca5 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c @@ -25,6 +25,7 @@ * Eric Anholt */ #include +#include #include "drmP.h" #include "drm.h" #include "drm_crtc.h" diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index 8cd791d..69bbef9 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index a30f8bf..1ed02f6 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -27,6 +27,7 @@ */ #include +#include #include #include "drmP.h" #include "drm.h" diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index fcc753c..c2649c7 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c @@ -26,6 +26,7 @@ * Eric Anholt */ #include +#include #include #include #include "drmP.h" diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 2b3fa7a..216e9f5 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "drmP.h" #include "drm.h" #include "drm_crtc.h" diff --git a/drivers/gpu/drm/i915/intel_modes.c b/drivers/gpu/drm/i915/intel_modes.c index 67e2f46..89d303d 100644 --- a/drivers/gpu/drm/i915/intel_modes.c +++ b/drivers/gpu/drm/i915/intel_modes.c @@ -23,6 +23,7 @@ * DEALINGS IN THE SOFTWARE. */ +#include #include #include #include "drmP.h" diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 48daee5..26e13a0 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -26,6 +26,7 @@ * Eric Anholt */ #include +#include #include #include "drmP.h" #include "drm.h" diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c index 0e0730a..e13f6af 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c @@ -1,5 +1,6 @@ #include #include +#include #include #include diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 028719f..69c575d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -34,6 +34,7 @@ #include "nouveau_dma.h" #include +#include static void nouveau_bo_del_ttm(struct ttm_buffer_object *bo) diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 68cedd9..8e7dc1d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/gpu/drm/nouveau/nouveau_grctx.c b/drivers/gpu/drm/nouveau/nouveau_grctx.c index c7ebec6..32f0e49 100644 --- a/drivers/gpu/drm/nouveau/nouveau_grctx.c +++ b/drivers/gpu/drm/nouveau/nouveau_grctx.c @@ -23,6 +23,7 @@ */ #include +#include #include "drmP.h" #include "nouveau_drv.h" diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c index ed15905..86785b8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c +++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c @@ -1,6 +1,7 @@ #include "drmP.h" #include "nouveau_drv.h" #include +#include #define NV_CTXDMA_PAGE_SHIFT 12 #define NV_CTXDMA_PAGE_SIZE (1 << NV_CTXDMA_PAGE_SHIFT) diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index eb8f084..e67f2ba 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -24,6 +24,7 @@ */ #include +#include #include "drmP.h" #include "drm.h" #include "drm_sarea.h" diff --git a/drivers/gpu/drm/r128/r128_cce.c b/drivers/gpu/drm/r128/r128_cce.c index 4c39a40..e671d0e 100644 --- a/drivers/gpu/drm/r128/r128_cce.c +++ b/drivers/gpu/drm/r128/r128_cce.c @@ -31,6 +31,7 @@ #include #include +#include #include "drmP.h" #include "drm.h" diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index d75788f..8538b88 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c @@ -24,6 +24,7 @@ #include #include +#include #include #define ATOM_DEBUG diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index bd2e7aa..438226a 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -23,6 +23,7 @@ */ #include #include +#include #include "drmP.h" #include "radeon.h" #include "radeon_drm.h" diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 91eb762..a6e6f17 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -26,6 +26,7 @@ * Jerome Glisse */ #include +#include #include "drmP.h" #include "drm.h" #include "radeon_drm.h" diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 4cef90c..5eeb810 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -26,6 +26,7 @@ * Jerome Glisse */ #include +#include #include "drmP.h" #include "drm.h" #include "radeon_reg.h" diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c index c7593b8..00bc77f 100644 --- a/drivers/gpu/drm/radeon/r420.c +++ b/drivers/gpu/drm/radeon/r420.c @@ -26,6 +26,7 @@ * Jerome Glisse */ #include +#include #include "drmP.h" #include "radeon_reg.h" #include "radeon.h" diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index c522901..8ea3658 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -25,6 +25,7 @@ * Alex Deucher * Jerome Glisse */ +#include #include #include #include diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c index 3f557c4..ed5dfe5 100644 --- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c @@ -7,6 +7,7 @@ * ATPX support for both Intel/ATI */ #include +#include #include #include #include diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c index 5572404..8ad71f7 100644 --- a/drivers/gpu/drm/radeon/radeon_bios.c +++ b/drivers/gpu/drm/radeon/radeon_bios.c @@ -31,6 +31,7 @@ #include "atom.h" #include +#include /* * BIOS. */ diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index e28e4ed..0cc337e 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -26,6 +26,7 @@ * Jerome Glisse */ #include +#include #include #include #include diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index 8fccbf2..9ac57a0 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c @@ -28,6 +28,7 @@ */ #include +#include #include #include "drmP.h" diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 8495d4e..d90f95b 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "drmP.h" #include "drm.h" #include "radeon_reg.h" diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 20ec276..d3657dc 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -31,6 +31,7 @@ #include "radeon_drm.h" #include +#include int radeon_driver_unload_kms(struct drm_device *dev) { diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index fc9d00a..ffce2c9 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -30,6 +30,7 @@ * Dave Airlie */ #include +#include #include #include "radeon_drm.h" #include "radeon.h" diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index e50513a..f6e1e8d 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c @@ -26,6 +26,7 @@ * Jerome Glisse */ #include +#include #include "drmP.h" #include "radeon_drm.h" #include "radeon_reg.h" diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 43c5ab3..d031b68 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -36,6 +36,7 @@ #include #include #include +#include #include "radeon_reg.h" #include "radeon.h" diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c index 626d518..273c7dc 100644 --- a/drivers/gpu/drm/radeon/rs400.c +++ b/drivers/gpu/drm/radeon/rs400.c @@ -26,6 +26,7 @@ * Jerome Glisse */ #include +#include #include #include "radeon.h" #include "rs400d.h" diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index bea747d..903b1e4 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c @@ -26,6 +26,7 @@ * Jerome Glisse */ #include +#include #include "drmP.h" #include "rv515d.h" #include "radeon.h" diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 37887de..188e62d 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -27,6 +27,7 @@ */ #include #include +#include #include "drmP.h" #include "radeon.h" #include "radeon_drm.h" diff --git a/drivers/gpu/drm/ttm/ttm_agp_backend.c b/drivers/gpu/drm/ttm/ttm_agp_backend.c index 4648ed2..4bf69c4 100644 --- a/drivers/gpu/drm/ttm/ttm_agp_backend.c +++ b/drivers/gpu/drm/ttm/ttm_agp_backend.c @@ -35,6 +35,7 @@ #include "ttm/ttm_placement.h" #include #include +#include #include #include diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index 5ca37a5..d764e82 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include diff --git a/drivers/gpu/drm/ttm/ttm_memory.c b/drivers/gpu/drm/ttm/ttm_memory.c index eb143e0..e055a3a 100644 --- a/drivers/gpu/drm/ttm/ttm_memory.c +++ b/drivers/gpu/drm/ttm/ttm_memory.c @@ -32,6 +32,7 @@ #include #include #include +#include #define TTM_MEMORY_ALLOC_RETRIES 4 diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c index a759170..0ef7f73 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "drm_cache.h" #include "ttm/ttm_module.h" #include "ttm/ttm_bo_driver.h" diff --git a/drivers/gpu/drm/via/via_dmablit.c b/drivers/gpu/drm/via/via_dmablit.c index 3273808..4c54f04 100644 --- a/drivers/gpu/drm/via/via_dmablit.c +++ b/drivers/gpu/drm/via/via_dmablit.c @@ -40,6 +40,7 @@ #include "via_dmablit.h" #include +#include #define VIA_PGDN(x) (((unsigned long)(x)) & PAGE_MASK) #define VIA_PGOFF(x) (((unsigned long)(x)) & ~PAGE_MASK) diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c index 8827814..441e38c 100644 --- a/drivers/gpu/vga/vgaarb.c +++ b/drivers/gpu/vga/vgaarb.c @@ -20,6 +20,7 @@ #include #include #include +#include #include diff --git a/drivers/hid/hid-3m-pct.c b/drivers/hid/hid-3m-pct.c index 2370aef..c31e0be 100644 --- a/drivers/hid/hid-3m-pct.c +++ b/drivers/hid/hid-3m-pct.c @@ -15,6 +15,7 @@ #include #include #include +#include #include MODULE_AUTHOR("Stephane Chatty "); diff --git a/drivers/hid/hid-a4tech.c b/drivers/hid/hid-a4tech.c index df474c6..3a2b223 100644 --- a/drivers/hid/hid-a4tech.c +++ b/drivers/hid/hid-a4tech.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "hid-ids.h" diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index 78286b1..bba05d0 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include "hid-ids.h" diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c index 0c4e755..56f314f 100644 --- a/drivers/hid/hid-debug.c +++ b/drivers/hid/hid-debug.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include diff --git a/drivers/hid/hid-drff.c b/drivers/hid/hid-drff.c index a239d20..968b04f 100644 --- a/drivers/hid/hid-drff.c +++ b/drivers/hid/hid-drff.c @@ -28,6 +28,7 @@ */ #include +#include #include #include diff --git a/drivers/hid/hid-gaff.c b/drivers/hid/hid-gaff.c index 8a11ccd..88dfcf4 100644 --- a/drivers/hid/hid-gaff.c +++ b/drivers/hid/hid-gaff.c @@ -28,6 +28,7 @@ */ #include +#include #include #include #include "hid-ids.h" diff --git a/drivers/hid/hid-lg2ff.c b/drivers/hid/hid-lg2ff.c index 4e6dc6e..d888f1e 100644 --- a/drivers/hid/hid-lg2ff.c +++ b/drivers/hid/hid-lg2ff.c @@ -22,6 +22,7 @@ #include +#include #include #include diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index c174b64..0d471fc2 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "hid-ids.h" diff --git a/drivers/hid/hid-mosart.c b/drivers/hid/hid-mosart.c index c871816..e91437c 100644 --- a/drivers/hid/hid-mosart.c +++ b/drivers/hid/hid-mosart.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include "usbhid/usbhid.h" diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c index edcc0c4..9b24fc5 100644 --- a/drivers/hid/hid-ntrig.c +++ b/drivers/hid/hid-ntrig.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "hid-ids.h" diff --git a/drivers/hid/hid-pl.c b/drivers/hid/hid-pl.c index c6d7dbc..9f41e2b 100644 --- a/drivers/hid/hid-pl.c +++ b/drivers/hid/hid-pl.c @@ -39,6 +39,7 @@ #define debug(format, arg...) pr_debug("hid-plff: " format "\n" , ## arg) #include +#include #include #include diff --git a/drivers/hid/hid-quanta.c b/drivers/hid/hid-quanta.c index 01dd51c..54d3db5 100644 --- a/drivers/hid/hid-quanta.c +++ b/drivers/hid/hid-quanta.c @@ -15,6 +15,7 @@ #include #include #include +#include MODULE_AUTHOR("Stephane Chatty "); MODULE_DESCRIPTION("Quanta dual-touch panel"); diff --git a/drivers/hid/hid-sjoy.c b/drivers/hid/hid-sjoy.c index 203c438..e10a768 100644 --- a/drivers/hid/hid-sjoy.c +++ b/drivers/hid/hid-sjoy.c @@ -27,6 +27,7 @@ /* #define DEBUG */ #include +#include #include #include #include "hid-ids.h" diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 9bf00d7..7502a4b 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include "hid-ids.h" diff --git a/drivers/hid/hid-stantum.c b/drivers/hid/hid-stantum.c index 2e592a0..90df886 100644 --- a/drivers/hid/hid-stantum.c +++ b/drivers/hid/hid-stantum.c @@ -15,6 +15,7 @@ #include #include #include +#include MODULE_AUTHOR("Stephane Chatty "); MODULE_DESCRIPTION("Stantum HID multitouch panels"); diff --git a/drivers/hid/hid-tmff.c b/drivers/hid/hid-tmff.c index c32f32c..15434c8 100644 --- a/drivers/hid/hid-tmff.c +++ b/drivers/hid/hid-tmff.c @@ -29,6 +29,7 @@ #include #include +#include #include #include "hid-ids.h" diff --git a/drivers/hid/hid-wacom.c b/drivers/hid/hid-wacom.c index 8d3b46f..f7700cf 100644 --- a/drivers/hid/hid-wacom.c +++ b/drivers/hid/hid-wacom.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "hid-ids.h" diff --git a/drivers/hid/hid-zpff.c b/drivers/hid/hid-zpff.c index a79f0d7..b7accea 100644 --- a/drivers/hid/hid-zpff.c +++ b/drivers/hid/hid-zpff.c @@ -23,6 +23,7 @@ #include #include +#include #include #include "hid-ids.h" diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index d044767..6eadf1a 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/hid/usbhid/hid-pidff.c b/drivers/hid/usbhid/hid-pidff.c index e565dbe..ef381d7 100644 --- a/drivers/hid/usbhid/hid-pidff.c +++ b/drivers/hid/usbhid/hid-pidff.c @@ -25,6 +25,7 @@ #define debug(format, arg...) pr_debug("hid-pidff: " format "\n" , ## arg) #include +#include #include #include diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 928943c..2cacbe8 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -16,6 +16,7 @@ */ #include +#include #include "../hid-ids.h" diff --git a/drivers/hwmon/ad7414.c b/drivers/hwmon/ad7414.c index bfda8c8..1e4c21f 100644 --- a/drivers/hwmon/ad7414.c +++ b/drivers/hwmon/ad7414.c @@ -27,6 +27,7 @@ #include #include #include +#include /* AD7414 registers */ diff --git a/drivers/hwmon/ad7418.c b/drivers/hwmon/ad7418.c index f97b5b3..ffc781f 100644 --- a/drivers/hwmon/ad7418.c +++ b/drivers/hwmon/ad7418.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "lm75.h" diff --git a/drivers/hwmon/adcxx.c b/drivers/hwmon/adcxx.c index 74d9c51..fbdc765 100644 --- a/drivers/hwmon/adcxx.c +++ b/drivers/hwmon/adcxx.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/hwmon/adt7411.c b/drivers/hwmon/adt7411.c index 3471884..4086c72 100644 --- a/drivers/hwmon/adt7411.c +++ b/drivers/hwmon/adt7411.c @@ -21,6 +21,7 @@ #include #include #include +#include #define ADT7411_REG_INT_TEMP_VDD_LSB 0x03 #define ADT7411_REG_EXT_TEMP_AIN14_LSB 0x04 diff --git a/drivers/hwmon/adt7462.c b/drivers/hwmon/adt7462.c index b8156b4..2af0c7b 100644 --- a/drivers/hwmon/adt7462.c +++ b/drivers/hwmon/adt7462.c @@ -28,6 +28,7 @@ #include #include #include +#include /* Addresses to scan */ static const unsigned short normal_i2c[] = { 0x58, 0x5C, I2C_CLIENT_END }; diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c index 3445ce1..9e77571 100644 --- a/drivers/hwmon/adt7470.c +++ b/drivers/hwmon/adt7470.c @@ -29,6 +29,7 @@ #include #include #include +#include /* Addresses to scan */ static const unsigned short normal_i2c[] = { 0x2C, 0x2E, 0x2F, I2C_CLIENT_END }; diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c index 028284f..75f3fa5 100644 --- a/drivers/hwmon/asus_atk0110.c +++ b/drivers/hwmon/asus_atk0110.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include diff --git a/drivers/hwmon/atxp1.c b/drivers/hwmon/atxp1.c index 94cadc1..33cc143 100644 --- a/drivers/hwmon/atxp1.c +++ b/drivers/hwmon/atxp1.c @@ -28,6 +28,7 @@ #include #include #include +#include MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("System voltages control via Attansic ATXP1"); diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c index 277398f..bad2cf3 100644 --- a/drivers/hwmon/f75375s.c +++ b/drivers/hwmon/f75375s.c @@ -35,6 +35,7 @@ #include #include #include +#include /* Addresses to scan */ static const unsigned short normal_i2c[] = { 0x2d, 0x2e, I2C_CLIENT_END }; diff --git a/drivers/hwmon/i5k_amb.c b/drivers/hwmon/i5k_amb.c index 27d7f72..e880e2c 100644 --- a/drivers/hwmon/i5k_amb.c +++ b/drivers/hwmon/i5k_amb.c @@ -30,6 +30,7 @@ #include #include #include +#include #define DRVNAME "i5k_amb" diff --git a/drivers/hwmon/ibmaem.c b/drivers/hwmon/ibmaem.c index 405d3fb..eaee546 100644 --- a/drivers/hwmon/ibmaem.c +++ b/drivers/hwmon/ibmaem.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/hwmon/ibmpex.c b/drivers/hwmon/ibmpex.c index a363633..06d4eaf 100644 --- a/drivers/hwmon/ibmpex.c +++ b/drivers/hwmon/ibmpex.c @@ -25,6 +25,7 @@ #include #include #include +#include #define REFRESH_INTERVAL (2 * HZ) #define DRVNAME "ibmpex" diff --git a/drivers/hwmon/lm70.c b/drivers/hwmon/lm70.c index ab8a5d3..fd108cf 100644 --- a/drivers/hwmon/lm70.c +++ b/drivers/hwmon/lm70.c @@ -34,6 +34,7 @@ #include #include #include +#include #define DRVNAME "lm70" diff --git a/drivers/hwmon/lm73.c b/drivers/hwmon/lm73.c index c5f39ba..4d1b76b 100644 --- a/drivers/hwmon/lm73.c +++ b/drivers/hwmon/lm73.c @@ -16,7 +16,6 @@ #include #include -#include #include #include #include diff --git a/drivers/hwmon/max1111.c b/drivers/hwmon/max1111.c index 9ac4972..12a54aa 100644 --- a/drivers/hwmon/max1111.c +++ b/drivers/hwmon/max1111.c @@ -20,6 +20,7 @@ #include #include #include +#include #define MAX1111_TX_BUF_SIZE 1 #define MAX1111_RX_BUF_SIZE 2 diff --git a/drivers/hwmon/mc13783-adc.c b/drivers/hwmon/mc13783-adc.c index 883fa81..ce3c7bc 100644 --- a/drivers/hwmon/mc13783-adc.c +++ b/drivers/hwmon/mc13783-adc.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c index 864a371..6b2d8ae 100644 --- a/drivers/hwmon/sht15.c +++ b/drivers/hwmon/sht15.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #define SHT15_MEASURE_TEMP 3 diff --git a/drivers/hwmon/wm831x-hwmon.c b/drivers/hwmon/wm831x-hwmon.c index c16e9e7..97b1f83 100644 --- a/drivers/hwmon/wm831x-hwmon.c +++ b/drivers/hwmon/wm831x-hwmon.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c index e8d568c..a39e6cf 100644 --- a/drivers/i2c/algos/i2c-algo-bit.c +++ b/drivers/i2c/algos/i2c-algo-bit.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/i2c/algos/i2c-algo-pcf.c b/drivers/i2c/algos/i2c-algo-pcf.c index 6b6bd06..5eebf56 100644 --- a/drivers/i2c/algos/i2c-algo-pcf.c +++ b/drivers/i2c/algos/i2c-algo-pcf.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c index d0dc970..2fbef27 100644 --- a/drivers/i2c/busses/i2c-amd8111.c +++ b/drivers/i2c/busses/i2c-amd8111.c @@ -17,6 +17,7 @@ #include #include #include +#include #include MODULE_LICENSE("GPL"); diff --git a/drivers/i2c/busses/i2c-bfin-twi.c b/drivers/i2c/busses/i2c-bfin-twi.c index fe3fb56..f1e14dd 100644 --- a/drivers/i2c/busses/i2c-bfin-twi.c +++ b/drivers/i2c/busses/i2c-bfin-twi.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index c89687a..4523364 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c @@ -35,6 +35,7 @@ #include #include #include +#include #include diff --git a/drivers/i2c/busses/i2c-designware.c b/drivers/i2c/busses/i2c-designware.c index 3e72b69..b664ed8 100644 --- a/drivers/i2c/busses/i2c-designware.c +++ b/drivers/i2c/busses/i2c-designware.c @@ -36,6 +36,7 @@ #include #include #include +#include /* * Registers offset diff --git a/drivers/i2c/busses/i2c-elektor.c b/drivers/i2c/busses/i2c-elektor.c index 448b4bf..6122556 100644 --- a/drivers/i2c/busses/i2c-elektor.c +++ b/drivers/i2c/busses/i2c-elektor.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c index 32104ea..c21077d 100644 --- a/drivers/i2c/busses/i2c-gpio.c +++ b/drivers/i2c/busses/i2c-gpio.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include diff --git a/drivers/i2c/busses/i2c-highlander.c b/drivers/i2c/busses/i2c-highlander.c index 87ecace..ce87a90 100644 --- a/drivers/i2c/busses/i2c-highlander.c +++ b/drivers/i2c/busses/i2c-highlander.c @@ -19,6 +19,7 @@ #include #include #include +#include #define SMCR 0x00 #define SMCR_START (1 << 0) diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c index 32375bd..f7e27b7 100644 --- a/drivers/i2c/busses/i2c-imx.c +++ b/drivers/i2c/busses/i2c-imx.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include diff --git a/drivers/i2c/busses/i2c-ixp2000.c b/drivers/i2c/busses/i2c-ixp2000.c index c016f7a..5d8aed5 100644 --- a/drivers/i2c/busses/i2c-ixp2000.c +++ b/drivers/i2c/busses/i2c-ixp2000.c @@ -32,6 +32,7 @@ #include #include #include +#include #include /* Pick up IXP2000-specific bits */ #include diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index 78a15af..f1321f7 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c index ed387ff..3623a44 100644 --- a/drivers/i2c/busses/i2c-mv64xxx.c +++ b/drivers/i2c/busses/i2c-mv64xxx.c @@ -10,6 +10,7 @@ * or implied. */ #include +#include #include #include #include diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c index 4a70058..4a48dd4 100644 --- a/drivers/i2c/busses/i2c-nforce2.c +++ b/drivers/i2c/busses/i2c-nforce2.c @@ -56,6 +56,7 @@ #include #include #include +#include #include MODULE_LICENSE("GPL"); diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c index a15f731..a4f8d33 100644 --- a/drivers/i2c/busses/i2c-nomadik.c +++ b/drivers/i2c/busses/i2c-nomadik.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c index 0dabe64..b4ed4ca 100644 --- a/drivers/i2c/busses/i2c-ocores.c +++ b/drivers/i2c/busses/i2c-ocores.c @@ -18,6 +18,7 @@ #include #include #include +#include #include struct ocores_i2c { diff --git a/drivers/i2c/busses/i2c-octeon.c b/drivers/i2c/busses/i2c-octeon.c index 6037550..a2481f4 100644 --- a/drivers/i2c/busses/i2c-octeon.c +++ b/drivers/i2c/busses/i2c-octeon.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index c7c2375..6bd0f19 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -37,6 +37,7 @@ #include #include #include +#include /* I2C controller revisions */ #define OMAP_I2C_REV_2 0x20 diff --git a/drivers/i2c/busses/i2c-parport.c b/drivers/i2c/busses/i2c-parport.c index 220fca7..846583e 100644 --- a/drivers/i2c/busses/i2c-parport.c +++ b/drivers/i2c/busses/i2c-parport.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "i2c-parport.h" /* ----- Device list ------------------------------------------------------ */ diff --git a/drivers/i2c/busses/i2c-pasemi.c b/drivers/i2c/busses/i2c-pasemi.c index 0d20ff4..d3d4a4b 100644 --- a/drivers/i2c/busses/i2c-pasemi.c +++ b/drivers/i2c/busses/i2c-pasemi.c @@ -24,6 +24,7 @@ #include #include #include +#include #include static struct pci_driver pasemi_smb_driver; diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c index 9532dee..2471033 100644 --- a/drivers/i2c/busses/i2c-pnx.c +++ b/drivers/i2c/busses/i2c-pnx.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index 90ffbf6..14d249f 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index 1d8c986..d27072b 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c index ccc4641..ffb405d 100644 --- a/drivers/i2c/busses/i2c-sh_mobile.c +++ b/drivers/i2c/busses/i2c-sh_mobile.c @@ -31,6 +31,7 @@ #include #include #include +#include /* Transmit operation: */ /* */ diff --git a/drivers/i2c/busses/i2c-simtec.c b/drivers/i2c/busses/i2c-simtec.c index 6407f47..78b0610 100644 --- a/drivers/i2c/busses/i2c-simtec.c +++ b/drivers/i2c/busses/i2c-simtec.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/drivers/i2c/busses/i2c-stu300.c b/drivers/i2c/busses/i2c-stu300.c index d2728a2..1f5b38b 100644 --- a/drivers/i2c/busses/i2c-stu300.c +++ b/drivers/i2c/busses/i2c-stu300.c @@ -16,6 +16,7 @@ #include #include #include +#include /* the name of this kernel module */ #define NAME "stu300" diff --git a/drivers/i2c/busses/i2c-tiny-usb.c b/drivers/i2c/busses/i2c-tiny-usb.c index b5b1bbf..d03b040 100644 --- a/drivers/i2c/busses/i2c-tiny-usb.c +++ b/drivers/i2c/busses/i2c-tiny-usb.c @@ -13,6 +13,7 @@ #include #include #include +#include #include /* include interfaces to usb layer */ diff --git a/drivers/i2c/busses/i2c-versatile.c b/drivers/i2c/busses/i2c-versatile.c index 70de821..5c47383 100644 --- a/drivers/i2c/busses/i2c-versatile.c +++ b/drivers/i2c/busses/i2c-versatile.c @@ -14,6 +14,7 @@ #include #include #include +#include #include diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c index f0ef8da..a9c419e 100644 --- a/drivers/i2c/busses/i2c-xiic.c +++ b/drivers/i2c/busses/i2c-xiic.c @@ -39,6 +39,7 @@ #include #include #include +#include #define DRIVER_NAME "xiic-i2c" diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c index cf994bd..684395b 100644 --- a/drivers/i2c/busses/scx200_acb.c +++ b/drivers/i2c/busses/scx200_acb.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include diff --git a/drivers/i2c/i2c-boardinfo.c b/drivers/i2c/i2c-boardinfo.c index a26a34a..7e6a63b 100644 --- a/drivers/i2c/i2c-boardinfo.c +++ b/drivers/i2c/i2c-boardinfo.c @@ -18,6 +18,7 @@ #include #include +#include #include #include "i2c-core.h" diff --git a/drivers/i2c/i2c-smbus.c b/drivers/i2c/i2c-smbus.c index 7a8201e..a24e0bf 100644 --- a/drivers/i2c/i2c-smbus.c +++ b/drivers/i2c/i2c-smbus.c @@ -26,6 +26,7 @@ #include #include #include +#include struct i2c_smbus_alert { unsigned int alert_edge_triggered:1; diff --git a/drivers/ide/hpt366.c b/drivers/ide/hpt366.c index b885c1d..4516369 100644 --- a/drivers/ide/hpt366.c +++ b/drivers/ide/hpt366.c @@ -128,6 +128,7 @@ #include #include #include +#include #include #include diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c index 5cb01e5..c26c119 100644 --- a/drivers/ide/ide-acpi.c +++ b/drivers/ide/ide-acpi.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index eb2181a..a4046e9 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -7,6 +7,7 @@ #include #include #include +#include #include diff --git a/drivers/ide/ide-cd_ioctl.c b/drivers/ide/ide-cd_ioctl.c index df3df00..02712bf 100644 --- a/drivers/ide/ide-cd_ioctl.c +++ b/drivers/ide/ide-cd_ioctl.c @@ -8,6 +8,7 @@ #include #include +#include #include #include diff --git a/drivers/ide/ide-devsets.c b/drivers/ide/ide-devsets.c index c6935c7..9e98122 100644 --- a/drivers/ide/ide-devsets.c +++ b/drivers/ide/ide-devsets.c @@ -1,5 +1,6 @@ #include +#include #include DEFINE_MUTEX(ide_setting_mtx); diff --git a/drivers/ide/ide-disk_proc.c b/drivers/ide/ide-disk_proc.c index 60b0590..f9bbd90 100644 --- a/drivers/ide/ide-disk_proc.c +++ b/drivers/ide/ide-disk_proc.c @@ -1,5 +1,6 @@ #include #include +#include #include #include "ide-disk.h" diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index ee58c88..2c17e3f 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -29,6 +29,7 @@ */ #include +#include #include #include #include diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index efd9076..4713bdc 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/ide/ide-gd.c b/drivers/ide/ide-gd.c index 7532414..c32d839 100644 --- a/drivers/ide/ide-gd.c +++ b/drivers/ide/ide-gd.c @@ -8,6 +8,7 @@ #include #include #include +#include #if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT) #define IDE_DISK_MINORS (1 << PARTN_BITS) diff --git a/drivers/ide/ide-ioctls.c b/drivers/ide/ide-ioctls.c index 6e7ae2b..9965ecd 100644 --- a/drivers/ide/ide-ioctls.c +++ b/drivers/ide/ide-ioctls.c @@ -4,6 +4,7 @@ #include #include +#include static const struct ide_ioctl_devset ide_ioctl_settings[] = { { HDIO_GET_32BIT, HDIO_SET_32BIT, &ide_devset_io_32bit }, diff --git a/drivers/ide/ide-park.c b/drivers/ide/ide-park.c index a914023..88a380c 100644 --- a/drivers/ide/ide-park.c +++ b/drivers/ide/ide-park.c @@ -1,4 +1,5 @@ #include +#include #include #include #include diff --git a/drivers/ide/ide-pm.c b/drivers/ide/ide-pm.c index ad7be266..1c08311 100644 --- a/drivers/ide/ide-pm.c +++ b/drivers/ide/ide-pm.c @@ -1,4 +1,5 @@ #include +#include #include int generic_ide_suspend(struct device *dev, pm_message_t mesg) diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index 017c095..a3133d7 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c @@ -25,6 +25,7 @@ #include #include #include +#include #include diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 16d0569..3cb9c4e 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -52,7 +52,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/ide/it821x.c b/drivers/ide/it821x.c index b2709c7..2e3169f 100644 --- a/drivers/ide/it821x.c +++ b/drivers/ide/it821x.c @@ -61,6 +61,7 @@ #include #include +#include #include #include #include diff --git a/drivers/ide/pmac.c b/drivers/ide/pmac.c index 850ee45..159955d 100644 --- a/drivers/ide/pmac.c +++ b/drivers/ide/pmac.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include diff --git a/drivers/ide/rapide.c b/drivers/ide/rapide.c index 00f5424..48d976a 100644 --- a/drivers/ide/rapide.c +++ b/drivers/ide/rapide.c @@ -3,7 +3,6 @@ */ #include -#include #include #include #include diff --git a/drivers/ide/sc1200.c b/drivers/ide/sc1200.c index 134f1fd..356b9b5 100644 --- a/drivers/ide/sc1200.c +++ b/drivers/ide/sc1200.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/ide/via82cxxx.c b/drivers/ide/via82cxxx.c index 48fd4ef..101f400 100644 --- a/drivers/ide/via82cxxx.c +++ b/drivers/ide/via82cxxx.c @@ -26,6 +26,7 @@ #include #include +#include #include #include #include diff --git a/drivers/idle/i7300_idle.c b/drivers/idle/i7300_idle.c index dd25300..15341fc 100644 --- a/drivers/idle/i7300_idle.c +++ b/drivers/idle/i7300_idle.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include diff --git a/drivers/ieee1394/dma.c b/drivers/ieee1394/dma.c index 8e7e334..d178699 100644 --- a/drivers/ieee1394/dma.c +++ b/drivers/ieee1394/dma.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index c88696a..4565cb5 100644 --- a/drivers/ieee1394/sbp2.c +++ b/drivers/ieee1394/sbp2.c @@ -56,7 +56,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index abbb069..0b926e4 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c @@ -35,6 +35,7 @@ #include #include +#include #include #include #include diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index 764787e..fc73d6a 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 875e34e..7794249 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include diff --git a/drivers/infiniband/core/iwcm.c b/drivers/infiniband/core/iwcm.c index 0f89909..bfead5b 100644 --- a/drivers/infiniband/core/iwcm.c +++ b/drivers/infiniband/core/iwcm.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index e351b15..1df1194 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c @@ -34,6 +34,7 @@ * */ #include +#include #include #include "mad_priv.h" diff --git a/drivers/infiniband/core/mad_rmpp.c b/drivers/infiniband/core/mad_rmpp.c index 4e0f282..f37878c 100644 --- a/drivers/infiniband/core/mad_rmpp.c +++ b/drivers/infiniband/core/mad_rmpp.c @@ -31,6 +31,8 @@ * SOFTWARE. */ +#include + #include "mad_priv.h" #include "mad_rmpp.h" diff --git a/drivers/infiniband/core/multicast.c b/drivers/infiniband/core/multicast.c index 8d82ba1..a519801 100644 --- a/drivers/infiniband/core/multicast.c +++ b/drivers/infiniband/core/multicast.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c index 017d6e2..512b1c4 100644 --- a/drivers/infiniband/core/ucm.c +++ b/drivers/infiniband/core/ucm.c @@ -44,6 +44,7 @@ #include #include #include +#include #include diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c index b2e16c3..4618508 100644 --- a/drivers/infiniband/core/ucma.c +++ b/drivers/infiniband/core/ucma.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c index 4f906f0..415e186 100644 --- a/drivers/infiniband/core/umem.c +++ b/drivers/infiniband/core/umem.c @@ -37,6 +37,7 @@ #include #include #include +#include #include "uverbs.h" diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index 04b585e..e7db054 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c @@ -46,6 +46,7 @@ #include #include #include +#include #include diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index f71cf13..6fcfbeb 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c @@ -35,6 +35,7 @@ #include #include +#include #include diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index d805cf3..fb35262 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c @@ -44,6 +44,7 @@ #include #include #include +#include #include diff --git a/drivers/infiniband/hw/amso1100/c2.c b/drivers/infiniband/hw/amso1100/c2.c index c61fd2b..dc85d77 100644 --- a/drivers/infiniband/hw/amso1100/c2.c +++ b/drivers/infiniband/hw/amso1100/c2.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include diff --git a/drivers/infiniband/hw/amso1100/c2_alloc.c b/drivers/infiniband/hw/amso1100/c2_alloc.c index e911016..d4f5f5d 100644 --- a/drivers/infiniband/hw/amso1100/c2_alloc.c +++ b/drivers/infiniband/hw/amso1100/c2_alloc.c @@ -32,7 +32,6 @@ */ #include -#include #include #include "c2.h" diff --git a/drivers/infiniband/hw/amso1100/c2_cm.c b/drivers/infiniband/hw/amso1100/c2_cm.c index 75b93e9..95f58ab 100644 --- a/drivers/infiniband/hw/amso1100/c2_cm.c +++ b/drivers/infiniband/hw/amso1100/c2_cm.c @@ -31,6 +31,8 @@ * SOFTWARE. * */ +#include + #include "c2.h" #include "c2_wr.h" #include "c2_vq.h" diff --git a/drivers/infiniband/hw/amso1100/c2_cq.c b/drivers/infiniband/hw/amso1100/c2_cq.c index f5c45b1..f7b0fc2 100644 --- a/drivers/infiniband/hw/amso1100/c2_cq.c +++ b/drivers/infiniband/hw/amso1100/c2_cq.c @@ -35,6 +35,8 @@ * SOFTWARE. * */ +#include + #include "c2.h" #include "c2_vq.h" #include "c2_status.h" diff --git a/drivers/infiniband/hw/amso1100/c2_mm.c b/drivers/infiniband/hw/amso1100/c2_mm.c index b506fe2..119c4f3 100644 --- a/drivers/infiniband/hw/amso1100/c2_mm.c +++ b/drivers/infiniband/hw/amso1100/c2_mm.c @@ -30,6 +30,8 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ +#include + #include "c2.h" #include "c2_vq.h" diff --git a/drivers/infiniband/hw/amso1100/c2_pd.c b/drivers/infiniband/hw/amso1100/c2_pd.c index 00c7099..161f2a2 100644 --- a/drivers/infiniband/hw/amso1100/c2_pd.c +++ b/drivers/infiniband/hw/amso1100/c2_pd.c @@ -34,6 +34,7 @@ */ #include +#include #include #include "c2.h" diff --git a/drivers/infiniband/hw/amso1100/c2_provider.c b/drivers/infiniband/hw/amso1100/c2_provider.c index ad723bd..c47f618 100644 --- a/drivers/infiniband/hw/amso1100/c2_provider.c +++ b/drivers/infiniband/hw/amso1100/c2_provider.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #include diff --git a/drivers/infiniband/hw/amso1100/c2_qp.c b/drivers/infiniband/hw/amso1100/c2_qp.c index ad51886..d8f4bb8 100644 --- a/drivers/infiniband/hw/amso1100/c2_qp.c +++ b/drivers/infiniband/hw/amso1100/c2_qp.c @@ -36,6 +36,7 @@ */ #include +#include #include "c2.h" #include "c2_vq.h" diff --git a/drivers/infiniband/hw/amso1100/c2_rnic.c b/drivers/infiniband/hw/amso1100/c2_rnic.c index dd05c48..78c4bcc 100644 --- a/drivers/infiniband/hw/amso1100/c2_rnic.c +++ b/drivers/infiniband/hw/amso1100/c2_rnic.c @@ -51,6 +51,7 @@ #include #include #include +#include #include diff --git a/drivers/infiniband/hw/cxgb3/cxio_dbg.c b/drivers/infiniband/hw/cxgb3/cxio_dbg.c index a8d24d5..8bca6b4 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_dbg.c +++ b/drivers/infiniband/hw/cxgb3/cxio_dbg.c @@ -31,6 +31,7 @@ */ #ifdef DEBUG #include +#include #include "common.h" #include "cxgb3_ioctl.h" #include "cxio_hal.h" diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.c b/drivers/infiniband/hw/cxgb3/cxio_hal.c index a28e862..35f286f 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_hal.c +++ b/drivers/infiniband/hw/cxgb3/cxio_hal.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include "cxio_resource.h" diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c index d94388b..4fef032 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_cm.c +++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c @@ -31,6 +31,7 @@ */ #include #include +#include #include #include #include diff --git a/drivers/infiniband/hw/cxgb3/iwch_ev.c b/drivers/infiniband/hw/cxgb3/iwch_ev.c index 743c5d8..6afc89e 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_ev.c +++ b/drivers/infiniband/hw/cxgb3/iwch_ev.c @@ -29,7 +29,7 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#include +#include #include #include #include "iwch_provider.h" diff --git a/drivers/infiniband/hw/cxgb3/iwch_mem.c b/drivers/infiniband/hw/cxgb3/iwch_mem.c index e1ec65e..5c36ee2 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_mem.c +++ b/drivers/infiniband/hw/cxgb3/iwch_mem.c @@ -29,6 +29,7 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ +#include #include #include diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c index 47b35c6..19b1c4a 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_provider.c +++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include diff --git a/drivers/infiniband/hw/cxgb3/iwch_qp.c b/drivers/infiniband/hw/cxgb3/iwch_qp.c index b4d893d..ae47bfd 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_qp.c +++ b/drivers/infiniband/hw/cxgb3/iwch_qp.c @@ -30,6 +30,7 @@ * SOFTWARE. */ #include +#include #include "iwch_provider.h" #include "iwch.h" #include "iwch_cm.h" diff --git a/drivers/infiniband/hw/ehca/ehca_av.c b/drivers/infiniband/hw/ehca/ehca_av.c index 56735ea..4659263 100644 --- a/drivers/infiniband/hw/ehca/ehca_av.c +++ b/drivers/infiniband/hw/ehca/ehca_av.c @@ -41,6 +41,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include + #include "ehca_tools.h" #include "ehca_iverbs.h" #include "hcp_if.h" diff --git a/drivers/infiniband/hw/ehca/ehca_cq.c b/drivers/infiniband/hw/ehca/ehca_cq.c index 97e4b23..d9b0ebc 100644 --- a/drivers/infiniband/hw/ehca/ehca_cq.c +++ b/drivers/infiniband/hw/ehca/ehca_cq.c @@ -43,6 +43,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include + #include "ehca_iverbs.h" #include "ehca_classes.h" #include "ehca_irq.h" diff --git a/drivers/infiniband/hw/ehca/ehca_hca.c b/drivers/infiniband/hw/ehca/ehca_hca.c index 8b92f85..73edc36 100644 --- a/drivers/infiniband/hw/ehca/ehca_hca.c +++ b/drivers/infiniband/hw/ehca/ehca_hca.c @@ -39,6 +39,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include + #include "ehca_tools.h" #include "ehca_iverbs.h" #include "hcp_if.h" diff --git a/drivers/infiniband/hw/ehca/ehca_irq.c b/drivers/infiniband/hw/ehca/ehca_irq.c index b2b6fea..07cae55 100644 --- a/drivers/infiniband/hw/ehca/ehca_irq.c +++ b/drivers/infiniband/hw/ehca/ehca_irq.c @@ -41,6 +41,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include + #include "ehca_classes.h" #include "ehca_irq.h" #include "ehca_iverbs.h" diff --git a/drivers/infiniband/hw/ehca/ehca_mrmw.c b/drivers/infiniband/hw/ehca/ehca_mrmw.c index 7550a53..31a68b9 100644 --- a/drivers/infiniband/hw/ehca/ehca_mrmw.c +++ b/drivers/infiniband/hw/ehca/ehca_mrmw.c @@ -40,6 +40,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include #include #include "ehca_iverbs.h" diff --git a/drivers/infiniband/hw/ehca/ehca_pd.c b/drivers/infiniband/hw/ehca/ehca_pd.c index 2fe5548..351577a 100644 --- a/drivers/infiniband/hw/ehca/ehca_pd.c +++ b/drivers/infiniband/hw/ehca/ehca_pd.c @@ -38,6 +38,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include + #include "ehca_tools.h" #include "ehca_iverbs.h" diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c index b105f66..47d388e 100644 --- a/drivers/infiniband/hw/ehca/ehca_qp.c +++ b/drivers/infiniband/hw/ehca/ehca_qp.c @@ -43,6 +43,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include + #include "ehca_classes.h" #include "ehca_tools.h" #include "ehca_qes.h" diff --git a/drivers/infiniband/hw/ehca/ehca_uverbs.c b/drivers/infiniband/hw/ehca/ehca_uverbs.c index f1565ca..45ee89b 100644 --- a/drivers/infiniband/hw/ehca/ehca_uverbs.c +++ b/drivers/infiniband/hw/ehca/ehca_uverbs.c @@ -40,6 +40,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include + #include "ehca_classes.h" #include "ehca_iverbs.h" #include "ehca_mrmw.h" diff --git a/drivers/infiniband/hw/ehca/ipz_pt_fn.c b/drivers/infiniband/hw/ehca/ipz_pt_fn.c index 1227c59..1596e30 100644 --- a/drivers/infiniband/hw/ehca/ipz_pt_fn.c +++ b/drivers/infiniband/hw/ehca/ipz_pt_fn.c @@ -38,6 +38,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include + #include "ehca_tools.h" #include "ipz_pt_fn.h" #include "ehca_classes.h" diff --git a/drivers/infiniband/hw/ipath/ipath_cq.c b/drivers/infiniband/hw/ipath/ipath_cq.c index d385e41..0416c6c 100644 --- a/drivers/infiniband/hw/ipath/ipath_cq.c +++ b/drivers/infiniband/hw/ipath/ipath_cq.c @@ -32,6 +32,7 @@ */ #include +#include #include #include "ipath_verbs.h" diff --git a/drivers/infiniband/hw/ipath/ipath_dma.c b/drivers/infiniband/hw/ipath/ipath_dma.c index e90a0ea..644c2c7 100644 --- a/drivers/infiniband/hw/ipath/ipath_dma.c +++ b/drivers/infiniband/hw/ipath/ipath_dma.c @@ -31,6 +31,7 @@ */ #include +#include #include #include "ipath_verbs.h" diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c index d2787fe..6302626 100644 --- a/drivers/infiniband/hw/ipath/ipath_driver.c +++ b/drivers/infiniband/hw/ipath/ipath_driver.c @@ -40,6 +40,7 @@ #include #include #include +#include #include "ipath_kernel.h" #include "ipath_verbs.h" diff --git a/drivers/infiniband/hw/ipath/ipath_file_ops.c b/drivers/infiniband/hw/ipath/ipath_file_ops.c index 73933a4..9c5c66d 100644 --- a/drivers/infiniband/hw/ipath/ipath_file_ops.c +++ b/drivers/infiniband/hw/ipath/ipath_file_ops.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/infiniband/hw/ipath/ipath_fs.c b/drivers/infiniband/hw/ipath/ipath_fs.c index 100da85..2fca708 100644 --- a/drivers/infiniband/hw/ipath/ipath_fs.c +++ b/drivers/infiniband/hw/ipath/ipath_fs.c @@ -37,6 +37,7 @@ #include #include #include +#include #include "ipath_kernel.h" diff --git a/drivers/infiniband/hw/ipath/ipath_init_chip.c b/drivers/infiniband/hw/ipath/ipath_init_chip.c index 077879c..7769382 100644 --- a/drivers/infiniband/hw/ipath/ipath_init_chip.c +++ b/drivers/infiniband/hw/ipath/ipath_init_chip.c @@ -33,6 +33,7 @@ #include #include +#include #include #include "ipath_kernel.h" diff --git a/drivers/infiniband/hw/ipath/ipath_mmap.c b/drivers/infiniband/hw/ipath/ipath_mmap.c index b28865f..e732742 100644 --- a/drivers/infiniband/hw/ipath/ipath_mmap.c +++ b/drivers/infiniband/hw/ipath/ipath_mmap.c @@ -32,6 +32,7 @@ #include #include +#include #include #include #include diff --git a/drivers/infiniband/hw/ipath/ipath_mr.c b/drivers/infiniband/hw/ipath/ipath_mr.c index 9d343b7..e346d38 100644 --- a/drivers/infiniband/hw/ipath/ipath_mr.c +++ b/drivers/infiniband/hw/ipath/ipath_mr.c @@ -31,6 +31,8 @@ * SOFTWARE. */ +#include + #include #include #include diff --git a/drivers/infiniband/hw/ipath/ipath_qp.c b/drivers/infiniband/hw/ipath/ipath_qp.c index cb2d3ef..0857a9c 100644 --- a/drivers/infiniband/hw/ipath/ipath_qp.c +++ b/drivers/infiniband/hw/ipath/ipath_qp.c @@ -33,6 +33,7 @@ #include #include +#include #include #include "ipath_verbs.h" diff --git a/drivers/infiniband/hw/ipath/ipath_sdma.c b/drivers/infiniband/hw/ipath/ipath_sdma.c index 4b06985..98ac18e 100644 --- a/drivers/infiniband/hw/ipath/ipath_sdma.c +++ b/drivers/infiniband/hw/ipath/ipath_sdma.c @@ -31,6 +31,7 @@ */ #include +#include #include "ipath_kernel.h" #include "ipath_verbs.h" diff --git a/drivers/infiniband/hw/ipath/ipath_srq.c b/drivers/infiniband/hw/ipath/ipath_srq.c index e3d80ca..386e2c7 100644 --- a/drivers/infiniband/hw/ipath/ipath_srq.c +++ b/drivers/infiniband/hw/ipath/ipath_srq.c @@ -32,6 +32,7 @@ */ #include +#include #include #include "ipath_verbs.h" diff --git a/drivers/infiniband/hw/ipath/ipath_user_pages.c b/drivers/infiniband/hw/ipath/ipath_user_pages.c index eb7d59a..5e86d73 100644 --- a/drivers/infiniband/hw/ipath/ipath_user_pages.c +++ b/drivers/infiniband/hw/ipath/ipath_user_pages.c @@ -33,6 +33,7 @@ #include #include +#include #include #include "ipath_kernel.h" diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.c b/drivers/infiniband/hw/ipath/ipath_verbs.c index 9289ab4..559f39b 100644 --- a/drivers/infiniband/hw/ipath/ipath_verbs.c +++ b/drivers/infiniband/hw/ipath/ipath_verbs.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include diff --git a/drivers/infiniband/hw/ipath/ipath_verbs_mcast.c b/drivers/infiniband/hw/ipath/ipath_verbs_mcast.c index 6923e1d..6216ea9 100644 --- a/drivers/infiniband/hw/ipath/ipath_verbs_mcast.c +++ b/drivers/infiniband/hw/ipath/ipath_verbs_mcast.c @@ -33,6 +33,7 @@ #include #include +#include #include "ipath_verbs.h" diff --git a/drivers/infiniband/hw/mlx4/ah.c b/drivers/infiniband/hw/mlx4/ah.c index c75ac94..11a236f 100644 --- a/drivers/infiniband/hw/mlx4/ah.c +++ b/drivers/infiniband/hw/mlx4/ah.c @@ -30,6 +30,8 @@ * SOFTWARE. */ +#include + #include "mlx4_ib.h" struct ib_ah *mlx4_ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr) diff --git a/drivers/infiniband/hw/mlx4/cq.c b/drivers/infiniband/hw/mlx4/cq.c index de5263b..cc2ddd2 100644 --- a/drivers/infiniband/hw/mlx4/cq.c +++ b/drivers/infiniband/hw/mlx4/cq.c @@ -33,6 +33,7 @@ #include #include +#include #include "mlx4_ib.h" #include "user.h" diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c index 19e68ab..f38d5b1 100644 --- a/drivers/infiniband/hw/mlx4/mad.c +++ b/drivers/infiniband/hw/mlx4/mad.c @@ -34,6 +34,7 @@ #include #include +#include #include "mlx4_ib.h" diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index e596537..01f2a3f 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c @@ -33,6 +33,7 @@ #include #include +#include #include #include diff --git a/drivers/infiniband/hw/mlx4/mr.c b/drivers/infiniband/hw/mlx4/mr.c index 8f3666b..56147b2 100644 --- a/drivers/infiniband/hw/mlx4/mr.c +++ b/drivers/infiniband/hw/mlx4/mr.c @@ -31,6 +31,8 @@ * SOFTWARE. */ +#include + #include "mlx4_ib.h" static u32 convert_access(int acc) diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index ae75389..5643f4a 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c @@ -32,6 +32,7 @@ */ #include +#include #include #include diff --git a/drivers/infiniband/hw/mlx4/srq.c b/drivers/infiniband/hw/mlx4/srq.c index cf8085b..818b7ec 100644 --- a/drivers/infiniband/hw/mlx4/srq.c +++ b/drivers/infiniband/hw/mlx4/srq.c @@ -33,6 +33,7 @@ #include #include +#include #include "mlx4_ib.h" #include "user.h" diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c index 8c2ed99..3603ae8 100644 --- a/drivers/infiniband/hw/mthca/mthca_cmd.c +++ b/drivers/infiniband/hw/mthca/mthca_cmd.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include diff --git a/drivers/infiniband/hw/mthca/mthca_cq.c b/drivers/infiniband/hw/mthca/mthca_cq.c index d9f4735..18ee3fa 100644 --- a/drivers/infiniband/hw/mthca/mthca_cq.c +++ b/drivers/infiniband/hw/mthca/mthca_cq.c @@ -34,6 +34,7 @@ * SOFTWARE. */ +#include #include #include diff --git a/drivers/infiniband/hw/mthca/mthca_eq.c b/drivers/infiniband/hw/mthca/mthca_eq.c index 8c31fa3..9388164 100644 --- a/drivers/infiniband/hw/mthca/mthca_eq.c +++ b/drivers/infiniband/hw/mthca/mthca_eq.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "mthca_dev.h" #include "mthca_cmd.h" diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c index b01b2898..5eee666 100644 --- a/drivers/infiniband/hw/mthca/mthca_main.c +++ b/drivers/infiniband/hw/mthca/mthca_main.c @@ -37,6 +37,7 @@ #include #include #include +#include #include "mthca_dev.h" #include "mthca_config_reg.h" diff --git a/drivers/infiniband/hw/mthca/mthca_mcg.c b/drivers/infiniband/hw/mthca/mthca_mcg.c index d4c8105..515790a 100644 --- a/drivers/infiniband/hw/mthca/mthca_mcg.c +++ b/drivers/infiniband/hw/mthca/mthca_mcg.c @@ -31,7 +31,7 @@ */ #include -#include +#include #include "mthca_dev.h" #include "mthca_cmd.h" diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c index 1f7d1a2..8c2a837 100644 --- a/drivers/infiniband/hw/mthca/mthca_memfree.c +++ b/drivers/infiniband/hw/mthca/mthca_memfree.c @@ -35,6 +35,7 @@ #include #include #include +#include #include diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c index bcf7a40..f080a78 100644 --- a/drivers/infiniband/hw/mthca/mthca_provider.c +++ b/drivers/infiniband/hw/mthca/mthca_provider.c @@ -39,6 +39,7 @@ #include #include +#include #include #include "mthca_dev.h" diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c index 4272c52..de7b9d7 100644 --- a/drivers/infiniband/hw/nes/nes.c +++ b/drivers/infiniband/hw/nes/nes.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index 2a49ee4..986d6f3 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c index 9250755..c36a3f5 100644 --- a/drivers/infiniband/hw/nes/nes_hw.c +++ b/drivers/infiniband/hw/nes/nes_hw.c @@ -39,6 +39,7 @@ #include #include #include +#include #include "nes.h" diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c index 91fdde3..b7c813f 100644 --- a/drivers/infiniband/hw/nes/nes_nic.c +++ b/drivers/infiniband/hw/nes/nes_nic.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include diff --git a/drivers/infiniband/hw/nes/nes_utils.c b/drivers/infiniband/hw/nes/nes_utils.c index 729d525..186623d 100644 --- a/drivers/infiniband/hw/nes/nes_utils.c +++ b/drivers/infiniband/hw/nes/nes_utils.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index 6992829..5a076e8 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index bc65837..bb10041 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include "ipoib.h" diff --git a/drivers/infiniband/ulp/ipoib/ipoib_fs.c b/drivers/infiniband/ulp/ipoib/ipoib_fs.c index 961c585..86eae22 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_fs.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_fs.c @@ -32,6 +32,7 @@ #include #include +#include struct file_operations; diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index 5df40b1..ec6b4fb 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c @@ -35,6 +35,7 @@ #include #include +#include #include #include diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index d41ea27..b166bb7 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -40,6 +40,7 @@ #include #include #include +#include #include diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c index 6832511..049a997 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c @@ -31,6 +31,8 @@ * SOFTWARE. */ +#include + #include "ipoib.h" int ipoib_mcast_attach(struct net_device *dev, u16 mlid, union ib_gid *mgid, int set_qkey) diff --git a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c index e3bf00d8..d7e9740 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c @@ -33,7 +33,6 @@ #include #include -#include #include #include diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index e78af36d..93399df 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c @@ -56,6 +56,7 @@ #include #include #include +#include #include diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c index 308d17b..b89d76b 100644 --- a/drivers/infiniband/ulp/iser/iser_verbs.c +++ b/drivers/infiniband/ulp/iser/iser_verbs.c @@ -32,6 +32,7 @@ */ #include #include +#include #include #include "iscsi_iser.h" diff --git a/drivers/input/ff-core.c b/drivers/input/ff-core.c index b2f07aa..03078c0 100644 --- a/drivers/input/ff-core.c +++ b/drivers/input/ff-core.c @@ -29,6 +29,7 @@ #include #include #include +#include /* * Check that the effect_id is a valid effect and whether the user diff --git a/drivers/input/ff-memless.c b/drivers/input/ff-memless.c index f967008..1d881c9 100644 --- a/drivers/input/ff-memless.c +++ b/drivers/input/ff-memless.c @@ -25,6 +25,7 @@ #define debug(format, arg...) pr_debug("ff-memless: " format "\n", ## arg) +#include #include #include #include diff --git a/drivers/input/gameport/lightning.c b/drivers/input/gameport/lightning.c index 06ad36e..85d6ee0 100644 --- a/drivers/input/gameport/lightning.c +++ b/drivers/input/gameport/lightning.c @@ -34,7 +34,6 @@ #include #include #include -#include #define L4_PORT 0x201 #define L4_SELECT_ANALOG 0xa4 diff --git a/drivers/input/input-polldev.c b/drivers/input/input-polldev.c index 291d939..10c9b0a 100644 --- a/drivers/input/input-polldev.c +++ b/drivers/input/input-polldev.c @@ -9,6 +9,7 @@ */ #include +#include #include #include diff --git a/drivers/input/input.c b/drivers/input/input.c index e2aad0a..afd4e2b 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/input/joystick/db9.c b/drivers/input/joystick/db9.c index 5239594..8e7de5c 100644 --- a/drivers/input/joystick/db9.c +++ b/drivers/input/joystick/db9.c @@ -36,6 +36,7 @@ #include #include #include +#include MODULE_AUTHOR("Vojtech Pavlik "); MODULE_DESCRIPTION("Atari, Amstrad, Commodore, Amiga, Sega, etc. joystick driver"); diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c index 7a55714..fbd62ab 100644 --- a/drivers/input/joystick/gamecon.c +++ b/drivers/input/joystick/gamecon.c @@ -39,6 +39,7 @@ #include #include #include +#include MODULE_AUTHOR("Vojtech Pavlik "); MODULE_DESCRIPTION("NES, SNES, N64, MultiSystem, PSX gamepad driver"); diff --git a/drivers/input/joystick/turbografx.c b/drivers/input/joystick/turbografx.c index b6f8598..d53b9e9 100644 --- a/drivers/input/joystick/turbografx.c +++ b/drivers/input/joystick/turbografx.c @@ -35,6 +35,7 @@ #include #include #include +#include MODULE_AUTHOR("Vojtech Pavlik "); MODULE_DESCRIPTION("TurboGraFX parallel port interface driver"); diff --git a/drivers/input/keyboard/adp5520-keys.c b/drivers/input/keyboard/adp5520-keys.c index a7ba27f..3db8006 100644 --- a/drivers/input/keyboard/adp5520-keys.c +++ b/drivers/input/keyboard/adp5520-keys.c @@ -12,6 +12,7 @@ #include #include #include +#include struct adp5520_keys { struct input_dev *input; diff --git a/drivers/input/keyboard/adp5588-keys.c b/drivers/input/keyboard/adp5588-keys.c index b5142d2..4771ab1 100644 --- a/drivers/input/keyboard/adp5588-keys.c +++ b/drivers/input/keyboard/adp5588-keys.c @@ -19,6 +19,7 @@ #include #include #include +#include #include diff --git a/drivers/input/keyboard/bf54x-keys.c b/drivers/input/keyboard/bf54x-keys.c index 593c052..7d98960 100644 --- a/drivers/input/keyboard/bf54x-keys.c +++ b/drivers/input/keyboard/bf54x-keys.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/input/keyboard/davinci_keyscan.c b/drivers/input/keyboard/davinci_keyscan.c index d410d7a..a91ee94 100644 --- a/drivers/input/keyboard/davinci_keyscan.c +++ b/drivers/input/keyboard/davinci_keyscan.c @@ -30,6 +30,7 @@ #include #include #include +#include #include diff --git a/drivers/input/keyboard/ep93xx_keypad.c b/drivers/input/keyboard/ep93xx_keypad.c index bd25a3a..c8242dd 100644 --- a/drivers/input/keyboard/ep93xx_keypad.c +++ b/drivers/input/keyboard/ep93xx_keypad.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index 2b708aa..b8213fd 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/input/keyboard/imx_keypad.c b/drivers/input/keyboard/imx_keypad.c index 2ee5b79..d92c15c 100644 --- a/drivers/input/keyboard/imx_keypad.c +++ b/drivers/input/keyboard/imx_keypad.c @@ -21,6 +21,7 @@ #include #include #include +#include #include /* diff --git a/drivers/input/keyboard/jornada680_kbd.c b/drivers/input/keyboard/jornada680_kbd.c index 781fc61..5fc976d 100644 --- a/drivers/input/keyboard/jornada680_kbd.c +++ b/drivers/input/keyboard/jornada680_kbd.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include diff --git a/drivers/input/keyboard/jornada720_kbd.c b/drivers/input/keyboard/jornada720_kbd.c index 4e016d8..2cd3e1d 100644 --- a/drivers/input/keyboard/jornada720_kbd.c +++ b/drivers/input/keyboard/jornada720_kbd.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/drivers/input/keyboard/lm8323.c b/drivers/input/keyboard/lm8323.c index 574eda2..60ac468 100644 --- a/drivers/input/keyboard/lm8323.c +++ b/drivers/input/keyboard/lm8323.c @@ -31,6 +31,7 @@ #include #include #include +#include /* Commands to send to the chip. */ #define LM8323_CMD_READ_ID 0x80 /* Read chip ID. */ diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c index d3c8b61..ffc25cf 100644 --- a/drivers/input/keyboard/matrix_keypad.c +++ b/drivers/input/keyboard/matrix_keypad.c @@ -22,6 +22,7 @@ #include #include #include +#include struct matrix_keypad { const struct matrix_keypad_platform_data *pdata; diff --git a/drivers/input/keyboard/max7359_keypad.c b/drivers/input/keyboard/max7359_keypad.c index 3b5b948..7fc8185 100644 --- a/drivers/input/keyboard/max7359_keypad.c +++ b/drivers/input/keyboard/max7359_keypad.c @@ -15,6 +15,7 @@ #include #include +#include #include #include #include diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c index 1a494d5..a72e61d 100644 --- a/drivers/input/keyboard/omap-keypad.c +++ b/drivers/input/keyboard/omap-keypad.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/input/keyboard/opencores-kbd.c b/drivers/input/keyboard/opencores-kbd.c index 78cccdd..1f1a556 100644 --- a/drivers/input/keyboard/opencores-kbd.c +++ b/drivers/input/keyboard/opencores-kbd.c @@ -14,6 +14,7 @@ #include #include #include +#include struct opencores_kbd { struct input_dev *input; diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c index 79cd3e9..0e53b3b 100644 --- a/drivers/input/keyboard/pxa27x_keypad.c +++ b/drivers/input/keyboard/pxa27x_keypad.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include diff --git a/drivers/input/keyboard/pxa930_rotary.c b/drivers/input/keyboard/pxa930_rotary.c index 95fbba47..b7123a4 100644 --- a/drivers/input/keyboard/pxa930_rotary.c +++ b/drivers/input/keyboard/pxa930_rotary.c @@ -13,6 +13,7 @@ #include #include #include +#include #include diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c index 854e203..d7dafd9 100644 --- a/drivers/input/keyboard/sh_keysc.c +++ b/drivers/input/keyboard/sh_keysc.c @@ -22,6 +22,7 @@ #include #include #include +#include static const struct { unsigned char kymd, keyout, keyin; diff --git a/drivers/input/keyboard/tosakbd.c b/drivers/input/keyboard/tosakbd.c index 42cb3fa..3910f26 100644 --- a/drivers/input/keyboard/tosakbd.c +++ b/drivers/input/keyboard/tosakbd.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include diff --git a/drivers/input/keyboard/twl4030_keypad.c b/drivers/input/keyboard/twl4030_keypad.c index 21d6184..7aa59e0 100644 --- a/drivers/input/keyboard/twl4030_keypad.c +++ b/drivers/input/keyboard/twl4030_keypad.c @@ -32,6 +32,7 @@ #include #include #include +#include /* diff --git a/drivers/input/keyboard/w90p910_keypad.c b/drivers/input/keyboard/w90p910_keypad.c index 6032def..4ef764c 100644 --- a/drivers/input/keyboard/w90p910_keypad.c +++ b/drivers/input/keyboard/w90p910_keypad.c @@ -19,6 +19,7 @@ #include #include #include +#include #include diff --git a/drivers/input/misc/88pm860x_onkey.c b/drivers/input/misc/88pm860x_onkey.c index 69a48e8..40dabd8 100644 --- a/drivers/input/misc/88pm860x_onkey.c +++ b/drivers/input/misc/88pm860x_onkey.c @@ -25,6 +25,7 @@ #include #include #include +#include #define PM8607_WAKEUP 0x0b diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c index 15be543..2124b99 100644 --- a/drivers/input/misc/ati_remote2.c +++ b/drivers/input/misc/ati_remote2.c @@ -10,6 +10,7 @@ */ #include +#include #define DRIVER_DESC "ATI/Philips USB RF remote driver" #define DRIVER_VERSION "0.3" diff --git a/drivers/input/misc/bfin_rotary.c b/drivers/input/misc/bfin_rotary.c index 61d1017..4f72bdd 100644 --- a/drivers/input/misc/bfin_rotary.c +++ b/drivers/input/misc/bfin_rotary.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include diff --git a/drivers/input/misc/cobalt_btns.c b/drivers/input/misc/cobalt_btns.c index ee73d72..fd8407a 100644 --- a/drivers/input/misc/cobalt_btns.c +++ b/drivers/input/misc/cobalt_btns.c @@ -22,6 +22,7 @@ #include #include #include +#include #define BUTTONS_POLL_INTERVAL 30 /* msec */ #define BUTTONS_COUNT_THRESHOLD 3 diff --git a/drivers/input/misc/dm355evm_keys.c b/drivers/input/misc/dm355evm_keys.c index 766c069..19af682 100644 --- a/drivers/input/misc/dm355evm_keys.c +++ b/drivers/input/misc/dm355evm_keys.c @@ -10,6 +10,7 @@ */ #include #include +#include #include #include #include diff --git a/drivers/input/misc/pcap_keys.c b/drivers/input/misc/pcap_keys.c index 7ea9693..99335c2 100644 --- a/drivers/input/misc/pcap_keys.c +++ b/drivers/input/misc/pcap_keys.c @@ -17,6 +17,7 @@ #include #include #include +#include struct pcap_keys { struct pcap_chip *pcap; diff --git a/drivers/input/misc/pcf50633-input.c b/drivers/input/misc/pcf50633-input.c index 008de0c..9556273 100644 --- a/drivers/input/misc/pcf50633-input.c +++ b/drivers/input/misc/pcf50633-input.c @@ -20,6 +20,7 @@ #include #include #include +#include #include diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c index 4ae0793..1f8e010 100644 --- a/drivers/input/misc/rotary_encoder.c +++ b/drivers/input/misc/rotary_encoder.c @@ -22,6 +22,7 @@ #include #include #include +#include #define DRV_NAME "rotary-encoder" diff --git a/drivers/input/misc/sgi_btns.c b/drivers/input/misc/sgi_btns.c index be3a15f..1a80c0d 100644 --- a/drivers/input/misc/sgi_btns.c +++ b/drivers/input/misc/sgi_btns.c @@ -22,6 +22,7 @@ #include #include #include +#include #ifdef CONFIG_SGI_IP22 #include diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c index b064419..0d45422 100644 --- a/drivers/input/misc/sparcspkr.c +++ b/drivers/input/misc/sparcspkr.c @@ -9,6 +9,7 @@ #include #include #include +#include #include diff --git a/drivers/input/misc/twl4030-vibra.c b/drivers/input/misc/twl4030-vibra.c index 2fb79e0..fee9eac 100644 --- a/drivers/input/misc/twl4030-vibra.c +++ b/drivers/input/misc/twl4030-vibra.c @@ -30,6 +30,7 @@ #include #include #include +#include /* MODULE ID2 */ #define LEDEN 0x00 diff --git a/drivers/input/misc/winbond-cir.c b/drivers/input/misc/winbond-cir.c index 9c155a4..64f1de7 100644 --- a/drivers/input/misc/winbond-cir.c +++ b/drivers/input/misc/winbond-cir.c @@ -56,6 +56,7 @@ #include #include #include +#include #define DRVNAME "winbond-cir" diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c index c0afb71..04d5a4a 100644 --- a/drivers/input/misc/wistron_btns.c +++ b/drivers/input/misc/wistron_btns.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/input/misc/wm831x-on.c b/drivers/input/misc/wm831x-on.c index 1e54bce..c3d7ba5 100644 --- a/drivers/input/misc/wm831x-on.c +++ b/drivers/input/misc/wm831x-on.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 7490f1d..99d5876 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -15,6 +15,7 @@ * the Free Software Foundation. */ +#include #include #include #include diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index b27684f..a138b5d 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c @@ -11,6 +11,7 @@ */ #include +#include #include #include #include diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c index 9169d15..08d66d8 100644 --- a/drivers/input/mouse/hgpk.c +++ b/drivers/input/mouse/hgpk.c @@ -30,6 +30,7 @@ */ #define DEBUG +#include #include #include #include diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c index 7c1d7d4..c31ad11 100644 --- a/drivers/input/mouse/lifebook.c +++ b/drivers/input/mouse/lifebook.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "psmouse.h" #include "lifebook.h" diff --git a/drivers/input/mouse/pxa930_trkball.c b/drivers/input/mouse/pxa930_trkball.c index 1e827ad..943cfec 100644 --- a/drivers/input/mouse/pxa930_trkball.c +++ b/drivers/input/mouse/pxa930_trkball.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include diff --git a/drivers/input/mouse/sentelic.c b/drivers/input/mouse/sentelic.c index 81a6b81..1242775 100644 --- a/drivers/input/mouse/sentelic.c +++ b/drivers/input/mouse/sentelic.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "psmouse.h" #include "sentelic.h" diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index d3f5243..026df60 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "psmouse.h" #include "synaptics.h" diff --git a/drivers/input/mouse/synaptics_i2c.c b/drivers/input/mouse/synaptics_i2c.c index 9867dfe..8291e73 100644 --- a/drivers/input/mouse/synaptics_i2c.c +++ b/drivers/input/mouse/synaptics_i2c.c @@ -17,6 +17,7 @@ #include #include #include +#include #define DRIVER_NAME "synaptics_i2c" /* maximum product id is 15 characters */ diff --git a/drivers/input/mouse/touchkit_ps2.c b/drivers/input/mouse/touchkit_ps2.c index 909431c..88121c5 100644 --- a/drivers/input/mouse/touchkit_ps2.c +++ b/drivers/input/mouse/touchkit_ps2.c @@ -26,7 +26,6 @@ */ #include -#include #include #include diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c index 63d4a67..0643e49 100644 --- a/drivers/input/mouse/trackpoint.c +++ b/drivers/input/mouse/trackpoint.c @@ -8,6 +8,7 @@ * Trademarks are the property of their respective owners. */ +#include #include #include #include diff --git a/drivers/input/serio/altera_ps2.c b/drivers/input/serio/altera_ps2.c index 320b7ca..7998560 100644 --- a/drivers/input/serio/altera_ps2.c +++ b/drivers/input/serio/altera_ps2.c @@ -18,6 +18,7 @@ #include #include #include +#include #define DRV_NAME "altera_ps2" diff --git a/drivers/input/serio/at32psif.c b/drivers/input/serio/at32psif.c index b54452a..6ee8f0d 100644 --- a/drivers/input/serio/at32psif.c +++ b/drivers/input/serio/at32psif.c @@ -18,6 +18,7 @@ #include #include #include +#include /* PSIF register offsets */ #define PSIF_CR 0x00 diff --git a/drivers/input/serio/ct82c710.c b/drivers/input/serio/ct82c710.c index d1380fc..4a30846 100644 --- a/drivers/input/serio/ct82c710.c +++ b/drivers/input/serio/ct82c710.c @@ -35,6 +35,7 @@ #include #include #include +#include #include diff --git a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c index 06addfa..3c287dd 100644 --- a/drivers/input/serio/gscps2.c +++ b/drivers/input/serio/gscps2.c @@ -24,6 +24,7 @@ #include #include +#include #include #include #include diff --git a/drivers/input/serio/hil_mlc.c b/drivers/input/serio/hil_mlc.c index 6cd03eb..c92f4ed 100644 --- a/drivers/input/serio/hil_mlc.c +++ b/drivers/input/serio/hil_mlc.c @@ -58,6 +58,7 @@ #include #include #include +#include #include #include diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 9302ba0..577688b 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c @@ -21,6 +21,7 @@ #include #include #include +#include #include diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c index f3876ac..980af94 100644 --- a/drivers/input/serio/libps2.c +++ b/drivers/input/serio/libps2.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/input/serio/parkbd.c b/drivers/input/serio/parkbd.c index b089977..26b4593 100644 --- a/drivers/input/serio/parkbd.c +++ b/drivers/input/serio/parkbd.c @@ -46,6 +46,7 @@ #include #include +#include #include #include diff --git a/drivers/input/serio/pcips2.c b/drivers/input/serio/pcips2.c index 797314b..4349474 100644 --- a/drivers/input/serio/pcips2.c +++ b/drivers/input/serio/pcips2.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c index e36a090..5eb84b3 100644 --- a/drivers/input/serio/q40kbd.c +++ b/drivers/input/serio/q40kbd.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include diff --git a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c index ed045c9..9da6fbc 100644 --- a/drivers/input/serio/rpckbd.c +++ b/drivers/input/serio/rpckbd.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include diff --git a/drivers/input/serio/xilinx_ps2.c b/drivers/input/serio/xilinx_ps2.c index 8298e1f..f84f8e3 100644 --- a/drivers/input/serio/xilinx_ps2.c +++ b/drivers/input/serio/xilinx_ps2.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/input/sparse-keymap.c b/drivers/input/sparse-keymap.c index e6bde55..82ae18d 100644 --- a/drivers/input/sparse-keymap.c +++ b/drivers/input/sparse-keymap.c @@ -15,6 +15,7 @@ #include #include +#include MODULE_AUTHOR("Dmitry Torokhov "); MODULE_DESCRIPTION("Generic support for sparse keymaps"); diff --git a/drivers/input/touchscreen/88pm860x-ts.c b/drivers/input/touchscreen/88pm860x-ts.c index 286bb49..b3aebc2 100644 --- a/drivers/input/touchscreen/88pm860x-ts.c +++ b/drivers/input/touchscreen/88pm860x-ts.c @@ -14,6 +14,7 @@ #include #include #include +#include #define MEAS_LEN (8) #define ACCURATE_BIT (12) diff --git a/drivers/input/touchscreen/atmel-wm97xx.c b/drivers/input/touchscreen/atmel-wm97xx.c index a12242f..fa8e56b 100644 --- a/drivers/input/touchscreen/atmel-wm97xx.c +++ b/drivers/input/touchscreen/atmel-wm97xx.c @@ -19,6 +19,7 @@ #include #include #include +#include #define AC97C_ICA 0x10 #define AC97C_CBRHR 0x30 diff --git a/drivers/input/touchscreen/da9034-ts.c b/drivers/input/touchscreen/da9034-ts.c index 3ffd4c4..2b72a59 100644 --- a/drivers/input/touchscreen/da9034-ts.c +++ b/drivers/input/touchscreen/da9034-ts.c @@ -19,6 +19,7 @@ #include #include #include +#include #define DA9034_MANUAL_CTRL 0x50 #define DA9034_LDO_ADC_EN (1 << 4) diff --git a/drivers/input/touchscreen/eeti_ts.c b/drivers/input/touchscreen/eeti_ts.c index 9029bd3..204b8a1 100644 --- a/drivers/input/touchscreen/eeti_ts.c +++ b/drivers/input/touchscreen/eeti_ts.c @@ -33,6 +33,7 @@ #include #include #include +#include static int flip_x; module_param(flip_x, bool, 0644); diff --git a/drivers/input/touchscreen/jornada720_ts.c b/drivers/input/touchscreen/jornada720_ts.c index c8b7e8a..4b0a061 100644 --- a/drivers/input/touchscreen/jornada720_ts.c +++ b/drivers/input/touchscreen/jornada720_ts.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include diff --git a/drivers/input/touchscreen/mc13783_ts.c b/drivers/input/touchscreen/mc13783_ts.c index be54fd6..c5bc62d 100644 --- a/drivers/input/touchscreen/mc13783_ts.c +++ b/drivers/input/touchscreen/mc13783_ts.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #define MC13783_TS_NAME "mc13783-ts" diff --git a/drivers/input/touchscreen/mcs5000_ts.c b/drivers/input/touchscreen/mcs5000_ts.c index 4c28b89..ce8ab02 100644 --- a/drivers/input/touchscreen/mcs5000_ts.c +++ b/drivers/input/touchscreen/mcs5000_ts.c @@ -20,6 +20,7 @@ #include #include #include +#include /* Registers */ #define MCS5000_TS_STATUS 0x00 diff --git a/drivers/input/touchscreen/migor_ts.c b/drivers/input/touchscreen/migor_ts.c index 141dd58..defe5dd 100644 --- a/drivers/input/touchscreen/migor_ts.c +++ b/drivers/input/touchscreen/migor_ts.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/input/touchscreen/pcap_ts.c b/drivers/input/touchscreen/pcap_ts.c index b79097e..ea6ef16 100644 --- a/drivers/input/touchscreen/pcap_ts.c +++ b/drivers/input/touchscreen/pcap_ts.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/input/touchscreen/s3c2410_ts.c b/drivers/input/touchscreen/s3c2410_ts.c index 3755a47..98a7d12 100644 --- a/drivers/input/touchscreen/s3c2410_ts.c +++ b/drivers/input/touchscreen/s3c2410_ts.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c index 89dcbe7..028a536 100644 --- a/drivers/input/touchscreen/ucb1400_ts.c +++ b/drivers/input/touchscreen/ucb1400_ts.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/input/touchscreen/w90p910_ts.c b/drivers/input/touchscreen/w90p910_ts.c index 6ccbdbb..cc18265 100644 --- a/drivers/input/touchscreen/w90p910_ts.c +++ b/drivers/input/touchscreen/w90p910_ts.c @@ -16,6 +16,7 @@ #include #include #include +#include /* ADC controller bit defines */ #define ADC_DELAY 0xf00 diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c index f944918..5109bf3 100644 --- a/drivers/input/touchscreen/wm97xx-core.c +++ b/drivers/input/touchscreen/wm97xx-core.c @@ -48,6 +48,7 @@ #include #include #include +#include #define TS_NAME "wm97xx" #define WM_CORE_VERSION "1.00" diff --git a/drivers/input/xen-kbdfront.c b/drivers/input/xen-kbdfront.c index d30436f..e140816 100644 --- a/drivers/input/xen-kbdfront.c +++ b/drivers/input/xen-kbdfront.c @@ -21,6 +21,7 @@ #include #include #include +#include #include diff --git a/drivers/isdn/act2000/module.c b/drivers/isdn/act2000/module.c index f774e12..05ed72c4 100644 --- a/drivers/isdn/act2000/module.c +++ b/drivers/isdn/act2000/module.c @@ -16,6 +16,7 @@ #include "act2000_isa.h" #include "capi.h" #include +#include #include static unsigned short act2000_isa_ports[] = diff --git a/drivers/isdn/capi/capifs.c b/drivers/isdn/capi/capifs.c index 8596bd1..2b83850 100644 --- a/drivers/isdn/capi/capifs.c +++ b/drivers/isdn/capi/capifs.c @@ -11,6 +11,7 @@ #include #include +#include #include #include #include diff --git a/drivers/isdn/capi/capilib.c b/drivers/isdn/capi/capilib.c index fcaa124..0b041df 100644 --- a/drivers/isdn/capi/capilib.c +++ b/drivers/isdn/capi/capilib.c @@ -1,4 +1,5 @@ +#include #include #include #include diff --git a/drivers/isdn/capi/capiutil.c b/drivers/isdn/capi/capiutil.c index 26626ee..03c469e 100644 --- a/drivers/isdn/capi/capiutil.c +++ b/drivers/isdn/capi/capiutil.c @@ -18,6 +18,7 @@ #include #include #include +#include /* from CAPI2.0 DDK AVM Berlin GmbH */ diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c index ce9b05b..bd00dce 100644 --- a/drivers/isdn/capi/kcapi.c +++ b/drivers/isdn/capi/kcapi.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/isdn/divert/divert_procfs.c b/drivers/isdn/divert/divert_procfs.c index 3697c40..9f49d90 100644 --- a/drivers/isdn/divert/divert_procfs.c +++ b/drivers/isdn/divert/divert_procfs.c @@ -11,6 +11,7 @@ #include #include +#include #ifdef CONFIG_PROC_FS #include #else diff --git a/drivers/isdn/divert/isdn_divert.c b/drivers/isdn/divert/isdn_divert.c index 77e9fdd..70cf6ba 100644 --- a/drivers/isdn/divert/isdn_divert.c +++ b/drivers/isdn/divert/isdn_divert.c @@ -10,6 +10,7 @@ */ #include +#include #include #include diff --git a/drivers/isdn/gigaset/capi.c b/drivers/isdn/gigaset/capi.c index 0220c19..eb7e271 100644 --- a/drivers/isdn/gigaset/capi.c +++ b/drivers/isdn/gigaset/capi.c @@ -12,6 +12,7 @@ */ #include "gigaset.h" +#include #include #include #include diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c index bdc01cb..0b39b38 100644 --- a/drivers/isdn/gigaset/common.c +++ b/drivers/isdn/gigaset/common.c @@ -17,6 +17,7 @@ #include #include #include +#include /* Version Information */ #define DRIVER_AUTHOR "Hansjoerg Lipp , Tilman Schmidt , Stefan Eilers" diff --git a/drivers/isdn/gigaset/gigaset.h b/drivers/isdn/gigaset/gigaset.h index cdd144e..9ef5b04 100644 --- a/drivers/isdn/gigaset/gigaset.h +++ b/drivers/isdn/gigaset/gigaset.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/isdn/gigaset/i4l.c b/drivers/isdn/gigaset/i4l.c index c22e5ac..c99fb97 100644 --- a/drivers/isdn/gigaset/i4l.c +++ b/drivers/isdn/gigaset/i4l.c @@ -15,6 +15,7 @@ #include "gigaset.h" #include +#include #define HW_HDR_LEN 2 /* Header size used to store ack info */ diff --git a/drivers/isdn/gigaset/ser-gigaset.c b/drivers/isdn/gigaset/ser-gigaset.c index 168d585..8b0afd2 100644 --- a/drivers/isdn/gigaset/ser-gigaset.c +++ b/drivers/isdn/gigaset/ser-gigaset.c @@ -17,6 +17,7 @@ #include #include #include +#include /* Version Information */ #define DRIVER_AUTHOR "Tilman Schmidt" diff --git a/drivers/isdn/hardware/avm/b1.c b/drivers/isdn/hardware/avm/b1.c index c38fa0f..2a57da59 100644 --- a/drivers/isdn/hardware/avm/b1.c +++ b/drivers/isdn/hardware/avm/b1.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/isdn/hardware/avm/b1dma.c b/drivers/isdn/hardware/avm/b1dma.c index 124550d..9c8d7aa0 100644 --- a/drivers/isdn/hardware/avm/b1dma.c +++ b/drivers/isdn/hardware/avm/b1dma.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/isdn/hardware/avm/c4.c b/drivers/isdn/hardware/avm/c4.c index de6e6b3..7715d32 100644 --- a/drivers/isdn/hardware/avm/c4.c +++ b/drivers/isdn/hardware/avm/c4.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/isdn/hardware/avm/t1isa.c b/drivers/isdn/hardware/avm/t1isa.c index baeeb3c..08216b1 100644 --- a/drivers/isdn/hardware/avm/t1isa.c +++ b/drivers/isdn/hardware/avm/t1isa.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/isdn/hardware/eicon/capimain.c b/drivers/isdn/hardware/eicon/capimain.c index 0f073cd..97a2096 100644 --- a/drivers/isdn/hardware/eicon/capimain.c +++ b/drivers/isdn/hardware/eicon/capimain.c @@ -11,6 +11,7 @@ */ #include +#include #include #include #include diff --git a/drivers/isdn/hardware/mISDN/avmfritz.c b/drivers/isdn/hardware/mISDN/avmfritz.c index 81ac541..d421536 100644 --- a/drivers/isdn/hardware/mISDN/avmfritz.c +++ b/drivers/isdn/hardware/mISDN/avmfritz.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include "ipac.h" diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c index 8affba3..75e71b5 100644 --- a/drivers/isdn/hardware/mISDN/hfcmulti.c +++ b/drivers/isdn/hardware/mISDN/hfcmulti.c @@ -153,6 +153,7 @@ #define HFC_MULTI_VERSION "2.03" #include +#include #include #include #include diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c index 70e6b0e..5940a2c 100644 --- a/drivers/isdn/hardware/mISDN/hfcpci.c +++ b/drivers/isdn/hardware/mISDN/hfcpci.c @@ -48,6 +48,7 @@ #include #include #include +#include #include "hfc_pci.h" diff --git a/drivers/isdn/hardware/mISDN/hfcsusb.c b/drivers/isdn/hardware/mISDN/hfcsusb.c index a64bb6c..b3b7e28 100644 --- a/drivers/isdn/hardware/mISDN/hfcsusb.c +++ b/drivers/isdn/hardware/mISDN/hfcsusb.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "hfcsusb.h" static const char *hfcsusb_rev = "Revision: 0.3.3 (socket), 2008-11-05"; diff --git a/drivers/isdn/hardware/mISDN/mISDNinfineon.c b/drivers/isdn/hardware/mISDN/mISDNinfineon.c index 36c6c61..f5b3d2b 100644 --- a/drivers/isdn/hardware/mISDN/mISDNinfineon.c +++ b/drivers/isdn/hardware/mISDN/mISDNinfineon.c @@ -42,6 +42,7 @@ #include #include #include +#include #include "ipac.h" #define INFINEON_REV "1.0" diff --git a/drivers/isdn/hardware/mISDN/mISDNipac.c b/drivers/isdn/hardware/mISDN/mISDNipac.c index 613ba04..64ecc6f 100644 --- a/drivers/isdn/hardware/mISDN/mISDNipac.c +++ b/drivers/isdn/hardware/mISDN/mISDNipac.c @@ -20,6 +20,7 @@ * */ +#include #include #include #include "ipac.h" diff --git a/drivers/isdn/hardware/mISDN/mISDNisar.c b/drivers/isdn/hardware/mISDN/mISDNisar.c index f0bc6fa..38eb314 100644 --- a/drivers/isdn/hardware/mISDN/mISDNisar.c +++ b/drivers/isdn/hardware/mISDN/mISDNisar.c @@ -25,6 +25,7 @@ */ /* #define DEBUG */ +#include #include #include #include diff --git a/drivers/isdn/hardware/mISDN/netjet.c b/drivers/isdn/hardware/mISDN/netjet.c index 6c1b164..0a3553d 100644 --- a/drivers/isdn/hardware/mISDN/netjet.c +++ b/drivers/isdn/hardware/mISDN/netjet.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "ipac.h" #include "iohelper.h" #include "netjet.h" diff --git a/drivers/isdn/hardware/mISDN/speedfax.c b/drivers/isdn/hardware/mISDN/speedfax.c index 7726afd..d097a4e 100644 --- a/drivers/isdn/hardware/mISDN/speedfax.c +++ b/drivers/isdn/hardware/mISDN/speedfax.c @@ -23,6 +23,7 @@ */ #include +#include #include #include #include diff --git a/drivers/isdn/hardware/mISDN/w6692.c b/drivers/isdn/hardware/mISDN/w6692.c index 2952a58..31f9d71 100644 --- a/drivers/isdn/hardware/mISDN/w6692.c +++ b/drivers/isdn/hardware/mISDN/w6692.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "w6692.h" #define W6692_REV "2.0" diff --git a/drivers/isdn/hisax/amd7930_fn.c b/drivers/isdn/hisax/amd7930_fn.c index d6fdf1f..5d72783 100644 --- a/drivers/isdn/hisax/amd7930_fn.c +++ b/drivers/isdn/hisax/amd7930_fn.c @@ -59,6 +59,7 @@ #include "amd7930_fn.h" #include #include +#include static void Amd7930_new_ph(struct IsdnCardState *cs); diff --git a/drivers/isdn/hisax/avm_pci.c b/drivers/isdn/hisax/avm_pci.c index 14295a1..fcf4ed1 100644 --- a/drivers/isdn/hisax/avm_pci.c +++ b/drivers/isdn/hisax/avm_pci.c @@ -17,6 +17,7 @@ #include "isac.h" #include "isdnl1.h" #include +#include #include #include diff --git a/drivers/isdn/hisax/callc.c b/drivers/isdn/hisax/callc.c index 475b1a0..f58ded8 100644 --- a/drivers/isdn/hisax/callc.c +++ b/drivers/isdn/hisax/callc.c @@ -17,6 +17,7 @@ */ #include +#include #include #include "hisax.h" #include diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c index 4fab18d..544cf4b 100644 --- a/drivers/isdn/hisax/config.c +++ b/drivers/isdn/hisax/config.c @@ -23,6 +23,7 @@ #include #include #include +#include #define HISAX_STATUS_BUFSIZE 4096 /* diff --git a/drivers/isdn/hisax/elsa.c b/drivers/isdn/hisax/elsa.c index 23c41fc..5d9d338 100644 --- a/drivers/isdn/hisax/elsa.c +++ b/drivers/isdn/hisax/elsa.c @@ -19,6 +19,7 @@ */ #include +#include #include "hisax.h" #include "arcofi.h" #include "isac.h" diff --git a/drivers/isdn/hisax/elsa_ser.c b/drivers/isdn/hisax/elsa_ser.c index 1657bba..cbda379 100644 --- a/drivers/isdn/hisax/elsa_ser.c +++ b/drivers/isdn/hisax/elsa_ser.c @@ -9,6 +9,7 @@ #include #include +#include #define MAX_MODEM_BUF 256 #define WAKEUP_CHARS (MAX_MODEM_BUF/2) diff --git a/drivers/isdn/hisax/fsm.c b/drivers/isdn/hisax/fsm.c index 34fade9..732ea63 100644 --- a/drivers/isdn/hisax/fsm.c +++ b/drivers/isdn/hisax/fsm.c @@ -15,6 +15,7 @@ */ #include +#include #include #include "hisax.h" diff --git a/drivers/isdn/hisax/hfc4s8s_l1.c b/drivers/isdn/hisax/hfc4s8s_l1.c index ab98e13..051b44e 100644 --- a/drivers/isdn/hisax/hfc4s8s_l1.c +++ b/drivers/isdn/hisax/hfc4s8s_l1.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/isdn/hisax/hfc_2bds0.c b/drivers/isdn/hisax/hfc_2bds0.c index 8d22f50..7250f56 100644 --- a/drivers/isdn/hisax/hfc_2bds0.c +++ b/drivers/isdn/hisax/hfc_2bds0.c @@ -12,6 +12,7 @@ #include #include +#include #include "hisax.h" #include "hfc_2bds0.h" #include "isdnl1.h" diff --git a/drivers/isdn/hisax/hfc_2bs0.c b/drivers/isdn/hisax/hfc_2bs0.c index d0520ad..b1f6481 100644 --- a/drivers/isdn/hisax/hfc_2bs0.c +++ b/drivers/isdn/hisax/hfc_2bs0.c @@ -16,6 +16,7 @@ #include "isac.h" #include "isdnl1.h" #include +#include static inline int WaitForBusy(struct IsdnCardState *cs) diff --git a/drivers/isdn/hisax/hfc_sx.c b/drivers/isdn/hisax/hfc_sx.c index 419f87c..be5faf4 100644 --- a/drivers/isdn/hisax/hfc_sx.c +++ b/drivers/isdn/hisax/hfc_sx.c @@ -17,6 +17,7 @@ #include "isdnl1.h" #include #include +#include static const char *hfcsx_revision = "$Revision: 1.12.2.5 $"; diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c index aaaeaaf..ed9527a 100644 --- a/drivers/isdn/hisax/hfc_usb.c +++ b/drivers/isdn/hisax/hfc_usb.c @@ -39,6 +39,7 @@ #include #include #include +#include #include "hisax.h" #include "hisax_if.h" #include "hfc_usb.h" diff --git a/drivers/isdn/hisax/hisax_isac.c b/drivers/isdn/hisax/hisax_isac.c index d0fefcf..a8447fa 100644 --- a/drivers/isdn/hisax/hisax_isac.c +++ b/drivers/isdn/hisax/hisax_isac.c @@ -21,6 +21,7 @@ */ #include +#include #include #include #include "hisax_isac.h" diff --git a/drivers/isdn/hisax/hscx.c b/drivers/isdn/hisax/hscx.c index c8f9951..904b910 100644 --- a/drivers/isdn/hisax/hscx.c +++ b/drivers/isdn/hisax/hscx.c @@ -16,6 +16,7 @@ #include "isac.h" #include "isdnl1.h" #include +#include static char *HSCXVer[] = {"A1", "?1", "A2", "?3", "A3", "V2.1", "?6", "?7", diff --git a/drivers/isdn/hisax/icc.c b/drivers/isdn/hisax/icc.c index c80cbb8..6305726 100644 --- a/drivers/isdn/hisax/icc.c +++ b/drivers/isdn/hisax/icc.c @@ -20,6 +20,7 @@ // #include "arcofi.h" #include "isdnl1.h" #include +#include #define DBUSY_TIMER_VALUE 80 #define ARCOFI_USE 0 diff --git a/drivers/isdn/hisax/ipacx.c b/drivers/isdn/hisax/ipacx.c index 00afd55..751b25f 100644 --- a/drivers/isdn/hisax/ipacx.c +++ b/drivers/isdn/hisax/ipacx.c @@ -10,6 +10,7 @@ * */ #include +#include #include #include "hisax_if.h" #include "hisax.h" diff --git a/drivers/isdn/hisax/isac.c b/drivers/isdn/hisax/isac.c index a19354d..2b66728 100644 --- a/drivers/isdn/hisax/isac.c +++ b/drivers/isdn/hisax/isac.c @@ -18,6 +18,7 @@ #include "arcofi.h" #include "isdnl1.h" #include +#include #include #define DBUSY_TIMER_VALUE 80 diff --git a/drivers/isdn/hisax/isar.c b/drivers/isdn/hisax/isar.c index 6bde16c..40b914b 100644 --- a/drivers/isdn/hisax/isar.c +++ b/drivers/isdn/hisax/isar.c @@ -13,6 +13,7 @@ #include "isar.h" #include "isdnl1.h" #include +#include #define DBG_LOADFIRM 0 #define DUMP_MBOXFRAME 2 diff --git a/drivers/isdn/hisax/isdnl1.c b/drivers/isdn/hisax/isdnl1.c index 9ce6abe..d5eeacf 100644 --- a/drivers/isdn/hisax/isdnl1.c +++ b/drivers/isdn/hisax/isdnl1.c @@ -19,6 +19,7 @@ */ #include +#include #include "hisax.h" #include "isdnl1.h" diff --git a/drivers/isdn/hisax/isdnl2.c b/drivers/isdn/hisax/isdnl2.c index 7b9496a..0858791 100644 --- a/drivers/isdn/hisax/isdnl2.c +++ b/drivers/isdn/hisax/isdnl2.c @@ -16,6 +16,7 @@ */ #include +#include #include "hisax.h" #include "isdnl2.h" diff --git a/drivers/isdn/hisax/isdnl3.c b/drivers/isdn/hisax/isdnl3.c index 0676602..fd0b643 100644 --- a/drivers/isdn/hisax/isdnl3.c +++ b/drivers/isdn/hisax/isdnl3.c @@ -16,6 +16,7 @@ */ #include +#include #include "hisax.h" #include "isdnl3.h" diff --git a/drivers/isdn/hisax/jade.c b/drivers/isdn/hisax/jade.c index 70840a7..ea8f840 100644 --- a/drivers/isdn/hisax/jade.c +++ b/drivers/isdn/hisax/jade.c @@ -17,6 +17,7 @@ #include "jade.h" #include "isdnl1.h" #include +#include int diff --git a/drivers/isdn/hisax/l3dss1.c b/drivers/isdn/hisax/l3dss1.c index a12fa4d..cc6ee2d 100644 --- a/drivers/isdn/hisax/l3dss1.c +++ b/drivers/isdn/hisax/l3dss1.c @@ -23,6 +23,7 @@ #include "isdnl3.h" #include "l3dss1.h" #include +#include extern char *HiSax_getrev(const char *revision); static const char *dss1_revision = "$Revision: 2.32.2.3 $"; diff --git a/drivers/isdn/hisax/l3ni1.c b/drivers/isdn/hisax/l3ni1.c index 4622d43..f958449 100644 --- a/drivers/isdn/hisax/l3ni1.c +++ b/drivers/isdn/hisax/l3ni1.c @@ -22,6 +22,7 @@ #include "isdnl3.h" #include "l3ni1.h" #include +#include extern char *HiSax_getrev(const char *revision); static const char *ni1_revision = "$Revision: 2.8.2.3 $"; diff --git a/drivers/isdn/hisax/netjet.c b/drivers/isdn/hisax/netjet.c index 02c6fba..5d7f0f2 100644 --- a/drivers/isdn/hisax/netjet.c +++ b/drivers/isdn/hisax/netjet.c @@ -21,6 +21,7 @@ #include "isdnl1.h" #include #include +#include #include #include "netjet.h" diff --git a/drivers/isdn/hisax/st5481_b.c b/drivers/isdn/hisax/st5481_b.c index 95b1cdd..e56e5af 100644 --- a/drivers/isdn/hisax/st5481_b.c +++ b/drivers/isdn/hisax/st5481_b.c @@ -11,8 +11,8 @@ */ #include +#include #include -#include #include #include #include "st5481.h" diff --git a/drivers/isdn/hisax/st5481_d.c b/drivers/isdn/hisax/st5481_d.c index 39e8e49..b7876b1 100644 --- a/drivers/isdn/hisax/st5481_d.c +++ b/drivers/isdn/hisax/st5481_d.c @@ -11,8 +11,8 @@ */ #include +#include #include -#include #include #include "st5481.h" diff --git a/drivers/isdn/hisax/tei.c b/drivers/isdn/hisax/tei.c index 6e65424..f4cb178 100644 --- a/drivers/isdn/hisax/tei.c +++ b/drivers/isdn/hisax/tei.c @@ -17,6 +17,7 @@ #include "hisax.h" #include "isdnl2.h" +#include #include #include diff --git a/drivers/isdn/hisax/w6692.c b/drivers/isdn/hisax/w6692.c index 9d6e864..e2cfb6f 100644 --- a/drivers/isdn/hisax/w6692.c +++ b/drivers/isdn/hisax/w6692.c @@ -16,6 +16,7 @@ #include "isdnl1.h" #include #include +#include /* table entry in the PCI devices list */ typedef struct { diff --git a/drivers/isdn/hysdn/hycapi.c b/drivers/isdn/hysdn/hycapi.c index fe874af..6299b06 100644 --- a/drivers/isdn/hysdn/hycapi.c +++ b/drivers/isdn/hysdn/hycapi.c @@ -17,6 +17,7 @@ #include #include #include +#include #define VER_DRIVER 0 #define VER_CARDTYPE 1 diff --git a/drivers/isdn/hysdn/hysdn_procconf.c b/drivers/isdn/hysdn/hysdn_procconf.c index 90b35e1..8096646 100644 --- a/drivers/isdn/hysdn/hysdn_procconf.c +++ b/drivers/isdn/hysdn/hysdn_procconf.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include diff --git a/drivers/isdn/hysdn/hysdn_proclog.c b/drivers/isdn/hysdn/hysdn_proclog.c index 8bcae28..e83f6fd 100644 --- a/drivers/isdn/hysdn/hysdn_proclog.c +++ b/drivers/isdn/hysdn/hysdn_proclog.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "hysdn_defs.h" diff --git a/drivers/isdn/i4l/isdn_audio.c b/drivers/isdn/i4l/isdn_audio.c index fb350c5..861bdf3 100644 --- a/drivers/isdn/i4l/isdn_audio.c +++ b/drivers/isdn/i4l/isdn_audio.c @@ -12,6 +12,7 @@ */ #include +#include #include "isdn_audio.h" #include "isdn_common.h" diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c index 00c60e2..70044ee 100644 --- a/drivers/isdn/i4l/isdn_common.c +++ b/drivers/isdn/i4l/isdn_common.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c index 507e13d..8c85d1e 100644 --- a/drivers/isdn/i4l/isdn_net.c +++ b/drivers/isdn/i4l/isdn_net.c @@ -23,6 +23,7 @@ */ #include +#include #include #include #include diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c index 45df667..f37b8f6 100644 --- a/drivers/isdn/i4l/isdn_ppp.c +++ b/drivers/isdn/i4l/isdn_ppp.c @@ -12,6 +12,7 @@ #include #include #include +#include #ifdef CONFIG_IPPP_FILTER #include #endif diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index 2881a66..fc8454d 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c @@ -12,6 +12,7 @@ #undef ISDN_TTY_STAT_DEBUG #include +#include #include #include #include "isdn_common.h" diff --git a/drivers/isdn/i4l/isdn_x25iface.c b/drivers/isdn/i4l/isdn_x25iface.c index 8b3efc2..efcf1f9 100644 --- a/drivers/isdn/i4l/isdn_x25iface.c +++ b/drivers/isdn/i4l/isdn_x25iface.c @@ -20,6 +20,7 @@ /* #include */ #include #include +#include #include #include #include "isdn_x25iface.h" diff --git a/drivers/isdn/icn/icn.c b/drivers/isdn/icn/icn.c index bf7997a..2e847a9 100644 --- a/drivers/isdn/icn/icn.c +++ b/drivers/isdn/icn/icn.c @@ -12,6 +12,7 @@ #include "icn.h" #include #include +#include #include static int portbase = ICN_BASEADDR; diff --git a/drivers/isdn/isdnloop/isdnloop.c b/drivers/isdn/isdnloop/isdnloop.c index a335c85..b8a1098 100644 --- a/drivers/isdn/isdnloop/isdnloop.c +++ b/drivers/isdn/isdnloop/isdnloop.c @@ -11,6 +11,7 @@ #include #include +#include #include #include #include "isdnloop.h" diff --git a/drivers/isdn/mISDN/clock.c b/drivers/isdn/mISDN/clock.c index f1bbc88..1fa629b 100644 --- a/drivers/isdn/mISDN/clock.c +++ b/drivers/isdn/mISDN/clock.c @@ -33,6 +33,7 @@ * */ +#include #include #include #include diff --git a/drivers/isdn/mISDN/core.c b/drivers/isdn/mISDN/core.c index 21d34be..afeebb0 100644 --- a/drivers/isdn/mISDN/core.c +++ b/drivers/isdn/mISDN/core.c @@ -12,6 +12,7 @@ * */ +#include #include #include #include diff --git a/drivers/isdn/mISDN/dsp_cmx.c b/drivers/isdn/mISDN/dsp_cmx.c index 9c7c0d1..713ef2b 100644 --- a/drivers/isdn/mISDN/dsp_cmx.c +++ b/drivers/isdn/mISDN/dsp_cmx.c @@ -124,6 +124,7 @@ /* delay.h is required for hw_lock.h */ +#include #include #include #include diff --git a/drivers/isdn/mISDN/dsp_core.c b/drivers/isdn/mISDN/dsp_core.c index 6eac588..6f5b548 100644 --- a/drivers/isdn/mISDN/dsp_core.c +++ b/drivers/isdn/mISDN/dsp_core.c @@ -154,6 +154,7 @@ */ #include +#include #include #include #include diff --git a/drivers/isdn/mISDN/dsp_pipeline.c b/drivers/isdn/mISDN/dsp_pipeline.c index e994167..621f310 100644 --- a/drivers/isdn/mISDN/dsp_pipeline.c +++ b/drivers/isdn/mISDN/dsp_pipeline.c @@ -25,6 +25,7 @@ */ #include +#include #include #include #include diff --git a/drivers/isdn/mISDN/dsp_tones.c b/drivers/isdn/mISDN/dsp_tones.c index 1debf53..7dbe54e 100644 --- a/drivers/isdn/mISDN/dsp_tones.c +++ b/drivers/isdn/mISDN/dsp_tones.c @@ -8,6 +8,7 @@ * */ +#include #include #include #include "core.h" diff --git a/drivers/isdn/mISDN/hwchannel.c b/drivers/isdn/mISDN/hwchannel.c index e8049be..307bd6e 100644 --- a/drivers/isdn/mISDN/hwchannel.c +++ b/drivers/isdn/mISDN/hwchannel.c @@ -15,6 +15,7 @@ * */ +#include #include #include diff --git a/drivers/isdn/mISDN/l1oip_core.c b/drivers/isdn/mISDN/l1oip_core.c index 325b1ad..22f38e4 100644 --- a/drivers/isdn/mISDN/l1oip_core.c +++ b/drivers/isdn/mISDN/l1oip_core.c @@ -233,6 +233,7 @@ socket process and create a new one. #include #include #include +#include #include #include "core.h" #include "l1oip.h" diff --git a/drivers/isdn/mISDN/layer1.c b/drivers/isdn/mISDN/layer1.c index e826eeb..ac4aa18 100644 --- a/drivers/isdn/mISDN/layer1.c +++ b/drivers/isdn/mISDN/layer1.c @@ -16,6 +16,7 @@ */ +#include #include #include #include "core.h" diff --git a/drivers/isdn/mISDN/layer2.c b/drivers/isdn/mISDN/layer2.c index e17f004..c973717 100644 --- a/drivers/isdn/mISDN/layer2.c +++ b/drivers/isdn/mISDN/layer2.c @@ -16,6 +16,7 @@ */ #include +#include #include "core.h" #include "fsm.h" #include "layer2.h" diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c index fcfe17a..3232206 100644 --- a/drivers/isdn/mISDN/socket.c +++ b/drivers/isdn/mISDN/socket.c @@ -16,6 +16,7 @@ */ #include +#include #include "core.h" static u_int *debug; diff --git a/drivers/isdn/mISDN/stack.c b/drivers/isdn/mISDN/stack.c index 0d05ec4..b159bd5 100644 --- a/drivers/isdn/mISDN/stack.c +++ b/drivers/isdn/mISDN/stack.c @@ -15,6 +15,7 @@ * */ +#include #include #include #include diff --git a/drivers/isdn/mISDN/tei.c b/drivers/isdn/mISDN/tei.c index 6d4da60..34e898f 100644 --- a/drivers/isdn/mISDN/tei.c +++ b/drivers/isdn/mISDN/tei.c @@ -16,6 +16,7 @@ */ #include "layer2.h" #include +#include #include "core.h" #define ID_REQUEST 1 diff --git a/drivers/isdn/mISDN/timerdev.c b/drivers/isdn/mISDN/timerdev.c index 5b7e9bf..8785004 100644 --- a/drivers/isdn/mISDN/timerdev.c +++ b/drivers/isdn/mISDN/timerdev.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include diff --git a/drivers/isdn/pcbit/callbacks.c b/drivers/isdn/pcbit/callbacks.c index 43ecd0f..976143b 100644 --- a/drivers/isdn/pcbit/callbacks.c +++ b/drivers/isdn/pcbit/callbacks.c @@ -19,7 +19,6 @@ #include #include -#include #include #include diff --git a/drivers/isdn/pcbit/edss1.c b/drivers/isdn/pcbit/edss1.c index 37e9626..d5920ae 100644 --- a/drivers/isdn/pcbit/edss1.c +++ b/drivers/isdn/pcbit/edss1.c @@ -19,7 +19,6 @@ #include #include -#include #include #include diff --git a/drivers/isdn/sc/init.c b/drivers/isdn/sc/init.c index 5a07748..ca710ab 100644 --- a/drivers/isdn/sc/init.c +++ b/drivers/isdn/sc/init.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "includes.h" #include "hardware.h" #include "card.h" diff --git a/drivers/leds/dell-led.c b/drivers/leds/dell-led.c index ee31089..5259029 100644 --- a/drivers/leds/dell-led.c +++ b/drivers/leds/dell-led.c @@ -13,6 +13,7 @@ #include #include +#include MODULE_AUTHOR("Louis Davis/Jim Dailey"); MODULE_DESCRIPTION("Dell LED Control Driver"); diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c index d8ddd9e..f1c00db 100644 --- a/drivers/leds/led-triggers.c +++ b/drivers/leds/led-triggers.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "leds.h" /* diff --git a/drivers/leds/leds-88pm860x.c b/drivers/leds/leds-88pm860x.c index d196073..16a60c0 100644 --- a/drivers/leds/leds-88pm860x.c +++ b/drivers/leds/leds-88pm860x.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff --git a/drivers/leds/leds-adp5520.c b/drivers/leds/leds-adp5520.c index a8f3159..7ba4c7b 100644 --- a/drivers/leds/leds-adp5520.c +++ b/drivers/leds/leds-adp5520.c @@ -20,6 +20,7 @@ #include #include #include +#include struct adp5520_led { struct led_classdev cdev; diff --git a/drivers/leds/leds-atmel-pwm.c b/drivers/leds/leds-atmel-pwm.c index 52297c3..c941d906 100644 --- a/drivers/leds/leds-atmel-pwm.c +++ b/drivers/leds/leds-atmel-pwm.c @@ -3,6 +3,7 @@ #include #include #include +#include struct pwmled { diff --git a/drivers/leds/leds-bd2802.c b/drivers/leds/leds-bd2802.c index 779d7f2..286b501 100644 --- a/drivers/leds/leds-bd2802.c +++ b/drivers/leds/leds-bd2802.c @@ -18,6 +18,7 @@ #include #include #include +#include #define LED_CTL(rgb2en, rgb1en) ((rgb2en) << 4 | ((rgb1en) << 0)) diff --git a/drivers/leds/leds-da903x.c b/drivers/leds/leds-da903x.c index 1f3cc51..f28931c 100644 --- a/drivers/leds/leds-da903x.c +++ b/drivers/leds/leds-da903x.c @@ -19,6 +19,7 @@ #include #include #include +#include #define DA9030_LED1_CONTROL 0x20 #define DA9030_LED2_CONTROL 0x21 diff --git a/drivers/leds/leds-dac124s085.c b/drivers/leds/leds-dac124s085.c index 2913d76..31cf0d6 100644 --- a/drivers/leds/leds-dac124s085.c +++ b/drivers/leds/leds-dac124s085.c @@ -9,7 +9,6 @@ * LED driver for the DAC124S085 SPI DAC */ -#include #include #include #include diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index 0823e26..c6e4b77 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include diff --git a/drivers/leds/leds-lp3944.c b/drivers/leds/leds-lp3944.c index 5946208..8d5ecce 100644 --- a/drivers/leds/leds-lp3944.c +++ b/drivers/leds/leds-lp3944.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include diff --git a/drivers/leds/leds-lt3593.c b/drivers/leds/leds-lt3593.c index fee40a8..2579678 100644 --- a/drivers/leds/leds-lt3593.c +++ b/drivers/leds/leds-lt3593.c @@ -23,6 +23,7 @@ #include #include #include +#include struct lt3593_led_data { struct led_classdev cdev; diff --git a/drivers/leds/leds-pca9532.c b/drivers/leds/leds-pca9532.c index adc561e..6682175 100644 --- a/drivers/leds/leds-pca9532.c +++ b/drivers/leds/leds-pca9532.c @@ -13,6 +13,7 @@ #include #include +#include #include #include #include diff --git a/drivers/leds/leds-pca955x.c b/drivers/leds/leds-pca955x.c index 4e2d1a4..8ff50f2 100644 --- a/drivers/leds/leds-pca955x.c +++ b/drivers/leds/leds-pca955x.c @@ -48,6 +48,7 @@ #include #include #include +#include /* LED select registers determine the source that drives LED outputs */ #define PCA955X_LS_LED_ON 0x0 /* Output LOW */ diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c index 88b1dd0..da3fa8d 100644 --- a/drivers/leds/leds-pwm.c +++ b/drivers/leds/leds-pwm.c @@ -21,6 +21,7 @@ #include #include #include +#include struct led_pwm_data { struct led_classdev cdev; diff --git a/drivers/leds/leds-regulator.c b/drivers/leds/leds-regulator.c index 7f00de3..3790816 100644 --- a/drivers/leds/leds-regulator.c +++ b/drivers/leds/leds-regulator.c @@ -13,6 +13,7 @@ #include #include +#include #include #include #include diff --git a/drivers/leds/leds-s3c24xx.c b/drivers/leds/leds-s3c24xx.c index aa7acf3..a77771d 100644 --- a/drivers/leds/leds-s3c24xx.c +++ b/drivers/leds/leds-s3c24xx.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include diff --git a/drivers/leds/leds-sunfire.c b/drivers/leds/leds-sunfire.c index 6b008f0..ab6d18f 100644 --- a/drivers/leds/leds-sunfire.c +++ b/drivers/leds/leds-sunfire.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include diff --git a/drivers/leds/leds-wm831x-status.c b/drivers/leds/leds-wm831x-status.c index c586d05..ef5c241 100644 --- a/drivers/leds/leds-wm831x-status.c +++ b/drivers/leds/leds-wm831x-status.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/leds/leds-wm8350.c b/drivers/leds/leds-wm8350.c index 38c6bcb..5aab32c 100644 --- a/drivers/leds/leds-wm8350.c +++ b/drivers/leds/leds-wm8350.c @@ -16,6 +16,7 @@ #include #include #include +#include /* Microamps */ static const int isink_cur[] = { diff --git a/drivers/leds/ledtrig-backlight.c b/drivers/leds/ledtrig-backlight.c index d3dfcfb..f948e57 100644 --- a/drivers/leds/ledtrig-backlight.c +++ b/drivers/leds/ledtrig-backlight.c @@ -12,6 +12,7 @@ #include #include +#include #include #include #include diff --git a/drivers/leds/ledtrig-gpio.c b/drivers/leds/ledtrig-gpio.c index f591337..991d93b 100644 --- a/drivers/leds/ledtrig-gpio.c +++ b/drivers/leds/ledtrig-gpio.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "leds.h" struct gpio_trig_data { diff --git a/drivers/leds/ledtrig-heartbeat.c b/drivers/leds/ledtrig-heartbeat.c index c1c1ea6..759c0bb 100644 --- a/drivers/leds/ledtrig-heartbeat.c +++ b/drivers/leds/ledtrig-heartbeat.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/leds/ledtrig-timer.c b/drivers/leds/ledtrig-timer.c index 38b3378..82b77bd 100644 --- a/drivers/leds/ledtrig-timer.c +++ b/drivers/leds/ledtrig-timer.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "leds.h" struct timer_trig_data { diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c index 8744d24..efa2024 100644 --- a/drivers/lguest/core.c +++ b/drivers/lguest/core.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h index bc28745..9136411 100644 --- a/drivers/lguest/lg.h +++ b/drivers/lguest/lg.h @@ -10,6 +10,7 @@ #include #include #include +#include #include diff --git a/drivers/lguest/lguest_device.c b/drivers/lguest/lguest_device.c index b6200bc..07090f3 100644 --- a/drivers/lguest/lguest_device.c +++ b/drivers/lguest/lguest_device.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c index bd16323..85b714d 100644 --- a/drivers/lguest/lguest_user.c +++ b/drivers/lguest/lguest_user.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "lg.h" /*L:056 diff --git a/drivers/lguest/page_tables.c b/drivers/lguest/page_tables.c index cf94326..04b2212 100644 --- a/drivers/lguest/page_tables.c +++ b/drivers/lguest/page_tables.c @@ -10,6 +10,7 @@ /* Copyright (C) Rusty Russell IBM Corporation 2006. * GPL v2 and any later version */ #include +#include #include #include #include diff --git a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c index e943d2a..067f996 100644 --- a/drivers/macintosh/mac_hid.c +++ b/drivers/macintosh/mac_hid.c @@ -13,6 +13,7 @@ #include #include #include +#include MODULE_LICENSE("GPL"); diff --git a/drivers/macintosh/rack-meter.c b/drivers/macintosh/rack-meter.c index 93fb320..7c54d80 100644 --- a/drivers/macintosh/rack-meter.c +++ b/drivers/macintosh/rack-meter.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c index f96feeb..888448c 100644 --- a/drivers/macintosh/smu.c +++ b/drivers/macintosh/smu.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c index 921373e..b18fa94 100644 --- a/drivers/macintosh/therm_pm72.c +++ b/drivers/macintosh/therm_pm72.c @@ -114,7 +114,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c index 7fb8b4d..0839770 100644 --- a/drivers/macintosh/therm_windtunnel.c +++ b/drivers/macintosh/therm_windtunnel.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/macintosh/via-pmu68k.c b/drivers/macintosh/via-pmu68k.c index fb9fa61..aeb30d0 100644 --- a/drivers/macintosh/via-pmu68k.c +++ b/drivers/macintosh/via-pmu68k.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include diff --git a/drivers/macintosh/windfarm_core.c b/drivers/macintosh/windfarm_core.c index 419795f..c092354 100644 --- a/drivers/macintosh/windfarm_core.c +++ b/drivers/macintosh/windfarm_core.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/md/dm-log-userspace-base.c b/drivers/md/dm-log-userspace-base.c index 7ac2c14..1ed0094 100644 --- a/drivers/md/dm-log-userspace-base.c +++ b/drivers/md/dm-log-userspace-base.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include diff --git a/drivers/md/dm-log-userspace-transfer.c b/drivers/md/dm-log-userspace-transfer.c index f1c8cae..075cbcf 100644 --- a/drivers/md/dm-log-userspace-transfer.c +++ b/drivers/md/dm-log-userspace-transfer.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include diff --git a/drivers/md/dm-region-hash.c b/drivers/md/dm-region-hash.c index 168bd38..bd5c58b 100644 --- a/drivers/md/dm-region-hash.c +++ b/drivers/md/dm-region-hash.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include "dm.h" diff --git a/drivers/md/dm-service-time.c b/drivers/md/dm-service-time.c index cfa668f..9c6c2e4 100644 --- a/drivers/md/dm-service-time.c +++ b/drivers/md/dm-service-time.c @@ -11,6 +11,8 @@ #include "dm.h" #include "dm-path-selector.h" +#include + #define DM_MSG_PREFIX "multipath service-time" #define ST_MIN_IO 1 #define ST_MAX_RELATIVE_THROUGHPUT 100 diff --git a/drivers/md/dm-target.c b/drivers/md/dm-target.c index 04feccf..11dea11 100644 --- a/drivers/md/dm-target.c +++ b/drivers/md/dm-target.c @@ -10,7 +10,6 @@ #include #include #include -#include #define DM_MSG_PREFIX "target" diff --git a/drivers/md/faulty.c b/drivers/md/faulty.c index 713acd0..8e3850b 100644 --- a/drivers/md/faulty.c +++ b/drivers/md/faulty.c @@ -64,6 +64,7 @@ #define MaxFault 50 #include #include +#include #include "md.h" #include diff --git a/drivers/md/linear.c b/drivers/md/linear.c index bb2a231..09437e9 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "md.h" #include "linear.h" diff --git a/drivers/md/md.c b/drivers/md/md.c index fdc1890..9712b2e 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -49,6 +49,7 @@ #include #include #include +#include #include "md.h" #include "bitmap.h" diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index 5558ebc..789bf53 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "md.h" #include "multipath.h" diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index 377cf2a..c3bec02 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -20,6 +20,7 @@ #include #include +#include #include "md.h" #include "raid0.h" diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index f741f77..e59b10e 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -31,6 +31,7 @@ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include #include #include #include diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index b4ba41e..e2766d8 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -18,6 +18,7 @@ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include #include #include #include diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 70ffbd0..e3e9a36 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -50,6 +50,7 @@ #include #include #include +#include #include "md.h" #include "raid5.h" #include "bitmap.h" diff --git a/drivers/md/raid6algos.c b/drivers/md/raid6algos.c index bffc61b..1f8784b 100644 --- a/drivers/md/raid6algos.c +++ b/drivers/md/raid6algos.c @@ -17,6 +17,7 @@ */ #include +#include #ifndef __KERNEL__ #include #include diff --git a/drivers/media/IR/ir-keytable.c b/drivers/media/IR/ir-keytable.c index 0a3b4ed..bfca26d5 100644 --- a/drivers/media/IR/ir-keytable.c +++ b/drivers/media/IR/ir-keytable.c @@ -14,6 +14,7 @@ #include +#include #include #define IR_TAB_MIN_SIZE 32 diff --git a/drivers/media/IR/ir-sysfs.c b/drivers/media/IR/ir-sysfs.c index bf5fbcd..e14e6c4 100644 --- a/drivers/media/IR/ir-sysfs.c +++ b/drivers/media/IR/ir-sysfs.c @@ -12,6 +12,7 @@ * GNU General Public License for more details. */ +#include #include #include #include diff --git a/drivers/media/common/tuners/max2165.c b/drivers/media/common/tuners/max2165.c index 3d03640..937e4b0 100644 --- a/drivers/media/common/tuners/max2165.c +++ b/drivers/media/common/tuners/max2165.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "dvb_frontend.h" diff --git a/drivers/media/common/tuners/mc44s803.c b/drivers/media/common/tuners/mc44s803.c index 20c4485..fe5c4b8 100644 --- a/drivers/media/common/tuners/mc44s803.c +++ b/drivers/media/common/tuners/mc44s803.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "dvb_frontend.h" diff --git a/drivers/media/common/tuners/mt2060.c b/drivers/media/common/tuners/mt2060.c index c7abe3d..2d0e768 100644 --- a/drivers/media/common/tuners/mt2060.c +++ b/drivers/media/common/tuners/mt2060.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "dvb_frontend.h" diff --git a/drivers/media/common/tuners/mt20xx.c b/drivers/media/common/tuners/mt20xx.c index 44608ad..d0e70e1 100644 --- a/drivers/media/common/tuners/mt20xx.c +++ b/drivers/media/common/tuners/mt20xx.c @@ -6,6 +6,7 @@ */ #include #include +#include #include #include "tuner-i2c.h" #include "mt20xx.h" diff --git a/drivers/media/common/tuners/mt2131.c b/drivers/media/common/tuners/mt2131.c index e8d3c48..a4f830b 100644 --- a/drivers/media/common/tuners/mt2131.c +++ b/drivers/media/common/tuners/mt2131.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "dvb_frontend.h" diff --git a/drivers/media/common/tuners/mt2266.c b/drivers/media/common/tuners/mt2266.c index 54b18f9..25a8ea3 100644 --- a/drivers/media/common/tuners/mt2266.c +++ b/drivers/media/common/tuners/mt2266.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "dvb_frontend.h" #include "mt2266.h" diff --git a/drivers/media/common/tuners/tda827x.c b/drivers/media/common/tuners/tda827x.c index 36a7bc7..b21b6ea 100644 --- a/drivers/media/common/tuners/tda827x.c +++ b/drivers/media/common/tuners/tda827x.c @@ -19,6 +19,7 @@ */ #include +#include #include #include #include diff --git a/drivers/media/common/tuners/tda8290.c b/drivers/media/common/tuners/tda8290.c index 2833137..c9062ce 100644 --- a/drivers/media/common/tuners/tda8290.c +++ b/drivers/media/common/tuners/tda8290.c @@ -21,6 +21,7 @@ */ #include +#include #include #include #include "tuner-i2c.h" diff --git a/drivers/media/common/tuners/tda9887.c b/drivers/media/common/tuners/tda9887.c index a71c100..bf14bd7 100644 --- a/drivers/media/common/tuners/tda9887.c +++ b/drivers/media/common/tuners/tda9887.c @@ -4,7 +4,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/media/common/tuners/tea5761.c b/drivers/media/common/tuners/tea5761.c index 60ed872..925399d 100644 --- a/drivers/media/common/tuners/tea5761.c +++ b/drivers/media/common/tuners/tea5761.c @@ -8,6 +8,7 @@ */ #include +#include #include #include #include diff --git a/drivers/media/common/tuners/tea5767.c b/drivers/media/common/tuners/tea5767.c index 223a226..36e85d8 100644 --- a/drivers/media/common/tuners/tea5767.c +++ b/drivers/media/common/tuners/tea5767.c @@ -11,6 +11,7 @@ */ #include +#include #include #include #include "tuner-i2c.h" diff --git a/drivers/media/common/tuners/tuner-i2c.h b/drivers/media/common/tuners/tuner-i2c.h index cb1c714..18f0056 100644 --- a/drivers/media/common/tuners/tuner-i2c.h +++ b/drivers/media/common/tuners/tuner-i2c.h @@ -22,6 +22,7 @@ #define __TUNER_I2C_H__ #include +#include struct tuner_i2c_props { u8 addr; diff --git a/drivers/media/common/tuners/tuner-xc2028.c b/drivers/media/common/tuners/tuner-xc2028.c index be51c29..96d6170 100644 --- a/drivers/media/common/tuners/tuner-xc2028.c +++ b/drivers/media/common/tuners/tuner-xc2028.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include "tuner-i2c.h" #include "tuner-xc2028.h" diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c index 0e246ea..770243c 100644 --- a/drivers/media/dvb/bt8xx/dst_ca.c +++ b/drivers/media/dvb/bt8xx/dst_ca.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c index 383cca3..b6d4696 100644 --- a/drivers/media/dvb/dm1105/dm1105.c +++ b/drivers/media/dvb/dm1105/dm1105.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include "demux.h" diff --git a/drivers/media/dvb/dvb-core/dmxdev.h b/drivers/media/dvb/dvb-core/dmxdev.h index c1379b5..02ebe28 100644 --- a/drivers/media/dvb/dvb-core/dmxdev.h +++ b/drivers/media/dvb/dvb-core/dmxdev.h @@ -31,6 +31,7 @@ #include #include #include +#include #include diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h index 80dda30..bf0e6be 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.h +++ b/drivers/media/dvb/dvb-core/dvb_frontend.h @@ -36,6 +36,7 @@ #include #include #include +#include #include diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c index d797538..74d94e4 100644 --- a/drivers/media/dvb/dvb-usb/af9015.c +++ b/drivers/media/dvb/dvb-usb/af9015.c @@ -22,6 +22,7 @@ */ #include +#include #include "af9015.h" #include "af9013.h" diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c index a7b8405..960376d 100644 --- a/drivers/media/dvb/dvb-usb/cxusb.c +++ b/drivers/media/dvb/dvb-usb/cxusb.c @@ -25,6 +25,7 @@ */ #include #include +#include #include "cxusb.h" diff --git a/drivers/media/dvb/firewire/firedtv-1394.c b/drivers/media/dvb/firewire/firedtv-1394.c index c3e0ec2..26333b4 100644 --- a/drivers/media/dvb/firewire/firedtv-1394.c +++ b/drivers/media/dvb/firewire/firedtv-1394.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff --git a/drivers/media/dvb/firewire/firedtv-rc.c b/drivers/media/dvb/firewire/firedtv-rc.c index 599d66e..fcf3828 100644 --- a/drivers/media/dvb/firewire/firedtv-rc.c +++ b/drivers/media/dvb/firewire/firedtv-rc.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/dvb/frontends/au8522_dig.c b/drivers/media/dvb/frontends/au8522_dig.c index 956b80f..a1fed0f 100644 --- a/drivers/media/dvb/frontends/au8522_dig.c +++ b/drivers/media/dvb/frontends/au8522_dig.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include "dvb_frontend.h" #include "au8522.h" diff --git a/drivers/media/dvb/frontends/dib0070.c b/drivers/media/dvb/frontends/dib0070.c index 0d12763..d4e466a 100644 --- a/drivers/media/dvb/frontends/dib0070.c +++ b/drivers/media/dvb/frontends/dib0070.c @@ -25,6 +25,7 @@ */ #include +#include #include #include "dvb_frontend.h" diff --git a/drivers/media/dvb/frontends/dib0090.c b/drivers/media/dvb/frontends/dib0090.c index 7eac178..65240b7 100644 --- a/drivers/media/dvb/frontends/dib0090.c +++ b/drivers/media/dvb/frontends/dib0090.c @@ -25,6 +25,7 @@ */ #include +#include #include #include "dvb_frontend.h" diff --git a/drivers/media/dvb/frontends/dib3000mc.c b/drivers/media/dvb/frontends/dib3000mc.c index fa85160..40a0998 100644 --- a/drivers/media/dvb/frontends/dib3000mc.c +++ b/drivers/media/dvb/frontends/dib3000mc.c @@ -12,6 +12,7 @@ */ #include +#include #include #include "dvb_frontend.h" diff --git a/drivers/media/dvb/frontends/dib7000m.c b/drivers/media/dvb/frontends/dib7000m.c index 0109720..0f09fd3 100644 --- a/drivers/media/dvb/frontends/dib7000m.c +++ b/drivers/media/dvb/frontends/dib7000m.c @@ -9,6 +9,7 @@ * published by the Free Software Foundation, version 2. */ #include +#include #include #include "dvb_frontend.h" diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c index 750ae61..85468a4 100644 --- a/drivers/media/dvb/frontends/dib7000p.c +++ b/drivers/media/dvb/frontends/dib7000p.c @@ -8,6 +8,7 @@ * published by the Free Software Foundation, version 2. */ #include +#include #include #include "dvb_math.h" diff --git a/drivers/media/dvb/frontends/dib8000.c b/drivers/media/dvb/frontends/dib8000.c index 2aa97dd6..df17b91 100644 --- a/drivers/media/dvb/frontends/dib8000.c +++ b/drivers/media/dvb/frontends/dib8000.c @@ -8,6 +8,7 @@ * published by the Free Software Foundation, version 2. */ #include +#include #include #include "dvb_math.h" diff --git a/drivers/media/dvb/frontends/drx397xD.c b/drivers/media/dvb/frontends/drx397xD.c index 868b78b..f74cca6 100644 --- a/drivers/media/dvb/frontends/drx397xD.c +++ b/drivers/media/dvb/frontends/drx397xD.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include "dvb_frontend.h" diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c index 6d865d6..4d4d0bb 100644 --- a/drivers/media/dvb/frontends/dvb-pll.c +++ b/drivers/media/dvb/frontends/dvb-pll.c @@ -18,6 +18,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include #include #include #include diff --git a/drivers/media/dvb/frontends/itd1000.c b/drivers/media/dvb/frontends/itd1000.c index 600dad6..f7a40a1 100644 --- a/drivers/media/dvb/frontends/itd1000.c +++ b/drivers/media/dvb/frontends/itd1000.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "dvb_frontend.h" diff --git a/drivers/media/dvb/frontends/lgdt3304.c b/drivers/media/dvb/frontends/lgdt3304.c index e334b5d..45a529b 100644 --- a/drivers/media/dvb/frontends/lgdt3304.c +++ b/drivers/media/dvb/frontends/lgdt3304.c @@ -7,6 +7,7 @@ #include #include +#include #include #include "dvb_frontend.h" #include "lgdt3304.h" diff --git a/drivers/media/dvb/frontends/lgdt3305.c b/drivers/media/dvb/frontends/lgdt3305.c index fde8c59..d69c775 100644 --- a/drivers/media/dvb/frontends/lgdt3305.c +++ b/drivers/media/dvb/frontends/lgdt3305.c @@ -21,6 +21,7 @@ #include #include +#include #include "dvb_math.h" #include "lgdt3305.h" diff --git a/drivers/media/dvb/frontends/mb86a16.c b/drivers/media/dvb/frontends/mb86a16.c index d05f750..599d1aa 100644 --- a/drivers/media/dvb/frontends/mb86a16.c +++ b/drivers/media/dvb/frontends/mb86a16.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "dvb_frontend.h" #include "mb86a16.h" diff --git a/drivers/media/dvb/frontends/s921_module.c b/drivers/media/dvb/frontends/s921_module.c index 3156b64..0eefff6 100644 --- a/drivers/media/dvb/frontends/s921_module.c +++ b/drivers/media/dvb/frontends/s921_module.c @@ -9,6 +9,7 @@ #include #include +#include #include #include "dvb_frontend.h" #include "s921_module.h" diff --git a/drivers/media/dvb/frontends/stb0899_drv.c b/drivers/media/dvb/frontends/stb0899_drv.c index 1570669..8e38fce 100644 --- a/drivers/media/dvb/frontends/stb0899_drv.c +++ b/drivers/media/dvb/frontends/stb0899_drv.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/drivers/media/dvb/frontends/stb6000.c b/drivers/media/dvb/frontends/stb6000.c index 0e2cb0d..ed69964 100644 --- a/drivers/media/dvb/frontends/stb6000.c +++ b/drivers/media/dvb/frontends/stb6000.c @@ -20,6 +20,7 @@ */ +#include #include #include #include diff --git a/drivers/media/dvb/frontends/stb6100.c b/drivers/media/dvb/frontends/stb6100.c index 60ee18a..f73c133 100644 --- a/drivers/media/dvb/frontends/stb6100.c +++ b/drivers/media/dvb/frontends/stb6100.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include "dvb_frontend.h" diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c index c52c335..a3c07fe 100644 --- a/drivers/media/dvb/frontends/stv090x.c +++ b/drivers/media/dvb/frontends/stv090x.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/drivers/media/dvb/frontends/stv6110.c b/drivers/media/dvb/frontends/stv6110.c index bef0cc8..2dca7c8 100644 --- a/drivers/media/dvb/frontends/stv6110.c +++ b/drivers/media/dvb/frontends/stv6110.c @@ -22,6 +22,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include #include #include diff --git a/drivers/media/dvb/frontends/stv6110x.c b/drivers/media/dvb/frontends/stv6110x.c index f931ed0..dea4245 100644 --- a/drivers/media/dvb/frontends/stv6110x.c +++ b/drivers/media/dvb/frontends/stv6110x.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include "dvb_frontend.h" diff --git a/drivers/media/dvb/frontends/tda665x.c b/drivers/media/dvb/frontends/tda665x.c index c44fefe..2c1c759 100644 --- a/drivers/media/dvb/frontends/tda665x.c +++ b/drivers/media/dvb/frontends/tda665x.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "dvb_frontend.h" #include "tda665x.h" diff --git a/drivers/media/dvb/frontends/tda8261.c b/drivers/media/dvb/frontends/tda8261.c index 614afce..1742056 100644 --- a/drivers/media/dvb/frontends/tda8261.c +++ b/drivers/media/dvb/frontends/tda8261.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "dvb_frontend.h" #include "tda8261.h" diff --git a/drivers/media/dvb/frontends/tda826x.c b/drivers/media/dvb/frontends/tda826x.c index a051554..06c9480 100644 --- a/drivers/media/dvb/frontends/tda826x.c +++ b/drivers/media/dvb/frontends/tda826x.c @@ -20,6 +20,7 @@ */ +#include #include #include #include diff --git a/drivers/media/dvb/frontends/tua6100.c b/drivers/media/dvb/frontends/tua6100.c index 1790bae..bcb95c2 100644 --- a/drivers/media/dvb/frontends/tua6100.c +++ b/drivers/media/dvb/frontends/tua6100.c @@ -28,6 +28,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include #include #include #include diff --git a/drivers/media/dvb/frontends/zl10036.c b/drivers/media/dvb/frontends/zl10036.c index 34c5de4..4627f49 100644 --- a/drivers/media/dvb/frontends/zl10036.c +++ b/drivers/media/dvb/frontends/zl10036.c @@ -29,6 +29,7 @@ #include #include +#include #include #include "zl10036.h" diff --git a/drivers/media/dvb/mantis/hopper_cards.c b/drivers/media/dvb/mantis/hopper_cards.c index d073c61..09e9fc7 100644 --- a/drivers/media/dvb/mantis/hopper_cards.c +++ b/drivers/media/dvb/mantis/hopper_cards.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/drivers/media/dvb/mantis/mantis_ca.c b/drivers/media/dvb/mantis/mantis_ca.c index 403ce04..330216f 100644 --- a/drivers/media/dvb/mantis/mantis_ca.c +++ b/drivers/media/dvb/mantis/mantis_ca.c @@ -19,6 +19,7 @@ */ #include +#include #include #include diff --git a/drivers/media/dvb/mantis/mantis_cards.c b/drivers/media/dvb/mantis/mantis_cards.c index 16f1708..cf4b39f 100644 --- a/drivers/media/dvb/mantis/mantis_cards.c +++ b/drivers/media/dvb/mantis/mantis_cards.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/drivers/media/dvb/ngene/ngene-core.c b/drivers/media/dvb/ngene/ngene-core.c index 0150dfe..645e8b8 100644 --- a/drivers/media/dvb/ngene/ngene-core.c +++ b/drivers/media/dvb/ngene/ngene-core.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/dvb/pluto2/pluto2.c index 80d14a0..1c79821 100644 --- a/drivers/media/dvb/pluto2/pluto2.c +++ b/drivers/media/dvb/pluto2/pluto2.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "demux.h" #include "dmxdev.h" diff --git a/drivers/media/dvb/pt1/pt1.c b/drivers/media/dvb/pt1/pt1.c index 81e623a..6aded23 100644 --- a/drivers/media/dvb/pt1/pt1.c +++ b/drivers/media/dvb/pt1/pt1.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index 4bfd345..0c87a3c 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c index 5f39398..b80d09b 100644 --- a/drivers/media/dvb/siano/smsdvb.c +++ b/drivers/media/dvb/siano/smsdvb.c @@ -20,6 +20,7 @@ along with this program. If not, see . ****************************************************************/ #include +#include #include #include "dmxdev.h" diff --git a/drivers/media/dvb/siano/smssdio.c b/drivers/media/dvb/siano/smssdio.c index 195244a..e57d38b 100644 --- a/drivers/media/dvb/siano/smssdio.c +++ b/drivers/media/dvb/siano/smssdio.c @@ -33,6 +33,7 @@ */ #include +#include #include #include #include diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index 5eac272..a9c27fb 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -23,6 +23,7 @@ along with this program. If not, see . #include #include #include +#include #include "smscoreapi.h" #include "sms-cards.h" diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index baf3159..3891559 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include diff --git a/drivers/media/dvb/ttpci/av7110_ca.c b/drivers/media/dvb/ttpci/av7110_ca.c index c7a65b1..ac7779c 100644 --- a/drivers/media/dvb/ttpci/av7110_ca.c +++ b/drivers/media/dvb/ttpci/av7110_ca.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "av7110.h" #include "av7110_hw.h" diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c index 000f4d3..7903967 100644 --- a/drivers/media/radio/radio-gemtek-pci.c +++ b/drivers/media/radio/radio-gemtek-pci.c @@ -48,6 +48,7 @@ #include #include /* for KERNEL_VERSION MACRO */ #include +#include #include #include diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c index f8213b7..08f1051 100644 --- a/drivers/media/radio/radio-maestro.c +++ b/drivers/media/radio/radio-maestro.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c index 44b4dbe..4349213 100644 --- a/drivers/media/radio/radio-maxiradio.c +++ b/drivers/media/radio/radio-maxiradio.c @@ -42,6 +42,7 @@ #include #include /* for KERNEL_VERSION MACRO */ #include +#include #include #include diff --git a/drivers/media/radio/radio-si4713.c b/drivers/media/radio/radio-si4713.c index 170bbe5..13554ab 100644 --- a/drivers/media/radio/radio-si4713.c +++ b/drivers/media/radio/radio-si4713.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/radio/radio-tea5764.c b/drivers/media/radio/radio-tea5764.c index 8e718bf..789d2ec 100644 --- a/drivers/media/radio/radio-tea5764.c +++ b/drivers/media/radio/radio-tea5764.c @@ -32,6 +32,7 @@ * add RDS support */ #include +#include #include #include /* Initdata */ #include /* kernel radio structs */ diff --git a/drivers/media/radio/radio-timb.c b/drivers/media/radio/radio-timb.c index 0de457f..b8bb3ef 100644 --- a/drivers/media/radio/radio-timb.c +++ b/drivers/media/radio/radio-timb.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/drivers/media/radio/saa7706h.c b/drivers/media/radio/saa7706h.c index 5db5528..585680f 100644 --- a/drivers/media/radio/saa7706h.c +++ b/drivers/media/radio/saa7706h.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/drivers/media/radio/si470x/radio-si470x-i2c.c b/drivers/media/radio/si470x/radio-si470x-i2c.c index 5466015..a5844d0 100644 --- a/drivers/media/radio/si470x/radio-si470x-i2c.c +++ b/drivers/media/radio/si470x/radio-si470x-i2c.c @@ -31,6 +31,7 @@ /* kernel includes */ #include +#include #include #include diff --git a/drivers/media/radio/si470x/radio-si470x-usb.c b/drivers/media/radio/si470x/radio-si470x-usb.c index 6f60841..5ec13e5 100644 --- a/drivers/media/radio/si470x/radio-si470x-usb.c +++ b/drivers/media/radio/si470x/radio-si470x-usb.c @@ -37,6 +37,7 @@ /* kernel includes */ #include #include +#include #include "radio-si470x.h" diff --git a/drivers/media/radio/si4713-i2c.c b/drivers/media/radio/si4713-i2c.c index 6a0028e..ab63dd5 100644 --- a/drivers/media/radio/si4713-i2c.c +++ b/drivers/media/radio/si4713-i2c.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/radio/tef6862.c b/drivers/media/radio/tef6862.c index 6e607ff..90cae90 100644 --- a/drivers/media/radio/tef6862.c +++ b/drivers/media/radio/tef6862.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/video/adv7170.c b/drivers/media/video/adv7170.c index 97b0034..48e89fb 100644 --- a/drivers/media/video/adv7170.c +++ b/drivers/media/video/adv7170.c @@ -30,6 +30,7 @@ #include #include +#include #include #include #include diff --git a/drivers/media/video/adv7175.c b/drivers/media/video/adv7175.c index cf8c06c..f1ba0d7 100644 --- a/drivers/media/video/adv7175.c +++ b/drivers/media/video/adv7175.c @@ -26,6 +26,7 @@ #include #include +#include #include #include #include diff --git a/drivers/media/video/adv7180.c b/drivers/media/video/adv7180.c index 0826f0d..23e610f 100644 --- a/drivers/media/video/adv7180.c +++ b/drivers/media/video/adv7180.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/video/adv7343.c b/drivers/media/video/adv7343.c index df26f2f..41b2930 100644 --- a/drivers/media/video/adv7343.c +++ b/drivers/media/video/adv7343.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/video/au0828/au0828-core.c b/drivers/media/video/au0828/au0828-core.c index 3544a2f..ca342e4 100644 --- a/drivers/media/video/au0828/au0828-core.c +++ b/drivers/media/video/au0828/au0828-core.c @@ -20,6 +20,7 @@ */ #include +#include #include #include #include diff --git a/drivers/media/video/au0828/au0828-dvb.c b/drivers/media/video/au0828/au0828-dvb.c index b8a4b52..f1edf1d 100644 --- a/drivers/media/video/au0828/au0828-dvb.c +++ b/drivers/media/video/au0828/au0828-dvb.c @@ -20,6 +20,7 @@ */ #include +#include #include #include #include diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c index dc67bc4..8c140c0 100644 --- a/drivers/media/video/au0828/au0828-video.c +++ b/drivers/media/video/au0828/au0828-video.c @@ -29,6 +29,7 @@ */ #include +#include #include #include #include diff --git a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c index 547e1a9..770cb9a 100644 --- a/drivers/media/video/bt819.c +++ b/drivers/media/video/bt819.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/video/bt856.c b/drivers/media/video/bt856.c index d0b4d49..ae33373 100644 --- a/drivers/media/video/bt856.c +++ b/drivers/media/video/bt856.c @@ -30,6 +30,7 @@ #include #include +#include #include #include #include diff --git a/drivers/media/video/bt866.c b/drivers/media/video/bt866.c index af7e3a5..62ac422 100644 --- a/drivers/media/video/bt866.c +++ b/drivers/media/video/bt866.c @@ -30,6 +30,7 @@ #include #include +#include #include #include #include diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index cb46e8f..f4860f0 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/video/bt8xx/bttv-gpio.c b/drivers/media/video/bt8xx/bttv-gpio.c index 74c325e..fd604d3 100644 --- a/drivers/media/video/bt8xx/bttv-gpio.c +++ b/drivers/media/video/bt8xx/bttv-gpio.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include "bttvp.h" diff --git a/drivers/media/video/bt8xx/bttv-input.c b/drivers/media/video/bt8xx/bttv-input.c index b320dbd..aa153a9 100644 --- a/drivers/media/video/bt8xx/bttv-input.c +++ b/drivers/media/video/bt8xx/bttv-input.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "bttv.h" #include "bttvp.h" diff --git a/drivers/media/video/bt8xx/bttv-risc.c b/drivers/media/video/bt8xx/bttv-risc.c index d16af28..c24b1c1 100644 --- a/drivers/media/video/bt8xx/bttv-risc.c +++ b/drivers/media/video/bt8xx/bttv-risc.c @@ -26,6 +26,7 @@ #include #include +#include #include #include #include diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index cbbf7e8..be35e69 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/video/cpia_pp.c b/drivers/media/video/cpia_pp.c index c431df8..f5604c1 100644 --- a/drivers/media/video/cpia_pp.c +++ b/drivers/media/video/cpia_pp.c @@ -35,6 +35,7 @@ #include #include #include +#include #include diff --git a/drivers/media/video/cs5345.c b/drivers/media/video/cs5345.c index 57dc170..8362db5 100644 --- a/drivers/media/video/cs5345.c +++ b/drivers/media/video/cs5345.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/video/cs53l32a.c b/drivers/media/video/cs53l32a.c index 80bca8d..3cc135a 100644 --- a/drivers/media/video/cs53l32a.c +++ b/drivers/media/video/cs53l32a.c @@ -22,6 +22,7 @@ #include #include +#include #include #include #include diff --git a/drivers/media/video/cx18/cx18-alsa-main.c b/drivers/media/video/cx18/cx18-alsa-main.c index eb41d7e..b5d7cbf 100644 --- a/drivers/media/video/cx18/cx18-alsa-main.c +++ b/drivers/media/video/cx18/cx18-alsa-main.c @@ -23,6 +23,7 @@ */ #include +#include #include #include #include diff --git a/drivers/media/video/cx18/cx18-controls.c b/drivers/media/video/cx18/cx18-controls.c index 93f0dae..7fa5892 100644 --- a/drivers/media/video/cx18/cx18-controls.c +++ b/drivers/media/video/cx18/cx18-controls.c @@ -21,6 +21,7 @@ * 02111-1307 USA */ #include +#include #include "cx18-driver.h" #include "cx18-cards.h" diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h index 23ad6d5..b9728e8 100644 --- a/drivers/media/video/cx18/cx18-driver.h +++ b/drivers/media/video/cx18/cx18-driver.h @@ -42,6 +42,7 @@ #include #include #include +#include #include #include diff --git a/drivers/media/video/cx231xx/cx231xx-cards.c b/drivers/media/video/cx231xx/cx231xx-cards.c index a549082..6bdc0ef 100644 --- a/drivers/media/video/cx231xx/cx231xx-cards.c +++ b/drivers/media/video/cx231xx/cx231xx-cards.c @@ -22,6 +22,7 @@ #include #include +#include #include #include #include diff --git a/drivers/media/video/cx231xx/cx231xx-core.c b/drivers/media/video/cx231xx/cx231xx-core.c index 4a60dfb..b24eee1 100644 --- a/drivers/media/video/cx231xx/cx231xx-core.c +++ b/drivers/media/video/cx231xx/cx231xx-core.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/video/cx231xx/cx231xx-dvb.c b/drivers/media/video/cx231xx/cx231xx-dvb.c index 64e025e..4ea3776 100644 --- a/drivers/media/video/cx231xx/cx231xx-dvb.c +++ b/drivers/media/video/cx231xx/cx231xx-dvb.c @@ -20,6 +20,7 @@ */ #include +#include #include #include "cx231xx.h" diff --git a/drivers/media/video/cx231xx/cx231xx-input.c b/drivers/media/video/cx231xx/cx231xx-input.c index c5771db..b473cd8 100644 --- a/drivers/media/video/cx231xx/cx231xx-input.c +++ b/drivers/media/video/cx231xx/cx231xx-input.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "cx231xx.h" diff --git a/drivers/media/video/cx231xx/cx231xx-vbi.c b/drivers/media/video/cx231xx/cx231xx-vbi.c index e97b802..689c5e2 100644 --- a/drivers/media/video/cx231xx/cx231xx-vbi.c +++ b/drivers/media/video/cx231xx/cx231xx-vbi.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include diff --git a/drivers/media/video/cx231xx/cx231xx-video.c b/drivers/media/video/cx231xx/cx231xx-video.c index d4f546f..16a73ea 100644 --- a/drivers/media/video/cx231xx/cx231xx-video.c +++ b/drivers/media/video/cx231xx/cx231xx-video.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c index 2ab97ad..a8ddc22 100644 --- a/drivers/media/video/cx23885/cx23885-417.c +++ b/drivers/media/video/cx23885/cx23885-417.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/video/cx23885/cx23885-input.c b/drivers/media/video/cx23885/cx23885-input.c index 9c6620f..8e9d990 100644 --- a/drivers/media/video/cx23885/cx23885-input.c +++ b/drivers/media/video/cx23885/cx23885-input.c @@ -36,6 +36,7 @@ */ #include +#include #include #include diff --git a/drivers/media/video/cx23885/cx23885-vbi.c b/drivers/media/video/cx23885/cx23885-vbi.c index 5b297f0..708a8c7 100644 --- a/drivers/media/video/cx23885/cx23885-vbi.c +++ b/drivers/media/video/cx23885/cx23885-vbi.c @@ -23,7 +23,6 @@ #include #include #include -#include #include "cx23885.h" diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h index 0e3a98d..8d6a55e 100644 --- a/drivers/media/video/cx23885/cx23885.h +++ b/drivers/media/video/cx23885/cx23885.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/drivers/media/video/cx23885/cx23888-ir.c b/drivers/media/video/cx23885/cx23888-ir.c index 2bf57a4..ad728d7 100644 --- a/drivers/media/video/cx23885/cx23888-ir.c +++ b/drivers/media/video/cx23885/cx23888-ir.c @@ -22,6 +22,7 @@ */ #include +#include #include #include diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c index 64b350d..33082c9 100644 --- a/drivers/media/video/cx88/cx88-alsa.c +++ b/drivers/media/video/cx88/cx88-alsa.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index 6fe30e6..e46e1ce 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c index eaf0ee7d..2918a6e 100644 --- a/drivers/media/video/cx88/cx88-cards.c +++ b/drivers/media/video/cx88/cx88-cards.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "cx88.h" #include "tea5767.h" diff --git a/drivers/media/video/cx88/cx88-dsp.c b/drivers/media/video/cx88/cx88-dsp.c index 3e5eaf3..a94e00a 100644 --- a/drivers/media/video/cx88/cx88-dsp.c +++ b/drivers/media/video/cx88/cx88-dsp.c @@ -19,6 +19,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include #include #include #include diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c index de180d4..6b6abf0 100644 --- a/drivers/media/video/cx88/cx88-input.c +++ b/drivers/media/video/cx88/cx88-input.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include "cx88.h" diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c index 338af77..6aba7af 100644 --- a/drivers/media/video/cx88/cx88-mpeg.c +++ b/drivers/media/video/cx88/cx88-mpeg.c @@ -23,6 +23,7 @@ */ #include +#include #include #include #include diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c index e8316cf..2396315 100644 --- a/drivers/media/video/cx88/cx88-tvaudio.c +++ b/drivers/media/video/cx88/cx88-tvaudio.c @@ -39,7 +39,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/media/video/cx88/cx88-vbi.c b/drivers/media/video/cx88/cx88-vbi.c index 0943060..d9445b0 100644 --- a/drivers/media/video/cx88/cx88-vbi.c +++ b/drivers/media/video/cx88/cx88-vbi.c @@ -3,7 +3,6 @@ #include #include #include -#include #include "cx88.h" diff --git a/drivers/media/video/cx88/cx88-vp3054-i2c.c b/drivers/media/video/cx88/cx88-vp3054-i2c.c index 2080042..794f293 100644 --- a/drivers/media/video/cx88/cx88-vp3054-i2c.c +++ b/drivers/media/video/cx88/cx88-vp3054-i2c.c @@ -23,6 +23,7 @@ */ #include +#include #include #include diff --git a/drivers/media/video/davinci/dm644x_ccdc.c b/drivers/media/video/davinci/dm644x_ccdc.c index 0c394ca..b4cc96d 100644 --- a/drivers/media/video/davinci/dm644x_ccdc.c +++ b/drivers/media/video/davinci/dm644x_ccdc.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include diff --git a/drivers/media/video/davinci/vpfe_capture.c b/drivers/media/video/davinci/vpfe_capture.c index 885cd54..7cf042f 100644 --- a/drivers/media/video/davinci/vpfe_capture.c +++ b/drivers/media/video/davinci/vpfe_capture.c @@ -67,6 +67,7 @@ * - Support for control ioctls */ #include +#include #include #include #include diff --git a/drivers/media/video/davinci/vpif_capture.c b/drivers/media/video/davinci/vpif_capture.c index 7813072..2e5a7fb 100644 --- a/drivers/media/video/davinci/vpif_capture.c +++ b/drivers/media/video/davinci/vpif_capture.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include diff --git a/drivers/media/video/davinci/vpif_display.c b/drivers/media/video/davinci/vpif_display.c index dfddef7..13c3a1b 100644 --- a/drivers/media/video/davinci/vpif_display.c +++ b/drivers/media/video/davinci/vpif_display.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index ecbcefb..b0fb083 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -24,6 +24,7 @@ #include #include +#include #include #include #include diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index 5a37ecc..a41cc55 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c index 1b96356..bcd3c37 100644 --- a/drivers/media/video/em28xx/em28xx-dvb.c +++ b/drivers/media/video/em28xx/em28xx-dvb.c @@ -20,6 +20,7 @@ */ #include +#include #include #include "em28xx.h" diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c index 1fb754e..20a0001 100644 --- a/drivers/media/video/em28xx/em28xx-input.c +++ b/drivers/media/video/em28xx/em28xx-input.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "em28xx.h" diff --git a/drivers/media/video/em28xx/em28xx-vbi.c b/drivers/media/video/em28xx/em28xx-vbi.c index c7dce39..7f1c4a2 100644 --- a/drivers/media/video/em28xx/em28xx-vbi.c +++ b/drivers/media/video/em28xx/em28xx-vbi.c @@ -24,7 +24,6 @@ #include #include #include -#include #include "em28xx.h" diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index ac2bd93..0fe2011 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c @@ -35,6 +35,7 @@ #include #include #include +#include #include "em28xx.h" #include diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h index 02c696a..8bb242f 100644 --- a/drivers/media/video/gspca/gspca.h +++ b/drivers/media/video/gspca/gspca.h @@ -7,6 +7,7 @@ #include #include #include +#include /* compilation option */ #define GSPCA_DEBUG 1 diff --git a/drivers/media/video/gspca/jeilinj.c b/drivers/media/video/gspca/jeilinj.c index 2019b04..84ecd56 100644 --- a/drivers/media/video/gspca/jeilinj.c +++ b/drivers/media/video/gspca/jeilinj.c @@ -24,6 +24,7 @@ #define MODULE_NAME "jeilinj" #include +#include #include "gspca.h" #include "jpeg.h" diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.c b/drivers/media/video/gspca/m5602/m5602_s5k83a.c index fbd9154..6b3be4f 100644 --- a/drivers/media/video/gspca/m5602/m5602_s5k83a.c +++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.c @@ -17,6 +17,7 @@ */ #include +#include #include "m5602_s5k83a.h" static int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val); diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c index 4a1bc08..38a6e15 100644 --- a/drivers/media/video/gspca/sn9c20x.c +++ b/drivers/media/video/gspca/sn9c20x.c @@ -23,6 +23,7 @@ #include #include #include +#include #endif #include "gspca.h" diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 83d5773..1d61b92 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -22,6 +22,7 @@ #define MODULE_NAME "sonixj" #include +#include #include "gspca.h" #include "jpeg.h" diff --git a/drivers/media/video/gspca/sq905.c b/drivers/media/video/gspca/sq905.c index 1fcaca6..09b3f93f 100644 --- a/drivers/media/video/gspca/sq905.c +++ b/drivers/media/video/gspca/sq905.c @@ -36,6 +36,7 @@ #define MODULE_NAME "sq905" #include +#include #include "gspca.h" MODULE_AUTHOR("Adam Baker , " diff --git a/drivers/media/video/gspca/sq905c.c b/drivers/media/video/gspca/sq905c.c index e646620..4c70628 100644 --- a/drivers/media/video/gspca/sq905c.c +++ b/drivers/media/video/gspca/sq905c.c @@ -30,6 +30,7 @@ #define MODULE_NAME "sq905c" #include +#include #include "gspca.h" MODULE_AUTHOR("Theodore Kilgore "); diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index 50986da..7d7814c 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c @@ -22,6 +22,7 @@ #define MODULE_NAME "zc3xx" #include +#include #include "gspca.h" #include "jpeg.h" diff --git a/drivers/media/video/hdpvr/hdpvr-i2c.c b/drivers/media/video/hdpvr/hdpvr-i2c.c index 296330a0..463b81b 100644 --- a/drivers/media/video/hdpvr/hdpvr-i2c.c +++ b/drivers/media/video/hdpvr/hdpvr-i2c.c @@ -11,6 +11,7 @@ */ #include +#include #include "hdpvr.h" diff --git a/drivers/media/video/ivtv/ivtv-controls.c b/drivers/media/video/ivtv/ivtv-controls.c index 4a9c8ce..b59475bf 100644 --- a/drivers/media/video/ivtv/ivtv-controls.c +++ b/drivers/media/video/ivtv/ivtv-controls.c @@ -18,6 +18,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include +#include #include "ivtv-driver.h" #include "ivtv-cards.h" diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h index e4816da..5028e31 100644 --- a/drivers/media/video/ivtv/ivtv-driver.h +++ b/drivers/media/video/ivtv/ivtv-driver.h @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c index fa6bb85..de2ff1c 100644 --- a/drivers/media/video/ivtv/ivtvfb.c +++ b/drivers/media/video/ivtv/ivtvfb.c @@ -42,6 +42,7 @@ #include #include #include +#include #ifdef CONFIG_MTRR #include diff --git a/drivers/media/video/ks0127.c b/drivers/media/video/ks0127.c index fab8e02..9473482 100644 --- a/drivers/media/video/ks0127.c +++ b/drivers/media/video/ks0127.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/video/m52790.c b/drivers/media/video/m52790.c index d7317e7..4491d01 100644 --- a/drivers/media/video/m52790.c +++ b/drivers/media/video/m52790.c @@ -22,6 +22,7 @@ #include #include +#include #include #include #include diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c index b421858..4404e5e 100644 --- a/drivers/media/video/meye.c +++ b/drivers/media/video/meye.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/video/msp3400-kthreads.c b/drivers/media/video/msp3400-kthreads.c index 168bca7..d5a69c5 100644 --- a/drivers/media/video/msp3400-kthreads.c +++ b/drivers/media/video/msp3400-kthreads.c @@ -22,7 +22,6 @@ #include #include -#include #include #include #include diff --git a/drivers/media/video/mt9v011.c b/drivers/media/video/mt9v011.c index cc85f77..72e55be 100644 --- a/drivers/media/video/mt9v011.c +++ b/drivers/media/video/mt9v011.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/video/mx1_camera.c index c167cc3..3c8ebfc 100644 --- a/drivers/media/video/mx1_camera.c +++ b/drivers/media/video/mx1_camera.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/video/omap24xxcam.c b/drivers/media/video/omap24xxcam.c index 142c327..b189fe6 100644 --- a/drivers/media/video/omap24xxcam.c +++ b/drivers/media/video/omap24xxcam.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c index 0e2184e..aaa50f9 100644 --- a/drivers/media/video/ov7670.c +++ b/drivers/media/video/ov7670.c @@ -12,6 +12,7 @@ */ #include #include +#include #include #include #include diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c index 11a2c26..0598bbd 100644 --- a/drivers/media/video/pms.c +++ b/drivers/media/video/pms.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c b/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c index 68980e1..8832090 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c +++ b/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c @@ -34,7 +34,6 @@ #include #include #include -#include struct routing_scheme { const int *def; diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c index 82c1358..2222da8 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c +++ b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c @@ -36,7 +36,6 @@ #include #include #include -#include struct routing_scheme_item { diff --git a/drivers/media/video/pvrusb2/pvrusb2-debugifc.c b/drivers/media/video/pvrusb2/pvrusb2-debugifc.c index ae97766..e9b11e1 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-debugifc.c +++ b/drivers/media/video/pvrusb2/pvrusb2-debugifc.c @@ -19,7 +19,6 @@ */ #include -#include #include "pvrusb2-debugifc.h" #include "pvrusb2-hdw.h" #include "pvrusb2-debug.h" diff --git a/drivers/media/video/pvrusb2/pvrusb2-dvb.c b/drivers/media/video/pvrusb2/pvrusb2-dvb.c index b7f5c49..8c95793 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-dvb.c +++ b/drivers/media/video/pvrusb2/pvrusb2-dvb.c @@ -20,6 +20,7 @@ #include #include +#include #include #include "dvbdev.h" #include "pvrusb2-debug.h" diff --git a/drivers/media/video/pvrusb2/pvrusb2-eeprom.c b/drivers/media/video/pvrusb2/pvrusb2-eeprom.c index 299afa4..aeed1c2 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-eeprom.c +++ b/drivers/media/video/pvrusb2/pvrusb2-eeprom.c @@ -19,6 +19,7 @@ * */ +#include #include "pvrusb2-eeprom.h" #include "pvrusb2-hdw-internal.h" #include "pvrusb2-debug.h" diff --git a/drivers/media/video/pvrusb2/pvrusb2-main.c b/drivers/media/video/pvrusb2/pvrusb2-main.c index 8689ddb..eeacd0f 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-main.c +++ b/drivers/media/video/pvrusb2/pvrusb2-main.c @@ -21,7 +21,6 @@ #include #include -#include #include #include #include diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c index cc8ddb2..bf1e0fe 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c @@ -20,6 +20,7 @@ */ #include +#include #include #include "pvrusb2-context.h" #include "pvrusb2-hdw.h" diff --git a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c index 4c96cf4..2e205c9 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c +++ b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c @@ -37,7 +37,6 @@ #include #include #include -#include struct routing_scheme { const int *def; diff --git a/drivers/media/video/pvrusb2/pvrusb2-wm8775.c b/drivers/media/video/pvrusb2/pvrusb2-wm8775.c index 8c1eae0..3ac8d75 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-wm8775.c +++ b/drivers/media/video/pvrusb2/pvrusb2-wm8775.c @@ -34,7 +34,6 @@ #include #include #include -#include void pvr2_wm8775_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd) { diff --git a/drivers/media/video/pwc/pwc-dec23.c b/drivers/media/video/pwc/pwc-dec23.c index 9e2d91f..0c801b8 100644 --- a/drivers/media/video/pwc/pwc-dec23.c +++ b/drivers/media/video/pwc/pwc-dec23.c @@ -30,6 +30,7 @@ #include #include +#include /* * USE_LOOKUP_TABLE_TO_CLAMP diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c index bdb4ced..62d89b3 100644 --- a/drivers/media/video/pwc/pwc-v4l.c +++ b/drivers/media/video/pwc/pwc-v4l.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h index 0902355..f1b2066 100644 --- a/drivers/media/video/pwc/pwc.h +++ b/drivers/media/video/pwc/pwc.h @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c index 322ac4e..5ecc30d 100644 --- a/drivers/media/video/pxa_camera.c +++ b/drivers/media/video/pxa_camera.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c index fb742f1..3de914d 100644 --- a/drivers/media/video/s2255drv.c +++ b/drivers/media/video/s2255drv.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c index 5ab6a0f..6b3b09e 100644 --- a/drivers/media/video/saa5246a.c +++ b/drivers/media/video/saa5246a.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c index 12835fb..31ff27df 100644 --- a/drivers/media/video/saa5249.c +++ b/drivers/media/video/saa5249.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index 73739d2..4ab4a98 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index ee5bff0..ea877a5 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c index 8096dac..da41b6b 100644 --- a/drivers/media/video/saa7134/saa7134-i2c.c +++ b/drivers/media/video/saa7134/saa7134-i2c.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include "saa7134-reg.h" diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index 9499000..58a0cdc 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "saa7134-reg.h" #include "saa7134.h" diff --git a/drivers/media/video/saa7134/saa7134-ts.c b/drivers/media/video/saa7134/saa7134-ts.c index b9817d7..2e3f4b4 100644 --- a/drivers/media/video/saa7134/saa7134-ts.c +++ b/drivers/media/video/saa7134/saa7134-ts.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include "saa7134-reg.h" diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c index 76b1640..3e7d2fd 100644 --- a/drivers/media/video/saa7134/saa7134-tvaudio.c +++ b/drivers/media/video/saa7134/saa7134-tvaudio.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/media/video/saa7134/saa7134-vbi.c b/drivers/media/video/saa7134/saa7134-vbi.c index cb03042..e9aa94b 100644 --- a/drivers/media/video/saa7134/saa7134-vbi.c +++ b/drivers/media/video/saa7134/saa7134-vbi.c @@ -24,7 +24,6 @@ #include #include #include -#include #include "saa7134-reg.h" #include "saa7134.h" diff --git a/drivers/media/video/saa7164/saa7164-api.c b/drivers/media/video/saa7164/saa7164-api.c index 1d487c1..3f1262b 100644 --- a/drivers/media/video/saa7164/saa7164-api.c +++ b/drivers/media/video/saa7164/saa7164-api.c @@ -20,6 +20,7 @@ */ #include +#include #include "saa7164.h" diff --git a/drivers/media/video/saa7164/saa7164-buffer.c b/drivers/media/video/saa7164/saa7164-buffer.c index 9ca5c83..5713f3a 100644 --- a/drivers/media/video/saa7164/saa7164-buffer.c +++ b/drivers/media/video/saa7164/saa7164-buffer.c @@ -19,6 +19,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include + #include "saa7164.h" /* The PCI address space for buffer handling looks like this: diff --git a/drivers/media/video/saa7164/saa7164-fw.c b/drivers/media/video/saa7164/saa7164-fw.c index ee0af35..270245d 100644 --- a/drivers/media/video/saa7164/saa7164-fw.c +++ b/drivers/media/video/saa7164/saa7164-fw.c @@ -20,6 +20,7 @@ */ #include +#include #include "saa7164.h" diff --git a/drivers/media/video/saa717x.c b/drivers/media/video/saa717x.c index 6818df5..d521c64 100644 --- a/drivers/media/video/saa717x.c +++ b/drivers/media/video/saa717x.c @@ -32,6 +32,7 @@ #include #include +#include #include #include diff --git a/drivers/media/video/saa7185.c b/drivers/media/video/saa7185.c index 212baa1..77db203 100644 --- a/drivers/media/video/saa7185.c +++ b/drivers/media/video/saa7185.c @@ -26,6 +26,7 @@ #include #include +#include #include #include #include diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c index fb88c63..6e16b39 100644 --- a/drivers/media/video/sh_mobile_ceu_camera.c +++ b/drivers/media/video/sh_mobile_ceu_camera.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index 80f6bfa..a24174d 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include diff --git a/drivers/media/video/tda9840.c b/drivers/media/video/tda9840.c index d381fce..92d22d8 100644 --- a/drivers/media/video/tda9840.c +++ b/drivers/media/video/tda9840.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include diff --git a/drivers/media/video/tea6415c.c b/drivers/media/video/tea6415c.c index 1585839..3021a1e 100644 --- a/drivers/media/video/tea6415c.c +++ b/drivers/media/video/tea6415c.c @@ -30,6 +30,7 @@ #include #include +#include #include #include #include diff --git a/drivers/media/video/tea6420.c b/drivers/media/video/tea6420.c index 6bf6bc7..49dafc5 100644 --- a/drivers/media/video/tea6420.c +++ b/drivers/media/video/tea6420.c @@ -30,6 +30,7 @@ #include #include +#include #include #include #include diff --git a/drivers/media/video/ths7303.c b/drivers/media/video/ths7303.c index 21781f8..61b1dd1 100644 --- a/drivers/media/video/ths7303.c +++ b/drivers/media/video/ths7303.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/video/tlg2300/pd-alsa.c b/drivers/media/video/tlg2300/pd-alsa.c index 6f42621..9f8b7da 100644 --- a/drivers/media/video/tlg2300/pd-alsa.c +++ b/drivers/media/video/tlg2300/pd-alsa.c @@ -4,10 +4,10 @@ #include #include #include -#include #include #include #include +#include #include #include #include diff --git a/drivers/media/video/tlg2300/pd-dvb.c b/drivers/media/video/tlg2300/pd-dvb.c index 4133aee..ebd9cb5 100644 --- a/drivers/media/video/tlg2300/pd-dvb.c +++ b/drivers/media/video/tlg2300/pd-dvb.c @@ -3,6 +3,7 @@ #include #include #include +#include #include "vendorcmds.h" #include diff --git a/drivers/media/video/tlg2300/pd-video.c b/drivers/media/video/tlg2300/pd-video.c index becfba6..cf8f18c 100644 --- a/drivers/media/video/tlg2300/pd-video.c +++ b/drivers/media/video/tlg2300/pd-video.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include diff --git a/drivers/media/video/tlv320aic23b.c b/drivers/media/video/tlv320aic23b.c index 07789c6..9ddb32b 100644 --- a/drivers/media/video/tlv320aic23b.c +++ b/drivers/media/video/tlv320aic23b.c @@ -25,6 +25,7 @@ #include #include +#include #include #include #include diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c index 26b4e71..e4815a1 100644 --- a/drivers/media/video/tvp514x.c +++ b/drivers/media/video/tvp514x.c @@ -29,6 +29,7 @@ */ #include +#include #include #include diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c index 2d38e25..908ffb6 100644 --- a/drivers/media/video/tvp5150.c +++ b/drivers/media/video/tvp5150.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include diff --git a/drivers/media/video/tvp7002.c b/drivers/media/video/tvp7002.c index 5a878bc..4a69bcc 100644 --- a/drivers/media/video/tvp7002.c +++ b/drivers/media/video/tvp7002.c @@ -26,6 +26,7 @@ */ #include #include +#include #include #include #include diff --git a/drivers/media/video/upd64031a.c b/drivers/media/video/upd64031a.c index a07a3fb..36c0c46 100644 --- a/drivers/media/video/upd64031a.c +++ b/drivers/media/video/upd64031a.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/video/upd64083.c b/drivers/media/video/upd64083.c index 6eb0e5b..c5af93b 100644 --- a/drivers/media/video/upd64083.c +++ b/drivers/media/video/upd64083.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/video/usbvideo/konicawc.c b/drivers/media/video/usbvideo/konicawc.c index a0addcb..562e1d1 100644 --- a/drivers/media/video/usbvideo/konicawc.c +++ b/drivers/media/video/usbvideo/konicawc.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "usbvideo.h" diff --git a/drivers/media/video/usbvideo/quickcam_messenger.c b/drivers/media/video/usbvideo/quickcam_messenger.c index c4d1b96..fab48ec 100644 --- a/drivers/media/video/usbvideo/quickcam_messenger.c +++ b/drivers/media/video/usbvideo/quickcam_messenger.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "usbvideo.h" #include "quickcam_messenger.h" diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c index e0f91e4..f7aae22 100644 --- a/drivers/media/video/usbvision/usbvision-core.c +++ b/drivers/media/video/usbvision/usbvision-core.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/media/video/usbvision/usbvision-i2c.c b/drivers/media/video/usbvision/usbvision-i2c.c index 0613922..0837652 100644 --- a/drivers/media/video/usbvision/usbvision-i2c.c +++ b/drivers/media/video/usbvision/usbvision-i2c.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c index 3b2e780..6d3850b 100644 --- a/drivers/media/video/uvc/uvc_ctrl.c +++ b/drivers/media/video/uvc/uvc_ctrl.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c index a814820..86ff8c1 100644 --- a/drivers/media/video/uvc/uvc_driver.c +++ b/drivers/media/video/uvc/uvc_driver.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/video/uvc/uvc_status.c b/drivers/media/video/uvc/uvc_status.c index 1ca6dff..85019bd 100644 --- a/drivers/media/video/uvc/uvc_status.c +++ b/drivers/media/video/uvc/uvc_status.c @@ -13,6 +13,7 @@ #include #include +#include #include #include diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c index 43152aa..7c9ab29 100644 --- a/drivers/media/video/uvc/uvc_v4l2.c +++ b/drivers/media/video/uvc/uvc_v4l2.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index 6b0666b..821a996 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c index 4b11257..7d59c10 100644 --- a/drivers/media/video/v4l2-ioctl.c +++ b/drivers/media/video/v4l2-ioctl.c @@ -13,6 +13,7 @@ */ #include +#include #include #include diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c index 22c0109..dce4f3a 100644 --- a/drivers/media/video/videobuf-dma-contig.c +++ b/drivers/media/video/videobuf-dma-contig.c @@ -20,6 +20,7 @@ #include #include #include +#include #include struct videobuf_dma_contig_memory { diff --git a/drivers/media/video/videobuf-dvb.c b/drivers/media/video/videobuf-dvb.c index a56cf0d..0afb62e 100644 --- a/drivers/media/video/videobuf-dvb.c +++ b/drivers/media/video/videobuf-dvb.c @@ -19,6 +19,7 @@ #include #include #include +#include #include diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c index a15d1e7..3eb15f7 100644 --- a/drivers/media/video/vino.c +++ b/drivers/media/video/vino.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/video/vp27smpx.c b/drivers/media/video/vp27smpx.c index 38e53b3..ca8303b 100644 --- a/drivers/media/video/vp27smpx.c +++ b/drivers/media/video/vp27smpx.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include diff --git a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c index 33205d7..77ebcea 100644 --- a/drivers/media/video/vpx3220.c +++ b/drivers/media/video/vpx3220.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c index dcade61..bf9bf65 100644 --- a/drivers/media/video/w9966.c +++ b/drivers/media/video/w9966.c @@ -58,6 +58,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/video/wm8739.c b/drivers/media/video/wm8739.c index b572ce2..a11b99b 100644 --- a/drivers/media/video/wm8739.c +++ b/drivers/media/video/wm8739.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c index f1f261a..5c2ba59 100644 --- a/drivers/media/video/wm8775.c +++ b/drivers/media/video/wm8775.c @@ -27,6 +27,7 @@ #include #include +#include #include #include #include diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c index be70574..bfcd3ae 100644 --- a/drivers/media/video/zoran/zoran_card.c +++ b/drivers/media/video/zoran/zoran_card.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include diff --git a/drivers/memstick/core/memstick.c b/drivers/memstick/core/memstick.c index b3bf1c4..c00fe82 100644 --- a/drivers/memstick/core/memstick.c +++ b/drivers/memstick/core/memstick.c @@ -16,6 +16,7 @@ #include #include #include +#include #define DRIVER_NAME "memstick" diff --git a/drivers/memstick/core/mspro_block.c b/drivers/memstick/core/mspro_block.c index 972b870..8327e24 100644 --- a/drivers/memstick/core/mspro_block.c +++ b/drivers/memstick/core/mspro_block.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #define DRIVER_NAME "mspro_block" diff --git a/drivers/memstick/host/jmb38x_ms.c b/drivers/memstick/host/jmb38x_ms.c index f4a162a..f2b894c 100644 --- a/drivers/memstick/host/jmb38x_ms.c +++ b/drivers/memstick/host/jmb38x_ms.c @@ -16,6 +16,7 @@ #include #include #include +#include #define DRIVER_NAME "jmb38x_ms" diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index 612ab3c..33f7256 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c @@ -54,6 +54,7 @@ #include /* notifier code */ #include #include +#include #include #include diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c index 34f3f36..4fa9665 100644 --- a/drivers/message/fusion/mptlan.c +++ b/drivers/message/fusion/mptlan.c @@ -57,6 +57,7 @@ #include #include #include +#include #define my_VERSION MPT_LINUX_VERSION_COMMON #define MYNAM "mptlan" diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index c20bbe4..7668712 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -45,6 +45,7 @@ #include #include +#include #include #include #include diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index 4a7d1af..6796597 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -46,6 +46,7 @@ #include #include +#include #include #include #include diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index 69f4257..e443651 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c @@ -46,6 +46,7 @@ #include #include +#include #include #include #include diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c index 2658b14..fc593fb 100644 --- a/drivers/message/i2o/i2o_block.c +++ b/drivers/message/i2o/i2o_block.c @@ -51,6 +51,7 @@ */ #include +#include #include #include diff --git a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c index 3d5f40c..11073fa 100644 --- a/drivers/message/i2o/i2o_config.c +++ b/drivers/message/i2o/i2o_config.c @@ -33,6 +33,7 @@ #include #include #include +#include #include diff --git a/drivers/message/i2o/i2o_proc.c b/drivers/message/i2o/i2o_proc.c index 949a648..07dbeaf 100644 --- a/drivers/message/i2o/i2o_proc.c +++ b/drivers/message/i2o/i2o_proc.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/message/i2o/iop.c b/drivers/message/i2o/iop.c index ef5ce26..090d2a3 100644 --- a/drivers/message/i2o/iop.c +++ b/drivers/message/i2o/iop.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "core.h" #define OSM_NAME "i2o" diff --git a/drivers/message/i2o/pci.c b/drivers/message/i2o/pci.c index 35ba2ae..73e4658 100644 --- a/drivers/message/i2o/pci.c +++ b/drivers/message/i2o/pci.c @@ -29,6 +29,7 @@ #include #include +#include #include #include "core.h" diff --git a/drivers/mfd/88pm860x-i2c.c b/drivers/mfd/88pm860x-i2c.c index c37e12b..4a6e718 100644 --- a/drivers/mfd/88pm860x-i2c.c +++ b/drivers/mfd/88pm860x-i2c.c @@ -13,6 +13,7 @@ #include #include #include +#include static inline int pm860x_read_device(struct i2c_client *i2c, int reg, int bytes, void *dest) diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c index a2ce3b6..e4ca590 100644 --- a/drivers/mfd/ab3100-core.c +++ b/drivers/mfd/ab3100-core.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/mfd/ab3100-otp.c b/drivers/mfd/ab3100-otp.c index b603469..2d14655 100644 --- a/drivers/mfd/ab3100-otp.c +++ b/drivers/mfd/ab3100-otp.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include diff --git a/drivers/mfd/ab4500-core.c b/drivers/mfd/ab4500-core.c index 1c44c19..c275daa 100644 --- a/drivers/mfd/ab4500-core.c +++ b/drivers/mfd/ab4500-core.c @@ -15,6 +15,7 @@ * Interrupt management to be added - TODO. */ #include +#include #include #include #include diff --git a/drivers/mfd/adp5520.c b/drivers/mfd/adp5520.c index b266447..0055328 100644 --- a/drivers/mfd/adp5520.c +++ b/drivers/mfd/adp5520.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c index 95c1e6b..7de708d 100644 --- a/drivers/mfd/asic3.c +++ b/drivers/mfd/asic3.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include diff --git a/drivers/mfd/da903x.c b/drivers/mfd/da903x.c index e5ffe56..67181b1 100644 --- a/drivers/mfd/da903x.c +++ b/drivers/mfd/da903x.c @@ -18,6 +18,7 @@ #include #include #include +#include #define DA9030_CHIP_ID 0x00 #define DA9030_EVENT_A 0x01 diff --git a/drivers/mfd/ezx-pcap.c b/drivers/mfd/ezx-pcap.c index df405af..134c69a 100644 --- a/drivers/mfd/ezx-pcap.c +++ b/drivers/mfd/ezx-pcap.c @@ -18,6 +18,7 @@ #include #include #include +#include #define PCAP_ADC_MAXQ 8 struct pcap_adc_request { diff --git a/drivers/mfd/htc-egpio.c b/drivers/mfd/htc-egpio.c index addb846..d3e74f8 100644 --- a/drivers/mfd/htc-egpio.c +++ b/drivers/mfd/htc-egpio.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff --git a/drivers/mfd/htc-i2cpld.c b/drivers/mfd/htc-i2cpld.c index 37b9fda..594c9a8 100644 --- a/drivers/mfd/htc-i2cpld.c +++ b/drivers/mfd/htc-i2cpld.c @@ -35,6 +35,7 @@ #include #include #include +#include struct htcpld_chip { spinlock_t lock; diff --git a/drivers/mfd/htc-pasic3.c b/drivers/mfd/htc-pasic3.c index cb73051..f04300e 100644 --- a/drivers/mfd/htc-pasic3.c +++ b/drivers/mfd/htc-pasic3.c @@ -19,6 +19,7 @@ #include #include #include +#include struct pasic3_data { void __iomem *mapping; diff --git a/drivers/mfd/max8925-i2c.c b/drivers/mfd/max8925-i2c.c index c0b883c..d9fd878 100644 --- a/drivers/mfd/max8925-i2c.c +++ b/drivers/mfd/max8925-i2c.c @@ -13,6 +13,7 @@ #include #include #include +#include #define RTC_I2C_ADDR 0x68 #define ADC_I2C_ADDR 0x47 diff --git a/drivers/mfd/mc13783-core.c b/drivers/mfd/mc13783-core.c index 62a847e..1f68eca 100644 --- a/drivers/mfd/mc13783-core.c +++ b/drivers/mfd/mc13783-core.c @@ -9,6 +9,7 @@ * the terms of the GNU General Public License version 2 as published by the * Free Software Foundation. */ +#include #include #include #include diff --git a/drivers/mfd/mcp-sa11x0.c b/drivers/mfd/mcp-sa11x0.c index 2584272..2dab02d 100644 --- a/drivers/mfd/mcp-sa11x0.c +++ b/drivers/mfd/mcp-sa11x0.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c index 970afa1..a94b131 100644 --- a/drivers/mfd/menelaus.c +++ b/drivers/mfd/menelaus.c @@ -40,6 +40,7 @@ #include #include #include +#include #include diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c index aa17f4b..8ffbb7a 100644 --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c @@ -15,6 +15,7 @@ #include #include #include +#include static int mfd_add_device(struct device *parent, int id, const struct mfd_cell *cell, diff --git a/drivers/mfd/pcf50633-adc.c b/drivers/mfd/pcf50633-adc.c index 6d2e846..fe8f922 100644 --- a/drivers/mfd/pcf50633-adc.c +++ b/drivers/mfd/pcf50633-adc.c @@ -17,6 +17,7 @@ */ #include +#include #include #include #include diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c index 03dcc92..63a614d 100644 --- a/drivers/mfd/pcf50633-core.c +++ b/drivers/mfd/pcf50633-core.c @@ -22,6 +22,7 @@ #include #include #include +#include #include diff --git a/drivers/mfd/sh_mobile_sdhi.c b/drivers/mfd/sh_mobile_sdhi.c index 468fd36..497f91b 100644 --- a/drivers/mfd/sh_mobile_sdhi.c +++ b/drivers/mfd/sh_mobile_sdhi.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c index 7b6652f..bc9275c 100644 --- a/drivers/mfd/sm501.c +++ b/drivers/mfd/sm501.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c index 26d9176..da6383a 100644 --- a/drivers/mfd/t7l66xb.c +++ b/drivers/mfd/t7l66xb.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/mfd/tc6387xb.c b/drivers/mfd/tc6387xb.c index 5c7f043..517f9bc 100644 --- a/drivers/mfd/tc6387xb.c +++ b/drivers/mfd/tc6387xb.c @@ -17,6 +17,7 @@ #include #include #include +#include enum { TC6387XB_CELL_MMC, diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c index c59e5c5..fcf9068 100644 --- a/drivers/mfd/tc6393xb.c +++ b/drivers/mfd/tc6393xb.c @@ -25,6 +25,7 @@ #include #include #include +#include #define SCR_REVID 0x08 /* b Revision ID */ #define SCR_ISR 0x50 /* b Interrupt Status */ diff --git a/drivers/mfd/timberdale.c b/drivers/mfd/timberdale.c index 1ed44d2..7f478ec 100644 --- a/drivers/mfd/timberdale.c +++ b/drivers/mfd/timberdale.c @@ -25,6 +25,7 @@ #include #include #include +#include #include diff --git a/drivers/mfd/twl4030-codec.c b/drivers/mfd/twl4030-codec.c index 700b149..add6f67 100644 --- a/drivers/mfd/twl4030-codec.c +++ b/drivers/mfd/twl4030-codec.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c index 9df9a5a..202bdd5 100644 --- a/drivers/mfd/twl4030-irq.c +++ b/drivers/mfd/twl4030-irq.c @@ -31,6 +31,7 @@ #include #include #include +#include #include diff --git a/drivers/mfd/ucb1400_core.c b/drivers/mfd/ucb1400_core.c index 85fd942..dbe2801 100644 --- a/drivers/mfd/ucb1400_core.c +++ b/drivers/mfd/ucb1400_core.c @@ -22,6 +22,7 @@ #include #include +#include #include unsigned int ucb1400_adc_read(struct snd_ac97 *ac97, u16 adc_channel, diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c index 07101e9..a3d5728 100644 --- a/drivers/mfd/wm831x-core.c +++ b/drivers/mfd/wm831x-core.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c index bd75807..e400a3b 100644 --- a/drivers/mfd/wm8350-core.c +++ b/drivers/mfd/wm8350-core.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/mfd/wm8350-i2c.c b/drivers/mfd/wm8350-i2c.c index 8d8c932..65830f5 100644 --- a/drivers/mfd/wm8350-i2c.c +++ b/drivers/mfd/wm8350-i2c.c @@ -19,6 +19,7 @@ #include #include #include +#include static int wm8350_i2c_read_device(struct wm8350 *wm8350, char reg, int bytes, void *dest) diff --git a/drivers/mfd/wm8400-core.c b/drivers/mfd/wm8400-core.c index ecfc8bb..865ce01 100644 --- a/drivers/mfd/wm8400-core.c +++ b/drivers/mfd/wm8400-core.c @@ -18,6 +18,7 @@ #include #include #include +#include static struct { u16 readable; /* Mask of readable bits */ diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c index 844e1c1..cc524df 100644 --- a/drivers/mfd/wm8994-core.c +++ b/drivers/mfd/wm8994-core.c @@ -14,6 +14,7 @@ #include #include +#include #include #include #include diff --git a/drivers/misc/atmel-ssc.c b/drivers/misc/atmel-ssc.c index 558bf3f..4afffe6 100644 --- a/drivers/misc/atmel-ssc.c +++ b/drivers/misc/atmel-ssc.c @@ -15,6 +15,7 @@ #include #include #include +#include /* Serialize access to ssc_list and user count */ static DEFINE_SPINLOCK(user_lock); diff --git a/drivers/misc/atmel_pwm.c b/drivers/misc/atmel_pwm.c index 6aa5294..0f3fb4f 100644 --- a/drivers/misc/atmel_pwm.c +++ b/drivers/misc/atmel_pwm.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/misc/atmel_tclib.c b/drivers/misc/atmel_tclib.c index 05dc8a3..3891124 100644 --- a/drivers/misc/atmel_tclib.c +++ b/drivers/misc/atmel_tclib.c @@ -6,6 +6,7 @@ #include #include #include +#include /* Number of bytes to reserve for the iomem resource */ #define ATMEL_TC_IOMEM_SIZE 256 diff --git a/drivers/misc/c2port/core.c b/drivers/misc/c2port/core.c index b7a85f4..ed090e7 100644 --- a/drivers/misc/c2port/core.c +++ b/drivers/misc/c2port/core.c @@ -20,6 +20,7 @@ #include #include #include +#include #include diff --git a/drivers/misc/cb710/core.c b/drivers/misc/cb710/core.c index b14eab0..efec413 100644 --- a/drivers/misc/cb710/core.c +++ b/drivers/misc/cb710/core.c @@ -9,11 +9,11 @@ */ #include #include -#include #include #include #include #include +#include static DEFINE_IDA(cb710_ida); static DEFINE_SPINLOCK(cb710_ida_lock); diff --git a/drivers/misc/cb710/debug.c b/drivers/misc/cb710/debug.c index 02358d0..fcb3b8e 100644 --- a/drivers/misc/cb710/debug.c +++ b/drivers/misc/cb710/debug.c @@ -10,7 +10,6 @@ #include #include #include -#include #define CB710_REG_COUNT 0x80 diff --git a/drivers/misc/cs5535-mfgpt.c b/drivers/misc/cs5535-mfgpt.c index 8110460..9bec24d 100644 --- a/drivers/misc/cs5535-mfgpt.c +++ b/drivers/misc/cs5535-mfgpt.c @@ -18,6 +18,7 @@ #include #include #include +#include #define DRV_NAME "cs5535-mfgpt" #define MFGPT_BAR 2 diff --git a/drivers/misc/ds1682.c b/drivers/misc/ds1682.c index f3ee4a1..9197cfc 100644 --- a/drivers/misc/ds1682.c +++ b/drivers/misc/ds1682.c @@ -33,7 +33,6 @@ #include #include -#include #include #include #include diff --git a/drivers/misc/enclosure.c b/drivers/misc/enclosure.c index 1eac626..48c84a5 100644 --- a/drivers/misc/enclosure.c +++ b/drivers/misc/enclosure.c @@ -27,6 +27,7 @@ #include #include #include +#include static LIST_HEAD(container_list); static DEFINE_MUTEX(container_list_lock); diff --git a/drivers/misc/ep93xx_pwm.c b/drivers/misc/ep93xx_pwm.c index ba46941..46b3439 100644 --- a/drivers/misc/ep93xx_pwm.c +++ b/drivers/misc/ep93xx_pwm.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include diff --git a/drivers/misc/hpilo.c b/drivers/misc/hpilo.c index a92a3a7..98ad012 100644 --- a/drivers/misc/hpilo.c +++ b/drivers/misc/hpilo.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "hpilo.h" static struct class *ilo_class; diff --git a/drivers/misc/ibmasm/command.c b/drivers/misc/ibmasm/command.c index e203173..5c766b4 100644 --- a/drivers/misc/ibmasm/command.c +++ b/drivers/misc/ibmasm/command.c @@ -23,6 +23,7 @@ */ #include +#include #include "ibmasm.h" #include "lowlevel.h" diff --git a/drivers/misc/ibmasm/event.c b/drivers/misc/ibmasm/event.c index 572d41f..76bfda1 100644 --- a/drivers/misc/ibmasm/event.c +++ b/drivers/misc/ibmasm/event.c @@ -23,6 +23,7 @@ */ #include +#include #include "ibmasm.h" #include "lowlevel.h" diff --git a/drivers/misc/ibmasm/ibmasmfs.c b/drivers/misc/ibmasm/ibmasmfs.c index aecf40e..8844a3f 100644 --- a/drivers/misc/ibmasm/ibmasmfs.c +++ b/drivers/misc/ibmasm/ibmasmfs.c @@ -75,6 +75,7 @@ #include #include +#include #include #include #include "ibmasm.h" diff --git a/drivers/misc/ibmasm/module.c b/drivers/misc/ibmasm/module.c index dc14b0b..a234d96 100644 --- a/drivers/misc/ibmasm/module.c +++ b/drivers/misc/ibmasm/module.c @@ -52,6 +52,7 @@ #include #include +#include #include "ibmasm.h" #include "lowlevel.h" #include "remote.h" diff --git a/drivers/misc/ics932s401.c b/drivers/misc/ics932s401.c index 395a4ea..152e9d9 100644 --- a/drivers/misc/ics932s401.c +++ b/drivers/misc/ics932s401.c @@ -26,6 +26,7 @@ #include #include #include +#include /* Addresses to scan */ static const unsigned short normal_i2c[] = { 0x69, I2C_CLIENT_END }; diff --git a/drivers/misc/ioc4.c b/drivers/misc/ioc4.c index 09dcb69..1932066 100644 --- a/drivers/misc/ioc4.c +++ b/drivers/misc/ioc4.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/misc/iwmc3200top/debugfs.c b/drivers/misc/iwmc3200top/debugfs.c index 0c8ea0a1..e9eda47 100644 --- a/drivers/misc/iwmc3200top/debugfs.c +++ b/drivers/misc/iwmc3200top/debugfs.c @@ -25,6 +25,7 @@ */ #include +#include #include #include #include diff --git a/drivers/misc/iwmc3200top/fw-download.c b/drivers/misc/iwmc3200top/fw-download.c index 9dbaeb5..e27afde 100644 --- a/drivers/misc/iwmc3200top/fw-download.c +++ b/drivers/misc/iwmc3200top/fw-download.c @@ -26,6 +26,7 @@ #include #include +#include #include #include "iwmc3200top.h" diff --git a/drivers/misc/iwmc3200top/log.c b/drivers/misc/iwmc3200top/log.c index d569279..a36a55a 100644 --- a/drivers/misc/iwmc3200top/log.c +++ b/drivers/misc/iwmc3200top/log.c @@ -26,6 +26,7 @@ #include #include +#include #include #include "fw-msg.h" #include "iwmc3200top.h" diff --git a/drivers/misc/iwmc3200top/main.c b/drivers/misc/iwmc3200top/main.c index 3b7292a..c73cef2 100644 --- a/drivers/misc/iwmc3200top/main.c +++ b/drivers/misc/iwmc3200top/main.c @@ -25,6 +25,7 @@ */ #include +#include #include #include #include diff --git a/drivers/misc/lkdtm.c b/drivers/misc/lkdtm.c index 4a06483..31a9911 100644 --- a/drivers/misc/lkdtm.c +++ b/drivers/misc/lkdtm.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include diff --git a/drivers/misc/phantom.c b/drivers/misc/phantom.c index 779aa8e..75ee0d3 100644 --- a/drivers/misc/phantom.c +++ b/drivers/misc/phantom.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/misc/sgi-xp/xpc_main.c b/drivers/misc/sgi-xp/xpc_main.c index 832ed4c..8d082b4 100644 --- a/drivers/misc/sgi-xp/xpc_main.c +++ b/drivers/misc/sgi-xp/xpc_main.c @@ -44,6 +44,7 @@ */ #include +#include #include #include #include diff --git a/drivers/misc/sgi-xp/xpc_partition.c b/drivers/misc/sgi-xp/xpc_partition.c index 9a6268c..d551f09 100644 --- a/drivers/misc/sgi-xp/xpc_partition.c +++ b/drivers/misc/sgi-xp/xpc_partition.c @@ -17,6 +17,7 @@ #include #include +#include #include "xpc.h" #include diff --git a/drivers/misc/sgi-xp/xpc_sn2.c b/drivers/misc/sgi-xp/xpc_sn2.c index 8b70e03..7d71c04 100644 --- a/drivers/misc/sgi-xp/xpc_sn2.c +++ b/drivers/misc/sgi-xp/xpc_sn2.c @@ -14,6 +14,7 @@ */ #include +#include #include #include #include diff --git a/drivers/misc/sgi-xp/xpc_uv.c b/drivers/misc/sgi-xp/xpc_uv.c index 8725d5e..1f59ee2 100644 --- a/drivers/misc/sgi-xp/xpc_uv.c +++ b/drivers/misc/sgi-xp/xpc_uv.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #if defined CONFIG_X86_64 #include diff --git a/drivers/misc/sgi-xp/xpnet.c b/drivers/misc/sgi-xp/xpnet.c index 57b152f..ee5109a 100644 --- a/drivers/misc/sgi-xp/xpnet.c +++ b/drivers/misc/sgi-xp/xpnet.c @@ -20,6 +20,7 @@ * */ +#include #include #include #include diff --git a/drivers/misc/tifm_core.c b/drivers/misc/tifm_core.c index 98bcba5..5f6852d 100644 --- a/drivers/misc/tifm_core.c +++ b/drivers/misc/tifm_core.c @@ -10,6 +10,7 @@ */ #include +#include #include #include diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 1f552c6..cb9fbc8 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c index e7f8027..445d7db 100644 --- a/drivers/mmc/card/mmc_test.c +++ b/drivers/mmc/card/mmc_test.c @@ -13,6 +13,7 @@ #include #include #include +#include #include diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index 381fe03..d6ded24 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c @@ -9,6 +9,7 @@ * published by the Free Software Foundation. * */ +#include #include #include #include diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c index 723e508..a071696 100644 --- a/drivers/mmc/card/sdio_uart.c +++ b/drivers/mmc/card/sdio_uart.c @@ -34,10 +34,10 @@ #include #include #include -#include #include #include #include +#include #include #include diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index bdb165f..49d9dca 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c @@ -13,6 +13,7 @@ #include #include +#include #include #include diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c index 96d10f4..53cb380c 100644 --- a/drivers/mmc/core/debugfs.c +++ b/drivers/mmc/core/debugfs.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index a268d12..4735390 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c @@ -16,6 +16,7 @@ #include #include #include +#include #include diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index e041c00..89f7a25 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -11,6 +11,7 @@ */ #include +#include #include #include diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index d2cb5c6..326447c 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c @@ -9,6 +9,7 @@ * your option) any later version. */ +#include #include #include diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index fdd414e..5eac21d 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -11,6 +11,7 @@ */ #include +#include #include #include diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c index 9e060c8..4a890dc 100644 --- a/drivers/mmc/core/sdio_bus.c +++ b/drivers/mmc/core/sdio_bus.c @@ -13,6 +13,7 @@ #include #include +#include #include #include diff --git a/drivers/mmc/core/sdio_cis.c b/drivers/mmc/core/sdio_cis.c index 9538389..541bdb8 100644 --- a/drivers/mmc/core/sdio_cis.c +++ b/drivers/mmc/core/sdio_cis.c @@ -14,6 +14,7 @@ */ #include +#include #include #include diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index 91dc60c..a6dd7da 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c @@ -65,6 +65,7 @@ #include #include #include +#include #include diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 8072128..88be37d 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index 57b2119..f583444 100644 --- a/drivers/mmc/host/au1xmmc.c +++ b/drivers/mmc/host/au1xmmc.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include diff --git a/drivers/mmc/host/bfin_sdh.c b/drivers/mmc/host/bfin_sdh.c index 56f7b44..6919e84 100644 --- a/drivers/mmc/host/bfin_sdh.c +++ b/drivers/mmc/host/bfin_sdh.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include diff --git a/drivers/mmc/host/cb710-mmc.c b/drivers/mmc/host/cb710-mmc.c index 4e72964..92a324f7 100644 --- a/drivers/mmc/host/cb710-mmc.c +++ b/drivers/mmc/host/cb710-mmc.c @@ -9,7 +9,6 @@ */ #include #include -#include #include #include #include "cb710-mmc.h" diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c index d55fe4f..ad847a2 100644 --- a/drivers/mmc/host/mmc_spi.c +++ b/drivers/mmc/host/mmc_spi.c @@ -26,6 +26,7 @@ */ #include #include +#include #include #include #include diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c index 4c068e5..04ae884 100644 --- a/drivers/mmc/host/msm_sdcc.c +++ b/drivers/mmc/host/msm_sdcc.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include diff --git a/drivers/mmc/host/of_mmc_spi.c b/drivers/mmc/host/of_mmc_spi.c index 0c7a63c..bb6cc54 100644 --- a/drivers/mmc/host/of_mmc_spi.c +++ b/drivers/mmc/host/of_mmc_spi.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index c6d7e8e..84d2804 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c index 0d783f3..0ed4895 100644 --- a/drivers/mmc/host/pxamci.c +++ b/drivers/mmc/host/pxamci.c @@ -29,6 +29,7 @@ #include #include #include +#include #include diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 8e1020c..6701af6 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c @@ -16,6 +16,7 @@ #include #include #include +#include #include diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index 50997d2..2136794 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index d6ab62d..9d4fdfa 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c index 89bf8cd..69efe01 100644 --- a/drivers/mmc/host/wbsd.c +++ b/drivers/mmc/host/wbsd.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c index 8c295f4..ce64240 100644 --- a/drivers/mtd/devices/block2mtd.c +++ b/drivers/mtd/devices/block2mtd.c @@ -17,6 +17,7 @@ #include #include #include +#include #define ERROR(fmt, args...) printk(KERN_ERR "block2mtd: " fmt "\n" , ## args) #define INFO(fmt, args...) printk(KERN_INFO "block2mtd: " fmt "\n" , ## args) diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index f3f4768..81e49a9 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include diff --git a/drivers/mtd/devices/sst25l.c b/drivers/mtd/devices/sst25l.c index 0a11721..fe17054 100644 --- a/drivers/mtd/devices/sst25l.c +++ b/drivers/mtd/devices/sst25l.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include diff --git a/drivers/mtd/lpddr/lpddr_cmds.c b/drivers/mtd/lpddr/lpddr_cmds.c index e22ca49..a73ee12 100644 --- a/drivers/mtd/lpddr/lpddr_cmds.c +++ b/drivers/mtd/lpddr/lpddr_cmds.c @@ -26,6 +26,7 @@ */ #include #include +#include static int lpddr_read(struct mtd_info *mtd, loff_t adr, size_t len, size_t *retlen, u_char *buf); diff --git a/drivers/mtd/maps/amd76xrom.c b/drivers/mtd/maps/amd76xrom.c index 237733d..19fe92d 100644 --- a/drivers/mtd/maps/amd76xrom.c +++ b/drivers/mtd/maps/amd76xrom.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/mtd/maps/bfin-async-flash.c b/drivers/mtd/maps/bfin-async-flash.c index a7c808b..c0fd99b 100644 --- a/drivers/mtd/maps/bfin-async-flash.c +++ b/drivers/mtd/maps/bfin-async-flash.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/drivers/mtd/maps/ck804xrom.c b/drivers/mtd/maps/ck804xrom.c index 424f17d..ddb462b 100644 --- a/drivers/mtd/maps/ck804xrom.c +++ b/drivers/mtd/maps/ck804xrom.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/mtd/maps/esb2rom.c b/drivers/mtd/maps/esb2rom.c index 11a2f57..d12c93d 100644 --- a/drivers/mtd/maps/esb2rom.c +++ b/drivers/mtd/maps/esb2rom.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/mtd/maps/gpio-addr-flash.c b/drivers/mtd/maps/gpio-addr-flash.c index 1ad5caf..32e89d7 100644 --- a/drivers/mtd/maps/gpio-addr-flash.c +++ b/drivers/mtd/maps/gpio-addr-flash.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #define pr_devinit(fmt, args...) ({ static const __devinitconst char __fmt[] = fmt; printk(__fmt, ## args); }) diff --git a/drivers/mtd/maps/ichxrom.c b/drivers/mtd/maps/ichxrom.c index c32bc28..f102bf2 100644 --- a/drivers/mtd/maps/ichxrom.c +++ b/drivers/mtd/maps/ichxrom.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/mtd/maps/intel_vr_nor.c b/drivers/mtd/maps/intel_vr_nor.c index 1e7814a..fc19985 100644 --- a/drivers/mtd/maps/intel_vr_nor.c +++ b/drivers/mtd/maps/intel_vr_nor.c @@ -29,6 +29,7 @@ #include #include +#include #include #include #include diff --git a/drivers/mtd/maps/octagon-5066.c b/drivers/mtd/maps/octagon-5066.c index 2b2e450..23fe178 100644 --- a/drivers/mtd/maps/octagon-5066.c +++ b/drivers/mtd/maps/octagon-5066.c @@ -24,7 +24,6 @@ ##################################################################### */ #include -#include #include #include #include diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c index 61e4eb4..101ee6e 100644 --- a/drivers/mtd/maps/physmap_of.c +++ b/drivers/mtd/maps/physmap_of.c @@ -23,6 +23,7 @@ #include #include #include +#include struct of_flash_list { struct mtd_info *mtd; diff --git a/drivers/mtd/maps/pismo.c b/drivers/mtd/maps/pismo.c index 30e12c8..60c068d 100644 --- a/drivers/mtd/maps/pismo.c +++ b/drivers/mtd/maps/pismo.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/mtd/maps/pmcmsp-flash.c b/drivers/mtd/maps/pmcmsp-flash.c index c8fd8da..acb13fa 100644 --- a/drivers/mtd/maps/pmcmsp-flash.c +++ b/drivers/mtd/maps/pmcmsp-flash.c @@ -28,6 +28,7 @@ * 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include #include #include #include diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c index b13f641..91dc633 100644 --- a/drivers/mtd/maps/pxa2xx-flash.c +++ b/drivers/mtd/maps/pxa2xx-flash.c @@ -11,6 +11,7 @@ #include #include +#include #include #include #include diff --git a/drivers/mtd/maps/sbc_gxx.c b/drivers/mtd/maps/sbc_gxx.c index 1b1c0b7..04b2781 100644 --- a/drivers/mtd/maps/sbc_gxx.c +++ b/drivers/mtd/maps/sbc_gxx.c @@ -45,7 +45,6 @@ separate MTD devices. // Includes #include -#include #include #include #include diff --git a/drivers/mtd/maps/sun_uflash.c b/drivers/mtd/maps/sun_uflash.c index fd7a101..fadc4c4 100644 --- a/drivers/mtd/maps/sun_uflash.c +++ b/drivers/mtd/maps/sun_uflash.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/mtd/maps/vmax301.c b/drivers/mtd/maps/vmax301.c index 6d452dc..6adaa6a 100644 --- a/drivers/mtd/maps/vmax301.c +++ b/drivers/mtd/maps/vmax301.c @@ -16,7 +16,6 @@ ##################################################################### */ #include -#include #include #include #include diff --git a/drivers/mtd/maps/vmu-flash.c b/drivers/mtd/maps/vmu-flash.c index 82afad0..4afc167 100644 --- a/drivers/mtd/maps/vmu-flash.c +++ b/drivers/mtd/maps/vmu-flash.c @@ -8,6 +8,7 @@ * GNU General Public Licence */ #include +#include #include #include #include diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index c356c0a..5b38b17 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/mtd/nand/bcm_umi_nand.c b/drivers/mtd/nand/bcm_umi_nand.c index 7d1cca7a..c997f98 100644 --- a/drivers/mtd/nand/bcm_umi_nand.c +++ b/drivers/mtd/nand/bcm_umi_nand.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c index c828d9a..e5a9f9c 100644 --- a/drivers/mtd/nand/cafe_nand.c +++ b/drivers/mtd/nand/cafe_nand.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #define CAFE_NAND_CTRL1 0x00 diff --git a/drivers/mtd/nand/cmx270_nand.c b/drivers/mtd/nand/cmx270_nand.c index 826cacf..6e64952 100644 --- a/drivers/mtd/nand/cmx270_nand.c +++ b/drivers/mtd/nand/cmx270_nand.c @@ -20,6 +20,7 @@ #include #include +#include #include #include diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index fe3eba8..76e2dc8 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c @@ -32,6 +32,7 @@ #include #include #include +#include #include diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c index b126cf8..47067bc 100644 --- a/drivers/mtd/nand/diskonchip.c +++ b/drivers/mtd/nand/diskonchip.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c index 071a60c..4b96296 100644 --- a/drivers/mtd/nand/fsl_upm.c +++ b/drivers/mtd/nand/fsl_upm.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #define FSL_UPM_WAIT_RUN_PATTERN 0x1 diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c index 40b5658..b983cae 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/ndfc.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/mtd/nand/nomadik_nand.c b/drivers/mtd/nand/nomadik_nand.c index 6612341..1f6f741 100644 --- a/drivers/mtd/nand/nomadik_nand.c +++ b/drivers/mtd/nand/nomadik_nand.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 26aec008..7545568 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index 1a5a036..5d55152 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c index 1842df8..34752fc 100644 --- a/drivers/mtd/nand/sh_flctl.c +++ b/drivers/mtd/nand/sh_flctl.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include diff --git a/drivers/mtd/nand/tmio_nand.c b/drivers/mtd/nand/tmio_nand.c index 92c7334..fa28f01 100644 --- a/drivers/mtd/nand/tmio_nand.c +++ b/drivers/mtd/nand/tmio_nand.c @@ -37,6 +37,7 @@ #include #include #include +#include /*--------------------------------------------------------------------------*/ diff --git a/drivers/mtd/ofpart.c b/drivers/mtd/ofpart.c index 62d6a78..4f0d635 100644 --- a/drivers/mtd/ofpart.c +++ b/drivers/mtd/ofpart.c @@ -17,6 +17,7 @@ #include #include #include +#include #include int __devinit of_mtd_parse_partitions(struct device *dev, diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c index 75f38b9..fd40634 100644 --- a/drivers/mtd/onenand/omap2.c +++ b/drivers/mtd/onenand/omap2.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index f63b1db..32f0ed3 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/mtd/onenand/onenand_sim.c b/drivers/mtd/onenand/onenand_sim.c index f6e3c8a..8b24606 100644 --- a/drivers/mtd/onenand/onenand_sim.c +++ b/drivers/mtd/onenand/onenand_sim.c @@ -16,6 +16,7 @@ */ #include +#include #include #include #include diff --git a/drivers/mtd/tests/mtd_nandecctest.c b/drivers/mtd/tests/mtd_nandecctest.c index c1f3105..70d6d7d 100644 --- a/drivers/mtd/tests/mtd_nandecctest.c +++ b/drivers/mtd/tests/mtd_nandecctest.c @@ -1,7 +1,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/mtd/tests/mtd_oobtest.c b/drivers/mtd/tests/mtd_oobtest.c index 5813920..dec92ae 100644 --- a/drivers/mtd/tests/mtd_oobtest.c +++ b/drivers/mtd/tests/mtd_oobtest.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #define PRINT_PREF KERN_INFO "mtd_oobtest: " diff --git a/drivers/mtd/tests/mtd_pagetest.c b/drivers/mtd/tests/mtd_pagetest.c index ce17cbe..921a85d 100644 --- a/drivers/mtd/tests/mtd_pagetest.c +++ b/drivers/mtd/tests/mtd_pagetest.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #define PRINT_PREF KERN_INFO "mtd_pagetest: " diff --git a/drivers/mtd/tests/mtd_readtest.c b/drivers/mtd/tests/mtd_readtest.c index 25c5dd0..7107fcc 100644 --- a/drivers/mtd/tests/mtd_readtest.c +++ b/drivers/mtd/tests/mtd_readtest.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #define PRINT_PREF KERN_INFO "mtd_readtest: " diff --git a/drivers/mtd/tests/mtd_speedtest.c b/drivers/mtd/tests/mtd_speedtest.c index 7fbb51d..56ca62b 100644 --- a/drivers/mtd/tests/mtd_speedtest.c +++ b/drivers/mtd/tests/mtd_speedtest.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #define PRINT_PREF KERN_INFO "mtd_speedtest: " diff --git a/drivers/mtd/tests/mtd_stresstest.c b/drivers/mtd/tests/mtd_stresstest.c index a99d3cd..3854afe 100644 --- a/drivers/mtd/tests/mtd_stresstest.c +++ b/drivers/mtd/tests/mtd_stresstest.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include diff --git a/drivers/mtd/tests/mtd_subpagetest.c b/drivers/mtd/tests/mtd_subpagetest.c index 5b88972..700237a 100644 --- a/drivers/mtd/tests/mtd_subpagetest.c +++ b/drivers/mtd/tests/mtd_subpagetest.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #define PRINT_PREF KERN_INFO "mtd_subpagetest: " diff --git a/drivers/mtd/tests/mtd_torturetest.c b/drivers/mtd/tests/mtd_torturetest.c index 631a0ab..5c6c3d2 100644 --- a/drivers/mtd/tests/mtd_torturetest.c +++ b/drivers/mtd/tests/mtd_torturetest.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #define PRINT_PREF KERN_INFO "mtd_torturetest: " diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index fad40aa..55c726d 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -44,6 +44,7 @@ #include #include #include +#include #include "ubi.h" /* Maximum length of the 'mtd=' parameter */ diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index 111ea41..72ebb3f 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c @@ -37,6 +37,7 @@ #include #include +#include #include #include #include diff --git a/drivers/mtd/ubi/gluebi.c b/drivers/mtd/ubi/gluebi.c index b5e478f..9aa8158 100644 --- a/drivers/mtd/ubi/gluebi.c +++ b/drivers/mtd/ubi/gluebi.c @@ -31,6 +31,7 @@ #include #include +#include #include #include #include diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index b4ecc84..533b1a4 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c @@ -88,6 +88,7 @@ #include #include +#include #include "ubi.h" #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID diff --git a/drivers/mtd/ubi/kapi.c b/drivers/mtd/ubi/kapi.c index 1361574..17f287d 100644 --- a/drivers/mtd/ubi/kapi.c +++ b/drivers/mtd/ubi/kapi.c @@ -22,6 +22,7 @@ #include #include +#include #include #include #include diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index 594184b..dc5f688 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c @@ -41,6 +41,7 @@ */ #include +#include #include #include #include "ubi.h" diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index 1af0817..5176d48 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c index ab64cb5..e42afab 100644 --- a/drivers/mtd/ubi/vmt.c +++ b/drivers/mtd/ubi/vmt.c @@ -25,6 +25,7 @@ #include #include +#include #include "ubi.h" #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index 4004402..cd90ff3 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -58,6 +58,7 @@ #include #include +#include #include #include "ubi.h" diff --git a/drivers/net/3c501.c b/drivers/net/3c501.c index b6de7b1..3ea42ff1 100644 --- a/drivers/net/3c501.c +++ b/drivers/net/3c501.c @@ -117,7 +117,6 @@ static const char version[] = #include #include #include -#include #include #include #include diff --git a/drivers/net/3c505.c b/drivers/net/3c505.c index 04b5bba..29b8d1d 100644 --- a/drivers/net/3c505.c +++ b/drivers/net/3c505.c @@ -102,12 +102,12 @@ #include #include #include -#include #include #include #include #include #include +#include #include #include diff --git a/drivers/net/3c507.c b/drivers/net/3c507.c index 77cf090..b32b7a1 100644 --- a/drivers/net/3c507.c +++ b/drivers/net/3c507.c @@ -58,7 +58,6 @@ static const char version[] = #include #include #include -#include #include #include diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c index 902435a..ab9bb3c 100644 --- a/drivers/net/3c509.c +++ b/drivers/net/3c509.c @@ -76,7 +76,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/3c515.c b/drivers/net/3c515.c index 1e898b1..2e17837 100644 --- a/drivers/net/3c515.c +++ b/drivers/net/3c515.c @@ -65,7 +65,6 @@ static int max_interrupt_work = 20; #include #include #include -#include #include #include #include diff --git a/drivers/net/3c523.c b/drivers/net/3c523.c index beed4fa..1719079 100644 --- a/drivers/net/3c523.c +++ b/drivers/net/3c523.c @@ -99,7 +99,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index f965431..5f92fdb 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c @@ -77,7 +77,6 @@ static int vortex_debug = 1; #include #include #include -#include #include #include #include @@ -90,6 +89,7 @@ static int vortex_debug = 1; #include #include #include +#include #include /* For nr_irqs only. */ #include #include diff --git a/drivers/net/7990.c b/drivers/net/7990.c index 4e9a5a2..500e135 100644 --- a/drivers/net/7990.c +++ b/drivers/net/7990.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c index 3d4406b..a09e6ce 100644 --- a/drivers/net/8139cp.c +++ b/drivers/net/8139cp.c @@ -64,6 +64,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c index b4efc91..a03d291 100644 --- a/drivers/net/8139too.c +++ b/drivers/net/8139too.c @@ -110,6 +110,7 @@ #include #include #include +#include #include #define RTL8139_DRIVER_NAME DRV_NAME " Fast Ethernet driver " DRV_VERSION diff --git a/drivers/net/82596.c b/drivers/net/82596.c index f94d17d..56e68db 100644 --- a/drivers/net/82596.c +++ b/drivers/net/82596.c @@ -45,7 +45,6 @@ #include #include #include -#include #include #include #include @@ -53,6 +52,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/a2065.c b/drivers/net/a2065.c index bd4d829..ed5e974 100644 --- a/drivers/net/a2065.c +++ b/drivers/net/a2065.c @@ -46,7 +46,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c index 4ae750e..97a3dfd 100644 --- a/drivers/net/acenic.c +++ b/drivers/net/acenic.c @@ -67,6 +67,7 @@ #include #include #include +#include #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) #include diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c index b8a59d2..8d58f0a 100644 --- a/drivers/net/amd8111e.c +++ b/drivers/net/amd8111e.c @@ -73,7 +73,6 @@ Revision History: #include #include #include -#include #include #include #include diff --git a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c index 73b38c2..6f8d620 100644 --- a/drivers/net/appletalk/cops.c +++ b/drivers/net/appletalk/cops.c @@ -56,7 +56,6 @@ static const char *version = #include #include #include -#include #include #include #include diff --git a/drivers/net/appletalk/ipddp.c b/drivers/net/appletalk/ipddp.c index eb0448b..79636ee 100644 --- a/drivers/net/appletalk/ipddp.c +++ b/drivers/net/appletalk/ipddp.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/appletalk/ltpc.c b/drivers/net/appletalk/ltpc.c index 8ea4ec7..6af65b6 100644 --- a/drivers/net/appletalk/ltpc.c +++ b/drivers/net/appletalk/ltpc.c @@ -215,7 +215,6 @@ static int dma; #include #include #include -#include #include #include #include @@ -228,6 +227,7 @@ static int dma; #include #include #include +#include #include #include diff --git a/drivers/net/arcnet/arc-rawmode.c b/drivers/net/arcnet/arc-rawmode.c index 8ea9c75..705e6ce 100644 --- a/drivers/net/arcnet/arc-rawmode.c +++ b/drivers/net/arcnet/arc-rawmode.c @@ -25,6 +25,7 @@ */ #include +#include #include #include #include diff --git a/drivers/net/arcnet/arc-rimi.c b/drivers/net/arcnet/arc-rimi.c index e6afab2..9efbbba 100644 --- a/drivers/net/arcnet/arc-rimi.c +++ b/drivers/net/arcnet/arc-rimi.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/arcnet/capmode.c b/drivers/net/arcnet/capmode.c index 66bcbbb..355797f 100644 --- a/drivers/net/arcnet/capmode.c +++ b/drivers/net/arcnet/capmode.c @@ -27,6 +27,7 @@ */ #include +#include #include #include #include diff --git a/drivers/net/arcnet/com20020-isa.c b/drivers/net/arcnet/com20020-isa.c index db08fc2..0402da3 100644 --- a/drivers/net/arcnet/com20020-isa.c +++ b/drivers/net/arcnet/com20020-isa.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c index b68e1eb..2c712af 100644 --- a/drivers/net/arcnet/com20020-pci.c +++ b/drivers/net/arcnet/com20020-pci.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/arcnet/com20020.c b/drivers/net/arcnet/com20020.c index 0a74f21..c9e4594 100644 --- a/drivers/net/arcnet/com20020.c +++ b/drivers/net/arcnet/com20020.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/arcnet/com90io.c b/drivers/net/arcnet/com90io.c index 28dea51..4cb4018 100644 --- a/drivers/net/arcnet/com90io.c +++ b/drivers/net/arcnet/com90io.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/arcnet/com90xx.c b/drivers/net/arcnet/com90xx.c index 112e230..f3b46f7 100644 --- a/drivers/net/arcnet/com90xx.c +++ b/drivers/net/arcnet/com90xx.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/arcnet/rfc1051.c b/drivers/net/arcnet/rfc1051.c index 06f8fa2..f81db40 100644 --- a/drivers/net/arcnet/rfc1051.c +++ b/drivers/net/arcnet/rfc1051.c @@ -24,6 +24,7 @@ * ********************** */ #include +#include #include #include #include diff --git a/drivers/net/arcnet/rfc1201.c b/drivers/net/arcnet/rfc1201.c index 7455306..b71431a 100644 --- a/drivers/net/arcnet/rfc1201.c +++ b/drivers/net/arcnet/rfc1201.c @@ -23,6 +23,7 @@ * * ********************** */ +#include #include #include #include diff --git a/drivers/net/ariadne.c b/drivers/net/ariadne.c index 08d8be4..fa1a235 100644 --- a/drivers/net/ariadne.c +++ b/drivers/net/ariadne.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/arm/at91_ether.c b/drivers/net/arm/at91_ether.c index 8b23d5a..aed5b54 100644 --- a/drivers/net/arm/at91_ether.c +++ b/drivers/net/arm/at91_ether.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/arm/ep93xx_eth.c b/drivers/net/arm/ep93xx_eth.c index bf72d57..6995169 100644 --- a/drivers/net/arm/ep93xx_eth.c +++ b/drivers/net/arm/ep93xx_eth.c @@ -23,6 +23,7 @@ #include #include #include +#include #include diff --git a/drivers/net/arm/etherh.c b/drivers/net/arm/etherh.c index f52f668c..4af235d 100644 --- a/drivers/net/arm/etherh.c +++ b/drivers/net/arm/etherh.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/arm/ixp4xx_eth.c b/drivers/net/arm/ixp4xx_eth.c index 6e2ae1d..6be8b09 100644 --- a/drivers/net/arm/ixp4xx_eth.c +++ b/drivers/net/arm/ixp4xx_eth.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/arm/ks8695net.c b/drivers/net/arm/ks8695net.c index e7810b7..84f8a8f 100644 --- a/drivers/net/arm/ks8695net.c +++ b/drivers/net/arm/ks8695net.c @@ -30,6 +30,7 @@ #include #include #include +#include #include diff --git a/drivers/net/arm/w90p910_ether.c b/drivers/net/arm/w90p910_ether.c index febd813..f7c9ca1 100644 --- a/drivers/net/arm/w90p910_ether.c +++ b/drivers/net/arm/w90p910_ether.c @@ -18,6 +18,7 @@ #include #include #include +#include #define DRV_MODULE_NAME "w90p910-emc" #define DRV_MODULE_VERSION "0.1" diff --git a/drivers/net/at1700.c b/drivers/net/at1700.c index 309843a..10a20fb 100644 --- a/drivers/net/at1700.c +++ b/drivers/net/at1700.c @@ -47,7 +47,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/atarilance.c b/drivers/net/atarilance.c index 280cfff..a8686bf 100644 --- a/drivers/net/atarilance.c +++ b/drivers/net/atarilance.c @@ -53,7 +53,6 @@ static char version[] = "atarilance.c: v1.3 04/04/96 " #include #include #include -#include #include #include #include diff --git a/drivers/net/atl1c/atl1c_ethtool.c b/drivers/net/atl1c/atl1c_ethtool.c index 61a0f2f..3233924 100644 --- a/drivers/net/atl1c/atl1c_ethtool.c +++ b/drivers/net/atl1c/atl1c_ethtool.c @@ -22,6 +22,7 @@ #include #include +#include #include "atl1c.h" diff --git a/drivers/net/atl1e/atl1e_ethtool.c b/drivers/net/atl1e/atl1e_ethtool.c index a76006c..ffd696e 100644 --- a/drivers/net/atl1e/atl1e_ethtool.c +++ b/drivers/net/atl1e/atl1e_ethtool.c @@ -22,6 +22,7 @@ #include #include +#include #include "atl1e.h" diff --git a/drivers/net/atlx/atl2.c b/drivers/net/atlx/atl2.c index 7061d71..54662f2 100644 --- a/drivers/net/atlx/atl2.c +++ b/drivers/net/atlx/atl2.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/atp.c b/drivers/net/atp.c index 6ad1620..55039d4 100644 --- a/drivers/net/atp.c +++ b/drivers/net/atp.c @@ -129,7 +129,6 @@ static int xcvr[NUM_UNITS]; /* The data transfer mode. */ #include #include #include -#include #include #include #include diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c index 1dd4403..b718dc6 100644 --- a/drivers/net/ax88796.c +++ b/drivers/net/ax88796.c @@ -25,6 +25,7 @@ #include #include #include +#include #include diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 332c603..69d9f3d 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/bcm63xx_enet.c b/drivers/net/bcm63xx_enet.c index 8cdcab7..17460ab 100644 --- a/drivers/net/bcm63xx_enet.c +++ b/drivers/net/bcm63xx_enet.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index 8f07525..56387b1 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -29,6 +29,7 @@ #include #include #include +#include #include "be_hw.h" diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c index 119468e..598b007 100644 --- a/drivers/net/bmac.c +++ b/drivers/net/bmac.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index 904aa36..d0f8c7e 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index f8cc168..b39b108 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c @@ -73,6 +73,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/can/sja1000/ems_pci.c b/drivers/net/can/sja1000/ems_pci.c index 8730060..5f53da0 100644 --- a/drivers/net/can/sja1000/ems_pci.c +++ b/drivers/net/can/sja1000/ems_pci.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/can/sja1000/plx_pci.c b/drivers/net/can/sja1000/plx_pci.c index 6b46a63..4aff407 100644 --- a/drivers/net/can/sja1000/plx_pci.c +++ b/drivers/net/can/sja1000/plx_pci.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c index d124d83..a30b8f4 100644 --- a/drivers/net/can/vcan.c +++ b/drivers/net/can/vcan.c @@ -48,6 +48,7 @@ #include #include #include +#include #include static __initdata const char banner[] = diff --git a/drivers/net/chelsio/common.h b/drivers/net/chelsio/common.h index 2d11afe..036b2df 100644 --- a/drivers/net/chelsio/common.h +++ b/drivers/net/chelsio/common.h @@ -51,6 +51,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/chelsio/pm3393.c b/drivers/net/chelsio/pm3393.c index a6eb30a..9e631b9 100644 --- a/drivers/net/chelsio/pm3393.c +++ b/drivers/net/chelsio/pm3393.c @@ -44,6 +44,7 @@ #include "suni1x10gexp_regs.h" #include +#include #define OFFSET(REG_ADDR) ((REG_ADDR) << 2) diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c index 55d99ca..df3a141 100644 --- a/drivers/net/chelsio/sge.c +++ b/drivers/net/chelsio/sge.c @@ -53,6 +53,7 @@ #include #include #include +#include #include "cpl5_cmd.h" #include "sge.h" diff --git a/drivers/net/cris/eth_v10.c b/drivers/net/cris/eth_v10.c index dd24aad..61a3391 100644 --- a/drivers/net/cris/eth_v10.c +++ b/drivers/net/cris/eth_v10.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c index b0208e4..4c38491 100644 --- a/drivers/net/cs89x0.c +++ b/drivers/net/cs89x0.c @@ -138,12 +138,12 @@ #include #include #include -#include #include #include #include #include #include +#include #include #include diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index 9e3e875..aced6c5 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include "common.h" diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c index 9498361..c6485b3 100644 --- a/drivers/net/cxgb3/cxgb3_offload.c +++ b/drivers/net/cxgb3/cxgb3_offload.c @@ -31,6 +31,7 @@ */ #include +#include #include #include #include diff --git a/drivers/net/cxgb3/l2t.c b/drivers/net/cxgb3/l2t.c index ff1611f..2f3ee72 100644 --- a/drivers/net/cxgb3/l2t.c +++ b/drivers/net/cxgb3/l2t.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include "common.h" #include "t3cdev.h" diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c index 67e61b2..07d7e7f 100644 --- a/drivers/net/cxgb3/sge.c +++ b/drivers/net/cxgb3/sge.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include "common.h" #include "regs.h" diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index 1c67f11..7f9960f 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index b33e3cb..983493f 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include "e1000.h" diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index e1cceb6..cfd09ce 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/eepro.c b/drivers/net/eepro.c index 1b05bdf..27c7bdb 100644 --- a/drivers/net/eepro.c +++ b/drivers/net/eepro.c @@ -137,7 +137,6 @@ static const char version[] = #include #include #include -#include #include #include #include diff --git a/drivers/net/eexpress.c b/drivers/net/eexpress.c index 7013dc8..1a7322b 100644 --- a/drivers/net/eexpress.c +++ b/drivers/net/eexpress.c @@ -111,7 +111,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index b004eab..809ccc9 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c index 18d405f..a1b4c7e 100644 --- a/drivers/net/ehea/ehea_qmr.c +++ b/drivers/net/ehea/ehea_qmr.c @@ -27,6 +27,7 @@ */ #include +#include #include "ehea.h" #include "ehea_phyp.h" #include "ehea_qmr.h" diff --git a/drivers/net/enc28j60.c b/drivers/net/enc28j60.c index 3ee32e5..ff27f72 100644 --- a/drivers/net/enc28j60.c +++ b/drivers/net/enc28j60.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c index 69b9b70..cf22de7 100644 --- a/drivers/net/enic/vnic_dev.c +++ b/drivers/net/enic/vnic_dev.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "vnic_resource.h" #include "vnic_devcmd.h" diff --git a/drivers/net/enic/vnic_rq.c b/drivers/net/enic/vnic_rq.c index 7558397..e186efa 100644 --- a/drivers/net/enic/vnic_rq.c +++ b/drivers/net/enic/vnic_rq.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "vnic_dev.h" #include "vnic_rq.h" diff --git a/drivers/net/enic/vnic_wq.c b/drivers/net/enic/vnic_wq.c index d2e00e5..d5f9843 100644 --- a/drivers/net/enic/vnic_wq.c +++ b/drivers/net/enic/vnic_wq.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "vnic_dev.h" #include "vnic_wq.h" diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c index 39c271b..7a567201 100644 --- a/drivers/net/epic100.c +++ b/drivers/net/epic100.c @@ -73,7 +73,6 @@ static int rx_copybreak; #include #include #include -#include #include #include #include diff --git a/drivers/net/eql.c b/drivers/net/eql.c index f5b96cad..b34a2dd 100644 --- a/drivers/net/eql.c +++ b/drivers/net/eql.c @@ -115,6 +115,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/eth16i.c b/drivers/net/eth16i.c index d3abeee..d4e24f0 100644 --- a/drivers/net/eth16i.c +++ b/drivers/net/eth16i.c @@ -152,7 +152,6 @@ static char *version = #include #include #include -#include #include #include #include diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c index 2097423..a8d9250 100644 --- a/drivers/net/ethoc.c +++ b/drivers/net/ethoc.c @@ -18,6 +18,7 @@ #include #include #include +#include #include static int buffer_size = 0x8000; /* 32 KBytes */ diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c index 9d5ad08..d11ae51 100644 --- a/drivers/net/fealnx.c +++ b/drivers/net/fealnx.c @@ -74,7 +74,6 @@ static int full_duplex[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 }; #include #include #include -#include #include #include #include diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c index 0dbd721..4a43e56 100644 --- a/drivers/net/fec_mpc52xx.c +++ b/drivers/net/fec_mpc52xx.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/fec_mpc52xx_phy.c b/drivers/net/fec_mpc52xx_phy.c index ee0f3c6..7658a08 100644 --- a/drivers/net/fec_mpc52xx_phy.c +++ b/drivers/net/fec_mpc52xx_phy.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index ca05e56..73b260c 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -59,6 +59,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c index cf4f674..0a973e7 100644 --- a/drivers/net/fs_enet/mac-fcc.c +++ b/drivers/net/fs_enet/mac-fcc.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -34,6 +33,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/fs_enet/mac-fec.c b/drivers/net/fs_enet/mac-fec.c index cd2c6cc..ec81f50 100644 --- a/drivers/net/fs_enet/mac-fec.c +++ b/drivers/net/fs_enet/mac-fec.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -33,6 +32,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/fs_enet/mac-scc.c b/drivers/net/fs_enet/mac-scc.c index c490a46..34d3da7 100644 --- a/drivers/net/fs_enet/mac-scc.c +++ b/drivers/net/fs_enet/mac-scc.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c index 1010367..9bda023 100644 --- a/drivers/net/gianfar_ethtool.c +++ b/drivers/net/gianfar_ethtool.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/gianfar_sysfs.c b/drivers/net/gianfar_sysfs.c index b98c6c5..64f4094 100644 --- a/drivers/net/gianfar_sysfs.c +++ b/drivers/net/gianfar_sysfs.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/greth.c b/drivers/net/greth.c index 2b9c1cb..3a90430 100644 --- a/drivers/net/greth.c +++ b/drivers/net/greth.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c index 373546d..5d6f13879 100644 --- a/drivers/net/hamachi.c +++ b/drivers/net/hamachi.c @@ -153,7 +153,6 @@ static int tx_params[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1}; #include #include #include -#include #include #include #include diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index 689b9bd..4b52c76 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c index bdadf3e..14f01d1 100644 --- a/drivers/net/hamradio/bpqether.c +++ b/drivers/net/hamradio/bpqether.c @@ -61,6 +61,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c index 9ee76b4..52b1425 100644 --- a/drivers/net/hamradio/dmascc.c +++ b/drivers/net/hamradio/dmascc.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/hamradio/hdlcdrv.c b/drivers/net/hamradio/hdlcdrv.c index 91c5790..b8bdf9d 100644 --- a/drivers/net/hamradio/hdlcdrv.c +++ b/drivers/net/hamradio/hdlcdrv.c @@ -48,7 +48,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index 7db0a1c..66e88bd 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c index 35c9361..f3a96b8 100644 --- a/drivers/net/hamradio/scc.c +++ b/drivers/net/hamradio/scc.c @@ -158,7 +158,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c index b766a69..4daad8c 100644 --- a/drivers/net/hp100.c +++ b/drivers/net/hp100.c @@ -102,7 +102,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/hplance.c b/drivers/net/hplance.c index 3e3528a..b6060f7 100644 --- a/drivers/net/hplance.c +++ b/drivers/net/hplance.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/hydra.c b/drivers/net/hydra.c index d496b6f..24724b4 100644 --- a/drivers/net/hydra.c +++ b/drivers/net/hydra.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index fb0ac6d..dd873cc 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/ibm_newemac/core.h b/drivers/net/ibm_newemac/core.h index 18d56c6..b1cbe6f 100644 --- a/drivers/net/ibm_newemac/core.h +++ b/drivers/net/ibm_newemac/core.h @@ -34,6 +34,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/ibm_newemac/mal.c b/drivers/net/ibm_newemac/mal.c index 2a2fc17..5b3d944 100644 --- a/drivers/net/ibm_newemac/mal.c +++ b/drivers/net/ibm_newemac/mal.c @@ -26,6 +26,7 @@ */ #include +#include #include "core.h" #include diff --git a/drivers/net/ibm_newemac/rgmii.c b/drivers/net/ibm_newemac/rgmii.c index 8d76cb8..5b90d34 100644 --- a/drivers/net/ibm_newemac/rgmii.c +++ b/drivers/net/ibm_newemac/rgmii.c @@ -21,6 +21,7 @@ * option) any later version. * */ +#include #include #include #include diff --git a/drivers/net/ibm_newemac/zmii.c b/drivers/net/ibm_newemac/zmii.c index 17b1541..1f038f8 100644 --- a/drivers/net/ibm_newemac/zmii.c +++ b/drivers/net/ibm_newemac/zmii.c @@ -21,6 +21,7 @@ * option) any later version. * */ +#include #include #include #include diff --git a/drivers/net/ibmlana.c b/drivers/net/ibmlana.c index b5d0f4e..7d6cf33 100644 --- a/drivers/net/ibmlana.c +++ b/drivers/net/ibmlana.c @@ -79,7 +79,6 @@ History: #include #include #include -#include #include #include #include diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 0bc777ba..cd508a8 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c index 0bc990e..4a32bed 100644 --- a/drivers/net/igb/e1000_82575.c +++ b/drivers/net/igb/e1000_82575.c @@ -30,7 +30,6 @@ */ #include -#include #include #include "e1000_mac.h" diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c index a4cead1..d313fae 100644 --- a/drivers/net/igb/igb_ethtool.c +++ b/drivers/net/igb/igb_ethtool.c @@ -35,6 +35,7 @@ #include #include #include +#include #include "igb.h" diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 01c65c7..9b3c51a 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c index b41037e..1b1edad 100644 --- a/drivers/net/igbvf/netdev.c +++ b/drivers/net/igbvf/netdev.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c index 70871b9..8f6197d 100644 --- a/drivers/net/ioc3-eth.c +++ b/drivers/net/ioc3-eth.c @@ -44,6 +44,7 @@ #include #include #include +#include #ifdef CONFIG_SERIAL_8250 #include diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c index 150415e..639bf9f 100644 --- a/drivers/net/ipg.c +++ b/drivers/net/ipg.c @@ -22,6 +22,7 @@ */ #include #include +#include #include #include diff --git a/drivers/net/irda/ali-ircc.c b/drivers/net/irda/ali-ircc.c index 12c7b00..28992c8 100644 --- a/drivers/net/irda/ali-ircc.c +++ b/drivers/net/irda/ali-ircc.c @@ -22,6 +22,7 @@ ********************************************************************/ #include +#include #include #include @@ -29,7 +30,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/irda/bfin_sir.h b/drivers/net/irda/bfin_sir.h index dac71b1..b54a6f0 100644 --- a/drivers/net/irda/bfin_sir.h +++ b/drivers/net/irda/bfin_sir.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c index 20f9bc6..ee1dde5 100644 --- a/drivers/net/irda/irtty-sir.c +++ b/drivers/net/irda/irtty-sir.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c index 2413295..e30cdbb 100644 --- a/drivers/net/irda/nsc-ircc.c +++ b/drivers/net/irda/nsc-ircc.c @@ -43,6 +43,7 @@ ********************************************************************/ #include +#include #include #include @@ -50,7 +51,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c index 84db145..1a54f6b 100644 --- a/drivers/net/irda/pxaficp_ir.c +++ b/drivers/net/irda/pxaficp_ir.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/irda/sh_sir.c b/drivers/net/irda/sh_sir.c index d7c983d..0745581 100644 --- a/drivers/net/irda/sh_sir.c +++ b/drivers/net/irda/sh_sir.c @@ -14,6 +14,7 @@ #include #include +#include #include #include #include diff --git a/drivers/net/irda/sir_dev.c b/drivers/net/irda/sir_dev.c index 4b2a1a9..de91cd1 100644 --- a/drivers/net/irda/sir_dev.c +++ b/drivers/net/irda/sir_dev.c @@ -13,6 +13,7 @@ #include #include +#include #include #include diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c index 8f7d0d1..6af84d8 100644 --- a/drivers/net/irda/smsc-ircc2.c +++ b/drivers/net/irda/smsc-ircc2.c @@ -48,13 +48,13 @@ #include #include #include -#include #include #include #include #include #include #include +#include #include #include diff --git a/drivers/net/irda/via-ircc.c b/drivers/net/irda/via-ircc.c index 6533c01..b0a6cd8 100644 --- a/drivers/net/irda/via-ircc.c +++ b/drivers/net/irda/via-ircc.c @@ -45,11 +45,11 @@ F02 Oct/28/02: Add SB device ID for 3147 and 3177. #include #include #include -#include #include #include #include #include +#include #include #include diff --git a/drivers/net/irda/w83977af_ir.c b/drivers/net/irda/w83977af_ir.c index 980625f..cb0cb75 100644 --- a/drivers/net/irda/w83977af_ir.c +++ b/drivers/net/irda/w83977af_ir.c @@ -46,10 +46,10 @@ #include #include #include -#include #include #include #include +#include #include #include diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index e6e972d..773c59c 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c @@ -69,6 +69,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 1959ef7..8f461d5 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -29,6 +29,7 @@ #include #include +#include #include #include #include diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c index 9276d59..6493049 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.c +++ b/drivers/net/ixgbe/ixgbe_fcoe.c @@ -31,6 +31,7 @@ #include "ixgbe_dcb_82599.h" #endif /* CONFIG_IXGBE_DCB */ #include +#include #include #include #include diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 0c553f6..8f677cb 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/ixgbevf/ethtool.c b/drivers/net/ixgbevf/ethtool.c index 6fdd651..4680b06 100644 --- a/drivers/net/ixgbevf/ethtool.c +++ b/drivers/net/ixgbevf/ethtool.c @@ -29,6 +29,7 @@ #include #include +#include #include #include #include diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c index 1bbbef3..0cd6202 100644 --- a/drivers/net/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ixgbevf/ixgbevf_main.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/ixp2000/ixpdev.c b/drivers/net/ixp2000/ixpdev.c index e9d9d59..d5932ca 100644 --- a/drivers/net/ixp2000/ixpdev.c +++ b/drivers/net/ixp2000/ixpdev.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include "ixp2400_rx.ucode" diff --git a/drivers/net/jazzsonic.c b/drivers/net/jazzsonic.c index f47d4d6..3e6aaf9 100644 --- a/drivers/net/jazzsonic.c +++ b/drivers/net/jazzsonic.c @@ -22,11 +22,11 @@ #include #include #include +#include #include #include #include #include -#include #include #include #include @@ -35,6 +35,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/jme.c b/drivers/net/jme.c index c0b59a5..b705ad3 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include "jme.h" diff --git a/drivers/net/ks8851_mll.c b/drivers/net/ks8851_mll.c index 84b0e15..6354ab3 100644 --- a/drivers/net/ks8851_mll.c +++ b/drivers/net/ks8851_mll.c @@ -31,6 +31,7 @@ #include #include #include +#include #define DRV_NAME "ks8851_mll" diff --git a/drivers/net/ksz884x.c b/drivers/net/ksz884x.c index 6c5327a..0606a1f 100644 --- a/drivers/net/ksz884x.c +++ b/drivers/net/ksz884x.c @@ -30,6 +30,7 @@ #include #include #include +#include /* DMA Registers */ diff --git a/drivers/net/lasi_82596.c b/drivers/net/lasi_82596.c index b77238d..6eba352 100644 --- a/drivers/net/lasi_82596.c +++ b/drivers/net/lasi_82596.c @@ -74,7 +74,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/lib82596.c b/drivers/net/lib82596.c index 443c39a..973390b 100644 --- a/drivers/net/lib82596.c +++ b/drivers/net/lib82596.c @@ -73,7 +73,6 @@ #include #include #include -#include #include #include #include @@ -85,6 +84,7 @@ #include #include #include +#include /* DEBUG flags */ diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c index a18e348..ba617e3c 100644 --- a/drivers/net/ll_temac_main.c +++ b/drivers/net/ll_temac_main.c @@ -49,6 +49,7 @@ #include #include #include +#include #include "ll_temac.h" diff --git a/drivers/net/ll_temac_mdio.c b/drivers/net/ll_temac_mdio.c index da0e462..5ae28c9 100644 --- a/drivers/net/ll_temac_mdio.c +++ b/drivers/net/ll_temac_mdio.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include "ll_temac.h" diff --git a/drivers/net/mac8390.c b/drivers/net/mac8390.c index a876867..c8e68fd 100644 --- a/drivers/net/mac8390.c +++ b/drivers/net/mac8390.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/mac89x0.c b/drivers/net/mac89x0.c index c292a60..c0876e9 100644 --- a/drivers/net/mac89x0.c +++ b/drivers/net/mac89x0.c @@ -88,7 +88,6 @@ static char *version = #include #include #include -#include #include #include #include @@ -98,6 +97,7 @@ static char *version = #include #include #include +#include #include #include diff --git a/drivers/net/mace.c b/drivers/net/mace.c index ab5f0bf6..962c41d 100644 --- a/drivers/net/mace.c +++ b/drivers/net/mace.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/macmace.c b/drivers/net/macmace.c index 13ba8f4..52e9a51 100644 --- a/drivers/net/macmace.c +++ b/drivers/net/macmace.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/macsonic.c b/drivers/net/macsonic.c index 24109c2..adb54fe 100644 --- a/drivers/net/macsonic.c +++ b/drivers/net/macsonic.c @@ -35,11 +35,11 @@ #include #include #include +#include #include #include #include #include -#include #include #include #include @@ -50,6 +50,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 55ceae0..abba3cc 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/mlx4/cmd.c b/drivers/net/mlx4/cmd.c index 65ec77d..23cee7b 100644 --- a/drivers/net/mlx4/cmd.c +++ b/drivers/net/mlx4/cmd.c @@ -33,6 +33,7 @@ */ #include +#include #include #include diff --git a/drivers/net/mlx4/cq.c b/drivers/net/mlx4/cq.c index ccfe276..7cd34e9 100644 --- a/drivers/net/mlx4/cq.c +++ b/drivers/net/mlx4/cq.c @@ -35,6 +35,7 @@ */ #include +#include #include #include diff --git a/drivers/net/mlx4/en_main.c b/drivers/net/mlx4/en_main.c index 507e11f..cbabf14 100644 --- a/drivers/net/mlx4/en_main.c +++ b/drivers/net/mlx4/en_main.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c index c48b0f4b..73c3d20 100644 --- a/drivers/net/mlx4/en_netdev.c +++ b/drivers/net/mlx4/en_netdev.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/mlx4/en_resources.c b/drivers/net/mlx4/en_resources.c index 1625678..0dfb4ec 100644 --- a/drivers/net/mlx4/en_resources.c +++ b/drivers/net/mlx4/en_resources.c @@ -31,6 +31,7 @@ * */ +#include #include #include diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c index 6439464..8e2fcb7 100644 --- a/drivers/net/mlx4/en_rx.c +++ b/drivers/net/mlx4/en_rx.c @@ -32,6 +32,7 @@ */ #include +#include #include #include #include diff --git a/drivers/net/mlx4/en_tx.c b/drivers/net/mlx4/en_tx.c index 3d1396a..580968f 100644 --- a/drivers/net/mlx4/en_tx.c +++ b/drivers/net/mlx4/en_tx.c @@ -33,6 +33,7 @@ #include #include +#include #include #include #include diff --git a/drivers/net/mlx4/eq.c b/drivers/net/mlx4/eq.c index bffb799..7365bf4 100644 --- a/drivers/net/mlx4/eq.c +++ b/drivers/net/mlx4/eq.c @@ -32,6 +32,7 @@ */ #include +#include #include #include diff --git a/drivers/net/mlx4/icm.c b/drivers/net/mlx4/icm.c index 04b382f..57288ca 100644 --- a/drivers/net/mlx4/icm.c +++ b/drivers/net/mlx4/icm.c @@ -34,6 +34,7 @@ #include #include #include +#include #include diff --git a/drivers/net/mlx4/intf.c b/drivers/net/mlx4/intf.c index 0e7eb10..5550678 100644 --- a/drivers/net/mlx4/intf.c +++ b/drivers/net/mlx4/intf.c @@ -31,6 +31,8 @@ * SOFTWARE. */ +#include + #include "mlx4.h" struct mlx4_device_context { diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c index b402a95..e3e0d54 100644 --- a/drivers/net/mlx4/main.c +++ b/drivers/net/mlx4/main.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/mlx4/mcg.c b/drivers/net/mlx4/mcg.c index 5ccbce9..c4f88b7 100644 --- a/drivers/net/mlx4/mcg.c +++ b/drivers/net/mlx4/mcg.c @@ -32,7 +32,6 @@ */ #include -#include #include diff --git a/drivers/net/mlx4/mr.c b/drivers/net/mlx4/mr.c index ca7ab8e..3dc69be 100644 --- a/drivers/net/mlx4/mr.c +++ b/drivers/net/mlx4/mr.c @@ -33,6 +33,7 @@ */ #include +#include #include diff --git a/drivers/net/mlx4/profile.c b/drivers/net/mlx4/profile.c index ca25b9d..5caf011 100644 --- a/drivers/net/mlx4/profile.c +++ b/drivers/net/mlx4/profile.c @@ -32,6 +32,8 @@ * SOFTWARE. */ +#include + #include "mlx4.h" #include "fw.h" diff --git a/drivers/net/mlx4/qp.c b/drivers/net/mlx4/qp.c index 42ab9fc..ec9350e 100644 --- a/drivers/net/mlx4/qp.c +++ b/drivers/net/mlx4/qp.c @@ -33,6 +33,7 @@ * SOFTWARE. */ +#include #include #include diff --git a/drivers/net/mlx4/srq.c b/drivers/net/mlx4/srq.c index 1377d0d..3b07b80 100644 --- a/drivers/net/mlx4/srq.c +++ b/drivers/net/mlx4/srq.c @@ -32,6 +32,7 @@ */ #include +#include #include "mlx4.h" #include "icm.h" diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index c97b6e4..8613a52 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -54,6 +54,7 @@ #include #include #include +#include #include static char mv643xx_eth_driver_name[] = "mv643xx_eth"; diff --git a/drivers/net/mvme147.c b/drivers/net/mvme147.c index 93c709d..3a7ad84 100644 --- a/drivers/net/mvme147.c +++ b/drivers/net/mvme147.c @@ -10,11 +10,11 @@ #include #include #include -#include #include #include #include #include +#include /* Used for the temporal inet entries and routing */ #include #include diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index e84dd3e..4718877 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -64,6 +64,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c index 8b43130..b72e749 100644 --- a/drivers/net/myri_sbus.c +++ b/drivers/net/myri_sbus.c @@ -14,7 +14,6 @@ static char version[] = #include #include #include -#include #include #include #include @@ -26,6 +25,7 @@ static char version[] = #include #include #include +#include #include #include diff --git a/drivers/net/ne2.c b/drivers/net/ne2.c index a53bb20..ff3c4c8 100644 --- a/drivers/net/ne2.c +++ b/drivers/net/ne2.c @@ -66,7 +66,6 @@ static const char *version = "ne2.c:v0.91 Nov 16 1998 Wim Dumon #include #include -#include #include #include #include diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index bf4af52..a361dea 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index a945591..b1cf46a 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -23,6 +23,7 @@ * */ +#include #include "netxen_nic.h" #include "netxen_nic_hw.h" diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 7eb925a..02876f5 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -25,6 +25,7 @@ #include #include +#include #include "netxen_nic.h" #include "netxen_nic_hw.h" diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 01808b2..ce838f7 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -23,6 +23,7 @@ * */ +#include #include #include #include "netxen_nic_hw.h" diff --git a/drivers/net/ni5010.c b/drivers/net/ni5010.c index c16cbfb..3892330 100644 --- a/drivers/net/ni5010.c +++ b/drivers/net/ni5010.c @@ -51,7 +51,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/ni52.c b/drivers/net/ni52.c index 05c29c2..f7a8f70 100644 --- a/drivers/net/ni52.c +++ b/drivers/net/ni52.c @@ -109,7 +109,6 @@ static int fifo = 0x8; /* don't change */ #include #include #include -#include #include #include #include diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 0678f31..d5cd16b 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -25,6 +25,7 @@ #include #include #include +#include #include diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c index 8dd509c..e88e97c 100644 --- a/drivers/net/ns83820.c +++ b/drivers/net/ns83820.c @@ -116,6 +116,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/octeon/octeon_mgmt.c b/drivers/net/octeon/octeon_mgmt.c index be368e5..8aadc8e 100644 --- a/drivers/net/octeon/octeon_mgmt.c +++ b/drivers/net/octeon/octeon_mgmt.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c index d44d4a2..370c147 100644 --- a/drivers/net/pasemi_mac.c +++ b/drivers/net/pasemi_mac.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index 09291e6..9f3d593 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index 1028fcb..4c0368d 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/phy/cicada.c b/drivers/net/phy/cicada.c index a1bd599..92282b3 100644 --- a/drivers/net/phy/cicada.c +++ b/drivers/net/phy/cicada.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/phy/davicom.c b/drivers/net/phy/davicom.c index d926168..c722e95 100644 --- a/drivers/net/phy/davicom.c +++ b/drivers/net/phy/davicom.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/phy/et1011c.c b/drivers/net/phy/et1011c.c index b031fa2..7712ebe 100644 --- a/drivers/net/phy/et1011c.c +++ b/drivers/net/phy/et1011c.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c index e707051..1fa4d73 100644 --- a/drivers/net/phy/fixed.c +++ b/drivers/net/phy/fixed.c @@ -20,6 +20,7 @@ #include #include #include +#include #define MII_REGS_NUM 29 diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c index af3f1f2..904208b 100644 --- a/drivers/net/phy/icplus.c +++ b/drivers/net/phy/icplus.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/phy/lxt.c b/drivers/net/phy/lxt.c index 4cf3324..057ecaa 100644 --- a/drivers/net/phy/lxt.c +++ b/drivers/net/phy/lxt.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index 65ed385..64c7fbe 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/phy/mdio-bitbang.c b/drivers/net/phy/mdio-bitbang.c index 2576055..19e70d7 100644 --- a/drivers/net/phy/mdio-bitbang.c +++ b/drivers/net/phy/mdio-bitbang.c @@ -19,7 +19,6 @@ #include #include -#include #include #include diff --git a/drivers/net/phy/mdio-octeon.c b/drivers/net/phy/mdio-octeon.c index 61a4461..a872aea 100644 --- a/drivers/net/phy/mdio-octeon.c +++ b/drivers/net/phy/mdio-octeon.c @@ -6,6 +6,7 @@ * Copyright (C) 2009 Cavium Networks */ +#include #include #include #include diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 0295097..64be466 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/phy/qsemi.c b/drivers/net/phy/qsemi.c index 23062d0..f6e190f 100644 --- a/drivers/net/phy/qsemi.c +++ b/drivers/net/phy/qsemi.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/plip.c b/drivers/net/plip.c index 3327e9f..9a2103a 100644 --- a/drivers/net/plip.c +++ b/drivers/net/plip.c @@ -94,6 +94,7 @@ static const char version[] = "NET3 PLIP version 2.4-parport gniibe@mri.co.jp\n" #include #include #include +#include #include #include #include diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c index 6a375ea..6c2e8fa 100644 --- a/drivers/net/ppp_async.c +++ b/drivers/net/ppp_async.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 6d61602..6e281bc 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c index 3a13cec..52938da 100644 --- a/drivers/net/ppp_synctty.c +++ b/drivers/net/ppp_synctty.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #define PPP_VERSION "2.4.2" diff --git a/drivers/net/pppox.c b/drivers/net/pppox.c index ac806b2..d4191ef 100644 --- a/drivers/net/pppox.c +++ b/drivers/net/pppox.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c index a849f6f..5bf229b 100644 --- a/drivers/net/ps3_gelic_net.c +++ b/drivers/net/ps3_gelic_net.c @@ -30,6 +30,7 @@ #include #include +#include #include #include diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c index 2663b2f..f0be507 100644 --- a/drivers/net/ps3_gelic_wireless.c +++ b/drivers/net/ps3_gelic_wireless.c @@ -21,6 +21,7 @@ #include #include +#include #include #include diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c index da00e16..a6ef266 100644 --- a/drivers/net/qlcnic/qlcnic_hw.c +++ b/drivers/net/qlcnic/qlcnic_hw.c @@ -24,6 +24,7 @@ #include "qlcnic.h" +#include #include #define MASK(n) ((1ULL<<(n))-1) diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index 7c34e4e..9d2c124 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c @@ -24,6 +24,7 @@ #include #include +#include #include "qlcnic.h" struct crb_addr_pair { diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index fc72156..234dab1 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -22,6 +22,7 @@ * */ +#include #include #include diff --git a/drivers/net/qlge/qlge_dbg.c b/drivers/net/qlge/qlge_dbg.c index ff8550d..3626646 100644 --- a/drivers/net/qlge/qlge_dbg.c +++ b/drivers/net/qlge/qlge_dbg.c @@ -1,3 +1,5 @@ +#include + #include "qlge.h" /* Read a NIC register from the alternate function. */ diff --git a/drivers/net/qlge/qlge_ethtool.c b/drivers/net/qlge/qlge_ethtool.c index 7dbff87..7e09ff4 100644 --- a/drivers/net/qlge/qlge_ethtool.c +++ b/drivers/net/qlge/qlge_ethtool.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 15d5373..43afdb6 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c index ede937e..07eb884 100644 --- a/drivers/net/rionet.c +++ b/drivers/net/rionet.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/rrunner.c b/drivers/net/rrunner.c index 266baf5..f2e335f 100644 --- a/drivers/net/rrunner.c +++ b/drivers/net/rrunner.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 2eb7f8a..92ae8d3 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -79,6 +79,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/sb1000.c b/drivers/net/sb1000.c index 9f83a11..abc8eef 100644 --- a/drivers/net/sb1000.c +++ b/drivers/net/sb1000.c @@ -42,7 +42,6 @@ static char version[] = "sb1000.c:v1.1.2 6/01/98 (fventuri@mediaone.net)\n"; #include #include /* for SIOGCM/SIOSCM stuff */ #include -#include #include #include #include @@ -52,6 +51,7 @@ static char version[] = "sb1000.c:v1.1.2 6/01/98 (fventuri@mediaone.net)\n"; #include #include #include +#include #include #include diff --git a/drivers/net/seeq8005.c b/drivers/net/seeq8005.c index fe806bd..374832c 100644 --- a/drivers/net/seeq8005.c +++ b/drivers/net/seeq8005.c @@ -37,7 +37,6 @@ static const char version[] = #include #include #include -#include #include #include #include diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 88f2fb1..6486657 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "net_driver.h" #include "efx.h" #include "mdio_10g.h" diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 1b8d836..d294d66 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "net_driver.h" #include "bitfield.h" #include "efx.h" diff --git a/drivers/net/sfc/mcdi_phy.c b/drivers/net/sfc/mcdi_phy.c index 34c22fa..2f23546 100644 --- a/drivers/net/sfc/mcdi_phy.c +++ b/drivers/net/sfc/mcdi_phy.c @@ -11,6 +11,7 @@ * Driver for PHY related operations via MCDI. */ +#include #include "efx.h" #include "phy.h" #include "mcdi.h" diff --git a/drivers/net/sfc/mtd.c b/drivers/net/sfc/mtd.c index 407bbad..f3ac7f3 100644 --- a/drivers/net/sfc/mtd.c +++ b/drivers/net/sfc/mtd.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #define EFX_DRIVER_NAME "sfc_mtd" diff --git a/drivers/net/sfc/qt202x_phy.c b/drivers/net/sfc/qt202x_phy.c index 1bee62c..e077bef 100644 --- a/drivers/net/sfc/qt202x_phy.c +++ b/drivers/net/sfc/qt202x_phy.c @@ -10,6 +10,7 @@ * Driver for AMCC QT202x SFP+ and XFP adapters; see www.amcc.com for details */ +#include #include #include #include "efx.h" diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c index a97c923..e308818 100644 --- a/drivers/net/sfc/rx.c +++ b/drivers/net/sfc/rx.c @@ -10,6 +10,7 @@ #include #include +#include #include #include #include diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c index cf0139a..0106b1d 100644 --- a/drivers/net/sfc/selftest.c +++ b/drivers/net/sfc/selftest.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include "net_driver.h" #include "efx.h" diff --git a/drivers/net/sfc/siena.c b/drivers/net/sfc/siena.c index 1619fb5..38dcc42 100644 --- a/drivers/net/sfc/siena.c +++ b/drivers/net/sfc/siena.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "net_driver.h" #include "bitfield.h" #include "efx.h" diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c index 10db071..f21efe7 100644 --- a/drivers/net/sfc/tenxpress.c +++ b/drivers/net/sfc/tenxpress.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "efx.h" #include "mdio_10g.h" #include "nic.h" diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c index a8b70ef..be0e110 100644 --- a/drivers/net/sfc/tx.c +++ b/drivers/net/sfc/tx.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c index ed999d3..beb537d 100644 --- a/drivers/net/sgiseeq.c +++ b/drivers/net/sgiseeq.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index 42a35f0..6242b85 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include "sh_eth.h" diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c index 760d9e8..b30ce75 100644 --- a/drivers/net/sis190.c +++ b/drivers/net/sis190.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #define PHY_MAX_ADDR 32 diff --git a/drivers/net/skfp/skfddi.c b/drivers/net/skfp/skfddi.c index 1921a54..d9016b7 100644 --- a/drivers/net/skfp/skfddi.c +++ b/drivers/net/skfp/skfddi.c @@ -78,13 +78,13 @@ static const char * const boot_msg = #include #include #include -#include #include #include #include #include #include #include +#include #include #include diff --git a/drivers/net/skge.c b/drivers/net/skge.c index d0058e5..50eb706 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include "skge.h" diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index d8ec4c1..088c797 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/slhc.c b/drivers/net/slhc.c index d640c0f..140d63f 100644 --- a/drivers/net/slhc.c +++ b/drivers/net/slhc.c @@ -51,6 +51,7 @@ */ #include +#include #include #include #include diff --git a/drivers/net/slip.c b/drivers/net/slip.c index ba5bbc5..8969615 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c @@ -83,6 +83,7 @@ #include #include #include +#include #include "slip.h" #ifdef CONFIG_INET #include diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index 9871a2b..635820d 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -59,7 +59,6 @@ static const char version[] = #include #include #include -#include #include #include #include diff --git a/drivers/net/smc9194.c b/drivers/net/smc9194.c index f9a960e..3f2f784 100644 --- a/drivers/net/smc9194.c +++ b/drivers/net/smc9194.c @@ -64,7 +64,6 @@ static const char version[] = #include #include #include -#include #include #include #include diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c index fc1b5a1..860339d 100644 --- a/drivers/net/smc91x.c +++ b/drivers/net/smc91x.c @@ -70,7 +70,6 @@ static const char version[] = #include #include #include -#include #include #include #include diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c index 4fd1d8b..cbf520d 100644 --- a/drivers/net/smsc911x.c +++ b/drivers/net/smsc911x.c @@ -41,7 +41,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/smsc9420.c b/drivers/net/smsc9420.c index 34fa10d..aafaebf 100644 --- a/drivers/net/smsc9420.c +++ b/drivers/net/smsc9420.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include "smsc9420.h" diff --git a/drivers/net/sni_82596.c b/drivers/net/sni_82596.c index 854ccf2..6b2a888 100644 --- a/drivers/net/sni_82596.c +++ b/drivers/net/sni_82596.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index 5ba9d98..dd3cb0f 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -40,7 +41,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/stmmac/dwmac100.c b/drivers/net/stmmac/dwmac100.c index 803b037..4cacca6 100644 --- a/drivers/net/stmmac/dwmac100.c +++ b/drivers/net/stmmac/dwmac100.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "common.h" #include "dwmac100.h" diff --git a/drivers/net/stmmac/dwmac1000_core.c b/drivers/net/stmmac/dwmac1000_core.c index a6538ae4..5bd95eb 100644 --- a/drivers/net/stmmac/dwmac1000_core.c +++ b/drivers/net/stmmac/dwmac1000_core.c @@ -27,6 +27,7 @@ *******************************************************************************/ #include +#include #include "dwmac1000.h" static void dwmac1000_core_init(unsigned long ioaddr) diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index a673361..a214a16 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c @@ -44,6 +44,7 @@ #include #include #include +#include #include "stmmac.h" #define STMMAC_RESOURCE_NAME "stmmaceth" diff --git a/drivers/net/stmmac/stmmac_mdio.c b/drivers/net/stmmac/stmmac_mdio.c index fffe1d0..40b2c79 100644 --- a/drivers/net/stmmac/stmmac_mdio.c +++ b/drivers/net/stmmac/stmmac_mdio.c @@ -26,6 +26,7 @@ #include #include +#include #include "stmmac.h" diff --git a/drivers/net/sun3_82586.c b/drivers/net/sun3_82586.c index 2f6a760..8b28c89 100644 --- a/drivers/net/sun3_82586.c +++ b/drivers/net/sun3_82586.c @@ -33,7 +33,6 @@ static int fifo=0x8; /* don't change */ #include #include #include -#include #include #include #include diff --git a/drivers/net/sun3lance.c b/drivers/net/sun3lance.c index 9999886..1694ca5 100644 --- a/drivers/net/sun3lance.c +++ b/drivers/net/sun3lance.c @@ -28,7 +28,6 @@ static char *version = "sun3lance.c: v1.2 1/12/2001 Sam Creasey (sammy@sammy.ne #include #include #include -#include #include #include #include diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c index a0bd361..ed7865a0 100644 --- a/drivers/net/sunbmac.c +++ b/drivers/net/sunbmac.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -25,6 +24,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c index a855934..8249a39 100644 --- a/drivers/net/sundance.c +++ b/drivers/net/sundance.c @@ -84,7 +84,6 @@ static char *media[MAX_UNITS]; #include #include #include -#include #include #include #include diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c index 70196bc..e6880f1 100644 --- a/drivers/net/sungem.c +++ b/drivers/net/sungem.c @@ -39,7 +39,6 @@ #include #include #include -#include #include #include #include @@ -58,6 +57,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c index d7c73f4..0c21653 100644 --- a/drivers/net/sunlance.c +++ b/drivers/net/sunlance.c @@ -78,7 +78,6 @@ static char lancestr[] = "LANCE"; #include #include #include -#include #include #include #include @@ -94,6 +93,7 @@ static char lancestr[] = "LANCE"; #include #include #include +#include #include #include diff --git a/drivers/net/tehuti.h b/drivers/net/tehuti.h index a19dcf8..cff98d0 100644 --- a/drivers/net/tehuti.h +++ b/drivers/net/tehuti.h @@ -32,6 +32,7 @@ #include #include #include +#include /* Compile Time Switches */ /* start */ diff --git a/drivers/net/tokenring/3c359.c b/drivers/net/tokenring/3c359.c index 0fb930f..7d7f3ee 100644 --- a/drivers/net/tokenring/3c359.c +++ b/drivers/net/tokenring/3c359.c @@ -63,6 +63,7 @@ #include #include #include +#include #include diff --git a/drivers/net/tokenring/lanstreamer.c b/drivers/net/tokenring/lanstreamer.c index dd028fe..7a5fbf5 100644 --- a/drivers/net/tokenring/lanstreamer.c +++ b/drivers/net/tokenring/lanstreamer.c @@ -121,6 +121,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/tokenring/madgemc.c b/drivers/net/tokenring/madgemc.c index 456f8bf..53f631e 100644 --- a/drivers/net/tokenring/madgemc.c +++ b/drivers/net/tokenring/madgemc.c @@ -21,6 +21,7 @@ static const char version[] = "madgemc.c: v0.91 23/01/2000 by Adam Fritzler\n"; #include #include +#include #include #include #include diff --git a/drivers/net/tokenring/smctr.c b/drivers/net/tokenring/smctr.c index 5401d86..e405601 100644 --- a/drivers/net/tokenring/smctr.c +++ b/drivers/net/tokenring/smctr.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/tokenring/tms380tr.c b/drivers/net/tokenring/tms380tr.c index ee71bcf..8b508c9 100644 --- a/drivers/net/tokenring/tms380tr.c +++ b/drivers/net/tokenring/tms380tr.c @@ -85,7 +85,6 @@ static const char version[] = "tms380tr.c: v1.10 30/12/2002 by Christoph Goos, A #include #include #include -#include #include #include #include diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c index 647cdd1..5b1fbb3 100644 --- a/drivers/net/tsi108_eth.c +++ b/drivers/net/tsi108_eth.c @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include @@ -48,6 +47,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c index cb42972..19cafc2 100644 --- a/drivers/net/tulip/de2104x.c +++ b/drivers/net/tulip/de2104x.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c index c4ecb9a..09b5719 100644 --- a/drivers/net/tulip/de4x5.c +++ b/drivers/net/tulip/de4x5.c @@ -450,7 +450,6 @@ #include #include #include -#include #include #include #include @@ -467,6 +466,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c index 95b38d8..9568156 100644 --- a/drivers/net/tulip/dmfe.c +++ b/drivers/net/tulip/dmfe.c @@ -74,7 +74,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/tulip/eeprom.c b/drivers/net/tulip/eeprom.c index 49f05d1..6002e65 100644 --- a/drivers/net/tulip/eeprom.c +++ b/drivers/net/tulip/eeprom.c @@ -13,6 +13,7 @@ */ #include +#include #include "tulip.h" #include #include diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index 7f544ef..3810db9 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c @@ -24,6 +24,7 @@ #include #include +#include #include "tulip.h" #include #include diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c index a4f09d4..a589dd3 100644 --- a/drivers/net/tulip/uli526x.c +++ b/drivers/net/tulip/uli526x.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c index 304f438..98dbf6c 100644 --- a/drivers/net/tulip/winbond-840.c +++ b/drivers/net/tulip/winbond-840.c @@ -114,7 +114,6 @@ static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1}; #include #include #include -#include #include #include #include diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index cd24e5f..98d818d 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c @@ -109,7 +109,6 @@ static const int multicast_filter_limit = 32; #include #include #include -#include #include #include #include diff --git a/drivers/net/ucc_geth_ethtool.c b/drivers/net/ucc_geth_ethtool.c index 7075f26..6f92e48 100644 --- a/drivers/net/ucc_geth_ethtool.c +++ b/drivers/net/ucc_geth_ethtool.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 9e05639..35f56fc 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c @@ -34,6 +34,7 @@ #include #include #include +#include #define DRIVER_VERSION "14-Jun-2006" static const char driver_name [] = "asix"; diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c index 96f1ebe..602e123 100644 --- a/drivers/net/usb/catc.c +++ b/drivers/net/usb/catc.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include @@ -44,6 +43,7 @@ #include #include #include +#include #include #undef DEBUG diff --git a/drivers/net/usb/cdc-phonet.c b/drivers/net/usb/cdc-phonet.c index 6491c9c..dc94445 100644 --- a/drivers/net/usb/cdc-phonet.c +++ b/drivers/net/usb/cdc-phonet.c @@ -22,6 +22,7 @@ #include #include +#include #include #include #include diff --git a/drivers/net/usb/cdc_eem.c b/drivers/net/usb/cdc_eem.c index a4a85a6..5f3b976 100644 --- a/drivers/net/usb/cdc_eem.c +++ b/drivers/net/usb/cdc_eem.c @@ -30,6 +30,7 @@ #include #include #include +#include /* diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c index 2693397..04b2810 100644 --- a/drivers/net/usb/dm9601.c +++ b/drivers/net/usb/dm9601.c @@ -21,6 +21,7 @@ #include #include #include +#include /* datasheet: http://ptm2.cc.utu.fi/ftp/network/cards/DM9601/From_NET/DM9601-DS-P01-930914.pdf diff --git a/drivers/net/usb/gl620a.c b/drivers/net/usb/gl620a.c index f7ccfad..dcd57c3 100644 --- a/drivers/net/usb/gl620a.c +++ b/drivers/net/usb/gl620a.c @@ -30,6 +30,7 @@ #include #include #include +#include /* diff --git a/drivers/net/usb/int51x1.c b/drivers/net/usb/int51x1.c index 3c228df..be02a25 100644 --- a/drivers/net/usb/int51x1.c +++ b/drivers/net/usb/int51x1.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c index 7097821..9f24e3f 100644 --- a/drivers/net/usb/mcs7830.c +++ b/drivers/net/usb/mcs7830.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/usb/net1080.c b/drivers/net/usb/net1080.c index bdcad45..961a8ed 100644 --- a/drivers/net/usb/net1080.c +++ b/drivers/net/usb/net1080.c @@ -29,6 +29,7 @@ #include #include #include +#include #include diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c index 4ce331f..dd8a4ad 100644 --- a/drivers/net/usb/rndis_host.c +++ b/drivers/net/usb/rndis_host.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c index 300e3e7..35b98b1 100644 --- a/drivers/net/usb/smsc75xx.c +++ b/drivers/net/usb/smsc75xx.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "smsc75xx.h" #define SMSC_CHIPNAME "smsc75xx" diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index 73f9a31..3135af6 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "smsc95xx.h" #define SMSC_CHIPNAME "smsc95xx" diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 17b6a62..7177abc 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -43,6 +43,7 @@ #include #include #include +#include #define DRIVER_VERSION "22-Aug-2005" diff --git a/drivers/net/veth.c b/drivers/net/veth.c index b583d49..f9f0730 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c @@ -9,6 +9,7 @@ */ #include +#include #include #include diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c index 50f881a..388751a 100644 --- a/drivers/net/via-rhine.c +++ b/drivers/net/via-rhine.c @@ -89,7 +89,6 @@ static const int multicast_filter_limit = 32; #include #include #include -#include #include #include #include diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 25dc77c..6fb783c 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -25,6 +25,7 @@ #include #include #include +#include static int napi_weight = 128; module_param(napi_weight, int, 0444); diff --git a/drivers/net/vxge/vxge-config.c b/drivers/net/vxge/vxge-config.c index 32a75fa..a21a25d 100644 --- a/drivers/net/vxge/vxge-config.c +++ b/drivers/net/vxge/vxge-config.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "vxge-traffic.h" #include "vxge-config.h" diff --git a/drivers/net/vxge/vxge-config.h b/drivers/net/vxge/vxge-config.h index e7877df..13f5416 100644 --- a/drivers/net/vxge/vxge-config.h +++ b/drivers/net/vxge/vxge-config.h @@ -14,6 +14,7 @@ #ifndef VXGE_CONFIG_H #define VXGE_CONFIG_H #include +#include #ifndef VXGE_CACHE_LINE_SIZE #define VXGE_CACHE_LINE_SIZE 128 diff --git a/drivers/net/vxge/vxge-ethtool.c b/drivers/net/vxge/vxge-ethtool.c index c6736b9..aaf374c 100644 --- a/drivers/net/vxge/vxge-ethtool.c +++ b/drivers/net/vxge/vxge-ethtool.c @@ -12,6 +12,7 @@ * Copyright(c) 2002-2009 Neterion Inc. ******************************************************************************/ #include +#include #include #include diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index 46a7c9e..ba6d0da 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -43,6 +43,7 @@ #include #include +#include #include #include #include diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c index f88c07c..a4859f7 100644 --- a/drivers/net/wan/dscc4.c +++ b/drivers/net/wan/dscc4.c @@ -89,6 +89,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c index 40d724a..e087b9a 100644 --- a/drivers/net/wan/farsync.c +++ b/drivers/net/wan/farsync.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/wan/hd64570.c b/drivers/net/wan/hd64570.c index 80114c9..4dde2ea 100644 --- a/drivers/net/wan/hd64570.c +++ b/drivers/net/wan/hd64570.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/wan/hd64572.c b/drivers/net/wan/hd64572.c index 84f0137..aad9ed4 100644 --- a/drivers/net/wan/hd64572.c +++ b/drivers/net/wan/hd64572.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c index 1ceccf1..ee7083f 100644 --- a/drivers/net/wan/hdlc_cisco.c +++ b/drivers/net/wan/hdlc_cisco.c @@ -20,7 +20,6 @@ #include #include #include -#include #undef DEBUG_HARD_HEADER diff --git a/drivers/net/wan/hdlc_raw.c b/drivers/net/wan/hdlc_raw.c index 19f51fd..5dc153e 100644 --- a/drivers/net/wan/hdlc_raw.c +++ b/drivers/net/wan/hdlc_raw.c @@ -20,7 +20,6 @@ #include #include #include -#include static int raw_ioctl(struct net_device *dev, struct ifreq *ifr); diff --git a/drivers/net/wan/hdlc_raw_eth.c b/drivers/net/wan/hdlc_raw_eth.c index 1b30fcc..05c9b0b 100644 --- a/drivers/net/wan/hdlc_raw_eth.c +++ b/drivers/net/wan/hdlc_raw_eth.c @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -21,7 +22,6 @@ #include #include #include -#include static int raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr); diff --git a/drivers/net/wan/hdlc_x25.c b/drivers/net/wan/hdlc_x25.c index 6e1ca25..c7adbb7 100644 --- a/drivers/net/wan/hdlc_x25.c +++ b/drivers/net/wan/hdlc_x25.c @@ -10,6 +10,7 @@ */ #include +#include #include #include #include @@ -21,7 +22,6 @@ #include #include #include -#include #include static int x25_ioctl(struct net_device *dev, struct ifreq *ifr); diff --git a/drivers/net/wan/hostess_sv11.c b/drivers/net/wan/hostess_sv11.c index 74164d2..48edc5f 100644 --- a/drivers/net/wan/hostess_sv11.c +++ b/drivers/net/wan/hostess_sv11.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/wan/ixp4xx_hss.c b/drivers/net/wan/ixp4xx_hss.c index c705046..0c2cdde 100644 --- a/drivers/net/wan/ixp4xx_hss.c +++ b/drivers/net/wan/ixp4xx_hss.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c index d1e3c67..98e2f99 100644 --- a/drivers/net/wan/lapbether.c +++ b/drivers/net/wan/lapbether.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/wan/lmc/lmc_media.c b/drivers/net/wan/lmc/lmc_media.c index f327674..5920c99 100644 --- a/drivers/net/wan/lmc/lmc_media.c +++ b/drivers/net/wan/lmc/lmc_media.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/wan/lmc/lmc_proto.c b/drivers/net/wan/lmc/lmc_proto.c index 044a481..f600075 100644 --- a/drivers/net/wan/lmc/lmc_proto.c +++ b/drivers/net/wan/lmc/lmc_proto.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c index f4f1c00..3f744c6 100644 --- a/drivers/net/wan/pc300_drv.c +++ b/drivers/net/wan/pc300_drv.c @@ -228,6 +228,7 @@ static char rcsid[] = #include #include #include +#include #include #include diff --git a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c index 25477b5..cff13a9 100644 --- a/drivers/net/wan/sbni.c +++ b/drivers/net/wan/sbni.c @@ -43,7 +43,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/wan/sealevel.c b/drivers/net/wan/sealevel.c index 61249f4..e91457d 100644 --- a/drivers/net/wan/sealevel.c +++ b/drivers/net/wan/sealevel.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c index b9f520b..80d5c58 100644 --- a/drivers/net/wan/x25_asy.c +++ b/drivers/net/wan/x25_asy.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "x25_asy.h" #include diff --git a/drivers/net/wan/z85230.c b/drivers/net/wan/z85230.c index 0be7ec7..fbf5e84 100644 --- a/drivers/net/wan/z85230.c +++ b/drivers/net/wan/z85230.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #define RT_LOCK diff --git a/drivers/net/wimax/i2400m/control.c b/drivers/net/wimax/i2400m/control.c index 9449455..6180772 100644 --- a/drivers/net/wimax/i2400m/control.c +++ b/drivers/net/wimax/i2400m/control.c @@ -76,6 +76,7 @@ #include #include "i2400m.h" #include +#include #include diff --git a/drivers/net/wimax/i2400m/driver.c b/drivers/net/wimax/i2400m/driver.c index 6cead32..94dc83c 100644 --- a/drivers/net/wimax/i2400m/driver.c +++ b/drivers/net/wimax/i2400m/driver.c @@ -69,6 +69,7 @@ #include #include #include +#include #define D_SUBMODULE driver #include "debug-levels.h" diff --git a/drivers/net/wimax/i2400m/fw.c b/drivers/net/wimax/i2400m/fw.c index 25c24f0..3f283bf 100644 --- a/drivers/net/wimax/i2400m/fw.c +++ b/drivers/net/wimax/i2400m/fw.c @@ -156,6 +156,7 @@ */ #include #include +#include #include #include "i2400m.h" diff --git a/drivers/net/wimax/i2400m/netdev.c b/drivers/net/wimax/i2400m/netdev.c index 599aa4e..b811c2f 100644 --- a/drivers/net/wimax/i2400m/netdev.c +++ b/drivers/net/wimax/i2400m/netdev.c @@ -73,6 +73,7 @@ * alloc_netdev. */ #include +#include #include #include #include "i2400m.h" diff --git a/drivers/net/wimax/i2400m/op-rfkill.c b/drivers/net/wimax/i2400m/op-rfkill.c index 43927b5..035e4cf 100644 --- a/drivers/net/wimax/i2400m/op-rfkill.c +++ b/drivers/net/wimax/i2400m/op-rfkill.c @@ -34,6 +34,7 @@ */ #include "i2400m.h" #include +#include diff --git a/drivers/net/wimax/i2400m/rx.c b/drivers/net/wimax/i2400m/rx.c index 7ddb173..fa2e11e 100644 --- a/drivers/net/wimax/i2400m/rx.c +++ b/drivers/net/wimax/i2400m/rx.c @@ -144,6 +144,7 @@ * i2400m_msg_size_check * wimax_msg */ +#include #include #include #include diff --git a/drivers/net/wimax/i2400m/sdio-rx.c b/drivers/net/wimax/i2400m/sdio-rx.c index 8adf6c9..d619da3 100644 --- a/drivers/net/wimax/i2400m/sdio-rx.c +++ b/drivers/net/wimax/i2400m/sdio-rx.c @@ -65,6 +65,7 @@ #include #include #include +#include #include "i2400m-sdio.h" #define D_SUBMODULE rx diff --git a/drivers/net/wimax/i2400m/sdio.c b/drivers/net/wimax/i2400m/sdio.c index 14f876b..7632f80 100644 --- a/drivers/net/wimax/i2400m/sdio.c +++ b/drivers/net/wimax/i2400m/sdio.c @@ -48,6 +48,7 @@ * __i2400ms_send_barker() */ +#include #include #include #include diff --git a/drivers/net/wimax/i2400m/tx.c b/drivers/net/wimax/i2400m/tx.c index 54480e8..b0cb906 100644 --- a/drivers/net/wimax/i2400m/tx.c +++ b/drivers/net/wimax/i2400m/tx.c @@ -244,6 +244,7 @@ * (FIFO empty). */ #include +#include #include "i2400m.h" diff --git a/drivers/net/wimax/i2400m/usb-fw.c b/drivers/net/wimax/i2400m/usb-fw.c index ce6b993..b58ec56 100644 --- a/drivers/net/wimax/i2400m/usb-fw.c +++ b/drivers/net/wimax/i2400m/usb-fw.c @@ -73,6 +73,7 @@ * i2400m_notif_submit */ #include +#include #include "i2400m-usb.h" diff --git a/drivers/net/wimax/i2400m/usb-notif.c b/drivers/net/wimax/i2400m/usb-notif.c index f88d1c6..7b6a1d9 100644 --- a/drivers/net/wimax/i2400m/usb-notif.c +++ b/drivers/net/wimax/i2400m/usb-notif.c @@ -56,6 +56,7 @@ * i2400mu_rx_kick() */ #include +#include #include "i2400m-usb.h" diff --git a/drivers/net/wimax/i2400m/usb-rx.c b/drivers/net/wimax/i2400m/usb-rx.c index ba1b023..a26483a 100644 --- a/drivers/net/wimax/i2400m/usb-rx.c +++ b/drivers/net/wimax/i2400m/usb-rx.c @@ -83,6 +83,7 @@ * i2400mu_rx_release() called from i2400mu_bus_dev_stop() */ #include +#include #include #include "i2400m-usb.h" diff --git a/drivers/net/wimax/i2400m/usb.c b/drivers/net/wimax/i2400m/usb.c index 99f04c4..d8c4d64 100644 --- a/drivers/net/wimax/i2400m/usb.c +++ b/drivers/net/wimax/i2400m/usb.c @@ -66,6 +66,7 @@ #include "i2400m-usb.h" #include #include +#include #define D_SUBMODULE usb diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c index 547912e6..ab61d2b 100644 --- a/drivers/net/wireless/adm8211.c +++ b/drivers/net/wireless/adm8211.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c index 257c734..c536929 100644 --- a/drivers/net/wireless/ath/ar9170/main.c +++ b/drivers/net/wireless/ath/ar9170/main.c @@ -38,6 +38,7 @@ */ #include +#include #include #include #include diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c index 4e30197..0b0d2dc 100644 --- a/drivers/net/wireless/ath/ar9170/usb.c +++ b/drivers/net/wireless/ath/ar9170/usb.c @@ -38,6 +38,7 @@ */ #include +#include #include #include #include diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index 4228444..dc0786c 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c @@ -21,6 +21,7 @@ \*************************************/ #include +#include #include "ath5k.h" #include "reg.h" #include "debug.h" diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 8dce007..3abbe75 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -50,6 +50,7 @@ #include #include #include +#include #include diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index 10b5226..67665cd 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c @@ -21,6 +21,8 @@ * EEPROM access functions and helpers * \*************************************/ +#include + #include "ath5k.h" #include "reg.h" #include "debug.h" diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index eff3323..68e2bcc 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -23,6 +23,7 @@ #define _ATH5K_PHY #include +#include #include "ath5k.h" #include "reg.h" diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 42d2a50..081e008 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -14,6 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include #include "ath9k.h" diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 2e767cf..78b5711 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -15,6 +15,7 @@ */ #include +#include #include #include "hw.h" diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 623c2f8..3d4d897 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -14,6 +14,8 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include + #include "ath9k.h" static char *dev_info = "ath9k"; diff --git a/drivers/net/wireless/ath/ath9k/phy.c b/drivers/net/wireless/ath/ath9k/phy.c index c3b5939..2547b3c 100644 --- a/drivers/net/wireless/ath/ath9k/phy.c +++ b/drivers/net/wireless/ath/ath9k/phy.c @@ -39,6 +39,8 @@ * AR9287 - 11n single-band 1x1 MIMO for USB */ +#include + #include "hw.h" /** diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index 0e79e58..244e1c6 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -15,6 +15,8 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include + #include "ath9k.h" static const struct ath_rate_table ar5416_11na_ratetable = { diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c index a43fbf8..00c0e21 100644 --- a/drivers/net/wireless/ath/ath9k/virtual.c +++ b/drivers/net/wireless/ath/ath9k/virtual.c @@ -14,6 +14,8 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include + #include "ath9k.h" struct ath9k_vif_iter_data { diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c index 04abd1f..00489c4 100644 --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c @@ -15,7 +15,6 @@ */ #include -#include #include #include #include "regd.h" diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index be7abf8..fa40fdf 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c @@ -38,6 +38,7 @@ #include #include #include +#include #include diff --git a/drivers/net/wireless/b43/lo.c b/drivers/net/wireless/b43/lo.c index 976104f..94e4f13 100644 --- a/drivers/net/wireless/b43/lo.c +++ b/drivers/net/wireless/b43/lo.c @@ -34,6 +34,7 @@ #include #include +#include static struct b43_lo_calib *b43_find_lo_calib(struct b43_txpower_lo_control *lo, diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 1521b1e..9a374ef 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include "b43.h" diff --git a/drivers/net/wireless/b43/pcmcia.c b/drivers/net/wireless/b43/pcmcia.c index 984174b..609e705 100644 --- a/drivers/net/wireless/b43/pcmcia.c +++ b/drivers/net/wireless/b43/pcmcia.c @@ -24,6 +24,7 @@ #include "pcmcia.h" #include +#include #include #include diff --git a/drivers/net/wireless/b43/phy_a.c b/drivers/net/wireless/b43/phy_a.c index d90217c..b6428ec 100644 --- a/drivers/net/wireless/b43/phy_a.c +++ b/drivers/net/wireless/b43/phy_a.c @@ -26,6 +26,8 @@ */ +#include + #include "b43.h" #include "phy_a.h" #include "phy_common.h" diff --git a/drivers/net/wireless/b43/phy_g.c b/drivers/net/wireless/b43/phy_g.c index 382826a..29bf34c 100644 --- a/drivers/net/wireless/b43/phy_g.c +++ b/drivers/net/wireless/b43/phy_g.c @@ -33,6 +33,7 @@ #include "main.h" #include +#include static const s8 b43_tssi2dbm_g_table[] = { diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c index 185219e..c6afe9d 100644 --- a/drivers/net/wireless/b43/phy_lp.c +++ b/drivers/net/wireless/b43/phy_lp.c @@ -23,6 +23,8 @@ */ +#include + #include "b43.h" #include "main.h" #include "phy_lp.h" diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 795bb1e..9c7cd28 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -23,6 +23,7 @@ */ #include +#include #include #include "b43.h" diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c index a6062c3..aa12273 100644 --- a/drivers/net/wireless/b43/pio.c +++ b/drivers/net/wireless/b43/pio.c @@ -31,6 +31,7 @@ #include #include +#include static u16 generate_cookie(struct b43_pio_txqueue *q, diff --git a/drivers/net/wireless/b43/sdio.c b/drivers/net/wireless/b43/sdio.c index 0d3ac64..4e56b7b 100644 --- a/drivers/net/wireless/b43/sdio.c +++ b/drivers/net/wireless/b43/sdio.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include "sdio.h" diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c index 8b9387c..e91520d 100644 --- a/drivers/net/wireless/b43legacy/dma.c +++ b/drivers/net/wireless/b43legacy/dma.c @@ -37,6 +37,7 @@ #include #include #include +#include #include /* 32bit DMA ops. */ diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 1d070be..bb2dd93 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/wireless/b43legacy/phy.c b/drivers/net/wireless/b43legacy/phy.c index aaf2272..35033dd 100644 --- a/drivers/net/wireless/b43legacy/phy.c +++ b/drivers/net/wireless/b43legacy/phy.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include "b43legacy.h" diff --git a/drivers/net/wireless/b43legacy/pio.c b/drivers/net/wireless/b43legacy/pio.c index 017c0e9..b033b0e 100644 --- a/drivers/net/wireless/b43legacy/pio.c +++ b/drivers/net/wireless/b43legacy/pio.c @@ -29,6 +29,7 @@ #include "xmit.h" #include +#include static void tx_start(struct b43legacy_pioqueue *queue) diff --git a/drivers/net/wireless/hostap/hostap_80211_rx.c b/drivers/net/wireless/hostap/hostap_80211_rx.c index 3816df9..f4c5612 100644 --- a/drivers/net/wireless/hostap/hostap_80211_rx.c +++ b/drivers/net/wireless/hostap/hostap_80211_rx.c @@ -1,4 +1,5 @@ #include +#include #include #include diff --git a/drivers/net/wireless/hostap/hostap_80211_tx.c b/drivers/net/wireless/hostap/hostap_80211_tx.c index 90108b6..c34a3b7 100644 --- a/drivers/net/wireless/hostap/hostap_80211_tx.c +++ b/drivers/net/wireless/hostap/hostap_80211_tx.c @@ -1,3 +1,5 @@ +#include + #include "hostap_80211.h" #include "hostap_common.h" #include "hostap_wlan.h" diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c index a2a203c..7e72ac1 100644 --- a/drivers/net/wireless/hostap/hostap_ap.c +++ b/drivers/net/wireless/hostap/hostap_ap.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "hostap_wlan.h" #include "hostap.h" diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c index d19748d..a36501d 100644 --- a/drivers/net/wireless/hostap/hostap_cs.c +++ b/drivers/net/wireless/hostap/hostap_cs.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/wireless/hostap/hostap_info.c b/drivers/net/wireless/hostap/hostap_info.c index 4dfb40a..d737091 100644 --- a/drivers/net/wireless/hostap/hostap_info.c +++ b/drivers/net/wireless/hostap/hostap_info.c @@ -2,6 +2,7 @@ #include #include +#include #include "hostap_wlan.h" #include "hostap.h" #include "hostap_ap.h" diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c index 9419ceb..9a08230 100644 --- a/drivers/net/wireless/hostap/hostap_ioctl.c +++ b/drivers/net/wireless/hostap/hostap_ioctl.c @@ -1,5 +1,6 @@ /* ioctl() (mostly Linux Wireless Extensions) routines for Host AP driver */ +#include #include #include #include diff --git a/drivers/net/wireless/hostap/hostap_pci.c b/drivers/net/wireless/hostap/hostap_pci.c index 4d97ae3..d24dc7d 100644 --- a/drivers/net/wireless/hostap/hostap_pci.c +++ b/drivers/net/wireless/hostap/hostap_pci.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/wireless/hostap/hostap_plx.c b/drivers/net/wireless/hostap/hostap_plx.c index fc04ccd..33e7903 100644 --- a/drivers/net/wireless/hostap/hostap_plx.c +++ b/drivers/net/wireless/hostap/hostap_plx.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index 5c7aa1b..8d72e3d 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c @@ -31,6 +31,7 @@ ******************************************************************************/ #include +#include #include "ipw2200.h" diff --git a/drivers/net/wireless/ipw2x00/libipw_geo.c b/drivers/net/wireless/ipw2x00/libipw_geo.c index 65e8c17..c9fe3c9 100644 --- a/drivers/net/wireless/ipw2x00/libipw_geo.c +++ b/drivers/net/wireless/ipw2x00/libipw_geo.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/wireless/ipw2x00/libipw_rx.c b/drivers/net/wireless/ipw2x00/libipw_rx.c index 282b1f7..39a34da 100644 --- a/drivers/net/wireless/ipw2x00/libipw_rx.c +++ b/drivers/net/wireless/ipw2x00/libipw_rx.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -24,7 +25,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/wireless/ipw2x00/libipw_wx.c b/drivers/net/wireless/ipw2x00/libipw_wx.c index 4d89f66..3633c66 100644 --- a/drivers/net/wireless/ipw2x00/libipw_wx.c +++ b/drivers/net/wireless/ipw2x00/libipw_wx.c @@ -31,6 +31,7 @@ ******************************************************************************/ #include +#include #include #include diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c index 47909f9..902c4d4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index e0678d9..0728054 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 8bf7c20..35f819a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 818367b..5e0c6bf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c index 845831a..de3b3f4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-calib.c @@ -60,6 +60,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ +#include #include #include "iwl-dev.h" diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 112149e..db050b8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include "iwl-eeprom.h" diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 7bf44f1..b6e1b0e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -26,6 +26,7 @@ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 *****************************************************************************/ +#include #include #include #include diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index fd37152..fb5bb48 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -63,6 +63,7 @@ #include #include +#include #include #include diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 1a1a9f0..548dac2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -29,6 +29,7 @@ #include #include +#include #include #include diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index df257bc..e5eb339 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -28,6 +28,7 @@ *****************************************************************************/ #include +#include #include #include #include "iwl-eeprom.h" diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index bd2f7c4..9ab0e41 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -25,6 +25,7 @@ * Intel Linux Wireless * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 *****************************************************************************/ +#include #include #include #include diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 8c12311..f0b7e6c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -29,6 +29,7 @@ #include #include +#include #include #include "iwl-eeprom.h" #include "iwl-dev.h" diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 54daa38..1eaa005 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c index 7c4f44a..a1d45cc 100644 --- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c +++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include "iwm.h" diff --git a/drivers/net/wireless/iwmc3200wifi/commands.c b/drivers/net/wireless/iwmc3200wifi/commands.c index 1e41ad0..42df726 100644 --- a/drivers/net/wireless/iwmc3200wifi/commands.c +++ b/drivers/net/wireless/iwmc3200wifi/commands.c @@ -41,6 +41,7 @@ #include #include #include +#include #include "iwm.h" #include "bus.h" diff --git a/drivers/net/wireless/iwmc3200wifi/debugfs.c b/drivers/net/wireless/iwmc3200wifi/debugfs.c index c29c994..cbb81be 100644 --- a/drivers/net/wireless/iwmc3200wifi/debugfs.c +++ b/drivers/net/wireless/iwmc3200wifi/debugfs.c @@ -21,6 +21,7 @@ * */ +#include #include #include #include diff --git a/drivers/net/wireless/iwmc3200wifi/eeprom.c b/drivers/net/wireless/iwmc3200wifi/eeprom.c index 8091421..e80e776 100644 --- a/drivers/net/wireless/iwmc3200wifi/eeprom.c +++ b/drivers/net/wireless/iwmc3200wifi/eeprom.c @@ -37,6 +37,7 @@ */ #include +#include #include "iwm.h" #include "umac.h" diff --git a/drivers/net/wireless/iwmc3200wifi/hal.c b/drivers/net/wireless/iwmc3200wifi/hal.c index d13c885..229de99 100644 --- a/drivers/net/wireless/iwmc3200wifi/hal.c +++ b/drivers/net/wireless/iwmc3200wifi/hal.c @@ -98,6 +98,7 @@ */ #include #include +#include #include "iwm.h" #include "bus.h" diff --git a/drivers/net/wireless/iwmc3200wifi/main.c b/drivers/net/wireless/iwmc3200wifi/main.c index 7f34d6d..23856d3 100644 --- a/drivers/net/wireless/iwmc3200wifi/main.c +++ b/drivers/net/wireless/iwmc3200wifi/main.c @@ -41,6 +41,7 @@ #include #include #include +#include #include "iwm.h" #include "debug.h" diff --git a/drivers/net/wireless/iwmc3200wifi/netdev.c b/drivers/net/wireless/iwmc3200wifi/netdev.c index c4c0d23..13a69eb 100644 --- a/drivers/net/wireless/iwmc3200wifi/netdev.c +++ b/drivers/net/wireless/iwmc3200wifi/netdev.c @@ -46,6 +46,7 @@ * -> sdio_disable_func() */ #include +#include #include "iwm.h" #include "commands.h" diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c index 8456b4d..3257d4f 100644 --- a/drivers/net/wireless/iwmc3200wifi/rx.c +++ b/drivers/net/wireless/iwmc3200wifi/rx.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include "iwm.h" diff --git a/drivers/net/wireless/iwmc3200wifi/sdio.c b/drivers/net/wireless/iwmc3200wifi/sdio.c index a7ec7ea..1eafd6d 100644 --- a/drivers/net/wireless/iwmc3200wifi/sdio.c +++ b/drivers/net/wireless/iwmc3200wifi/sdio.c @@ -63,6 +63,7 @@ */ #include +#include #include #include #include diff --git a/drivers/net/wireless/iwmc3200wifi/tx.c b/drivers/net/wireless/iwmc3200wifi/tx.c index 55905f0..f6a02f1 100644 --- a/drivers/net/wireless/iwmc3200wifi/tx.c +++ b/drivers/net/wireless/iwmc3200wifi/tx.c @@ -64,6 +64,7 @@ * (i.e. half of the max size). [iwm_tx_worker] */ +#include #include #include #include diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c index f03d5e4..12a2ef9 100644 --- a/drivers/net/wireless/libertas/assoc.c +++ b/drivers/net/wireless/libertas/assoc.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include "assoc.h" diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 4396dcc..e196b84 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c @@ -6,6 +6,7 @@ * */ +#include #include #include "cfg.h" diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index 82371ef..cdb9b96 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c @@ -5,6 +5,7 @@ #include #include +#include #include "host.h" #include "decl.h" diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c index e747044..88f7131 100644 --- a/drivers/net/wireless/libertas/cmdresp.c +++ b/drivers/net/wireless/libertas/cmdresp.c @@ -2,6 +2,7 @@ * This file contains the handling of command * responses as well as events generated by firmware. */ +#include #include #include #include diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c index 587b0cb..a48ccaf 100644 --- a/drivers/net/wireless/libertas/debugfs.c +++ b/drivers/net/wireless/libertas/debugfs.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c index 1f6cb58..6d55439 100644 --- a/drivers/net/wireless/libertas/if_cs.c +++ b/drivers/net/wireless/libertas/if_cs.c @@ -22,6 +22,7 @@ */ #include +#include #include #include #include diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index 7a73f62..7d1a3c6 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c index 3ea03f2..fe3f080 100644 --- a/drivers/net/wireless/libertas/if_spi.c +++ b/drivers/net/wireless/libertas/if_spi.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c index 65e1745..fcea574 100644 --- a/drivers/net/wireless/libertas/if_usb.c +++ b/drivers/net/wireless/libertas/if_usb.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #ifdef CONFIG_OLPC diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 28a1c9d..5980804 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c index 2daf8ff..784dae7 100644 --- a/drivers/net/wireless/libertas/rx.c +++ b/drivers/net/wireless/libertas/rx.c @@ -2,6 +2,7 @@ * This file contains the handling of RX in wlan driver. */ #include +#include #include #include "host.h" diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c index 220361e..24cd54b 100644 --- a/drivers/net/wireless/libertas/scan.c +++ b/drivers/net/wireless/libertas/scan.c @@ -4,6 +4,7 @@ * IOCTL handlers as well as command preperation and response routines * for sending scan commands to the firmware. */ +#include #include #include #include diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c index 71f88a0..9b55588 100644 --- a/drivers/net/wireless/libertas/wext.c +++ b/drivers/net/wireless/libertas/wext.c @@ -2,6 +2,7 @@ * This file contains ioctl functions */ #include +#include #include #include #include diff --git a/drivers/net/wireless/libertas_tf/cmd.c b/drivers/net/wireless/libertas_tf/cmd.c index 28790e0..b620daf 100644 --- a/drivers/net/wireless/libertas_tf/cmd.c +++ b/drivers/net/wireless/libertas_tf/cmd.c @@ -7,6 +7,8 @@ * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. */ +#include + #include "libertas_tf.h" static const struct channel_range channel_ranges[] = { diff --git a/drivers/net/wireless/libertas_tf/if_usb.c b/drivers/net/wireless/libertas_tf/if_usb.c index 3691c30..8cc9db6 100644 --- a/drivers/net/wireless/libertas_tf/if_usb.c +++ b/drivers/net/wireless/libertas_tf/if_usb.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #define DRV_NAME "lbtf_usb" diff --git a/drivers/net/wireless/libertas_tf/main.c b/drivers/net/wireless/libertas_tf/main.c index 6ab3003..7945ff5 100644 --- a/drivers/net/wireless/libertas_tf/main.c +++ b/drivers/net/wireless/libertas_tf/main.c @@ -7,6 +7,8 @@ * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. */ +#include + #include "libertas_tf.h" #include "linux/etherdevice.h" diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 6ea77e9..7cd5f56 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -14,6 +14,7 @@ */ #include +#include #include #include #include diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index ac65e13..89354c2 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/wireless/orinoco/fw.c b/drivers/net/wireless/orinoco/fw.c index cfa7296..5ea0f7c 100644 --- a/drivers/net/wireless/orinoco/fw.c +++ b/drivers/net/wireless/orinoco/fw.c @@ -3,6 +3,7 @@ * See copyright notice in main.c */ #include +#include #include #include diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c index b42634c..413e9ab 100644 --- a/drivers/net/wireless/orinoco/main.c +++ b/drivers/net/wireless/orinoco/main.c @@ -78,6 +78,7 @@ #include #include +#include #include #include #include diff --git a/drivers/net/wireless/orinoco/scan.c b/drivers/net/wireless/orinoco/scan.c index d2f10e9..330d42d 100644 --- a/drivers/net/wireless/orinoco/scan.c +++ b/drivers/net/wireless/orinoco/scan.c @@ -3,6 +3,7 @@ * See copyright notice in main.c */ +#include #include #include #include diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c index 31ca241..fbcc6e1 100644 --- a/drivers/net/wireless/orinoco/wext.c +++ b/drivers/net/wireless/orinoco/wext.c @@ -2,6 +2,7 @@ * * See copyright notice in main.c */ +#include #include #include #include diff --git a/drivers/net/wireless/p54/eeprom.c b/drivers/net/wireless/p54/eeprom.c index 8e3818f..187e263 100644 --- a/drivers/net/wireless/p54/eeprom.c +++ b/drivers/net/wireless/p54/eeprom.c @@ -20,6 +20,7 @@ #include #include #include +#include #include diff --git a/drivers/net/wireless/p54/fwio.c b/drivers/net/wireless/p54/fwio.c index e7b9e9c..c43a5d4 100644 --- a/drivers/net/wireless/p54/fwio.c +++ b/drivers/net/wireless/p54/fwio.c @@ -17,6 +17,7 @@ */ #include +#include #include #include diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c index 4f752a2..a7cb9eb 100644 --- a/drivers/net/wireless/p54/main.c +++ b/drivers/net/wireless/p54/main.c @@ -17,6 +17,7 @@ */ #include +#include #include #include diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c index ed4bdff..269fda3 100644 --- a/drivers/net/wireless/p54/p54pci.c +++ b/drivers/net/wireless/p54/p54pci.c @@ -15,6 +15,7 @@ #include #include +#include #include #include #include diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c index afd26bf..c8f09da 100644 --- a/drivers/net/wireless/p54/p54spi.c +++ b/drivers/net/wireless/p54/p54spi.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "p54spi.h" #include "p54spi_eeprom.h" diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index b3c4fbd..762952d 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c index f7f5c79..a45818e 100644 --- a/drivers/net/wireless/prism54/isl_ioctl.c +++ b/drivers/net/wireless/prism54/isl_ioctl.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c index a3ba353..689d59a 100644 --- a/drivers/net/wireless/prism54/islpci_dev.c +++ b/drivers/net/wireless/prism54/islpci_dev.c @@ -19,6 +19,7 @@ */ #include +#include #include #include diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c index 872b647..ac99eaa 100644 --- a/drivers/net/wireless/prism54/islpci_eth.c +++ b/drivers/net/wireless/prism54/islpci_eth.c @@ -17,6 +17,7 @@ */ #include +#include #include #include diff --git a/drivers/net/wireless/prism54/islpci_mgt.c b/drivers/net/wireless/prism54/islpci_mgt.c index 69d2f88..adb2897 100644 --- a/drivers/net/wireless/prism54/islpci_mgt.c +++ b/drivers/net/wireless/prism54/islpci_mgt.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/wireless/prism54/islpci_mgt.h b/drivers/net/wireless/prism54/islpci_mgt.h index 87a1734..0b27e50 100644 --- a/drivers/net/wireless/prism54/islpci_mgt.h +++ b/drivers/net/wireless/prism54/islpci_mgt.h @@ -22,6 +22,7 @@ #include #include +#include /* * Function definitions diff --git a/drivers/net/wireless/prism54/oid_mgt.c b/drivers/net/wireless/prism54/oid_mgt.c index 1187e61..d66933d 100644 --- a/drivers/net/wireless/prism54/oid_mgt.c +++ b/drivers/net/wireless/prism54/oid_mgt.c @@ -17,6 +17,7 @@ */ #include +#include #include "prismcompat.h" #include "islpci_dev.h" diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index 84c530a..11865ea 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 2887047..1de5b22 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index c22b040..5f5204b 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "rt2x00.h" #include "rt2x00pci.h" diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 52bbcf1..2a73f59 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "rt2x00.h" #include "rt2x00pci.h" diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 9b04964..d2cc445 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include "rt2x00.h" diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 18d4d8e..58c7f21 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -35,6 +35,7 @@ #include #include +#include #include "rt2x00.h" #if defined(CONFIG_RT2X00_LIB_USB) || defined(CONFIG_RT2X00_LIB_USB_MODULE) diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c index 28a1c46..9569fb4 100644 --- a/drivers/net/wireless/rt2x00/rt2x00debug.c +++ b/drivers/net/wireless/rt2x00/rt2x00debug.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include "rt2x00.h" diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index dd5ab8f..eda73ba 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -25,6 +25,7 @@ #include #include +#include #include "rt2x00.h" #include "rt2x00lib.h" diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index 047123b..cf3f1c0 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "rt2x00.h" #include "rt2x00pci.h" diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 5b6b789..a0bd36f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -24,6 +24,7 @@ Abstract: rt2x00 queue specific routines. */ +#include #include #include #include diff --git a/drivers/net/wireless/rt2x00/rt2x00soc.c b/drivers/net/wireless/rt2x00/rt2x00soc.c index 111c0ff..fc98063 100644 --- a/drivers/net/wireless/rt2x00/rt2x00soc.c +++ b/drivers/net/wireless/rt2x00/rt2x00soc.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "rt2x00.h" #include "rt2x00soc.h" diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 0a751e7..f9a7f8b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -25,6 +25,7 @@ #include #include +#include #include #include diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 1774727..432e75f 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 290d70b..bb58d79 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include "rt2x00.h" diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c index 2b928ec..2131a44 100644 --- a/drivers/net/wireless/rtl818x/rtl8180_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c index 0fb850e..1d30792 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c @@ -22,6 +22,7 @@ #include #include +#include #include #include #include diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.c b/drivers/net/wireless/wl12xx/wl1251_acx.c index beff084..91891f9 100644 --- a/drivers/net/wireless/wl12xx/wl1251_acx.c +++ b/drivers/net/wireless/wl12xx/wl1251_acx.c @@ -1,6 +1,7 @@ #include "wl1251_acx.h" #include +#include #include #include "wl1251.h" diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.c b/drivers/net/wireless/wl12xx/wl1251_boot.c index 28a8086..d5ac79a 100644 --- a/drivers/net/wireless/wl12xx/wl1251_boot.c +++ b/drivers/net/wireless/wl12xx/wl1251_boot.c @@ -22,6 +22,7 @@ */ #include +#include #include "wl1251_reg.h" #include "wl1251_boot.h" diff --git a/drivers/net/wireless/wl12xx/wl1251_cmd.c b/drivers/net/wireless/wl12xx/wl1251_cmd.c index 0320b47..a37b30c 100644 --- a/drivers/net/wireless/wl12xx/wl1251_cmd.c +++ b/drivers/net/wireless/wl12xx/wl1251_cmd.c @@ -1,6 +1,7 @@ #include "wl1251_cmd.h" #include +#include #include #include "wl1251.h" diff --git a/drivers/net/wireless/wl12xx/wl1251_debugfs.c b/drivers/net/wireless/wl12xx/wl1251_debugfs.c index 05e4d68..5e4465a 100644 --- a/drivers/net/wireless/wl12xx/wl1251_debugfs.c +++ b/drivers/net/wireless/wl12xx/wl1251_debugfs.c @@ -24,6 +24,7 @@ #include "wl1251_debugfs.h" #include +#include #include "wl1251.h" #include "wl1251_acx.h" diff --git a/drivers/net/wireless/wl12xx/wl1251_init.c b/drivers/net/wireless/wl12xx/wl1251_init.c index 5aad56e..b538bdd 100644 --- a/drivers/net/wireless/wl12xx/wl1251_init.c +++ b/drivers/net/wireless/wl12xx/wl1251_init.c @@ -23,6 +23,7 @@ #include #include +#include #include "wl1251_init.h" #include "wl12xx_80211.h" diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c index 24ae6a3..1c8226e 100644 --- a/drivers/net/wireless/wl12xx/wl1251_main.c +++ b/drivers/net/wireless/wl12xx/wl1251_main.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "wl1251.h" #include "wl12xx_80211.h" diff --git a/drivers/net/wireless/wl12xx/wl1251_rx.c b/drivers/net/wireless/wl12xx/wl1251_rx.c index b567322..6f229e0 100644 --- a/drivers/net/wireless/wl12xx/wl1251_rx.c +++ b/drivers/net/wireless/wl12xx/wl1251_rx.c @@ -23,6 +23,7 @@ */ #include +#include #include #include "wl1251.h" diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.c b/drivers/net/wireless/wl12xx/wl1251_spi.c index 9cc8c32..3bfb59b 100644 --- a/drivers/net/wireless/wl12xx/wl1251_spi.c +++ b/drivers/net/wireless/wl12xx/wl1251_spi.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.c b/drivers/net/wireless/wl12xx/wl1271_acx.c index 60f10dc..3087824 100644 --- a/drivers/net/wireless/wl12xx/wl1271_acx.c +++ b/drivers/net/wireless/wl12xx/wl1271_acx.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "wl1271.h" #include "wl12xx_80211.h" diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/wl1271_boot.c index 2be76ee..0243562 100644 --- a/drivers/net/wireless/wl12xx/wl1271_boot.c +++ b/drivers/net/wireless/wl12xx/wl1271_boot.c @@ -22,6 +22,7 @@ */ #include +#include #include "wl1271_acx.h" #include "wl1271_reg.h" diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c index 36a64e0..e7832f3 100644 --- a/drivers/net/wireless/wl12xx/wl1271_cmd.c +++ b/drivers/net/wireless/wl12xx/wl1271_cmd.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "wl1271.h" #include "wl1271_reg.h" diff --git a/drivers/net/wireless/wl12xx/wl1271_debugfs.c b/drivers/net/wireless/wl12xx/wl1271_debugfs.c index 8d7588c..3f7ff8d 100644 --- a/drivers/net/wireless/wl12xx/wl1271_debugfs.c +++ b/drivers/net/wireless/wl12xx/wl1271_debugfs.c @@ -24,6 +24,7 @@ #include "wl1271_debugfs.h" #include +#include #include "wl1271.h" #include "wl1271_acx.h" diff --git a/drivers/net/wireless/wl12xx/wl1271_init.c b/drivers/net/wireless/wl12xx/wl1271_init.c index 86c30a8..d189e8f 100644 --- a/drivers/net/wireless/wl12xx/wl1271_init.c +++ b/drivers/net/wireless/wl12xx/wl1271_init.c @@ -23,6 +23,7 @@ #include #include +#include #include "wl1271_init.h" #include "wl12xx_80211.h" diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index 2a864b2..65a1aeb 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "wl1271.h" #include "wl12xx_80211.h" diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.c b/drivers/net/wireless/wl12xx/wl1271_rx.c index 6730f5b..c723d9c 100644 --- a/drivers/net/wireless/wl12xx/wl1271_rx.c +++ b/drivers/net/wireless/wl12xx/wl1271_rx.c @@ -21,6 +21,8 @@ * */ +#include + #include "wl1271.h" #include "wl1271_acx.h" #include "wl1271_reg.h" diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.c b/drivers/net/wireless/wl12xx/wl1271_spi.c index 67a8293..053c84a 100644 --- a/drivers/net/wireless/wl12xx/wl1271_spi.c +++ b/drivers/net/wireless/wl12xx/wl1271_spi.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "wl1271.h" #include "wl12xx_80211.h" diff --git a/drivers/net/wireless/wl12xx/wl1271_testmode.c b/drivers/net/wireless/wl12xx/wl1271_testmode.c index 3919102..5c1c4f5 100644 --- a/drivers/net/wireless/wl12xx/wl1271_testmode.c +++ b/drivers/net/wireless/wl12xx/wl1271_testmode.c @@ -22,6 +22,7 @@ */ #include "wl1271_testmode.h" +#include #include #include "wl1271.h" diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c index 6917286..9d12778 100644 --- a/drivers/net/wireless/zd1201.c +++ b/drivers/net/wireless/zd1201.c @@ -14,6 +14,7 @@ #include #include +#include #include #include #include diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c index 7ca95c4..b2af3c5 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.c +++ b/drivers/net/wireless/zd1211rw/zd_chip.c @@ -25,6 +25,7 @@ #include #include +#include #include "zd_def.h" #include "zd_chip.h" diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 00e09e2..16fa289 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -22,6 +22,7 @@ #include #include +#include #include #include #include diff --git a/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c b/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c index 439799b..9e74eb1 100644 --- a/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c +++ b/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c @@ -19,6 +19,7 @@ */ #include +#include #include "zd_rf.h" #include "zd_usb.h" diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index 442fc11..d91ad1a 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index a869b45..d504e2b 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c index 1a74594..1e783cc 100644 --- a/drivers/net/xilinx_emaclite.c +++ b/drivers/net/xilinx_emaclite.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/xtsonic.c b/drivers/net/xtsonic.c index 389ba9d..fdba9cb 100644 --- a/drivers/net/xtsonic.c +++ b/drivers/net/xtsonic.c @@ -20,11 +20,11 @@ #include #include #include +#include #include #include #include #include -#include #include #include #include @@ -33,6 +33,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c index 7d4107f..ede5b24 100644 --- a/drivers/net/yellowfin.c +++ b/drivers/net/yellowfin.c @@ -90,7 +90,6 @@ static int gx_fix; #include #include #include -#include #include #include #include diff --git a/drivers/net/znet.c b/drivers/net/znet.c index def49d2..dbfef8d 100644 --- a/drivers/net/znet.c +++ b/drivers/net/znet.c @@ -88,6 +88,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/nubus/nubus.c b/drivers/nubus/nubus.c index f5f7584..b764ac22d 100644 --- a/drivers/nubus/nubus.c +++ b/drivers/nubus/nubus.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/of/base.c b/drivers/of/base.c index cb96888..b5ad974 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -20,6 +20,7 @@ #include #include #include +#include #include struct device_node *allnodes; diff --git a/drivers/of/gpio.c b/drivers/of/gpio.c index 24c3606..a1b31a4 100644 --- a/drivers/of/gpio.c +++ b/drivers/of/gpio.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff --git a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c index c9e2ae9..a9352b2 100644 --- a/drivers/oprofile/buffer_sync.c +++ b/drivers/oprofile/buffer_sync.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "oprofile_stats.h" #include "event_buffer.h" diff --git a/drivers/parisc/asp.c b/drivers/parisc/asp.c index 9ca2109..6a1ab25 100644 --- a/drivers/parisc/asp.c +++ b/drivers/parisc/asp.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/parisc/ccio-rm-dma.c b/drivers/parisc/ccio-rm-dma.c index 356b835..f78f6f1 100644 --- a/drivers/parisc/ccio-rm-dma.c +++ b/drivers/parisc/ccio-rm-dma.c @@ -38,6 +38,7 @@ #include #include #include +#include #include diff --git a/drivers/parisc/gsc.c b/drivers/parisc/gsc.c index c4e1f3c..20a1bce 100644 --- a/drivers/parisc/gsc.c +++ b/drivers/parisc/gsc.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include diff --git a/drivers/parport/daisy.c b/drivers/parport/daisy.c index 3c8f06c..5bed17f 100644 --- a/drivers/parport/daisy.c +++ b/drivers/parport/daisy.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/drivers/parport/parport_ax88796.c b/drivers/parport/parport_ax88796.c index 6938d2e..2c5ac2b 100644 --- a/drivers/parport/parport_ax88796.c +++ b/drivers/parport/parport_ax88796.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff --git a/drivers/parport/parport_ip32.c b/drivers/parport/parport_ip32.c index 6d58bf8..d3d7809 100644 --- a/drivers/parport/parport_ip32.c +++ b/drivers/parport/parport_ip32.c @@ -103,6 +103,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c index c3bb84a..40e208d 100644 --- a/drivers/parport/parport_serial.c +++ b/drivers/parport/parport_serial.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/parport/probe.c b/drivers/parport/probe.c index 0f65507..d763bc9 100644 --- a/drivers/parport/probe.c +++ b/drivers/parport/probe.c @@ -9,6 +9,7 @@ #include #include #include +#include #include static const struct { diff --git a/drivers/pci/access.c b/drivers/pci/access.c index db23200..2f646fe 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 26301cb..628ea20 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "pci.h" diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index 83aae47..33ead97 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c @@ -35,6 +35,7 @@ #include #include #include +#include #define PREFIX "DMAR: " diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c index 3c76fc6..45fcc1e 100644 --- a/drivers/pci/hotplug/acpi_pcihp.c +++ b/drivers/pci/hotplug/acpi_pcihp.c @@ -32,6 +32,7 @@ #include #include #include +#include #define MY_NAME "acpi_pcihp" diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index b5dad9f3..cb23aa2 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -47,6 +47,7 @@ #include #include #include +#include #include "../pci.h" #include "acpiphp.h" diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c index aa5df48..6ecbfb2 100644 --- a/drivers/pci/hotplug/acpiphp_ibm.c +++ b/drivers/pci/hotplug/acpiphp_ibm.c @@ -26,6 +26,7 @@ */ #include +#include #include #include #include diff --git a/drivers/pci/hotplug/cpqphp_sysfs.c b/drivers/pci/hotplug/cpqphp_sysfs.c index e6089bd..5621532 100644 --- a/drivers/pci/hotplug/cpqphp_sysfs.c +++ b/drivers/pci/hotplug/cpqphp_sysfs.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c index 0a894ef..5317e4d7 100644 --- a/drivers/pci/hotplug/fakephp.c +++ b/drivers/pci/hotplug/fakephp.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "../pci.h" struct legacy_slot { diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c index 728b119..6d2eea9 100644 --- a/drivers/pci/hotplug/pci_hotplug_core.c +++ b/drivers/pci/hotplug/pci_hotplug_core.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/pci/hotplug/pciehp_acpi.c b/drivers/pci/hotplug/pciehp_acpi.c index b09b083..1f4000a 100644 --- a/drivers/pci/hotplug/pciehp_acpi.c +++ b/drivers/pci/hotplug/pciehp_acpi.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "pciehp.h" #define PCIEHP_DETECT_PCIE (0) diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index 920f820..3588ea6 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include "pciehp.h" diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index 9a7f247..8f58148 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include "../pci.h" diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 9665d6b..0cd4204 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -36,6 +36,7 @@ #include #include #include +#include #include "../pci.h" #include "pciehp.h" diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index dcaae72..7197022 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include /* for eeh_add_device() */ diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c index 8aebe1e9..72d507b 100644 --- a/drivers/pci/hotplug/sgi_hotplug.c +++ b/drivers/pci/hotplug/sgi_hotplug.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c index a506229..a7bd504 100644 --- a/drivers/pci/hotplug/shpchp_core.c +++ b/drivers/pci/hotplug/shpchp_core.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include "shpchp.h" diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c index 3bba0c0..3387fbf 100644 --- a/drivers/pci/hotplug/shpchp_ctrl.c +++ b/drivers/pci/hotplug/shpchp_ctrl.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include "../pci.h" diff --git a/drivers/pci/htirq.c b/drivers/pci/htirq.c index 737a1c4..98abf8b 100644 --- a/drivers/pci/htirq.c +++ b/drivers/pci/htirq.c @@ -10,7 +10,6 @@ #include #include #include -#include #include /* Global ht irq lock. diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c index 95b8491..6ee98a5 100644 --- a/drivers/pci/intr_remapping.c +++ b/drivers/pci/intr_remapping.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/pci/ioapic.c b/drivers/pci/ioapic.c index fb9fdf4..203508b 100644 --- a/drivers/pci/ioapic.c +++ b/drivers/pci/ioapic.c @@ -18,6 +18,7 @@ #include #include +#include #include struct ioapic { diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index 3e5ab2b..ce6a366 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c @@ -9,6 +9,7 @@ */ #include +#include #include #include #include diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index f9cf317..77b68ea 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "pci.h" #include "msi.h" diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 9976685..fad9398 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "pci.h" static int sysfs_initialized; /* = 0 */ diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 1531f3a..5ea587e 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/pci/pcie/aer/aer_inject.c b/drivers/pci/pcie/aer/aer_inject.c index 223052b..f8f425b 100644 --- a/drivers/pci/pcie/aer/aer_inject.c +++ b/drivers/pci/pcie/aer/aer_inject.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c index 21f215f..aa495ad 100644 --- a/drivers/pci/pcie/aer/aerdrv.c +++ b/drivers/pci/pcie/aer/aerdrv.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "aerdrv.h" #include "../../pci.h" diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index c843a79..aceb04b 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "aerdrv.h" static int forceload; diff --git a/drivers/pci/pcie/pme/pcie_pme.c b/drivers/pci/pcie/pme/pcie_pme.c index 7b3cbff..aac285a 100644 --- a/drivers/pci/pcie/pme/pcie_pme.c +++ b/drivers/pci/pcie/pme/pcie_pme.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index 127e8f1..3debed2 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index 593bb84..449e890 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include diff --git a/drivers/pci/search.c b/drivers/pci/search.c index 4a471dc..20d03f7 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include "pci.h" diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c index f75a44d..659eaa0 100644 --- a/drivers/pci/slot.c +++ b/drivers/pci/slot.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include "pci.h" diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c index fb904f4..fb33fa4 100644 --- a/drivers/pcmcia/at91_cf.c +++ b/drivers/pcmcia/at91_cf.c @@ -15,6 +15,7 @@ #include #include #include +#include #include diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c index ac4d089..88c4c40 100644 --- a/drivers/pcmcia/au1000_generic.c +++ b/drivers/pcmcia/au1000_generic.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include diff --git a/drivers/pcmcia/bcm63xx_pcmcia.c b/drivers/pcmcia/bcm63xx_pcmcia.c index bc88a3b..693577e 100644 --- a/drivers/pcmcia/bcm63xx_pcmcia.c +++ b/drivers/pcmcia/bcm63xx_pcmcia.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/pcmcia/bfin_cf_pcmcia.c b/drivers/pcmcia/bfin_cf_pcmcia.c index 93f9dde..9e84d03 100644 --- a/drivers/pcmcia/bfin_cf_pcmcia.c +++ b/drivers/pcmcia/bfin_cf_pcmcia.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/pcmcia/db1xxx_ss.c b/drivers/pcmcia/db1xxx_ss.c index a520193..6206408 100644 --- a/drivers/pcmcia/db1xxx_ss.c +++ b/drivers/pcmcia/db1xxx_ss.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 52d33b2..cb6036d 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include diff --git a/drivers/pcmcia/electra_cf.c b/drivers/pcmcia/electra_cf.c index 89cfddc..2e59fe9 100644 --- a/drivers/pcmcia/electra_cf.c +++ b/drivers/pcmcia/electra_cf.c @@ -31,6 +31,7 @@ #include #include #include +#include #include diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c index d53d9b5..9e2a156 100644 --- a/drivers/pcmcia/i82365.c +++ b/drivers/pcmcia/i82365.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c index ab21264..7e16ed8 100644 --- a/drivers/pcmcia/m32r_cfc.c +++ b/drivers/pcmcia/m32r_cfc.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c index 0caf3db..6c5c3f9 100644 --- a/drivers/pcmcia/m32r_pcc.c +++ b/drivers/pcmcia/m32r_pcc.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c index 01ef7de..41cc954 100644 --- a/drivers/pcmcia/m8xx_pcmcia.c +++ b/drivers/pcmcia/m8xx_pcmcia.c @@ -42,7 +42,6 @@ #include #include -#include #include #include #include diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c index 9edc396..a7cfc79 100644 --- a/drivers/pcmcia/omap_cf.c +++ b/drivers/pcmcia/omap_cf.c @@ -16,6 +16,7 @@ #include #include #include +#include #include diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c index 13a7132..104e73d 100644 --- a/drivers/pcmcia/pcmcia_ioctl.c +++ b/drivers/pcmcia/pcmcia_ioctl.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index c4612c5..caec1de 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c index 4a34268..b61a136 100644 --- a/drivers/pcmcia/pd6729.c +++ b/drivers/pcmcia/pd6729.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c index 0a876fa..df4532e 100644 --- a/drivers/pcmcia/pxa2xx_base.c +++ b/drivers/pcmcia/pxa2xx_base.c @@ -17,6 +17,7 @@ ======================================================================*/ #include +#include #include #include #include diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c index 452c83b..ffa5f3c 100644 --- a/drivers/pcmcia/rsrc_mgr.c +++ b/drivers/pcmcia/rsrc_mgr.c @@ -12,6 +12,7 @@ * (C) 1999 David A. Hinds */ +#include #include #include diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c index 5188962..edbd8c4 100644 --- a/drivers/pcmcia/sa1100_generic.c +++ b/drivers/pcmcia/sa1100_generic.c @@ -32,6 +32,7 @@ #include #include +#include #include #include diff --git a/drivers/pcmcia/sa1111_generic.c b/drivers/pcmcia/sa1111_generic.c index 799e979..5986690 100644 --- a/drivers/pcmcia/sa1111_generic.c +++ b/drivers/pcmcia/sa1111_generic.c @@ -12,6 +12,7 @@ #include #include #include +#include #include diff --git a/drivers/pcmcia/sa11xx_base.c b/drivers/pcmcia/sa11xx_base.c index fc9a652..fa28d89 100644 --- a/drivers/pcmcia/sa11xx_base.c +++ b/drivers/pcmcia/sa11xx_base.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c index 0827801..80e36bc 100644 --- a/drivers/pcmcia/socket_sysfs.c +++ b/drivers/pcmcia/socket_sysfs.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c index bac85f3..56004a1 100644 --- a/drivers/pcmcia/tcic.c +++ b/drivers/pcmcia/tcic.c @@ -39,7 +39,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/pcmcia/xxs1500_ss.c b/drivers/pcmcia/xxs1500_ss.c index f9009d3..201ccfa 100644 --- a/drivers/pcmcia/xxs1500_ss.c +++ b/drivers/pcmcia/xxs1500_ss.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index f19ad02..83ace277 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index cbca40a..1ea6c43 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c @@ -36,6 +36,7 @@ #include #include #include +#include #include diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index db5f7db..c2d4569 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include diff --git a/drivers/platform/x86/asus_acpi.c b/drivers/platform/x86/asus_acpi.c index ee52035..92fd30c 100644 --- a/drivers/platform/x86/asus_acpi.c +++ b/drivers/platform/x86/asus_acpi.c @@ -32,6 +32,7 @@ #include #include +#include #include #include #include diff --git a/drivers/platform/x86/classmate-laptop.c b/drivers/platform/x86/classmate-laptop.c index c696cf1..7f9e5dd 100644 --- a/drivers/platform/x86/classmate-laptop.c +++ b/drivers/platform/x86/classmate-laptop.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index 46435ac..661e3ac 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "../../firmware/dcdbas.h" #define BRIGHTNESS_TOKEN 0x7d diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c index bed764e..6ba6c30 100644 --- a/drivers/platform/x86/dell-wmi.c +++ b/drivers/platform/x86/dell-wmi.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 3fdf21e..54a0157 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c index c1074b3..47b4fd7 100644 --- a/drivers/platform/x86/fujitsu-laptop.c +++ b/drivers/platform/x86/fujitsu-laptop.c @@ -66,6 +66,7 @@ #include #include #include +#include #if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) #include #endif diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index 5608636..51c07a0 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/platform/x86/intel_menlow.c b/drivers/platform/x86/intel_menlow.c index f0a90a6..1190bad 100644 --- a/drivers/platform/x86/intel_menlow.c +++ b/drivers/platform/x86/intel_menlow.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/platform/x86/msi-wmi.c b/drivers/platform/x86/msi-wmi.c index 367caaa..d173600 100644 --- a/drivers/platform/x86/msi-wmi.c +++ b/drivers/platform/x86/msi-wmi.c @@ -26,6 +26,7 @@ #include #include #include +#include MODULE_AUTHOR("Thomas Renninger "); MODULE_DESCRIPTION("MSI laptop WMI hotkeys driver"); diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c index 726f02a..2fb9a32 100644 --- a/drivers/platform/x86/panasonic-laptop.c +++ b/drivers/platform/x86/panasonic-laptop.c @@ -124,6 +124,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index 6553b91..1387c5f 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c @@ -58,6 +58,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/platform/x86/tc1100-wmi.c b/drivers/platform/x86/tc1100-wmi.c index dd33b51..1fe0f1f 100644 --- a/drivers/platform/x86/tc1100-wmi.c +++ b/drivers/platform/x86/tc1100-wmi.c @@ -27,6 +27,7 @@ #include #include +#include #include #include #include diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 770b853..63290b3 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -58,6 +58,7 @@ #include #include #include +#include #include #include diff --git a/drivers/platform/x86/topstar-laptop.c b/drivers/platform/x86/topstar-laptop.c index 4d6516f..ff4b476 100644 --- a/drivers/platform/x86/topstar-laptop.c +++ b/drivers/platform/x86/topstar-laptop.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index def4841..37aa147 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -47,6 +47,7 @@ #include #include #include +#include #include diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index 09e9918..39ec5b6 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c index e851160..918d5f0 100644 --- a/drivers/pnp/isapnp/core.c +++ b/drivers/pnp/isapnp/core.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c index 00fd3577..0a15664 100644 --- a/drivers/pnp/manager.c +++ b/drivers/pnp/manager.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include "base.h" diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index 5314bf6..f7ff628 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c @@ -21,6 +21,7 @@ #include #include +#include #include #include diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 54514aa..c6c552f 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "../base.h" #include "pnpacpi.h" diff --git a/drivers/pnp/pnpbios/bioscalls.c b/drivers/pnp/pnpbios/bioscalls.c index fc83783c..8591f6a 100644 --- a/drivers/pnp/pnpbios/bioscalls.c +++ b/drivers/pnp/pnpbios/bioscalls.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c index a5135eb..cb1f47b 100644 --- a/drivers/pnp/pnpbios/rsparser.c +++ b/drivers/pnp/pnpbios/rsparser.c @@ -5,7 +5,6 @@ #include #include #include -#include #ifdef CONFIG_PCI #include diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c index 5b277db..2e54e6a 100644 --- a/drivers/pnp/resource.c +++ b/drivers/pnp/resource.c @@ -8,6 +8,7 @@ */ #include +#include #include #include #include diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c index bece33e..3ec9c6a 100644 --- a/drivers/power/bq27x00_battery.c +++ b/drivers/power/bq27x00_battery.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #define DRIVER_VERSION "1.1.0" diff --git a/drivers/power/da9030_battery.c b/drivers/power/da9030_battery.c index a2e71f7..d2c793cf 100644 --- a/drivers/power/da9030_battery.c +++ b/drivers/power/da9030_battery.c @@ -10,6 +10,7 @@ */ #include +#include #include #include #include diff --git a/drivers/power/ds2760_battery.c b/drivers/power/ds2760_battery.c index 6f1dba5..3bf8d1f 100644 --- a/drivers/power/ds2760_battery.c +++ b/drivers/power/ds2760_battery.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include diff --git a/drivers/power/ds2782_battery.c b/drivers/power/ds2782_battery.c index da14f37..99c8997 100644 --- a/drivers/power/ds2782_battery.c +++ b/drivers/power/ds2782_battery.c @@ -19,6 +19,7 @@ #include #include #include +#include #define DS2782_REG_RARC 0x06 /* Remaining active relative capacity */ diff --git a/drivers/power/max17040_battery.c b/drivers/power/max17040_battery.c index 87b98bf..f3e22c9 100644 --- a/drivers/power/max17040_battery.c +++ b/drivers/power/max17040_battery.c @@ -19,6 +19,7 @@ #include #include #include +#include #define MAX17040_VCELL_MSB 0x02 #define MAX17040_VCELL_LSB 0x03 diff --git a/drivers/power/max8925_power.c b/drivers/power/max8925_power.c index a1b4410..8e5aec2 100644 --- a/drivers/power/max8925_power.c +++ b/drivers/power/max8925_power.c @@ -11,6 +11,7 @@ #include #include +#include #include #include #include diff --git a/drivers/power/pcf50633-charger.c b/drivers/power/pcf50633-charger.c index ea3fdfa..066f994 100644 --- a/drivers/power/pcf50633-charger.c +++ b/drivers/power/pcf50633-charger.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include diff --git a/drivers/power/pmu_battery.c b/drivers/power/pmu_battery.c index 9c87ad5..023d249 100644 --- a/drivers/power/pmu_battery.c +++ b/drivers/power/pmu_battery.c @@ -14,6 +14,7 @@ #include #include #include +#include static struct pmu_battery_dev { struct power_supply bat; diff --git a/drivers/power/power_supply_leds.c b/drivers/power/power_supply_leds.c index 2dece40..031a554 100644 --- a/drivers/power/power_supply_leds.c +++ b/drivers/power/power_supply_leds.c @@ -12,6 +12,7 @@ #include #include +#include #include "power_supply.h" diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c index ff05e61..5b6e352 100644 --- a/drivers/power/power_supply_sysfs.c +++ b/drivers/power/power_supply_sysfs.c @@ -13,6 +13,7 @@ #include #include +#include #include "power_supply.h" diff --git a/drivers/power/wm831x_backup.c b/drivers/power/wm831x_backup.c index bf4f387..0fd130d 100644 --- a/drivers/power/wm831x_backup.c +++ b/drivers/power/wm831x_backup.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include diff --git a/drivers/power/wm831x_power.c b/drivers/power/wm831x_power.c index f85e80b..875c4d0 100644 --- a/drivers/power/wm831x_power.c +++ b/drivers/power/wm831x_power.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include diff --git a/drivers/power/wm97xx_battery.c b/drivers/power/wm97xx_battery.c index 23eed35..94c7065 100644 --- a/drivers/power/wm97xx_battery.c +++ b/drivers/power/wm97xx_battery.c @@ -23,6 +23,7 @@ #include #include #include +#include static DEFINE_MUTEX(bat_lock); static struct work_struct bat_work; diff --git a/drivers/pps/kapi.c b/drivers/pps/kapi.c index 2d414e2..1aa02db 100644 --- a/drivers/pps/kapi.c +++ b/drivers/pps/kapi.c @@ -29,6 +29,7 @@ #include #include #include +#include /* * Global variables diff --git a/drivers/ps3/ps3-lpm.c b/drivers/ps3/ps3-lpm.c index fe96793..8000985 100644 --- a/drivers/ps3/ps3-lpm.c +++ b/drivers/ps3/ps3-lpm.c @@ -18,6 +18,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include #include #include #include diff --git a/drivers/ps3/ps3-vuart.c b/drivers/ps3/ps3-vuart.c index e4ad5ba..d9fb729 100644 --- a/drivers/ps3/ps3-vuart.c +++ b/drivers/ps3/ps3-vuart.c @@ -19,6 +19,7 @@ */ #include +#include #include #include #include diff --git a/drivers/ps3/ps3av.c b/drivers/ps3/ps3av.c index 95a689b..a409fa0 100644 --- a/drivers/ps3/ps3av.c +++ b/drivers/ps3/ps3av.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 5af16c2..2b4e40d 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c index d11f762..2fe9d99c 100644 --- a/drivers/regulator/fixed.c +++ b/drivers/regulator/fixed.c @@ -25,6 +25,7 @@ #include #include #include +#include struct fixed_voltage_data { struct regulator_desc desc; diff --git a/drivers/regulator/lp3971.c b/drivers/regulator/lp3971.c index b20b3e1..671a7d1 100644 --- a/drivers/regulator/lp3971.c +++ b/drivers/regulator/lp3971.c @@ -18,6 +18,7 @@ #include #include #include +#include struct lp3971 { struct device *dev; diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c index c0b09e1..b3c1afc 100644 --- a/drivers/regulator/max1586.c +++ b/drivers/regulator/max1586.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #define MAX1586_V3_MAX_VSEL 31 diff --git a/drivers/regulator/max8649.c b/drivers/regulator/max8649.c index 833aaed..bfc4c5f 100644 --- a/drivers/regulator/max8649.c +++ b/drivers/regulator/max8649.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #define MAX8649_DCDC_VMIN 750000 /* uV */ diff --git a/drivers/regulator/max8660.c b/drivers/regulator/max8660.c index 47f90b2..3790b21 100644 --- a/drivers/regulator/max8660.c +++ b/drivers/regulator/max8660.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #define MAX8660_DCDC_MIN_UV 725000 diff --git a/drivers/regulator/mc13783-regulator.c b/drivers/regulator/mc13783-regulator.c index f7b8184..a681f5e 100644 --- a/drivers/regulator/mc13783-regulator.c +++ b/drivers/regulator/mc13783-regulator.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include diff --git a/drivers/regulator/tps65023-regulator.c b/drivers/regulator/tps65023-regulator.c index 1f18354..8e2f209 100644 --- a/drivers/regulator/tps65023-regulator.c +++ b/drivers/regulator/tps65023-regulator.c @@ -24,6 +24,7 @@ #include #include #include +#include /* Register definitions */ #define TPS65023_REG_VERSION 0 diff --git a/drivers/regulator/tps6507x-regulator.c b/drivers/regulator/tps6507x-regulator.c index c2a9539..74841ab 100644 --- a/drivers/regulator/tps6507x-regulator.c +++ b/drivers/regulator/tps6507x-regulator.c @@ -24,6 +24,7 @@ #include #include #include +#include /* Register definitions */ #define TPS6507X_REG_PPATH1 0X01 diff --git a/drivers/regulator/userspace-consumer.c b/drivers/regulator/userspace-consumer.c index 44917da..9d5ba93 100644 --- a/drivers/regulator/userspace-consumer.c +++ b/drivers/regulator/userspace-consumer.c @@ -21,6 +21,7 @@ #include #include #include +#include struct userspace_consumer_data { const char *name; diff --git a/drivers/regulator/virtual.c b/drivers/regulator/virtual.c index d96ceca..69e550f 100644 --- a/drivers/regulator/virtual.c +++ b/drivers/regulator/virtual.c @@ -15,6 +15,7 @@ #include #include #include +#include struct virtual_consumer_data { struct mutex lock; diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c index 6e18e56..dbfaf59 100644 --- a/drivers/regulator/wm831x-dcdc.c +++ b/drivers/regulator/wm831x-dcdc.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include diff --git a/drivers/regulator/wm831x-isink.c b/drivers/regulator/wm831x-isink.c index ca0f6b6..6c446cd 100644 --- a/drivers/regulator/wm831x-isink.c +++ b/drivers/regulator/wm831x-isink.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c index d2406c1..e686cdb 100644 --- a/drivers/regulator/wm831x-ldo.c +++ b/drivers/regulator/wm831x-ldo.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include diff --git a/drivers/regulator/wm8994-regulator.c b/drivers/regulator/wm8994-regulator.c index 95454a4..5a1dc8a 100644 --- a/drivers/regulator/wm8994-regulator.c +++ b/drivers/regulator/wm8994-regulator.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index 40845c7..565562b 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "rtc-core.h" diff --git a/drivers/rtc/rtc-at32ap700x.c b/drivers/rtc/rtc-at32ap700x.c index 8825695..b2752b6 100644 --- a/drivers/rtc/rtc-at32ap700x.c +++ b/drivers/rtc/rtc-at32ap700x.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c index 78a018b..f677e07 100644 --- a/drivers/rtc/rtc-at91sam9.c +++ b/drivers/rtc/rtc-at91sam9.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include diff --git a/drivers/rtc/rtc-bfin.c b/drivers/rtc/rtc-bfin.c index b11485b..72b2bcc 100644 --- a/drivers/rtc/rtc-bfin.c +++ b/drivers/rtc/rtc-bfin.c @@ -51,6 +51,7 @@ #include #include #include +#include #include diff --git a/drivers/rtc/rtc-bq4802.c b/drivers/rtc/rtc-bq4802.c index 280fe48..128270c 100644 --- a/drivers/rtc/rtc-bq4802.c +++ b/drivers/rtc/rtc-bq4802.c @@ -10,6 +10,7 @@ #include #include #include +#include MODULE_AUTHOR("David S. Miller "); MODULE_DESCRIPTION("TI BQ4802 RTC driver"); diff --git a/drivers/rtc/rtc-coh901331.c b/drivers/rtc/rtc-coh901331.c index 44c4399..316f484 100644 --- a/drivers/rtc/rtc-coh901331.c +++ b/drivers/rtc/rtc-coh901331.c @@ -14,6 +14,7 @@ #include #include #include +#include /* * Registers in the COH 901 331 diff --git a/drivers/rtc/rtc-ds1216.c b/drivers/rtc/rtc-ds1216.c index 4aedc70..45cd8c9 100644 --- a/drivers/rtc/rtc-ds1216.c +++ b/drivers/rtc/rtc-ds1216.c @@ -9,6 +9,7 @@ #include #include #include +#include #define DRV_VERSION "0.2" diff --git a/drivers/rtc/rtc-ds1286.c b/drivers/rtc/rtc-ds1286.c index 4fcb16b..bf430f9 100644 --- a/drivers/rtc/rtc-ds1286.c +++ b/drivers/rtc/rtc-ds1286.c @@ -18,6 +18,7 @@ #include #include #include +#include #define DRV_VERSION "1.0" diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c index 9630e7d..7836c9c 100644 --- a/drivers/rtc/rtc-ds1305.c +++ b/drivers/rtc/rtc-ds1305.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c index 5317bbc..6194573 100644 --- a/drivers/rtc/rtc-ds1374.c +++ b/drivers/rtc/rtc-ds1374.c @@ -24,6 +24,7 @@ #include #include #include +#include #define DS1374_REG_TOD0 0x00 /* Time of Day */ #define DS1374_REG_TOD1 0x01 diff --git a/drivers/rtc/rtc-ds1390.c b/drivers/rtc/rtc-ds1390.c index cdb7050..26a86d2 100644 --- a/drivers/rtc/rtc-ds1390.c +++ b/drivers/rtc/rtc-ds1390.c @@ -19,6 +19,7 @@ #include #include #include +#include #define DS1390_REG_100THS 0x00 #define DS1390_REG_SECONDS 0x01 diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c index 4166b84..06b8566 100644 --- a/drivers/rtc/rtc-ds1511.c +++ b/drivers/rtc/rtc-ds1511.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c index ed1ef7c..244f999 100644 --- a/drivers/rtc/rtc-ds1553.c +++ b/drivers/rtc/rtc-ds1553.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/rtc/rtc-ds1742.c b/drivers/rtc/rtc-ds1742.c index cad9ceb..2b4b0bc 100644 --- a/drivers/rtc/rtc-ds1742.c +++ b/drivers/rtc/rtc-ds1742.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/rtc/rtc-ep93xx.c b/drivers/rtc/rtc-ep93xx.c index 91bde97..11ae64d 100644 --- a/drivers/rtc/rtc-ep93xx.c +++ b/drivers/rtc/rtc-ep93xx.c @@ -13,6 +13,7 @@ #include #include #include +#include #define EP93XX_RTC_DATA 0x000 #define EP93XX_RTC_MATCH 0x004 diff --git a/drivers/rtc/rtc-fm3130.c b/drivers/rtc/rtc-fm3130.c index 812c667..ff6fce6 100644 --- a/drivers/rtc/rtc-fm3130.c +++ b/drivers/rtc/rtc-fm3130.c @@ -13,6 +13,7 @@ #include #include #include +#include #define FM3130_RTC_CONTROL (0x0) #define FM3130_CAL_CONTROL (0x1) diff --git a/drivers/rtc/rtc-m48t35.c b/drivers/rtc/rtc-m48t35.c index 8cb5b89..7410875 100644 --- a/drivers/rtc/rtc-m48t35.c +++ b/drivers/rtc/rtc-m48t35.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include diff --git a/drivers/rtc/rtc-m48t59.c b/drivers/rtc/rtc-m48t59.c index ede43b8..365ff3a 100644 --- a/drivers/rtc/rtc-m48t59.c +++ b/drivers/rtc/rtc-m48t59.c @@ -19,6 +19,7 @@ #include #include #include +#include #ifndef NO_IRQ #define NO_IRQ (-1) diff --git a/drivers/rtc/rtc-max8925.c b/drivers/rtc/rtc-max8925.c index acdbb17..174036d 100644 --- a/drivers/rtc/rtc-max8925.c +++ b/drivers/rtc/rtc-max8925.c @@ -11,6 +11,7 @@ #include #include +#include #include #include #include diff --git a/drivers/rtc/rtc-mc13783.c b/drivers/rtc/rtc-mc13783.c index 1379c7f..675bfb5 100644 --- a/drivers/rtc/rtc-mc13783.c +++ b/drivers/rtc/rtc-mc13783.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #define DRIVER_NAME "mc13783-rtc" diff --git a/drivers/rtc/rtc-mpc5121.c b/drivers/rtc/rtc-mpc5121.c index 4313ca0..f0dbf9c 100644 --- a/drivers/rtc/rtc-mpc5121.c +++ b/drivers/rtc/rtc-mpc5121.c @@ -15,6 +15,7 @@ #include #include #include +#include struct mpc5121_rtc_regs { u8 set_time; /* RTC + 0x00 */ diff --git a/drivers/rtc/rtc-msm6242.c b/drivers/rtc/rtc-msm6242.c index 5f5968a..b2fff0c 100644 --- a/drivers/rtc/rtc-msm6242.c +++ b/drivers/rtc/rtc-msm6242.c @@ -13,6 +13,7 @@ #include #include #include +#include enum { diff --git a/drivers/rtc/rtc-mv.c b/drivers/rtc/rtc-mv.c index dc052ce..bcca472 100644 --- a/drivers/rtc/rtc-mv.c +++ b/drivers/rtc/rtc-mv.c @@ -13,6 +13,7 @@ #include #include #include +#include #define RTC_TIME_REG_OFFS 0 diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c index 8710f94..c77f6f7 100644 --- a/drivers/rtc/rtc-mxc.c +++ b/drivers/rtc/rtc-mxc.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/rtc/rtc-nuc900.c b/drivers/rtc/rtc-nuc900.c index bf59c9c..a351bd5 100644 --- a/drivers/rtc/rtc-nuc900.c +++ b/drivers/rtc/rtc-nuc900.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/rtc/rtc-pcap.c b/drivers/rtc/rtc-pcap.c index a99c289..25c0b3f 100644 --- a/drivers/rtc/rtc-pcap.c +++ b/drivers/rtc/rtc-pcap.c @@ -17,6 +17,7 @@ #include #include #include +#include #include struct pcap_rtc { diff --git a/drivers/rtc/rtc-pcf2123.c b/drivers/rtc/rtc-pcf2123.c index 2ceb365..71bab0e 100644 --- a/drivers/rtc/rtc-pcf2123.c +++ b/drivers/rtc/rtc-pcf2123.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include diff --git a/drivers/rtc/rtc-pcf50633.c b/drivers/rtc/rtc-pcf50633.c index 854c3cb..16edf94 100644 --- a/drivers/rtc/rtc-pcf50633.c +++ b/drivers/rtc/rtc-pcf50633.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index 65f346b..1af42b4 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c @@ -17,6 +17,7 @@ #include #include #include +#include #define DRV_VERSION "0.4.3" diff --git a/drivers/rtc/rtc-pl030.c b/drivers/rtc/rtc-pl030.c index 457231b..bbdb2f0 100644 --- a/drivers/rtc/rtc-pl030.c +++ b/drivers/rtc/rtc-pl030.c @@ -13,6 +13,7 @@ #include #include #include +#include #define RTC_DR (0) #define RTC_MR (4) diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c index c256aac..3587d99 100644 --- a/drivers/rtc/rtc-pl031.c +++ b/drivers/rtc/rtc-pl031.c @@ -24,6 +24,7 @@ #include #include #include +#include /* * Register definitions diff --git a/drivers/rtc/rtc-pxa.c b/drivers/rtc/rtc-pxa.c index e6351b7..e9c6fa0 100644 --- a/drivers/rtc/rtc-pxa.c +++ b/drivers/rtc/rtc-pxa.c @@ -26,6 +26,7 @@ #include #include #include +#include #include diff --git a/drivers/rtc/rtc-rp5c01.c b/drivers/rtc/rtc-rp5c01.c index e1313fe..a95f733 100644 --- a/drivers/rtc/rtc-rp5c01.c +++ b/drivers/rtc/rtc-rp5c01.c @@ -12,6 +12,7 @@ #include #include #include +#include enum { diff --git a/drivers/rtc/rtc-rs5c348.c b/drivers/rtc/rtc-rs5c348.c index 2099037..368d0e6 100644 --- a/drivers/rtc/rtc-rs5c348.c +++ b/drivers/rtc/rtc-rs5c348.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c index 2f2c68d..90cf0a6 100644 --- a/drivers/rtc/rtc-rs5c372.c +++ b/drivers/rtc/rtc-rs5c372.c @@ -13,6 +13,7 @@ #include #include #include +#include #define DRV_VERSION "0.6" diff --git a/drivers/rtc/rtc-rx8025.c b/drivers/rtc/rtc-rx8025.c index b1a29bc..b65c82f 100644 --- a/drivers/rtc/rtc-rx8025.c +++ b/drivers/rtc/rtc-rx8025.c @@ -20,6 +20,7 @@ */ #include #include +#include #include #include #include diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index e0d7b99..4969b60 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c index e95cc6f..5efbd59 100644 --- a/drivers/rtc/rtc-sh.c +++ b/drivers/rtc/rtc-sh.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #define DRV_NAME "sh-rtc" diff --git a/drivers/rtc/rtc-stk17ta8.c b/drivers/rtc/rtc-stk17ta8.c index 6770083..875ba09 100644 --- a/drivers/rtc/rtc-stk17ta8.c +++ b/drivers/rtc/rtc-stk17ta8.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/rtc/rtc-stmp3xxx.c b/drivers/rtc/rtc-stmp3xxx.c index d7ce1a5..7e7d0c8 100644 --- a/drivers/rtc/rtc-stmp3xxx.c +++ b/drivers/rtc/rtc-stmp3xxx.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/drivers/rtc/rtc-tx4939.c b/drivers/rtc/rtc-tx4939.c index 9ee81d8..20bfc64 100644 --- a/drivers/rtc/rtc-tx4939.c +++ b/drivers/rtc/rtc-tx4939.c @@ -12,6 +12,7 @@ #include #include #include +#include #include struct tx4939rtc_plat_data { diff --git a/drivers/rtc/rtc-v3020.c b/drivers/rtc/rtc-v3020.c index bed4cab..f71c3ce 100644 --- a/drivers/rtc/rtc-v3020.c +++ b/drivers/rtc/rtc-v3020.c @@ -28,6 +28,7 @@ #include #include #include +#include #include diff --git a/drivers/rtc/rtc-wm831x.c b/drivers/rtc/rtc-wm831x.c index 000c7e4..b16cfe5 100644 --- a/drivers/rtc/rtc-wm831x.c +++ b/drivers/rtc/rtc-wm831x.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c index b3736b8..6927e75 100644 --- a/drivers/s390/block/dasd_3990_erp.c +++ b/drivers/s390/block/dasd_3990_erp.c @@ -10,7 +10,6 @@ #define KMSG_COMPONENT "dasd-eckd" #include -#include #include #define PRINTK_HEADER "dasd_erp(3990): " diff --git a/drivers/s390/block/dasd_alias.c b/drivers/s390/block/dasd_alias.c index 148b1dd..8c48142 100644 --- a/drivers/s390/block/dasd_alias.c +++ b/drivers/s390/block/dasd_alias.c @@ -8,6 +8,7 @@ #define KMSG_COMPONENT "dasd-eckd" #include +#include #include #include "dasd_int.h" #include "dasd_eckd.h" diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c index 8e23919..eff9c81 100644 --- a/drivers/s390/block/dasd_devmap.c +++ b/drivers/s390/block/dasd_devmap.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include diff --git a/drivers/s390/block/dasd_eer.c b/drivers/s390/block/dasd_eer.c index 1f3e967..dd88803 100644 --- a/drivers/s390/block/dasd_eer.c +++ b/drivers/s390/block/dasd_eer.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c index 3479f81..1557214 100644 --- a/drivers/s390/block/dasd_ioctl.c +++ b/drivers/s390/block/dasd_ioctl.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c index f13a0bd..2eb0255 100644 --- a/drivers/s390/block/dasd_proc.c +++ b/drivers/s390/block/dasd_proc.c @@ -14,6 +14,7 @@ #define KMSG_COMPONENT "dasd" #include +#include #include #include #include diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c index 118de39..c881a14 100644 --- a/drivers/s390/block/xpram.c +++ b/drivers/s390/block/xpram.c @@ -33,7 +33,6 @@ #include /* isdigit, isxdigit */ #include #include -#include #include #include #include /* HDIO_GETGEO */ @@ -41,6 +40,7 @@ #include #include #include +#include #include #define XPRAM_NAME "xpram" diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c index 6bca81a..bb07577 100644 --- a/drivers/s390/char/con3270.c +++ b/drivers/s390/char/con3270.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c index 31c59b0..0eabcca 100644 --- a/drivers/s390/char/fs3270.c +++ b/drivers/s390/char/fs3270.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include diff --git a/drivers/s390/char/keyboard.c b/drivers/s390/char/keyboard.c index cee4d4e..cb6bffe 100644 --- a/drivers/s390/char/keyboard.c +++ b/drivers/s390/char/keyboard.c @@ -9,6 +9,7 @@ #include #include +#include #include #include diff --git a/drivers/s390/char/monreader.c b/drivers/s390/char/monreader.c index 33e9648..2ed3f82 100644 --- a/drivers/s390/char/monreader.c +++ b/drivers/s390/char/monreader.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/s390/char/monwriter.c b/drivers/s390/char/monwriter.c index 668a057..98a49df 100644 --- a/drivers/s390/char/monwriter.c +++ b/drivers/s390/char/monwriter.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/s390/char/sclp_async.c b/drivers/s390/char/sclp_async.c index f449c69..2aecf7f 100644 --- a/drivers/s390/char/sclp_async.c +++ b/drivers/s390/char/sclp_async.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/s390/char/sclp_con.c b/drivers/s390/char/sclp_con.c index ad698d3..ecf45c5 100644 --- a/drivers/s390/char/sclp_con.c +++ b/drivers/s390/char/sclp_con.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "sclp.h" #include "sclp_rw.h" diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c index 434ba04..8258d59 100644 --- a/drivers/s390/char/sclp_tty.c +++ b/drivers/s390/char/sclp_tty.c @@ -13,10 +13,10 @@ #include #include #include -#include #include #include #include +#include #include #include "ctrlchar.h" diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index 3796ffd..5d706e6 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include "sclp.h" diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c index cb70fa1..c17f35b 100644 --- a/drivers/s390/char/tape_34xx.c +++ b/drivers/s390/char/tape_34xx.c @@ -15,6 +15,7 @@ #include #include #include +#include #define TAPE_DBF_AREA tape_34xx_dbf diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c index 9821c58..fc993ac 100644 --- a/drivers/s390/char/tape_3590.c +++ b/drivers/s390/char/tape_3590.c @@ -12,6 +12,7 @@ #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt #include +#include #include #include #include diff --git a/drivers/s390/char/tape_class.c b/drivers/s390/char/tape_class.c index b2864e3..55343df 100644 --- a/drivers/s390/char/tape_class.c +++ b/drivers/s390/char/tape_class.c @@ -11,6 +11,8 @@ #define KMSG_COMPONENT "tape" #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#include + #include "tape_class.h" MODULE_AUTHOR("Stefan Bader "); diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c index 81b094e..29c2d73 100644 --- a/drivers/s390/char/tape_core.c +++ b/drivers/s390/char/tape_core.c @@ -20,6 +20,7 @@ #include // for locks #include #include +#include #include // for variable types diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c index 921dcda..5bb59d3 100644 --- a/drivers/s390/char/vmcp.c +++ b/drivers/s390/char/vmcp.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c index 7dfa541..e40a1b8 100644 --- a/drivers/s390/char/vmlogrdr.c +++ b/drivers/s390/char/vmlogrdr.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c index cc56fc7..1de672f 100644 --- a/drivers/s390/char/vmur.c +++ b/drivers/s390/char/vmur.c @@ -12,6 +12,7 @@ #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt #include +#include #include #include diff --git a/drivers/s390/char/vmwatchdog.c b/drivers/s390/char/vmwatchdog.c index c974058..e13508c 100644 --- a/drivers/s390/char/vmwatchdog.c +++ b/drivers/s390/char/vmwatchdog.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c index 3166d85..18daf16a 100644 --- a/drivers/s390/char/zcore.c +++ b/drivers/s390/char/zcore.c @@ -13,6 +13,7 @@ #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt #include +#include #include #include #include diff --git a/drivers/s390/cio/blacklist.c b/drivers/s390/cio/blacklist.c index 7eab9ab..13cb601 100644 --- a/drivers/s390/cio/blacklist.c +++ b/drivers/s390/cio/blacklist.c @@ -14,7 +14,6 @@ #include #include -#include #include #include #include diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c index c268a2e..1d16189 100644 --- a/drivers/s390/cio/chp.c +++ b/drivers/s390/cio/chp.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c index 852612f..404f630 100644 --- a/drivers/s390/cio/chsc_sch.c +++ b/drivers/s390/cio/chsc_sch.c @@ -7,6 +7,7 @@ * */ +#include #include #include #include diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c index 4f8f743..88be7b9 100644 --- a/drivers/s390/cio/qdio_main.c +++ b/drivers/s390/cio/qdio_main.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/s390/cio/qdio_thinint.c b/drivers/s390/cio/qdio_thinint.c index 9942c10..ce5f891 100644 --- a/drivers/s390/cio/qdio_thinint.c +++ b/drivers/s390/cio/qdio_thinint.c @@ -7,6 +7,7 @@ * Jan Glauber */ #include +#include #include #include #include diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 20836ef..91c6028 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c index ba50fe0..304caf5 100644 --- a/drivers/s390/crypto/zcrypt_api.c +++ b/drivers/s390/crypto/zcrypt_api.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/s390/crypto/zcrypt_cex2a.c b/drivers/s390/crypto/zcrypt_cex2a.c index c6fb0aa..9c409ef 100644 --- a/drivers/s390/crypto/zcrypt_cex2a.c +++ b/drivers/s390/crypto/zcrypt_cex2a.c @@ -27,6 +27,7 @@ */ #include +#include #include #include #include diff --git a/drivers/s390/crypto/zcrypt_pcica.c b/drivers/s390/crypto/zcrypt_pcica.c index e78df36..09e934b 100644 --- a/drivers/s390/crypto/zcrypt_pcica.c +++ b/drivers/s390/crypto/zcrypt_pcica.c @@ -27,6 +27,7 @@ */ #include +#include #include #include #include diff --git a/drivers/s390/crypto/zcrypt_pcicc.c b/drivers/s390/crypto/zcrypt_pcicc.c index 142f72a..9dec5c7 100644 --- a/drivers/s390/crypto/zcrypt_pcicc.c +++ b/drivers/s390/crypto/zcrypt_pcicc.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c index 68f3e62..510fab4 100644 --- a/drivers/s390/crypto/zcrypt_pcixcc.c +++ b/drivers/s390/crypto/zcrypt_pcixcc.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include diff --git a/drivers/s390/kvm/kvm_virtio.c b/drivers/s390/kvm/kvm_virtio.c index b2fc4fd..4e298bc 100644 --- a/drivers/s390/kvm/kvm_virtio.c +++ b/drivers/s390/kvm/kvm_virtio.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/s390/net/ctcm_dbug.c b/drivers/s390/net/ctcm_dbug.c index 1ca58f1..d962fd7 100644 --- a/drivers/s390/net/ctcm_dbug.c +++ b/drivers/s390/net/ctcm_dbug.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/s390/net/ctcm_sysfs.c b/drivers/s390/net/ctcm_sysfs.c index 738ad26..2b24550 100644 --- a/drivers/s390/net/ctcm_sysfs.c +++ b/drivers/s390/net/ctcm_sysfs.c @@ -14,6 +14,7 @@ #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt #include +#include #include "ctcm_main.h" /* diff --git a/drivers/s390/net/fsm.c b/drivers/s390/net/fsm.c index cae48cb..e5dea67 100644 --- a/drivers/s390/net/fsm.c +++ b/drivers/s390/net/fsm.c @@ -5,6 +5,7 @@ #include "fsm.h" #include +#include #include MODULE_AUTHOR("(C) 2000 IBM Corp. by Fritz Elfert (felfert@millenux.com)"); diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index f6cc46d..9b19ea1 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 3bd4206..3ba738b 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 6f1e303..6a801dc 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index b3b6e87..fc6ca1d 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/drivers/s390/net/qeth_l3_sys.c b/drivers/s390/net/qeth_l3_sys.c index 3f08b11..25b3e7a 100644 --- a/drivers/s390/net/qeth_l3_sys.c +++ b/drivers/s390/net/qeth_l3_sys.c @@ -8,6 +8,8 @@ * Frank Blaschka */ +#include + #include "qeth_l3.h" #define QETH_DEVICE_ATTR(_id, _name, _mode, _show, _store) \ diff --git a/drivers/s390/net/smsgiucv.c b/drivers/s390/net/smsgiucv.c index ecef1ed..7049127 100644 --- a/drivers/s390/net/smsgiucv.c +++ b/drivers/s390/net/smsgiucv.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/s390/net/smsgiucv_app.c b/drivers/s390/net/smsgiucv_app.c index 91579dc..1376887 100644 --- a/drivers/s390/net/smsgiucv_app.c +++ b/drivers/s390/net/smsgiucv_app.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 66d6c01..1e6183a8 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c @@ -30,6 +30,7 @@ #include #include +#include #include "zfcp_ext.h" #include "zfcp_fc.h" #include "zfcp_reqlist.h" diff --git a/drivers/s390/scsi/zfcp_cfdc.c b/drivers/s390/scsi/zfcp_cfdc.c index 0eb6eef..25d9e0a 100644 --- a/drivers/s390/scsi/zfcp_cfdc.c +++ b/drivers/s390/scsi/zfcp_cfdc.c @@ -10,6 +10,7 @@ #define KMSG_COMPONENT "zfcp" #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#include #include #include #include diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c index 7a149fd..075852f 100644 --- a/drivers/s390/scsi/zfcp_dbf.c +++ b/drivers/s390/scsi/zfcp_dbf.c @@ -10,6 +10,7 @@ #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt #include +#include #include #include "zfcp_dbf.h" #include "zfcp_ext.h" diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c index 5219670..2a1cbb7 100644 --- a/drivers/s390/scsi/zfcp_fc.c +++ b/drivers/s390/scsi/zfcp_fc.c @@ -10,6 +10,7 @@ #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt #include +#include #include #include #include "zfcp_ext.h" diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 6538742..1856489 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -10,6 +10,7 @@ #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt #include +#include #include #include "zfcp_ext.h" #include "zfcp_fc.h" diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c index 6479273..dbfa312 100644 --- a/drivers/s390/scsi/zfcp_qdio.c +++ b/drivers/s390/scsi/zfcp_qdio.c @@ -9,6 +9,7 @@ #define KMSG_COMPONENT "zfcp" #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#include #include "zfcp_ext.h" #include "zfcp_qdio.h" diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index c3c4178..174b6d5 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c @@ -10,6 +10,7 @@ #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt #include +#include #include #include #include "zfcp_ext.h" diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c index a43035d..f5f6069 100644 --- a/drivers/s390/scsi/zfcp_sysfs.c +++ b/drivers/s390/scsi/zfcp_sysfs.c @@ -9,6 +9,7 @@ #define KMSG_COMPONENT "zfcp" #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#include #include "zfcp_ext.h" #define ZFCP_DEV_ATTR(_feat, _name, _mode, _show, _store) \ diff --git a/drivers/sbus/char/bbc_envctrl.c b/drivers/sbus/char/bbc_envctrl.c index 28d86f9..b4951eb 100644 --- a/drivers/sbus/char/bbc_envctrl.c +++ b/drivers/sbus/char/bbc_envctrl.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include diff --git a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c index 4431578..3e59189 100644 --- a/drivers/sbus/char/display7seg.c +++ b/drivers/sbus/char/display7seg.c @@ -12,6 +12,7 @@ #include #include #include /* request_region */ +#include #include #include #include diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c index aa2b60a..c6e2eff 100644 --- a/drivers/sbus/char/envctrl.c +++ b/drivers/sbus/char/envctrl.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/sbus/char/flash.c b/drivers/sbus/char/flash.c index 4108347..19f255b 100644 --- a/drivers/sbus/char/flash.c +++ b/drivers/sbus/char/flash.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/sbus/char/jsflash.c b/drivers/sbus/char/jsflash.c index 869a30b..4942050 100644 --- a/drivers/sbus/char/jsflash.c +++ b/drivers/sbus/char/jsflash.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index 84d3bba..e9788f5 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c @@ -91,6 +91,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/scsi/3w-sas.c b/drivers/scsi/3w-sas.c index 4d314d7..54c5ffb 100644 --- a/drivers/scsi/3w-sas.c +++ b/drivers/scsi/3w-sas.c @@ -65,6 +65,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c index f65a1e9..5faf903 100644 --- a/drivers/scsi/3w-xxxx.c +++ b/drivers/scsi/3w-xxxx.c @@ -205,6 +205,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c index 9f4a911..80dc3ac 100644 --- a/drivers/scsi/53c700.c +++ b/drivers/scsi/53c700.c @@ -117,6 +117,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c index 1ddcf40..fc0b4b8 100644 --- a/drivers/scsi/BusLogic.c +++ b/drivers/scsi/BusLogic.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include diff --git a/drivers/scsi/NCR_D700.c b/drivers/scsi/NCR_D700.c index 1cdf09a..8647256 100644 --- a/drivers/scsi/NCR_D700.c +++ b/drivers/scsi/NCR_D700.c @@ -97,6 +97,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/scsi/NCR_Q720.c b/drivers/scsi/NCR_Q720.c index a8bbdc2..afdbb9a 100644 --- a/drivers/scsi/NCR_Q720.c +++ b/drivers/scsi/NCR_Q720.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/scsi/a100u2w.c b/drivers/scsi/a100u2w.c index ff5716d..dbbc601 100644 --- a/drivers/scsi/a100u2w.c +++ b/drivers/scsi/a100u2w.c @@ -69,7 +69,6 @@ #include #include #include -#include #include #include diff --git a/drivers/scsi/a2091.c b/drivers/scsi/a2091.c index 4b38c47..d8fe5b7 100644 --- a/drivers/scsi/a2091.c +++ b/drivers/scsi/a2091.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include diff --git a/drivers/scsi/a3000.c b/drivers/scsi/a3000.c index 6970ce8..c35fc55 100644 --- a/drivers/scsi/a3000.c +++ b/drivers/scsi/a3000.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include diff --git a/drivers/scsi/a4000t.c b/drivers/scsi/a4000t.c index e3519fa..11ae6be 100644 --- a/drivers/scsi/a4000t.c +++ b/drivers/scsi/a4000t.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/scsi/aacraid/rx.c b/drivers/scsi/aacraid/rx.c index f70d9f8..04057ab 100644 --- a/drivers/scsi/aacraid/rx.c +++ b/drivers/scsi/aacraid/rx.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/scsi/aacraid/sa.c b/drivers/scsi/aacraid/sa.c index b6a3c5c..622c21c 100644 --- a/drivers/scsi/aacraid/sa.c +++ b/drivers/scsi/aacraid/sa.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index 1e5478a..8eab858 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c @@ -254,6 +254,7 @@ #include #include #include +#include #include #include "scsi.h" diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c index 8059494..2a8cf13 100644 --- a/drivers/scsi/aha1542.c +++ b/drivers/scsi/aha1542.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include diff --git a/drivers/scsi/aha1740.c b/drivers/scsi/aha1740.c index 5381357..0107a4c 100644 --- a/drivers/scsi/aha1740.c +++ b/drivers/scsi/aha1740.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #include diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index 1222a7a..4c41332 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c @@ -53,6 +53,7 @@ static struct scsi_transport_template *ahd_linux_transport_template = NULL; #include /* For block_size() */ #include /* For ssleep/msleep */ #include +#include /* * Bucket size for counting good commands in between bad ones. diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index 8cb05dc..5e42dac 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c @@ -129,6 +129,7 @@ static struct scsi_transport_template *ahc_linux_transport_template = NULL; #include /* For fetching system memory size */ #include /* For block_size() */ #include /* For ssleep/msleep */ +#include /* diff --git a/drivers/scsi/aic94xx/aic94xx_hwi.c b/drivers/scsi/aic94xx/aic94xx_hwi.c index eb9dc31..81b736c 100644 --- a/drivers/scsi/aic94xx/aic94xx_hwi.c +++ b/drivers/scsi/aic94xx/aic94xx_hwi.c @@ -25,6 +25,7 @@ */ #include +#include #include #include #include diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c index 996f722..24ac231 100644 --- a/drivers/scsi/aic94xx/aic94xx_init.c +++ b/drivers/scsi/aic94xx/aic94xx_init.c @@ -30,6 +30,7 @@ #include #include #include +#include #include diff --git a/drivers/scsi/aic94xx/aic94xx_scb.c b/drivers/scsi/aic94xx/aic94xx_scb.c index ca55013..c43698b 100644 --- a/drivers/scsi/aic94xx/aic94xx_scb.c +++ b/drivers/scsi/aic94xx/aic94xx_scb.c @@ -24,6 +24,7 @@ * */ +#include #include #include "aic94xx.h" diff --git a/drivers/scsi/aic94xx/aic94xx_sds.c b/drivers/scsi/aic94xx/aic94xx_sds.c index 8630a75..edb43fd 100644 --- a/drivers/scsi/aic94xx/aic94xx_sds.c +++ b/drivers/scsi/aic94xx/aic94xx_sds.c @@ -26,6 +26,7 @@ */ #include +#include #include #include "aic94xx.h" diff --git a/drivers/scsi/aic94xx/aic94xx_seq.c b/drivers/scsi/aic94xx/aic94xx_seq.c index 8f98e33..d01dcc6 100644 --- a/drivers/scsi/aic94xx/aic94xx_seq.c +++ b/drivers/scsi/aic94xx/aic94xx_seq.c @@ -27,6 +27,7 @@ */ #include +#include #include #include #include diff --git a/drivers/scsi/aic94xx/aic94xx_tmf.c b/drivers/scsi/aic94xx/aic94xx_tmf.c index 78eb86f..0add73b 100644 --- a/drivers/scsi/aic94xx/aic94xx_tmf.c +++ b/drivers/scsi/aic94xx/aic94xx_tmf.c @@ -25,6 +25,7 @@ */ #include +#include #include "aic94xx.h" #include "aic94xx_sas.h" #include "aic94xx_hwi.h" diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 47d5d19..ffbe219 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -58,6 +58,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c index 4240b05..158ebc3 100644 --- a/drivers/scsi/atari_NCR5380.c +++ b/drivers/scsi/atari_NCR5380.c @@ -651,6 +651,7 @@ static inline void NCR5380_print_phase(struct Scsi_Host *instance) * interrupt or bottom half. */ +#include #include #include diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index b137e56..ab5bdda 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index fcfb29e..dd5b105 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c @@ -19,6 +19,7 @@ */ #include #include +#include #include #include #include diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c index 6bff08e..13f5feb 100644 --- a/drivers/scsi/bfa/bfad.c +++ b/drivers/scsi/bfa/bfad.c @@ -19,6 +19,7 @@ * bfad.c Linux driver PCI interface module. */ +#include #include #include #include "bfad_drv.h" diff --git a/drivers/scsi/bfa/bfad_attr.c b/drivers/scsi/bfa/bfad_attr.c index d97f691..6a2efdd 100644 --- a/drivers/scsi/bfa/bfad_attr.c +++ b/drivers/scsi/bfa/bfad_attr.c @@ -19,6 +19,7 @@ * bfa_attr.c Linux driver configuration interface module. */ +#include #include "bfad_drv.h" #include "bfad_im.h" #include "bfad_trcmod.h" diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c index f9fc67a..78f42aa 100644 --- a/drivers/scsi/bfa/bfad_im.c +++ b/drivers/scsi/bfa/bfad_im.c @@ -19,6 +19,7 @@ * bfad_im.c Linux driver IM module. */ +#include #include "bfad_drv.h" #include "bfad_im.h" #include "bfad_trcmod.h" diff --git a/drivers/scsi/bfa/rport.c b/drivers/scsi/bfa/rport.c index 8e73dd9..7b096f2 100644 --- a/drivers/scsi/bfa/rport.c +++ b/drivers/scsi/bfa/rport.c @@ -19,6 +19,7 @@ * rport.c Remote port implementation. */ +#include #include #include #include "fcbuild.h" diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c index 1af578d..18352ff 100644 --- a/drivers/scsi/bnx2i/bnx2i_hwi.c +++ b/drivers/scsi/bnx2i/bnx2i_hwi.c @@ -11,6 +11,7 @@ * Written by: Anil Veerabhadrappa (anilgv@broadcom.com) */ +#include #include #include #include "bnx2i.h" diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c index cb71dc9..f2e9b18 100644 --- a/drivers/scsi/bnx2i/bnx2i_iscsi.c +++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c @@ -12,6 +12,7 @@ * Written by: Anil Veerabhadrappa (anilgv@broadcom.com) */ +#include #include #include #include "bnx2i.h" diff --git a/drivers/scsi/bvme6000_scsi.c b/drivers/scsi/bvme6000_scsi.c index 5799cb5..d40ea2f 100644 --- a/drivers/scsi/bvme6000_scsi.c +++ b/drivers/scsi/bvme6000_scsi.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c index fe11c1d..4799d43 100644 --- a/drivers/scsi/ch.c +++ b/drivers/scsi/ch.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/drivers/scsi/cxgb3i/cxgb3i_ddp.c b/drivers/scsi/cxgb3i/cxgb3i_ddp.c index 344fd53..b58d913 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_ddp.c +++ b/drivers/scsi/cxgb3i/cxgb3i_ddp.c @@ -10,6 +10,7 @@ * Written by: Karen Xie (kxie@chelsio.com) */ +#include #include #include diff --git a/drivers/scsi/cxgb3i/cxgb3i_ddp.h b/drivers/scsi/cxgb3i/cxgb3i_ddp.h index 87dd56b..6761b32 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_ddp.h +++ b/drivers/scsi/cxgb3i/cxgb3i_ddp.h @@ -13,6 +13,7 @@ #ifndef __CXGB3I_ULP2_DDP_H__ #define __CXGB3I_ULP2_DDP_H__ +#include #include /** diff --git a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c index b7c3058..7b686ab 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c +++ b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c @@ -12,6 +12,7 @@ */ #include +#include #include #include #include diff --git a/drivers/scsi/cxgb3i/cxgb3i_offload.c b/drivers/scsi/cxgb3i/cxgb3i_offload.c index 3e08c43..a175be9 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_offload.c +++ b/drivers/scsi/cxgb3i/cxgb3i_offload.c @@ -13,6 +13,7 @@ */ #include +#include #include #include "cxgb3_defs.h" diff --git a/drivers/scsi/cxgb3i/cxgb3i_pdu.c b/drivers/scsi/cxgb3i/cxgb3i_pdu.c index 9c38539..dc5e3e7 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_pdu.c +++ b/drivers/scsi/cxgb3i/cxgb3i_pdu.c @@ -12,6 +12,7 @@ * Written by: Karen Xie (kxie@chelsio.com) */ +#include #include #include #include diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c index 6c59c02..bd977be 100644 --- a/drivers/scsi/dc395x.c +++ b/drivers/scsi/dc395x.c @@ -57,6 +57,7 @@ #include #include #include +#include #include #include diff --git a/drivers/scsi/device_handler/scsi_dh.c b/drivers/scsi/device_handler/scsi_dh.c index e19a1a5..6fae3d2 100644 --- a/drivers/scsi/device_handler/scsi_dh.c +++ b/drivers/scsi/device_handler/scsi_dh.c @@ -21,6 +21,7 @@ * Mike Anderson */ +#include #include #include "../scsi_priv.h" diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index bc9e94f..1a970a7 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -19,6 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ +#include #include #include #include diff --git a/drivers/scsi/device_handler/scsi_dh_emc.c b/drivers/scsi/device_handler/scsi_dh_emc.c index 63032ec3..e8a0bc3 100644 --- a/drivers/scsi/device_handler/scsi_dh_emc.c +++ b/drivers/scsi/device_handler/scsi_dh_emc.c @@ -20,6 +20,7 @@ * along with this program; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include #include #include #include diff --git a/drivers/scsi/device_handler/scsi_dh_hp_sw.c b/drivers/scsi/device_handler/scsi_dh_hp_sw.c index 857fdd6..e391664 100644 --- a/drivers/scsi/device_handler/scsi_dh_hp_sw.c +++ b/drivers/scsi/device_handler/scsi_dh_hp_sw.c @@ -21,6 +21,7 @@ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include #include #include #include diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c index 1a66019..5b683e4 100644 --- a/drivers/scsi/device_handler/scsi_dh_rdac.c +++ b/drivers/scsi/device_handler/scsi_dh_rdac.c @@ -23,6 +23,7 @@ #include #include #include +#include #define RDAC_NAME "rdac" #define RDAC_RETRY_COUNT 5 diff --git a/drivers/scsi/eata.c b/drivers/scsi/eata.c index 3c5abf7..d1c3137 100644 --- a/drivers/scsi/eata.c +++ b/drivers/scsi/eata.c @@ -490,6 +490,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/scsi/eata_pio.c b/drivers/scsi/eata_pio.c index 152dd15..60886c1 100644 --- a/drivers/scsi/eata_pio.c +++ b/drivers/scsi/eata_pio.c @@ -50,7 +50,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 2f47ae7..f01b9b4 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c index 511cb6b..3440da4 100644 --- a/drivers/scsi/fcoe/libfcoe.c +++ b/drivers/scsi/fcoe/libfcoe.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include diff --git a/drivers/scsi/fd_mcs.c b/drivers/scsi/fd_mcs.c index 85bd54c7..2ad95aa 100644 --- a/drivers/scsi/fd_mcs.c +++ b/drivers/scsi/fd_mcs.c @@ -88,6 +88,7 @@ #include #include #include +#include #include #include diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c index 32eef66..e296bcc5 100644 --- a/drivers/scsi/fdomain.c +++ b/drivers/scsi/fdomain.c @@ -279,6 +279,7 @@ #include #include #include +#include #include #include diff --git a/drivers/scsi/fnic/fnic_fcs.c b/drivers/scsi/fnic/fnic_fcs.c index 54f8d0e..5259888 100644 --- a/drivers/scsi/fnic/fnic_fcs.c +++ b/drivers/scsi/fnic/fnic_fcs.c @@ -17,6 +17,7 @@ */ #include #include +#include #include #include #include diff --git a/drivers/scsi/fnic/fnic_main.c b/drivers/scsi/fnic/fnic_main.c index 507e26c..97b2125 100644 --- a/drivers/scsi/fnic/fnic_main.c +++ b/drivers/scsi/fnic/fnic_main.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index 65a39b0..3cc47c6 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/scsi/fnic/vnic_dev.c b/drivers/scsi/fnic/vnic_dev.c index 5667706..db71014 100644 --- a/drivers/scsi/fnic/vnic_dev.c +++ b/drivers/scsi/fnic/vnic_dev.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "vnic_resource.h" #include "vnic_devcmd.h" #include "vnic_dev.h" diff --git a/drivers/scsi/fnic/vnic_rq.c b/drivers/scsi/fnic/vnic_rq.c index bedd0d2..fd2068f 100644 --- a/drivers/scsi/fnic/vnic_rq.c +++ b/drivers/scsi/fnic/vnic_rq.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "vnic_dev.h" #include "vnic_rq.h" diff --git a/drivers/scsi/fnic/vnic_wq.c b/drivers/scsi/fnic/vnic_wq.c index 1f9ea79..a414135 100644 --- a/drivers/scsi/fnic/vnic_wq.c +++ b/drivers/scsi/fnic/vnic_wq.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "vnic_dev.h" #include "vnic_wq.h" diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index ba3c94c..35a4b30 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -121,6 +121,7 @@ #include #include #include +#include #ifdef GDTH_RTC #include diff --git a/drivers/scsi/gdth_proc.c b/drivers/scsi/gdth_proc.c index ffb2b21..0572b9b 100644 --- a/drivers/scsi/gdth_proc.c +++ b/drivers/scsi/gdth_proc.c @@ -3,6 +3,7 @@ */ #include +#include int gdth_proc_info(struct Scsi_Host *host, char *buffer,char **start,off_t offset,int length, int inout) diff --git a/drivers/scsi/gvp11.c b/drivers/scsi/gvp11.c index 5d1bf7e..48f4068 100644 --- a/drivers/scsi/gvp11.c +++ b/drivers/scsi/gvp11.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 09dbcb8..6660fa9 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/scsi/hptiop.c b/drivers/scsi/hptiop.c index 4f05565..645f7cd 100644 --- a/drivers/scsi/hptiop.c +++ b/drivers/scsi/hptiop.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index 4e577e2..c2eea71 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index dc1bcbe..ff5ec5a 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -70,6 +70,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/scsi/ibmvscsi/ibmvstgt.c b/drivers/scsi/ibmvscsi/ibmvstgt.c index d5eaf97..e2056d5 100644 --- a/drivers/scsi/ibmvscsi/ibmvstgt.c +++ b/drivers/scsi/ibmvscsi/ibmvstgt.c @@ -23,6 +23,7 @@ */ #include #include +#include #include #include #include diff --git a/drivers/scsi/ibmvscsi/rpa_vscsi.c b/drivers/scsi/ibmvscsi/rpa_vscsi.c index 63a30cb..a864ccc 100644 --- a/drivers/scsi/ibmvscsi/rpa_vscsi.c +++ b/drivers/scsi/ibmvscsi/rpa_vscsi.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include "ibmvscsi.h" diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c index c2a9a13..4734ab0 100644 --- a/drivers/scsi/imm.c +++ b/drivers/scsi/imm.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index c79cd98..520461b 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -59,6 +59,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 249053a..0ee725c 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include diff --git a/drivers/scsi/jazz_esp.c b/drivers/scsi/jazz_esp.c index b2d481d..08e26d4 100644 --- a/drivers/scsi/jazz_esp.c +++ b/drivers/scsi/jazz_esp.c @@ -4,6 +4,7 @@ */ #include +#include #include #include #include diff --git a/drivers/scsi/lasi700.c b/drivers/scsi/lasi700.c index b3d3131..23880f8 100644 --- a/drivers/scsi/lasi700.c +++ b/drivers/scsi/lasi700.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c index 9b0a519..1087a7f1 100644 --- a/drivers/scsi/libfc/fc_disc.c +++ b/drivers/scsi/libfc/fc_disc.c @@ -33,6 +33,7 @@ */ #include +#include #include #include diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c index 7f43647..e5df0d4 100644 --- a/drivers/scsi/libfc/fc_exch.c +++ b/drivers/scsi/libfc/fc_exch.c @@ -24,7 +24,7 @@ */ #include -#include +#include #include #include diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c index 774e7ac..17396c7 100644 --- a/drivers/scsi/libfc/fc_fcp.c +++ b/drivers/scsi/libfc/fc_fcp.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include diff --git a/drivers/scsi/libfc/fc_frame.c b/drivers/scsi/libfc/fc_frame.c index 6da01c6..981329a 100644 --- a/drivers/scsi/libfc/fc_frame.c +++ b/drivers/scsi/libfc/fc_frame.c @@ -24,6 +24,7 @@ #include #include #include +#include #include diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c index 7ec8ce7..d126ecf 100644 --- a/drivers/scsi/libfc/fc_lport.c +++ b/drivers/scsi/libfc/fc_lport.c @@ -88,6 +88,7 @@ */ #include +#include #include #include diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c index 97923bb..b37d0ff 100644 --- a/drivers/scsi/libfc/fc_rport.c +++ b/drivers/scsi/libfc/fc_rport.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 685eaec..abdb66d 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/scsi/libiscsi_tcp.c b/drivers/scsi/libiscsi_tcp.c index 4ad87fd..5c92620 100644 --- a/drivers/scsi/libiscsi_tcp.c +++ b/drivers/scsi/libiscsi_tcp.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index e155011..b00efd1 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c @@ -22,6 +22,7 @@ */ #include +#include #include #include "sas_internal.h" diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c index facc5bfc..f583193 100644 --- a/drivers/scsi/libsas/sas_discover.c +++ b/drivers/scsi/libsas/sas_discover.c @@ -23,6 +23,7 @@ */ #include +#include #include #include #include "sas_internal.h" diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index 33cf988..c65af02 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c @@ -24,6 +24,7 @@ #include #include +#include #include "sas_internal.h" diff --git a/drivers/scsi/libsas/sas_host_smp.c b/drivers/scsi/libsas/sas_host_smp.c index 1bc3b75..04ad8dd 100644 --- a/drivers/scsi/libsas/sas_host_smp.c +++ b/drivers/scsi/libsas/sas_host_smp.c @@ -10,6 +10,7 @@ */ #include #include +#include #include "sas_internal.h" diff --git a/drivers/scsi/libsas/sas_init.c b/drivers/scsi/libsas/sas_init.c index 9cd5abe..2dc5534 100644 --- a/drivers/scsi/libsas/sas_init.c +++ b/drivers/scsi/libsas/sas_init.c @@ -24,6 +24,7 @@ */ #include +#include #include #include #include diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index 14b1319..2660e1b 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include diff --git a/drivers/scsi/libsrp.c b/drivers/scsi/libsrp.c index 2277516..ff6a28c 100644 --- a/drivers/scsi/libsrp.c +++ b/drivers/scsi/libsrp.c @@ -19,6 +19,7 @@ * 02110-1301 USA */ #include +#include #include #include #include diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 64cd17e..1849e33 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c index 692c29f..ec37238 100644 --- a/drivers/scsi/lpfc/lpfc_bsg.c +++ b/drivers/scsi/lpfc/lpfc_bsg.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index c7e9219..463b749 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index 3915841..a80d938 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index ee980bd..5fbdb22 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -21,6 +21,7 @@ /* See Fibre Channel protocol T11 FC-LS for details */ #include #include +#include #include #include diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index c555e3b..e1466ee 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -20,6 +20,7 @@ *******************************************************************/ #include +#include #include #include #include diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index ea44239..774663e 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c index 1e61ae3..72e6adb 100644 --- a/drivers/scsi/lpfc/lpfc_mbox.c +++ b/drivers/scsi/lpfc/lpfc_mbox.c @@ -21,6 +21,7 @@ #include #include +#include #include #include diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c index a1b6db6..8f879e4 100644 --- a/drivers/scsi/lpfc/lpfc_mem.c +++ b/drivers/scsi/lpfc/lpfc_mem.c @@ -20,6 +20,7 @@ *******************************************************************/ #include +#include #include #include diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index d20ae6b..e331204 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -21,6 +21,7 @@ #include #include +#include #include #include diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index b16bb2c..dccdb82 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -19,6 +19,7 @@ * included with this package. * *******************************************************************/ #include +#include #include #include #include diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index fe6660c..049fb9a 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c index 869f76c..ffd575c 100644 --- a/drivers/scsi/lpfc/lpfc_vport.c +++ b/drivers/scsi/lpfc/lpfc_vport.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include diff --git a/drivers/scsi/mac_esp.c b/drivers/scsi/mac_esp.c index 4a90eaf..3893337 100644 --- a/drivers/scsi/mac_esp.c +++ b/drivers/scsi/mac_esp.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index 49eb061..4bf7edc 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include "scsi.h" diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c index 7f97796..a7810a1 100644 --- a/drivers/scsi/megaraid/megaraid_mbox.c +++ b/drivers/scsi/megaraid/megaraid_mbox.c @@ -70,6 +70,7 @@ * For history of changes, see Documentation/ChangeLog.megaraid */ +#include #include "megaraid_mbox.h" static int megaraid_init(void); diff --git a/drivers/scsi/megaraid/megaraid_mm.c b/drivers/scsi/megaraid/megaraid_mm.c index f680561..36e0b7d 100644 --- a/drivers/scsi/megaraid/megaraid_mm.c +++ b/drivers/scsi/megaraid/megaraid_mm.c @@ -15,6 +15,7 @@ * Common management module */ #include +#include #include #include "megaraid_mm.h" diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index 409648f..99e4478 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c index 11aa917..a1c97e8 100644 --- a/drivers/scsi/mesh.c +++ b/drivers/scsi/mesh.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/scsi/mpt2sas/mpt2sas_config.c b/drivers/scsi/mpt2sas/mpt2sas_config.c index 411c27d..cf44b35 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_config.c +++ b/drivers/scsi/mpt2sas/mpt2sas_config.c @@ -51,6 +51,7 @@ #include #include #include +#include #include "mpt2sas_base.h" diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c index c7ec3f1..be171ed 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c @@ -53,6 +53,7 @@ #include #include #include +#include #include "mpt2sas_base.h" diff --git a/drivers/scsi/mpt2sas/mpt2sas_transport.c b/drivers/scsi/mpt2sas/mpt2sas_transport.c index 789f9ee..bd7ca2b 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_transport.c +++ b/drivers/scsi/mpt2sas/mpt2sas_transport.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include diff --git a/drivers/scsi/mvme16x_scsi.c b/drivers/scsi/mvme16x_scsi.c index b5fbfd6..39f554f 100644 --- a/drivers/scsi/mvme16x_scsi.c +++ b/drivers/scsi/mvme16x_scsi.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/scsi/mvsas/mv_sas.h b/drivers/scsi/mvsas/mv_sas.h index aa2270a..885858b 100644 --- a/drivers/scsi/mvsas/mv_sas.h +++ b/drivers/scsi/mvsas/mv_sas.h @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c index a2d5698..d013a2a 100644 --- a/drivers/scsi/ncr53c8xx.c +++ b/drivers/scsi/ncr53c8xx.c @@ -98,6 +98,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c index 2c98a6e..4c1e545 100644 --- a/drivers/scsi/nsp32.c +++ b/drivers/scsi/nsp32.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c index 60de850..ee4b691 100644 --- a/drivers/scsi/osd/osd_initiator.c +++ b/drivers/scsi/osd/osd_initiator.c @@ -39,6 +39,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include + #include #include #include diff --git a/drivers/scsi/osd/osd_uld.c b/drivers/scsi/osd/osd_uld.c index 0a90702..ffdd9fd 100644 --- a/drivers/scsi/osd/osd_uld.c +++ b/drivers/scsi/osd/osd_uld.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #include diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c index acb8358..b219118 100644 --- a/drivers/scsi/osst.c +++ b/drivers/scsi/osst.c @@ -38,6 +38,7 @@ static const char * osst_version = "0.99.4"; #include #include #include +#include #include #include #include diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c index 14b13ac..45bc197 100644 --- a/drivers/scsi/pm8001/pm8001_ctl.c +++ b/drivers/scsi/pm8001/pm8001_ctl.c @@ -38,6 +38,7 @@ * */ #include +#include #include "pm8001_sas.h" #include "pm8001_ctl.h" diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index 7985ae4..909c00e 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c @@ -37,6 +37,7 @@ * POSSIBILITY OF SUCH DAMAGES. * */ + #include #include "pm8001_sas.h" #include "pm8001_hwi.h" #include "pm8001_chips.h" diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index f80c1da8..f8c86b2 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c @@ -38,6 +38,7 @@ * */ +#include #include "pm8001_sas.h" #include "pm8001_chips.h" diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c index 3b2c98f..bff4f51 100644 --- a/drivers/scsi/pm8001/pm8001_sas.c +++ b/drivers/scsi/pm8001/pm8001_sas.c @@ -38,6 +38,7 @@ * */ +#include #include "pm8001_sas.h" /** diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index 9b1c143..53aefff 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c index 8aa0bd9..7bc2d79 100644 --- a/drivers/scsi/ppa.c +++ b/drivers/scsi/ppa.c @@ -10,6 +10,7 @@ #include #include +#include #include #include #include diff --git a/drivers/scsi/ps3rom.c b/drivers/scsi/ps3rom.c index db90caf..92ffbb5 100644 --- a/drivers/scsi/ps3rom.c +++ b/drivers/scsi/ps3rom.c @@ -20,6 +20,7 @@ #include #include +#include #include #include diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c index 49ac414..8ef8778 100644 --- a/drivers/scsi/qla1280.c +++ b/drivers/scsi/qla1280.c @@ -346,7 +346,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 90d1e06..29414df 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -8,6 +8,7 @@ #include #include +#include #include static int qla24xx_vport_disable(struct fc_vport *, bool); diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index a67b2ba..4229bb4 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -8,6 +8,7 @@ #include "qla_gbl.h" #include +#include #include #include "qla_devtbl.h" diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index ab90329..875adb4 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -7,6 +7,7 @@ #include "qla_def.h" #include +#include #include #include diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 6e53bdb..e95ebab 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -7,6 +7,7 @@ #include "qla_def.h" #include +#include /* diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index ff17dee..8220e7b 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c @@ -9,6 +9,7 @@ #include #include +#include #include #include diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 46720b2..b696cff 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index 371dc89..8b3de4e 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c @@ -7,6 +7,7 @@ #include "qla_def.h" #include +#include #include #include diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 83c8b5e..2ccad36 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@ -5,6 +5,7 @@ * See LICENSE.qla4xxx for copyright and licensing details. */ #include +#include #include #include diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c index 1b82170..aa40649 100644 --- a/drivers/scsi/qlogicpti.c +++ b/drivers/scsi/qlogicpti.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 0b575c8..3e10c30 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index 37af178..43fad4c 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 08ed506..d45c69c 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include diff --git a/drivers/scsi/scsi_netlink.c b/drivers/scsi/scsi_netlink.c index 0fd6ae6..d53e650 100644 --- a/drivers/scsi/scsi_netlink.c +++ b/drivers/scsi/scsi_netlink.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/drivers/scsi/scsi_proc.c b/drivers/scsi/scsi_proc.c index 77fbddb..c99da92 100644 --- a/drivers/scsi/scsi_proc.c +++ b/drivers/scsi/scsi_proc.c @@ -20,12 +20,12 @@ #include #include #include -#include #include #include #include #include #include +#include #include #include diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 4bc8b77..38518b0 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 19ec9e2..429c9b7 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -7,6 +7,7 @@ */ #include +#include #include #include #include diff --git a/drivers/scsi/scsi_tgt_if.c b/drivers/scsi/scsi_tgt_if.c index 0e9533f..a87e21c 100644 --- a/drivers/scsi/scsi_tgt_if.c +++ b/drivers/scsi/scsi_tgt_if.c @@ -20,6 +20,7 @@ * 02110-1301 USA */ #include +#include #include #include #include diff --git a/drivers/scsi/scsi_tgt_lib.c b/drivers/scsi/scsi_tgt_lib.c index 1030327..66241dd 100644 --- a/drivers/scsi/scsi_tgt_lib.c +++ b/drivers/scsi/scsi_tgt_lib.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index 1d5b721..a895a0e 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -27,6 +27,7 @@ */ #include #include +#include #include #include #include diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index ea3892e..1e6d479 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -22,6 +22,7 @@ */ #include #include +#include #include #include #include diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c index c25bd9a..8a172d4 100644 --- a/drivers/scsi/scsi_transport_spi.c +++ b/drivers/scsi/scsi_transport_spi.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include "scsi_priv.h" #include diff --git a/drivers/scsi/scsicam.c b/drivers/scsi/scsicam.c index 3f21bc6..6803b1e 100644 --- a/drivers/scsi/scsicam.c +++ b/drivers/scsi/scsicam.c @@ -11,6 +11,7 @@ */ #include +#include #include #include #include diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 7b75c8a..58c62ff 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c index 0d9d6f7..7f5a6a8 100644 --- a/drivers/scsi/ses.c +++ b/drivers/scsi/ses.c @@ -21,6 +21,7 @@ **----------------------------------------------------------------------------- */ +#include #include #include #include diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index c996d98..dee1c96 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -38,6 +38,7 @@ static int sg_version_num = 30534; /* 2 digits for each component */ #include #include #include +#include #include #include #include diff --git a/drivers/scsi/sim710.c b/drivers/scsi/sim710.c index 6dc8b84..8ac6ce7 100644 --- a/drivers/scsi/sim710.c +++ b/drivers/scsi/sim710.c @@ -27,6 +27,7 @@ */ #include +#include #include #include diff --git a/drivers/scsi/sni_53c710.c b/drivers/scsi/sni_53c710.c index 56cf0bb..9acc2b2 100644 --- a/drivers/scsi/sni_53c710.c +++ b/drivers/scsi/sni_53c710.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index d6f340f..0a90abc 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c index 291236e..cbb38c5 100644 --- a/drivers/scsi/sr_ioctl.c +++ b/drivers/scsi/sr_ioctl.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include diff --git a/drivers/scsi/sr_vendor.c b/drivers/scsi/sr_vendor.c index 4ad3e01..92cc2ef 100644 --- a/drivers/scsi/sr_vendor.c +++ b/drivers/scsi/sr_vendor.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index f67d1a1..3ea1a71 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -27,6 +27,7 @@ static const char *verstr = "20081215"; #include #include #include +#include #include #include #include diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c index fd7b15b..9c73dbd 100644 --- a/drivers/scsi/stex.c +++ b/drivers/scsi/stex.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/scsi/sun3_NCR5380.c b/drivers/scsi/sun3_NCR5380.c index 75da6e5..b5838d5 100644 --- a/drivers/scsi/sun3_NCR5380.c +++ b/drivers/scsi/sun3_NCR5380.c @@ -645,6 +645,7 @@ __inline__ void NCR5380_print_phase(struct Scsi_Host *instance) { }; * interrupt or bottom half. */ +#include #include #include diff --git a/drivers/scsi/sun3x_esp.c b/drivers/scsi/sun3x_esp.c index 34a9962..0621037 100644 --- a/drivers/scsi/sun3x_esp.c +++ b/drivers/scsi/sun3x_esp.c @@ -4,6 +4,7 @@ */ #include +#include #include #include #include diff --git a/drivers/scsi/sun_esp.c b/drivers/scsi/sun_esp.c index 3d73aad..fc23d27 100644 --- a/drivers/scsi/sun_esp.c +++ b/drivers/scsi/sun_esp.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include diff --git a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c index 9a42734..27866b0 100644 --- a/drivers/scsi/tmscsim.c +++ b/drivers/scsi/tmscsim.c @@ -233,6 +233,7 @@ #include #include #include +#include #include #include diff --git a/drivers/scsi/u14-34f.c b/drivers/scsi/u14-34f.c index 26e8e0e..5d9fdee 100644 --- a/drivers/scsi/u14-34f.c +++ b/drivers/scsi/u14-34f.c @@ -420,6 +420,7 @@ #include #include #include +#include #include #include diff --git a/drivers/scsi/vmw_pvscsi.c b/drivers/scsi/vmw_pvscsi.c index e4ac582..2689445 100644 --- a/drivers/scsi/vmw_pvscsi.c +++ b/drivers/scsi/vmw_pvscsi.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include diff --git a/drivers/scsi/wd7000.c b/drivers/scsi/wd7000.c index 2f6e9d8..d0b7d2f 100644 --- a/drivers/scsi/wd7000.c +++ b/drivers/scsi/wd7000.c @@ -171,7 +171,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/scsi/zorro7xx.c b/drivers/scsi/zorro7xx.c index 64d40a2..105449c 100644 --- a/drivers/scsi/zorro7xx.c +++ b/drivers/scsi/zorro7xx.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c index ae0251e..78ed24b 100644 --- a/drivers/serial/68328serial.c +++ b/drivers/serial/68328serial.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index c3db16b..2b1ea3d 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include diff --git a/drivers/serial/8250_gsc.c b/drivers/serial/8250_gsc.c index 33149d9..d8c0ffb 100644 --- a/drivers/serial/8250_gsc.c +++ b/drivers/serial/8250_gsc.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include diff --git a/drivers/serial/8250_hp300.c b/drivers/serial/8250_hp300.c index 0e1410f..c13438c 100644 --- a/drivers/serial/8250_hp300.c +++ b/drivers/serial/8250_hp300.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include "8250.h" diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c index e4b3c2c..b09a638 100644 --- a/drivers/serial/amba-pl010.c +++ b/drivers/serial/amba-pl010.c @@ -47,6 +47,7 @@ #include #include #include +#include #include diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c index ce6c353..743ebf5 100644 --- a/drivers/serial/amba-pl011.c +++ b/drivers/serial/amba-pl011.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index fcf273e..96f7e74 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c @@ -14,6 +14,7 @@ #include #include +#include #include #include #include diff --git a/drivers/serial/bfin_sport_uart.c b/drivers/serial/bfin_sport_uart.c index 7c72888..c88f8ad 100644 --- a/drivers/serial/bfin_sport_uart.c +++ b/drivers/serial/bfin_sport_uart.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/serial/cpm_uart/cpm_uart_cpm1.c index 1b94c56..3fc1d66 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c +++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c @@ -29,6 +29,7 @@ #include #include +#include #include #include #include diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c index 722eac1..814ac00 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c +++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index e579d7a..4315b23 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include diff --git a/drivers/serial/ioc3_serial.c b/drivers/serial/ioc3_serial.c index 23ba6b4..f164ba4 100644 --- a/drivers/serial/ioc3_serial.c +++ b/drivers/serial/ioc3_serial.c @@ -20,6 +20,7 @@ #include #include #include +#include /* * Interesting things about the ioc3 diff --git a/drivers/serial/ioc4_serial.c b/drivers/serial/ioc4_serial.c index 836d9ab..8ad28fc 100644 --- a/drivers/serial/ioc4_serial.c +++ b/drivers/serial/ioc4_serial.c @@ -22,6 +22,7 @@ #include #include #include +#include /* * interesting things about the ioc4 diff --git a/drivers/serial/jsm/jsm_driver.c b/drivers/serial/jsm/jsm_driver.c index 12cb5e4..eaf5450 100644 --- a/drivers/serial/jsm/jsm_driver.c +++ b/drivers/serial/jsm/jsm_driver.c @@ -26,6 +26,7 @@ ***********************************************************************/ #include #include +#include #include "jsm.h" diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/serial/jsm/jsm_tty.c index 5673ca9..7a4a914 100644 --- a/drivers/serial/jsm/jsm_tty.c +++ b/drivers/serial/jsm/jsm_tty.c @@ -30,6 +30,7 @@ #include #include /* For udelay */ #include +#include #include "jsm.h" diff --git a/drivers/serial/max3100.c b/drivers/serial/max3100.c index 3c30c56..3351c3b 100644 --- a/drivers/serial/max3100.c +++ b/drivers/serial/max3100.c @@ -41,6 +41,7 @@ #define MAX_MAX3100 4 #include +#include #include #include #include diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c index b5496c2..55e113a 100644 --- a/drivers/serial/mpsc.c +++ b/drivers/serial/mpsc.c @@ -70,6 +70,7 @@ #include #include #include +#include #include #include diff --git a/drivers/serial/mux.c b/drivers/serial/mux.c index 7571aaa..9711e06 100644 --- a/drivers/serial/mux.c +++ b/drivers/serial/mux.c @@ -22,7 +22,6 @@ #include #include #include -#include #include /* for udelay */ #include #include diff --git a/drivers/serial/of_serial.c b/drivers/serial/of_serial.c index cdf172e..4abfebd 100644 --- a/drivers/serial/of_serial.c +++ b/drivers/serial/of_serial.c @@ -11,6 +11,7 @@ */ #include #include +#include #include #include #include diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c index f020de1..4eaa043 100644 --- a/drivers/serial/pmac_zilog.c +++ b/drivers/serial/pmac_zilog.c @@ -54,7 +54,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c index 56ee082..1102a39 100644 --- a/drivers/serial/pxa.c +++ b/drivers/serial/pxa.c @@ -44,6 +44,7 @@ #include #include #include +#include struct uart_pxa_port { struct uart_port port; diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 309de6b..8eb094c 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -50,6 +50,7 @@ #include #include #include +#include #ifdef CONFIG_SUPERH #include diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index 170d3d6..81fc269 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/serial/sunsu.c @@ -29,6 +29,7 @@ #include #include #include +#include #ifdef CONFIG_SERIO #include #endif diff --git a/drivers/serial/timbuart.c b/drivers/serial/timbuart.c index 7bf1026..786ba85 100644 --- a/drivers/serial/timbuart.c +++ b/drivers/serial/timbuart.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "timbuart.h" diff --git a/drivers/serial/ucc_uart.c b/drivers/serial/ucc_uart.c index 465f2fa..0749049 100644 --- a/drivers/serial/ucc_uart.c +++ b/drivers/serial/ucc_uart.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include diff --git a/drivers/sh/intc.c b/drivers/sh/intc.c index a3d8677..94ad6bd 100644 --- a/drivers/sh/intc.c +++ b/drivers/sh/intc.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/sn/ioc3.c b/drivers/sn/ioc3.c index 66802a4..b3b33fa 100644 --- a/drivers/sn/ioc3.c +++ b/drivers/sn/ioc3.c @@ -16,6 +16,7 @@ #include #include #include +#include #define IOC3_PCI_SIZE 0x100000 diff --git a/drivers/spi/amba-pl022.c b/drivers/spi/amba-pl022.c index 9aeb681..e9aeee1 100644 --- a/drivers/spi/amba-pl022.c +++ b/drivers/spi/amba-pl022.c @@ -44,6 +44,7 @@ #include #include #include +#include /* * This macro is used to define some register default values. diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c index d21c24e..c4e0442 100644 --- a/drivers/spi/atmel_spi.c +++ b/drivers/spi/atmel_spi.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include diff --git a/drivers/spi/au1550_spi.c b/drivers/spi/au1550_spi.c index ba8ac4f..3c9ade6 100644 --- a/drivers/spi/au1550_spi.c +++ b/drivers/spi/au1550_spi.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c index 225ab60..95afb6b7 100644 --- a/drivers/spi/davinci_spi.c +++ b/drivers/spi/davinci_spi.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include diff --git a/drivers/spi/dw_spi.c b/drivers/spi/dw_spi.c index 8ed38f1..d256cb0 100644 --- a/drivers/spi/dw_spi.c +++ b/drivers/spi/dw_spi.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include diff --git a/drivers/spi/dw_spi_mmio.c b/drivers/spi/dw_spi_mmio.c index e35b45a..db35bd9 100644 --- a/drivers/spi/dw_spi_mmio.c +++ b/drivers/spi/dw_spi_mmio.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include diff --git a/drivers/spi/dw_spi_pci.c b/drivers/spi/dw_spi_pci.c index 1f0735f..1f52755 100644 --- a/drivers/spi/dw_spi_pci.c +++ b/drivers/spi/dw_spi_pci.c @@ -19,6 +19,7 @@ #include #include +#include #include #include diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c index 0474786..77d4cc8 100644 --- a/drivers/spi/mpc52xx_psc_spi.c +++ b/drivers/spi/mpc52xx_psc_spi.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include diff --git a/drivers/spi/mpc52xx_spi.c b/drivers/spi/mpc52xx_spi.c index 6eab465..cd68f1c 100644 --- a/drivers/spi/mpc52xx_spi.c +++ b/drivers/spi/mpc52xx_spi.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c index 4dd786b..d8356af 100644 --- a/drivers/spi/omap2_mcspi.c +++ b/drivers/spi/omap2_mcspi.c @@ -32,6 +32,7 @@ #include #include #include +#include #include diff --git a/drivers/spi/omap_spi_100k.c b/drivers/spi/omap_spi_100k.c index 5355d90..24668b3 100644 --- a/drivers/spi/omap_spi_100k.c +++ b/drivers/spi/omap_spi_100k.c @@ -33,6 +33,7 @@ #include #include #include +#include #include diff --git a/drivers/spi/omap_uwire.c b/drivers/spi/omap_uwire.c index 6c3a855..160d326 100644 --- a/drivers/spi/omap_uwire.c +++ b/drivers/spi/omap_uwire.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index c2f707e..3682835 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index b76f246..9ffb0fd 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c index 1d41058..10a6dc3 100644 --- a/drivers/spi/spi_bfin5xx.c +++ b/drivers/spi/spi_bfin5xx.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/spi/spi_bitbang.c b/drivers/spi/spi_bitbang.c index f1db395..5265330a 100644 --- a/drivers/spi/spi_bitbang.c +++ b/drivers/spi/spi_bitbang.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c index 0ddbbe4..7972e90 100644 --- a/drivers/spi/spi_imx.c +++ b/drivers/spi/spi_imx.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/spi/spi_mpc8xxx.c b/drivers/spi/spi_mpc8xxx.c index 4f0cc9d..14d0523 100644 --- a/drivers/spi/spi_mpc8xxx.c +++ b/drivers/spi/spi_mpc8xxx.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include diff --git a/drivers/spi/spi_nuc900.c b/drivers/spi/spi_nuc900.c index b319f9b..dff63be 100644 --- a/drivers/spi/spi_nuc900.c +++ b/drivers/spi/spi_nuc900.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include diff --git a/drivers/spi/spi_ppc4xx.c b/drivers/spi/spi_ppc4xx.c index 6d8d402..7cb5ff3 100644 --- a/drivers/spi/spi_ppc4xx.c +++ b/drivers/spi/spi_ppc4xx.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/spi/spi_s3c24xx.c b/drivers/spi/spi_s3c24xx.c index 1fabede..151a95e 100644 --- a/drivers/spi/spi_s3c24xx.c +++ b/drivers/spi/spi_s3c24xx.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include diff --git a/drivers/spi/tle62x0.c b/drivers/spi/tle62x0.c index bf9540f..a393895 100644 --- a/drivers/spi/tle62x0.c +++ b/drivers/spi/tle62x0.c @@ -11,6 +11,7 @@ #include #include +#include #include #include diff --git a/drivers/spi/xilinx_spi_of.c b/drivers/spi/xilinx_spi_of.c index ed34a8d..748d33a 100644 --- a/drivers/spi/xilinx_spi_of.c +++ b/drivers/spi/xilinx_spi_of.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include diff --git a/drivers/ssb/driver_gige.c b/drivers/ssb/driver_gige.c index 172f904..5ba92a2 100644 --- a/drivers/ssb/driver_gige.c +++ b/drivers/ssb/driver_gige.c @@ -12,6 +12,7 @@ #include #include #include +#include /* diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index 03dfd27..80ff7d9 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c index 9e50896..a8dbb06 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c @@ -17,6 +17,7 @@ #include #include +#include #include #include diff --git a/drivers/ssb/pcihost_wrapper.c b/drivers/ssb/pcihost_wrapper.c index 26737a0..6536a04 100644 --- a/drivers/ssb/pcihost_wrapper.c +++ b/drivers/ssb/pcihost_wrapper.c @@ -12,6 +12,7 @@ */ #include +#include #include diff --git a/drivers/ssb/sprom.c b/drivers/ssb/sprom.c index d0e6762..f2f920f 100644 --- a/drivers/ssb/sprom.c +++ b/drivers/ssb/sprom.c @@ -14,6 +14,7 @@ #include "ssb_private.h" #include +#include static const struct ssb_sprom *fallback_sprom; diff --git a/drivers/staging/batman-adv/device.c b/drivers/staging/batman-adv/device.c index e7f4421..2f61500 100644 --- a/drivers/staging/batman-adv/device.c +++ b/drivers/staging/batman-adv/device.c @@ -20,6 +20,7 @@ */ #include +#include #include "main.h" #include "device.h" #include "send.h" diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h index deb41f5..2e9bb89 100644 --- a/drivers/staging/batman-adv/main.h +++ b/drivers/staging/batman-adv/main.h @@ -109,6 +109,7 @@ extern int bat_debug_type(int type); #include /* kernel threads */ #include /* schedule types */ #include /* workqueue */ +#include #include /* struct sock */ #include #include "types.h" diff --git a/drivers/staging/batman-adv/soft-interface.c b/drivers/staging/batman-adv/soft-interface.c index c9b35d9f..0e2307f 100644 --- a/drivers/staging/batman-adv/soft-interface.c +++ b/drivers/staging/batman-adv/soft-interface.c @@ -26,6 +26,7 @@ #include "translation-table.h" #include "types.h" #include "hash.h" +#include #include #include diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c index 10f488f..2d54993 100644 --- a/drivers/staging/comedi/drivers/8255.c +++ b/drivers/staging/comedi/drivers/8255.c @@ -81,6 +81,7 @@ I/O port base address can be found in the output of 'lspci -v'. #include "../comedidev.h" #include +#include #define _8255_SIZE 4 diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 8db5ab6..6625fdc 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -50,7 +50,6 @@ You should also find the complete GPL in the COPYING file accompanying this sour #include #include #include -#include #include #include #include @@ -58,6 +57,7 @@ You should also find the complete GPL in the COPYING file accompanying this sour #include #include #include +#include #include "../../comedidev.h" #include #if defined(CONFIG_APCI_1710) || defined(CONFIG_APCI_3200) || defined(CONFIG_APCI_3300) diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index 9934a3c..944f20a 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -66,6 +66,7 @@ Configuration options: #include "../pci_ids.h" #include +#include #include #include "amcc_s5933.h" diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 204f30e..92bcc205 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -206,6 +206,7 @@ order they appear in the channel list. */ #include +#include #include "../comedidev.h" diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index b41e5e59..c54cca8 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -104,6 +104,7 @@ Caveats: */ #include +#include #include "../comedidev.h" diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index bc375e7..5632991 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -32,6 +32,7 @@ Status: experimental */ #include +#include #include "../comedidev.h" #include #include diff --git a/drivers/staging/comedi/drivers/comedi_bond.c b/drivers/staging/comedi/drivers/comedi_bond.c index d7260cc..41311d9 100644 --- a/drivers/staging/comedi/drivers/comedi_bond.c +++ b/drivers/staging/comedi/drivers/comedi_bond.c @@ -90,6 +90,7 @@ Configuration Options: #include "../comedilib.h" #include "../comedidev.h" #include +#include /* The maxiumum number of channels per subdevice. */ #define MAX_CHANS 256 diff --git a/drivers/staging/comedi/drivers/das08_cs.c b/drivers/staging/comedi/drivers/das08_cs.c index f12ef1c..9164ce1 100644 --- a/drivers/staging/comedi/drivers/das08_cs.c +++ b/drivers/staging/comedi/drivers/das08_cs.c @@ -43,6 +43,7 @@ Command support does not exist, but could be added for this board. #include #include +#include #include "das08.h" diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c index 10a87e6..f2aadda 100644 --- a/drivers/staging/comedi/drivers/das16.c +++ b/drivers/staging/comedi/drivers/das16.c @@ -79,6 +79,7 @@ Computer boards manuals also available from their website www.measurementcomputi */ #include +#include #include #include #include "../comedidev.h" diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c index 6ea59cc..3c3e045 100644 --- a/drivers/staging/comedi/drivers/das1800.c +++ b/drivers/staging/comedi/drivers/das1800.c @@ -101,6 +101,7 @@ TODO: */ #include +#include #include "../comedidev.h" #include diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c index 99ca294..e548763 100644 --- a/drivers/staging/comedi/drivers/dt282x.c +++ b/drivers/staging/comedi/drivers/dt282x.c @@ -58,6 +58,7 @@ Notes: #include "../comedidev.h" +#include #include #include #include diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index fe5b495..d330b18 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c @@ -46,6 +46,7 @@ Devices: [JR3] PCI force sensor board (jr3_pci) #include #include #include +#include #include #include "comedi_pci.h" #include "jr3_pci.h" diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index c223f76..9a4fffe 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -52,6 +52,7 @@ except maybe the 6514. #define DEBUG 1 #define DEBUG_FLAGS #include +#include #include "../comedidev.h" #include "mite.h" diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c index 1e792d5..68221bf 100644 --- a/drivers/staging/comedi/drivers/ni_670x.c +++ b/drivers/staging/comedi/drivers/ni_670x.c @@ -42,6 +42,7 @@ Commands are not supported. */ #include +#include #include "../comedidev.h" #include "mite.h" diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c index dd75dfb..9bff34c 100644 --- a/drivers/staging/comedi/drivers/ni_at_a2150.c +++ b/drivers/staging/comedi/drivers/ni_at_a2150.c @@ -65,6 +65,7 @@ TRIG_WAKE_EOS */ #include +#include #include "../comedidev.h" #include diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index c9b0395..7ea6453 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -42,6 +42,7 @@ IRQ is assigned but not used. */ #include +#include #include "../comedidev.h" #include diff --git a/drivers/staging/comedi/drivers/ni_daq_dio24.c b/drivers/staging/comedi/drivers/ni_daq_dio24.c index 9017be3..ddc312b 100644 --- a/drivers/staging/comedi/drivers/ni_daq_dio24.c +++ b/drivers/staging/comedi/drivers/ni_daq_dio24.c @@ -41,6 +41,7 @@ the PCMCIA interface. #undef LABPC_DEBUG #include +#include #include "../comedidev.h" #include diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index 3c88caa..558e525 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -77,6 +77,7 @@ NI manuals: /* #define LABPC_DEBUG enable debugging messages */ #include +#include #include "../comedidev.h" #include diff --git a/drivers/staging/comedi/drivers/ni_labpc_cs.c b/drivers/staging/comedi/drivers/ni_labpc_cs.c index 0b963bb..8ad1055 100644 --- a/drivers/staging/comedi/drivers/ni_labpc_cs.c +++ b/drivers/staging/comedi/drivers/ni_labpc_cs.c @@ -64,6 +64,7 @@ NI manuals: #include "../comedidev.h" #include +#include #include "8253.h" #include "8255.h" diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c index d4634c4..1ddc19c 100644 --- a/drivers/staging/comedi/drivers/pcl812.c +++ b/drivers/staging/comedi/drivers/pcl812.c @@ -108,6 +108,7 @@ Options for ACL-8113, ISO-813: */ #include +#include #include "../comedidev.h" #include diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c index 9820759..71c2a3a 100644 --- a/drivers/staging/comedi/drivers/pcl816.c +++ b/drivers/staging/comedi/drivers/pcl816.c @@ -36,6 +36,7 @@ Configuration Options: #include #include +#include #include #include diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c index c9d7538..9d6aa39 100644 --- a/drivers/staging/comedi/drivers/pcl818.c +++ b/drivers/staging/comedi/drivers/pcl818.c @@ -102,6 +102,7 @@ A word or two about DMA. Driver support DMA operations at two ways: #include #include +#include #include #include diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c index 6ca4105..025a52e 100644 --- a/drivers/staging/comedi/drivers/pcmmio.c +++ b/drivers/staging/comedi/drivers/pcmmio.c @@ -77,6 +77,7 @@ Configuration Options: */ #include +#include #include "../comedidev.h" #include "pcm_common.h" #include /* for PCI devices */ diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c index c1ae20f..5af4c84 100644 --- a/drivers/staging/comedi/drivers/pcmuio.c +++ b/drivers/staging/comedi/drivers/pcmuio.c @@ -76,6 +76,7 @@ Configuration Options: */ #include +#include #include "../comedidev.h" #include "pcm_common.h" diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c index dd2b903..0792617 100644 --- a/drivers/staging/comedi/drivers/serial2002.c +++ b/drivers/staging/comedi/drivers/serial2002.c @@ -36,6 +36,7 @@ Status: in development #include #include #include +#include #include #include diff --git a/drivers/staging/comedi/drivers/unioxx5.c b/drivers/staging/comedi/drivers/unioxx5.c index 75a9a62..be1d83d 100644 --- a/drivers/staging/comedi/drivers/unioxx5.c +++ b/drivers/staging/comedi/drivers/unioxx5.c @@ -44,6 +44,7 @@ Devices: [Fastwel] UNIOxx-5 (unioxx5), #include "../comedidev.h" #include +#include #define DRIVER_NAME "unioxx5" #define UNIOXX5_SIZE 0x10 diff --git a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c index 6552ef6..288fef4 100644 --- a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c +++ b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include "../comedi.h" diff --git a/drivers/staging/comedi/kcomedilib/ksyms.c b/drivers/staging/comedi/kcomedilib/ksyms.c index 19293d1..8bf4471 100644 --- a/drivers/staging/comedi/kcomedilib/ksyms.c +++ b/drivers/staging/comedi/kcomedilib/ksyms.c @@ -34,7 +34,6 @@ #include #include #include -#include /* functions specific to kcomedilib */ diff --git a/drivers/staging/crystalhd/crystalhd_hw.c b/drivers/staging/crystalhd/crystalhd_hw.c index 01819d3..c438c48 100644 --- a/drivers/staging/crystalhd/crystalhd_hw.c +++ b/drivers/staging/crystalhd/crystalhd_hw.c @@ -23,6 +23,7 @@ **********************************************************************/ #include +#include #include #include "crystalhd_hw.h" diff --git a/drivers/staging/crystalhd/crystalhd_lnx.c b/drivers/staging/crystalhd/crystalhd_lnx.c index 3eac70a..54bad65 100644 --- a/drivers/staging/crystalhd/crystalhd_lnx.c +++ b/drivers/staging/crystalhd/crystalhd_lnx.c @@ -16,6 +16,7 @@ ***************************************************************************/ #include +#include #include "crystalhd_lnx.h" diff --git a/drivers/staging/crystalhd/crystalhd_misc.c b/drivers/staging/crystalhd/crystalhd_misc.c index 587dcc4..73593b0 100644 --- a/drivers/staging/crystalhd/crystalhd_misc.c +++ b/drivers/staging/crystalhd/crystalhd_misc.c @@ -24,6 +24,8 @@ * along with this driver. If not, see . **********************************************************************/ +#include + #include "crystalhd_misc.h" #include "crystalhd_lnx.h" diff --git a/drivers/staging/cx25821/cx25821-alsa.c b/drivers/staging/cx25821/cx25821-alsa.c index e0eef12..061add3 100644 --- a/drivers/staging/cx25821/cx25821-alsa.c +++ b/drivers/staging/cx25821/cx25821-alsa.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include diff --git a/drivers/staging/cx25821/cx25821-audio-upstream.c b/drivers/staging/cx25821/cx25821-audio-upstream.c index ddddf65..11c56bd 100644 --- a/drivers/staging/cx25821/cx25821-audio-upstream.c +++ b/drivers/staging/cx25821/cx25821-audio-upstream.c @@ -32,6 +32,7 @@ #include #include #include +#include #include MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards"); diff --git a/drivers/staging/cx25821/cx25821-audups11.c b/drivers/staging/cx25821/cx25821-audups11.c index 46c7f78..e76451c 100644 --- a/drivers/staging/cx25821/cx25821-audups11.c +++ b/drivers/staging/cx25821/cx25821-audups11.c @@ -21,6 +21,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include + #include "cx25821-video.h" static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) diff --git a/drivers/staging/cx25821/cx25821-core.c b/drivers/staging/cx25821/cx25821-core.c index 67f689d..9e9b8c3 100644 --- a/drivers/staging/cx25821/cx25821-core.c +++ b/drivers/staging/cx25821/cx25821-core.c @@ -22,6 +22,7 @@ */ #include +#include #include "cx25821.h" #include "cx25821-sram.h" #include "cx25821-video.h" diff --git a/drivers/staging/cx25821/cx25821-video-upstream-ch2.c b/drivers/staging/cx25821/cx25821-video-upstream-ch2.c index c8905e0..cc51618 100644 --- a/drivers/staging/cx25821/cx25821-video-upstream-ch2.c +++ b/drivers/staging/cx25821/cx25821-video-upstream-ch2.c @@ -31,6 +31,7 @@ #include #include #include +#include #include MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards"); diff --git a/drivers/staging/cx25821/cx25821-video-upstream.c b/drivers/staging/cx25821/cx25821-video-upstream.c index 3d7dd3f..6d48a1e 100644 --- a/drivers/staging/cx25821/cx25821-video-upstream.c +++ b/drivers/staging/cx25821/cx25821-video-upstream.c @@ -31,6 +31,7 @@ #include #include #include +#include #include MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards"); diff --git a/drivers/staging/dream/camera/msm_camera.c b/drivers/staging/dream/camera/msm_camera.c index dc7c603..81bd71f 100644 --- a/drivers/staging/dream/camera/msm_camera.c +++ b/drivers/staging/dream/camera/msm_camera.c @@ -12,6 +12,7 @@ #include #include +#include #include #include #include diff --git a/drivers/staging/dream/camera/msm_v4l2.c b/drivers/staging/dream/camera/msm_v4l2.c index 6a7d46c..c276f2f 100644 --- a/drivers/staging/dream/camera/msm_v4l2.c +++ b/drivers/staging/dream/camera/msm_v4l2.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/staging/dream/camera/msm_vfe7x.c b/drivers/staging/dream/camera/msm_vfe7x.c index 62fd24d..198656a 100644 --- a/drivers/staging/dream/camera/msm_vfe7x.c +++ b/drivers/staging/dream/camera/msm_vfe7x.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/staging/dream/camera/msm_vfe8x.c b/drivers/staging/dream/camera/msm_vfe8x.c index 03de6ec..e61fdba 100644 --- a/drivers/staging/dream/camera/msm_vfe8x.c +++ b/drivers/staging/dream/camera/msm_vfe8x.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2008-2009 QUALCOMM Incorporated. */ +#include #include #include #include diff --git a/drivers/staging/dream/camera/mt9d112.c b/drivers/staging/dream/camera/mt9d112.c index 4f938f9..e6f2d51 100644 --- a/drivers/staging/dream/camera/mt9d112.c +++ b/drivers/staging/dream/camera/mt9d112.c @@ -3,6 +3,7 @@ */ #include +#include #include #include #include diff --git a/drivers/staging/dream/camera/mt9p012_fox.c b/drivers/staging/dream/camera/mt9p012_fox.c index 70119d5..791bd6c 100644 --- a/drivers/staging/dream/camera/mt9p012_fox.c +++ b/drivers/staging/dream/camera/mt9p012_fox.c @@ -4,6 +4,7 @@ #include #include +#include #include #include #include diff --git a/drivers/staging/dream/camera/mt9t013.c b/drivers/staging/dream/camera/mt9t013.c index 88229f2..8fd7727 100644 --- a/drivers/staging/dream/camera/mt9t013.c +++ b/drivers/staging/dream/camera/mt9t013.c @@ -4,6 +4,7 @@ #include #include +#include #include #include #include diff --git a/drivers/staging/dream/camera/s5k3e2fx.c b/drivers/staging/dream/camera/s5k3e2fx.c index 841792e..1459903 100644 --- a/drivers/staging/dream/camera/s5k3e2fx.c +++ b/drivers/staging/dream/camera/s5k3e2fx.c @@ -3,6 +3,7 @@ */ #include +#include #include #include #include diff --git a/drivers/staging/dream/gpio_axis.c b/drivers/staging/dream/gpio_axis.c index c801172..eb54724 100644 --- a/drivers/staging/dream/gpio_axis.c +++ b/drivers/staging/dream/gpio_axis.c @@ -14,6 +14,7 @@ */ #include +#include #include #include #include diff --git a/drivers/staging/dream/gpio_event.c b/drivers/staging/dream/gpio_event.c index e60e2c0..97a511d 100644 --- a/drivers/staging/dream/gpio_event.c +++ b/drivers/staging/dream/gpio_event.c @@ -14,6 +14,7 @@ */ +#include #include #include #include diff --git a/drivers/staging/dream/gpio_input.c b/drivers/staging/dream/gpio_input.c index 0638ec4..ca29e5e 100644 --- a/drivers/staging/dream/gpio_input.c +++ b/drivers/staging/dream/gpio_input.c @@ -19,6 +19,7 @@ #include #include #include +#include enum { DEBOUNCE_UNSTABLE = BIT(0), /* Got irq, while debouncing */ diff --git a/drivers/staging/dream/gpio_matrix.c b/drivers/staging/dream/gpio_matrix.c index 796de4f..b377ee1 100644 --- a/drivers/staging/dream/gpio_matrix.c +++ b/drivers/staging/dream/gpio_matrix.c @@ -14,6 +14,7 @@ */ #include +#include #include #include #include diff --git a/drivers/staging/dream/pmem.c b/drivers/staging/dream/pmem.c index 503ba21..6edfdd4 100644 --- a/drivers/staging/dream/pmem.c +++ b/drivers/staging/dream/pmem.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/staging/dream/qdsp5/adsp.c b/drivers/staging/dream/qdsp5/adsp.c index 9069535..f1e9d81 100644 --- a/drivers/staging/dream/qdsp5/adsp.c +++ b/drivers/staging/dream/qdsp5/adsp.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include diff --git a/drivers/staging/dream/qdsp5/adsp_driver.c b/drivers/staging/dream/qdsp5/adsp_driver.c index e55a0db..8197765 100644 --- a/drivers/staging/dream/qdsp5/adsp_driver.c +++ b/drivers/staging/dream/qdsp5/adsp_driver.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include "adsp.h" diff --git a/drivers/staging/dream/qdsp5/audio_aac.c b/drivers/staging/dream/qdsp5/audio_aac.c index ad2390f..a373f35 100644 --- a/drivers/staging/dream/qdsp5/audio_aac.c +++ b/drivers/staging/dream/qdsp5/audio_aac.c @@ -24,6 +24,7 @@ #include #include #include +#include #include diff --git a/drivers/staging/dream/qdsp5/audio_amrnb.c b/drivers/staging/dream/qdsp5/audio_amrnb.c index cd818a5..07b79d5 100644 --- a/drivers/staging/dream/qdsp5/audio_amrnb.c +++ b/drivers/staging/dream/qdsp5/audio_amrnb.c @@ -32,6 +32,7 @@ #include #include #include +#include #include diff --git a/drivers/staging/dream/qdsp5/audio_evrc.c b/drivers/staging/dream/qdsp5/audio_evrc.c index 4b43e18..ad989ee 100644 --- a/drivers/staging/dream/qdsp5/audio_evrc.c +++ b/drivers/staging/dream/qdsp5/audio_evrc.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include diff --git a/drivers/staging/dream/qdsp5/audio_in.c b/drivers/staging/dream/qdsp5/audio_in.c index 3d950a2..6ae48e7 100644 --- a/drivers/staging/dream/qdsp5/audio_in.c +++ b/drivers/staging/dream/qdsp5/audio_in.c @@ -23,6 +23,7 @@ #include #include #include +#include #include diff --git a/drivers/staging/dream/qdsp5/audio_mp3.c b/drivers/staging/dream/qdsp5/audio_mp3.c index 7ed6e26..530e1f3 100644 --- a/drivers/staging/dream/qdsp5/audio_mp3.c +++ b/drivers/staging/dream/qdsp5/audio_mp3.c @@ -23,6 +23,7 @@ #include #include #include +#include #include diff --git a/drivers/staging/dream/qdsp5/audio_out.c b/drivers/staging/dream/qdsp5/audio_out.c index df87ca3..fe7809d 100644 --- a/drivers/staging/dream/qdsp5/audio_out.c +++ b/drivers/staging/dream/qdsp5/audio_out.c @@ -26,6 +26,7 @@ #include #include #include +#include #include diff --git a/drivers/staging/dream/qdsp5/audio_qcelp.c b/drivers/staging/dream/qdsp5/audio_qcelp.c index f0f50e3..effa96f 100644 --- a/drivers/staging/dream/qdsp5/audio_qcelp.c +++ b/drivers/staging/dream/qdsp5/audio_qcelp.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include diff --git a/drivers/staging/dream/qdsp5/audmgr.c b/drivers/staging/dream/qdsp5/audmgr.c index 1ad8b82..427ae6c 100644 --- a/drivers/staging/dream/qdsp5/audmgr.c +++ b/drivers/staging/dream/qdsp5/audmgr.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include diff --git a/drivers/staging/dream/smd/smd_rpcrouter.c b/drivers/staging/dream/smd/smd_rpcrouter.c index 69911a7..8744a6e 100644 --- a/drivers/staging/dream/smd/smd_rpcrouter.c +++ b/drivers/staging/dream/smd/smd_rpcrouter.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/staging/dream/smd/smd_rpcrouter_device.c b/drivers/staging/dream/smd/smd_rpcrouter_device.c index cd3910b..e9c28ed 100644 --- a/drivers/staging/dream/smd/smd_rpcrouter_device.c +++ b/drivers/staging/dream/smd/smd_rpcrouter_device.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include diff --git a/drivers/staging/dream/smd/smd_rpcrouter_servers.c b/drivers/staging/dream/smd/smd_rpcrouter_servers.c index 2597bbb..1b152ab 100644 --- a/drivers/staging/dream/smd/smd_rpcrouter_servers.c +++ b/drivers/staging/dream/smd/smd_rpcrouter_servers.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include diff --git a/drivers/staging/dream/synaptics_i2c_rmi.c b/drivers/staging/dream/synaptics_i2c_rmi.c index 4de6bc9..d2ca116 100644 --- a/drivers/staging/dream/synaptics_i2c_rmi.c +++ b/drivers/staging/dream/synaptics_i2c_rmi.c @@ -18,6 +18,7 @@ #include #include +#include #ifdef CONFIG_HAS_EARLYSUSPEND #include #endif diff --git a/drivers/staging/dt3155/allocator.c b/drivers/staging/dt3155/allocator.c index c74234c..db382ef 100644 --- a/drivers/staging/dt3155/allocator.c +++ b/drivers/staging/dt3155/allocator.c @@ -55,6 +55,7 @@ #include #include /* PAGE_ALIGN() */ #include +#include #include diff --git a/drivers/staging/dt3155/dt3155_isr.c b/drivers/staging/dt3155/dt3155_isr.c index fd7f93d..09d7d9b 100644 --- a/drivers/staging/dt3155/dt3155_isr.c +++ b/drivers/staging/dt3155/dt3155_isr.c @@ -45,7 +45,7 @@ Purpose: Buffer management routines, and other routines for the ISR */ #include -#include +#include #include #include diff --git a/drivers/staging/et131x/et1310_eeprom.c b/drivers/staging/et131x/et1310_eeprom.c index 3ca2536..e4d095b 100644 --- a/drivers/staging/et131x/et1310_eeprom.c +++ b/drivers/staging/et131x/et1310_eeprom.c @@ -66,7 +66,6 @@ #include #include -#include #include #include #include diff --git a/drivers/staging/et131x/et1310_mac.c b/drivers/staging/et131x/et1310_mac.c index 737a9f5..16fa13d 100644 --- a/drivers/staging/et131x/et1310_mac.c +++ b/drivers/staging/et131x/et1310_mac.c @@ -65,7 +65,6 @@ #include #include -#include #include #include #include diff --git a/drivers/staging/et131x/et1310_phy.c b/drivers/staging/et131x/et1310_phy.c index 4a55fbf..34cd5d1 100644 --- a/drivers/staging/et131x/et1310_phy.c +++ b/drivers/staging/et131x/et1310_phy.c @@ -66,7 +66,6 @@ #include #include -#include #include #include #include diff --git a/drivers/staging/et131x/et1310_pm.c b/drivers/staging/et131x/et1310_pm.c index 41019e3..c64bb2c 100644 --- a/drivers/staging/et131x/et1310_pm.c +++ b/drivers/staging/et131x/et1310_pm.c @@ -65,7 +65,6 @@ #include #include -#include #include #include #include diff --git a/drivers/staging/et131x/et131x_initpci.c b/drivers/staging/et131x/et131x_initpci.c index 5ad7e5a..1dd5fa5 100644 --- a/drivers/staging/et131x/et131x_initpci.c +++ b/drivers/staging/et131x/et131x_initpci.c @@ -68,7 +68,6 @@ #include #include -#include #include #include #include diff --git a/drivers/staging/et131x/et131x_isr.c b/drivers/staging/et131x/et131x_isr.c index 8b6e0b7..cb7f677 100644 --- a/drivers/staging/et131x/et131x_isr.c +++ b/drivers/staging/et131x/et131x_isr.c @@ -66,7 +66,6 @@ #include #include -#include #include #include #include diff --git a/drivers/staging/et131x/et131x_netdev.c b/drivers/staging/et131x/et131x_netdev.c index 40f8954..ab047f2 100644 --- a/drivers/staging/et131x/et131x_netdev.c +++ b/drivers/staging/et131x/et131x_netdev.c @@ -65,7 +65,6 @@ #include #include -#include #include #include #include diff --git a/drivers/staging/go7007/go7007-driver.c b/drivers/staging/go7007/go7007-driver.c index d42ba16..372a7c6 100644 --- a/drivers/staging/go7007/go7007-driver.c +++ b/drivers/staging/go7007/go7007-driver.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/staging/go7007/go7007-fw.c b/drivers/staging/go7007/go7007-fw.c index a8bb264..ee622ff 100644 --- a/drivers/staging/go7007/go7007-fw.c +++ b/drivers/staging/go7007/go7007-fw.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include "go7007-priv.h" diff --git a/drivers/staging/go7007/go7007-v4l2.c b/drivers/staging/go7007/go7007-v4l2.c index 3af7924..723c1a6 100644 --- a/drivers/staging/go7007/go7007-v4l2.c +++ b/drivers/staging/go7007/go7007-v4l2.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/staging/go7007/s2250-board.c b/drivers/staging/go7007/s2250-board.c index dc89502..93f2604 100644 --- a/drivers/staging/go7007/s2250-board.c +++ b/drivers/staging/go7007/s2250-board.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/staging/go7007/s2250-loader.c b/drivers/staging/go7007/s2250-loader.c index 1de2dfb..7547a8f 100644 --- a/drivers/staging/go7007/s2250-loader.c +++ b/drivers/staging/go7007/s2250-loader.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include diff --git a/drivers/staging/go7007/snd-go7007.c b/drivers/staging/go7007/snd-go7007.c index 03c4dfc..deac938 100644 --- a/drivers/staging/go7007/snd-go7007.c +++ b/drivers/staging/go7007/snd-go7007.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/staging/go7007/wis-saa7113.c b/drivers/staging/go7007/wis-saa7113.c index d196e16f..5c12b4d 100644 --- a/drivers/staging/go7007/wis-saa7113.c +++ b/drivers/staging/go7007/wis-saa7113.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "wis-i2c.h" diff --git a/drivers/staging/go7007/wis-saa7115.c b/drivers/staging/go7007/wis-saa7115.c index 0f2b4a0..73f2283 100644 --- a/drivers/staging/go7007/wis-saa7115.c +++ b/drivers/staging/go7007/wis-saa7115.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "wis-i2c.h" diff --git a/drivers/staging/go7007/wis-sony-tuner.c b/drivers/staging/go7007/wis-sony-tuner.c index c723e4a..b101329 100644 --- a/drivers/staging/go7007/wis-sony-tuner.c +++ b/drivers/staging/go7007/wis-sony-tuner.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/staging/go7007/wis-tw2804.c b/drivers/staging/go7007/wis-tw2804.c index 1983839..315268d 100644 --- a/drivers/staging/go7007/wis-tw2804.c +++ b/drivers/staging/go7007/wis-tw2804.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "wis-i2c.h" diff --git a/drivers/staging/go7007/wis-tw9903.c b/drivers/staging/go7007/wis-tw9903.c index f97e2be..3ac6f78 100644 --- a/drivers/staging/go7007/wis-tw9903.c +++ b/drivers/staging/go7007/wis-tw9903.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "wis-i2c.h" diff --git a/drivers/staging/hv/Channel.c b/drivers/staging/hv/Channel.c index d46eb14..e69e9ee 100644 --- a/drivers/staging/hv/Channel.c +++ b/drivers/staging/hv/Channel.c @@ -20,6 +20,7 @@ */ #include #include +#include #include "osd.h" #include "logging.h" #include "VmbusPrivate.h" diff --git a/drivers/staging/hv/ChannelMgmt.c b/drivers/staging/hv/ChannelMgmt.c index ef38467..5f92c21 100644 --- a/drivers/staging/hv/ChannelMgmt.c +++ b/drivers/staging/hv/ChannelMgmt.c @@ -20,6 +20,7 @@ */ #include #include +#include #include #include "osd.h" #include "logging.h" diff --git a/drivers/staging/hv/Connection.c b/drivers/staging/hv/Connection.c index 43c2e68..e0ea9cf 100644 --- a/drivers/staging/hv/Connection.c +++ b/drivers/staging/hv/Connection.c @@ -22,6 +22,7 @@ */ #include #include +#include #include #include "osd.h" #include "logging.h" diff --git a/drivers/staging/hv/Hv.c b/drivers/staging/hv/Hv.c index 51149e6..5d53889 100644 --- a/drivers/staging/hv/Hv.c +++ b/drivers/staging/hv/Hv.c @@ -21,6 +21,7 @@ */ #include #include +#include #include #include "osd.h" #include "logging.h" diff --git a/drivers/staging/hv/NetVsc.c b/drivers/staging/hv/NetVsc.c index 1c717f9..e4bf822 100644 --- a/drivers/staging/hv/NetVsc.c +++ b/drivers/staging/hv/NetVsc.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "osd.h" #include "logging.h" #include "NetVsc.h" diff --git a/drivers/staging/hv/RndisFilter.c b/drivers/staging/hv/RndisFilter.c index 1ab7fa9..cd2930d 100644 --- a/drivers/staging/hv/RndisFilter.c +++ b/drivers/staging/hv/RndisFilter.c @@ -20,6 +20,7 @@ */ #include #include +#include #include #include "osd.h" #include "logging.h" diff --git a/drivers/staging/hv/StorVsc.c b/drivers/staging/hv/StorVsc.c index 38ea140..e426a23 100644 --- a/drivers/staging/hv/StorVsc.c +++ b/drivers/staging/hv/StorVsc.c @@ -20,6 +20,7 @@ */ #include #include +#include #include #include #include "osd.h" diff --git a/drivers/staging/hv/Vmbus.c b/drivers/staging/hv/Vmbus.c index 3d0a240..2f84bf7 100644 --- a/drivers/staging/hv/Vmbus.c +++ b/drivers/staging/hv/Vmbus.c @@ -21,6 +21,7 @@ */ #include #include +#include #include "osd.h" #include "logging.h" #include "VersionInfo.h" diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index abeac12..8f1fda3 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index 1af3dcb..2ccb6b9 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/staging/hv/osd.c b/drivers/staging/hv/osd.c index 3a4793a..9aea310 100644 --- a/drivers/staging/hv/osd.c +++ b/drivers/staging/hv/osd.c @@ -40,6 +40,7 @@ #include #include #include +#include #include "osd.h" struct osd_callback_struct { diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 3988f4b..8a58272 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -19,6 +19,7 @@ * Hank Janssen */ #include +#include #include #include #include diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 2c90619..3397ef0 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "VersionInfo.h" #include "osd.h" #include "logging.h" diff --git a/drivers/staging/iio/accel/kxsd9.c b/drivers/staging/iio/accel/kxsd9.c index 33d16b6..db2dd53 100644 --- a/drivers/staging/iio/accel/kxsd9.c +++ b/drivers/staging/iio/accel/kxsd9.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "../iio.h" #include "../sysfs.h" diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c index f008837..ea76902 100644 --- a/drivers/staging/iio/accel/lis3l02dq_core.c +++ b/drivers/staging/iio/accel/lis3l02dq_core.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c index a6b7c72..9371243 100644 --- a/drivers/staging/iio/accel/lis3l02dq_ring.c +++ b/drivers/staging/iio/accel/lis3l02dq_ring.c @@ -8,6 +8,7 @@ #include #include #include +#include #include "../iio.h" #include "../sysfs.h" diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c index cedcaa2..1c22986 100644 --- a/drivers/staging/iio/accel/sca3000_core.c +++ b/drivers/staging/iio/accel/sca3000_core.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c index d5ea237..40cbab2 100644 --- a/drivers/staging/iio/accel/sca3000_ring.c +++ b/drivers/staging/iio/accel/sca3000_ring.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c index 9703881..790d1cc 100644 --- a/drivers/staging/iio/adc/max1363_core.c +++ b/drivers/staging/iio/adc/max1363_core.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "../iio.h" #include "../sysfs.h" diff --git a/drivers/staging/iio/adc/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c index a953eac..f94fe2d 100644 --- a/drivers/staging/iio/adc/max1363_ring.c +++ b/drivers/staging/iio/adc/max1363_ring.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c index b456dfc..37f58f6 100644 --- a/drivers/staging/iio/industrialio-core.c +++ b/drivers/staging/iio/industrialio-core.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "iio.h" #include "trigger_consumer.h" diff --git a/drivers/staging/iio/industrialio-ring.c b/drivers/staging/iio/industrialio-ring.c index ebe5ccc..e53e214 100644 --- a/drivers/staging/iio/industrialio-ring.c +++ b/drivers/staging/iio/industrialio-ring.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "iio.h" #include "ring_generic.h" diff --git a/drivers/staging/iio/industrialio-trigger.c b/drivers/staging/iio/industrialio-trigger.c index 693ebc4..35ec80b 100644 --- a/drivers/staging/iio/industrialio-trigger.c +++ b/drivers/staging/iio/industrialio-trigger.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "iio.h" #include "trigger.h" diff --git a/drivers/staging/iio/light/tsl2563.c b/drivers/staging/iio/light/tsl2563.c index 78b9432..1ba4aa3 100644 --- a/drivers/staging/iio/light/tsl2563.c +++ b/drivers/staging/iio/light/tsl2563.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "../iio.h" #include "tsl2563.h" diff --git a/drivers/staging/iio/ring_sw.c b/drivers/staging/iio/ring_sw.c index 6f7f4d5..b104c3d 100644 --- a/drivers/staging/iio/ring_sw.c +++ b/drivers/staging/iio/ring_sw.c @@ -7,6 +7,7 @@ * the Free Software Foundation. */ +#include #include #include #include diff --git a/drivers/staging/iio/trigger/iio-trig-gpio.c b/drivers/staging/iio/trigger/iio-trig-gpio.c index 539e416..0c3bad3 100644 --- a/drivers/staging/iio/trigger/iio-trig-gpio.c +++ b/drivers/staging/iio/trigger/iio-trig-gpio.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "../iio.h" #include "../trigger.h" diff --git a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c index e310dc00..4295bbc 100644 --- a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c +++ b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "../iio.h" #include "../trigger.h" diff --git a/drivers/staging/line6/capture.c b/drivers/staging/line6/capture.c index fd4890d..ca09224 100644 --- a/drivers/staging/line6/capture.c +++ b/drivers/staging/line6/capture.c @@ -11,6 +11,8 @@ #include "driver.h" +#include + #include #include #include diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c index 0392a4b..2585554 100644 --- a/drivers/staging/line6/driver.c +++ b/drivers/staging/line6/driver.c @@ -13,6 +13,7 @@ #include #include +#include #include #include "audio.h" diff --git a/drivers/staging/line6/dumprequest.c b/drivers/staging/line6/dumprequest.c index decbaa9..bb8c9da 100644 --- a/drivers/staging/line6/dumprequest.c +++ b/drivers/staging/line6/dumprequest.c @@ -10,6 +10,9 @@ */ #include "driver.h" + +#include + #include "dumprequest.h" diff --git a/drivers/staging/line6/midi.c b/drivers/staging/line6/midi.c index 6ef4455..32b6ca7 100644 --- a/drivers/staging/line6/midi.c +++ b/drivers/staging/line6/midi.c @@ -12,6 +12,7 @@ #include "driver.h" #include +#include #include #include diff --git a/drivers/staging/line6/pcm.c b/drivers/staging/line6/pcm.c index dd98121..fbe4b08 100644 --- a/drivers/staging/line6/pcm.c +++ b/drivers/staging/line6/pcm.c @@ -11,6 +11,8 @@ #include "driver.h" +#include + #include #include #include diff --git a/drivers/staging/line6/playback.c b/drivers/staging/line6/playback.c index 3431f5c..fbcd6e1 100644 --- a/drivers/staging/line6/playback.c +++ b/drivers/staging/line6/playback.c @@ -11,6 +11,8 @@ #include "driver.h" +#include + #include #include #include diff --git a/drivers/staging/line6/pod.c b/drivers/staging/line6/pod.c index 685c529..4983f2b 100644 --- a/drivers/staging/line6/pod.c +++ b/drivers/staging/line6/pod.c @@ -11,6 +11,8 @@ #include "driver.h" +#include + #include "audio.h" #include "capture.h" #include "control.h" diff --git a/drivers/staging/line6/variax.c b/drivers/staging/line6/variax.c index 58fef82..28eb899 100644 --- a/drivers/staging/line6/variax.c +++ b/drivers/staging/line6/variax.c @@ -11,6 +11,8 @@ #include "driver.h" +#include + #include "audio.h" #include "control.h" #include "variax.h" diff --git a/drivers/staging/netwave/netwave_cs.c b/drivers/staging/netwave/netwave_cs.c index e936717..3875a72 100644 --- a/drivers/staging/netwave/netwave_cs.c +++ b/drivers/staging/netwave/netwave_cs.c @@ -46,7 +46,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/octeon/ethernet-mem.c b/drivers/staging/octeon/ethernet-mem.c index 00cc91d..635bb86 100644 --- a/drivers/staging/octeon/ethernet-mem.c +++ b/drivers/staging/octeon/ethernet-mem.c @@ -26,6 +26,7 @@ **********************************************************************/ #include #include +#include #include diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c index 4a2161f..e50a17d 100644 --- a/drivers/staging/octeon/ethernet.c +++ b/drivers/staging/octeon/ethernet.c @@ -30,6 +30,7 @@ #include #include #include +#include #include diff --git a/drivers/staging/otus/ioctl.c b/drivers/staging/otus/ioctl.c index 8c47b1a..84be4b2 100644 --- a/drivers/staging/otus/ioctl.c +++ b/drivers/staging/otus/ioctl.c @@ -23,6 +23,7 @@ /* Platform dependent. */ /* */ /************************************************************************/ +#include #include #include #include diff --git a/drivers/staging/otus/usbdrv.c b/drivers/staging/otus/usbdrv.c index 5e6a120..0ce65b5 100644 --- a/drivers/staging/otus/usbdrv.c +++ b/drivers/staging/otus/usbdrv.c @@ -38,6 +38,7 @@ #include "linux/netlink.h" #include "linux/rtnetlink.h" +#include "linux/slab.h" #include diff --git a/drivers/staging/otus/wrap_mem.c b/drivers/staging/otus/wrap_mem.c index 47cbce1..b003756 100644 --- a/drivers/staging/otus/wrap_mem.c +++ b/drivers/staging/otus/wrap_mem.c @@ -27,6 +27,7 @@ #include "usbdrv.h" #include +#include #include /* Memory management */ diff --git a/drivers/staging/otus/wrap_pkt.c b/drivers/staging/otus/wrap_pkt.c index a2f5cb1..5ecf38e 100644 --- a/drivers/staging/otus/wrap_pkt.c +++ b/drivers/staging/otus/wrap_pkt.c @@ -28,6 +28,7 @@ #include "usbdrv.h" #include +#include #include diff --git a/drivers/staging/otus/wrap_usb.c b/drivers/staging/otus/wrap_usb.c index 6b336ed..93459ca 100644 --- a/drivers/staging/otus/wrap_usb.c +++ b/drivers/staging/otus/wrap_usb.c @@ -28,6 +28,7 @@ #include "usbdrv.h" #include +#include #include extern void zfLnxInitUsbTxQ(zdev_t *dev); diff --git a/drivers/staging/otus/wwrap.c b/drivers/staging/otus/wwrap.c index 53d2a45..a74f7ee 100644 --- a/drivers/staging/otus/wwrap.c +++ b/drivers/staging/otus/wwrap.c @@ -26,6 +26,7 @@ #include "usbdrv.h" #include +#include #include extern void zfiRecv80211(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* addInfo); diff --git a/drivers/staging/otus/zdusb.c b/drivers/staging/otus/zdusb.c index 4cd9b7f..bb89d85 100644 --- a/drivers/staging/otus/zdusb.c +++ b/drivers/staging/otus/zdusb.c @@ -29,6 +29,7 @@ #endif #include +#include #include #include "usbdrv.h" diff --git a/drivers/staging/poch/poch.c b/drivers/staging/poch/poch.c index 9095158..f940a34 100644 --- a/drivers/staging/poch/poch.c +++ b/drivers/staging/poch/poch.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "poch.h" diff --git a/drivers/staging/pohmelfs/config.c b/drivers/staging/pohmelfs/config.c index 5d04bf5..eed0e55 100644 --- a/drivers/staging/pohmelfs/config.c +++ b/drivers/staging/pohmelfs/config.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "netfs.h" diff --git a/drivers/staging/pohmelfs/dir.c b/drivers/staging/pohmelfs/dir.c index aacd25b..79819f0 100644 --- a/drivers/staging/pohmelfs/dir.c +++ b/drivers/staging/pohmelfs/dir.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include "netfs.h" diff --git a/drivers/staging/pohmelfs/lock.c b/drivers/staging/pohmelfs/lock.c index 22fef18..6710114cd 100644 --- a/drivers/staging/pohmelfs/lock.c +++ b/drivers/staging/pohmelfs/lock.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include "netfs.h" diff --git a/drivers/staging/pohmelfs/net.c b/drivers/staging/pohmelfs/net.c index af7f262..4a86f0b 100644 --- a/drivers/staging/pohmelfs/net.c +++ b/drivers/staging/pohmelfs/net.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/staging/pohmelfs/path_entry.c b/drivers/staging/pohmelfs/path_entry.c index 3bad888..cdc4dd5 100644 --- a/drivers/staging/pohmelfs/path_entry.c +++ b/drivers/staging/pohmelfs/path_entry.c @@ -14,7 +14,6 @@ */ #include -#include #include #include #include diff --git a/drivers/staging/ramzswap/ramzswap_drv.c b/drivers/staging/ramzswap/ramzswap_drv.c index 5e422e2..ee5eb12 100644 --- a/drivers/staging/ramzswap/ramzswap_drv.c +++ b/drivers/staging/ramzswap/ramzswap_drv.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/staging/rt2860/pci_main_dev.c b/drivers/staging/rt2860/pci_main_dev.c index 6af4304..e665d86 100644 --- a/drivers/staging/rt2860/pci_main_dev.c +++ b/drivers/staging/rt2860/pci_main_dev.c @@ -37,6 +37,7 @@ #include "rt_config.h" #include +#include /* Following information will be show when you run 'modinfo' */ /* *** If you have a solution for the bug in current version of driver, please mail to me. */ diff --git a/drivers/staging/rt2860/rt_linux.c b/drivers/staging/rt2860/rt_linux.c index b5c78ae..fd9a207 100644 --- a/drivers/staging/rt2860/rt_linux.c +++ b/drivers/staging/rt2860/rt_linux.c @@ -27,6 +27,7 @@ #include #include +#include #include "rt_config.h" unsigned long RTDebugLevel = RT_DEBUG_ERROR; diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c index c2f472e..be2d17f 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c @@ -18,6 +18,7 @@ #include #include +#include #include #include diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c index bd5e77b..c5b80f9 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c @@ -31,6 +31,7 @@ ******************************************************************************/ #include #include +#include #include #include "ieee80211.h" diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c index b1757ac..55d12e3 100644 --- a/drivers/staging/rtl8187se/r8180_core.c +++ b/drivers/staging/rtl8187se/r8180_core.c @@ -30,6 +30,7 @@ #undef RX_DONT_PASS_UL #undef DUMMY_RX +#include #include #include diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c index ea96c49..d1d7b08 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #ifdef ENABLE_DOT11D diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c index a3302d5..de57967 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include "ieee80211.h" diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c b/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c index e2cbfd3..e869961 100644 --- a/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c +++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c @@ -1,5 +1,6 @@ #include "ieee80211.h" #include +#include #include "rtl819x_TS.h" #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 886105d..bb7e1ef 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -47,6 +47,7 @@ //#define CONFIG_RTL8192_IO_MAP #include +#include #include #include "r8192E_hw.h" #include "r8192E.h" diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c index 9d8cb0e..84a4e23 100644 --- a/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include "dot11d.h" diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c index 122f800..727cc55 100644 --- a/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c +++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c @@ -31,6 +31,7 @@ ******************************************************************************/ #include #include +#include #include #include "ieee80211.h" diff --git a/drivers/staging/rtl8192su/ieee80211/rtl819x_TSProc.c b/drivers/staging/rtl8192su/ieee80211/rtl819x_TSProc.c index 60cf1f8..38468c5 100644 --- a/drivers/staging/rtl8192su/ieee80211/rtl819x_TSProc.c +++ b/drivers/staging/rtl8192su/ieee80211/rtl819x_TSProc.c @@ -1,5 +1,6 @@ #include "ieee80211.h" #include +#include #include "rtl819x_TS.h" void TsSetupTimeOut(unsigned long data) diff --git a/drivers/staging/rtl8192su/r8192U_core.c b/drivers/staging/rtl8192su/r8192U_core.c index 7d0305c..e16256f 100644 --- a/drivers/staging/rtl8192su/r8192U_core.c +++ b/drivers/staging/rtl8192su/r8192U_core.c @@ -25,6 +25,7 @@ */ #include +#include #undef LOOP_TEST #undef DUMP_RX diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c index 27d9257..d54e3a7 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #ifdef ENABLE_DOT11D diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c index c0b2c02..750e94e 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_wx.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include "ieee80211.h" diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c index d1275e8..451120f 100644 --- a/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c +++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c @@ -1,5 +1,6 @@ #include "ieee80211.h" #include +#include #include "rtl819x_TS.h" void TsSetupTimeOut(unsigned long data) diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index f1e085b..68ebb02 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -70,6 +70,7 @@ double __extendsfdf2(float a) {return a;} #include "r8192U_dm.h" //#include "r8192xU_phyreg.h" #include +#include // FIXME: check if 2.6.7 is ok #ifdef CONFIG_RTL8192_PM diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c index 265de79..8888073 100644 --- a/drivers/staging/sep/sep_driver.c +++ b/drivers/staging/sep/sep_driver.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/staging/sm7xx/smtcfb.c b/drivers/staging/sm7xx/smtcfb.c index 9c82a1a..8d7261c 100644 --- a/drivers/staging/sm7xx/smtcfb.c +++ b/drivers/staging/sm7xx/smtcfb.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/staging/strip/strip.c b/drivers/staging/strip/strip.c index 698aade..c976c6b 100644 --- a/drivers/staging/strip/strip.c +++ b/drivers/staging/strip/strip.c @@ -107,6 +107,7 @@ static const char StripVersion[] = "1.3A-STUART.CHESHIRE"; #include #include #include +#include #include #include diff --git a/drivers/staging/udlfb/udlfb.c b/drivers/staging/udlfb/udlfb.c index 8f6223c..a78ade0 100644 --- a/drivers/staging/udlfb/udlfb.c +++ b/drivers/staging/udlfb/udlfb.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "udlfb.h" diff --git a/drivers/staging/usbip/stub_dev.c b/drivers/staging/usbip/stub_dev.c index 173b018..3f95605 100644 --- a/drivers/staging/usbip/stub_dev.c +++ b/drivers/staging/usbip/stub_dev.c @@ -17,6 +17,8 @@ * USA. */ +#include + #include "usbip_common.h" #include "stub.h" diff --git a/drivers/staging/usbip/stub_main.c b/drivers/staging/usbip/stub_main.c index ba1678f..6665cef 100644 --- a/drivers/staging/usbip/stub_main.c +++ b/drivers/staging/usbip/stub_main.c @@ -17,6 +17,7 @@ * USA. */ +#include #include "usbip_common.h" #include "stub.h" diff --git a/drivers/staging/usbip/stub_rx.c b/drivers/staging/usbip/stub_rx.c index 815fb7c..bc26740 100644 --- a/drivers/staging/usbip/stub_rx.c +++ b/drivers/staging/usbip/stub_rx.c @@ -17,6 +17,8 @@ * USA. */ +#include + #include "usbip_common.h" #include "stub.h" #include "../../usb/core/hcd.h" diff --git a/drivers/staging/usbip/stub_tx.c b/drivers/staging/usbip/stub_tx.c index e2ab4f3..d7136e2 100644 --- a/drivers/staging/usbip/stub_tx.c +++ b/drivers/staging/usbip/stub_tx.c @@ -17,6 +17,8 @@ * USA. */ +#include + #include "usbip_common.h" #include "stub.h" diff --git a/drivers/staging/usbip/usbip_common.c b/drivers/staging/usbip/usbip_common.c index 7a45da8..e3fa421 100644 --- a/drivers/staging/usbip/usbip_common.c +++ b/drivers/staging/usbip/usbip_common.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "usbip_common.h" /* version information */ diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c index ef43713..0b17661 100644 --- a/drivers/staging/usbip/vhci_hcd.c +++ b/drivers/staging/usbip/vhci_hcd.c @@ -17,6 +17,7 @@ * USA. */ +#include #include "usbip_common.h" #include "vhci.h" diff --git a/drivers/staging/usbip/vhci_rx.c b/drivers/staging/usbip/vhci_rx.c index 7636d86..8147d72 100644 --- a/drivers/staging/usbip/vhci_rx.c +++ b/drivers/staging/usbip/vhci_rx.c @@ -17,6 +17,8 @@ * USA. */ +#include + #include "usbip_common.h" #include "vhci.h" diff --git a/drivers/staging/usbip/vhci_tx.c b/drivers/staging/usbip/vhci_tx.c index 7a00eb4..b71b4c2 100644 --- a/drivers/staging/usbip/vhci_tx.c +++ b/drivers/staging/usbip/vhci_tx.c @@ -17,6 +17,8 @@ * USA. */ +#include + #include "usbip_common.h" #include "vhci.h" diff --git a/drivers/staging/vme/bridges/vme_ca91cx42.c b/drivers/staging/vme/bridges/vme_ca91cx42.c index 2795ff2..b159ea5 100644 --- a/drivers/staging/vme/bridges/vme_ca91cx42.c +++ b/drivers/staging/vme/bridges/vme_ca91cx42.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/staging/vme/bridges/vme_tsi148.c b/drivers/staging/vme/bridges/vme_tsi148.c index faf652e..68f2442 100644 --- a/drivers/staging/vme/bridges/vme_tsi148.c +++ b/drivers/staging/vme/bridges/vme_tsi148.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c index c60c80f..1ab9a98 100644 --- a/drivers/staging/vme/devices/vme_user.c +++ b/drivers/staging/vme/devices/vme_user.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/staging/vme/vme.c b/drivers/staging/vme/vme.c index d6d84eb..934283a 100644 --- a/drivers/staging/vme/vme.c +++ b/drivers/staging/vme/vme.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "vme.h" #include "vme_bridge.h" diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 1d64365..e40a2e9 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -84,6 +84,7 @@ #include "iowpa.h" #include #include +#include //#define DEBUG /*--------------------- Static Definitions -------------------------*/ diff --git a/drivers/staging/winbond/wb35reg.c b/drivers/staging/winbond/wb35reg.c index f5608ad..1b93547 100644 --- a/drivers/staging/winbond/wb35reg.c +++ b/drivers/staging/winbond/wb35reg.c @@ -2,6 +2,7 @@ #include "wb35reg_f.h" #include +#include extern void phy_calibration_winbond(struct hw_data *phw_data, u32 frequency); diff --git a/drivers/staging/winbond/wb35rx.c b/drivers/staging/winbond/wb35rx.c index 4d41f6c..d7b57e6 100644 --- a/drivers/staging/winbond/wb35rx.c +++ b/drivers/staging/winbond/wb35rx.c @@ -9,6 +9,7 @@ // //============================================================================ #include +#include #include "core.h" #include "sysdef.h" diff --git a/drivers/staging/winbond/wb35tx.c b/drivers/staging/winbond/wb35tx.c index 5869ef4..bda7a91 100644 --- a/drivers/staging/winbond/wb35tx.c +++ b/drivers/staging/winbond/wb35tx.c @@ -9,6 +9,7 @@ // //============================================================================ #include +#include #include "wb35tx_f.h" #include "mds_f.h" diff --git a/drivers/staging/wlags49_h2/wl_cs.c b/drivers/staging/wlags49_h2/wl_cs.c index 811a8da..9da42e6 100644 --- a/drivers/staging/wlags49_h2/wl_cs.c +++ b/drivers/staging/wlags49_h2/wl_cs.c @@ -67,7 +67,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/wlags49_h2/wl_netdev.c b/drivers/staging/wlags49_h2/wl_netdev.c index fa082d9..1db73eb 100644 --- a/drivers/staging/wlags49_h2/wl_netdev.c +++ b/drivers/staging/wlags49_h2/wl_netdev.c @@ -65,6 +65,7 @@ #include #include +#include #include #include // #include diff --git a/drivers/staging/wlags49_h2/wl_pci.c b/drivers/staging/wlags49_h2/wl_pci.c index 01e4bec..6751b4b 100644 --- a/drivers/staging/wlags49_h2/wl_pci.c +++ b/drivers/staging/wlags49_h2/wl_pci.c @@ -71,7 +71,6 @@ #include #include #include -#include #include #include //#include diff --git a/drivers/staging/wlags49_h2/wl_priv.c b/drivers/staging/wlags49_h2/wl_priv.c index ee610c7..727ea8a 100644 --- a/drivers/staging/wlags49_h2/wl_priv.c +++ b/drivers/staging/wlags49_h2/wl_priv.c @@ -65,6 +65,7 @@ #include #include +#include #include #include diff --git a/drivers/staging/wlan-ng/p80211req.c b/drivers/staging/wlan-ng/p80211req.c index c2e95f1..e1e7bf1 100644 --- a/drivers/staging/wlan-ng/p80211req.c +++ b/drivers/staging/wlan-ng/p80211req.c @@ -55,7 +55,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/wlan-ng/p80211wep.c b/drivers/staging/wlan-ng/p80211wep.c index ecbb15b..80c2d3b 100644 --- a/drivers/staging/wlan-ng/p80211wep.c +++ b/drivers/staging/wlan-ng/p80211wep.c @@ -50,7 +50,6 @@ #include #include -#include #include #include diff --git a/drivers/staging/wlan-ng/p80211wext.c b/drivers/staging/wlan-ng/p80211wext.c index 2fa1dfa..83f1d6c 100644 --- a/drivers/staging/wlan-ng/p80211wext.c +++ b/drivers/staging/wlan-ng/p80211wext.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/wlan-ng/prism2fw.c b/drivers/staging/wlan-ng/prism2fw.c index 4be54ce..d383ea8 100644 --- a/drivers/staging/wlan-ng/prism2fw.c +++ b/drivers/staging/wlan-ng/prism2fw.c @@ -48,6 +48,7 @@ /*================================================================*/ /* System Includes */ #include +#include /*================================================================*/ /* Local Constants */ diff --git a/drivers/staging/wlan-ng/prism2mgmt.c b/drivers/staging/wlan-ng/prism2mgmt.c index ad163da..4d1cdfc 100644 --- a/drivers/staging/wlan-ng/prism2mgmt.c +++ b/drivers/staging/wlan-ng/prism2mgmt.c @@ -63,7 +63,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/wlan-ng/prism2mib.c b/drivers/staging/wlan-ng/prism2mib.c index 98a5d58..0b0ec9c 100644 --- a/drivers/staging/wlan-ng/prism2mib.c +++ b/drivers/staging/wlan-ng/prism2mib.c @@ -54,7 +54,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/tc/tc.c b/drivers/tc/tc.c index e5bd447..a8aaf6a 100644 --- a/drivers/tc/tc.c +++ b/drivers/tc/tc.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c index 5066de5..9b6297f 100644 --- a/drivers/thermal/thermal_sys.c +++ b/drivers/thermal/thermal_sys.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c index 4de382a..bff1afb 100644 --- a/drivers/uio/uio.c +++ b/drivers/uio/uio.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/uio/uio_aec.c b/drivers/uio/uio_aec.c index b7830e9..72b22d4 100644 --- a/drivers/uio/uio_aec.c +++ b/drivers/uio/uio_aec.c @@ -27,6 +27,7 @@ #include #include #include +#include #define PCI_VENDOR_ID_AEC 0xaecb #define PCI_DEVICE_ID_AEC_VITCLTC 0x6250 diff --git a/drivers/uio/uio_cif.c b/drivers/uio/uio_cif.c index 28034c8..371f87f 100644 --- a/drivers/uio/uio_cif.c +++ b/drivers/uio/uio_cif.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include diff --git a/drivers/uio/uio_netx.c b/drivers/uio/uio_netx.c index afbf0bd..5a18e9f 100644 --- a/drivers/uio/uio_netx.c +++ b/drivers/uio/uio_netx.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #define PCI_VENDOR_ID_HILSCHER 0x15CF diff --git a/drivers/uio/uio_pci_generic.c b/drivers/uio/uio_pci_generic.c index 313da35..85c9884 100644 --- a/drivers/uio/uio_pci_generic.c +++ b/drivers/uio/uio_pci_generic.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/drivers/uio/uio_pdrv.c b/drivers/uio/uio_pdrv.c index d494ce9..7d3e469 100644 --- a/drivers/uio/uio_pdrv.c +++ b/drivers/uio/uio_pdrv.c @@ -11,6 +11,7 @@ #include #include #include +#include #define DRIVER_NAME "uio_pdrv" diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c index 1ef3b8f..61e569d 100644 --- a/drivers/uio/uio_pdrv_genirq.c +++ b/drivers/uio/uio_pdrv_genirq.c @@ -21,6 +21,7 @@ #include #include #include +#include #define DRIVER_NAME "uio_pdrv_genirq" diff --git a/drivers/uio/uio_sercos3.c b/drivers/uio/uio_sercos3.c index a6d1b2b..3d461cd 100644 --- a/drivers/uio/uio_sercos3.c +++ b/drivers/uio/uio_sercos3.c @@ -28,6 +28,7 @@ #include #include #include +#include /* ID's for SERCOS III PCI card (PLX 9030) */ #define SERCOS_SUB_VENDOR_ID 0x1971 diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c index 3e86240..1e9ba4b 100644 --- a/drivers/usb/atm/speedtch.c +++ b/drivers/usb/atm/speedtch.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index c539524..25f01b5 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c @@ -66,6 +66,7 @@ #include #include #include +#include #include diff --git a/drivers/usb/c67x00/c67x00-drv.c b/drivers/usb/c67x00/c67x00-drv.c index 029ee4a..b6d4923 100644 --- a/drivers/usb/c67x00/c67x00-drv.c +++ b/drivers/usb/c67x00/c67x00-drv.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include diff --git a/drivers/usb/c67x00/c67x00-sched.c b/drivers/usb/c67x00/c67x00-sched.c index 85dfe29..f6b3c25 100644 --- a/drivers/usb/c67x00/c67x00-sched.c +++ b/drivers/usb/c67x00/c67x00-sched.c @@ -22,6 +22,7 @@ */ #include +#include #include "c67x00.h" #include "c67x00-hcd.h" diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c index 8588c09..3e7c1b8 100644 --- a/drivers/usb/class/usbtmc.c +++ b/drivers/usb/class/usbtmc.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c index d41811b..19bc03a 100644 --- a/drivers/usb/core/devices.c +++ b/drivers/usb/core/devices.c @@ -50,7 +50,7 @@ #include #include -#include +#include #include #include #include diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index f3c2338..6a3b5ca 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -23,6 +23,7 @@ */ #include +#include #include #include #include diff --git a/drivers/usb/core/endpoint.c b/drivers/usb/core/endpoint.c index d26b9ea..4f84a41 100644 --- a/drivers/usb/core/endpoint.c +++ b/drivers/usb/core/endpoint.c @@ -11,6 +11,7 @@ #include #include +#include #include #include #include "usb.h" diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c index c3536f1..f06f5db 100644 --- a/drivers/usb/core/file.c +++ b/drivers/usb/core/file.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c index f79bdfe..75a256f 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/atmel_usba_udc.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c index c7cb87a..6996951 100644 --- a/drivers/usb/gadget/ci13xxx_udc.c +++ b/drivers/usb/gadget/ci13xxx_udc.c @@ -62,6 +62,7 @@ #include #include #include +#include #include #include diff --git a/drivers/usb/gadget/config.c b/drivers/usb/gadget/config.c index e1191b9..47e8e72 100644 --- a/drivers/usb/gadget/config.c +++ b/drivers/usb/gadget/config.c @@ -19,6 +19,7 @@ */ #include +#include #include #include #include diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c index e49c732..400e1eb 100644 --- a/drivers/usb/gadget/f_acm.c +++ b/drivers/usb/gadget/f_acm.c @@ -14,6 +14,7 @@ /* #define VERBOSE_DEBUG */ +#include #include #include diff --git a/drivers/usb/gadget/f_audio.c b/drivers/usb/gadget/f_audio.c index f1e3aad..43bf445 100644 --- a/drivers/usb/gadget/f_audio.c +++ b/drivers/usb/gadget/f_audio.c @@ -9,6 +9,7 @@ * Licensed under the GPL-2 or later. */ +#include #include #include #include diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c index 2fff530..4e59532 100644 --- a/drivers/usb/gadget/f_ecm.c +++ b/drivers/usb/gadget/f_ecm.c @@ -21,6 +21,7 @@ /* #define VERBOSE_DEBUG */ +#include #include #include #include diff --git a/drivers/usb/gadget/f_eem.c b/drivers/usb/gadget/f_eem.c index d4f0db5..38226e9 100644 --- a/drivers/usb/gadget/f_eem.c +++ b/drivers/usb/gadget/f_eem.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "u_ether.h" diff --git a/drivers/usb/gadget/f_loopback.c b/drivers/usb/gadget/f_loopback.c index 6cb29d3..e91d1b1 100644 --- a/drivers/usb/gadget/f_loopback.c +++ b/drivers/usb/gadget/f_loopback.c @@ -21,6 +21,7 @@ /* #define VERBOSE_DEBUG */ +#include #include #include diff --git a/drivers/usb/gadget/f_obex.c b/drivers/usb/gadget/f_obex.c index b4a3ba6..8f8c643 100644 --- a/drivers/usb/gadget/f_obex.c +++ b/drivers/usb/gadget/f_obex.c @@ -23,6 +23,7 @@ /* #define VERBOSE_DEBUG */ +#include #include #include diff --git a/drivers/usb/gadget/f_phonet.c b/drivers/usb/gadget/f_phonet.c index d2de10b..3c6e1a0 100644 --- a/drivers/usb/gadget/f_phonet.c +++ b/drivers/usb/gadget/f_phonet.c @@ -20,6 +20,7 @@ * 02110-1301 USA */ +#include #include #include diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c index a30e60c..56b0221 100644 --- a/drivers/usb/gadget/f_rndis.c +++ b/drivers/usb/gadget/f_rndis.c @@ -24,6 +24,7 @@ /* #define VERBOSE_DEBUG */ +#include #include #include #include diff --git a/drivers/usb/gadget/f_serial.c b/drivers/usb/gadget/f_serial.c index db0aa93..490b00b 100644 --- a/drivers/usb/gadget/f_serial.c +++ b/drivers/usb/gadget/f_serial.c @@ -10,6 +10,7 @@ * either version 2 of that License or (at your option) any later version. */ +#include #include #include diff --git a/drivers/usb/gadget/f_sourcesink.c b/drivers/usb/gadget/f_sourcesink.c index 09cba273..6d3cc44 100644 --- a/drivers/usb/gadget/f_sourcesink.c +++ b/drivers/usb/gadget/f_sourcesink.c @@ -21,6 +21,7 @@ /* #define VERBOSE_DEBUG */ +#include #include #include diff --git a/drivers/usb/gadget/f_subset.c b/drivers/usb/gadget/f_subset.c index a9c98fd..8675ca4 100644 --- a/drivers/usb/gadget/f_subset.c +++ b/drivers/usb/gadget/f_subset.c @@ -19,6 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include #include #include #include diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c index 04f6224..2b56ce6 100644 --- a/drivers/usb/gadget/gmidi.c +++ b/drivers/usb/gadget/gmidi.c @@ -21,6 +21,7 @@ /* #define VERBOSE_DEBUG */ #include +#include #include #include diff --git a/drivers/usb/gadget/imx_udc.c b/drivers/usb/gadget/imx_udc.c index 01ee0b9..e743122 100644 --- a/drivers/usb/gadget/imx_udc.c +++ b/drivers/usb/gadget/imx_udc.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c index 6cd3d54..fded3fc 100644 --- a/drivers/usb/gadget/lh7a40x_udc.c +++ b/drivers/usb/gadget/lh7a40x_udc.c @@ -22,6 +22,7 @@ */ #include +#include #include "lh7a40x_udc.h" diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c index a8c8543..166bf71 100644 --- a/drivers/usb/gadget/m66592-udc.c +++ b/drivers/usb/gadget/m66592-udc.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c index 05b892c..85b0d89 100644 --- a/drivers/usb/gadget/pxa27x_udc.c +++ b/drivers/usb/gadget/pxa27x_udc.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c index 5e13d23..e848ecb 100644 --- a/drivers/usb/gadget/r8a66597-udc.c +++ b/drivers/usb/gadget/r8a66597-udc.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c index 48267bc..5c0d06c 100644 --- a/drivers/usb/gadget/rndis.c +++ b/drivers/usb/gadget/rndis.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index f742c8e..124a8cc 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/drivers/usb/gadget/u_audio.c b/drivers/usb/gadget/u_audio.c index 35e0930..7a86d2c 100644 --- a/drivers/usb/gadget/u_audio.c +++ b/drivers/usb/gadget/u_audio.c @@ -10,6 +10,7 @@ */ #include +#include #include #include #include diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c index 84ca195..07f4178 100644 --- a/drivers/usb/gadget/u_ether.c +++ b/drivers/usb/gadget/u_ether.c @@ -23,6 +23,7 @@ /* #define VERBOSE_DEBUG */ #include +#include #include #include #include diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c index adf8260..16bdf77 100644 --- a/drivers/usb/gadget/u_serial.c +++ b/drivers/usb/gadget/u_serial.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "u_serial.h" diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index fac81ee..807280d 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c @@ -50,6 +50,7 @@ /* #define VERBOSE_DEBUG */ #include +#include #include #include diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index dc55a62..207e7a8 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -35,6 +34,7 @@ #include #include #include +#include #include "../core/hcd.h" diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c index 23cd917..ead59f4 100644 --- a/drivers/usb/host/ehci-mxc.c +++ b/drivers/usb/host/ehci-mxc.c @@ -21,6 +21,7 @@ #include #include #include +#include #include diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index f0282d6..a67a003 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -37,6 +37,7 @@ #include #include #include +#include #include /* diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c index 5dcfb3d..15379c6 100644 --- a/drivers/usb/host/fhci-hcd.c +++ b/drivers/usb/host/fhci-hcd.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include "../core/hcd.h" diff --git a/drivers/usb/host/fhci-mem.c b/drivers/usb/host/fhci-mem.c index 2c0736c..5591bfb 100644 --- a/drivers/usb/host/fhci-mem.c +++ b/drivers/usb/host/fhci-mem.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include "../core/hcd.h" diff --git a/drivers/usb/host/fhci-q.c b/drivers/usb/host/fhci-q.c index b0a1446..f73c923 100644 --- a/drivers/usb/host/fhci-q.c +++ b/drivers/usb/host/fhci-q.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include "../core/hcd.h" diff --git a/drivers/usb/host/fhci-tds.c b/drivers/usb/host/fhci-tds.c index e123289..5701347 100644 --- a/drivers/usb/host/fhci-tds.c +++ b/drivers/usb/host/fhci-tds.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/host/hwa-hc.c b/drivers/usb/host/hwa-hc.c index 88b0321..35742f8 100644 --- a/drivers/usb/host/hwa-hc.c +++ b/drivers/usb/host/hwa-hc.c @@ -55,6 +55,7 @@ */ #include #include +#include #include #include #include diff --git a/drivers/usb/host/imx21-hcd.c b/drivers/usb/host/imx21-hcd.c index 213e270..8a12f29 100644 --- a/drivers/usb/host/imx21-hcd.c +++ b/drivers/usb/host/imx21-hcd.c @@ -54,6 +54,7 @@ #include #include #include +#include #include #include "../core/hcd.h" diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index a2b3054..92de71d 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c @@ -62,6 +62,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index 35288bc..83094d0 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c @@ -8,6 +8,7 @@ */ #include +#include static void urb_free_priv (struct ohci_hcd *hc, urb_priv_t *urb_priv) { diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index f71a73a..d478ffa 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include "../core/hcd.h" diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c index e52b954..98cf0b2 100644 --- a/drivers/usb/host/uhci-debug.c +++ b/drivers/usb/host/uhci-debug.c @@ -9,6 +9,7 @@ * (C) Copyright 1999-2001 Johannes Erdfelt */ +#include #include #include #include diff --git a/drivers/usb/host/whci/asl.c b/drivers/usb/host/whci/asl.c index 562eba1..7732493 100644 --- a/drivers/usb/host/whci/asl.c +++ b/drivers/usb/host/whci/asl.c @@ -16,6 +16,7 @@ * along with this program. If not, see . */ #include +#include #include #include #include diff --git a/drivers/usb/host/whci/debug.c b/drivers/usb/host/whci/debug.c index 8c1c610..c5305b5 100644 --- a/drivers/usb/host/whci/debug.c +++ b/drivers/usb/host/whci/debug.c @@ -15,6 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ +#include #include #include #include diff --git a/drivers/usb/host/whci/init.c b/drivers/usb/host/whci/init.c index 34a783c..f7582e8 100644 --- a/drivers/usb/host/whci/init.c +++ b/drivers/usb/host/whci/init.c @@ -16,6 +16,7 @@ * along with this program. If not, see . */ #include +#include #include #include diff --git a/drivers/usb/host/whci/pzl.c b/drivers/usb/host/whci/pzl.c index 0db3fb2..33c5580 100644 --- a/drivers/usb/host/whci/pzl.c +++ b/drivers/usb/host/whci/pzl.c @@ -16,6 +16,7 @@ * along with this program. If not, see . */ #include +#include #include #include #include diff --git a/drivers/usb/host/whci/qset.c b/drivers/usb/host/whci/qset.c index 7d4204d..141d049 100644 --- a/drivers/usb/host/whci/qset.c +++ b/drivers/usb/host/whci/qset.c @@ -17,6 +17,7 @@ */ #include #include +#include #include #include diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index bba9b19..c09539b 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -22,6 +22,7 @@ #include #include +#include #include #include "xhci.h" diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 6ba841b..85d7e8f 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -65,6 +65,7 @@ */ #include +#include #include "xhci.h" /* diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 492a61c..7e42772 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "xhci.h" diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c index 3adab04..094f91c 100644 --- a/drivers/usb/misc/appledisplay.c +++ b/drivers/usb/misc/appledisplay.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/misc/cypress_cy7c63.c b/drivers/usb/misc/cypress_cy7c63.c index 1547d8c..2f43c57 100644 --- a/drivers/usb/misc/cypress_cy7c63.c +++ b/drivers/usb/misc/cypress_cy7c63.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #define DRIVER_AUTHOR "Oliver Bock (bock@tfh-berlin.de)" diff --git a/drivers/usb/misc/cytherm.c b/drivers/usb/misc/cytherm.c index b9cbbbd..1d7251b 100644 --- a/drivers/usb/misc/cytherm.c +++ b/drivers/usb/misc/cytherm.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include diff --git a/drivers/usb/misc/isight_firmware.c b/drivers/usb/misc/isight_firmware.c index 06e990a..fe1d443 100644 --- a/drivers/usb/misc/isight_firmware.c +++ b/drivers/usb/misc/isight_firmware.c @@ -25,6 +25,7 @@ #include #include #include +#include static const struct usb_device_id id_table[] = { {USB_DEVICE(0x05ac, 0x8300)}, diff --git a/drivers/usb/misc/sisusbvga/sisusb_con.c b/drivers/usb/misc/sisusbvga/sisusb_con.c index b624320..b271b05 100644 --- a/drivers/usb/misc/sisusbvga/sisusb_con.c +++ b/drivers/usb/misc/sisusbvga/sisusb_con.c @@ -58,7 +58,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/usb/misc/sisusbvga/sisusb_init.c b/drivers/usb/misc/sisusbvga/sisusb_init.c index 0ab9907..cb8a3d9 100644 --- a/drivers/usb/misc/sisusbvga/sisusb_init.c +++ b/drivers/usb/misc/sisusbvga/sisusb_init.c @@ -41,7 +41,6 @@ #include #include #include -#include #include #include "sisusb.h" diff --git a/drivers/usb/misc/trancevibrator.c b/drivers/usb/misc/trancevibrator.c index 5da28ea..d77aba4 100644 --- a/drivers/usb/misc/trancevibrator.c +++ b/drivers/usb/misc/trancevibrator.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c index f56fed5..796e2f6 100644 --- a/drivers/usb/misc/uss720.c +++ b/drivers/usb/misc/uss720.c @@ -49,6 +49,7 @@ #include #include #include +#include /* * Version Information diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c index 6dd44bc..ddf7f9a 100644 --- a/drivers/usb/mon/mon_bin.c +++ b/drivers/usb/mon/mon_bin.c @@ -17,6 +17,7 @@ #include #include #include +#include #include diff --git a/drivers/usb/mon/mon_main.c b/drivers/usb/mon/mon_main.c index e0c2db3..e4af18b 100644 --- a/drivers/usb/mon/mon_main.c +++ b/drivers/usb/mon/mon_main.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include diff --git a/drivers/usb/mon/mon_stat.c b/drivers/usb/mon/mon_stat.c index ac8b0d5..1becdc3 100644 --- a/drivers/usb/mon/mon_stat.c +++ b/drivers/usb/mon/mon_stat.c @@ -8,6 +8,7 @@ */ #include +#include #include #include #include diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c index 31c1188..4d0be13 100644 --- a/drivers/usb/mon/mon_text.c +++ b/drivers/usb/mon/mon_text.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index bcee133..719a22d 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c index 3c69a76..59dc3d3 100644 --- a/drivers/usb/musb/cppi_dma.c +++ b/drivers/usb/musb/cppi_dma.c @@ -7,6 +7,7 @@ */ #include +#include #include #include "musb_core.h" diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index a883f9d..29bce5c 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index a9f288c..6fca870 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -43,6 +43,7 @@ #include #include #include +#include #include "musb_core.h" diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c index bfe5fe4..7775e1c 100644 --- a/drivers/usb/musb/musb_virthub.c +++ b/drivers/usb/musb/musb_virthub.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c index 2fa7d5c..1008044 100644 --- a/drivers/usb/musb/musbhsdma.c +++ b/drivers/usb/musb/musbhsdma.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "musb_core.h" #include "musbhsdma.h" diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 3fe1686..490cdf1 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c index 1c86809..5afa070 100644 --- a/drivers/usb/musb/tusb6010_omap.c +++ b/drivers/usb/musb/tusb6010_omap.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff --git a/drivers/usb/otg/gpio_vbus.c b/drivers/usb/otg/gpio_vbus.c index 1c26c94..221c444 100644 --- a/drivers/usb/otg/gpio_vbus.c +++ b/drivers/usb/otg/gpio_vbus.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/otg/nop-usb-xceiv.c b/drivers/usb/otg/nop-usb-xceiv.c index af456b4..e70014a 100644 --- a/drivers/usb/otg/nop-usb-xceiv.c +++ b/drivers/usb/otg/nop-usb-xceiv.c @@ -30,6 +30,7 @@ #include #include #include +#include struct nop_usb_xceiv { struct otg_transceiver otg; diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c index 3e4e9f4..223cdf4 100644 --- a/drivers/usb/otg/twl4030-usb.c +++ b/drivers/usb/otg/twl4030-usb.c @@ -37,6 +37,7 @@ #include #include #include +#include /* Register defines */ diff --git a/drivers/usb/otg/ulpi.c b/drivers/usb/otg/ulpi.c index 8965274..9010225 100644 --- a/drivers/usb/otg/ulpi.c +++ b/drivers/usb/otg/ulpi.c @@ -24,6 +24,7 @@ */ #include +#include #include #include #include diff --git a/drivers/usb/serial/aircable.c b/drivers/usb/serial/aircable.c index 365db10..4fd7af9 100644 --- a/drivers/usb/serial/aircable.c +++ b/drivers/usb/serial/aircable.c @@ -43,6 +43,7 @@ */ #include +#include #include #include #include diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index 547c944..9b66bf1 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c index ba555c5..7f547dc 100644 --- a/drivers/usb/serial/bus.c +++ b/drivers/usb/serial/bus.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c index 9f4fed1..7e8e398 100644 --- a/drivers/usb/serial/ch341.c +++ b/drivers/usb/serial/ch341.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/serial/navman.c b/drivers/usb/serial/navman.c index 04a6cbb..a6b207c 100644 --- a/drivers/usb/serial/navman.c +++ b/drivers/usb/serial/navman.c @@ -12,6 +12,7 @@ * flags as the navman is rx only so cannot echo. */ +#include #include #include #include diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index 701452a..ed01f3b 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 950cb31..ca9d866 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c index 4b463cd..43a0cad 100644 --- a/drivers/usb/serial/safe_serial.c +++ b/drivers/usb/serial/safe_serial.c @@ -64,8 +64,8 @@ #include #include +#include #include -#include #include #include #include diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 34e6f89..9202f94 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/serial/symbolserial.c b/drivers/usb/serial/symbolserial.c index ee190cc..d9457bd 100644 --- a/drivers/usb/serial/symbolserial.c +++ b/drivers/usb/serial/symbolserial.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/serial/usb_debug.c b/drivers/usb/serial/usb_debug.c index 252cc2d..28026b4 100644 --- a/drivers/usb/serial/usb_debug.c +++ b/drivers/usb/serial/usb_debug.c @@ -8,6 +8,7 @@ * 2 as published by the Free Software Foundation. */ +#include #include #include #include diff --git a/drivers/usb/storage/alauda.c b/drivers/usb/storage/alauda.c index 67edc65..42d0eae 100644 --- a/drivers/usb/storage/alauda.c +++ b/drivers/usb/storage/alauda.c @@ -32,6 +32,7 @@ */ #include +#include #include #include diff --git a/drivers/usb/storage/karma.c b/drivers/usb/storage/karma.c index 7953d93..ba1b789 100644 --- a/drivers/usb/storage/karma.c +++ b/drivers/usb/storage/karma.c @@ -19,6 +19,7 @@ */ #include +#include #include #include diff --git a/drivers/usb/storage/option_ms.c b/drivers/usb/storage/option_ms.c index 773a5cd..8946018 100644 --- a/drivers/usb/storage/option_ms.c +++ b/drivers/usb/storage/option_ms.c @@ -21,6 +21,7 @@ */ #include +#include #include "usb.h" #include "transport.h" diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index 4cc0355..d8d98cf 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -43,7 +43,6 @@ * 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include #include #include diff --git a/drivers/usb/storage/sierra_ms.c b/drivers/usb/storage/sierra_ms.c index 4395c41..57fc2f5 100644 --- a/drivers/usb/storage/sierra_ms.c +++ b/drivers/usb/storage/sierra_ms.c @@ -3,6 +3,7 @@ #include #include #include +#include #include "usb.h" #include "transport.h" diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index 4680381..f253ede 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c @@ -44,8 +44,8 @@ */ #include +#include #include -#include #include diff --git a/drivers/usb/wusbcore/cbaf.c b/drivers/usb/wusbcore/cbaf.c index 51a8e0d..c0c5665 100644 --- a/drivers/usb/wusbcore/cbaf.c +++ b/drivers/usb/wusbcore/cbaf.c @@ -92,6 +92,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/usb/wusbcore/crypto.c b/drivers/usb/wusbcore/crypto.c index 9579cf4..827c87f 100644 --- a/drivers/usb/wusbcore/crypto.c +++ b/drivers/usb/wusbcore/crypto.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include diff --git a/drivers/usb/wusbcore/devconnect.c b/drivers/usb/wusbcore/devconnect.c index 1c91828..46e79d3 100644 --- a/drivers/usb/wusbcore/devconnect.c +++ b/drivers/usb/wusbcore/devconnect.c @@ -88,6 +88,7 @@ #include #include +#include #include #include "wusbhc.h" diff --git a/drivers/usb/wusbcore/mmc.c b/drivers/usb/wusbcore/mmc.c index 2d82739..0a57ff0 100644 --- a/drivers/usb/wusbcore/mmc.c +++ b/drivers/usb/wusbcore/mmc.c @@ -37,6 +37,7 @@ * - add timers that autoremove intervalled IEs? */ #include +#include #include "wusbhc.h" /* Initialize the MMCIEs handling mechanism */ diff --git a/drivers/usb/wusbcore/rh.c b/drivers/usb/wusbcore/rh.c index 9fe4246..a68ad7a 100644 --- a/drivers/usb/wusbcore/rh.c +++ b/drivers/usb/wusbcore/rh.c @@ -69,6 +69,7 @@ * * wusbhc_rh_start_port_reset() ??? unimplemented */ +#include #include "wusbhc.h" /* diff --git a/drivers/usb/wusbcore/security.c b/drivers/usb/wusbcore/security.c index edcd2d7..b60799b 100644 --- a/drivers/usb/wusbcore/security.c +++ b/drivers/usb/wusbcore/security.c @@ -23,6 +23,7 @@ * FIXME: docs */ #include +#include #include #include #include "wusbhc.h" diff --git a/drivers/usb/wusbcore/wa-hc.c b/drivers/usb/wusbcore/wa-hc.c index 9d04722..59a748a 100644 --- a/drivers/usb/wusbcore/wa-hc.c +++ b/drivers/usb/wusbcore/wa-hc.c @@ -22,6 +22,7 @@ * * FIXME: docs */ +#include #include "wusbhc.h" #include "wa-hc.h" diff --git a/drivers/usb/wusbcore/wa-nep.c b/drivers/usb/wusbcore/wa-nep.c index 17d2626..f67f7f1 100644 --- a/drivers/usb/wusbcore/wa-nep.c +++ b/drivers/usb/wusbcore/wa-nep.c @@ -51,6 +51,7 @@ */ #include #include +#include #include "wa-hc.h" #include "wusbhc.h" diff --git a/drivers/usb/wusbcore/wa-rpipe.c b/drivers/usb/wusbcore/wa-rpipe.c index 7369655..c7b1d81 100644 --- a/drivers/usb/wusbcore/wa-rpipe.c +++ b/drivers/usb/wusbcore/wa-rpipe.c @@ -60,6 +60,7 @@ #include #include #include +#include #include "wusbhc.h" #include "wa-hc.h" diff --git a/drivers/usb/wusbcore/wa-xfer.c b/drivers/usb/wusbcore/wa-xfer.c index 489b478..112ef7e 100644 --- a/drivers/usb/wusbcore/wa-xfer.c +++ b/drivers/usb/wusbcore/wa-xfer.c @@ -81,6 +81,7 @@ */ #include #include +#include #include #include "wa-hc.h" diff --git a/drivers/uwb/address.c b/drivers/uwb/address.c index ad21b1d..9733213 100644 --- a/drivers/uwb/address.c +++ b/drivers/uwb/address.c @@ -23,6 +23,7 @@ * FIXME: docs */ +#include #include #include #include diff --git a/drivers/uwb/allocator.c b/drivers/uwb/allocator.c index c13cec7..436e4f7 100644 --- a/drivers/uwb/allocator.c +++ b/drivers/uwb/allocator.c @@ -16,6 +16,7 @@ * along with this program. If not, see . */ #include +#include #include #include "uwb-internal.h" diff --git a/drivers/uwb/beacon.c b/drivers/uwb/beacon.c index 36bc315..dcdd59b 100644 --- a/drivers/uwb/beacon.c +++ b/drivers/uwb/beacon.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "uwb-internal.h" diff --git a/drivers/uwb/drp-ie.c b/drivers/uwb/drp-ie.c index 2840d7b..5206731 100644 --- a/drivers/uwb/drp-ie.c +++ b/drivers/uwb/drp-ie.c @@ -18,6 +18,7 @@ */ #include #include +#include #include #include "uwb-internal.h" diff --git a/drivers/uwb/drp.c b/drivers/uwb/drp.c index 4f5ca99..a8d83e2 100644 --- a/drivers/uwb/drp.c +++ b/drivers/uwb/drp.c @@ -20,6 +20,7 @@ */ #include #include +#include #include #include "uwb-internal.h" diff --git a/drivers/uwb/est.c b/drivers/uwb/est.c index 328fcc2..a2eaa3c 100644 --- a/drivers/uwb/est.c +++ b/drivers/uwb/est.c @@ -40,6 +40,7 @@ * uwb_est_get_size() */ #include +#include #include "uwb-internal.h" diff --git a/drivers/uwb/hwa-rc.c b/drivers/uwb/hwa-rc.c index b409c228f..2babcd4 100644 --- a/drivers/uwb/hwa-rc.c +++ b/drivers/uwb/hwa-rc.c @@ -53,6 +53,7 @@ */ #include #include +#include #include #include #include diff --git a/drivers/uwb/i1480/dfu/mac.c b/drivers/uwb/i1480/dfu/mac.c index 694d0da..6ec14f5 100644 --- a/drivers/uwb/i1480/dfu/mac.c +++ b/drivers/uwb/i1480/dfu/mac.c @@ -28,6 +28,7 @@ */ #include #include +#include #include #include "i1480-dfu.h" diff --git a/drivers/uwb/i1480/dfu/usb.c b/drivers/uwb/i1480/dfu/usb.c index a99e211..ba86643 100644 --- a/drivers/uwb/i1480/dfu/usb.c +++ b/drivers/uwb/i1480/dfu/usb.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/uwb/i1480/i1480u-wlp/lc.c b/drivers/uwb/i1480/i1480u-wlp/lc.c index f272dfe..def778c 100644 --- a/drivers/uwb/i1480/i1480u-wlp/lc.c +++ b/drivers/uwb/i1480/i1480u-wlp/lc.c @@ -55,6 +55,7 @@ * is being removed. * i1480u_rm() */ +#include #include #include diff --git a/drivers/uwb/i1480/i1480u-wlp/netdev.c b/drivers/uwb/i1480/i1480u-wlp/netdev.c index b236e69..f98f6ce 100644 --- a/drivers/uwb/i1480/i1480u-wlp/netdev.c +++ b/drivers/uwb/i1480/i1480u-wlp/netdev.c @@ -39,6 +39,7 @@ * i1480u_set_config(): */ +#include #include #include diff --git a/drivers/uwb/i1480/i1480u-wlp/rx.c b/drivers/uwb/i1480/i1480u-wlp/rx.c index 25a2758..d4e51e1 100644 --- a/drivers/uwb/i1480/i1480u-wlp/rx.c +++ b/drivers/uwb/i1480/i1480u-wlp/rx.c @@ -64,6 +64,7 @@ * */ +#include #include #include #include "i1480u-wlp.h" diff --git a/drivers/uwb/i1480/i1480u-wlp/tx.c b/drivers/uwb/i1480/i1480u-wlp/tx.c index 3db3449..3c117a3 100644 --- a/drivers/uwb/i1480/i1480u-wlp/tx.c +++ b/drivers/uwb/i1480/i1480u-wlp/tx.c @@ -54,6 +54,7 @@ * the times the MTU will be smaller than one page... */ +#include #include "i1480u-wlp.h" enum { diff --git a/drivers/uwb/ie.c b/drivers/uwb/ie.c index ab97668..30acec7 100644 --- a/drivers/uwb/ie.c +++ b/drivers/uwb/ie.c @@ -24,6 +24,7 @@ * FIXME: docs */ +#include #include "uwb-internal.h" /** diff --git a/drivers/uwb/lc-dev.c b/drivers/uwb/lc-dev.c index 1097e81..90113ba 100644 --- a/drivers/uwb/lc-dev.c +++ b/drivers/uwb/lc-dev.c @@ -23,6 +23,7 @@ * FIXME: docs */ #include +#include #include #include #include diff --git a/drivers/uwb/lc-rc.c b/drivers/uwb/lc-rc.c index 9611ef3..b0091c7 100644 --- a/drivers/uwb/lc-rc.c +++ b/drivers/uwb/lc-rc.c @@ -35,6 +35,7 @@ #include #include #include +#include #include "uwb-internal.h" diff --git a/drivers/uwb/neh.c b/drivers/uwb/neh.c index 78510a1..697e56a 100644 --- a/drivers/uwb/neh.c +++ b/drivers/uwb/neh.c @@ -83,6 +83,7 @@ */ #include #include +#include #include #include "uwb-internal.h" diff --git a/drivers/uwb/reset.c b/drivers/uwb/reset.c index 7f0512e..2784929 100644 --- a/drivers/uwb/reset.c +++ b/drivers/uwb/reset.c @@ -30,6 +30,7 @@ */ #include #include +#include #include #include "uwb-internal.h" diff --git a/drivers/uwb/rsv.c b/drivers/uwb/rsv.c index 6b76f4b..78c8922 100644 --- a/drivers/uwb/rsv.c +++ b/drivers/uwb/rsv.c @@ -17,6 +17,7 @@ */ #include #include +#include #include #include "uwb-internal.h" diff --git a/drivers/uwb/scan.c b/drivers/uwb/scan.c index 2d27074..76a1a1e 100644 --- a/drivers/uwb/scan.c +++ b/drivers/uwb/scan.c @@ -35,6 +35,7 @@ #include #include +#include #include "uwb-internal.h" diff --git a/drivers/uwb/umc-dev.c b/drivers/uwb/umc-dev.c index 1fc7d82..43ea998 100644 --- a/drivers/uwb/umc-dev.c +++ b/drivers/uwb/umc-dev.c @@ -6,6 +6,7 @@ * This file is released under the GNU GPL v2. */ #include +#include #include static void umc_device_release(struct device *dev) diff --git a/drivers/uwb/uwbd.c b/drivers/uwb/uwbd.c index 6210fe1..001c8b4 100644 --- a/drivers/uwb/uwbd.c +++ b/drivers/uwb/uwbd.c @@ -69,6 +69,7 @@ * Handler functions are called normally uwbd_evt_handle_*(). */ #include +#include #include #include diff --git a/drivers/uwb/whc-rc.c b/drivers/uwb/whc-rc.c index 01950c6..7349558 100644 --- a/drivers/uwb/whc-rc.c +++ b/drivers/uwb/whc-rc.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/uwb/whci.c b/drivers/uwb/whci.c index 2e27846..b221142 100644 --- a/drivers/uwb/whci.c +++ b/drivers/uwb/whci.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include diff --git a/drivers/uwb/wlp/eda.c b/drivers/uwb/wlp/eda.c index 69e0200..086fc0c 100644 --- a/drivers/uwb/wlp/eda.c +++ b/drivers/uwb/wlp/eda.c @@ -53,6 +53,7 @@ #include #include +#include #include #include "wlp-internal.h" diff --git a/drivers/uwb/wlp/messages.c b/drivers/uwb/wlp/messages.c index 7516486..3a8e033 100644 --- a/drivers/uwb/wlp/messages.c +++ b/drivers/uwb/wlp/messages.c @@ -24,6 +24,7 @@ */ #include +#include #include "wlp-internal.h" diff --git a/drivers/uwb/wlp/txrx.c b/drivers/uwb/wlp/txrx.c index 7350ed6..05dde44 100644 --- a/drivers/uwb/wlp/txrx.c +++ b/drivers/uwb/wlp/txrx.c @@ -25,6 +25,7 @@ */ #include +#include #include #include "wlp-internal.h" diff --git a/drivers/uwb/wlp/wlp-lc.c b/drivers/uwb/wlp/wlp-lc.c index 13db739..7f6a630 100644 --- a/drivers/uwb/wlp/wlp-lc.c +++ b/drivers/uwb/wlp/wlp-lc.c @@ -22,6 +22,7 @@ * FIXME: docs */ #include +#include #include "wlp-internal.h" diff --git a/drivers/uwb/wlp/wss-lc.c b/drivers/uwb/wlp/wss-lc.c index 5913c7a..90accdd 100644 --- a/drivers/uwb/wlp/wss-lc.c +++ b/drivers/uwb/wlp/wss-lc.c @@ -45,6 +45,7 @@ */ #include /* for is_valid_ether_addr */ #include +#include #include #include "wlp-internal.h" diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index a6a88df..9777583 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 7bd7a1e..5be11c9 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/drivers/video/68328fb.c b/drivers/video/68328fb.c index 2110556..75a39ea 100644 --- a/drivers/video/68328fb.c +++ b/drivers/video/68328fb.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/video/acornfb.c b/drivers/video/acornfb.c index 43d7d50..82acb8d 100644 --- a/drivers/video/acornfb.c +++ b/drivers/video/acornfb.c @@ -22,13 +22,13 @@ #include #include #include -#include #include #include #include #include #include #include +#include #include #include diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c index 82bedd7..dca48df 100644 --- a/drivers/video/amifb.c +++ b/drivers/video/amifb.c @@ -45,7 +45,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/video/arcfb.c b/drivers/video/arcfb.c index 01554d6..8d406fb 100644 --- a/drivers/video/arcfb.c +++ b/drivers/video/arcfb.c @@ -39,7 +39,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/video/asiliantfb.c b/drivers/video/asiliantfb.c index e70bc22..8cdf88e 100644 --- a/drivers/video/asiliantfb.c +++ b/drivers/video/asiliantfb.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/video/atafb.c b/drivers/video/atafb.c index b7687c5..f3aada2 100644 --- a/drivers/video/atafb.c +++ b/drivers/video/atafb.c @@ -52,7 +52,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index 11de3bf..8dce251 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c index a489be0..34a0851 100644 --- a/drivers/video/aty/aty128fb.c +++ b/drivers/video/aty/aty128fb.c @@ -52,7 +52,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/video/aty/mach64_cursor.c b/drivers/video/aty/mach64_cursor.c index 04c710804..2ba8b3c 100644 --- a/drivers/video/aty/mach64_cursor.c +++ b/drivers/video/aty/mach64_cursor.c @@ -2,7 +2,6 @@ * ATI Mach64 CT/VT/GT/LT Cursor Support */ -#include #include #include #include diff --git a/drivers/video/aty/radeon_backlight.c b/drivers/video/aty/radeon_backlight.c index 9fc8c66..256966e 100644 --- a/drivers/video/aty/radeon_backlight.c +++ b/drivers/video/aty/radeon_backlight.c @@ -12,6 +12,7 @@ #include "radeonfb.h" #include +#include #ifdef CONFIG_PMAC_BACKLIGHT #include diff --git a/drivers/video/aty/radeon_monitor.c b/drivers/video/aty/radeon_monitor.c index b4d4b88..9261c91 100644 --- a/drivers/video/aty/radeon_monitor.c +++ b/drivers/video/aty/radeon_monitor.c @@ -1,4 +1,7 @@ #include "radeonfb.h" + +#include + #include "../edid.h" static struct fb_var_screeninfo radeonfb_default_var = { diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c index a699aab..40f6132 100644 --- a/drivers/video/au1100fb.c +++ b/drivers/video/au1100fb.c @@ -52,6 +52,7 @@ #include #include #include +#include #include diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c index 0d96f1d..e77e8e4 100644 --- a/drivers/video/au1200fb.c +++ b/drivers/video/au1200fb.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include "au1200fb.h" diff --git a/drivers/video/backlight/88pm860x_bl.c b/drivers/video/backlight/88pm860x_bl.c index 93e25c7..68d2518 100644 --- a/drivers/video/backlight/88pm860x_bl.c +++ b/drivers/video/backlight/88pm860x_bl.c @@ -16,6 +16,7 @@ #include #include #include +#include #define MAX_BRIGHTNESS (0xFF) #define MIN_BRIGHTNESS (0) diff --git a/drivers/video/backlight/adp5520_bl.c b/drivers/video/backlight/adp5520_bl.c index 5183f0e..9f436e0 100644 --- a/drivers/video/backlight/adp5520_bl.c +++ b/drivers/video/backlight/adp5520_bl.c @@ -12,6 +12,7 @@ #include #include #include +#include struct adp5520_bl { struct device *master; diff --git a/drivers/video/backlight/adx_bl.c b/drivers/video/backlight/adx_bl.c index b0624b9..7f4a7c3 100644 --- a/drivers/video/backlight/adx_bl.c +++ b/drivers/video/backlight/adx_bl.c @@ -12,6 +12,7 @@ #include #include +#include #include #include #include diff --git a/drivers/video/backlight/atmel-pwm-bl.c b/drivers/video/backlight/atmel-pwm-bl.c index 2d97605..e6a66da 100644 --- a/drivers/video/backlight/atmel-pwm-bl.c +++ b/drivers/video/backlight/atmel-pwm-bl.c @@ -17,6 +17,7 @@ #include #include #include +#include struct atmel_pwm_bl { const struct atmel_pwm_bl_platform_data *pdata; diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index 68bb838..e207810 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c @@ -13,6 +13,7 @@ #include #include #include +#include #ifdef CONFIG_PMAC_BACKLIGHT #include diff --git a/drivers/video/backlight/corgi_lcd.c b/drivers/video/backlight/corgi_lcd.c index 73bdd84..1e71c35 100644 --- a/drivers/video/backlight/corgi_lcd.c +++ b/drivers/video/backlight/corgi_lcd.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL) diff --git a/drivers/video/backlight/cr_bllcd.c b/drivers/video/backlight/cr_bllcd.c index 1cce603..a4f4546 100644 --- a/drivers/video/backlight/cr_bllcd.c +++ b/drivers/video/backlight/cr_bllcd.c @@ -36,6 +36,7 @@ #include #include #include +#include /* The LVDS- and panel power controls sits on the * GPIO port of the ISA bridge. diff --git a/drivers/video/backlight/da903x_bl.c b/drivers/video/backlight/da903x_bl.c index 686e4a7..87659ed 100644 --- a/drivers/video/backlight/da903x_bl.c +++ b/drivers/video/backlight/da903x_bl.c @@ -18,6 +18,7 @@ #include #include #include +#include #define DA9030_WLED_CONTROL 0x25 #define DA9030_WLED_CP_EN (1 << 6) diff --git a/drivers/video/backlight/ili9320.c b/drivers/video/backlight/ili9320.c index ba89b41..5118a9f 100644 --- a/drivers/video/backlight/ili9320.c +++ b/drivers/video/backlight/ili9320.c @@ -17,6 +17,7 @@ #include #include #include +#include #include diff --git a/drivers/video/backlight/l4f00242t03.c b/drivers/video/backlight/l4f00242t03.c index 74abd69..bcdb12c 100644 --- a/drivers/video/backlight/l4f00242t03.c +++ b/drivers/video/backlight/l4f00242t03.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c index 9b3be74..71a11ca 100644 --- a/drivers/video/backlight/lcd.c +++ b/drivers/video/backlight/lcd.c @@ -13,6 +13,7 @@ #include #include #include +#include #if defined(CONFIG_FB) || (defined(CONFIG_FB_MODULE) && \ defined(CONFIG_LCD_CLASS_DEVICE_MODULE)) diff --git a/drivers/video/backlight/lms283gf05.c b/drivers/video/backlight/lms283gf05.c index 447b542..abc43a0 100644 --- a/drivers/video/backlight/lms283gf05.c +++ b/drivers/video/backlight/lms283gf05.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include diff --git a/drivers/video/backlight/ltv350qv.c b/drivers/video/backlight/ltv350qv.c index 4631ca8..8010aae 100644 --- a/drivers/video/backlight/ltv350qv.c +++ b/drivers/video/backlight/ltv350qv.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include "ltv350qv.h" diff --git a/drivers/video/backlight/max8925_bl.c b/drivers/video/backlight/max8925_bl.c index c91adaf..b5accc9 100644 --- a/drivers/video/backlight/max8925_bl.c +++ b/drivers/video/backlight/max8925_bl.c @@ -16,6 +16,7 @@ #include #include #include +#include #define MAX_BRIGHTNESS (0xff) #define MIN_BRIGHTNESS (0) diff --git a/drivers/video/backlight/omap1_bl.c b/drivers/video/backlight/omap1_bl.c index 333d28e..d3bc562 100644 --- a/drivers/video/backlight/omap1_bl.c +++ b/drivers/video/backlight/omap1_bl.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include diff --git a/drivers/video/backlight/platform_lcd.c b/drivers/video/backlight/platform_lcd.c index 738694d..302330a 100644 --- a/drivers/video/backlight/platform_lcd.c +++ b/drivers/video/backlight/platform_lcd.c @@ -16,6 +16,7 @@ #include #include #include +#include #include